From 48f4db30d9dd970c4daa5dc7615d2f8b03051524 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 22 Feb 2017 02:25:55 +0000 Subject: [PATCH] The 3.2.65-1+deb7u2 kernel is no longer used. --- .../lib/platform-config-defaults-x86-64.yml | 14 +- .../any/kernels/3.2.65-1+deb7u2/.gitignore | 4 - .../configs/powerpc-e500v-all/.gitignore | 1 - .../configs/powerpc-e500v-all/Makefile | 44 - .../powerpc-e500v-all.config | 2365 - .../configs/x86_64-all/.gitignore | 1 - .../configs/x86_64-all/Makefile | 42 - .../configs/x86_64-all/x86_64-all.config | 3071 - .../any/kernels/3.2.65-1+deb7u2/kconfig.mk | 31 - .../patches/CVE-2016-5195.patch | 75 - .../kernels/3.2.65-1+deb7u2/patches/README | 17 - .../3.2.65-1+deb7u2/patches/README.cumulus | 36 - .../patches/arch-intel-centerton-pci-id.patch | 20 - .../arch-intel-centerton-reboot-cf9.patch | 91 - ...-driven-pci-maxpayload-readreq-setup.patch | 121 - .../patches/arch-intel-reboot-cf9-cold.patch | 23 - .../patches/arch-nr-gpio.patch | 15 - .../patches/arch-powerpc-cacheinfo.patch | 89 - .../arch-powerpc-emulated-lwsync.patch | 45 - .../patches/arch-powerpc-jtag.patch | 59 - ...-driven-pci-maxpayload-readreq-setup.patch | 126 - ...-specific-overrides-of-panic_timeout.patch | 33 - .../patches/arch-powerpc-topology-info.patch | 63 - .../arch-powerpc-warn-unmapped-irq.patch | 20 - .../patches/debian-build.patch | 13 - .../debian-cumulus-config-abi-ref.patch | 4920 - .../patches/debian-cumulus-controlfiles.patch | 163 - .../patches/debian-cumulus-post-inst.patch | 60 - .../debian-postinstall-call-depmod.patch | 32 - ...dt7470-knob-to-disable-smbus-timeout.patch | 57 - ...river-at24-add-i2cblock-disable-flag.patch | 41 - .../driver-at24-byte-word-write-access.patch | 105 - .../patches/driver-at24-eeprom-class.patch | 78 - ...-at24-fix-odd-length-two-byte-access.patch | 40 - .../patches/driver-at24-smbus-addr16.patch | 49 - .../patches/driver-broadcom-tigon3.patch | 27389 --- .../patches/driver-cy8c3245-hwmon.patch | 1126 - .../patches/driver-cy8c3245r1-hwmon.patch | 1127 - .../patches/driver-ds100df410-retimer.patch | 546 - .../patches/driver-early-dma-allocator.patch | 357 - .../patches/driver-eeprom-class.patch | 345 - .../driver-esdhc-p2020-broken-timeout.patch | 16 - .../patches/driver-fsl-dpaa_eth.patch | 154125 --------------- .../patches/driver-gpio-intel-sch.patch | 233 - .../driver-gpio-mpc8xxx-do-not-set.patch | 22 - ...r-hwmon-adt7475-clear-pwm-invert-bit.patch | 47 - .../driver-hwmon-max6620-fix-rpm-calc.patch | 190 - .../patches/driver-hwmon-max6620.patch | 743 - .../patches/driver-hwmon-max6697.patch | 856 - .../driver-hwmon-pmbus-dni_dps460.patch | 294 - .../patches/driver-i2c-bus-intel-avoton.patch | 22 - .../driver-i2c-bus-intel-i801-update.patch | 974 - ...r-i2c-bus-intel-ismt-add-delay-param.patch | 50 - .../driver-i2c-bus-intel-ismt-header.patch | 159 - .../patches/driver-i2c-bus-intel-ismt.patch | 1137 - .../patches/driver-i2c-mux-device-tree.patch | 247 - .../driver-mfd-intel-centerton-lpc-sch.patch | 210 - .../patches/driver-mfd-lpc-ich.patch | 1191 - .../patches/driver-mtd-micron-spiroms.patch | 134 - .../patches/driver-pata-port-width.patch | 270 - .../patches/driver-pca9505-i2c-gpio.patch | 874 - ...c-mux-deselect-on-exit-config-option.patch | 30 - ...2c-mux-deselect-on-exit-dtb-property.patch | 66 - .../patches/driver-rtc-hw-clock-fix-up.patch | 92 - .../driver-run-time-cfi-byte-swapping.patch | 236 - .../patches/driver-s6000-i2c-gpio-mux.patch | 157 - .../patches/driver-smsc-emc2305-hwmon.patch | 1040 - ...river-support-intel-igb-bcm54616-phy.patch | 77 - ...river-support-intel-igb-bcm5461s-phy.patch | 229 - .../driver-support-sff-8436-eeprom.patch | 1072 - .../patches/driver-watchdog-itco-wd.patch | 2150 - .../drivers-hwmon-adm1021-detect.patch | 29 - .../drivers-i2c-busses-i2c-isch-timeout.patch | 36 - ...ethernet-broadcom-tg3-preamble-reset.patch | 44 - .../ethtool-stats-fix-kzalloc-flags.patch | 24 - .../3.2.65-1+deb7u2/patches/git-ignore.patch | 37 - ...out-unsafe-suid_dumpable-core_patter.patch | 130 - ...ompiling-firmware-into-kernel-binary.patch | 301 - ...pable-2-require-fully-qualified-path.patch | 134 - .../patches/kernel-fs-overlayfs-inode.patch | 12 - ...ernel-generic-access-phys-null-check.patch | 22 - .../patches/kernel-nowarn-sysctl.patch | 28 - .../kernel-oom-proc-file-warning.patch | 21 - .../patches/kernel-overlayfs-v11.patch | 3219 - ...anic-Make-panic_timeout-configurable.patch | 68 - .../kernel-ubifs-xattr-symlinks-bugs.patch | 106 - .../patches/network-add-port-genl.patch | 1399 - ...-xtables-match-and-target-extensions.patch | 1402 - .../network-arp-allow-per-if-arp_accept.patch | 43 - ...ork-bonding-advertise-slave-activity.patch | 317 - ...twork-bonding-advertise-speed-duplex.patch | 143 - .../network-bonding-clag-proto-down.patch | 137 - .../patches/network-bonding-clag.patch | 108 - ...nk-event-when-bonding-option-changes.patch | 372 - ...-cumulus-add-support-for-RTM_GETLINK.patch | 412 - ...rk-bonding-fix-bond-open-slave-state.patch | 17 - ...twork-bonding-fix-inconsistent-stats.patch | 177 - .../network-bonding-fix-min-links.patch | 56 - ...-race-between-sysfs-and-bond_enslave.patch | 39 - ...-bonding-fix-scheduling-while-atomic.patch | 57 - ...ing-lacp-fallback-check-bonding-mode.patch | 48 - ...bonding-lacp-fix-incorrect-mux-state.patch | 135 - ...twork-bonding-lacp-no-tx-full-duplex.patch | 79 - .../network-bonding-no-initial-bond0.patch | 19 - ...ding-rtnl-dump-lacp-fallback-support.patch | 83 - ...network-bonding-set-sys-mac-priority.patch | 298 - ...ridge-Add-br_multicast_start_querier.patch | 55 - ...cast_querier-toggle-and-disable-quer.patch | 122 - ...-encode-addresses-when-dumping-mdb-e.patch | 28 - ...ly-unregister-MDB-rtnetlink-handlers.patch | 56 - ...register-all-PF_BRIDGE-rtnl-operatio.patch | 75 - ...-typo-in-setup-of-multicast_querier_.patch | 36 - ...rt-queries-when-last-querier-expires.patch | 59 - ...-to-distinguish-permanent-mdb-entire.patch | 112 - ...ge-add-per-vlan-igmp-querier-support.patch | 411 - ...rt-of-adding-and-deleting-mdb-entrie.patch | 410 - .../network-bridge-address-from-brport | 20 - ...dge-allow-fdb-replace-in-block-state.patch | 20 - ...ow-unprivileged-users-add-delete-mdb.patch | 25 - .../patches/network-bridge-cdp-process.patch | 32 - .../patches/network-bridge-default-pvid.patch | 146 - .../network-bridge-disable-mixed-vlans.patch | 155 - ...able-multiple-sub-intfs-on-same-port.patch | 79 - ...able-snooping-if-there-is-no-querier.patch | 197 - .../network-bridge-disable-sw-bridging.patch | 135 - ...-to-update-timers-in-case-of-broken-.patch | 34 - ...etwork-bridge-dont-install-local-mac.patch | 148 - ...xport-multicast-database-via-netlink.patch | 374 - ...ork-bridge-fdb-add-check-port-status.patch | 19 - .../patches/network-bridge-fdb-add-self.patch | 149 - .../patches/network-bridge-fdb-del-fix.patch | 65 - .../network-bridge-fdb-learn-priority.patch | 161 - .../network-bridge-fdb-mdb-vlan-fix.patch | 161 - ...ink-dump-interface-in-par-with-brctl.patch | 210 - .../network-bridge-fdb-show-filter.patch | 91 - ...bridge-fdb-show-fix-filter-by-bridge.patch | 33 - ...e-filtering-support-for-default-pvid.patch | 210 - ...-when-set-mac-address-of-br-interfac.patch | 33 - .../patches/network-bridge-fix-endian.patch | 22 - .../network-bridge-fix-fdb-show-filter.patch | 129 - ...network-bridge-fix-fdb-update-notify.patch | 70 - ...6-endian-bug-and-other-sparse-warnin.patch | 33 - ...-bridge-fix-link-local-rx-drop-count.patch | 44 - .../network-bridge-fix-pvid-delete.patch | 96 - ...-bridge-fix-seq-check-in-br_mdb_dump.patch | 69 - .../network-bridge-get-default-pvid.patch | 55 - .../network-bridge-igmp-fast-leave.patch | 76 - .../network-bridge-igmp-ifupdown-fixes.patch | 49 - .../patches/network-bridge-igmpv3.patch | 58 - ...ridge-implement-multicast-fast-leave.patch | 97 - .../patches/network-bridge-initial-mac.patch | 43 - .../network-bridge-ipoptions-fix.patch | 43 - .../network-bridge-lacp-fallback.patch | 820 - ...etwork-bridge-local-fdb-delete-check.patch | 139 - .../network-bridge-mac-move-notify-vm.patch | 26 - ...ake-master-index-partof-rtmneigh-msh.patch | 34 - ...ge-make-path-cost-setting-persistent.patch | 52 - .../network-bridge-mdb-dump-vlan.patch | 46 - .../patches/network-bridge-mdb-hash.patch | 26 - ...rk-bridge-mdb-leave-dually-connected.patch | 21 - .../patches/network-bridge-mdb-notify.patch | 152 - .../patches/network-bridge-mdb-replace.patch | 15 - .../network-bridge-mdb-rtrport-opt.patch | 27 - .../network-bridge-mdb-static-del.patch | 22 - .../patches/network-bridge-mdb-timer.patch | 162 - .../network-bridge-mdb-unspecified-vlan.patch | 98 - .../network-bridge-mlag-peer-dual-link.patch | 113 - ...-rid-of-MLDV2_MRC-and-simplify-calcu.patch | 100 - ...work-bridge-move-logging-to-pr-debug.patch | 15 - .../patches/network-bridge-mrouter-fix.patch | 61 - ...ridge-notify-mdb-changes-via-netlink.patch | 129 - .../network-bridge-porting-new-driver.patch | 9687 - ...revent-fdb-insert-in-disallowed-vlan.patch | 107 - .../patches/network-bridge-pvst.patch | 33 - .../network-bridge-querier-ifaddr.patch | 66 - ...k-bridge-rearrange-fdb-notifications.patch | 214 - .../network-bridge-remove-vid-end-check.patch | 21 - .../network-bridge-report-supression.patch | 269 - ...rk-bridge-revert-v6-link-local-snoop.patch | 98 - ...d-query-as-soon-as-leave-is-received.patch | 51 - .../patches/network-bridge-single-stp.patch | 308 - ...etwork-bridge-solicited-node-forward.patch | 45 - .../patches/network-bridge-static-addr.patch | 194 - .../network-bridge-static-mcgrp-fix.patch | 222 - .../network-bridge-stp-carrier-check.patch | 18 - .../patches/network-bridge-stp-changes.patch | 80 - ...ork-bridge-stp-disabled-bpdu-forward.patch | 93 - .../patches/network-bridge-stp-logging.patch | 64 - ...e-use-ipv4_is_local_multicast-helper.patch | 21 - ...ridge-IP-addr-as-source-addr-for-que.patch | 111 - ...twork-bridge-vlan-filter-auto-enable.patch | 136 - .../network-bridge-vlan-range-support.patch | 196 - ...TM_DELLINK-to-until-after-ndo-uninit.patch | 171 - ...TM_DELLINK-to-until-after-ndo-uninit.patch | 54 - .../patches/network-core-proto-down.patch | 254 - ...r-mtu-change-even-if-iface-is-not-up.patch | 23 - .../patches/network-disable-hw-aclstats.patch | 138 - .../network-disable-mixed-vlans-bridge.patch | 87 - .../network-ethtool-sfp-gang-support.patch | 17 - .../network-fix-dead-route-issues.patch | 266 - ...route-lookup-failures-when-link-down.patch | 131 - ...network-fixup-ipv6-route-link-issues.patch | 72 - .../network-increase-max-igmp-groups.patch | 23 - ...rk-ipv4-fib-flush-dead-routes-notify.patch | 59 - ...gmp-use-in_dev_put-in-timer-handlers.patch | 46 - ...-include-append-flag-in-notification.patch | 32 - ...d-nlflags-in-route-insert-notify-msg.patch | 15 - .../network-ipv6-add-ecmp-support.patch | 348 - ...ited-ND-on-link-layer-address-change.patch | 89 - ...ipv6-assign-rt6_info-to-inet6_ifaddr.patch | 38 - ...network-ipv6-blackhole-route-support.patch | 107 - ...addrconf_dst_alloc-again-when-enable.patch | 37 - ...dont-disable-interface-with-no-addrs.patch | 27 - ...6-fib-fix-fib-dump-restart-next-node.patch | 37 - ...etwork-ipv6-fib-fix-fib-dump-restart.patch | 33 - ...st-use-in6_dev_put-in-timer-handlers.patch | 46 - ...ute-fix-multipath-duplicate-nexthops.patch | 71 - ...prefix-route-for-prefix-route-lookup.patch | 79 - .../network-link-routes-and-carrier.patch | 356 - .../patches/network-mcast-maxvifs.patch | 15 - .../patches/network-mdb-top-change.patch | 288 - ...etwork-neigh-fix-neigh-update-notify.patch | 14 - ...pdate-neighbour-h-to-latest-upstream.patch | 18 - ...thtool-get-return-success-on-enodata.patch | 25 - .../network-port-ethtool-handle-errors.patch | 44 - ...ort-ethtool-rtnl-lock-handling-fixes.patch | 484 - ...-port-genl-add-ethtool-settings-pull.patch | 171 - ...network-restore-default-tun-behavior.patch | 79 - ...i-for-getting-and-setting-slave-info.patch | 308 - ...dd-del-remove-redundant-notification.patch | 30 - .../patches/network-stp-sysctl.patch | 146 - .../patches/network-tcp-md5sig-debug.patch | 436 - ...-md5sig-pseudoheader-calc-workaround.patch | 89 - .../network-tun-64-bit-statistics.patch | 130 - .../patches/network-tun-ethtool.patch | 248 - .../patches/network-tun-max-mtu.patch | 21 - .../patches/network-tun-no-carrier.patch | 34 - .../patches/network-virt-ethtool.patch | 703 - ...work-virtio-net-ethtool-set-settings.patch | 104 - .../network-virtio-net-speed-duplex.patch | 32 - .../patches/network-virtio-proto-down.patch | 96 - .../patches/network-vlan-sysctl-tune.patch | 35 - ...vxlan-fdb-update-hardware-forwarding.patch | 21 - .../network-vxlan-fdb-update-used.patch | 52 - .../network-vxlan-fix-fdb-update.patch | 49 - ...etwork-vxlan-fix-incomplete-backport.patch | 19 - ...ip-select-ident-parameter-iph-to-skb.patch | 15 - .../network-vxlan-self-replication.patch | 350 - .../patches/network-vxlan-support.patch | 2426 - .../patches/overlayfs_notify.patch | 264 - .../patches/platform-accton-5652.patch | 1252 - .../patches/platform-accton-as4600_54t.patch | 574 - .../patches/platform-accton-as5610_52x.patch | 1443 - .../patches/platform-accton-as6700_32x.patch | 1142 - .../patches/platform-accton-as6701-32x.patch | 436 - .../platform-bcm98548xmc-fix-reset-init.patch | 54 - .../patches/platform-bcm98548xmc.patch | 580 - .../patches/platform-cel-p2020.patch | 2151 - .../patches/platform-celestica-cpld-i2c.patch | 701 - .../patches/platform-cumulus-p2020.patch | 469 - .../patches/platform-dni-6448-i2c-mux.patch | 349 - .../patches/platform-dni-6448.patch | 672 - .../patches/platform-dni-7448.patch | 608 - .../patches/platform-dni-c7448n.patch | 607 - .../platform-powerpc-85xx-Makefile.patch | 132 - ...latform-powerpc-accton-as4600-54t-r0.patch | 483 - ...latform-powerpc-accton-as5610-52x-r0.patch | 588 - ...platform-powerpc-dell-s4810-p2020-r0.patch | 496 - .../platform-powerpc-dni-7448-r0.patch | 496 - .../platform-powerpc-quanta-lb9-r0.patch | 722 - .../platform-powerpc-quanta-ly2-r0.patch | 2491 - .../patches/platform-quanta-i2c-mux.patch | 303 - .../patches/platform-quanta-lb8.patch | 789 - .../patches/platform-quanta-lb9.patch | 762 - .../patches/platform-quanta-ly2-ly2r.patch | 1917 - .../patches/platform-quanta-ly2.patch | 1768 - .../patches/platform-quanta-ly6-p2020.patch | 1024 - .../replace-fallback-with-bypass.patch | 833 - .../kernels/3.2.65-1+deb7u2/patches/series | 246 - 279 files changed, 1 insertion(+), 271675 deletions(-) delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/.gitignore delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/configs/powerpc-e500v-all/.gitignore delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/configs/powerpc-e500v-all/Makefile delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/configs/powerpc-e500v-all/powerpc-e500v-all.config delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/configs/x86_64-all/.gitignore delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/configs/x86_64-all/Makefile delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/configs/x86_64-all/x86_64-all.config delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/kconfig.mk delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/CVE-2016-5195.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/README delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/README.cumulus delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-centerton-pci-id.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-centerton-reboot-cf9.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-os-driven-pci-maxpayload-readreq-setup.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-reboot-cf9-cold.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-nr-gpio.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-cacheinfo.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-emulated-lwsync.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-jtag.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-os-driven-pci-maxpayload-readreq-setup.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-remove-arch-specific-overrides-of-panic_timeout.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-topology-info.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-warn-unmapped-irq.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-build.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-cumulus-config-abi-ref.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-cumulus-controlfiles.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-cumulus-post-inst.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-postinstall-call-depmod.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-adt7470-knob-to-disable-smbus-timeout.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-add-i2cblock-disable-flag.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-byte-word-write-access.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-eeprom-class.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-fix-odd-length-two-byte-access.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-smbus-addr16.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-broadcom-tigon3.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-cy8c3245-hwmon.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-cy8c3245r1-hwmon.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-ds100df410-retimer.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-early-dma-allocator.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-eeprom-class.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-esdhc-p2020-broken-timeout.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-fsl-dpaa_eth.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-gpio-intel-sch.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-gpio-mpc8xxx-do-not-set.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-adt7475-clear-pwm-invert-bit.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-max6620-fix-rpm-calc.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-max6620.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-max6697.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-pmbus-dni_dps460.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-avoton.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-i801-update.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-ismt-add-delay-param.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-ismt-header.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-ismt.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-mux-device-tree.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-mfd-intel-centerton-lpc-sch.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-mfd-lpc-ich.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-mtd-micron-spiroms.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pata-port-width.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pca9505-i2c-gpio.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pca954x-i2c-mux-deselect-on-exit-config-option.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pca954x-i2c-mux-deselect-on-exit-dtb-property.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-rtc-hw-clock-fix-up.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-run-time-cfi-byte-swapping.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-s6000-i2c-gpio-mux.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-smsc-emc2305-hwmon.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-support-intel-igb-bcm54616-phy.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-support-intel-igb-bcm5461s-phy.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-support-sff-8436-eeprom.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-watchdog-itco-wd.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/drivers-hwmon-adm1021-detect.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/drivers-i2c-busses-i2c-isch-timeout.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/drivers-net-ethernet-broadcom-tg3-preamble-reset.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/ethtool-stats-fix-kzalloc-flags.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/git-ignore.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-coredump-warn-about-unsafe-suid_dumpable-core_patter.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-enable-compiling-firmware-into-kernel-binary.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-fs-make-dumpable-2-require-fully-qualified-path.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-fs-overlayfs-inode.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-generic-access-phys-null-check.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-nowarn-sysctl.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-oom-proc-file-warning.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-overlayfs-v11.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-panic-Make-panic_timeout-configurable.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-ubifs-xattr-symlinks-bugs.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-add-port-genl.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-add-xtables-match-and-target-extensions.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-arp-allow-per-if-arp_accept.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-advertise-slave-activity.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-advertise-speed-duplex.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-clag-proto-down.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-clag.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-create-netlink-event-when-bonding-option-changes.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-cumulus-add-support-for-RTM_GETLINK.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-bond-open-slave-state.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-inconsistent-stats.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-min-links.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-race-between-sysfs-and-bond_enslave.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-scheduling-while-atomic.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-lacp-fallback-check-bonding-mode.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-lacp-fix-incorrect-mux-state.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-lacp-no-tx-full-duplex.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-no-initial-bond0.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-rtnl-dump-lacp-fallback-support.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-set-sys-mac-priority.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Add-br_multicast_start_querier.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Add-multicast_querier-toggle-and-disable-quer.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Correctly-encode-addresses-when-dumping-mdb-e.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Correctly-unregister-MDB-rtnetlink-handlers.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Do-not-unregister-all-PF_BRIDGE-rtnl-operatio.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Fix-fatal-typo-in-setup-of-multicast_querier_.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Restart-queries-when-last-querier-expires.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-add-flags-to-distinguish-permanent-mdb-entire.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-add-per-vlan-igmp-querier-support.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-add-support-of-adding-and-deleting-mdb-entrie.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-address-from-brport delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-allow-fdb-replace-in-block-state.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-allow-unprivileged-users-add-delete-mdb.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-cdp-process.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-default-pvid.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-mixed-vlans.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-multiple-sub-intfs-on-same-port.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-snooping-if-there-is-no-querier.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-sw-bridging.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-don-t-try-to-update-timers-in-case-of-broken-.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-dont-install-local-mac.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-export-multicast-database-via-netlink.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-add-check-port-status.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-add-self.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-del-fix.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-learn-priority.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-mdb-vlan-fix.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-netlink-dump-interface-in-par-with-brctl.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-show-filter.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-show-fix-filter-by-bridge.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-filtering-support-for-default-pvid.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-crash-when-set-mac-address-of-br-interfac.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-endian.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-fdb-show-filter.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-fdb-update-notify.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-icmpv6-endian-bug-and-other-sparse-warnin.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-link-local-rx-drop-count.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-pvid-delete.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-seq-check-in-br_mdb_dump.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-get-default-pvid.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-igmp-fast-leave.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-igmp-ifupdown-fixes.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-igmpv3.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-implement-multicast-fast-leave.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-initial-mac.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-ipoptions-fix.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-lacp-fallback.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-local-fdb-delete-check.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mac-move-notify-vm.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-make-master-index-partof-rtmneigh-msh.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-make-path-cost-setting-persistent.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-dump-vlan.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-hash.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-leave-dually-connected.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-notify.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-replace.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-rtrport-opt.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-static-del.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-timer.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-unspecified-vlan.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mlag-peer-dual-link.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mld-get-rid-of-MLDV2_MRC-and-simplify-calcu.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-move-logging-to-pr-debug.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mrouter-fix.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-notify-mdb-changes-via-netlink.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-porting-new-driver.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-prevent-fdb-insert-in-disallowed-vlan.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-pvst.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-querier-ifaddr.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-rearrange-fdb-notifications.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-remove-vid-end-check.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-report-supression.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-revert-v6-link-local-snoop.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-send-query-as-soon-as-leave-is-received.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-single-stp.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-solicited-node-forward.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-static-addr.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-static-mcgrp-fix.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-carrier-check.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-changes.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-disabled-bpdu-forward.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-logging.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-use-ipv4_is_local_multicast-helper.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-use-the-bridge-IP-addr-as-source-addr-for-que.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-vlan-filter-auto-enable.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-vlan-range-support.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-core-fix-notify-for-move-RTM_DELLINK-to-until-after-ndo-uninit.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-core-move-RTM_DELLINK-to-until-after-ndo-uninit.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-core-proto-down.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-dev-net-call-notifiers-for-mtu-change-even-if-iface-is-not-up.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-disable-hw-aclstats.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-disable-mixed-vlans-bridge.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ethtool-sfp-gang-support.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-fix-dead-route-issues.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-fix-route-lookup-failures-when-link-down.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-fixup-ipv6-route-link-issues.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-increase-max-igmp-groups.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-fib-flush-dead-routes-notify.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-igmp-use-in_dev_put-in-timer-handlers.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-include-append-flag-in-notification.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-send-nlflags-in-route-insert-notify-msg.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-add-ecmp-support.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-add-knob-to-send-unsolicited-ND-on-link-layer-address-change.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-assign-rt6_info-to-inet6_ifaddr.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-blackhole-route-support.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-dont-call-addrconf_dst_alloc-again-when-enable.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-dont-disable-interface-with-no-addrs.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-fib-fix-fib-dump-restart-next-node.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-fib-fix-fib-dump-restart.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-mcast-use-in6_dev_put-in-timer-handlers.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-route-fix-multipath-duplicate-nexthops.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-use-addrconf-get-prefix-route-for-prefix-route-lookup.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-link-routes-and-carrier.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-mcast-maxvifs.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-mdb-top-change.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-neigh-fix-neigh-update-notify.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-neighbour-update-neighbour-h-to-latest-upstream.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-ethtool-get-return-success-on-enodata.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-ethtool-handle-errors.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-ethtool-rtnl-lock-handling-fixes.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-genl-add-ethtool-settings-pull.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-restore-default-tun-behavior.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-rtnetlink-provide-api-for-getting-and-setting-slave-info.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-rtnl-fdb-add-del-remove-redundant-notification.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-stp-sysctl.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tcp-md5sig-debug.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tcp-md5sig-pseudoheader-calc-workaround.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-64-bit-statistics.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-ethtool.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-max-mtu.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-no-carrier.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virt-ethtool.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virtio-net-ethtool-set-settings.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virtio-net-speed-duplex.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virtio-proto-down.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vlan-sysctl-tune.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fdb-update-hardware-forwarding.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fdb-update-used.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fix-fdb-update.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fix-incomplete-backport.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-ip-select-ident-parameter-iph-to-skb.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-self-replication.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-support.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/overlayfs_notify.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-5652.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as4600_54t.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as5610_52x.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as6700_32x.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as6701-32x.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-bcm98548xmc-fix-reset-init.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-bcm98548xmc.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-cel-p2020.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-celestica-cpld-i2c.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-cumulus-p2020.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-6448-i2c-mux.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-6448.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-7448.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-c7448n.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-85xx-Makefile.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-accton-as4600-54t-r0.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-accton-as5610-52x-r0.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-dell-s4810-p2020-r0.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-dni-7448-r0.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-quanta-lb9-r0.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-quanta-ly2-r0.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-i2c-mux.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-lb8.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-lb9.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-ly2-ly2r.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-ly2.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-ly6-p2020.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/replace-fallback-with-bypass.patch delete mode 100644 packages/base/any/kernels/3.2.65-1+deb7u2/patches/series diff --git a/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-x86-64.yml b/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-x86-64.yml index 114ca762..eb446a9c 100644 --- a/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-x86-64.yml +++ b/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-x86-64.yml @@ -19,25 +19,13 @@ default: # this is mostly to *reject* invalid disk labels, # since we will never create our own - kernel-3.2: &kernel-3-2 - =: kernel-3.2-deb7-x86_64-all - package: onl-kernel-3.2-deb7-x86-64-all:amd64 - - kernel-3.9.6: &kernel-3-9-6 - =: kernel-3.9.6-x86-64-all - package: onl-kernel-3.9.6-x86-64-all:amd64 - - kernel-3.18: &kernel-3-18 - =: kernel-3.18-x86_64-all - package: onl-kernel-3.18-x86-64-all:amd64 - kernel-3.16: &kernel-3-16 =: kernel-3.16-lts-x86_64-all package: onl-kernel-3.16-lts-x86-64-all:amd64 # pick one of the above kernels kernel: - <<: *kernel-3-2 + <<: *kernel-3-16 # GRUB command line arguments for 'serial' declaration # this is equivalent to, but not in the same format as, diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/.gitignore b/packages/base/any/kernels/3.2.65-1+deb7u2/.gitignore deleted file mode 100644 index 88a4b311..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -linux-3.2.65-1+deb7u2 -linux-3.2.65-1+deb7u2-mbuild -linux-3.2.65-1+deb7u2-dtbs - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/configs/powerpc-e500v-all/.gitignore b/packages/base/any/kernels/3.2.65-1+deb7u2/configs/powerpc-e500v-all/.gitignore deleted file mode 100644 index 921a8fc4..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/configs/powerpc-e500v-all/.gitignore +++ /dev/null @@ -1 +0,0 @@ -kernel-3.2-deb7-powerpc-e500-all* diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/configs/powerpc-e500v-all/Makefile b/packages/base/any/kernels/3.2.65-1+deb7u2/configs/powerpc-e500v-all/Makefile deleted file mode 100644 index 9d66ae1e..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/configs/powerpc-e500v-all/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -############################################################ -# -# -# Copyright 2015 Big Switch Networks, Inc. -# -# Licensed under the Eclipse Public License, Version 1.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.eclipse.org/legal/epl-v10.html -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -# either express or implied. See the License for the specific -# language governing permissions and limitations under the -# License. -# -# -############################################################ -# -# Default 3.2.65-1+deb7u2 configuration for PowerPC e500v platforms. -# -############################################################ -THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) -include $(ONL)/make/config.mk - -ifndef K_TARGET_DIR -K_TARGET_DIR := $(THIS_DIR) -endif - -include ../../kconfig.mk -K_CONFIG := powerpc-e500v-all.config -K_BUILD_TARGET := uImage -K_COPY_SRC := vmlinux.bin.gz -ifndef K_COPY_DST -K_COPY_DST := kernel-3.2-deb7-powerpc-e500-all.bin.gz -endif - -export ARCH=powerpc -DTS_LIST := powerpc-quanta-lb9-r0 powerpc-quanta-ly2-r0 powerpc-accton-as4600-54t-r0 powerpc-accton-as5610-52x-r0 powerpc-dni-7448-r0 powerpc-dell-s4810-p2020-r0 - -include $(ONL)/make/kbuild.mk - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/configs/powerpc-e500v-all/powerpc-e500v-all.config b/packages/base/any/kernels/3.2.65-1+deb7u2/configs/powerpc-e500v-all/powerpc-e500v-all.config deleted file mode 100644 index 80590231..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/configs/powerpc-e500v-all/powerpc-e500v-all.config +++ /dev/null @@ -1,2365 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# Linux/powerpc 3.2.65 Kernel Configuration -# -# CONFIG_PPC64 is not set - -# -# Processor support -# -# CONFIG_PPC_BOOK3S_32 is not set -CONFIG_PPC_85xx=y -# CONFIG_PPC_8xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set -CONFIG_E500=y -# CONFIG_PPC_E500MC is not set -CONFIG_FSL_EMB_PERFMON=y -CONFIG_FSL_EMB_PERF_EVENT=y -CONFIG_FSL_EMB_PERF_EVENT_E500=y -CONFIG_BOOKE=y -CONFIG_FSL_BOOKE=y -CONFIG_PPC_FSL_BOOK3E=y -# CONFIG_PHYS_64BIT is not set -CONFIG_SPE=y -CONFIG_PPC_MMU_NOHASH=y -CONFIG_PPC_BOOK3E_MMU=y -# CONFIG_PPC_MM_SLICES is not set -CONFIG_SMP=y -CONFIG_NR_CPUS=8 -CONFIG_PPC32=y -CONFIG_32BIT=y -CONFIG_WORD_SIZE=32 -# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set -CONFIG_MMU=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set -# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set -CONFIG_NR_IRQS=512 -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_GPIO=y -# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_PPC_UDBG_16550=y -CONFIG_GENERIC_TBSYNC=y -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -# CONFIG_EPAPR_BOOT is not set -CONFIG_DEFAULT_UIMAGE=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y -CONFIG_PPC_ADV_DEBUG_REGS=y -CONFIG_PPC_ADV_DEBUG_IACS=2 -CONFIG_PPC_ADV_DEBUG_DACS=2 -CONFIG_PPC_ADV_DEBUG_DVCS=0 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_HAVE_IRQ_WORK=y -CONFIG_IRQ_WORK=y - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_CROSS_COMPILE="powerpc-linux-gnu-" -CONFIG_LOCALVERSION="-1+deb7u2-OpenNetworkLinux" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_DEFAULT_HOSTNAME="(none)" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -CONFIG_POSIX_MQUEUE_SYSCTL=y -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_FHANDLE is not set -# CONFIG_TASKSTATS is not set -CONFIG_AUDIT=y -# CONFIG_AUDITSYSCALL is not set -CONFIG_HAVE_GENERIC_HARDIRQS=y - -# -# IRQ subsystem -# -CONFIG_GENERIC_HARDIRQS=y -CONFIG_HAVE_SPARSE_IRQ=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_SPARSE_IRQ=y - -# -# RCU Subsystem -# -CONFIG_TREE_RCU=y -# CONFIG_PREEMPT_RCU is not set -# CONFIG_RCU_TRACE is not set -CONFIG_RCU_FANOUT=32 -# CONFIG_RCU_FANOUT_EXACT is not set -# CONFIG_RCU_FAST_NO_HZ is not set -# CONFIG_TREE_RCU_TRACE is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=17 -# CONFIG_CGROUPS is not set -# CONFIG_NAMESPACES is not set -# CONFIG_SCHED_AUTOGROUP is not set -# CONFIG_SYSFS_DEPRECATED is not set -# CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_RD_GZIP=y -# CONFIG_RD_BZIP2 is not set -# CONFIG_RD_LZMA is not set -# CONFIG_RD_XZ is not set -# CONFIG_RD_LZO is not set -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -CONFIG_EXPERT=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_EMBEDDED=y -CONFIG_HAVE_PERF_EVENTS=y - -# -# Kernel Performance Events And Counters -# -CONFIG_PERF_EVENTS=y -# CONFIG_PERF_COUNTERS is not set -# CONFIG_DEBUG_PERF_USE_VMALLOC is not set -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_PCI_QUIRKS=y -CONFIG_SLUB_DEBUG=y -CONFIG_COMPAT_BRK=y -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -# CONFIG_JUMP_LABEL is not set -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_IOREMAP_PROT=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_DMA_ATTRS=y -CONFIG_USE_GENERIC_SMP_HELPERS=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_RCU_TABLE_FREE=y -CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y - -# -# GCOV-based kernel profiling -# -# CONFIG_GCOV_KERNEL is not set -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_STOP_MACHINE=y -CONFIG_BLOCK=y -CONFIG_LBDAF=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_BSGLIB is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -CONFIG_INLINE_SPIN_UNLOCK=y -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -CONFIG_INLINE_READ_UNLOCK=y -# CONFIG_INLINE_READ_UNLOCK_BH is not set -CONFIG_INLINE_READ_UNLOCK_IRQ=y -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -CONFIG_INLINE_WRITE_UNLOCK=y -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -# CONFIG_FREEZER is not set -CONFIG_PPC_MSI_BITMAP=y -# CONFIG_PPC_XICS is not set -# CONFIG_PPC_ICP_NATIVE is not set -# CONFIG_PPC_ICP_HV is not set -# CONFIG_PPC_ICS_RTAS is not set - -# -# Platform support -# -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PQ2ADS is not set -CONFIG_FSL_SOC_BOOKE=y -# CONFIG_MPC8540_ADS is not set -# CONFIG_MPC8560_ADS is not set -# CONFIG_MPC85xx_CDS is not set -# CONFIG_MPC85xx_MDS is not set -# CONFIG_MPC8536_DS is not set -# CONFIG_MPC85xx_DS is not set -CONFIG_MPC85xx_RDB=y -# CONFIG_P1010_RDB is not set -# CONFIG_P1022_DS is not set -# CONFIG_P1023_RDS is not set -# CONFIG_SOCRATES is not set -# CONFIG_KSI8560 is not set -# CONFIG_XES_MPC85xx is not set -# CONFIG_STX_GP3 is not set -# CONFIG_TQM8540 is not set -# CONFIG_TQM8541 is not set -# CONFIG_TQM8548 is not set -# CONFIG_TQM8555 is not set -# CONFIG_TQM8560 is not set -# CONFIG_SBC8548 is not set -# CONFIG_SBC8560 is not set -# CONFIG_P2041_RDB is not set -# CONFIG_P3041_DS is not set -# CONFIG_P3060_QDS is not set -# CONFIG_P4080_DS is not set -# CONFIG_ACCTON_AS4600_54T is not set -# CONFIG_ACCTON_AS5610_52X is not set -# CONFIG_ACCTON_AS6701_32X is not set -# CONFIG_ACCTON_5652 is not set -# CONFIG_BCM98548XMC is not set -# CONFIG_CEL_P2020 is not set -# CONFIG_CEL_REDSTONE is not set -# CONFIG_CEL_KENNISIS is not set -# CONFIG_CEL_SMALLSTONE is not set -# CONFIG_CUMULUS_P2020 is not set -# CONFIG_DNI_6448 is not set -CONFIG_DNI_7448=y -# CONFIG_DNI_C7448N is not set -# CONFIG_QUANTA_LB8 is not set -CONFIG_QUANTA_LB9=y -# CONFIG_QUANTA_LY2_LY2R is not set -# CONFIG_QUANTA_LY2 is not set -# CONFIG_QUANTA_LY2R is not set -# CONFIG_QUANTA_LY6_P2020 is not set -# CONFIG_P5020_DS is not set -# CONFIG_PPC_WSP is not set -# CONFIG_KVM_GUEST is not set -CONFIG_PPC_SMP_MUXED_IPI=y -# CONFIG_IPIC is not set -CONFIG_MPIC=y -# CONFIG_PPC_EPAPR_HV_PIC is not set -# CONFIG_MPIC_WEIRD is not set -CONFIG_PPC_I8259=y -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_MPIC_U3_HT_IRQS is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_P7_NAP is not set - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set -# CONFIG_QUICC_ENGINE is not set -CONFIG_CPM2=y -CONFIG_FSL_ULI1575=y -CONFIG_CPM=y -# CONFIG_SIMPLE_GPIO is not set - -# -# Kernel options -# -CONFIG_HIGHMEM=y -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_SCHED_HRTICK=y -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -# CONFIG_HAVE_AOUT is not set -CONFIG_BINFMT_MISC=m -CONFIG_MATH_EMULATION=y -CONFIG_IOMMU_HELPER=y -CONFIG_SWIOTLB=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_HAS_WALK_MEMORY=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y -CONFIG_KEXEC=y -CONFIG_CRASH_DUMP=y -CONFIG_IRQ_ALL_CPUS=y -CONFIG_MAX_ACTIVE_REGIONS=32 -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_COMPACTION is not set -CONFIG_MIGRATION=y -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -# CONFIG_KSM is not set -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -# CONFIG_CLEANCACHE is not set -CONFIG_PPC_4K_PAGES=y -CONFIG_FORCE_MAX_ZONEORDER=11 -# CONFIG_CMDLINE_BOOL is not set -CONFIG_EXTRA_TARGETS="" -# CONFIG_HIBERNATION is not set -# CONFIG_PM_RUNTIME is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -# CONFIG_NEED_DMA_MAP_STATE is not set -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_GENERIC_ISA_DMA=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_FSL_SOC=y -CONFIG_FSL_PCI=y -CONFIG_FSL_LBC=y -# CONFIG_HAS_FSL_PAMU is not set -# CONFIG_HAS_FSL_QBMAN is not set -CONFIG_PPC_PCI_CHOICE=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_SYSCALL=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCIEAER=y -# CONFIG_PCIE_ECRC is not set -# CONFIG_PCIEAER_INJECT is not set -CONFIG_PCIEASPM=y -# CONFIG_PCIEASPM_DEBUG is not set -CONFIG_ARCH_SUPPORTS_MSI=y -CONFIG_PCI_MSI=y -# CONFIG_PCI_DEBUG is not set -# CONFIG_PCI_STUB is not set -# CONFIG_PCI_IOV is not set -# CONFIG_PCI_PRI is not set -# CONFIG_PCI_PASID is not set -# CONFIG_PCCARD is not set -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HAS_RAPIDIO is not set -# CONFIG_RAPIDIO is not set - -# -# Advanced setup -# -CONFIG_ADVANCED_OPTIONS=y -# CONFIG_LOWMEM_SIZE_BOOL is not set -CONFIG_LOWMEM_SIZE=0x30000000 -# CONFIG_LOWMEM_CAM_NUM_BOOL is not set -CONFIG_LOWMEM_CAM_NUM=3 -CONFIG_RELOCATABLE=y -# CONFIG_PAGE_OFFSET_BOOL is not set -CONFIG_PAGE_OFFSET=0xc0000000 -# CONFIG_KERNEL_START_BOOL is not set -CONFIG_KERNEL_START=0xc0000000 -# CONFIG_PHYSICAL_START_BOOL is not set -CONFIG_PHYSICAL_START=0x00000000 -CONFIG_PHYSICAL_ALIGN=0x04000000 -# CONFIG_TASK_SIZE_BOOL is not set -CONFIG_TASK_SIZE=0xc0000000 -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_NET_KEY=y -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -# CONFIG_IP_FIB_TRIE_STATS is not set -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE_DEMUX is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -CONFIG_IPV6=y -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_MIP6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET6_XFRM_MODE_TUNNEL is not set -# CONFIG_INET6_XFRM_MODE_BEET is not set -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -# CONFIG_IPV6_SIT is not set -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_IPV6_MROUTE is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_NETFILTER_ADVANCED=y - -# -# Core Netfilter Configuration -# -# CONFIG_NETFILTER_NETLINK_QUEUE is not set -# CONFIG_NETFILTER_NETLINK_LOG is not set -# CONFIG_NF_CONNTRACK is not set -CONFIG_NETFILTER_XTABLES=y - -# -# Xtables combined modules -# -# CONFIG_NETFILTER_XT_MARK is not set - -# -# Xtables targets -# -# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set -# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set -# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set -# CONFIG_NETFILTER_XT_TARGET_LED is not set -# CONFIG_NETFILTER_XT_TARGET_MARK is not set -# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set -# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set -# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set -# CONFIG_NETFILTER_XT_TARGET_TEE is not set -# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -# CONFIG_NETFILTER_XT_TARGET_ERSPAN is not set -# CONFIG_NETFILTER_XT_TARGET_SPAN is not set -# CONFIG_NETFILTER_XT_TARGET_POLICE is not set -# CONFIG_NETFILTER_XT_TARGET_TRICOLORPOLICE is not set -# CONFIG_NETFILTER_XT_TARGET_SETCLASS is not set -# CONFIG_NETFILTER_XT_TARGET_SETQOS is not set - -# -# Xtables matches -# -# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set -# CONFIG_NETFILTER_XT_MATCH_CPU is not set -# CONFIG_NETFILTER_XT_MATCH_DCCP is not set -# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -# CONFIG_NETFILTER_XT_MATCH_ESP is not set -# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set -CONFIG_NETFILTER_XT_MATCH_HL=y -# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set -# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set -# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_MAC is not set -# CONFIG_NETFILTER_XT_MATCH_MARK is not set -# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set -# CONFIG_NETFILTER_XT_MATCH_OWNER is not set -# CONFIG_NETFILTER_XT_MATCH_POLICY is not set -# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set -# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set -# CONFIG_NETFILTER_XT_MATCH_REALM is not set -# CONFIG_NETFILTER_XT_MATCH_RECENT is not set -CONFIG_NETFILTER_XT_MATCH_SCTP=y -# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set -# CONFIG_NETFILTER_XT_MATCH_STRING is not set -# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set -# CONFIG_NETFILTER_XT_MATCH_TIME is not set -# CONFIG_NETFILTER_XT_MATCH_U32 is not set -# CONFIG_IP_VS is not set - -# -# IP: Netfilter Configuration -# -# CONFIG_NF_DEFRAG_IPV4 is not set -# CONFIG_IP_NF_QUEUE is not set -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_AH=y -CONFIG_IP_NF_MATCH_ECN=y -CONFIG_IP_NF_MATCH_TTL=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y -# CONFIG_IP_NF_TARGET_LOG is not set -# CONFIG_IP_NF_TARGET_ULOG is not set -# CONFIG_IP_NF_MANGLE is not set -# CONFIG_IP_NF_RAW is not set -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -# CONFIG_IP_NF_ARP_MANGLE is not set - -# -# IPv6: Netfilter Configuration -# -# CONFIG_NF_DEFRAG_IPV6 is not set -# CONFIG_IP6_NF_QUEUE is not set -CONFIG_IP6_NF_IPTABLES=y -CONFIG_IP6_NF_MATCH_AH=y -CONFIG_IP6_NF_MATCH_EUI64=y -CONFIG_IP6_NF_MATCH_FRAG=y -CONFIG_IP6_NF_MATCH_OPTS=y -CONFIG_IP6_NF_MATCH_HL=y -CONFIG_IP6_NF_MATCH_IPV6HEADER=y -CONFIG_IP6_NF_MATCH_MH=y -CONFIG_IP6_NF_MATCH_RT=y -# CONFIG_IP6_NF_TARGET_LOG is not set -CONFIG_IP6_NF_FILTER=y -CONFIG_IP6_NF_TARGET_REJECT=y -# CONFIG_IP6_NF_MANGLE is not set -# CONFIG_IP6_NF_RAW is not set -# CONFIG_IP_DCCP is not set -CONFIG_IP_SCTP=y -# CONFIG_SCTP_DBG_MSG is not set -# CONFIG_SCTP_DBG_OBJCNT is not set -# CONFIG_SCTP_HMAC_NONE is not set -# CONFIG_SCTP_HMAC_SHA1 is not set -CONFIG_SCTP_HMAC_MD5=y -# CONFIG_RDS is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_L2TP is not set -# CONFIG_BRIDGE is not set -# CONFIG_NET_DSA is not set -CONFIG_VLAN_8021Q=y -# CONFIG_VLAN_8021Q_GVRP is not set -# CONFIG_VLAN_8021Q_MVRP is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_PHONET is not set -# CONFIG_IEEE802154 is not set -# CONFIG_NET_SCHED is not set -# CONFIG_DCB is not set -# CONFIG_BATMAN_ADV is not set -CONFIG_RPS=y -CONFIG_RFS_ACCEL=y -CONFIG_XPS=y -CONFIG_BQL=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -CONFIG_FIB_RULES=y -# CONFIG_WIRELESS is not set -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set -# CONFIG_CAIF is not set -# CONFIG_CEPH_LIB is not set -# CONFIG_NFC is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_GENERIC_CPU_DEVICES is not set -CONFIG_CONNECTOR=y -CONFIG_PROC_EVENTS=y -CONFIG_MTD=y -# CONFIG_MTD_TESTS is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_SM_FTL is not set -# CONFIG_MTD_OOPS is not set -# CONFIG_MTD_SWAP is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -# CONFIG_MTD_CFI_NOSWAP is not set -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_OF_BYTE_SWAP=y -# CONFIG_MTD_CFI_GEOMETRY is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_OTP is not set -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=y -# CONFIG_MTD_PHYSMAP_COMPAT is not set -CONFIG_MTD_PHYSMAP_OF=y -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_DATAFLASH is not set -CONFIG_MTD_M25P80=y -CONFIG_M25PXX_USE_FAST_READ=y -# CONFIG_MTD_SST25L is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -# CONFIG_MTD_DOCG3 is not set -CONFIG_MTD_NAND_ECC=y -# CONFIG_MTD_NAND_ECC_SMC is not set -CONFIG_MTD_NAND=y -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -# CONFIG_MTD_NAND_ECC_BCH is not set -# CONFIG_MTD_SM_COMMON is not set -# CONFIG_MTD_NAND_MUSEUM_IDS is not set -# CONFIG_MTD_NAND_DENALI is not set -CONFIG_MTD_NAND_IDS=y -# CONFIG_MTD_NAND_RICOH is not set -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_CAFE is not set -# CONFIG_MTD_NAND_NANDSIM is not set -CONFIG_MTD_NAND_PLATFORM=y -# CONFIG_MTD_ALAUDA is not set -CONFIG_MTD_NAND_FSL_ELBC=y -CONFIG_MTD_NAND_FSL_UPM=y -# CONFIG_MTD_ONENAND is not set - -# -# LPDDR flash memory drivers -# -# CONFIG_MTD_LPDDR is not set -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MTD_UBI_BEB_RESERVE=1 -# CONFIG_MTD_UBI_GLUEBI is not set -# CONFIG_MTD_UBI_DEBUG is not set -CONFIG_DTC=y -CONFIG_OF=y - -# -# Device Tree and Open Firmware support -# -CONFIG_PROC_DEVICETREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_DYNAMIC=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_IRQ=y -CONFIG_OF_DEVICE=y -CONFIG_OF_GPIO=y -CONFIG_OF_I2C=y -CONFIG_OF_NET=y -CONFIG_OF_SPI=y -CONFIG_OF_MDIO=y -CONFIG_OF_PCI=y -CONFIG_OF_PCI_IRQ=y -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_DRBD is not set -CONFIG_BLK_DEV_NBD=y -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=131072 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_BLK_DEV_HD is not set -# CONFIG_BLK_DEV_RBD is not set -CONFIG_MISC_DEVICES=y -# CONFIG_AD525X_DPOT is not set -# CONFIG_ATMEL_PWM is not set -# CONFIG_PHANTOM is not set -# CONFIG_INTEL_MID_PTI is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HP_ILO is not set -# CONFIG_APDS9802ALS is not set -# CONFIG_ISL29003 is not set -# CONFIG_ISL29020 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_BH1780 is not set -# CONFIG_SENSORS_BH1770 is not set -# CONFIG_SENSORS_APDS990X is not set -# CONFIG_HMC6352 is not set -# CONFIG_DS1682 is not set -# CONFIG_TI_DAC7512 is not set -# CONFIG_BMP085 is not set -# CONFIG_PCH_PHUB is not set -# CONFIG_USB_SWITCH_FSA9480 is not set -# CONFIG_EARLY_DMA_ALLOC is not set -CONFIG_RETIMER_CLASS=y -# CONFIG_DS100DF410 is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -CONFIG_EEPROM_CLASS=y -CONFIG_EEPROM_AT24=y -# CONFIG_EEPROM_AT25 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_EEPROM_93XX46 is not set -# CONFIG_EEPROM_SFF_8436 is not set -# CONFIG_CB710_CORE is not set -# CONFIG_IWMC3200TOP is not set - -# -# Texas Instruments shared transport line discipline -# -# CONFIG_TI_ST is not set - -# -# Altera FPGA firmware download module -# -# CONFIG_ALTERA_STAPL is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_SCSI_MOD=y -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=y -# CONFIG_CHR_DEV_SCH is not set -CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_CONSTANTS is not set -CONFIG_SCSI_LOGGING=y -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_ISCSI_BOOT_SYSFS is not set -# CONFIG_SCSI_CXGB3_ISCSI is not set -# CONFIG_SCSI_CXGB4_ISCSI is not set -# CONFIG_SCSI_BNX2_ISCSI is not set -# CONFIG_SCSI_BNX2X_FCOE is not set -# CONFIG_BE2ISCSI is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_HPSA is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_3W_SAS is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_MVUMI is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_MPT2SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_LIBFC is not set -# CONFIG_LIBFCOE is not set -# CONFIG_FCOE is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_PMCRAID is not set -# CONFIG_SCSI_PM8001 is not set -# CONFIG_SCSI_SRP is not set -# CONFIG_SCSI_BFA_FC is not set -# CONFIG_SCSI_DH is not set -# CONFIG_SCSI_OSD_INITIATOR is not set -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -CONFIG_ATA_VERBOSE_ERROR=y -# CONFIG_SATA_PMP is not set - -# -# Controllers with non-SFF native interface -# -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_AHCI_PLATFORM is not set -# CONFIG_SATA_FSL is not set -# CONFIG_SATA_INIC162X is not set -# CONFIG_SATA_ACARD_AHCI is not set -# CONFIG_SATA_SIL24 is not set -CONFIG_ATA_SFF=y - -# -# SFF controllers with custom DMA interface -# -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_SX4 is not set -# CONFIG_ATA_BMDMA is not set - -# -# PIO-only SFF controllers -# -# CONFIG_PATA_CMD640_PCI is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -CONFIG_PATA_PLATFORM=y -CONFIG_PATA_OF_PLATFORM=y -# CONFIG_PATA_RZ1000 is not set -CONFIG_PATA_QUANTA_LB=y - -# -# Generic fallback / legacy drivers -# -# CONFIG_PATA_LEGACY is not set -CONFIG_MD=y -# CONFIG_BLK_DEV_MD is not set -CONFIG_BLK_DEV_DM_BUILTIN=y -CONFIG_BLK_DEV_DM=y -# CONFIG_DM_DEBUG is not set -CONFIG_DM_CRYPT=y -# CONFIG_DM_SNAPSHOT is not set -# CONFIG_DM_THIN_PROVISIONING is not set -# CONFIG_DM_MIRROR is not set -# CONFIG_DM_RAID is not set -# CONFIG_DM_ZERO is not set -# CONFIG_DM_MULTIPATH is not set -# CONFIG_DM_DELAY is not set -# CONFIG_DM_UEVENT is not set -# CONFIG_DM_FLAKEY is not set -# CONFIG_TARGET_CORE is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_FIREWIRE is not set -# CONFIG_FIREWIRE_NOSY is not set -# CONFIG_I2O is not set -# CONFIG_MACINTOSH_DRIVERS is not set -CONFIG_NETDEVICES=y -CONFIG_NET_CORE=y -# CONFIG_BONDING is not set -# CONFIG_DUMMY is not set -# CONFIG_EQUALIZER is not set -# CONFIG_NET_FC is not set -CONFIG_MII=y -# CONFIG_MACVLAN is not set -# CONFIG_VXLAN is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -CONFIG_TUN=y -CONFIG_VETH=y -# CONFIG_ARCNET is not set - -# -# CAIF transport drivers -# -CONFIG_ETHERNET=y -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_VENDOR_ADAPTEC is not set -# CONFIG_NET_VENDOR_ALTEON is not set -# CONFIG_NET_VENDOR_AMD is not set -# CONFIG_NET_VENDOR_ATHEROS is not set -# CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_VENDOR_BROCADE is not set -# CONFIG_NET_VENDOR_CHELSIO is not set -# CONFIG_NET_VENDOR_CISCO is not set -# CONFIG_DNET is not set -# CONFIG_NET_VENDOR_DEC is not set -# CONFIG_NET_VENDOR_DLINK is not set -# CONFIG_NET_VENDOR_EMULEX is not set -# CONFIG_NET_VENDOR_EXAR is not set -CONFIG_NET_VENDOR_FREESCALE=y -# CONFIG_FS_ENET is not set -CONFIG_FSL_PQ_MDIO=y -CONFIG_GIANFAR=y -# CONFIG_NET_VENDOR_HP is not set -# CONFIG_NET_VENDOR_INTEL is not set -# CONFIG_IP1000 is not set -# CONFIG_JME is not set -# CONFIG_NET_VENDOR_MARVELL is not set -# CONFIG_NET_VENDOR_MELLANOX is not set -# CONFIG_NET_VENDOR_MICREL is not set -# CONFIG_NET_VENDOR_MICROCHIP is not set -# CONFIG_NET_VENDOR_MYRI is not set -# CONFIG_FEALNX is not set -# CONFIG_NET_VENDOR_NATSEMI is not set -# CONFIG_NET_VENDOR_NVIDIA is not set -# CONFIG_NET_VENDOR_OKI is not set -# CONFIG_ETHOC is not set -# CONFIG_NET_PACKET_ENGINE is not set -# CONFIG_NET_VENDOR_QLOGIC is not set -# CONFIG_NET_VENDOR_REALTEK is not set -# CONFIG_NET_VENDOR_RDC is not set -# CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_SILAN is not set -# CONFIG_NET_VENDOR_SIS is not set -# CONFIG_SFC is not set -# CONFIG_NET_VENDOR_SMSC is not set -# CONFIG_NET_VENDOR_STMICRO is not set -# CONFIG_NET_VENDOR_SUN is not set -# CONFIG_NET_VENDOR_TEHUTI is not set -# CONFIG_NET_VENDOR_TI is not set -# CONFIG_NET_VENDOR_VIA is not set -# CONFIG_NET_VENDOR_XILINX is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -CONFIG_BROADCOM_PHY=y -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_MICREL_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_TR is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_USB_IPHETH is not set -# CONFIG_WLAN is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# -# CONFIG_WAN is not set -# CONFIG_VMXNET3 is not set -# CONFIG_DPAA_ETH_USE_NDO_SELECT_QUEUE is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set -# CONFIG_N_GSM is not set -# CONFIG_TRACE_SINK is not set -# CONFIG_PPC_EPAPR_HV_BYTECHAN is not set -CONFIG_DEVKMEM=y - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_RSA is not set -# CONFIG_SERIAL_8250_DW is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_MAX3100 is not set -# CONFIG_SERIAL_MAX3107 is not set -# CONFIG_SERIAL_MFD_HSU is not set -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_CPM is not set -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_OF_PLATFORM is not set -# CONFIG_SERIAL_TIMBERDALE is not set -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -# CONFIG_SERIAL_IFX6X60 is not set -# CONFIG_SERIAL_PCH_UART is not set -# CONFIG_SERIAL_XILINX_PS_UART is not set -# CONFIG_TTY_PRINTK is not set -# CONFIG_HVC_UDBG is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_HW_RANDOM_TIMERIOMEM is not set -CONFIG_NVRAM=y -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -# CONFIG_RAMOOPS is not set -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MUX=y - -# -# Multiplexer I2C Chip support -# -# CONFIG_I2C_MUX_ACCTON_AS5712_54x_CPLD is not set -# CONFIG_I2C_MUX_ACCTON_AS6712_32x_CPLD is not set -# CONFIG_I2C_MUX_ACCTON_AS5812_54x_CPLD is not set -# CONFIG_I2C_MUX_ACCTON_AS6812_32x_CPLD is not set -# CONFIG_I2C_MUX_GPIO is not set -# CONFIG_I2C_MUX_PCA9541 is not set -CONFIG_I2C_MUX_PCA954x=y -# CONFIG_I2C_MUX_PCA954X_DESELECT_ON_EXIT is not set -# CONFIG_I2C_MUX_DNI_6448 is not set -# CONFIG_I2C_MUX_QUANTA is not set -CONFIG_I2C_MUX_QUANTA_LY2=y -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# - -# -# PC SMBus host controller drivers -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_ISCH is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -CONFIG_I2C_CPM=y -# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -# CONFIG_I2C_DESIGNWARE_PCI is not set -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_INTEL_MID is not set -CONFIG_I2C_MPC=y -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_PXA_PCI is not set -# CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_XILINX is not set -# CONFIG_I2C_EG20T is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_DIOLAN_U2C is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -CONFIG_SPI=y -# CONFIG_SPI_DEBUG is not set -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -# CONFIG_SPI_ALTERA is not set -# CONFIG_SPI_BITBANG is not set -# CONFIG_SPI_GPIO is not set -CONFIG_SPI_FSL_LIB=y -CONFIG_SPI_FSL_SPI=y -CONFIG_SPI_FSL_ESPI=y -# CONFIG_SPI_OC_TINY is not set -# CONFIG_SPI_PXA2XX_PCI is not set -# CONFIG_SPI_TOPCLIFF_PCH is not set -# CONFIG_SPI_XILINX is not set -# CONFIG_SPI_DESIGNWARE is not set - -# -# SPI Protocol Masters -# -# CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set - -# -# PPS support -# -# CONFIG_PPS is not set - -# -# PPS generators support -# - -# -# PTP clock support -# - -# -# Enable Device Drivers -> PPS to see the PTP clock options. -# -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -CONFIG_GPIO_SYSFS=y - -# -# Memory mapped GPIO drivers: -# -# CONFIG_GPIO_GENERIC_PLATFORM is not set -# CONFIG_GPIO_IT8761E is not set -CONFIG_GPIO_MPC8XXX=y -# CONFIG_GPIO_XILINX is not set -# CONFIG_GPIO_VX855 is not set - -# -# I2C GPIO expanders: -# -# CONFIG_GPIO_MAX7300 is not set -# CONFIG_GPIO_MAX732X is not set -CONFIG_GPIO_PCA953X=y -# CONFIG_GPIO_PCA953X_IRQ is not set -# CONFIG_GPIO_PCF857X is not set -# CONFIG_GPIO_SX150X is not set -# CONFIG_GPIO_ADP5588 is not set - -# -# PCI GPIO expanders: -# -# CONFIG_GPIO_BT8XX is not set -# CONFIG_GPIO_ML_IOH is not set -# CONFIG_GPIO_RDC321X is not set - -# -# SPI GPIO expanders: -# -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MCP23S08 is not set -# CONFIG_GPIO_MC33880 is not set -# CONFIG_GPIO_74X164 is not set - -# -# AC97 GPIO expanders: -# - -# -# MODULbus GPIO expanders: -# -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Native drivers -# -# CONFIG_SENSORS_AD7314 is not set -# CONFIG_SENSORS_AD7414 is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADCXX is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7411 is not set -# CONFIG_SENSORS_ADT7462 is not set -CONFIG_SENSORS_ADT7470=y -# CONFIG_SENSORS_ADT7475 is not set -# CONFIG_SENSORS_ASC7621 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_CY8CXX is not set -# CONFIG_SENSORS_CY8C3245R1 is not set -# CONFIG_SENSORS_DS620 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_I5K_AMB is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_G760A is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_GPIO_FAN is not set -# CONFIG_SENSORS_JC42 is not set -# CONFIG_SENSORS_LINEAGE is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 is not set -# CONFIG_SENSORS_LM73 is not set -CONFIG_SENSORS_LM75=y -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_LTC4151 is not set -CONFIG_SENSORS_LTC4215=y -# CONFIG_SENSORS_LTC4245 is not set -# CONFIG_SENSORS_LTC4261 is not set -# CONFIG_SENSORS_LM95241 is not set -# CONFIG_SENSORS_LM95245 is not set -# CONFIG_SENSORS_MAX1111 is not set -# CONFIG_SENSORS_MAX16065 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX1668 is not set -# CONFIG_SENSORS_MAX6639 is not set -# CONFIG_SENSORS_MAX6642 is not set -CONFIG_SENSORS_MAX6650=y -# CONFIG_SENSORS_MAX6620 is not set -# CONFIG_SENSORS_MAX6697 is not set -# CONFIG_SENSORS_NTC_THERMISTOR is not set -# CONFIG_SENSORS_PCF8591 is not set -CONFIG_PMBUS=y -CONFIG_SENSORS_PMBUS=y -# CONFIG_SENSORS_ADM1275 is not set -# CONFIG_SENSORS_LM25066 is not set -# CONFIG_SENSORS_LTC2978 is not set -# CONFIG_SENSORS_MAX16064 is not set -# CONFIG_SENSORS_MAX34440 is not set -# CONFIG_SENSORS_DNI_DPS460 is not set -# CONFIG_SENSORS_MAX8688 is not set -# CONFIG_SENSORS_UCD9000 is not set -# CONFIG_SENSORS_UCD9200 is not set -# CONFIG_SENSORS_ZL6100 is not set -# CONFIG_SENSORS_SHT15 is not set -# CONFIG_SENSORS_SHT21 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMM665 is not set -# CONFIG_SENSORS_EMC1403 is not set -# CONFIG_SENSORS_EMC2103 is not set -CONFIG_SENSORS_EMC2305=y -# CONFIG_SENSORS_EMC6W201 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SCH56XX_COMMON is not set -# CONFIG_SENSORS_ADS1015 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_ADS7871 is not set -# CONFIG_SENSORS_AMC6821 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_TMP102 is not set -# CONFIG_SENSORS_TMP401 is not set -# CONFIG_SENSORS_TMP421 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83795 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -CONFIG_SENSORS_QUANTA_LY_HWMON=y -# CONFIG_SENSORS_CPR_4011_4MXX is not set -# CONFIG_SENSORS_ACCTON_I2C_CPLD is not set -# CONFIG_SENSORS_YM2651Y is not set -# CONFIG_THERMAL is not set -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_ALIM7101_WDT is not set -CONFIG_BOOKE_WDT=y -CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=38 - -# -# PCI-based Watchdog Cards -# -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set -CONFIG_BCMA_POSSIBLE=y - -# -# Broadcom specific AMBA -# -# CONFIG_BCMA is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTC_I2CPLD is not set -# CONFIG_TPS6105X is not set -# CONFIG_TPS65010 is not set -# CONFIG_TPS6507X is not set -# CONFIG_MFD_TPS6586X is not set -# CONFIG_MFD_TPS65910 is not set -# CONFIG_MFD_TPS65912_I2C is not set -# CONFIG_MFD_TPS65912_SPI is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_MFD_STMPE is not set -# CONFIG_MFD_TC3589X is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX8998 is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM831X_I2C is not set -# CONFIG_MFD_WM831X_SPI is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8994 is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_MFD_MC13XXX is not set -# CONFIG_ABX500_CORE is not set -# CONFIG_EZX_PCAP is not set -# CONFIG_MFD_TIMBERDALE is not set -# CONFIG_LPC_SCH is not set -# CONFIG_MFD_RDC321X is not set -# CONFIG_MFD_JANZ_CMODIO is not set -# CONFIG_MFD_VX855 is not set -# CONFIG_MFD_WL1273_CORE is not set -# CONFIG_MFD_AAT2870_CORE is not set -# CONFIG_REGULATOR is not set -# CONFIG_MEDIA_SUPPORT is not set - -# -# Graphics support -# -# CONFIG_AGP is not set -# CONFIG_VGA_ARB is not set -# CONFIG_DRM is not set -# CONFIG_STUB_POULSBO is not set -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_SOUND is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_COMMON=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB_ARCH_HAS_XHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -# CONFIG_USB_DEVICE_CLASS is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_DWC3 is not set -# CONFIG_USB_MON is not set -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -# CONFIG_USB_XHCI_HCD is not set -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EHCI_TT_NEWSCHED=y -# CONFIG_XPS_USB_HCD_XILINX is not set -CONFIG_USB_FSL_MPH_DR_OF=y -CONFIG_USB_EHCI_FSL=y -CONFIG_USB_EHCI_HCD_PPC_OF=y -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -# CONFIG_USB_ISP1362_HCD is not set -# CONFIG_USB_OHCI_HCD is not set -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_WHCI_HCD is not set -# CONFIG_USB_HWA_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -# - -# -# also be needed; see USB_STORAGE Help for more info -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_REALTEK is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_STORAGE_ENE_UB6250 is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_YUREX is not set -# CONFIG_USB_GADGET is not set - -# -# OTG and related infrastructure -# -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_NOP_USB_XCEIV is not set -# CONFIG_UWB is not set -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -# CONFIG_MMC_UNSAFE_RESUME is not set -# CONFIG_MMC_CLKGATE is not set - -# -# MMC/SD/SDIO Card Drivers -# -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=8 -CONFIG_MMC_BLOCK_BOUNCE=y -# CONFIG_SDIO_UART is not set -# CONFIG_MMC_TEST is not set - -# -# MMC/SD/SDIO Host Controller Drivers -# -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_IO_ACCESSORS=y -CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER=y -# CONFIG_MMC_SDHCI_PCI is not set -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MMC_SDHCI_OF_ESDHC=y -# CONFIG_MMC_SDHCI_OF_HLWD is not set -# CONFIG_MMC_WBSD is not set -# CONFIG_MMC_TIFM_SD is not set -# CONFIG_MMC_CB710 is not set -# CONFIG_MMC_VIA_SDMMC is not set -# CONFIG_MMC_VUB300 is not set -# CONFIG_MMC_USHC is not set -# CONFIG_MEMSTICK is not set -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y - -# -# LED drivers -# -# CONFIG_LEDS_LM3530 is not set -CONFIG_LEDS_GPIO=y -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -CONFIG_LEDS_PCA955X=y -# CONFIG_LEDS_DAC124S085 is not set -# CONFIG_LEDS_BD2802 is not set -# CONFIG_LEDS_LT3593 is not set -# CONFIG_LEDS_RENESAS_TPU is not set -CONFIG_LEDS_TRIGGERS=y - -# -# LED Triggers -# -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set -# CONFIG_LEDS_TRIGGER_GPIO is not set -CONFIG_LEDS_TRIGGER_DEFAULT_ON=y - -# -# iptables trigger is under Netfilter config (LED target) -# -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -# CONFIG_EDAC is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -CONFIG_RTC_DRV_DS1307=y -CONFIG_RTC_DRV_DS1374=y -CONFIG_RTC_DRV_DS1672=y -CONFIG_RTC_DRV_DS3232=y -CONFIG_RTC_DRV_MAX6900=y -CONFIG_RTC_DRV_RS5C372=y -CONFIG_RTC_DRV_ISL1208=y -CONFIG_RTC_DRV_ISL12022=y -CONFIG_RTC_DRV_X1205=y -CONFIG_RTC_DRV_PCF8563=y -CONFIG_RTC_DRV_PCF8583=y -CONFIG_RTC_DRV_M41T80=y -CONFIG_RTC_DRV_M41T80_WDT=y -CONFIG_RTC_DRV_BQ32K=y -CONFIG_RTC_DRV_S35390A=y -CONFIG_RTC_DRV_FM3130=y -CONFIG_RTC_DRV_RX8581=y -CONFIG_RTC_DRV_RX8025=y -CONFIG_RTC_DRV_EM3027=y -CONFIG_RTC_DRV_RV3029C2=y - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_M41T93 is not set -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_DS3234 is not set -# CONFIG_RTC_DRV_PCF2123 is not set - -# -# Platform RTC drivers -# -CONFIG_RTC_DRV_CMOS=y -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_RTC_DRV_GENERIC is not set -CONFIG_DMADEVICES=y -# CONFIG_DMADEVICES_DEBUG is not set - -# -# DMA Devices -# -CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y -# CONFIG_DW_DMAC is not set -CONFIG_FSL_DMA=y -# CONFIG_TIMB_DMA is not set -CONFIG_DMA_ENGINE=y - -# -# DMA Clients -# -CONFIG_NET_DMA_DUMMY=y -# CONFIG_ASYNC_TX_DMA is not set -# CONFIG_DMATEST is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set - -# -# Virtio drivers -# -# CONFIG_VIRTIO_PCI is not set -# CONFIG_VIRTIO_BALLOON is not set -# CONFIG_VIRTIO_MMIO is not set -# CONFIG_STAGING is not set - -# -# Hardware Spinlock drivers -# -# CONFIG_IOMMU_SUPPORT is not set -# CONFIG_VIRT_DRIVERS is not set - -# -# Microsoft Hyper-V guest support -# -# CONFIG_PM_DEVFREQ is not set - -# -# Frame Manager support -# -CONFIG_FSL_FMAN=y -# CONFIG_FSL_FMAN_TEST is not set - -# -# FMAN Processor support -# -CONFIG_FMAN_P3040_P4080_P5020=y -# CONFIG_FMAN_P1023 is not set -# CONFIG_FMAN_T4240 is not set -# CONFIG_FMAN_RESOURCE_ALLOCATION_ALGORITHM is not set -# CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN is not set -CONFIG_FSL_FM_MAX_FRAME_SIZE=1522 -CONFIG_FSL_FM_RX_EXTRA_HEADROOM=64 - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -CONFIG_EXT4_FS=y -CONFIG_EXT4_USE_FOR_EXT23=y -# CONFIG_EXT4_FS_XATTR is not set -# CONFIG_EXT4_DEBUG is not set -CONFIG_JBD2=y -# CONFIG_JBD2_DEBUG is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_BTRFS_FS is not set -# CONFIG_NILFS2_FS is not set -# CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y -CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y -CONFIG_INOTIFY_USER=y -CONFIG_INOTIFY_STACKFS=y -CONFIG_FANOTIFY=y -# CONFIG_QUOTA is not set -# CONFIG_QUOTACTL is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set -CONFIG_OVERLAYFS_FS=y - -# -# Caches -# -# CONFIG_FSCACHE is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_VMCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -CONFIG_TMPFS_XATTR=y -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -CONFIG_JFFS2_SUMMARY=y -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -CONFIG_UBIFS_FS=y -# CONFIG_UBIFS_FS_XATTR is not set -# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -CONFIG_UBIFS_FS_LZO=y -CONFIG_UBIFS_FS_ZLIB=y -# CONFIG_UBIFS_FS_DEBUG is not set -# CONFIG_LOGFS is not set -# CONFIG_CRAMFS is not set -CONFIG_SQUASHFS=y -# CONFIG_SQUASHFS_XATTR is not set -CONFIG_SQUASHFS_ZLIB=y -CONFIG_SQUASHFS_LZO=y -CONFIG_SQUASHFS_XZ=y -# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_PSTORE is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -# CONFIG_AUFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFSD is not set -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_CEPH_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -CONFIG_EFI_PARTITION=y -# CONFIG_SYSV68_PARTITION is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=y -# CONFIG_BINARY_PRINTF is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -CONFIG_CRC16=y -# CONFIG_CRC_T10DIF is not set -CONFIG_CRC_ITU_T=y -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -CONFIG_LIBCRC32C=y -# CONFIG_CRC8 is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_XZ_DEC=y -# CONFIG_XZ_DEC_X86 is not set -CONFIG_XZ_DEC_POWERPC=y -# CONFIG_XZ_DEC_IA64 is not set -# CONFIG_XZ_DEC_ARM is not set -# CONFIG_XZ_DEC_ARMTHUMB is not set -# CONFIG_XZ_DEC_SPARC is not set -CONFIG_XZ_DEC_BCJ=y -# CONFIG_XZ_DEC_TEST is not set -CONFIG_DECOMPRESS_GZIP=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_CPU_RMAP=y -CONFIG_DQL=y -CONFIG_NLATTR=y -CONFIG_GENERIC_ATOMIC64=y -# CONFIG_AVERAGE is not set -# CONFIG_CORDIC is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -CONFIG_MAGIC_SYSRQ_DEFAULT_MASK=0x1 -# CONFIG_STRIP_ASM_SYMS is not set -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_SECTION_MISMATCH is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -# CONFIG_LOCKUP_DETECTOR is not set -# CONFIG_HARDLOCKUP_DETECTOR is not set -CONFIG_DETECT_HUNG_TASK=y -CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -CONFIG_PANIC_TIMEOUT=0 -# CONFIG_SCHED_DEBUG is not set -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_SPARSE_RCU_POINTER is not set -# CONFIG_LOCK_STAT is not set -# CONFIG_DEBUG_ATOMIC_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_HIGHMEM is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_INFO_REDUCED is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_CREDENTIALS is not set -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_RCU_CPU_STALL_TIMEOUT=60 -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -# CONFIG_DEBUG_PER_CPU_MAPS is not set -# CONFIG_LKDTM is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y -# CONFIG_DEBUG_PAGEALLOC is not set -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_ENABLE_DEFAULT_TRACERS is not set -# CONFIG_FTRACE_SYSCALLS is not set -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_STACK_TRACER is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -CONFIG_DYNAMIC_DEBUG=y -# CONFIG_DMA_API_DEBUG is not set -# CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -# CONFIG_TEST_KSTRTOX is not set -# CONFIG_PPC_DISABLE_WERROR is not set -CONFIG_PPC_WERROR=y -CONFIG_PRINT_STACK_DEPTH=64 -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_PPC_EMULATED_STATS is not set -# CONFIG_CODE_PATCHING_SELFTEST is not set -# CONFIG_FTR_FIXUP_SELFTEST is not set -# CONFIG_MSI_BITMAP_SELFTEST is not set -# CONFIG_XMON is not set -CONFIG_VIRQ_DEBUG=y -# CONFIG_BDI_SWITCH is not set -# CONFIG_JTAG_DEBUGGER is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY_DMESG_RESTRICT is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DEFAULT_SECURITY="" -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_PCOMP2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -# CONFIG_CRYPTO_USER is not set -CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_PCRYPT is not set -CONFIG_CRYPTO_WORKQUEUE=y -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_AUTHENC=y -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_VMAC is not set - -# -# Digest -# -CONFIG_CRYPTO_CRC32C=y -# CONFIG_CRYPTO_GHASH is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=y -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -CONFIG_CRYPTO_AES=y -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=y -# CONFIG_CRYPTO_ZLIB is not set -CONFIG_CRYPTO_LZO=y - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_USER_API_HASH is not set -# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -CONFIG_CRYPTO_HW=y -# CONFIG_CRYPTO_DEV_HIFN_795X is not set -# CONFIG_CRYPTO_DEV_FSL_CAAM is not set -CONFIG_CRYPTO_DEV_TALITOS=y -CONFIG_PPC_CLOCK=y -CONFIG_PPC_LIB_RHEAP=y -# CONFIG_VIRTUALIZATION is not set diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/configs/x86_64-all/.gitignore b/packages/base/any/kernels/3.2.65-1+deb7u2/configs/x86_64-all/.gitignore deleted file mode 100644 index b220e48d..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/configs/x86_64-all/.gitignore +++ /dev/null @@ -1 +0,0 @@ -kernel-3.2-deb7-x86_64-all diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/configs/x86_64-all/Makefile b/packages/base/any/kernels/3.2.65-1+deb7u2/configs/x86_64-all/Makefile deleted file mode 100644 index 0d857115..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/configs/x86_64-all/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -############################################################ -# -# -# Copyright 2015 Big Switch Networks, Inc. -# -# Licensed under the Eclipse Public License, Version 1.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.eclipse.org/legal/epl-v10.html -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -# either express or implied. See the License for the specific -# language governing permissions and limitations under the -# License. -# -# -############################################################ -# -# Default 3.2.65-1+deb7u2 configuration for x86_64 platforms. -# -############################################################ -THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) -include $(ONL)/make/config.mk - -export ARCH := x86_64 -ifndef K_TARGET_DIR -K_TARGET_DIR := $(THIS_DIR) -endif - -include ../../kconfig.mk -K_CONFIG := x86_64-all.config -K_BUILD_TARGET := bzImage -K_COPY_SRC := arch/x86/boot/bzImage -ifndef K_COPY_DST -K_COPY_DST := kernel-3.2-deb7-x86_64-all -endif - -include $(ONL)/make/kbuild.mk - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/configs/x86_64-all/x86_64-all.config b/packages/base/any/kernels/3.2.65-1+deb7u2/configs/x86_64-all/x86_64-all.config deleted file mode 100644 index 42e2b67b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/configs/x86_64-all/x86_64-all.config +++ /dev/null @@ -1,3071 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# Linux/x86_64 3.2.65 Kernel Configuration -# -CONFIG_64BIT=y -# CONFIG_X86_32 is not set -CONFIG_X86_64=y -CONFIG_X86=y -CONFIG_INSTRUCTION_DECODER=y -CONFIG_OUTPUT_FORMAT="elf64-x86-64" -CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_CLOCKSOURCE_WATCHDOG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_MMU=y -CONFIG_ZONE_DMA=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_GENERIC_ISA_DMA=y -CONFIG_GENERIC_IOMAP=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_GPIO=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -# CONFIG_RWSEM_GENERIC_SPINLOCK is not set -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_ARCH_HAS_CPU_RELAX=y -CONFIG_ARCH_HAS_DEFAULT_IDLE=y -CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y -CONFIG_ARCH_HAS_CPU_AUTOPROBE=y -CONFIG_HAVE_SETUP_PER_CPU_AREA=y -CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y -CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ZONE_DMA32=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_AUDIT_ARCH=y -CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y -CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y -CONFIG_X86_64_SMP=y -CONFIG_X86_HT=y -CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" -# CONFIG_KTIME_SCALAR is not set -CONFIG_ARCH_CPU_PROBE_RELEASE=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_HAVE_IRQ_WORK=y -CONFIG_IRQ_WORK=y - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_CROSS_COMPILE="" -CONFIG_LOCALVERSION="-1+deb7u2-OpenNetworkLinux" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_BZIP2=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_XZ=y -CONFIG_HAVE_KERNEL_LZO=y -# CONFIG_KERNEL_GZIP is not set -CONFIG_KERNEL_BZIP2=y -# CONFIG_KERNEL_LZMA is not set -# CONFIG_KERNEL_XZ is not set -# CONFIG_KERNEL_LZO is not set -CONFIG_DEFAULT_HOSTNAME="(none)" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -CONFIG_POSIX_MQUEUE_SYSCTL=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_FHANDLE=y -CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y -CONFIG_TASK_XACCT=y -CONFIG_TASK_IO_ACCOUNTING=y -CONFIG_AUDIT=y -CONFIG_AUDITSYSCALL=y -CONFIG_AUDIT_WATCH=y -CONFIG_AUDIT_TREE=y -CONFIG_HAVE_GENERIC_HARDIRQS=y - -# -# IRQ subsystem -# -CONFIG_GENERIC_HARDIRQS=y -CONFIG_HAVE_SPARSE_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_PENDING_IRQ=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_SPARSE_IRQ=y - -# -# RCU Subsystem -# -CONFIG_TREE_RCU=y -# CONFIG_PREEMPT_RCU is not set -# CONFIG_RCU_TRACE is not set -CONFIG_RCU_FANOUT=64 -# CONFIG_RCU_FANOUT_EXACT is not set -CONFIG_RCU_FAST_NO_HZ=y -# CONFIG_TREE_RCU_TRACE is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=17 -CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y -CONFIG_CGROUPS=y -# CONFIG_CGROUP_DEBUG is not set -CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_DEVICE=y -CONFIG_CPUSETS=y -CONFIG_PROC_PID_CPUSET=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_RESOURCE_COUNTERS=y -CONFIG_CGROUP_MEM_RES_CTLR=y -CONFIG_CGROUP_MEM_RES_CTLR_DISABLED=y -CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y -# CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED is not set -CONFIG_CGROUP_PERF=y -CONFIG_CGROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_CFS_BANDWIDTH is not set -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_BLK_CGROUP=y -# CONFIG_DEBUG_BLK_CGROUP is not set -CONFIG_NAMESPACES=y -CONFIG_UTS_NS=y -CONFIG_IPC_NS=y -CONFIG_USER_NS=y -CONFIG_PID_NS=y -CONFIG_NET_NS=y -CONFIG_SCHED_AUTOGROUP=y -CONFIG_MM_OWNER=y -# CONFIG_SYSFS_DEPRECATED is not set -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_RD_GZIP=y -CONFIG_RD_BZIP2=y -CONFIG_RD_LZMA=y -CONFIG_RD_XZ=y -CONFIG_RD_LZO=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -CONFIG_EXPERT=y -CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_PCSPKR_PLATFORM=y -CONFIG_HAVE_PCSPKR_PLATFORM=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_EMBEDDED=y -CONFIG_HAVE_PERF_EVENTS=y - -# -# Kernel Performance Events And Counters -# -CONFIG_PERF_EVENTS=y -# CONFIG_PERF_COUNTERS is not set -# CONFIG_DEBUG_PERF_USE_VMALLOC is not set -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_PCI_QUIRKS=y -# CONFIG_COMPAT_BRK is not set -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -CONFIG_TRACEPOINTS=y -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -# CONFIG_JUMP_LABEL is not set -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_IOREMAP_PROT=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_OPTPROBES=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_DMA_ATTRS=y -CONFIG_USE_GENERIC_SMP_HELPERS=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_HW_BREAKPOINT=y -CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y -CONFIG_HAVE_USER_RETURN_NOTIFIER=y -CONFIG_HAVE_PERF_EVENTS_NMI=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y - -# -# GCOV-based kernel profiling -# -# CONFIG_GCOV_KERNEL is not set -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_STOP_MACHINE=y -CONFIG_BLOCK=y -CONFIG_BLK_DEV_BSG=y -CONFIG_BLK_DEV_BSGLIB=y -CONFIG_BLK_DEV_INTEGRITY=y -# CONFIG_BLK_DEV_THROTTLING is not set -CONFIG_BLOCK_COMPAT=y - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_CFQ_GROUP_IOSCHED=y -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -CONFIG_INLINE_SPIN_UNLOCK=y -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -CONFIG_INLINE_READ_UNLOCK=y -# CONFIG_INLINE_READ_UNLOCK_BH is not set -CONFIG_INLINE_READ_UNLOCK_IRQ=y -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -CONFIG_INLINE_WRITE_UNLOCK=y -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_FREEZER=y - -# -# Processor type and features -# -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y -CONFIG_SMP=y -CONFIG_X86_MPPARSE=y -# CONFIG_X86_EXTENDED_PLATFORM is not set -CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y -CONFIG_SCHED_OMIT_FRAME_POINTER=y -CONFIG_PARAVIRT_GUEST=y -# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -CONFIG_XEN=y -CONFIG_XEN_DOM0=y -CONFIG_XEN_PRIVILEGED_GUEST=y -CONFIG_XEN_PVHVM=y -CONFIG_XEN_MAX_DOMAIN_MEMORY=128 -CONFIG_XEN_SAVE_RESTORE=y -# CONFIG_XEN_DEBUG_FS is not set -CONFIG_KVM_CLOCK=y -CONFIG_KVM_GUEST=y -CONFIG_PARAVIRT=y -# CONFIG_PARAVIRT_SPINLOCKS is not set -CONFIG_PARAVIRT_CLOCK=y -# CONFIG_PARAVIRT_DEBUG is not set -CONFIG_NO_BOOTMEM=y -CONFIG_MEMTEST=y -# CONFIG_MK8 is not set -# CONFIG_MPSC is not set -# CONFIG_MCORE2 is not set -# CONFIG_MATOM is not set -CONFIG_GENERIC_CPU=y -CONFIG_X86_INTERNODE_CACHE_SHIFT=6 -CONFIG_X86_CMPXCHG=y -CONFIG_CMPXCHG_LOCAL=y -CONFIG_CMPXCHG_DOUBLE=y -CONFIG_X86_L1_CACHE_SHIFT=6 -CONFIG_X86_XADD=y -CONFIG_X86_WP_WORKS_OK=y -CONFIG_X86_TSC=y -CONFIG_X86_CMPXCHG64=y -CONFIG_X86_CMOV=y -CONFIG_X86_MINIMUM_CPU_FAMILY=64 -CONFIG_X86_DEBUGCTLMSR=y -# CONFIG_PROCESSOR_SELECT is not set -CONFIG_CPU_SUP_INTEL=y -CONFIG_CPU_SUP_AMD=y -CONFIG_CPU_SUP_CENTAUR=y -CONFIG_HPET_TIMER=y -CONFIG_HPET_EMULATE_RTC=y -CONFIG_DMI=y -CONFIG_GART_IOMMU=y -CONFIG_CALGARY_IOMMU=y -CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y -CONFIG_SWIOTLB=y -CONFIG_IOMMU_HELPER=y -# CONFIG_MAXSMP is not set -CONFIG_NR_CPUS=512 -CONFIG_SCHED_SMT=y -CONFIG_SCHED_MC=y -# CONFIG_IRQ_TIME_ACCOUNTING is not set -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y -# CONFIG_PREEMPT is not set -CONFIG_X86_LOCAL_APIC=y -CONFIG_X86_IO_APIC=y -CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y -CONFIG_X86_MCE=y -CONFIG_X86_MCE_INTEL=y -CONFIG_X86_MCE_AMD=y -CONFIG_X86_MCE_THRESHOLD=y -# CONFIG_X86_MCE_INJECT is not set -CONFIG_X86_THERMAL_VECTOR=y -# CONFIG_X86_16BIT is not set -# CONFIG_I8K is not set -# CONFIG_MICROCODE is not set -CONFIG_X86_MSR=y -CONFIG_X86_CPUID=y -CONFIG_ARCH_PHYS_ADDR_T_64BIT=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_DIRECT_GBPAGES=y -# CONFIG_NUMA is not set -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SPARSEMEM_DEFAULT=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_MEMORY_PROBE=y -CONFIG_ARCH_PROC_KCORE_TEXT=y -CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_SPARSEMEM_MANUAL=y -CONFIG_SPARSEMEM=y -CONFIG_HAVE_MEMORY_PRESENT=y -CONFIG_SPARSEMEM_EXTREME=y -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y -CONFIG_SPARSEMEM_VMEMMAP=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_MEMORY_HOTPLUG=y -CONFIG_MEMORY_HOTPLUG_SPARSE=y -CONFIG_MEMORY_HOTREMOVE=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_COMPACTION=y -CONFIG_MIGRATION=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -CONFIG_MMU_NOTIFIER=y -CONFIG_KSM=y -CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 -CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y -CONFIG_MEMORY_FAILURE=y -CONFIG_HWPOISON_INJECT=y -CONFIG_TRANSPARENT_HUGEPAGE=y -# CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set -CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y -# CONFIG_CLEANCACHE is not set -# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set -CONFIG_X86_RESERVE_LOW=64 -CONFIG_MTRR=y -CONFIG_MTRR_SANITIZER=y -CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0 -CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 -CONFIG_X86_PAT=y -CONFIG_ARCH_USES_PG_UNCACHED=y -CONFIG_ARCH_RANDOM=y -# CONFIG_EFI is not set -CONFIG_SECCOMP=y -CONFIG_CC_STACKPROTECTOR=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_SCHED_HRTICK=y -CONFIG_KEXEC=y -CONFIG_CRASH_DUMP=y -CONFIG_PHYSICAL_START=0x1000000 -CONFIG_RELOCATABLE=y -CONFIG_PHYSICAL_ALIGN=0x1000000 -CONFIG_HOTPLUG_CPU=y -# CONFIG_COMPAT_VDSO is not set -# CONFIG_CMDLINE_BOOL is not set -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y - -# -# Power management and ACPI options -# -# CONFIG_SUSPEND is not set -CONFIG_HIBERNATE_CALLBACKS=y -# CONFIG_HIBERNATION is not set -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -# CONFIG_PM_RUNTIME is not set -CONFIG_PM=y -# CONFIG_PM_DEBUG is not set -CONFIG_ACPI=y -# CONFIG_ACPI_PROCFS is not set -# CONFIG_ACPI_PROCFS_POWER is not set -# CONFIG_ACPI_EC_DEBUGFS is not set -CONFIG_ACPI_PROC_EVENT=y -CONFIG_ACPI_AC=y -CONFIG_ACPI_BATTERY=y -CONFIG_ACPI_BUTTON=y -CONFIG_ACPI_FAN=y -# CONFIG_ACPI_DOCK is not set -CONFIG_ACPI_PROCESSOR=y -CONFIG_ACPI_HOTPLUG_CPU=y -# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set -CONFIG_ACPI_THERMAL=y -# CONFIG_ACPI_CUSTOM_DSDT is not set -CONFIG_ACPI_BLACKLIST_YEAR=0 -# CONFIG_ACPI_DEBUG is not set -# CONFIG_ACPI_PCI_SLOT is not set -CONFIG_X86_PM_TIMER=y -CONFIG_ACPI_CONTAINER=y -# CONFIG_ACPI_HOTPLUG_MEMORY is not set -# CONFIG_ACPI_SBS is not set -# CONFIG_ACPI_HED is not set -CONFIG_ACPI_CUSTOM_METHOD=y -# CONFIG_ACPI_APEI is not set -# CONFIG_SFI is not set - -# -# CPU Frequency scaling -# -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_TABLE=y -CONFIG_CPU_FREQ_STAT=y -# CONFIG_CPU_FREQ_STAT_DETAILS is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y - -# -# x86 CPU frequency scaling drivers -# -# CONFIG_X86_PCC_CPUFREQ is not set -# CONFIG_X86_ACPI_CPUFREQ is not set -# CONFIG_X86_POWERNOW_K8 is not set -# CONFIG_X86_SPEEDSTEP_CENTRINO is not set -CONFIG_X86_P4_CLOCKMOD=y - -# -# shared options -# -CONFIG_X86_SPEEDSTEP_LIB=y -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_INTEL_IDLE=y - -# -# Memory power savings -# -CONFIG_I7300_IDLE_IOAT_CHANNEL=y -CONFIG_I7300_IDLE=y - -# -# Bus options (PCI etc.) -# -CONFIG_PCI=y -CONFIG_PCI_DIRECT=y -CONFIG_PCI_MMCONFIG=y -CONFIG_PCI_XEN=y -CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_CNB20LE_QUIRK is not set -CONFIG_PCIEPORTBUS=y -CONFIG_HOTPLUG_PCI_PCIE=y -CONFIG_PCIEAER=y -# CONFIG_PCIE_ECRC is not set -CONFIG_PCIEAER_INJECT=y -CONFIG_PCIEASPM=y -# CONFIG_PCIEASPM_DEBUG is not set -CONFIG_ARCH_SUPPORTS_MSI=y -CONFIG_PCI_MSI=y -# CONFIG_PCI_DEBUG is not set -# CONFIG_PCI_STUB is not set -# CONFIG_XEN_PCIDEV_FRONTEND is not set -CONFIG_HT_IRQ=y -CONFIG_PCI_ATS=y -CONFIG_PCI_IOV=y -# CONFIG_PCI_PRI is not set -# CONFIG_PCI_PASID is not set -CONFIG_PCI_IOAPIC=y -CONFIG_PCI_LABEL=y -CONFIG_ISA_DMA_API=y -CONFIG_AMD_NB=y -CONFIG_PCCARD=y -CONFIG_PCMCIA=y -CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_CARDBUS=y - -# -# PC-card bridges -# -# CONFIG_YENTA is not set -CONFIG_PD6729=y -CONFIG_I82092=y -CONFIG_PCCARD_NONSTATIC=y -CONFIG_HOTPLUG_PCI=y -CONFIG_HOTPLUG_PCI_FAKE=y -# CONFIG_HOTPLUG_PCI_ACPI is not set -CONFIG_HOTPLUG_PCI_CPCI=y -CONFIG_HOTPLUG_PCI_CPCI_ZT5550=y -CONFIG_HOTPLUG_PCI_CPCI_GENERIC=y -CONFIG_HOTPLUG_PCI_SHPC=y -# CONFIG_RAPIDIO is not set - -# -# Executable file formats / Emulations -# -CONFIG_BINFMT_ELF=y -CONFIG_COMPAT_BINFMT_ELF=y -CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -# CONFIG_HAVE_AOUT is not set -CONFIG_BINFMT_MISC=y -CONFIG_IA32_EMULATION=y -CONFIG_IA32_AOUT=y -CONFIG_COMPAT=y -CONFIG_COMPAT_FOR_U64_ALIGNMENT=y -CONFIG_SYSVIPC_COMPAT=y -CONFIG_KEYS_COMPAT=y -CONFIG_HAVE_TEXT_POKE_SMP=y -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=y -CONFIG_XFRM_SUB_POLICY=y -CONFIG_XFRM_MIGRATE=y -# CONFIG_XFRM_STATISTICS is not set -CONFIG_XFRM_IPCOMP=y -CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_FIB_TRIE_STATS=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_CLASSID=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE_DEMUX is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -CONFIG_INET_TUNNEL=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -CONFIG_INET_LRO=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -CONFIG_TCP_CONG_ADVANCED=y -CONFIG_TCP_CONG_BIC=y -CONFIG_TCP_CONG_CUBIC=y -CONFIG_TCP_CONG_WESTWOOD=y -CONFIG_TCP_CONG_HTCP=y -CONFIG_TCP_CONG_HSTCP=y -CONFIG_TCP_CONG_HYBLA=y -CONFIG_TCP_CONG_VEGAS=y -CONFIG_TCP_CONG_SCALABLE=y -CONFIG_TCP_CONG_LP=y -CONFIG_TCP_CONG_VENO=y -CONFIG_TCP_CONG_YEAH=y -CONFIG_TCP_CONG_ILLINOIS=y -# CONFIG_DEFAULT_BIC is not set -CONFIG_DEFAULT_CUBIC=y -# CONFIG_DEFAULT_HTCP is not set -# CONFIG_DEFAULT_HYBLA is not set -# CONFIG_DEFAULT_VEGAS is not set -# CONFIG_DEFAULT_VENO is not set -# CONFIG_DEFAULT_WESTWOOD is not set -# CONFIG_DEFAULT_RENO is not set -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y -CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -CONFIG_IPV6_OPTIMISTIC_DAD=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_IPV6_MIP6=y -CONFIG_INET6_XFRM_TUNNEL=y -CONFIG_INET6_TUNNEL=y -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=y -CONFIG_IPV6_SIT=y -CONFIG_IPV6_SIT_6RD=y -CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=y -CONFIG_IPV6_MULTIPLE_TABLES=y -CONFIG_IPV6_SUBTREES=y -CONFIG_IPV6_MROUTE=y -CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -CONFIG_IPV6_PIMSM_V2=y -CONFIG_NETWORK_SECMARK=y -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_NETFILTER_ADVANCED=y - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_NETLINK=y -CONFIG_NETFILTER_NETLINK_QUEUE=y -CONFIG_NETFILTER_NETLINK_LOG=y -CONFIG_NF_CONNTRACK=y -CONFIG_NF_CONNTRACK_MARK=y -CONFIG_NF_CONNTRACK_SECMARK=y -CONFIG_NF_CONNTRACK_ZONES=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CONNTRACK_TIMESTAMP=y -CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_GRE=y -CONFIG_NF_CT_PROTO_SCTP=y -CONFIG_NF_CT_PROTO_UDPLITE=y -CONFIG_NF_CONNTRACK_AMANDA=y -CONFIG_NF_CONNTRACK_FTP=y -CONFIG_NF_CONNTRACK_H323=y -CONFIG_NF_CONNTRACK_IRC=y -CONFIG_NF_CONNTRACK_BROADCAST=y -CONFIG_NF_CONNTRACK_NETBIOS_NS=y -CONFIG_NF_CONNTRACK_SNMP=y -CONFIG_NF_CONNTRACK_PPTP=y -CONFIG_NF_CONNTRACK_SANE=y -CONFIG_NF_CONNTRACK_SIP=y -CONFIG_NF_CONNTRACK_TFTP=y -CONFIG_NF_CT_NETLINK=y -CONFIG_NETFILTER_TPROXY=y -CONFIG_NETFILTER_XTABLES=y - -# -# Xtables combined modules -# -CONFIG_NETFILTER_XT_MARK=y -CONFIG_NETFILTER_XT_CONNMARK=y -CONFIG_NETFILTER_XT_SET=y - -# -# Xtables targets -# -CONFIG_NETFILTER_XT_TARGET_AUDIT=y -CONFIG_NETFILTER_XT_TARGET_CHECKSUM=y -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y -CONFIG_NETFILTER_XT_TARGET_CONNMARK=y -CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y -CONFIG_NETFILTER_XT_TARGET_CT=y -CONFIG_NETFILTER_XT_TARGET_DSCP=y -CONFIG_NETFILTER_XT_TARGET_HL=y -CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y -CONFIG_NETFILTER_XT_TARGET_MARK=y -CONFIG_NETFILTER_XT_TARGET_NFLOG=y -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y -CONFIG_NETFILTER_XT_TARGET_NOTRACK=y -CONFIG_NETFILTER_XT_TARGET_RATEEST=y -CONFIG_NETFILTER_XT_TARGET_TEE=y -CONFIG_NETFILTER_XT_TARGET_TPROXY=y -CONFIG_NETFILTER_XT_TARGET_TRACE=y -CONFIG_NETFILTER_XT_TARGET_SECMARK=y -CONFIG_NETFILTER_XT_TARGET_TCPMSS=y -CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=y -# CONFIG_NETFILTER_XT_TARGET_ERSPAN is not set -# CONFIG_NETFILTER_XT_TARGET_SPAN is not set -# CONFIG_NETFILTER_XT_TARGET_POLICE is not set -# CONFIG_NETFILTER_XT_TARGET_TRICOLORPOLICE is not set -# CONFIG_NETFILTER_XT_TARGET_SETCLASS is not set -# CONFIG_NETFILTER_XT_TARGET_SETQOS is not set - -# -# Xtables matches -# -CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y -CONFIG_NETFILTER_XT_MATCH_CLUSTER=y -CONFIG_NETFILTER_XT_MATCH_COMMENT=y -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y -CONFIG_NETFILTER_XT_MATCH_CONNMARK=y -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -CONFIG_NETFILTER_XT_MATCH_CPU=y -CONFIG_NETFILTER_XT_MATCH_DCCP=y -CONFIG_NETFILTER_XT_MATCH_DEVGROUP=y -CONFIG_NETFILTER_XT_MATCH_DSCP=y -CONFIG_NETFILTER_XT_MATCH_ESP=y -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y -CONFIG_NETFILTER_XT_MATCH_HELPER=y -CONFIG_NETFILTER_XT_MATCH_HL=y -CONFIG_NETFILTER_XT_MATCH_IPRANGE=y -CONFIG_NETFILTER_XT_MATCH_IPVS=y -CONFIG_NETFILTER_XT_MATCH_LENGTH=y -CONFIG_NETFILTER_XT_MATCH_LIMIT=y -CONFIG_NETFILTER_XT_MATCH_MAC=y -CONFIG_NETFILTER_XT_MATCH_MARK=y -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y -CONFIG_NETFILTER_XT_MATCH_OSF=y -CONFIG_NETFILTER_XT_MATCH_OWNER=y -CONFIG_NETFILTER_XT_MATCH_POLICY=y -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y -CONFIG_NETFILTER_XT_MATCH_QUOTA=y -CONFIG_NETFILTER_XT_MATCH_RATEEST=y -CONFIG_NETFILTER_XT_MATCH_REALM=y -CONFIG_NETFILTER_XT_MATCH_RECENT=y -CONFIG_NETFILTER_XT_MATCH_SCTP=y -CONFIG_NETFILTER_XT_MATCH_SOCKET=y -CONFIG_NETFILTER_XT_MATCH_STATE=y -CONFIG_NETFILTER_XT_MATCH_STATISTIC=y -CONFIG_NETFILTER_XT_MATCH_STRING=y -CONFIG_NETFILTER_XT_MATCH_TCPMSS=y -CONFIG_NETFILTER_XT_MATCH_TIME=y -CONFIG_NETFILTER_XT_MATCH_U32=y -CONFIG_IP_SET=y -CONFIG_IP_SET_MAX=256 -CONFIG_IP_SET_BITMAP_IP=y -CONFIG_IP_SET_BITMAP_IPMAC=y -CONFIG_IP_SET_BITMAP_PORT=y -CONFIG_IP_SET_HASH_IP=y -CONFIG_IP_SET_HASH_IPPORT=y -CONFIG_IP_SET_HASH_IPPORTIP=y -CONFIG_IP_SET_HASH_IPPORTNET=y -CONFIG_IP_SET_HASH_NET=y -CONFIG_IP_SET_HASH_NETPORT=y -CONFIG_IP_SET_HASH_NETIFACE=y -CONFIG_IP_SET_LIST_SET=y -CONFIG_IP_VS=y -CONFIG_IP_VS_IPV6=y -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 - -# -# IPVS transport protocol load balancing support -# -CONFIG_IP_VS_PROTO_TCP=y -CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_PROTO_AH_ESP=y -CONFIG_IP_VS_PROTO_ESP=y -CONFIG_IP_VS_PROTO_AH=y -CONFIG_IP_VS_PROTO_SCTP=y - -# -# IPVS scheduler -# -CONFIG_IP_VS_RR=y -CONFIG_IP_VS_WRR=y -CONFIG_IP_VS_LC=y -CONFIG_IP_VS_WLC=y -CONFIG_IP_VS_LBLC=y -CONFIG_IP_VS_LBLCR=y -CONFIG_IP_VS_DH=y -CONFIG_IP_VS_SH=y -CONFIG_IP_VS_SED=y -CONFIG_IP_VS_NQ=y - -# -# IPVS application helper -# -CONFIG_IP_VS_FTP=y -CONFIG_IP_VS_NFCT=y -CONFIG_IP_VS_PE_SIP=y - -# -# IP: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV4=y -CONFIG_NF_CONNTRACK_IPV4=y -CONFIG_NF_CONNTRACK_PROC_COMPAT=y -CONFIG_IP_NF_QUEUE=y -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_AH=y -CONFIG_IP_NF_MATCH_ECN=y -CONFIG_IP_NF_MATCH_TTL=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y -CONFIG_IP_NF_TARGET_LOG=y -CONFIG_IP_NF_TARGET_ULOG=y -CONFIG_NF_NAT=y -CONFIG_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_NETMAP=y -CONFIG_IP_NF_TARGET_REDIRECT=y -CONFIG_NF_NAT_SNMP_BASIC=y -CONFIG_NF_NAT_PROTO_DCCP=y -CONFIG_NF_NAT_PROTO_GRE=y -CONFIG_NF_NAT_PROTO_UDPLITE=y -CONFIG_NF_NAT_PROTO_SCTP=y -CONFIG_NF_NAT_FTP=y -CONFIG_NF_NAT_IRC=y -CONFIG_NF_NAT_TFTP=y -CONFIG_NF_NAT_AMANDA=y -CONFIG_NF_NAT_PPTP=y -CONFIG_NF_NAT_H323=y -CONFIG_NF_NAT_SIP=y -CONFIG_IP_NF_MANGLE=y -CONFIG_IP_NF_TARGET_CLUSTERIP=y -CONFIG_IP_NF_TARGET_ECN=y -CONFIG_IP_NF_TARGET_TTL=y -CONFIG_IP_NF_RAW=y -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -CONFIG_IP_NF_ARP_MANGLE=y - -# -# IPv6: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV6=y -CONFIG_NF_CONNTRACK_IPV6=y -CONFIG_IP6_NF_QUEUE=y -CONFIG_IP6_NF_IPTABLES=y -CONFIG_IP6_NF_MATCH_AH=y -CONFIG_IP6_NF_MATCH_EUI64=y -CONFIG_IP6_NF_MATCH_FRAG=y -CONFIG_IP6_NF_MATCH_OPTS=y -CONFIG_IP6_NF_MATCH_HL=y -CONFIG_IP6_NF_MATCH_IPV6HEADER=y -CONFIG_IP6_NF_MATCH_MH=y -CONFIG_IP6_NF_MATCH_RT=y -CONFIG_IP6_NF_TARGET_HL=y -CONFIG_IP6_NF_TARGET_LOG=y -CONFIG_IP6_NF_FILTER=y -CONFIG_IP6_NF_TARGET_REJECT=y -CONFIG_IP6_NF_MANGLE=y -CONFIG_IP6_NF_RAW=y -# CONFIG_IP_DCCP is not set -CONFIG_IP_SCTP=y -# CONFIG_SCTP_DBG_MSG is not set -# CONFIG_SCTP_DBG_OBJCNT is not set -# CONFIG_SCTP_HMAC_NONE is not set -# CONFIG_SCTP_HMAC_SHA1 is not set -CONFIG_SCTP_HMAC_MD5=y -# CONFIG_RDS is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_L2TP is not set -# CONFIG_BRIDGE is not set -# CONFIG_NET_DSA is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_PHONET is not set -# CONFIG_IEEE802154 is not set -# CONFIG_NET_SCHED is not set -# CONFIG_DCB is not set -CONFIG_DNS_RESOLVER=y -# CONFIG_BATMAN_ADV is not set -CONFIG_RPS=y -CONFIG_RFS_ACCEL=y -CONFIG_XPS=y -CONFIG_BQL=y -# CONFIG_BPF_JIT is not set - -# -# Network testing -# -CONFIG_NET_PKTGEN=y -CONFIG_NET_DROP_MONITOR=y -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_AF_RXRPC=y -# CONFIG_AF_RXRPC_DEBUG is not set -# CONFIG_RXKAD is not set -CONFIG_FIB_RULES=y -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_LIB80211=y -# CONFIG_LIB80211_DEBUG is not set - -# -# CFG80211 needs to be enabled for MAC80211 -# -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set -# CONFIG_CAIF is not set -CONFIG_CEPH_LIB=y -# CONFIG_CEPH_LIB_PRETTYDEBUG is not set -# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set -# CONFIG_NFC is not set -CONFIG_HAVE_BPF_JIT=y - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_DEVTMPFS=y -# CONFIG_DEVTMPFS_MOUNT is not set -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_FIRMWARE_IN_KERNEL is not set -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -CONFIG_SYS_HYPERVISOR=y -# CONFIG_GENERIC_CPU_DEVICES is not set -CONFIG_CONNECTOR=y -CONFIG_PROC_EVENTS=y -# CONFIG_MTD is not set -# CONFIG_PARPORT is not set -CONFIG_PNP=y -CONFIG_PNP_DEBUG_MESSAGES=y - -# -# Protocols -# -CONFIG_PNPACPI=y -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_DRBD is not set -CONFIG_BLK_DEV_NBD=y -# CONFIG_BLK_DEV_OSD is not set -CONFIG_BLK_DEV_SX8=y -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=65536 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_XEN_BLKDEV_FRONTEND is not set -# CONFIG_XEN_BLKDEV_BACKEND is not set -# CONFIG_BLK_DEV_HD is not set -# CONFIG_BLK_DEV_RBD is not set -# CONFIG_SENSORS_LIS3LV02D is not set -CONFIG_MISC_DEVICES=y -# CONFIG_AD525X_DPOT is not set -# CONFIG_IBM_ASM is not set -# CONFIG_PHANTOM is not set -# CONFIG_INTEL_MID_PTI is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HP_ILO is not set -# CONFIG_APDS9802ALS is not set -# CONFIG_ISL29003 is not set -# CONFIG_ISL29020 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_BH1780 is not set -# CONFIG_SENSORS_BH1770 is not set -# CONFIG_SENSORS_APDS990X is not set -# CONFIG_HMC6352 is not set -# CONFIG_DS1682 is not set -CONFIG_TI_DAC7512=y -# CONFIG_VMWARE_BALLOON is not set -# CONFIG_BMP085 is not set -# CONFIG_PCH_PHUB is not set -# CONFIG_USB_SWITCH_FSA9480 is not set -CONFIG_EARLY_DMA_ALLOC=y -CONFIG_EDA_DEF_SIZE=0x04000000 -CONFIG_EDA_DEF_ALIGN=0x00100000 -# CONFIG_RETIMER_CLASS is not set -# CONFIG_DS100DF410 is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -CONFIG_EEPROM_CLASS=y -CONFIG_EEPROM_AT24=y -CONFIG_EEPROM_AT25=y -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set -CONFIG_EEPROM_ACCTON_AS5712_54x_SFP=y -CONFIG_EEPROM_ACCTON_AS6712_32x_SFP=y -CONFIG_EEPROM_ACCTON_AS7512_32x_SFP=y -CONFIG_EEPROM_ACCTON_AS7712_32x_SFP=y -CONFIG_EEPROM_ACCTON_AS5812_54x_SFP=y -CONFIG_EEPROM_ACCTON_AS6812_32x_SFP=y -CONFIG_EEPROM_ACCTON_AS5812_54t_SFP=y -CONFIG_EEPROM_ACCTON_AS5512_54X_SFP=y -CONFIG_EEPROM_ACCTON_AS7716_32x_SFP=y -CONFIG_EEPROM_93CX6=y -# CONFIG_EEPROM_93XX46 is not set -CONFIG_EEPROM_SFF_8436=y -CONFIG_CB710_CORE=y -# CONFIG_CB710_DEBUG is not set -CONFIG_CB710_DEBUG_ASSUMPTIONS=y -# CONFIG_IWMC3200TOP is not set - -# -# Texas Instruments shared transport line discipline -# -# CONFIG_TI_ST is not set -# CONFIG_SENSORS_LIS3_I2C is not set - -# -# Altera FPGA firmware download module -# -# CONFIG_ALTERA_STAPL is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_SCSI_MOD=y -CONFIG_RAID_ATTRS=y -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -CONFIG_SCSI_TGT=y -CONFIG_SCSI_NETLINK=y -# CONFIG_SCSI_PROC_FS is not set - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -CONFIG_CHR_DEV_SG=y -# CONFIG_CHR_DEV_SCH is not set -CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -CONFIG_SCSI_SPI_ATTRS=y -CONFIG_SCSI_FC_ATTRS=y -CONFIG_SCSI_FC_TGT_ATTRS=y -CONFIG_SCSI_ISCSI_ATTRS=y -CONFIG_SCSI_SAS_ATTRS=y -CONFIG_SCSI_SAS_LIBSAS=y -CONFIG_SCSI_SAS_ATA=y -CONFIG_SCSI_SAS_HOST_SMP=y -CONFIG_SCSI_SRP_ATTRS=y -CONFIG_SCSI_SRP_TGT_ATTRS=y -CONFIG_SCSI_LOWLEVEL=y -CONFIG_ISCSI_TCP=y -CONFIG_ISCSI_BOOT_SYSFS=y -CONFIG_SCSI_CXGB3_ISCSI=y -CONFIG_SCSI_CXGB4_ISCSI=y -CONFIG_SCSI_BNX2_ISCSI=y -CONFIG_SCSI_BNX2X_FCOE=y -CONFIG_BE2ISCSI=y -CONFIG_BLK_DEV_3W_XXXX_RAID=y -CONFIG_SCSI_HPSA=y -CONFIG_SCSI_3W_9XXX=y -CONFIG_SCSI_3W_SAS=y -CONFIG_SCSI_ACARD=y -CONFIG_SCSI_AACRAID=y -CONFIG_SCSI_AIC7XXX=y -CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -CONFIG_AIC7XXX_DEBUG_ENABLE=y -CONFIG_AIC7XXX_DEBUG_MASK=0 -CONFIG_AIC7XXX_REG_PRETTY_PRINT=y -CONFIG_SCSI_AIC7XXX_OLD=y -CONFIG_SCSI_AIC79XX=y -CONFIG_AIC79XX_CMDS_PER_DEVICE=32 -CONFIG_AIC79XX_RESET_DELAY_MS=15000 -CONFIG_AIC79XX_DEBUG_ENABLE=y -CONFIG_AIC79XX_DEBUG_MASK=0 -CONFIG_AIC79XX_REG_PRETTY_PRINT=y -CONFIG_SCSI_AIC94XX=y -# CONFIG_AIC94XX_DEBUG is not set -CONFIG_SCSI_MVSAS=y -# CONFIG_SCSI_MVSAS_DEBUG is not set -# CONFIG_SCSI_MVSAS_TASKLET is not set -CONFIG_SCSI_MVUMI=y -CONFIG_SCSI_DPT_I2O=y -CONFIG_SCSI_ADVANSYS=y -CONFIG_SCSI_ARCMSR=y -CONFIG_MEGARAID_NEWGEN=y -CONFIG_MEGARAID_MM=y -CONFIG_MEGARAID_MAILBOX=y -CONFIG_MEGARAID_LEGACY=y -CONFIG_MEGARAID_SAS=y -CONFIG_SCSI_MPT2SAS=y -CONFIG_SCSI_MPT2SAS_MAX_SGE=128 -# CONFIG_SCSI_MPT2SAS_LOGGING is not set -CONFIG_SCSI_HPTIOP=y -CONFIG_SCSI_BUSLOGIC=y -CONFIG_VMWARE_PVSCSI=y -CONFIG_LIBFC=y -CONFIG_LIBFCOE=y -CONFIG_FCOE=y -CONFIG_FCOE_FNIC=y -CONFIG_SCSI_DMX3191D=y -CONFIG_SCSI_EATA=y -CONFIG_SCSI_EATA_TAGGED_QUEUE=y -CONFIG_SCSI_EATA_LINKED_COMMANDS=y -CONFIG_SCSI_EATA_MAX_TAGS=16 -CONFIG_SCSI_FUTURE_DOMAIN=y -CONFIG_SCSI_GDTH=y -CONFIG_SCSI_ISCI=y -CONFIG_SCSI_IPS=y -CONFIG_SCSI_INITIO=y -CONFIG_SCSI_INIA100=y -CONFIG_SCSI_STEX=y -CONFIG_SCSI_SYM53C8XX_2=y -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -CONFIG_SCSI_SYM53C8XX_MMIO=y -CONFIG_SCSI_IPR=y -# CONFIG_SCSI_IPR_TRACE is not set -# CONFIG_SCSI_IPR_DUMP is not set -CONFIG_SCSI_QLOGIC_1280=y -CONFIG_SCSI_QLA_FC=y -CONFIG_SCSI_QLA_ISCSI=y -CONFIG_SCSI_LPFC=y -# CONFIG_SCSI_LPFC_DEBUG_FS is not set -CONFIG_SCSI_DC395x=y -CONFIG_SCSI_DC390T=y -CONFIG_SCSI_DEBUG=y -CONFIG_SCSI_PMCRAID=y -CONFIG_SCSI_PM8001=y -CONFIG_SCSI_SRP=y -CONFIG_SCSI_BFA_FC=y -CONFIG_SCSI_LOWLEVEL_PCMCIA=y -# CONFIG_PCMCIA_AHA152X is not set -# CONFIG_PCMCIA_FDOMAIN is not set -# CONFIG_PCMCIA_QLOGIC is not set -# CONFIG_PCMCIA_SYM53C500 is not set -CONFIG_SCSI_DH=y -CONFIG_SCSI_DH_RDAC=y -CONFIG_SCSI_DH_HP_SW=y -CONFIG_SCSI_DH_EMC=y -CONFIG_SCSI_DH_ALUA=y -CONFIG_SCSI_OSD_INITIATOR=y -CONFIG_SCSI_OSD_ULD=y -CONFIG_SCSI_OSD_DPRINT_SENSE=1 -# CONFIG_SCSI_OSD_DEBUG is not set -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -CONFIG_ATA_VERBOSE_ERROR=y -CONFIG_ATA_ACPI=y -CONFIG_SATA_PMP=y - -# -# Controllers with non-SFF native interface -# -CONFIG_SATA_AHCI=y -CONFIG_SATA_AHCI_PLATFORM=y -# CONFIG_SATA_INIC162X is not set -CONFIG_SATA_ACARD_AHCI=y -CONFIG_SATA_SIL24=y -CONFIG_ATA_SFF=y - -# -# SFF controllers with custom DMA interface -# -CONFIG_PDC_ADMA=y -CONFIG_SATA_QSTOR=y -CONFIG_SATA_SX4=y -CONFIG_ATA_BMDMA=y - -# -# SATA SFF controllers with BMDMA -# -CONFIG_ATA_PIIX=y -CONFIG_SATA_MV=y -CONFIG_SATA_NV=y -CONFIG_SATA_PROMISE=y -CONFIG_SATA_SIL=y -CONFIG_SATA_SIS=y -CONFIG_SATA_SVW=y -CONFIG_SATA_ULI=y -CONFIG_SATA_VIA=y -CONFIG_SATA_VITESSE=y - -# -# PATA SFF controllers with BMDMA -# -CONFIG_PATA_ALI=y -CONFIG_PATA_AMD=y -CONFIG_PATA_ARTOP=y -CONFIG_PATA_ATIIXP=y -CONFIG_PATA_ATP867X=y -CONFIG_PATA_CMD64X=y -CONFIG_PATA_CS5520=y -CONFIG_PATA_CS5530=y -# CONFIG_PATA_CS5536 is not set -# CONFIG_PATA_CYPRESS is not set -CONFIG_PATA_EFAR=y -CONFIG_PATA_HPT366=y -CONFIG_PATA_HPT37X=y -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -CONFIG_PATA_IT8213=y -CONFIG_PATA_IT821X=y -CONFIG_PATA_JMICRON=y -CONFIG_PATA_MARVELL=y -CONFIG_PATA_NETCELL=y -CONFIG_PATA_NINJA32=y -CONFIG_PATA_NS87415=y -CONFIG_PATA_OLDPIIX=y -# CONFIG_PATA_OPTIDMA is not set -CONFIG_PATA_PDC2027X=y -CONFIG_PATA_PDC_OLD=y -# CONFIG_PATA_RADISYS is not set -CONFIG_PATA_RDC=y -CONFIG_PATA_SC1200=y -CONFIG_PATA_SCH=y -CONFIG_PATA_SERVERWORKS=y -CONFIG_PATA_SIL680=y -CONFIG_PATA_SIS=y -CONFIG_PATA_TOSHIBA=y -CONFIG_PATA_TRIFLEX=y -CONFIG_PATA_VIA=y -# CONFIG_PATA_WINBOND is not set - -# -# PIO-only SFF controllers -# -# CONFIG_PATA_CMD640_PCI is not set -CONFIG_PATA_MPIIX=y -CONFIG_PATA_NS87410=y -# CONFIG_PATA_OPTI is not set -CONFIG_PATA_PCMCIA=y -CONFIG_PATA_PLATFORM=y -CONFIG_PATA_RZ1000=y - -# -# Generic fallback / legacy drivers -# -# CONFIG_PATA_ACPI is not set -CONFIG_ATA_GENERIC=y -# CONFIG_PATA_LEGACY is not set -CONFIG_MD=y -# CONFIG_BLK_DEV_MD is not set -CONFIG_BLK_DEV_DM_BUILTIN=y -CONFIG_BLK_DEV_DM=y -# CONFIG_DM_DEBUG is not set -CONFIG_DM_CRYPT=y -# CONFIG_DM_SNAPSHOT is not set -# CONFIG_DM_THIN_PROVISIONING is not set -# CONFIG_DM_MIRROR is not set -# CONFIG_DM_RAID is not set -# CONFIG_DM_ZERO is not set -# CONFIG_DM_MULTIPATH is not set -# CONFIG_DM_DELAY is not set -# CONFIG_DM_UEVENT is not set -# CONFIG_DM_FLAKEY is not set -# CONFIG_TARGET_CORE is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -CONFIG_FIREWIRE=y -CONFIG_FIREWIRE_OHCI=y -CONFIG_FIREWIRE_OHCI_DEBUG=y -CONFIG_FIREWIRE_SBP2=y -CONFIG_FIREWIRE_NET=y -CONFIG_FIREWIRE_NOSY=y -# CONFIG_I2O is not set -# CONFIG_MACINTOSH_DRIVERS is not set -CONFIG_NETDEVICES=y -CONFIG_NET_CORE=y -# CONFIG_BONDING is not set -# CONFIG_DUMMY is not set -# CONFIG_EQUALIZER is not set -# CONFIG_NET_FC is not set -CONFIG_MII=y -# CONFIG_MACVLAN is not set -# CONFIG_VXLAN is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -CONFIG_TUN=y -CONFIG_VETH=y -# CONFIG_ARCNET is not set - -# -# CAIF transport drivers -# -CONFIG_ETHERNET=y -CONFIG_MDIO=y -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_VENDOR_ADAPTEC is not set -# CONFIG_NET_VENDOR_ALTEON is not set -# CONFIG_NET_VENDOR_AMD is not set -# CONFIG_NET_VENDOR_ATHEROS is not set -CONFIG_NET_VENDOR_BROADCOM=y -CONFIG_B44=y -CONFIG_B44_PCI_AUTOSELECT=y -CONFIG_B44_PCICORE_AUTOSELECT=y -CONFIG_B44_PCI=y -CONFIG_BNX2=y -CONFIG_CNIC=y -CONFIG_TIGON3=y -CONFIG_BNX2X=y -# CONFIG_NET_VENDOR_BROCADE is not set -CONFIG_NET_VENDOR_CHELSIO=y -# CONFIG_CHELSIO_T1 is not set -CONFIG_CHELSIO_T3=y -CONFIG_CHELSIO_T4=y -CONFIG_CHELSIO_T4VF=y -# CONFIG_NET_VENDOR_CISCO is not set -# CONFIG_DNET is not set -# CONFIG_NET_VENDOR_DEC is not set -# CONFIG_NET_VENDOR_DLINK is not set -# CONFIG_NET_VENDOR_EMULEX is not set -# CONFIG_NET_VENDOR_EXAR is not set -# CONFIG_NET_VENDOR_FUJITSU is not set -# CONFIG_NET_VENDOR_HP is not set -CONFIG_NET_VENDOR_INTEL=y -# CONFIG_E100 is not set -CONFIG_E1000=y -CONFIG_E1000E=y -# CONFIG_E1000E_PTP is not set -CONFIG_IGB=y -CONFIG_IGB_HWMON=y -# CONFIG_IGB_PTP is not set -CONFIG_IGBVF=y -CONFIG_IXGB=y -CONFIG_IXGBE=y -CONFIG_IXGBEVF=y -CONFIG_NET_VENDOR_I825XX=y -# CONFIG_ZNET is not set -# CONFIG_IP1000 is not set -# CONFIG_JME is not set -# CONFIG_NET_VENDOR_MARVELL is not set -CONFIG_NET_VENDOR_MELLANOX=y -# CONFIG_MLX4_EN is not set -# CONFIG_MLX4_CORE is not set -# CONFIG_NET_VENDOR_MICREL is not set -CONFIG_NET_VENDOR_MICROCHIP=y -CONFIG_ENC28J60=y -CONFIG_ENC28J60_WRITEVERIFY=y -# CONFIG_NET_VENDOR_MYRI is not set -# CONFIG_FEALNX is not set -# CONFIG_NET_VENDOR_NATSEMI is not set -# CONFIG_NET_VENDOR_NVIDIA is not set -# CONFIG_NET_VENDOR_OKI is not set -# CONFIG_ETHOC is not set -# CONFIG_NET_PACKET_ENGINE is not set -# CONFIG_NET_VENDOR_QLOGIC is not set -CONFIG_NET_VENDOR_REALTEK=y -CONFIG_ATP=y -CONFIG_8139CP=y -# CONFIG_8139TOO is not set -# CONFIG_8139TOO_PIO is not set -CONFIG_8139TOO_TUNE_TWISTER=y -CONFIG_8139TOO_8129=y -# CONFIG_8139_OLD_RX_RESET is not set -CONFIG_R8169=y -# CONFIG_NET_VENDOR_RDC is not set -# CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_SILAN is not set -# CONFIG_NET_VENDOR_SIS is not set -# CONFIG_SFC is not set -# CONFIG_NET_VENDOR_SMSC is not set -# CONFIG_NET_VENDOR_STMICRO is not set -# CONFIG_NET_VENDOR_SUN is not set -# CONFIG_NET_VENDOR_TEHUTI is not set -# CONFIG_NET_VENDOR_TI is not set -# CONFIG_NET_VENDOR_VIA is not set -# CONFIG_NET_VENDOR_XIRCOM is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_NET_SB1000 is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=y -CONFIG_DAVICOM_PHY=y -CONFIG_QSEMI_PHY=y -CONFIG_LXT_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_SMSC_PHY=y -CONFIG_BROADCOM_PHY=y -# CONFIG_ICPLUS_PHY is not set -CONFIG_REALTEK_PHY=y -CONFIG_NATIONAL_PHY=y -CONFIG_STE10XP=y -CONFIG_LSI_ET1011C_PHY=y -CONFIG_MICREL_PHY=y -CONFIG_FIXED_PHY=y -CONFIG_MDIO_BITBANG=y -# CONFIG_MDIO_GPIO is not set -CONFIG_PPP=y -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_FILTER is not set -# CONFIG_PPP_MPPE is not set -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPPOE is not set -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_SLIP is not set -CONFIG_SLHC=y -# CONFIG_TR is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_USB_IPHETH is not set -# CONFIG_WLAN is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# -# CONFIG_WAN is not set -# CONFIG_XEN_NETDEV_FRONTEND is not set -# CONFIG_XEN_NETDEV_BACKEND is not set -# CONFIG_VMXNET3 is not set -# CONFIG_DPAA_ETH_USE_NDO_SELECT_QUEUE is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -CONFIG_INPUT_FF_MEMLESS=y -CONFIG_INPUT_POLLDEV=y -CONFIG_INPUT_SPARSEKMAP=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_JOYDEV=y -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_UNIX98_PTYS=y -CONFIG_DEVPTS_MULTIPLE_INSTANCES=y -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_NONSTANDARD=y -# CONFIG_ROCKETPORT is not set -# CONFIG_CYCLADES is not set -# CONFIG_MOXA_INTELLIO is not set -# CONFIG_MOXA_SMARTIO is not set -# CONFIG_SYNCLINK is not set -# CONFIG_SYNCLINKMP is not set -# CONFIG_SYNCLINK_GT is not set -# CONFIG_NOZOMI is not set -# CONFIG_ISI is not set -# CONFIG_N_HDLC is not set -# CONFIG_N_GSM is not set -# CONFIG_TRACE_SINK is not set -# CONFIG_DEVKMEM is not set -# CONFIG_STALDRV is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_PNP=y -CONFIG_SERIAL_8250_CS=y -CONFIG_SERIAL_8250_NR_UARTS=32 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -CONFIG_SERIAL_8250_RSA=y - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_MAX3100 is not set -# CONFIG_SERIAL_MAX3107 is not set -CONFIG_SERIAL_MFD_HSU=y -# CONFIG_SERIAL_MFD_HSU_CONSOLE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_JSM=y -# CONFIG_SERIAL_TIMBERDALE is not set -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -# CONFIG_SERIAL_IFX6X60 is not set -CONFIG_SERIAL_PCH_UART=y -# CONFIG_SERIAL_XILINX_PS_UART is not set -# CONFIG_TTY_PRINTK is not set -# CONFIG_HVC_XEN is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_TIMERIOMEM=y -CONFIG_HW_RANDOM_INTEL=y -CONFIG_HW_RANDOM_AMD=y -CONFIG_HW_RANDOM_VIA=y -CONFIG_NVRAM=y -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# PCMCIA character devices -# -CONFIG_SYNCLINK_CS=y -CONFIG_CARDMAN_4000=y -CONFIG_CARDMAN_4040=y -CONFIG_IPWIRELESS=y -# CONFIG_MWAVE is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_HPET is not set -# CONFIG_HANGCHECK_TIMER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set -CONFIG_DEVPORT=y -# CONFIG_RAMOOPS is not set -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MUX=y - -# -# Multiplexer I2C Chip support -# -CONFIG_I2C_MUX_ACCTON_AS5712_54x_CPLD=y -CONFIG_I2C_MUX_ACCTON_AS6712_32x_CPLD=y -CONFIG_I2C_MUX_ACCTON_AS5812_54x_CPLD=y -CONFIG_I2C_MUX_ACCTON_AS6812_32x_CPLD=y -CONFIG_I2C_MUX_GPIO=y -CONFIG_I2C_MUX_PCA9541=y -CONFIG_I2C_MUX_PCA954x=y -CONFIG_I2C_MUX_PCA954X_DESELECT_ON_EXIT=y -# CONFIG_I2C_MUX_DNI_6448 is not set -# CONFIG_I2C_MUX_QUANTA is not set -# CONFIG_I2C_MUX_QUANTA_LY2 is not set -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_ALGOBIT=y -CONFIG_I2C_ALGOPCA=y - -# -# I2C Hardware Bus support -# - -# -# PC SMBus host controller drivers -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -CONFIG_I2C_I801=y -CONFIG_I2C_ISCH=y -CONFIG_I2C_ISMT=y -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set - -# -# ACPI drivers -# -# CONFIG_I2C_SCMI is not set - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_DESIGNWARE_PCI is not set -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_INTEL_MID is not set -# CONFIG_I2C_OCORES is not set -CONFIG_I2C_PCA_PLATFORM=y -# CONFIG_I2C_PXA_PCI is not set -# CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_XILINX is not set -# CONFIG_I2C_EG20T is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_DIOLAN_U2C is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -CONFIG_SPI=y -# CONFIG_SPI_DEBUG is not set -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -# CONFIG_SPI_ALTERA is not set -# CONFIG_SPI_BITBANG is not set -# CONFIG_SPI_GPIO is not set -# CONFIG_SPI_OC_TINY is not set -# CONFIG_SPI_PXA2XX_PCI is not set -# CONFIG_SPI_TOPCLIFF_PCH is not set -# CONFIG_SPI_XILINX is not set -# CONFIG_SPI_DESIGNWARE is not set - -# -# SPI Protocol Masters -# -# CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set - -# -# PPS support -# -CONFIG_PPS=y -# CONFIG_PPS_DEBUG is not set - -# -# PPS clients support -# -# CONFIG_PPS_CLIENT_KTIMER is not set -# CONFIG_PPS_CLIENT_LDISC is not set -# CONFIG_PPS_CLIENT_GPIO is not set - -# -# PPS generators support -# - -# -# PTP clock support -# -# CONFIG_PTP_1588_CLOCK is not set -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -CONFIG_GPIO_SYSFS=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_MAX730X=y - -# -# Memory mapped GPIO drivers: -# -CONFIG_GPIO_GENERIC_PLATFORM=y -# CONFIG_GPIO_IT8761E is not set -CONFIG_GPIO_SCH=y -# CONFIG_GPIO_VX855 is not set - -# -# I2C GPIO expanders: -# -# CONFIG_GPIO_MAX7300 is not set -# CONFIG_GPIO_MAX732X is not set -CONFIG_GPIO_PCA953X=y -# CONFIG_GPIO_PCA953X_IRQ is not set -CONFIG_GPIO_PCF857X=y -# CONFIG_GPIO_SX150X is not set -# CONFIG_GPIO_ADP5588 is not set - -# -# PCI GPIO expanders: -# -# CONFIG_GPIO_BT8XX is not set -# CONFIG_GPIO_LANGWELL is not set -# CONFIG_GPIO_PCH is not set -# CONFIG_GPIO_ML_IOH is not set -# CONFIG_GPIO_RDC321X is not set - -# -# SPI GPIO expanders: -# -CONFIG_GPIO_MAX7301=y -# CONFIG_GPIO_MCP23S08 is not set -CONFIG_GPIO_MC33880=y -CONFIG_GPIO_74X164=y - -# -# AC97 GPIO expanders: -# - -# -# MODULbus GPIO expanders: -# -# CONFIG_W1 is not set -CONFIG_POWER_SUPPLY=y -# CONFIG_POWER_SUPPLY_DEBUG is not set -# CONFIG_PDA_POWER is not set -# CONFIG_TEST_POWER is not set -# CONFIG_BATTERY_DS2780 is not set -# CONFIG_BATTERY_DS2782 is not set -# CONFIG_BATTERY_BQ20Z75 is not set -# CONFIG_BATTERY_BQ27x00 is not set -# CONFIG_BATTERY_MAX17040 is not set -# CONFIG_BATTERY_MAX17042 is not set -# CONFIG_CHARGER_MAX8903 is not set -# CONFIG_CHARGER_GPIO is not set -CONFIG_HWMON=y -CONFIG_HWMON_VID=y -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Native drivers -# -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ABITUGURU3 is not set -# CONFIG_SENSORS_AD7314 is not set -# CONFIG_SENSORS_AD7414 is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADCXX is not set -CONFIG_SENSORS_ADM1021=y -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7411 is not set -# CONFIG_SENSORS_ADT7462 is not set -CONFIG_SENSORS_ADT7470=y -# CONFIG_SENSORS_ADT7475 is not set -# CONFIG_SENSORS_ASC7621 is not set -# CONFIG_SENSORS_K8TEMP is not set -# CONFIG_SENSORS_K10TEMP is not set -# CONFIG_SENSORS_FAM15H_POWER is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_CY8CXX is not set -# CONFIG_SENSORS_CY8C3245R1 is not set -# CONFIG_SENSORS_DS620 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_I5K_AMB is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_FSCHMD is not set -# CONFIG_SENSORS_G760A is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -CONFIG_SENSORS_GPIO_FAN=y -CONFIG_SENSORS_CORETEMP=y -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_JC42 is not set -# CONFIG_SENSORS_LINEAGE is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 is not set -# CONFIG_SENSORS_LM73 is not set -CONFIG_SENSORS_LM75=y -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -CONFIG_SENSORS_LM85=y -# CONFIG_SENSORS_LM87 is not set -CONFIG_SENSORS_LM90=y -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -CONFIG_SENSORS_LTC4151=y -CONFIG_SENSORS_LTC4215=y -CONFIG_SENSORS_LTC4245=y -CONFIG_SENSORS_LTC4261=y -# CONFIG_SENSORS_LM95241 is not set -# CONFIG_SENSORS_LM95245 is not set -# CONFIG_SENSORS_MAX1111 is not set -# CONFIG_SENSORS_MAX16065 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX1668 is not set -# CONFIG_SENSORS_MAX6639 is not set -# CONFIG_SENSORS_MAX6642 is not set -CONFIG_SENSORS_MAX6650=y -CONFIG_SENSORS_MAX6620=y -# CONFIG_SENSORS_MAX6697 is not set -# CONFIG_SENSORS_NTC_THERMISTOR is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_PCF8591 is not set -CONFIG_PMBUS=y -CONFIG_SENSORS_PMBUS=y -# CONFIG_SENSORS_ADM1275 is not set -# CONFIG_SENSORS_LM25066 is not set -# CONFIG_SENSORS_LTC2978 is not set -# CONFIG_SENSORS_MAX16064 is not set -# CONFIG_SENSORS_MAX34440 is not set -# CONFIG_SENSORS_DNI_DPS460 is not set -# CONFIG_SENSORS_MAX8688 is not set -# CONFIG_SENSORS_UCD9000 is not set -# CONFIG_SENSORS_UCD9200 is not set -# CONFIG_SENSORS_ZL6100 is not set -# CONFIG_SENSORS_SHT15 is not set -# CONFIG_SENSORS_SHT21 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMM665 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_EMC1403 is not set -# CONFIG_SENSORS_EMC2103 is not set -# CONFIG_SENSORS_EMC2305 is not set -# CONFIG_SENSORS_EMC6W201 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SCH56XX_COMMON is not set -# CONFIG_SENSORS_SCH5627 is not set -# CONFIG_SENSORS_SCH5636 is not set -# CONFIG_SENSORS_ADS1015 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_ADS7871 is not set -# CONFIG_SENSORS_AMC6821 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_TMP102 is not set -# CONFIG_SENSORS_TMP401 is not set -# CONFIG_SENSORS_TMP421 is not set -# CONFIG_SENSORS_VIA_CPUTEMP is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -CONFIG_SENSORS_W83781D=y -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83795 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_SENSORS_APPLESMC is not set -# CONFIG_SENSORS_QUANTA_LY_HWMON is not set -CONFIG_SENSORS_CPR_4011_4MXX=y -CONFIG_SENSORS_ACCTON_AS5712_54x_FAN=y -CONFIG_SENSORS_ACCTON_AS5712_54x_PSU=y -CONFIG_SENSORS_ACCTON_AS6712_32x_FAN=y -CONFIG_SENSORS_ACCTON_AS6712_32x_PSU=y -CONFIG_SENSORS_ACCTON_I2C_CPLD=y -CONFIG_SENSORS_ACCTON_AS7512_32x_FAN=y -CONFIG_SENSORS_ACCTON_AS7512_32x_PSU=y -CONFIG_SENSORS_YM2651Y=y -CONFIG_SENSORS_ACCTON_AS7712_32x_FAN=y -CONFIG_SENSORS_ACCTON_AS7712_32x_PSU=y -CONFIG_SENSORS_ACCTON_AS5812_54x_FAN=y -CONFIG_SENSORS_ACCTON_AS5812_54x_PSU=y -CONFIG_SENSORS_ACCTON_AS6812_32x_FAN=y -CONFIG_SENSORS_ACCTON_AS6812_32x_PSU=y -CONFIG_SENSORS_ACCTON_AS5812_54t_FAN=y -CONFIG_SENSORS_ACCTON_AS5812_54t_PSU=y -CONFIG_SENSORS_ACCTON_AS5512_54X_PSU=y -CONFIG_SENSORS_ACCTON_AS5512_54X_FAN=y -CONFIG_SENSORS_ACCTON_AS7716_32x_FAN=y -CONFIG_SENSORS_ACCTON_AS7716_32x_PSU=y - -# -# ACPI drivers -# -# CONFIG_SENSORS_ACPI_POWER is not set -# CONFIG_SENSORS_ATK0110 is not set -CONFIG_THERMAL=y -CONFIG_THERMAL_HWMON=y -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_ACQUIRE_WDT is not set -# CONFIG_ADVANTECH_WDT is not set -# CONFIG_ALIM1535_WDT is not set -# CONFIG_ALIM7101_WDT is not set -# CONFIG_F71808E_WDT is not set -# CONFIG_SP5100_TCO is not set -# CONFIG_SC520_WDT is not set -# CONFIG_SBC_FITPC2_WATCHDOG is not set -# CONFIG_EUROTECH_WDT is not set -# CONFIG_IB700_WDT is not set -# CONFIG_IBMASR is not set -# CONFIG_WAFER_WDT is not set -# CONFIG_I6300ESB_WDT is not set -CONFIG_ITCO_WDT=y -# CONFIG_ITCO_VENDOR_SUPPORT is not set -# CONFIG_IT8712F_WDT is not set -# CONFIG_IT87_WDT is not set -# CONFIG_HP_WATCHDOG is not set -# CONFIG_SC1200_WDT is not set -# CONFIG_PC87413_WDT is not set -# CONFIG_NV_TCO is not set -# CONFIG_60XX_WDT is not set -# CONFIG_SBC8360_WDT is not set -# CONFIG_CPU5_WDT is not set -# CONFIG_SMSC_SCH311X_WDT is not set -# CONFIG_SMSC37B787_WDT is not set -# CONFIG_W83627HF_WDT is not set -# CONFIG_W83697HF_WDT is not set -# CONFIG_W83697UG_WDT is not set -# CONFIG_W83877F_WDT is not set -# CONFIG_W83977F_WDT is not set -# CONFIG_MACHZ_WDT is not set -# CONFIG_SBC_EPX_C3_WATCHDOG is not set -# CONFIG_XEN_WDT is not set - -# -# PCI-based Watchdog Cards -# -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -CONFIG_SSB=y -CONFIG_SSB_SPROM=y -CONFIG_SSB_PCIHOST_POSSIBLE=y -CONFIG_SSB_PCIHOST=y -# CONFIG_SSB_B43_PCI_BRIDGE is not set -CONFIG_SSB_PCMCIAHOST_POSSIBLE=y -CONFIG_SSB_PCMCIAHOST=y -CONFIG_SSB_SDIOHOST_POSSIBLE=y -CONFIG_SSB_SDIOHOST=y -# CONFIG_SSB_SILENT is not set -# CONFIG_SSB_DEBUG is not set -CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y -CONFIG_SSB_DRIVER_PCICORE=y -CONFIG_BCMA_POSSIBLE=y - -# -# Broadcom specific AMBA -# -CONFIG_BCMA=y -CONFIG_BCMA_HOST_PCI_POSSIBLE=y -CONFIG_BCMA_HOST_PCI=y -# CONFIG_BCMA_DEBUG is not set - -# -# Multifunction device drivers -# -CONFIG_MFD_CORE=y -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTC_I2CPLD is not set -# CONFIG_TPS6105X is not set -# CONFIG_TPS65010 is not set -# CONFIG_TPS6507X is not set -# CONFIG_MFD_TPS6586X is not set -# CONFIG_MFD_TPS65910 is not set -# CONFIG_MFD_TPS65912_I2C is not set -# CONFIG_MFD_TPS65912_SPI is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_MFD_STMPE is not set -# CONFIG_MFD_TC3589X is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX8998 is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM831X_I2C is not set -# CONFIG_MFD_WM831X_SPI is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8994 is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_MFD_MC13XXX is not set -# CONFIG_ABX500_CORE is not set -# CONFIG_EZX_PCAP is not set -# CONFIG_MFD_CS5535 is not set -# CONFIG_MFD_TIMBERDALE is not set -CONFIG_LPC_ICH=y -CONFIG_LPC_SCH=y -# CONFIG_MFD_RDC321X is not set -# CONFIG_MFD_JANZ_CMODIO is not set -# CONFIG_MFD_VX855 is not set -CONFIG_MFD_WL1273_CORE=y -# CONFIG_MFD_AAT2870_CORE is not set -# CONFIG_REGULATOR is not set -# CONFIG_MEDIA_SUPPORT is not set - -# -# Graphics support -# -# CONFIG_AGP is not set -# CONFIG_VGA_ARB is not set -# CONFIG_VGA_SWITCHEROO is not set -# CONFIG_DRM is not set -# CONFIG_STUB_POULSBO is not set -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -CONFIG_DISPLAY_SUPPORT=y - -# -# Display hardware drivers -# - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -# CONFIG_VGACON_SOFT_SCROLLBACK is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_SOUND is not set -# CONFIG_HID_SUPPORT is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_COMMON=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB_ARCH_HAS_XHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_DWC3 is not set -# CONFIG_USB_MON is not set -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -CONFIG_USB_XHCI_HCD=y -# CONFIG_USB_XHCI_HCD_DEBUGGING is not set -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EHCI_TT_NEWSCHED=y -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -# CONFIG_USB_ISP1362_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_HCD_SSB is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -CONFIG_USB_UHCI_HCD=y -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_WHCI_HCD is not set -# CONFIG_USB_HWA_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -# - -# -# also be needed; see USB_STORAGE Help for more info -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_REALTEK is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_STORAGE_ENE_UB6250 is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -CONFIG_USB_SERIAL=y -CONFIG_USB_SERIAL_CONSOLE=y -# CONFIG_USB_EZUSB is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_AIRCABLE is not set -# CONFIG_USB_SERIAL_ARK3116 is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_CH341 is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_CP210X is not set -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_FUNSOFT is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_GARMIN is not set -# CONFIG_USB_SERIAL_IPW is not set -# CONFIG_USB_SERIAL_IUU is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_MOS7720 is not set -# CONFIG_USB_SERIAL_MOS7840 is not set -# CONFIG_USB_SERIAL_MOTOROLA is not set -# CONFIG_USB_SERIAL_NAVMAN is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_OTI6858 is not set -# CONFIG_USB_SERIAL_QCAUX is not set -# CONFIG_USB_SERIAL_QUALCOMM is not set -# CONFIG_USB_SERIAL_SPCP8X5 is not set -# CONFIG_USB_SERIAL_HP4X is not set -# CONFIG_USB_SERIAL_SAFE is not set -# CONFIG_USB_SERIAL_SIEMENS_MPI is not set -# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set -# CONFIG_USB_SERIAL_SYMBOL is not set -# CONFIG_USB_SERIAL_TI is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OPTION is not set -# CONFIG_USB_SERIAL_OMNINET is not set -# CONFIG_USB_SERIAL_OPTICON is not set -# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set -# CONFIG_USB_SERIAL_ZIO is not set -# CONFIG_USB_SERIAL_SSU100 is not set -# CONFIG_USB_SERIAL_DEBUG is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_YUREX is not set -# CONFIG_USB_GADGET is not set - -# -# OTG and related infrastructure -# -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_NOP_USB_XCEIV is not set -# CONFIG_UWB is not set -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -# CONFIG_MMC_UNSAFE_RESUME is not set -# CONFIG_MMC_CLKGATE is not set - -# -# MMC/SD/SDIO Card Drivers -# -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=8 -CONFIG_MMC_BLOCK_BOUNCE=y -# CONFIG_SDIO_UART is not set -# CONFIG_MMC_TEST is not set - -# -# MMC/SD/SDIO Host Controller Drivers -# -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_PCI=y -# CONFIG_MMC_RICOH_MMC is not set -CONFIG_MMC_SDHCI_PLTFM=y -# CONFIG_MMC_WBSD is not set -# CONFIG_MMC_TIFM_SD is not set -CONFIG_MMC_SPI=y -# CONFIG_MMC_SDRICOH_CS is not set -# CONFIG_MMC_CB710 is not set -# CONFIG_MMC_VIA_SDMMC is not set -# CONFIG_MMC_VUB300 is not set -# CONFIG_MMC_USHC is not set -# CONFIG_MEMSTICK is not set -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y - -# -# LED drivers -# -CONFIG_LEDS_ACCTON_AS5712_54x=y -CONFIG_LEDS_ACCTON_AS6712_32x=y -CONFIG_LEDS_ACCTON_AS7512_32x=y -CONFIG_LEDS_ACCTON_AS7712_32x=y -CONFIG_LEDS_ACCTON_AS5812_54x=y -CONFIG_LEDS_ACCTON_AS6812_32x=y -CONFIG_LEDS_ACCTON_AS5812_54t=y -CONFIG_LEDS_ACCTON_AS5512_54X=y -CONFIG_LEDS_ACCTON_AS7716_32x=y -# CONFIG_LEDS_LM3530 is not set -# CONFIG_LEDS_PCA9532 is not set -# CONFIG_LEDS_GPIO is not set -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -# CONFIG_LEDS_PCA955X is not set -# CONFIG_LEDS_DAC124S085 is not set -# CONFIG_LEDS_BD2802 is not set -# CONFIG_LEDS_INTEL_SS4200 is not set -# CONFIG_LEDS_LT3593 is not set -# CONFIG_LEDS_TRIGGERS is not set - -# -# LED Triggers -# -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -# CONFIG_EDAC is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -CONFIG_RTC_DRV_DS1307=y -CONFIG_RTC_DRV_DS1374=y -CONFIG_RTC_DRV_DS1672=y -CONFIG_RTC_DRV_DS3232=y -CONFIG_RTC_DRV_MAX6900=y -CONFIG_RTC_DRV_RS5C372=y -CONFIG_RTC_DRV_ISL1208=y -CONFIG_RTC_DRV_ISL12022=y -CONFIG_RTC_DRV_X1205=y -CONFIG_RTC_DRV_PCF8563=y -CONFIG_RTC_DRV_PCF8583=y -CONFIG_RTC_DRV_M41T80=y -# CONFIG_RTC_DRV_M41T80_WDT is not set -CONFIG_RTC_DRV_BQ32K=y -CONFIG_RTC_DRV_S35390A=y -CONFIG_RTC_DRV_FM3130=y -CONFIG_RTC_DRV_RX8581=y -CONFIG_RTC_DRV_RX8025=y -# CONFIG_RTC_DRV_EM3027 is not set -# CONFIG_RTC_DRV_RV3029C2 is not set - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_M41T93 is not set -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_DS3234 is not set -# CONFIG_RTC_DRV_PCF2123 is not set - -# -# Platform RTC drivers -# -CONFIG_RTC_DRV_CMOS=y -CONFIG_RTC_DRV_DS1286=y -CONFIG_RTC_DRV_DS1511=y -CONFIG_RTC_DRV_DS1553=y -CONFIG_RTC_DRV_DS1742=y -CONFIG_RTC_DRV_STK17TA8=y -CONFIG_RTC_DRV_M48T86=y -CONFIG_RTC_DRV_M48T35=y -CONFIG_RTC_DRV_M48T59=y -CONFIG_RTC_DRV_MSM6242=y -CONFIG_RTC_DRV_BQ4802=y -CONFIG_RTC_DRV_RP5C01=y -CONFIG_RTC_DRV_V3020=y - -# -# on-CPU RTC drivers -# -# CONFIG_DMADEVICES is not set -# CONFIG_AUXDISPLAY is not set -CONFIG_UIO=y -# CONFIG_UIO_CIF is not set -# CONFIG_UIO_PDRV is not set -# CONFIG_UIO_PDRV_GENIRQ is not set -# CONFIG_UIO_AEC is not set -# CONFIG_UIO_SERCOS3 is not set -# CONFIG_UIO_PCI_GENERIC is not set -# CONFIG_UIO_NETX is not set - -# -# Virtio drivers -# -# CONFIG_VIRTIO_PCI is not set -# CONFIG_VIRTIO_BALLOON is not set -# CONFIG_VIRTIO_MMIO is not set - -# -# Xen driver support -# -CONFIG_XEN_BALLOON=y -# CONFIG_XEN_BALLOON_MEMORY_HOTPLUG is not set -CONFIG_XEN_SCRUB_PAGES=y -CONFIG_XEN_DEV_EVTCHN=y -CONFIG_XEN_BACKEND=y -CONFIG_XENFS=y -CONFIG_XEN_COMPAT_XENFS=y -CONFIG_XEN_SYS_HYPERVISOR=y -CONFIG_XEN_GNTDEV=y -CONFIG_XEN_GRANT_DEV_ALLOC=y -CONFIG_SWIOTLB_XEN=y -CONFIG_XEN_PCIDEV_BACKEND=m -# CONFIG_STAGING is not set -CONFIG_X86_PLATFORM_DEVICES=y -# CONFIG_ACERHDF is not set -# CONFIG_ASUS_LAPTOP is not set -# CONFIG_HP_ACCEL is not set -# CONFIG_THINKPAD_ACPI is not set -# CONFIG_SENSORS_HDAPS is not set -# CONFIG_INTEL_MENLOW is not set -# CONFIG_EEEPC_LAPTOP is not set -# CONFIG_ACPI_WMI is not set -# CONFIG_ACPI_ASUS is not set -# CONFIG_TOPSTAR_LAPTOP is not set -# CONFIG_TOSHIBA_BT_RFKILL is not set -# CONFIG_ACPI_CMPC is not set -# CONFIG_INTEL_IPS is not set -# CONFIG_IBM_RTL is not set -# CONFIG_XO15_EBOOK is not set -# CONFIG_SAMSUNG_Q10 is not set -CONFIG_X86_64_DELL_S6000_S1220_R0=y - -# -# Hardware Spinlock drivers -# -CONFIG_CLKEVT_I8253=y -CONFIG_I8253_LOCK=y -CONFIG_CLKBLD_I8253=y -CONFIG_IOMMU_SUPPORT=y -# CONFIG_AMD_IOMMU is not set -# CONFIG_INTEL_IOMMU is not set -# CONFIG_IRQ_REMAP is not set -# CONFIG_VIRT_DRIVERS is not set - -# -# Microsoft Hyper-V guest support -# -# CONFIG_HYPERV is not set -# CONFIG_PM_DEVFREQ is not set - -# -# Frame Manager support -# -# CONFIG_FSL_FMAN is not set - -# -# Firmware Drivers -# -CONFIG_EDD=y -# CONFIG_EDD_OFF is not set -CONFIG_FIRMWARE_MEMMAP=y -CONFIG_DELL_RBU=y -CONFIG_DCDBAS=y -CONFIG_DMIID=y -CONFIG_DMI_SYSFS=y -CONFIG_ISCSI_IBFT_FIND=y -CONFIG_ISCSI_IBFT=y -# CONFIG_SIGMA is not set -# CONFIG_GOOGLE_FIRMWARE is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_DEFAULTS_TO_ORDERED=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_XATTR=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -# CONFIG_EXT4_DEBUG is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_JBD2=y -# CONFIG_JBD2_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set -# CONFIG_NILFS2_FS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_EXPORTFS=y -CONFIG_FILE_LOCKING=y -CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y -CONFIG_INOTIFY_USER=y -CONFIG_INOTIFY_STACKFS=y -CONFIG_FANOTIFY=y -# CONFIG_QUOTA is not set -# CONFIG_QUOTACTL is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set -CONFIG_OVERLAYFS_FS=y -CONFIG_GENERIC_ACL=y - -# -# Caches -# -CONFIG_FSCACHE=y -CONFIG_FSCACHE_STATS=y -# CONFIG_FSCACHE_HISTOGRAM is not set -# CONFIG_FSCACHE_DEBUG is not set -# CONFIG_FSCACHE_OBJECT_LIST is not set -CONFIG_CACHEFILES=y -# CONFIG_CACHEFILES_DEBUG is not set -# CONFIG_CACHEFILES_HISTOGRAM is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=y -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_VMCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_TMPFS_XATTR=y -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y -CONFIG_CONFIGFS_FS=y -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_LOGFS is not set -# CONFIG_CRAMFS is not set -CONFIG_SQUASHFS=y -CONFIG_SQUASHFS_XATTR=y -CONFIG_SQUASHFS_ZLIB=y -CONFIG_SQUASHFS_LZO=y -CONFIG_SQUASHFS_XZ=y -# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_PSTORE is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -# CONFIG_EXOFS_FS is not set -# CONFIG_AUFS_FS is not set -CONFIG_ORE=m -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=y -CONFIG_NFS_V4_1=y -CONFIG_PNFS_FILE_LAYOUT=y -CONFIG_PNFS_BLOCK=m -CONFIG_PNFS_OBJLAYOUT=m -# CONFIG_NFS_FSCACHE is not set -# CONFIG_NFS_USE_LEGACY_DNS is not set -CONFIG_NFS_USE_KERNEL_DNS=y -# CONFIG_NFS_USE_NEW_IDMAPPER is not set -CONFIG_NFSD=y -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3=y -CONFIG_NFSD_V3_ACL=y -CONFIG_NFSD_V4=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -CONFIG_SUNRPC_BACKCHANNEL=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_CEPH_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -CONFIG_ACORN_PARTITION=y -CONFIG_ACORN_PARTITION_CUMANA=y -CONFIG_ACORN_PARTITION_EESOX=y -CONFIG_ACORN_PARTITION_ICS=y -CONFIG_ACORN_PARTITION_ADFS=y -CONFIG_ACORN_PARTITION_POWERTEC=y -CONFIG_ACORN_PARTITION_RISCIX=y -CONFIG_OSF_PARTITION=y -CONFIG_AMIGA_PARTITION=y -CONFIG_ATARI_PARTITION=y -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -CONFIG_MINIX_SUBPARTITION=y -CONFIG_SOLARIS_X86_PARTITION=y -CONFIG_UNIXWARE_DISKLABEL=y -CONFIG_LDM_PARTITION=y -# CONFIG_LDM_DEBUG is not set -CONFIG_SGI_PARTITION=y -CONFIG_ULTRIX_PARTITION=y -CONFIG_SUN_PARTITION=y -CONFIG_KARMA_PARTITION=y -CONFIG_EFI_PARTITION=y -# CONFIG_SYSV68_PARTITION is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="utf8" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=y -# CONFIG_DLM is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=2048 -CONFIG_MAGIC_SYSRQ=y -CONFIG_MAGIC_SYSRQ_DEFAULT_MASK=0x01b6 -CONFIG_STRIP_ASM_SYMS=y -CONFIG_UNUSED_SYMBOLS=y -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_SECTION_MISMATCH is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_LOCKUP_DETECTOR=y -CONFIG_HARDLOCKUP_DETECTOR=y -# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_DETECT_HUNG_TASK=y -CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -CONFIG_PANIC_TIMEOUT=0 -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -CONFIG_TIMER_STATS=y -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_SPARSE_RCU_POINTER is not set -# CONFIG_LOCK_STAT is not set -# CONFIG_DEBUG_ATOMIC_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -CONFIG_STACKTRACE=y -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_INFO_REDUCED is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_VIRTUAL is not set -# CONFIG_DEBUG_WRITECOUNT is not set -CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_DEBUG_LIST is not set -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_CREDENTIALS is not set -CONFIG_ARCH_WANT_FRAME_POINTERS=y -# CONFIG_FRAME_POINTER is not set -CONFIG_BOOT_PRINTK_DELAY=y -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_RCU_CPU_STALL_TIMEOUT=60 -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -# CONFIG_DEBUG_PER_CPU_MAPS is not set -# CONFIG_LKDTM is not set -# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y -# CONFIG_DEBUG_PAGEALLOC is not set -CONFIG_USER_STACKTRACE_SUPPORT=y -CONFIG_NOP_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y -CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_EVENT_POWER_TRACING_DEPRECATED=y -CONFIG_CONTEXT_SWITCH_TRACER=y -CONFIG_TRACING=y -CONFIG_GENERIC_TRACER=y -CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_FTRACE_SYSCALLS is not set -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_STACK_TRACER is not set -CONFIG_BLK_DEV_IO_TRACE=y -# CONFIG_FTRACE_STARTUP_TEST is not set -# CONFIG_MMIOTRACE is not set -# CONFIG_RING_BUFFER_BENCHMARK is not set -# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set -# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set -# CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_DMA_API_DEBUG is not set -# CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -CONFIG_HAVE_ARCH_KMEMCHECK=y -# CONFIG_TEST_KSTRTOX is not set -CONFIG_STRICT_DEVMEM=y -CONFIG_X86_VERBOSE_BOOTUP=y -CONFIG_EARLY_PRINTK=y -# CONFIG_EARLY_PRINTK_DBGP is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_X86_PTDUMP is not set -CONFIG_DEBUG_RODATA=y -# CONFIG_DEBUG_RODATA_TEST is not set -# CONFIG_DEBUG_SET_MODULE_RONX is not set -# CONFIG_DEBUG_NX_TEST is not set -# CONFIG_IOMMU_DEBUG is not set -# CONFIG_IOMMU_STRESS is not set -CONFIG_HAVE_MMIOTRACE_SUPPORT=y -CONFIG_IO_DELAY_TYPE_0X80=0 -CONFIG_IO_DELAY_TYPE_0XED=1 -CONFIG_IO_DELAY_TYPE_UDELAY=2 -CONFIG_IO_DELAY_TYPE_NONE=3 -CONFIG_IO_DELAY_0X80=y -# CONFIG_IO_DELAY_0XED is not set -# CONFIG_IO_DELAY_UDELAY is not set -# CONFIG_IO_DELAY_NONE is not set -CONFIG_DEFAULT_IO_DELAY_TYPE=0 -# CONFIG_DEBUG_BOOT_PARAMS is not set -# CONFIG_CPA_DEBUG is not set -CONFIG_OPTIMIZE_INLINING=y -# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set - -# -# Security options -# -CONFIG_KEYS=y -# CONFIG_ENCRYPTED_KEYS is not set -# CONFIG_KEYS_DEBUG_PROC_KEYS is not set -# CONFIG_SECURITY_DMESG_RESTRICT is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DEFAULT_SECURITY="" -CONFIG_XOR_BLOCKS=m -CONFIG_ASYNC_CORE=m -CONFIG_ASYNC_XOR=m -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_FIPS=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_PCOMP=y -CONFIG_CRYPTO_PCOMP2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -# CONFIG_CRYPTO_USER is not set -# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set -CONFIG_CRYPTO_GF128MUL=y -CONFIG_CRYPTO_NULL=y -# CONFIG_CRYPTO_PCRYPT is not set -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_AUTHENC=y -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -CONFIG_CRYPTO_CCM=y -CONFIG_CRYPTO_GCM=y -CONFIG_CRYPTO_SEQIV=y - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_CTR=y -CONFIG_CRYPTO_CTS=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_LRW=y -CONFIG_CRYPTO_PCBC=y -CONFIG_CRYPTO_XTS=y - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_VMAC=y - -# -# Digest -# -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CRC32C_INTEL=y -CONFIG_CRYPTO_GHASH=y -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_MICHAEL_MIC=y -CONFIG_CRYPTO_RMD128=y -CONFIG_CRYPTO_RMD160=y -CONFIG_CRYPTO_RMD256=y -CONFIG_CRYPTO_RMD320=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA1_SSSE3=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_TGR192=y -CONFIG_CRYPTO_WP512=y -CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=y - -# -# Ciphers -# -CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_X86_64=y -CONFIG_CRYPTO_AES_NI_INTEL=y -CONFIG_CRYPTO_ANUBIS=y -CONFIG_CRYPTO_ARC4=y -CONFIG_CRYPTO_BLOWFISH=y -CONFIG_CRYPTO_BLOWFISH_COMMON=y -CONFIG_CRYPTO_BLOWFISH_X86_64=y -CONFIG_CRYPTO_CAMELLIA=y -CONFIG_CRYPTO_CAST5=y -CONFIG_CRYPTO_CAST6=y -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=y -CONFIG_CRYPTO_KHAZAD=y -CONFIG_CRYPTO_SALSA20=y -CONFIG_CRYPTO_SALSA20_X86_64=y -CONFIG_CRYPTO_SEED=y -CONFIG_CRYPTO_SERPENT=y -CONFIG_CRYPTO_TEA=y -CONFIG_CRYPTO_TWOFISH=y -CONFIG_CRYPTO_TWOFISH_COMMON=y -CONFIG_CRYPTO_TWOFISH_X86_64=y -CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=y - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_ZLIB=y -CONFIG_CRYPTO_LZO=y - -# -# Random Number Generation -# -CONFIG_CRYPTO_ANSI_CPRNG=y -CONFIG_CRYPTO_USER_API=y -CONFIG_CRYPTO_USER_API_HASH=y -CONFIG_CRYPTO_USER_API_SKCIPHER=y -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_DEV_PADLOCK=y -CONFIG_CRYPTO_DEV_PADLOCK_AES=y -CONFIG_CRYPTO_DEV_PADLOCK_SHA=y -CONFIG_HAVE_KVM=y -# CONFIG_VIRTUALIZATION is not set -CONFIG_BINARY_PRINTF=y - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_FIRST_BIT=y -CONFIG_CRC_CCITT=y -CONFIG_CRC16=y -CONFIG_CRC_T10DIF=y -CONFIG_CRC_ITU_T=y -CONFIG_CRC32=y -CONFIG_CRC7=y -CONFIG_LIBCRC32C=y -CONFIG_CRC8=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_XZ_DEC=y -CONFIG_XZ_DEC_X86=y -CONFIG_XZ_DEC_POWERPC=y -CONFIG_XZ_DEC_IA64=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_ARMTHUMB=y -CONFIG_XZ_DEC_SPARC=y -CONFIG_XZ_DEC_BCJ=y -# CONFIG_XZ_DEC_TEST is not set -CONFIG_DECOMPRESS_GZIP=y -CONFIG_DECOMPRESS_BZIP2=y -CONFIG_DECOMPRESS_LZMA=y -CONFIG_DECOMPRESS_XZ=y -CONFIG_DECOMPRESS_LZO=y -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=y -CONFIG_TEXTSEARCH_BM=y -CONFIG_TEXTSEARCH_FSM=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_CHECK_SIGNATURE=y -CONFIG_CPU_RMAP=y -CONFIG_DQL=y -CONFIG_NLATTR=y -CONFIG_AVERAGE=y -CONFIG_CORDIC=y diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/kconfig.mk b/packages/base/any/kernels/3.2.65-1+deb7u2/kconfig.mk deleted file mode 100644 index 164623a9..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/kconfig.mk +++ /dev/null @@ -1,31 +0,0 @@ -############################################################ -# -# -# Copyright 2015 Big Switch Networks, Inc. -# -# Licensed under the Eclipse Public License, Version 1.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.eclipse.org/legal/epl-v10.html -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -# either express or implied. See the License for the specific -# language governing permissions and limitations under the -# License. -# -# -############################################################ -# -# 3.2.65-1+deb7u2 Kernel Builds -# -############################################################ -THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) -K_MAJOR_VERSION := 3 -K_PATCH_LEVEL := 2 -K_SUB_LEVEL := 65 -K_SUFFIX := -1+deb7u2 -K_PATCH_DIR := $(THIS_DIR)/patches -K_ARCHIVE_URL := http://opennetlinux.org/tarballs/linux-3.2.65-1+deb7u2.tar.xz diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/CVE-2016-5195.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/CVE-2016-5195.patch deleted file mode 100644 index 199eb2ce..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/CVE-2016-5195.patch +++ /dev/null @@ -1,75 +0,0 @@ -diff -urpN a/include/linux/mm.h b/include/linux/mm.h ---- a/include/linux/mm.h 2016-11-02 14:46:33.278862661 -0700 -+++ b/include/linux/mm.h 2016-11-02 14:47:01.338863270 -0700 -@@ -1526,6 +1526,7 @@ struct page *follow_page(struct vm_area_ - #define FOLL_MLOCK 0x40 /* mark page as mlocked */ - #define FOLL_SPLIT 0x80 /* don't return transhuge pages, split them */ - #define FOLL_HWPOISON 0x100 /* check page is hwpoisoned */ -+#define FOLL_COW 0x4000 /* internal GUP flag */ - - typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, - void *data); -diff -urpN a/mm/memory.c b/mm/memory.c ---- a/mm/memory.c 2016-11-02 14:46:33.938862676 -0700 -+++ b/mm/memory.c 2016-11-02 14:50:52.086868277 -0700 -@@ -1427,6 +1427,23 @@ int zap_vma_ptes(struct vm_area_struct * - } - EXPORT_SYMBOL_GPL(zap_vma_ptes); - -+static inline bool can_follow_write_pte(pte_t pte, struct page *page, -+ unsigned int flags) -+{ -+ if (pte_write(pte)) -+ return true; -+ -+ /* -+ * Make sure that we are really following CoWed page. We do not really -+ * have to care about exclusiveness of the page because we only want -+ * to ensure that once COWed page hasn't disappeared in the meantime -+ * or it hasn't been merged to a KSM page. -+ */ -+ if ((flags & FOLL_FORCE) && (flags & FOLL_COW)) -+ return page && PageAnon(page) && !PageKsm(page); -+ -+ return false; -+} - /** - * follow_page - look up a page descriptor from a user-virtual address - * @vma: vm_area_struct mapping @address -@@ -1509,10 +1526,12 @@ split_fallthrough: - pte = *ptep; - if (!pte_present(pte)) - goto no_page; -- if ((flags & FOLL_WRITE) && !pte_write(pte)) -- goto unlock; - - page = vm_normal_page(vma, address, pte); -+ if ((flags & FOLL_WRITE) && !can_follow_write_pte(pte, page, flags)) { -+ pte_unmap_unlock(ptep, ptl); -+ return NULL; -+ } - if (unlikely(!page)) { - if ((flags & FOLL_DUMP) || - !is_zero_pfn(pte_pfn(pte))) -@@ -1789,17 +1808,13 @@ int __get_user_pages(struct task_struct - * The VM_FAULT_WRITE bit tells us that - * do_wp_page has broken COW when necessary, - * even if maybe_mkwrite decided not to set -- * pte_write. We can thus safely do subsequent -- * page lookups as if they were reads. But only -- * do so when looping for pte_write is futile: -- * in some cases userspace may also be wanting -- * to write to the gotten user page, which a -- * read fault here might prevent (a readonly -- * page might get reCOWed by userspace write). -+ * pte_write. We cannot simply drop FOLL_WRITE -+ * here because the COWed page might be gone by -+ * the time we do the subsequent page lookups. - */ - if ((ret & VM_FAULT_WRITE) && - !(vma->vm_flags & VM_WRITE)) -- foll_flags &= ~FOLL_WRITE; -+ foll_flags |= FOLL_COW; - - cond_resched(); - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/README b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/README deleted file mode 100644 index e9fd4c70..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/README +++ /dev/null @@ -1,17 +0,0 @@ -############################################################ -# -# Debian 3.2 Kernel Patches -# -############################################################ -# -# The majority of these patches were imported from -# the Cumulus OSS Repository, version 2.5.1, for the Debian 3.2 kernel -# distributed with Wheezy. -# -# http://oss.cumulusnetworks.com/CumulusLinux-2.5.1 -# -# See the kernel patch directory: -# -# http://oss.cumulusnetworks.com/CumulusLinux-2.5.1/patches/kernel -# -############################################################ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/README.cumulus b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/README.cumulus deleted file mode 100644 index f759061a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/README.cumulus +++ /dev/null @@ -1,36 +0,0 @@ -Kernel stgit notes -================== - -See also: https://wiki.cumulusnetworks.com/display/DE/Linux+Kernel+stgit+patches - -The Linux kernel stg patches are broken up into categories. The patch -name is prefixed with the category. - -When creating a new patch please put it into an existing category. If -you really need a new category open a discussion. - -Categories: - -Prefix Meaning -=============+=========== -git- Specific to git, e.g. the standard gitignore.patch. -arch-powerpc- PowerPC CPU patches. Not tied to a specific platform. -arch-intel- Intel CPU patches. Not tied to a specific platform. -kernel- Kernel features, like file systems, back ported items. -driver- Device drivers. Not tied to a specific platform. -platform- Switching hardware platforms, like DNI-7448. -network- Networking, routing, bridging, tun, ipv4, ipv6, etc. - - -platform- Category Specific Notes -================================= - -Within this category the platforms are stored alphabetically. - -One patch, platform-powerpc-85xx-Makefile.patch, is used by all the -powerpc platforms. This patch contains changes to -arch/powerpc/platforms/85xx/Makefile and -arch/powerpc/platforms/85xx/Kconfig. - -By keeping these changes in a separate patch allows the platform -specific patchsets to sink/float without conflicts in these two files. diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-centerton-pci-id.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-centerton-pci-id.patch deleted file mode 100644 index daf6556c..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-centerton-pci-id.patch +++ /dev/null @@ -1,20 +0,0 @@ -arch-intel-centerton-pci-id.patch - -Add the PCI device ID for the Intel Centerton Integrated Legacy Block -(ILB). - -This device ID is used by a number of drivers, including GPIO and -Multifunction Devices. - -diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h -index d93f417..d35b1f4 100644 ---- a/include/linux/pci_ids.h -+++ b/include/linux/pci_ids.h -@@ -2484,6 +2484,7 @@ - #define PCI_DEVICE_ID_INTEL_MRST_SD2 0x084F - #define PCI_DEVICE_ID_INTEL_I960 0x0960 - #define PCI_DEVICE_ID_INTEL_I960RM 0x0962 -+#define PCI_DEVICE_ID_INTEL_CENTERTON_ILB 0x0c60 - #define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062 - #define PCI_DEVICE_ID_INTEL_82573E_SOL 0x1085 - #define PCI_DEVICE_ID_INTEL_82573L_SOL 0x108F diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-centerton-reboot-cf9.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-centerton-reboot-cf9.patch deleted file mode 100644 index 7b9bca62..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-centerton-reboot-cf9.patch +++ /dev/null @@ -1,91 +0,0 @@ -Patch to reboot x86_64 machines using boot code CF9 - -diff --git a/arch/x86/include/asm/emergency-restart.h b/arch/x86/include/asm/emergency-restart.h -index cc70c1c..441a910 100644 ---- a/arch/x86/include/asm/emergency-restart.h -+++ b/arch/x86/include/asm/emergency-restart.h -@@ -11,6 +11,7 @@ enum reboot_type { - BOOT_EFI = 'e', - BOOT_CF9 = 'p', - BOOT_CF9_COND = 'q', -+ BOOT_CF9_COLD = 'd', - }; - - extern enum reboot_type reboot_type; -diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c -index f411aca..a10547c 100644 ---- a/arch/x86/kernel/reboot.c -+++ b/arch/x86/kernel/reboot.c -@@ -93,6 +93,7 @@ static int __init reboot_setup(char *str) - case 'b': - #endif - case 'a': -+ case 'd': - case 'k': - case 't': - case 'e': -@@ -395,6 +396,16 @@ static int __init set_pci_reboot(const struct dmi_system_id *d) - return 0; - } - -+static int __init set_cold_cf9_reboot(const struct dmi_system_id *d) -+{ -+ if (reboot_type != BOOT_CF9_COLD) { -+ reboot_type = BOOT_CF9_COLD; -+ printk(KERN_INFO "%s series board detected. " -+ "Selecting CF9 Cold Reset method for reboots.\n", d->ident); -+ } -+ return 0; -+} -+ - static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { - { /* Handle problems with rebooting on Apple MacBook5 */ - .callback = set_pci_reboot, -@@ -468,6 +479,23 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"), - }, - }, -+ { /* Perform cold reset on Dell S6000 */ -+ .callback = set_cold_cf9_reboot, -+ .ident = "Dell S6000", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "S6000"), -+ }, -+ }, -+ { /* Dell S6000 could have either manufacturer names: Dell Inc or -+ Dell Force10 Networks. Accomodating for both */ -+ .callback = set_cold_cf9_reboot, -+ .ident = "Dell S6000", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Force10 Networks"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "S6000"), -+ }, -+ }, - { /* Handle problems with rebooting on the Dell PowerEdge C6100. */ - .callback = set_pci_reboot, - .ident = "Dell PowerEdge C6100", -@@ -569,6 +597,7 @@ static void native_machine_emergency_restart(void) - int i; - int attempt = 0; - int orig_reboot_type = reboot_type; -+ u8 cf9_cold = 0; - - if (reboot_emergency) - emergency_vmx_disable_all(); -@@ -641,6 +670,15 @@ static void native_machine_emergency_restart(void) - } - reboot_type = BOOT_KBD; - break; -+ -+ case BOOT_CF9_COLD: -+ cf9_cold = inb(0xcf9) & ~6; -+ outb(cf9_cold|8, 0xcf9); /* Request cold reset */ -+ udelay(50); -+ outb(cf9_cold|12, 0xcf9); /* Actually do the reset */ -+ udelay(50); -+ reboot_type = BOOT_KBD; -+ break; - } - } - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-os-driven-pci-maxpayload-readreq-setup.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-os-driven-pci-maxpayload-readreq-setup.patch deleted file mode 100644 index f1bc2e0d..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-os-driven-pci-maxpayload-readreq-setup.patch +++ /dev/null @@ -1,121 +0,0 @@ -#Copyright 2014 Cumulus Networks, Inc. All rights reserved. -Have the OS set up all PCI device maxpayload and maxreadrequest on the PCIe bus -Notes: -1. This is similar to the payload size fixup done for powerpc. -Ref: arch-powerpc-os-driven-pci-maxpayload-readreq-setup.patch -2. pci=pcie_bus_safe is supposed to fix up the entire tree below a root complex -with the smallest common denominator MPS. However it is only setting the -devices associated with the children (child buses) of the root. And that leaves -some of the devices on the root with a different (and in some cases lower MPS -based on the bios setting). -2. This patch works by walking the bus underneath each PCIe controller, -querying PCI_EXP_DEVCAP_PAYLOAD, and finding the minimum value underneath each -controller. Then it walks though the same set of devices setting -PCI_EXP_DEVCTL_PAYLOAD and PCI_EXP_DEVCTL_READRQ to this value. The payloads -are powers of 2 starting at 128... - -0 -> 128 -1 -> 256 -... -7 -> 16,384:1 - -diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c -index 0ed97d8..f1a970f 100644 ---- a/arch/x86/pci/acpi.c -+++ b/arch/x86/pci/acpi.c -@@ -329,6 +329,66 @@ res_alloc_fail: - return; - } - -+/* -+ * scan and set the PCIe bus payload and read request sizes. -+ */ -+static int __devinit __fixup_pcie_scan_payload(struct pci_dev *pdev, -+ void *data) -+{ -+ int *payload_size = data; -+ int rval, cap, payload_cap; -+ uint32_t devcap; -+ -+ if (!pci_is_pcie(pdev)) -+ return 0; -+ -+ cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); -+ if (cap == 0) -+ return -ENODEV; -+ -+ rval = pci_read_config_dword(pdev, cap + PCI_EXP_DEVCAP, &devcap); -+ if (rval) -+ return rval; -+ -+ payload_cap = devcap & PCI_EXP_DEVCAP_PAYLOAD; -+ if (payload_cap < *payload_size) -+ *payload_size = payload_cap; -+ -+ return 0; -+} -+ -+static int __devinit __fixup_pcie_set_payload(struct pci_dev *pdev, -+ void *data) -+{ -+ int *payload_size = data; -+ int rval, cap; -+ uint16_t devctl; -+ -+ if (!pci_is_pcie(pdev)) -+ return 0; -+ -+ cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); -+ if (cap == 0) -+ return -ENODEV; -+ -+ rval = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &devctl); -+ if (rval) -+ return rval; -+ -+ devctl &= ~PCI_EXP_DEVCTL_PAYLOAD; -+ devctl |= *payload_size << 5; -+ -+ devctl &= ~PCI_EXP_DEVCTL_READRQ; -+ devctl |= *payload_size << 12; -+ -+ rval = pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, devctl); -+ if (rval) -+ return rval; -+ -+ return 0; -+} -+ -+ - struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) - { - struct acpi_device *device = root->device; -@@ -395,6 +455,28 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) - } - } - -+/* Set the payload size for all devices on the bus */ -+ if (bus) { -+ int payload_size; -+ payload_size = PCI_EXP_DEVCAP_PAYLOAD; -+ pci_walk_bus(bus, __fixup_pcie_scan_payload, &payload_size); -+ if (payload_size < PCI_EXP_DEVCAP_PAYLOAD) { -+ pci_walk_bus(bus, __fixup_pcie_set_payload, -+ &payload_size); -+ dev_info(&bus->dev, -+ "Set PCIe payload and read request to %d\n", -+ (payload_size == 0) ? 128 : -+ (payload_size == 1) ? 256 : -+ (payload_size == 2) ? 512 : -+ (payload_size == 3) ? 1024 : -+ (payload_size == 4) ? 2048 : -+ (payload_size == 5) ? 4096 : -+ (payload_size == 6) ? 8192 : -+ 16384 -+ ); -+ } -+ } -+ - /* After the PCI-E bus has been walked and all devices discovered, - * configure any settings of the fabric that might be necessary. - */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-reboot-cf9-cold.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-reboot-cf9-cold.patch deleted file mode 100644 index 8794ad73..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-intel-reboot-cf9-cold.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/arch/x86/kernel/reboot.c 2016-06-01 13:19:53.102025910 -0700 -+++ b/arch/x86/kernel/reboot.c 2016-06-01 13:21:04.250027454 -0700 -@@ -672,13 +672,13 @@ static void native_machine_emergency_res - break; - - case BOOT_CF9_COLD: -- cf9_cold = inb(0xcf9) & ~6; -- outb(cf9_cold|8, 0xcf9); /* Request cold reset */ -- udelay(50); -- outb(cf9_cold|12, 0xcf9); /* Actually do the reset */ -- udelay(50); -- reboot_type = BOOT_KBD; -- break; -+ cf9_cold = inb(0xcf9) & ~0xE; -+ outb(cf9_cold|2, 0xcf9); /* Request cold reset */ -+ udelay(50); -+ outb(cf9_cold|0xE, 0xcf9); /* Actually do the reset */ -+ udelay(50); -+ reboot_type = BOOT_KBD; -+ break; - } - } - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-nr-gpio.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-nr-gpio.patch deleted file mode 100644 index 50aaf232..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-nr-gpio.patch +++ /dev/null @@ -1,15 +0,0 @@ - - -diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h -index 91d915a..31ce3f7 100644 ---- a/arch/x86/include/asm/gpio.h -+++ b/arch/x86/include/asm/gpio.h -@@ -16,6 +16,8 @@ - #ifndef _ASM_X86_GPIO_H - #define _ASM_X86_GPIO_H - -+#define ARCH_NR_GPIOS 512 -+ - #include - - #ifdef CONFIG_GPIOLIB diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-cacheinfo.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-cacheinfo.patch deleted file mode 100644 index 61d04d92..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-cacheinfo.patch +++ /dev/null @@ -1,89 +0,0 @@ -Fix missing L2 cache in /sys/devices/system/cpu/cpu0/cache/index2/size -This appears to have been introduced in 2.6.29 by -93197a36a9c16a85fb24cf5a8639f7bf9af838a3. - -This caused lscpu to error out on e500v2 devices, and probably others - error: cannot open /sys/devices/system/cpu/cpu0/cache/index2/size: No such file or directory - -Some embedded powerpc sysystems use cache-size in DTS for the unified L2 cache -size, not d-cache-size, so we need to allow for both DTS names. Added a -second CACHE_TYPE_UNIFIED_D cache_type_info structure to handle this. - -This is a redo after trying to push the previous version upstream, and finding out -that the previous patch broke OpenFirmware PowerPC systems like the Mac. This also -now includes all descriptive entries in the index2 directory; the previous still had -some missing. - -diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c -index b4437e8..592b096 100644 ---- a/arch/powerpc/kernel/cacheinfo.c -+++ b/arch/powerpc/kernel/cacheinfo.c -@@ -62,12 +62,22 @@ struct cache_type_info { - }; - - /* These are used to index the cache_type_info array. */ --#define CACHE_TYPE_UNIFIED 0 --#define CACHE_TYPE_INSTRUCTION 1 --#define CACHE_TYPE_DATA 2 -+#define CACHE_TYPE_UNIFIED 0 /* cache-size, cache-block-size, etc. */ -+#define CACHE_TYPE_UNIFIED_D 1 /* d-cache-size, d-cache-block-size, etc */ -+#define CACHE_TYPE_INSTRUCTION 2 -+#define CACHE_TYPE_DATA 3 - - static const struct cache_type_info cache_type_info[] = { - { -+ /* Embedded systems that use cache-size, cache-block-size, -+ * etc. for the Unified (typically L2) cache. */ -+ .name = "Unified", -+ .size_prop = "cache-size", -+ .line_size_props = { "cache-line-size", -+ "cache-block-size", }, -+ .nr_sets_prop = "cache-sets", -+ }, -+ { - /* PowerPC Processor binding says the [di]-cache-* - * must be equal on unified caches, so just use - * d-cache properties. */ -@@ -293,7 +303,8 @@ static struct cache *cache_find_first_sibling(struct cache *cache) - { - struct cache *iter; - -- if (cache->type == CACHE_TYPE_UNIFIED) -+ if (cache->type == CACHE_TYPE_UNIFIED || -+ cache->type == CACHE_TYPE_UNIFIED_D) - return cache; - - list_for_each_entry(iter, &cache_list, list) -@@ -324,13 +335,31 @@ static bool cache_node_is_unified(const struct device_node *np) - return of_get_property(np, "cache-unified", NULL); - } - -+/* -+ * Handle unified caches that have two different types of tags. Most embedded -+ * use cache-size, etc. for the unified cache size, but open firmware systems -+ * use d-cache-size, etc. Since they all appear to be consistent, check on -+ * initialization for which type we are, and use the appropriate structure. -+ */ - static struct cache *__cpuinit cache_do_one_devnode_unified(struct device_node *node, int level) - { - struct cache *cache; -+ int ucache; - - pr_debug("creating L%d ucache for %s\n", level, node->full_name); - -- cache = new_cache(CACHE_TYPE_UNIFIED, level, node); -+ if (of_get_property(node, -+ cache_type_info[CACHE_TYPE_UNIFIED_D].size_prop, NULL)) { -+ ucache = CACHE_TYPE_UNIFIED_D; -+ } else { -+ ucache = CACHE_TYPE_UNIFIED; /* assume embedded */ -+ if (of_get_property(node, -+ cache_type_info[CACHE_TYPE_UNIFIED].size_prop, NULL) == -+ NULL) -+ printk(KERN_WARNING "Unified cache property missing\n"); -+ } -+ -+ cache = new_cache(ucache, level, node); - - return cache; - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-emulated-lwsync.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-emulated-lwsync.patch deleted file mode 100644 index 4cd3a1b6..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-emulated-lwsync.patch +++ /dev/null @@ -1,45 +0,0 @@ -#Copyright 2012 Cumulus Networks, Inc. All rights reserved. - -Emulate the 603 lwsync instruction - -Issue a memory barrier (mbar) instead of lwsync on e500 processors. This, along with SW emuluation of the FPU allow us to run PPC603 code from the Debian repositories directly on the e500 cores. - -diff --git a/arch/powerpc/include/asm/emulated_ops.h b/arch/powerpc/include/asm/emulated_ops.h -index 63f2a22..093359a 100644 ---- a/arch/powerpc/include/asm/emulated_ops.h -+++ b/arch/powerpc/include/asm/emulated_ops.h -@@ -44,6 +44,7 @@ extern struct ppc_emulated { - struct ppc_emulated_entry spe; - struct ppc_emulated_entry string; - struct ppc_emulated_entry unaligned; -+ struct ppc_emulated_entry lwsync; - #ifdef CONFIG_MATH_EMULATION - struct ppc_emulated_entry math; - #elif defined(CONFIG_8XX_MINIMAL_FPEMU) -diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c -index 9844662..a689b66 100644 ---- a/arch/powerpc/kernel/traps.c -+++ b/arch/powerpc/kernel/traps.c -@@ -928,6 +928,14 @@ static int emulate_instruction(struct pt_regs *regs) - return emulate_isel(regs, instword); - } - -+ /* Emulate lwsync (Lightweight Sync) instruction */ -+ if (instword == PPC_INST_LWSYNC) { -+ PPC_WARN_EMULATED(lwsync, regs); -+ /* This is probably more pessimistic than required */ -+ mb(); -+ return 0; -+ } -+ - #ifdef CONFIG_PPC64 - /* Emulate the mfspr rD, DSCR. */ - if (((instword & PPC_INST_MFSPR_DSCR_MASK) == PPC_INST_MFSPR_DSCR) && -@@ -1542,6 +1550,7 @@ struct ppc_emulated ppc_emulated = { - WARN_EMULATED_SETUP(spe), - WARN_EMULATED_SETUP(string), - WARN_EMULATED_SETUP(unaligned), -+ WARN_EMULATED_SETUP(lwsync), - #ifdef CONFIG_MATH_EMULATION - WARN_EMULATED_SETUP(math), - #elif defined(CONFIG_8XX_MINIMAL_FPEMU) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-jtag.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-jtag.patch deleted file mode 100644 index 64503dd7..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-jtag.patch +++ /dev/null @@ -1,59 +0,0 @@ -#Copyright 2012 Cumulus Networks, Inc. All rights reserved. - -Tweak the kernel to support a JTAG hardware debugger - -- disable the software watchdog -- enable Debug Interrupt in the PPC Machine State Register - -diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug -index 1b8a9c9..aba8704 100644 ---- a/arch/powerpc/Kconfig.debug -+++ b/arch/powerpc/Kconfig.debug -@@ -132,6 +132,15 @@ config BDI_SWITCH - Unless you are intending to debug the kernel with one of these - machines, say N here. - -+config JTAG_DEBUGGER -+ bool "Kernel modifications for JTAG debuggers" -+ depends on DEBUG_KERNEL && PPC32 -+ help -+ Modify kernel to allow JTAG debuggers to work. So far, this includes -+ setting the "DE" bit in booke ppc MSR_KERNEL and set the kernel's -+ softlockup threshold to be negative, effectively disabling software based -+ watchdogs. -+ - config BOOTX_TEXT - bool "Support for early boot text console (BootX or OpenFirmware only)" - depends on PPC_OF && PPC_BOOK3S -diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h -index 03c48e8..cd7b5af 100644 ---- a/arch/powerpc/include/asm/reg_booke.h -+++ b/arch/powerpc/include/asm/reg_booke.h -@@ -37,7 +37,11 @@ - #define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR|MSR_CE) - #define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE) - #else -+#if defined(CONFIG_JTAG_DEBUGGER) -+#define MSR_KERNEL (MSR_ME|MSR_RI|MSR_CE|MSR_DE) -+#else - #define MSR_KERNEL (MSR_ME|MSR_RI|MSR_CE) -+#endif - #define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE) - #endif - -diff --git a/kernel/watchdog.c b/kernel/watchdog.c -index a8bc4d9..08beea7 100644 ---- a/kernel/watchdog.c -+++ b/kernel/watchdog.c -@@ -28,7 +28,11 @@ - #include - - int watchdog_enabled = 1; -+#if defined(CONFIG_JTAG_DEBUGGER) -+int __read_mostly watchdog_thresh = -10; -+#else - int __read_mostly watchdog_thresh = 10; -+#endif - - static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts); - static DEFINE_PER_CPU(struct task_struct *, softlockup_watchdog); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-os-driven-pci-maxpayload-readreq-setup.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-os-driven-pci-maxpayload-readreq-setup.patch deleted file mode 100644 index c4597215..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-os-driven-pci-maxpayload-readreq-setup.patch +++ /dev/null @@ -1,126 +0,0 @@ -#Copyright 2012 Cumulus Networks, Inc. All rights reserved. - -Have the OS set up all PCI device maxpayload and maxreadrequest on the PCIe bus - -This version of the linux kernel doesn't do anything regarding the PCIe max -payload size or read request size, but rather rely on BIOS to take care of -things. Upcoming versions of the kernel patch core PCI code in cool and useful -ways, but there is a lot of flux, every version I've looked at has a different -take on this. - -Rather than patching PCI core code, I've chosen to patch this in an arch -dependent manner (powerpc only) that will not conflict with any work at the PCI -core (redundant, but no functional or merge conflicts). We can remove this -patch once the PCI core code settles down. - -The patch works by walking the bus underneath each PCIe controller, querying -PCI_EXP_DEVCAP_PAYLOAD, and finding the minimum value underneath each -controller. Then we walk though the same set of devices setting -PCI_EXP_DEVCTL_PAYLOAD and PCI_EXP_DEVCTL_READRQ to this value. The payloads -are powers of 2 starting at 128... - -0 -> 128 -1 -> 256 -... -7 -> 16,384 - -diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c -index 9508bec..abb9e95 100644 ---- a/arch/powerpc/kernel/pci-common.c -+++ b/arch/powerpc/kernel/pci-common.c -@@ -1697,6 +1697,62 @@ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) - return of_node_get(hose->dn); - } - -+/* -+ * scan and set the PCIe bus payload and read request sizes. -+ */ -+static int __devinit __fixup_pcie_scan_payload(struct pci_dev * pdev, -+ void * data) -+{ -+ int * payload_size = data; -+ int rval, cap, payload_cap; -+ uint32_t devcap; -+ -+ cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); -+ if (cap == 0) { -+ return -ENODEV; -+ } -+ -+ rval = pci_read_config_dword(pdev, cap + PCI_EXP_DEVCAP, &devcap); -+ if (rval) { -+ return rval; -+ } -+ payload_cap = devcap & PCI_EXP_DEVCAP_PAYLOAD; -+ if (payload_cap < *payload_size) { -+ *payload_size = payload_cap; -+ } -+ return 0; -+} -+ -+static int __devinit __fixup_pcie_set_payload(struct pci_dev * pdev, -+ void * data) -+{ -+ int * payload_size = data; -+ int rval, cap; -+ uint16_t devctl; -+ -+ cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); -+ if (cap == 0) { -+ return -ENODEV; -+ } -+ -+ rval = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &devctl); -+ if (rval) { -+ return rval; -+ } -+ -+ devctl &= ~PCI_EXP_DEVCTL_PAYLOAD; -+ devctl |= *payload_size << 5; -+ -+ devctl &= ~PCI_EXP_DEVCTL_READRQ; -+ devctl |= *payload_size << 12; -+ -+ rval = pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, devctl); -+ if (rval) { -+ return rval; -+ } -+ return 0; -+} -+ - /** - * pci_scan_phb - Given a pci_controller, setup and scan the PCI bus - * @hose: Pointer to the PCI host controller instance structure -@@ -1706,6 +1762,7 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose) - struct pci_bus *bus; - struct device_node *node = hose->dn; - int mode; -+ int payload_size; - - pr_debug("PCI: Scanning PHB %s\n", - node ? node->full_name : ""); -@@ -1739,6 +1796,24 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose) - if (mode == PCI_PROBE_NORMAL) - hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); - -+ /* Set the payload size for all devices on the bus */ -+ payload_size = PCI_EXP_DEVCAP_PAYLOAD; -+ pci_walk_bus(hose->bus, __fixup_pcie_scan_payload, &payload_size); -+ if (payload_size < PCI_EXP_DEVCAP_PAYLOAD) { -+ pci_walk_bus(hose->bus, __fixup_pcie_set_payload, &payload_size); -+ dev_info(&hose->bus->dev, -+ "Set PCIe payload and read request to %d\n", -+ (payload_size == 0) ? 128 : -+ (payload_size == 1) ? 256 : -+ (payload_size == 2) ? 512 : -+ (payload_size == 3) ? 1024 : -+ (payload_size == 4) ? 2048 : -+ (payload_size == 5) ? 4096 : -+ (payload_size == 6) ? 8192 : -+ 16384 -+ ); -+ } -+ - /* Configure PCI Express settings */ - if (bus && !pci_has_flag(PCI_PROBE_ONLY)) { - struct pci_bus *child; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-remove-arch-specific-overrides-of-panic_timeout.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-remove-arch-specific-overrides-of-panic_timeout.patch deleted file mode 100644 index d90efa32..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-remove-arch-specific-overrides-of-panic_timeout.patch +++ /dev/null @@ -1,33 +0,0 @@ -From e5ae2bb5c7cf0389f0333e5d36be193e7738f4e9 Mon Sep 17 00:00:00 2001 -Subject: [PATCH 2/2] powerpc: remove arch specific overrides of panic_timeout - -Signed-off-by: Jonathan Toppins - -diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c -index ac76108..287d120 100644 ---- a/arch/powerpc/kernel/setup_32.c -+++ b/arch/powerpc/kernel/setup_32.c -@@ -317,9 +317,6 @@ void __init setup_arch(char **cmdline_p) - if (cpu_has_feature(CPU_FTR_UNIFIED_ID_CACHE)) - ucache_bsize = icache_bsize = dcache_bsize; - -- /* reboot on panic */ -- panic_timeout = 180; -- - if (ppc_md.panic) - setup_panic(); - -diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c -index 2c8890a..38533f2 100644 ---- a/arch/powerpc/kernel/setup_64.c -+++ b/arch/powerpc/kernel/setup_64.c -@@ -554,9 +554,6 @@ void __init setup_arch(char **cmdline_p) - dcache_bsize = ppc64_caches.dline_size; - icache_bsize = ppc64_caches.iline_size; - -- /* reboot on panic */ -- panic_timeout = 180; -- - if (ppc_md.panic) - setup_panic(); - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-topology-info.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-topology-info.patch deleted file mode 100644 index b19b2568..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-topology-info.patch +++ /dev/null @@ -1,63 +0,0 @@ -Fix PPC toology macros - -diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h -index c971858..eefc7df 100644 ---- a/arch/powerpc/include/asm/topology.h -+++ b/arch/powerpc/include/asm/topology.h -@@ -124,13 +124,15 @@ static inline int stop_topology_update(void) - #include - #define smt_capable() (cpu_has_feature(CPU_FTR_SMT)) - --#ifdef CONFIG_PPC64 - #include - --#define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) --#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) --#define topology_core_id(cpu) (cpu_to_core_id(cpu)) -+#ifdef CONFIG_PPC64 -+#define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) -+#define topology_physical_package_id(cpu) (get_hard_smp_processor_id(cpu)) - #endif -+#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) -+#define topology_core_id(cpu) (cpu_to_core_id(cpu)) -+#define topology_physical_package_id(cpu) (0) - #endif - - #endif /* __KERNEL__ */ -diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c -index 77bb77d..efd43dd 100644 ---- a/arch/powerpc/kernel/setup-common.c -+++ b/arch/powerpc/kernel/setup-common.c -@@ -199,6 +199,23 @@ static void show_cpuinfo_summary(struct seq_file *m) - #endif - } - -+/* -+ * Get CPU information for use by the procfs. -+ */ -+static void show_cpuinfo_core(struct seq_file *m, unsigned int cpu) -+{ -+ -+ -+#ifdef CONFIG_SMP -+#ifdef CONFIG_PPC64 -+ seq_printf(m, "physical id\t: %d\n", get_hard_smp_processor_id(cpu)); -+#else /* Assume 32 bit archs are single package */ -+ seq_printf(m, "physical id\t: %d\n", (0)); -+#endif /* CONFIG_PPC64 */ -+ seq_printf(m, "core id\t\t: %d\n", (cpu_to_core_id(cpu))); -+#endif -+} -+ - static int show_cpuinfo(struct seq_file *m, void *v) - { - unsigned long cpu_id = (unsigned long)v - 1; -@@ -302,6 +319,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) - seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", - maj, min, PVR_VER(pvr), PVR_REV(pvr)); - -+ show_cpuinfo_core(m, cpu_id); -+ - #ifdef CONFIG_PPC32 - seq_printf(m, "bogomips\t: %lu.%02lu\n", - loops_per_jiffy / (500000/HZ), diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-warn-unmapped-irq.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-warn-unmapped-irq.patch deleted file mode 100644 index 578fe4b1..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/arch-powerpc-warn-unmapped-irq.patch +++ /dev/null @@ -1,20 +0,0 @@ -#Copyright 2012 Cumulus Networks, Inc. All rights reserved. - -diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c -index 458ed3b..9508bec 100644 ---- a/arch/powerpc/kernel/pci-common.c -+++ b/arch/powerpc/kernel/pci-common.c -@@ -1112,6 +1112,13 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) - ppc_md.pci_dma_dev_setup(dev); - - /* Read default IRQs and fixup if necessary */ -+ if (pci_read_irq_line(dev) && (dev->devfn != 0)) { -+ printk(KERN_WARNING -+ "WARNING: Unable to map IRQ in device tree for pci device " -+ "%04x:%02x:%02x.%d\n", -+ pci_domain_nr(dev->bus), dev->bus->number, PCI_SLOT(dev->devfn), -+ PCI_FUNC(dev->devfn)); -+ } - pci_read_irq_line(dev); - if (ppc_md.pci_irq_fixup) - ppc_md.pci_irq_fixup(dev); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-build.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-build.patch deleted file mode 100644 index 7714a316..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-build.patch +++ /dev/null @@ -1,13 +0,0 @@ -Add control and postinstall - -diff --git a/debiancl/control.bcm-modules b/debiancl/control.bcm-modules -new file mode 100644 -index 0000000..98dd20b ---- /dev/null -+++ b/debiancl/control.bcm-modules -@@ -0,0 +1,5 @@ -+Package: bcm-modules -+Version: =V -+Architecture: =A -+Maintainer: support@cumulusnetworks.com -+Description: Modules for BCM SDK diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-cumulus-config-abi-ref.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-cumulus-config-abi-ref.patch deleted file mode 100644 index 32e87bca..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-cumulus-config-abi-ref.patch +++ /dev/null @@ -1,4920 +0,0 @@ -Abi ref generated with cumulus config file - -diff --git a/debian/abi/3.2.0-4/powerpc_none_powerpc-smp-cumulus b/debian/abi/3.2.0-4/powerpc_none_powerpc-smp-cumulus -new file mode 100644 -index 0000000..f461280 ---- /dev/null -+++ b/debian/abi/3.2.0-4/powerpc_none_powerpc-smp-cumulus -@@ -0,0 +1,4912 @@ -+0x897b7f0f usb_serial_generic_submit_read_urb vmlinux EXPORT_SYMBOL_GPL -+0x7de5bdf0 generic_file_splice_write vmlinux EXPORT_SYMBOL -+0x801e2bc9 set_anon_super vmlinux EXPORT_SYMBOL -+0x6fce9192 kmem_cache_alloc vmlinux EXPORT_SYMBOL -+0x96f799f3 replace_page_cache_page vmlinux EXPORT_SYMBOL_GPL -+0x70523a7a __cond_resched_softirq vmlinux EXPORT_SYMBOL -+0x9147a486 of_get_property vmlinux EXPORT_SYMBOL -+0x009a3fb6 i2c_put_adapter vmlinux EXPORT_SYMBOL -+0x495ed07e rtc_class_open vmlinux EXPORT_SYMBOL_GPL -+0x96cd2b04 scsi_sense_key_string vmlinux EXPORT_SYMBOL -+0x0a2487e0 unblock_all_signals vmlinux EXPORT_SYMBOL -+0x3dcfd253 dev_uc_sync vmlinux EXPORT_SYMBOL -+0x8bdf1749 dev_mc_sync vmlinux EXPORT_SYMBOL -+0xccd91589 hwmon_device_unregister vmlinux EXPORT_SYMBOL_GPL -+0xdf27877b register_timer_hook vmlinux EXPORT_SYMBOL_GPL -+0xfbaaf01e console_lock vmlinux EXPORT_SYMBOL -+0xe113bbbc csum_partial vmlinux EXPORT_SYMBOL -+0xa39d9220 unregister_timer_hook vmlinux EXPORT_SYMBOL_GPL -+0xc068440e __kfifo_alloc vmlinux EXPORT_SYMBOL -+0xddf5478d nf_log_register vmlinux EXPORT_SYMBOL -+0x69aa9637 scsi_execute vmlinux EXPORT_SYMBOL -+0x1b17e06c kstrtoll vmlinux EXPORT_SYMBOL -+0xc161fa2b proc_net_remove vmlinux EXPORT_SYMBOL_GPL -+0xcb8c9724 raw_seq_open vmlinux EXPORT_SYMBOL_GPL -+0x8f6f24c7 device_del vmlinux EXPORT_SYMBOL_GPL -+0x0058381b device_add vmlinux EXPORT_SYMBOL_GPL -+0x416460c6 crypto_hash_walk_done vmlinux EXPORT_SYMBOL_GPL -+0xaf063510 _raw_spin_lock_bh vmlinux EXPORT_SYMBOL -+0x3c942368 profile_event_unregister vmlinux EXPORT_SYMBOL_GPL -+0x89ff43f6 init_uts_ns vmlinux EXPORT_SYMBOL_GPL -+0xca8f2cf7 __inet6_hash vmlinux EXPORT_SYMBOL -+0x69181415 dst_release vmlinux EXPORT_SYMBOL -+0x33213a5f sock_no_mmap vmlinux EXPORT_SYMBOL -+0xba0cf4bd disk_map_sector_rcu vmlinux EXPORT_SYMBOL_GPL -+0x206e3996 sysfs_update_group vmlinux EXPORT_SYMBOL_GPL -+0xa38602cd drain_workqueue vmlinux EXPORT_SYMBOL_GPL -+0xfdb9b629 ioread32be vmlinux EXPORT_SYMBOL -+0x436708b0 tcp_initialize_rcv_mss vmlinux EXPORT_SYMBOL -+0x54e6fcdd net_enable_timestamp vmlinux EXPORT_SYMBOL -+0xea2c390d sockfd_lookup vmlinux EXPORT_SYMBOL -+0xc4f9f419 usb_serial_generic_write_bulk_callback vmlinux EXPORT_SYMBOL_GPL -+0xea9855ae blk_limits_max_hw_sectors vmlinux EXPORT_SYMBOL -+0x3dcb51c4 directly_mappable_cdev_bdi vmlinux EXPORT_SYMBOL -+0x6bc3fbc0 __unregister_chrdev vmlinux EXPORT_SYMBOL -+0xa72f6b4b srcu_notifier_chain_register vmlinux EXPORT_SYMBOL_GPL -+0xb5dea7ef g_token_size vmlinux EXPORT_SYMBOL_GPL -+0x122d10bc dev_graft_qdisc vmlinux EXPORT_SYMBOL -+0x829e76cd scsi_get_command vmlinux EXPORT_SYMBOL -+0x7ff10ccf raw_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL -+0xca18d700 flush_tlb_range vmlinux EXPORT_SYMBOL -+0xd54291e6 scsi_target_quiesce vmlinux EXPORT_SYMBOL -+0x2f225631 transport_class_register vmlinux EXPORT_SYMBOL_GPL -+0x30cada8f radix_tree_next_hole vmlinux EXPORT_SYMBOL -+0x66d0ee54 vfsmount_lock_global_unlock vmlinux EXPORT_SYMBOL -+0xdad1a719 input_handler_for_each_handle vmlinux EXPORT_SYMBOL -+0xe3e619b2 transport_class_unregister vmlinux EXPORT_SYMBOL_GPL -+0xffd5a395 default_wake_function vmlinux EXPORT_SYMBOL -+0x434c3c59 pci_bus_read_config_byte vmlinux EXPORT_SYMBOL -+0x1a58b8f5 mount_subtree vmlinux EXPORT_SYMBOL -+0x7eaa917d iget_locked vmlinux EXPORT_SYMBOL -+0x9a696827 sock_get_timestampns vmlinux EXPORT_SYMBOL -+0x0f4ca848 class_interface_register vmlinux EXPORT_SYMBOL_GPL -+0xb711d84e key_type_keyring vmlinux EXPORT_SYMBOL -+0xa4b94fea iowrite8_rep vmlinux EXPORT_SYMBOL -+0x8c7a3757 of_get_named_gpio_flags vmlinux EXPORT_SYMBOL -+0x0f05e347 spi_get_device_id vmlinux EXPORT_SYMBOL_GPL -+0xfa010184 class_interface_unregister vmlinux EXPORT_SYMBOL_GPL -+0x73a903c4 vfsmount_lock_local_lock vmlinux EXPORT_SYMBOL -+0xa9c530b8 unregister_oom_notifier vmlinux EXPORT_SYMBOL_GPL -+0x2eec63c9 xdr_encode_netobj vmlinux EXPORT_SYMBOL_GPL -+0xd5cd5612 xdr_decode_word vmlinux EXPORT_SYMBOL_GPL -+0x9d92332a tty_register_device vmlinux EXPORT_SYMBOL -+0x44366cfc simple_write_to_buffer vmlinux EXPORT_SYMBOL -+0xa28d5490 __srcu_read_unlock vmlinux EXPORT_SYMBOL_GPL -+0xc2e587d1 reset_devices vmlinux EXPORT_SYMBOL -+0x9cdd28bc of_find_all_nodes vmlinux EXPORT_SYMBOL -+0xac1b6c1d mmc_app_cmd vmlinux EXPORT_SYMBOL_GPL -+0x3df5e4b2 usb_bus_list_lock vmlinux EXPORT_SYMBOL_GPL -+0xa5a633b9 sg_last vmlinux EXPORT_SYMBOL -+0xe601908d __blk_run_queue vmlinux EXPORT_SYMBOL -+0x643eaec8 param_get_string vmlinux EXPORT_SYMBOL -+0x99bb8806 memmove vmlinux EXPORT_SYMBOL -+0xf0904255 __block_page_mkwrite vmlinux EXPORT_SYMBOL -+0x76d3cd60 laptop_mode vmlinux EXPORT_SYMBOL -+0xa10b7029 generic_file_direct_write vmlinux EXPORT_SYMBOL -+0xb7032a2f end_page_writeback vmlinux EXPORT_SYMBOL -+0x50f5e532 call_rcu_sched vmlinux EXPORT_SYMBOL_GPL -+0x46e0a7f2 skb_recv_datagram vmlinux EXPORT_SYMBOL -+0xe230598d d_alloc_pseudo vmlinux EXPORT_SYMBOL -+0x871c0a7e fiemap_check_flags vmlinux EXPORT_SYMBOL -+0x51221294 generic_file_readonly_mmap vmlinux EXPORT_SYMBOL -+0x5d730e7b raw_notifier_chain_unregister vmlinux EXPORT_SYMBOL_GPL -+0x0d542439 __ipv6_addr_type vmlinux EXPORT_SYMBOL -+0x8c5e419b unregister_qdisc vmlinux EXPORT_SYMBOL -+0xe3ebc041 phy_device_register vmlinux EXPORT_SYMBOL -+0x7fd37e2b pci_map_rom vmlinux EXPORT_SYMBOL -+0xdfef1b84 crypto_shash_finup vmlinux EXPORT_SYMBOL_GPL -+0xb58965de crypto_shash_final vmlinux EXPORT_SYMBOL_GPL -+0xea9ea6f1 crypto_ahash_finup vmlinux EXPORT_SYMBOL_GPL -+0x34e42b95 crypto_ahash_final vmlinux EXPORT_SYMBOL_GPL -+0x8da17b42 scatterwalk_copychunks vmlinux EXPORT_SYMBOL_GPL -+0xf9d1164c rpc_free vmlinux EXPORT_SYMBOL_GPL -+0xc78a46ea vm_insert_page vmlinux EXPORT_SYMBOL -+0xad9cdfab register_console vmlinux EXPORT_SYMBOL -+0x243c6e2f nf_conntrack_l4proto_tcp4 net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x227491cf sock_no_socketpair vmlinux EXPORT_SYMBOL -+0x1a0cac4b input_ff_event vmlinux EXPORT_SYMBOL_GPL -+0xb7e566f8 arpt_do_table net/ipv4/netfilter/arp_tables EXPORT_SYMBOL -+0xdfcd2d6f dev_addr_del vmlinux EXPORT_SYMBOL -+0x8631f469 gnet_stats_start_copy vmlinux EXPORT_SYMBOL -+0x87a8ad19 nfs_retry_commit vmlinux EXPORT_SYMBOL_GPL -+0x7aa1a681 tcp_tso_segment vmlinux EXPORT_SYMBOL -+0x9620e18a i2c_lock_adapter vmlinux EXPORT_SYMBOL_GPL -+0xd7ea90c8 platform_device_del vmlinux EXPORT_SYMBOL_GPL -+0x1511ba61 platform_device_put vmlinux EXPORT_SYMBOL_GPL -+0x3e96ee6c __fat_fs_error vmlinux EXPORT_SYMBOL_GPL -+0xb741990c bio_copy_kern vmlinux EXPORT_SYMBOL -+0xe0878bfe __krealloc vmlinux EXPORT_SYMBOL -+0xd8605470 devm_free_irq vmlinux EXPORT_SYMBOL -+0x995d1071 prof_on vmlinux EXPORT_SYMBOL_GPL -+0xa652c4ef __kfifo_dma_in_prepare_r vmlinux EXPORT_SYMBOL -+0xa662b253 task_nice vmlinux EXPORT_SYMBOL -+0x4e9dffb5 ip_fast_csum vmlinux EXPORT_SYMBOL -+0xb9524c5c rpc_exit vmlinux EXPORT_SYMBOL_GPL -+0x5195426a kernel_accept vmlinux EXPORT_SYMBOL -+0x1a26398f pcim_iounmap vmlinux EXPORT_SYMBOL -+0x420ffdd5 kset_create_and_add vmlinux EXPORT_SYMBOL_GPL -+0xc47933f9 mm_kobj vmlinux EXPORT_SYMBOL_GPL -+0xd6d48dbb set_bdi_congested vmlinux EXPORT_SYMBOL -+0x5d9c4677 xt_proto_fini vmlinux EXPORT_SYMBOL_GPL -+0x481bf5f1 driver_find vmlinux EXPORT_SYMBOL_GPL -+0xd461ba2e sg_miter_start vmlinux EXPORT_SYMBOL -+0x4aef7e80 blk_queue_unprep_rq vmlinux EXPORT_SYMBOL -+0x54b411de lock_may_read vmlinux EXPORT_SYMBOL -+0xdbe4131c tty_mode_ioctl vmlinux EXPORT_SYMBOL_GPL -+0x0dc5ceb6 load_nls vmlinux EXPORT_SYMBOL -+0x4563a37d qe_setbrg vmlinux EXPORT_SYMBOL -+0x4859b8bb rtc_year_days vmlinux EXPORT_SYMBOL -+0x4d172ccb ehci_cf_port_reset_rwsem vmlinux EXPORT_SYMBOL_GPL -+0x0c65e73c scsi_normalize_sense vmlinux EXPORT_SYMBOL -+0xb65bd3fc add_timer_on vmlinux EXPORT_SYMBOL_GPL -+0x7e17ba7b klist_iter_exit vmlinux EXPORT_SYMBOL_GPL -+0xcbf1d339 ip6_local_out vmlinux EXPORT_SYMBOL_GPL -+0x8818a3de pci_slots_kset vmlinux EXPORT_SYMBOL_GPL -+0x215ebd78 bitrev16 vmlinux EXPORT_SYMBOL -+0x390def22 kstrtou16_from_user vmlinux EXPORT_SYMBOL -+0x9a74417e kstrtoull_from_user vmlinux EXPORT_SYMBOL -+0x72b243d4 free_dma vmlinux EXPORT_SYMBOL -+0x6e13f758 xdr_init_decode vmlinux EXPORT_SYMBOL_GPL -+0xd072d7d2 device_unregister vmlinux EXPORT_SYMBOL_GPL -+0x30e54d7e crypto_aead_type vmlinux EXPORT_SYMBOL_GPL -+0xafda2ff8 xfrm_state_add vmlinux EXPORT_SYMBOL -+0xcbf4e023 mmc_cleanup_queue vmlinux EXPORT_SYMBOL -+0xed23b4df nf_ct_l3proto_put net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x5b57fe3e scsicam_bios_param vmlinux EXPORT_SYMBOL -+0x853adf25 single_release_net vmlinux EXPORT_SYMBOL_GPL -+0xcd24efa3 I_BDEV vmlinux EXPORT_SYMBOL -+0x74abdafa task_handoff_register vmlinux EXPORT_SYMBOL_GPL -+0x68887e62 tty_port_tty_set vmlinux EXPORT_SYMBOL -+0x5791030d tty_port_tty_get vmlinux EXPORT_SYMBOL -+0x3441c3d6 gpio_set_value_cansleep vmlinux EXPORT_SYMBOL_GPL -+0x6852cd21 seq_release_net vmlinux EXPORT_SYMBOL_GPL -+0x3c0fca43 inet_csk_route_child_sock vmlinux EXPORT_SYMBOL_GPL -+0x28c3aed9 phy_stop_interrupts vmlinux EXPORT_SYMBOL -+0xea5974e8 vfs_path_lookup vmlinux EXPORT_SYMBOL -+0x4790c5b9 find_or_create_page vmlinux EXPORT_SYMBOL -+0x5b0d97e2 schedule_hrtimeout_range vmlinux EXPORT_SYMBOL_GPL -+0xd8849ae7 usb_sg_init vmlinux EXPORT_SYMBOL_GPL -+0x4af7e190 usb_sg_wait vmlinux EXPORT_SYMBOL_GPL -+0xfaf32193 scsi_reset_provider vmlinux EXPORT_SYMBOL -+0x115de368 crypto_register_pcomp vmlinux EXPORT_SYMBOL_GPL -+0x3a47e130 invalidate_bdev vmlinux EXPORT_SYMBOL -+0x9aeacb87 ring_buffer_iter_empty vmlinux EXPORT_SYMBOL_GPL -+0x1f8cee61 tcp_twsk_unique vmlinux EXPORT_SYMBOL_GPL -+0xd3984b47 netdev_info vmlinux EXPORT_SYMBOL -+0x0ba0a26c mmc_try_claim_host vmlinux EXPORT_SYMBOL -+0x11267875 scsi_extd_sense_format vmlinux EXPORT_SYMBOL -+0xeefae453 xdr_buf_from_iov vmlinux EXPORT_SYMBOL_GPL -+0x65b252e9 of_n_addr_cells vmlinux EXPORT_SYMBOL -+0x0e3ead77 pci_bus_write_config_dword vmlinux EXPORT_SYMBOL -+0xf18f172c __dev_printk vmlinux EXPORT_SYMBOL -+0x9445ac6b tty_hung_up_p vmlinux EXPORT_SYMBOL -+0x02e24269 blk_cleanup_queue vmlinux EXPORT_SYMBOL -+0x24995a6b generic_setlease vmlinux EXPORT_SYMBOL -+0x00372404 ipv6_getsockopt vmlinux EXPORT_SYMBOL -+0xdc047fc4 scsi_dev_info_list_add_keyed vmlinux EXPORT_SYMBOL -+0x06094818 pcim_enable_device vmlinux EXPORT_SYMBOL -+0xf9091ce7 timerqueue_del vmlinux EXPORT_SYMBOL_GPL -+0xc742c7f7 usb_driver_release_interface vmlinux EXPORT_SYMBOL_GPL -+0xdaa3f256 swiotlb_unmap_sg vmlinux EXPORT_SYMBOL -+0xbbfeb33c mpage_writepages vmlinux EXPORT_SYMBOL -+0xe1b2b01a write_one_page vmlinux EXPORT_SYMBOL -+0xd944d8f9 ktime_get_boottime vmlinux EXPORT_SYMBOL_GPL -+0x15892417 async_synchronize_cookie vmlinux EXPORT_SYMBOL_GPL -+0x04f58c37 inet_add_protocol vmlinux EXPORT_SYMBOL -+0xd48581cf n_tty_ioctl_helper vmlinux EXPORT_SYMBOL -+0x763793e1 nlmsvc_ops vmlinux EXPORT_SYMBOL_GPL -+0xe01bf95f sync_blockdev vmlinux EXPORT_SYMBOL -+0x4cae72a5 nobh_write_end vmlinux EXPORT_SYMBOL -+0xb753bcc8 __ashrdi3 vmlinux EXPORT_SYMBOL -+0xbd9e5d49 __lshrdi3 vmlinux EXPORT_SYMBOL -+0x6e720ff2 rtnl_unlock vmlinux EXPORT_SYMBOL -+0xfad6aff2 sock_rfree vmlinux EXPORT_SYMBOL -+0x4c4d5c41 kernel_recvmsg vmlinux EXPORT_SYMBOL -+0x9336642f sdhci_alloc_host vmlinux EXPORT_SYMBOL_GPL -+0x809ed043 __root_device_register vmlinux EXPORT_SYMBOL_GPL -+0xc0a3d105 find_next_bit vmlinux EXPORT_SYMBOL -+0x7c43ef3e disk_part_iter_init vmlinux EXPORT_SYMBOL_GPL -+0x2e3f5691 freeze_bdev vmlinux EXPORT_SYMBOL -+0x5bff2a2d srcu_batches_completed vmlinux EXPORT_SYMBOL_GPL -+0x515e24a7 flush_instruction_cache vmlinux EXPORT_SYMBOL -+0x6e44d7eb ip_xfrm_me_harder vmlinux EXPORT_SYMBOL -+0xd7f36357 __netdev_printk vmlinux EXPORT_SYMBOL -+0xc1085178 skb_kill_datagram vmlinux EXPORT_SYMBOL -+0x6d139e79 kfree_skb vmlinux EXPORT_SYMBOL -+0x0d385349 kernel_kobj vmlinux EXPORT_SYMBOL_GPL -+0x0d5b063c atomic_notifier_chain_register vmlinux EXPORT_SYMBOL_GPL -+0x7ce0ae7c param_get_long vmlinux EXPORT_SYMBOL -+0x96cbb2f4 inet_twsk_schedule vmlinux EXPORT_SYMBOL_GPL -+0x79387c50 pci_msi_off vmlinux EXPORT_SYMBOL_GPL -+0x31634792 nfnetlink_parse_nat_setup_hook net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xcc645e42 svc_set_num_threads vmlinux EXPORT_SYMBOL_GPL -+0x11ba3f13 skb_copy_datagram_iovec vmlinux EXPORT_SYMBOL -+0xf674ecb9 __kfree_skb vmlinux EXPORT_SYMBOL -+0x476b6a01 get_mtd_device_nm vmlinux EXPORT_SYMBOL_GPL -+0x55ceb682 pci_find_parent_resource vmlinux EXPORT_SYMBOL -+0x6d69fa17 ip_defrag vmlinux EXPORT_SYMBOL -+0x65b9b8a1 register_qdisc vmlinux EXPORT_SYMBOL -+0x6eab6815 mmc_interrupt_hpi vmlinux EXPORT_SYMBOL -+0x82feec40 mmc_can_discard vmlinux EXPORT_SYMBOL -+0x0d9a9ca3 scsi_flush_work vmlinux EXPORT_SYMBOL_GPL -+0x5b323547 sysdev_show_int vmlinux EXPORT_SYMBOL_GPL -+0x11cf27a9 idr_destroy vmlinux EXPORT_SYMBOL -+0xb857da73 ida_destroy vmlinux EXPORT_SYMBOL -+0x58bd4122 generic_file_aio_read vmlinux EXPORT_SYMBOL -+0x4596db6a sys_sigreturn vmlinux EXPORT_SYMBOL -+0xa9571d6d DMA_MODE_WRITE vmlinux EXPORT_SYMBOL -+0x80c07906 arpt_alloc_initial_table net/ipv4/netfilter/arp_tables EXPORT_SYMBOL_GPL -+0x5013cc99 xprt_wait_for_buffer_space vmlinux EXPORT_SYMBOL_GPL -+0x4379a238 free_netdev vmlinux EXPORT_SYMBOL -+0xc9ec4e21 free_percpu vmlinux EXPORT_SYMBOL_GPL -+0x966ae342 qe_issue_cmd vmlinux EXPORT_SYMBOL -+0x191af13e gss_mech_get_by_pseudoflavor vmlinux EXPORT_SYMBOL_GPL -+0x2764067e sk_setup_caps vmlinux EXPORT_SYMBOL_GPL -+0x6696da6c spi_sync_locked vmlinux EXPORT_SYMBOL_GPL -+0x2e89318f scsi_host_get vmlinux EXPORT_SYMBOL -+0x668da8d5 zlib_inflateIncomp vmlinux EXPORT_SYMBOL -+0xbcffe639 idr_pre_get vmlinux EXPORT_SYMBOL -+0x4430c75c ida_pre_get vmlinux EXPORT_SYMBOL -+0x28d664ff __raw_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL -+0x4d3c153f sigprocmask vmlinux EXPORT_SYMBOL -+0xbafed486 sk_stream_wait_connect vmlinux EXPORT_SYMBOL -+0x2d3dc22e mtd_concat_destroy vmlinux EXPORT_SYMBOL -+0x4a3551ae do_mmap_pgoff vmlinux EXPORT_SYMBOL -+0x8d551bef sysctl_tcp_rmem vmlinux EXPORT_SYMBOL -+0x28053699 sock_no_sendmsg vmlinux EXPORT_SYMBOL -+0x11dee08f i2c_master_recv vmlinux EXPORT_SYMBOL -+0x8239ab90 vfs_unlink vmlinux EXPORT_SYMBOL -+0x7d83ac1c key_revoke vmlinux EXPORT_SYMBOL -+0x4e560ec4 pipe_unlock vmlinux EXPORT_SYMBOL -+0x9f0020c3 xprt_reserve_xprt_cong vmlinux EXPORT_SYMBOL_GPL -+0x777919af genlmsg_multicast_allns vmlinux EXPORT_SYMBOL -+0xd0a074bc bus_rescan_devices vmlinux EXPORT_SYMBOL_GPL -+0x1676e2aa put_tty_driver vmlinux EXPORT_SYMBOL -+0x1655bb05 queue_work_on vmlinux EXPORT_SYMBOL_GPL -+0x59d8223a ioport_resource vmlinux EXPORT_SYMBOL -+0xc7a4fbed rtnl_lock vmlinux EXPORT_SYMBOL -+0x73dc60ee debugfs_create_bool vmlinux EXPORT_SYMBOL_GPL -+0x490c6774 generic_file_splice_read vmlinux EXPORT_SYMBOL -+0xdd2efc0f ring_buffer_reset_cpu vmlinux EXPORT_SYMBOL_GPL -+0x1e10f34d prepare_kernel_cred vmlinux EXPORT_SYMBOL -+0x897473df mktime vmlinux EXPORT_SYMBOL -+0x582a4747 cacheable_memcpy vmlinux EXPORT_SYMBOL -+0x2288378f system_state vmlinux EXPORT_SYMBOL -+0xbe28b63a xfrm6_tunnel_alloc_spi net/ipv6/xfrm6_tunnel EXPORT_SYMBOL -+0x55e7d3c6 llc_add_pack vmlinux EXPORT_SYMBOL -+0x725c25a5 hidinput_connect vmlinux EXPORT_SYMBOL_GPL -+0x906e4ad5 splice_from_pipe_next vmlinux EXPORT_SYMBOL -+0xc3fe87c8 param_ops_uint vmlinux EXPORT_SYMBOL -+0x6f0036d9 del_timer_sync vmlinux EXPORT_SYMBOL -+0xd3187da4 pcibios_align_resource vmlinux EXPORT_SYMBOL -+0x00e8097b csum_partial_copy_fromiovecend vmlinux EXPORT_SYMBOL -+0xda7c407f pci_device_from_OF_node vmlinux EXPORT_SYMBOL -+0xb7ac4d23 __qdisc_calculate_pkt_len vmlinux EXPORT_SYMBOL -+0x0aef6a87 dev_get_by_index vmlinux EXPORT_SYMBOL -+0x8136020d mtd_do_chip_probe vmlinux EXPORT_SYMBOL -+0x75d1b1a3 pci_enable_ido vmlinux EXPORT_SYMBOL -+0x462a2e75 match_strlcpy vmlinux EXPORT_SYMBOL -+0x9eaa0939 ioctl_by_bdev vmlinux EXPORT_SYMBOL -+0x680b7306 init_net vmlinux EXPORT_SYMBOL -+0x43db0e97 mmc_power_restore_host vmlinux EXPORT_SYMBOL -+0x56dbc713 textsearch_find_continuous vmlinux EXPORT_SYMBOL -+0xf0c9ee0d __next_cpu vmlinux EXPORT_SYMBOL -+0x8741e2bf crypto_larval_lookup vmlinux EXPORT_SYMBOL_GPL -+0x6b0bc2b4 __crypto_alloc_tfm vmlinux EXPORT_SYMBOL_GPL -+0xf520946d key_unlink vmlinux EXPORT_SYMBOL -+0xc746051c keyring_search vmlinux EXPORT_SYMBOL -+0xd820c283 eventfd_ctx_remove_wait_queue vmlinux EXPORT_SYMBOL_GPL -+0x4d89bb43 generic_delete_inode vmlinux EXPORT_SYMBOL -+0xb5f17edf perf_register_guest_info_callbacks vmlinux EXPORT_SYMBOL_GPL -+0xb99f2613 nf_nat_pptp_hook_expectfn net/netfilter/nf_conntrack_pptp EXPORT_SYMBOL_GPL -+0x51fa9bbe mmc_wait_for_req vmlinux EXPORT_SYMBOL -+0xd5b037e1 kref_put vmlinux EXPORT_SYMBOL -+0xcf8bcc49 blk_run_queue vmlinux EXPORT_SYMBOL -+0xf1814894 __secpath_destroy vmlinux EXPORT_SYMBOL -+0x5ab518a3 i2c_smbus_write_i2c_block_data vmlinux EXPORT_SYMBOL -+0xaf64ad0d zlib_deflate vmlinux EXPORT_SYMBOL -+0x24fdac79 wake_bit_function vmlinux EXPORT_SYMBOL -+0xe55658d4 inet_csk_route_req vmlinux EXPORT_SYMBOL_GPL -+0xb6a61a86 qdisc_get_rtab vmlinux EXPORT_SYMBOL -+0x87b6bcc7 hid_set_field vmlinux EXPORT_SYMBOL_GPL -+0xb8d10b39 bus_remove_file vmlinux EXPORT_SYMBOL_GPL -+0x91b9e2f2 locks_release_private vmlinux EXPORT_SYMBOL_GPL -+0x06bbb24a mempool_resize vmlinux EXPORT_SYMBOL -+0x739f99ed xfrm_unregister_km vmlinux EXPORT_SYMBOL -+0xee4d52d7 in_dev_finish_destroy vmlinux EXPORT_SYMBOL -+0xadd26e5f of_find_node_by_phandle vmlinux EXPORT_SYMBOL -+0xe01c7326 hid_destroy_device vmlinux EXPORT_SYMBOL_GPL -+0xe094ef39 sg_next vmlinux EXPORT_SYMBOL -+0xe16a87dd bio_map_user vmlinux EXPORT_SYMBOL -+0x0b07abe2 unshare_fs_struct vmlinux EXPORT_SYMBOL_GPL -+0x3a746f01 smp_call_function_any vmlinux EXPORT_SYMBOL_GPL -+0x3534e2a3 system_nrt_wq vmlinux EXPORT_SYMBOL_GPL -+0xd0fb7cd4 __tasklet_hi_schedule_first vmlinux EXPORT_SYMBOL -+0x3913cd81 __nf_conntrack_confirm net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xce24147c mdiobus_scan vmlinux EXPORT_SYMBOL -+0xe4633d09 dmam_alloc_coherent vmlinux EXPORT_SYMBOL -+0xab3a9f77 tty_port_carrier_raised vmlinux EXPORT_SYMBOL -+0x58811a0b __brelse vmlinux EXPORT_SYMBOL -+0xe68e5b43 pipe_lock vmlinux EXPORT_SYMBOL -+0x7de53067 rpc_init_rtt vmlinux EXPORT_SYMBOL_GPL -+0xe05b0141 scsi_device_set_state vmlinux EXPORT_SYMBOL -+0x347fd4b3 eventfd_ctx_get vmlinux EXPORT_SYMBOL_GPL -+0x941f2aaa eventfd_ctx_put vmlinux EXPORT_SYMBOL_GPL -+0xd0d75837 mark_buffer_async_write vmlinux EXPORT_SYMBOL -+0x46d12956 wait_for_completion_interruptible_timeout vmlinux EXPORT_SYMBOL -+0x28e23139 xfrm_probe_algs vmlinux EXPORT_SYMBOL_GPL -+0xf16deeae ip_route_me_harder vmlinux EXPORT_SYMBOL -+0xb0463cdc inet_sock_destruct vmlinux EXPORT_SYMBOL -+0xab462791 nf_reinject vmlinux EXPORT_SYMBOL -+0x27ccd3d0 mmc_add_host vmlinux EXPORT_SYMBOL -+0xd4664535 tty_chars_in_buffer vmlinux EXPORT_SYMBOL -+0x3a9b6fb9 blk_unregister_region vmlinux EXPORT_SYMBOL -+0xb72e0ba9 unregister_nls vmlinux EXPORT_SYMBOL -+0x5358fc36 ring_buffer_discard_commit vmlinux EXPORT_SYMBOL_GPL -+0x2b607170 ktime_sub_ns vmlinux EXPORT_SYMBOL_GPL -+0xc17515d7 usb_hcds_loaded vmlinux EXPORT_SYMBOL_GPL -+0x97e692df skb_pull_rcsum vmlinux EXPORT_SYMBOL_GPL -+0x93055e19 __scsi_device_lookup_by_target vmlinux EXPORT_SYMBOL -+0x01902adf netpoll_trap vmlinux EXPORT_SYMBOL -+0x1a53c006 ethtool_invalid_flags vmlinux EXPORT_SYMBOL -+0xebdbe48c radix_tree_gang_lookup vmlinux EXPORT_SYMBOL -+0x07191aeb register_nls vmlinux EXPORT_SYMBOL -+0x9445cf38 locks_alloc_lock vmlinux EXPORT_SYMBOL_GPL -+0x6585e310 alloc_pages_exact_nid vmlinux EXPORT_SYMBOL -+0x1627ed72 register_dcbevent_notifier vmlinux EXPORT_SYMBOL -+0x62bc31e3 svc_prepare_thread vmlinux EXPORT_SYMBOL_GPL -+0x3dee3f15 xfrm_state_lookup vmlinux EXPORT_SYMBOL -+0x6c1c469c tcp_parse_options vmlinux EXPORT_SYMBOL -+0xd5e04f9e rps_may_expire_flow vmlinux EXPORT_SYMBOL -+0x2c1aaab6 of_gpio_simple_xlate vmlinux EXPORT_SYMBOL -+0xf52be163 i2c_smbus_write_block_data vmlinux EXPORT_SYMBOL -+0x71b46d5a svc_gss_principal vmlinux EXPORT_SYMBOL_GPL -+0x6013246a rpc_unlink vmlinux EXPORT_SYMBOL_GPL -+0x6f959b35 locks_in_grace vmlinux EXPORT_SYMBOL_GPL -+0x2749fd92 module_refcount vmlinux EXPORT_SYMBOL -+0xb1ac2e02 inet_ctl_sock_create vmlinux EXPORT_SYMBOL_GPL -+0xdee5a777 dev_addr_add_multiple vmlinux EXPORT_SYMBOL -+0x2f2c9199 firmware_kobj vmlinux EXPORT_SYMBOL_GPL -+0x91696a6a pci_store_saved_state vmlinux EXPORT_SYMBOL_GPL -+0x009653bb usb_lock_device_for_reset vmlinux EXPORT_SYMBOL_GPL -+0xb95e4ac4 mdiobus_alloc vmlinux EXPORT_SYMBOL -+0x31da061a get_qe_base vmlinux EXPORT_SYMBOL -+0xa3e75545 flush_tlb_kernel_range vmlinux EXPORT_SYMBOL -+0x371d2130 check_legacy_ioport vmlinux EXPORT_SYMBOL -+0xbc8b4faf genl_register_mc_group vmlinux EXPORT_SYMBOL -+0xb7ac5dda ___pskb_trim vmlinux EXPORT_SYMBOL -+0xbaa1069f tty_driver_flush_buffer vmlinux EXPORT_SYMBOL -+0x328b8594 pci_setup_cardbus vmlinux EXPORT_SYMBOL -+0x85df9b6c strsep vmlinux EXPORT_SYMBOL -+0x788fe103 iomem_resource vmlinux EXPORT_SYMBOL -+0xe2d5255a strcmp vmlinux EXPORT_SYMBOL -+0xea07d51b usb_serial_register vmlinux EXPORT_SYMBOL_GPL -+0x355bc233 devm_kfree vmlinux EXPORT_SYMBOL_GPL -+0x051fbdb5 mnt_unpin vmlinux EXPORT_SYMBOL -+0x94da4dd0 end_writeback vmlinux EXPORT_SYMBOL -+0x0e08028c vfs_create vmlinux EXPORT_SYMBOL -+0x2e5fb132 mtd_erase_callback vmlinux EXPORT_SYMBOL_GPL -+0x4b72a3d8 __ablkcipher_walk_complete vmlinux EXPORT_SYMBOL_GPL -+0x750794d1 sb_min_blocksize vmlinux EXPORT_SYMBOL -+0x59d696b6 register_module_notifier vmlinux EXPORT_SYMBOL -+0xf3d30d7b setup_deferrable_timer_on_stack_key vmlinux EXPORT_SYMBOL_GPL -+0xc7208c3a serial8250_resume_port vmlinux EXPORT_SYMBOL -+0xc490d869 hid_input_report vmlinux EXPORT_SYMBOL_GPL -+0xced3e4fb pcix_set_mmrbc vmlinux EXPORT_SYMBOL -+0xaf91d89f __kernel_param_lock vmlinux EXPORT_SYMBOL -+0xadd63611 unregister_sysctl_table vmlinux EXPORT_SYMBOL -+0xd9e09e0c of_find_property vmlinux EXPORT_SYMBOL -+0xb7bd1f4f del_gendisk vmlinux EXPORT_SYMBOL -+0x54d4dba9 block_write_full_page vmlinux EXPORT_SYMBOL -+0x70e009d6 machine_id vmlinux EXPORT_SYMBOL -+0x2af8b550 nf_ct_invert_tuple net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xcc75ede8 xfrm_register_type vmlinux EXPORT_SYMBOL -+0xf6933c48 lockd_up vmlinux EXPORT_SYMBOL_GPL -+0x58652a56 fat_sync_inode vmlinux EXPORT_SYMBOL_GPL -+0xe36816d8 put_mnt_ns vmlinux EXPORT_SYMBOL -+0xe16e2b9f clear_bdi_congested vmlinux EXPORT_SYMBOL -+0x1239f785 ____pagevec_lru_add vmlinux EXPORT_SYMBOL -+0x8df5da63 memstart_addr vmlinux EXPORT_SYMBOL -+0xd1cd3585 sock_no_setsockopt vmlinux EXPORT_SYMBOL -+0x13435bdb sock_no_getsockopt vmlinux EXPORT_SYMBOL -+0x6f0843c1 __blockdev_direct_IO vmlinux EXPORT_SYMBOL -+0x1336c951 splice_from_pipe_end vmlinux EXPORT_SYMBOL -+0x2261d711 migrate_page vmlinux EXPORT_SYMBOL -+0x2e45e488 rcu_note_context_switch vmlinux EXPORT_SYMBOL_GPL -+0x4ae11ab9 ip6_route_me_harder vmlinux EXPORT_SYMBOL -+0x05bfdc15 thermal_zone_device_update vmlinux EXPORT_SYMBOL -+0xe165d0ce nfs_commit_release_pages vmlinux EXPORT_SYMBOL_GPL -+0x10d4e73e nf_nat_proto_range_to_nlattr net/ipv4/netfilter/nf_nat EXPORT_SYMBOL_GPL -+0xee7d731d km_new_mapping vmlinux EXPORT_SYMBOL -+0x408bf35b napi_complete vmlinux EXPORT_SYMBOL -+0xa155dccc of_property_count_strings vmlinux EXPORT_SYMBOL_GPL -+0x96d1f2a7 mmc_assume_removable vmlinux EXPORT_SYMBOL -+0x47229b5c gpio_request vmlinux EXPORT_SYMBOL_GPL -+0x3d0b6923 swiotlb_sync_single_for_cpu vmlinux EXPORT_SYMBOL -+0x7f968718 generic_block_bmap vmlinux EXPORT_SYMBOL -+0x868784cb __symbol_get vmlinux EXPORT_SYMBOL_GPL -+0x36dc730d __ip_dev_find vmlinux EXPORT_SYMBOL -+0xbe0e5118 nla_memcmp vmlinux EXPORT_SYMBOL -+0xf1db1704 nla_memcpy vmlinux EXPORT_SYMBOL -+0x8348bb59 nfs_put_client vmlinux EXPORT_SYMBOL_GPL -+0xbca1e919 d_materialise_unique vmlinux EXPORT_SYMBOL_GPL -+0xf229af8b kmem_cache_free vmlinux EXPORT_SYMBOL -+0x617a2e8b file_remove_suid vmlinux EXPORT_SYMBOL -+0x13b77367 get_cpu_device vmlinux EXPORT_SYMBOL_GPL -+0x4ebf144b swiotlb_bounce vmlinux EXPORT_SYMBOL_GPL -+0x5edd0762 bin2bcd vmlinux EXPORT_SYMBOL -+0x2e9c1dbc lookup_hash vmlinux EXPORT_SYMBOL_GPL -+0xaf2d872c prepare_to_wait vmlinux EXPORT_SYMBOL -+0xadf42bd5 __request_region vmlinux EXPORT_SYMBOL -+0xf71521ba atomic64_add_return vmlinux EXPORT_SYMBOL -+0x5027f8ae bdev_read_only vmlinux EXPORT_SYMBOL -+0xf0009fee put_pages_list vmlinux EXPORT_SYMBOL -+0x3d043ff4 sock_wfree vmlinux EXPORT_SYMBOL -+0x2b318955 test_set_page_writeback vmlinux EXPORT_SYMBOL -+0xa3abc422 abort_exclusive_wait vmlinux EXPORT_SYMBOL -+0x091eb9b4 round_jiffies vmlinux EXPORT_SYMBOL_GPL -+0x86e66c33 gss_mech_get_by_OID vmlinux EXPORT_SYMBOL_GPL -+0xc705dfbd qdisc_destroy vmlinux EXPORT_SYMBOL -+0x5594be03 bitmap_remap vmlinux EXPORT_SYMBOL -+0x23ef48a6 truncate_inode_pages vmlinux EXPORT_SYMBOL -+0x0422fe4a inet_csk_timer_bug_msg vmlinux EXPORT_SYMBOL -+0x58fea811 input_flush_device vmlinux EXPORT_SYMBOL -+0x3b2b6b53 sysfs_notify vmlinux EXPORT_SYMBOL_GPL -+0x0948cde9 num_physpages vmlinux EXPORT_SYMBOL -+0x06295425 inet_hash vmlinux EXPORT_SYMBOL_GPL -+0x9a1dfd65 strpbrk vmlinux EXPORT_SYMBOL -+0x8734a5cd sysfs_create_file vmlinux EXPORT_SYMBOL_GPL -+0xf6a14396 seq_lseek vmlinux EXPORT_SYMBOL -+0xfb596d67 ip6_frag_match vmlinux EXPORT_SYMBOL -+0xa9647a71 sdhci_add_host vmlinux EXPORT_SYMBOL_GPL -+0xb53620d1 pci_vpd_find_info_keyword vmlinux EXPORT_SYMBOL_GPL -+0x1551dc51 bitmap_find_free_region vmlinux EXPORT_SYMBOL -+0x71fa908a cache_flush vmlinux EXPORT_SYMBOL_GPL -+0xd582227a leds_list_lock vmlinux EXPORT_SYMBOL_GPL -+0xe32cbdf9 set_disk_ro vmlinux EXPORT_SYMBOL -+0xfc765c13 journal_invalidatepage vmlinux EXPORT_SYMBOL -+0x4a541e7f bus_find_device vmlinux EXPORT_SYMBOL_GPL -+0xfb814465 blk_rq_unprep_clone vmlinux EXPORT_SYMBOL_GPL -+0xbb7929e0 relay_switch_subbuf vmlinux EXPORT_SYMBOL_GPL -+0xa7a37016 rpc_create vmlinux EXPORT_SYMBOL_GPL -+0x32d5e7fc xfrm_aalg_get_byid vmlinux EXPORT_SYMBOL_GPL -+0x50661a88 tcp_create_openreq_child vmlinux EXPORT_SYMBOL -+0xbe39e738 sk_common_release vmlinux EXPORT_SYMBOL -+0x096bfc06 skb_queue_head vmlinux EXPORT_SYMBOL -+0x03cfa4a0 skb_prepare_seq_read vmlinux EXPORT_SYMBOL -+0x0ecca40e sk_reset_timer vmlinux EXPORT_SYMBOL -+0x90c7fdae irq_get_irq_data vmlinux EXPORT_SYMBOL_GPL -+0x4dfed71c flex_array_get_ptr vmlinux EXPORT_SYMBOL -+0x98ed958c bio_alloc_bioset vmlinux EXPORT_SYMBOL -+0x281bf2dd usb_driver_set_configuration vmlinux EXPORT_SYMBOL_GPL -+0xb5c52e5f mii_ethtool_sset vmlinux EXPORT_SYMBOL -+0x267fd50e mii_ethtool_gset vmlinux EXPORT_SYMBOL -+0x3171d976 class_compat_create_link vmlinux EXPORT_SYMBOL_GPL -+0xfee5e630 vfs_cancel_lock vmlinux EXPORT_SYMBOL_GPL -+0xb602c57e nf_ct_l3proto_module_put net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x3f68a347 release_sock vmlinux EXPORT_SYMBOL -+0xd2d51180 of_gpio_count vmlinux EXPORT_SYMBOL -+0x50e7193a __i2c_first_dynamic_bus_num vmlinux EXPORT_SYMBOL_GPL -+0xcf062b87 class_remove_file vmlinux EXPORT_SYMBOL_GPL -+0xefdcf0e8 textsearch_destroy vmlinux EXPORT_SYMBOL -+0x4610c824 of_phy_connect_fixed_link vmlinux EXPORT_SYMBOL -+0xd71d1167 unmap_underlying_metadata vmlinux EXPORT_SYMBOL -+0x7cd5feb0 sync_inode vmlinux EXPORT_SYMBOL -+0xb859f38b krealloc vmlinux EXPORT_SYMBOL -+0x46ece9e7 input_register_device vmlinux EXPORT_SYMBOL -+0x50e787f3 __invalidate_device vmlinux EXPORT_SYMBOL -+0x2ba707a8 sysctl_tcp_low_latency vmlinux EXPORT_SYMBOL -+0x1163f0a7 blk_max_low_pfn vmlinux EXPORT_SYMBOL -+0x06fd5926 blk_queue_free_tags vmlinux EXPORT_SYMBOL -+0x3cca63a0 elv_unregister_queue vmlinux EXPORT_SYMBOL -+0x67b78eb3 seq_hlist_next_rcu vmlinux EXPORT_SYMBOL -+0x5a9effe0 register_sysctl_table vmlinux EXPORT_SYMBOL -+0x7c9291d1 csum_partial_copy_generic vmlinux EXPORT_SYMBOL -+0xb9a1c8b8 tty_flip_buffer_push vmlinux EXPORT_SYMBOL -+0x929d7ef0 uart_get_divisor vmlinux EXPORT_SYMBOL -+0x425c1c0b ktime_add_safe vmlinux EXPORT_SYMBOL_GPL -+0xf9a482f9 msleep vmlinux EXPORT_SYMBOL -+0x2786a8a5 unregister_netdev vmlinux EXPORT_SYMBOL -+0xdaecbaf2 proc_net_mkdir vmlinux EXPORT_SYMBOL_GPL -+0x832ad813 __bforget vmlinux EXPORT_SYMBOL -+0xcd1dafbc __audit_inode_child vmlinux EXPORT_SYMBOL_GPL -+0xaeffe8a2 xdr_reserve_space vmlinux EXPORT_SYMBOL_GPL -+0xee4de802 inet6_add_protocol vmlinux EXPORT_SYMBOL -+0xb0240e99 raw_unhash_sk vmlinux EXPORT_SYMBOL_GPL -+0xb5be6114 xt_register_table vmlinux EXPORT_SYMBOL_GPL -+0x9e43ccf6 sock_no_listen vmlinux EXPORT_SYMBOL -+0x19990104 input_mt_destroy_slots vmlinux EXPORT_SYMBOL -+0x882fd7db usb_serial_generic_unthrottle vmlinux EXPORT_SYMBOL_GPL -+0x39d7bb0a usb_unpoison_anchored_urbs vmlinux EXPORT_SYMBOL_GPL -+0x3ab69e8f scsi_device_lookup_by_target vmlinux EXPORT_SYMBOL -+0x79aa04a2 get_random_bytes vmlinux EXPORT_SYMBOL -+0xf0efa6e0 rpcauth_unregister vmlinux EXPORT_SYMBOL_GPL -+0x67e38cdf sdhci_get_of_property vmlinux EXPORT_SYMBOL_GPL -+0x3c9390db pci_vpd_find_tag vmlinux EXPORT_SYMBOL_GPL -+0xd38480a0 rb_augment_erase_end vmlinux EXPORT_SYMBOL -+0xa474d088 blk_peek_request vmlinux EXPORT_SYMBOL -+0x5cba6ab9 sock_no_poll vmlinux EXPORT_SYMBOL -+0x2c36d879 sdio_unregister_driver vmlinux EXPORT_SYMBOL_GPL -+0x055c8258 usb_serial_generic_close vmlinux EXPORT_SYMBOL_GPL -+0x8896e0d3 blk_rq_prep_clone vmlinux EXPORT_SYMBOL_GPL -+0xc55a9a33 crypto_alloc_shash vmlinux EXPORT_SYMBOL_GPL -+0xc79bf957 crypto_alloc_ahash vmlinux EXPORT_SYMBOL_GPL -+0x89cafb57 vlan_ioctl_set vmlinux EXPORT_SYMBOL -+0xb75534fa of_alias_get_id vmlinux EXPORT_SYMBOL_GPL -+0xc11d8093 iov_shorten vmlinux EXPORT_SYMBOL -+0x6a037cf1 mempool_kfree vmlinux EXPORT_SYMBOL -+0xcf29542b scsi_scan_target vmlinux EXPORT_SYMBOL -+0xfda88943 subsys_dev_iter_init vmlinux EXPORT_SYMBOL_GPL -+0x27715359 subsys_dev_iter_exit vmlinux EXPORT_SYMBOL_GPL -+0xf0ef15b4 list_sort vmlinux EXPORT_SYMBOL -+0x71d0143a remove_arg_zero vmlinux EXPORT_SYMBOL -+0x328c1012 remap_pfn_range vmlinux EXPORT_SYMBOL -+0x52760ca9 getnstimeofday vmlinux EXPORT_SYMBOL -+0xd1cc986f phy_register_fixup vmlinux EXPORT_SYMBOL -+0xf55a56b6 device_bind_driver vmlinux EXPORT_SYMBOL_GPL -+0x0b137c47 device_store_ulong vmlinux EXPORT_SYMBOL_GPL -+0xe5c97713 pci_vpd_truncate vmlinux EXPORT_SYMBOL -+0x294da23e skcipher_geniv_exit vmlinux EXPORT_SYMBOL_GPL -+0x11eaefc3 file_update_time vmlinux EXPORT_SYMBOL -+0x529c370a bdi_unregister vmlinux EXPORT_SYMBOL -+0xae946285 inet6_csk_search_req vmlinux EXPORT_SYMBOL_GPL -+0x04dfc4d6 dev_mc_init vmlinux EXPORT_SYMBOL -+0x88c994d7 dev_uc_init vmlinux EXPORT_SYMBOL -+0x865029ac __hw_addr_sync vmlinux EXPORT_SYMBOL -+0x5f46d244 of_irq_map_raw vmlinux EXPORT_SYMBOL_GPL -+0x0e516b0a scsi_setup_blk_pc_cmnd vmlinux EXPORT_SYMBOL -+0x11a13e31 _kstrtol vmlinux EXPORT_SYMBOL -+0xc72d33bf mb_cache_entry_alloc vmlinux EXPORT_SYMBOL -+0x0d8d877a relay_file_operations vmlinux EXPORT_SYMBOL_GPL -+0x132a7a5b init_timer_key vmlinux EXPORT_SYMBOL -+0xa473aea0 rpc_wake_up_status vmlinux EXPORT_SYMBOL_GPL -+0xf39bf4d9 put_cmsg vmlinux EXPORT_SYMBOL -+0xe5dd0af1 skb_free_datagram vmlinux EXPORT_SYMBOL -+0x14d5945d of_fdt_unflatten_tree vmlinux EXPORT_SYMBOL_GPL -+0xe8790d79 pci_wake_from_d3 vmlinux EXPORT_SYMBOL -+0x0e23fb6a filp_close vmlinux EXPORT_SYMBOL -+0xb9b1637c truncate_setsize vmlinux EXPORT_SYMBOL -+0x44bcfa6d system_nrt_freezable_wq vmlinux EXPORT_SYMBOL_GPL -+0x39cdf63c wait_for_completion_interruptible vmlinux EXPORT_SYMBOL -+0x86333584 svcauth_gss_flavor vmlinux EXPORT_SYMBOL_GPL -+0x8d1a827e svcauth_gss_register_pseudoflavor vmlinux EXPORT_SYMBOL_GPL -+0x38fb9933 tty_std_termios vmlinux EXPORT_SYMBOL -+0x38320348 generic_readlink vmlinux EXPORT_SYMBOL -+0xe2e0c7c6 __flush_icache_range vmlinux EXPORT_SYMBOL -+0x33b2d26d ether_setup vmlinux EXPORT_SYMBOL -+0xd200c6d4 usb_deregister_device_driver vmlinux EXPORT_SYMBOL_GPL -+0x889b7ccd device_create_file vmlinux EXPORT_SYMBOL_GPL -+0x610d2493 __break_lease vmlinux EXPORT_SYMBOL -+0x5330e4ea get_task_comm vmlinux EXPORT_SYMBOL_GPL -+0xba464a1d __get_vm_area vmlinux EXPORT_SYMBOL_GPL -+0x7a1390f7 param_set_bool vmlinux EXPORT_SYMBOL -+0x034f9e73 param_ops_byte vmlinux EXPORT_SYMBOL -+0xc88f3891 xprt_free vmlinux EXPORT_SYMBOL_GPL -+0x8ab4079e atomic64_add vmlinux EXPORT_SYMBOL -+0xc5f46566 rb_augment_insert vmlinux EXPORT_SYMBOL -+0xb0520bf3 would_dump vmlinux EXPORT_SYMBOL -+0x4a20d82f truncate_inode_pages_range vmlinux EXPORT_SYMBOL -+0x0f62d3b5 force_sig vmlinux EXPORT_SYMBOL -+0xd0417995 pci_set_dma_max_seg_size vmlinux EXPORT_SYMBOL -+0x05240ee7 percpu_counter_batch vmlinux EXPORT_SYMBOL -+0xe3646dbc d_path vmlinux EXPORT_SYMBOL -+0x116ccd8c vfs_fstatat vmlinux EXPORT_SYMBOL -+0x2228a27e sdev_evt_send vmlinux EXPORT_SYMBOL_GPL -+0x175adc1b igrab vmlinux EXPORT_SYMBOL -+0x9d95a606 rtnl_notify vmlinux EXPORT_SYMBOL -+0xc0e1c9dd __rtnl_link_register vmlinux EXPORT_SYMBOL_GPL -+0xf1c8f28f sock_recvmsg vmlinux EXPORT_SYMBOL -+0xcb649c67 mmc_can_secure_erase_trim vmlinux EXPORT_SYMBOL -+0x83ba622a usb_hcd_unmap_urb_for_dma vmlinux EXPORT_SYMBOL_GPL -+0x5bf0f5f6 pci_back_from_sleep vmlinux EXPORT_SYMBOL -+0x0c62cfe7 blk_end_request_err vmlinux EXPORT_SYMBOL_GPL -+0x59d1c938 blk_end_request_all vmlinux EXPORT_SYMBOL -+0x9dba46f5 blk_queue_bio vmlinux EXPORT_SYMBOL_GPL -+0xd16712f3 crypto_check_attr_type vmlinux EXPORT_SYMBOL_GPL -+0x6a80a3f5 cpm_muram_free vmlinux EXPORT_SYMBOL -+0x8c0279d5 nf_ct_l3protos net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x8b63beee linkwatch_fire_event vmlinux EXPORT_SYMBOL -+0xd3505d0c ndisc_build_skb vmlinux EXPORT_SYMBOL -+0x1598dc9d unregister_netevent_notifier vmlinux EXPORT_SYMBOL_GPL -+0xb2dc7101 input_mt_report_slot_state vmlinux EXPORT_SYMBOL -+0xcf0c65bc scsi_init_io vmlinux EXPORT_SYMBOL -+0x8307be63 rpc_queue_upcall vmlinux EXPORT_SYMBOL_GPL -+0xdb484b6d sdhci_remove_host vmlinux EXPORT_SYMBOL_GPL -+0x25b7fdec fib_default_rule_pref vmlinux EXPORT_SYMBOL -+0x12b20fd2 swiotlb_sync_single_for_device vmlinux EXPORT_SYMBOL -+0x6531a053 debugfs_create_x8 vmlinux EXPORT_SYMBOL_GPL -+0x03070efa of_scan_pci_bridge vmlinux EXPORT_SYMBOL -+0x6796dc42 uart_write_wakeup vmlinux EXPORT_SYMBOL -+0xc1e35bf5 pci_bus_read_config_word vmlinux EXPORT_SYMBOL -+0x0c081027 skb_append vmlinux EXPORT_SYMBOL -+0x1aec4408 read_cache_page_gfp vmlinux EXPORT_SYMBOL -+0x9fc89fd1 schedule_delayed_work_on vmlinux EXPORT_SYMBOL -+0xe3319fe9 sk_stream_error vmlinux EXPORT_SYMBOL -+0xeef4a738 usb_stor_CB_reset vmlinux EXPORT_SYMBOL_GPL -+0x6332cc1a audit_log_start vmlinux EXPORT_SYMBOL -+0x1330b831 netdev_crit vmlinux EXPORT_SYMBOL -+0x5651005a sysfs_create_files vmlinux EXPORT_SYMBOL_GPL -+0x27f4a872 sget vmlinux EXPORT_SYMBOL -+0x5f754e5a memset vmlinux EXPORT_SYMBOL -+0x5ca89b3d mtd_kmalloc_up_to vmlinux EXPORT_SYMBOL_GPL -+0xdc3fcbc9 __sw_hweight8 vmlinux EXPORT_SYMBOL -+0x02ee26c1 free_pages_exact vmlinux EXPORT_SYMBOL -+0x95edd27e tasklet_hrtimer_init vmlinux EXPORT_SYMBOL_GPL -+0x064db9a5 mark_mounts_for_expiry vmlinux EXPORT_SYMBOL_GPL -+0xacfd81f6 work_cpu vmlinux EXPORT_SYMBOL_GPL -+0xbc316de4 tty_termios_input_baud_rate vmlinux EXPORT_SYMBOL -+0x0537dc03 d_set_d_op vmlinux EXPORT_SYMBOL -+0x2e47f677 xfrm_aalg_get_byidx vmlinux EXPORT_SYMBOL_GPL -+0x5577ef9e udp_table vmlinux EXPORT_SYMBOL -+0x70bcb245 mmc_erase_group_aligned vmlinux EXPORT_SYMBOL -+0xb24c2db9 idr_get_new_above vmlinux EXPORT_SYMBOL -+0x9704e93a ida_get_new_above vmlinux EXPORT_SYMBOL -+0x2e2f1740 ring_buffer_record_disable_cpu vmlinux EXPORT_SYMBOL_GPL -+0xa1a8f438 transport_configure_device vmlinux EXPORT_SYMBOL_GPL -+0xbd903883 nla_put vmlinux EXPORT_SYMBOL -+0x429bdb0b revalidate_disk vmlinux EXPORT_SYMBOL -+0x72e50086 vm_stat vmlinux EXPORT_SYMBOL -+0xd5b1376d register_shrinker vmlinux EXPORT_SYMBOL -+0xf23fcb99 __kfifo_in vmlinux EXPORT_SYMBOL -+0x38abcc37 get_immrbase vmlinux EXPORT_SYMBOL -+0x624a6406 hwrng_register vmlinux EXPORT_SYMBOL_GPL -+0xfa21edf6 misc_register vmlinux EXPORT_SYMBOL -+0x5d558bfa block_invalidatepage vmlinux EXPORT_SYMBOL -+0x2c793286 may_umount_tree vmlinux EXPORT_SYMBOL -+0x206687ad cpm_muram_alloc_fixed vmlinux EXPORT_SYMBOL -+0x9cedf6bd dma_direct_ops vmlinux EXPORT_SYMBOL -+0x636b12c8 nf_nat_need_gre net/ipv4/netfilter/nf_nat_proto_gre EXPORT_SYMBOL_GPL -+0x0150a066 udp_lib_get_port vmlinux EXPORT_SYMBOL -+0x7b590ac8 skb_defer_rx_timestamp vmlinux EXPORT_SYMBOL_GPL -+0x594b398f tty_ldisc_ref vmlinux EXPORT_SYMBOL_GPL -+0x68d241c1 devm_ioport_map vmlinux EXPORT_SYMBOL -+0x17ce645d locks_end_grace vmlinux EXPORT_SYMBOL_GPL -+0xc3b2d983 rtnl_af_unregister vmlinux EXPORT_SYMBOL_GPL -+0xbfee3ad5 loop_unregister_transfer vmlinux EXPORT_SYMBOL -+0x43d497ca class_dev_iter_exit vmlinux EXPORT_SYMBOL_GPL -+0x7064d556 iget_failed vmlinux EXPORT_SYMBOL -+0xc3880471 xdr_decode_netobj vmlinux EXPORT_SYMBOL_GPL -+0x25c677c4 mac_pton vmlinux EXPORT_SYMBOL -+0x99caf7d2 ethtool_op_set_tso vmlinux EXPORT_SYMBOL -+0xc94c34d0 mmc_cache_ctrl vmlinux EXPORT_SYMBOL -+0x22258364 pci_restore_state vmlinux EXPORT_SYMBOL -+0x1d16856b filemap_fdatawait_range vmlinux EXPORT_SYMBOL -+0xc9833005 skb_complete_tx_timestamp vmlinux EXPORT_SYMBOL_GPL -+0x65b82e1f usb_enable_xhci_ports vmlinux EXPORT_SYMBOL_GPL -+0xa7ddce90 inode_sub_bytes vmlinux EXPORT_SYMBOL -+0x0395d6d3 inode_set_bytes vmlinux EXPORT_SYMBOL -+0x2bd8303c svc_unreg_xprt_class vmlinux EXPORT_SYMBOL_GPL -+0xc59f0fc7 arp_xmit vmlinux EXPORT_SYMBOL -+0x9cb92c72 __dev_getfirstbyhwtype vmlinux EXPORT_SYMBOL -+0xccc53d95 __dev_get_by_index vmlinux EXPORT_SYMBOL -+0xa41a68b5 usb_serial_generic_write vmlinux EXPORT_SYMBOL_GPL -+0xabe0867d mdiobus_register vmlinux EXPORT_SYMBOL -+0xaa5fb7af pci_release_selected_regions vmlinux EXPORT_SYMBOL -+0x6c665691 flex_array_shrink vmlinux EXPORT_SYMBOL -+0xcc17504d _raw_read_unlock_irqrestore vmlinux EXPORT_SYMBOL -+0xedcf6be4 qword_add vmlinux EXPORT_SYMBOL_GPL -+0x9fc77642 __inet6_lookup_established vmlinux EXPORT_SYMBOL -+0x001b7570 skb_recycle vmlinux EXPORT_SYMBOL -+0x4b54f71e sdio_claim_host vmlinux EXPORT_SYMBOL_GPL -+0x7ca60166 __nla_put_nohdr vmlinux EXPORT_SYMBOL -+0x34d8298e bdi_init vmlinux EXPORT_SYMBOL -+0x889c066f flush_tlb_page vmlinux EXPORT_SYMBOL -+0x40973662 sysctl_udp_mem vmlinux EXPORT_SYMBOL -+0x17df17bc sysctl_tcp_ecn vmlinux EXPORT_SYMBOL -+0xa0ebd14c sysctl_tcp_mem vmlinux EXPORT_SYMBOL -+0xc94834cd ethtool_op_set_tx_csum vmlinux EXPORT_SYMBOL -+0x669a989a inet_csk_accept vmlinux EXPORT_SYMBOL -+0xc0574cac inet_hash_connect vmlinux EXPORT_SYMBOL_GPL -+0x74d6ceef generic_mii_ioctl vmlinux EXPORT_SYMBOL -+0x0334da4e scsi_command_size_tbl vmlinux EXPORT_SYMBOL -+0xb58dcfa2 synchronize_sched_expedited vmlinux EXPORT_SYMBOL_GPL -+0xa18106f8 xprt_wake_pending_tasks vmlinux EXPORT_SYMBOL_GPL -+0x35e5a105 usb_bulk_msg vmlinux EXPORT_SYMBOL_GPL -+0x1bb9d4e9 xfrm_state_delete_tunnel vmlinux EXPORT_SYMBOL -+0x03198068 platform_device_add_resources vmlinux EXPORT_SYMBOL_GPL -+0x0a5cfbc7 in6_dev_finish_destroy vmlinux EXPORT_SYMBOL -+0x909a1b12 tcp_gro_receive vmlinux EXPORT_SYMBOL -+0xa9f90244 eth_header vmlinux EXPORT_SYMBOL -+0xdacdd5df scsi_rescan_device vmlinux EXPORT_SYMBOL -+0x8f48679a rb_prev vmlinux EXPORT_SYMBOL -+0x56653400 user_match vmlinux EXPORT_SYMBOL_GPL -+0x21c5a2e1 request_key_async_with_auxdata vmlinux EXPORT_SYMBOL -+0x2a20e3db bd_unlink_disk_holder vmlinux EXPORT_SYMBOL_GPL -+0xea065e01 task_handoff_unregister vmlinux EXPORT_SYMBOL_GPL -+0xfbcac494 down_killable vmlinux EXPORT_SYMBOL -+0x83f383cb napi_gro_receive vmlinux EXPORT_SYMBOL -+0x2750609c pci_reset_function vmlinux EXPORT_SYMBOL_GPL -+0x05eb2ed0 nf_unregister_queue_handler vmlinux EXPORT_SYMBOL -+0x24eb7e32 leds_list vmlinux EXPORT_SYMBOL_GPL -+0x7b6a7955 tcp_v4_tw_get_peer vmlinux EXPORT_SYMBOL -+0x34a52594 dev_get_by_flags_rcu vmlinux EXPORT_SYMBOL -+0x7647726c handle_sysrq vmlinux EXPORT_SYMBOL -+0xea3f9431 pcie_port_bus_type vmlinux EXPORT_SYMBOL_GPL -+0x996bdb64 _kstrtoul vmlinux EXPORT_SYMBOL -+0x7f859c50 __block_write_begin vmlinux EXPORT_SYMBOL -+0x1cc6719a register_reboot_notifier vmlinux EXPORT_SYMBOL -+0xf5c9012e timespec_trunc vmlinux EXPORT_SYMBOL -+0x2b5c303b smp_send_reschedule vmlinux EXPORT_SYMBOL_GPL -+0x5e15425b tcp_sockets_allocated vmlinux EXPORT_SYMBOL -+0xcc167694 inode_owner_or_capable vmlinux EXPORT_SYMBOL -+0x079a369f generic_pipe_buf_confirm vmlinux EXPORT_SYMBOL -+0xc1eecd72 scsi_device_quiesce vmlinux EXPORT_SYMBOL -+0x9748927f _outsw_ns vmlinux EXPORT_SYMBOL -+0xfbfddf0b pci_select_bars vmlinux EXPORT_SYMBOL -+0xf184d189 kernel_power_off vmlinux EXPORT_SYMBOL_GPL -+0x84d095a1 ip6t_unregister_table net/ipv6/netfilter/ip6_tables EXPORT_SYMBOL -+0xdc3ed1f8 svc_create_pooled vmlinux EXPORT_SYMBOL_GPL -+0xcb1fe4f5 genl_register_ops vmlinux EXPORT_SYMBOL -+0x544b760f tty_ldisc_ref_wait vmlinux EXPORT_SYMBOL_GPL -+0x310a0a1b debugfs_create_u64 vmlinux EXPORT_SYMBOL_GPL -+0x9f915995 block_commit_write vmlinux EXPORT_SYMBOL -+0x87e86028 __netdev_alloc_skb vmlinux EXPORT_SYMBOL -+0xfec3c2f2 bcd2bin vmlinux EXPORT_SYMBOL -+0x5d631b05 journal_get_undo_access vmlinux EXPORT_SYMBOL -+0x1fc9cb5b perf_event_create_kernel_counter vmlinux EXPORT_SYMBOL_GPL -+0x90ff6c9f nf_ct_invert_tuplepr net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xe1a5b39b tty_kref_put vmlinux EXPORT_SYMBOL -+0x60d768c8 locks_delete_block vmlinux EXPORT_SYMBOL -+0x8eec5353 dput vmlinux EXPORT_SYMBOL -+0x1314f71a is_container_init vmlinux EXPORT_SYMBOL -+0x5bd26000 rpc_proc_unregister vmlinux EXPORT_SYMBOL_GPL -+0x66df8787 rpc_delay vmlinux EXPORT_SYMBOL_GPL -+0xbefd162c fill_inquiry_response vmlinux EXPORT_SYMBOL_GPL -+0xc4536e19 usb_match_one_id vmlinux EXPORT_SYMBOL_GPL -+0xd1e93218 srcu_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL -+0xe46682b1 sk_free vmlinux EXPORT_SYMBOL -+0xcacd6472 scsi_is_sdev_device vmlinux EXPORT_SYMBOL -+0x50f5d9f6 pci_bus_max_busnr vmlinux EXPORT_SYMBOL_GPL -+0xaaa286ec kobject_init vmlinux EXPORT_SYMBOL -+0x42160169 flush_workqueue vmlinux EXPORT_SYMBOL_GPL -+0x4b7ed27b sleep_on vmlinux EXPORT_SYMBOL -+0x331ac747 key_type_user vmlinux EXPORT_SYMBOL_GPL -+0x80bd6f7b bio_flush_dcache_pages vmlinux EXPORT_SYMBOL -+0xaf4e1072 simple_lookup vmlinux EXPORT_SYMBOL -+0xec4769ef qe_clock_source vmlinux EXPORT_SYMBOL -+0xf78d04ab netlink_register_notifier vmlinux EXPORT_SYMBOL -+0xf8a70670 usb_match_id vmlinux EXPORT_SYMBOL_GPL -+0x9be8ead9 xfrm_policy_insert vmlinux EXPORT_SYMBOL -+0xf360c71e __netpoll_cleanup vmlinux EXPORT_SYMBOL_GPL -+0x1bdf3140 skb_segment vmlinux EXPORT_SYMBOL_GPL -+0x184b82fb mmc_vddrange_to_ocrmask vmlinux EXPORT_SYMBOL -+0x9d02a2b9 usb_add_hcd vmlinux EXPORT_SYMBOL_GPL -+0x88355cbb blk_queue_max_segments vmlinux EXPORT_SYMBOL -+0x3d8aa9cd unlock_rename vmlinux EXPORT_SYMBOL -+0x1983094e fsl_lbc_ctrl_dev vmlinux EXPORT_SYMBOL -+0x2406dae3 pci_address_to_pio vmlinux EXPORT_SYMBOL_GPL -+0xe771423f tcp_init_congestion_ops vmlinux EXPORT_SYMBOL_GPL -+0xa7c0801f dev_gro_receive vmlinux EXPORT_SYMBOL -+0x5732e368 skb_push vmlinux EXPORT_SYMBOL -+0xbeb96094 sdio_f0_writeb vmlinux EXPORT_SYMBOL_GPL -+0x70033701 device_create vmlinux EXPORT_SYMBOL_GPL -+0x6848d183 blk_run_queue_async vmlinux EXPORT_SYMBOL -+0x09949de0 simple_rmdir vmlinux EXPORT_SYMBOL -+0xd28b05ff alloc_file vmlinux EXPORT_SYMBOL -+0xfefb0432 free_task vmlinux EXPORT_SYMBOL -+0x4a9eefcb i2c_del_adapter vmlinux EXPORT_SYMBOL -+0x5838f6c9 rtc_valid_tm vmlinux EXPORT_SYMBOL -+0xdcb944af usb_register_driver vmlinux EXPORT_SYMBOL_GPL -+0xbcda8829 scsi_block_requests vmlinux EXPORT_SYMBOL -+0xaa8a0279 sysfs_get vmlinux EXPORT_SYMBOL_GPL -+0x543ef284 seq_hlist_start vmlinux EXPORT_SYMBOL -+0x96573b80 __kfifo_dma_in_finish_r vmlinux EXPORT_SYMBOL -+0xe2f01afd mmc_release_host vmlinux EXPORT_SYMBOL -+0x3a374dcf fat_dir_empty vmlinux EXPORT_SYMBOL_GPL -+0x74cbb34b __getblk vmlinux EXPORT_SYMBOL -+0xd2f64b53 cdev_alloc vmlinux EXPORT_SYMBOL -+0xfb853c2c rpc_put_task_async vmlinux EXPORT_SYMBOL_GPL -+0x42d56457 usb_hcd_unlink_urb_from_ep vmlinux EXPORT_SYMBOL_GPL -+0xc48ee272 dev_warn vmlinux EXPORT_SYMBOL -+0xab3d1f95 nf_ct_untracked_status_or net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x9cedcd62 get_phy_device vmlinux EXPORT_SYMBOL -+0x74c134b9 __sw_hweight32 vmlinux EXPORT_SYMBOL -+0x57674fd7 __sw_hweight16 vmlinux EXPORT_SYMBOL -+0x9f46ced8 __sw_hweight64 vmlinux EXPORT_SYMBOL -+0xad0a6e0a flex_array_prealloc vmlinux EXPORT_SYMBOL -+0x93215e1d __kfifo_skip_r vmlinux EXPORT_SYMBOL -+0xa5377e1f svc_exit_thread vmlinux EXPORT_SYMBOL_GPL -+0x137b3ec2 pagevec_lookup_tag vmlinux EXPORT_SYMBOL -+0x67053080 current_kernel_time vmlinux EXPORT_SYMBOL -+0x3e187f83 print_tuple net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x4ef191e6 tcp_reno_cong_avoid vmlinux EXPORT_SYMBOL_GPL -+0x5a744b86 netlink_set_nonroot vmlinux EXPORT_SYMBOL -+0x82942563 usb_reset_device vmlinux EXPORT_SYMBOL_GPL -+0x7505bdef memchr_inv vmlinux EXPORT_SYMBOL -+0x1223591c locks_copy_lock vmlinux EXPORT_SYMBOL -+0xaa413a43 gnet_stats_start_copy_compat vmlinux EXPORT_SYMBOL -+0x1029fa00 rtc_alarm_irq_enable vmlinux EXPORT_SYMBOL_GPL -+0x785f307d pcim_iounmap_regions vmlinux EXPORT_SYMBOL -+0x7522f3ba irq_modify_status vmlinux EXPORT_SYMBOL_GPL -+0x52ccfd70 dcbnl_ieee_notify vmlinux EXPORT_SYMBOL -+0xbfd69829 inet6_del_protocol vmlinux EXPORT_SYMBOL -+0x753e1c04 xfrm_input_resume vmlinux EXPORT_SYMBOL -+0xde22dda4 udplite_prot vmlinux EXPORT_SYMBOL -+0xf19b1812 sock_create_kern vmlinux EXPORT_SYMBOL -+0x76b656be scsi_eh_restore_cmnd vmlinux EXPORT_SYMBOL -+0x00b8174b transport_remove_device vmlinux EXPORT_SYMBOL_GPL -+0x8260686f bitmap_find_next_zero_area vmlinux EXPORT_SYMBOL -+0x4a487484 i2c_del_mux_adapter vmlinux EXPORT_SYMBOL_GPL -+0x74cda2a1 sk_detach_filter vmlinux EXPORT_SYMBOL_GPL -+0xf1734ac9 sk_attach_filter vmlinux EXPORT_SYMBOL_GPL -+0x77bebd69 pci_unregister_driver vmlinux EXPORT_SYMBOL -+0xf741c793 zlib_deflateEnd vmlinux EXPORT_SYMBOL -+0x7469fcfe radix_tree_tagged vmlinux EXPORT_SYMBOL -+0x59659594 unload_nls vmlinux EXPORT_SYMBOL -+0x25673182 seq_open_private vmlinux EXPORT_SYMBOL -+0xe9d6801d sunrpc_cache_update vmlinux EXPORT_SYMBOL_GPL -+0xec56166e skb_gso_segment vmlinux EXPORT_SYMBOL -+0x4e128338 kernel_listen vmlinux EXPORT_SYMBOL -+0x76bf656d __bitmap_shift_left vmlinux EXPORT_SYMBOL -+0x291fef69 gss_mech_get vmlinux EXPORT_SYMBOL_GPL -+0x6713b9ea napi_skb_finish vmlinux EXPORT_SYMBOL -+0xdb9433e3 __scsi_device_lookup vmlinux EXPORT_SYMBOL -+0xe23ae481 blk_iopoll_complete vmlinux EXPORT_SYMBOL -+0xb11b4eca crypto_chain vmlinux EXPORT_SYMBOL_GPL -+0x9d669763 memcpy vmlinux EXPORT_SYMBOL -+0x03a5674f ip6t_do_table net/ipv6/netfilter/ip6_tables EXPORT_SYMBOL -+0x86ed218d rpc_run_task vmlinux EXPORT_SYMBOL_GPL -+0x43a0458b blk_start_plug vmlinux EXPORT_SYMBOL -+0xa67752f3 bdevname vmlinux EXPORT_SYMBOL -+0x3d4d9f3c cdev_init vmlinux EXPORT_SYMBOL -+0xbe63ee40 request_resource vmlinux EXPORT_SYMBOL -+0x697cbbb4 threads_per_core vmlinux EXPORT_SYMBOL_GPL -+0xc24dd028 nf_ct_expect_init net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x98ed718a inet_getname vmlinux EXPORT_SYMBOL -+0xe7609b0d generate_netlink_event vmlinux EXPORT_SYMBOL -+0x85e7deb2 iov_iter_fault_in_readable vmlinux EXPORT_SYMBOL -+0x15e9ff97 module_mutex vmlinux EXPORT_SYMBOL_GPL -+0xf5a62ecc _memset_io vmlinux EXPORT_SYMBOL -+0x7c1ac45d put_mtd_device vmlinux EXPORT_SYMBOL_GPL -+0xbf9bcc8d __cap_empty_set vmlinux EXPORT_SYMBOL -+0xe2504d65 xprt_register_transport vmlinux EXPORT_SYMBOL_GPL -+0xe0ead969 i2c_smbus_process_call vmlinux EXPORT_SYMBOL -+0x313f13aa platform_get_resource vmlinux EXPORT_SYMBOL_GPL -+0x42b7e450 pci_disable_pcie_error_reporting vmlinux EXPORT_SYMBOL_GPL -+0xfed042ab crypto_shoot_alg vmlinux EXPORT_SYMBOL_GPL -+0xf37d86d3 iput vmlinux EXPORT_SYMBOL -+0x245a5a94 sleep_on_timeout vmlinux EXPORT_SYMBOL -+0x30a3ce2d xprt_complete_rqst vmlinux EXPORT_SYMBOL_GPL -+0x28a82da4 snmp_mib_init vmlinux EXPORT_SYMBOL_GPL -+0xd91b9062 input_ff_upload vmlinux EXPORT_SYMBOL_GPL -+0x072e69d7 create_proc_entry vmlinux EXPORT_SYMBOL -+0x03fd2571 vm_unmap_ram vmlinux EXPORT_SYMBOL -+0xd39230da proc_doulongvec_ms_jiffies_minmax vmlinux EXPORT_SYMBOL -+0x2d2f8405 xfrm_output vmlinux EXPORT_SYMBOL_GPL -+0x62dd148f of_phy_connect vmlinux EXPORT_SYMBOL -+0x796ef373 pci_enable_device_mem vmlinux EXPORT_SYMBOL -+0xeea9dbaf bitmap_bitremap vmlinux EXPORT_SYMBOL -+0x71a50dbc register_blkdev vmlinux EXPORT_SYMBOL -+0xe1ead0f9 nf_conntrack_alter_reply net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x596ca373 neigh_event_ns vmlinux EXPORT_SYMBOL -+0x88aa1b8c sdhci_free_host vmlinux EXPORT_SYMBOL_GPL -+0xe58fb452 aer_irq vmlinux EXPORT_SYMBOL_GPL -+0x76e3aed7 elevator_change vmlinux EXPORT_SYMBOL -+0x14dc18d8 iterate_supers_type vmlinux EXPORT_SYMBOL -+0x2285200f usb_kill_anchored_urbs vmlinux EXPORT_SYMBOL_GPL -+0x09775cdc kref_get vmlinux EXPORT_SYMBOL -+0x1f46d410 netdev_change_features vmlinux EXPORT_SYMBOL -+0xaa27750a init_dummy_netdev vmlinux EXPORT_SYMBOL_GPL -+0x9e4f1cfb ring_buffer_resize vmlinux EXPORT_SYMBOL_GPL -+0xcb0c622b dst_destroy vmlinux EXPORT_SYMBOL -+0xc4b45e74 pci_disable_rom vmlinux EXPORT_SYMBOL_GPL -+0x443ddc6e pci_disable_ido vmlinux EXPORT_SYMBOL -+0x21962aa1 pci_disable_ltr vmlinux EXPORT_SYMBOL -+0x2c8d9ecf journal_errno vmlinux EXPORT_SYMBOL -+0x78e988ed svc_wake_up vmlinux EXPORT_SYMBOL_GPL -+0x3e4a8504 xprt_write_space vmlinux EXPORT_SYMBOL_GPL -+0x61a39807 ndisc_send_skb vmlinux EXPORT_SYMBOL -+0x2ab23b9b nf_unregister_queue_handlers vmlinux EXPORT_SYMBOL_GPL -+0x3f2f77c8 mtd_blktrans_cease_background vmlinux EXPORT_SYMBOL_GPL -+0x70a7409f scsi_mode_sense vmlinux EXPORT_SYMBOL -+0x2d89342a scsi_show_sense_hdr vmlinux EXPORT_SYMBOL -+0xe87b346a pci_enable_ltr vmlinux EXPORT_SYMBOL -+0x2e5a7064 journal_check_available_features vmlinux EXPORT_SYMBOL -+0x78ed3e5c __init_waitqueue_head vmlinux EXPORT_SYMBOL -+0x836afd32 nf_ct_get_tuple net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x989fa19e xfrm6_tunnel_register net/ipv6/tunnel6 EXPORT_SYMBOL -+0x3d961c15 xfrm4_tunnel_register net/ipv4/tunnel4 EXPORT_SYMBOL -+0x405d6987 of_property_read_u64 vmlinux EXPORT_SYMBOL_GPL -+0x20edb24a blk_insert_cloned_request vmlinux EXPORT_SYMBOL_GPL -+0x6f4b609a init_timer_deferrable_key vmlinux EXPORT_SYMBOL -+0x2dc5379b skb_copy_datagram_from_iovec vmlinux EXPORT_SYMBOL -+0x5f8a2728 isa_io_base vmlinux EXPORT_SYMBOL -+0x907fa9b5 dst_alloc vmlinux EXPORT_SYMBOL -+0xe93e49c3 devres_free vmlinux EXPORT_SYMBOL_GPL -+0x84ecb7cb timerqueue_iterate_next vmlinux EXPORT_SYMBOL_GPL -+0x1fad8e64 blk_put_queue vmlinux EXPORT_SYMBOL -+0xa5df3b80 single_release vmlinux EXPORT_SYMBOL -+0x23663ac5 get_user_pages vmlinux EXPORT_SYMBOL -+0xa108eb4d sysctl_optmem_max vmlinux EXPORT_SYMBOL -+0x14b1b51c enable_kernel_spe vmlinux EXPORT_SYMBOL -+0xe57878a1 in6_pton vmlinux EXPORT_SYMBOL -+0xaccabc6a in4_pton vmlinux EXPORT_SYMBOL -+0xd55d1a4c of_get_mac_address vmlinux EXPORT_SYMBOL -+0x30d70fa9 of_get_pci_address vmlinux EXPORT_SYMBOL -+0x02b1d92b scsi_mode_select vmlinux EXPORT_SYMBOL_GPL -+0xd0181f4f __bitmap_xor vmlinux EXPORT_SYMBOL -+0xed746f71 mnt_want_write vmlinux EXPORT_SYMBOL_GPL -+0xf3341268 __clear_user vmlinux EXPORT_SYMBOL -+0x9d14983a ppc_enable_pmcs vmlinux EXPORT_SYMBOL -+0x519e4247 xprt_lock_and_alloc_slot vmlinux EXPORT_SYMBOL_GPL -+0x62bdb353 __dev_remove_pack vmlinux EXPORT_SYMBOL -+0x1aa8db0c __starget_for_each_device vmlinux EXPORT_SYMBOL -+0x90a1004a crypto_has_alg vmlinux EXPORT_SYMBOL_GPL -+0xd6321e2a iget5_locked vmlinux EXPORT_SYMBOL -+0x3dcb88a0 irq_set_handler_data vmlinux EXPORT_SYMBOL -+0xa5a4e6a7 yield_to vmlinux EXPORT_SYMBOL_GPL -+0x8056c327 mii_check_media vmlinux EXPORT_SYMBOL -+0xc47af61f user_revoke vmlinux EXPORT_SYMBOL -+0x0b263573 debugfs_create_dir vmlinux EXPORT_SYMBOL_GPL -+0xb23b2262 dcache_dir_lseek vmlinux EXPORT_SYMBOL -+0x0c2cdbf1 synchronize_sched vmlinux EXPORT_SYMBOL_GPL -+0x6fff393f time_to_tm vmlinux EXPORT_SYMBOL -+0x651a4139 test_taint vmlinux EXPORT_SYMBOL -+0x6b7d903c netdev_printk vmlinux EXPORT_SYMBOL -+0x8dad55e8 of_address_to_resource vmlinux EXPORT_SYMBOL_GPL -+0x90b3ac7f thermal_zone_device_register vmlinux EXPORT_SYMBOL -+0x73cd0f30 pci_scan_bus_parented vmlinux EXPORT_SYMBOL -+0xf5a691cd invalidate_bh_lrus vmlinux EXPORT_SYMBOL_GPL -+0x518889d8 ipcomp_init_state net/xfrm/xfrm_ipcomp EXPORT_SYMBOL_GPL -+0x90599000 xt_check_match vmlinux EXPORT_SYMBOL_GPL -+0x41cb6ae6 cfi_qry_mode_on vmlinux EXPORT_SYMBOL_GPL -+0x32c3cb4e class_compat_register vmlinux EXPORT_SYMBOL_GPL -+0x24aac4d9 crypto_aes_expand_key vmlinux EXPORT_SYMBOL_GPL -+0x1eb914cc d_splice_alias vmlinux EXPORT_SYMBOL -+0x038de4b7 do_sync_read vmlinux EXPORT_SYMBOL -+0x5be5cfd3 mem_map vmlinux EXPORT_SYMBOL -+0xfedd35fc console_suspend_enabled vmlinux EXPORT_SYMBOL -+0x78f9b710 nf_ct_l3proto_try_module_get net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x199f8f28 svc_reg_xprt_class vmlinux EXPORT_SYMBOL_GPL -+0x40b1319f sdio_release_irq vmlinux EXPORT_SYMBOL_GPL -+0x6986e70b mmc_wait_for_cmd vmlinux EXPORT_SYMBOL -+0x59c20bea kobject_rename vmlinux EXPORT_SYMBOL_GPL -+0x72aa82c6 param_ops_charp vmlinux EXPORT_SYMBOL -+0x8a0e5ca2 rpc_mkpipe vmlinux EXPORT_SYMBOL_GPL -+0x9854bf90 cad_pid vmlinux EXPORT_SYMBOL -+0x5a5a94a6 kstrtou8 vmlinux EXPORT_SYMBOL -+0xb0477a75 get_task_pid vmlinux EXPORT_SYMBOL_GPL -+0x85478a0b inet6_hash_frag vmlinux EXPORT_SYMBOL_GPL -+0x6849a15f flex_array_clear vmlinux EXPORT_SYMBOL -+0x5a7bfe41 crypto_probing_notify vmlinux EXPORT_SYMBOL_GPL -+0xf0a118b4 ip6t_alloc_initial_table net/ipv6/netfilter/ip6_tables EXPORT_SYMBOL_GPL -+0x9ef5eb8e netif_receive_skb vmlinux EXPORT_SYMBOL -+0x196d40cb spi_new_device vmlinux EXPORT_SYMBOL_GPL -+0xc906a49f journal_update_format vmlinux EXPORT_SYMBOL -+0xfb6af58d recalc_sigpending vmlinux EXPORT_SYMBOL -+0x5fc7e979 nf_nat_proto_unique_tuple net/ipv4/netfilter/nf_nat EXPORT_SYMBOL_GPL -+0xdcb45617 nf_nat_mangle_udp_packet net/ipv4/netfilter/nf_nat EXPORT_SYMBOL -+0xaeb5ccdc anon_transport_class_register vmlinux EXPORT_SYMBOL_GPL -+0xf39ae0fb disk_part_iter_exit vmlinux EXPORT_SYMBOL_GPL -+0x6c85445f follow_down_one vmlinux EXPORT_SYMBOL -+0x7944e0fc tracing_off vmlinux EXPORT_SYMBOL_GPL -+0x9fa181ba rpcauth_init_credcache vmlinux EXPORT_SYMBOL_GPL -+0x81c6ed08 raw_seq_next vmlinux EXPORT_SYMBOL_GPL -+0x05f187fd ip_setsockopt vmlinux EXPORT_SYMBOL -+0x1c72d333 ip_getsockopt vmlinux EXPORT_SYMBOL -+0x38074cf6 qdisc_watchdog_schedule vmlinux EXPORT_SYMBOL -+0xed709aff tty_encode_baud_rate vmlinux EXPORT_SYMBOL_GPL -+0x80dd3e42 blk_unprep_request vmlinux EXPORT_SYMBOL_GPL -+0x6e50c56b xdr_shift_buf vmlinux EXPORT_SYMBOL_GPL -+0xf106c813 ip_options_rcv_srr vmlinux EXPORT_SYMBOL -+0x9a5a79fd device_register vmlinux EXPORT_SYMBOL_GPL -+0x3ca8a6b3 pcim_iomap_regions_request_all vmlinux EXPORT_SYMBOL -+0xc159495b dentry_open vmlinux EXPORT_SYMBOL -+0xbb2b98fa skb_checksum_help vmlinux EXPORT_SYMBOL -+0x60ee6103 unregister_netdevice_queue vmlinux EXPORT_SYMBOL -+0x40a27c37 scsi_dev_info_remove_list vmlinux EXPORT_SYMBOL -+0x9545af6d tasklet_init vmlinux EXPORT_SYMBOL -+0x68a29b9a nf_nat_setup_info net/ipv4/netfilter/nf_nat EXPORT_SYMBOL -+0xdf56dcb2 stop_machine vmlinux EXPORT_SYMBOL_GPL -+0x53986488 register_die_notifier vmlinux EXPORT_SYMBOL_GPL -+0x580dfef9 nf_ct_unlink_expect_report net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x3257c865 sock_no_recvmsg vmlinux EXPORT_SYMBOL -+0x6a2126c6 hrtimer_cancel vmlinux EXPORT_SYMBOL_GPL -+0x0a22b996 xt_unregister_matches vmlinux EXPORT_SYMBOL -+0xfdfc0b3b fiemap_fill_next_extent vmlinux EXPORT_SYMBOL -+0x4087f0c0 qdisc_watchdog_cancel vmlinux EXPORT_SYMBOL -+0x4ce6c680 crypto_shash_digest vmlinux EXPORT_SYMBOL_GPL -+0xe8d8b9c7 crypto_ahash_digest vmlinux EXPORT_SYMBOL_GPL -+0x3de9cae1 crypto_remove_final vmlinux EXPORT_SYMBOL_GPL -+0x296b5561 svc_authenticate vmlinux EXPORT_SYMBOL_GPL -+0xd0108d65 rtnl_set_sk_err vmlinux EXPORT_SYMBOL -+0x4865167d usb_hcd_pci_remove vmlinux EXPORT_SYMBOL_GPL -+0xec9ca601 driver_add_kobj vmlinux EXPORT_SYMBOL_GPL -+0x89797060 _raw_read_lock vmlinux EXPORT_SYMBOL -+0x897f061d downgrade_write vmlinux EXPORT_SYMBOL -+0x5568c553 complete vmlinux EXPORT_SYMBOL -+0x6fd12bcc ip_check_defrag vmlinux EXPORT_SYMBOL -+0xdb864d65 iov_iter_single_seg_count vmlinux EXPORT_SYMBOL -+0x9c44f35a scsi_test_unit_ready vmlinux EXPORT_SYMBOL -+0xad37975e dentry_update_name_case vmlinux EXPORT_SYMBOL -+0x8a7d1c31 high_memory vmlinux EXPORT_SYMBOL -+0xd7b213fa smp_call_function_many vmlinux EXPORT_SYMBOL -+0xbdb6ee0c usb_serial_deregister vmlinux EXPORT_SYMBOL_GPL -+0x4d9edeae simple_link vmlinux EXPORT_SYMBOL -+0xbdd2f42a rcu_bh_force_quiescent_state vmlinux EXPORT_SYMBOL_GPL -+0xc458c88f hidinput_find_field vmlinux EXPORT_SYMBOL_GPL -+0x4a6c3f1a usb_serial_suspend vmlinux EXPORT_SYMBOL -+0x14193672 scsi_remove_target vmlinux EXPORT_SYMBOL -+0xb6c5a973 scsi_show_result vmlinux EXPORT_SYMBOL -+0x03e32c1d sysdev_remove_file vmlinux EXPORT_SYMBOL_GPL -+0x99faa353 journal_blocks_per_page vmlinux EXPORT_SYMBOL -+0x63b8f6ef page_cache_async_readahead vmlinux EXPORT_SYMBOL_GPL -+0x8de0b5ac mempool_create vmlinux EXPORT_SYMBOL -+0xe3a98a71 kblockd_schedule_work vmlinux EXPORT_SYMBOL -+0x79d654ef send_sig_info vmlinux EXPORT_SYMBOL -+0x20030ecd ioremap vmlinux EXPORT_SYMBOL -+0xedc03953 iounmap vmlinux EXPORT_SYMBOL -+0xc865db6b xprt_release_xprt vmlinux EXPORT_SYMBOL_GPL -+0xc628e72a __neigh_event_send vmlinux EXPORT_SYMBOL -+0x0c61e098 sk_stream_wait_close vmlinux EXPORT_SYMBOL -+0x3c396f87 show_class_attr_string vmlinux EXPORT_SYMBOL_GPL -+0x441257b7 sysdev_store_int vmlinux EXPORT_SYMBOL_GPL -+0xf3970f1b read_cache_page_async vmlinux EXPORT_SYMBOL -+0xd0ee38b8 schedule_timeout_uninterruptible vmlinux EXPORT_SYMBOL -+0xd79b5a02 allow_signal vmlinux EXPORT_SYMBOL -+0xd3081dfa qe_upload_firmware vmlinux EXPORT_SYMBOL -+0xf4d880ae platform_get_irq vmlinux EXPORT_SYMBOL_GPL -+0x0781bf45 kill_anon_super vmlinux EXPORT_SYMBOL -+0x6676c50d nf_ct_delete_from_lists net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x730d37a5 xfrm6_rcv vmlinux EXPORT_SYMBOL -+0x119a95b0 xfrm4_rcv vmlinux EXPORT_SYMBOL -+0x309ea25a pci_enable_pcie_error_reporting vmlinux EXPORT_SYMBOL_GPL -+0x88ddfe5e xdr_buf_subsegment vmlinux EXPORT_SYMBOL_GPL -+0xed08815e inet_dgram_connect vmlinux EXPORT_SYMBOL -+0x715fb53b usb_find_alt_setting vmlinux EXPORT_SYMBOL_GPL -+0x0f6fbd82 phy_connect vmlinux EXPORT_SYMBOL -+0x34ab3ee2 driver_unregister vmlinux EXPORT_SYMBOL_GPL -+0xc87f94e8 generic_pipe_buf_unmap vmlinux EXPORT_SYMBOL -+0xddd4147d generic_pipe_buf_steal vmlinux EXPORT_SYMBOL -+0xa2c56c31 param_ops_ulong vmlinux EXPORT_SYMBOL -+0x01ca7533 inet_frags_exit_net vmlinux EXPORT_SYMBOL -+0x8e4b1069 kobject_get vmlinux EXPORT_SYMBOL -+0x3fb18605 kobject_put vmlinux EXPORT_SYMBOL -+0x9d033f64 nfs4_reset_write vmlinux EXPORT_SYMBOL_GPL -+0x46214106 files_lglock_local_unlock_cpu vmlinux EXPORT_SYMBOL -+0x58688735 relay_open vmlinux EXPORT_SYMBOL_GPL -+0x4029d238 param_set_copystring vmlinux EXPORT_SYMBOL -+0x59e70f93 __send_remote_softirq vmlinux EXPORT_SYMBOL -+0x2afbe2a5 usb_scuttle_anchored_urbs vmlinux EXPORT_SYMBOL_GPL -+0x51cc13a8 cfi_read_pri vmlinux EXPORT_SYMBOL -+0xf1deabf2 div64_u64 vmlinux EXPORT_SYMBOL -+0x52b34107 relay_close vmlinux EXPORT_SYMBOL_GPL -+0xfc39e32f ioport_unmap vmlinux EXPORT_SYMBOL -+0xbe3ce140 usb_reset_configuration vmlinux EXPORT_SYMBOL_GPL -+0x03dd0aff sysfs_merge_group vmlinux EXPORT_SYMBOL_GPL -+0xc84a0a7e seq_hlist_start_rcu vmlinux EXPORT_SYMBOL -+0xcdada4b3 d_validate vmlinux EXPORT_SYMBOL -+0xb2ebe0b7 __get_user_pages_fast vmlinux EXPORT_SYMBOL_GPL -+0x7bcc3ec6 down_trylock vmlinux EXPORT_SYMBOL -+0x16b67679 genl_register_family vmlinux EXPORT_SYMBOL -+0xc256e762 __bitmap_equal vmlinux EXPORT_SYMBOL -+0x019e7765 __init_rwsem vmlinux EXPORT_SYMBOL -+0x5342878d page_zero_new_buffers vmlinux EXPORT_SYMBOL -+0x7a6737e5 mntget vmlinux EXPORT_SYMBOL -+0x61406732 mntput vmlinux EXPORT_SYMBOL -+0x4f62563b fasync_helper vmlinux EXPORT_SYMBOL -+0x64203ccb mount_mtd vmlinux EXPORT_SYMBOL_GPL -+0x2f4113a2 dcookie_register vmlinux EXPORT_SYMBOL_GPL -+0xeee9690b locks_mandatory_area vmlinux EXPORT_SYMBOL -+0x99060d85 inet_twsk_deschedule vmlinux EXPORT_SYMBOL -+0x140d6513 xt_table_unlock vmlinux EXPORT_SYMBOL_GPL -+0x88b210e6 ethtool_op_set_ufo vmlinux EXPORT_SYMBOL -+0xb887455c sock_alloc_send_pskb vmlinux EXPORT_SYMBOL -+0x0acb1a3c __bitmap_shift_right vmlinux EXPORT_SYMBOL -+0x402b8281 __request_module vmlinux EXPORT_SYMBOL -+0xba215bc2 inet_register_protosw vmlinux EXPORT_SYMBOL -+0x9e041871 __inet_inherit_port vmlinux EXPORT_SYMBOL_GPL -+0x2b4f08e0 dev_deactivate vmlinux EXPORT_SYMBOL -+0x8eed09dc phy_find_first vmlinux EXPORT_SYMBOL -+0xb89af9bf srandom32 vmlinux EXPORT_SYMBOL -+0x23fd3028 vmalloc_node vmlinux EXPORT_SYMBOL -+0x891fbb10 mempool_destroy vmlinux EXPORT_SYMBOL -+0x054e550b kernel_halt vmlinux EXPORT_SYMBOL_GPL -+0xe0b0b13d xfrm6_tunnel_spi_lookup net/ipv6/xfrm6_tunnel EXPORT_SYMBOL -+0xe7a8d75d netpoll_cleanup vmlinux EXPORT_SYMBOL -+0x62005346 scsi_ioctl vmlinux EXPORT_SYMBOL -+0xe7bd56ce set_binfmt vmlinux EXPORT_SYMBOL -+0x9933f8fa km_policy_expired vmlinux EXPORT_SYMBOL -+0xdff2d6cd spi_unregister_master vmlinux EXPORT_SYMBOL_GPL -+0xae973946 __first_cpu vmlinux EXPORT_SYMBOL -+0xe2a6904b elv_rb_find vmlinux EXPORT_SYMBOL -+0xbee90f2f __kfifo_out_peek_r vmlinux EXPORT_SYMBOL -+0xa04a01bd qdisc_class_hash_insert vmlinux EXPORT_SYMBOL -+0xe5867808 dlci_ioctl_set vmlinux EXPORT_SYMBOL -+0x13e1e53c crypto_alg_lookup vmlinux EXPORT_SYMBOL_GPL -+0x8b4ac748 __rpc_wait_for_completion_task vmlinux EXPORT_SYMBOL_GPL -+0x742ec05d ethtool_op_set_tx_ipv6_csum vmlinux EXPORT_SYMBOL -+0x6195e83d scsi_report_device_reset vmlinux EXPORT_SYMBOL -+0x21e29754 scsi_print_sense vmlinux EXPORT_SYMBOL -+0xa34a1e0b locks_free_lock vmlinux EXPORT_SYMBOL -+0xe71c31f7 simple_attr_release vmlinux EXPORT_SYMBOL_GPL -+0xed120683 usb_submit_urb vmlinux EXPORT_SYMBOL_GPL -+0x928dc8b5 rename_lock vmlinux EXPORT_SYMBOL -+0xdebe699e page_symlink_inode_operations vmlinux EXPORT_SYMBOL -+0x99afe916 _raw_write_unlock_bh vmlinux EXPORT_SYMBOL -+0x060ea2d6 kstrtoull vmlinux EXPORT_SYMBOL -+0x5ac15bae kstrtou16 vmlinux EXPORT_SYMBOL -+0x94961283 vunmap vmlinux EXPORT_SYMBOL -+0xc97eeec5 write_cache_pages vmlinux EXPORT_SYMBOL -+0x160a0cad nf_conntrack_l4proto_tcp6 net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x3b21e0c3 xfrm_policy_alloc vmlinux EXPORT_SYMBOL -+0x81b8ae05 __nf_ct_ext_add net/netfilter/nf_conntrack EXPORT_SYMBOL -+0x117093be qdisc_class_hash_init vmlinux EXPORT_SYMBOL -+0xd4fb8ce7 sk_prot_clear_portaddr_nulls vmlinux EXPORT_SYMBOL -+0x787ae952 mtd_del_partition vmlinux EXPORT_SYMBOL_GPL -+0x25f3bd2e atomic64_xchg vmlinux EXPORT_SYMBOL -+0xfcc95cae task_current_syscall vmlinux EXPORT_SYMBOL_GPL -+0x574ed83f single_open_net vmlinux EXPORT_SYMBOL_GPL -+0xcc4c11c3 set_page_dirty_lock vmlinux EXPORT_SYMBOL -+0x8bc74143 tcp_v4_conn_request vmlinux EXPORT_SYMBOL -+0xeace373d usb_get_descriptor vmlinux EXPORT_SYMBOL_GPL -+0xf7064a0d spi_async_locked vmlinux EXPORT_SYMBOL_GPL -+0xca62af4c get_mtd_device vmlinux EXPORT_SYMBOL_GPL -+0x4897a00b blk_rq_init vmlinux EXPORT_SYMBOL -+0x26e76fb8 sysctl_udp_wmem_min vmlinux EXPORT_SYMBOL -+0x60b3b58a tcp_v4_syn_recv_sock vmlinux EXPORT_SYMBOL -+0x906c274e usb_put_dev vmlinux EXPORT_SYMBOL_GPL -+0xa7b0d968 swiotlb_tbl_sync_single vmlinux EXPORT_SYMBOL_GPL -+0x6d464175 __sg_free_table vmlinux EXPORT_SYMBOL -+0x4d6c0e8d kmem_cache_shrink vmlinux EXPORT_SYMBOL -+0x10d9d048 icmp_err_convert vmlinux EXPORT_SYMBOL -+0xf67a2d46 mii_check_link vmlinux EXPORT_SYMBOL -+0xd334a2bd tcp_hashinfo vmlinux EXPORT_SYMBOL -+0x2d140a58 genl_unlock vmlinux EXPORT_SYMBOL -+0x4256c8a3 of_n_size_cells vmlinux EXPORT_SYMBOL -+0xf040786d hid_report_raw_event vmlinux EXPORT_SYMBOL_GPL -+0x8c70d5ae scsi_unregister vmlinux EXPORT_SYMBOL -+0x0087d496 crypto_aead_setauthsize vmlinux EXPORT_SYMBOL_GPL -+0x5676c702 nlmclnt_init vmlinux EXPORT_SYMBOL_GPL -+0xcb09bf1a fd_install vmlinux EXPORT_SYMBOL -+0x4c11435a _raw_read_lock_bh vmlinux EXPORT_SYMBOL -+0x7681e3ba nf_nat_used_tuple net/ipv4/netfilter/nf_nat EXPORT_SYMBOL -+0xc927923a nf_nat_packet net/ipv4/netfilter/nf_nat EXPORT_SYMBOL_GPL -+0x9b8f7dca scsi_internal_device_unblock vmlinux EXPORT_SYMBOL_GPL -+0xbee5153c blk_init_tags vmlinux EXPORT_SYMBOL -+0x0d7d89ce vfs_fsync_range vmlinux EXPORT_SYMBOL -+0x3ce4ca6f disable_irq vmlinux EXPORT_SYMBOL -+0x87754115 raw_notifier_chain_register vmlinux EXPORT_SYMBOL_GPL -+0x20f357ca scsi_host_alloc vmlinux EXPORT_SYMBOL -+0xee146e0a bus_get_device_klist vmlinux EXPORT_SYMBOL_GPL -+0xd25133ac sysfs_remove_file vmlinux EXPORT_SYMBOL_GPL -+0x889d27ce path_put vmlinux EXPORT_SYMBOL -+0x5a9f996e apply_to_page_range vmlinux EXPORT_SYMBOL_GPL -+0xa0ceef51 out_of_line_wait_on_bit vmlinux EXPORT_SYMBOL -+0x70aca666 dst_discard vmlinux EXPORT_SYMBOL -+0xaa2a72bf __iowrite64_copy vmlinux EXPORT_SYMBOL_GPL -+0xf1bcf383 invalidate_partition vmlinux EXPORT_SYMBOL -+0xc26b1d80 kick_process vmlinux EXPORT_SYMBOL_GPL -+0xea41576c sk_release_kernel vmlinux EXPORT_SYMBOL -+0x13701441 sg_miter_stop vmlinux EXPORT_SYMBOL -+0x6f5febee key_reject_and_link vmlinux EXPORT_SYMBOL -+0xe4fe8ca1 _raw_spin_unlock_bh vmlinux EXPORT_SYMBOL -+0xc4aa788d xt_proto_init vmlinux EXPORT_SYMBOL_GPL -+0xdd1c65f6 blk_finish_plug vmlinux EXPORT_SYMBOL -+0x0b1beb31 vmalloc_32_user vmlinux EXPORT_SYMBOL -+0x756f9875 pci_get_subsys vmlinux EXPORT_SYMBOL -+0x9eecde16 do_brk vmlinux EXPORT_SYMBOL -+0x878ab3ce sysctl_tcp_adv_win_scale vmlinux EXPORT_SYMBOL -+0x7d32f0ad ip_local_out vmlinux EXPORT_SYMBOL_GPL -+0xe163a0d1 usb_hcd_check_unlink_urb vmlinux EXPORT_SYMBOL_GPL -+0xb1a9725f phy_device_free vmlinux EXPORT_SYMBOL -+0xb0104373 generic_permission vmlinux EXPORT_SYMBOL -+0xd59668e6 unlock_flocks vmlinux EXPORT_SYMBOL_GPL -+0xd7b7c7e4 uart_get_baud_rate vmlinux EXPORT_SYMBOL -+0xd6d2bfe8 pci_find_next_bus vmlinux EXPORT_SYMBOL -+0x9d3aa376 blk_iopoll_init vmlinux EXPORT_SYMBOL -+0xcbc2c8dd atomic_notifier_chain_unregister vmlinux EXPORT_SYMBOL_GPL -+0x8ba65b48 secpath_dup vmlinux EXPORT_SYMBOL -+0xe1b3830a set_user_nice vmlinux EXPORT_SYMBOL -+0x35c4c2bc gss_pseudoflavor_to_service vmlinux EXPORT_SYMBOL_GPL -+0xe7d71ad5 splice_direct_to_actor vmlinux EXPORT_SYMBOL -+0xf34806ec hrtimer_get_res vmlinux EXPORT_SYMBOL_GPL -+0x7d1541f1 nf_nat_pptp_hook_inbound net/netfilter/nf_conntrack_pptp EXPORT_SYMBOL_GPL -+0x1fdf5145 nf_conntrack_l3proto_unregister net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x895b81a5 nf_conntrack_l4proto_unregister net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x2b9da7a4 genl_lock vmlinux EXPORT_SYMBOL -+0x2d187f6f qdisc_class_hash_grow vmlinux EXPORT_SYMBOL -+0x7528c327 sock_setsockopt vmlinux EXPORT_SYMBOL -+0x7587dd64 tty_port_close_start vmlinux EXPORT_SYMBOL -+0x074989f8 ida_simple_remove vmlinux EXPORT_SYMBOL -+0xdfc46245 unlock_buffer vmlinux EXPORT_SYMBOL -+0x3429114e simple_transaction_release vmlinux EXPORT_SYMBOL -+0x5e4d4180 nfulnl_log_packet net/netfilter/nfnetlink_log EXPORT_SYMBOL_GPL -+0x01010c6d klist_add_before vmlinux EXPORT_SYMBOL_GPL -+0x9cb96e92 qdisc_put_rtab vmlinux EXPORT_SYMBOL -+0x91fd73a4 subsys_find_device_by_id vmlinux EXPORT_SYMBOL_GPL -+0x093e125a crypto_attr_alg2 vmlinux EXPORT_SYMBOL_GPL -+0xfc01e0ca nfs_commit_free vmlinux EXPORT_SYMBOL_GPL -+0x1176e07f __per_cpu_offset vmlinux EXPORT_SYMBOL -+0xbbcd407c proto_register vmlinux EXPORT_SYMBOL -+0x175b8a58 rtc_irq_unregister vmlinux EXPORT_SYMBOL_GPL -+0x9c7a72be tty_wakeup vmlinux EXPORT_SYMBOL_GPL -+0xb1f5c533 check_disk_size_change vmlinux EXPORT_SYMBOL -+0x33839ed8 d_clear_need_lookup vmlinux EXPORT_SYMBOL -+0xbc3f6afa down_read vmlinux EXPORT_SYMBOL -+0x5850f4cd km_report vmlinux EXPORT_SYMBOL -+0x1694ba86 __napi_complete vmlinux EXPORT_SYMBOL -+0xc3bc62fb skb_copy_expand vmlinux EXPORT_SYMBOL -+0xabd0c91c rtc_time_to_tm vmlinux EXPORT_SYMBOL -+0x274f1f9b dmam_free_coherent vmlinux EXPORT_SYMBOL -+0x98c6103a transport_setup_device vmlinux EXPORT_SYMBOL_GPL -+0x3da3a6f5 blk_queue_softirq_done vmlinux EXPORT_SYMBOL -+0x190c3ccc d_lookup vmlinux EXPORT_SYMBOL -+0xabdd83b5 genl_unregister_mc_group vmlinux EXPORT_SYMBOL -+0xf811e69d scsi_eh_flush_done_q vmlinux EXPORT_SYMBOL -+0x99f66401 path_is_under vmlinux EXPORT_SYMBOL -+0xfa590506 pci_iomap vmlinux EXPORT_SYMBOL -+0xa8119c49 xt_hook_unlink vmlinux EXPORT_SYMBOL_GPL -+0xc6435be3 skb_morph vmlinux EXPORT_SYMBOL_GPL -+0xdb0c48bb mmc_erase vmlinux EXPORT_SYMBOL -+0x8baf3116 percpu_counter_set vmlinux EXPORT_SYMBOL -+0x61a90c54 klist_add_head vmlinux EXPORT_SYMBOL_GPL -+0x5269ab27 ethtool_op_set_flags vmlinux EXPORT_SYMBOL -+0x7701acae scsi_remove_host vmlinux EXPORT_SYMBOL -+0x2c88b964 pci_request_selected_regions_exclusive vmlinux EXPORT_SYMBOL -+0xb6822a33 radix_tree_gang_lookup_tag vmlinux EXPORT_SYMBOL -+0xe8e99f5c flush_dcache_page vmlinux EXPORT_SYMBOL -+0xf4449388 timer_interrupt vmlinux EXPORT_SYMBOL -+0x12aab7d1 scsi_is_host_device vmlinux EXPORT_SYMBOL -+0x36ca51ab devm_ioremap_nocache vmlinux EXPORT_SYMBOL -+0xf370333d sync_dirty_buffer vmlinux EXPORT_SYMBOL -+0x6c81fae0 tcp_reno_ssthresh vmlinux EXPORT_SYMBOL_GPL -+0xca461664 netlink_has_listeners vmlinux EXPORT_SYMBOL_GPL -+0xc761c4bf pci_remove_bus_device vmlinux EXPORT_SYMBOL -+0xe075d6eb iter_div_u64_rem vmlinux EXPORT_SYMBOL -+0xd6c9eb4a nf_nat_seq_adjust_hook net/ipv4/netfilter/nf_conntrack_ipv4 EXPORT_SYMBOL_GPL -+0x53bce6b9 usb_alloc_urb vmlinux EXPORT_SYMBOL_GPL -+0x876e5b30 spi_setup vmlinux EXPORT_SYMBOL_GPL -+0x205125b9 __pci_enable_wake vmlinux EXPORT_SYMBOL -+0x1f0ffbff inode_init_once vmlinux EXPORT_SYMBOL -+0x73d69364 ring_buffer_change_overwrite vmlinux EXPORT_SYMBOL_GPL -+0x7fc827a5 __srcu_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL -+0x5bc2e5a1 nf_ip6_checksum vmlinux EXPORT_SYMBOL -+0xeec2364d netpoll_send_skb_on_dev vmlinux EXPORT_SYMBOL -+0x7879bfc8 device_move vmlinux EXPORT_SYMBOL_GPL -+0xc19d6d2b scsi_cmd_ioctl vmlinux EXPORT_SYMBOL -+0x4a22c7b5 neigh_seq_stop vmlinux EXPORT_SYMBOL -+0xfad37936 usb_stor_clear_halt vmlinux EXPORT_SYMBOL_GPL -+0x77fa5d1f ns_to_timespec vmlinux EXPORT_SYMBOL -+0x95c6c48a qe_pin_set_gpio vmlinux EXPORT_SYMBOL -+0xed93f29e __kunmap_atomic vmlinux EXPORT_SYMBOL -+0x8ff80bf7 dev_mc_del_global vmlinux EXPORT_SYMBOL -+0x14880357 dev_mc_add_global vmlinux EXPORT_SYMBOL -+0x99525e3a vfsmount_lock_local_unlock vmlinux EXPORT_SYMBOL -+0xdb7cbcf1 blocking_notifier_chain_unregister vmlinux EXPORT_SYMBOL_GPL -+0x5651fb34 fifo_create_dflt vmlinux EXPORT_SYMBOL -+0x82a1419b neigh_table_init vmlinux EXPORT_SYMBOL -+0x89c4cbce mmc_register_driver vmlinux EXPORT_SYMBOL -+0x38a9c2c7 input_ff_effect_from_user vmlinux EXPORT_SYMBOL_GPL -+0x737e3d28 attribute_container_register vmlinux EXPORT_SYMBOL_GPL -+0x71da73ee blk_queue_segment_boundary vmlinux EXPORT_SYMBOL -+0x76c6ee5c blk_stop_queue vmlinux EXPORT_SYMBOL -+0x40979bcc blk_insert_request vmlinux EXPORT_SYMBOL -+0xea3210a9 blkcipher_walk_virt_block vmlinux EXPORT_SYMBOL_GPL -+0xa2bc62ac sysfs_create_link vmlinux EXPORT_SYMBOL_GPL -+0x3be9e6e8 task_active_pid_ns vmlinux EXPORT_SYMBOL_GPL -+0x94a08134 nf_nat_proto_nlattr_to_range net/ipv4/netfilter/nf_nat EXPORT_SYMBOL_GPL -+0x44dded3f svc_set_client vmlinux EXPORT_SYMBOL_GPL -+0x411b3b69 pci_add_dynid vmlinux EXPORT_SYMBOL_GPL -+0x6d294e43 clock_t_to_jiffies vmlinux EXPORT_SYMBOL -+0xe97f4ce5 qword_get vmlinux EXPORT_SYMBOL_GPL -+0x1f986505 ethtool_op_set_sg vmlinux EXPORT_SYMBOL -+0x4ccb8b94 pcim_iomap_table vmlinux EXPORT_SYMBOL -+0x669f27de crypto_larval_alloc vmlinux EXPORT_SYMBOL_GPL -+0xc7fdc711 journal_revoke vmlinux EXPORT_SYMBOL -+0x72aea9ce seq_release vmlinux EXPORT_SYMBOL -+0x3c5d0faa insert_inode_locked vmlinux EXPORT_SYMBOL -+0x4c3866c0 ring_buffer_size vmlinux EXPORT_SYMBOL_GPL -+0x838b13e7 ring_buffer_free vmlinux EXPORT_SYMBOL_GPL -+0x18852bcc module_layout vmlinux EXPORT_SYMBOL -+0x33945b7d xfrm_audit_state_notfound vmlinux EXPORT_SYMBOL_GPL -+0x37a8f9c9 hidinput_disconnect vmlinux EXPORT_SYMBOL_GPL -+0xcae03562 tun_get_socket drivers/net/tun EXPORT_SYMBOL_GPL -+0x0014c4da __blk_put_request vmlinux EXPORT_SYMBOL_GPL -+0x875ef85c elv_rb_latter_request vmlinux EXPORT_SYMBOL -+0x0ce1b711 sysfs_create_bin_file vmlinux EXPORT_SYMBOL_GPL -+0x66b2a859 nr_free_buffer_pages vmlinux EXPORT_SYMBOL_GPL -+0xeb8ae736 klist_init vmlinux EXPORT_SYMBOL_GPL -+0x0aabe623 xfrm_state_unregister_afinfo vmlinux EXPORT_SYMBOL -+0x60f4c230 of_find_node_by_name vmlinux EXPORT_SYMBOL -+0x83f9a3c9 serial8250_do_pm vmlinux EXPORT_SYMBOL -+0x05aa4eb1 pci_ltr_supported vmlinux EXPORT_SYMBOL -+0x6cdc5c6b nla_strlcpy vmlinux EXPORT_SYMBOL -+0xa46f2f1b kstrtouint vmlinux EXPORT_SYMBOL -+0x4121db0b blk_init_queue_node vmlinux EXPORT_SYMBOL -+0xe4a895fa up_write vmlinux EXPORT_SYMBOL -+0x7665e61c cpu_all_bits vmlinux EXPORT_SYMBOL -+0xb66350c3 auth_domain_put vmlinux EXPORT_SYMBOL_GPL -+0x4d8219f4 scsi_target_block vmlinux EXPORT_SYMBOL_GPL -+0x00d4f811 scsi_prep_state_check vmlinux EXPORT_SYMBOL -+0x8176ea3f free_buffer_head vmlinux EXPORT_SYMBOL -+0x6e4b5afd fget vmlinux EXPORT_SYMBOL -+0xfa1eb910 unregister_syscore_ops vmlinux EXPORT_SYMBOL_GPL -+0x44e9a829 match_token vmlinux EXPORT_SYMBOL -+0x2332418c vmtruncate vmlinux EXPORT_SYMBOL -+0xdbb24fc2 down_write vmlinux EXPORT_SYMBOL -+0xcaf2fc3d ip_route_output_flow vmlinux EXPORT_SYMBOL_GPL -+0x1b9e0ff1 scsilun_to_int vmlinux EXPORT_SYMBOL -+0x3b4572b8 posix_test_lock vmlinux EXPORT_SYMBOL -+0xd127c42a kill_block_super vmlinux EXPORT_SYMBOL -+0x14b68061 flush_signals vmlinux EXPORT_SYMBOL -+0x8c724794 nf_ct_remove_expectations net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x843a658f neigh_lookup_nodev vmlinux EXPORT_SYMBOL -+0x1b52b0d2 kernel_setsockopt vmlinux EXPORT_SYMBOL -+0xfab0ef6e kernel_getsockopt vmlinux EXPORT_SYMBOL -+0x9e4bdfff kernel_sock_ioctl vmlinux EXPORT_SYMBOL -+0x7c9208ff usb_stor_disconnect vmlinux EXPORT_SYMBOL_GPL -+0xcf39c94b mb_cache_entry_insert vmlinux EXPORT_SYMBOL -+0x5242d3b7 kallsyms_on_each_symbol vmlinux EXPORT_SYMBOL_GPL -+0xd2a8caf0 work_on_cpu vmlinux EXPORT_SYMBOL_GPL -+0x59de3119 nfnetlink_unicast net/netfilter/nfnetlink EXPORT_SYMBOL_GPL -+0xab694444 bsearch vmlinux EXPORT_SYMBOL -+0xf3dff1a3 blk_put_request vmlinux EXPORT_SYMBOL -+0x9f40a6d6 async_synchronize_full_domain vmlinux EXPORT_SYMBOL_GPL -+0x6974ef19 usb_serial_generic_throttle vmlinux EXPORT_SYMBOL_GPL -+0xf5fce407 crypto_create_tfm vmlinux EXPORT_SYMBOL_GPL -+0xa3a2d9af walk_system_ram_range vmlinux EXPORT_SYMBOL_GPL -+0xa2dc5981 of_get_cpu_node vmlinux EXPORT_SYMBOL -+0x363380e6 nf_conntrack_in net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xb77ba3a1 sock_queue_rcv_skb vmlinux EXPORT_SYMBOL -+0xfcd35070 blk_limits_io_min vmlinux EXPORT_SYMBOL -+0x05871953 sysfs_remove_files vmlinux EXPORT_SYMBOL_GPL -+0xa3f9df4e mapping_tagged vmlinux EXPORT_SYMBOL -+0x02d848d4 rpc_setbufsize vmlinux EXPORT_SYMBOL_GPL -+0x115258a5 put_disk vmlinux EXPORT_SYMBOL -+0xd9605d4c add_timer vmlinux EXPORT_SYMBOL -+0xabfbc63f irq_find_host vmlinux EXPORT_SYMBOL_GPL -+0x86d76ed4 hid_allocate_device vmlinux EXPORT_SYMBOL_GPL -+0xaaa509d1 spi_sync vmlinux EXPORT_SYMBOL_GPL -+0x732b7833 irq_cpu_rmap_add vmlinux EXPORT_SYMBOL -+0x9ba7089d argv_split vmlinux EXPORT_SYMBOL -+0xf6882e97 blk_queue_max_hw_sectors vmlinux EXPORT_SYMBOL -+0x31a89d59 rpc_debug vmlinux EXPORT_SYMBOL_GPL -+0x223326b1 svc_xprt_enqueue vmlinux EXPORT_SYMBOL_GPL -+0x162a441b bus_create_file vmlinux EXPORT_SYMBOL_GPL -+0x4872ee63 crypto_aes_set_key vmlinux EXPORT_SYMBOL_GPL -+0x5086ac3a alg_test vmlinux EXPORT_SYMBOL_GPL -+0xbef43296 console_conditional_schedule vmlinux EXPORT_SYMBOL -+0x774f22b3 svc_destroy vmlinux EXPORT_SYMBOL_GPL -+0xabb8322f pci_target_state vmlinux EXPORT_SYMBOL -+0xf2ec5b45 blkdev_issue_discard vmlinux EXPORT_SYMBOL -+0x38871428 crypto_unregister_pcomp vmlinux EXPORT_SYMBOL_GPL -+0xdf62a75b debugfs_create_symlink vmlinux EXPORT_SYMBOL_GPL -+0xece345ed fat_detach vmlinux EXPORT_SYMBOL_GPL -+0x698a899f ring_buffer_peek vmlinux EXPORT_SYMBOL_GPL -+0x96937cf7 xt_request_find_match vmlinux EXPORT_SYMBOL_GPL -+0x278d3cc1 writeback_inodes_sb_nr_if_idle vmlinux EXPORT_SYMBOL -+0x8b1b0eea xattr_getsecurity vmlinux EXPORT_SYMBOL_GPL -+0x6228c21f smp_call_function_single vmlinux EXPORT_SYMBOL -+0xc0580937 rb_erase vmlinux EXPORT_SYMBOL -+0x46a23e08 fsnotify_alloc_group vmlinux EXPORT_SYMBOL_GPL -+0xaafdc258 strcasecmp vmlinux EXPORT_SYMBOL -+0x962a13e8 save_mount_options vmlinux EXPORT_SYMBOL -+0xf69dd1ab clockevents_register_device vmlinux EXPORT_SYMBOL_GPL -+0x5672add2 nf_conntrack_set_hashsize net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xe5cf9c6b cache_check vmlinux EXPORT_SYMBOL_GPL -+0x4bc96635 ifla_policy vmlinux EXPORT_SYMBOL -+0x35cb4429 tty_unthrottle vmlinux EXPORT_SYMBOL -+0xdd9d1ca1 set_blocksize vmlinux EXPORT_SYMBOL -+0x8e13511f block_page_mkwrite vmlinux EXPORT_SYMBOL -+0x85b9e216 set_timer_slack vmlinux EXPORT_SYMBOL_GPL -+0x0569dca2 class_compat_remove_link vmlinux EXPORT_SYMBOL_GPL -+0x7d5c1ae6 uart_unregister_driver vmlinux EXPORT_SYMBOL -+0x6fd7b2a5 crypto_spawn_tfm vmlinux EXPORT_SYMBOL_GPL -+0x2e77637b generic_error_remove_page vmlinux EXPORT_SYMBOL -+0xcc344f76 nf_ct_nat_offset net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x4fb169f5 ipv6_chk_prefix vmlinux EXPORT_SYMBOL -+0xed1bfd69 ip6_dst_lookup_flow vmlinux EXPORT_SYMBOL_GPL -+0x39d847fa inet_csk_search_req vmlinux EXPORT_SYMBOL_GPL -+0x6ddfd8bc inet_unhash vmlinux EXPORT_SYMBOL_GPL -+0x6aed133e mdio_bus_type vmlinux EXPORT_SYMBOL -+0xf8ccb652 blk_execute_rq vmlinux EXPORT_SYMBOL -+0x993019f7 rpc_call_sync vmlinux EXPORT_SYMBOL_GPL -+0xef6a7e95 ip6_xmit vmlinux EXPORT_SYMBOL -+0xb5044271 vsscanf vmlinux EXPORT_SYMBOL -+0xa583f8ce seq_open_net vmlinux EXPORT_SYMBOL_GPL -+0x82d79b51 sysctl_vfs_cache_pressure vmlinux EXPORT_SYMBOL_GPL -+0x04486e88 rcu_batches_completed vmlinux EXPORT_SYMBOL_GPL -+0x0e52592a panic vmlinux EXPORT_SYMBOL -+0x96dbcca2 ioremap_prot vmlinux EXPORT_SYMBOL -+0x97f6197b pci_set_dma_seg_boundary vmlinux EXPORT_SYMBOL -+0x5c265cba sg_init_one vmlinux EXPORT_SYMBOL -+0x12da5bb2 __kmalloc vmlinux EXPORT_SYMBOL -+0x26477c07 __vmalloc vmlinux EXPORT_SYMBOL -+0xc19db54a kobject_init_and_add vmlinux EXPORT_SYMBOL_GPL -+0x0aa2fcd3 rpc_wake_up_next vmlinux EXPORT_SYMBOL_GPL -+0x7da4ef46 __ip_select_ident vmlinux EXPORT_SYMBOL -+0x81fb8fe5 skb_gro_receive vmlinux EXPORT_SYMBOL_GPL -+0xbe7e6656 pci_find_ht_capability vmlinux EXPORT_SYMBOL_GPL -+0x066cab2a pci_find_next_ht_capability vmlinux EXPORT_SYMBOL_GPL -+0x18765207 journal_load vmlinux EXPORT_SYMBOL -+0xd9bdbb86 flock_lock_file_wait vmlinux EXPORT_SYMBOL -+0x81f1044c xt_find_match vmlinux EXPORT_SYMBOL -+0x21de11a8 __skb_warn_lro_forwarding vmlinux EXPORT_SYMBOL -+0xbe6f064d idr_for_each vmlinux EXPORT_SYMBOL -+0xf3013d91 shash_ahash_digest vmlinux EXPORT_SYMBOL_GPL -+0x5fcadf66 locks_init_lock vmlinux EXPORT_SYMBOL -+0xfede227a bio_add_pc_page vmlinux EXPORT_SYMBOL -+0x71c90087 memcmp vmlinux EXPORT_SYMBOL -+0x77ec2fe2 netif_stacked_transfer_operstate vmlinux EXPORT_SYMBOL -+0xf5fc2242 d_alloc_name vmlinux EXPORT_SYMBOL -+0xaa6e4df5 _raw_write_lock_irqsave vmlinux EXPORT_SYMBOL -+0xc0a0f334 napi_frags_finish vmlinux EXPORT_SYMBOL -+0xce7ce037 of_translate_address vmlinux EXPORT_SYMBOL -+0xaba0a17d devm_ioport_unmap vmlinux EXPORT_SYMBOL -+0xe809a0f7 cont_write_begin vmlinux EXPORT_SYMBOL -+0x9a48be6f vfs_readdir vmlinux EXPORT_SYMBOL -+0x881039d0 zlib_inflate vmlinux EXPORT_SYMBOL -+0xa43b1297 vscnprintf vmlinux EXPORT_SYMBOL -+0xee4fe3e4 blk_recount_segments vmlinux EXPORT_SYMBOL -+0x94a1af32 simple_statfs vmlinux EXPORT_SYMBOL -+0x3e0e9023 param_set_long vmlinux EXPORT_SYMBOL -+0xd8326202 xfrm6_tunnel_deregister net/ipv6/tunnel6 EXPORT_SYMBOL -+0x3b5a4e82 xfrm4_tunnel_deregister net/ipv4/tunnel4 EXPORT_SYMBOL -+0x5b14ec1a rpc_put_mount vmlinux EXPORT_SYMBOL_GPL -+0x602cf2ee km_policy_notify vmlinux EXPORT_SYMBOL -+0xa47d64bf ip_mc_join_group vmlinux EXPORT_SYMBOL -+0xc099fc6f usb_is_intel_switchable_xhci vmlinux EXPORT_SYMBOL_GPL -+0x3244fd7d usb_string vmlinux EXPORT_SYMBOL_GPL -+0xdb760f52 __kfifo_free vmlinux EXPORT_SYMBOL -+0x0b8fef76 nf_ct_unexpect_related net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x328d3c91 inet_csk_reqsk_queue_hash_add vmlinux EXPORT_SYMBOL_GPL -+0xe6e1c5fe uuid_be_gen vmlinux EXPORT_SYMBOL_GPL -+0xa6fb4d71 debugfs_remove vmlinux EXPORT_SYMBOL_GPL -+0x2f4ac4ea lease_modify vmlinux EXPORT_SYMBOL -+0xf441ac43 ioread8_rep vmlinux EXPORT_SYMBOL -+0x979eddb8 xfrm_dst_ifdown vmlinux EXPORT_SYMBOL -+0x64f428d3 neigh_seq_start vmlinux EXPORT_SYMBOL -+0x59825b9a pci_assign_unassigned_bridge_resources vmlinux EXPORT_SYMBOL_GPL -+0x3f0546a8 ioread32_rep vmlinux EXPORT_SYMBOL -+0xfe7887e9 rpc_put_task vmlinux EXPORT_SYMBOL_GPL -+0xf9f40caa eth_header_cache_update vmlinux EXPORT_SYMBOL -+0xb31526ee sg_copy_from_buffer vmlinux EXPORT_SYMBOL -+0x73e20c1c strlcpy vmlinux EXPORT_SYMBOL -+0x8abacc47 get_max_files vmlinux EXPORT_SYMBOL_GPL -+0x328a05f1 strncpy vmlinux EXPORT_SYMBOL -+0x548a40b6 scsi_release_buffers vmlinux EXPORT_SYMBOL -+0x13574bbf nf_net_netfilter_sysctl_path vmlinux EXPORT_SYMBOL_GPL -+0x738196bf driver_create_file vmlinux EXPORT_SYMBOL_GPL -+0x7193680a kern_mount_data vmlinux EXPORT_SYMBOL_GPL -+0x8ef33ff8 __init_kthread_worker vmlinux EXPORT_SYMBOL_GPL -+0xa10f05a8 par_io_of_config vmlinux EXPORT_SYMBOL -+0xf6367114 blk_requeue_request vmlinux EXPORT_SYMBOL -+0x84fc4fe5 insert_inode_locked4 vmlinux EXPORT_SYMBOL -+0x41482d8b strndup_user vmlinux EXPORT_SYMBOL -+0xddd58dc0 ring_buffer_reset vmlinux EXPORT_SYMBOL_GPL -+0xfae9f8ef crypto_init_spawn vmlinux EXPORT_SYMBOL_GPL -+0x9c78b4da mount_nodev vmlinux EXPORT_SYMBOL -+0xf40fbfa7 pagevec_lookup vmlinux EXPORT_SYMBOL -+0x376591a1 xfrm_find_acq vmlinux EXPORT_SYMBOL -+0xaf7abced eth_mac_addr vmlinux EXPORT_SYMBOL -+0xe7a0dd2c scsi_scan_host vmlinux EXPORT_SYMBOL -+0xa22fa240 scsi_setup_fs_cmnd vmlinux EXPORT_SYMBOL -+0xebf65040 svc_xprt_received vmlinux EXPORT_SYMBOL_GPL -+0x12c92332 tcp_sendpage vmlinux EXPORT_SYMBOL -+0xb98a0185 rtc_tm_to_time vmlinux EXPORT_SYMBOL -+0xe5883bd9 class_compat_unregister vmlinux EXPORT_SYMBOL_GPL -+0x47b3f862 radix_tree_lookup_slot vmlinux EXPORT_SYMBOL -+0x91621d6a allocate_resource vmlinux EXPORT_SYMBOL -+0xc08647ff ring_buffer_bytes_cpu vmlinux EXPORT_SYMBOL_GPL -+0x02d81845 audit_log_task_context vmlinux EXPORT_SYMBOL -+0x6b13f214 task_ns_capable vmlinux EXPORT_SYMBOL -+0x49a08acf spi_write_then_read vmlinux EXPORT_SYMBOL_GPL -+0x264aab93 mtd_device_parse_register vmlinux EXPORT_SYMBOL_GPL -+0x40946686 splice_from_pipe_feed vmlinux EXPORT_SYMBOL -+0xf9a054b5 __round_jiffies vmlinux EXPORT_SYMBOL_GPL -+0xfe822d55 get_brgfreq vmlinux EXPORT_SYMBOL -+0x03c06156 bitmap_fold vmlinux EXPORT_SYMBOL -+0x734b6620 vfs_rmdir vmlinux EXPORT_SYMBOL -+0x92eb404f generic_shutdown_super vmlinux EXPORT_SYMBOL -+0x37e74642 get_jiffies_64 vmlinux EXPORT_SYMBOL -+0x3f3d5755 scsi_track_queue_full vmlinux EXPORT_SYMBOL -+0x45d4a34f init_buffer vmlinux EXPORT_SYMBOL -+0xfa2e134e __sock_recv_ts_and_drops vmlinux EXPORT_SYMBOL_GPL -+0xbf7fd2f5 schedule_timeout_killable vmlinux EXPORT_SYMBOL -+0xc14de4a4 rpcauth_create vmlinux EXPORT_SYMBOL_GPL -+0x286a504e sock_no_getname vmlinux EXPORT_SYMBOL -+0xb2abf6e7 vfs_link vmlinux EXPORT_SYMBOL -+0x85050965 __irq_alloc_descs vmlinux EXPORT_SYMBOL_GPL -+0x6e0778f8 call_usermodehelper_setup vmlinux EXPORT_SYMBOL -+0x46de0081 netlink_rcv_skb vmlinux EXPORT_SYMBOL -+0x7e7aea36 phy_driver_unregister vmlinux EXPORT_SYMBOL -+0xf82abc1d isa_dma_bridge_buggy vmlinux EXPORT_SYMBOL -+0x5aa2ba6e crypto_alloc_pcomp vmlinux EXPORT_SYMBOL_GPL -+0x0254aae8 journal_flush vmlinux EXPORT_SYMBOL -+0xedc2994d ktime_get_real vmlinux EXPORT_SYMBOL_GPL -+0x6258ff7a panic_notifier_list vmlinux EXPORT_SYMBOL -+0x493615f0 __xfrm_state_delete vmlinux EXPORT_SYMBOL -+0x91781620 unregister_mtd_chip_driver vmlinux EXPORT_SYMBOL -+0x82f776b7 gpio_export vmlinux EXPORT_SYMBOL_GPL -+0x8aee4b8e do_splice_from vmlinux EXPORT_SYMBOL_GPL -+0x5edbbeed d_delete vmlinux EXPORT_SYMBOL -+0x35829944 find_get_pages_tag vmlinux EXPORT_SYMBOL -+0xc8fd727e mod_timer vmlinux EXPORT_SYMBOL -+0x68e0e289 idr_remove vmlinux EXPORT_SYMBOL -+0xc61be59c ida_remove vmlinux EXPORT_SYMBOL -+0x76053cac mnt_set_expiry vmlinux EXPORT_SYMBOL -+0xd0ec1a6b use_mm vmlinux EXPORT_SYMBOL_GPL -+0x1d3865da param_get_invbool vmlinux EXPORT_SYMBOL -+0xcc964b37 flush_delayed_work_sync vmlinux EXPORT_SYMBOL -+0xbf9d1b96 nfsd_debug vmlinux EXPORT_SYMBOL_GPL -+0xb84fe6ac devres_destroy vmlinux EXPORT_SYMBOL_GPL -+0xbe3f06f3 tty_hangup vmlinux EXPORT_SYMBOL -+0x67d548bf pci_disable_device vmlinux EXPORT_SYMBOL -+0x873f76af add_page_wait_queue vmlinux EXPORT_SYMBOL_GPL -+0x1a2bc07b flush_tlb_mm vmlinux EXPORT_SYMBOL -+0x17643c44 mdiobus_read vmlinux EXPORT_SYMBOL -+0xd9bac924 tty_termios_copy_hw vmlinux EXPORT_SYMBOL -+0x2f8ebbe0 rpc_ntop vmlinux EXPORT_SYMBOL_GPL -+0x44ed046c rpc_pton vmlinux EXPORT_SYMBOL_GPL -+0xcfd9a2c0 des_ekey vmlinux EXPORT_SYMBOL_GPL -+0x1407c6e7 kmap_prot vmlinux EXPORT_SYMBOL -+0xf120872a dql_completed vmlinux EXPORT_SYMBOL -+0x43a939cc key_link vmlinux EXPORT_SYMBOL -+0x34a8b7a1 read_cache_page vmlinux EXPORT_SYMBOL -+0x1cfc799e dev_change_flags vmlinux EXPORT_SYMBOL -+0x801f5a3f __strncpy_from_user vmlinux EXPORT_SYMBOL -+0x41f9eb17 xfrm_state_walk vmlinux EXPORT_SYMBOL -+0x1165ba63 phy_scan_fixups vmlinux EXPORT_SYMBOL -+0x65420d1e nla_put_nohdr vmlinux EXPORT_SYMBOL -+0x98691115 napi_gro_flush vmlinux EXPORT_SYMBOL -+0xa51f1bdd scsi_set_medium_removal vmlinux EXPORT_SYMBOL -+0x77dab830 keyring_clear vmlinux EXPORT_SYMBOL -+0xff8862d7 rh_get_stats vmlinux EXPORT_SYMBOL_GPL -+0x8fbf37e0 profile_pc vmlinux EXPORT_SYMBOL -+0x6532831c gss_service_to_auth_domain_name vmlinux EXPORT_SYMBOL_GPL -+0x7e1183c9 async_schedule vmlinux EXPORT_SYMBOL_GPL -+0x9e1cfc90 ioremap_wc vmlinux EXPORT_SYMBOL -+0xa47434fb __nla_put vmlinux EXPORT_SYMBOL -+0x4c2ae700 strnstr vmlinux EXPORT_SYMBOL -+0xcbe78671 svc_sock_names vmlinux EXPORT_SYMBOL_GPL -+0x6415b696 inet_diag_register vmlinux EXPORT_SYMBOL_GPL -+0x41a855a9 sdhci_pltfm_unregister vmlinux EXPORT_SYMBOL_GPL -+0xf5222143 _raw_spin_lock_irqsave vmlinux EXPORT_SYMBOL -+0xe17482f0 tcp_done vmlinux EXPORT_SYMBOL_GPL -+0x7fdf3256 sysdev_show_ulong vmlinux EXPORT_SYMBOL_GPL -+0x2fb6de5d add_device_randomness vmlinux EXPORT_SYMBOL -+0xde417b81 async_schedule_domain vmlinux EXPORT_SYMBOL_GPL -+0x6ff5969a usb_init_urb vmlinux EXPORT_SYMBOL_GPL -+0xd4e0fb01 get_phy_id vmlinux EXPORT_SYMBOL -+0x35cca30f blk_free_tags vmlinux EXPORT_SYMBOL -+0xc0b2494c vfsmount_lock_lock_init vmlinux EXPORT_SYMBOL -+0xefdd5a63 ktime_get_ts vmlinux EXPORT_SYMBOL_GPL -+0xe7ce7439 _memcpy_fromio vmlinux EXPORT_SYMBOL -+0xe4ab69a4 usb_hcd_unmap_urb_setup_for_dma vmlinux EXPORT_SYMBOL_GPL -+0xadf804eb scsi_device_get vmlinux EXPORT_SYMBOL -+0xe2ab0f51 scsi_device_put vmlinux EXPORT_SYMBOL -+0x51ce5ad3 files_lglock_local_lock_cpu vmlinux EXPORT_SYMBOL -+0x37eab51b map_vm_area vmlinux EXPORT_SYMBOL_GPL -+0x0084e86d unregister_shrinker vmlinux EXPORT_SYMBOL -+0x05c1da0d isa_bridge_pcidev vmlinux EXPORT_SYMBOL_GPL -+0xcb1c9e78 ipv6_dev_get_saddr vmlinux EXPORT_SYMBOL -+0xcbbd7b2f xfrm_policy_flush vmlinux EXPORT_SYMBOL -+0xab5e43fc mmc_set_blocklen vmlinux EXPORT_SYMBOL -+0xb8aa2342 __check_region vmlinux EXPORT_SYMBOL -+0x328aa64c par_io_data_set vmlinux EXPORT_SYMBOL -+0x90dd262f nf_nat_protocol_register net/ipv4/netfilter/nf_nat EXPORT_SYMBOL -+0xf6388c56 sysctl_ip_default_ttl vmlinux EXPORT_SYMBOL -+0xba7ff9a8 napi_gro_frags vmlinux EXPORT_SYMBOL -+0x59923e50 pci_load_saved_state vmlinux EXPORT_SYMBOL_GPL -+0x15864b03 flex_array_get vmlinux EXPORT_SYMBOL -+0x0cf9a646 key_task_permission vmlinux EXPORT_SYMBOL -+0x9cbb7f29 nf_nat_protocol_unregister net/ipv4/netfilter/nf_nat EXPORT_SYMBOL -+0xfc464847 inet_diag_unregister vmlinux EXPORT_SYMBOL_GPL -+0x70a6efa3 sock_sendmsg vmlinux EXPORT_SYMBOL -+0x61308070 disk_get_part vmlinux EXPORT_SYMBOL_GPL -+0x2333005e netlink_kernel_release vmlinux EXPORT_SYMBOL -+0x0ffc7c8b __sock_create vmlinux EXPORT_SYMBOL -+0x190f4530 rtc_set_mmss vmlinux EXPORT_SYMBOL_GPL -+0x8384d453 pci_bus_resource_n vmlinux EXPORT_SYMBOL_GPL -+0x4289f7df down_interruptible vmlinux EXPORT_SYMBOL -+0x3064cd91 netif_carrier_off vmlinux EXPORT_SYMBOL -+0x26b9af4e mmc_request_done vmlinux EXPORT_SYMBOL -+0x46074c17 sdev_evt_alloc vmlinux EXPORT_SYMBOL_GPL -+0xa43e2c08 lease_get_mtime vmlinux EXPORT_SYMBOL -+0x17d3b09a sb_set_blocksize vmlinux EXPORT_SYMBOL -+0x850ac629 sdio_writew vmlinux EXPORT_SYMBOL_GPL -+0x3744cf36 vmalloc_to_pfn vmlinux EXPORT_SYMBOL -+0x4c18ad3a get_task_mm vmlinux EXPORT_SYMBOL_GPL -+0xe8b2187c nf_ct_expect_put net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xb9b9df41 usb_amd_dev_put vmlinux EXPORT_SYMBOL_GPL -+0x5a642ff0 crypto_unregister_alg vmlinux EXPORT_SYMBOL_GPL -+0x4484a83b dump_write vmlinux EXPORT_SYMBOL -+0x0fae7d45 lock_super vmlinux EXPORT_SYMBOL -+0xb8f92e75 __class_create vmlinux EXPORT_SYMBOL_GPL -+0x86e44713 filp_open vmlinux EXPORT_SYMBOL -+0xad91149b generic_file_aio_write vmlinux EXPORT_SYMBOL -+0x43af7a67 xfrm6_prepare_output vmlinux EXPORT_SYMBOL -+0x4d4fd5f1 xfrm_calg_get_byname vmlinux EXPORT_SYMBOL_GPL -+0xc6c1239b xfrm4_prepare_output vmlinux EXPORT_SYMBOL -+0x14665bed pci_read_vpd vmlinux EXPORT_SYMBOL -+0x51014234 get_disk vmlinux EXPORT_SYMBOL -+0xb2c3e937 __free_pages vmlinux EXPORT_SYMBOL -+0x4ff0cd36 inet_bind vmlinux EXPORT_SYMBOL -+0x034e17a5 qdisc_watchdog_init vmlinux EXPORT_SYMBOL -+0xe861f9ad class_find_device vmlinux EXPORT_SYMBOL_GPL -+0xfe3c4e28 __register_binfmt vmlinux EXPORT_SYMBOL -+0x058e4b7d xfrm_init_state vmlinux EXPORT_SYMBOL -+0x37ac26b3 pci_assign_resource vmlinux EXPORT_SYMBOL -+0x89ca47bf kstrtos8_from_user vmlinux EXPORT_SYMBOL -+0xff18ef68 crypto_init_spawn2 vmlinux EXPORT_SYMBOL_GPL -+0x358365c5 xfrm_user_policy vmlinux EXPORT_SYMBOL -+0x6117420a netif_notify_peers vmlinux EXPORT_SYMBOL -+0xf94b112b netif_napi_add vmlinux EXPORT_SYMBOL -+0x562ccd0e skb_split vmlinux EXPORT_SYMBOL -+0xf5b3060b input_grab_device vmlinux EXPORT_SYMBOL -+0xa177bc19 default_mtd_writev vmlinux EXPORT_SYMBOL_GPL -+0x2376e92b tty_port_block_til_ready vmlinux EXPORT_SYMBOL -+0x81b22cf9 journal_try_to_free_buffers vmlinux EXPORT_SYMBOL -+0xf10de535 ioread8 vmlinux EXPORT_SYMBOL -+0x686c703f xfrm_count_auth_supported vmlinux EXPORT_SYMBOL_GPL -+0x8c10c6f6 netlink_broadcast vmlinux EXPORT_SYMBOL -+0x66645e38 of_property_read_string_index vmlinux EXPORT_SYMBOL_GPL -+0x0343bdf1 __i2c_board_list vmlinux EXPORT_SYMBOL_GPL -+0xa07bb953 block_write_full_page_endio vmlinux EXPORT_SYMBOL -+0x317a1174 shmem_file_setup vmlinux EXPORT_SYMBOL_GPL -+0xc3cf1128 in_group_p vmlinux EXPORT_SYMBOL -+0xc631580a console_unlock vmlinux EXPORT_SYMBOL -+0x9524b0ae _outsb vmlinux EXPORT_SYMBOL -+0xcfea9e86 udp_sendmsg vmlinux EXPORT_SYMBOL -+0x318394d8 mmc_start_req vmlinux EXPORT_SYMBOL -+0xbdfcce9d elv_rb_former_request vmlinux EXPORT_SYMBOL -+0x35fbd6a1 __kfifo_dma_out_prepare_r vmlinux EXPORT_SYMBOL -+0xf34bd1d5 dcb_ieee_setapp vmlinux EXPORT_SYMBOL -+0xcbb30a2b dcb_ieee_delapp vmlinux EXPORT_SYMBOL -+0xf53d4c26 qdisc_class_hash_destroy vmlinux EXPORT_SYMBOL -+0xcc26e5cf sdio_register_driver vmlinux EXPORT_SYMBOL_GPL -+0x50deef5c usb_kill_urb vmlinux EXPORT_SYMBOL_GPL -+0xa87e68e1 usb_get_intf vmlinux EXPORT_SYMBOL_GPL -+0x9e607910 audit_log vmlinux EXPORT_SYMBOL -+0x767b18fb set_security_override_from_ctx vmlinux EXPORT_SYMBOL -+0x5ab3b29b xdr_process_buf vmlinux EXPORT_SYMBOL_GPL -+0x065f3688 sk_wait_data vmlinux EXPORT_SYMBOL -+0xc724970d pci_enable_obff vmlinux EXPORT_SYMBOL -+0x762ea593 crypto_remove_spawns vmlinux EXPORT_SYMBOL_GPL -+0x4fd4e89d ring_buffer_empty_cpu vmlinux EXPORT_SYMBOL_GPL -+0x0f28cb91 nvram_read_byte vmlinux EXPORT_SYMBOL -+0xc390630a xt_replace_table vmlinux EXPORT_SYMBOL_GPL -+0xf9943f1b __netpoll_setup vmlinux EXPORT_SYMBOL_GPL -+0x08cc84e7 __percpu_counter_init vmlinux EXPORT_SYMBOL -+0x6d6c930c irq_set_affinity_notifier vmlinux EXPORT_SYMBOL_GPL -+0x698fe0cc inet_hashinfo_init vmlinux EXPORT_SYMBOL_GPL -+0x262e9a73 input_mt_report_pointer_emulation vmlinux EXPORT_SYMBOL -+0x333bf31b usb_stor_bulk_transfer_sg vmlinux EXPORT_SYMBOL_GPL -+0x56cd1a50 pci_ioremap_bar vmlinux EXPORT_SYMBOL_GPL -+0xadd2969f end_buffer_read_sync vmlinux EXPORT_SYMBOL -+0x227badd6 mod_timer_pinned vmlinux EXPORT_SYMBOL -+0x8276963f set_cpus_allowed_ptr vmlinux EXPORT_SYMBOL_GPL -+0xfd168974 neigh_for_each vmlinux EXPORT_SYMBOL -+0x7e8699a8 rtc_initialize_alarm vmlinux EXPORT_SYMBOL_GPL -+0x6971447a rtc_month_days vmlinux EXPORT_SYMBOL -+0x7e64181d usb_calc_bus_time vmlinux EXPORT_SYMBOL_GPL -+0xabc7e656 sg_miter_next vmlinux EXPORT_SYMBOL -+0xdd8e46ba crypto_init_shash_spawn vmlinux EXPORT_SYMBOL_GPL -+0xe9b01876 crypto_init_ahash_spawn vmlinux EXPORT_SYMBOL_GPL -+0x6e50cff7 posix_timers_register_clock vmlinux EXPORT_SYMBOL_GPL -+0x8ff66782 param_get_ushort vmlinux EXPORT_SYMBOL -+0xe6dd236d clear_pages vmlinux EXPORT_SYMBOL -+0x67ef2a40 svc_sock_update_bufs vmlinux EXPORT_SYMBOL_GPL -+0x5c27b6d6 skb_pull vmlinux EXPORT_SYMBOL -+0x2aa1292b usb_find_interface vmlinux EXPORT_SYMBOL_GPL -+0x8574ca6c gpio_request_array vmlinux EXPORT_SYMBOL_GPL -+0xd988b61f swiotlb_unmap_page vmlinux EXPORT_SYMBOL_GPL -+0x6da928f4 _insw_ns vmlinux EXPORT_SYMBOL -+0x05a514a1 _insl_ns vmlinux EXPORT_SYMBOL -+0x93d2422d snmp_mib_free vmlinux EXPORT_SYMBOL_GPL -+0x1e41fddb neigh_app_ns vmlinux EXPORT_SYMBOL -+0xc9501ade phy_start_interrupts vmlinux EXPORT_SYMBOL -+0x09d998e1 scsi_get_vpd_page vmlinux EXPORT_SYMBOL_GPL -+0x9dfdf722 gpio_free_array vmlinux EXPORT_SYMBOL_GPL -+0x5d51bcf7 scatterwalk_start vmlinux EXPORT_SYMBOL_GPL -+0x53472771 sysfs_put vmlinux EXPORT_SYMBOL_GPL -+0x526c437a xfrm_state_check_expire vmlinux EXPORT_SYMBOL -+0x393c4c4e netdev_boot_setup_check vmlinux EXPORT_SYMBOL -+0x1ef1100f sock_i_uid vmlinux EXPORT_SYMBOL -+0xf4009166 sock_i_ino vmlinux EXPORT_SYMBOL -+0xc046033e seq_bitmap vmlinux EXPORT_SYMBOL -+0x3942b0c9 ip_build_and_send_pkt vmlinux EXPORT_SYMBOL_GPL -+0xb93c76a8 register_gifconf vmlinux EXPORT_SYMBOL -+0xcd07f6b1 gpiochip_find vmlinux EXPORT_SYMBOL_GPL -+0x292be0eb crypto_rng_type vmlinux EXPORT_SYMBOL_GPL -+0x457594fa crypto_alg_list vmlinux EXPORT_SYMBOL_GPL -+0xc04e7aa9 sync_inode_metadata vmlinux EXPORT_SYMBOL -+0xafff3d1d mempool_alloc vmlinux EXPORT_SYMBOL -+0x86f6b99d synchronize_rcu_expedited vmlinux EXPORT_SYMBOL_GPL -+0xaa6901ac __kfifo_out_r vmlinux EXPORT_SYMBOL -+0x52f1bf6b __srcu_read_lock vmlinux EXPORT_SYMBOL_GPL -+0xd03c7700 secure_ipv4_port_ephemeral vmlinux EXPORT_SYMBOL_GPL -+0x79578100 proc_dointvec_minmax vmlinux EXPORT_SYMBOL -+0x8581db4c i2c_bus_type vmlinux EXPORT_SYMBOL_GPL -+0xcd898fd4 do_truncate vmlinux EXPORT_SYMBOL_GPL -+0x7cd81e29 kmalloc_caches vmlinux EXPORT_SYMBOL -+0xdc43a9c8 daemonize vmlinux EXPORT_SYMBOL -+0x390dd42a rpc_malloc vmlinux EXPORT_SYMBOL_GPL -+0xb2390b29 icmpv6_send vmlinux EXPORT_SYMBOL -+0x19ade8fc put_driver vmlinux EXPORT_SYMBOL_GPL -+0xc00f7d59 blk_queue_make_request vmlinux EXPORT_SYMBOL -+0x9cb013cc put_page vmlinux EXPORT_SYMBOL -+0x74954462 timecounter_read vmlinux EXPORT_SYMBOL_GPL -+0x6fff8279 nf_conntrack_lock net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xab930e2e rpc_lookup_cred vmlinux EXPORT_SYMBOL_GPL -+0x801c8645 rtc_device_register vmlinux EXPORT_SYMBOL_GPL -+0x445fc790 input_reset_device vmlinux EXPORT_SYMBOL -+0xbc8a443b tty_ldisc_deref vmlinux EXPORT_SYMBOL_GPL -+0x7b645a57 vfs_getattr vmlinux EXPORT_SYMBOL -+0x31f79892 pci_domain_nr vmlinux EXPORT_SYMBOL -+0x5b582800 inet_del_protocol vmlinux EXPORT_SYMBOL -+0x03b7b2e4 neigh_update vmlinux EXPORT_SYMBOL -+0xe03951df phy_stop vmlinux EXPORT_SYMBOL -+0xcce40c42 put_io_context vmlinux EXPORT_SYMBOL -+0x5baf344d blk_queue_io_min vmlinux EXPORT_SYMBOL -+0xf9fbdc25 nobh_truncate_page vmlinux EXPORT_SYMBOL -+0xc9b8c308 __kfifo_dma_out_prepare vmlinux EXPORT_SYMBOL -+0x045072cd nf_ct_port_nla_policy net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xdfaecb3e ethtool_op_set_tx_hw_csum vmlinux EXPORT_SYMBOL -+0x5412c7c7 up vmlinux EXPORT_SYMBOL -+0x23f5e02a rpc_call_start vmlinux EXPORT_SYMBOL_GPL -+0x8eed1f0d icmp_send vmlinux EXPORT_SYMBOL -+0x1ed928f6 nfs4_set_ds_client vmlinux EXPORT_SYMBOL_GPL -+0x98d5de4f path_get vmlinux EXPORT_SYMBOL -+0x07077c7d iov_iter_copy_from_user_atomic vmlinux EXPORT_SYMBOL -+0x93a2cb47 reserve_pmc_hardware vmlinux EXPORT_SYMBOL_GPL -+0xa726ec8b xfrm_state_update vmlinux EXPORT_SYMBOL -+0x8a74500b usb_deregister_dev vmlinux EXPORT_SYMBOL_GPL -+0x3e2e9995 usb_hcd_is_primary_hcd vmlinux EXPORT_SYMBOL_GPL -+0x9f7d9edf crypto_grab_aead vmlinux EXPORT_SYMBOL_GPL -+0x9c57851d hrtimer_start vmlinux EXPORT_SYMBOL_GPL -+0x0a43ebfc get_pid_task vmlinux EXPORT_SYMBOL_GPL -+0x6c702af7 sysctl_udp_rmem_min vmlinux EXPORT_SYMBOL -+0x6f4d5b8b dev_open vmlinux EXPORT_SYMBOL -+0x25ae2be1 lock_sock_fast vmlinux EXPORT_SYMBOL -+0x65a76805 ilookup vmlinux EXPORT_SYMBOL -+0x4302d0eb free_pages vmlinux EXPORT_SYMBOL -+0xbfc177bc iowrite32_rep vmlinux EXPORT_SYMBOL -+0x8cc79cab iowrite16_rep vmlinux EXPORT_SYMBOL -+0x4e7df11b irq_create_of_mapping vmlinux EXPORT_SYMBOL_GPL -+0x4b48ebf0 of_irq_map_pci vmlinux EXPORT_SYMBOL_GPL -+0x6e999abc mdiobus_free vmlinux EXPORT_SYMBOL -+0x8d610fe8 generic_file_fsync vmlinux EXPORT_SYMBOL -+0x96b22cab unlock_new_inode vmlinux EXPORT_SYMBOL -+0x3f3633b3 __f_setown vmlinux EXPORT_SYMBOL -+0xf82f16b3 execute_in_process_context vmlinux EXPORT_SYMBOL_GPL -+0x11f3795f xt_find_table_lock vmlinux EXPORT_SYMBOL_GPL -+0x62737e1d sock_unregister vmlinux EXPORT_SYMBOL -+0x760a3bf8 kset_register vmlinux EXPORT_SYMBOL -+0xf2e55f98 fput vmlinux EXPORT_SYMBOL -+0x6cf0d67d qe_get_num_of_snums vmlinux EXPORT_SYMBOL -+0x6b3ec69d platform_device_alloc vmlinux EXPORT_SYMBOL_GPL -+0x60da3cf0 posix_timer_event vmlinux EXPORT_SYMBOL_GPL -+0x52e15131 ip6_frag_init vmlinux EXPORT_SYMBOL -+0x234bde50 journal_set_features vmlinux EXPORT_SYMBOL -+0x4cd38ab6 __fsnotify_parent vmlinux EXPORT_SYMBOL_GPL -+0xb78c61e8 param_ops_bool vmlinux EXPORT_SYMBOL -+0xa4274b10 usb_ep0_reinit vmlinux EXPORT_SYMBOL_GPL -+0x8b92c65b add_disk vmlinux EXPORT_SYMBOL -+0x3e1dd4ab xt_rateest_put net/netfilter/xt_RATEEST EXPORT_SYMBOL_GPL -+0xe23deb2d inet_shutdown vmlinux EXPORT_SYMBOL -+0x33ee9189 posix_lock_file_wait vmlinux EXPORT_SYMBOL -+0xc079de49 inet_csk_clone vmlinux EXPORT_SYMBOL_GPL -+0x5dc54a6c xt_unregister_table vmlinux EXPORT_SYMBOL_GPL -+0x2c5b1d98 uart_remove_one_port vmlinux EXPORT_SYMBOL -+0x4e830a3e strnicmp vmlinux EXPORT_SYMBOL -+0x4ef107d9 vmalloc_to_page vmlinux EXPORT_SYMBOL -+0x00a15cc7 usb_get_hcd vmlinux EXPORT_SYMBOL_GPL -+0x9b5913f9 blk_update_request vmlinux EXPORT_SYMBOL_GPL -+0x45c43667 journal_start_commit vmlinux EXPORT_SYMBOL -+0x235e90f3 __wake_up_bit vmlinux EXPORT_SYMBOL -+0x71504b18 xdr_encode_array2 vmlinux EXPORT_SYMBOL_GPL -+0x661a2f0b sock_release vmlinux EXPORT_SYMBOL -+0x56039b1c usb_hcd_giveback_urb vmlinux EXPORT_SYMBOL_GPL -+0x59423726 user_instantiate vmlinux EXPORT_SYMBOL_GPL -+0x75994700 add_wait_queue_exclusive vmlinux EXPORT_SYMBOL -+0xdc9b0085 nf_nat_icmp_reply_translation net/ipv4/netfilter/nf_nat EXPORT_SYMBOL_GPL -+0x34908c14 print_hex_dump_bytes vmlinux EXPORT_SYMBOL -+0x4a37f460 nlmclnt_proc vmlinux EXPORT_SYMBOL_GPL -+0x62118f48 d_add_ci vmlinux EXPORT_SYMBOL -+0xb5020657 phys_mem_access_prot vmlinux EXPORT_SYMBOL -+0x5e6947f7 unregister_dcbevent_notifier vmlinux EXPORT_SYMBOL -+0x017543f0 net_ipv6_ctl_path vmlinux EXPORT_SYMBOL_GPL -+0xa9f3f261 net_ipv4_ctl_path vmlinux EXPORT_SYMBOL_GPL -+0x5243725c netdev_set_master vmlinux EXPORT_SYMBOL -+0x82939f08 __skb_checksum_complete_head vmlinux EXPORT_SYMBOL -+0xe053341e swiotlb_map_sg vmlinux EXPORT_SYMBOL -+0x7c9ac32e __percpu_counter_sum vmlinux EXPORT_SYMBOL -+0xb770be3e __percpu_counter_add vmlinux EXPORT_SYMBOL -+0x9d9c9597 idr_init vmlinux EXPORT_SYMBOL -+0xeaf16558 ida_init vmlinux EXPORT_SYMBOL -+0x9a19604d mpage_readpage vmlinux EXPORT_SYMBOL -+0x70bc17d7 inode_wait vmlinux EXPORT_SYMBOL -+0xd6ee688f vmalloc vmlinux EXPORT_SYMBOL -+0xf31b3fd1 workqueue_set_max_active vmlinux EXPORT_SYMBOL_GPL -+0xe10c1552 tty_port_raise_dtr_rts vmlinux EXPORT_SYMBOL -+0xb32bff81 pci_request_region vmlinux EXPORT_SYMBOL -+0xfa83da2c blk_queue_io_opt vmlinux EXPORT_SYMBOL -+0xd4c14632 system_unbound_wq vmlinux EXPORT_SYMBOL_GPL -+0x576da704 cpm_muram_dma vmlinux EXPORT_SYMBOL -+0xe7420df4 scsi_adjust_queue_depth vmlinux EXPORT_SYMBOL -+0xeae958fa mb_cache_entry_find_first vmlinux EXPORT_SYMBOL -+0x10e22972 gss_mech_get_by_name vmlinux EXPORT_SYMBOL_GPL -+0xc8910e47 tcp_unregister_congestion_control vmlinux EXPORT_SYMBOL_GPL -+0x28811101 bio_split vmlinux EXPORT_SYMBOL -+0x02456663 lock_rename vmlinux EXPORT_SYMBOL -+0x1ab0d653 class_destroy vmlinux EXPORT_SYMBOL_GPL -+0x584637d7 pci_pme_active vmlinux EXPORT_SYMBOL -+0x864fd4d7 gpiochip_remove vmlinux EXPORT_SYMBOL_GPL -+0xae93b4d8 __locks_copy_lock vmlinux EXPORT_SYMBOL -+0x83df0d38 mutex_lock_killable vmlinux EXPORT_SYMBOL -+0xa17874dd nf_ct_remove_userspace_expectations net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xcc9846dc xdr_inline_decode vmlinux EXPORT_SYMBOL_GPL -+0x070f6230 tcp_check_req vmlinux EXPORT_SYMBOL -+0x4fc41dd7 netlink_unicast vmlinux EXPORT_SYMBOL -+0x6c03f58c neigh_sysctl_register vmlinux EXPORT_SYMBOL -+0x534f54dd usb_serial_generic_read_bulk_callback vmlinux EXPORT_SYMBOL_GPL -+0xdcb0349b sys_close vmlinux EXPORT_SYMBOL -+0x3f2c31ce kill_pgrp vmlinux EXPORT_SYMBOL -+0x512c741a ppc_md vmlinux EXPORT_SYMBOL -+0x09959de7 fat_build_inode vmlinux EXPORT_SYMBOL_GPL -+0xd34ed65a seq_read vmlinux EXPORT_SYMBOL -+0x7d19ed18 is_bad_inode vmlinux EXPORT_SYMBOL -+0xf612809a param_get_int vmlinux EXPORT_SYMBOL -+0x915e1208 tb_ticks_per_usec vmlinux EXPORT_SYMBOL -+0xeb903aa6 start_tty vmlinux EXPORT_SYMBOL -+0x7ffc8718 gpio_set_debounce vmlinux EXPORT_SYMBOL_GPL -+0x2b296823 shash_ahash_finup vmlinux EXPORT_SYMBOL_GPL -+0x6544cafe user_update vmlinux EXPORT_SYMBOL_GPL -+0xb454572a irqd_to_hwirq vmlinux EXPORT_SYMBOL_GPL -+0x4ea0d14b nf_ct_get_tuplepr net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x095a5e59 skb_free_datagram_locked vmlinux EXPORT_SYMBOL -+0x76fc0f60 kernel_sock_shutdown vmlinux EXPORT_SYMBOL -+0xa5b5f374 notify_change vmlinux EXPORT_SYMBOL -+0xae5c1715 follow_up vmlinux EXPORT_SYMBOL -+0x0b7086d9 param_get_short vmlinux EXPORT_SYMBOL -+0x944b9776 nf_log_bind_pf vmlinux EXPORT_SYMBOL -+0xe2b8b326 skb_copy_and_csum_datagram_iovec vmlinux EXPORT_SYMBOL -+0x304d21f5 sock_no_ioctl vmlinux EXPORT_SYMBOL -+0x2c738b3f get_user_pages_fast vmlinux EXPORT_SYMBOL_GPL -+0x644e6c65 nf_conntrack_find_get net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x2a873ac0 scsi_remove_device vmlinux EXPORT_SYMBOL -+0x738da129 simple_empty vmlinux EXPORT_SYMBOL -+0xe6e2bc75 shmem_read_mapping_page_gfp vmlinux EXPORT_SYMBOL_GPL -+0x8c3682d4 xfrm_cfg_mutex vmlinux EXPORT_SYMBOL -+0x096e161a __sk_mem_schedule vmlinux EXPORT_SYMBOL -+0xab9efe2e __hid_register_driver vmlinux EXPORT_SYMBOL_GPL -+0xc94631af hid_disconnect vmlinux EXPORT_SYMBOL_GPL -+0x70cf032f usb_hcd_irq vmlinux EXPORT_SYMBOL_GPL -+0x16edea5d __pci_register_driver vmlinux EXPORT_SYMBOL -+0xcde172ac radix_tree_gang_lookup_tag_slot vmlinux EXPORT_SYMBOL -+0xedb6385a blk_queue_merge_bvec vmlinux EXPORT_SYMBOL -+0x920fe930 journal_lock_updates vmlinux EXPORT_SYMBOL -+0x10b39a9d mnt_want_write_file vmlinux EXPORT_SYMBOL_GPL -+0xec1efa4e ip_ct_attach vmlinux EXPORT_SYMBOL -+0xabe640fc dev_set_mtu vmlinux EXPORT_SYMBOL -+0x82ae4fe5 crypto_unregister_template vmlinux EXPORT_SYMBOL_GPL -+0xcddd85e0 bd_link_disk_holder vmlinux EXPORT_SYMBOL_GPL -+0x2919b156 xdr_decode_string_inplace vmlinux EXPORT_SYMBOL_GPL -+0x565b6892 uuid_le_gen vmlinux EXPORT_SYMBOL_GPL -+0xca988dd7 svc_seq_show vmlinux EXPORT_SYMBOL_GPL -+0x52078d48 scsi_free_host_dev vmlinux EXPORT_SYMBOL -+0xd1010d6c driver_register vmlinux EXPORT_SYMBOL_GPL -+0x346c4ded rwsem_down_write_failed vmlinux EXPORT_SYMBOL -+0xc630666e should_remove_suid vmlinux EXPORT_SYMBOL -+0xe9e4c8f7 input_ff_create vmlinux EXPORT_SYMBOL_GPL -+0x103497cf device_destroy vmlinux EXPORT_SYMBOL_GPL -+0x8fae9b4b find_lock_page vmlinux EXPORT_SYMBOL -+0x022d3702 srcu_notifier_chain_unregister vmlinux EXPORT_SYMBOL_GPL -+0x917e424e local_flush_tlb_mm vmlinux EXPORT_SYMBOL -+0x1219dd23 unregister_pernet_device vmlinux EXPORT_SYMBOL_GPL -+0x5fd09748 input_ff_destroy vmlinux EXPORT_SYMBOL_GPL -+0x1b46e897 platform_get_irq_byname vmlinux EXPORT_SYMBOL_GPL -+0x48404b9a remove_wait_queue vmlinux EXPORT_SYMBOL -+0x0f59f197 param_array_ops vmlinux EXPORT_SYMBOL -+0xfe88da83 napi_get_frags vmlinux EXPORT_SYMBOL -+0x21daf6a9 sk_stream_write_space vmlinux EXPORT_SYMBOL -+0x52af66d4 scsi_verify_blk_ioctl vmlinux EXPORT_SYMBOL -+0x446ffab6 sysfs_notify_dirent vmlinux EXPORT_SYMBOL_GPL -+0x13bf0f2d ipv6_dup_options vmlinux EXPORT_SYMBOL_GPL -+0x341c8ed1 phy_register_fixup_for_id vmlinux EXPORT_SYMBOL -+0x59021bf3 add_mtd_blktrans_dev vmlinux EXPORT_SYMBOL_GPL -+0x40344dfc mmc_do_release_host vmlinux EXPORT_SYMBOL -+0x52c1fde9 zap_vma_ptes vmlinux EXPORT_SYMBOL_GPL -+0xa22bc9de rpc_init_priority_wait_queue vmlinux EXPORT_SYMBOL_GPL -+0x0e889016 xfrm_policy_bysel_ctx vmlinux EXPORT_SYMBOL -+0x35d4ae0a tcp_sendmsg vmlinux EXPORT_SYMBOL -+0xfd5866dc i2c_smbus_write_word_data vmlinux EXPORT_SYMBOL -+0x7e275ea8 scsi_complete_async_scans vmlinux EXPORT_SYMBOL_GPL -+0x3bc40f39 elv_rb_del vmlinux EXPORT_SYMBOL -+0x20223395 elv_rb_add vmlinux EXPORT_SYMBOL -+0x2115a784 init_user_ns vmlinux EXPORT_SYMBOL_GPL -+0xa5b00659 ppc_proc_freq vmlinux EXPORT_SYMBOL_GPL -+0x4a4a77e3 netif_skb_features vmlinux EXPORT_SYMBOL -+0xde0a03d6 sock_map_fd vmlinux EXPORT_SYMBOL -+0x00632780 work_busy vmlinux EXPORT_SYMBOL_GPL -+0xc368849f nvram_sync vmlinux EXPORT_SYMBOL -+0x06c5142a __sk_mem_reclaim vmlinux EXPORT_SYMBOL -+0x4be38e61 pcim_pin_device vmlinux EXPORT_SYMBOL -+0xc45755de find_next_zero_bit_le vmlinux EXPORT_SYMBOL -+0x04acf587 d_prune_aliases vmlinux EXPORT_SYMBOL -+0x12a38747 usleep_range vmlinux EXPORT_SYMBOL -+0x11e746e0 flush_icache_user_range vmlinux EXPORT_SYMBOL -+0x2691412e boot_cpuid_phys vmlinux EXPORT_SYMBOL_GPL -+0xa43b9539 memcpy_fromiovecend vmlinux EXPORT_SYMBOL -+0x86e2446c blk_make_request vmlinux EXPORT_SYMBOL -+0xd75c1a07 __pagevec_release vmlinux EXPORT_SYMBOL -+0x51b65a26 rtc_lock vmlinux EXPORT_SYMBOL_GPL -+0xdebf6baa hid_unregister_driver vmlinux EXPORT_SYMBOL_GPL -+0x62062d4b pcie_set_readrq vmlinux EXPORT_SYMBOL -+0xa73e3fb4 pcie_bus_configure_settings vmlinux EXPORT_SYMBOL_GPL -+0x0bf2c9fd nla_reserve_nohdr vmlinux EXPORT_SYMBOL -+0x6d16edba ilookup5 vmlinux EXPORT_SYMBOL -+0x1650bf27 rcutorture_record_progress vmlinux EXPORT_SYMBOL_GPL -+0xcd0529c7 _raw_spin_lock_irq vmlinux EXPORT_SYMBOL -+0x38f962da prepare_creds vmlinux EXPORT_SYMBOL -+0x44399123 mutex_unlock vmlinux EXPORT_SYMBOL -+0xdf8a2c89 genl_register_family_with_ops vmlinux EXPORT_SYMBOL -+0x27ad46ae dev_addr_flush vmlinux EXPORT_SYMBOL -+0x8acf07d0 pci_block_user_cfg_access vmlinux EXPORT_SYMBOL_GPL -+0x83a476ce bitmap_scnlistprintf vmlinux EXPORT_SYMBOL -+0xaee9c392 journal_release_buffer vmlinux EXPORT_SYMBOL -+0xce86792d sunrpc_cache_pipe_upcall vmlinux EXPORT_SYMBOL_GPL -+0x08cf1a7f blkdev_get_by_dev vmlinux EXPORT_SYMBOL -+0xd89da37f movable_zone vmlinux EXPORT_SYMBOL -+0xd87601cc ring_buffer_unlock_commit vmlinux EXPORT_SYMBOL_GPL -+0xd69b30e0 atomic64_add_unless vmlinux EXPORT_SYMBOL -+0xb792aa40 simple_fill_super vmlinux EXPORT_SYMBOL -+0xd7780596 have_submounts vmlinux EXPORT_SYMBOL -+0x07cc4a5d printk_timed_ratelimit vmlinux EXPORT_SYMBOL -+0x0a51ae5b virq_to_hw vmlinux EXPORT_SYMBOL_GPL -+0xeb62ec54 sock_queue_err_skb vmlinux EXPORT_SYMBOL -+0xe6ebc016 key_create_or_update vmlinux EXPORT_SYMBOL -+0x1f8db7f9 ring_buffer_overrun_cpu vmlinux EXPORT_SYMBOL_GPL -+0x0faef0ed __tasklet_schedule vmlinux EXPORT_SYMBOL -+0xfded48ed enable_kernel_fp vmlinux EXPORT_SYMBOL -+0x7b890c7b xprt_adjust_cwnd vmlinux EXPORT_SYMBOL_GPL -+0xf4f14de6 rtnl_trylock vmlinux EXPORT_SYMBOL -+0x1b852c21 dev_load vmlinux EXPORT_SYMBOL -+0xac0ba8c1 blk_iopoll_disable vmlinux EXPORT_SYMBOL -+0x5424df82 debugfs_create_u16 vmlinux EXPORT_SYMBOL_GPL -+0x4bbd1ffa bio_add_page vmlinux EXPORT_SYMBOL -+0x74193242 init_pid_ns vmlinux EXPORT_SYMBOL_GPL -+0x7ca341af kernel_thread vmlinux EXPORT_SYMBOL -+0x70aabf3e ipt_unregister_table net/ipv4/netfilter/ip_tables EXPORT_SYMBOL -+0x159abb63 usb_unlink_anchored_urbs vmlinux EXPORT_SYMBOL_GPL -+0x77ecac9f zlib_inflateEnd vmlinux EXPORT_SYMBOL -+0xa336c35b contig_page_data vmlinux EXPORT_SYMBOL -+0xcaaaccd0 inet_frag_evictor vmlinux EXPORT_SYMBOL -+0x68e0937e xt_unregister_target vmlinux EXPORT_SYMBOL -+0xb4fac2f9 pci_bus_add_device vmlinux EXPORT_SYMBOL_GPL -+0x23679939 __iowrite32_copy vmlinux EXPORT_SYMBOL_GPL -+0x11c5a183 nf_conntrack_unregister_notifier net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x324d7c16 xdr_enter_page vmlinux EXPORT_SYMBOL_GPL -+0x2fff2281 fib_rules_register vmlinux EXPORT_SYMBOL_GPL -+0x612390ad netpoll_set_trap vmlinux EXPORT_SYMBOL -+0xfaf98462 bitrev32 vmlinux EXPORT_SYMBOL -+0xb20a3754 simple_transaction_read vmlinux EXPORT_SYMBOL -+0x8a99a016 mempool_free_slab vmlinux EXPORT_SYMBOL -+0xe384a102 usb_speed_string vmlinux EXPORT_SYMBOL_GPL -+0x27ee902c generic_setxattr vmlinux EXPORT_SYMBOL -+0x00c37822 generic_getxattr vmlinux EXPORT_SYMBOL -+0x6e46a481 dma_mmap_coherent vmlinux EXPORT_SYMBOL_GPL -+0x3d7855c9 gss_mech_register vmlinux EXPORT_SYMBOL_GPL -+0x44a12e1b mpage_readpages vmlinux EXPORT_SYMBOL -+0x01a4494d i2c_unlock_adapter vmlinux EXPORT_SYMBOL_GPL -+0x0960ffb8 pci_request_regions vmlinux EXPORT_SYMBOL -+0x6b807a5f gpio_sysfs_set_active_low vmlinux EXPORT_SYMBOL_GPL -+0x4df119fa __bitmap_parse vmlinux EXPORT_SYMBOL -+0x6bd74d1a __wait_on_buffer vmlinux EXPORT_SYMBOL -+0xe1d61c3a cancel_delayed_work_sync vmlinux EXPORT_SYMBOL -+0xf870a8ab sock_create vmlinux EXPORT_SYMBOL -+0x4315bd81 usb_serial_handle_sysrq_char vmlinux EXPORT_SYMBOL_GPL -+0xadbc1c68 class_dev_iter_next vmlinux EXPORT_SYMBOL_GPL -+0x9dd28e76 debugfs_create_x32 vmlinux EXPORT_SYMBOL_GPL -+0xae6f72ac bprm_change_interp vmlinux EXPORT_SYMBOL -+0x673b3584 kill_litter_super vmlinux EXPORT_SYMBOL -+0x5133c2b5 inet_proto_csum_replace4 vmlinux EXPORT_SYMBOL -+0xadf3fc4c neigh_direct_output vmlinux EXPORT_SYMBOL -+0x0c8395fa usb_free_urb vmlinux EXPORT_SYMBOL_GPL -+0x7aee148f tty_prepare_flip_string_flags vmlinux EXPORT_SYMBOL_GPL -+0x119c901d tty_prepare_flip_string vmlinux EXPORT_SYMBOL_GPL -+0xf1216c75 prandom32 vmlinux EXPORT_SYMBOL -+0x55ba3776 blk_rq_check_limits vmlinux EXPORT_SYMBOL_GPL -+0x75bda77a seq_hlist_next vmlinux EXPORT_SYMBOL -+0x9fd078d4 account_page_dirtied vmlinux EXPORT_SYMBOL -+0x27d7e97e __lock_page_killable vmlinux EXPORT_SYMBOL_GPL -+0x622ef684 fib_rules_unregister vmlinux EXPORT_SYMBOL_GPL -+0x371d2b7d skb_copy_bits vmlinux EXPORT_SYMBOL -+0x189868d7 get_random_bytes_arch vmlinux EXPORT_SYMBOL -+0x6e1d6881 pcim_iomap vmlinux EXPORT_SYMBOL -+0x9b339c60 __blk_end_request_all vmlinux EXPORT_SYMBOL -+0xca601c92 crypto_register_ahash vmlinux EXPORT_SYMBOL_GPL -+0x8453215f sysfs_remove_link vmlinux EXPORT_SYMBOL_GPL -+0x8924eb1e rcu_force_quiescent_state vmlinux EXPORT_SYMBOL_GPL -+0x2827efe8 tcp_make_synack vmlinux EXPORT_SYMBOL -+0xf4979615 mii_check_gmii_support vmlinux EXPORT_SYMBOL -+0xa0d1a668 sysdev_class_create_file vmlinux EXPORT_SYMBOL_GPL -+0xc4fe793b find_get_page vmlinux EXPORT_SYMBOL -+0xae1a6d66 hrtimer_forward vmlinux EXPORT_SYMBOL_GPL -+0xf322a206 bit_waitqueue vmlinux EXPORT_SYMBOL -+0xefc93e71 threads_core_mask vmlinux EXPORT_SYMBOL_GPL -+0xae652611 sock_common_recvmsg vmlinux EXPORT_SYMBOL -+0x6a555f7c drop_file_write_access vmlinux EXPORT_SYMBOL_GPL -+0x966dd23b inet_csk_addr2sockaddr vmlinux EXPORT_SYMBOL_GPL -+0xeda0d76e gen_estimator_active vmlinux EXPORT_SYMBOL -+0x794ed58e get_driver vmlinux EXPORT_SYMBOL_GPL -+0x8251bcc3 bitmap_release_region vmlinux EXPORT_SYMBOL -+0x7054a3e4 request_dma vmlinux EXPORT_SYMBOL -+0x84f47571 ip_mc_inc_group vmlinux EXPORT_SYMBOL -+0x71621fe0 tcp_orphan_count vmlinux EXPORT_SYMBOL_GPL -+0x5f86d84e request_key_with_auxdata vmlinux EXPORT_SYMBOL -+0xaf2518eb fat_attach vmlinux EXPORT_SYMBOL_GPL -+0x22d8e440 sysfs_remove_bin_file vmlinux EXPORT_SYMBOL_GPL -+0xa53e8fbc kick_iocb vmlinux EXPORT_SYMBOL -+0xbc070ddd hid_dump_device vmlinux EXPORT_SYMBOL_GPL -+0xb81960ca snprintf vmlinux EXPORT_SYMBOL -+0x6b5064c6 get_io_context vmlinux EXPORT_SYMBOL -+0x80b3e715 proc_mkdir_mode vmlinux EXPORT_SYMBOL -+0xf57b6671 tag_pages_for_writeback vmlinux EXPORT_SYMBOL -+0x092d50a4 rpcauth_destroy_credcache vmlinux EXPORT_SYMBOL_GPL -+0x22586218 devm_kzalloc vmlinux EXPORT_SYMBOL_GPL -+0x97a8cbdc swiotlb_dma_supported vmlinux EXPORT_SYMBOL -+0x2296c00d crypto_attr_u32 vmlinux EXPORT_SYMBOL_GPL -+0x77dcb28d __bread vmlinux EXPORT_SYMBOL -+0xbba159e0 files_lglock_local_unlock vmlinux EXPORT_SYMBOL -+0xd640e8b8 follow_pfn vmlinux EXPORT_SYMBOL -+0xaa764215 hrtimer_init vmlinux EXPORT_SYMBOL_GPL -+0x954488a4 syncookie_secret vmlinux EXPORT_SYMBOL -+0x9ceb163c memcpy_toiovec vmlinux EXPORT_SYMBOL -+0x74b5d898 usb_disable_xhci_ports vmlinux EXPORT_SYMBOL_GPL -+0x1b6314fd in_aton vmlinux EXPORT_SYMBOL -+0x8bf80102 neigh_resolve_output vmlinux EXPORT_SYMBOL -+0xd6677342 journal_init_dev vmlinux EXPORT_SYMBOL -+0x176b3f91 posix_unblock_lock vmlinux EXPORT_SYMBOL -+0x9acd079c __mnt_is_readonly vmlinux EXPORT_SYMBOL_GPL -+0x500dda7f nf_nat_ftp_hook net/netfilter/nf_conntrack_ftp EXPORT_SYMBOL_GPL -+0x6b52164d tcp_close vmlinux EXPORT_SYMBOL -+0x190b6c5c __scm_send vmlinux EXPORT_SYMBOL -+0x227822d5 usb_register_dev vmlinux EXPORT_SYMBOL_GPL -+0x8fb45bb1 scsi_dma_map vmlinux EXPORT_SYMBOL -+0xa07ed110 xz_dec_init vmlinux EXPORT_SYMBOL -+0x3f906124 try_to_free_buffers vmlinux EXPORT_SYMBOL -+0xef120637 wait_iff_congested vmlinux EXPORT_SYMBOL -+0xe7b1acbe __put_cred vmlinux EXPORT_SYMBOL -+0xb15bd8fa tb_ticks_per_sec vmlinux EXPORT_SYMBOL -+0x3cd06035 add_input_randomness vmlinux EXPORT_SYMBOL_GPL -+0x9ed685ee iov_iter_advance vmlinux EXPORT_SYMBOL -+0x757f088f cpm_muram_offset vmlinux EXPORT_SYMBOL -+0x90501868 transfer_to_handler vmlinux EXPORT_SYMBOL -+0xacf5a07d xdr_set_scratch_buffer vmlinux EXPORT_SYMBOL_GPL -+0x0ac28878 scsi_unblock_requests vmlinux EXPORT_SYMBOL -+0xf6d1a555 device_remove_bin_file vmlinux EXPORT_SYMBOL_GPL -+0x980fd9e0 tty_port_free_xmit_buf vmlinux EXPORT_SYMBOL -+0x8c28d738 nf_ct_deliver_cached_events net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xaf5bf6ef nfs_debug vmlinux EXPORT_SYMBOL_GPL -+0x7267db00 hwrng_unregister vmlinux EXPORT_SYMBOL_GPL -+0x94202ff1 crypto_nivaead_type vmlinux EXPORT_SYMBOL_GPL -+0x4f0d0c17 bdi_writeout_inc vmlinux EXPORT_SYMBOL_GPL -+0xdc7776cc xfrm6_rcv_spi vmlinux EXPORT_SYMBOL -+0x27c1e63f usb_amd_find_chipset_info vmlinux EXPORT_SYMBOL_GPL -+0xcf307410 disk_stack_limits vmlinux EXPORT_SYMBOL -+0x75e8f3c3 crypto_register_notifier vmlinux EXPORT_SYMBOL_GPL -+0x57b57ebe jiffies_to_timespec vmlinux EXPORT_SYMBOL -+0x5f4e77a9 pskb_put vmlinux EXPORT_SYMBOL_GPL -+0xfa6583df i2c_master_send vmlinux EXPORT_SYMBOL -+0xcaae18ce device_reprobe vmlinux EXPORT_SYMBOL_GPL -+0x479c3c86 find_next_zero_bit vmlinux EXPORT_SYMBOL -+0x8ee69235 timeval_to_jiffies vmlinux EXPORT_SYMBOL -+0x0840985a dev_kfree_skb_any vmlinux EXPORT_SYMBOL -+0x384455fa journal_abort vmlinux EXPORT_SYMBOL -+0x2d550ef5 seq_open vmlinux EXPORT_SYMBOL -+0x88c8ae9d mnt_drop_write vmlinux EXPORT_SYMBOL_GPL -+0x297d6b80 rpc_uaddr2sockaddr vmlinux EXPORT_SYMBOL_GPL -+0x7e394c4e sysctl_local_reserved_ports vmlinux EXPORT_SYMBOL -+0x1cc4c90f pci_bus_type vmlinux EXPORT_SYMBOL -+0xeaf46b33 pci_enable_bridges vmlinux EXPORT_SYMBOL -+0x8cf4e71e simple_readpage vmlinux EXPORT_SYMBOL -+0x83f092b9 __lock_page vmlinux EXPORT_SYMBOL -+0xb140d14c ring_buffer_read vmlinux EXPORT_SYMBOL_GPL -+0xf499fdb2 rcu_barrier_bh vmlinux EXPORT_SYMBOL_GPL -+0x46b6baff synchronize_srcu_expedited vmlinux EXPORT_SYMBOL_GPL -+0xe98d2676 cpu_remove_dev_attr vmlinux EXPORT_SYMBOL_GPL -+0xfeb79024 tcp_cong_avoid_ai vmlinux EXPORT_SYMBOL_GPL -+0xab6bde28 sysctl_max_syn_backlog vmlinux EXPORT_SYMBOL -+0xca059c46 usb_altnum_to_altsetting vmlinux EXPORT_SYMBOL_GPL -+0x6f497d79 pci_create_slot vmlinux EXPORT_SYMBOL_GPL -+0xa43762aa blk_delay_queue vmlinux EXPORT_SYMBOL -+0xe6a1e7fb follow_down vmlinux EXPORT_SYMBOL -+0xc06502c4 __generic_file_aio_write vmlinux EXPORT_SYMBOL -+0x5aed6e64 filemap_write_and_wait_range vmlinux EXPORT_SYMBOL -+0xf229625e devm_ioremap_prot vmlinux EXPORT_SYMBOL -+0xd85028c2 genphy_read_status vmlinux EXPORT_SYMBOL -+0x97d977b5 tty_unregister_driver vmlinux EXPORT_SYMBOL -+0xc404cbb3 pci_reenable_device vmlinux EXPORT_SYMBOL -+0xc6a0b57b get_write_access vmlinux EXPORT_SYMBOL -+0x7c22ff1f invalidate_mapping_pages vmlinux EXPORT_SYMBOL -+0xc0c17332 pci_enable_rom vmlinux EXPORT_SYMBOL_GPL -+0xf3bf0bce __bitmap_complement vmlinux EXPORT_SYMBOL -+0xe2e8065e memdup_user vmlinux EXPORT_SYMBOL -+0x221623f5 thermal_cooling_device_unregister vmlinux EXPORT_SYMBOL -+0xcca27eeb del_timer vmlinux EXPORT_SYMBOL -+0xeb9aea7d dma_get_required_mask vmlinux EXPORT_SYMBOL_GPL -+0x4dc45be9 nf_log_unbind_pf vmlinux EXPORT_SYMBOL -+0xeaae7eca usb_get_current_frame_number vmlinux EXPORT_SYMBOL_GPL -+0x80fdefab map_destroy vmlinux EXPORT_SYMBOL -+0x3e3944d8 pcie_update_link_speed vmlinux EXPORT_SYMBOL_GPL -+0x5bb906a7 wait_rcu_gp vmlinux EXPORT_SYMBOL_GPL -+0x74046876 nf_ct_expect_find_get net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xf397c836 tcp_v4_send_check vmlinux EXPORT_SYMBOL -+0xbba15e0b dev_close vmlinux EXPORT_SYMBOL -+0x6e22c276 __mark_inode_dirty vmlinux EXPORT_SYMBOL -+0x97c92d4b noop_qdisc vmlinux EXPORT_SYMBOL -+0x1ce622fb sock_alloc_send_skb vmlinux EXPORT_SYMBOL -+0xd9ce8f0c strnlen vmlinux EXPORT_SYMBOL -+0x4953f064 unregister_filesystem vmlinux EXPORT_SYMBOL -+0xd418e1c0 adjust_resource vmlinux EXPORT_SYMBOL -+0xdd91ae2a xfrm_state_insert vmlinux EXPORT_SYMBOL -+0x030d11a8 kmsg_dump_register vmlinux EXPORT_SYMBOL_GPL -+0x4e05fd2a rpc_peeraddr2str vmlinux EXPORT_SYMBOL_GPL -+0x40728a63 xt_find_revision vmlinux EXPORT_SYMBOL_GPL -+0x82e3b54d of_node_get vmlinux EXPORT_SYMBOL -+0x08ad10e2 of_node_put vmlinux EXPORT_SYMBOL -+0x8d18a199 __destroy_inode vmlinux EXPORT_SYMBOL -+0xb18b572e nf_conntrack_l3proto_generic net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x9a1c768a tcp_is_cwnd_limited vmlinux EXPORT_SYMBOL_GPL -+0xdcc97380 pci_bus_add_devices vmlinux EXPORT_SYMBOL -+0xce9b668c blk_rq_unmap_user vmlinux EXPORT_SYMBOL -+0x768f9bc5 crypto_mod_get vmlinux EXPORT_SYMBOL_GPL -+0x0bc477a2 irq_set_irq_type vmlinux EXPORT_SYMBOL -+0xce2840e7 irq_set_irq_wake vmlinux EXPORT_SYMBOL -+0x36efd128 __remove_inode_hash vmlinux EXPORT_SYMBOL -+0xae52c20e __lru_cache_add vmlinux EXPORT_SYMBOL -+0x6128b5fc __printk_ratelimit vmlinux EXPORT_SYMBOL -+0x7db8133c switch_mmu_context vmlinux EXPORT_SYMBOL -+0xb6938e50 xdr_read_pages vmlinux EXPORT_SYMBOL_GPL -+0xad06c17e xdr_encode_pages vmlinux EXPORT_SYMBOL_GPL -+0xcc1f1c3d inet_twdr_hangman vmlinux EXPORT_SYMBOL_GPL -+0xcacd272d atomic64_sub_return vmlinux EXPORT_SYMBOL -+0x5b256543 __blk_end_request_cur vmlinux EXPORT_SYMBOL -+0x5b40de9d __blk_end_request_err vmlinux EXPORT_SYMBOL_GPL -+0xb2682405 utf8_to_utf32 vmlinux EXPORT_SYMBOL -+0x9621849f ring_buffer_event_data vmlinux EXPORT_SYMBOL_GPL -+0xd2423d66 scsi_prep_return vmlinux EXPORT_SYMBOL -+0x2cf5fa92 __bus_register vmlinux EXPORT_SYMBOL_GPL -+0x4fe99583 atomic64_dec_if_positive vmlinux EXPORT_SYMBOL -+0x2c3b9273 crypto_sha1_update vmlinux EXPORT_SYMBOL -+0x2d727890 override_creds vmlinux EXPORT_SYMBOL -+0x131db64a system_long_wq vmlinux EXPORT_SYMBOL_GPL -+0x3ca16d23 kmsg_dump_unregister vmlinux EXPORT_SYMBOL_GPL -+0x606d0b09 secure_tcpv6_sequence_number vmlinux EXPORT_SYMBOL -+0x78381b79 input_register_handle vmlinux EXPORT_SYMBOL -+0x6ca1d1a4 atomic64_read vmlinux EXPORT_SYMBOL -+0x979a2d28 blkdev_issue_zeroout vmlinux EXPORT_SYMBOL -+0x461818bb journal_get_create_access vmlinux EXPORT_SYMBOL -+0xe15b92eb handle_level_irq vmlinux EXPORT_SYMBOL_GPL -+0xd31ccb06 of_machine_is_compatible vmlinux EXPORT_SYMBOL -+0xf971d6e2 sdio_writesb vmlinux EXPORT_SYMBOL_GPL -+0x42b364ef scatterwalk_done vmlinux EXPORT_SYMBOL_GPL -+0x58ffec8b request_key vmlinux EXPORT_SYMBOL -+0x3923bd3b kern_unmount vmlinux EXPORT_SYMBOL -+0xfa9dd504 timecompare_transform vmlinux EXPORT_SYMBOL_GPL -+0xae616697 usb_control_msg vmlinux EXPORT_SYMBOL_GPL -+0x9846a085 mtd_table_mutex vmlinux EXPORT_SYMBOL_GPL -+0x0c8aadeb nla_append vmlinux EXPORT_SYMBOL -+0x351f3c81 pcim_iomap_regions vmlinux EXPORT_SYMBOL -+0xb86e4ab9 random32 vmlinux EXPORT_SYMBOL -+0x51ad88ca skcipher_geniv_free vmlinux EXPORT_SYMBOL_GPL -+0x2c204319 vfs_llseek vmlinux EXPORT_SYMBOL -+0x81d70b6e __irq_set_handler vmlinux EXPORT_SYMBOL_GPL -+0xa8bdd720 dev_set_drvdata vmlinux EXPORT_SYMBOL -+0xdca20876 dev_get_drvdata vmlinux EXPORT_SYMBOL -+0x7ceaf0d5 generic_handle_irq vmlinux EXPORT_SYMBOL_GPL -+0x9ea865cf blocking_notifier_chain_cond_register vmlinux EXPORT_SYMBOL_GPL -+0xb75cd36b __xfrm_state_destroy vmlinux EXPORT_SYMBOL -+0x400bf80a bfifo_qdisc_ops vmlinux EXPORT_SYMBOL -+0x01c4ff56 usb_unpoison_urb vmlinux EXPORT_SYMBOL_GPL -+0x4242db6e tty_port_init vmlinux EXPORT_SYMBOL -+0x74bae351 complete_request_key vmlinux EXPORT_SYMBOL -+0x1f8544b8 panic_timeout vmlinux EXPORT_SYMBOL_GPL -+0xa20ce1b8 net_msg_warn vmlinux EXPORT_SYMBOL -+0x7e7052eb __sock_recv_timestamp vmlinux EXPORT_SYMBOL_GPL -+0x6225637e md5_transform vmlinux EXPORT_SYMBOL -+0xc0d579ef noop_fsync vmlinux EXPORT_SYMBOL -+0x357d2c4a scsi_add_host_with_dma vmlinux EXPORT_SYMBOL -+0x1d119736 devres_remove_group vmlinux EXPORT_SYMBOL_GPL -+0x4f2a0c62 crypto_hash_walk_first vmlinux EXPORT_SYMBOL_GPL -+0x118f01ea putname vmlinux EXPORT_SYMBOL -+0xb74b1b5c inet_sendpage vmlinux EXPORT_SYMBOL -+0x5fa17c73 sk_filter_release_rcu vmlinux EXPORT_SYMBOL -+0x52aa3821 dev_get_by_index_rcu vmlinux EXPORT_SYMBOL -+0x161edd60 dev_set_allmulti vmlinux EXPORT_SYMBOL -+0x556b4614 mmc_can_erase vmlinux EXPORT_SYMBOL -+0x6fdc65c4 i2c_add_adapter vmlinux EXPORT_SYMBOL -+0x8c140a5a input_mt_report_finger_count vmlinux EXPORT_SYMBOL -+0xea10655a __bitmap_intersects vmlinux EXPORT_SYMBOL -+0xf313da4e sha_transform vmlinux EXPORT_SYMBOL -+0x9b6eb137 ksize vmlinux EXPORT_SYMBOL -+0xf747dd44 kstat vmlinux EXPORT_SYMBOL -+0x68748335 pci_stop_bus_device vmlinux EXPORT_SYMBOL_GPL -+0xf2334557 kobject_set_name vmlinux EXPORT_SYMBOL -+0xcf586f6d shmem_truncate_range vmlinux EXPORT_SYMBOL_GPL -+0xa3e7c113 ring_buffer_iter_peek vmlinux EXPORT_SYMBOL_GPL -+0xa5efbf4c async_synchronize_full vmlinux EXPORT_SYMBOL_GPL -+0xc141de33 set_device_ro vmlinux EXPORT_SYMBOL -+0xbb038ce4 perf_unregister_guest_info_callbacks vmlinux EXPORT_SYMBOL_GPL -+0x6c9e8a40 usb_anchor_urb vmlinux EXPORT_SYMBOL_GPL -+0xa553f1ed pci_clear_mwi vmlinux EXPORT_SYMBOL -+0x0b0c5bc2 shash_attr_alg vmlinux EXPORT_SYMBOL_GPL -+0x63eb9355 panic_blink vmlinux EXPORT_SYMBOL -+0x9b349bdd __sync_dirty_buffer vmlinux EXPORT_SYMBOL -+0xcfbb9503 kmap_high vmlinux EXPORT_SYMBOL -+0x6f86e89e cancel_dirty_page vmlinux EXPORT_SYMBOL -+0xf4fc2d6c __ring_buffer_alloc vmlinux EXPORT_SYMBOL_GPL -+0x82072614 tasklet_kill vmlinux EXPORT_SYMBOL -+0xa8de6a48 i2c_use_client vmlinux EXPORT_SYMBOL -+0xdd66b703 scsi_print_command vmlinux EXPORT_SYMBOL -+0xbb1da1d5 pci_try_set_mwi vmlinux EXPORT_SYMBOL -+0xcda0bf50 bio_endio vmlinux EXPORT_SYMBOL -+0x85c7f674 ring_buffer_normalize_time_stamp vmlinux EXPORT_SYMBOL_GPL -+0x438b62ec nf_ct_expect_unregister_notifier net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xc6f3dff4 sk_stop_timer vmlinux EXPORT_SYMBOL -+0x530e0f8a of_platform_bus_probe vmlinux EXPORT_SYMBOL -+0xffdb82bc sg_free_table vmlinux EXPORT_SYMBOL -+0xbac7a6de locks_remove_posix vmlinux EXPORT_SYMBOL -+0xb0b85f47 ring_buffer_iter_reset vmlinux EXPORT_SYMBOL_GPL -+0xbc68ed8a pcie_port_service_unregister vmlinux EXPORT_SYMBOL -+0x5d5b5a16 radix_tree_delete vmlinux EXPORT_SYMBOL -+0x76831f67 tcp_slow_start vmlinux EXPORT_SYMBOL_GPL -+0xdb9628fb proc_net_netfilter vmlinux EXPORT_SYMBOL -+0x503a9a19 dev_activate vmlinux EXPORT_SYMBOL -+0xa6abec58 __pneigh_lookup vmlinux EXPORT_SYMBOL_GPL -+0xac20b868 i2c_add_mux_adapter vmlinux EXPORT_SYMBOL_GPL -+0xe8cfb9b7 devm_ioremap vmlinux EXPORT_SYMBOL -+0x050dd9e3 devm_iounmap vmlinux EXPORT_SYMBOL -+0x5541ea93 on_each_cpu vmlinux EXPORT_SYMBOL -+0x53775014 dma_set_mask vmlinux EXPORT_SYMBOL -+0x12c21380 nla_reserve vmlinux EXPORT_SYMBOL -+0x179f2b81 bioset_create vmlinux EXPORT_SYMBOL -+0x5717b1d8 rtnl_put_cacheinfo vmlinux EXPORT_SYMBOL_GPL -+0xea124bd1 gcd vmlinux EXPORT_SYMBOL_GPL -+0xb954f080 ihold vmlinux EXPORT_SYMBOL -+0x8a6d1314 names_cachep vmlinux EXPORT_SYMBOL -+0x8aaa5d67 invalidate_inode_pages2_range vmlinux EXPORT_SYMBOL_GPL -+0xc8e96dea qword_addhex vmlinux EXPORT_SYMBOL_GPL -+0x78328e4d xfrm_policy_register_afinfo vmlinux EXPORT_SYMBOL -+0x5d63436b pci_unmap_rom vmlinux EXPORT_SYMBOL -+0x118e0f3d key_instantiate_and_link vmlinux EXPORT_SYMBOL -+0xb1aaff79 dentry_path_raw vmlinux EXPORT_SYMBOL -+0x6a28defe xfrm_sad_getinfo vmlinux EXPORT_SYMBOL -+0x0ac2bf08 netif_napi_del vmlinux EXPORT_SYMBOL -+0x8014b6af input_event_from_user vmlinux EXPORT_SYMBOL_GPL -+0x4484a5a4 wait_for_device_probe vmlinux EXPORT_SYMBOL_GPL -+0xd6244170 tty_port_put vmlinux EXPORT_SYMBOL -+0xf8fa9744 crypto_register_alg vmlinux EXPORT_SYMBOL_GPL -+0xf79a16f8 debugfs_rename vmlinux EXPORT_SYMBOL_GPL -+0xe4653d19 single_open vmlinux EXPORT_SYMBOL -+0xc794266c page_follow_link_light vmlinux EXPORT_SYMBOL -+0x4146fc0f xfrm6_find_1stfragopt vmlinux EXPORT_SYMBOL -+0xfef96e23 __scsi_print_command vmlinux EXPORT_SYMBOL -+0xc40d19d3 kthread_stop vmlinux EXPORT_SYMBOL -+0xa7b91a7b lockd_down vmlinux EXPORT_SYMBOL_GPL -+0xd3481bf6 journal_trans_will_send_data_barrier vmlinux EXPORT_SYMBOL -+0x750b2814 xprt_reserve_xprt vmlinux EXPORT_SYMBOL_GPL -+0x090ed695 hid_register_report vmlinux EXPORT_SYMBOL_GPL -+0x1963b26f rtc_set_alarm vmlinux EXPORT_SYMBOL_GPL -+0x3fe72f15 __scsi_get_command vmlinux EXPORT_SYMBOL_GPL -+0x1b97d8ce __scsi_put_command vmlinux EXPORT_SYMBOL -+0xaa4a7797 hex2bin vmlinux EXPORT_SYMBOL -+0x91d266c7 crypto_default_rng vmlinux EXPORT_SYMBOL_GPL -+0x2c103133 inet_csk_listen_start vmlinux EXPORT_SYMBOL_GPL -+0xb91453c1 of_register_spi_devices vmlinux EXPORT_SYMBOL -+0xfcc2a43c utf32_to_utf8 vmlinux EXPORT_SYMBOL -+0x800df1d7 groups_free vmlinux EXPORT_SYMBOL -+0xf611bda0 cleanup_srcu_struct vmlinux EXPORT_SYMBOL_GPL -+0x3980aac1 unregister_reboot_notifier vmlinux EXPORT_SYMBOL -+0x3aa91a68 tcf_destroy_chain vmlinux EXPORT_SYMBOL -+0x255f3a7f sk_clone vmlinux EXPORT_SYMBOL_GPL -+0x3bd2becc tty_perform_flush vmlinux EXPORT_SYMBOL_GPL -+0x447e96b6 pci_request_region_exclusive vmlinux EXPORT_SYMBOL -+0x9cdf0ec5 vfsmount_lock_global_lock_online vmlinux EXPORT_SYMBOL -+0x495c501c debugfs_remove_recursive vmlinux EXPORT_SYMBOL_GPL -+0xfdb6cedc _raw_read_unlock_bh vmlinux EXPORT_SYMBOL -+0x117b494d neigh_parms_alloc vmlinux EXPORT_SYMBOL -+0x19a304ba usb_disabled vmlinux EXPORT_SYMBOL_GPL -+0xf52321e0 atomic64_sub vmlinux EXPORT_SYMBOL -+0x0bb7c01f mount_single vmlinux EXPORT_SYMBOL -+0xef109449 interruptible_sleep_on vmlinux EXPORT_SYMBOL -+0x111d29eb __ip_route_output_key vmlinux EXPORT_SYMBOL_GPL -+0xb9c425de register_syscore_ops vmlinux EXPORT_SYMBOL_GPL -+0x91a5865c blk_queue_invalidate_tags vmlinux EXPORT_SYMBOL -+0xab5d4b6c remove_irq vmlinux EXPORT_SYMBOL_GPL -+0x93a6e0b2 io_schedule vmlinux EXPORT_SYMBOL -+0x61ce005d disk_part_iter_next vmlinux EXPORT_SYMBOL_GPL -+0xb08b4f8a block_write_end vmlinux EXPORT_SYMBOL -+0xaa8e4c8a pid_vnr vmlinux EXPORT_SYMBOL_GPL -+0x56fa71f2 __xfrm_decode_session vmlinux EXPORT_SYMBOL -+0xad5f1b39 nf_net_ipv4_netfilter_sysctl_path vmlinux EXPORT_SYMBOL_GPL -+0x576dc245 tty_port_lower_dtr_rts vmlinux EXPORT_SYMBOL -+0xf803fe39 bitmap_set vmlinux EXPORT_SYMBOL -+0x230e0698 __clocksource_updatefreq_scale vmlinux EXPORT_SYMBOL_GPL -+0x1528ad8f netlink_set_err vmlinux EXPORT_SYMBOL -+0x8e488ec3 alloc_netdev_mqs vmlinux EXPORT_SYMBOL -+0xc71e5323 bus_register_notifier vmlinux EXPORT_SYMBOL_GPL -+0x1d021d32 gpiochip_add vmlinux EXPORT_SYMBOL_GPL -+0x336154ca rcutorture_record_test_transition vmlinux EXPORT_SYMBOL_GPL -+0xf77020ef inet_listen vmlinux EXPORT_SYMBOL -+0x32e49bab register_snap_client vmlinux EXPORT_SYMBOL -+0x9287ab43 __dst_destroy_metrics_generic vmlinux EXPORT_SYMBOL -+0x3281d137 skb_queue_purge vmlinux EXPORT_SYMBOL -+0xcd0b9f77 get_unmapped_area vmlinux EXPORT_SYMBOL -+0xa196356e add_to_page_cache_lru vmlinux EXPORT_SYMBOL_GPL -+0x07b52e38 rtnl_unregister vmlinux EXPORT_SYMBOL_GPL -+0x816a4a8f platform_bus_type vmlinux EXPORT_SYMBOL_GPL -+0x8eb489cc blk_rq_map_user vmlinux EXPORT_SYMBOL -+0x95666f79 generic_pipe_buf_release vmlinux EXPORT_SYMBOL -+0x9b49a62b nf_ct_gre_keymap_add net/netfilter/nf_conntrack_proto_gre EXPORT_SYMBOL_GPL -+0x76486f91 d_find_alias vmlinux EXPORT_SYMBOL -+0x760a0f4f yield vmlinux EXPORT_SYMBOL -+0xdfce92d0 xt_check_target vmlinux EXPORT_SYMBOL_GPL -+0x693bf8ad sdio_claim_irq vmlinux EXPORT_SYMBOL_GPL -+0x6bd2a517 fsstack_copy_attr_all vmlinux EXPORT_SYMBOL_GPL -+0x7d2d68ef __nf_ct_try_assign_helper net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xf3bfc4a0 udp6_lib_lookup vmlinux EXPORT_SYMBOL_GPL -+0xa9ff0067 xfrm_init_replay vmlinux EXPORT_SYMBOL -+0x4cd13364 udp4_lib_lookup vmlinux EXPORT_SYMBOL_GPL -+0xaee50a42 genl_unregister_ops vmlinux EXPORT_SYMBOL -+0x9e2000a7 memcpy_toiovecend vmlinux EXPORT_SYMBOL -+0xcc3ad809 scsi_command_normalize_sense vmlinux EXPORT_SYMBOL -+0x2f19f806 inode_sb_list_add vmlinux EXPORT_SYMBOL_GPL -+0xc0072342 inode_init_always vmlinux EXPORT_SYMBOL -+0x37443f52 d_invalidate vmlinux EXPORT_SYMBOL -+0xa0b04675 vmalloc_32 vmlinux EXPORT_SYMBOL -+0x8a13f155 pid_task vmlinux EXPORT_SYMBOL -+0x33b84f74 copy_page vmlinux EXPORT_SYMBOL -+0x115dd19b seq_print_acct net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x447aabed stp_proto_register vmlinux EXPORT_SYMBOL_GPL -+0x40b9610d input_register_handler vmlinux EXPORT_SYMBOL -+0xc0572d04 textsearch_unregister vmlinux EXPORT_SYMBOL -+0xf54c51a2 dma_pool_free vmlinux EXPORT_SYMBOL -+0xdb274e52 monotonic_to_bootbased vmlinux EXPORT_SYMBOL_GPL -+0x86b4b68f inet6_csk_bind_conflict vmlinux EXPORT_SYMBOL_GPL -+0xa35de80f ipv4_config vmlinux EXPORT_SYMBOL -+0x94ecde24 netif_carrier_on vmlinux EXPORT_SYMBOL -+0x74b8aeab fib_rules_lookup vmlinux EXPORT_SYMBOL_GPL -+0xb0b847ac __bitmap_full vmlinux EXPORT_SYMBOL -+0x4059792f print_hex_dump vmlinux EXPORT_SYMBOL -+0x22f5f5bd ip6_route_output vmlinux EXPORT_SYMBOL -+0x98c1c63d __rta_fill vmlinux EXPORT_SYMBOL -+0x87b20911 __dst_free vmlinux EXPORT_SYMBOL -+0xfe1c56c4 inode_newsize_ok vmlinux EXPORT_SYMBOL -+0x89b3107b isa_mem_base vmlinux EXPORT_SYMBOL -+0xcbb1b165 inet_csk_destroy_sock vmlinux EXPORT_SYMBOL -+0x290bcd04 pci_disable_obff vmlinux EXPORT_SYMBOL -+0x78df6bd7 no_pci_devices vmlinux EXPORT_SYMBOL -+0xc2e00f4e nfs_pageio_reset_read_mds vmlinux EXPORT_SYMBOL_GPL -+0x1e26be3b get_anon_bdev vmlinux EXPORT_SYMBOL -+0x6b29a1fa ring_buffer_event_length vmlinux EXPORT_SYMBOL_GPL -+0x84b183ae strncmp vmlinux EXPORT_SYMBOL -+0x5ee2150e sock_kfree_s vmlinux EXPORT_SYMBOL -+0xaf67115a usb_stor_access_xfer_buf vmlinux EXPORT_SYMBOL_GPL -+0xa34f1ef5 crc32_le vmlinux EXPORT_SYMBOL -+0xf54bd49b lcm vmlinux EXPORT_SYMBOL_GPL -+0x13354608 scatterwalk_map_and_copy vmlinux EXPORT_SYMBOL_GPL -+0xf7dcfb23 empty_aops vmlinux EXPORT_SYMBOL -+0x43b911a1 __task_pid_nr_ns vmlinux EXPORT_SYMBOL -+0xe368f912 ethtool_op_get_link vmlinux EXPORT_SYMBOL -+0xa40a8590 input_event_to_user vmlinux EXPORT_SYMBOL_GPL -+0x657aa70a input_unregister_device vmlinux EXPORT_SYMBOL -+0xbfbebdf2 read_cache_pages vmlinux EXPORT_SYMBOL -+0x4aadeb9a ring_buffer_alloc_read_page vmlinux EXPORT_SYMBOL_GPL -+0x53445f68 nlm_debug vmlinux EXPORT_SYMBOL_GPL -+0x8ac6cdbe ip_generic_getfrag vmlinux EXPORT_SYMBOL -+0x825f0e72 stp_proto_unregister vmlinux EXPORT_SYMBOL_GPL -+0x42671630 call_netdevice_notifiers vmlinux EXPORT_SYMBOL -+0xdc825d6c usb_amd_quirk_pll_disable vmlinux EXPORT_SYMBOL_GPL -+0xc50de15c mii_nway_restart vmlinux EXPORT_SYMBOL -+0x208c9e61 crypto_dequeue_request vmlinux EXPORT_SYMBOL_GPL -+0x33ee71a8 crypto_enqueue_request vmlinux EXPORT_SYMBOL_GPL -+0x3a45b778 fat_add_entries vmlinux EXPORT_SYMBOL_GPL -+0x63709e0c thaw_bdev vmlinux EXPORT_SYMBOL -+0xec38d5b9 irq_create_mapping vmlinux EXPORT_SYMBOL_GPL -+0x64f9ca11 sk_run_filter vmlinux EXPORT_SYMBOL -+0xa1ec4dcb netdev_rx_csum_fault vmlinux EXPORT_SYMBOL -+0x55e74041 of_pci_address_to_resource vmlinux EXPORT_SYMBOL_GPL -+0xa7355e76 devres_release_group vmlinux EXPORT_SYMBOL_GPL -+0xa2d161c9 ipt_register_table net/ipv4/netfilter/ip_tables EXPORT_SYMBOL -+0x33274026 xdr_decode_array2 vmlinux EXPORT_SYMBOL_GPL -+0x7b594a76 ipv6_push_nfrag_opts vmlinux EXPORT_SYMBOL -+0x7a73b3d5 neigh_sysctl_unregister vmlinux EXPORT_SYMBOL -+0x7d1d23b5 blk_abort_request vmlinux EXPORT_SYMBOL_GPL -+0x7cefa3c8 __scm_destroy vmlinux EXPORT_SYMBOL -+0x88ebb649 sdio_writeb_readb vmlinux EXPORT_SYMBOL_GPL -+0x8b82c4cf d_move vmlinux EXPORT_SYMBOL -+0x5091b823 ring_buffer_read_start vmlinux EXPORT_SYMBOL_GPL -+0x77b851c4 cacheable_memzero vmlinux EXPORT_SYMBOL -+0x8d80529b virq_is_host vmlinux EXPORT_SYMBOL_GPL -+0x450872a4 ipcomp_destroy net/xfrm/xfrm_ipcomp EXPORT_SYMBOL_GPL -+0xd0035e43 dev_addr_del_multiple vmlinux EXPORT_SYMBOL -+0x5f0c41ea request_key_async vmlinux EXPORT_SYMBOL -+0x639ad9ba touch_atime vmlinux EXPORT_SYMBOL -+0x733b2383 next_tlbcam_idx vmlinux EXPORT_SYMBOL -+0x61c243fc mod_timer_pending vmlinux EXPORT_SYMBOL -+0x1f6cf216 rtnl_configure_link vmlinux EXPORT_SYMBOL -+0x5f26443b sock_wmalloc vmlinux EXPORT_SYMBOL -+0x1e6d26a8 strstr vmlinux EXPORT_SYMBOL -+0x349cba85 strchr vmlinux EXPORT_SYMBOL -+0xafba9111 qe_immr vmlinux EXPORT_SYMBOL -+0xadabd59e inet_csk_listen_stop vmlinux EXPORT_SYMBOL_GPL -+0x7ba60ec5 usb_serial_generic_resume vmlinux EXPORT_SYMBOL_GPL -+0x0cf5646d usb_wait_anchor_empty_timeout vmlinux EXPORT_SYMBOL_GPL -+0x71f78ce2 cfi_qry_mode_off vmlinux EXPORT_SYMBOL_GPL -+0xf2fca922 uart_parse_options vmlinux EXPORT_SYMBOL_GPL -+0xcfa90d57 kobject_create_and_add vmlinux EXPORT_SYMBOL_GPL -+0x589483d5 setup_new_exec vmlinux EXPORT_SYMBOL -+0xa65972b8 _memcpy_toio vmlinux EXPORT_SYMBOL -+0x109bccfc xfrm_state_lookup_byaddr vmlinux EXPORT_SYMBOL -+0xac888215 pskb_expand_head vmlinux EXPORT_SYMBOL -+0xeabea9a3 of_i2c_register_devices vmlinux EXPORT_SYMBOL -+0x6f9f1dde i2c_release_client vmlinux EXPORT_SYMBOL -+0xdf2478f7 giveup_fpu vmlinux EXPORT_SYMBOL -+0xbff12409 giveup_spe vmlinux EXPORT_SYMBOL -+0xa19aa2a4 rtnl_link_register vmlinux EXPORT_SYMBOL_GPL -+0xc53bb9d1 lock_may_write vmlinux EXPORT_SYMBOL -+0x7a461bdf bh_submit_read vmlinux EXPORT_SYMBOL -+0x1bb795cc of_create_pci_dev vmlinux EXPORT_SYMBOL -+0x91f08ce3 xdr_buf_read_netobj vmlinux EXPORT_SYMBOL_GPL -+0xad37c04e eth_change_mtu vmlinux EXPORT_SYMBOL -+0x78bb1ee1 eth_header_parse vmlinux EXPORT_SYMBOL -+0x42977ad4 __hw_addr_del_multiple vmlinux EXPORT_SYMBOL -+0x6e586165 bdev_stack_limits vmlinux EXPORT_SYMBOL -+0x1114011d threads_shift vmlinux EXPORT_SYMBOL_GPL -+0x3c9e7dc8 nf_nat_pptp_hook_exp_gre net/netfilter/nf_conntrack_pptp EXPORT_SYMBOL_GPL -+0x3c514b70 nf_conntrack_hash_insert net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xad01e7b9 sock_wake_async vmlinux EXPORT_SYMBOL -+0x506746b6 getrawmonotonic vmlinux EXPORT_SYMBOL -+0xb6599b9a machine_check_exception vmlinux EXPORT_SYMBOL -+0xfd4b9fec of_platform_device_create vmlinux EXPORT_SYMBOL -+0x0e2b0fec fat_free_clusters vmlinux EXPORT_SYMBOL_GPL -+0x7e006219 __set_page_dirty_buffers vmlinux EXPORT_SYMBOL -+0x978f24b1 __wake_up_locked vmlinux EXPORT_SYMBOL_GPL -+0x5994a0d7 sock_prot_inuse_add vmlinux EXPORT_SYMBOL_GPL -+0xbd05294b usb_hcd_platform_shutdown vmlinux EXPORT_SYMBOL_GPL -+0xf9e73082 scnprintf vmlinux EXPORT_SYMBOL -+0x1fb2a93c aead_geniv_exit vmlinux EXPORT_SYMBOL_GPL -+0x0c917640 mod_zone_page_state vmlinux EXPORT_SYMBOL -+0xf4a37928 perf_event_refresh vmlinux EXPORT_SYMBOL_GPL -+0x40f1ad10 tb_ticks_per_jiffy vmlinux EXPORT_SYMBOL -+0xae40342e blk_add_request_payload vmlinux EXPORT_SYMBOL_GPL -+0xf1a62b6f of_i8042_kbd_irq vmlinux EXPORT_SYMBOL_GPL -+0xcd5fcf06 rtnl_link_unregister vmlinux EXPORT_SYMBOL_GPL -+0xe1ad275d copy_strings_kernel vmlinux EXPORT_SYMBOL -+0x751c2917 __wait_on_bit vmlinux EXPORT_SYMBOL -+0x55467ede fsl_upm_find vmlinux EXPORT_SYMBOL -+0x002de09c vfsmount_lock_global_unlock_online vmlinux EXPORT_SYMBOL -+0xc7156d34 hrtimer_get_remaining vmlinux EXPORT_SYMBOL_GPL -+0x3b42483e tcp_enter_memory_pressure vmlinux EXPORT_SYMBOL -+0x1df3dda5 skb_add_rx_frag vmlinux EXPORT_SYMBOL -+0xe9587909 usb_unregister_notify vmlinux EXPORT_SYMBOL_GPL -+0x4982a57f probe_kernel_write vmlinux EXPORT_SYMBOL_GPL -+0x972d7aee arp_create vmlinux EXPORT_SYMBOL -+0xf1e706a7 of_modalias_node vmlinux EXPORT_SYMBOL_GPL -+0xae30905c tty_port_alloc_xmit_buf vmlinux EXPORT_SYMBOL -+0x46d4fb35 no_llseek vmlinux EXPORT_SYMBOL -+0x7da3ce6f rt_mutex_timed_lock vmlinux EXPORT_SYMBOL_GPL -+0xeded8d0e rtc_irq_set_freq vmlinux EXPORT_SYMBOL_GPL -+0xf0fd4e8f rwsem_down_read_failed vmlinux EXPORT_SYMBOL -+0xc606cd3c boot_cpuid vmlinux EXPORT_SYMBOL_GPL -+0xfab35004 generic_show_options vmlinux EXPORT_SYMBOL -+0xbf79c72e pagecache_write_begin vmlinux EXPORT_SYMBOL -+0xe6e1982f register_sysctl_paths vmlinux EXPORT_SYMBOL -+0xc6cbbc89 capable vmlinux EXPORT_SYMBOL -+0x39688afa nf_afinfo vmlinux EXPORT_SYMBOL -+0xa4f7e7fb hid_debug_event vmlinux EXPORT_SYMBOL_GPL -+0x0a0a8628 mmc_can_trim vmlinux EXPORT_SYMBOL -+0x620ed98f input_set_capability vmlinux EXPORT_SYMBOL -+0x4ef5bcf4 perf_swevent_get_recursion_context vmlinux EXPORT_SYMBOL_GPL -+0xc8b57c27 autoremove_wake_function vmlinux EXPORT_SYMBOL -+0x13e5ea13 __wake_up_sync vmlinux EXPORT_SYMBOL_GPL -+0x2e8e2944 irq_find_mapping vmlinux EXPORT_SYMBOL_GPL -+0xb9c06bda nf_ct_port_tuple_to_nlattr net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x7c60d66e getname vmlinux EXPORT_SYMBOL -+0xe7ffe877 pcpu_base_addr vmlinux EXPORT_SYMBOL_GPL -+0xa78649d2 nf_conntrack_helper_register net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x9a11a0fc crypto_attr_alg_name vmlinux EXPORT_SYMBOL_GPL -+0x0d86c5c3 par_io_config_pin vmlinux EXPORT_SYMBOL -+0x1c852e7c xfrm_calg_get_byid vmlinux EXPORT_SYMBOL_GPL -+0x8b26f12b uhci_check_and_reset_hc vmlinux EXPORT_SYMBOL_GPL -+0x05520f5f usb_hc_died vmlinux EXPORT_SYMBOL_GPL -+0xe61a6d2f gpio_unexport vmlinux EXPORT_SYMBOL_GPL -+0xf20dabd8 free_irq vmlinux EXPORT_SYMBOL -+0xa861ab6e __ioremap vmlinux EXPORT_SYMBOL -+0x7976a3fa usb_serial_probe vmlinux EXPORT_SYMBOL_GPL -+0x2b2f2776 deactivate_locked_super vmlinux EXPORT_SYMBOL -+0x432b5ac1 filemap_fdatawait vmlinux EXPORT_SYMBOL -+0x432a0255 rpcauth_register vmlinux EXPORT_SYMBOL_GPL -+0x36ac1b69 xfrm_audit_policy_delete vmlinux EXPORT_SYMBOL_GPL -+0xfb788409 netdev_class_create_file vmlinux EXPORT_SYMBOL -+0x09d44df9 in_lock_functions vmlinux EXPORT_SYMBOL -+0x27e4a550 rpc_wake_up vmlinux EXPORT_SYMBOL_GPL -+0xe67b9f1c netpoll_parse_options vmlinux EXPORT_SYMBOL -+0xe4c4673a netdev_rx_handler_unregister vmlinux EXPORT_SYMBOL_GPL -+0xf3c9e5de skb_copy_datagram_const_iovec vmlinux EXPORT_SYMBOL -+0x1b0d73b7 kernel_getpeername vmlinux EXPORT_SYMBOL -+0xcca50e42 platform_driver_probe vmlinux EXPORT_SYMBOL_GPL -+0x2bb7074d serial8250_do_set_termios vmlinux EXPORT_SYMBOL -+0x436cab8f sysfs_chmod_file vmlinux EXPORT_SYMBOL_GPL -+0x1e69be37 find_module vmlinux EXPORT_SYMBOL_GPL -+0x09b54a84 rt_mutex_lock vmlinux EXPORT_SYMBOL_GPL -+0x28a9171c input_event vmlinux EXPORT_SYMBOL -+0x11f7ed4c hex_to_bin vmlinux EXPORT_SYMBOL -+0xa4338205 simple_pin_fs vmlinux EXPORT_SYMBOL -+0x5635a60a vmalloc_user vmlinux EXPORT_SYMBOL -+0x95fcd41e posix_clock_unregister vmlinux EXPORT_SYMBOL_GPL -+0x31bd442e schedule_delayed_work vmlinux EXPORT_SYMBOL -+0x4d45d89e udp_memory_allocated vmlinux EXPORT_SYMBOL -+0x99dbcc23 tc_classify vmlinux EXPORT_SYMBOL -+0x6b8e3569 sock_no_sendpage vmlinux EXPORT_SYMBOL -+0x6a61f874 to_tm vmlinux EXPORT_SYMBOL -+0x4b4a6de0 get_current_tty vmlinux EXPORT_SYMBOL_GPL -+0x4c1182cb bitmap_scnprintf vmlinux EXPORT_SYMBOL -+0xde6daef6 proc_create_data vmlinux EXPORT_SYMBOL -+0x810b3618 param_ops_string vmlinux EXPORT_SYMBOL -+0xcafc76d2 sunrpc_cache_register_pipefs vmlinux EXPORT_SYMBOL_GPL -+0x4d15f777 kernel_getsockname vmlinux EXPORT_SYMBOL -+0xa5ea73be kernel_sendmsg vmlinux EXPORT_SYMBOL -+0x5f965ae1 uart_register_driver vmlinux EXPORT_SYMBOL -+0xd77a5aa5 __bitmap_and vmlinux EXPORT_SYMBOL -+0xf3012f6c rh_free vmlinux EXPORT_SYMBOL_GPL -+0x38df0067 xfrm_alloc_spi vmlinux EXPORT_SYMBOL -+0xce2e6bf5 netdev_set_bond_master vmlinux EXPORT_SYMBOL -+0xdab749af blk_rq_err_bytes vmlinux EXPORT_SYMBOL_GPL -+0x5390ec7d crypto_blkcipher_type vmlinux EXPORT_SYMBOL_GPL -+0xd5ce0859 crypto_givcipher_type vmlinux EXPORT_SYMBOL_GPL -+0x001425a3 nf_log_packet vmlinux EXPORT_SYMBOL -+0xc9a72270 qdisc_tree_decrease_qlen vmlinux EXPORT_SYMBOL -+0xdd671a8d dev_remove_pack vmlinux EXPORT_SYMBOL -+0x2c256e1f input_scancode_to_scalar vmlinux EXPORT_SYMBOL -+0x647e76d5 rq_flush_dcache_pages vmlinux EXPORT_SYMBOL_GPL -+0xb6a0b482 blkcipher_walk_virt vmlinux EXPORT_SYMBOL_GPL -+0x9607f187 posix_lock_file vmlinux EXPORT_SYMBOL -+0x71a672ef dmam_pool_destroy vmlinux EXPORT_SYMBOL -+0xeb6bb956 set_page_dirty vmlinux EXPORT_SYMBOL -+0xde9360ba totalram_pages vmlinux EXPORT_SYMBOL -+0x6a0a2dcc nf_conntrack_l4proto_udp4 net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x31afdcc9 udp_disconnect vmlinux EXPORT_SYMBOL -+0xc9ef093b dev_uc_unsync vmlinux EXPORT_SYMBOL -+0x92cc73cf dev_mc_unsync vmlinux EXPORT_SYMBOL -+0xde68b34d usb_free_streams vmlinux EXPORT_SYMBOL_GPL -+0x106c8a3c dump_seek vmlinux EXPORT_SYMBOL -+0x67d84b74 mtd_add_partition vmlinux EXPORT_SYMBOL_GPL -+0xd0c663ae bus_get_kset vmlinux EXPORT_SYMBOL_GPL -+0x0874bd6b journal_get_write_access vmlinux EXPORT_SYMBOL -+0x2e4d6a64 __register_chrdev vmlinux EXPORT_SYMBOL -+0xe5919cb1 xdr_encode_opaque vmlinux EXPORT_SYMBOL_GPL -+0x100e6158 rtc_class_close vmlinux EXPORT_SYMBOL_GPL -+0x61c2dac6 kstrtoll_from_user vmlinux EXPORT_SYMBOL -+0x8e010d2c svc_max_payload vmlinux EXPORT_SYMBOL_GPL -+0x4be46578 devres_alloc vmlinux EXPORT_SYMBOL_GPL -+0x2ecee7fb sysdev_unregister vmlinux EXPORT_SYMBOL_GPL -+0xdc14eda7 pci_pci_problems vmlinux EXPORT_SYMBOL -+0x956a91ba gpio_get_value_cansleep vmlinux EXPORT_SYMBOL_GPL -+0x18bff16e blk_queue_stack_limits vmlinux EXPORT_SYMBOL -+0x01e56d33 free_vm_area vmlinux EXPORT_SYMBOL_GPL -+0x748022c5 nf_conntrack_free net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x9317d258 udp_lib_setsockopt vmlinux EXPORT_SYMBOL -+0xfad5b90d udp_lib_getsockopt vmlinux EXPORT_SYMBOL -+0x96898769 sysfs_format_mac vmlinux EXPORT_SYMBOL -+0xddbc1ffe sk_send_sigurg vmlinux EXPORT_SYMBOL -+0x246f019e spi_bus_lock vmlinux EXPORT_SYMBOL_GPL -+0xaa89d28e dev_crit vmlinux EXPORT_SYMBOL -+0x8e45aa4a drop_super vmlinux EXPORT_SYMBOL -+0x27e1a049 printk vmlinux EXPORT_SYMBOL -+0x2f97857d sk_alloc vmlinux EXPORT_SYMBOL -+0xa49390ab bus_unregister_notifier vmlinux EXPORT_SYMBOL_GPL -+0xc48f3373 try_to_release_page vmlinux EXPORT_SYMBOL -+0x7e448a8f synchronize_srcu vmlinux EXPORT_SYMBOL_GPL -+0x9aad6540 klist_iter_init vmlinux EXPORT_SYMBOL_GPL -+0xc3512c1e rpcauth_lookup_credcache vmlinux EXPORT_SYMBOL_GPL -+0x03bab655 platform_driver_register vmlinux EXPORT_SYMBOL_GPL -+0xe381eae4 kobject_add vmlinux EXPORT_SYMBOL -+0xf5a87370 nfs_commitdata_release vmlinux EXPORT_SYMBOL_GPL -+0x10138352 tracing_on vmlinux EXPORT_SYMBOL_GPL -+0x9025d41c xfrm_audit_policy_add vmlinux EXPORT_SYMBOL_GPL -+0x4cedc318 platform_driver_unregister vmlinux EXPORT_SYMBOL_GPL -+0x61634f05 lock_flocks vmlinux EXPORT_SYMBOL_GPL -+0xd19a96e6 queue_kthread_work vmlinux EXPORT_SYMBOL_GPL -+0x756dd160 start_thread vmlinux EXPORT_SYMBOL -+0x219de8a0 br_should_route_hook vmlinux EXPORT_SYMBOL -+0xf6190b08 gnet_stats_copy_queue vmlinux EXPORT_SYMBOL -+0x94ae4c23 of_match_device vmlinux EXPORT_SYMBOL -+0x2bb7992e usb_get_urb vmlinux EXPORT_SYMBOL_GPL -+0x4c715546 pci_scan_single_device vmlinux EXPORT_SYMBOL -+0x12e85778 kstrtol_from_user vmlinux EXPORT_SYMBOL -+0x3aad440e simple_dir_operations vmlinux EXPORT_SYMBOL -+0x6403e338 tcp_memory_pressure vmlinux EXPORT_SYMBOL -+0xb233762c atomic64_set vmlinux EXPORT_SYMBOL -+0xab0e7894 setattr_copy vmlinux EXPORT_SYMBOL -+0xc26c0f33 inet_frags_fini vmlinux EXPORT_SYMBOL -+0xe4cf504e scsi_queue_work vmlinux EXPORT_SYMBOL_GPL -+0x90ef84ba elv_dispatch_sort vmlinux EXPORT_SYMBOL -+0x891a622e elv_add_request vmlinux EXPORT_SYMBOL -+0xf346231f seq_list_start_head vmlinux EXPORT_SYMBOL -+0xa32629f6 dns_query vmlinux EXPORT_SYMBOL -+0x73e659e1 netif_device_attach vmlinux EXPORT_SYMBOL -+0x17de79c5 netif_device_detach vmlinux EXPORT_SYMBOL -+0xe94d82f3 sdhci_pltfm_init vmlinux EXPORT_SYMBOL_GPL -+0x9c247860 device_rename vmlinux EXPORT_SYMBOL_GPL -+0xc88c586d simple_attr_read vmlinux EXPORT_SYMBOL_GPL -+0x7e620c98 relay_flush vmlinux EXPORT_SYMBOL_GPL -+0xc12435e3 rpc_calc_rto vmlinux EXPORT_SYMBOL_GPL -+0x0ffe2bd3 kernel_bind vmlinux EXPORT_SYMBOL -+0xf511e930 dev_notice vmlinux EXPORT_SYMBOL -+0xcc248d26 serial8250_suspend_port vmlinux EXPORT_SYMBOL -+0xcd279169 nla_find vmlinux EXPORT_SYMBOL -+0x3a4dd68a kernel_read vmlinux EXPORT_SYMBOL -+0x8c7b3af2 vfs_read vmlinux EXPORT_SYMBOL -+0xc8add232 ring_buffer_record_disable vmlinux EXPORT_SYMBOL_GPL -+0xf68fe563 __devm_release_region vmlinux EXPORT_SYMBOL -+0xca559706 __inet_hash_nolisten vmlinux EXPORT_SYMBOL_GPL -+0x9fb3dd30 memcpy_fromiovec vmlinux EXPORT_SYMBOL -+0x7e40b8e4 pci_bus_find_capability vmlinux EXPORT_SYMBOL -+0x8a6d8c12 blk_queue_prep_rq vmlinux EXPORT_SYMBOL -+0x262f20a8 local_clock vmlinux EXPORT_SYMBOL_GPL -+0x5b7f8452 vlan_dev_vlan_id vmlinux EXPORT_SYMBOL -+0xce3148ed of_find_matching_node vmlinux EXPORT_SYMBOL -+0xe2457ef0 sysdev_class_register vmlinux EXPORT_SYMBOL_GPL -+0xd6f88a0e journal_unlock_updates vmlinux EXPORT_SYMBOL -+0x457de0d3 sunrpc_cache_unregister_pipefs vmlinux EXPORT_SYMBOL_GPL -+0x7e72637f __class_register vmlinux EXPORT_SYMBOL_GPL -+0xd5e8444a __div64_32 vmlinux EXPORT_SYMBOL -+0xf04ae1ba idr_remove_all vmlinux EXPORT_SYMBOL -+0x3446615d bio_alloc vmlinux EXPORT_SYMBOL -+0x93fca811 __get_free_pages vmlinux EXPORT_SYMBOL -+0xbb189cad disallow_signal vmlinux EXPORT_SYMBOL -+0xd3d2de27 rawv6_mh_filter_register vmlinux EXPORT_SYMBOL -+0xdbcd416e sysctl_ip_nonlocal_bind vmlinux EXPORT_SYMBOL -+0x8fd02ebd usb_free_coherent vmlinux EXPORT_SYMBOL_GPL -+0xa675804c utf8s_to_utf16s vmlinux EXPORT_SYMBOL -+0x31212876 proc_net_fops_create vmlinux EXPORT_SYMBOL_GPL -+0x39e569fd ns_capable vmlinux EXPORT_SYMBOL -+0x979a54c8 rawv6_mh_filter_unregister vmlinux EXPORT_SYMBOL -+0x7fd28838 mmc_fixup_device vmlinux EXPORT_SYMBOL -+0x0ea29024 blk_queue_resize_tags vmlinux EXPORT_SYMBOL -+0x4301f246 nf_ct_l3proto_find_get net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xb391c0ae ipv4_specific vmlinux EXPORT_SYMBOL -+0x3aa08439 proto_unregister vmlinux EXPORT_SYMBOL -+0x70e3ab78 i2c_new_dummy vmlinux EXPORT_SYMBOL_GPL -+0x14f9849f register_mtd_chip_driver vmlinux EXPORT_SYMBOL -+0x9334e2ee __fsnotify_inode_delete vmlinux EXPORT_SYMBOL_GPL -+0xfedbb984 deregister_mtd_parser vmlinux EXPORT_SYMBOL_GPL -+0x6e09073c __any_online_cpu vmlinux EXPORT_SYMBOL -+0xb0d651f5 lookup_instantiate_filp vmlinux EXPORT_SYMBOL_GPL -+0xadf0811d get_baudrate vmlinux EXPORT_SYMBOL -+0x6f7b3dee rtnl_af_register vmlinux EXPORT_SYMBOL_GPL -+0xc6c208cb kunmap_high vmlinux EXPORT_SYMBOL -+0xea8a6c75 param_ops_long vmlinux EXPORT_SYMBOL -+0xacf4d843 match_strdup vmlinux EXPORT_SYMBOL -+0x870bf928 radix_tree_lookup vmlinux EXPORT_SYMBOL -+0x4672e88b __crypto_dequeue_request vmlinux EXPORT_SYMBOL_GPL -+0x7b0f1ab3 ring_buffer_free_read_page vmlinux EXPORT_SYMBOL_GPL -+0xff00f5a4 rt_mutex_unlock vmlinux EXPORT_SYMBOL_GPL -+0xe9d6425d neigh_seq_next vmlinux EXPORT_SYMBOL -+0xb587371d vfs_rename vmlinux EXPORT_SYMBOL -+0x8c2d546c generic_ro_fops vmlinux EXPORT_SYMBOL -+0xabc5855f nf_nat_get_offset net/ipv4/netfilter/nf_nat EXPORT_SYMBOL_GPL -+0xc7037e1e user_path_create vmlinux EXPORT_SYMBOL -+0x78c76bdd kthread_bind vmlinux EXPORT_SYMBOL -+0xc92969b1 xprt_disconnect_done vmlinux EXPORT_SYMBOL_GPL -+0xefd8281a ipv6_setsockopt vmlinux EXPORT_SYMBOL -+0x17c3edfd usb_serial_port_softint vmlinux EXPORT_SYMBOL_GPL -+0x486bfa52 del_mtd_blktrans_dev vmlinux EXPORT_SYMBOL_GPL -+0xdd19ee65 cache_register vmlinux EXPORT_SYMBOL_GPL -+0xc92254c9 inet_frag_find vmlinux EXPORT_SYMBOL -+0x2b281f0e inetdev_by_index vmlinux EXPORT_SYMBOL -+0x7c6b8d30 usb_poison_anchored_urbs vmlinux EXPORT_SYMBOL_GPL -+0x75b20f59 eventfd_signal vmlinux EXPORT_SYMBOL_GPL -+0x21f678b9 clocksource_unregister vmlinux EXPORT_SYMBOL -+0x461ebfa0 __copy_tofrom_user vmlinux EXPORT_SYMBOL -+0xc9ed05e3 fifo_set_limit vmlinux EXPORT_SYMBOL -+0x195d71f7 writeback_in_progress vmlinux EXPORT_SYMBOL -+0x76b28f53 filemap_fdatawrite vmlinux EXPORT_SYMBOL -+0x807d2b2c xt_recseq vmlinux EXPORT_SYMBOL_GPL -+0xc6ff126b __ethtool_get_settings vmlinux EXPORT_SYMBOL -+0x17648396 dev_base_lock vmlinux EXPORT_SYMBOL -+0xbfb8b0b7 _raw_read_lock_irqsave vmlinux EXPORT_SYMBOL -+0x219da672 xt_request_find_target vmlinux EXPORT_SYMBOL_GPL -+0x5ec1f3aa sg_scsi_ioctl vmlinux EXPORT_SYMBOL_GPL -+0xc22a3091 vm_unmap_aliases vmlinux EXPORT_SYMBOL_GPL -+0x0cc6165c cpu_remove_dev_attr_group vmlinux EXPORT_SYMBOL_GPL -+0x418fdef0 gnet_stats_finish_copy vmlinux EXPORT_SYMBOL -+0x5e3c3f48 scsi_get_device_flags_keyed vmlinux EXPORT_SYMBOL -+0x7282cf02 device_show_int vmlinux EXPORT_SYMBOL_GPL -+0x94552a4e swiotlb_tbl_unmap_single vmlinux EXPORT_SYMBOL_GPL -+0x5a6143d7 blk_fetch_request vmlinux EXPORT_SYMBOL -+0xcee07d7c free_inode_nonrcu vmlinux EXPORT_SYMBOL -+0xb7cb7543 dma_pool_create vmlinux EXPORT_SYMBOL -+0x4b34fbf5 block_all_signals vmlinux EXPORT_SYMBOL -+0x1e7af842 sdio_writeb vmlinux EXPORT_SYMBOL_GPL -+0x2e5f37cd usb_hcd_pci_probe vmlinux EXPORT_SYMBOL_GPL -+0x955a8e9a tty_name vmlinux EXPORT_SYMBOL -+0xb5aa7165 dma_pool_destroy vmlinux EXPORT_SYMBOL -+0x9045913c of_dev_put vmlinux EXPORT_SYMBOL -+0x78ab4762 of_dev_get vmlinux EXPORT_SYMBOL -+0xc22d32e4 sysfs_get_dirent vmlinux EXPORT_SYMBOL_GPL -+0x35f7dc5f perf_event_release_kernel vmlinux EXPORT_SYMBOL_GPL -+0x8c03d20c destroy_workqueue vmlinux EXPORT_SYMBOL_GPL -+0xd5901a2e inet6_csk_reqsk_queue_hash_add vmlinux EXPORT_SYMBOL_GPL -+0x7aff474c inet_twsk_put vmlinux EXPORT_SYMBOL_GPL -+0x6409d9b1 fib_default_rule_add vmlinux EXPORT_SYMBOL -+0xc1402a83 do_SAK vmlinux EXPORT_SYMBOL -+0xb5c93022 pci_load_and_free_saved_state vmlinux EXPORT_SYMBOL_GPL -+0x4ed00fb3 pci_save_state vmlinux EXPORT_SYMBOL -+0x5581df9d fat_get_dotdot_entry vmlinux EXPORT_SYMBOL_GPL -+0xcc19c3b6 check_disk_change vmlinux EXPORT_SYMBOL -+0xbcce8393 default_file_splice_read vmlinux EXPORT_SYMBOL -+0x32b2fbcf writeback_inodes_sb vmlinux EXPORT_SYMBOL -+0x8e555738 param_get_uint vmlinux EXPORT_SYMBOL -+0x5d650a5f elv_register vmlinux EXPORT_SYMBOL_GPL -+0x4523b9b7 page_put_link vmlinux EXPORT_SYMBOL -+0xcd70c7f7 release_pages vmlinux EXPORT_SYMBOL -+0xb4cab2ed rpc_sleep_on vmlinux EXPORT_SYMBOL_GPL -+0xc1a33294 km_state_expired vmlinux EXPORT_SYMBOL -+0xfef1d118 qdisc_list_del vmlinux EXPORT_SYMBOL -+0xb0e10781 get_option vmlinux EXPORT_SYMBOL -+0xb323ab9f nf_ct_gre_keymap_destroy net/netfilter/nf_conntrack_proto_gre EXPORT_SYMBOL_GPL -+0xce19bac5 register_inet6addr_notifier vmlinux EXPORT_SYMBOL -+0xcb117d64 inet_accept vmlinux EXPORT_SYMBOL -+0x49b07aec tcp_select_initial_window vmlinux EXPORT_SYMBOL -+0x762ff2b9 register_pernet_device vmlinux EXPORT_SYMBOL_GPL -+0x33b91f1c class_for_each_device vmlinux EXPORT_SYMBOL_GPL -+0xe697d108 __blk_iopoll_complete vmlinux EXPORT_SYMBOL -+0x13e38f5c up_read vmlinux EXPORT_SYMBOL -+0xa1c76e0a _cond_resched vmlinux EXPORT_SYMBOL -+0x595d0946 empty_zero_page vmlinux EXPORT_SYMBOL -+0x76e2075c nfnetlink_subsys_register net/netfilter/nfnetlink EXPORT_SYMBOL_GPL -+0xe5205ca9 __pskb_pull_tail vmlinux EXPORT_SYMBOL -+0x123a8ed7 mtd_is_partition vmlinux EXPORT_SYMBOL_GPL -+0x25c7b476 dev_alert vmlinux EXPORT_SYMBOL -+0xa8e85346 tty_wait_until_sent vmlinux EXPORT_SYMBOL -+0x74d1c3d7 bioset_free vmlinux EXPORT_SYMBOL -+0x7362dd1e vfs_fstat vmlinux EXPORT_SYMBOL -+0x127f1cf8 vfs_lstat vmlinux EXPORT_SYMBOL -+0x5b9828c5 dma_spin_lock vmlinux EXPORT_SYMBOL -+0x20bc3470 orderly_poweroff vmlinux EXPORT_SYMBOL_GPL -+0x0be13004 usb_storage_usb_ids vmlinux EXPORT_SYMBOL_GPL -+0x1556756b usermodehelper_is_disabled vmlinux EXPORT_SYMBOL_GPL -+0x82e704cc __netif_schedule vmlinux EXPORT_SYMBOL -+0x63f7a522 gpio_export_link vmlinux EXPORT_SYMBOL_GPL -+0x75bb9ca1 generic_fh_to_parent vmlinux EXPORT_SYMBOL_GPL -+0xc123374d generic_fillattr vmlinux EXPORT_SYMBOL -+0x183fa88b mempool_alloc_slab vmlinux EXPORT_SYMBOL -+0x379f5837 param_set_invbool vmlinux EXPORT_SYMBOL -+0xc5534d64 ioread16 vmlinux EXPORT_SYMBOL -+0x9f185a94 i2c_register_driver vmlinux EXPORT_SYMBOL -+0x343b3ac1 pci_bus_alloc_resource vmlinux EXPORT_SYMBOL -+0x6579d2f7 d_instantiate_unique vmlinux EXPORT_SYMBOL -+0xd6b8e852 request_threaded_irq vmlinux EXPORT_SYMBOL -+0x9d7ce8dd _raw_spin_trylock vmlinux EXPORT_SYMBOL -+0xc496da96 svc_drop vmlinux EXPORT_SYMBOL_GPL -+0x3a24b303 mutex_lock_interruptible vmlinux EXPORT_SYMBOL -+0xf47788cf skb_clone vmlinux EXPORT_SYMBOL -+0xad167cd8 input_get_keycode vmlinux EXPORT_SYMBOL -+0x6afa9ce8 crypto_find_alg vmlinux EXPORT_SYMBOL_GPL -+0xc6aac677 set_task_ioprio vmlinux EXPORT_SYMBOL_GPL -+0xbe5e9490 setup_arg_pages vmlinux EXPORT_SYMBOL -+0x5dc8d493 usb_serial_generic_process_read_urb vmlinux EXPORT_SYMBOL_GPL -+0x055c3bb2 inode_dio_wait vmlinux EXPORT_SYMBOL_GPL -+0xc34efe27 snmp_fold_field vmlinux EXPORT_SYMBOL_GPL -+0x9d5a6e79 tcp_init_xmit_timers vmlinux EXPORT_SYMBOL -+0x93f1e027 phy_ethtool_gset vmlinux EXPORT_SYMBOL -+0xc200ab97 phy_ethtool_sset vmlinux EXPORT_SYMBOL -+0xd67364f7 eventfd_ctx_fdget vmlinux EXPORT_SYMBOL_GPL -+0x446b3e02 thermal_zone_device_unregister vmlinux EXPORT_SYMBOL -+0x4980c504 vfs_lock_file vmlinux EXPORT_SYMBOL_GPL -+0xa00f2ea1 bio_uncopy_user vmlinux EXPORT_SYMBOL -+0x07f3051f make_bad_inode vmlinux EXPORT_SYMBOL -+0x04cb56f3 __d_drop vmlinux EXPORT_SYMBOL -+0xadb98035 __mmdrop vmlinux EXPORT_SYMBOL_GPL -+0x3065f579 gss_mech_unregister vmlinux EXPORT_SYMBOL_GPL -+0x33dbfd93 tcp_memory_allocated vmlinux EXPORT_SYMBOL -+0xea7be216 hid_check_keys_pressed vmlinux EXPORT_SYMBOL_GPL -+0x0a2e681f scsi_bus_type vmlinux EXPORT_SYMBOL_GPL -+0xa8232c78 strtobool vmlinux EXPORT_SYMBOL -+0xa807009b seq_release_private vmlinux EXPORT_SYMBOL -+0xb9ea2b35 clear_user_page vmlinux EXPORT_SYMBOL -+0x94d397ff uart_console_write vmlinux EXPORT_SYMBOL_GPL -+0x7b59e193 writeback_inodes_sb_nr vmlinux EXPORT_SYMBOL -+0x4f005ac7 vfs_removexattr vmlinux EXPORT_SYMBOL_GPL -+0x3bc25df9 find_symbol vmlinux EXPORT_SYMBOL_GPL -+0x55139b31 __mutex_init vmlinux EXPORT_SYMBOL -+0x807fb25f sdio_readsb vmlinux EXPORT_SYMBOL_GPL -+0x73883f28 mmc_host_enable vmlinux EXPORT_SYMBOL -+0xa4536a78 rtc_set_time vmlinux EXPORT_SYMBOL_GPL -+0x131e5c6e pcix_get_mmrbc vmlinux EXPORT_SYMBOL -+0x6f7d4b21 auth_domain_lookup vmlinux EXPORT_SYMBOL_GPL -+0x0b0d888b icmpv6_err_convert vmlinux EXPORT_SYMBOL -+0x6a010ac4 xfrm_audit_state_delete vmlinux EXPORT_SYMBOL_GPL -+0x7f00decc serial8250_register_port vmlinux EXPORT_SYMBOL -+0xd40d44fb vfs_readv vmlinux EXPORT_SYMBOL -+0xe10285f5 do_sync_write vmlinux EXPORT_SYMBOL -+0x3a63d1e5 mmc_detect_change vmlinux EXPORT_SYMBOL -+0xfe29a782 crypto_shash_setkey vmlinux EXPORT_SYMBOL_GPL -+0x1ad011b8 crypto_ahash_setkey vmlinux EXPORT_SYMBOL_GPL -+0x6b569c7b search_binary_handler vmlinux EXPORT_SYMBOL -+0xaa5dc44d rt_mutex_trylock vmlinux EXPORT_SYMBOL_GPL -+0xa0cc8b48 rtnl_link_get_net vmlinux EXPORT_SYMBOL -+0x4d88ec39 sdio_readw vmlinux EXPORT_SYMBOL_GPL -+0x7a1cde57 sdio_readl vmlinux EXPORT_SYMBOL_GPL -+0x1b2bbad1 sdio_readb vmlinux EXPORT_SYMBOL_GPL -+0xdc8e7a1f usb_remove_hcd vmlinux EXPORT_SYMBOL_GPL -+0x861c1a61 ahash_attr_alg vmlinux EXPORT_SYMBOL_GPL -+0xcfb5871c irq_work_queue vmlinux EXPORT_SYMBOL_GPL -+0x6bac7336 tcp_disconnect vmlinux EXPORT_SYMBOL -+0x0d030f2e put_device vmlinux EXPORT_SYMBOL_GPL -+0xb675788e nfs_initiate_write vmlinux EXPORT_SYMBOL_GPL -+0xef990a5a bio_pair_release vmlinux EXPORT_SYMBOL -+0xd44a50f2 spi_alloc_device vmlinux EXPORT_SYMBOL_GPL -+0xece65659 journal_start vmlinux EXPORT_SYMBOL -+0x77a203d6 register_filesystem vmlinux EXPORT_SYMBOL -+0xba497f13 loops_per_jiffy vmlinux EXPORT_SYMBOL -+0xd850fe94 eth_validate_addr vmlinux EXPORT_SYMBOL -+0xc5718627 sg_copy_to_buffer vmlinux EXPORT_SYMBOL -+0xc316b98c jiffies_to_clock_t vmlinux EXPORT_SYMBOL -+0x0c875058 usb_debug_root vmlinux EXPORT_SYMBOL_GPL -+0x69ef82cd generic_make_request vmlinux EXPORT_SYMBOL -+0x308c701c generic_file_llseek_size vmlinux EXPORT_SYMBOL -+0x38bd731f queue_delayed_work vmlinux EXPORT_SYMBOL_GPL -+0x1c87a811 __round_jiffies_up vmlinux EXPORT_SYMBOL_GPL -+0x98fe7882 DMA_MODE_READ vmlinux EXPORT_SYMBOL -+0x1c80de9c ip_send_check vmlinux EXPORT_SYMBOL -+0xdc8e4d19 __rtnl_register vmlinux EXPORT_SYMBOL_GPL -+0xa6c839d3 usb_serial_generic_disconnect vmlinux EXPORT_SYMBOL_GPL -+0x57db7242 mangle_path vmlinux EXPORT_SYMBOL -+0x81612cb7 pci_get_domain_bus_and_slot vmlinux EXPORT_SYMBOL -+0x4cd416fe anon_inode_getfd vmlinux EXPORT_SYMBOL_GPL -+0xef22332a filemap_flush vmlinux EXPORT_SYMBOL -+0xa4a94d26 find_next_bit_le vmlinux EXPORT_SYMBOL -+0xc1d7d179 blk_stack_limits vmlinux EXPORT_SYMBOL -+0x28ea0728 of_scan_bus vmlinux EXPORT_SYMBOL_GPL -+0x774b6448 unix_domain_find vmlinux EXPORT_SYMBOL_GPL -+0xcc8ebe78 tcp_set_state vmlinux EXPORT_SYMBOL_GPL -+0x00239c1b i2c_smbus_read_i2c_block_data vmlinux EXPORT_SYMBOL -+0x9bd59d1d tty_mutex vmlinux EXPORT_SYMBOL -+0xb28f5ef1 xt_free_table_info vmlinux EXPORT_SYMBOL -+0x0e1fa4e9 mnt_pin vmlinux EXPORT_SYMBOL -+0x616456a1 set_create_files_as vmlinux EXPORT_SYMBOL -+0xb609d16c dev_get_by_name vmlinux EXPORT_SYMBOL -+0x8848b690 __page_symlink vmlinux EXPORT_SYMBOL -+0xd2044f1c install_exec_creds vmlinux EXPORT_SYMBOL -+0xaf488b30 sched_setscheduler vmlinux EXPORT_SYMBOL_GPL -+0x6923ce63 irq_work_sync vmlinux EXPORT_SYMBOL_GPL -+0x30a80826 __kfifo_from_user vmlinux EXPORT_SYMBOL -+0x595c70ed ipcomp_input net/xfrm/xfrm_ipcomp EXPORT_SYMBOL_GPL -+0xead1e53c xdr_skb_read_bits vmlinux EXPORT_SYMBOL_GPL -+0xf20020d8 udp_prot vmlinux EXPORT_SYMBOL -+0x552567c0 inet_putpeer vmlinux EXPORT_SYMBOL_GPL -+0x6a1a16cb mmc_card_sleep vmlinux EXPORT_SYMBOL -+0x0c167229 i2c_adapter_type vmlinux EXPORT_SYMBOL_GPL -+0xebd52fa9 inet6_sk_rebuild_header vmlinux EXPORT_SYMBOL_GPL -+0xe506bc98 mb_cache_shrink vmlinux EXPORT_SYMBOL -+0x2d3385d3 system_wq vmlinux EXPORT_SYMBOL_GPL -+0xf1e98c74 avenrun vmlinux EXPORT_SYMBOL -+0x366e962c nf_ct_extend_register net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x634b5ff0 mmc_calc_max_discard vmlinux EXPORT_SYMBOL -+0xb1356813 register_mtd_parser vmlinux EXPORT_SYMBOL_GPL -+0x3281f449 mark_page_accessed vmlinux EXPORT_SYMBOL -+0x9cb8037b xfrm_count_enc_supported vmlinux EXPORT_SYMBOL_GPL -+0x02a18c74 nf_conntrack_destroy vmlinux EXPORT_SYMBOL -+0x7cac5792 scsi_report_bus_reset vmlinux EXPORT_SYMBOL -+0x5c8a36aa ip6_sk_dst_lookup_flow vmlinux EXPORT_SYMBOL_GPL -+0x460f95b8 hid_output_report vmlinux EXPORT_SYMBOL_GPL -+0xaa072d41 cdev_add vmlinux EXPORT_SYMBOL -+0xfcd7bc0b ring_buffer_empty vmlinux EXPORT_SYMBOL_GPL -+0x69447467 ring_buffer_write vmlinux EXPORT_SYMBOL_GPL -+0x82939ebd rcu_batches_completed_sched vmlinux EXPORT_SYMBOL_GPL -+0xeeacab69 rpc_update_rtt vmlinux EXPORT_SYMBOL_GPL -+0x6ee56ac5 xfrm_input vmlinux EXPORT_SYMBOL -+0x7fccf2c7 dev_mc_del vmlinux EXPORT_SYMBOL -+0xd44258b7 dev_uc_add vmlinux EXPORT_SYMBOL -+0x54a36ee2 dev_mc_add vmlinux EXPORT_SYMBOL -+0xff2dc492 dev_uc_del vmlinux EXPORT_SYMBOL -+0xe17df33d register_pernet_subsys vmlinux EXPORT_SYMBOL_GPL -+0xef850ef5 rtc_update_irq vmlinux EXPORT_SYMBOL_GPL -+0xebdef3fd blk_queue_update_dma_pad vmlinux EXPORT_SYMBOL -+0x30d8f8a2 blkdev_get_by_path vmlinux EXPORT_SYMBOL -+0x8745258d open_exec vmlinux EXPORT_SYMBOL -+0x5fc3a25a cpu_subsys vmlinux EXPORT_SYMBOL_GPL -+0x00f7937a mb_cache_entry_find_next vmlinux EXPORT_SYMBOL -+0xef3c9907 inode_init_owner vmlinux EXPORT_SYMBOL -+0x0b48677a __kfifo_init vmlinux EXPORT_SYMBOL -+0xd7d19d8c pci_find_next_capability vmlinux EXPORT_SYMBOL_GPL -+0xa166674c journal_forget vmlinux EXPORT_SYMBOL -+0xe6506d9b rt_mutex_destroy vmlinux EXPORT_SYMBOL_GPL -+0xa8b1f0bd queue_delayed_work_on vmlinux EXPORT_SYMBOL_GPL -+0xd4034828 system_freezable_wq vmlinux EXPORT_SYMBOL_GPL -+0x615be263 devres_open_group vmlinux EXPORT_SYMBOL_GPL -+0x5b19634d div_s64_rem vmlinux EXPORT_SYMBOL -+0x4a2e3575 __set_page_dirty_nobuffers vmlinux EXPORT_SYMBOL -+0x4b08f423 __nf_ct_kill_acct net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x0561fdb5 svc_xprt_copy_addrs vmlinux EXPORT_SYMBOL_GPL -+0x48000553 mempool_create_node vmlinux EXPORT_SYMBOL -+0xd853827a find_get_pid vmlinux EXPORT_SYMBOL_GPL -+0x1826f0a0 dev_set_promiscuity vmlinux EXPORT_SYMBOL -+0x42ee873c usb_stor_transparent_scsi_command vmlinux EXPORT_SYMBOL_GPL -+0x0eaa69cc scsi_bios_ptable vmlinux EXPORT_SYMBOL -+0x9f4e5960 pci_write_vpd vmlinux EXPORT_SYMBOL -+0x169d875d neigh_connected_output vmlinux EXPORT_SYMBOL -+0xe9f7149c zlib_deflate_workspacesize vmlinux EXPORT_SYMBOL -+0x11633870 param_set_ushort vmlinux EXPORT_SYMBOL -+0x7ae5d317 qe_get_snum vmlinux EXPORT_SYMBOL -+0x910e2911 qe_put_snum vmlinux EXPORT_SYMBOL -+0x4fba15b0 svc_recv vmlinux EXPORT_SYMBOL_GPL -+0x5dcfccd8 udp_flush_pending_frames vmlinux EXPORT_SYMBOL -+0xd445ec0d netlink_kernel_create vmlinux EXPORT_SYMBOL -+0xe5da4ca8 dev_get_stats vmlinux EXPORT_SYMBOL -+0x86fb9b05 bitmap_parse_user vmlinux EXPORT_SYMBOL -+0x01000e51 schedule vmlinux EXPORT_SYMBOL -+0x4f040a49 nlmsg_notify vmlinux EXPORT_SYMBOL -+0x9ac0cf66 mmput vmlinux EXPORT_SYMBOL_GPL -+0x9d438cba init_task vmlinux EXPORT_SYMBOL -+0x0a52a70f rpc_task_reset_client vmlinux EXPORT_SYMBOL_GPL -+0x871477d5 sysdev_class_remove_file vmlinux EXPORT_SYMBOL_GPL -+0x17e28473 fsl_upm_run_pattern vmlinux EXPORT_SYMBOL -+0x262e8cd3 pcibios_resource_to_bus vmlinux EXPORT_SYMBOL -+0x89d66811 build_ehash_secret vmlinux EXPORT_SYMBOL -+0x38e36730 __inet_twsk_hashdance vmlinux EXPORT_SYMBOL_GPL -+0xdfd88ae5 neigh_table_init_no_netlink vmlinux EXPORT_SYMBOL -+0x3c17abfe gnet_stats_copy_app vmlinux EXPORT_SYMBOL -+0x9567b24a i2c_verify_client vmlinux EXPORT_SYMBOL -+0xa2557f57 input_allocate_device vmlinux EXPORT_SYMBOL -+0x1cd4aca8 dev_printk vmlinux EXPORT_SYMBOL -+0x655a6117 pci_set_pcie_reset_state vmlinux EXPORT_SYMBOL_GPL -+0x1b015d25 bitmap_parselist vmlinux EXPORT_SYMBOL -+0x66e042c6 __insert_inode_hash vmlinux EXPORT_SYMBOL -+0x0619ca8a getboottime vmlinux EXPORT_SYMBOL_GPL -+0x80b9cedd revert_creds vmlinux EXPORT_SYMBOL -+0xdf929370 fs_overflowgid vmlinux EXPORT_SYMBOL -+0x9c5f81da cpu_rmap_add vmlinux EXPORT_SYMBOL -+0x0b157e07 swiotlb_unmap_sg_attrs vmlinux EXPORT_SYMBOL -+0x6b252ff6 bio_clone vmlinux EXPORT_SYMBOL -+0xedb52e09 xfrm_policy_walk vmlinux EXPORT_SYMBOL -+0x32f08411 blocking_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL -+0xf6428305 nfs_init_commit vmlinux EXPORT_SYMBOL_GPL -+0x594bf15b ioport_map vmlinux EXPORT_SYMBOL -+0x8cff16ad xfrm_audit_state_add vmlinux EXPORT_SYMBOL_GPL -+0x83b50e64 __skb_checksum_complete vmlinux EXPORT_SYMBOL -+0xed302f0f tty_lock vmlinux EXPORT_SYMBOL -+0xb5a459dc unregister_blkdev vmlinux EXPORT_SYMBOL -+0x3ebc5a82 key_alloc vmlinux EXPORT_SYMBOL -+0xa4b0ca7b write_inode_now vmlinux EXPORT_SYMBOL -+0x5da7c835 sysdev_store_ulong vmlinux EXPORT_SYMBOL_GPL -+0x1bc4ff03 tty_termios_hw_change vmlinux EXPORT_SYMBOL -+0xf2d69a5d fat_search_long vmlinux EXPORT_SYMBOL_GPL -+0x5e181c16 seq_path vmlinux EXPORT_SYMBOL -+0xcc5005fe msleep_interruptible vmlinux EXPORT_SYMBOL -+0xf8b2ff6e g_verify_token_header vmlinux EXPORT_SYMBOL_GPL -+0x7345829d dev_addr_add vmlinux EXPORT_SYMBOL -+0x99544b2e netdev_err vmlinux EXPORT_SYMBOL -+0x65414e67 dev_valid_name vmlinux EXPORT_SYMBOL -+0x3be89d3c usb_register_notify vmlinux EXPORT_SYMBOL_GPL -+0xd2a941d4 sg_init_table vmlinux EXPORT_SYMBOL -+0x5642793a radix_tree_tag_clear vmlinux EXPORT_SYMBOL -+0x17115d7c fsnotify vmlinux EXPORT_SYMBOL_GPL -+0x04d7d50a generic_file_open vmlinux EXPORT_SYMBOL -+0xa357d56e ktime_get vmlinux EXPORT_SYMBOL_GPL -+0x5e4ed6a0 genphy_update_link vmlinux EXPORT_SYMBOL -+0xa0df5c38 generic_cont_expand_simple vmlinux EXPORT_SYMBOL -+0x9000a23c d_instantiate vmlinux EXPORT_SYMBOL -+0x1b6b594c blk_queue_rq_timed_out vmlinux EXPORT_SYMBOL_GPL -+0x08c473b7 xt_alloc_table_info vmlinux EXPORT_SYMBOL -+0xb2f5f9e1 sysdev_create_file vmlinux EXPORT_SYMBOL_GPL -+0xb7b61546 crc32_be vmlinux EXPORT_SYMBOL -+0xe52fec95 rpc_restart_call vmlinux EXPORT_SYMBOL_GPL -+0x660920a6 xfrm_output_resume vmlinux EXPORT_SYMBOL_GPL -+0xc84ba62e skb_find_text vmlinux EXPORT_SYMBOL -+0x500e2d6e i2c_unregister_device vmlinux EXPORT_SYMBOL_GPL -+0xb088b8f4 pci_clear_master vmlinux EXPORT_SYMBOL -+0x1b848d78 current_fs_time vmlinux EXPORT_SYMBOL -+0xc009c0f0 skb_queue_tail vmlinux EXPORT_SYMBOL -+0x953db383 free_irq_cpu_rmap vmlinux EXPORT_SYMBOL -+0x530dca11 crypto_lookup_template vmlinux EXPORT_SYMBOL_GPL -+0x1608951e vfs_test_lock vmlinux EXPORT_SYMBOL_GPL -+0x952664c5 do_exit vmlinux EXPORT_SYMBOL_GPL -+0x7dbeb00f mmc_host_lazy_disable vmlinux EXPORT_SYMBOL -+0xc46197ca mark_buffer_dirty_inode vmlinux EXPORT_SYMBOL -+0x3109b751 cpu_clock vmlinux EXPORT_SYMBOL_GPL -+0x07121133 __put_mtd_device vmlinux EXPORT_SYMBOL_GPL -+0xefbe88ae __get_mtd_device vmlinux EXPORT_SYMBOL_GPL -+0x56011f32 scsi_execute_req vmlinux EXPORT_SYMBOL -+0x33543801 queue_work vmlinux EXPORT_SYMBOL_GPL -+0xb1c3a01a oops_in_progress vmlinux EXPORT_SYMBOL -+0xf1ec57f6 tty_insert_flip_string_fixed_flag vmlinux EXPORT_SYMBOL -+0x19a433b2 tty_register_ldisc vmlinux EXPORT_SYMBOL -+0x1dad9e54 tty_throttle vmlinux EXPORT_SYMBOL -+0xb72b50d8 tty_check_change vmlinux EXPORT_SYMBOL -+0x57f7d2b8 blk_get_backing_dev_info vmlinux EXPORT_SYMBOL -+0xf1abb528 elevator_init vmlinux EXPORT_SYMBOL -+0xe0423822 kill_fasync vmlinux EXPORT_SYMBOL -+0x736c79dc param_get_byte vmlinux EXPORT_SYMBOL -+0x69708997 dev_disable_lro vmlinux EXPORT_SYMBOL -+0x446c0616 attribute_container_classdev_to_container vmlinux EXPORT_SYMBOL_GPL -+0x7d2b62e9 kblockd_schedule_delayed_work vmlinux EXPORT_SYMBOL -+0x6f2fe28d debugfs_create_u8 vmlinux EXPORT_SYMBOL_GPL -+0x6c8d5ae8 __gpio_get_value vmlinux EXPORT_SYMBOL_GPL -+0x432fd7f6 __gpio_set_value vmlinux EXPORT_SYMBOL_GPL -+0xd62c833f schedule_timeout vmlinux EXPORT_SYMBOL -+0x2cadb791 netlink_dump_start vmlinux EXPORT_SYMBOL -+0x65ccb6f0 call_netevent_notifiers vmlinux EXPORT_SYMBOL_GPL -+0xd1cc0681 percpu_counter_compare vmlinux EXPORT_SYMBOL -+0xc365ca35 crypto_alloc_base vmlinux EXPORT_SYMBOL_GPL -+0x7e92c53a aio_put_req vmlinux EXPORT_SYMBOL -+0xb8bddf33 ip6t_ext_hdr net/ipv6/netfilter/ip6_tables EXPORT_SYMBOL -+0x8e0b7743 ipv6_ext_hdr vmlinux EXPORT_SYMBOL -+0x5c311da9 neigh_destroy vmlinux EXPORT_SYMBOL -+0x914859fb netdev_warn vmlinux EXPORT_SYMBOL -+0x32445441 mmc_wait_for_app_cmd vmlinux EXPORT_SYMBOL -+0xcefcd99a serial8250_unregister_port vmlinux EXPORT_SYMBOL -+0x0c077439 blk_end_request_cur vmlinux EXPORT_SYMBOL -+0x5aed1672 replace_mount_options vmlinux EXPORT_SYMBOL -+0x37ea921e vfsmount_lock_local_lock_cpu vmlinux EXPORT_SYMBOL -+0x7303f848 __xfrm_policy_check vmlinux EXPORT_SYMBOL -+0xe9f5462d blk_lld_busy vmlinux EXPORT_SYMBOL_GPL -+0x70f16495 blk_sync_queue vmlinux EXPORT_SYMBOL -+0xf15a9bc6 skb_clone_tx_timestamp vmlinux EXPORT_SYMBOL_GPL -+0xdbba9970 pskb_copy vmlinux EXPORT_SYMBOL -+0x9da1d86b scsi_schedule_eh vmlinux EXPORT_SYMBOL_GPL -+0xa0b474d5 class_unregister vmlinux EXPORT_SYMBOL_GPL -+0xa185f0cd fat_alloc_new_dir vmlinux EXPORT_SYMBOL_GPL -+0x17368f42 simple_write_end vmlinux EXPORT_SYMBOL -+0x37d2c2c5 rh_dump_blk vmlinux EXPORT_SYMBOL_GPL -+0xd07885a5 ip_mc_rejoin_groups vmlinux EXPORT_SYMBOL -+0xa6f04ef7 netdev_update_features vmlinux EXPORT_SYMBOL -+0x45f9ef6a spi_async vmlinux EXPORT_SYMBOL_GPL -+0xd75c79df smp_call_function vmlinux EXPORT_SYMBOL -+0xef6c3f70 round_jiffies_up_relative vmlinux EXPORT_SYMBOL_GPL -+0xd5c1febc of_rescan_bus vmlinux EXPORT_SYMBOL_GPL -+0xd5b2e52a single_step_exception vmlinux EXPORT_SYMBOL -+0xe3f587bb eth_header_cache vmlinux EXPORT_SYMBOL -+0xfd3a2bf8 i2c_smbus_read_byte_data vmlinux EXPORT_SYMBOL -+0xca5dbc50 scsi_print_sense_hdr vmlinux EXPORT_SYMBOL -+0x6bedb1fb scsi_host_lookup vmlinux EXPORT_SYMBOL -+0x83ed980f uart_set_options vmlinux EXPORT_SYMBOL_GPL -+0xf385cf08 pci_find_capability vmlinux EXPORT_SYMBOL -+0x0675c7eb atomic64_cmpxchg vmlinux EXPORT_SYMBOL -+0xb9d025c9 llist_del_first vmlinux EXPORT_SYMBOL_GPL -+0xb678366f int_sqrt vmlinux EXPORT_SYMBOL -+0xfdbe54c4 dec_zone_page_state vmlinux EXPORT_SYMBOL -+0x0799aca4 local_bh_enable vmlinux EXPORT_SYMBOL -+0xf38bcdf3 nf_conntrack_max net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x60763401 tcp_syn_flood_action vmlinux EXPORT_SYMBOL -+0xb9099fb2 llc_mac_hdr_init vmlinux EXPORT_SYMBOL -+0xee8d918e journal_dirty_metadata vmlinux EXPORT_SYMBOL -+0x1eb9516e round_jiffies_relative vmlinux EXPORT_SYMBOL_GPL -+0x17aa156a __ucmpdi2 vmlinux EXPORT_SYMBOL -+0xfab60503 klist_iter_init_node vmlinux EXPORT_SYMBOL_GPL -+0x0634100a bitmap_parselist_user vmlinux EXPORT_SYMBOL -+0xf45c1434 ida_simple_get vmlinux EXPORT_SYMBOL -+0xe87ffb37 blk_queue_update_dma_alignment vmlinux EXPORT_SYMBOL -+0x18d30e30 blk_start_request vmlinux EXPORT_SYMBOL -+0x7c003aef _raw_read_lock_irq vmlinux EXPORT_SYMBOL -+0xf243a51d hrtimer_try_to_cancel vmlinux EXPORT_SYMBOL_GPL -+0xbb543a9f nf_register_hook vmlinux EXPORT_SYMBOL -+0xae870b28 __dev_get_by_name vmlinux EXPORT_SYMBOL -+0x4cfd46aa skb_copy_and_csum_dev vmlinux EXPORT_SYMBOL -+0xb02612a3 input_unregister_handle vmlinux EXPORT_SYMBOL -+0x7e6c28a6 usb_hcd_map_urb_for_dma vmlinux EXPORT_SYMBOL_GPL -+0x8e63350d idr_replace vmlinux EXPORT_SYMBOL -+0x82acfb70 blk_iopoll_sched vmlinux EXPORT_SYMBOL -+0xaa17a2e2 rh_alloc_align vmlinux EXPORT_SYMBOL_GPL -+0x2c7db649 irq_dispose_mapping vmlinux EXPORT_SYMBOL_GPL -+0x2971c44c register_netdev vmlinux EXPORT_SYMBOL -+0xa8223905 blk_limits_io_opt vmlinux EXPORT_SYMBOL -+0x612e9fe1 inet_twsk_purge vmlinux EXPORT_SYMBOL_GPL -+0x9e9f1714 __bitmap_andnot vmlinux EXPORT_SYMBOL -+0x737de5e9 radix_tree_tag_get vmlinux EXPORT_SYMBOL -+0x9941925e get_pci_dma_ops vmlinux EXPORT_SYMBOL -+0xc7041cc2 skb_seq_read vmlinux EXPORT_SYMBOL -+0x712be89f i2c_transfer vmlinux EXPORT_SYMBOL -+0x67eb757c scsi_device_lookup vmlinux EXPORT_SYMBOL -+0xe0fc24aa param_set_int vmlinux EXPORT_SYMBOL -+0x3ec32668 xdr_inline_pages vmlinux EXPORT_SYMBOL_GPL -+0x17d5b36f crypto_drop_spawn vmlinux EXPORT_SYMBOL_GPL -+0x834658ac cmxgcr_lock vmlinux EXPORT_SYMBOL -+0x9ce3f83f nvram_write_byte vmlinux EXPORT_SYMBOL -+0x13ec80f3 param_set_short vmlinux EXPORT_SYMBOL -+0xf4e2a909 nf_nat_tftp_hook net/netfilter/nf_conntrack_tftp EXPORT_SYMBOL_GPL -+0x1d39c751 nf_nat_snmp_hook net/netfilter/nf_conntrack_snmp EXPORT_SYMBOL_GPL -+0xeb810de9 skb_pad vmlinux EXPORT_SYMBOL -+0x77bc13a0 strim vmlinux EXPORT_SYMBOL -+0xc4191169 shash_register_instance vmlinux EXPORT_SYMBOL_GPL -+0xbf84d6ad seq_write vmlinux EXPORT_SYMBOL -+0x3ed6ecb7 generic_file_llseek vmlinux EXPORT_SYMBOL -+0x95922601 rtc_update_irq_enable vmlinux EXPORT_SYMBOL_GPL -+0x999e8297 vfree vmlinux EXPORT_SYMBOL -+0x6906c2dc wait_on_page_bit vmlinux EXPORT_SYMBOL -+0xcbdab685 mutex_lock vmlinux EXPORT_SYMBOL -+0x097d06aa scsi_get_host_dev vmlinux EXPORT_SYMBOL -+0x240bd3e5 swiotlb_sync_sg_for_device vmlinux EXPORT_SYMBOL -+0x6c03da58 elv_rq_merge_ok vmlinux EXPORT_SYMBOL -+0xee3496c3 dma_pool_alloc vmlinux EXPORT_SYMBOL -+0xee766000 tcp_v4_do_rcv vmlinux EXPORT_SYMBOL -+0x0ec55ed1 get_device vmlinux EXPORT_SYMBOL_GPL -+0xbee1171d blk_dump_rq_flags vmlinux EXPORT_SYMBOL -+0x3cfa0f3d sysfs_create_group vmlinux EXPORT_SYMBOL_GPL -+0xf065f629 ioread16be vmlinux EXPORT_SYMBOL -+0x00c52ef5 g_make_token_header vmlinux EXPORT_SYMBOL_GPL -+0xcd2f69d1 xprt_release_rqst_cong vmlinux EXPORT_SYMBOL_GPL -+0x05e73ebe xfrm_unregister_mode vmlinux EXPORT_SYMBOL -+0xa84245d3 consume_skb vmlinux EXPORT_SYMBOL -+0xdd978be5 scsi_add_device vmlinux EXPORT_SYMBOL -+0x2d832e72 pci_match_id vmlinux EXPORT_SYMBOL -+0x01674bbb pci_dev_run_wake vmlinux EXPORT_SYMBOL_GPL -+0x64e716c4 rpc_alloc_iostats vmlinux EXPORT_SYMBOL_GPL -+0xa2a8b984 ethtool_op_get_tso vmlinux EXPORT_SYMBOL -+0xdfc02652 i2c_add_numbered_adapter vmlinux EXPORT_SYMBOL_GPL -+0x12fa94c6 usb_unanchor_urb vmlinux EXPORT_SYMBOL_GPL -+0x8071ec90 bio_kmalloc vmlinux EXPORT_SYMBOL -+0xa62884a3 poll_schedule_timeout vmlinux EXPORT_SYMBOL -+0x30ddb019 tcp_prot vmlinux EXPORT_SYMBOL -+0xbc912b04 root_device_unregister vmlinux EXPORT_SYMBOL_GPL -+0x5ff1e29f textsearch_prepare vmlinux EXPORT_SYMBOL -+0x50ab4c6d files_lglock_global_lock vmlinux EXPORT_SYMBOL -+0x7914c68c proc_dointvec_ms_jiffies vmlinux EXPORT_SYMBOL -+0x63f22305 inet_frag_kill vmlinux EXPORT_SYMBOL -+0x4f90f253 simple_setattr vmlinux EXPORT_SYMBOL -+0xcfea7e86 simple_getattr vmlinux EXPORT_SYMBOL -+0x23f2243d mempool_free vmlinux EXPORT_SYMBOL -+0xc0b11f65 pci_iounmap vmlinux EXPORT_SYMBOL -+0x9edf6333 llc_sap_open vmlinux EXPORT_SYMBOL -+0x88164429 cred_to_ucred vmlinux EXPORT_SYMBOL_GPL -+0x3d418f49 sock_tx_timestamp vmlinux EXPORT_SYMBOL -+0x8d4097dd usb_stor_Bulk_reset vmlinux EXPORT_SYMBOL_GPL -+0x9eb18e34 attribute_container_unregister vmlinux EXPORT_SYMBOL_GPL -+0x277034d4 driver_for_each_device vmlinux EXPORT_SYMBOL_GPL -+0x5c443f95 bdget_disk vmlinux EXPORT_SYMBOL -+0x717ed11e journal_init_inode vmlinux EXPORT_SYMBOL -+0xb41c85dd tcp_v4_get_peer vmlinux EXPORT_SYMBOL -+0xa99ef722 tcp_rcv_state_process vmlinux EXPORT_SYMBOL -+0xf83a1c06 ethtool_op_get_tx_csum vmlinux EXPORT_SYMBOL -+0xf368fcf8 skb_to_sgvec vmlinux EXPORT_SYMBOL_GPL -+0x42224298 sscanf vmlinux EXPORT_SYMBOL -+0x77e35ccc nlmsvc_unlock_all_by_ip vmlinux EXPORT_SYMBOL_GPL -+0x1a24588e nlmsvc_unlock_all_by_sb vmlinux EXPORT_SYMBOL_GPL -+0xdaf873fe __breadahead vmlinux EXPORT_SYMBOL -+0x9531cde3 rpc_bind_new_program vmlinux EXPORT_SYMBOL_GPL -+0x291d6625 pfifo_fast_ops vmlinux EXPORT_SYMBOL -+0x3301ac32 platform_device_register_full vmlinux EXPORT_SYMBOL_GPL -+0x0111955c journal_stop vmlinux EXPORT_SYMBOL -+0x44eb192e wait_for_completion vmlinux EXPORT_SYMBOL -+0x72c09e5c csum_partial_copy_to_xdr vmlinux EXPORT_SYMBOL_GPL -+0xcdbc9355 dev_get_by_name_rcu vmlinux EXPORT_SYMBOL -+0x7f72cd44 i2c_smbus_write_byte_data vmlinux EXPORT_SYMBOL -+0x96786360 usb_unlink_urb vmlinux EXPORT_SYMBOL_GPL -+0xea968c96 ___ratelimit vmlinux EXPORT_SYMBOL -+0x4806976c __nf_nat_mangle_tcp_packet net/ipv4/netfilter/nf_nat EXPORT_SYMBOL -+0x9e672ff6 scsi_kmap_atomic_sg vmlinux EXPORT_SYMBOL -+0xe4c58b28 platform_device_add_data vmlinux EXPORT_SYMBOL_GPL -+0x3a26ed11 sched_clock vmlinux EXPORT_SYMBOL_GPL -+0xefde1bbe flush_dcache_range vmlinux EXPORT_SYMBOL -+0xe1286b24 put_rpccred vmlinux EXPORT_SYMBOL_GPL -+0x4bf99462 rpcauth_init_cred vmlinux EXPORT_SYMBOL_GPL -+0x3cce336f xfrm_audit_state_replay_overflow vmlinux EXPORT_SYMBOL_GPL -+0x1fcece42 inet_twdr_twcal_tick vmlinux EXPORT_SYMBOL_GPL -+0x533977ad sock_create_lite vmlinux EXPORT_SYMBOL -+0x97dba41d mmc_hw_reset_check vmlinux EXPORT_SYMBOL -+0xf1be02c3 swiotlb_dma_mapping_error vmlinux EXPORT_SYMBOL -+0xb1c3fd5a d_obtain_alias vmlinux EXPORT_SYMBOL -+0x493e60ab file_sb_list_del vmlinux EXPORT_SYMBOL_GPL -+0x656e8057 nf_conntrack_helper_try_module_get net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xe160bbbe ip4_datagram_connect vmlinux EXPORT_SYMBOL -+0x6ba0b373 tcp_timewait_state_process vmlinux EXPORT_SYMBOL -+0x75bdea12 iommu_area_alloc vmlinux EXPORT_SYMBOL -+0xc46d877e schedule_hrtimeout vmlinux EXPORT_SYMBOL_GPL -+0x587b892e qe_get_num_of_risc vmlinux EXPORT_SYMBOL -+0x9f8fb40b starget_for_each_device vmlinux EXPORT_SYMBOL -+0x585be6d1 subsys_interface_register vmlinux EXPORT_SYMBOL_GPL -+0x6fdbcab8 nobh_writepage vmlinux EXPORT_SYMBOL -+0xb34ab28b clear_page_dirty_for_io vmlinux EXPORT_SYMBOL -+0xe0573294 srcu_init_notifier_head vmlinux EXPORT_SYMBOL_GPL -+0xcfb9006e jiffies_to_timeval vmlinux EXPORT_SYMBOL -+0x60421247 tcp_reno_min_cwnd vmlinux EXPORT_SYMBOL_GPL -+0x21b65a0b tty_schedule_flip vmlinux EXPORT_SYMBOL -+0x62d55839 tty_get_baud_rate vmlinux EXPORT_SYMBOL -+0x96877ac4 locks_start_grace vmlinux EXPORT_SYMBOL_GPL -+0x2d2aefd5 vfs_follow_link vmlinux EXPORT_SYMBOL -+0xc9d29672 svc_create_xprt vmlinux EXPORT_SYMBOL_GPL -+0xc74a0c83 sysdev_class_unregister vmlinux EXPORT_SYMBOL_GPL -+0xcf038dc7 tty_shutdown vmlinux EXPORT_SYMBOL -+0xfc885e13 tty_devnum vmlinux EXPORT_SYMBOL -+0xbed06f95 sysfs_rename_link vmlinux EXPORT_SYMBOL_GPL -+0x4f391d0e nla_parse vmlinux EXPORT_SYMBOL -+0xc1868f6a write_dirty_buffer vmlinux EXPORT_SYMBOL -+0xe633499a noop_llseek vmlinux EXPORT_SYMBOL -+0xc65d3eed ring_buffer_entries_cpu vmlinux EXPORT_SYMBOL_GPL -+0xf1e28f9a llc_sap_find vmlinux EXPORT_SYMBOL -+0x30fbaf1e input_free_device vmlinux EXPORT_SYMBOL -+0x69f56098 xprt_set_retrans_timeout_rtt vmlinux EXPORT_SYMBOL_GPL -+0x3e9110fa __hw_addr_unsync vmlinux EXPORT_SYMBOL -+0x7d11c268 jiffies vmlinux EXPORT_SYMBOL -+0x3e7bb605 dev_queue_xmit vmlinux EXPORT_SYMBOL -+0x5fa8e9f9 of_device_alloc vmlinux EXPORT_SYMBOL -+0xac57677c do_map_probe vmlinux EXPORT_SYMBOL -+0x5a324753 proc_mkdir vmlinux EXPORT_SYMBOL -+0x13d0adf7 __kfifo_out vmlinux EXPORT_SYMBOL -+0x8379c763 dmam_free_noncoherent vmlinux EXPORT_SYMBOL -+0x0964a2f2 blk_rq_map_sg vmlinux EXPORT_SYMBOL -+0x9b68e095 proc_dointvec_jiffies vmlinux EXPORT_SYMBOL -+0xb53a4336 kmap_pte vmlinux EXPORT_SYMBOL -+0x9105b5ec __napi_schedule vmlinux EXPORT_SYMBOL -+0x48c6fdb8 sk_stream_wait_memory vmlinux EXPORT_SYMBOL -+0xaf78c424 usb_set_interface vmlinux EXPORT_SYMBOL_GPL -+0x8384a2c5 tty_unlock vmlinux EXPORT_SYMBOL -+0x0d3cb182 kstrtos16_from_user vmlinux EXPORT_SYMBOL -+0x9f2bdaac __bitmap_or vmlinux EXPORT_SYMBOL -+0x4b29940c get_dcookie vmlinux EXPORT_SYMBOL_GPL -+0x87480e3f netlink_broadcast_filtered vmlinux EXPORT_SYMBOL -+0x5dd67618 register_netevent_notifier vmlinux EXPORT_SYMBOL_GPL -+0xc7ec6c27 strspn vmlinux EXPORT_SYMBOL -+0x0727c4f3 iowrite8 vmlinux EXPORT_SYMBOL -+0x97255bdf strlen vmlinux EXPORT_SYMBOL -+0x3f44c83f scsi_allocate_command vmlinux EXPORT_SYMBOL -+0xedbaee5e nla_strcmp vmlinux EXPORT_SYMBOL -+0x55786827 crypto_ahash_type vmlinux EXPORT_SYMBOL_GPL -+0x26bb950b __kfifo_from_user_r vmlinux EXPORT_SYMBOL -+0xadd1e971 alignment_exception vmlinux EXPORT_SYMBOL -+0xf6cb376c skb_trim vmlinux EXPORT_SYMBOL -+0x403f9529 gpio_request_one vmlinux EXPORT_SYMBOL_GPL -+0xce3e3387 svc_proc_register vmlinux EXPORT_SYMBOL_GPL -+0x6f35aea7 xfrm_policy_delete vmlinux EXPORT_SYMBOL -+0x40cb7613 inet_frags_init vmlinux EXPORT_SYMBOL -+0x60d5f317 rtc_irq_register vmlinux EXPORT_SYMBOL_GPL -+0x4e3567f7 match_int vmlinux EXPORT_SYMBOL -+0x054434d6 radix_tree_tag_set vmlinux EXPORT_SYMBOL -+0x7c763d45 blk_queue_lld_busy vmlinux EXPORT_SYMBOL_GPL -+0xcfd8a363 shash_free_instance vmlinux EXPORT_SYMBOL_GPL -+0xb663c828 debugfs_create_x64 vmlinux EXPORT_SYMBOL_GPL -+0x7e003b33 bdi_setup_and_register vmlinux EXPORT_SYMBOL -+0x510e2136 rpcauth_generic_bind_cred vmlinux EXPORT_SYMBOL_GPL -+0x5da31da0 skb_cow_data vmlinux EXPORT_SYMBOL_GPL -+0xdc6b4513 pci_fixup_cardbus vmlinux EXPORT_SYMBOL -+0x91acac9a i2c_get_adapter vmlinux EXPORT_SYMBOL -+0x868acba5 get_options vmlinux EXPORT_SYMBOL -+0xe2d57cb8 setup_irq vmlinux EXPORT_SYMBOL_GPL -+0x7e64ffb7 xdr_partial_copy_from_skb vmlinux EXPORT_SYMBOL_GPL -+0xac01fe4e input_unregister_handler vmlinux EXPORT_SYMBOL -+0x467b133c bh_uptodate_or_lock vmlinux EXPORT_SYMBOL -+0x2ec524ad __kfifo_in_r vmlinux EXPORT_SYMBOL -+0x51dce73b xfrm_state_walk_init vmlinux EXPORT_SYMBOL -+0xabeb086a rtc_read_alarm vmlinux EXPORT_SYMBOL_GPL -+0x8841dda6 pci_remove_behind_bridge vmlinux EXPORT_SYMBOL -+0x3c9d1211 string_get_size vmlinux EXPORT_SYMBOL -+0x14a5ead6 fat_fill_super vmlinux EXPORT_SYMBOL_GPL -+0x7b03848a verify_mem_not_deleted vmlinux EXPORT_SYMBOL -+0xee1a5125 register_exec_domain vmlinux EXPORT_SYMBOL -+0x4227283f fl6_sock_lookup vmlinux EXPORT_SYMBOL_GPL -+0x4c40ef7a pci_bus_write_config_word vmlinux EXPORT_SYMBOL -+0x9330cb9f sg_alloc_table vmlinux EXPORT_SYMBOL -+0x9c8d5b93 handle_simple_irq vmlinux EXPORT_SYMBOL_GPL -+0xda1be8e1 async_synchronize_cookie_domain vmlinux EXPORT_SYMBOL_GPL -+0xabd30091 call_usermodehelper_exec vmlinux EXPORT_SYMBOL -+0xa39b4cf2 udelay vmlinux EXPORT_SYMBOL -+0xe7a664c4 nf_hooks vmlinux EXPORT_SYMBOL -+0x339f4657 pci_release_region vmlinux EXPORT_SYMBOL -+0xff1e9dd8 seq_list_start vmlinux EXPORT_SYMBOL -+0x3f5b1415 nf_ct_port_nlattr_to_tuple net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xaeea3073 xfrm_aead_get_byname vmlinux EXPORT_SYMBOL_GPL -+0x02889771 km_state_notify vmlinux EXPORT_SYMBOL -+0xac26b820 _raw_write_lock vmlinux EXPORT_SYMBOL -+0x59b3378a completion_done vmlinux EXPORT_SYMBOL -+0x357c90d2 qdisc_put_stab vmlinux EXPORT_SYMBOL -+0x96a6cb6a seq_printf vmlinux EXPORT_SYMBOL -+0x8669d18f call_usermodehelper_setfns vmlinux EXPORT_SYMBOL -+0x4b98827c rh_init vmlinux EXPORT_SYMBOL_GPL -+0xa35b2101 mmc_free_host vmlinux EXPORT_SYMBOL -+0xe0b0dd36 pci_dev_driver vmlinux EXPORT_SYMBOL -+0x0b742fd7 simple_strtol vmlinux EXPORT_SYMBOL -+0x4da7c931 rwsem_downgrade_wake vmlinux EXPORT_SYMBOL -+0xfd9e2a19 ilookup5_nowait vmlinux EXPORT_SYMBOL -+0xac6855b0 gen_kill_estimator vmlinux EXPORT_SYMBOL -+0xdacc5bd6 pci_set_power_state vmlinux EXPORT_SYMBOL -+0x0a0db355 blk_queue_alignment_offset vmlinux EXPORT_SYMBOL -+0x5f4c2d4c unlock_super vmlinux EXPORT_SYMBOL -+0xdb3aca5d qe_pin_request vmlinux EXPORT_SYMBOL -+0x796fc5ce scsi_get_sense_info_fld vmlinux EXPORT_SYMBOL -+0x16db989b pci_bus_size_bridges vmlinux EXPORT_SYMBOL -+0x7e17c66d __bio_clone vmlinux EXPORT_SYMBOL -+0x4d025d04 vfs_stat vmlinux EXPORT_SYMBOL -+0xa0fbac79 wake_up_bit vmlinux EXPORT_SYMBOL -+0xe1e5b5a7 flush_fp_to_thread vmlinux EXPORT_SYMBOL_GPL -+0x3c93c386 nf_conntrack_flush_report net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x48a488a0 sysctl_tcp_cookie_size vmlinux EXPORT_SYMBOL_GPL -+0xe3a73fdb sysdev_driver_register vmlinux EXPORT_SYMBOL_GPL -+0x48034724 zlib_deflateReset vmlinux EXPORT_SYMBOL -+0x013b835b cap_netlink_recv vmlinux EXPORT_SYMBOL -+0xcdca3691 nr_irqs vmlinux EXPORT_SYMBOL_GPL -+0x8ec04552 _raw_spin_trylock_bh vmlinux EXPORT_SYMBOL -+0x56c8799d scsi_kunmap_atomic_sg vmlinux EXPORT_SYMBOL -+0x1b54f3f0 scsi_block_when_processing_errors vmlinux EXPORT_SYMBOL -+0x2d6604af wait_for_key_construction vmlinux EXPORT_SYMBOL -+0xa85da1dd f_setown vmlinux EXPORT_SYMBOL -+0x05e807a9 xdr_encode_string vmlinux EXPORT_SYMBOL_GPL -+0x3a434310 ip6_dst_hoplimit vmlinux EXPORT_SYMBOL -+0x03e7b88a arp_invalidate vmlinux EXPORT_SYMBOL -+0x81bf1cbf mmc_can_sanitize vmlinux EXPORT_SYMBOL -+0xfb1ebb24 usb_clear_halt vmlinux EXPORT_SYMBOL_GPL -+0xb640c303 swiotlb_map_sg_attrs vmlinux EXPORT_SYMBOL -+0x6d27ef64 __bitmap_empty vmlinux EXPORT_SYMBOL -+0x7c5f611a elv_unregister vmlinux EXPORT_SYMBOL_GPL -+0xf85746f7 submit_bh vmlinux EXPORT_SYMBOL -+0x7babd7ea mnt_clone_write vmlinux EXPORT_SYMBOL_GPL -+0x4e94f614 page_mkclean vmlinux EXPORT_SYMBOL_GPL -+0x405c1144 get_seconds vmlinux EXPORT_SYMBOL -+0x0d706d2e rh_set_owner vmlinux EXPORT_SYMBOL_GPL -+0xcf56c41f unregister_8022_client vmlinux EXPORT_SYMBOL -+0x2ddee4bb usb_anchor_empty vmlinux EXPORT_SYMBOL_GPL -+0xf0f1246c kvasprintf vmlinux EXPORT_SYMBOL -+0xa6dcc773 rb_insert_color vmlinux EXPORT_SYMBOL -+0x09c27acb svcauth_unix_set_client vmlinux EXPORT_SYMBOL_GPL -+0x9cd435ec __xfrm_init_state vmlinux EXPORT_SYMBOL -+0x1b17f158 hid_dump_field vmlinux EXPORT_SYMBOL_GPL -+0xdb80a388 __module_text_address vmlinux EXPORT_SYMBOL_GPL -+0x66d87d38 symbol_put_addr vmlinux EXPORT_SYMBOL_GPL -+0x2a639aaf hrtimer_start_range_ns vmlinux EXPORT_SYMBOL_GPL -+0x7c62d042 cpu_possible_mask vmlinux EXPORT_SYMBOL -+0x65319f3d llc_set_station_handler vmlinux EXPORT_SYMBOL -+0x12500d33 i2c_smbus_read_word_data vmlinux EXPORT_SYMBOL -+0xc2ac0cfe tty_buffer_request_room vmlinux EXPORT_SYMBOL_GPL -+0x00b37551 d_alloc vmlinux EXPORT_SYMBOL -+0xf7b796cc unuse_mm vmlinux EXPORT_SYMBOL_GPL -+0x0b73663b __alloc_pages_nodemask vmlinux EXPORT_SYMBOL -+0x2b0a269a elv_abort_queue vmlinux EXPORT_SYMBOL -+0xe189aa6f journal_extend vmlinux EXPORT_SYMBOL -+0x918ad429 ring_buffer_lock_reserve vmlinux EXPORT_SYMBOL_GPL -+0xe2755929 irq_set_affinity_hint vmlinux EXPORT_SYMBOL_GPL -+0x3abc78ce dev_err vmlinux EXPORT_SYMBOL -+0xfcfa8b04 blk_execute_rq_nowait vmlinux EXPORT_SYMBOL_GPL -+0x6d02eb17 udp_proc_register vmlinux EXPORT_SYMBOL -+0x7bf1cc3b kernel_sendpage vmlinux EXPORT_SYMBOL -+0x9d7e0cfa pci_choose_state vmlinux EXPORT_SYMBOL -+0x0a6c9682 delete_from_page_cache vmlinux EXPORT_SYMBOL -+0x3b615a21 wait_for_completion_killable vmlinux EXPORT_SYMBOL -+0x50c89f23 __alloc_percpu vmlinux EXPORT_SYMBOL_GPL -+0xe7cd06a1 scsi_cmd_get_serial vmlinux EXPORT_SYMBOL -+0xbd8ed748 svc_close_xprt vmlinux EXPORT_SYMBOL_GPL -+0x2fb84137 neigh_parms_release vmlinux EXPORT_SYMBOL -+0xbfd18198 mmc_card_awake vmlinux EXPORT_SYMBOL -+0xba386aa9 usb_hcd_link_urb_to_ep vmlinux EXPORT_SYMBOL_GPL -+0x50c6ae87 device_release_driver vmlinux EXPORT_SYMBOL_GPL -+0xa01f4485 swiotlb_alloc_coherent vmlinux EXPORT_SYMBOL -+0x572e85d4 blk_lookup_devt vmlinux EXPORT_SYMBOL -+0xe415316a crypto_grab_skcipher vmlinux EXPORT_SYMBOL_GPL -+0xe953b21f get_next_ino vmlinux EXPORT_SYMBOL -+0x546c5565 ppc_tb_freq vmlinux EXPORT_SYMBOL_GPL -+0x0bf06d6d usb_serial_handle_dcd_change vmlinux EXPORT_SYMBOL_GPL -+0xcd1bbf43 usb_stor_bulk_srb vmlinux EXPORT_SYMBOL_GPL -+0x326ee682 usb_alloc_streams vmlinux EXPORT_SYMBOL_GPL -+0x984ca836 scsi_register_interface vmlinux EXPORT_SYMBOL -+0xeb72182a vfs_setlease vmlinux EXPORT_SYMBOL_GPL -+0x40d04664 console_trylock vmlinux EXPORT_SYMBOL -+0x2ee496e6 i2c_smbus_read_block_data vmlinux EXPORT_SYMBOL -+0x71d6687e usb_put_intf vmlinux EXPORT_SYMBOL_GPL -+0x5040a36f blk_queue_dma_pad vmlinux EXPORT_SYMBOL -+0x0521b2ee set_current_groups vmlinux EXPORT_SYMBOL -+0xb1c6e787 wait_for_completion_timeout vmlinux EXPORT_SYMBOL -+0x107aa06a dcb_ieee_getapp_mask vmlinux EXPORT_SYMBOL -+0x60ac991d xfrm6_input_addr vmlinux EXPORT_SYMBOL -+0x3aa32d81 usb_stor_probe2 vmlinux EXPORT_SYMBOL_GPL -+0x12cd39ae usb_stor_probe1 vmlinux EXPORT_SYMBOL_GPL -+0x81db6ebb xz_dec_reset vmlinux EXPORT_SYMBOL -+0x661601de sprint_symbol vmlinux EXPORT_SYMBOL_GPL -+0x6e8698ee scm_fp_dup vmlinux EXPORT_SYMBOL -+0x9c2b3860 mmc_card_can_sleep vmlinux EXPORT_SYMBOL -+0x6a7e90da devres_remove vmlinux EXPORT_SYMBOL_GPL -+0x30e28a09 tty_vhangup vmlinux EXPORT_SYMBOL -+0xd3434c3f kref_sub vmlinux EXPORT_SYMBOL -+0x2ce98559 kcrypto_wq vmlinux EXPORT_SYMBOL_GPL -+0x8f860b23 shrink_dcache_parent vmlinux EXPORT_SYMBOL -+0x75c8a11c inet_twdr_twkill_work vmlinux EXPORT_SYMBOL_GPL -+0x609f1c7e synchronize_net vmlinux EXPORT_SYMBOL -+0xa638cf54 bus_for_each_dev vmlinux EXPORT_SYMBOL_GPL -+0x8dcf576a bus_for_each_drv vmlinux EXPORT_SYMBOL_GPL -+0x42825ce2 rcu_scheduler_active vmlinux EXPORT_SYMBOL_GPL -+0xe523ad75 synchronize_irq vmlinux EXPORT_SYMBOL -+0xfa393103 pneigh_lookup vmlinux EXPORT_SYMBOL -+0x0ba2668c kern_path_create vmlinux EXPORT_SYMBOL -+0xc47cdf9c _raw_write_lock_bh vmlinux EXPORT_SYMBOL -+0x72dc286d xdr_terminate_string vmlinux EXPORT_SYMBOL_GPL -+0x28531ce3 blk_queue_find_tag vmlinux EXPORT_SYMBOL -+0x4bc62a81 audit_enabled vmlinux EXPORT_SYMBOL_GPL -+0xd8a2ab95 in_egroup_p vmlinux EXPORT_SYMBOL -+0x919d1163 tty_termios_baud_rate vmlinux EXPORT_SYMBOL -+0x184e6c85 radix_tree_gang_lookup_slot vmlinux EXPORT_SYMBOL -+0xcdb01877 ktime_add_ns vmlinux EXPORT_SYMBOL_GPL -+0x8b96c05a nf_conntrack_broadcast_help net/netfilter/nf_conntrack_broadcast EXPORT_SYMBOL_GPL -+0xcb6e6aa8 skb_append_datato_frags vmlinux EXPORT_SYMBOL -+0x9e0c711d vzalloc_node vmlinux EXPORT_SYMBOL -+0x7f24de73 jiffies_to_usecs vmlinux EXPORT_SYMBOL -+0x37befc70 jiffies_to_msecs vmlinux EXPORT_SYMBOL -+0x436c2179 iowrite32 vmlinux EXPORT_SYMBOL -+0x8c183cbe iowrite16 vmlinux EXPORT_SYMBOL -+0x17774e80 tcp_child_process vmlinux EXPORT_SYMBOL -+0xb6896671 crc_t10dif vmlinux EXPORT_SYMBOL -+0x9ab8808c param_get_charp vmlinux EXPORT_SYMBOL -+0x8025065c mdiobus_write vmlinux EXPORT_SYMBOL -+0x1f852c0d prepare_binprm vmlinux EXPORT_SYMBOL -+0x4db9ec4c tcp_v4_destroy_sock vmlinux EXPORT_SYMBOL -+0x6d6cbadc rb_last vmlinux EXPORT_SYMBOL -+0x7ab3ca18 eventfd_ctx_read vmlinux EXPORT_SYMBOL_GPL -+0x86eb50bf mount_bdev vmlinux EXPORT_SYMBOL -+0xe6fbe430 can_do_mlock vmlinux EXPORT_SYMBOL -+0x60a13e90 rcu_barrier vmlinux EXPORT_SYMBOL_GPL -+0xdf60cc27 __print_symbol vmlinux EXPORT_SYMBOL -+0x96c287fe ndisc_mc_map vmlinux EXPORT_SYMBOL -+0x55da0153 sysdev_register vmlinux EXPORT_SYMBOL_GPL -+0x91715312 sprintf vmlinux EXPORT_SYMBOL -+0x0d05dd4f simple_unlink vmlinux EXPORT_SYMBOL -+0xaa563302 simple_attr_write vmlinux EXPORT_SYMBOL_GPL -+0x099b48fd generic_listxattr vmlinux EXPORT_SYMBOL -+0xf6ebc03b net_ratelimit vmlinux EXPORT_SYMBOL -+0xf9c8fc44 dev_addr_init vmlinux EXPORT_SYMBOL -+0x09ae2253 mmc_host_disable vmlinux EXPORT_SYMBOL -+0x6559ae6c pci_set_ltr vmlinux EXPORT_SYMBOL -+0x1ebf6c2a pci_power_names vmlinux EXPORT_SYMBOL_GPL -+0x57e7529b shash_ahash_update vmlinux EXPORT_SYMBOL_GPL -+0x05c6b149 invalidate_inode_buffers vmlinux EXPORT_SYMBOL -+0x48bea168 scsi_register vmlinux EXPORT_SYMBOL -+0x764c2f05 crypto_shash_update vmlinux EXPORT_SYMBOL_GPL -+0x2eef0ac9 journal_dirty_data vmlinux EXPORT_SYMBOL -+0xb5e31b10 find_vma vmlinux EXPORT_SYMBOL -+0x0d0f4d51 nf_ct_extend_unregister net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x5c936853 svc_print_addr vmlinux EXPORT_SYMBOL_GPL -+0x12505fc7 kernel_connect vmlinux EXPORT_SYMBOL -+0xb8546237 inet_stream_connect vmlinux EXPORT_SYMBOL -+0xa05c03df mempool_kmalloc vmlinux EXPORT_SYMBOL -+0x8dc76dc4 qdisc_warn_nonwc vmlinux EXPORT_SYMBOL -+0x9a7a6123 pci_release_regions vmlinux EXPORT_SYMBOL -+0xc9eec5c2 splice_from_pipe_begin vmlinux EXPORT_SYMBOL -+0xfd6293c2 boot_tvec_bases vmlinux EXPORT_SYMBOL -+0x126cabd2 netdev_class_remove_file vmlinux EXPORT_SYMBOL -+0xbccdc2f6 flex_array_put vmlinux EXPORT_SYMBOL -+0x8164e310 blk_queue_physical_block_size vmlinux EXPORT_SYMBOL -+0x9b724801 nlmclnt_done vmlinux EXPORT_SYMBOL_GPL -+0xf9e2e40e dio_end_io vmlinux EXPORT_SYMBOL_GPL -+0x53735d40 relay_subbufs_consumed vmlinux EXPORT_SYMBOL_GPL -+0xc0bf6ead timecounter_cyc2time vmlinux EXPORT_SYMBOL_GPL -+0x37f6fee5 fsl_lbc_find vmlinux EXPORT_SYMBOL -+0x4f881b16 rtc_tm_to_ktime vmlinux EXPORT_SYMBOL_GPL -+0x325ffbe2 journal_ack_err vmlinux EXPORT_SYMBOL -+0x307c2fd0 generic_check_addressable vmlinux EXPORT_SYMBOL -+0xee2d8f00 perf_event_read_value vmlinux EXPORT_SYMBOL_GPL -+0xc065a455 cpu_core_index_of_thread vmlinux EXPORT_SYMBOL_GPL -+0x33dc9781 inet6_csk_addr2sockaddr vmlinux EXPORT_SYMBOL_GPL -+0x4c50029a netdev_refcnt_read vmlinux EXPORT_SYMBOL -+0xd1b2bc7a input_mt_init_slots vmlinux EXPORT_SYMBOL -+0xa16d230d devres_close_group vmlinux EXPORT_SYMBOL_GPL -+0xa92b183a __blk_end_request vmlinux EXPORT_SYMBOL -+0x7f7bc710 klist_next vmlinux EXPORT_SYMBOL_GPL -+0x0140c06a tcp_rcv_established vmlinux EXPORT_SYMBOL -+0x80c1ac2b ip_queue_rcv_skb vmlinux EXPORT_SYMBOL -+0x4865f9b3 inet_getpeer vmlinux EXPORT_SYMBOL_GPL -+0x3d0688cd xt_unregister_targets vmlinux EXPORT_SYMBOL -+0x4e592d6c spi_alloc_master vmlinux EXPORT_SYMBOL_GPL -+0xce53932d scsi_prep_fn vmlinux EXPORT_SYMBOL -+0xd7e56a4e simple_strtoll vmlinux EXPORT_SYMBOL -+0x20000329 simple_strtoul vmlinux EXPORT_SYMBOL -+0xa3c8685d nfs_initiate_commit vmlinux EXPORT_SYMBOL_GPL -+0xbedc5a25 fsnotify_destroy_mark vmlinux EXPORT_SYMBOL_GPL -+0x65400222 __irq_offset_value vmlinux EXPORT_SYMBOL -+0x540fbf55 nf_register_afinfo vmlinux EXPORT_SYMBOL_GPL -+0x783c65c7 net_ns_type_operations vmlinux EXPORT_SYMBOL_GPL -+0x0d733a10 proc_symlink vmlinux EXPORT_SYMBOL -+0x983c7494 rh_detach_region vmlinux EXPORT_SYMBOL_GPL -+0x6428da4f rh_attach_region vmlinux EXPORT_SYMBOL_GPL -+0xe0f45eeb __rtnl_link_unregister vmlinux EXPORT_SYMBOL_GPL -+0x5497669a blk_queue_dma_alignment vmlinux EXPORT_SYMBOL -+0xc51e0e79 remap_vmalloc_range vmlinux EXPORT_SYMBOL -+0xda869994 noop_backing_dev_info vmlinux EXPORT_SYMBOL_GPL -+0xd985dc99 mempool_free_pages vmlinux EXPORT_SYMBOL -+0xfcec0987 enable_irq vmlinux EXPORT_SYMBOL -+0x1e7bbcb3 kernel_restart vmlinux EXPORT_SYMBOL_GPL -+0x0cc3cab1 dev_alloc_skb vmlinux EXPORT_SYMBOL -+0xdd27fa87 memchr vmlinux EXPORT_SYMBOL -+0xc18ac88d nf_ct_expect_hsize net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x7a00ec15 inet6_release vmlinux EXPORT_SYMBOL -+0xbeff3d59 of_get_parent vmlinux EXPORT_SYMBOL -+0x15a94e65 pci_destroy_slot vmlinux EXPORT_SYMBOL_GPL -+0x2cfc679e vfs_kern_mount vmlinux EXPORT_SYMBOL_GPL -+0xd5bd7dac ring_buffer_record_enable_cpu vmlinux EXPORT_SYMBOL_GPL -+0x1a3c4cdf local_flush_tlb_page vmlinux EXPORT_SYMBOL -+0x36bc9a29 gss_mech_list_pseudoflavors vmlinux EXPORT_SYMBOL_GPL -+0x977832e8 spi_bus_type vmlinux EXPORT_SYMBOL_GPL -+0x840efb10 anon_transport_class_unregister vmlinux EXPORT_SYMBOL_GPL -+0x315c65fd zlib_deflateInit2 vmlinux EXPORT_SYMBOL -+0x6bed2572 submit_bio vmlinux EXPORT_SYMBOL -+0x1aacd048 alloc_page_buffers vmlinux EXPORT_SYMBOL_GPL -+0xfbf9be5d register_oom_notifier vmlinux EXPORT_SYMBOL_GPL -+0xcfc68341 synchronize_rcu_bh vmlinux EXPORT_SYMBOL_GPL -+0x549525ef handle_nested_irq vmlinux EXPORT_SYMBOL_GPL -+0x25a81cc5 qe_get_firmware_info vmlinux EXPORT_SYMBOL -+0xd8525ea7 fl6_update_dst vmlinux EXPORT_SYMBOL_GPL -+0xa4e81ac2 tcp_valid_rtt_meas vmlinux EXPORT_SYMBOL -+0xe0a7f614 neigh_lookup vmlinux EXPORT_SYMBOL -+0x0680ca81 mmc_remove_host vmlinux EXPORT_SYMBOL -+0x7bd25d47 usb_put_hcd vmlinux EXPORT_SYMBOL_GPL -+0x2ef63ad6 scsi_dev_info_list_del_keyed vmlinux EXPORT_SYMBOL -+0x091c824a machine_power_off vmlinux EXPORT_SYMBOL_GPL -+0x3996b31d tcp_mtup_init vmlinux EXPORT_SYMBOL -+0x0ea07ec7 kstrtou8_from_user vmlinux EXPORT_SYMBOL -+0x973d0f9e kstrtoul_from_user vmlinux EXPORT_SYMBOL -+0x45cfa828 cache_purge vmlinux EXPORT_SYMBOL_GPL -+0x222e7ce2 sysfs_streq vmlinux EXPORT_SYMBOL -+0x71dd6c34 alloc_buffer_head vmlinux EXPORT_SYMBOL -+0x49dcec10 xdr_write_pages vmlinux EXPORT_SYMBOL_GPL -+0xbb73bb5c swiotlb_tbl_map_single vmlinux EXPORT_SYMBOL_GPL -+0x1ac51c1e device_remove_file vmlinux EXPORT_SYMBOL_GPL -+0x60506751 unmap_kernel_range_noflush vmlinux EXPORT_SYMBOL_GPL -+0x289c3714 nf_ct_alloc_hashtable net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x49ffc48e ipv6_skip_exthdr vmlinux EXPORT_SYMBOL -+0x5b723c46 ip_options_compile vmlinux EXPORT_SYMBOL -+0x45a37cf4 aio_complete vmlinux EXPORT_SYMBOL -+0x44402b6f param_get_ulong vmlinux EXPORT_SYMBOL -+0x0b19ea8e kill_pid vmlinux EXPORT_SYMBOL -+0x69642f88 pcibios_bus_to_resource vmlinux EXPORT_SYMBOL -+0xea710ef9 rt6_lookup vmlinux EXPORT_SYMBOL -+0x12f99022 inet_frags_init_net vmlinux EXPORT_SYMBOL -+0x796b252b device_store_int vmlinux EXPORT_SYMBOL_GPL -+0x64999478 congestion_wait vmlinux EXPORT_SYMBOL -+0x59eae699 ring_buffer_read_prepare vmlinux EXPORT_SYMBOL_GPL -+0xe4a65c70 i2c_del_driver vmlinux EXPORT_SYMBOL -+0x419b695a blk_queue_dma_drain vmlinux EXPORT_SYMBOL_GPL -+0x9d8331c0 ring_buffer_read_page vmlinux EXPORT_SYMBOL_GPL -+0xae545f06 _raw_write_unlock_irqrestore vmlinux EXPORT_SYMBOL -+0xbad26090 __atomic_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL -+0x057ce975 hex_dump_to_buffer vmlinux EXPORT_SYMBOL -+0x119db340 file_ra_state_init vmlinux EXPORT_SYMBOL_GPL -+0xcd212027 usb_alloc_coherent vmlinux EXPORT_SYMBOL_GPL -+0x74b35a2e crypto_larval_kill vmlinux EXPORT_SYMBOL_GPL -+0xfaa1f7a6 xfrm_register_mode vmlinux EXPORT_SYMBOL -+0xb0559860 inet_csk_get_port vmlinux EXPORT_SYMBOL_GPL -+0x20e9c644 mmc_flush_cache vmlinux EXPORT_SYMBOL -+0xd5f63191 i2c_clients_command vmlinux EXPORT_SYMBOL -+0xd77c0bc8 klist_remove vmlinux EXPORT_SYMBOL_GPL -+0xff121d12 ethtool_op_get_ufo vmlinux EXPORT_SYMBOL -+0x3755e17d dev_get_flags vmlinux EXPORT_SYMBOL -+0x5296e7f4 usb_get_status vmlinux EXPORT_SYMBOL_GPL -+0x790df6ca __wait_on_bit_lock vmlinux EXPORT_SYMBOL -+0x5a4eec67 svc_auth_register vmlinux EXPORT_SYMBOL_GPL -+0xe5122890 flow_cache_genid vmlinux EXPORT_SYMBOL -+0x2c919c63 gen_new_estimator vmlinux EXPORT_SYMBOL -+0x0c812da4 input_class vmlinux EXPORT_SYMBOL_GPL -+0x4e00ab3c pci_set_master vmlinux EXPORT_SYMBOL -+0xfcc8f571 crypto_alg_mod_lookup vmlinux EXPORT_SYMBOL_GPL -+0x31c5af62 freeze_super vmlinux EXPORT_SYMBOL -+0x00c0514b __devm_request_region vmlinux EXPORT_SYMBOL -+0xfb905a24 hid_connect vmlinux EXPORT_SYMBOL_GPL -+0x4b824206 mmc_set_data_timeout vmlinux EXPORT_SYMBOL -+0x1040ca42 usb_set_device_state vmlinux EXPORT_SYMBOL_GPL -+0x12c83422 scsi_eh_finish_cmd vmlinux EXPORT_SYMBOL -+0x87177c3d mmc_can_reset vmlinux EXPORT_SYMBOL -+0x5bc4f32c cpu_rmap_update vmlinux EXPORT_SYMBOL -+0xdd0a2ba2 strlcat vmlinux EXPORT_SYMBOL -+0xd627480b strncat vmlinux EXPORT_SYMBOL -+0xcfeb0be9 rb_augment_erase_begin vmlinux EXPORT_SYMBOL -+0xd6c357db blk_queue_max_discard_sectors vmlinux EXPORT_SYMBOL -+0xd2965f6f kthread_should_stop vmlinux EXPORT_SYMBOL -+0xd0ad960f nfnetlink_set_err net/netfilter/nfnetlink EXPORT_SYMBOL_GPL -+0x1c460693 netdev_notice vmlinux EXPORT_SYMBOL -+0x7f185424 blk_rq_map_kern vmlinux EXPORT_SYMBOL -+0x551de792 sync_mapping_buffers vmlinux EXPORT_SYMBOL -+0x4ac7a222 usb_serial_handle_break vmlinux EXPORT_SYMBOL_GPL -+0x204d23f2 __scsi_add_device vmlinux EXPORT_SYMBOL -+0xaaec89e2 fat_scan vmlinux EXPORT_SYMBOL_GPL -+0x4ca16694 inode_change_ok vmlinux EXPORT_SYMBOL -+0xf1a0626d datagram_poll vmlinux EXPORT_SYMBOL -+0x69d38ed9 __scsi_print_sense vmlinux EXPORT_SYMBOL -+0xf0c18cc1 blk_queue_end_tag vmlinux EXPORT_SYMBOL -+0x1e9edfb7 seq_hlist_start_head_rcu vmlinux EXPORT_SYMBOL -+0x87604ac8 dev_mc_flush vmlinux EXPORT_SYMBOL -+0xf0eb6c0e dev_uc_flush vmlinux EXPORT_SYMBOL -+0xd9fb3de3 usb_stor_Bulk_transport vmlinux EXPORT_SYMBOL_GPL -+0x0bc753c7 flush_old_exec vmlinux EXPORT_SYMBOL -+0x00c4dc87 timecounter_init vmlinux EXPORT_SYMBOL_GPL -+0x0c9b6089 nvram_get_size vmlinux EXPORT_SYMBOL -+0xad9e43be inet_addr_type vmlinux EXPORT_SYMBOL -+0xf22414e2 inet_recvmsg vmlinux EXPORT_SYMBOL -+0xd454b29f llc_sap_close vmlinux EXPORT_SYMBOL -+0x80132d25 mdiobus_unregister vmlinux EXPORT_SYMBOL -+0x65291cff timekeeping_inject_offset vmlinux EXPORT_SYMBOL -+0x7be4827c pci_dram_offset vmlinux EXPORT_SYMBOL -+0xb09c5030 phy_detach vmlinux EXPORT_SYMBOL -+0x01b08eb0 mii_link_ok vmlinux EXPORT_SYMBOL -+0xc741f047 nfs_commitdata_alloc vmlinux EXPORT_SYMBOL_GPL -+0x5892f832 release_pmc_hardware vmlinux EXPORT_SYMBOL_GPL -+0x583c4f4e nf_conntrack_l4proto_udp6 net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xb0a8c94f tcp_proc_register vmlinux EXPORT_SYMBOL -+0x2a939f0e stop_tty vmlinux EXPORT_SYMBOL -+0xb7a99781 __irq_regs vmlinux EXPORT_SYMBOL -+0x774406ff generic_write_sync vmlinux EXPORT_SYMBOL -+0xf5b52822 sdio_writel vmlinux EXPORT_SYMBOL_GPL -+0xa0088161 nfs_pageio_reset_write_mds vmlinux EXPORT_SYMBOL_GPL -+0x92a84998 xfrm_policy_destroy vmlinux EXPORT_SYMBOL -+0x0538c307 sdhci_pltfm_register vmlinux EXPORT_SYMBOL_GPL -+0x43ed8622 sdio_memcpy_toio vmlinux EXPORT_SYMBOL_GPL -+0xb0a6f554 neigh_ifdown vmlinux EXPORT_SYMBOL -+0x00d43c47 cfi_fixup vmlinux EXPORT_SYMBOL -+0x6c1ce5ce strcspn vmlinux EXPORT_SYMBOL -+0x6cc25857 thermal_zone_unbind_cooling_device vmlinux EXPORT_SYMBOL -+0xcea93771 do_kern_mount vmlinux EXPORT_SYMBOL_GPL -+0xa32cec39 nf_conntrack_l3proto_register net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xdfb4377e nf_conntrack_l4proto_register net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xd4b929a5 hid_parse_report vmlinux EXPORT_SYMBOL_GPL -+0xc9b13a79 usb_serial_resume vmlinux EXPORT_SYMBOL -+0xad85acb1 blkdev_aio_write vmlinux EXPORT_SYMBOL_GPL -+0xfc21ea7b seq_bitmap_list vmlinux EXPORT_SYMBOL -+0xaec655c7 alloc_pages_exact vmlinux EXPORT_SYMBOL -+0x283780f9 gss_svc_to_pseudoflavor vmlinux EXPORT_SYMBOL_GPL -+0xeb5f1beb svc_find_xprt vmlinux EXPORT_SYMBOL_GPL -+0xb27c96eb svc_process vmlinux EXPORT_SYMBOL_GPL -+0xf40325f9 rpc_force_rebind vmlinux EXPORT_SYMBOL_GPL -+0x031337c7 __nla_reserve vmlinux EXPORT_SYMBOL -+0x29537c9e alloc_chrdev_region vmlinux EXPORT_SYMBOL -+0xa794e5af inc_zone_page_state vmlinux EXPORT_SYMBOL -+0xbe2ae37c nf_ct_iterate_cleanup net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x159caf84 rpc_killall_tasks vmlinux EXPORT_SYMBOL_GPL -+0x7faee9ca arp_find vmlinux EXPORT_SYMBOL -+0xc9e3b1e4 skb_checksum vmlinux EXPORT_SYMBOL -+0x2ccabce7 deregister_mtd_blktrans vmlinux EXPORT_SYMBOL_GPL -+0x8d8718ca pci_pme_capable vmlinux EXPORT_SYMBOL -+0xbdf5c25c rb_next vmlinux EXPORT_SYMBOL -+0xca4c7f40 inode_permission vmlinux EXPORT_SYMBOL -+0xcc3e77da buffer_migrate_page vmlinux EXPORT_SYMBOL -+0x519b0da3 finish_wait vmlinux EXPORT_SYMBOL -+0x4a290d4d cur_cpu_spec vmlinux EXPORT_SYMBOL -+0x564f1dca klist_add_after vmlinux EXPORT_SYMBOL_GPL -+0xd329f4b2 svc_xprt_init vmlinux EXPORT_SYMBOL_GPL -+0x52d7b2fd llc_sap_list vmlinux EXPORT_SYMBOL -+0x91fe4a85 phy_start_aneg vmlinux EXPORT_SYMBOL -+0x8695c5de scsi_print_result vmlinux EXPORT_SYMBOL -+0x4cbbd171 __bitmap_weight vmlinux EXPORT_SYMBOL -+0x61b7b126 simple_strtoull vmlinux EXPORT_SYMBOL -+0x528c709d simple_read_from_buffer vmlinux EXPORT_SYMBOL -+0x349e53f1 clockevent_delta2ns vmlinux EXPORT_SYMBOL_GPL -+0x6eb85693 nf_defrag_ipv6_enable net/ipv6/netfilter/nf_defrag_ipv6 EXPORT_SYMBOL_GPL -+0x6b6c3d10 nf_defrag_ipv4_enable net/ipv4/netfilter/nf_defrag_ipv4 EXPORT_SYMBOL_GPL -+0xa681fe88 generate_random_uuid vmlinux EXPORT_SYMBOL -+0xad1bb027 nf_ct_free_hashtable net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xc181af4a get_net_ns_by_pid vmlinux EXPORT_SYMBOL_GPL -+0xa1c47d5e mmc_power_save_host vmlinux EXPORT_SYMBOL -+0x86a1aabc vfs_statfs vmlinux EXPORT_SYMBOL -+0x8a50868d iterate_mounts vmlinux EXPORT_SYMBOL_GPL -+0x45838122 udp_ioctl vmlinux EXPORT_SYMBOL -+0xa02f471b i2c_new_probed_device vmlinux EXPORT_SYMBOL_GPL -+0x2e258c1f cfi_cmdset_0003 vmlinux EXPORT_SYMBOL_GPL -+0xe5ccb818 cfi_cmdset_0001 vmlinux EXPORT_SYMBOL_GPL -+0x037508a0 cfi_cmdset_0200 vmlinux EXPORT_SYMBOL_GPL -+0xeacafb73 cfi_cmdset_0006 vmlinux EXPORT_SYMBOL_GPL -+0xa669953c cfi_cmdset_0002 vmlinux EXPORT_SYMBOL_GPL -+0x8c101558 cfi_cmdset_0701 vmlinux EXPORT_SYMBOL_GPL -+0xf32fddac cfi_cmdset_0020 vmlinux EXPORT_SYMBOL_GPL -+0x58d4f625 __pci_complete_power_transition vmlinux EXPORT_SYMBOL_GPL -+0x0223b9bf __nla_reserve_nohdr vmlinux EXPORT_SYMBOL -+0x11fac1b6 __get_page_tail vmlinux EXPORT_SYMBOL -+0x5f5fc264 rtnetlink_put_metrics vmlinux EXPORT_SYMBOL -+0xea10212a int_to_scsilun vmlinux EXPORT_SYMBOL -+0x96fae2c1 may_umount vmlinux EXPORT_SYMBOL -+0xf6f92407 pcix_get_max_mmrbc vmlinux EXPORT_SYMBOL -+0x0b508415 block_read_full_page vmlinux EXPORT_SYMBOL -+0xf7535902 console_drivers vmlinux EXPORT_SYMBOL_GPL -+0x8de519db mmc_hw_reset vmlinux EXPORT_SYMBOL -+0x015ffc4f __scsi_alloc_queue vmlinux EXPORT_SYMBOL -+0x277ba2d9 bus_sort_breadthfirst vmlinux EXPORT_SYMBOL_GPL -+0xe11c50a5 ipt_alloc_initial_table net/ipv4/netfilter/ip_tables EXPORT_SYMBOL_GPL -+0x86c14d2e tcp_v4_connect vmlinux EXPORT_SYMBOL -+0x2c2f763c tcp_sync_mss vmlinux EXPORT_SYMBOL -+0xd0c05159 emergency_restart vmlinux EXPORT_SYMBOL_GPL -+0x3ff62317 local_bh_disable vmlinux EXPORT_SYMBOL -+0x3c5a83ec tcp_death_row vmlinux EXPORT_SYMBOL_GPL -+0xe187693c kstrtouint_from_user vmlinux EXPORT_SYMBOL -+0x1f3e84a0 bio_get_nr_vecs vmlinux EXPORT_SYMBOL -+0xf92a5458 xfrm_policy_byid vmlinux EXPORT_SYMBOL -+0xc871c13b pci_prepare_to_sleep vmlinux EXPORT_SYMBOL -+0x0f6690cf ahash_register_instance vmlinux EXPORT_SYMBOL_GPL -+0x686145ef load_nls_default vmlinux EXPORT_SYMBOL -+0xf209fa23 nonseekable_open vmlinux EXPORT_SYMBOL -+0x3d9e1db6 kmem_cache_create vmlinux EXPORT_SYMBOL -+0x475100c2 inet_get_local_port_range vmlinux EXPORT_SYMBOL -+0xd5683a1b __seq_open_private vmlinux EXPORT_SYMBOL -+0x13bdfe24 seq_escape vmlinux EXPORT_SYMBOL -+0x3108ea46 xfrm_ealg_get_byname vmlinux EXPORT_SYMBOL_GPL -+0x48c5e0f4 of_mdiobus_register vmlinux EXPORT_SYMBOL -+0x22692356 d_alloc_root vmlinux EXPORT_SYMBOL -+0xa0243187 page_address vmlinux EXPORT_SYMBOL -+0x89c72573 xfrm_lookup vmlinux EXPORT_SYMBOL -+0xc4a5fb77 skb_store_bits vmlinux EXPORT_SYMBOL -+0x9565a5a2 page_cache_sync_readahead vmlinux EXPORT_SYMBOL_GPL -+0x79c480da rh_dump vmlinux EXPORT_SYMBOL_GPL -+0xfba770b8 pcibios_fixup_bus vmlinux EXPORT_SYMBOL -+0xa93da361 inet_unregister_protosw vmlinux EXPORT_SYMBOL -+0x7cef3f58 i2c_probe_func_quick_read vmlinux EXPORT_SYMBOL_GPL -+0x65c8d17e i2c_smbus_read_byte vmlinux EXPORT_SYMBOL -+0x294d91c5 platform_create_bundle vmlinux EXPORT_SYMBOL_GPL -+0x99dc6ab8 _dev_info vmlinux EXPORT_SYMBOL -+0x1e4a32eb mb_cache_entry_free vmlinux EXPORT_SYMBOL -+0xeeac816f svc_xprt_put vmlinux EXPORT_SYMBOL_GPL -+0x1345ef47 ethtool_op_get_flags vmlinux EXPORT_SYMBOL -+0xa31feac5 blkcipher_walk_phys vmlinux EXPORT_SYMBOL_GPL -+0x3dfc897c seq_hlist_start_head vmlinux EXPORT_SYMBOL -+0xc34ff0bb clocksource_change_rating vmlinux EXPORT_SYMBOL -+0x9272763d sdio_set_block_size vmlinux EXPORT_SYMBOL_GPL -+0x439751b0 usb_stor_post_reset vmlinux EXPORT_SYMBOL_GPL -+0x9924c496 __usb_get_extra_descriptor vmlinux EXPORT_SYMBOL_GPL -+0xb0b3b849 pci_bus_assign_resources vmlinux EXPORT_SYMBOL -+0x9159b9d6 profile_event_register vmlinux EXPORT_SYMBOL_GPL -+0x6ca4d6ee __nf_conntrack_helper_find net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xd251093f nfs_generic_pg_test vmlinux EXPORT_SYMBOL_GPL -+0x5460c8d8 fsnotify_get_cookie vmlinux EXPORT_SYMBOL_GPL -+0xbeeb9715 dcb_getapp vmlinux EXPORT_SYMBOL -+0xb9a9fe46 dcb_setapp vmlinux EXPORT_SYMBOL -+0xb84d7d46 register_netdevice vmlinux EXPORT_SYMBOL -+0x0c38172a usb_serial_generic_open vmlinux EXPORT_SYMBOL_GPL -+0xfc532eb4 scsi_finish_command vmlinux EXPORT_SYMBOL -+0x11f447ce __gpio_to_irq vmlinux EXPORT_SYMBOL_GPL -+0xeba6034f user_describe vmlinux EXPORT_SYMBOL_GPL -+0x1fb3a608 blkdev_put vmlinux EXPORT_SYMBOL -+0xae6c3303 blkdev_get vmlinux EXPORT_SYMBOL -+0xc7c3a66d tcp_get_info vmlinux EXPORT_SYMBOL_GPL -+0x7a39ec0d __alloc_skb vmlinux EXPORT_SYMBOL -+0x8226642f __gpio_cansleep vmlinux EXPORT_SYMBOL_GPL -+0x98c5718a mutex_trylock vmlinux EXPORT_SYMBOL -+0xe24d3a97 jiffies_64 vmlinux EXPORT_SYMBOL -+0x61eef2c9 _insb vmlinux EXPORT_SYMBOL -+0x89863b3d svc_create vmlinux EXPORT_SYMBOL_GPL -+0xe387568c rpc_lookup_machine_cred vmlinux EXPORT_SYMBOL_GPL -+0x272caed2 pci_cleanup_aer_uncorrect_error_status vmlinux EXPORT_SYMBOL_GPL -+0x6def2db2 half_md4_transform vmlinux EXPORT_SYMBOL -+0xb835b3e4 radix_tree_prev_hole vmlinux EXPORT_SYMBOL -+0xd23a5bcb dcache_readdir vmlinux EXPORT_SYMBOL -+0x0b5cb616 inode_add_bytes vmlinux EXPORT_SYMBOL -+0xdb03e514 thaw_super vmlinux EXPORT_SYMBOL -+0x992edcea generic_file_mmap vmlinux EXPORT_SYMBOL -+0x3bf0c89b abort_creds vmlinux EXPORT_SYMBOL -+0x38b92846 llc_remove_pack vmlinux EXPORT_SYMBOL -+0x4188d439 neigh_rand_reach_time vmlinux EXPORT_SYMBOL -+0x5009e8d3 dev_forward_skb vmlinux EXPORT_SYMBOL_GPL -+0x88a779be sock_common_getsockopt vmlinux EXPORT_SYMBOL -+0xf532f540 sock_common_setsockopt vmlinux EXPORT_SYMBOL -+0xfb09342d n_tty_inherit_ops vmlinux EXPORT_SYMBOL_GPL -+0x65d6d0f0 gpio_direction_input vmlinux EXPORT_SYMBOL_GPL -+0x65408378 zlib_inflate_blob vmlinux EXPORT_SYMBOL -+0x14e837a0 idr_find vmlinux EXPORT_SYMBOL -+0xf1da72e2 vfs_mknod vmlinux EXPORT_SYMBOL -+0xca0bb1d5 ethtool_op_get_sg vmlinux EXPORT_SYMBOL -+0x1c7611b9 skb_dequeue vmlinux EXPORT_SYMBOL -+0x977653c9 filemap_write_and_wait vmlinux EXPORT_SYMBOL -+0x27bbf221 disable_irq_nosync vmlinux EXPORT_SYMBOL -+0x24a79d66 call_usermodehelper_freeinfo vmlinux EXPORT_SYMBOL -+0x00000000 softirq_work_list vmlinux EXPORT_SYMBOL -+0x14e7ca7c alloc_cpu_rmap vmlinux EXPORT_SYMBOL -+0xbc3d7933 netdev_features_change vmlinux EXPORT_SYMBOL -+0x50d5aae6 platform_get_resource_byname vmlinux EXPORT_SYMBOL_GPL -+0x7272c3c8 cpu_online_mask vmlinux EXPORT_SYMBOL -+0x62813e5c nf_ct_port_nlattr_tuple_size net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xe39bc3c9 of_find_node_by_type vmlinux EXPORT_SYMBOL -+0x5fee0ee3 of_find_node_by_path vmlinux EXPORT_SYMBOL -+0x8de66ff6 phy_start vmlinux EXPORT_SYMBOL -+0x2e919a67 devres_find vmlinux EXPORT_SYMBOL_GPL -+0x5df73517 proc_dostring vmlinux EXPORT_SYMBOL -+0xb54533f7 usecs_to_jiffies vmlinux EXPORT_SYMBOL -+0x0037d54d xt_hook_link vmlinux EXPORT_SYMBOL_GPL -+0xb93e2e16 pci_bus_write_config_byte vmlinux EXPORT_SYMBOL -+0x090d7ed0 sysfs_schedule_callback vmlinux EXPORT_SYMBOL_GPL -+0xabcaa577 free_anon_bdev vmlinux EXPORT_SYMBOL -+0xfb7d26f4 files_lglock_lock_init vmlinux EXPORT_SYMBOL -+0xa601a566 raw_hash_sk vmlinux EXPORT_SYMBOL_GPL -+0xa2ef34d7 rps_sock_flow_table vmlinux EXPORT_SYMBOL -+0x9b08b01c skb_insert vmlinux EXPORT_SYMBOL -+0x87ae2dae usb_stor_control_msg vmlinux EXPORT_SYMBOL_GPL -+0x18f9dd97 dev_emerg vmlinux EXPORT_SYMBOL -+0xb012f582 journal_force_commit_nested vmlinux EXPORT_SYMBOL -+0x1c132024 request_any_context_irq vmlinux EXPORT_SYMBOL_GPL -+0xedc410d0 udplite_table vmlinux EXPORT_SYMBOL -+0xbdc36d56 tc_classify_compat vmlinux EXPORT_SYMBOL -+0xcf469f8a blk_queue_max_segment_size vmlinux EXPORT_SYMBOL -+0xf158f170 klist_add_tail vmlinux EXPORT_SYMBOL_GPL -+0x2499acdc dev_kfree_skb_irq vmlinux EXPORT_SYMBOL -+0x8e0fe91b kill_mtd_super vmlinux EXPORT_SYMBOL_GPL -+0x1a2cbf5f pci_find_ext_capability vmlinux EXPORT_SYMBOL_GPL -+0xb9592633 log_wait_commit vmlinux EXPORT_SYMBOL -+0x6e9dd606 __symbol_put vmlinux EXPORT_SYMBOL -+0x884f0c0b netpoll_send_udp vmlinux EXPORT_SYMBOL -+0x89085598 genphy_restart_aneg vmlinux EXPORT_SYMBOL -+0x651b6806 pci_claim_resource vmlinux EXPORT_SYMBOL -+0x9b388444 get_zeroed_page vmlinux EXPORT_SYMBOL -+0xe7bf317d fsl_lbc_addr vmlinux EXPORT_SYMBOL -+0xa1c4b6d2 of_translate_dma_address vmlinux EXPORT_SYMBOL -+0x36d57a24 of_device_is_available vmlinux EXPORT_SYMBOL -+0x6b90f49a input_close_device vmlinux EXPORT_SYMBOL -+0x6bd60be5 key_validate vmlinux EXPORT_SYMBOL -+0xcaea3297 rtnl_create_link vmlinux EXPORT_SYMBOL -+0x92e047fd phy_connect_direct vmlinux EXPORT_SYMBOL -+0xba6f5ed2 tty_insert_flip_string_flags vmlinux EXPORT_SYMBOL -+0xb7188ca3 address_space_init_once vmlinux EXPORT_SYMBOL -+0x8f85f835 prepare_to_wait_exclusive vmlinux EXPORT_SYMBOL -+0x1105338b xfrm_audit_state_replay vmlinux EXPORT_SYMBOL_GPL -+0x0b0fcce8 inet_dev_addr_type vmlinux EXPORT_SYMBOL -+0xe792f22e platform_device_add vmlinux EXPORT_SYMBOL_GPL -+0x035223fb debugfs_create_size_t vmlinux EXPORT_SYMBOL_GPL -+0xdc9c0fca remove_proc_entry vmlinux EXPORT_SYMBOL -+0xd547ec64 fsnotify_add_mark vmlinux EXPORT_SYMBOL_GPL -+0xa502eb8f arpt_register_table net/ipv4/netfilter/arp_tables EXPORT_SYMBOL -+0xbe27f880 ipv6_opt_accepted vmlinux EXPORT_SYMBOL_GPL -+0x46b75886 xfrm_spd_getinfo vmlinux EXPORT_SYMBOL -+0xcd13ff57 pci_walk_bus vmlinux EXPORT_SYMBOL_GPL -+0xf729527b block_is_partially_uptodate vmlinux EXPORT_SYMBOL -+0xd9ecb670 ring_buffer_overruns vmlinux EXPORT_SYMBOL_GPL -+0xcee467f3 xprt_load_transport vmlinux EXPORT_SYMBOL_GPL -+0x9a13af3e alloc_etherdev_mqs vmlinux EXPORT_SYMBOL -+0x2179d22c uart_resume_port vmlinux EXPORT_SYMBOL -+0x83d9de3d ahash_free_instance vmlinux EXPORT_SYMBOL_GPL -+0xe965217d bdi_register_dev vmlinux EXPORT_SYMBOL -+0x9a303feb xt_rateest_lookup net/netfilter/xt_RATEEST EXPORT_SYMBOL_GPL -+0x076eb1e3 nfs_commit_clear_lock vmlinux EXPORT_SYMBOL_GPL -+0x2b76aaca pagecache_write_end vmlinux EXPORT_SYMBOL -+0xc4708199 cpm_muram_addr vmlinux EXPORT_SYMBOL -+0xf5629e6e rpc_clone_client vmlinux EXPORT_SYMBOL_GPL -+0x45704bee xfrm_audit_state_icvfail vmlinux EXPORT_SYMBOL_GPL -+0xb9da2997 snmp_fold_field64 vmlinux EXPORT_SYMBOL_GPL -+0x42621f9f of_get_next_child vmlinux EXPORT_SYMBOL -+0x2618e30b hid_resolv_usage vmlinux EXPORT_SYMBOL_GPL -+0x3e44ea18 sdio_f0_readb vmlinux EXPORT_SYMBOL_GPL -+0x6b645db0 spi_register_master vmlinux EXPORT_SYMBOL_GPL -+0xcc36f32e fb_unregister_client vmlinux EXPORT_SYMBOL -+0x87925ca6 kstrtoint_from_user vmlinux EXPORT_SYMBOL -+0xfde0b92c crypto_larval_error vmlinux EXPORT_SYMBOL_GPL -+0xc8d428d1 __nf_ct_l4proto_find net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x9e9e305b xfrm_inner_extract_output vmlinux EXPORT_SYMBOL_GPL -+0x564436dc inet_csk_init_xmit_timers vmlinux EXPORT_SYMBOL -+0x1b52db1c probe_kernel_read vmlinux EXPORT_SYMBOL_GPL -+0x8111c5eb kmap_atomic_prot vmlinux EXPORT_SYMBOL -+0x900d37fb transport_add_device vmlinux EXPORT_SYMBOL_GPL -+0xbee5ca31 vfs_readlink vmlinux EXPORT_SYMBOL -+0xd00652f3 timecompare_offset vmlinux EXPORT_SYMBOL_GPL -+0x68609857 complete_and_exit vmlinux EXPORT_SYMBOL -+0x6cfe0225 inet6_lookup vmlinux EXPORT_SYMBOL_GPL -+0xae4c9e70 sysfs_remove_group vmlinux EXPORT_SYMBOL_GPL -+0xf583db29 sysfs_remove_file_from_group vmlinux EXPORT_SYMBOL_GPL -+0x83ce82eb get_monotonic_boottime vmlinux EXPORT_SYMBOL_GPL -+0xc91ff664 down_read_trylock vmlinux EXPORT_SYMBOL -+0x4235ac11 dcbnl_cee_notify vmlinux EXPORT_SYMBOL -+0x93200b86 serial8250_handle_irq vmlinux EXPORT_SYMBOL_GPL -+0x4dcec118 nf_nat_set_seq_adjust net/ipv4/netfilter/nf_nat EXPORT_SYMBOL_GPL -+0xc6721caa nf_setsockopt vmlinux EXPORT_SYMBOL -+0x66297ceb nf_getsockopt vmlinux EXPORT_SYMBOL -+0x579e0bf5 rtnl_unregister_all vmlinux EXPORT_SYMBOL_GPL -+0x28d06a1f netif_rx_ni vmlinux EXPORT_SYMBOL -+0x160c8e49 i2c_smbus_xfer vmlinux EXPORT_SYMBOL -+0x1d1183eb device_attach vmlinux EXPORT_SYMBOL_GPL -+0x7b3d0f33 tty_port_open vmlinux EXPORT_SYMBOL -+0xe6faea36 alloc_disk vmlinux EXPORT_SYMBOL -+0xfa0ff0b4 blk_rq_map_user_iov vmlinux EXPORT_SYMBOL -+0x3ec13a0e seq_puts vmlinux EXPORT_SYMBOL -+0x3c620520 seq_putc vmlinux EXPORT_SYMBOL -+0xd7112524 usb_create_shared_hcd vmlinux EXPORT_SYMBOL_GPL -+0xca91df2e uart_update_timeout vmlinux EXPORT_SYMBOL -+0xeea70e8b part_round_stats vmlinux EXPORT_SYMBOL_GPL -+0x5374fd5a d_genocide vmlinux EXPORT_SYMBOL -+0x23af09db __module_put_and_exit vmlinux EXPORT_SYMBOL -+0x0088a193 __alloc_workqueue_key vmlinux EXPORT_SYMBOL_GPL -+0xaee6643e elv_dispatch_add_tail vmlinux EXPORT_SYMBOL -+0xaa966bf7 end_buffer_write_sync vmlinux EXPORT_SYMBOL -+0xa8835c2b d_drop vmlinux EXPORT_SYMBOL -+0xf165adc2 d_rehash vmlinux EXPORT_SYMBOL -+0xdea3251f file_open_root vmlinux EXPORT_SYMBOL -+0xc154f8f2 flush_kthread_work vmlinux EXPORT_SYMBOL_GPL -+0xa89464b7 __ashldi3 vmlinux EXPORT_SYMBOL -+0xb292666e __mmc_claim_host vmlinux EXPORT_SYMBOL -+0xed6010a9 usb_poison_urb vmlinux EXPORT_SYMBOL_GPL -+0xbf7c5874 pci_get_class vmlinux EXPORT_SYMBOL -+0x6b1b67d3 __bdevname vmlinux EXPORT_SYMBOL -+0xad4ba1e4 vfs_write vmlinux EXPORT_SYMBOL -+0xbea16979 netif_rx vmlinux EXPORT_SYMBOL -+0x1fbf241d swiotlb_sync_sg_for_cpu vmlinux EXPORT_SYMBOL -+0x955b0e2e kthread_worker_fn vmlinux EXPORT_SYMBOL_GPL -+0x9d0abaf6 xfrm_stateonly_find vmlinux EXPORT_SYMBOL -+0x34733550 usb_create_hcd vmlinux EXPORT_SYMBOL_GPL -+0x72ea7b2d scsi_device_type vmlinux EXPORT_SYMBOL -+0xadf2bd53 unregister_binfmt vmlinux EXPORT_SYMBOL -+0x2d9402fe alloc_vm_area vmlinux EXPORT_SYMBOL_GPL -+0x65bb58a2 _raw_read_trylock vmlinux EXPORT_SYMBOL -+0x844404cf ISA_DMA_THRESHOLD vmlinux EXPORT_SYMBOL -+0x908169b4 xdr_init_encode vmlinux EXPORT_SYMBOL_GPL -+0xb4bd61df netdev_bonding_change vmlinux EXPORT_SYMBOL -+0xe15c2179 sk_reset_txq vmlinux EXPORT_SYMBOL -+0xb2af542a sock_no_accept vmlinux EXPORT_SYMBOL -+0x2fa50e36 set_groups vmlinux EXPORT_SYMBOL -+0xec25f967 klist_del vmlinux EXPORT_SYMBOL_GPL -+0x3c9d911f skb_dst_set_noref vmlinux EXPORT_SYMBOL -+0x839c2a1f mmc_unregister_driver vmlinux EXPORT_SYMBOL -+0x21f0b642 elevator_exit vmlinux EXPORT_SYMBOL -+0xc4fa4b8f __lock_buffer vmlinux EXPORT_SYMBOL -+0xbb0ab47b debug_locks vmlinux EXPORT_SYMBOL_GPL -+0x6d953c4b ablkcipher_walk_done vmlinux EXPORT_SYMBOL_GPL -+0xed2498e7 ablkcipher_walk_phys vmlinux EXPORT_SYMBOL_GPL -+0x3999991e aead_geniv_alloc vmlinux EXPORT_SYMBOL_GPL -+0x20a789ac irq_set_chip_data vmlinux EXPORT_SYMBOL -+0x5971a2d5 inet6_csk_xmit vmlinux EXPORT_SYMBOL_GPL -+0x4d648b71 tcp_ioctl vmlinux EXPORT_SYMBOL -+0x5d9b4dd5 vfs_symlink vmlinux EXPORT_SYMBOL -+0x3ae34d58 find_vpid vmlinux EXPORT_SYMBOL_GPL -+0xd273b1b1 __round_jiffies_up_relative vmlinux EXPORT_SYMBOL_GPL -+0x17fe13bd unmap_mapping_range vmlinux EXPORT_SYMBOL -+0xeecb92f0 inet_select_addr vmlinux EXPORT_SYMBOL -+0x51855d05 dev_getbyhwaddr_rcu vmlinux EXPORT_SYMBOL -+0xadfbdc10 skb_flow_dissect vmlinux EXPORT_SYMBOL -+0xcd336604 pci_enable_device vmlinux EXPORT_SYMBOL -+0xc86a546a cpu_present_mask vmlinux EXPORT_SYMBOL -+0x6373d84b xprt_release_xprt_cong vmlinux EXPORT_SYMBOL_GPL -+0xbbca5c26 dcache_dir_close vmlinux EXPORT_SYMBOL -+0x82e5a238 vm_get_page_prot vmlinux EXPORT_SYMBOL -+0x6450bfd7 rpc_wake_up_queued_task vmlinux EXPORT_SYMBOL_GPL -+0xa9ade535 unregister_snap_client vmlinux EXPORT_SYMBOL -+0xee6e2a28 rtc_irq_set_state vmlinux EXPORT_SYMBOL_GPL -+0xbd040986 phy_driver_register vmlinux EXPORT_SYMBOL -+0x3b555ebf scsi_dma_unmap vmlinux EXPORT_SYMBOL -+0xb4232cab relay_reset vmlinux EXPORT_SYMBOL_GPL -+0x6971a684 nf_conntrack_register_notifier net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x0dcff8e4 inet_put_port vmlinux EXPORT_SYMBOL -+0xcee525f4 sock_no_connect vmlinux EXPORT_SYMBOL -+0x036f74a7 phy_print_status vmlinux EXPORT_SYMBOL -+0x070473ec pci_remove_bus vmlinux EXPORT_SYMBOL -+0xb3305d52 send_remote_softirq vmlinux EXPORT_SYMBOL -+0xa1f8fe75 wait_for_completion_killable_timeout vmlinux EXPORT_SYMBOL -+0x10ecc52c usb_amd_quirk_pll_enable vmlinux EXPORT_SYMBOL_GPL -+0x279ef3e3 skcipher_geniv_alloc vmlinux EXPORT_SYMBOL_GPL -+0x6e224a7a need_conntrack net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x4a358252 __bitmap_subset vmlinux EXPORT_SYMBOL -+0x1c1af916 set_normalized_timespec vmlinux EXPORT_SYMBOL -+0xbeccc586 eth_type_trans vmlinux EXPORT_SYMBOL -+0xbfdff814 of_get_address vmlinux EXPORT_SYMBOL -+0xaed8bc14 debugfs_create_blob vmlinux EXPORT_SYMBOL_GPL -+0x928f76ce mb_cache_entry_get vmlinux EXPORT_SYMBOL -+0x6655f24b vm_insert_mixed vmlinux EXPORT_SYMBOL -+0x7b08c0c5 send_sig vmlinux EXPORT_SYMBOL -+0xd8d36fcd tcp_shutdown vmlinux EXPORT_SYMBOL -+0x581f6a59 usb_stor_set_xfer_buf vmlinux EXPORT_SYMBOL_GPL -+0xab303c2a scsi_nonblockable_ioctl vmlinux EXPORT_SYMBOL -+0xbe77aebe down_write_trylock vmlinux EXPORT_SYMBOL -+0x730ff363 param_set_uint vmlinux EXPORT_SYMBOL -+0x776637d2 rpc_init_wait_queue vmlinux EXPORT_SYMBOL_GPL -+0xf389fe60 __hw_addr_init vmlinux EXPORT_SYMBOL -+0x199ed0cd net_disable_timestamp vmlinux EXPORT_SYMBOL -+0x96f5cd3e sdio_set_host_pm_flags vmlinux EXPORT_SYMBOL_GPL -+0xe251fc75 usb_stor_ctrl_transfer vmlinux EXPORT_SYMBOL_GPL -+0x4afe9a77 scsi_partsize vmlinux EXPORT_SYMBOL -+0x9ac8f3af of_find_device_by_node vmlinux EXPORT_SYMBOL -+0x4aaab2b1 groups_alloc vmlinux EXPORT_SYMBOL -+0xf338d4c3 netlink_unregister_notifier vmlinux EXPORT_SYMBOL -+0xc4c41664 simple_release_fs vmlinux EXPORT_SYMBOL -+0xdc9498dd down vmlinux EXPORT_SYMBOL -+0x5ab67931 do_IRQ vmlinux EXPORT_SYMBOL -+0x8e2ea861 blk_end_request vmlinux EXPORT_SYMBOL -+0xf3a0e01f skb_put vmlinux EXPORT_SYMBOL -+0xdc5da161 mtd_concat_create vmlinux EXPORT_SYMBOL -+0x22ef965d scsi_host_put vmlinux EXPORT_SYMBOL -+0x3895cd7a nfnl_unlock net/netfilter/nfnetlink EXPORT_SYMBOL_GPL -+0x07ae60b6 nf_nat_proto_in_range net/ipv4/netfilter/nf_nat EXPORT_SYMBOL_GPL -+0xe464582e generic_block_fiemap vmlinux EXPORT_SYMBOL -+0x735d8503 add_wait_queue vmlinux EXPORT_SYMBOL -+0xd276f795 param_ops_invbool vmlinux EXPORT_SYMBOL -+0x65dabd9c dev_add_pack vmlinux EXPORT_SYMBOL -+0xbde3c08a usb_hub_clear_tt_buffer vmlinux EXPORT_SYMBOL_GPL -+0x0a3131f6 strnchr vmlinux EXPORT_SYMBOL -+0x9f984513 strrchr vmlinux EXPORT_SYMBOL -+0xd20bf6ba dcookie_unregister vmlinux EXPORT_SYMBOL_GPL -+0x557e3153 balance_dirty_pages_ratelimited_nr vmlinux EXPORT_SYMBOL -+0x7afa89fc vsnprintf vmlinux EXPORT_SYMBOL -+0x44b911c3 rb_replace_node vmlinux EXPORT_SYMBOL -+0x6ff607b6 crypto_get_default_rng vmlinux EXPORT_SYMBOL_GPL -+0x668402aa crypto_put_default_rng vmlinux EXPORT_SYMBOL_GPL -+0x07c13af6 crypto_mod_put vmlinux EXPORT_SYMBOL_GPL -+0x94a69fd0 journal_clear_err vmlinux EXPORT_SYMBOL -+0x09531a7b mount_pseudo vmlinux EXPORT_SYMBOL -+0x0530dede _raw_write_trylock vmlinux EXPORT_SYMBOL -+0x4205ad24 cancel_work_sync vmlinux EXPORT_SYMBOL_GPL -+0x37382ea4 nf_ct_gre_keymap_flush net/netfilter/nf_conntrack_proto_gre EXPORT_SYMBOL -+0x99cdc86b sysctl_tcp_reordering vmlinux EXPORT_SYMBOL -+0xa3431157 input_set_keycode vmlinux EXPORT_SYMBOL -+0x6b44d1af alloc_pci_dev vmlinux EXPORT_SYMBOL -+0x9754ec10 radix_tree_preload vmlinux EXPORT_SYMBOL -+0x9d1341ef blkdev_ioctl vmlinux EXPORT_SYMBOL_GPL -+0xd11c0dc1 __kernel_param_unlock vmlinux EXPORT_SYMBOL -+0x88279f25 cpm_muram_alloc vmlinux EXPORT_SYMBOL -+0x56a10763 csum_tcpudp_magic vmlinux EXPORT_SYMBOL -+0x9fedb268 __i2c_board_lock vmlinux EXPORT_SYMBOL_GPL -+0x65dba254 tty_ldisc_flush vmlinux EXPORT_SYMBOL_GPL -+0x29028646 crypto_register_instance vmlinux EXPORT_SYMBOL_GPL -+0x2251978a crypto_alloc_tfm vmlinux EXPORT_SYMBOL_GPL -+0x760afcf0 bdi_destroy vmlinux EXPORT_SYMBOL -+0xe88cba4b skb_tstamp_tx vmlinux EXPORT_SYMBOL_GPL -+0x28830c73 tty_set_operations vmlinux EXPORT_SYMBOL -+0x616b825d dql_init vmlinux EXPORT_SYMBOL -+0x69e27c7a bitmap_copy_le vmlinux EXPORT_SYMBOL -+0x4dec6038 memscan vmlinux EXPORT_SYMBOL -+0x239b6d58 mark_buffer_dirty vmlinux EXPORT_SYMBOL -+0x150beb03 get_super vmlinux EXPORT_SYMBOL -+0x00801678 flush_scheduled_work vmlinux EXPORT_SYMBOL -+0xffb6efb2 write_bytes_to_xdr_buf vmlinux EXPORT_SYMBOL_GPL -+0xafdc3bb7 skb_copy_and_csum_bits vmlinux EXPORT_SYMBOL -+0xe03114f3 ll_rw_block vmlinux EXPORT_SYMBOL -+0xd59e518f block_write_begin vmlinux EXPORT_SYMBOL -+0xbe2e3b75 kstrtos8 vmlinux EXPORT_SYMBOL -+0x124f2056 crypto_get_attr_type vmlinux EXPORT_SYMBOL_GPL -+0x1cbc0b01 nfnetlink_send net/netfilter/nfnetlink EXPORT_SYMBOL_GPL -+0x12e280e3 svc_proc_unregister vmlinux EXPORT_SYMBOL_GPL -+0x26c90ea4 scsi_eh_get_sense vmlinux EXPORT_SYMBOL_GPL -+0x5d83dda1 device_create_bin_file vmlinux EXPORT_SYMBOL_GPL -+0xdef35215 pci_intx vmlinux EXPORT_SYMBOL_GPL -+0x83800bfa kref_init vmlinux EXPORT_SYMBOL -+0x2d5cc8db crypto_alloc_aead vmlinux EXPORT_SYMBOL_GPL -+0xba5ad651 crypto_spawn_tfm2 vmlinux EXPORT_SYMBOL_GPL -+0x50fad434 round_jiffies_up vmlinux EXPORT_SYMBOL_GPL -+0x46c1ef6e dev_set_mac_address vmlinux EXPORT_SYMBOL -+0x05c9593c sk_receive_skb vmlinux EXPORT_SYMBOL -+0xf5c05914 generic_segment_checks vmlinux EXPORT_SYMBOL -+0xd0f36f0d audit_log_format vmlinux EXPORT_SYMBOL -+0xec15f00a tcp_cookie_generator vmlinux EXPORT_SYMBOL -+0x6d2fc5a6 net_namespace_list vmlinux EXPORT_SYMBOL_GPL -+0x37287a4f sock_register vmlinux EXPORT_SYMBOL -+0xbcbaf605 loop_register_transfer vmlinux EXPORT_SYMBOL -+0x2c7e8020 pci_find_bus vmlinux EXPORT_SYMBOL -+0x1f58e71b nfnl_lock net/netfilter/nfnetlink EXPORT_SYMBOL_GPL -+0x16bd8d7a inet6_register_protosw vmlinux EXPORT_SYMBOL -+0x3f1c88ef netif_set_real_num_tx_queues vmlinux EXPORT_SYMBOL -+0xb0819781 netif_set_real_num_rx_queues vmlinux EXPORT_SYMBOL -+0x5ad98fe1 dev_set_group vmlinux EXPORT_SYMBOL -+0x8ac0ffc6 phy_register_fixup_for_uid vmlinux EXPORT_SYMBOL -+0xfdbc60ef register_mtd_blktrans vmlinux EXPORT_SYMBOL_GPL -+0xb4709322 scsi_dev_info_add_list vmlinux EXPORT_SYMBOL -+0xf50c9445 end_buffer_async_write vmlinux EXPORT_SYMBOL -+0x111fa7c9 qe_pin_set_dedicated vmlinux EXPORT_SYMBOL -+0x2f045815 ip_nat_decode_session vmlinux EXPORT_SYMBOL -+0xbb9cfeb4 sdio_get_host_pm_caps vmlinux EXPORT_SYMBOL_GPL -+0x75de8c53 vfs_writev vmlinux EXPORT_SYMBOL -+0xb258347c svc_rpcb_cleanup vmlinux EXPORT_SYMBOL_GPL -+0x9062c322 ring_buffer_consume vmlinux EXPORT_SYMBOL_GPL -+0x1c5b1f28 irq_free_descs vmlinux EXPORT_SYMBOL_GPL -+0x4fc9418d proc_dointvec vmlinux EXPORT_SYMBOL -+0xa2a5fd77 inet_ehash_secret vmlinux EXPORT_SYMBOL -+0x7f6680dd __inet_lookup_established vmlinux EXPORT_SYMBOL_GPL -+0x2ab95de3 netdev_alert vmlinux EXPORT_SYMBOL -+0x0a540769 rpc_print_iostats vmlinux EXPORT_SYMBOL_GPL -+0x4bb15c8c udp_lib_rehash vmlinux EXPORT_SYMBOL -+0xb8f4d294 udp_lib_unhash vmlinux EXPORT_SYMBOL -+0x1d9496fc of_pci_find_child_device vmlinux EXPORT_SYMBOL_GPL -+0x05495392 hid_debug vmlinux EXPORT_SYMBOL_GPL -+0x112dcb5f device_show_ulong vmlinux EXPORT_SYMBOL_GPL -+0x79df9c12 cpumask_next_and vmlinux EXPORT_SYMBOL -+0x3969cdfb nf_hook_slow vmlinux EXPORT_SYMBOL -+0xce5ac24f zlib_inflate_workspacesize vmlinux EXPORT_SYMBOL -+0x6103edc6 tcp_recvmsg vmlinux EXPORT_SYMBOL -+0xace5c0fc usb_bus_list vmlinux EXPORT_SYMBOL_GPL -+0x80f2bf56 xfrm_audit_state_notfound_simple vmlinux EXPORT_SYMBOL_GPL -+0xe8b63ace radix_tree_range_tag_if_tagged vmlinux EXPORT_SYMBOL -+0xc2882ea4 proc_dointvec_userhz_jiffies vmlinux EXPORT_SYMBOL -+0xd48f3111 console_start vmlinux EXPORT_SYMBOL -+0x21398e9d tcp_simple_retransmit vmlinux EXPORT_SYMBOL -+0xad58729e inet_csk_bind_conflict vmlinux EXPORT_SYMBOL_GPL -+0x8d93899a xt_register_match vmlinux EXPORT_SYMBOL -+0x68f40f80 of_find_node_with_property vmlinux EXPORT_SYMBOL -+0x17eb9b10 anon_inode_getfile vmlinux EXPORT_SYMBOL_GPL -+0x8ec1678f simple_dir_inode_operations vmlinux EXPORT_SYMBOL -+0x065f1d39 fsl_pq_mdio_bus_name vmlinux EXPORT_SYMBOL_GPL -+0x75a4001c dmam_pool_create vmlinux EXPORT_SYMBOL -+0x8fc5a78b genphy_suspend vmlinux EXPORT_SYMBOL -+0x0878c365 subsys_system_register vmlinux EXPORT_SYMBOL_GPL -+0x55c887e2 __find_get_block vmlinux EXPORT_SYMBOL -+0xcc276874 dcache_dir_open vmlinux EXPORT_SYMBOL -+0x3f4547a7 put_unused_fd vmlinux EXPORT_SYMBOL -+0xd2555f19 jiffies_64_to_clock_t vmlinux EXPORT_SYMBOL -+0x9d51befe inet6_lookup_listener vmlinux EXPORT_SYMBOL_GPL -+0xfbe27a1c rb_first vmlinux EXPORT_SYMBOL -+0x7c904ded unregister_module_notifier vmlinux EXPORT_SYMBOL -+0xddc16c88 flush_delayed_work vmlinux EXPORT_SYMBOL -+0xe5ab60b2 mmc_switch vmlinux EXPORT_SYMBOL_GPL -+0xfb65ffac scsi_cmd_print_sense_hdr vmlinux EXPORT_SYMBOL -+0x616e9785 zero_fill_bio vmlinux EXPORT_SYMBOL -+0xb628f715 files_lglock_local_lock vmlinux EXPORT_SYMBOL -+0x082c3213 pci_root_buses vmlinux EXPORT_SYMBOL -+0x72d4c23c fsl_get_sys_freq vmlinux EXPORT_SYMBOL -+0xfc4d7b87 tcp_syn_ack_timeout vmlinux EXPORT_SYMBOL -+0x0397f6b0 nf_log_unregister vmlinux EXPORT_SYMBOL -+0x72975f42 mmc_alloc_host vmlinux EXPORT_SYMBOL -+0x110020ff scsi_eh_ready_devs vmlinux EXPORT_SYMBOL_GPL -+0x18f4e85e generic_file_buffered_write vmlinux EXPORT_SYMBOL -+0xc1c2dd09 __hw_addr_flush vmlinux EXPORT_SYMBOL -+0x548a8689 of_property_read_string vmlinux EXPORT_SYMBOL_GPL -+0x05b82c15 thermal_cooling_device_register vmlinux EXPORT_SYMBOL -+0xb0e70ae3 input_open_device vmlinux EXPORT_SYMBOL -+0xfe990052 gpio_free vmlinux EXPORT_SYMBOL_GPL -+0xea054b22 nla_policy_len vmlinux EXPORT_SYMBOL -+0xd92afabe bitmap_clear vmlinux EXPORT_SYMBOL -+0xa6e1a05f fsync_bdev vmlinux EXPORT_SYMBOL -+0x710fed59 cache_unregister vmlinux EXPORT_SYMBOL_GPL -+0xa3bbc0ac xprt_set_retrans_timeout_def vmlinux EXPORT_SYMBOL_GPL -+0x0d4d2a18 ip6_dst_lookup vmlinux EXPORT_SYMBOL_GPL -+0xedd0ed46 i2c_new_device vmlinux EXPORT_SYMBOL_GPL -+0xdc39e99d device_for_each_child vmlinux EXPORT_SYMBOL_GPL -+0x40a9b349 vzalloc vmlinux EXPORT_SYMBOL -+0xbaaab8ae timespec_to_jiffies vmlinux EXPORT_SYMBOL -+0x51c251f8 unregister_key_type vmlinux EXPORT_SYMBOL -+0xa38e691a ioremap_bot vmlinux EXPORT_SYMBOL -+0x8530e62e rpc_shutdown_client vmlinux EXPORT_SYMBOL_GPL -+0x11089ac7 _ctype vmlinux EXPORT_SYMBOL -+0x649ddc16 blk_get_queue vmlinux EXPORT_SYMBOL -+0x5eb6f94d bd_set_size vmlinux EXPORT_SYMBOL -+0xa28aaf29 rh_create vmlinux EXPORT_SYMBOL_GPL -+0x0e74417a udp_proc_unregister vmlinux EXPORT_SYMBOL -+0x0deebb29 mtd_device_unregister vmlinux EXPORT_SYMBOL_GPL -+0x37f614b7 __kfifo_len_r vmlinux EXPORT_SYMBOL -+0x6f868b48 svc_xprt_names vmlinux EXPORT_SYMBOL_GPL -+0x92cff065 inet_sk_rebuild_header vmlinux EXPORT_SYMBOL -+0x0ea878cd skb_copy vmlinux EXPORT_SYMBOL -+0x829b3b9d input_inject_event vmlinux EXPORT_SYMBOL -+0x17ec8f5b pci_bus_read_config_dword vmlinux EXPORT_SYMBOL -+0x7593d385 div64_s64 vmlinux EXPORT_SYMBOL -+0x27864d57 memparse vmlinux EXPORT_SYMBOL -+0x3ead9a33 block_truncate_page vmlinux EXPORT_SYMBOL -+0x9d130651 generic_write_checks vmlinux EXPORT_SYMBOL -+0x1d2e87c6 do_gettimeofday vmlinux EXPORT_SYMBOL -+0xcf015f7b do_settimeofday vmlinux EXPORT_SYMBOL -+0xd172cb8d netdev_increment_features vmlinux EXPORT_SYMBOL -+0x264b5eda uart_match_port vmlinux EXPORT_SYMBOL -+0x9e04279a cap_file_mmap vmlinux EXPORT_SYMBOL_GPL -+0xc5a37aa8 flow_cache_lookup vmlinux EXPORT_SYMBOL -+0x55da6c07 alloc_tty_driver vmlinux EXPORT_SYMBOL -+0xfda98690 pcie_port_service_register vmlinux EXPORT_SYMBOL -+0x722852be pci_request_selected_regions vmlinux EXPORT_SYMBOL -+0x45666d9b __splice_from_pipe vmlinux EXPORT_SYMBOL -+0x9c3dd03a __nf_ct_ext_destroy net/netfilter/nf_conntrack EXPORT_SYMBOL -+0x3c65c88c unregister_net_sysctl_table vmlinux EXPORT_SYMBOL_GPL -+0x24e6d442 sdio_align_size vmlinux EXPORT_SYMBOL_GPL -+0x2114d287 tty_write_room vmlinux EXPORT_SYMBOL -+0x586527c3 sysfs_add_file_to_group vmlinux EXPORT_SYMBOL_GPL -+0x8436f8e3 param_ops_ushort vmlinux EXPORT_SYMBOL -+0x546027e3 dev_trans_start vmlinux EXPORT_SYMBOL -+0x94cbd061 dql_reset vmlinux EXPORT_SYMBOL -+0x6a33ea8b blk_register_region vmlinux EXPORT_SYMBOL -+0x93dd83ef bio_put vmlinux EXPORT_SYMBOL -+0x65f9016f task_tgid_nr_ns vmlinux EXPORT_SYMBOL -+0x1b767055 of_find_compatible_node vmlinux EXPORT_SYMBOL -+0xabc50916 input_alloc_absinfo vmlinux EXPORT_SYMBOL -+0x13fe75bb scsi_is_target_device vmlinux EXPORT_SYMBOL -+0x7da357d0 journal_force_commit vmlinux EXPORT_SYMBOL -+0xef91072e each_symbol_section vmlinux EXPORT_SYMBOL_GPL -+0xe697313d sk_dst_check vmlinux EXPORT_SYMBOL -+0x6a76f3ac blk_iopoll_enable vmlinux EXPORT_SYMBOL -+0xb906fe4a inode_needs_sync vmlinux EXPORT_SYMBOL -+0x7d38f2e3 grab_cache_page_nowait vmlinux EXPORT_SYMBOL -+0x8b70e8ea __wake_up_sync_key vmlinux EXPORT_SYMBOL_GPL -+0x042333d2 dev_getfirstbyhwtype vmlinux EXPORT_SYMBOL -+0x9ea7341b scsi_internal_device_block vmlinux EXPORT_SYMBOL_GPL -+0x25820c64 fs_overflowuid vmlinux EXPORT_SYMBOL -+0x4ebd6a47 wake_up_process vmlinux EXPORT_SYMBOL -+0x53ebab1b _outsl_ns vmlinux EXPORT_SYMBOL -+0x9e2ae014 __nf_ct_refresh_acct net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x556a7629 skb_dequeue_tail vmlinux EXPORT_SYMBOL -+0x311f6ed3 input_ff_erase vmlinux EXPORT_SYMBOL_GPL -+0x8472112c scsi_target_resume vmlinux EXPORT_SYMBOL -+0x4cc325f1 nfs_initiate_read vmlinux EXPORT_SYMBOL_GPL -+0x58392cb3 __get_user_pages vmlinux EXPORT_SYMBOL -+0x0c485af1 __module_address vmlinux EXPORT_SYMBOL_GPL -+0x5b076b1b inet_stream_ops vmlinux EXPORT_SYMBOL -+0xe791c07d qdisc_reset vmlinux EXPORT_SYMBOL -+0x63ecad53 register_netdevice_notifier vmlinux EXPORT_SYMBOL -+0xb573cf83 pci_get_device vmlinux EXPORT_SYMBOL -+0x5b237650 blk_complete_request vmlinux EXPORT_SYMBOL -+0x808ec1a3 crypto_alg_tested vmlinux EXPORT_SYMBOL_GPL -+0x583c0845 bio_unmap_user vmlinux EXPORT_SYMBOL -+0xe4a5911c udp_seq_open vmlinux EXPORT_SYMBOL -+0x133b4ee4 idr_get_next vmlinux EXPORT_SYMBOL -+0xc4571a56 fail_migrate_page vmlinux EXPORT_SYMBOL -+0xdf4c8767 ns_to_timeval vmlinux EXPORT_SYMBOL -+0xcacba0a5 nf_ct_expect_register_notifier net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x721b1851 skip_spaces vmlinux EXPORT_SYMBOL -+0x0c0c015e ring_buffer_swap_cpu vmlinux EXPORT_SYMBOL_GPL -+0xdc2adb35 add_taint vmlinux EXPORT_SYMBOL -+0x60a32ea9 pm_power_off vmlinux EXPORT_SYMBOL_GPL -+0x466c14a7 __delay vmlinux EXPORT_SYMBOL -+0x3e09fbde __neigh_for_each_release vmlinux EXPORT_SYMBOL -+0x1ee9814e irq_of_parse_and_map vmlinux EXPORT_SYMBOL_GPL -+0xe0e37b4c spi_busnum_to_master vmlinux EXPORT_SYMBOL_GPL -+0xb73e0c9c device_initialize vmlinux EXPORT_SYMBOL_GPL -+0x0d558de0 blk_queue_init_tags vmlinux EXPORT_SYMBOL -+0x690a7b30 user_destroy vmlinux EXPORT_SYMBOL_GPL -+0x4f69f21d bdget vmlinux EXPORT_SYMBOL -+0x1c326670 bdput vmlinux EXPORT_SYMBOL -+0x42cdd5c5 fsstack_copy_inode_size vmlinux EXPORT_SYMBOL_GPL -+0xd5248f66 nf_conntrack_untracked net/netfilter/nf_conntrack EXPORT_SYMBOL -+0x0e93bb22 usb_usual_ignore_device vmlinux EXPORT_SYMBOL_GPL -+0xed9f8e6d kstrtos16 vmlinux EXPORT_SYMBOL -+0xfb32b30f ring_buffer_read_prepare_sync vmlinux EXPORT_SYMBOL_GPL -+0xadcac4a3 vfsmount_lock_local_unlock_cpu vmlinux EXPORT_SYMBOL -+0xaef2c83c fs_kobj vmlinux EXPORT_SYMBOL_GPL -+0x956657df crypto_alloc_ablkcipher vmlinux EXPORT_SYMBOL_GPL -+0xfb3b51e1 bio_init vmlinux EXPORT_SYMBOL -+0x7278d328 all_vm_events vmlinux EXPORT_SYMBOL_GPL -+0xfe3c4307 gss_mech_put vmlinux EXPORT_SYMBOL_GPL -+0x2ca3edba rpc_max_payload vmlinux EXPORT_SYMBOL_GPL -+0x288092c9 inet6_hash_connect vmlinux EXPORT_SYMBOL_GPL -+0x6dbad0b5 gnet_stats_copy_rate_est vmlinux EXPORT_SYMBOL -+0x115b689d skb_partial_csum_set vmlinux EXPORT_SYMBOL_GPL -+0x0f2bd6b9 sdio_enable_func vmlinux EXPORT_SYMBOL_GPL -+0x4e505436 subsys_dev_iter_next vmlinux EXPORT_SYMBOL_GPL -+0x334a0cd1 create_empty_buffers vmlinux EXPORT_SYMBOL -+0x2f1cd7a8 init_special_inode vmlinux EXPORT_SYMBOL -+0x0e4a8c58 inet_frag_destroy vmlinux EXPORT_SYMBOL -+0x48dd2a9a skb_make_writable vmlinux EXPORT_SYMBOL -+0x2eeceb42 sk_chk_filter vmlinux EXPORT_SYMBOL -+0xf8a88294 cfi_qry_present vmlinux EXPORT_SYMBOL_GPL -+0x6bb87ddb pipe_to_file vmlinux EXPORT_SYMBOL -+0x114604eb __dec_zone_page_state vmlinux EXPORT_SYMBOL -+0x4b6cb580 __inc_zone_page_state vmlinux EXPORT_SYMBOL -+0xd9c6efac __mod_zone_page_state vmlinux EXPORT_SYMBOL -+0x0b55a26a flush_kthread_worker vmlinux EXPORT_SYMBOL_GPL -+0xa5cef8ad release_resource vmlinux EXPORT_SYMBOL -+0x9ef6b7ea powerpc_debugfs_root vmlinux EXPORT_SYMBOL -+0x5e906550 brioctl_set vmlinux EXPORT_SYMBOL -+0x6a496bc1 input_set_abs_params vmlinux EXPORT_SYMBOL -+0x378abc81 spi_bus_unlock vmlinux EXPORT_SYMBOL_GPL -+0xc60fe5e9 device_schedule_callback_owner vmlinux EXPORT_SYMBOL_GPL -+0x8b498a59 vm_insert_pfn vmlinux EXPORT_SYMBOL -+0xfcaa04a0 out_of_line_wait_on_bit_lock vmlinux EXPORT_SYMBOL -+0xf0bfe668 register_net_sysctl_table vmlinux EXPORT_SYMBOL_GPL -+0x2370b4df xfrm_state_alloc vmlinux EXPORT_SYMBOL -+0x85670f1d rtnl_is_locked vmlinux EXPORT_SYMBOL -+0xedd06a1b of_parse_phandles_with_args vmlinux EXPORT_SYMBOL -+0xecc376f4 fat_remove_entries vmlinux EXPORT_SYMBOL_GPL -+0x8a2b65f0 page_symlink vmlinux EXPORT_SYMBOL -+0xbc6f931b workqueue_congested vmlinux EXPORT_SYMBOL_GPL -+0x3d6d8275 __xfrm_route_forward vmlinux EXPORT_SYMBOL -+0xe2ae4be3 gen_replace_estimator vmlinux EXPORT_SYMBOL -+0xe2353e10 scsi_target_unblock vmlinux EXPORT_SYMBOL_GPL -+0x751b2247 param_get_bool vmlinux EXPORT_SYMBOL -+0xb0146c3a param_set_byte vmlinux EXPORT_SYMBOL -+0xf5e3f6f8 rpc_call_null vmlinux EXPORT_SYMBOL_GPL -+0x9fdecc31 unregister_netdevice_many vmlinux EXPORT_SYMBOL -+0x31c11871 rtc_device_unregister vmlinux EXPORT_SYMBOL_GPL -+0x5a21f0f4 blk_abort_queue vmlinux EXPORT_SYMBOL_GPL -+0x3e6e75c0 blk_queue_logical_block_size vmlinux EXPORT_SYMBOL -+0x63f608e4 init_srcu_struct vmlinux EXPORT_SYMBOL_GPL -+0x594b47d6 sunrpc_cache_lookup vmlinux EXPORT_SYMBOL_GPL -+0xdda28e49 arp_tbl vmlinux EXPORT_SYMBOL -+0xfea540c6 __skb_recv_datagram vmlinux EXPORT_SYMBOL -+0x376e7e39 phy_attach vmlinux EXPORT_SYMBOL -+0xfe7c4287 nr_cpu_ids vmlinux EXPORT_SYMBOL -+0xf5e7f053 rh_destroy vmlinux EXPORT_SYMBOL_GPL -+0x065994f1 xdr_encode_opaque_fixed vmlinux EXPORT_SYMBOL_GPL -+0xa516a4a3 tcp_splice_read vmlinux EXPORT_SYMBOL -+0x7c478694 xt_unregister_match vmlinux EXPORT_SYMBOL -+0x36e360e3 __hw_addr_add_multiple vmlinux EXPORT_SYMBOL -+0x0d0c109d of_irq_to_resource vmlinux EXPORT_SYMBOL_GPL -+0xcbc9557f unregister_sysrq_key vmlinux EXPORT_SYMBOL -+0x74ad740d simple_transaction_set vmlinux EXPORT_SYMBOL -+0xed7d1156 simple_transaction_get vmlinux EXPORT_SYMBOL -+0x5f629129 find_pid_ns vmlinux EXPORT_SYMBOL_GPL -+0x17913f3c __nf_conntrack_find net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x56e75d47 klist_node_attached vmlinux EXPORT_SYMBOL_GPL -+0x8b0896a8 lock_sock_nested vmlinux EXPORT_SYMBOL -+0xc0ad921a hid_add_device vmlinux EXPORT_SYMBOL_GPL -+0x1605388f sdio_disable_func vmlinux EXPORT_SYMBOL_GPL -+0x45582f48 scsi_free_command vmlinux EXPORT_SYMBOL -+0xd45c92cb platform_add_devices vmlinux EXPORT_SYMBOL_GPL -+0x92b57248 flush_work vmlinux EXPORT_SYMBOL_GPL -+0x9dd6edf6 usb_deregister vmlinux EXPORT_SYMBOL_GPL -+0x3b261e90 of_device_is_compatible vmlinux EXPORT_SYMBOL -+0x851187ae crypto_alloc_instance vmlinux EXPORT_SYMBOL_GPL -+0xe18b50f9 mpage_writepage vmlinux EXPORT_SYMBOL -+0x18ef997d set_security_override vmlinux EXPORT_SYMBOL -+0x6b2dc060 dump_stack vmlinux EXPORT_SYMBOL -+0x40797035 nfnetlink_subsys_unregister net/netfilter/nfnetlink EXPORT_SYMBOL_GPL -+0xfb9b2d0e raw_seq_start vmlinux EXPORT_SYMBOL_GPL -+0x17f28d7c dst_cow_metrics_generic vmlinux EXPORT_SYMBOL -+0xfa3657fe rtc_read_time vmlinux EXPORT_SYMBOL_GPL -+0x7eacf564 swiotlb_map_page vmlinux EXPORT_SYMBOL_GPL -+0xe8850089 mount_ns vmlinux EXPORT_SYMBOL -+0xf0c82f30 cpu_add_dev_attr vmlinux EXPORT_SYMBOL_GPL -+0x11886e11 kobject_del vmlinux EXPORT_SYMBOL -+0x1343402c crypto_unregister_shash vmlinux EXPORT_SYMBOL_GPL -+0xfbacc823 crypto_unregister_ahash vmlinux EXPORT_SYMBOL_GPL -+0x5eb8e514 usb_reset_endpoint vmlinux EXPORT_SYMBOL_GPL -+0xb6a68816 find_last_bit vmlinux EXPORT_SYMBOL -+0x712dc4d8 inode_dio_done vmlinux EXPORT_SYMBOL_GPL -+0x9a030dc8 poll_initwait vmlinux EXPORT_SYMBOL -+0x5e19264c unregister_console vmlinux EXPORT_SYMBOL -+0xff6dea25 smp_hw_index vmlinux EXPORT_SYMBOL -+0xbe85ec13 nf_ct_helper_ext_add net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x293d41a8 phy_disconnect vmlinux EXPORT_SYMBOL -+0xa8cb5076 aead_geniv_free vmlinux EXPORT_SYMBOL_GPL -+0xd8e484f0 register_chrdev_region vmlinux EXPORT_SYMBOL -+0xf52f4bc3 inet_csk_reqsk_queue_prune vmlinux EXPORT_SYMBOL_GPL -+0xed5f822a netdev_state_change vmlinux EXPORT_SYMBOL -+0x310917fe sort vmlinux EXPORT_SYMBOL -+0x3d19d9ca nfs4_reset_read vmlinux EXPORT_SYMBOL_GPL -+0x541bd60a irq_work_run vmlinux EXPORT_SYMBOL_GPL -+0x6c49c4f2 clockevents_notify vmlinux EXPORT_SYMBOL_GPL -+0x6c1b16e2 usb_sg_cancel vmlinux EXPORT_SYMBOL_GPL -+0xbe3f901e kern_path vmlinux EXPORT_SYMBOL -+0x33817a73 nf_register_queue_handler vmlinux EXPORT_SYMBOL -+0xea91aa6f netpoll_print_options vmlinux EXPORT_SYMBOL -+0x29b1c366 __sg_alloc_table vmlinux EXPORT_SYMBOL -+0x79f9a580 shrink_dcache_sb vmlinux EXPORT_SYMBOL -+0x3ec8886f param_ops_int vmlinux EXPORT_SYMBOL -+0x1b87a6f0 blkdev_issue_flush vmlinux EXPORT_SYMBOL -+0x499043d3 crypto_init_queue vmlinux EXPORT_SYMBOL_GPL -+0xb11b1747 default_backing_dev_info vmlinux EXPORT_SYMBOL_GPL -+0xbdbe7378 cookie_check_timestamp vmlinux EXPORT_SYMBOL -+0x59020915 fsnotify_put_mark vmlinux EXPORT_SYMBOL_GPL -+0x6b4435a7 generic_drop_inode vmlinux EXPORT_SYMBOL_GPL -+0xf57db0bd find_inode_number vmlinux EXPORT_SYMBOL -+0xf5cf326a param_ops_short vmlinux EXPORT_SYMBOL -+0x1f925c00 rpcb_getport_async vmlinux EXPORT_SYMBOL_GPL -+0x8c354480 ip_route_input_common vmlinux EXPORT_SYMBOL -+0xa6970398 __kfifo_to_user_r vmlinux EXPORT_SYMBOL -+0x1de33a9e softnet_data vmlinux EXPORT_SYMBOL -+0x00f42699 files_lglock_global_unlock vmlinux EXPORT_SYMBOL -+0x24e1307e flush_work_sync vmlinux EXPORT_SYMBOL_GPL -+0xfe5d4bb2 sys_tz vmlinux EXPORT_SYMBOL -+0x1ae6ffc8 __skb_tx_hash vmlinux EXPORT_SYMBOL -+0x241f0763 blk_init_queue vmlinux EXPORT_SYMBOL -+0xce67b38d unlock_page vmlinux EXPORT_SYMBOL -+0xcbf10c5b sdio_memcpy_fromio vmlinux EXPORT_SYMBOL_GPL -+0x5785384a flex_array_free_parts vmlinux EXPORT_SYMBOL -+0x0f668ba9 svc_auth_unregister vmlinux EXPORT_SYMBOL_GPL -+0x45456905 xfrm_unregister_type vmlinux EXPORT_SYMBOL -+0x4e781803 nf_ip_checksum vmlinux EXPORT_SYMBOL -+0xe1982309 pci_request_regions_exclusive vmlinux EXPORT_SYMBOL -+0x773a9c94 blk_iopoll_enabled vmlinux EXPORT_SYMBOL -+0xd4d24bb4 hrtimer_init_sleeper vmlinux EXPORT_SYMBOL_GPL -+0x5e1c7425 eth_rebuild_header vmlinux EXPORT_SYMBOL -+0x533031ec neigh_compat_output vmlinux EXPORT_SYMBOL -+0xc6f2dadd user_path_at vmlinux EXPORT_SYMBOL -+0xfd46510b module_put vmlinux EXPORT_SYMBOL -+0x2459bbcc console_set_on_cmdline vmlinux EXPORT_SYMBOL -+0xe9379468 usb_get_from_anchor vmlinux EXPORT_SYMBOL_GPL -+0x2d938d67 genphy_resume vmlinux EXPORT_SYMBOL -+0xee4db89d inode_get_bytes vmlinux EXPORT_SYMBOL -+0x5e3a8a9c __wake_up vmlinux EXPORT_SYMBOL -+0x9fd9cdb0 nf_conntrack_helper_unregister net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xa8a585c0 i2c_for_each_dev vmlinux EXPORT_SYMBOL_GPL -+0x599adf11 dev_driver_string vmlinux EXPORT_SYMBOL -+0x5e52b566 pcie_get_readrq vmlinux EXPORT_SYMBOL -+0xc7a1840e llist_add_batch vmlinux EXPORT_SYMBOL_GPL -+0x0010abad vfs_mkdir vmlinux EXPORT_SYMBOL -+0x79272d01 of_match_node vmlinux EXPORT_SYMBOL -+0x2edfd91a usb_driver_claim_interface vmlinux EXPORT_SYMBOL_GPL -+0x9cfd56c5 scsi_print_status vmlinux EXPORT_SYMBOL -+0x4bf98954 eventfd_ctx_fileget vmlinux EXPORT_SYMBOL_GPL -+0x01139ffc max_mapnr vmlinux EXPORT_SYMBOL -+0xc1ef47df rpc_pipe_generic_upcall vmlinux EXPORT_SYMBOL_GPL -+0x98a76b33 xprt_unregister_transport vmlinux EXPORT_SYMBOL_GPL -+0x93b9629e of_find_i2c_device_by_node vmlinux EXPORT_SYMBOL -+0x7cee66f5 eventfd_fget vmlinux EXPORT_SYMBOL_GPL -+0xc58850d7 dget_parent vmlinux EXPORT_SYMBOL -+0xb36388b7 hid_dump_input vmlinux EXPORT_SYMBOL_GPL -+0x8541878a usb_get_dev vmlinux EXPORT_SYMBOL_GPL -+0x6ecdaa65 mb_cache_create vmlinux EXPORT_SYMBOL -+0x769ec6bc iunique vmlinux EXPORT_SYMBOL -+0x01a4ea6d unregister_die_notifier vmlinux EXPORT_SYMBOL_GPL -+0x5614b010 xfrm_policy_walk_done vmlinux EXPORT_SYMBOL -+0xe0e2d273 inet_dgram_ops vmlinux EXPORT_SYMBOL -+0x8a20e1aa input_release_device vmlinux EXPORT_SYMBOL -+0x9c1c727f scsi_put_command vmlinux EXPORT_SYMBOL -+0xa2134525 blk_alloc_queue vmlinux EXPORT_SYMBOL -+0xdcadc348 mb_cache_destroy vmlinux EXPORT_SYMBOL -+0x0903c239 vid_from_reg drivers/hwmon/hwmon-vid EXPORT_SYMBOL -+0x89253799 get_gendisk vmlinux EXPORT_SYMBOL -+0x99bfbe39 get_unused_fd vmlinux EXPORT_SYMBOL -+0x7a50a315 files_lglock_global_unlock_online vmlinux EXPORT_SYMBOL -+0xbfad4db7 proc_doulongvec_minmax vmlinux EXPORT_SYMBOL -+0x2d36c57b rh_alloc vmlinux EXPORT_SYMBOL_GPL -+0xdd56dbe7 tcp_proc_unregister vmlinux EXPORT_SYMBOL -+0x851d3cba hwmon_device_register vmlinux EXPORT_SYMBOL_GPL -+0xbf4c8a06 sdev_evt_send_simple vmlinux EXPORT_SYMBOL_GPL -+0x6746ae74 pci_renumber_slot vmlinux EXPORT_SYMBOL_GPL -+0xef17cdaf simple_attr_open vmlinux EXPORT_SYMBOL_GPL -+0x9a49d937 __wake_up_locked_key vmlinux EXPORT_SYMBOL_GPL -+0x85c10896 rcu_batches_completed_bh vmlinux EXPORT_SYMBOL_GPL -+0x4578f528 __kfifo_to_user vmlinux EXPORT_SYMBOL -+0xcc7fa952 local_bh_enable_ip vmlinux EXPORT_SYMBOL -+0x27f7e224 xfrm4_rcv_encap vmlinux EXPORT_SYMBOL -+0xc7654bfd udp_poll vmlinux EXPORT_SYMBOL -+0x51ef33b8 kstrndup vmlinux EXPORT_SYMBOL -+0x0583b1a3 irq_set_chip vmlinux EXPORT_SYMBOL -+0x4f513a91 console_stop vmlinux EXPORT_SYMBOL -+0x419cc91e nf_conntrack_tuple_taken net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xd1a9044f inet6_getname vmlinux EXPORT_SYMBOL -+0x8a2cf4b8 xdr_encode_word vmlinux EXPORT_SYMBOL_GPL -+0xf6f682ab auth_domain_find vmlinux EXPORT_SYMBOL_GPL -+0xb95bbaa0 register_mtd_user vmlinux EXPORT_SYMBOL_GPL -+0xbe91f299 debugfs_create_file vmlinux EXPORT_SYMBOL_GPL -+0xc15de2b9 new_inode vmlinux EXPORT_SYMBOL -+0xe16ce22c rpc_restart_call_prepare vmlinux EXPORT_SYMBOL_GPL -+0xa8657869 of_get_phy_mode vmlinux EXPORT_SYMBOL_GPL -+0x28a2ed02 scsi_build_sense_buffer vmlinux EXPORT_SYMBOL -+0xd11042c0 tty_port_close vmlinux EXPORT_SYMBOL -+0x65dccf13 xz_dec_end vmlinux EXPORT_SYMBOL -+0xf9348cbc xz_dec_run vmlinux EXPORT_SYMBOL -+0x76e07962 idr_get_new vmlinux EXPORT_SYMBOL -+0x92a2c46d ida_get_new vmlinux EXPORT_SYMBOL -+0xe0b13336 argv_free vmlinux EXPORT_SYMBOL -+0x3240c65b files_lglock_global_lock_online vmlinux EXPORT_SYMBOL -+0xb7a383e5 genl_unregister_family vmlinux EXPORT_SYMBOL -+0xfe769456 unregister_netdevice_notifier vmlinux EXPORT_SYMBOL -+0x3e01160a tty_register_driver vmlinux EXPORT_SYMBOL -+0xefadeaf0 sdio_release_host vmlinux EXPORT_SYMBOL_GPL -+0xc27db015 driver_remove_file vmlinux EXPORT_SYMBOL_GPL -+0x87f98b5b swiotlb_free_coherent vmlinux EXPORT_SYMBOL -+0x39cb510c kset_unregister vmlinux EXPORT_SYMBOL -+0x1abb4c45 debugfs_create_u32 vmlinux EXPORT_SYMBOL_GPL -+0x98b9e82b register_net_sysctl_rotable vmlinux EXPORT_SYMBOL_GPL -+0x76495a16 llc_build_and_send_ui_pkt vmlinux EXPORT_SYMBOL -+0x87c85967 netdev_rx_handler_register vmlinux EXPORT_SYMBOL_GPL -+0xf0ad1471 inet_csk_reset_keepalive_timer vmlinux EXPORT_SYMBOL -+0xc27d3a6d user_read vmlinux EXPORT_SYMBOL_GPL -+0x53326531 mempool_alloc_pages vmlinux EXPORT_SYMBOL -+0x47939e0d __tasklet_hi_schedule vmlinux EXPORT_SYMBOL -+0x4e4fee60 read_bytes_from_xdr_buf vmlinux EXPORT_SYMBOL_GPL -+0x84d64671 arp_send vmlinux EXPORT_SYMBOL -+0x7b9dea01 xt_register_matches vmlinux EXPORT_SYMBOL -+0x3ed63055 zlib_inflateReset vmlinux EXPORT_SYMBOL -+0xb19760c3 bitmap_onto vmlinux EXPORT_SYMBOL -+0x26faebf0 cdev_del vmlinux EXPORT_SYMBOL -+0x281823c5 __kfifo_out_peek vmlinux EXPORT_SYMBOL -+0x341c41c5 tcp_seq_open vmlinux EXPORT_SYMBOL -+0x456144b4 pneigh_enqueue vmlinux EXPORT_SYMBOL -+0xcc3f71f3 dev_alloc_name vmlinux EXPORT_SYMBOL -+0x6086fae9 rwsem_wake vmlinux EXPORT_SYMBOL -+0x51ee205d fsnotify_init_mark vmlinux EXPORT_SYMBOL_GPL -+0x6c91b04d iov_iter_copy_from_user vmlinux EXPORT_SYMBOL -+0xd5dde498 generic_fh_to_dentry vmlinux EXPORT_SYMBOL_GPL -+0xa3225eb1 try_to_del_timer_sync vmlinux EXPORT_SYMBOL -+0x70469604 ipcomp_output net/xfrm/xfrm_ipcomp EXPORT_SYMBOL_GPL -+0x77d48f27 nf_ct_expect_related_report net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x4afdeb11 svc_addsock vmlinux EXPORT_SYMBOL_GPL -+0xe266f2c3 usb_stor_bulk_transfer_buf vmlinux EXPORT_SYMBOL_GPL -+0x824b05c2 tty_init_termios vmlinux EXPORT_SYMBOL_GPL -+0x20257b88 pci_enable_device_io vmlinux EXPORT_SYMBOL -+0x5d6bdce1 flex_array_alloc vmlinux EXPORT_SYMBOL -+0x61471532 blk_queue_bounce vmlinux EXPORT_SYMBOL -+0x97b13dad __clocksource_register_scale vmlinux EXPORT_SYMBOL_GPL -+0x3145216f pci_dev_present vmlinux EXPORT_SYMBOL -+0x4ff7c43d pci_dev_get vmlinux EXPORT_SYMBOL -+0xe23d3f77 pci_dev_put vmlinux EXPORT_SYMBOL -+0x45d0d7e1 scsi_cmd_blk_ioctl vmlinux EXPORT_SYMBOL -+0x51f53371 crypto_alloc_instance2 vmlinux EXPORT_SYMBOL_GPL -+0x62916e11 read_dev_sector vmlinux EXPORT_SYMBOL -+0x31389d75 usb_ifnum_to_if vmlinux EXPORT_SYMBOL_GPL -+0xd34d1db1 debugfs_create_x16 vmlinux EXPORT_SYMBOL_GPL -+0x14ae9650 journal_create vmlinux EXPORT_SYMBOL -+0x8f6ab23e fsnotify_put_group vmlinux EXPORT_SYMBOL_GPL -+0xd81de62c ring_buffer_record_enable vmlinux EXPORT_SYMBOL_GPL -+0x7400f11e inet6_destroy_sock vmlinux EXPORT_SYMBOL_GPL -+0xc15f809f mb_cache_entry_release vmlinux EXPORT_SYMBOL -+0x5c37f319 _raw_spin_unlock_irqrestore vmlinux EXPORT_SYMBOL -+0x061651be strcat vmlinux EXPORT_SYMBOL -+0xec7e08c7 crypto_register_shash vmlinux EXPORT_SYMBOL_GPL -+0x37c68932 inet6_unregister_protosw vmlinux EXPORT_SYMBOL -+0xa869fd87 nf_register_hooks vmlinux EXPORT_SYMBOL -+0x218ce3f7 pfifo_qdisc_ops vmlinux EXPORT_SYMBOL -+0xf202c5cb radix_tree_insert vmlinux EXPORT_SYMBOL -+0xc59cbc6c vfs_listxattr vmlinux EXPORT_SYMBOL_GPL -+0x1f01c966 find_get_pages_contig vmlinux EXPORT_SYMBOL -+0x388f9128 xfrm_state_walk_done vmlinux EXPORT_SYMBOL -+0xf09c4ca9 qdisc_create_dflt vmlinux EXPORT_SYMBOL -+0x3dbda9ad uart_add_one_port vmlinux EXPORT_SYMBOL -+0xee449310 key_put vmlinux EXPORT_SYMBOL -+0x354798cd bmap vmlinux EXPORT_SYMBOL -+0xe2fae716 kmemdup vmlinux EXPORT_SYMBOL -+0x3f629ad2 __blocking_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL -+0xc6314004 _copy_from_pages vmlinux EXPORT_SYMBOL_GPL -+0xcf901697 __strnlen_user vmlinux EXPORT_SYMBOL -+0x50ff1361 nf_conntrack_alloc net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x1445f5e0 tcp_register_congestion_control vmlinux EXPORT_SYMBOL_GPL -+0xbe130622 tcp_gro_complete vmlinux EXPORT_SYMBOL -+0x4d974b9c register_sysrq_key vmlinux EXPORT_SYMBOL -+0x77747da3 timerqueue_add vmlinux EXPORT_SYMBOL_GPL -+0x481b8361 sync_filesystem vmlinux EXPORT_SYMBOL_GPL -+0x15c3f98b tcp_connect vmlinux EXPORT_SYMBOL -+0xdce0a469 neigh_table_clear vmlinux EXPORT_SYMBOL -+0xb185dff3 of_phy_find_device vmlinux EXPORT_SYMBOL -+0x89f238f8 thermal_zone_bind_cooling_device vmlinux EXPORT_SYMBOL -+0x7c3b0956 do_munmap vmlinux EXPORT_SYMBOL -+0xd05dc2a3 xfrm_aalg_get_byname vmlinux EXPORT_SYMBOL_GPL -+0x2ebf2b40 xfrm_state_flush vmlinux EXPORT_SYMBOL -+0x5fd6befa mmc_align_data_size vmlinux EXPORT_SYMBOL -+0xd2fd47b5 pci_fixup_device vmlinux EXPORT_SYMBOL -+0xd6e34b40 fat_flush_inodes vmlinux EXPORT_SYMBOL_GPL -+0xbdf53fa0 xfrm_find_acq_byseq vmlinux EXPORT_SYMBOL -+0xee328371 xfrm_policy_unregister_afinfo vmlinux EXPORT_SYMBOL -+0x06aee4ce __rtnl_af_register vmlinux EXPORT_SYMBOL_GPL -+0x09c55cec schedule_timeout_interruptible vmlinux EXPORT_SYMBOL -+0x1ace138d bitmap_allocate_region vmlinux EXPORT_SYMBOL -+0x250113b4 memory_read_from_buffer vmlinux EXPORT_SYMBOL -+0xbb5d343d xfrm_get_acqseq vmlinux EXPORT_SYMBOL -+0x33deca5d __scsi_iterate_devices vmlinux EXPORT_SYMBOL -+0xa94aefc1 svc_reserve vmlinux EXPORT_SYMBOL_GPL -+0x6709e159 spi_register_driver vmlinux EXPORT_SYMBOL_GPL -+0xb03b00cd platform_bus vmlinux EXPORT_SYMBOL_GPL -+0xe92bef79 blk_queue_bounce_limit vmlinux EXPORT_SYMBOL -+0x7c543650 netpoll_setup vmlinux EXPORT_SYMBOL -+0xc6ef7368 skb_abort_seq_read vmlinux EXPORT_SYMBOL -+0x2b0ba2b0 scsi_sense_desc_find vmlinux EXPORT_SYMBOL -+0xe197c70b journal_destroy vmlinux EXPORT_SYMBOL -+0xef33727a journal_restart vmlinux EXPORT_SYMBOL -+0x5857b225 ioread16_rep vmlinux EXPORT_SYMBOL -+0x251c3936 inet6_ioctl vmlinux EXPORT_SYMBOL -+0x91fbfe0b tcp_getsockopt vmlinux EXPORT_SYMBOL -+0x1a4fb9e4 tcp_setsockopt vmlinux EXPORT_SYMBOL -+0x6d346876 rtnl_unicast vmlinux EXPORT_SYMBOL -+0x03564dce alloc_disk_node vmlinux EXPORT_SYMBOL -+0x8949858b schedule_work vmlinux EXPORT_SYMBOL -+0x503b8f3e dequeue_signal vmlinux EXPORT_SYMBOL_GPL -+0x91279f07 __rtnl_af_unregister vmlinux EXPORT_SYMBOL_GPL -+0xc8d078df skb_gro_reset_offset vmlinux EXPORT_SYMBOL -+0xb93672bb sysdev_driver_unregister vmlinux EXPORT_SYMBOL_GPL -+0xc553e282 crypto_ablkcipher_type vmlinux EXPORT_SYMBOL_GPL -+0x405b9539 ip6t_register_table net/ipv6/netfilter/ip6_tables EXPORT_SYMBOL -+0x5228f707 crypto_tfm_in_queue vmlinux EXPORT_SYMBOL_GPL -+0x8133f7e5 fget_raw vmlinux EXPORT_SYMBOL -+0x30301151 atomic_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL -+0xcb3c7b08 spi_add_device vmlinux EXPORT_SYMBOL_GPL -+0xfc02b7ad sysctl_tcp_wmem vmlinux EXPORT_SYMBOL -+0xb075d9fd nf_unregister_hook vmlinux EXPORT_SYMBOL -+0x9c723b65 napi_frags_skb vmlinux EXPORT_SYMBOL -+0xe5f91be5 dev_change_net_namespace vmlinux EXPORT_SYMBOL_GPL -+0xd0243795 unregister_mtd_user vmlinux EXPORT_SYMBOL_GPL -+0xc63a5ea9 blk_queue_flush_queueable vmlinux EXPORT_SYMBOL_GPL -+0xa6c79ad9 blk_queue_rq_timeout vmlinux EXPORT_SYMBOL_GPL -+0x04f27610 xdr_init_decode_pages vmlinux EXPORT_SYMBOL_GPL -+0x39a0825d tcp_twsk_destructor vmlinux EXPORT_SYMBOL_GPL -+0xc363ac9f scm_detach_fds vmlinux EXPORT_SYMBOL -+0x1bab249b rtc_ktime_to_tm vmlinux EXPORT_SYMBOL_GPL -+0x7d7fd860 usb_stor_pre_reset vmlinux EXPORT_SYMBOL_GPL -+0x50c8b1e3 put_pid vmlinux EXPORT_SYMBOL_GPL -+0xa77ad493 driver_find_device vmlinux EXPORT_SYMBOL_GPL -+0x58918a30 posix_clock_register vmlinux EXPORT_SYMBOL_GPL -+0xcc4bd58a __par_io_config_pin vmlinux EXPORT_SYMBOL -+0xc35e28f7 llc_sap_list_lock vmlinux EXPORT_SYMBOL -+0xa03ef198 blk_get_request vmlinux EXPORT_SYMBOL -+0x6a3e01d7 pci_read_irq_line vmlinux EXPORT_SYMBOL -+0x6e7474fc xfrm_ealg_get_byid vmlinux EXPORT_SYMBOL_GPL -+0x71dc9998 crypto_il_tab vmlinux EXPORT_SYMBOL_GPL -+0x0cc1e40f crypto_it_tab vmlinux EXPORT_SYMBOL_GPL -+0x3dc916b6 crypto_fl_tab vmlinux EXPORT_SYMBOL_GPL -+0x40d46b21 crypto_ft_tab vmlinux EXPORT_SYMBOL_GPL -+0x4678aa19 down_timeout vmlinux EXPORT_SYMBOL -+0xd2d0e6b4 nfnetlink_has_listeners net/netfilter/nfnetlink EXPORT_SYMBOL_GPL -+0x3bd1b1f6 msecs_to_jiffies vmlinux EXPORT_SYMBOL -+0xce06503d misc_deregister vmlinux EXPORT_SYMBOL -+0xd03a6957 blkdev_fsync vmlinux EXPORT_SYMBOL -+0x5f945856 lookup_one_len vmlinux EXPORT_SYMBOL -+0x7e50cea1 relay_buf_full vmlinux EXPORT_SYMBOL_GPL -+0x6437bd2e inet6_bind vmlinux EXPORT_SYMBOL -+0x3e45e9ff register_inetaddr_notifier vmlinux EXPORT_SYMBOL -+0xa1f0bf08 atomic_dec_and_mutex_lock vmlinux EXPORT_SYMBOL -+0x0de06988 cpu_first_thread_of_core vmlinux EXPORT_SYMBOL_GPL -+0xc5338f4a devres_add vmlinux EXPORT_SYMBOL_GPL -+0xcacda582 devres_get vmlinux EXPORT_SYMBOL_GPL -+0x43e83ea6 journal_wipe vmlinux EXPORT_SYMBOL -+0x8fc5394e pci_set_mwi vmlinux EXPORT_SYMBOL -+0xdce39544 sync_inodes_sb vmlinux EXPORT_SYMBOL -+0x7485e15e unregister_chrdev_region vmlinux EXPORT_SYMBOL -+0x7e25ca93 generic_writepages vmlinux EXPORT_SYMBOL -+0x9d13ddee register_8022_client vmlinux EXPORT_SYMBOL -+0x3847c175 gpiochip_is_requested vmlinux EXPORT_SYMBOL_GPL -+0xf1cf3036 blk_set_default_limits vmlinux EXPORT_SYMBOL -+0x861bbc41 blk_init_allocated_queue vmlinux EXPORT_SYMBOL -+0xe7c5e070 rtnl_register vmlinux EXPORT_SYMBOL_GPL -+0x58f81e73 lookup_bdev vmlinux EXPORT_SYMBOL -+0x0ef20db1 kernstart_addr vmlinux EXPORT_SYMBOL -+0xe484e35f ioread32 vmlinux EXPORT_SYMBOL -+0xdc732024 irq_stat vmlinux EXPORT_SYMBOL -+0x88632b55 raw_seq_stop vmlinux EXPORT_SYMBOL_GPL -+0x1087ecc8 gnet_stats_copy_basic vmlinux EXPORT_SYMBOL -+0xfe35aa4a percpu_counter_destroy vmlinux EXPORT_SYMBOL -+0xa974f717 create_mnt_ns vmlinux EXPORT_SYMBOL -+0xaf8e5276 vm_map_ram vmlinux EXPORT_SYMBOL -+0x7b82dc37 filemap_fdatawrite_range vmlinux EXPORT_SYMBOL -+0xa6cf1ffb inet_sendmsg vmlinux EXPORT_SYMBOL -+0xa60ddb99 ip_cmsg_recv vmlinux EXPORT_SYMBOL -+0xb77bbb6e hidinput_report_event vmlinux EXPORT_SYMBOL_GPL -+0x397ef9ad crypto_alg_sem vmlinux EXPORT_SYMBOL_GPL -+0x3e2af9cd bio_sector_offset vmlinux EXPORT_SYMBOL -+0x2bc61da1 program_check_exception vmlinux EXPORT_SYMBOL -+0xa4beec26 rpc_call_async vmlinux EXPORT_SYMBOL_GPL -+0xed312eb2 pci_unblock_user_cfg_access vmlinux EXPORT_SYMBOL_GPL -+0x79ac1dd3 cpu_sibling_map vmlinux EXPORT_SYMBOL -+0x760b437a unregister_inetaddr_notifier vmlinux EXPORT_SYMBOL -+0x6f707520 unregister_exec_domain vmlinux EXPORT_SYMBOL -+0x262e837a nobh_write_begin vmlinux EXPORT_SYMBOL -+0xd2cd5568 interruptible_sleep_on_timeout vmlinux EXPORT_SYMBOL -+0xbcdd82e7 netlink_ack vmlinux EXPORT_SYMBOL -+0x4b24bd8a sock_no_bind vmlinux EXPORT_SYMBOL -+0x29080e5d sock_get_timestamp vmlinux EXPORT_SYMBOL -+0x4211c3c1 zlib_inflateInit2 vmlinux EXPORT_SYMBOL -+0x8fc7f839 param_set_charp vmlinux EXPORT_SYMBOL -+0xb60b5707 of_i8042_aux_irq vmlinux EXPORT_SYMBOL_GPL -+0x9dbbba05 bio_free vmlinux EXPORT_SYMBOL -+0xef1c781c vid_which_vrm drivers/hwmon/hwmon-vid EXPORT_SYMBOL -+0x6bdcfd99 qdisc_class_hash_remove vmlinux EXPORT_SYMBOL -+0x5e59780b dmam_alloc_noncoherent vmlinux EXPORT_SYMBOL -+0x495b01eb transport_destroy_device vmlinux EXPORT_SYMBOL_GPL -+0x37179733 tty_unregister_device vmlinux EXPORT_SYMBOL -+0xbf8ba54a vprintk vmlinux EXPORT_SYMBOL -+0x2e2ce9e0 sysctl_tcp_syncookies vmlinux EXPORT_SYMBOL -+0xcb40eb53 tcp_poll vmlinux EXPORT_SYMBOL -+0x2482e688 vsprintf vmlinux EXPORT_SYMBOL -+0x3d055d0f generic_splice_sendpage vmlinux EXPORT_SYMBOL -+0xdda593ad attribute_container_find_class_device vmlinux EXPORT_SYMBOL_GPL -+0x0b92397e register_key_type vmlinux EXPORT_SYMBOL -+0xeaea2b74 grab_cache_page_write_begin vmlinux EXPORT_SYMBOL -+0xc2f8a90a rt_mutex_lock_interruptible vmlinux EXPORT_SYMBOL_GPL -+0x598ee3d1 cpu_add_dev_attr_group vmlinux EXPORT_SYMBOL_GPL -+0x10e1bae1 __mtd_next_device vmlinux EXPORT_SYMBOL_GPL -+0xc62f6317 class_create_file vmlinux EXPORT_SYMBOL_GPL -+0x0cae232b utf16s_to_utf8s vmlinux EXPORT_SYMBOL -+0x2f15682e __put_task_struct vmlinux EXPORT_SYMBOL_GPL -+0xcd86c87f __cond_resched_lock vmlinux EXPORT_SYMBOL -+0x1a6a10dd rpc_get_mount vmlinux EXPORT_SYMBOL_GPL -+0x854bdca7 unregister_pernet_subsys vmlinux EXPORT_SYMBOL_GPL -+0x13bbe2f0 wait_on_sync_kiocb vmlinux EXPORT_SYMBOL -+0x7c39cb83 simple_write_begin vmlinux EXPORT_SYMBOL -+0x219087eb bdi_set_max_ratio vmlinux EXPORT_SYMBOL -+0x53bc4229 redirty_page_for_writepage vmlinux EXPORT_SYMBOL -+0x8ffe7e89 nf_conntrack_htable_size net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x44427913 netdev_emerg vmlinux EXPORT_SYMBOL -+0x610b8968 sk_stream_kill_queues vmlinux EXPORT_SYMBOL -+0xe151f34a dev_set_name vmlinux EXPORT_SYMBOL_GPL -+0xeb37101c audit_log_end vmlinux EXPORT_SYMBOL -+0x6d40a921 need_ipv4_conntrack net/ipv4/netfilter/nf_conntrack_ipv4 EXPORT_SYMBOL_GPL -+0xf8bb5353 __sk_dst_check vmlinux EXPORT_SYMBOL -+0x65dbe5b6 usb_queue_reset_device vmlinux EXPORT_SYMBOL_GPL -+0xd7592f72 cfi_varsize_frob vmlinux EXPORT_SYMBOL -+0xbfff4b41 elv_register_queue vmlinux EXPORT_SYMBOL -+0x716265c7 debugfs_initialized vmlinux EXPORT_SYMBOL_GPL -+0x73564277 __timecompare_update vmlinux EXPORT_SYMBOL_GPL -+0x003ed69a __kfifo_dma_in_prepare vmlinux EXPORT_SYMBOL -+0x6db428e3 cpu_core_map vmlinux EXPORT_SYMBOL -+0x9bf6538b usb_interrupt_msg vmlinux EXPORT_SYMBOL_GPL -+0xe30d26f6 bus_unregister vmlinux EXPORT_SYMBOL_GPL -+0x4c759827 byte_rev_table vmlinux EXPORT_SYMBOL_GPL -+0x964d2406 __elv_add_request vmlinux EXPORT_SYMBOL -+0x37305e47 skcipher_geniv_init vmlinux EXPORT_SYMBOL_GPL -+0x5e3c72b7 set_bh_page vmlinux EXPORT_SYMBOL -+0x01a5485d crypto_destroy_tfm vmlinux EXPORT_SYMBOL_GPL -+0x73331311 filemap_fault vmlinux EXPORT_SYMBOL -+0xe914e41e strcpy vmlinux EXPORT_SYMBOL -+0x1bc3edc2 usb_stor_sense_invalidCDB vmlinux EXPORT_SYMBOL_GPL -+0xa1076c97 tty_pair_get_tty vmlinux EXPORT_SYMBOL -+0xa7d098e3 tty_pair_get_pty vmlinux EXPORT_SYMBOL -+0xa0ada1ea key_payload_reserve vmlinux EXPORT_SYMBOL -+0x9da8160b blocking_notifier_chain_register vmlinux EXPORT_SYMBOL_GPL -+0x462da1bf nf_ct_insert_dying_list net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x2e4f42a4 skb_unlink vmlinux EXPORT_SYMBOL -+0x4a9e6b51 crypto_register_template vmlinux EXPORT_SYMBOL_GPL -+0xaab9f7e7 node_states vmlinux EXPORT_SYMBOL -+0x6a5fb566 rcu_sched_force_quiescent_state vmlinux EXPORT_SYMBOL_GPL -+0x6cc37c70 of_property_read_u32_array vmlinux EXPORT_SYMBOL_GPL -+0xbf1cc04b tty_termios_encode_baud_rate vmlinux EXPORT_SYMBOL_GPL -+0x0199224f inet_csk_delete_keepalive_timer vmlinux EXPORT_SYMBOL -+0x47776c55 of_parse_phandle vmlinux EXPORT_SYMBOL -+0x10daa86c usb_hcd_pci_shutdown vmlinux EXPORT_SYMBOL_GPL -+0x6b25bb62 pci_bus_set_ops vmlinux EXPORT_SYMBOL -+0x24518ffa xfrm_state_register_afinfo vmlinux EXPORT_SYMBOL -+0xd2e16256 usb_register_device_driver vmlinux EXPORT_SYMBOL_GPL -+0x8df7d3c5 subsys_interface_unregister vmlinux EXPORT_SYMBOL_GPL -+0x9ed6b52d kmem_cache_size vmlinux EXPORT_SYMBOL -+0x8be716ab inet_ioctl vmlinux EXPORT_SYMBOL -+0x8a1f2ce8 of_device_register vmlinux EXPORT_SYMBOL -+0x0c8c9e99 scsi_show_extd_sense vmlinux EXPORT_SYMBOL -+0x503084b0 __pci_reset_function vmlinux EXPORT_SYMBOL_GPL -+0x5c4260ae kobject_get_path vmlinux EXPORT_SYMBOL_GPL -+0xc55c2a9d inode_sb_list_lock vmlinux EXPORT_SYMBOL_GPL -+0xd8ce7e67 clocksource_register vmlinux EXPORT_SYMBOL -+0x66dc52b5 xt_register_target vmlinux EXPORT_SYMBOL -+0x0a882a67 ping_prot vmlinux EXPORT_SYMBOL -+0x814e7730 nf_ct_destroy vmlinux EXPORT_SYMBOL -+0xbceeac4f nf_unregister_hooks vmlinux EXPORT_SYMBOL -+0x1db99742 device_create_vargs vmlinux EXPORT_SYMBOL_GPL -+0x3668dd26 tty_port_hangup vmlinux EXPORT_SYMBOL -+0x8810ad5e crypto_xor vmlinux EXPORT_SYMBOL_GPL -+0x45bf1ff3 crypto_inc vmlinux EXPORT_SYMBOL_GPL -+0x8f784e32 cpu_bit_bitmap vmlinux EXPORT_SYMBOL_GPL -+0x35448c65 rpc_free_iostats vmlinux EXPORT_SYMBOL_GPL -+0xede6b327 rpc_destroy_wait_queue vmlinux EXPORT_SYMBOL_GPL -+0x6eea229d svcauth_unix_purge vmlinux EXPORT_SYMBOL_GPL -+0xb286adee usb_hcd_poll_rh_status vmlinux EXPORT_SYMBOL_GPL -+0xfa4b3895 device_find_child vmlinux EXPORT_SYMBOL_GPL -+0xe5404b68 fat_getattr vmlinux EXPORT_SYMBOL_GPL -+0xda5c059a fat_setattr vmlinux EXPORT_SYMBOL_GPL -+0x7a43615e generic_read_dir vmlinux EXPORT_SYMBOL -+0x88afffc0 dentry_unhash vmlinux EXPORT_SYMBOL -+0xe007de41 kallsyms_lookup_name vmlinux EXPORT_SYMBOL_GPL -+0xe99d91ed validate_sp vmlinux EXPORT_SYMBOL -+0xf0933596 xprt_lookup_rqst vmlinux EXPORT_SYMBOL_GPL -+0xfade055f do_splice_to vmlinux EXPORT_SYMBOL_GPL -+0xda28eb83 writeback_inodes_sb_if_idle vmlinux EXPORT_SYMBOL -+0xdf86ee64 truncate_pagecache vmlinux EXPORT_SYMBOL -+0x26b71fb4 ring_buffer_time_stamp vmlinux EXPORT_SYMBOL_GPL -+0x5fcdec5d xfrm_ealg_get_byidx vmlinux EXPORT_SYMBOL_GPL -+0xdf7531cb sock_no_shutdown vmlinux EXPORT_SYMBOL -+0x2764e8b7 of_device_unregister vmlinux EXPORT_SYMBOL -+0xf5f63ca5 __generic_block_fiemap vmlinux EXPORT_SYMBOL -+0xb1acbcce rcu_barrier_sched vmlinux EXPORT_SYMBOL_GPL -+0xdc2519e0 param_set_ulong vmlinux EXPORT_SYMBOL -+0xee2d0fc7 _local_bh_enable vmlinux EXPORT_SYMBOL -+0x36b0e732 try_wait_for_completion vmlinux EXPORT_SYMBOL -+0x80dfc988 nf_ct_expect_alloc net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0xc4bf0a92 sysfs_unmerge_group vmlinux EXPORT_SYMBOL_GPL -+0xcbf0b653 cpu_active_mask vmlinux EXPORT_SYMBOL -+0x4498d5aa bus_find_device_by_name vmlinux EXPORT_SYMBOL_GPL -+0x29b96a8a inet_peer_xrlim_allow vmlinux EXPORT_SYMBOL -+0x2a23b66d nf_ct_attach vmlinux EXPORT_SYMBOL -+0xe5ed5467 xfrm_policy_walk_init vmlinux EXPORT_SYMBOL -+0xb0f3f389 driver_attach vmlinux EXPORT_SYMBOL_GPL -+0x0dbd5a25 textsearch_register vmlinux EXPORT_SYMBOL -+0x74baf17a tracing_is_on vmlinux EXPORT_SYMBOL_GPL -+0x381a798a setup_max_cpus vmlinux EXPORT_SYMBOL -+0x5bfbe895 commit_creds vmlinux EXPORT_SYMBOL -+0xd772ed24 __nf_ct_expect_find net/netfilter/nf_conntrack EXPORT_SYMBOL_GPL -+0x5db93a7c platform_device_register vmlinux EXPORT_SYMBOL_GPL -+0x5934392b fb_register_client vmlinux EXPORT_SYMBOL -+0xad0413d4 match_hex vmlinux EXPORT_SYMBOL -+0x0ffce14a __inet_lookup_listener vmlinux EXPORT_SYMBOL_GPL -+0x79eb7536 nf_unregister_sockopt vmlinux EXPORT_SYMBOL -+0x63f2715f __skb_get_rxhash vmlinux EXPORT_SYMBOL -+0x6029f865 skb_realloc_headroom vmlinux EXPORT_SYMBOL -+0x183abba7 platform_device_unregister vmlinux EXPORT_SYMBOL_GPL -+0x4373b84f serial8250_set_isa_configurator vmlinux EXPORT_SYMBOL -+0x9e38fbad generic_pipe_buf_map vmlinux EXPORT_SYMBOL -+0xba1338f3 generic_pipe_buf_get vmlinux EXPORT_SYMBOL -+0xb4b61245 ipv6_find_hdr net/ipv6/netfilter/ip6_tables EXPORT_SYMBOL -+0x2a14e5c1 uhci_reset_hc vmlinux EXPORT_SYMBOL_GPL -+0xfd1f0623 tty_port_close_end vmlinux EXPORT_SYMBOL -+0x77df0847 __set_personality vmlinux EXPORT_SYMBOL -+0x0e3bcc66 blkcipher_walk_done vmlinux EXPORT_SYMBOL_GPL -+0x731705d7 page_readlink vmlinux EXPORT_SYMBOL -+0xaa181411 account_page_writeback vmlinux EXPORT_SYMBOL -+0x6976522d nf_unregister_afinfo vmlinux EXPORT_SYMBOL_GPL -+0xf5eb86ea blk_verify_command vmlinux EXPORT_SYMBOL -+0xc499ae1e kstrdup vmlinux EXPORT_SYMBOL -+0x0e8f30f6 _raw_write_lock_irq vmlinux EXPORT_SYMBOL -+0x89da4432 of_iomap vmlinux EXPORT_SYMBOL -+0x81a07f4e _atomic_dec_and_lock vmlinux EXPORT_SYMBOL -+0xea7987f1 key_update vmlinux EXPORT_SYMBOL -+0xe18ba8e7 xfrm_register_km vmlinux EXPORT_SYMBOL -+0x31a77643 ip_mc_dec_group vmlinux EXPORT_SYMBOL -+0x733c3b54 kasprintf vmlinux EXPORT_SYMBOL -+0x2a24f9c2 simple_rename vmlinux EXPORT_SYMBOL -+0xb2729dbd vfs_setxattr vmlinux EXPORT_SYMBOL_GPL -+0x7d012ee7 vfs_getxattr vmlinux EXPORT_SYMBOL_GPL -+0xa3dd3ddd sock_init_data vmlinux EXPORT_SYMBOL -+0xb2d2b9ab tty_set_termios vmlinux EXPORT_SYMBOL_GPL -+0xe02eb6d0 ring_buffer_commit_overrun_cpu vmlinux EXPORT_SYMBOL_GPL -+0x3a536bd7 ring_buffer_read_finish vmlinux EXPORT_SYMBOL_GPL -+0xde48e9ca _raw_spin_lock vmlinux EXPORT_SYMBOL -+0xba707a78 qe_get_brg_clk vmlinux EXPORT_SYMBOL -+0xc37dddf0 ip_queue_xmit vmlinux EXPORT_SYMBOL -+0x715949d4 class_dev_iter_init vmlinux EXPORT_SYMBOL_GPL -+0x2b2f7e10 pci_get_slot vmlinux EXPORT_SYMBOL -+0x2eb91dfe scatterwalk_map vmlinux EXPORT_SYMBOL_GPL -+0x69a0ca7d iowrite16be vmlinux EXPORT_SYMBOL -+0x6acb973d iowrite32be vmlinux EXPORT_SYMBOL -+0xf4a2585b km_query vmlinux EXPORT_SYMBOL -+0xf9ea6336 inet_release vmlinux EXPORT_SYMBOL -+0x85da4665 blk_queue_start_tag vmlinux EXPORT_SYMBOL -+0x5549ab6e xprt_alloc vmlinux EXPORT_SYMBOL_GPL -+0xe9492d51 neigh_create vmlinux EXPORT_SYMBOL -+0xd3af87a4 usb_stor_CB_transport vmlinux EXPORT_SYMBOL_GPL -+0x9fce80db fb_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL -+0x373db350 kstrtoint vmlinux EXPORT_SYMBOL -+0xdd4a0569 log_start_commit vmlinux EXPORT_SYMBOL -+0x8f6cee77 __round_jiffies_relative vmlinux EXPORT_SYMBOL_GPL -+0x002c769b svc_pool_stats_open vmlinux EXPORT_SYMBOL -+0x536fa1b6 inet_twsk_alloc vmlinux EXPORT_SYMBOL_GPL -+0x978bfc35 tty_put_char vmlinux EXPORT_SYMBOL_GPL -+0x037a0cba kfree vmlinux EXPORT_SYMBOL -+0x5868f579 __rt_mutex_init vmlinux EXPORT_SYMBOL_GPL -+0x6e545da1 kill_pid_info_as_cred vmlinux EXPORT_SYMBOL_GPL -+0x17b07df4 vlan_dev_real_dev vmlinux EXPORT_SYMBOL -+0x3562e58c xfrm_state_delete vmlinux EXPORT_SYMBOL -+0xe492a8e1 nf_register_sockopt vmlinux EXPORT_SYMBOL -+0xbc979fa3 sock_kmalloc vmlinux EXPORT_SYMBOL -+0xb894926d schedule_work_on vmlinux EXPORT_SYMBOL -+0xb2c6eb9f pci_lost_interrupt vmlinux EXPORT_SYMBOL -+0xe7d4daac seq_list_next vmlinux EXPORT_SYMBOL -+0x538383c0 unregister_inet6addr_notifier vmlinux EXPORT_SYMBOL -+0x0d3cc82c of_irq_map_one vmlinux EXPORT_SYMBOL_GPL -+0xa06df9e1 __kfifo_dma_out_finish_r vmlinux EXPORT_SYMBOL -+0xeb7e4ace ipv6_chk_addr vmlinux EXPORT_SYMBOL -+0xdf967a1b uart_suspend_port vmlinux EXPORT_SYMBOL -+0xfb8ca5ae __blkdev_driver_ioctl vmlinux EXPORT_SYMBOL_GPL -+0x1f020c91 blk_alloc_queue_node vmlinux EXPORT_SYMBOL -+0xa3fb4a58 scsi_device_resume vmlinux EXPORT_SYMBOL -+0xafd68c33 flex_array_free vmlinux EXPORT_SYMBOL -+0xc3fb5b3d blk_queue_flush vmlinux EXPORT_SYMBOL_GPL -+0x98b9afaa bio_phys_segments vmlinux EXPORT_SYMBOL -+0xdaa57ec3 totalhigh_pages vmlinux EXPORT_SYMBOL -+0x540c4404 ipv6_find_tlv vmlinux EXPORT_SYMBOL_GPL -+0xfb3ac86b neigh_changeaddr vmlinux EXPORT_SYMBOL -+0xd59bf139 skb_recycle_check vmlinux EXPORT_SYMBOL -+0xa120d33c tty_unregister_ldisc vmlinux EXPORT_SYMBOL -+0x7dc5d0b6 crypto_unregister_notifier vmlinux EXPORT_SYMBOL_GPL -+0x9c09632d invalidate_inode_pages2 vmlinux EXPORT_SYMBOL_GPL -+0x317ce92f ipt_do_table net/ipv4/netfilter/ip_tables EXPORT_SYMBOL -+0xd726d95c scsi_calculate_bounce_limit vmlinux EXPORT_SYMBOL -+0x798959ae kmem_cache_destroy vmlinux EXPORT_SYMBOL -+0x3778ec77 add_to_page_cache_locked vmlinux EXPORT_SYMBOL -+0x4e109192 ring_buffer_entries vmlinux EXPORT_SYMBOL_GPL -+0x6d054375 xfrm_prepare_input vmlinux EXPORT_SYMBOL -+0x4333cc58 xt_find_target vmlinux EXPORT_SYMBOL -+0xb1faff50 usb_serial_disconnect vmlinux EXPORT_SYMBOL_GPL -+0xa1ba2fdb vfsmount_lock_global_lock vmlinux EXPORT_SYMBOL -+0x16947341 rpc_proc_register vmlinux EXPORT_SYMBOL_GPL -+0x6c7c7b9a rpc_queue_empty vmlinux EXPORT_SYMBOL_GPL -+0x6c394758 phy_mii_ioctl vmlinux EXPORT_SYMBOL -+0x905bba18 vm_event_states vmlinux EXPORT_SYMBOL -+0x9bce482f __release_region vmlinux EXPORT_SYMBOL -+0x43a01f90 complete_all vmlinux EXPORT_SYMBOL -+0xf020d96e tty_free_termios vmlinux EXPORT_SYMBOL -+0x347013de nla_validate vmlinux EXPORT_SYMBOL -+0x27adac45 bdi_register vmlinux EXPORT_SYMBOL -+0xc5322a9c xprt_alloc_slot vmlinux EXPORT_SYMBOL_GPL -+0x9eb0209a inet_csk_clear_xmit_timers vmlinux EXPORT_SYMBOL -+0x7129e5f8 hex_asc vmlinux EXPORT_SYMBOL -+0x7dc2f75e fat_time_unix2fat vmlinux EXPORT_SYMBOL_GPL -+0x09dfe73d nf_nat_follow_master net/ipv4/netfilter/nf_nat EXPORT_SYMBOL -+0x8ef99ed3 tty_get_pgrp vmlinux EXPORT_SYMBOL_GPL -+0x2aa0e4fc strncasecmp vmlinux EXPORT_SYMBOL -+0x53301e75 default_llseek vmlinux EXPORT_SYMBOL -+0x5e0120a8 ring_buffer_oldest_event_ts vmlinux EXPORT_SYMBOL_GPL -+0xcb3334bb tcp_read_sock vmlinux EXPORT_SYMBOL -+0xfa741e99 sdhci_pltfm_free vmlinux EXPORT_SYMBOL_GPL -+0x28535cb6 rpc_peeraddr vmlinux EXPORT_SYMBOL_GPL -+0x57958d5a ip_fragment vmlinux EXPORT_SYMBOL -+0x9aa9a810 scsi_eh_prep_cmnd vmlinux EXPORT_SYMBOL -+0x4997d11c pci_set_cacheline_size vmlinux EXPORT_SYMBOL_GPL -+0x815b5dd4 match_octal vmlinux EXPORT_SYMBOL -+0x99baa259 bio_map_kern vmlinux EXPORT_SYMBOL -+0x43969dbe rh_alloc_fixed vmlinux EXPORT_SYMBOL_GPL -+0x531c3179 xt_register_targets vmlinux EXPORT_SYMBOL -+0xf88eee18 i2c_smbus_write_byte vmlinux EXPORT_SYMBOL -+0xf77ff57d scsi_register_driver vmlinux EXPORT_SYMBOL -+0x82e96562 vfs_fsync vmlinux EXPORT_SYMBOL -+0x86acb6ae poll_freewait vmlinux EXPORT_SYMBOL -+0xb3a307c6 si_meminfo vmlinux EXPORT_SYMBOL -+0x7835cfc7 kthread_create_on_node vmlinux EXPORT_SYMBOL -+0x5e95b1cd current_umask vmlinux EXPORT_SYMBOL -+0xbd40cacd get_fs_type vmlinux EXPORT_SYMBOL -+0x377a3400 ref_module vmlinux EXPORT_SYMBOL_GPL -+0xb44478a6 qe_pin_free vmlinux EXPORT_SYMBOL -+0x8f56dfc6 nf_nat_pptp_hook_outbound net/netfilter/nf_conntrack_pptp EXPORT_SYMBOL_GPL -+0x36e46f38 tty_driver_kref_put vmlinux EXPORT_SYMBOL -+0x8e26fda2 sock_prot_inuse_get vmlinux EXPORT_SYMBOL_GPL -+0x932e22fc scsi_host_set_state vmlinux EXPORT_SYMBOL -+0x70b879e3 aead_geniv_init vmlinux EXPORT_SYMBOL_GPL -+0xf9d89d7c generic_write_end vmlinux EXPORT_SYMBOL -+0x362e23ec call_rcu_bh vmlinux EXPORT_SYMBOL_GPL -+0xbf9be642 devm_request_threaded_irq vmlinux EXPORT_SYMBOL -+0x67955ce6 profile_hits vmlinux EXPORT_SYMBOL_GPL -+0xcf764d46 __vlan_find_dev_deep vmlinux EXPORT_SYMBOL -+0x7d62fe80 of_mm_gpiochip_add vmlinux EXPORT_SYMBOL -+0x1c30dd9c genphy_config_aneg vmlinux EXPORT_SYMBOL -+0x95ad803f blk_start_queue vmlinux EXPORT_SYMBOL -+0x9c9c6a5a journal_check_used_features vmlinux EXPORT_SYMBOL -+0xe0dd2be0 bio_copy_user vmlinux EXPORT_SYMBOL -+0x7a4497db kzfree vmlinux EXPORT_SYMBOL -+0xc197d453 arpt_unregister_table net/ipv4/netfilter/arp_tables EXPORT_SYMBOL -+0x2bbf27ee sk_filter vmlinux EXPORT_SYMBOL -+0xa8f59416 gpio_direction_output vmlinux EXPORT_SYMBOL_GPL -+0x92e682eb generic_removexattr vmlinux EXPORT_SYMBOL -+0x83b88ae3 deactivate_super vmlinux EXPORT_SYMBOL -+0xa924a7ed vmap vmlinux EXPORT_SYMBOL -+0x31f0bb78 __kmap_atomic_idx vmlinux EXPORT_SYMBOL diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-cumulus-controlfiles.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-cumulus-controlfiles.patch deleted file mode 100644 index 1d7fee1f..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-cumulus-controlfiles.patch +++ /dev/null @@ -1,163 +0,0 @@ -Patch for debian post install script - -diff --git a/cumulus/control.linux-headers b/cumulus/control.linux-headers -new file mode 100644 -index 0000000..6d999dd ---- /dev/null -+++ b/cumulus/control.linux-headers -@@ -0,0 +1,5 @@ -+Package: linux-headers -+Version: =V -+Maintainer: support@cumulusnetworks.com -+Architecture: =A -+Description: Cumulus Linux kernel headers -diff --git a/cumulus/control.linux-image b/cumulus/control.linux-image -new file mode 100644 -index 0000000..03fccc4 ---- /dev/null -+++ b/cumulus/control.linux-image -@@ -0,0 +1,5 @@ -+Package: linux-image -+Version: =V -+Maintainer: support@cumulusnetworks.com -+Architecture: =A -+Description: Cumulus Linux kernel -diff --git a/cumulus/control.linux-libc-dev b/cumulus/control.linux-libc-dev -new file mode 100644 -index 0000000..4ae15ce ---- /dev/null -+++ b/cumulus/control.linux-libc-dev -@@ -0,0 +1,12 @@ -+Package: linux-libc-dev -+Source: linux-upstream -+Version: =V -+Architecture: =A -+Maintainer: cumulus -+Provides: linux-kernel-headers -+Section: devel -+Priority: optional -+Homepage: http://www.kernel.org/ -+Description: Linux support headers for userspace development -+ This package provides userspaces headers from the Linux kernel. These headers -+ are used by the installed headers for GNU glibc and other system libraries. -diff --git a/cumulus/etc/kernel/postinst.d/update-cumulus b/cumulus/etc/kernel/postinst.d/update-cumulus -new file mode 100755 -index 0000000..0333980 ---- /dev/null -+++ b/cumulus/etc/kernel/postinst.d/update-cumulus -@@ -0,0 +1,52 @@ -+#!/bin/sh -e -+ -+version="$1" -+ -+# exit if we dont need to update the kernel and initrd -+if [ "$UPDATE_CUMULUS" = 'No' ]; then -+ exit 0 -+fi -+ -+. /usr/share/cumulus/img/functions -+ -+# passing the kernel version is required -+if [ -z "${version}" ]; then -+ echo >&2 "W: cumulus-kernel: ${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} did not pass a version number" -+ exit 2 -+fi -+ -+bootdir="/boot" -+kernel_newimg_src="${bootdir}/vmlinuz-${version}" -+initrd_newimg_src="${bootdir}/initrd.img-${version}" -+ -+if [ ! -e "$kernel_newimg_src" ]; then -+ echo >&2 "W: cumulus-kernel: ${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} cannot find kernel image" -+ exit 2 -+fi -+ -+if [ ! -e "$initrd_newimg_src" ]; then -+ echo >&2 "W: cumulus-kernel: ${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} cannot find initrd image" -+ exit 2 -+fi -+ -+cl_check_env root-priv -+ -+currslot=${slot_prefix}${active} -+kernel_oldimg=${bootdir}/${kernel_prefix}vmlinuz-*-${currslot} -+initrd_oldimg=${bootdir}/${kernel_prefix}initrd.img-*-${currslot} -+ -+kernel_newimg_dst=${bootdir}/${kernel_prefix}vmlinuz-${version}-${currslot} -+initrd_newimg_dst=${bootdir}/${kernel_prefix}initrd.img-${version}-${currslot} -+ -+#remove existing currslot images -+rm -f ${kernel_oldimg} -+rm -f ${initrd_oldimg} -+ -+# Move kernel/initrd files to the kernel initrd dst files -+cmd="mv -f $kernel_newimg_src $kernel_newimg_dst" -+echo "$cmd" -+$cmd -+ -+cmd="mv -f $initrd_newimg_src $initrd_newimg_dst" -+echo "$cmd" -+$cmd -diff --git a/cumulus/postinst.linux-image.powerpc b/cumulus/postinst.linux-image.powerpc -new file mode 100755 -index 0000000..2aabfea ---- /dev/null -+++ b/cumulus/postinst.linux-image.powerpc -@@ -0,0 +1,57 @@ -+#!/bin/sh -+# postinst script for switchd -+# -+# see: dh_installdeb(1) -+ -+set -e -+ -+# summary of how this script can be called: -+# * `configure' -+# * `abort-upgrade' -+# * `abort-remove' `in-favour' -+# -+# * `abort-remove' -+# * `abort-deconfigure' `in-favour' -+# `removing' -+# -+# for details, see http://www.debian.org/doc/debian-policy/ or -+# the debian-policy package -+ -+ -+case "$1" in -+ configure) -+ ;; -+ -+ abort-upgrade|abort-remove|abort-deconfigue) -+ exit 1 -+ ;; -+ *) -+ echo "postinst called with unknown argument \`$1'" >&2 -+ exit 1 -+ ;; -+esac -+ -+. /usr/share/cumulus/img/functions -+ -+install_file=/usr/share/cumulus/.installer/kernel_install.sh -+kimage_linkname="uImage.itb" -+kimage_name="uImage-=V-=A.itb" -+kimage_path="/boot/"$kimage_name -+ -+if [ -e "/.buildroot" ]; then -+ cd /boot && ln -sf $kimage_name $kimage_linkname -+ exit 0 -+fi -+ -+cl_check_env root-priv -+slot=$active -+ -+sh $install_file $kimage_path $slot || { -+ log_failure_msg "Kernel installtion failed." -+ log_failure_msg "Problems installing image file." -+ exit 1 -+} -+ -+cd /boot && ln -sf $kimage_name $kimage_linkname -+ -+exit 0 diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-cumulus-post-inst.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-cumulus-post-inst.patch deleted file mode 100644 index b0e357c0..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-cumulus-post-inst.patch +++ /dev/null @@ -1,60 +0,0 @@ -Patch for debian post install script - -diff --git a/cumulus/postinst b/cumulus/postinst -new file mode 100755 -index 0000000..6b9ca39 ---- /dev/null -+++ b/cumulus/postinst -@@ -0,0 +1,52 @@ -+#!/bin/sh -+# postinst script for switchd -+# -+# see: dh_installdeb(1) -+ -+set -e -+ -+# summary of how this script can be called: -+# * `configure' -+# * `abort-upgrade' -+# * `abort-remove' `in-favour' -+# -+# * `abort-remove' -+# * `abort-deconfigure' `in-favour' -+# `removing' -+# -+# for details, see http://www.debian.org/doc/debian-policy/ or -+# the debian-policy package -+ -+ -+case "$1" in -+ configure) -+ ;; -+ -+ abort-upgrade|abort-remove|abort-deconfigue) -+ exit 1 -+ ;; -+ *) -+ echo "postinst called with unknown argument \`$1'" >&2 -+ exit 1 -+ ;; -+esac -+ -+. /usr/share/cumulus/img/functions -+cl_check_env root-priv -+ -+install_file=/usr/share/cumulus/.installer/kernel_install.sh -+slot=$active -+kimage="/boot/uImage-${arch}.itb" -+ -+sh $install_file $kimage $slot || { -+ log_failure_msg "Kernel installtion failed." -+ log_failure_msg "Problems installing image file." -+ clean_up 1 -+} -+ -+# dh_installdeb will replace this with shell code automatically -+# generated by other debhelper scripts. -+ -+#DEBHELPER# -+ -+exit 0 diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-postinstall-call-depmod.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-postinstall-call-depmod.patch deleted file mode 100644 index dae87459..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/debian-postinstall-call-depmod.patch +++ /dev/null @@ -1,32 +0,0 @@ -Post install hooks need to call depmod to properly load kernel modules after -reboot. - -diff --git a/cumulus/etc/kernel/postinst.d/update-cumulus b/cumulus/etc/kernel/postinst.d/update-cumulus -index 0333980..cd8d311 100755 ---- a/cumulus/etc/kernel/postinst.d/update-cumulus -+++ b/cumulus/etc/kernel/postinst.d/update-cumulus -@@ -50,3 +50,5 @@ $cmd - cmd="mv -f $initrd_newimg_src $initrd_newimg_dst" - echo "$cmd" - $cmd -+ -+depmod -a $version -diff --git a/cumulus/postinst.linux-image.powerpc b/cumulus/postinst.linux-image.powerpc -index 2aabfea..fb775d4 100755 ---- a/cumulus/postinst.linux-image.powerpc -+++ b/cumulus/postinst.linux-image.powerpc -@@ -1,5 +1,5 @@ - #!/bin/sh --# postinst script for switchd -+# postinst script for kernel - # - # see: dh_installdeb(1) - -@@ -54,4 +54,7 @@ sh $install_file $kimage_path $slot || { - - cd /boot && ln -sf $kimage_name $kimage_linkname - -+echo "depmod -a =V" -+depmod -a =V -+ - exit 0 diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-adt7470-knob-to-disable-smbus-timeout.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-adt7470-knob-to-disable-smbus-timeout.patch deleted file mode 100644 index 9efc5fa5..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-adt7470-knob-to-disable-smbus-timeout.patch +++ /dev/null @@ -1,57 +0,0 @@ -driver adt7470 add knob to disable smbus timeout feature - -The ADT7470 has a configurable feature called "disable SMBUS timeout". - -Quoting their data sheet: - - The ADT7470 includes an SMBus timeout feature. If there is no SMBus - activity for more than 31 ms, the ADT7470 assumes that the bus is - locked and releases the bus. This prevents the device from locking - or holding the SMBus expecting data. Some SMBus controllers cannot - handle the SMBus timeout feature, so it can be disabled. - -It appears the FSL I2C controller cannot handle this feature. With -the timeout enabled we see intermittent failures waiting for the bus -to become ready or for transaction to complete. - -This patch adds a configurable option to the device tree. If the -property "disable-smbus-timeout" exists in the node then the ADT7470 -driver will disable the SMBUS timeout feature. - -This way platforms that need to can disable this feature. - -diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c -index a9726c1..6ca8aae 100644 ---- a/drivers/hwmon/adt7470.c -+++ b/drivers/hwmon/adt7470.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - - /* Addresses to scan */ - static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; -@@ -48,6 +49,7 @@ static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; - #define ADT7470_REG_PWM_MAX_MAX_ADDR 0x3B - #define ADT7470_REG_CFG 0x40 - #define ADT7470_FSPD_MASK 0x04 -+#define ADT7470_TODIS_MASK 0x08 - #define ADT7470_REG_ALARM1 0x41 - #define ADT7470_R1T_ALARM 0x01 - #define ADT7470_R2T_ALARM 0x02 -@@ -225,6 +227,14 @@ static void adt7470_init_client(struct i2c_client *client) - if (reg < 0) { - dev_err(&client->dev, "cannot read configuration register\n"); - } else { -+ struct property *pp; -+ pp = of_find_property(client->dev.of_node, -+ "disable-smbus-timeout", NULL); -+ if (pp) -+ reg |= ADT7470_TODIS_MASK; -+ else -+ reg &= ~ADT7470_TODIS_MASK; -+ - /* start monitoring (and do a self-test) */ - i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, reg | 3); - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-add-i2cblock-disable-flag.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-add-i2cblock-disable-flag.patch deleted file mode 100644 index 5e709dcb..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-add-i2cblock-disable-flag.patch +++ /dev/null @@ -1,41 +0,0 @@ -Adds a flag that lets you disable FEATURE_I2C_BLOCK_READ on a device basis. - -diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c -index 841631c..67f4e6f 100644 ---- a/drivers/misc/eeprom/at24.c -+++ b/drivers/misc/eeprom/at24.c -@@ -582,8 +582,9 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - if (chip.flags & AT24_FLAG_ADDR16) { - use_smbus = I2C_SMBUS_BYTE_DATA; -- } else if (i2c_check_functionality(client->adapter, -- I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { -+ } else if (!(chip.flags & AT24_FLAG_DISABLE_I2CBLOCK) && -+ (i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_READ_I2C_BLOCK))) { - use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; - } else if (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_WORD_DATA)) { -@@ -630,8 +631,9 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) - writable = !(chip.flags & AT24_FLAG_READONLY); - if (writable) { - if (!use_smbus || -+ (!(chip.flags & AT24_FLAG_DISABLE_I2CBLOCK) && - i2c_check_functionality(client->adapter, -- I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) || -+ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) || - i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_WRITE_WORD_DATA) || - i2c_check_functionality(client->adapter, -diff --git a/include/linux/i2c/at24.h b/include/linux/i2c/at24.h -index a881e5e..3bdb466 100644 ---- a/include/linux/i2c/at24.h -+++ b/include/linux/i2c/at24.h -@@ -25,6 +25,7 @@ struct at24_platform_data { - #define AT24_FLAG_READONLY 0x40 /* sysfs-entry will be read-only */ - #define AT24_FLAG_IRUGO 0x20 /* sysfs-entry will be world-readable */ - #define AT24_FLAG_TAKE8ADDR 0x10 /* take always 8 addresses (24c00) */ -+#define AT24_FLAG_DISABLE_I2CBLOCK 0x08 /*disable smbus i2c block access */ - - void (*setup)(struct memory_accessor *, void *context); - void *context; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-byte-word-write-access.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-byte-word-write-access.patch deleted file mode 100644 index 2ab2c2b2..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-byte-word-write-access.patch +++ /dev/null @@ -1,105 +0,0 @@ -Adds byte and word write access to the at24 driver - -diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c -index c98c736..2ec05ce 100644 ---- a/drivers/misc/eeprom/at24.c -+++ b/drivers/misc/eeprom/at24.c -@@ -332,6 +332,7 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf, - ssize_t status; - unsigned long timeout, write_time; - unsigned next_page; -+ int i = 0; - - /* Get corresponding I2C address and adjust offset */ - client = at24_translate_offset(at24, &offset); -@@ -345,10 +346,22 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf, - if (offset + count > next_page) - count = next_page - offset; - -- /* If we'll use I2C calls for I/O, set up the message */ -- if (!at24->use_smbus) { -- int i = 0; - -+ switch (at24->use_smbus) { -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ /* Smaller eeproms can work given some SMBus extension calls */ -+ if (count > I2C_SMBUS_BLOCK_MAX) -+ count = I2C_SMBUS_BLOCK_MAX; -+ break; -+ case I2C_SMBUS_WORD_DATA: -+ /* Check for odd length transaction */ -+ count = (count == 1) ? 1 : 2; -+ break; -+ case I2C_SMBUS_BYTE_DATA: -+ count = 1; -+ break; -+ default: -+ /* If we'll use I2C calls for I/O, set up the message */ - msg.addr = client->addr; - msg.flags = 0; - -@@ -360,6 +373,7 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf, - msg.buf[i++] = offset; - memcpy(&msg.buf[i], buf, count); - msg.len = i + count; -+ break; - } - - /* -@@ -370,15 +384,37 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf, - timeout = jiffies + msecs_to_jiffies(write_timeout); - do { - write_time = jiffies; -- if (at24->use_smbus) { -+ switch (at24->use_smbus) { -+ case I2C_SMBUS_I2C_BLOCK_DATA: - status = i2c_smbus_write_i2c_block_data(client, - offset, count, buf); - if (status == 0) - status = count; -- } else { -+ break; -+ case I2C_SMBUS_WORD_DATA: -+ if (count == 2) { -+ status = i2c_smbus_write_word_data( -+ client,offset,(u16)((buf[0]) | -+ (buf[1] << 8))); -+ } else { -+ /* count = 1 */ -+ status = i2c_smbus_write_byte_data( -+ client, offset, buf[0]); -+ } -+ if (status == 0) -+ status = count; -+ break; -+ case I2C_SMBUS_BYTE_DATA: -+ status = i2c_smbus_write_byte_data(client, offset, -+ buf[0]); -+ if (status == 0) -+ status = count; -+ break; -+ default: - status = i2c_transfer(client->adapter, &msg, 1); - if (status == 1) - status = count; -+ break; - } - dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", - count, offset, status, jiffies); -@@ -585,9 +621,13 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) - - writable = !(chip.flags & AT24_FLAG_READONLY); - if (writable) { -- if (!use_smbus || i2c_check_functionality(client->adapter, -- I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { -- -+ if (!use_smbus || -+ i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) || -+ i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_WRITE_WORD_DATA) || -+ i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { - unsigned write_max = chip.page_size; - - at24->macc.write = at24_macc_write; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-eeprom-class.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-eeprom-class.patch deleted file mode 100644 index 784eadf7..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-eeprom-class.patch +++ /dev/null @@ -1,78 +0,0 @@ -Add at24 based EEPROMs to the eeprom_dev hardware class - -During device instantiation have the at24 driver add the new device to -the eeprom_dev hardware class. The functionality is enabled by -CONFIG_EEPROM_CLASS. - -diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c -index 47bcd10..c98c736 100644 ---- a/drivers/misc/eeprom/at24.c -+++ b/drivers/misc/eeprom/at24.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - /* - * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. -@@ -68,6 +69,8 @@ struct at24_data { - unsigned write_max; - unsigned num_addresses; - -+ struct eeprom_device *eeprom_dev; -+ - /* - * Some chips tie up multiple I2C addresses; dummy devices reserve - * them for us, and we'll use them with SMBus calls. -@@ -514,6 +517,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) - - chip.setup = NULL; - chip.context = NULL; -+ chip.eeprom_data = NULL; - } - - if (!is_power_of_2(chip.byte_len)) -@@ -627,6 +631,13 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) - if (err) - goto err_clients; - -+ at24->eeprom_dev = eeprom_device_register(&client->dev, chip.eeprom_data); -+ if (IS_ERR(at24->eeprom_dev)) { -+ dev_err(&client->dev, "error registering eeprom device.\n"); -+ err = PTR_ERR(at24->eeprom_dev); -+ goto err_clients; -+ } -+ - i2c_set_clientdata(client, at24); - - dev_info(&client->dev, "%zu byte %s EEPROM, %s, %u bytes/write\n", -@@ -669,6 +680,8 @@ static int __devexit at24_remove(struct i2c_client *client) - for (i = 1; i < at24->num_addresses; i++) - i2c_unregister_device(at24->client[i]); - -+ eeprom_device_unregister(at24->eeprom_dev); -+ - kfree(at24->writebuf); - kfree(at24); - return 0; -diff --git a/include/linux/i2c/at24.h b/include/linux/i2c/at24.h -index 8ace930..a881e5e 100644 ---- a/include/linux/i2c/at24.h -+++ b/include/linux/i2c/at24.h -@@ -3,6 +3,7 @@ - - #include - #include -+#include - - /* - * As seen through Linux I2C, differences between the most common types of I2C -@@ -27,6 +28,7 @@ struct at24_platform_data { - - void (*setup)(struct memory_accessor *, void *context); - void *context; -+ struct eeprom_platform_data *eeprom_data; /* extra data for the eeprom_class */ - }; - - #endif /* _LINUX_AT24_H */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-fix-odd-length-two-byte-access.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-fix-odd-length-two-byte-access.patch deleted file mode 100644 index 0bdd69b7..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-fix-odd-length-two-byte-access.patch +++ /dev/null @@ -1,40 +0,0 @@ -driver at24 fix odd length two byte access - -For I2C_SMBUS_WORD_DATA read accesses check if the access length is -one or two bytes. For transactions that have an odd length eventualy -we read 1 byte at the end to complete the request. - -The previous code always used a count of 2, which works fine if the -requested total length is even. If the requested length was odd, -however, the code would cause a kernel OOPS. - -The while (count) loop would go forever as count went from 1 to -1, -never becoming zero. Also the return buffer would overrun. - -This patch allows for reading an odd number of bytes in -I2C_SMBUS_WORD_DATA mode. - -diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c -index ab1ad41..47bcd10 100644 ---- a/drivers/misc/eeprom/at24.c -+++ b/drivers/misc/eeprom/at24.c -@@ -192,7 +192,8 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, - count = I2C_SMBUS_BLOCK_MAX; - break; - case I2C_SMBUS_WORD_DATA: -- count = 2; -+ /* Check for odd length transaction */ -+ count = (count == 1) ? 1 : 2; - break; - case I2C_SMBUS_BYTE_DATA: - count = 1; -@@ -237,7 +238,8 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, - status = i2c_smbus_read_word_data(client, offset); - if (status >= 0) { - buf[0] = status & 0xff; -- buf[1] = status >> 8; -+ if (count == 2) -+ buf[1] = status >> 8; - status = count; - } - break; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-smbus-addr16.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-smbus-addr16.patch deleted file mode 100644 index 53e7ddaf..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-at24-smbus-addr16.patch +++ /dev/null @@ -1,49 +0,0 @@ -patch for celestica Redstone XP - -diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c -index 2ec05ce..841631c 100644 ---- a/drivers/misc/eeprom/at24.c -+++ b/drivers/misc/eeprom/at24.c -@@ -247,7 +247,14 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, - } - break; - case I2C_SMBUS_BYTE_DATA: -- status = i2c_smbus_read_byte_data(client, offset); -+ if (at24->chip.flags & AT24_FLAG_ADDR16) { -+ status = i2c_smbus_write_byte_data(client, (offset >> 8) & 0xff, offset & 0xff); -+ if (status >= 0) { -+ status = i2c_smbus_read_byte(client); -+ } -+ } else { -+ status = i2c_smbus_read_byte_data(client, offset); -+ } - if (status >= 0) { - buf[0] = status; - status = count; -@@ -405,8 +412,11 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf, - status = count; - break; - case I2C_SMBUS_BYTE_DATA: -- status = i2c_smbus_write_byte_data(client, offset, -- buf[0]); -+ if (at24->chip.flags & AT24_FLAG_ADDR16) { -+ status = i2c_smbus_write_word_data(client, (offset >> 8) & 0xff, buf[0] << 8 | (offset & 0xff)); -+ } else { -+ status = i2c_smbus_write_byte_data(client, offset, buf[0]); -+ } - if (status == 0) - status = count; - break; -@@ -571,10 +581,8 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) - /* Use I2C operations unless we're stuck with SMBus extensions. */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - if (chip.flags & AT24_FLAG_ADDR16) { -- err = -EPFNOSUPPORT; -- goto err_out; -- } -- if (i2c_check_functionality(client->adapter, -+ use_smbus = I2C_SMBUS_BYTE_DATA; -+ } else if (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { - use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; - } else if (i2c_check_functionality(client->adapter, diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-broadcom-tigon3.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-broadcom-tigon3.patch deleted file mode 100644 index ffff1d30..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-broadcom-tigon3.patch +++ /dev/null @@ -1,27389 +0,0 @@ -support Broadcom Tigon3 Ethernet driver - -diff --git a/drivers/net/ethernet/broadcom/Makefile b/drivers/net/ethernet/broadcom/Makefile -index b789605..486c71c 100644 ---- a/drivers/net/ethernet/broadcom/Makefile -+++ b/drivers/net/ethernet/broadcom/Makefile -@@ -8,4 +8,4 @@ obj-$(CONFIG_BNX2) += bnx2.o - obj-$(CONFIG_CNIC) += cnic.o - obj-$(CONFIG_BNX2X) += bnx2x/ - obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o --obj-$(CONFIG_TIGON3) += tg3.o -+obj-$(CONFIG_TIGON3) += tg3/ -diff --git a/drivers/net/ethernet/broadcom/tg3/Makefile b/drivers/net/ethernet/broadcom/tg3/Makefile -new file mode 100644 -index 0000000..22b6141 ---- /dev/null -+++ b/drivers/net/ethernet/broadcom/tg3/Makefile -@@ -0,0 +1,5 @@ -+# -+# Makefile for Broadcom Tigon3 ethernet driver -+# -+ -+obj-$(CONFIG_TIGON3) += tg3.o -diff --git a/drivers/net/ethernet/broadcom/tg3/tg3.c b/drivers/net/ethernet/broadcom/tg3/tg3.c -new file mode 100644 -index 0000000..4894a11 ---- /dev/null -+++ b/drivers/net/ethernet/broadcom/tg3/tg3.c -@@ -0,0 +1,19937 @@ -+/* -+ * tg3.c: Broadcom Tigon3 ethernet driver. -+ * -+ * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) -+ * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) -+ * Copyright (C) 2004 Sun Microsystems Inc. -+ * Copyright (C) 2005-2015 Broadcom Corporation. -+ * Portions Copyright (C) VMware, Inc. 2007-2010. All Rights Reserved. -+ * -+ * Firmware is: -+ * Derived from proprietary unpublished source code, -+ * Copyright (C) 2000-2003 Broadcom Corporation. -+ * -+ * Permission is hereby granted for the distribution of this firmware -+ * data in hexadecimal or equivalent format, provided this copyright -+ * notice is accompanying it. -+ */ -+ -+#include "tg3_flags.h" -+ -+#include -+ -+#if (LINUX_VERSION_CODE < 0x020612) -+#include -+#endif -+ -+#if (LINUX_VERSION_CODE < 0x020500) -+#if defined(CONFIG_MODVERSIONS) && defined(MODULE) && ! defined(MODVERSIONS) -+#define MODVERSIONS -+#include -+#endif -+#endif -+#include -+#if (LINUX_VERSION_CODE >= 0x20600) -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef BCM_HAS_MDIO_H -+#include -+#endif -+#include -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+#include -+#include -+#include -+#endif -+#include -+#include -+#include -+#if (LINUX_VERSION_CODE >= 0x20600) -+#include -+#endif -+#include -+#if (LINUX_VERSION_CODE >= 0x020600) -+#include -+#endif -+#ifdef BCM_HAS_REQUEST_FIRMWARE -+#include -+#else -+#include "tg3_firmware.h" -+#endif -+#include -+ -+#ifndef IS_ENABLED -+#define __ARG_PLACEHOLDER_1 0, -+#define config_enabled(cfg) _config_enabled(cfg) -+#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value) -+#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0) -+#define ___config_enabled(__ignored, val, ...) val -+ -+#define IS_ENABLED(option) \ -+ (config_enabled(option) || config_enabled(option##_MODULE)) -+#endif -+ -+#if IS_ENABLED(CONFIG_HWMON) && !defined(__VMKLNX__) -+#include -+#include -+#endif -+ -+#include -+#include -+ -+#include -+#include -+#include -+ -+#ifdef BCM_HAS_IEEE1588_SUPPORT -+#include -+#if IS_ENABLED(CONFIG_PTP_1588_CLOCK) -+#include -+#else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */ -+#include -+#include -+#endif /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */ -+#endif -+ -+#ifdef CONFIG_SPARC -+#include -+#include -+#endif -+ -+#define BAR_0 0 -+#define BAR_2 2 -+ -+#include "tg3.h" -+ -+/* Functions & macros to verify TG3_FLAGS types */ -+ -+static inline int _tg3_flag(enum TG3_FLAGS flag, unsigned long *bits) -+{ -+ return test_bit(flag, bits); -+} -+ -+static inline void _tg3_flag_set(enum TG3_FLAGS flag, unsigned long *bits) -+{ -+ set_bit(flag, bits); -+} -+ -+static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) -+{ -+ clear_bit(flag, bits); -+} -+ -+#define tg3_flag(tp, flag) \ -+ _tg3_flag(TG3_FLAG_##flag, (tp)->tg3_flags) -+#define tg3_flag_set(tp, flag) \ -+ _tg3_flag_set(TG3_FLAG_##flag, (tp)->tg3_flags) -+#define tg3_flag_clear(tp, flag) \ -+ _tg3_flag_clear(TG3_FLAG_##flag, (tp)->tg3_flags) -+ -+#define DRV_MODULE_NAME "tg3" -+#define TG3_MAJ_NUM 3 -+#define TG3_MIN_NUM 137 -+#define TG3_REVISION "k" -+#define DRV_MODULE_VERSION \ -+ __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)\ -+ TG3_REVISION -+#define DRV_MODULE_RELDATE "April 1, 2015" -+#define RESET_KIND_SHUTDOWN 0 -+#define RESET_KIND_INIT 1 -+#define RESET_KIND_SUSPEND 2 -+ -+#define TG3_DEF_RX_MODE 0 -+#define TG3_DEF_TX_MODE 0 -+#define TG3_DEF_MSG_ENABLE \ -+ (NETIF_MSG_DRV | \ -+ NETIF_MSG_PROBE | \ -+ NETIF_MSG_LINK | \ -+ NETIF_MSG_TIMER | \ -+ NETIF_MSG_IFDOWN | \ -+ NETIF_MSG_IFUP | \ -+ NETIF_MSG_RX_ERR | \ -+ NETIF_MSG_TX_ERR) -+ -+#define TG3_GRC_LCLCTL_PWRSW_DELAY 100 -+ -+/* length of time before we decide the hardware is borked, -+ * and dev->tx_timeout() should be called to fix the problem -+ */ -+#if defined(__VMKLNX__) -+/* On VMware ESX there is a possibility that that netdev watchdog thread -+ * runs before the reset task if the machine is loaded. If this occurs -+ * too many times, these premature watchdog triggers will cause a PSOD -+ * on a VMware ESX beta build */ -+#define TG3_TX_TIMEOUT (20 * HZ) -+#else -+#define TG3_TX_TIMEOUT (5 * HZ) -+#endif /* defined(__VMKLNX__) */ -+ -+/* hardware minimum and maximum for a single frame's data payload */ -+#define TG3_MIN_MTU 60 -+#define TG3_MAX_MTU(tp) \ -+ (tg3_flag(tp, JUMBO_CAPABLE) ? 9000 : 1500) -+ -+/* These numbers seem to be hard coded in the NIC firmware somehow. -+ * You can't change the ring sizes, but you can change where you place -+ * them in the NIC onboard memory. -+ */ -+#define TG3_RX_STD_RING_SIZE(tp) \ -+ (tg3_flag(tp, LRG_PROD_RING_CAP) ? \ -+ TG3_RX_STD_MAX_SIZE_5717 : TG3_RX_STD_MAX_SIZE_5700) -+#define TG3_RX_JMB_RING_SIZE(tp) \ -+ (tg3_flag(tp, LRG_PROD_RING_CAP) ? \ -+ TG3_RX_JMB_MAX_SIZE_5717 : TG3_RX_JMB_MAX_SIZE_5700) -+ -+#if defined(__VMKLNX__) -+#define TG3_DEF_RX_RING_PENDING 255 -+#define TG3_DEF_RX_JUMBO_RING_PENDING 200 -+#else -+#define TG3_DEF_RX_RING_PENDING 200 -+#define TG3_DEF_RX_JUMBO_RING_PENDING 100 -+#endif -+ -+/* Do not place this n-ring entries value into the tp struct itself, -+ * we really want to expose these constants to GCC so that modulo et -+ * al. operations are done with shifts and masks instead of with -+ * hw multiply/modulo instructions. Another solution would be to -+ * replace things like '% foo' with '& (foo - 1)'. -+ */ -+ -+#define TG3_TX_RING_SIZE 512 -+#define TG3_DEF_TX_RING_PENDING (TG3_TX_RING_SIZE - 1) -+ -+#define TG3_RX_STD_RING_BYTES(tp) \ -+ (sizeof(struct tg3_rx_buffer_desc) * TG3_RX_STD_RING_SIZE(tp)) -+#define TG3_RX_JMB_RING_BYTES(tp) \ -+ (sizeof(struct tg3_ext_rx_buffer_desc) * TG3_RX_JMB_RING_SIZE(tp)) -+#define TG3_RX_RCB_RING_BYTES(tp) \ -+ (sizeof(struct tg3_rx_buffer_desc) * (tp->rx_ret_ring_mask + 1)) -+#define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * \ -+ TG3_TX_RING_SIZE) -+#define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1)) -+ -+#define TG3_DMA_BYTE_ENAB 64 -+ -+#define TG3_RX_STD_DMA_SZ 1536 -+#define TG3_RX_JMB_DMA_SZ 9046 -+ -+#define TG3_RX_DMA_TO_MAP_SZ(x) ((x) + TG3_DMA_BYTE_ENAB) -+ -+#define TG3_RX_STD_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_STD_DMA_SZ) -+#define TG3_RX_JMB_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ) -+ -+#define TG3_RX_STD_BUFF_RING_SIZE(tp) \ -+ (sizeof(struct ring_info) * TG3_RX_STD_RING_SIZE(tp)) -+ -+#define TG3_RX_JMB_BUFF_RING_SIZE(tp) \ -+ (sizeof(struct ring_info) * TG3_RX_JMB_RING_SIZE(tp)) -+ -+/* Due to a hardware bug, the 5701 can only DMA to memory addresses -+ * that are at least dword aligned when used in PCIX mode. The driver -+ * works around this bug by double copying the packet. This workaround -+ * is built into the normal double copy length check for efficiency. -+ * -+ * However, the double copy is only necessary on those architectures -+ * where unaligned memory accesses are inefficient. For those architectures -+ * where unaligned memory accesses incur little penalty, we can reintegrate -+ * the 5701 in the normal rx path. Doing so saves a device structure -+ * dereference by hardcoding the double copy threshold in place. -+ */ -+#define TG3_RX_COPY_THRESHOLD 256 -+#if NET_IP_ALIGN == 0 || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) -+ #define TG3_RX_COPY_THRESH(tp) TG3_RX_COPY_THRESHOLD -+#else -+ #define TG3_RX_COPY_THRESH(tp) ((tp)->rx_copy_thresh) -+#endif -+ -+#if (NET_IP_ALIGN != 0) -+#define TG3_RX_OFFSET(tp) ((tp)->rx_offset) -+#else -+#ifdef BCM_HAS_BUILD_SKB -+#define TG3_RX_OFFSET(tp) (NET_SKB_PAD) -+#else -+#define TG3_RX_OFFSET(tp) 0 -+#endif -+#endif -+ -+/* minimum number of free TX descriptors required to wake up TX process */ -+#define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4) -+#define TG3_TX_BD_DMA_MAX_2K 2048 -+#define TG3_TX_BD_DMA_MAX_4K 4096 -+#define TG3_TX_BD_DMA_MAX_32K 32768 -+ -+#define TG3_RAW_IP_ALIGN 2 -+ -+#define TG3_MAX_UCAST_ADDR(tp) (tg3_flag((tp), ENABLE_ASF) ? 2 : 3) -+#define TG3_UCAST_ADDR_IDX(tp) (tg3_flag((tp), ENABLE_ASF) ? 2 : 1) -+ -+#include "tg3_compat2.h" -+ -+#if defined(__VMKLNX__) -+/* see pr141646, 626764*/ -+#define TG3_FW_UPDATE_TIMEOUT_SEC 30 -+#else -+#define TG3_FW_UPDATE_TIMEOUT_SEC 5 -+#endif -+#define TG3_FW_UPDATE_FREQ_SEC (TG3_FW_UPDATE_TIMEOUT_SEC / 2) -+ -+#define FIRMWARE_TG3 "tigon/tg3.bin" -+#define FIRMWARE_TG357766 "tigon/tg357766.bin" -+#define FIRMWARE_TG3TSO "tigon/tg3_tso.bin" -+#define FIRMWARE_TG3TSO5 "tigon/tg3_tso5.bin" -+ -+static char version[] __devinitdata = -+ DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; -+ -+MODULE_AUTHOR("David S. Miller (davem@redhat.com) and Jeff Garzik (jgarzik@pobox.com)"); -+MODULE_DESCRIPTION("Broadcom Tigon3 ethernet driver"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(DRV_MODULE_VERSION); -+MODULE_FIRMWARE(FIRMWARE_TG3); -+MODULE_FIRMWARE(FIRMWARE_TG3TSO); -+MODULE_FIRMWARE(FIRMWARE_TG3TSO5); -+ -+static int tg3_debug = -1; /* -1 == use TG3_DEF_MSG_ENABLE as value */ -+#if (LINUX_VERSION_CODE >= 0x20600) -+module_param(tg3_debug, int, 0); -+MODULE_PARM_DESC(tg3_debug, "Tigon3 bitmapped debugging message enable value"); -+#endif -+#if defined(__VMKLNX__) && (VMWARE_ESX_DDK_VERSION >= 55000) -+static int disable_fw_dmp; -+module_param(disable_fw_dmp, int, 0); -+MODULE_PARM_DESC(disable_fw_dmp, "For debugging purposes, disable firmware " -+ "dump feature when set to value of 1"); -+#endif -+ -+static int tg3_disable_eee = -1; -+#if (LINUX_VERSION_CODE >= 0x20600) -+module_param(tg3_disable_eee, int, 0); -+MODULE_PARM_DESC(tg3_disable_eee, "Disable Energy Efficient Ethernet (EEE) support"); -+#endif -+ -+#define TG3_DRV_DATA_FLAG_10_100_ONLY 0x0001 -+#define TG3_DRV_DATA_FLAG_5705_10_100 0x0002 -+ -+static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = { -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5700)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5701)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702FE)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705_2)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705M)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705M_2)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702X)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703X)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702A3)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703A3)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5782)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5788)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5789)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901), -+ .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY | -+ TG3_DRV_DATA_FLAG_5705_10_100}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2), -+ .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY | -+ TG3_DRV_DATA_FLAG_5705_10_100}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S_2)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705F), -+ .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY | -+ TG3_DRV_DATA_FLAG_5705_10_100}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5721)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5722)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751M)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751F), -+ .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752M)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753M)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753F), -+ .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754M)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755M)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5756)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5786)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787)}, -+ {PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5787M, -+ PCI_VENDOR_ID_LENOVO, -+ TG3PCI_SUBDEVICE_ID_LENOVO_5787M), -+ .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787F), -+ .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714S)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715S)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5781)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906M)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5784)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5764)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5723)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761E)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761S)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761SE)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5785_G)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5785_F)}, -+ {PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57780, -+ PCI_VENDOR_ID_AI, TG3PCI_SUBDEVICE_ID_ACER_57780_A), -+ .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY}, -+ {PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57780, -+ PCI_VENDOR_ID_AI, TG3PCI_SUBDEVICE_ID_ACER_57780_B), -+ .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57780)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57760)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57790), -+ .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57788)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717_C)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5718)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57781)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57785)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57761)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57765)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57791), -+ .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57795), -+ .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5720)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57762)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57766)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5762)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5725)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5727)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57764)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57767)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57787)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57782)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57786)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1001)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1003)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC9100)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_TIGON3)}, -+ {} -+}; -+ -+MODULE_DEVICE_TABLE(pci, tg3_pci_tbl); -+ -+static const struct { -+ const char string[ETH_GSTRING_LEN]; -+} ethtool_stats_keys[] = { -+ { "rx_octets" }, -+ { "rx_fragments" }, -+ { "rx_ucast_packets" }, -+ { "rx_mcast_packets" }, -+ { "rx_bcast_packets" }, -+ { "rx_fcs_errors" }, -+ { "rx_align_errors" }, -+ { "rx_xon_pause_rcvd" }, -+ { "rx_xoff_pause_rcvd" }, -+ { "rx_mac_ctrl_rcvd" }, -+ { "rx_xoff_entered" }, -+ { "rx_frame_too_long_errors" }, -+ { "rx_jabbers" }, -+ { "rx_undersize_packets" }, -+ { "rx_in_length_errors" }, -+ { "rx_out_length_errors" }, -+ { "rx_64_or_less_octet_packets" }, -+ { "rx_65_to_127_octet_packets" }, -+ { "rx_128_to_255_octet_packets" }, -+ { "rx_256_to_511_octet_packets" }, -+ { "rx_512_to_1023_octet_packets" }, -+ { "rx_1024_to_1522_octet_packets" }, -+ { "rx_1523_to_2047_octet_packets" }, -+ { "rx_2048_to_4095_octet_packets" }, -+ { "rx_4096_to_8191_octet_packets" }, -+ { "rx_8192_to_9022_octet_packets" }, -+ -+ { "tx_octets" }, -+ { "tx_collisions" }, -+ -+ { "tx_xon_sent" }, -+ { "tx_xoff_sent" }, -+ { "tx_flow_control" }, -+ { "tx_mac_errors" }, -+ { "tx_single_collisions" }, -+ { "tx_mult_collisions" }, -+ { "tx_deferred" }, -+ { "tx_excessive_collisions" }, -+ { "tx_late_collisions" }, -+ { "tx_collide_2times" }, -+ { "tx_collide_3times" }, -+ { "tx_collide_4times" }, -+ { "tx_collide_5times" }, -+ { "tx_collide_6times" }, -+ { "tx_collide_7times" }, -+ { "tx_collide_8times" }, -+ { "tx_collide_9times" }, -+ { "tx_collide_10times" }, -+ { "tx_collide_11times" }, -+ { "tx_collide_12times" }, -+ { "tx_collide_13times" }, -+ { "tx_collide_14times" }, -+ { "tx_collide_15times" }, -+ { "tx_ucast_packets" }, -+ { "tx_mcast_packets" }, -+ { "tx_bcast_packets" }, -+ { "tx_carrier_sense_errors" }, -+ { "tx_discards" }, -+ { "tx_errors" }, -+ -+ { "dma_writeq_full" }, -+ { "dma_write_prioq_full" }, -+ { "rxbds_empty" }, -+ { "rx_discards" }, -+ { "rx_errors" }, -+ { "rx_threshold_hit" }, -+ -+ { "dma_readq_full" }, -+ { "dma_read_prioq_full" }, -+ { "tx_comp_queue_full" }, -+ -+ { "ring_set_send_prod_index" }, -+ { "ring_status_update" }, -+ { "nic_irqs" }, -+ { "nic_avoided_irqs" }, -+ { "nic_tx_threshold_hit" }, -+ -+ { "mbuf_lwm_thresh_hit" }, -+ { "dma_4g_cross" }, -+#if !defined(__VMKLNX__) -+ { "recoverable_err" }, -+ { "unrecoverable_err" }, -+#endif -+}; -+ -+#define TG3_NUM_STATS ARRAY_SIZE(ethtool_stats_keys) -+#define TG3_NVRAM_TEST 0 -+#define TG3_LINK_TEST 1 -+#define TG3_REGISTER_TEST 2 -+#define TG3_MEMORY_TEST 3 -+#define TG3_MAC_LOOPB_TEST 4 -+#define TG3_PHY_LOOPB_TEST 5 -+#define TG3_EXT_LOOPB_TEST 6 -+#define TG3_INTERRUPT_TEST 7 -+ -+ -+static const struct { -+ const char string[ETH_GSTRING_LEN]; -+} ethtool_test_keys[] = { -+ [TG3_NVRAM_TEST] = { "nvram test (online) " }, -+ [TG3_LINK_TEST] = { "link test (online) " }, -+ [TG3_REGISTER_TEST] = { "register test (offline)" }, -+ [TG3_MEMORY_TEST] = { "memory test (offline)" }, -+ [TG3_MAC_LOOPB_TEST] = { "mac loopback test (offline)" }, -+ [TG3_PHY_LOOPB_TEST] = { "phy loopback test (offline)" }, -+ [TG3_EXT_LOOPB_TEST] = { "ext loopback test (offline)" }, -+ [TG3_INTERRUPT_TEST] = { "interrupt test (offline)" }, -+}; -+ -+#define TG3_NUM_TEST ARRAY_SIZE(ethtool_test_keys) -+ -+ -+static void tg3_write32(struct tg3 *tp, u32 off, u32 val) -+{ -+ writel(val, tp->regs + off); -+} -+ -+static u32 tg3_read32(struct tg3 *tp, u32 off) -+{ -+ return readl(tp->regs + off); -+} -+ -+static void tg3_ape_write32(struct tg3 *tp, u32 off, u32 val) -+{ -+ writel(val, tp->aperegs + off); -+} -+ -+static u32 tg3_ape_read32(struct tg3 *tp, u32 off) -+{ -+ return readl(tp->aperegs + off); -+} -+ -+static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tp->indirect_lock, flags); -+ pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); -+ pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); -+ spin_unlock_irqrestore(&tp->indirect_lock, flags); -+} -+ -+static void tg3_write_flush_reg32(struct tg3 *tp, u32 off, u32 val) -+{ -+ writel(val, tp->regs + off); -+ readl(tp->regs + off); -+} -+ -+static u32 tg3_read_indirect_reg32(struct tg3 *tp, u32 off) -+{ -+ unsigned long flags; -+ u32 val; -+ -+ spin_lock_irqsave(&tp->indirect_lock, flags); -+ pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); -+ pci_read_config_dword(tp->pdev, TG3PCI_REG_DATA, &val); -+ spin_unlock_irqrestore(&tp->indirect_lock, flags); -+ return val; -+} -+ -+static void tg3_write_indirect_mbox(struct tg3 *tp, u32 off, u32 val) -+{ -+ unsigned long flags; -+ -+ if (off == (MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW)) { -+ pci_write_config_dword(tp->pdev, TG3PCI_RCV_RET_RING_CON_IDX + -+ TG3_64BIT_REG_LOW, val); -+ return; -+ } -+ if (off == TG3_RX_STD_PROD_IDX_REG) { -+ pci_write_config_dword(tp->pdev, TG3PCI_STD_RING_PROD_IDX + -+ TG3_64BIT_REG_LOW, val); -+ return; -+ } -+ -+ spin_lock_irqsave(&tp->indirect_lock, flags); -+ pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off + 0x5600); -+ pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); -+ spin_unlock_irqrestore(&tp->indirect_lock, flags); -+ -+ /* In indirect mode when disabling interrupts, we also need -+ * to clear the interrupt bit in the GRC local ctrl register. -+ */ -+ if ((off == (MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW)) && -+ (val == 0x1)) { -+ pci_write_config_dword(tp->pdev, TG3PCI_MISC_LOCAL_CTRL, -+ tp->grc_local_ctrl|GRC_LCLCTRL_CLEARINT); -+ } -+} -+ -+static u32 tg3_read_indirect_mbox(struct tg3 *tp, u32 off) -+{ -+ unsigned long flags; -+ u32 val; -+ -+ spin_lock_irqsave(&tp->indirect_lock, flags); -+ pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off + 0x5600); -+ pci_read_config_dword(tp->pdev, TG3PCI_REG_DATA, &val); -+ spin_unlock_irqrestore(&tp->indirect_lock, flags); -+ return val; -+} -+ -+/* usec_wait specifies the wait time in usec when writing to certain registers -+ * where it is unsafe to read back the register without some delay. -+ * GRC_LOCAL_CTRL is one example if the GPIOs are toggled to switch power. -+ * TG3PCI_CLOCK_CTRL is another example if the clock frequencies are changed. -+ */ -+static void _tw32_flush(struct tg3 *tp, u32 off, u32 val, u32 usec_wait) -+{ -+ if (tg3_flag(tp, PCIX_TARGET_HWBUG) || tg3_flag(tp, ICH_WORKAROUND)) -+ /* Non-posted methods */ -+ tp->write32(tp, off, val); -+ else { -+ /* Posted method */ -+ tg3_write32(tp, off, val); -+ if (usec_wait) -+ udelay(usec_wait); -+ tp->read32(tp, off); -+ } -+ /* Wait again after the read for the posted method to guarantee that -+ * the wait time is met. -+ */ -+ if (usec_wait) -+ udelay(usec_wait); -+} -+ -+static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val) -+{ -+ tp->write32_mbox(tp, off, val); -+ if (tg3_flag(tp, FLUSH_POSTED_WRITES) || -+ (!tg3_flag(tp, MBOX_WRITE_REORDER) && -+ !tg3_flag(tp, ICH_WORKAROUND))) -+ tp->read32_mbox(tp, off); -+} -+ -+static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val) -+{ -+ void __iomem *mbox = tp->regs + off; -+ writel(val, mbox); -+ if (tg3_flag(tp, TXD_MBOX_HWBUG)) -+ writel(val, mbox); -+ if (tg3_flag(tp, MBOX_WRITE_REORDER) || -+ tg3_flag(tp, FLUSH_POSTED_WRITES)) -+ readl(mbox); -+} -+ -+static u32 tg3_read32_mbox_5906(struct tg3 *tp, u32 off) -+{ -+ return readl(tp->regs + off + GRCMBOX_BASE); -+} -+ -+static void tg3_write32_mbox_5906(struct tg3 *tp, u32 off, u32 val) -+{ -+ writel(val, tp->regs + off + GRCMBOX_BASE); -+} -+ -+#define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val) -+#define tw32_mailbox_f(reg, val) tw32_mailbox_flush(tp, (reg), (val)) -+#define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val) -+#define tw32_tx_mbox(reg, val) tp->write32_tx_mbox(tp, reg, val) -+#define tr32_mailbox(reg) tp->read32_mbox(tp, reg) -+ -+#define tw32(reg, val) tp->write32(tp, reg, val) -+#define tw32_f(reg, val) _tw32_flush(tp, (reg), (val), 0) -+#define tw32_wait_f(reg, val, us) _tw32_flush(tp, (reg), (val), (us)) -+#define tr32(reg) tp->read32(tp, reg) -+ -+static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) -+{ -+ unsigned long flags; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5906 && -+ (off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC)) -+ return; -+ -+ spin_lock_irqsave(&tp->indirect_lock, flags); -+ if (tg3_flag(tp, SRAM_USE_CONFIG)) { -+ pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); -+ pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); -+ -+ /* Always leave this as zero. */ -+ pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); -+ } else { -+ tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); -+ tw32_f(TG3PCI_MEM_WIN_DATA, val); -+ -+ /* Always leave this as zero. */ -+ tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); -+ } -+ spin_unlock_irqrestore(&tp->indirect_lock, flags); -+} -+ -+static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) -+{ -+ unsigned long flags; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5906 && -+ (off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC)) { -+ *val = 0; -+ return; -+ } -+ -+ spin_lock_irqsave(&tp->indirect_lock, flags); -+ if (tg3_flag(tp, SRAM_USE_CONFIG)) { -+ pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); -+ pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); -+ -+ /* Always leave this as zero. */ -+ pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); -+ } else { -+ tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); -+ *val = tr32(TG3PCI_MEM_WIN_DATA); -+ -+ /* Always leave this as zero. */ -+ tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); -+ } -+ spin_unlock_irqrestore(&tp->indirect_lock, flags); -+} -+ -+static void tg3_ape_lock_init(struct tg3 *tp) -+{ -+ int i; -+ u32 regbase, bit; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5761) -+ regbase = TG3_APE_LOCK_GRANT; -+ else -+ regbase = TG3_APE_PER_LOCK_GRANT; -+ -+ /* Make sure the driver hasn't any stale locks. */ -+ for (i = TG3_APE_LOCK_PHY0; i <= TG3_APE_LOCK_GPIO; i++) { -+ switch (i) { -+ case TG3_APE_LOCK_PHY0: -+ case TG3_APE_LOCK_PHY1: -+ case TG3_APE_LOCK_PHY2: -+ case TG3_APE_LOCK_PHY3: -+ bit = APE_LOCK_GRANT_DRIVER; -+ break; -+ default: -+ if (!tp->pci_fn) -+ bit = APE_LOCK_GRANT_DRIVER; -+ else -+ bit = 1 << tp->pci_fn; -+ } -+ tg3_ape_write32(tp, regbase + 4 * i, bit); -+ } -+ -+} -+ -+static int tg3_ape_lock(struct tg3 *tp, int locknum) -+{ -+ int i, off; -+ int ret = 0; -+ u32 status, req, gnt, bit; -+ -+ if (!tg3_flag(tp, ENABLE_APE)) -+ return 0; -+ -+ switch (locknum) { -+ case TG3_APE_LOCK_GPIO: -+ if (tg3_asic_rev(tp) == ASIC_REV_5761) -+ return 0; -+ case TG3_APE_LOCK_GRC: -+ case TG3_APE_LOCK_MEM: -+ if (!tp->pci_fn) -+ bit = APE_LOCK_REQ_DRIVER; -+ else -+ bit = 1 << tp->pci_fn; -+ break; -+ case TG3_APE_LOCK_PHY0: -+ case TG3_APE_LOCK_PHY1: -+ case TG3_APE_LOCK_PHY2: -+ case TG3_APE_LOCK_PHY3: -+ bit = APE_LOCK_REQ_DRIVER; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5761) { -+ req = TG3_APE_LOCK_REQ; -+ gnt = TG3_APE_LOCK_GRANT; -+ } else { -+ req = TG3_APE_PER_LOCK_REQ; -+ gnt = TG3_APE_PER_LOCK_GRANT; -+ } -+ -+ off = 4 * locknum; -+ -+ tg3_ape_write32(tp, req + off, bit); -+ -+ /* Wait for up to 1 millisecond to acquire lock. */ -+ for (i = 0; i < 100; i++) { -+ status = tg3_ape_read32(tp, gnt + off); -+ if (status == bit) -+ break; -+ if (pci_channel_offline(tp->pdev)) -+ break; -+ -+ udelay(10); -+ } -+ -+ if (status != bit) { -+ /* Revoke the lock request. */ -+ tg3_ape_write32(tp, gnt + off, bit); -+ ret = -EBUSY; -+ } -+ -+ return ret; -+} -+ -+static void tg3_ape_unlock(struct tg3 *tp, int locknum) -+{ -+ u32 gnt, bit; -+ -+ if (!tg3_flag(tp, ENABLE_APE)) -+ return; -+ -+ switch (locknum) { -+ case TG3_APE_LOCK_GPIO: -+ if (tg3_asic_rev(tp) == ASIC_REV_5761) -+ return; -+ case TG3_APE_LOCK_GRC: -+ case TG3_APE_LOCK_MEM: -+ if (!tp->pci_fn) -+ bit = APE_LOCK_GRANT_DRIVER; -+ else -+ bit = 1 << tp->pci_fn; -+ break; -+ case TG3_APE_LOCK_PHY0: -+ case TG3_APE_LOCK_PHY1: -+ case TG3_APE_LOCK_PHY2: -+ case TG3_APE_LOCK_PHY3: -+ bit = APE_LOCK_GRANT_DRIVER; -+ break; -+ default: -+ return; -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5761) -+ gnt = TG3_APE_LOCK_GRANT; -+ else -+ gnt = TG3_APE_PER_LOCK_GRANT; -+ -+ tg3_ape_write32(tp, gnt + 4 * locknum, bit); -+} -+ -+static int tg3_ape_event_lock(struct tg3 *tp, u32 timeout_us) -+{ -+ u32 apedata; -+ -+ while (timeout_us) { -+ if (tg3_ape_lock(tp, TG3_APE_LOCK_MEM)) -+ return -EBUSY; -+ -+ apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS); -+ if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING)) -+ break; -+ -+ tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); -+ -+#if defined(__VMKLNX__) || (LINUX_VERSION_CODE < 0x020627) /* 2.6.39 */ -+ udelay(10); -+#else -+ usleep_range(10, 20); -+#endif -+ timeout_us -= (timeout_us > 10) ? 10 : timeout_us; -+ } -+ -+ return timeout_us ? 0 : -EBUSY; -+} -+ -+/* ESX needs tg3_ape_scratchpad_read for FW dump for ESX 5.5 and after */ -+#if (IS_ENABLED(CONFIG_HWMON) && !defined(__VMKLNX__)) || \ -+ (defined(__VMKLNX__) && VMWARE_ESX_DDK_VERSION >= 55000) -+static int tg3_ape_wait_for_event(struct tg3 *tp, u32 timeout_us) -+{ -+ u32 i, apedata; -+ -+ for (i = 0; i < timeout_us / 10; i++) { -+ apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS); -+ -+ if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING)) -+ break; -+ -+ udelay(10); -+ } -+ -+ return i == timeout_us / 10; -+} -+ -+static int tg3_ape_scratchpad_read(struct tg3 *tp, u32 *data, u32 base_off, -+ u32 len) -+{ -+ int err; -+ u32 i, bufoff, msgoff, maxlen, apedata; -+ -+ if (!tg3_flag(tp, APE_HAS_NCSI)) -+ return 0; -+ -+ apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG); -+ if (apedata != APE_SEG_SIG_MAGIC) -+ return -ENODEV; -+ -+ apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS); -+ if (!(apedata & APE_FW_STATUS_READY)) -+ return -EAGAIN; -+ -+ bufoff = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_OFF) + -+ TG3_APE_SHMEM_BASE; -+ msgoff = bufoff + 2 * sizeof(u32); -+ maxlen = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_LEN); -+ -+ while (len) { -+ u32 length; -+ -+ /* Cap xfer sizes to scratchpad limits. */ -+ length = (len > maxlen) ? maxlen : len; -+ len -= length; -+ -+ apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS); -+ if (!(apedata & APE_FW_STATUS_READY)) -+ return -EAGAIN; -+ -+ /* Wait for up to 1 msec for APE to service previous event. */ -+ err = tg3_ape_event_lock(tp, 1000); -+ if (err) -+ return err; -+ -+ apedata = APE_EVENT_STATUS_DRIVER_EVNT | -+ APE_EVENT_STATUS_SCRTCHPD_READ | -+ APE_EVENT_STATUS_EVENT_PENDING; -+ tg3_ape_write32(tp, TG3_APE_EVENT_STATUS, apedata); -+ -+ tg3_ape_write32(tp, bufoff, base_off); -+ tg3_ape_write32(tp, bufoff + sizeof(u32), length); -+ -+ tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); -+ tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1); -+ -+ base_off += length; -+ -+ if (tg3_ape_wait_for_event(tp, 30000)) -+ return -EAGAIN; -+ -+ for (i = 0; length; i += 4, length -= 4) { -+ u32 val = tg3_ape_read32(tp, msgoff + i); -+ memcpy(data, &val, sizeof(u32)); -+ data++; -+ } -+ } -+ -+ return 0; -+} -+#endif -+ -+static int tg3_ape_send_event(struct tg3 *tp, u32 event) -+{ -+ int err; -+ u32 apedata; -+ -+ apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG); -+ if (apedata != APE_SEG_SIG_MAGIC) -+ return -EAGAIN; -+ -+ apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS); -+ if (!(apedata & APE_FW_STATUS_READY)) -+ return -EAGAIN; -+ -+ /* Wait for up to 20 millisecond for APE to service previous event. */ -+ err = tg3_ape_event_lock(tp, 20000); -+ if (err) -+ return err; -+ -+ tg3_ape_write32(tp, TG3_APE_EVENT_STATUS, -+ event | APE_EVENT_STATUS_EVENT_PENDING); -+ -+ tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); -+ tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1); -+ -+ return 0; -+} -+ -+static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) -+{ -+ u32 event; -+ u32 apedata; -+ -+ if (!tg3_flag(tp, ENABLE_APE)) -+ return; -+ -+ switch (kind) { -+ case RESET_KIND_INIT: -+ tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_COUNT, tp->ape_hb++); -+ tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, -+ APE_HOST_SEG_SIG_MAGIC); -+ tg3_ape_write32(tp, TG3_APE_HOST_SEG_LEN, -+ APE_HOST_SEG_LEN_MAGIC); -+ apedata = tg3_ape_read32(tp, TG3_APE_HOST_INIT_COUNT); -+ tg3_ape_write32(tp, TG3_APE_HOST_INIT_COUNT, ++apedata); -+ tg3_ape_write32(tp, TG3_APE_HOST_DRIVER_ID, -+ APE_HOST_DRIVER_ID_MAGIC(TG3_MAJ_NUM, -+ TG3_MIN_NUM, -+ TG3_REVISION[0])); -+ tg3_ape_write32(tp, TG3_APE_HOST_BEHAVIOR, -+ APE_HOST_BEHAV_NO_PHYLOCK); -+ tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE, -+ TG3_APE_HOST_DRVR_STATE_START); -+ -+ event = APE_EVENT_STATUS_STATE_START; -+ break; -+ case RESET_KIND_SHUTDOWN: -+ if (device_may_wakeup(&tp->pdev->dev) && -+ tg3_flag(tp, WOL_ENABLE)) { -+ tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED, -+ TG3_APE_HOST_WOL_SPEED_AUTO); -+ apedata = TG3_APE_HOST_DRVR_STATE_WOL; -+ } else -+ apedata = TG3_APE_HOST_DRVR_STATE_UNLOAD; -+ -+ tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE, apedata); -+ -+ event = APE_EVENT_STATUS_STATE_UNLOAD; -+ break; -+ default: -+ return; -+ } -+ -+ event |= APE_EVENT_STATUS_DRIVER_EVNT | APE_EVENT_STATUS_STATE_CHNGE; -+ -+ tg3_ape_send_event(tp, event); -+} -+ -+static void tg3_disable_ints(struct tg3 *tp) -+{ -+ int i; -+ -+ tw32(TG3PCI_MISC_HOST_CTRL, -+ (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT)); -+ for (i = 0; i < tp->irq_max; i++) -+ tw32_mailbox_f(tp->napi[i].int_mbox, 0x00000001); -+} -+ -+static void tg3_enable_ints(struct tg3 *tp) -+{ -+ int i; -+ -+ tp->irq_sync = 0; -+ wmb(); -+ -+ tw32(TG3PCI_MISC_HOST_CTRL, -+ (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); -+ -+ tp->coal_now = tp->coalesce_mode | HOSTCC_MODE_ENABLE; -+ for (i = 0; i < tp->irq_cnt; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ -+ tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24); -+ if (tg3_flag(tp, 1SHOT_MSI)) -+ tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24); -+ -+ tp->coal_now |= tnapi->coal_now; -+ } -+ -+ /* Force an initial interrupt */ -+ if (!tg3_flag(tp, TAGGED_STATUS) && -+#if defined(__VMKLNX__) -+ tp->napi[0].hw_status && -+#endif -+ (tp->napi[0].hw_status->status & SD_STATUS_UPDATED)) -+ tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); -+ else -+ tw32(HOSTCC_MODE, tp->coal_now); -+ -+#ifndef TG3_INBOX -+ if (tp->irq_cnt > 1) -+ tp->coal_now &= ~(tp->napi[0].coal_now | tp->napi[1].coal_now); -+ else -+ tp->coal_now &= ~(tp->napi[0].coal_now); -+#else -+ tp->coal_now &= ~(tp->napi[0].coal_now); -+#endif -+} -+ -+static inline unsigned int tg3_has_work(struct tg3_napi *tnapi) -+{ -+ struct tg3 *tp = tnapi->tp; -+ struct tg3_hw_status *sblk = tnapi->hw_status; -+ unsigned int work_exists = 0; -+ -+ /* check for phy events */ -+ if (!(tg3_flag(tp, USE_LINKCHG_REG) || tg3_flag(tp, POLL_SERDES))) { -+ if (sblk->status & SD_STATUS_LINK_CHG) -+ work_exists = 1; -+ } -+ -+ /* check for TX work to do */ -+ if (sblk->idx[0].tx_consumer != tnapi->tx_cons) -+ work_exists = 1; -+ -+ /* check for RX work to do */ -+ if (tnapi->rx_rcb_prod_idx && -+ *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr) -+ work_exists = 1; -+ -+ return work_exists; -+} -+ -+/* tg3_int_reenable -+ * similar to tg3_enable_ints, but it accurately determines whether there -+ * is new work pending and can return without flushing the PIO write -+ * which reenables interrupts -+ */ -+static void tg3_int_reenable(struct tg3_napi *tnapi) -+{ -+ struct tg3 *tp = tnapi->tp; -+ -+ tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24); -+ mmiowb(); -+ -+ /* When doing tagged status, this work check is unnecessary. -+ * The last_tag we write above tells the chip which piece of -+ * work we've completed. -+ */ -+ if (!tg3_flag(tp, TAGGED_STATUS) && tg3_has_work(tnapi)) -+ tw32(HOSTCC_MODE, tp->coalesce_mode | -+ HOSTCC_MODE_ENABLE | tnapi->coal_now); -+} -+ -+static void tg3_switch_clocks(struct tg3 *tp) -+{ -+ u32 clock_ctrl; -+ u32 orig_clock_ctrl; -+ -+ if (tg3_flag(tp, CPMU_PRESENT) || tg3_flag(tp, 5780_CLASS)) -+ return; -+ -+ clock_ctrl = tr32(TG3PCI_CLOCK_CTRL); -+ -+ orig_clock_ctrl = clock_ctrl; -+ clock_ctrl &= (CLOCK_CTRL_FORCE_CLKRUN | -+ CLOCK_CTRL_CLKRUN_OENABLE | -+ 0x1f); -+ tp->pci_clock_ctrl = clock_ctrl; -+ -+ if (tg3_flag(tp, 5705_PLUS)) { -+ if (orig_clock_ctrl & CLOCK_CTRL_625_CORE) { -+ tw32_wait_f(TG3PCI_CLOCK_CTRL, -+ clock_ctrl | CLOCK_CTRL_625_CORE, 40); -+ } -+ } else if ((orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) { -+ tw32_wait_f(TG3PCI_CLOCK_CTRL, -+ clock_ctrl | -+ (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK), -+ 40); -+ tw32_wait_f(TG3PCI_CLOCK_CTRL, -+ clock_ctrl | (CLOCK_CTRL_ALTCLK), -+ 40); -+ } -+ tw32_wait_f(TG3PCI_CLOCK_CTRL, clock_ctrl, 40); -+} -+ -+#define PHY_BUSY_LOOPS 5000 -+ -+static int __tg3_readphy(struct tg3 *tp, unsigned int phy_addr, int reg, -+ u32 *val) -+{ -+ u32 frame_val; -+ unsigned int loops; -+ int ret; -+ -+ if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { -+ tw32_f(MAC_MI_MODE, -+ (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL)); -+ udelay(80); -+ } -+ -+ tg3_ape_lock(tp, tp->phy_ape_lock); -+ -+ *val = 0x0; -+ -+ frame_val = ((phy_addr << MI_COM_PHY_ADDR_SHIFT) & -+ MI_COM_PHY_ADDR_MASK); -+ frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) & -+ MI_COM_REG_ADDR_MASK); -+ frame_val |= (MI_COM_CMD_READ | MI_COM_START); -+ -+ tw32_f(MAC_MI_COM, frame_val); -+ -+ loops = PHY_BUSY_LOOPS; -+ while (loops != 0) { -+ udelay(10); -+ frame_val = tr32(MAC_MI_COM); -+ -+ if ((frame_val & MI_COM_BUSY) == 0) { -+ udelay(5); -+ frame_val = tr32(MAC_MI_COM); -+ break; -+ } -+ loops -= 1; -+ } -+ -+ ret = -EBUSY; -+ if (loops != 0) { -+ *val = frame_val & MI_COM_DATA_MASK; -+ ret = 0; -+ } -+ -+ if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { -+ tw32_f(MAC_MI_MODE, tp->mi_mode); -+ udelay(80); -+ } -+ -+ tg3_ape_unlock(tp, tp->phy_ape_lock); -+ -+ return ret; -+} -+ -+static int tg3_readphy(struct tg3 *tp, int reg, u32 *val) -+{ -+ return __tg3_readphy(tp, tp->phy_addr, reg, val); -+} -+ -+static int __tg3_writephy(struct tg3 *tp, unsigned int phy_addr, int reg, -+ u32 val) -+{ -+ u32 frame_val; -+ unsigned int loops; -+ int ret; -+ -+ if ((tp->phy_flags & TG3_PHYFLG_IS_FET) && -+ (reg == MII_CTRL1000 || reg == MII_TG3_AUX_CTRL)) -+ return 0; -+ -+ if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { -+ tw32_f(MAC_MI_MODE, -+ (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL)); -+ udelay(80); -+ } -+ -+ tg3_ape_lock(tp, tp->phy_ape_lock); -+ -+ frame_val = ((phy_addr << MI_COM_PHY_ADDR_SHIFT) & -+ MI_COM_PHY_ADDR_MASK); -+ frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) & -+ MI_COM_REG_ADDR_MASK); -+ frame_val |= (val & MI_COM_DATA_MASK); -+ frame_val |= (MI_COM_CMD_WRITE | MI_COM_START); -+ -+ tw32_f(MAC_MI_COM, frame_val); -+ -+ loops = PHY_BUSY_LOOPS; -+ while (loops != 0) { -+ udelay(10); -+ frame_val = tr32(MAC_MI_COM); -+ if ((frame_val & MI_COM_BUSY) == 0) { -+ udelay(5); -+ frame_val = tr32(MAC_MI_COM); -+ break; -+ } -+ loops -= 1; -+ } -+ -+ ret = -EBUSY; -+ if (loops != 0) -+ ret = 0; -+ -+ if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { -+ tw32_f(MAC_MI_MODE, tp->mi_mode); -+ udelay(80); -+ } -+ -+ tg3_ape_unlock(tp, tp->phy_ape_lock); -+ -+ return ret; -+} -+ -+static int tg3_writephy(struct tg3 *tp, int reg, u32 val) -+{ -+ return __tg3_writephy(tp, tp->phy_addr, reg, val); -+} -+ -+static int tg3_phy_cl45_write(struct tg3 *tp, u32 devad, u32 addr, u32 val) -+{ -+ int err; -+ -+ err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad); -+ if (err) -+ goto done; -+ -+ err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr); -+ if (err) -+ goto done; -+ -+ err = tg3_writephy(tp, MII_TG3_MMD_CTRL, -+ MII_TG3_MMD_CTRL_DATA_NOINC | devad); -+ if (err) -+ goto done; -+ -+ err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, val); -+ -+done: -+ return err; -+} -+ -+static int tg3_phy_cl45_read(struct tg3 *tp, u32 devad, u32 addr, u32 *val) -+{ -+ int err; -+ -+ err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad); -+ if (err) -+ goto done; -+ -+ err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr); -+ if (err) -+ goto done; -+ -+ err = tg3_writephy(tp, MII_TG3_MMD_CTRL, -+ MII_TG3_MMD_CTRL_DATA_NOINC | devad); -+ if (err) -+ goto done; -+ -+ err = tg3_readphy(tp, MII_TG3_MMD_ADDRESS, val); -+ -+done: -+ return err; -+} -+ -+static int tg3_phydsp_read(struct tg3 *tp, u32 reg, u32 *val) -+{ -+ int err; -+ -+ err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg); -+ if (!err) -+ err = tg3_readphy(tp, MII_TG3_DSP_RW_PORT, val); -+ -+ return err; -+} -+ -+static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val) -+{ -+ int err; -+ -+ err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg); -+ if (!err) -+ err = tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val); -+ -+ return err; -+} -+ -+static int tg3_phy_auxctl_read(struct tg3 *tp, int reg, u32 *val) -+{ -+ int err; -+ -+ err = tg3_writephy(tp, MII_TG3_AUX_CTRL, -+ (reg << MII_TG3_AUXCTL_MISC_RDSEL_SHIFT) | -+ MII_TG3_AUXCTL_SHDWSEL_MISC); -+ if (!err) -+ err = tg3_readphy(tp, MII_TG3_AUX_CTRL, val); -+ -+ return err; -+} -+ -+static int tg3_phy_auxctl_write(struct tg3 *tp, int reg, u32 set) -+{ -+ if (reg == MII_TG3_AUXCTL_SHDWSEL_MISC) -+ set |= MII_TG3_AUXCTL_MISC_WREN; -+ -+ return tg3_writephy(tp, MII_TG3_AUX_CTRL, set | reg); -+} -+ -+static int tg3_phy_toggle_auxctl_smdsp(struct tg3 *tp, bool enable) -+{ -+ u32 val; -+ int err; -+ -+ err = tg3_phy_auxctl_read(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, &val); -+ -+ if (err) -+ return err; -+ -+ if (enable) -+ val |= MII_TG3_AUXCTL_ACTL_SMDSP_ENA; -+ else -+ val &= ~MII_TG3_AUXCTL_ACTL_SMDSP_ENA; -+ -+ err = tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, -+ val | MII_TG3_AUXCTL_ACTL_TX_6DB); -+ -+ return err; -+} -+ -+static int tg3_phy_shdw_read(struct tg3 *tp, int reg, u32 *val) -+{ -+ int err; -+ -+ err = tg3_writephy(tp, MII_TG3_MISC_SHDW, reg); -+ if (!err) -+ err = tg3_readphy(tp, MII_TG3_MISC_SHDW, val); -+ -+ return err; -+} -+ -+static int tg3_phy_shdw_write(struct tg3 *tp, int reg, u32 val) -+{ -+ return tg3_writephy(tp, MII_TG3_MISC_SHDW, -+ reg | val | MII_TG3_MISC_SHDW_WREN); -+} -+ -+static int tg3_bmcr_reset(struct tg3 *tp) -+{ -+ u32 phy_control; -+ int limit, err; -+ -+ /* OK, reset it, and poll the BMCR_RESET bit until it -+ * clears or we time out. -+ */ -+ phy_control = BMCR_RESET; -+ err = tg3_writephy(tp, MII_BMCR, phy_control); -+ if (err != 0) -+ return -EBUSY; -+ -+ limit = 5000; -+ while (limit--) { -+ err = tg3_readphy(tp, MII_BMCR, &phy_control); -+ if (err != 0) -+ return -EBUSY; -+ -+ if ((phy_control & BMCR_RESET) == 0) { -+ udelay(40); -+ break; -+ } -+ udelay(10); -+ } -+ if (limit < 0) -+ return -EBUSY; -+ -+ return 0; -+} -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg) -+{ -+ struct tg3 *tp = bp->priv; -+ u32 val; -+ -+ spin_lock_bh(&tp->lock); -+ -+ if (__tg3_readphy(tp, mii_id, reg, &val)) -+ val = -EIO; -+ -+ spin_unlock_bh(&tp->lock); -+ -+ return val; -+} -+ -+static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val) -+{ -+ struct tg3 *tp = bp->priv; -+ u32 ret = 0; -+ -+ spin_lock_bh(&tp->lock); -+ -+ if (__tg3_writephy(tp, mii_id, reg, val)) -+ ret = -EIO; -+ -+ spin_unlock_bh(&tp->lock); -+ -+ return ret; -+} -+ -+static int tg3_mdio_reset(struct mii_bus *bp) -+{ -+ return 0; -+} -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+ -+static void tg3_mdio_config_5785(struct tg3 *tp) -+{ -+ u32 val; -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ struct phy_device *phydev; -+ -+ phydev = tp->mdio_bus->phy_map[tp->phy_addr]; -+ switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) { -+ case PHY_ID_BCM50610: -+ case PHY_ID_BCM50610M: -+ case PHY_ID_BCM50612E: -+ val = MAC_PHYCFG2_50610_LED_MODES; -+ break; -+ case PHY_ID_BCMAC131: -+ val = MAC_PHYCFG2_AC131_LED_MODES; -+ break; -+ case PHY_ID_RTL8211C: -+ val = MAC_PHYCFG2_RTL8211C_LED_MODES; -+ break; -+ case PHY_ID_RTL8201E: -+ val = MAC_PHYCFG2_RTL8201E_LED_MODES; -+ break; -+ default: -+ return; -+ } -+ -+ if (phydev->interface != PHY_INTERFACE_MODE_RGMII) { -+ tw32(MAC_PHYCFG2, val); -+ -+ val = tr32(MAC_PHYCFG1); -+ val &= ~(MAC_PHYCFG1_RGMII_INT | -+ MAC_PHYCFG1_RXCLK_TO_MASK | MAC_PHYCFG1_TXCLK_TO_MASK); -+ val |= MAC_PHYCFG1_RXCLK_TIMEOUT | MAC_PHYCFG1_TXCLK_TIMEOUT; -+ tw32(MAC_PHYCFG1, val); -+ -+ return; -+ } -+#else -+ if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCMAC131) { -+ tw32(MAC_PHYCFG2, MAC_PHYCFG2_AC131_LED_MODES); -+ -+ val = tr32(MAC_PHYCFG1); -+ val &= ~(MAC_PHYCFG1_RGMII_INT | -+ MAC_PHYCFG1_RXCLK_TO_MASK | MAC_PHYCFG1_TXCLK_TO_MASK); -+ val |= MAC_PHYCFG1_RXCLK_TIMEOUT | MAC_PHYCFG1_TXCLK_TIMEOUT; -+ tw32(MAC_PHYCFG1, val); -+ -+ return; -+ } -+ -+ val = MAC_PHYCFG2_50610_LED_MODES; -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+ -+ if (!tg3_flag(tp, RGMII_INBAND_DISABLE)) -+ val |= MAC_PHYCFG2_EMODE_MASK_MASK | -+ MAC_PHYCFG2_FMODE_MASK_MASK | -+ MAC_PHYCFG2_GMODE_MASK_MASK | -+ MAC_PHYCFG2_ACT_MASK_MASK | -+ MAC_PHYCFG2_QUAL_MASK_MASK | -+ MAC_PHYCFG2_INBAND_ENABLE; -+ -+ tw32(MAC_PHYCFG2, val); -+ -+ val = tr32(MAC_PHYCFG1); -+ val &= ~(MAC_PHYCFG1_RXCLK_TO_MASK | MAC_PHYCFG1_TXCLK_TO_MASK | -+ MAC_PHYCFG1_RGMII_EXT_RX_DEC | MAC_PHYCFG1_RGMII_SND_STAT_EN); -+ if (!tg3_flag(tp, RGMII_INBAND_DISABLE)) { -+ if (tg3_flag(tp, RGMII_EXT_IBND_RX_EN)) -+ val |= MAC_PHYCFG1_RGMII_EXT_RX_DEC; -+ if (tg3_flag(tp, RGMII_EXT_IBND_TX_EN)) -+ val |= MAC_PHYCFG1_RGMII_SND_STAT_EN; -+ } -+ val |= MAC_PHYCFG1_RXCLK_TIMEOUT | MAC_PHYCFG1_TXCLK_TIMEOUT | -+ MAC_PHYCFG1_RGMII_INT | MAC_PHYCFG1_TXC_DRV; -+ tw32(MAC_PHYCFG1, val); -+ -+ val = tr32(MAC_EXT_RGMII_MODE); -+ val &= ~(MAC_RGMII_MODE_RX_INT_B | -+ MAC_RGMII_MODE_RX_QUALITY | -+ MAC_RGMII_MODE_RX_ACTIVITY | -+ MAC_RGMII_MODE_RX_ENG_DET | -+ MAC_RGMII_MODE_TX_ENABLE | -+ MAC_RGMII_MODE_TX_LOWPWR | -+ MAC_RGMII_MODE_TX_RESET); -+ if (!tg3_flag(tp, RGMII_INBAND_DISABLE)) { -+ if (tg3_flag(tp, RGMII_EXT_IBND_RX_EN)) -+ val |= MAC_RGMII_MODE_RX_INT_B | -+ MAC_RGMII_MODE_RX_QUALITY | -+ MAC_RGMII_MODE_RX_ACTIVITY | -+ MAC_RGMII_MODE_RX_ENG_DET; -+ if (tg3_flag(tp, RGMII_EXT_IBND_TX_EN)) -+ val |= MAC_RGMII_MODE_TX_ENABLE | -+ MAC_RGMII_MODE_TX_LOWPWR | -+ MAC_RGMII_MODE_TX_RESET; -+ } -+ tw32(MAC_EXT_RGMII_MODE, val); -+} -+ -+static void tg3_mdio_start(struct tg3 *tp) -+{ -+ tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL; -+ tw32_f(MAC_MI_MODE, tp->mi_mode); -+ udelay(80); -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_flag(tp, MDIOBUS_INITED) && -+ tg3_asic_rev(tp) == ASIC_REV_5785) -+ tg3_mdio_config_5785(tp); -+#else -+ if (tg3_asic_rev(tp) != ASIC_REV_5785) -+ return; -+ -+ tg3_mdio_config_5785(tp); -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_IS_FET)) { -+ u32 val; -+ -+ /* FIXME -- This shouldn't be required, but without -+ * it, the device will not pass traffic until -+ * the phy is reset via a link up event or -+ * through a change in speed settings. -+ */ -+ tg3_phy_auxctl_read(tp, MII_TG3_AUXCTL_SHDWSEL_MISC, &val); -+ if (tg3_flag(tp, RGMII_INBAND_DISABLE)) -+ val |= MII_TG3_AUXCTL_MISC_RGMII_OOBSC; -+ else -+ val &= ~MII_TG3_AUXCTL_MISC_RGMII_OOBSC; -+ tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_MISC, val); -+ } -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+} -+ -+static int tg3_mdio_init(struct tg3 *tp) -+{ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ int i; -+ u32 reg; -+ struct phy_device *phydev; -+#endif -+ -+ if (tg3_flag(tp, 5717_PLUS)) { -+ u32 is_serdes; -+ -+ tp->phy_addr = tp->pci_fn + 1; -+ -+ if (tg3_chip_rev_id(tp) != CHIPREV_ID_5717_A0) -+ is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES; -+ else -+ is_serdes = tr32(TG3_CPMU_PHY_STRAP) & -+ TG3_CPMU_PHY_STRAP_IS_SERDES; -+ if (is_serdes) -+ tp->phy_addr += 7; -+ } else if (tg3_flag(tp, IS_SSB_CORE) && tg3_flag(tp, ROBOSWITCH)) { -+ int addr; -+ -+ addr = ssb_gige_get_phyaddr(tp->pdev); -+ if (addr < 0) -+ return addr; -+ tp->phy_addr = addr; -+ } else -+ tp->phy_addr = TG3_PHY_MII_ADDR; -+ -+ tg3_mdio_start(tp); -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (!tg3_flag(tp, USE_PHYLIB) || tg3_flag(tp, MDIOBUS_INITED)) -+ return 0; -+ -+ tp->mdio_bus = mdiobus_alloc(); -+ if (tp->mdio_bus == NULL) -+ return -ENOMEM; -+ -+ tp->mdio_bus->name = "tg3 mdio bus"; -+#ifdef MII_BUS_ID_SIZE -+ snprintf(tp->mdio_bus->id, MII_BUS_ID_SIZE, "%x", -+ (tp->pdev->bus->number << 8) | tp->pdev->devfn); -+#else -+ tp->mdio_bus->id = tp->pdev->devfn; -+#endif -+ tp->mdio_bus->priv = tp; -+#ifdef BCM_MDIOBUS_HAS_PARENT -+ tp->mdio_bus->parent = &tp->pdev->dev; -+#endif -+ tp->mdio_bus->read = &tg3_mdio_read; -+ tp->mdio_bus->write = &tg3_mdio_write; -+ tp->mdio_bus->reset = &tg3_mdio_reset; -+ tp->mdio_bus->phy_mask = ~(1 << tp->phy_addr); -+ tp->mdio_bus->irq = &tp->mdio_irq[0]; -+ -+ for (i = 0; i < PHY_MAX_ADDR; i++) -+ tp->mdio_bus->irq[i] = PHY_POLL; -+ -+ /* The bus registration will look for all the PHYs on the mdio bus. -+ * Unfortunately, it does not ensure the PHY is powered up before -+ * accessing the PHY ID registers. A chip reset is the -+ * quickest way to bring the device back to an operational state.. -+ */ -+ if (tg3_readphy(tp, MII_BMCR, ®) || (reg & BMCR_PDOWN)) -+ tg3_bmcr_reset(tp); -+ -+ i = mdiobus_register(tp->mdio_bus); -+ if (i) { -+ dev_warn(&tp->pdev->dev, "mdiobus_reg failed (0x%x)\n", i); -+ mdiobus_free(tp->mdio_bus); -+ return i; -+ } -+ -+ phydev = tp->mdio_bus->phy_map[tp->phy_addr]; -+ -+ if (!phydev || !phydev->drv) { -+ dev_warn(&tp->pdev->dev, "No PHY devices\n"); -+ mdiobus_unregister(tp->mdio_bus); -+ mdiobus_free(tp->mdio_bus); -+ return -ENODEV; -+ } -+ -+ switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) { -+ case PHY_ID_BCM57780: -+ phydev->interface = PHY_INTERFACE_MODE_GMII; -+ phydev->dev_flags |= PHY_BRCM_AUTO_PWRDWN_ENABLE; -+ break; -+ case PHY_ID_BCM50610: -+ case PHY_ID_BCM50610M: -+ case PHY_ID_BCM50612E: -+ phydev->dev_flags |= PHY_BRCM_CLEAR_RGMII_MODE | -+ PHY_BRCM_RX_REFCLK_UNUSED | -+ PHY_BRCM_DIS_TXCRXC_NOENRGY | -+ PHY_BRCM_AUTO_PWRDWN_ENABLE; -+ if (tg3_flag(tp, RGMII_INBAND_DISABLE)) -+ phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE; -+ if (tg3_flag(tp, RGMII_EXT_IBND_RX_EN)) -+ phydev->dev_flags |= PHY_BRCM_EXT_IBND_RX_ENABLE; -+ if (tg3_flag(tp, RGMII_EXT_IBND_TX_EN)) -+ phydev->dev_flags |= PHY_BRCM_EXT_IBND_TX_ENABLE; -+ /* fallthru */ -+ case PHY_ID_RTL8211C: -+ phydev->interface = PHY_INTERFACE_MODE_RGMII; -+ break; -+ case PHY_ID_RTL8201E: -+ case PHY_ID_BCMAC131: -+ phydev->interface = PHY_INTERFACE_MODE_MII; -+ phydev->dev_flags |= PHY_BRCM_AUTO_PWRDWN_ENABLE; -+ tp->phy_flags |= TG3_PHYFLG_IS_FET; -+ break; -+ } -+ -+ tg3_flag_set(tp, MDIOBUS_INITED); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5785) -+ tg3_mdio_config_5785(tp); -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+ -+ return 0; -+} -+ -+static void tg3_mdio_fini(struct tg3 *tp) -+{ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_flag(tp, MDIOBUS_INITED)) { -+ tg3_flag_clear(tp, MDIOBUS_INITED); -+ mdiobus_unregister(tp->mdio_bus); -+ mdiobus_free(tp->mdio_bus); -+ } -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+} -+ -+/* tp->lock is held. */ -+static inline void tg3_generate_fw_event(struct tg3 *tp) -+{ -+ u32 val; -+ -+ val = tr32(GRC_RX_CPU_EVENT); -+ val |= GRC_RX_CPU_DRIVER_EVENT; -+ tw32_f(GRC_RX_CPU_EVENT, val); -+ -+ tp->last_event_jiffies = jiffies; -+} -+ -+#define TG3_FW_EVENT_TIMEOUT_USEC 2500 -+ -+/* tp->lock is held. */ -+static void tg3_wait_for_event_ack(struct tg3 *tp) -+{ -+ int i; -+ unsigned int delay_cnt; -+ long time_remain; -+ -+ /* If enough time has passed, no wait is necessary. */ -+ time_remain = (long)(tp->last_event_jiffies + 1 + -+ usecs_to_jiffies(TG3_FW_EVENT_TIMEOUT_USEC)) - -+ (long)jiffies; -+ if (time_remain < 0) -+ return; -+ -+ /* Check if we can shorten the wait time. */ -+ delay_cnt = jiffies_to_usecs(time_remain); -+ if (delay_cnt > TG3_FW_EVENT_TIMEOUT_USEC) -+ delay_cnt = TG3_FW_EVENT_TIMEOUT_USEC; -+ delay_cnt = (delay_cnt >> 3) + 1; -+ -+ for (i = 0; i < delay_cnt; i++) { -+ if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT)) -+ break; -+ if (pci_channel_offline(tp->pdev)) -+ break; -+ -+ udelay(8); -+ } -+} -+ -+/* tp->lock is held. */ -+static void tg3_phy_gather_ump_data(struct tg3 *tp, u32 *data) -+{ -+ u32 reg, val; -+ -+ val = 0; -+ if (!tg3_readphy(tp, MII_BMCR, ®)) -+ val = reg << 16; -+ if (!tg3_readphy(tp, MII_BMSR, ®)) -+ val |= (reg & 0xffff); -+ *data++ = val; -+ -+ val = 0; -+ if (!tg3_readphy(tp, MII_ADVERTISE, ®)) -+ val = reg << 16; -+ if (!tg3_readphy(tp, MII_LPA, ®)) -+ val |= (reg & 0xffff); -+ *data++ = val; -+ -+ val = 0; -+ if (!(tp->phy_flags & TG3_PHYFLG_MII_SERDES)) { -+ if (!tg3_readphy(tp, MII_CTRL1000, ®)) -+ val = reg << 16; -+ if (!tg3_readphy(tp, MII_STAT1000, ®)) -+ val |= (reg & 0xffff); -+ } -+ *data++ = val; -+ -+ if (!tg3_readphy(tp, MII_PHYADDR, ®)) -+ val = reg << 16; -+ else -+ val = 0; -+ *data++ = val; -+} -+ -+/* tp->lock is held. */ -+static void tg3_ump_link_report(struct tg3 *tp) -+{ -+ u32 data[4]; -+ -+ if (!tg3_flag(tp, 5780_CLASS) || !tg3_flag(tp, ENABLE_ASF)) -+ return; -+ -+ tg3_phy_gather_ump_data(tp, data); -+ -+ tg3_wait_for_event_ack(tp); -+ -+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_LINK_UPDATE); -+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 14); -+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 0x0, data[0]); -+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 0x4, data[1]); -+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 0x8, data[2]); -+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 0xc, data[3]); -+ -+ tg3_generate_fw_event(tp); -+} -+ -+/* tp->lock is held. */ -+static void tg3_stop_fw(struct tg3 *tp) -+{ -+ if (tg3_flag(tp, ENABLE_ASF) && !tg3_flag(tp, ENABLE_APE)) { -+ /* Wait for RX cpu to ACK the previous event. */ -+ tg3_wait_for_event_ack(tp); -+ -+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW); -+ -+ tg3_generate_fw_event(tp); -+ -+ /* Wait for RX cpu to ACK this event. */ -+ tg3_wait_for_event_ack(tp); -+ } -+} -+ -+/* tp->lock is held. */ -+static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind) -+{ -+ tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, -+ NIC_SRAM_FIRMWARE_MBOX_MAGIC1); -+ -+ if (tg3_flag(tp, ASF_NEW_HANDSHAKE)) { -+ switch (kind) { -+ case RESET_KIND_INIT: -+ tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, -+ DRV_STATE_START); -+ break; -+ -+ case RESET_KIND_SHUTDOWN: -+ tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, -+ DRV_STATE_UNLOAD); -+ break; -+ -+ case RESET_KIND_SUSPEND: -+ tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, -+ DRV_STATE_SUSPEND); -+ break; -+ -+ default: -+ break; -+ } -+ } -+} -+ -+/* tp->lock is held. */ -+static void tg3_write_sig_post_reset(struct tg3 *tp, int kind) -+{ -+ if (tg3_flag(tp, ASF_NEW_HANDSHAKE)) { -+ switch (kind) { -+ case RESET_KIND_INIT: -+ tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, -+ DRV_STATE_START_DONE); -+ break; -+ -+ case RESET_KIND_SHUTDOWN: -+ tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, -+ DRV_STATE_UNLOAD_DONE); -+ break; -+ -+ default: -+ break; -+ } -+ } -+} -+ -+/* tp->lock is held. */ -+static void tg3_write_sig_legacy(struct tg3 *tp, int kind) -+{ -+ if (tg3_flag(tp, ENABLE_ASF)) { -+ switch (kind) { -+ case RESET_KIND_INIT: -+ tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, -+ DRV_STATE_START); -+ break; -+ -+ case RESET_KIND_SHUTDOWN: -+ tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, -+ DRV_STATE_UNLOAD); -+ break; -+ -+ case RESET_KIND_SUSPEND: -+ tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, -+ DRV_STATE_SUSPEND); -+ break; -+ -+ default: -+ break; -+ } -+ } -+} -+ -+static int tg3_poll_fw(struct tg3 *tp) -+{ -+ int i; -+ u32 val; -+ int fw_timeout = 350000; -+ -+ if (tg3_flag(tp, NO_FWARE_REPORTED)) -+ return 0; -+ -+ if (tg3_flag(tp, IS_SSB_CORE)) { -+ /* We don't use firmware. */ -+ return 0; -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5906) { -+ /* Wait up to 20ms for init done. */ -+ for (i = 0; i < 200; i++) { -+ if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE) -+ return 0; -+ if (pci_channel_offline(tp->pdev)) -+ return -ENODEV; -+ -+ udelay(100); -+ } -+ return -ENODEV; -+ } -+ -+ /* Wait for firmware initialization to complete. */ -+ for (i = 0; i < fw_timeout; i++) { -+ tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); -+ if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) -+ break; -+ if (pci_channel_offline(tp->pdev)) { -+ if (!tg3_flag(tp, NO_FWARE_REPORTED)) { -+ tg3_flag_set(tp, NO_FWARE_REPORTED); -+ netdev_info(tp->dev, "No firmware running\n"); -+ } -+ -+ break; -+ } -+ -+ udelay(10); -+ } -+ -+ /* Chip might not be fitted with firmware. Some Sun onboard -+ * parts are configured like that. So don't signal the timeout -+ * of the above loop as an error, but do report the lack of -+ * running firmware once. -+ */ -+ if (i >= fw_timeout && !tg3_flag(tp, NO_FWARE_REPORTED)) { -+ tg3_flag_set(tp, NO_FWARE_REPORTED); -+ -+ netdev_info(tp->dev, "No firmware running\n"); -+ } -+ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_57765_A0) { -+ /* The 57765 A0 needs a little more -+ * time to do some important work. -+ */ -+ mdelay(10); -+ } -+ -+ return 0; -+} -+ -+static void tg3_link_report(struct tg3 *tp) -+{ -+ if (!netif_carrier_ok(tp->dev)) { -+ netif_info(tp, link, tp->dev, "Link is down\n"); -+ tg3_ump_link_report(tp); -+ } else if (netif_msg_link(tp)) { -+ netdev_info(tp->dev, "Link is up at %d Mbps, %s duplex\n", -+ (tp->link_config.active_speed == SPEED_1000 ? -+ 1000 : -+ (tp->link_config.active_speed == SPEED_100 ? -+ 100 : 10)), -+ (tp->link_config.active_duplex == DUPLEX_FULL ? -+ "full" : "half")); -+ -+ netdev_info(tp->dev, "Flow control is %s for TX and %s for RX\n", -+ (tp->link_config.active_flowctrl & FLOW_CTRL_TX) ? -+ "on" : "off", -+ (tp->link_config.active_flowctrl & FLOW_CTRL_RX) ? -+ "on" : "off"); -+ -+ if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) -+ netdev_info(tp->dev, "EEE is %s\n", -+ tp->setlpicnt ? "enabled" : "disabled"); -+ -+ tg3_ump_link_report(tp); -+ } -+ -+ tp->link_up = netif_carrier_ok(tp->dev); -+} -+ -+static u32 tg3_decode_flowctrl_1000T(u32 adv) -+{ -+ u32 flowctrl = 0; -+ -+ if (adv & ADVERTISE_PAUSE_CAP) { -+ flowctrl |= FLOW_CTRL_RX; -+ if (!(adv & ADVERTISE_PAUSE_ASYM)) -+ flowctrl |= FLOW_CTRL_TX; -+ } else if (adv & ADVERTISE_PAUSE_ASYM) -+ flowctrl |= FLOW_CTRL_TX; -+ -+ return flowctrl; -+} -+ -+static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl) -+{ -+ u16 miireg; -+ -+ if ((flow_ctrl & FLOW_CTRL_TX) && (flow_ctrl & FLOW_CTRL_RX)) -+ miireg = ADVERTISE_1000XPAUSE; -+ else if (flow_ctrl & FLOW_CTRL_TX) -+ miireg = ADVERTISE_1000XPSE_ASYM; -+ else if (flow_ctrl & FLOW_CTRL_RX) -+ miireg = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM; -+ else -+ miireg = 0; -+ -+ return miireg; -+} -+ -+static u32 tg3_decode_flowctrl_1000X(u32 adv) -+{ -+ u32 flowctrl = 0; -+ -+ if (adv & ADVERTISE_1000XPAUSE) { -+ flowctrl |= FLOW_CTRL_RX; -+ if (!(adv & ADVERTISE_1000XPSE_ASYM)) -+ flowctrl |= FLOW_CTRL_TX; -+ } else if (adv & ADVERTISE_1000XPSE_ASYM) -+ flowctrl |= FLOW_CTRL_TX; -+ -+ return flowctrl; -+} -+ -+static u8 tg3_resolve_flowctrl_1000X(u16 lcladv, u16 rmtadv) -+{ -+ u8 cap = 0; -+ -+ if (lcladv & rmtadv & ADVERTISE_1000XPAUSE) { -+ cap = FLOW_CTRL_TX | FLOW_CTRL_RX; -+ } else if (lcladv & rmtadv & ADVERTISE_1000XPSE_ASYM) { -+ if (lcladv & ADVERTISE_1000XPAUSE) -+ cap = FLOW_CTRL_RX; -+ if (rmtadv & ADVERTISE_1000XPAUSE) -+ cap = FLOW_CTRL_TX; -+ } -+ -+ return cap; -+} -+ -+static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv) -+{ -+ u8 autoneg; -+ u8 flowctrl = 0; -+ u32 old_rx_mode = tp->rx_mode; -+ u32 old_tx_mode = tp->tx_mode; -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_flag(tp, USE_PHYLIB)) -+ autoneg = tp->mdio_bus->phy_map[tp->phy_addr]->autoneg; -+ else -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+ autoneg = tp->link_config.autoneg; -+ -+ if (autoneg == AUTONEG_ENABLE && tg3_flag(tp, PAUSE_AUTONEG)) { -+ if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) -+ flowctrl = tg3_resolve_flowctrl_1000X(lcladv, rmtadv); -+ else -+ flowctrl = mii_resolve_flowctrl_fdx(lcladv, rmtadv); -+ } else -+ flowctrl = tp->link_config.flowctrl; -+ -+ tp->link_config.active_flowctrl = flowctrl; -+ -+ if (flowctrl & FLOW_CTRL_RX) -+ tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE; -+ else -+ tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE; -+ -+ if (old_rx_mode != tp->rx_mode) -+ tw32_f(MAC_RX_MODE, tp->rx_mode); -+ -+ if (flowctrl & FLOW_CTRL_TX) -+ tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE; -+ else -+ tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE; -+ -+ if (old_tx_mode != tp->tx_mode) -+ tw32_f(MAC_TX_MODE, tp->tx_mode); -+} -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+static void tg3_adjust_link(struct net_device *dev) -+{ -+ u8 oldflowctrl, linkmesg = 0; -+ u32 mac_mode, lcl_adv, rmt_adv; -+ struct tg3 *tp = netdev_priv(dev); -+ struct phy_device *phydev = tp->mdio_bus->phy_map[tp->phy_addr]; -+ -+ spin_lock_bh(&tp->lock); -+ -+ mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK | -+ MAC_MODE_HALF_DUPLEX); -+ -+ oldflowctrl = tp->link_config.active_flowctrl; -+ -+ if (phydev->link) { -+ lcl_adv = 0; -+ rmt_adv = 0; -+ -+ if (phydev->speed == SPEED_100 || phydev->speed == SPEED_10) -+ mac_mode |= MAC_MODE_PORT_MODE_MII; -+ else if (phydev->speed == SPEED_1000 || -+ tg3_asic_rev(tp) != ASIC_REV_5785) -+ mac_mode |= MAC_MODE_PORT_MODE_GMII; -+ else -+ mac_mode |= MAC_MODE_PORT_MODE_MII; -+ -+ if (phydev->duplex == DUPLEX_HALF) -+ mac_mode |= MAC_MODE_HALF_DUPLEX; -+ else { -+ lcl_adv = mii_advertise_flowctrl( -+ tp->link_config.flowctrl); -+ -+ if (phydev->pause) -+ rmt_adv = LPA_PAUSE_CAP; -+ if (phydev->asym_pause) -+ rmt_adv |= LPA_PAUSE_ASYM; -+ } -+ -+ tg3_setup_flow_control(tp, lcl_adv, rmt_adv); -+ } else -+ mac_mode |= MAC_MODE_PORT_MODE_GMII; -+ -+ if (mac_mode != tp->mac_mode) { -+ tp->mac_mode = mac_mode; -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5785) { -+ if (phydev->speed == SPEED_10) -+ tw32(MAC_MI_STAT, -+ MAC_MI_STAT_10MBPS_MODE | -+ MAC_MI_STAT_LNKSTAT_ATTN_ENAB); -+ else -+ tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); -+ } -+ -+ if (phydev->speed == SPEED_1000 && phydev->duplex == DUPLEX_HALF) -+ tw32(MAC_TX_LENGTHS, -+ ((2 << TX_LENGTHS_IPG_CRS_SHIFT) | -+ (6 << TX_LENGTHS_IPG_SHIFT) | -+ (0xff << TX_LENGTHS_SLOT_TIME_SHIFT))); -+ else -+ tw32(MAC_TX_LENGTHS, -+ ((2 << TX_LENGTHS_IPG_CRS_SHIFT) | -+ (6 << TX_LENGTHS_IPG_SHIFT) | -+ (32 << TX_LENGTHS_SLOT_TIME_SHIFT))); -+ -+ if (phydev->link != tp->old_link || -+ phydev->speed != tp->link_config.active_speed || -+ phydev->duplex != tp->link_config.active_duplex || -+ oldflowctrl != tp->link_config.active_flowctrl) -+ linkmesg = 1; -+ -+ tp->old_link = phydev->link; -+ tp->link_config.active_speed = phydev->speed; -+ tp->link_config.active_duplex = phydev->duplex; -+ -+ spin_unlock_bh(&tp->lock); -+ -+ if (linkmesg) -+ tg3_link_report(tp); -+} -+ -+static int tg3_phy_init(struct tg3 *tp) -+{ -+ struct phy_device *phydev; -+ -+ if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) -+ return 0; -+ -+ /* Bring the PHY back to a known state. */ -+ tg3_bmcr_reset(tp); -+ -+ phydev = tp->mdio_bus->phy_map[tp->phy_addr]; -+ -+ /* Attach the MAC to the PHY. */ -+ phydev = phy_connect(tp->dev, dev_name(&phydev->dev), -+ tg3_adjust_link, phydev->interface); -+ if (IS_ERR(phydev)) { -+ dev_err(&tp->pdev->dev, "Could not attach to PHY\n"); -+ return PTR_ERR(phydev); -+ } -+ -+ /* Mask with MAC supported features. */ -+ switch (phydev->interface) { -+ case PHY_INTERFACE_MODE_GMII: -+ case PHY_INTERFACE_MODE_RGMII: -+ if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) { -+ phydev->supported &= (PHY_GBIT_FEATURES | -+ SUPPORTED_Pause | -+ SUPPORTED_Asym_Pause); -+ break; -+ } -+ /* fallthru */ -+ case PHY_INTERFACE_MODE_MII: -+ phydev->supported &= (PHY_BASIC_FEATURES | -+ SUPPORTED_Pause | -+ SUPPORTED_Asym_Pause); -+ break; -+ default: -+ phy_disconnect(tp->mdio_bus->phy_map[tp->phy_addr]); -+ return -EINVAL; -+ } -+ -+ tp->phy_flags |= TG3_PHYFLG_IS_CONNECTED; -+ -+ phydev->advertising = phydev->supported; -+ -+ return 0; -+} -+ -+static void tg3_phy_start(struct tg3 *tp) -+{ -+ struct phy_device *phydev; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) -+ return; -+ -+ phydev = tp->mdio_bus->phy_map[tp->phy_addr]; -+ -+ if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) { -+ tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER; -+ phydev->speed = tp->link_config.speed; -+ phydev->duplex = tp->link_config.duplex; -+ phydev->autoneg = tp->link_config.autoneg; -+ phydev->advertising = tp->link_config.advertising; -+ } -+ -+ phy_start(phydev); -+ -+ phy_start_aneg(phydev); -+} -+ -+static void tg3_phy_stop(struct tg3 *tp) -+{ -+ if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) -+ return; -+ -+ phy_stop(tp->mdio_bus->phy_map[tp->phy_addr]); -+} -+ -+static void tg3_phy_fini(struct tg3 *tp) -+{ -+ if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) { -+ phy_disconnect(tp->mdio_bus->phy_map[tp->phy_addr]); -+ tp->phy_flags &= ~TG3_PHYFLG_IS_CONNECTED; -+ } -+} -+#else -+#define tg3_phy_init(tp) 0 -+#define tg3_phy_start(tp) -+#define tg3_phy_stop(tp) -+#define tg3_phy_fini(tp) -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+ -+static int tg3_phy_set_extloopbk(struct tg3 *tp) -+{ -+ int err; -+ u32 val; -+ -+ if (tp->phy_flags & TG3_PHYFLG_IS_FET) -+ return 0; -+ -+ if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5401) { -+ /* Cannot do read-modify-write on 5401 */ -+ err = tg3_phy_auxctl_write(tp, -+ MII_TG3_AUXCTL_SHDWSEL_AUXCTL, -+ MII_TG3_AUXCTL_ACTL_EXTLOOPBK | -+ 0x4c20); -+ goto done; -+ } -+ -+ err = tg3_phy_auxctl_read(tp, -+ MII_TG3_AUXCTL_SHDWSEL_AUXCTL, &val); -+ if (err) -+ return err; -+ -+ val |= MII_TG3_AUXCTL_ACTL_EXTLOOPBK; -+ err = tg3_phy_auxctl_write(tp, -+ MII_TG3_AUXCTL_SHDWSEL_AUXCTL, val); -+ -+done: -+ return err; -+} -+ -+static void tg3_phy_fet_toggle_apd(struct tg3 *tp, bool enable) -+{ -+ u32 phytest; -+ -+ if (!tg3_readphy(tp, MII_TG3_FET_TEST, &phytest)) { -+ u32 phy; -+ -+ tg3_writephy(tp, MII_TG3_FET_TEST, -+ phytest | MII_TG3_FET_SHADOW_EN); -+ if (!tg3_readphy(tp, MII_TG3_FET_SHDW_AUXSTAT2, &phy)) { -+ if (enable) -+ phy |= MII_TG3_FET_SHDW_AUXSTAT2_APD; -+ else -+ phy &= ~MII_TG3_FET_SHDW_AUXSTAT2_APD; -+ tg3_writephy(tp, MII_TG3_FET_SHDW_AUXSTAT2, phy); -+ } -+ tg3_writephy(tp, MII_TG3_FET_TEST, phytest); -+ } -+} -+ -+static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable) -+{ -+ u32 reg; -+ -+ if (!tg3_flag(tp, 5705_PLUS) || -+ (tg3_flag(tp, 5717_PLUS) && -+ (tp->phy_flags & TG3_PHYFLG_MII_SERDES))) -+ return; -+ -+ if (tp->phy_flags & TG3_PHYFLG_IS_FET) { -+ tg3_phy_fet_toggle_apd(tp, enable); -+ return; -+ } -+ -+#ifndef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_asic_rev(tp) == ASIC_REV_5785) { -+ reg = MII_TG3_MISC_SHDW_SCR5_TRDDAPD | -+ MII_TG3_MISC_SHDW_SCR5_LPED | -+ MII_TG3_MISC_SHDW_SCR5_DLPTLM | -+ MII_TG3_MISC_SHDW_SCR5_SDTL; -+ if ((tp->phy_id & ~TG3_PHY_ID_MASK) < 0x3) { -+ reg |= MII_TG3_MISC_SHDW_SCR5_C125OE; -+ if (!enable) -+ reg |= MII_TG3_MISC_SHDW_SCR5_DLLAPD; -+ } -+ } else { -+#endif -+ reg = MII_TG3_MISC_SHDW_SCR5_LPED | -+ MII_TG3_MISC_SHDW_SCR5_DLPTLM | -+ MII_TG3_MISC_SHDW_SCR5_SDTL | -+ MII_TG3_MISC_SHDW_SCR5_C125OE; -+ if (tg3_asic_rev(tp) != ASIC_REV_5784 || !enable) -+ reg |= MII_TG3_MISC_SHDW_SCR5_DLLAPD; -+#ifndef BCM_INCLUDE_PHYLIB_SUPPORT -+ } -+#endif -+ -+ tg3_phy_shdw_write(tp, MII_TG3_MISC_SHDW_SCR5_SEL, reg); -+ -+ -+ reg = MII_TG3_MISC_SHDW_APD_WKTM_84MS; -+ if (enable) -+ reg |= MII_TG3_MISC_SHDW_APD_ENABLE; -+ -+ tg3_phy_shdw_write(tp, MII_TG3_MISC_SHDW_APD_SEL, reg); -+} -+ -+static void tg3_phy_toggle_automdix(struct tg3 *tp, bool enable) -+{ -+ u32 phy; -+ -+ if (!tg3_flag(tp, 5705_PLUS) || -+ (tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) -+ return; -+ -+ if (tp->phy_flags & TG3_PHYFLG_IS_FET) { -+ u32 ephy; -+ -+ if (!tg3_readphy(tp, MII_TG3_FET_TEST, &ephy)) { -+ u32 reg = MII_TG3_FET_SHDW_MISCCTRL; -+ -+ tg3_writephy(tp, MII_TG3_FET_TEST, -+ ephy | MII_TG3_FET_SHADOW_EN); -+ if (!tg3_readphy(tp, reg, &phy)) { -+ if (enable) -+ phy |= MII_TG3_FET_SHDW_MISCCTRL_MDIX; -+ else -+ phy &= ~MII_TG3_FET_SHDW_MISCCTRL_MDIX; -+ tg3_writephy(tp, reg, phy); -+ } -+ tg3_writephy(tp, MII_TG3_FET_TEST, ephy); -+ } -+ } else { -+ int ret; -+ -+ ret = tg3_phy_auxctl_read(tp, -+ MII_TG3_AUXCTL_SHDWSEL_MISC, &phy); -+ if (!ret) { -+ if (enable) -+ phy |= MII_TG3_AUXCTL_MISC_FORCE_AMDIX; -+ else -+ phy &= ~MII_TG3_AUXCTL_MISC_FORCE_AMDIX; -+ tg3_phy_auxctl_write(tp, -+ MII_TG3_AUXCTL_SHDWSEL_MISC, phy); -+ } -+ } -+} -+ -+static void tg3_phy_set_wirespeed(struct tg3 *tp) -+{ -+ int ret; -+ u32 val; -+ -+ if (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED) -+ return; -+ -+ ret = tg3_phy_auxctl_read(tp, MII_TG3_AUXCTL_SHDWSEL_MISC, &val); -+ if (!ret) -+ tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_MISC, -+ val | MII_TG3_AUXCTL_MISC_WIRESPD_EN); -+} -+ -+static void tg3_phy_apply_otp(struct tg3 *tp) -+{ -+ u32 otp, phy; -+ -+ if (!tp->phy_otp) -+ return; -+ -+ otp = tp->phy_otp; -+ -+ if (tg3_phy_toggle_auxctl_smdsp(tp, true)) -+ return; -+ -+ phy = ((otp & TG3_OTP_AGCTGT_MASK) >> TG3_OTP_AGCTGT_SHIFT); -+ phy |= MII_TG3_DSP_TAP1_AGCTGT_DFLT; -+ tg3_phydsp_write(tp, MII_TG3_DSP_TAP1, phy); -+ -+ phy = ((otp & TG3_OTP_HPFFLTR_MASK) >> TG3_OTP_HPFFLTR_SHIFT) | -+ ((otp & TG3_OTP_HPFOVER_MASK) >> TG3_OTP_HPFOVER_SHIFT); -+ tg3_phydsp_write(tp, MII_TG3_DSP_AADJ1CH0, phy); -+ -+ phy = ((otp & TG3_OTP_LPFDIS_MASK) >> TG3_OTP_LPFDIS_SHIFT); -+ phy |= MII_TG3_DSP_AADJ1CH3_ADCCKADJ; -+ tg3_phydsp_write(tp, MII_TG3_DSP_AADJ1CH3, phy); -+ -+ phy = ((otp & TG3_OTP_VDAC_MASK) >> TG3_OTP_VDAC_SHIFT); -+ tg3_phydsp_write(tp, MII_TG3_DSP_EXP75, phy); -+ -+ phy = ((otp & TG3_OTP_10BTAMP_MASK) >> TG3_OTP_10BTAMP_SHIFT); -+ tg3_phydsp_write(tp, MII_TG3_DSP_EXP96, phy); -+ -+ phy = ((otp & TG3_OTP_ROFF_MASK) >> TG3_OTP_ROFF_SHIFT) | -+ ((otp & TG3_OTP_RCOFF_MASK) >> TG3_OTP_RCOFF_SHIFT); -+ tg3_phydsp_write(tp, MII_TG3_DSP_EXP97, phy); -+ -+ tg3_phy_toggle_auxctl_smdsp(tp, false); -+} -+ -+static void tg3_eee_pull_config(struct tg3 *tp, struct ethtool_eee *eee) -+{ -+ u32 val; -+ struct ethtool_eee *dest = &tp->eee; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) -+ return; -+ -+ if (eee) -+ dest = eee; -+ -+ if (tg3_phy_cl45_read(tp, MDIO_MMD_AN, TG3_CL45_D7_EEERES_STAT, &val)) -+ return; -+ -+ /* Pull eee_active */ -+ if (val == TG3_CL45_D7_EEERES_STAT_LP_1000T || -+ val == TG3_CL45_D7_EEERES_STAT_LP_100TX) { -+ dest->eee_active = 1; -+ } else -+ dest->eee_active = 0; -+ -+ /* Pull lp advertised settings */ -+ if (tg3_phy_cl45_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE, &val)) -+ return; -+ dest->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val); -+ -+ /* Pull advertised and eee_enabled settings */ -+ if (tg3_phy_cl45_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, &val)) -+ return; -+ dest->eee_enabled = !!val; -+ dest->advertised = mmd_eee_adv_to_ethtool_adv_t(val); -+ -+ /* Pull tx_lpi_enabled */ -+ val = tr32(TG3_CPMU_EEE_MODE); -+ dest->tx_lpi_enabled = !!(val & TG3_CPMU_EEEMD_LPI_IN_TX); -+ -+ /* Pull lpi timer value */ -+ dest->tx_lpi_timer = tr32(TG3_CPMU_EEE_DBTMR1) & 0xffff; -+} -+ -+static void tg3_phy_eee_adjust(struct tg3 *tp, bool current_link_up) -+{ -+ u32 val; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) -+ return; -+ -+#ifndef BCM_INCLUDE_PHYLIB_SUPPORT -+ if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM50612E) -+ return; -+#endif -+ -+ tp->setlpicnt = 0; -+ -+ if (tp->link_config.autoneg == AUTONEG_ENABLE && -+ current_link_up && -+ tp->link_config.active_duplex == DUPLEX_FULL && -+ (tp->link_config.active_speed == SPEED_100 || -+ tp->link_config.active_speed == SPEED_1000)) { -+ u32 eeectl; -+ -+ if (tp->link_config.active_speed == SPEED_1000) -+ eeectl = TG3_CPMU_EEE_CTRL_EXIT_16_5_US; -+ else -+ eeectl = TG3_CPMU_EEE_CTRL_EXIT_36_US; -+ -+ tw32(TG3_CPMU_EEE_CTRL, eeectl); -+ -+ tg3_eee_pull_config(tp, NULL); -+ if (tp->eee.eee_active) -+ tp->setlpicnt = 2; -+ } -+ -+ if (!tp->setlpicnt) { -+ if (current_link_up && -+ !tg3_phy_toggle_auxctl_smdsp(tp, true)) { -+ tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000); -+ tg3_phy_toggle_auxctl_smdsp(tp, false); -+ } -+ -+ val = tr32(TG3_CPMU_EEE_MODE); -+ tw32(TG3_CPMU_EEE_MODE, val & ~TG3_CPMU_EEEMD_LPI_ENABLE); -+ } -+} -+ -+static void tg3_phy_eee_enable(struct tg3 *tp) -+{ -+ u32 val; -+ -+ if (tp->link_config.active_speed == SPEED_1000 && -+ (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_flag(tp, 57765_CLASS)) && -+ !tg3_phy_toggle_auxctl_smdsp(tp, true)) { -+ val = MII_TG3_DSP_TAP26_ALNOKO | -+ MII_TG3_DSP_TAP26_RMRXSTO; -+ tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); -+ tg3_phy_toggle_auxctl_smdsp(tp, false); -+ } -+ -+ val = tr32(TG3_CPMU_EEE_MODE); -+ tw32(TG3_CPMU_EEE_MODE, val | TG3_CPMU_EEEMD_LPI_ENABLE); -+} -+ -+static int tg3_wait_macro_done(struct tg3 *tp) -+{ -+ int limit = 100; -+ -+ while (limit--) { -+ u32 tmp32; -+ -+ if (!tg3_readphy(tp, MII_TG3_DSP_CONTROL, &tmp32)) { -+ if ((tmp32 & 0x1000) == 0) -+ break; -+ } -+ } -+ if (limit < 0) -+ return -EBUSY; -+ -+ return 0; -+} -+ -+static int tg3_phy_write_and_check_testpat(struct tg3 *tp, int *resetp) -+{ -+ static const u32 test_pat[4][6] = { -+ { 0x00005555, 0x00000005, 0x00002aaa, 0x0000000a, 0x00003456, 0x00000003 }, -+ { 0x00002aaa, 0x0000000a, 0x00003333, 0x00000003, 0x0000789a, 0x00000005 }, -+ { 0x00005a5a, 0x00000005, 0x00002a6a, 0x0000000a, 0x00001bcd, 0x00000003 }, -+ { 0x00002a5a, 0x0000000a, 0x000033c3, 0x00000003, 0x00002ef1, 0x00000005 } -+ }; -+ int chan; -+ -+ for (chan = 0; chan < 4; chan++) { -+ int i; -+ -+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, -+ (chan * 0x2000) | 0x0200); -+ tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0002); -+ -+ for (i = 0; i < 6; i++) -+ tg3_writephy(tp, MII_TG3_DSP_RW_PORT, -+ test_pat[chan][i]); -+ -+ tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0202); -+ if (tg3_wait_macro_done(tp)) { -+ *resetp = 1; -+ return -EBUSY; -+ } -+ -+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, -+ (chan * 0x2000) | 0x0200); -+ tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0082); -+ if (tg3_wait_macro_done(tp)) { -+ *resetp = 1; -+ return -EBUSY; -+ } -+ -+ tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0802); -+ if (tg3_wait_macro_done(tp)) { -+ *resetp = 1; -+ return -EBUSY; -+ } -+ -+ for (i = 0; i < 6; i += 2) { -+ u32 low, high; -+ -+ if (tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &low) || -+ tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &high) || -+ tg3_wait_macro_done(tp)) { -+ *resetp = 1; -+ return -EBUSY; -+ } -+ low &= 0x7fff; -+ high &= 0x000f; -+ if (low != test_pat[chan][i] || -+ high != test_pat[chan][i+1]) { -+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000b); -+ tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x4001); -+ tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x4005); -+ -+ return -EBUSY; -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static int tg3_phy_reset_chanpat(struct tg3 *tp) -+{ -+ int chan; -+ -+ for (chan = 0; chan < 4; chan++) { -+ int i; -+ -+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, -+ (chan * 0x2000) | 0x0200); -+ tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0002); -+ for (i = 0; i < 6; i++) -+ tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x000); -+ tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0202); -+ if (tg3_wait_macro_done(tp)) -+ return -EBUSY; -+ } -+ -+ return 0; -+} -+ -+static int tg3_phy_reset_5703_4_5(struct tg3 *tp) -+{ -+ u32 reg32, phy9_orig; -+ int retries, do_phy_reset, err; -+ -+ retries = 10; -+ do_phy_reset = 1; -+ do { -+ if (do_phy_reset) { -+ err = tg3_bmcr_reset(tp); -+ if (err) -+ return err; -+ do_phy_reset = 0; -+ } -+ -+ /* Disable transmitter and interrupt. */ -+ if (tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32)) -+ continue; -+ -+ reg32 |= 0x3000; -+ tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); -+ -+ /* Set full-duplex, 1000 mbps. */ -+ tg3_writephy(tp, MII_BMCR, -+ BMCR_FULLDPLX | BMCR_SPEED1000); -+ -+ /* Set to master mode. */ -+ if (tg3_readphy(tp, MII_CTRL1000, &phy9_orig)) -+ continue; -+ -+ tg3_writephy(tp, MII_CTRL1000, -+ CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER); -+ -+ err = tg3_phy_toggle_auxctl_smdsp(tp, true); -+ if (err) -+ return err; -+ -+ /* Block the PHY control access. */ -+ tg3_phydsp_write(tp, 0x8005, 0x0800); -+ -+ err = tg3_phy_write_and_check_testpat(tp, &do_phy_reset); -+ if (!err) -+ break; -+ } while (--retries); -+ -+ err = tg3_phy_reset_chanpat(tp); -+ if (err) -+ return err; -+ -+ tg3_phydsp_write(tp, 0x8005, 0x0000); -+ -+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200); -+ tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000); -+ -+ tg3_phy_toggle_auxctl_smdsp(tp, false); -+ -+ tg3_writephy(tp, MII_CTRL1000, phy9_orig); -+ -+ if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32)) { -+ reg32 &= ~0x3000; -+ tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); -+ } else if (!err) -+ err = -EBUSY; -+ -+ return err; -+} -+ -+static void tg3_carrier_off(struct tg3 *tp) -+{ -+ netif_carrier_off(tp->dev); -+ tp->link_up = false; -+} -+ -+static void tg3_warn_mgmt_link_flap(struct tg3 *tp) -+{ -+ if (tg3_flag(tp, ENABLE_ASF)) -+ netdev_warn(tp->dev, -+ "Management side-band traffic will be interrupted during phy settings change\n"); -+} -+ -+/* This will reset the tigon3 PHY if there is no valid -+ * link unless the FORCE argument is non-zero. -+ */ -+static int tg3_phy_reset(struct tg3 *tp) -+{ -+ u32 val, cpmuctrl; -+ int err; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5906) { -+ val = tr32(GRC_MISC_CFG); -+ tw32_f(GRC_MISC_CFG, val & ~GRC_MISC_CFG_EPHY_IDDQ); -+ udelay(40); -+ } -+ err = tg3_readphy(tp, MII_BMSR, &val); -+ err |= tg3_readphy(tp, MII_BMSR, &val); -+ if (err != 0) -+ return -EBUSY; -+ -+ if (netif_running(tp->dev) && tp->link_up) { -+ netif_carrier_off(tp->dev); -+ tg3_link_report(tp); -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5703 || -+ tg3_asic_rev(tp) == ASIC_REV_5704 || -+ tg3_asic_rev(tp) == ASIC_REV_5705) { -+ err = tg3_phy_reset_5703_4_5(tp); -+ if (err) -+ return err; -+ goto out; -+ } -+ -+ cpmuctrl = 0; -+ if (tg3_asic_rev(tp) == ASIC_REV_5784 && -+ tg3_chip_rev(tp) != CHIPREV_5784_AX) { -+ cpmuctrl = tr32(TG3_CPMU_CTRL); -+ if (cpmuctrl & CPMU_CTRL_GPHY_10MB_RXONLY) -+ tw32(TG3_CPMU_CTRL, -+ cpmuctrl & ~CPMU_CTRL_GPHY_10MB_RXONLY); -+ } -+ -+ err = tg3_bmcr_reset(tp); -+ if (err) -+ return err; -+ -+ if (cpmuctrl & CPMU_CTRL_GPHY_10MB_RXONLY) { -+ val = MII_TG3_DSP_EXP8_AEDW | MII_TG3_DSP_EXP8_REJ2MHz; -+ tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, val); -+ -+ tw32(TG3_CPMU_CTRL, cpmuctrl); -+ } -+ -+ if (tg3_chip_rev(tp) == CHIPREV_5784_AX || -+ tg3_chip_rev(tp) == CHIPREV_5761_AX) { -+ val = tr32(TG3_CPMU_LSPD_1000MB_CLK); -+ if ((val & CPMU_LSPD_1000MB_MACCLK_MASK) == -+ CPMU_LSPD_1000MB_MACCLK_12_5) { -+ val &= ~CPMU_LSPD_1000MB_MACCLK_MASK; -+ udelay(40); -+ tw32_f(TG3_CPMU_LSPD_1000MB_CLK, val); -+ } -+ } -+ -+ if (tg3_flag(tp, 5717_PLUS) && -+ (tp->phy_flags & TG3_PHYFLG_MII_SERDES)) -+ return 0; -+ -+ tg3_phy_apply_otp(tp); -+ -+ if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD) -+ tg3_phy_toggle_apd(tp, true); -+ else -+ tg3_phy_toggle_apd(tp, false); -+ -+out: -+#ifndef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_asic_rev(tp) == ASIC_REV_5785 && -+ (tp->phy_id & TG3_PHY_ID_MASK) != TG3_PHY_ID_BCMAC131) { -+ /* A0 */ -+ if (tp->phy_id == TG3_PHY_ID_BCM50612E && -+ !tg3_phy_toggle_auxctl_smdsp(tp, true)) { -+ tg3_phydsp_write(tp, 0x0fff, 0x4000); -+ tg3_phydsp_write(tp, 0x0021, 0x4600); -+ tg3_phy_toggle_auxctl_smdsp(tp, false); -+ } -+ -+ if (((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM50610 || -+ (tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM50610M) && -+ !tg3_phy_toggle_auxctl_smdsp(tp, true)) { -+ val = MII_TG3_DSP_EXP8_REJ2MHz; -+ tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, val); -+ -+ /* Apply workaround to A0 revision parts only. */ -+ if (tp->phy_id == TG3_PHY_ID_BCM50610 || -+ tp->phy_id == TG3_PHY_ID_BCM50610M) { -+ tg3_phydsp_write(tp, 0x001F, 0x0300); -+ tg3_phydsp_write(tp, 0x601F, 0x0002); -+ tg3_phydsp_write(tp, 0x0F75, 0x003C); -+ tg3_phydsp_write(tp, 0x0F96, 0x0010); -+ tg3_phydsp_write(tp, 0x0F97, 0x0C0C); -+ } -+ -+ tg3_phy_toggle_auxctl_smdsp(tp, false); -+ } -+ -+ tg3_phy_auxctl_read(tp, MII_TG3_AUXCTL_SHDWSEL_MISC, &val); -+ if (tg3_flag(tp, RGMII_INBAND_DISABLE)) -+ val |= MII_TG3_AUXCTL_MISC_RGMII_OOBSC; -+ else -+ val &= ~MII_TG3_AUXCTL_MISC_RGMII_OOBSC; -+ tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_MISC, val); -+ -+ /* Clear all mode configuration bits. */ -+ if (!tg3_phy_shdw_read(tp, MII_TG3_MISC_SHDW_RGMII_SEL, &val)) { -+ val &= ~(MII_TG3_MISC_SHDW_RGMII_MODESEL0 | -+ MII_TG3_MISC_SHDW_RGMII_MODESEL1); -+ tg3_phy_shdw_write(tp, -+ MII_TG3_MISC_SHDW_RGMII_SEL, val); -+ } -+ } -+ -+ if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM57780 && -+ !tg3_phy_toggle_auxctl_smdsp(tp, true)) { -+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, MII_TG3_DSP_EXP75); -+ tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &val); -+ val |= MII_TG3_DSP_EXP75_SUP_CM_OSC; -+ tg3_phydsp_write(tp, MII_TG3_DSP_EXP75, val); -+ -+ tg3_phy_toggle_auxctl_smdsp(tp, false); -+ } -+#endif -+ if ((tp->phy_flags & TG3_PHYFLG_ADC_BUG) && -+ !tg3_phy_toggle_auxctl_smdsp(tp, true)) { -+ tg3_phydsp_write(tp, 0x201f, 0x2aaa); -+ tg3_phydsp_write(tp, 0x000a, 0x0323); -+ tg3_phy_toggle_auxctl_smdsp(tp, false); -+ } -+ -+ if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) { -+ tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68); -+ tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68); -+ } -+ -+ if (tp->phy_flags & TG3_PHYFLG_BER_BUG) { -+ if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) { -+ tg3_phydsp_write(tp, 0x000a, 0x310b); -+ tg3_phydsp_write(tp, 0x201f, 0x9506); -+ tg3_phydsp_write(tp, 0x401f, 0x14e2); -+ tg3_phy_toggle_auxctl_smdsp(tp, false); -+ } -+ } else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) { -+ if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) { -+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a); -+ if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) { -+ tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b); -+ tg3_writephy(tp, MII_TG3_TEST1, -+ MII_TG3_TEST1_TRIM_EN | 0x4); -+ } else -+ tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b); -+ -+ tg3_phy_toggle_auxctl_smdsp(tp, false); -+ } -+ } -+ -+ /* Set Extended packet length bit (bit 14) on all chips that */ -+ /* support jumbo frames */ -+ if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5401) { -+ /* Cannot do read-modify-write on 5401 */ -+ tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, 0x4c20); -+ } else if (tg3_flag(tp, JUMBO_CAPABLE)) { -+ /* Set bit 14 with read-modify-write to preserve other bits */ -+ err = tg3_phy_auxctl_read(tp, -+ MII_TG3_AUXCTL_SHDWSEL_AUXCTL, &val); -+ if (!err) -+ tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, -+ val | MII_TG3_AUXCTL_ACTL_EXTPKTLEN); -+ } -+ -+ /* Set phy register 0x10 bit 0 to high fifo elasticity to support -+ * jumbo frames transmission. -+ */ -+ if (tg3_flag(tp, JUMBO_CAPABLE)) { -+ if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &val)) -+ tg3_writephy(tp, MII_TG3_EXT_CTRL, -+ val | MII_TG3_EXT_CTRL_FIFO_ELASTIC); -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5906) { -+ /* adjust output voltage */ -+ tg3_writephy(tp, MII_TG3_FET_PTEST, 0x12); -+ } -+#ifndef BCM_INCLUDE_PHYLIB_SUPPORT -+ else if (tp->phy_flags & TG3_PHYFLG_IS_FET) { -+ u32 brcmtest; -+ if (!tg3_readphy(tp, MII_TG3_FET_TEST, &brcmtest) && -+ !tg3_writephy(tp, MII_TG3_FET_TEST, -+ brcmtest | MII_TG3_FET_SHADOW_EN)) { -+ u32 reg = MII_TG3_FET_SHDW_AUXMODE4; -+ -+ if (!tg3_readphy(tp, reg, &val)) { -+ val &= ~MII_TG3_FET_SHDW_AM4_LED_MASK; -+ val |= MII_TG3_FET_SHDW_AM4_LED_MODE1; -+ tg3_writephy(tp, reg, val); -+ } -+ -+ tg3_writephy(tp, MII_TG3_FET_TEST, brcmtest); -+ } -+ } -+#endif -+ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5762_A0) -+ tg3_phydsp_write(tp, 0xffb, 0x4000); -+ -+ tg3_phy_toggle_automdix(tp, true); -+ tg3_phy_set_wirespeed(tp); -+ return 0; -+} -+ -+#define TG3_GPIO_MSG_DRVR_PRES 0x00000001 -+#define TG3_GPIO_MSG_NEED_VAUX 0x00000002 -+#define TG3_GPIO_MSG_MASK (TG3_GPIO_MSG_DRVR_PRES | \ -+ TG3_GPIO_MSG_NEED_VAUX) -+#define TG3_GPIO_MSG_ALL_DRVR_PRES_MASK \ -+ ((TG3_GPIO_MSG_DRVR_PRES << 0) | \ -+ (TG3_GPIO_MSG_DRVR_PRES << 4) | \ -+ (TG3_GPIO_MSG_DRVR_PRES << 8) | \ -+ (TG3_GPIO_MSG_DRVR_PRES << 12)) -+ -+#define TG3_GPIO_MSG_ALL_NEED_VAUX_MASK \ -+ ((TG3_GPIO_MSG_NEED_VAUX << 0) | \ -+ (TG3_GPIO_MSG_NEED_VAUX << 4) | \ -+ (TG3_GPIO_MSG_NEED_VAUX << 8) | \ -+ (TG3_GPIO_MSG_NEED_VAUX << 12)) -+ -+static inline u32 tg3_set_function_status(struct tg3 *tp, u32 newstat) -+{ -+ u32 status, shift; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_asic_rev(tp) == ASIC_REV_5719) -+ status = tg3_ape_read32(tp, TG3_APE_GPIO_MSG); -+ else -+ status = tr32(TG3_CPMU_DRV_STATUS); -+ -+ shift = TG3_APE_GPIO_MSG_SHIFT + 4 * tp->pci_fn; -+ status &= ~(TG3_GPIO_MSG_MASK << shift); -+ status |= (newstat << shift); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_asic_rev(tp) == ASIC_REV_5719) -+ tg3_ape_write32(tp, TG3_APE_GPIO_MSG, status); -+ else -+ tw32(TG3_CPMU_DRV_STATUS, status); -+ -+ return status >> TG3_APE_GPIO_MSG_SHIFT; -+} -+ -+static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp) -+{ -+ if (!tg3_flag(tp, IS_NIC)) -+ return 0; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_asic_rev(tp) == ASIC_REV_5720) { -+ if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO)) -+ return -EIO; -+ -+ tg3_set_function_status(tp, TG3_GPIO_MSG_DRVR_PRES); -+ -+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, -+ TG3_GRC_LCLCTL_PWRSW_DELAY); -+ -+ tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO); -+ } else { -+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, -+ TG3_GRC_LCLCTL_PWRSW_DELAY); -+ } -+ -+ return 0; -+} -+ -+static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp) -+{ -+ u32 grc_local_ctrl; -+ -+ if (!tg3_flag(tp, IS_NIC) || -+ tg3_asic_rev(tp) == ASIC_REV_5700 || -+ tg3_asic_rev(tp) == ASIC_REV_5701) -+ return; -+ -+ grc_local_ctrl = tp->grc_local_ctrl | GRC_LCLCTRL_GPIO_OE1; -+ -+ tw32_wait_f(GRC_LOCAL_CTRL, -+ grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1, -+ TG3_GRC_LCLCTL_PWRSW_DELAY); -+ -+ tw32_wait_f(GRC_LOCAL_CTRL, -+ grc_local_ctrl, -+ TG3_GRC_LCLCTL_PWRSW_DELAY); -+ -+ tw32_wait_f(GRC_LOCAL_CTRL, -+ grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1, -+ TG3_GRC_LCLCTL_PWRSW_DELAY); -+} -+ -+static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp) -+{ -+ if (!tg3_flag(tp, IS_NIC)) -+ return; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5700 || -+ tg3_asic_rev(tp) == ASIC_REV_5701) { -+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | -+ (GRC_LCLCTRL_GPIO_OE0 | -+ GRC_LCLCTRL_GPIO_OE1 | -+ GRC_LCLCTRL_GPIO_OE2 | -+ GRC_LCLCTRL_GPIO_OUTPUT0 | -+ GRC_LCLCTRL_GPIO_OUTPUT1), -+ TG3_GRC_LCLCTL_PWRSW_DELAY); -+ } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) { -+ /* The 5761 non-e device swaps GPIO 0 and GPIO 2. */ -+ u32 grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 | -+ GRC_LCLCTRL_GPIO_OE1 | -+ GRC_LCLCTRL_GPIO_OE2 | -+ GRC_LCLCTRL_GPIO_OUTPUT0 | -+ GRC_LCLCTRL_GPIO_OUTPUT1 | -+ tp->grc_local_ctrl; -+ tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, -+ TG3_GRC_LCLCTL_PWRSW_DELAY); -+ -+ grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT2; -+ tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, -+ TG3_GRC_LCLCTL_PWRSW_DELAY); -+ -+ grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT0; -+ tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, -+ TG3_GRC_LCLCTL_PWRSW_DELAY); -+ } else { -+ u32 no_gpio2; -+ u32 grc_local_ctrl = 0; -+ -+ /* Workaround to prevent overdrawing Amps. */ -+ if (tg3_asic_rev(tp) == ASIC_REV_5714) { -+ grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3; -+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | -+ grc_local_ctrl, -+ TG3_GRC_LCLCTL_PWRSW_DELAY); -+ } -+ -+ /* On 5753 and variants, GPIO2 cannot be used. */ -+ no_gpio2 = tp->nic_sram_data_cfg & -+ NIC_SRAM_DATA_CFG_NO_GPIO2; -+ -+ grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 | -+ GRC_LCLCTRL_GPIO_OE1 | -+ GRC_LCLCTRL_GPIO_OE2 | -+ GRC_LCLCTRL_GPIO_OUTPUT1 | -+ GRC_LCLCTRL_GPIO_OUTPUT2; -+ if (no_gpio2) { -+ grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 | -+ GRC_LCLCTRL_GPIO_OUTPUT2); -+ } -+ tw32_wait_f(GRC_LOCAL_CTRL, -+ tp->grc_local_ctrl | grc_local_ctrl, -+ TG3_GRC_LCLCTL_PWRSW_DELAY); -+ -+ grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0; -+ -+ tw32_wait_f(GRC_LOCAL_CTRL, -+ tp->grc_local_ctrl | grc_local_ctrl, -+ TG3_GRC_LCLCTL_PWRSW_DELAY); -+ -+ if (!no_gpio2) { -+ grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2; -+ tw32_wait_f(GRC_LOCAL_CTRL, -+ tp->grc_local_ctrl | grc_local_ctrl, -+ TG3_GRC_LCLCTL_PWRSW_DELAY); -+ } -+ } -+} -+ -+static void tg3_frob_aux_power_5717(struct tg3 *tp, bool wol_enable) -+{ -+ u32 msg = 0; -+ -+ /* Serialize power state transitions */ -+ if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO)) -+ return; -+ -+ if (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) || wol_enable) -+ msg = TG3_GPIO_MSG_NEED_VAUX; -+ -+ msg = tg3_set_function_status(tp, msg); -+ -+ if (msg & TG3_GPIO_MSG_ALL_DRVR_PRES_MASK) -+ goto done; -+ -+ if (msg & TG3_GPIO_MSG_ALL_NEED_VAUX_MASK) -+ tg3_pwrsrc_switch_to_vaux(tp); -+ else -+ tg3_pwrsrc_die_with_vmain(tp); -+ -+done: -+ tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO); -+} -+ -+static void tg3_frob_aux_power(struct tg3 *tp, bool include_wol) -+{ -+ bool need_vaux = false; -+ -+ /* The GPIOs do something completely different on 57765. */ -+ if (!tg3_flag(tp, IS_NIC) || tg3_flag(tp, 57765_CLASS)) -+ return; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_asic_rev(tp) == ASIC_REV_5720) { -+ tg3_frob_aux_power_5717(tp, include_wol ? -+ tg3_flag(tp, WOL_ENABLE) != 0 : 0); -+ return; -+ } -+ -+ if (tp->pdev_peer && tp->pdev_peer != tp->pdev) { -+ struct net_device *dev_peer; -+ -+ dev_peer = pci_get_drvdata(tp->pdev_peer); -+ -+ /* remove_one() may have been run on the peer. */ -+ if (dev_peer) { -+ struct tg3 *tp_peer = netdev_priv(dev_peer); -+ -+ if (tg3_flag(tp_peer, INIT_COMPLETE)) -+ return; -+ -+ if ((include_wol && tg3_flag(tp_peer, WOL_ENABLE)) || -+ tg3_flag(tp_peer, ENABLE_ASF)) -+ need_vaux = true; -+ } -+ } -+ -+ if ((include_wol && tg3_flag(tp, WOL_ENABLE)) || -+ tg3_flag(tp, ENABLE_ASF)) -+ need_vaux = true; -+ -+ if (need_vaux) -+ tg3_pwrsrc_switch_to_vaux(tp); -+ else -+ tg3_pwrsrc_die_with_vmain(tp); -+} -+ -+static int tg3_5700_link_polarity(struct tg3 *tp, u32 speed) -+{ -+ if (tp->led_ctrl == LED_CTRL_MODE_PHY_2) -+ return 1; -+ else if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5411) { -+ if (speed != SPEED_10) -+ return 1; -+ } else if (speed == SPEED_10) -+ return 1; -+ -+ return 0; -+} -+ -+static bool tg3_phy_power_bug(struct tg3 *tp) -+{ -+ switch (tg3_asic_rev(tp)) { -+ case ASIC_REV_5700: -+ case ASIC_REV_5704: -+ return true; -+ case ASIC_REV_5780: -+ if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) -+ return true; -+ return false; -+ case ASIC_REV_5717: -+ if (!tp->pci_fn) -+ return true; -+ return false; -+ case ASIC_REV_5719: -+ case ASIC_REV_5720: -+ if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) && -+ !tp->pci_fn) -+ return true; -+ return false; -+ } -+ -+ return false; -+} -+ -+static bool tg3_phy_led_bug(struct tg3 *tp) -+{ -+ switch (tg3_asic_rev(tp)) { -+ case ASIC_REV_5719: -+ case ASIC_REV_5720: -+ if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) && -+ !tp->pci_fn) -+ return true; -+ return false; -+ } -+ -+ return false; -+} -+ -+static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power) -+{ -+ u32 val; -+ -+ if (tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN) -+ return; -+ -+ if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { -+ if (tg3_asic_rev(tp) == ASIC_REV_5704) { -+ u32 sg_dig_ctrl = tr32(SG_DIG_CTRL); -+ u32 serdes_cfg = tr32(MAC_SERDES_CFG); -+ -+ sg_dig_ctrl |= -+ SG_DIG_USING_HW_AUTONEG | SG_DIG_SOFT_RESET; -+ tw32(SG_DIG_CTRL, sg_dig_ctrl); -+ tw32(MAC_SERDES_CFG, serdes_cfg | (1 << 15)); -+ } -+ return; -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5906) { -+ tg3_bmcr_reset(tp); -+ val = tr32(GRC_MISC_CFG); -+ tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ); -+ udelay(40); -+ return; -+ } else if (tp->phy_flags & TG3_PHYFLG_IS_FET) { -+ u32 phytest; -+ if (!tg3_readphy(tp, MII_TG3_FET_TEST, &phytest)) { -+ u32 phy; -+ -+ tg3_writephy(tp, MII_ADVERTISE, 0); -+ tg3_writephy(tp, MII_BMCR, -+ BMCR_ANENABLE | BMCR_ANRESTART); -+ -+ tg3_writephy(tp, MII_TG3_FET_TEST, -+ phytest | MII_TG3_FET_SHADOW_EN); -+ if (!tg3_readphy(tp, MII_TG3_FET_SHDW_AUXMODE4, &phy)) { -+ phy |= MII_TG3_FET_SHDW_AUXMODE4_SBPD; -+ tg3_writephy(tp, -+ MII_TG3_FET_SHDW_AUXMODE4, -+ phy); -+ } -+ tg3_writephy(tp, MII_TG3_FET_TEST, phytest); -+ } -+ return; -+ } else if (do_low_power) { -+ if (!tg3_phy_led_bug(tp)) -+ tg3_writephy(tp, MII_TG3_EXT_CTRL, -+ MII_TG3_EXT_CTRL_FORCE_LED_OFF); -+ -+ val = MII_TG3_AUXCTL_PCTL_100TX_LPWR | -+ MII_TG3_AUXCTL_PCTL_SPR_ISOLATE | -+ MII_TG3_AUXCTL_PCTL_VREG_11V; -+ tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_PWRCTL, val); -+ } -+ -+ /* The PHY should not be powered down on some chips because -+ * of bugs. -+ */ -+ if (tg3_phy_power_bug(tp)) -+ return; -+ -+ if (tg3_chip_rev(tp) == CHIPREV_5784_AX || -+ tg3_chip_rev(tp) == CHIPREV_5761_AX) { -+ val = tr32(TG3_CPMU_LSPD_1000MB_CLK); -+ val &= ~CPMU_LSPD_1000MB_MACCLK_MASK; -+ val |= CPMU_LSPD_1000MB_MACCLK_12_5; -+ tw32_f(TG3_CPMU_LSPD_1000MB_CLK, val); -+ } -+ -+ tg3_writephy(tp, MII_BMCR, BMCR_PDOWN); -+} -+ -+/* tp->lock is held. */ -+static int tg3_nvram_lock(struct tg3 *tp) -+{ -+ if (tg3_flag(tp, NVRAM)) { -+ int i; -+ -+ if (tp->nvram_lock_cnt == 0) { -+ tw32(NVRAM_SWARB, SWARB_REQ_SET1); -+ for (i = 0; i < 8000; i++) { -+ if (tr32(NVRAM_SWARB) & SWARB_GNT1) -+ break; -+ udelay(20); -+ } -+ if (i == 8000) { -+ tw32(NVRAM_SWARB, SWARB_REQ_CLR1); -+ return -ENODEV; -+ } -+ } -+ tp->nvram_lock_cnt++; -+ } -+ return 0; -+} -+ -+/* tp->lock is held. */ -+static void tg3_nvram_unlock(struct tg3 *tp) -+{ -+ if (tg3_flag(tp, NVRAM)) { -+ if (tp->nvram_lock_cnt > 0) -+ tp->nvram_lock_cnt--; -+ if (tp->nvram_lock_cnt == 0) -+ tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1); -+ } -+} -+ -+/* tp->lock is held. */ -+static void tg3_enable_nvram_access(struct tg3 *tp) -+{ -+ if (tg3_flag(tp, 5750_PLUS) && !tg3_flag(tp, PROTECTED_NVRAM)) { -+ u32 nvaccess = tr32(NVRAM_ACCESS); -+ -+ tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE); -+ } -+} -+ -+/* tp->lock is held. */ -+static void tg3_disable_nvram_access(struct tg3 *tp) -+{ -+ if (tg3_flag(tp, 5750_PLUS) && !tg3_flag(tp, PROTECTED_NVRAM)) { -+ u32 nvaccess = tr32(NVRAM_ACCESS); -+ -+ tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE); -+ } -+} -+ -+static int tg3_nvram_read_using_eeprom(struct tg3 *tp, -+ u32 offset, u32 *val) -+{ -+ u32 tmp; -+ int i; -+ -+ if (offset > EEPROM_ADDR_ADDR_MASK || (offset % 4) != 0) -+ return -EINVAL; -+ -+ tmp = tr32(GRC_EEPROM_ADDR) & ~(EEPROM_ADDR_ADDR_MASK | -+ EEPROM_ADDR_DEVID_MASK | -+ EEPROM_ADDR_READ); -+ tw32(GRC_EEPROM_ADDR, -+ tmp | -+ (0 << EEPROM_ADDR_DEVID_SHIFT) | -+ ((offset << EEPROM_ADDR_ADDR_SHIFT) & -+ EEPROM_ADDR_ADDR_MASK) | -+ EEPROM_ADDR_READ | EEPROM_ADDR_START); -+ -+ for (i = 0; i < 1000; i++) { -+ tmp = tr32(GRC_EEPROM_ADDR); -+ -+ if (tmp & EEPROM_ADDR_COMPLETE) -+ break; -+ msleep(1); -+ } -+ if (!(tmp & EEPROM_ADDR_COMPLETE)) -+ return -EBUSY; -+ -+ tmp = tr32(GRC_EEPROM_DATA); -+ -+ /* -+ * The data will always be opposite the native endian -+ * format. Perform a blind byteswap to compensate. -+ */ -+ *val = swab32(tmp); -+ -+ return 0; -+} -+ -+#define NVRAM_CMD_TIMEOUT 10000 -+ -+static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd) -+{ -+ int i; -+ -+ tw32(NVRAM_CMD, nvram_cmd); -+ for (i = 0; i < NVRAM_CMD_TIMEOUT; i++) { -+#if defined(__VMKLNX__) || (LINUX_VERSION_CODE < 0x020627) /* 2.6.39 */ -+ udelay(10); -+#else -+ usleep_range(10, 40); -+#endif -+ if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) { -+ udelay(10); -+ break; -+ } -+ } -+ -+ if (i == NVRAM_CMD_TIMEOUT) -+ return -EBUSY; -+ -+ return 0; -+} -+ -+static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr) -+{ -+ if (tg3_flag(tp, NVRAM) && -+ tg3_flag(tp, NVRAM_BUFFERED) && -+ tg3_flag(tp, FLASH) && -+ !tg3_flag(tp, NO_NVRAM_ADDR_TRANS) && -+ (tp->nvram_jedecnum == JEDEC_ATMEL)) -+ -+ addr = ((addr / tp->nvram_pagesize) << -+ ATMEL_AT45DB0X1B_PAGE_POS) + -+ (addr % tp->nvram_pagesize); -+ -+ return addr; -+} -+ -+static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr) -+{ -+ if (tg3_flag(tp, NVRAM) && -+ tg3_flag(tp, NVRAM_BUFFERED) && -+ tg3_flag(tp, FLASH) && -+ !tg3_flag(tp, NO_NVRAM_ADDR_TRANS) && -+ (tp->nvram_jedecnum == JEDEC_ATMEL)) -+ -+ addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) * -+ tp->nvram_pagesize) + -+ (addr & ((1 << ATMEL_AT45DB0X1B_PAGE_POS) - 1)); -+ -+ return addr; -+} -+ -+/* NOTE: Data read in from NVRAM is byteswapped according to -+ * the byteswapping settings for all other register accesses. -+ * tg3 devices are BE devices, so on a BE machine, the data -+ * returned will be exactly as it is seen in NVRAM. On a LE -+ * machine, the 32-bit value will be byteswapped. -+ */ -+static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val) -+{ -+ int ret; -+ -+ if (!tg3_flag(tp, NVRAM)) -+ return tg3_nvram_read_using_eeprom(tp, offset, val); -+ -+ offset = tg3_nvram_phys_addr(tp, offset); -+ -+ if (offset > NVRAM_ADDR_MSK) -+ return -EINVAL; -+ -+ ret = tg3_nvram_lock(tp); -+ if (ret) -+ return ret; -+ -+ tg3_enable_nvram_access(tp); -+ -+ tw32(NVRAM_ADDR, offset); -+ ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_RD | NVRAM_CMD_GO | -+ NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE); -+ -+ if (ret == 0) -+ *val = tr32(NVRAM_RDDATA); -+ -+ tg3_disable_nvram_access(tp); -+ -+ tg3_nvram_unlock(tp); -+ -+ return ret; -+} -+ -+/* Ensures NVRAM data is in bytestream format. */ -+static int tg3_nvram_read_be32(struct tg3 *tp, u32 offset, __be32 *val) -+{ -+ u32 v; -+ int res = tg3_nvram_read(tp, offset, &v); -+ if (!res) -+ *val = cpu_to_be32(v); -+ return res; -+} -+ -+static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp, -+ u32 offset, u32 len, u8 *buf) -+{ -+ int i, j, rc = 0; -+ u32 val; -+ -+ for (i = 0; i < len; i += 4) { -+ u32 addr; -+ __be32 data; -+ -+ addr = offset + i; -+ -+ memcpy(&data, buf + i, 4); -+ -+ /* -+ * The SEEPROM interface expects the data to always be opposite -+ * the native endian format. We accomplish this by reversing -+ * all the operations that would have been performed on the -+ * data from a call to tg3_nvram_read_be32(). -+ */ -+ tw32(GRC_EEPROM_DATA, swab32(be32_to_cpu(data))); -+ -+ val = tr32(GRC_EEPROM_ADDR); -+ tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE); -+ -+ val &= ~(EEPROM_ADDR_ADDR_MASK | EEPROM_ADDR_DEVID_MASK | -+ EEPROM_ADDR_READ); -+ tw32(GRC_EEPROM_ADDR, val | -+ (0 << EEPROM_ADDR_DEVID_SHIFT) | -+ (addr & EEPROM_ADDR_ADDR_MASK) | -+ EEPROM_ADDR_START | -+ EEPROM_ADDR_WRITE); -+ -+ for (j = 0; j < 1000; j++) { -+ val = tr32(GRC_EEPROM_ADDR); -+ -+ if (val & EEPROM_ADDR_COMPLETE) -+ break; -+ msleep(1); -+ } -+ if (!(val & EEPROM_ADDR_COMPLETE)) { -+ rc = -EBUSY; -+ break; -+ } -+ } -+ -+ return rc; -+} -+ -+/* offset and length are dword aligned */ -+static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len, -+ u8 *buf) -+{ -+ int ret = 0; -+ u32 pagesize = tp->nvram_pagesize; -+ u32 pagemask = pagesize - 1; -+ u32 nvram_cmd; -+ u8 *tmp; -+ -+ tmp = kmalloc(pagesize, GFP_KERNEL); -+ if (tmp == NULL) -+ return -ENOMEM; -+ -+ while (len) { -+ int j; -+ u32 phy_addr, page_off, size; -+ -+ phy_addr = offset & ~pagemask; -+ -+ for (j = 0; j < pagesize; j += 4) { -+ ret = tg3_nvram_read_be32(tp, phy_addr + j, -+ (__be32 *) (tmp + j)); -+ if (ret) -+ break; -+ } -+ if (ret) -+ break; -+ -+ page_off = offset & pagemask; -+ size = pagesize; -+ if (len < size) -+ size = len; -+ -+ len -= size; -+ -+ memcpy(tmp + page_off, buf, size); -+ -+ offset = offset + (pagesize - page_off); -+ -+ tg3_enable_nvram_access(tp); -+ -+ /* -+ * Before we can erase the flash page, we need -+ * to issue a special "write enable" command. -+ */ -+ nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE; -+ -+ if (tg3_nvram_exec_cmd(tp, nvram_cmd)) -+ break; -+ -+ /* Erase the target page */ -+ tw32(NVRAM_ADDR, phy_addr); -+ -+ nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR | -+ NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_ERASE; -+ -+ if (tg3_nvram_exec_cmd(tp, nvram_cmd)) -+ break; -+ -+ /* Issue another write enable to start the write. */ -+ nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE; -+ -+ if (tg3_nvram_exec_cmd(tp, nvram_cmd)) -+ break; -+ -+ for (j = 0; j < pagesize; j += 4) { -+ __be32 data; -+ -+ data = *((__be32 *) (tmp + j)); -+ -+ tw32(NVRAM_WRDATA, be32_to_cpu(data)); -+ -+ tw32(NVRAM_ADDR, phy_addr + j); -+ -+ nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | -+ NVRAM_CMD_WR; -+ -+ if (j == 0) -+ nvram_cmd |= NVRAM_CMD_FIRST; -+ else if (j == (pagesize - 4)) -+ nvram_cmd |= NVRAM_CMD_LAST; -+ -+ ret = tg3_nvram_exec_cmd(tp, nvram_cmd); -+ if (ret) -+ break; -+ } -+ if (ret) -+ break; -+ } -+ -+ nvram_cmd = NVRAM_CMD_WRDI | NVRAM_CMD_GO | NVRAM_CMD_DONE; -+ tg3_nvram_exec_cmd(tp, nvram_cmd); -+ -+ kfree(tmp); -+ -+ return ret; -+} -+ -+/* offset and length are dword aligned */ -+static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len, -+ u8 *buf) -+{ -+ int i, ret = 0; -+ -+ for (i = 0; i < len; i += 4, offset += 4) { -+ u32 page_off, phy_addr, nvram_cmd; -+ __be32 data; -+ -+ memcpy(&data, buf + i, 4); -+ tw32(NVRAM_WRDATA, be32_to_cpu(data)); -+ -+ page_off = offset % tp->nvram_pagesize; -+ -+ phy_addr = tg3_nvram_phys_addr(tp, offset); -+ -+ nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR; -+ -+ if (page_off == 0 || i == 0) -+ nvram_cmd |= NVRAM_CMD_FIRST; -+ if (page_off == (tp->nvram_pagesize - 4)) -+ nvram_cmd |= NVRAM_CMD_LAST; -+ -+ if (i == (len - 4)) -+ nvram_cmd |= NVRAM_CMD_LAST; -+ -+ if ((nvram_cmd & NVRAM_CMD_FIRST) || -+ !tg3_flag(tp, FLASH) || -+ !tg3_flag(tp, 57765_PLUS)) -+ tw32(NVRAM_ADDR, phy_addr); -+ -+ if (tg3_asic_rev(tp) != ASIC_REV_5752 && -+ !tg3_flag(tp, 5755_PLUS) && -+ (tp->nvram_jedecnum == JEDEC_ST) && -+ (nvram_cmd & NVRAM_CMD_FIRST)) { -+ u32 cmd; -+ -+ cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE; -+ ret = tg3_nvram_exec_cmd(tp, cmd); -+ if (ret) -+ break; -+ } -+ if (!tg3_flag(tp, FLASH)) { -+ /* We always do complete word writes to eeprom. */ -+ nvram_cmd |= (NVRAM_CMD_FIRST | NVRAM_CMD_LAST); -+ } -+ -+ ret = tg3_nvram_exec_cmd(tp, nvram_cmd); -+ if (ret) -+ break; -+ } -+ return ret; -+} -+ -+/* offset and length are dword aligned */ -+static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf) -+{ -+ int ret; -+ -+ if (tg3_flag(tp, EEPROM_WRITE_PROT)) { -+ tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl & -+ ~GRC_LCLCTRL_GPIO_OUTPUT1); -+ udelay(40); -+ } -+ -+ if (!tg3_flag(tp, NVRAM)) { -+ ret = tg3_nvram_write_block_using_eeprom(tp, offset, len, buf); -+ } else { -+ u32 grc_mode; -+ -+ ret = tg3_nvram_lock(tp); -+ if (ret) -+ return ret; -+ -+ tg3_enable_nvram_access(tp); -+ if (tg3_flag(tp, 5750_PLUS) && !tg3_flag(tp, PROTECTED_NVRAM)) -+ tw32(NVRAM_WRITE1, 0x406); -+ -+ grc_mode = tr32(GRC_MODE); -+ tw32(GRC_MODE, grc_mode | GRC_MODE_NVRAM_WR_ENABLE); -+ -+ if (tg3_flag(tp, NVRAM_BUFFERED) || !tg3_flag(tp, FLASH)) { -+ ret = tg3_nvram_write_block_buffered(tp, offset, len, -+ buf); -+ } else { -+ ret = tg3_nvram_write_block_unbuffered(tp, offset, len, -+ buf); -+ } -+ -+ grc_mode = tr32(GRC_MODE); -+ tw32(GRC_MODE, grc_mode & ~GRC_MODE_NVRAM_WR_ENABLE); -+ -+ tg3_disable_nvram_access(tp); -+ tg3_nvram_unlock(tp); -+ } -+ -+ if (tg3_flag(tp, EEPROM_WRITE_PROT)) { -+ tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); -+ udelay(40); -+ } -+ -+ return ret; -+} -+ -+#define RX_CPU_SCRATCH_BASE 0x30000 -+#define RX_CPU_SCRATCH_SIZE 0x04000 -+#define TX_CPU_SCRATCH_BASE 0x34000 -+#define TX_CPU_SCRATCH_SIZE 0x04000 -+ -+/* tp->lock is held. */ -+static int tg3_pause_cpu(struct tg3 *tp, u32 cpu_base) -+{ -+ int i; -+ const int iters = 10000; -+ -+ for (i = 0; i < iters; i++) { -+ tw32(cpu_base + CPU_STATE, 0xffffffff); -+ tw32(cpu_base + CPU_MODE, CPU_MODE_HALT); -+ if (tr32(cpu_base + CPU_MODE) & CPU_MODE_HALT) -+ break; -+ if (pci_channel_offline(tp->pdev)) -+ return -EBUSY; -+ } -+ -+ return (i == iters) ? -EBUSY : 0; -+} -+ -+/* tp->lock is held. */ -+static int tg3_rxcpu_pause(struct tg3 *tp) -+{ -+ int rc = tg3_pause_cpu(tp, RX_CPU_BASE); -+ -+ tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff); -+ tw32_f(RX_CPU_BASE + CPU_MODE, CPU_MODE_HALT); -+ udelay(10); -+ -+ return rc; -+} -+ -+/* tp->lock is held. */ -+static int tg3_txcpu_pause(struct tg3 *tp) -+{ -+ return tg3_pause_cpu(tp, TX_CPU_BASE); -+} -+ -+/* tp->lock is held. */ -+static void tg3_resume_cpu(struct tg3 *tp, u32 cpu_base) -+{ -+ tw32(cpu_base + CPU_STATE, 0xffffffff); -+ tw32_f(cpu_base + CPU_MODE, 0x00000000); -+} -+ -+/* tp->lock is held. */ -+static void tg3_rxcpu_resume(struct tg3 *tp) -+{ -+ tg3_resume_cpu(tp, RX_CPU_BASE); -+} -+ -+/* tp->lock is held. */ -+static int tg3_halt_cpu(struct tg3 *tp, u32 cpu_base) -+{ -+ int rc; -+ -+ BUG_ON(cpu_base == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS)); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5906) { -+ u32 val = tr32(GRC_VCPU_EXT_CTRL); -+ -+ tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_HALT_CPU); -+ return 0; -+ } -+ if (cpu_base == RX_CPU_BASE) { -+ rc = tg3_rxcpu_pause(tp); -+ } else { -+ /* -+ * There is only an Rx CPU for the 5750 derivative in the -+ * BCM4785. -+ */ -+ if (tg3_flag(tp, IS_SSB_CORE)) -+ return 0; -+ -+ rc = tg3_txcpu_pause(tp); -+ } -+ -+ if (rc) { -+ netdev_err(tp->dev, "%s timed out, %s CPU\n", -+ __func__, cpu_base == RX_CPU_BASE ? "RX" : "TX"); -+ return -ENODEV; -+ } -+ -+ /* Clear firmware's nvram arbitration. */ -+ if (tg3_flag(tp, NVRAM)) -+ tw32(NVRAM_SWARB, SWARB_REQ_CLR0); -+ return 0; -+} -+ -+static int tg3_fw_data_len(const struct tg3_firmware_hdr *fw_hdr) -+{ -+ return (fw_hdr->len - TG3_FW_HDR_LEN) / sizeof(u32); -+} -+ -+/* tp->lock is held. */ -+static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, -+ u32 cpu_scratch_base, int cpu_scratch_size, -+ const struct tg3_firmware_hdr *fw_hdr) -+{ -+ int err, i; -+ void (*write_op)(struct tg3 *, u32, u32); -+ int total_len = tp->fw->size; -+ -+ if (cpu_base == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS)) { -+ netdev_err(tp->dev, -+ "%s: Trying to load TX cpu firmware which is 5705\n", -+ __func__); -+ return -EINVAL; -+ } -+ -+ if (tg3_flag(tp, 5705_PLUS) && tg3_asic_rev(tp) != ASIC_REV_57766) -+ write_op = tg3_write_mem; -+ else -+ write_op = tg3_write_indirect_reg32; -+ -+ if (tg3_asic_rev(tp) != ASIC_REV_57766) { -+ /* It is possible that bootcode is still loading at this point. -+ * Get the nvram lock first before halting the cpu. -+ */ -+ int lock_err = tg3_nvram_lock(tp); -+ err = tg3_halt_cpu(tp, cpu_base); -+ if (!lock_err) -+ tg3_nvram_unlock(tp); -+ if (err) -+ goto out; -+ -+ for (i = 0; i < cpu_scratch_size; i += sizeof(u32)) -+ write_op(tp, cpu_scratch_base + i, 0); -+ tw32(cpu_base + CPU_STATE, 0xffffffff); -+ tw32(cpu_base + CPU_MODE, -+ tr32(cpu_base + CPU_MODE) | CPU_MODE_HALT); -+ } else { -+ /* Subtract additional main header for fragmented firmware and -+ * advance to the first fragment -+ */ -+ total_len -= TG3_FW_HDR_LEN; -+ fw_hdr++; -+ } -+ -+ do { -+ u32 *fw_data = (u32 *)(fw_hdr + 1); -+ for (i = 0; i < tg3_fw_data_len(fw_hdr); i++) -+ write_op(tp, cpu_scratch_base + -+ (fw_hdr->base_addr & 0xffff) + -+ (i * sizeof(u32)), -+ fw_data[i]); -+ -+ total_len -= fw_hdr->len; -+ -+ /* Advance to next fragment */ -+ fw_hdr = (struct tg3_firmware_hdr *) -+ ((void *)fw_hdr + fw_hdr->len); -+ } while (total_len > 0); -+ -+ err = 0; -+ -+out: -+ return err; -+} -+ -+/* tp->lock is held. */ -+static int tg3_pause_cpu_and_set_pc(struct tg3 *tp, u32 cpu_base, u32 pc) -+{ -+ int i; -+ const int iters = 5; -+ -+ tw32(cpu_base + CPU_STATE, 0xffffffff); -+ tw32_f(cpu_base + CPU_PC, pc); -+ -+ for (i = 0; i < iters; i++) { -+ if (tr32(cpu_base + CPU_PC) == pc) -+ break; -+ tw32(cpu_base + CPU_STATE, 0xffffffff); -+ tw32(cpu_base + CPU_MODE, CPU_MODE_HALT); -+ tw32_f(cpu_base + CPU_PC, pc); -+ udelay(1000); -+ } -+ -+ return (i == iters) ? -EBUSY : 0; -+} -+ -+/* tp->lock is held. */ -+static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) -+{ -+ const struct tg3_firmware_hdr *fw_hdr; -+ int err; -+ -+ fw_hdr = (struct tg3_firmware_hdr *)tp->fw->data; -+ -+ /* Firmware blob starts with version numbers, followed by -+ start address and length. We are setting complete length. -+ length = end_address_of_bss - start_address_of_text. -+ Remainder is the blob to be loaded contiguously -+ from start address. */ -+ -+ err = tg3_load_firmware_cpu(tp, RX_CPU_BASE, -+ RX_CPU_SCRATCH_BASE, RX_CPU_SCRATCH_SIZE, -+ fw_hdr); -+ if (err) -+ return err; -+ -+ err = tg3_load_firmware_cpu(tp, TX_CPU_BASE, -+ TX_CPU_SCRATCH_BASE, TX_CPU_SCRATCH_SIZE, -+ fw_hdr); -+ if (err) -+ return err; -+ -+ /* Now startup only the RX cpu. */ -+ err = tg3_pause_cpu_and_set_pc(tp, RX_CPU_BASE, -+ fw_hdr->base_addr); -+ if (err) { -+ netdev_err(tp->dev, "%s fails to set RX CPU PC, is %08x " -+ "should be %08x\n", __func__, -+ tr32(RX_CPU_BASE + CPU_PC), -+ fw_hdr->base_addr); -+ return -ENODEV; -+ } -+ -+ tg3_rxcpu_resume(tp); -+ -+ return 0; -+} -+ -+static int tg3_validate_rxcpu_state(struct tg3 *tp) -+{ -+ const int iters = 1000; -+ int i; -+ u32 val; -+ -+ /* Wait for boot code to complete initialization and enter service -+ * loop. It is then safe to download service patches -+ */ -+ for (i = 0; i < iters; i++) { -+ if (tr32(RX_CPU_HWBKPT) == TG3_SBROM_IN_SERVICE_LOOP) -+ break; -+ -+ udelay(10); -+ } -+ -+ if (i == iters) { -+ netdev_err(tp->dev, "Boot code not ready for service patches\n"); -+ return -EBUSY; -+ } -+ -+ val = tg3_read_indirect_reg32(tp, TG3_57766_FW_HANDSHAKE); -+ if (val & 0xff) { -+ netdev_warn(tp->dev, -+ "Other patches exist. Not downloading EEE patch\n"); -+ return -EEXIST; -+ } -+ -+ return 0; -+} -+ -+/* tp->lock is held. */ -+static void tg3_load_57766_firmware(struct tg3 *tp) -+{ -+ struct tg3_firmware_hdr *fw_hdr; -+ -+ if (!tg3_flag(tp, NO_NVRAM)) -+ return; -+ -+ if (tg3_validate_rxcpu_state(tp)) -+ return; -+ -+ if (!tp->fw) -+ return; -+ -+ /* This firmware blob has a different format than older firmware -+ * releases as given below. The main difference is we have fragmented -+ * data to be written to non-contiguous locations. -+ * -+ * In the beginning we have a firmware header identical to other -+ * firmware which consists of version, base addr and length. The length -+ * here is unused and set to 0xffffffff. -+ * -+ * This is followed by a series of firmware fragments which are -+ * individually identical to previous firmware. i.e. they have the -+ * firmware header and followed by data for that fragment. The version -+ * field of the individual fragment header is unused. -+ */ -+ -+ fw_hdr = (struct tg3_firmware_hdr *)tp->fw->data; -+ if (fw_hdr->base_addr != TG3_57766_FW_BASE_ADDR) -+ return; -+ -+ if (tg3_rxcpu_pause(tp)) -+ return; -+ -+ /* tg3_load_firmware_cpu() will always succeed for the 57766 */ -+ tg3_load_firmware_cpu(tp, 0, TG3_57766_FW_BASE_ADDR, 0, fw_hdr); -+ -+ tg3_rxcpu_resume(tp); -+} -+ -+#if TG3_TSO_SUPPORT != 0 -+ -+/* tp->lock is held. */ -+static int tg3_load_tso_firmware(struct tg3 *tp) -+{ -+ const struct tg3_firmware_hdr *fw_hdr; -+ unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size; -+ int err; -+ -+ if (!tg3_flag(tp, FW_TSO)) -+ return 0; -+ -+ fw_hdr = (struct tg3_firmware_hdr *)tp->fw->data; -+ -+ /* Firmware blob starts with version numbers, followed by -+ start address and length. We are setting complete length. -+ length = end_address_of_bss - start_address_of_text. -+ Remainder is the blob to be loaded contiguously -+ from start address. */ -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5705) { -+ cpu_base = RX_CPU_BASE; -+ cpu_scratch_base = NIC_SRAM_MBUF_POOL_BASE5705; -+ cpu_scratch_size = (tp->fw->size - TG3_FW_HDR_LEN + -+ TG3_TSO5_FW_SBSS_LEN + -+ TG3_TSO5_FW_BSS_LEN); -+ } else { -+ cpu_base = TX_CPU_BASE; -+ cpu_scratch_base = TX_CPU_SCRATCH_BASE; -+ cpu_scratch_size = TX_CPU_SCRATCH_SIZE; -+ } -+ -+ err = tg3_load_firmware_cpu(tp, cpu_base, -+ cpu_scratch_base, cpu_scratch_size, -+ fw_hdr); -+ if (err) -+ return err; -+ -+ /* Now startup the cpu. */ -+ err = tg3_pause_cpu_and_set_pc(tp, cpu_base, -+ fw_hdr->base_addr); -+ if (err) { -+ netdev_err(tp->dev, -+ "%s fails to set CPU PC, is %08x should be %08x\n", -+ __func__, tr32(cpu_base + CPU_PC), -+ fw_hdr->base_addr); -+ return -ENODEV; -+ } -+ -+ tg3_resume_cpu(tp, cpu_base); -+ return 0; -+} -+ -+#endif /* TG3_TSO_SUPPORT != 0 */ -+ -+/* tp->lock is held. */ -+static void __tg3_set_one_mac_addr(struct tg3 *tp, u8 *mac_addr, int index) -+{ -+ u32 addr_high, addr_low; -+ -+ addr_high = ((mac_addr[0] << 8) | mac_addr[1]); -+ addr_low = ((mac_addr[2] << 24) | (mac_addr[3] << 16) | -+ (mac_addr[4] << 8) | mac_addr[5]); -+ -+ if (index < 4) { -+ tw32(MAC_ADDR_0_HIGH + (index * 8), addr_high); -+ tw32(MAC_ADDR_0_LOW + (index * 8), addr_low); -+ } else { -+ index -= 4; -+ tw32(MAC_EXTADDR_0_HIGH + (index * 8), addr_high); -+ tw32(MAC_EXTADDR_0_LOW + (index * 8), addr_low); -+ } -+} -+ -+/* tp->lock is held. */ -+static void __tg3_set_mac_addr(struct tg3 *tp, bool skip_mac_1) -+{ -+ u32 addr_high; -+ int i; -+ -+ for (i = 0; i < 4; i++) { -+ if (i == 1 && skip_mac_1) -+ continue; -+ __tg3_set_one_mac_addr(tp, tp->dev->dev_addr, i); -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5703 || -+ tg3_asic_rev(tp) == ASIC_REV_5704) { -+ for (i = 4; i < 16; i++) -+ __tg3_set_one_mac_addr(tp, tp->dev->dev_addr, i); -+ } -+ -+ addr_high = (tp->dev->dev_addr[0] + -+ tp->dev->dev_addr[1] + -+ tp->dev->dev_addr[2] + -+ tp->dev->dev_addr[3] + -+ tp->dev->dev_addr[4] + -+ tp->dev->dev_addr[5]) & -+ TX_BACKOFF_SEED_MASK; -+ tw32(MAC_TX_BACKOFF_SEED, addr_high); -+} -+ -+static void tg3_enable_register_access(struct tg3 *tp) -+{ -+ /* -+ * Make sure register accesses (indirect or otherwise) will function -+ * correctly. -+ */ -+ pci_write_config_dword(tp->pdev, -+ TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl); -+} -+ -+static int tg3_power_up(struct tg3 *tp) -+{ -+ int err; -+ -+ tg3_enable_register_access(tp); -+ -+ /* Kernels less than around 2.6.37 still need this */ -+ pci_enable_wake(tp->pdev, PCI_D0, false); -+ -+ err = pci_set_power_state(tp->pdev, PCI_D0); -+ if (!err) { -+ /* Switch out of Vaux if it is a NIC */ -+ tg3_pwrsrc_switch_to_vmain(tp); -+ } else { -+ netdev_err(tp->dev, "Transition to D0 failed\n"); -+ } -+ -+ return err; -+} -+ -+static void tg3_power_down(struct tg3 *tp) -+{ -+ pci_wake_from_d3(tp->pdev, tg3_flag(tp, WOL_ENABLE)); -+ pci_set_power_state(tp->pdev, PCI_D3hot); -+} -+ -+static int tg3_setup_phy(struct tg3 *, bool); -+ -+static int tg3_power_down_prepare(struct tg3 *tp) -+{ -+ u32 misc_host_ctrl; -+ bool device_should_wake, do_low_power; -+ -+ tg3_enable_register_access(tp); -+ -+ /* Restore the CLKREQ setting. */ -+ if (tg3_flag(tp, CLKREQ_BUG)) -+ pcie_capability_set_word(tp->pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_CLKREQ_EN); -+ -+ misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL); -+ tw32(TG3PCI_MISC_HOST_CTRL, -+ misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT); -+ -+ device_should_wake = device_may_wakeup(&tp->pdev->dev) && -+ tg3_flag(tp, WOL_ENABLE); -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_flag(tp, USE_PHYLIB)) { -+ do_low_power = false; -+ if ((tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) && -+ !(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) { -+ struct phy_device *phydev; -+ u32 phyid, advertising; -+ -+ phydev = tp->mdio_bus->phy_map[tp->phy_addr]; -+ -+ tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER; -+ -+ tp->link_config.speed = phydev->speed; -+ tp->link_config.duplex = phydev->duplex; -+ tp->link_config.autoneg = phydev->autoneg; -+ tp->link_config.advertising = phydev->advertising; -+ -+ advertising = ADVERTISED_TP | -+ ADVERTISED_Pause | -+ ADVERTISED_Autoneg | -+ ADVERTISED_10baseT_Half; -+ -+ if (tg3_flag(tp, ENABLE_ASF) || device_should_wake) { -+ if (tg3_flag(tp, WOL_SPEED_100MB)) -+ advertising |= -+ ADVERTISED_100baseT_Half | -+ ADVERTISED_100baseT_Full | -+ ADVERTISED_10baseT_Full; -+ else -+ advertising |= ADVERTISED_10baseT_Full; -+ } -+ -+ phydev->advertising = advertising; -+ -+ phy_start_aneg(phydev); -+ -+ phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask; -+ if (phyid != PHY_ID_BCMAC131) { -+ phyid &= PHY_BCM_OUI_MASK; -+ if (phyid == PHY_BCM_OUI_1 || -+ phyid == PHY_BCM_OUI_2 || -+ phyid == PHY_BCM_OUI_3) -+ do_low_power = true; -+ } -+ } -+ } else -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+ { -+ do_low_power = true; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) -+ tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) -+ tg3_setup_phy(tp, false); -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5906) { -+ u32 val; -+ -+ val = tr32(GRC_VCPU_EXT_CTRL); -+ tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_DISABLE_WOL); -+ } else if (!tg3_flag(tp, ENABLE_ASF)) { -+ int i; -+ u32 val; -+ -+ for (i = 0; i < 200; i++) { -+ tg3_read_mem(tp, NIC_SRAM_FW_ASF_STATUS_MBOX, &val); -+ if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) -+ break; -+ msleep(1); -+ } -+ } -+ if (tg3_flag(tp, WOL_CAP)) -+ tg3_write_mem(tp, NIC_SRAM_WOL_MBOX, WOL_SIGNATURE | -+ WOL_DRV_STATE_SHUTDOWN | -+ WOL_DRV_WOL | -+ WOL_SET_MAGIC_PKT); -+ -+ if (device_should_wake) { -+ u32 mac_mode; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) { -+ if (do_low_power && -+ !(tp->phy_flags & TG3_PHYFLG_IS_FET)) { -+ tg3_phy_auxctl_write(tp, -+ MII_TG3_AUXCTL_SHDWSEL_PWRCTL, -+ MII_TG3_AUXCTL_PCTL_WOL_EN | -+ MII_TG3_AUXCTL_PCTL_100TX_LPWR | -+ MII_TG3_AUXCTL_PCTL_CL_AB_TXDAC); -+ udelay(40); -+ } -+ -+ if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) -+ mac_mode = MAC_MODE_PORT_MODE_GMII; -+ else if (tp->phy_flags & -+ TG3_PHYFLG_KEEP_LINK_ON_PWRDN) { -+ if (tp->link_config.active_speed == SPEED_1000) -+ mac_mode = MAC_MODE_PORT_MODE_GMII; -+ else -+ mac_mode = MAC_MODE_PORT_MODE_MII; -+ } else -+ mac_mode = MAC_MODE_PORT_MODE_MII; -+ -+ mac_mode |= tp->mac_mode & MAC_MODE_LINK_POLARITY; -+ if (tg3_asic_rev(tp) == ASIC_REV_5700) { -+ u32 speed = tg3_flag(tp, WOL_SPEED_100MB) ? -+ SPEED_100 : SPEED_10; -+ if (tg3_5700_link_polarity(tp, speed)) -+ mac_mode |= MAC_MODE_LINK_POLARITY; -+ else -+ mac_mode &= ~MAC_MODE_LINK_POLARITY; -+ } -+ } else { -+ mac_mode = MAC_MODE_PORT_MODE_TBI; -+ } -+ -+ if (!tg3_flag(tp, 5750_PLUS)) -+ tw32(MAC_LED_CTRL, tp->led_ctrl); -+ -+ mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE; -+ if ((tg3_flag(tp, 5705_PLUS) && !tg3_flag(tp, 5780_CLASS)) && -+ (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE))) -+ mac_mode |= MAC_MODE_KEEP_FRAME_IN_WOL; -+ -+ if (tg3_flag(tp, ENABLE_APE)) -+ mac_mode |= MAC_MODE_APE_TX_EN | -+ MAC_MODE_APE_RX_EN | -+ MAC_MODE_TDE_ENABLE; -+ -+ tw32_f(MAC_MODE, mac_mode); -+ udelay(100); -+ -+ tw32_f(MAC_RX_MODE, RX_MODE_ENABLE); -+ udelay(10); -+ } -+ -+ if (!tg3_flag(tp, WOL_SPEED_100MB) && -+ (tg3_asic_rev(tp) == ASIC_REV_5700 || -+ tg3_asic_rev(tp) == ASIC_REV_5701)) { -+ u32 base_val; -+ -+ base_val = tp->pci_clock_ctrl; -+ base_val |= (CLOCK_CTRL_RXCLK_DISABLE | -+ CLOCK_CTRL_TXCLK_DISABLE); -+ -+ tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK | -+ CLOCK_CTRL_PWRDOWN_PLL133, 40); -+ } else if (tg3_flag(tp, 5780_CLASS) || -+ tg3_flag(tp, CPMU_PRESENT) || -+ tg3_asic_rev(tp) == ASIC_REV_5906) { -+ /* do nothing */ -+ } else if (!(tg3_flag(tp, 5750_PLUS) && tg3_flag(tp, ENABLE_ASF))) { -+ u32 newbits1, newbits2; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5700 || -+ tg3_asic_rev(tp) == ASIC_REV_5701) { -+ newbits1 = (CLOCK_CTRL_RXCLK_DISABLE | -+ CLOCK_CTRL_TXCLK_DISABLE | -+ CLOCK_CTRL_ALTCLK); -+ newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE; -+ } else if (tg3_flag(tp, 5705_PLUS)) { -+ newbits1 = CLOCK_CTRL_625_CORE; -+ newbits2 = newbits1 | CLOCK_CTRL_ALTCLK; -+ } else { -+ newbits1 = CLOCK_CTRL_ALTCLK; -+ newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE; -+ } -+ -+ tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1, -+ 40); -+ -+ tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2, -+ 40); -+ -+ if (!tg3_flag(tp, 5705_PLUS)) { -+ u32 newbits3; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5700 || -+ tg3_asic_rev(tp) == ASIC_REV_5701) { -+ newbits3 = (CLOCK_CTRL_RXCLK_DISABLE | -+ CLOCK_CTRL_TXCLK_DISABLE | -+ CLOCK_CTRL_44MHZ_CORE); -+ } else { -+ newbits3 = CLOCK_CTRL_44MHZ_CORE; -+ } -+ -+ tw32_wait_f(TG3PCI_CLOCK_CTRL, -+ tp->pci_clock_ctrl | newbits3, 40); -+ } -+ } -+ -+ if (!(device_should_wake) && !tg3_flag(tp, ENABLE_ASF)) -+ tg3_power_down_phy(tp, do_low_power); -+ -+ tg3_frob_aux_power(tp, true); -+ -+ /* Workaround for unstable PLL clock */ -+ if ((!tg3_flag(tp, IS_SSB_CORE)) && -+ ((tg3_chip_rev(tp) == CHIPREV_5750_AX) || -+ (tg3_chip_rev(tp) == CHIPREV_5750_BX))) { -+ u32 val = tr32(0x7d00); -+ -+ val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1); -+ tw32(0x7d00, val); -+ if (!tg3_flag(tp, ENABLE_ASF)) { -+ int err; -+ -+ err = tg3_nvram_lock(tp); -+ tg3_halt_cpu(tp, RX_CPU_BASE); -+ if (!err) -+ tg3_nvram_unlock(tp); -+ } -+ } -+ -+ tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); -+ -+ tg3_ape_driver_state_change(tp, RESET_KIND_SHUTDOWN); -+ -+ return 0; -+} -+ -+static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 *duplex) -+{ -+ switch (val & MII_TG3_AUX_STAT_SPDMASK) { -+ case MII_TG3_AUX_STAT_10HALF: -+ *speed = SPEED_10; -+ *duplex = DUPLEX_HALF; -+ break; -+ -+ case MII_TG3_AUX_STAT_10FULL: -+ *speed = SPEED_10; -+ *duplex = DUPLEX_FULL; -+ break; -+ -+ case MII_TG3_AUX_STAT_100HALF: -+ *speed = SPEED_100; -+ *duplex = DUPLEX_HALF; -+ break; -+ -+ case MII_TG3_AUX_STAT_100FULL: -+ *speed = SPEED_100; -+ *duplex = DUPLEX_FULL; -+ break; -+ -+ case MII_TG3_AUX_STAT_1000HALF: -+ *speed = SPEED_1000; -+ *duplex = DUPLEX_HALF; -+ break; -+ -+ case MII_TG3_AUX_STAT_1000FULL: -+ *speed = SPEED_1000; -+ *duplex = DUPLEX_FULL; -+ break; -+ -+ default: -+ if (tp->phy_flags & TG3_PHYFLG_IS_FET) { -+ *speed = (val & MII_TG3_AUX_STAT_100) ? SPEED_100 : -+ SPEED_10; -+ *duplex = (val & MII_TG3_AUX_STAT_FULL) ? DUPLEX_FULL : -+ DUPLEX_HALF; -+ break; -+ } -+ *speed = SPEED_UNKNOWN; -+ *duplex = DUPLEX_UNKNOWN; -+ break; -+ } -+} -+ -+static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) -+{ -+ int err = 0; -+ u32 val, new_adv; -+ -+ new_adv = ADVERTISE_CSMA; -+ new_adv |= ethtool_adv_to_mii_adv_t(advertise) & ADVERTISE_ALL; -+ new_adv |= mii_advertise_flowctrl(flowctrl); -+ -+ err = tg3_writephy(tp, MII_ADVERTISE, new_adv); -+ if (err) -+ goto done; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) { -+ new_adv = ethtool_adv_to_mii_ctrl1000_t(advertise); -+ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5701_A0 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5701_B0) -+ new_adv |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER; -+ -+ err = tg3_writephy(tp, MII_CTRL1000, new_adv); -+ if (err) -+ goto done; -+ } -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) -+ goto done; -+ -+#ifndef BCM_INCLUDE_PHYLIB_SUPPORT -+ if ((tp->phy_id & TG3_PHY_ID_MASK) != TG3_PHY_ID_BCM50612E) -+#endif -+ tw32(TG3_CPMU_EEE_MODE, -+ tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE); -+ -+ err = tg3_phy_toggle_auxctl_smdsp(tp, true); -+ if (!err) { -+ u32 err2; -+ -+ val = 0; -+ /* Advertise 100-BaseTX EEE ability */ -+ if (advertise & ADVERTISED_100baseT_Full) -+ val |= MDIO_AN_EEE_ADV_100TX; -+ /* Advertise 1000-BaseT EEE ability */ -+ if (advertise & ADVERTISED_1000baseT_Full) -+ val |= MDIO_AN_EEE_ADV_1000T; -+ -+ if (!tp->eee.eee_enabled) { -+ val = 0; -+ tp->eee.advertised = 0; -+ } else { -+ tp->eee.advertised = advertise & -+ (ADVERTISED_100baseT_Full | -+ ADVERTISED_1000baseT_Full); -+ } -+ -+ err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); -+ if (err) -+ goto err_out; -+ -+ switch (tg3_asic_rev(tp)) { -+ case ASIC_REV_5717: -+ case ASIC_REV_57765: -+ case ASIC_REV_57766: -+ case ASIC_REV_5719: -+ /* If we advertised any eee advertisements above... */ -+ if (val) -+ val = MII_TG3_DSP_TAP26_ALNOKO | -+ MII_TG3_DSP_TAP26_RMRXSTO | -+ MII_TG3_DSP_TAP26_OPCSINPT; -+ tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); -+ /* Fall through */ -+ case ASIC_REV_5720: -+ case ASIC_REV_5762: -+ if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val)) -+ tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val | -+ MII_TG3_DSP_CH34TP2_HIBW01); -+ } -+ -+#ifndef BCM_INCLUDE_PHYLIB_SUPPORT -+ if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM50612E) { -+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, MII_TG3_DSP_TLER); -+ tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &val); -+ if (tp->link_config.autoneg == AUTONEG_ENABLE) -+ val |= MII_TG3_DSP_TLER_AUTOGREEEN_EN; -+ else -+ val &= ~MII_TG3_DSP_TLER_AUTOGREEEN_EN; -+ tg3_phydsp_write(tp, MII_TG3_DSP_TLER, val); -+ } -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+ -+err_out: -+ err2 = tg3_phy_toggle_auxctl_smdsp(tp, false); -+ if (!err) -+ err = err2; -+ } -+ -+done: -+ return err; -+} -+ -+static void tg3_phy_copper_begin(struct tg3 *tp) -+{ -+ if (tp->link_config.autoneg == AUTONEG_ENABLE || -+ (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) { -+ u32 adv, fc; -+ -+ if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) && -+ !(tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN)) { -+ adv = ADVERTISED_10baseT_Half | -+ ADVERTISED_10baseT_Full; -+ if (tg3_flag(tp, WOL_SPEED_100MB)) -+ adv |= ADVERTISED_100baseT_Half | -+ ADVERTISED_100baseT_Full; -+ if (tp->phy_flags & TG3_PHYFLG_1G_ON_VAUX_OK) { -+ if (!(tp->phy_flags & -+ TG3_PHYFLG_DISABLE_1G_HD_ADV)) -+ adv |= ADVERTISED_1000baseT_Half; -+ adv |= ADVERTISED_1000baseT_Full; -+ } -+ -+ fc = FLOW_CTRL_TX | FLOW_CTRL_RX; -+ } else { -+ adv = tp->link_config.advertising; -+ if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) -+ adv &= ~(ADVERTISED_1000baseT_Half | -+ ADVERTISED_1000baseT_Full); -+ -+ fc = tp->link_config.flowctrl; -+ } -+ -+ tg3_phy_autoneg_cfg(tp, adv, fc); -+ -+ if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) && -+ (tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN)) { -+ /* Normally during power down we want to autonegotiate -+ * the lowest possible speed for WOL. However, to avoid -+ * link flap, we leave it untouched. -+ */ -+ return; -+ } -+ -+ tg3_writephy(tp, MII_BMCR, -+ BMCR_ANENABLE | BMCR_ANRESTART); -+ } else { -+ int i; -+ u32 bmcr, orig_bmcr; -+ -+ tp->link_config.active_speed = tp->link_config.speed; -+ tp->link_config.active_duplex = tp->link_config.duplex; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5714) { -+ /* With autoneg disabled, 5715 only links up when the -+ * advertisement register has the configured speed -+ * enabled. -+ */ -+ tg3_writephy(tp, MII_ADVERTISE, ADVERTISE_ALL); -+ } -+ -+ bmcr = 0; -+ switch (tp->link_config.speed) { -+ default: -+ case SPEED_10: -+ break; -+ -+ case SPEED_100: -+ bmcr |= BMCR_SPEED100; -+ break; -+ -+ case SPEED_1000: -+ bmcr |= BMCR_SPEED1000; -+ break; -+ } -+ -+ if (tp->link_config.duplex == DUPLEX_FULL) -+ bmcr |= BMCR_FULLDPLX; -+ -+ if (!tg3_readphy(tp, MII_BMCR, &orig_bmcr) && -+ (bmcr != orig_bmcr)) { -+ tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK); -+ for (i = 0; i < 1500; i++) { -+ u32 tmp; -+ -+ udelay(10); -+ if (tg3_readphy(tp, MII_BMSR, &tmp) || -+ tg3_readphy(tp, MII_BMSR, &tmp)) -+ continue; -+ if (!(tmp & BMSR_LSTATUS)) { -+ udelay(40); -+ break; -+ } -+ } -+ tg3_writephy(tp, MII_BMCR, bmcr); -+ udelay(40); -+ } -+ } -+} -+ -+static int tg3_phy_pull_config(struct tg3 *tp) -+{ -+ int err; -+ u32 val; -+ -+ err = tg3_readphy(tp, MII_BMCR, &val); -+ if (err) -+ goto done; -+ -+ if (!(val & BMCR_ANENABLE)) { -+ tp->link_config.autoneg = AUTONEG_DISABLE; -+ tp->link_config.advertising = 0; -+ tg3_flag_clear(tp, PAUSE_AUTONEG); -+ -+ err = -EIO; -+ -+ switch (val & (BMCR_SPEED1000 | BMCR_SPEED100)) { -+ case 0: -+ if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) -+ goto done; -+ -+ tp->link_config.speed = SPEED_10; -+ break; -+ case BMCR_SPEED100: -+ if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) -+ goto done; -+ -+ tp->link_config.speed = SPEED_100; -+ break; -+ case BMCR_SPEED1000: -+ if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) { -+ tp->link_config.speed = SPEED_1000; -+ break; -+ } -+ /* Fall through */ -+ default: -+ goto done; -+ } -+ -+ if (val & BMCR_FULLDPLX) -+ tp->link_config.duplex = DUPLEX_FULL; -+ else -+ tp->link_config.duplex = DUPLEX_HALF; -+ -+ tp->link_config.flowctrl = FLOW_CTRL_RX | FLOW_CTRL_TX; -+ -+ err = 0; -+ goto done; -+ } -+ -+ tp->link_config.autoneg = AUTONEG_ENABLE; -+ tp->link_config.advertising = ADVERTISED_Autoneg; -+ tg3_flag_set(tp, PAUSE_AUTONEG); -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) { -+ u32 adv; -+ -+ err = tg3_readphy(tp, MII_ADVERTISE, &val); -+ if (err) -+ goto done; -+ -+ adv = mii_adv_to_ethtool_adv_t(val & ADVERTISE_ALL); -+ tp->link_config.advertising |= adv | ADVERTISED_TP; -+ -+ tp->link_config.flowctrl = tg3_decode_flowctrl_1000T(val); -+ } else { -+ tp->link_config.advertising |= ADVERTISED_FIBRE; -+ } -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) { -+ u32 adv; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) { -+ err = tg3_readphy(tp, MII_CTRL1000, &val); -+ if (err) -+ goto done; -+ -+ adv = mii_ctrl1000_to_ethtool_adv_t(val); -+ } else { -+ err = tg3_readphy(tp, MII_ADVERTISE, &val); -+ if (err) -+ goto done; -+ -+ adv = tg3_decode_flowctrl_1000X(val); -+ tp->link_config.flowctrl = adv; -+ -+ val &= (ADVERTISE_1000XHALF | ADVERTISE_1000XFULL); -+ adv = mii_adv_to_ethtool_adv_x(val); -+ } -+ -+ tp->link_config.advertising |= adv; -+ } -+ -+done: -+ return err; -+} -+ -+static int tg3_init_5401phy_dsp(struct tg3 *tp) -+{ -+ int err; -+ -+ /* Turn off tap power management. */ -+ /* Set Extended packet length bit */ -+ err = tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, 0x4c20); -+ -+ err |= tg3_phydsp_write(tp, 0x0012, 0x1804); -+ err |= tg3_phydsp_write(tp, 0x0013, 0x1204); -+ err |= tg3_phydsp_write(tp, 0x8006, 0x0132); -+ err |= tg3_phydsp_write(tp, 0x8006, 0x0232); -+ err |= tg3_phydsp_write(tp, 0x201f, 0x0a20); -+ -+ udelay(40); -+ -+ return err; -+} -+ -+static bool tg3_phy_eee_config_ok(struct tg3 *tp) -+{ -+ struct ethtool_eee eee; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) -+ return true; -+ -+ tg3_eee_pull_config(tp, &eee); -+ -+ if (tp->eee.eee_enabled) { -+ if (tp->eee.advertised != eee.advertised || -+ tp->eee.tx_lpi_timer != eee.tx_lpi_timer || -+ tp->eee.tx_lpi_enabled != eee.tx_lpi_enabled) -+ return false; -+ } else { -+ /* EEE is disabled but we're advertising */ -+ if (eee.advertised) -+ return false; -+ } -+ -+ return true; -+} -+ -+static bool tg3_phy_copper_an_config_ok(struct tg3 *tp, u32 *lcladv) -+{ -+ u32 advmsk, tgtadv, advertising; -+ -+ advertising = tp->link_config.advertising; -+ tgtadv = ethtool_adv_to_mii_adv_t(advertising) & ADVERTISE_ALL; -+ -+ advmsk = ADVERTISE_ALL; -+ if (tp->link_config.active_duplex == DUPLEX_FULL) { -+ tgtadv |= mii_advertise_flowctrl(tp->link_config.flowctrl); -+ advmsk |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; -+ } -+ -+ if (tg3_readphy(tp, MII_ADVERTISE, lcladv)) -+ return false; -+ -+ if ((*lcladv & advmsk) != tgtadv) -+ return false; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) { -+ u32 tg3_ctrl; -+ -+ tgtadv = ethtool_adv_to_mii_ctrl1000_t(advertising); -+ -+ if (tg3_readphy(tp, MII_CTRL1000, &tg3_ctrl)) -+ return false; -+ -+ if (tgtadv && -+ (tg3_chip_rev_id(tp) == CHIPREV_ID_5701_A0 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5701_B0)) { -+ tgtadv |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER; -+ tg3_ctrl &= (ADVERTISE_1000HALF | ADVERTISE_1000FULL | -+ CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER); -+ } else { -+ tg3_ctrl &= (ADVERTISE_1000HALF | ADVERTISE_1000FULL); -+ } -+ -+ if (tg3_ctrl != tgtadv) -+ return false; -+ } -+ -+ return true; -+} -+ -+static bool tg3_phy_copper_fetch_rmtadv(struct tg3 *tp, u32 *rmtadv) -+{ -+ u32 lpeth = 0; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) { -+ u32 val; -+ -+ if (tg3_readphy(tp, MII_STAT1000, &val)) -+ return false; -+ -+ lpeth = mii_stat1000_to_ethtool_lpa_t(val); -+ } -+ -+ if (tg3_readphy(tp, MII_LPA, rmtadv)) -+ return false; -+ -+ lpeth |= mii_lpa_to_ethtool_lpa_t(*rmtadv); -+ tp->link_config.rmt_adv = lpeth; -+ -+ return true; -+} -+ -+static bool tg3_test_and_report_link_chg(struct tg3 *tp, bool curr_link_up) -+{ -+ if (curr_link_up != tp->link_up) { -+ if (curr_link_up) { -+ netif_carrier_on(tp->dev); -+ } else { -+ netif_carrier_off(tp->dev); -+ if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) -+ tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; -+ } -+ -+ tg3_link_report(tp); -+ return true; -+ } -+ -+ return false; -+} -+ -+static void tg3_clear_mac_status(struct tg3 *tp) -+{ -+ tw32(MAC_EVENT, 0); -+ -+ tw32_f(MAC_STATUS, -+ MAC_STATUS_SYNC_CHANGED | -+ MAC_STATUS_CFG_CHANGED | -+ MAC_STATUS_MI_COMPLETION | -+ MAC_STATUS_LNKSTATE_CHANGED); -+ udelay(40); -+} -+ -+static void tg3_setup_eee(struct tg3 *tp) -+{ -+ u32 val; -+ -+ val = TG3_CPMU_EEE_LNKIDL_PCIE_NL0 | -+ TG3_CPMU_EEE_LNKIDL_UART_IDL; -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_57765_A0) -+ val |= TG3_CPMU_EEE_LNKIDL_APE_TX_MT; -+ -+ tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL, val); -+ -+ tw32_f(TG3_CPMU_EEE_CTRL, -+ TG3_CPMU_EEE_CTRL_EXIT_20_1_US); -+ -+ val = TG3_CPMU_EEEMD_ERLY_L1_XIT_DET | -+ (tp->eee.tx_lpi_enabled ? TG3_CPMU_EEEMD_LPI_IN_TX : 0) | -+ TG3_CPMU_EEEMD_LPI_IN_RX | -+ TG3_CPMU_EEEMD_EEE_ENABLE; -+ -+ if (tg3_asic_rev(tp) != ASIC_REV_5717) -+ val |= TG3_CPMU_EEEMD_SND_IDX_DET_EN; -+ -+ if (tg3_flag(tp, ENABLE_APE)) -+ val |= TG3_CPMU_EEEMD_APE_TX_DET_EN; -+ -+ tw32_f(TG3_CPMU_EEE_MODE, tp->eee.eee_enabled ? val : 0); -+ -+ tw32_f(TG3_CPMU_EEE_DBTMR1, -+ TG3_CPMU_DBTMR1_PCIEXIT_2047US | -+ (tp->eee.tx_lpi_timer & 0xffff)); -+ -+ tw32_f(TG3_CPMU_EEE_DBTMR2, -+ TG3_CPMU_DBTMR2_APE_TX_2047US | -+ TG3_CPMU_DBTMR2_TXIDXEQ_2047US); -+} -+ -+static int tg3_setup_copper_phy(struct tg3 *tp, bool force_reset) -+{ -+ bool current_link_up; -+ u32 bmsr, val; -+ u32 lcl_adv, rmt_adv; -+ u16 current_speed; -+ u8 current_duplex; -+ int i, err; -+ -+ tg3_clear_mac_status(tp); -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_IS_FET)) -+ tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_PWRCTL, 0); -+ -+ /* Some third-party PHYs need to be reset on link going -+ * down. -+ */ -+ if ((tg3_asic_rev(tp) == ASIC_REV_5703 || -+ tg3_asic_rev(tp) == ASIC_REV_5704 || -+ tg3_asic_rev(tp) == ASIC_REV_5705) && -+ tp->link_up) { -+ tg3_readphy(tp, MII_BMSR, &bmsr); -+ if (!tg3_readphy(tp, MII_BMSR, &bmsr) && -+ !(bmsr & BMSR_LSTATUS)) -+ force_reset = true; -+ } -+ if (force_reset) -+ tg3_phy_reset(tp); -+ -+ if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5401) { -+ tg3_readphy(tp, MII_BMSR, &bmsr); -+ if (tg3_readphy(tp, MII_BMSR, &bmsr) || -+ !tg3_flag(tp, INIT_COMPLETE)) -+ bmsr = 0; -+ -+ if (!(bmsr & BMSR_LSTATUS)) { -+ err = tg3_init_5401phy_dsp(tp); -+ if (err) -+ return err; -+ -+ tg3_readphy(tp, MII_BMSR, &bmsr); -+ for (i = 0; i < 1000; i++) { -+ udelay(10); -+ if (!tg3_readphy(tp, MII_BMSR, &bmsr) && -+ (bmsr & BMSR_LSTATUS)) { -+ udelay(40); -+ break; -+ } -+ } -+ -+ if ((tp->phy_id & TG3_PHY_ID_REV_MASK) == -+ TG3_PHY_REV_BCM5401_B0 && -+ !(bmsr & BMSR_LSTATUS) && -+ tp->link_config.active_speed == SPEED_1000) { -+ err = tg3_phy_reset(tp); -+ if (!err) -+ err = tg3_init_5401phy_dsp(tp); -+ if (err) -+ return err; -+ } -+ } -+ } else if (tg3_chip_rev_id(tp) == CHIPREV_ID_5701_A0 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5701_B0) { -+ /* 5701 {A0,B0} CRC bug workaround */ -+ tg3_writephy(tp, 0x15, 0x0a75); -+ tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8c68); -+ tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68); -+ tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8c68); -+ } -+ -+ /* Clear pending interrupts... */ -+ tg3_readphy(tp, MII_TG3_ISTAT, &val); -+ tg3_readphy(tp, MII_TG3_ISTAT, &val); -+ -+ if (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT) -+ tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG); -+ else if (!(tp->phy_flags & TG3_PHYFLG_IS_FET)) -+ tg3_writephy(tp, MII_TG3_IMASK, ~0); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5700 || -+ tg3_asic_rev(tp) == ASIC_REV_5701) { -+ if (tp->led_ctrl == LED_CTRL_MODE_PHY_1) -+ tg3_writephy(tp, MII_TG3_EXT_CTRL, -+ MII_TG3_EXT_CTRL_LNK3_LED_MODE); -+ else -+ tg3_writephy(tp, MII_TG3_EXT_CTRL, 0); -+ } -+ -+ current_link_up = false; -+ current_speed = SPEED_UNKNOWN; -+ current_duplex = DUPLEX_UNKNOWN; -+ tp->phy_flags &= ~TG3_PHYFLG_MDIX_STATE; -+ tp->link_config.rmt_adv = 0; -+ -+ if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) { -+ err = tg3_phy_auxctl_read(tp, -+ MII_TG3_AUXCTL_SHDWSEL_MISCTEST, -+ &val); -+ if (!err && !(val & (1 << 10))) { -+ tg3_phy_auxctl_write(tp, -+ MII_TG3_AUXCTL_SHDWSEL_MISCTEST, -+ val | (1 << 10)); -+ goto relink; -+ } -+ } -+ -+ bmsr = 0; -+ for (i = 0; i < 100; i++) { -+ tg3_readphy(tp, MII_BMSR, &bmsr); -+ if (!tg3_readphy(tp, MII_BMSR, &bmsr) && -+ (bmsr & BMSR_LSTATUS)) -+ break; -+ udelay(40); -+ } -+ -+ if (bmsr & BMSR_LSTATUS) { -+ u32 aux_stat, bmcr; -+ -+ tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat); -+ for (i = 0; i < 2000; i++) { -+ udelay(10); -+ if (!tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat) && -+ aux_stat) -+ break; -+ } -+ -+ tg3_aux_stat_to_speed_duplex(tp, aux_stat, -+ ¤t_speed, -+ ¤t_duplex); -+ -+ bmcr = 0; -+ for (i = 0; i < 200; i++) { -+ tg3_readphy(tp, MII_BMCR, &bmcr); -+ if (tg3_readphy(tp, MII_BMCR, &bmcr)) -+ continue; -+ if (bmcr && bmcr != 0x7fff) -+ break; -+ udelay(10); -+ } -+ -+ lcl_adv = 0; -+ rmt_adv = 0; -+ -+ tp->link_config.active_speed = current_speed; -+ tp->link_config.active_duplex = current_duplex; -+ -+ if (tp->link_config.autoneg == AUTONEG_ENABLE) { -+ bool eee_config_ok = tg3_phy_eee_config_ok(tp); -+ -+ if ((bmcr & BMCR_ANENABLE) && -+ eee_config_ok && -+ tg3_phy_copper_an_config_ok(tp, &lcl_adv) && -+ tg3_phy_copper_fetch_rmtadv(tp, &rmt_adv)) -+ current_link_up = true; -+ -+ /* EEE settings changes take effect only after a phy -+ * reset. If we have skipped a reset due to Link Flap -+ * Avoidance being enabled, do it now. -+ */ -+ if (!eee_config_ok && -+ (tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN) && -+ !force_reset) { -+ tg3_setup_eee(tp); -+ tg3_phy_reset(tp); -+ } -+ } else { -+ if (!(bmcr & BMCR_ANENABLE) && -+ tp->link_config.speed == current_speed && -+ tp->link_config.duplex == current_duplex) { -+ current_link_up = true; -+ } -+ } -+ -+ if (current_link_up && -+ tp->link_config.active_duplex == DUPLEX_FULL) { -+ u32 reg, bit; -+ -+ if (tp->phy_flags & TG3_PHYFLG_IS_FET) { -+ reg = MII_TG3_FET_GEN_STAT; -+ bit = MII_TG3_FET_GEN_STAT_MDIXSTAT; -+ } else { -+ reg = MII_TG3_EXT_STAT; -+ bit = MII_TG3_EXT_STAT_MDIX; -+ } -+ -+ if (!tg3_readphy(tp, reg, &val) && (val & bit)) -+ tp->phy_flags |= TG3_PHYFLG_MDIX_STATE; -+ -+ tg3_setup_flow_control(tp, lcl_adv, rmt_adv); -+ } -+ } -+ -+relink: -+ if (!current_link_up || (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) { -+ tg3_phy_copper_begin(tp); -+ -+ if (tg3_flag(tp, ROBOSWITCH)) { -+ current_link_up = true; -+ /* FIXME: when BCM5325 switch is used use 100 MBit/s */ -+ current_speed = SPEED_1000; -+ current_duplex = DUPLEX_FULL; -+ tp->link_config.active_speed = current_speed; -+ tp->link_config.active_duplex = current_duplex; -+ } -+ -+ tg3_readphy(tp, MII_BMSR, &bmsr); -+ if ((!tg3_readphy(tp, MII_BMSR, &bmsr) && (bmsr & BMSR_LSTATUS)) || -+ (tp->mac_mode & MAC_MODE_PORT_INT_LPBACK)) -+ current_link_up = true; -+ } -+ -+ tp->mac_mode &= ~MAC_MODE_PORT_MODE_MASK; -+ if (current_link_up) { -+ if (tp->link_config.active_speed == SPEED_100 || -+ tp->link_config.active_speed == SPEED_10) -+ tp->mac_mode |= MAC_MODE_PORT_MODE_MII; -+ else -+ tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; -+ } else if ((tp->phy_flags & TG3_PHYFLG_IS_FET) || -+ tg3_asic_rev(tp) == ASIC_REV_5785) -+ tp->mac_mode |= MAC_MODE_PORT_MODE_MII; -+ else -+ tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; -+ -+ /* In order for the 5750 core in BCM4785 chip to work properly -+ * in RGMII mode, the Led Control Register must be set up. -+ */ -+ if (tg3_flag(tp, RGMII_MODE)) { -+ u32 led_ctrl = tr32(MAC_LED_CTRL); -+ led_ctrl &= ~(LED_CTRL_1000MBPS_ON | LED_CTRL_100MBPS_ON); -+ -+ if (tp->link_config.active_speed == SPEED_10) -+ led_ctrl |= LED_CTRL_LNKLED_OVERRIDE; -+ else if (tp->link_config.active_speed == SPEED_100) -+ led_ctrl |= (LED_CTRL_LNKLED_OVERRIDE | -+ LED_CTRL_100MBPS_ON); -+ else if (tp->link_config.active_speed == SPEED_1000) -+ led_ctrl |= (LED_CTRL_LNKLED_OVERRIDE | -+ LED_CTRL_1000MBPS_ON); -+ -+ tw32(MAC_LED_CTRL, led_ctrl); -+ udelay(40); -+ } -+ -+ tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX; -+ if (tp->link_config.active_duplex == DUPLEX_HALF) -+ tp->mac_mode |= MAC_MODE_HALF_DUPLEX; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5700) { -+ if (current_link_up && -+ tg3_5700_link_polarity(tp, tp->link_config.active_speed)) -+ tp->mac_mode |= MAC_MODE_LINK_POLARITY; -+ else -+ tp->mac_mode &= ~MAC_MODE_LINK_POLARITY; -+ } -+ -+ /* ??? Without this setting Netgear GA302T PHY does not -+ * ??? send/receive packets... -+ */ -+ if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5411 && -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5700_ALTIMA) { -+ tp->mi_mode |= MAC_MI_MODE_AUTO_POLL; -+ tw32_f(MAC_MI_MODE, tp->mi_mode); -+ udelay(80); -+ } -+ -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ -+ tg3_phy_eee_adjust(tp, current_link_up); -+ -+#ifndef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_asic_rev(tp) == ASIC_REV_5785) { -+ /* A0 */ -+ if (tp->phy_id == TG3_PHY_ID_BCM50612E && -+ !tg3_phy_toggle_auxctl_smdsp(tp, true)) { -+ if (tp->link_config.active_speed == SPEED_10) -+ tg3_phydsp_write(tp, 0x0ff0, 0x2000); -+ else -+ tg3_phydsp_write(tp, 0x0ff0, 0x0000); -+ -+ tg3_phy_toggle_auxctl_smdsp(tp, false); -+ } -+ -+ if (tp->link_config.active_speed == SPEED_10) -+ tw32(MAC_MI_STAT, -+ MAC_MI_STAT_10MBPS_MODE | -+ MAC_MI_STAT_LNKSTAT_ATTN_ENAB); -+ else -+ tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); -+ } -+#endif -+ -+ if (tg3_flag(tp, USE_LINKCHG_REG)) { -+ /* Polled via timer. */ -+ tw32_f(MAC_EVENT, 0); -+ } else { -+ tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); -+ } -+ udelay(40); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5700 && -+ current_link_up && -+ tp->link_config.active_speed == SPEED_1000 && -+ (tg3_flag(tp, PCIX_MODE) || tg3_flag(tp, PCI_HIGH_SPEED))) { -+ udelay(120); -+ tw32_f(MAC_STATUS, -+ (MAC_STATUS_SYNC_CHANGED | -+ MAC_STATUS_CFG_CHANGED)); -+ udelay(40); -+ tg3_write_mem(tp, -+ NIC_SRAM_FIRMWARE_MBOX, -+ NIC_SRAM_FIRMWARE_MBOX_MAGIC2); -+ } -+ -+ /* Prevent send BD corruption. */ -+ if (tg3_flag(tp, CLKREQ_BUG)) { -+ if (tp->link_config.active_speed == SPEED_100 || -+ tp->link_config.active_speed == SPEED_10) -+ pcie_capability_clear_word(tp->pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_CLKREQ_EN); -+ else -+ pcie_capability_set_word(tp->pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_CLKREQ_EN); -+ } -+ -+ tg3_test_and_report_link_chg(tp, current_link_up); -+ -+ return 0; -+} -+ -+struct tg3_fiber_aneginfo { -+ int state; -+#define ANEG_STATE_UNKNOWN 0 -+#define ANEG_STATE_AN_ENABLE 1 -+#define ANEG_STATE_RESTART_INIT 2 -+#define ANEG_STATE_RESTART 3 -+#define ANEG_STATE_DISABLE_LINK_OK 4 -+#define ANEG_STATE_ABILITY_DETECT_INIT 5 -+#define ANEG_STATE_ABILITY_DETECT 6 -+#define ANEG_STATE_ACK_DETECT_INIT 7 -+#define ANEG_STATE_ACK_DETECT 8 -+#define ANEG_STATE_COMPLETE_ACK_INIT 9 -+#define ANEG_STATE_COMPLETE_ACK 10 -+#define ANEG_STATE_IDLE_DETECT_INIT 11 -+#define ANEG_STATE_IDLE_DETECT 12 -+#define ANEG_STATE_LINK_OK 13 -+#define ANEG_STATE_NEXT_PAGE_WAIT_INIT 14 -+#define ANEG_STATE_NEXT_PAGE_WAIT 15 -+ -+ u32 flags; -+#define MR_AN_ENABLE 0x00000001 -+#define MR_RESTART_AN 0x00000002 -+#define MR_AN_COMPLETE 0x00000004 -+#define MR_PAGE_RX 0x00000008 -+#define MR_NP_LOADED 0x00000010 -+#define MR_TOGGLE_TX 0x00000020 -+#define MR_LP_ADV_FULL_DUPLEX 0x00000040 -+#define MR_LP_ADV_HALF_DUPLEX 0x00000080 -+#define MR_LP_ADV_SYM_PAUSE 0x00000100 -+#define MR_LP_ADV_ASYM_PAUSE 0x00000200 -+#define MR_LP_ADV_REMOTE_FAULT1 0x00000400 -+#define MR_LP_ADV_REMOTE_FAULT2 0x00000800 -+#define MR_LP_ADV_NEXT_PAGE 0x00001000 -+#define MR_TOGGLE_RX 0x00002000 -+#define MR_NP_RX 0x00004000 -+ -+#define MR_LINK_OK 0x80000000 -+ -+ unsigned long link_time, cur_time; -+ -+ u32 ability_match_cfg; -+ int ability_match_count; -+ -+ char ability_match, idle_match, ack_match; -+ -+ u32 txconfig, rxconfig; -+#define ANEG_CFG_NP 0x00000080 -+#define ANEG_CFG_ACK 0x00000040 -+#define ANEG_CFG_RF2 0x00000020 -+#define ANEG_CFG_RF1 0x00000010 -+#define ANEG_CFG_PS2 0x00000001 -+#define ANEG_CFG_PS1 0x00008000 -+#define ANEG_CFG_HD 0x00004000 -+#define ANEG_CFG_FD 0x00002000 -+#define ANEG_CFG_INVAL 0x00001f06 -+ -+}; -+#define ANEG_OK 0 -+#define ANEG_DONE 1 -+#define ANEG_TIMER_ENAB 2 -+#define ANEG_FAILED -1 -+ -+#define ANEG_STATE_SETTLE_TIME 10000 -+ -+static int tg3_fiber_aneg_smachine(struct tg3 *tp, -+ struct tg3_fiber_aneginfo *ap) -+{ -+ u16 flowctrl; -+ unsigned long delta; -+ u32 rx_cfg_reg; -+ int ret; -+ -+ if (ap->state == ANEG_STATE_UNKNOWN) { -+ ap->rxconfig = 0; -+ ap->link_time = 0; -+ ap->cur_time = 0; -+ ap->ability_match_cfg = 0; -+ ap->ability_match_count = 0; -+ ap->ability_match = 0; -+ ap->idle_match = 0; -+ ap->ack_match = 0; -+ } -+ ap->cur_time++; -+ -+ if (tr32(MAC_STATUS) & MAC_STATUS_RCVD_CFG) { -+ rx_cfg_reg = tr32(MAC_RX_AUTO_NEG); -+ -+ if (rx_cfg_reg != ap->ability_match_cfg) { -+ ap->ability_match_cfg = rx_cfg_reg; -+ ap->ability_match = 0; -+ ap->ability_match_count = 0; -+ } else { -+ if (++ap->ability_match_count > 1) { -+ ap->ability_match = 1; -+ ap->ability_match_cfg = rx_cfg_reg; -+ } -+ } -+ if (rx_cfg_reg & ANEG_CFG_ACK) -+ ap->ack_match = 1; -+ else -+ ap->ack_match = 0; -+ -+ ap->idle_match = 0; -+ } else { -+ ap->idle_match = 1; -+ ap->ability_match_cfg = 0; -+ ap->ability_match_count = 0; -+ ap->ability_match = 0; -+ ap->ack_match = 0; -+ -+ rx_cfg_reg = 0; -+ } -+ -+ ap->rxconfig = rx_cfg_reg; -+ ret = ANEG_OK; -+ -+ switch (ap->state) { -+ case ANEG_STATE_UNKNOWN: -+ if (ap->flags & (MR_AN_ENABLE | MR_RESTART_AN)) -+ ap->state = ANEG_STATE_AN_ENABLE; -+ -+ /* fallthru */ -+ case ANEG_STATE_AN_ENABLE: -+ ap->flags &= ~(MR_AN_COMPLETE | MR_PAGE_RX); -+ if (ap->flags & MR_AN_ENABLE) { -+ ap->link_time = 0; -+ ap->cur_time = 0; -+ ap->ability_match_cfg = 0; -+ ap->ability_match_count = 0; -+ ap->ability_match = 0; -+ ap->idle_match = 0; -+ ap->ack_match = 0; -+ -+ ap->state = ANEG_STATE_RESTART_INIT; -+ } else { -+ ap->state = ANEG_STATE_DISABLE_LINK_OK; -+ } -+ break; -+ -+ case ANEG_STATE_RESTART_INIT: -+ ap->link_time = ap->cur_time; -+ ap->flags &= ~(MR_NP_LOADED); -+ ap->txconfig = 0; -+ tw32(MAC_TX_AUTO_NEG, 0); -+ tp->mac_mode |= MAC_MODE_SEND_CONFIGS; -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ -+ ret = ANEG_TIMER_ENAB; -+ ap->state = ANEG_STATE_RESTART; -+ -+ /* fallthru */ -+ case ANEG_STATE_RESTART: -+ delta = ap->cur_time - ap->link_time; -+ if (delta > ANEG_STATE_SETTLE_TIME) -+ ap->state = ANEG_STATE_ABILITY_DETECT_INIT; -+ else -+ ret = ANEG_TIMER_ENAB; -+ break; -+ -+ case ANEG_STATE_DISABLE_LINK_OK: -+ ret = ANEG_DONE; -+ break; -+ -+ case ANEG_STATE_ABILITY_DETECT_INIT: -+ ap->flags &= ~(MR_TOGGLE_TX); -+ ap->txconfig = ANEG_CFG_FD; -+ flowctrl = tg3_advert_flowctrl_1000X(tp->link_config.flowctrl); -+ if (flowctrl & ADVERTISE_1000XPAUSE) -+ ap->txconfig |= ANEG_CFG_PS1; -+ if (flowctrl & ADVERTISE_1000XPSE_ASYM) -+ ap->txconfig |= ANEG_CFG_PS2; -+ tw32(MAC_TX_AUTO_NEG, ap->txconfig); -+ tp->mac_mode |= MAC_MODE_SEND_CONFIGS; -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ -+ ap->state = ANEG_STATE_ABILITY_DETECT; -+ break; -+ -+ case ANEG_STATE_ABILITY_DETECT: -+ if (ap->ability_match != 0 && ap->rxconfig != 0) -+ ap->state = ANEG_STATE_ACK_DETECT_INIT; -+ break; -+ -+ case ANEG_STATE_ACK_DETECT_INIT: -+ ap->txconfig |= ANEG_CFG_ACK; -+ tw32(MAC_TX_AUTO_NEG, ap->txconfig); -+ tp->mac_mode |= MAC_MODE_SEND_CONFIGS; -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ -+ ap->state = ANEG_STATE_ACK_DETECT; -+ -+ /* fallthru */ -+ case ANEG_STATE_ACK_DETECT: -+ if (ap->ack_match != 0) { -+ if ((ap->rxconfig & ~ANEG_CFG_ACK) == -+ (ap->ability_match_cfg & ~ANEG_CFG_ACK)) { -+ ap->state = ANEG_STATE_COMPLETE_ACK_INIT; -+ } else { -+ ap->state = ANEG_STATE_AN_ENABLE; -+ } -+ } else if (ap->ability_match != 0 && -+ ap->rxconfig == 0) { -+ ap->state = ANEG_STATE_AN_ENABLE; -+ } -+ break; -+ -+ case ANEG_STATE_COMPLETE_ACK_INIT: -+ if (ap->rxconfig & ANEG_CFG_INVAL) { -+ ret = ANEG_FAILED; -+ break; -+ } -+ ap->flags &= ~(MR_LP_ADV_FULL_DUPLEX | -+ MR_LP_ADV_HALF_DUPLEX | -+ MR_LP_ADV_SYM_PAUSE | -+ MR_LP_ADV_ASYM_PAUSE | -+ MR_LP_ADV_REMOTE_FAULT1 | -+ MR_LP_ADV_REMOTE_FAULT2 | -+ MR_LP_ADV_NEXT_PAGE | -+ MR_TOGGLE_RX | -+ MR_NP_RX); -+ if (ap->rxconfig & ANEG_CFG_FD) -+ ap->flags |= MR_LP_ADV_FULL_DUPLEX; -+ if (ap->rxconfig & ANEG_CFG_HD) -+ ap->flags |= MR_LP_ADV_HALF_DUPLEX; -+ if (ap->rxconfig & ANEG_CFG_PS1) -+ ap->flags |= MR_LP_ADV_SYM_PAUSE; -+ if (ap->rxconfig & ANEG_CFG_PS2) -+ ap->flags |= MR_LP_ADV_ASYM_PAUSE; -+ if (ap->rxconfig & ANEG_CFG_RF1) -+ ap->flags |= MR_LP_ADV_REMOTE_FAULT1; -+ if (ap->rxconfig & ANEG_CFG_RF2) -+ ap->flags |= MR_LP_ADV_REMOTE_FAULT2; -+ if (ap->rxconfig & ANEG_CFG_NP) -+ ap->flags |= MR_LP_ADV_NEXT_PAGE; -+ -+ ap->link_time = ap->cur_time; -+ -+ ap->flags ^= (MR_TOGGLE_TX); -+ if (ap->rxconfig & 0x0008) -+ ap->flags |= MR_TOGGLE_RX; -+ if (ap->rxconfig & ANEG_CFG_NP) -+ ap->flags |= MR_NP_RX; -+ ap->flags |= MR_PAGE_RX; -+ -+ ap->state = ANEG_STATE_COMPLETE_ACK; -+ ret = ANEG_TIMER_ENAB; -+ break; -+ -+ case ANEG_STATE_COMPLETE_ACK: -+ if (ap->ability_match != 0 && -+ ap->rxconfig == 0) { -+ ap->state = ANEG_STATE_AN_ENABLE; -+ break; -+ } -+ delta = ap->cur_time - ap->link_time; -+ if (delta > ANEG_STATE_SETTLE_TIME) { -+ if (!(ap->flags & (MR_LP_ADV_NEXT_PAGE))) { -+ ap->state = ANEG_STATE_IDLE_DETECT_INIT; -+ } else { -+ if ((ap->txconfig & ANEG_CFG_NP) == 0 && -+ !(ap->flags & MR_NP_RX)) { -+ ap->state = ANEG_STATE_IDLE_DETECT_INIT; -+ } else { -+ ret = ANEG_FAILED; -+ } -+ } -+ } -+ break; -+ -+ case ANEG_STATE_IDLE_DETECT_INIT: -+ ap->link_time = ap->cur_time; -+ tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS; -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ -+ ap->state = ANEG_STATE_IDLE_DETECT; -+ ret = ANEG_TIMER_ENAB; -+ break; -+ -+ case ANEG_STATE_IDLE_DETECT: -+ if (ap->ability_match != 0 && -+ ap->rxconfig == 0) { -+ ap->state = ANEG_STATE_AN_ENABLE; -+ break; -+ } -+ delta = ap->cur_time - ap->link_time; -+ if (delta > ANEG_STATE_SETTLE_TIME) { -+ /* XXX another gem from the Broadcom driver :( */ -+ ap->state = ANEG_STATE_LINK_OK; -+ } -+ break; -+ -+ case ANEG_STATE_LINK_OK: -+ ap->flags |= (MR_AN_COMPLETE | MR_LINK_OK); -+ ret = ANEG_DONE; -+ break; -+ -+ case ANEG_STATE_NEXT_PAGE_WAIT_INIT: -+ /* ??? unimplemented */ -+ break; -+ -+ case ANEG_STATE_NEXT_PAGE_WAIT: -+ /* ??? unimplemented */ -+ break; -+ -+ default: -+ ret = ANEG_FAILED; -+ break; -+ } -+ -+ return ret; -+} -+ -+static int fiber_autoneg(struct tg3 *tp, u32 *txflags, u32 *rxflags) -+{ -+ int res = 0; -+ struct tg3_fiber_aneginfo aninfo; -+ int status = ANEG_FAILED; -+ unsigned int tick; -+ u32 tmp; -+ -+ tw32_f(MAC_TX_AUTO_NEG, 0); -+ -+ tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK; -+ tw32_f(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII); -+ udelay(40); -+ -+ tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS); -+ udelay(40); -+ -+ memset(&aninfo, 0, sizeof(aninfo)); -+ aninfo.flags |= MR_AN_ENABLE; -+ aninfo.state = ANEG_STATE_UNKNOWN; -+ aninfo.cur_time = 0; -+ tick = 0; -+ while (++tick < 195000) { -+ status = tg3_fiber_aneg_smachine(tp, &aninfo); -+ if (status == ANEG_DONE || status == ANEG_FAILED) -+ break; -+ -+ udelay(1); -+ } -+ -+ tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS; -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ -+ *txflags = aninfo.txconfig; -+ *rxflags = aninfo.flags; -+ -+ if (status == ANEG_DONE && -+ (aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK | -+ MR_LP_ADV_FULL_DUPLEX))) -+ res = 1; -+ -+ return res; -+} -+ -+static void tg3_init_bcm8002(struct tg3 *tp) -+{ -+ u32 mac_status = tr32(MAC_STATUS); -+ int i; -+ -+ /* Reset when initting first time or we have a link. */ -+ if (tg3_flag(tp, INIT_COMPLETE) && -+ !(mac_status & MAC_STATUS_PCS_SYNCED)) -+ return; -+ -+ /* Set PLL lock range. */ -+ tg3_writephy(tp, 0x16, 0x8007); -+ -+ /* SW reset */ -+ tg3_writephy(tp, MII_BMCR, BMCR_RESET); -+ -+ /* Wait for reset to complete. */ -+ /* XXX schedule_timeout() ... */ -+ for (i = 0; i < 500; i++) -+ udelay(10); -+ -+ /* Config mode; select PMA/Ch 1 regs. */ -+ tg3_writephy(tp, 0x10, 0x8411); -+ -+ /* Enable auto-lock and comdet, select txclk for tx. */ -+ tg3_writephy(tp, 0x11, 0x0a10); -+ -+ tg3_writephy(tp, 0x18, 0x00a0); -+ tg3_writephy(tp, 0x16, 0x41ff); -+ -+ /* Assert and deassert POR. */ -+ tg3_writephy(tp, 0x13, 0x0400); -+ udelay(40); -+ tg3_writephy(tp, 0x13, 0x0000); -+ -+ tg3_writephy(tp, 0x11, 0x0a50); -+ udelay(40); -+ tg3_writephy(tp, 0x11, 0x0a10); -+ -+ /* Wait for signal to stabilize */ -+ /* XXX schedule_timeout() ... */ -+ for (i = 0; i < 15000; i++) -+ udelay(10); -+ -+ /* Deselect the channel register so we can read the PHYID -+ * later. -+ */ -+ tg3_writephy(tp, 0x10, 0x8011); -+} -+ -+static bool tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status) -+{ -+ u16 flowctrl; -+ bool current_link_up; -+ u32 sg_dig_ctrl, sg_dig_status; -+ u32 serdes_cfg, expected_sg_dig_ctrl; -+ int workaround, port_a; -+ -+ serdes_cfg = 0; -+ expected_sg_dig_ctrl = 0; -+ workaround = 0; -+ port_a = 1; -+ current_link_up = false; -+ -+ if (tg3_chip_rev_id(tp) != CHIPREV_ID_5704_A0 && -+ tg3_chip_rev_id(tp) != CHIPREV_ID_5704_A1) { -+ workaround = 1; -+ if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID) -+ port_a = 0; -+ -+ /* preserve bits 0-11,13,14 for signal pre-emphasis */ -+ /* preserve bits 20-23 for voltage regulator */ -+ serdes_cfg = tr32(MAC_SERDES_CFG) & 0x00f06fff; -+ } -+ -+ sg_dig_ctrl = tr32(SG_DIG_CTRL); -+ -+ if (tp->link_config.autoneg != AUTONEG_ENABLE) { -+ if (sg_dig_ctrl & SG_DIG_USING_HW_AUTONEG) { -+ if (workaround) { -+ u32 val = serdes_cfg; -+ -+ if (port_a) -+ val |= 0xc010000; -+ else -+ val |= 0x4010000; -+ tw32_f(MAC_SERDES_CFG, val); -+ } -+ -+ tw32_f(SG_DIG_CTRL, SG_DIG_COMMON_SETUP); -+ } -+ if (mac_status & MAC_STATUS_PCS_SYNCED) { -+ tg3_setup_flow_control(tp, 0, 0); -+ current_link_up = true; -+ } -+ goto out; -+ } -+ -+ /* Want auto-negotiation. */ -+ expected_sg_dig_ctrl = SG_DIG_USING_HW_AUTONEG | SG_DIG_COMMON_SETUP; -+ -+ flowctrl = tg3_advert_flowctrl_1000X(tp->link_config.flowctrl); -+ if (flowctrl & ADVERTISE_1000XPAUSE) -+ expected_sg_dig_ctrl |= SG_DIG_PAUSE_CAP; -+ if (flowctrl & ADVERTISE_1000XPSE_ASYM) -+ expected_sg_dig_ctrl |= SG_DIG_ASYM_PAUSE; -+ -+ if (sg_dig_ctrl != expected_sg_dig_ctrl) { -+ if ((tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT) && -+ tp->serdes_counter && -+ ((mac_status & (MAC_STATUS_PCS_SYNCED | -+ MAC_STATUS_RCVD_CFG)) == -+ MAC_STATUS_PCS_SYNCED)) { -+ tp->serdes_counter--; -+ current_link_up = true; -+ goto out; -+ } -+restart_autoneg: -+ if (workaround) -+ tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011000); -+ tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | SG_DIG_SOFT_RESET); -+ udelay(5); -+ tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl); -+ -+ tp->serdes_counter = SERDES_AN_TIMEOUT_5704S; -+ tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; -+ } else if (mac_status & (MAC_STATUS_PCS_SYNCED | -+ MAC_STATUS_SIGNAL_DET)) { -+ sg_dig_status = tr32(SG_DIG_STATUS); -+ mac_status = tr32(MAC_STATUS); -+ -+ if ((sg_dig_status & SG_DIG_AUTONEG_COMPLETE) && -+ (mac_status & MAC_STATUS_PCS_SYNCED)) { -+ u32 local_adv = 0, remote_adv = 0; -+ -+ if (sg_dig_ctrl & SG_DIG_PAUSE_CAP) -+ local_adv |= ADVERTISE_1000XPAUSE; -+ if (sg_dig_ctrl & SG_DIG_ASYM_PAUSE) -+ local_adv |= ADVERTISE_1000XPSE_ASYM; -+ -+ if (sg_dig_status & SG_DIG_PARTNER_PAUSE_CAPABLE) -+ remote_adv |= LPA_1000XPAUSE; -+ if (sg_dig_status & SG_DIG_PARTNER_ASYM_PAUSE) -+ remote_adv |= LPA_1000XPAUSE_ASYM; -+ -+ tp->link_config.rmt_adv = -+ mii_adv_to_ethtool_adv_x(remote_adv); -+ -+ tg3_setup_flow_control(tp, local_adv, remote_adv); -+ current_link_up = true; -+ tp->serdes_counter = 0; -+ tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; -+ } else if (!(sg_dig_status & SG_DIG_AUTONEG_COMPLETE)) { -+ if (tp->serdes_counter) -+ tp->serdes_counter--; -+ else { -+ if (workaround) { -+ u32 val = serdes_cfg; -+ -+ if (port_a) -+ val |= 0xc010000; -+ else -+ val |= 0x4010000; -+ -+ tw32_f(MAC_SERDES_CFG, val); -+ } -+ -+ tw32_f(SG_DIG_CTRL, SG_DIG_COMMON_SETUP); -+ udelay(40); -+ -+ /* Link parallel detection - link is up */ -+ /* only if we have PCS_SYNC and not */ -+ /* receiving config code words */ -+ mac_status = tr32(MAC_STATUS); -+ if ((mac_status & MAC_STATUS_PCS_SYNCED) && -+ !(mac_status & MAC_STATUS_RCVD_CFG)) { -+ tg3_setup_flow_control(tp, 0, 0); -+ current_link_up = true; -+ tp->phy_flags |= -+ TG3_PHYFLG_PARALLEL_DETECT; -+ tp->serdes_counter = -+ SERDES_PARALLEL_DET_TIMEOUT; -+ } else -+ goto restart_autoneg; -+ } -+ } -+ } else { -+ tp->serdes_counter = SERDES_AN_TIMEOUT_5704S; -+ tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; -+ } -+ -+out: -+ return current_link_up; -+} -+ -+static bool tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status) -+{ -+ bool current_link_up = false; -+ -+ if (!(mac_status & MAC_STATUS_PCS_SYNCED)) -+ goto out; -+ -+ if (tp->link_config.autoneg == AUTONEG_ENABLE) { -+ u32 txflags, rxflags; -+ int i; -+ -+ if (fiber_autoneg(tp, &txflags, &rxflags)) { -+ u32 local_adv = 0, remote_adv = 0; -+ -+ if (txflags & ANEG_CFG_PS1) -+ local_adv |= ADVERTISE_1000XPAUSE; -+ if (txflags & ANEG_CFG_PS2) -+ local_adv |= ADVERTISE_1000XPSE_ASYM; -+ -+ if (rxflags & MR_LP_ADV_SYM_PAUSE) -+ remote_adv |= LPA_1000XPAUSE; -+ if (rxflags & MR_LP_ADV_ASYM_PAUSE) -+ remote_adv |= LPA_1000XPAUSE_ASYM; -+ -+ tp->link_config.rmt_adv = -+ mii_adv_to_ethtool_adv_x(remote_adv); -+ -+ tg3_setup_flow_control(tp, local_adv, remote_adv); -+ -+ current_link_up = true; -+ } -+ for (i = 0; i < 30; i++) { -+ udelay(20); -+ tw32_f(MAC_STATUS, -+ (MAC_STATUS_SYNC_CHANGED | -+ MAC_STATUS_CFG_CHANGED)); -+ udelay(40); -+ if ((tr32(MAC_STATUS) & -+ (MAC_STATUS_SYNC_CHANGED | -+ MAC_STATUS_CFG_CHANGED)) == 0) -+ break; -+ } -+ -+ mac_status = tr32(MAC_STATUS); -+ if (!current_link_up && -+ (mac_status & MAC_STATUS_PCS_SYNCED) && -+ !(mac_status & MAC_STATUS_RCVD_CFG)) -+ current_link_up = true; -+ } else { -+ tg3_setup_flow_control(tp, 0, 0); -+ -+ /* Forcing 1000FD link up. */ -+ current_link_up = true; -+ -+ tw32_f(MAC_MODE, (tp->mac_mode | MAC_MODE_SEND_CONFIGS)); -+ udelay(40); -+ -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ } -+ -+out: -+ return current_link_up; -+} -+ -+static int tg3_setup_fiber_phy(struct tg3 *tp, bool force_reset) -+{ -+ u32 orig_pause_cfg; -+ u16 orig_active_speed; -+ u8 orig_active_duplex; -+ u32 mac_status; -+ bool current_link_up; -+ int i; -+ -+ orig_pause_cfg = tp->link_config.active_flowctrl; -+ orig_active_speed = tp->link_config.active_speed; -+ orig_active_duplex = tp->link_config.active_duplex; -+ -+ if (!tg3_flag(tp, HW_AUTONEG) && -+ tp->link_up && -+ tg3_flag(tp, INIT_COMPLETE)) { -+ mac_status = tr32(MAC_STATUS); -+ mac_status &= (MAC_STATUS_PCS_SYNCED | -+ MAC_STATUS_SIGNAL_DET | -+ MAC_STATUS_CFG_CHANGED | -+ MAC_STATUS_RCVD_CFG); -+ if (mac_status == (MAC_STATUS_PCS_SYNCED | -+ MAC_STATUS_SIGNAL_DET)) { -+ tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED | -+ MAC_STATUS_CFG_CHANGED)); -+ return 0; -+ } -+ } -+ -+ tw32_f(MAC_TX_AUTO_NEG, 0); -+ -+ tp->mac_mode &= ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX); -+ tp->mac_mode |= MAC_MODE_PORT_MODE_TBI; -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ -+ if (tp->phy_id == TG3_PHY_ID_BCM8002) -+ tg3_init_bcm8002(tp); -+ -+ /* Enable link change event even when serdes polling. */ -+ tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); -+ udelay(40); -+ -+ current_link_up = false; -+ tp->link_config.rmt_adv = 0; -+ mac_status = tr32(MAC_STATUS); -+ -+ if (tg3_flag(tp, HW_AUTONEG)) -+ current_link_up = tg3_setup_fiber_hw_autoneg(tp, mac_status); -+ else -+ current_link_up = tg3_setup_fiber_by_hand(tp, mac_status); -+ -+ tp->napi[0].hw_status->status = -+ (SD_STATUS_UPDATED | -+ (tp->napi[0].hw_status->status & ~SD_STATUS_LINK_CHG)); -+ -+ for (i = 0; i < 100; i++) { -+ tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED | -+ MAC_STATUS_CFG_CHANGED)); -+ udelay(5); -+ if ((tr32(MAC_STATUS) & (MAC_STATUS_SYNC_CHANGED | -+ MAC_STATUS_CFG_CHANGED | -+ MAC_STATUS_LNKSTATE_CHANGED)) == 0) -+ break; -+ } -+ -+ mac_status = tr32(MAC_STATUS); -+ if ((mac_status & MAC_STATUS_PCS_SYNCED) == 0) { -+ current_link_up = false; -+ if (tp->link_config.autoneg == AUTONEG_ENABLE && -+ tp->serdes_counter == 0) { -+ tw32_f(MAC_MODE, (tp->mac_mode | -+ MAC_MODE_SEND_CONFIGS)); -+ udelay(1); -+ tw32_f(MAC_MODE, tp->mac_mode); -+ } -+ } -+ -+ if (current_link_up) { -+ tp->link_config.active_speed = SPEED_1000; -+ tp->link_config.active_duplex = DUPLEX_FULL; -+ tw32(MAC_LED_CTRL, (tp->led_ctrl | -+ LED_CTRL_LNKLED_OVERRIDE | -+ LED_CTRL_1000MBPS_ON)); -+ } else { -+ tp->link_config.active_speed = SPEED_UNKNOWN; -+ tp->link_config.active_duplex = DUPLEX_UNKNOWN; -+ tw32(MAC_LED_CTRL, (tp->led_ctrl | -+ LED_CTRL_LNKLED_OVERRIDE | -+ LED_CTRL_TRAFFIC_OVERRIDE)); -+ } -+ -+ if (!tg3_test_and_report_link_chg(tp, current_link_up)) { -+ u32 now_pause_cfg = tp->link_config.active_flowctrl; -+ if (orig_pause_cfg != now_pause_cfg || -+ orig_active_speed != tp->link_config.active_speed || -+ orig_active_duplex != tp->link_config.active_duplex) -+ tg3_link_report(tp); -+ } -+ -+ return 0; -+} -+ -+static int tg3_setup_fiber_mii_phy(struct tg3 *tp, bool force_reset) -+{ -+ int err = 0; -+ u32 bmsr, bmcr; -+ u16 current_speed = SPEED_UNKNOWN; -+ u8 current_duplex = DUPLEX_UNKNOWN; -+ bool current_link_up = false; -+ u32 local_adv, remote_adv, sgsr; -+ -+ if ((tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_asic_rev(tp) == ASIC_REV_5720) && -+ !tg3_readphy(tp, SERDES_TG3_1000X_STATUS, &sgsr) && -+ (sgsr & SERDES_TG3_SGMII_MODE)) { -+ -+ if (force_reset) -+ tg3_phy_reset(tp); -+ -+ tp->mac_mode &= ~MAC_MODE_PORT_MODE_MASK; -+ -+ if (!(sgsr & SERDES_TG3_LINK_UP)) { -+ tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; -+ } else { -+ current_link_up = true; -+ if (sgsr & SERDES_TG3_SPEED_1000) { -+ current_speed = SPEED_1000; -+ tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; -+ } else if (sgsr & SERDES_TG3_SPEED_100) { -+ current_speed = SPEED_100; -+ tp->mac_mode |= MAC_MODE_PORT_MODE_MII; -+ } else { -+ current_speed = SPEED_10; -+ tp->mac_mode |= MAC_MODE_PORT_MODE_MII; -+ } -+ -+ if (sgsr & SERDES_TG3_FULL_DUPLEX) -+ current_duplex = DUPLEX_FULL; -+ else -+ current_duplex = DUPLEX_HALF; -+ } -+ -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ -+ tg3_clear_mac_status(tp); -+ -+ goto fiber_setup_done; -+ } -+ -+ tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ -+ tg3_clear_mac_status(tp); -+ -+ if (force_reset) -+ tg3_phy_reset(tp); -+ -+ tp->link_config.rmt_adv = 0; -+ -+ err |= tg3_readphy(tp, MII_BMSR, &bmsr); -+ err |= tg3_readphy(tp, MII_BMSR, &bmsr); -+ if (tg3_asic_rev(tp) == ASIC_REV_5714) { -+ if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP) -+ bmsr |= BMSR_LSTATUS; -+ else -+ bmsr &= ~BMSR_LSTATUS; -+ } -+ -+ err |= tg3_readphy(tp, MII_BMCR, &bmcr); -+ -+ if ((tp->link_config.autoneg == AUTONEG_ENABLE) && !force_reset && -+ (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) { -+ /* do nothing, just check for link up at the end */ -+ } else if (tp->link_config.autoneg == AUTONEG_ENABLE) { -+ u32 adv, newadv; -+ -+ err |= tg3_readphy(tp, MII_ADVERTISE, &adv); -+ newadv = adv & ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF | -+ ADVERTISE_1000XPAUSE | -+ ADVERTISE_1000XPSE_ASYM | -+ ADVERTISE_SLCT); -+ -+ newadv |= tg3_advert_flowctrl_1000X(tp->link_config.flowctrl); -+ newadv |= ethtool_adv_to_mii_adv_x(tp->link_config.advertising); -+ -+ if ((newadv != adv) || !(bmcr & BMCR_ANENABLE)) { -+ tg3_writephy(tp, MII_ADVERTISE, newadv); -+ bmcr |= BMCR_ANENABLE | BMCR_ANRESTART; -+ tg3_writephy(tp, MII_BMCR, bmcr); -+ -+ tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); -+ tp->serdes_counter = SERDES_AN_TIMEOUT_5714S; -+ tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; -+ -+ return err; -+ } -+ } else { -+ u32 new_bmcr; -+ -+ bmcr &= ~BMCR_SPEED1000; -+ new_bmcr = bmcr & ~(BMCR_ANENABLE | BMCR_FULLDPLX); -+ -+ if (tp->link_config.duplex == DUPLEX_FULL) -+ new_bmcr |= BMCR_FULLDPLX; -+ -+ if (new_bmcr != bmcr) { -+ /* BMCR_SPEED1000 is a reserved bit that needs -+ * to be set on write. -+ */ -+ new_bmcr |= BMCR_SPEED1000; -+ -+ /* Force a linkdown */ -+ if (tp->link_up) { -+ u32 adv; -+ -+ err |= tg3_readphy(tp, MII_ADVERTISE, &adv); -+ adv &= ~(ADVERTISE_1000XFULL | -+ ADVERTISE_1000XHALF | -+ ADVERTISE_SLCT); -+ tg3_writephy(tp, MII_ADVERTISE, adv); -+ tg3_writephy(tp, MII_BMCR, bmcr | -+ BMCR_ANRESTART | -+ BMCR_ANENABLE); -+ udelay(10); -+ tg3_carrier_off(tp); -+ } -+ tg3_writephy(tp, MII_BMCR, new_bmcr); -+ bmcr = new_bmcr; -+ err |= tg3_readphy(tp, MII_BMSR, &bmsr); -+ err |= tg3_readphy(tp, MII_BMSR, &bmsr); -+ if (tg3_asic_rev(tp) == ASIC_REV_5714) { -+ if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP) -+ bmsr |= BMSR_LSTATUS; -+ else -+ bmsr &= ~BMSR_LSTATUS; -+ } -+ tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; -+ } -+ } -+ -+ if (bmsr & BMSR_LSTATUS) { -+ current_speed = SPEED_1000; -+ current_link_up = true; -+ if (bmcr & BMCR_FULLDPLX) -+ current_duplex = DUPLEX_FULL; -+ else -+ current_duplex = DUPLEX_HALF; -+ -+ local_adv = 0; -+ remote_adv = 0; -+ -+ if (bmcr & BMCR_ANENABLE) { -+ u32 common; -+ -+ err |= tg3_readphy(tp, MII_ADVERTISE, &local_adv); -+ err |= tg3_readphy(tp, MII_LPA, &remote_adv); -+ common = local_adv & remote_adv; -+ if (common & (ADVERTISE_1000XHALF | -+ ADVERTISE_1000XFULL)) { -+ if (common & ADVERTISE_1000XFULL) -+ current_duplex = DUPLEX_FULL; -+ else -+ current_duplex = DUPLEX_HALF; -+ -+ tp->link_config.rmt_adv = -+ mii_adv_to_ethtool_adv_x(remote_adv); -+ } else if (!tg3_flag(tp, 5780_CLASS)) { -+ /* Link is up via parallel detect */ -+ } else { -+ current_link_up = false; -+ } -+ } -+ } -+ -+fiber_setup_done: -+ if (current_link_up && current_duplex == DUPLEX_FULL) -+ tg3_setup_flow_control(tp, local_adv, remote_adv); -+ -+ tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX; -+ if (tp->link_config.active_duplex == DUPLEX_HALF) -+ tp->mac_mode |= MAC_MODE_HALF_DUPLEX; -+ -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ -+ tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); -+ -+ tp->link_config.active_speed = current_speed; -+ tp->link_config.active_duplex = current_duplex; -+ -+ tg3_test_and_report_link_chg(tp, current_link_up); -+ return err; -+} -+ -+static void tg3_serdes_parallel_detect(struct tg3 *tp) -+{ -+ if (tp->serdes_counter) { -+ /* Give autoneg time to complete. */ -+ tp->serdes_counter--; -+ return; -+ } -+ -+ if (!tp->link_up && -+ (tp->link_config.autoneg == AUTONEG_ENABLE)) { -+ u32 bmcr; -+ -+ tg3_readphy(tp, MII_BMCR, &bmcr); -+ if (bmcr & BMCR_ANENABLE) { -+ u32 phy1, phy2; -+ -+ /* Select shadow register 0x1f */ -+ tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x7c00); -+ tg3_readphy(tp, MII_TG3_MISC_SHDW, &phy1); -+ -+ /* Select expansion interrupt status register */ -+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, -+ MII_TG3_DSP_EXP1_INT_STAT); -+ tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2); -+ tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2); -+ -+ if ((phy1 & 0x10) && !(phy2 & 0x20)) { -+ /* We have signal detect and not receiving -+ * config code words, link is up by parallel -+ * detection. -+ */ -+ -+ bmcr &= ~BMCR_ANENABLE; -+ bmcr |= BMCR_SPEED1000 | BMCR_FULLDPLX; -+ tg3_writephy(tp, MII_BMCR, bmcr); -+ tp->phy_flags |= TG3_PHYFLG_PARALLEL_DETECT; -+ } -+ } -+ } else if (tp->link_up && -+ (tp->link_config.autoneg == AUTONEG_ENABLE) && -+ (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) { -+ u32 phy2; -+ -+ /* Select expansion interrupt status register */ -+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, -+ MII_TG3_DSP_EXP1_INT_STAT); -+ tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2); -+ if (phy2 & 0x20) { -+ u32 bmcr; -+ -+ /* Config code words received, turn on autoneg. */ -+ tg3_readphy(tp, MII_BMCR, &bmcr); -+ tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANENABLE); -+ -+ tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; -+ -+ } -+ } -+} -+ -+static int tg3_setup_phy(struct tg3 *tp, bool force_reset) -+{ -+ u32 val; -+ int err; -+ -+ if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) -+ err = tg3_setup_fiber_phy(tp, force_reset); -+ else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) -+ err = tg3_setup_fiber_mii_phy(tp, force_reset); -+ else -+ err = tg3_setup_copper_phy(tp, force_reset); -+ -+ if (tg3_chip_rev(tp) == CHIPREV_5784_AX) { -+ u32 scale; -+ -+ val = tr32(TG3_CPMU_CLCK_STAT) & CPMU_CLCK_STAT_MAC_CLCK_MASK; -+ if (val == CPMU_CLCK_STAT_MAC_CLCK_62_5) -+ scale = 65; -+ else if (val == CPMU_CLCK_STAT_MAC_CLCK_6_25) -+ scale = 6; -+ else -+ scale = 12; -+ -+ val = tr32(GRC_MISC_CFG) & ~GRC_MISC_CFG_PRESCALAR_MASK; -+ val |= (scale << GRC_MISC_CFG_PRESCALAR_SHIFT); -+ tw32(GRC_MISC_CFG, val); -+ } -+ -+ val = (2 << TX_LENGTHS_IPG_CRS_SHIFT) | -+ (6 << TX_LENGTHS_IPG_SHIFT); -+ if (tg3_asic_rev(tp) == ASIC_REV_5720 || -+ tg3_asic_rev(tp) == ASIC_REV_5762) -+ val |= tr32(MAC_TX_LENGTHS) & -+ (TX_LENGTHS_JMB_FRM_LEN_MSK | -+ TX_LENGTHS_CNT_DWN_VAL_MSK); -+ -+ if (tp->link_config.active_speed == SPEED_1000 && -+ tp->link_config.active_duplex == DUPLEX_HALF) -+ tw32(MAC_TX_LENGTHS, val | -+ (0xff << TX_LENGTHS_SLOT_TIME_SHIFT)); -+ else -+ tw32(MAC_TX_LENGTHS, val | -+ (32 << TX_LENGTHS_SLOT_TIME_SHIFT)); -+ -+ if (!tg3_flag(tp, 5705_PLUS)) { -+ if (tp->link_up) { -+ tw32(HOSTCC_STAT_COAL_TICKS, -+ tp->coal.stats_block_coalesce_usecs); -+ } else { -+ tw32(HOSTCC_STAT_COAL_TICKS, 0); -+ } -+ } -+ -+ if (tg3_flag(tp, ASPM_WORKAROUND)) { -+ val = tr32(PCIE_PWR_MGMT_THRESH); -+ if (!tp->link_up) -+ val = (val & ~PCIE_PWR_MGMT_L1_THRESH_MSK) | -+ tp->pwrmgmt_thresh; -+ else -+ val |= PCIE_PWR_MGMT_L1_THRESH_MSK; -+ tw32(PCIE_PWR_MGMT_THRESH, val); -+ } -+ -+ return err; -+} -+ -+#ifdef BCM_HAS_IEEE1588_SUPPORT -+/* tp->lock must be held */ -+static u64 tg3_refclk_read(struct tg3 *tp) -+{ -+ u64 stamp = tr32(TG3_EAV_REF_CLCK_LSB); -+ return stamp | (u64)tr32(TG3_EAV_REF_CLCK_MSB) << 32; -+} -+ -+/* tp->lock must be held */ -+static void tg3_refclk_write(struct tg3 *tp, u64 newval) -+{ -+ u32 clock_ctl = tr32(TG3_EAV_REF_CLCK_CTL); -+ -+ tw32(TG3_EAV_REF_CLCK_CTL, clock_ctl | TG3_EAV_REF_CLCK_CTL_STOP); -+ tw32(TG3_EAV_REF_CLCK_LSB, newval & 0xffffffff); -+ tw32(TG3_EAV_REF_CLCK_MSB, newval >> 32); -+ tw32_f(TG3_EAV_REF_CLCK_CTL, clock_ctl | TG3_EAV_REF_CLCK_CTL_RESUME); -+} -+ -+static inline void tg3_full_lock(struct tg3 *tp, int irq_sync); -+static inline void tg3_full_unlock(struct tg3 *tp); -+#if IS_ENABLED(CONFIG_PTP_1588_CLOCK) -+#ifdef ETHTOOL_GET_TS_INFO -+static int tg3_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE | -+ SOF_TIMESTAMPING_RX_SOFTWARE | -+ SOF_TIMESTAMPING_SOFTWARE; -+ -+ if (tg3_flag(tp, PTP_CAPABLE)) { -+ info->so_timestamping |= SOF_TIMESTAMPING_TX_HARDWARE | -+ SOF_TIMESTAMPING_RX_HARDWARE | -+ SOF_TIMESTAMPING_RAW_HARDWARE; -+ } -+ -+ if (tp->ptp_clock) -+ info->phc_index = ptp_clock_index(tp->ptp_clock); -+ else -+ info->phc_index = -1; -+ -+ info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); -+ -+ info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) | -+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) | -+ (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | -+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT); -+ return 0; -+} -+#endif -+ -+static int tg3_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) -+{ -+ struct tg3 *tp = container_of(ptp, struct tg3, ptp_info); -+ bool neg_adj = false; -+ u32 correction = 0; -+ -+ if (ppb < 0) { -+ neg_adj = true; -+ ppb = -ppb; -+ } -+ -+ /* Frequency adjustment is performed using hardware with a 24 bit -+ * accumulator and a programmable correction value. On each clk, the -+ * correction value gets added to the accumulator and when it -+ * overflows, the time counter is incremented/decremented. -+ * -+ * So conversion from ppb to correction value is -+ * ppb * (1 << 24) / 1000000000 -+ */ -+ correction = div_u64((u64)ppb * (1 << 24), 1000000000ULL) & -+ TG3_EAV_REF_CLK_CORRECT_MASK; -+ -+ tg3_full_lock(tp, 0); -+ -+ if (correction) -+ tw32(TG3_EAV_REF_CLK_CORRECT_CTL, -+ TG3_EAV_REF_CLK_CORRECT_EN | -+ (neg_adj ? TG3_EAV_REF_CLK_CORRECT_NEG : 0) | correction); -+ else -+ tw32(TG3_EAV_REF_CLK_CORRECT_CTL, 0); -+ -+ tg3_full_unlock(tp); -+ -+ return 0; -+} -+ -+static int tg3_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) -+{ -+ struct tg3 *tp = container_of(ptp, struct tg3, ptp_info); -+ -+ tg3_full_lock(tp, 0); -+ tp->ptp_adjust += delta; -+ tg3_full_unlock(tp); -+ -+ return 0; -+} -+ -+static int tg3_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) -+{ -+ u64 ns; -+ u32 remainder; -+ struct tg3 *tp = container_of(ptp, struct tg3, ptp_info); -+ -+ tg3_full_lock(tp, 0); -+ ns = tg3_refclk_read(tp); -+ ns += tp->ptp_adjust; -+ tg3_full_unlock(tp); -+ -+ ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder); -+ ts->tv_nsec = remainder; -+ -+ return 0; -+} -+ -+static int tg3_ptp_settime(struct ptp_clock_info *ptp, -+ const struct timespec *ts) -+{ -+ u64 ns; -+ struct tg3 *tp = container_of(ptp, struct tg3, ptp_info); -+ -+ ns = timespec_to_ns(ts); -+ -+ tg3_full_lock(tp, 0); -+ tg3_refclk_write(tp, ns); -+ tp->ptp_adjust = 0; -+ tg3_full_unlock(tp); -+ -+ return 0; -+} -+ -+static int tg3_ptp_enable(struct ptp_clock_info *ptp, -+ struct ptp_clock_request *rq, int on) -+{ -+ struct tg3 *tp = container_of(ptp, struct tg3, ptp_info); -+ u32 clock_ctl; -+ int rval = 0; -+ -+ switch (rq->type) { -+ case PTP_CLK_REQ_PEROUT: -+ if (rq->perout.index != 0) -+ return -EINVAL; -+ -+ tg3_full_lock(tp, 0); -+ clock_ctl = tr32(TG3_EAV_REF_CLCK_CTL); -+ clock_ctl &= ~TG3_EAV_CTL_TSYNC_GPIO_MASK; -+ -+ if (on) { -+ u64 nsec; -+ -+ nsec = rq->perout.start.sec * 1000000000ULL + -+ rq->perout.start.nsec; -+ -+ if (rq->perout.period.sec || rq->perout.period.nsec) { -+ netdev_warn(tp->dev, -+ "Device supports only a one-shot timesync output, period must be 0\n"); -+ rval = -EINVAL; -+ goto err_out; -+ } -+ -+ if (nsec & (1ULL << 63)) { -+ netdev_warn(tp->dev, -+ "Start value (nsec) is over limit. Maximum size of start is only 63 bits\n"); -+ rval = -EINVAL; -+ goto err_out; -+ } -+ -+ tw32(TG3_EAV_WATCHDOG0_LSB, (nsec & 0xffffffff)); -+ tw32(TG3_EAV_WATCHDOG0_MSB, -+ TG3_EAV_WATCHDOG0_EN | -+ ((nsec >> 32) & TG3_EAV_WATCHDOG_MSB_MASK)); -+ -+ tw32(TG3_EAV_REF_CLCK_CTL, -+ clock_ctl | TG3_EAV_CTL_TSYNC_WDOG0); -+ } else { -+ tw32(TG3_EAV_WATCHDOG0_MSB, 0); -+ tw32(TG3_EAV_REF_CLCK_CTL, clock_ctl); -+ } -+ -+err_out: -+ tg3_full_unlock(tp); -+ return rval; -+ -+ default: -+ break; -+ } -+ -+ return -EOPNOTSUPP; -+} -+ -+static const struct ptp_clock_info tg3_ptp_caps = { -+ .owner = THIS_MODULE, -+ .name = "tg3 clock", -+ .max_adj = 250000000, -+ .n_alarm = 0, -+ .n_ext_ts = 0, -+ .n_per_out = 1, -+ .pps = 0, -+ .adjfreq = tg3_ptp_adjfreq, -+ .adjtime = tg3_ptp_adjtime, -+ .gettime = tg3_ptp_gettime, -+ .settime = tg3_ptp_settime, -+ .enable = tg3_ptp_enable, -+}; -+ -+static void tg3_hwclock_to_timestamp(struct tg3 *tp, u64 hwclock, -+ struct skb_shared_hwtstamps *timestamp) -+{ -+ memset(timestamp, 0, sizeof(struct skb_shared_hwtstamps)); -+ timestamp->hwtstamp = ns_to_ktime((hwclock & TG3_TSTAMP_MASK) + -+ tp->ptp_adjust); -+} -+ -+/* tp->lock must be held */ -+static void tg3_ptp_init(struct tg3 *tp) -+{ -+ if (!tg3_flag(tp, PTP_CAPABLE)) -+ return; -+ -+ /* Initialize the hardware clock to the system time. */ -+ tg3_refclk_write(tp, ktime_to_ns(ktime_get_real())); -+ tp->ptp_adjust = 0; -+ tp->ptp_info = tg3_ptp_caps; -+} -+ -+/* tp->lock must be held */ -+static void tg3_ptp_resume(struct tg3 *tp) -+{ -+ if (!tg3_flag(tp, PTP_CAPABLE)) -+ return; -+ -+ tg3_refclk_write(tp, ktime_to_ns(ktime_get_real()) + tp->ptp_adjust); -+ tp->ptp_adjust = 0; -+} -+ -+static void tg3_ptp_fini(struct tg3 *tp) -+{ -+ if (!tg3_flag(tp, PTP_CAPABLE) || !tp->ptp_clock) -+ return; -+ -+ ptp_clock_unregister(tp->ptp_clock); -+ tp->ptp_clock = NULL; -+ tp->ptp_adjust = 0; -+} -+ -+#else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */ -+ -+static cycle_t tg3_timecntr_read_clock(const struct cyclecounter *tc) -+{ -+ struct tg3 *tp = container_of(tc, struct tg3, cycles); -+ return tg3_refclk_read(tp); -+} -+ -+static void tg3_ptp_calibrate(struct tg3 *tp) -+{ -+ struct timespec now; -+ -+ getnstimeofday(&now); -+ tg3_refclk_write(tp, timespec_to_ns(&now)); -+ -+ /* Synchronize our NIC clock against system wall clock. */ -+ memset(&tp->cycles, 0, sizeof(tp->cycles)); -+ tp->cycles.read = tg3_timecntr_read_clock; -+ tp->cycles.mask = CLOCKSOURCE_MASK(64); -+ tp->cycles.mult = 1; -+ -+ timecounter_init(&tp->clock, -+ &tp->cycles, -+ ktime_to_ns(ktime_get_real())); -+ -+ memset(&tp->compare, 0, sizeof(tp->compare)); -+ tp->compare.source = &tp->clock; -+ tp->compare.target = ktime_get_real; -+ tp->compare.num_samples = 10; -+ timecompare_update(&tp->compare, 0); -+} -+ -+static void tg3_hwclock_to_timestamp(struct tg3 *tp, u64 hwclock, -+ struct skb_shared_hwtstamps *timestamp) -+{ -+ u64 ns = timecounter_cyc2time(&tp->clock, hwclock & TG3_TSTAMP_MASK); -+ timecompare_update(&tp->compare, ns); -+ -+ memset(timestamp, 0, sizeof(struct skb_shared_hwtstamps)); -+ timestamp->hwtstamp = ns_to_ktime(ns); -+ timestamp->syststamp = timecompare_transform(&tp->compare, ns); -+} -+ -+static void tg3_ptp_init(struct tg3 *tp) -+{ -+ if (!tg3_flag(tp, PTP_CAPABLE)) -+ return; -+ -+ tg3_ptp_calibrate(tp); -+} -+ -+static void tg3_ptp_resume(struct tg3 *tp) -+{ -+ if (!tg3_flag(tp, PTP_CAPABLE)) -+ return; -+ -+ tg3_ptp_calibrate(tp); -+} -+ -+static void tg3_ptp_fini(struct tg3 *tp) -+{ -+} -+#endif /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */ -+ -+#else /* BCM_HAS_IEEE1588_SUPPORT */ -+#define tg3_ptp_init(tp) -+#define tg3_ptp_resume(tp) -+#define tg3_ptp_fini(tp) -+#endif /* BCM_HAS_IEEE1588_SUPPORT */ -+ -+static inline int tg3_irq_sync(struct tg3 *tp) -+{ -+ return tp->irq_sync; -+} -+ -+static inline void tg3_rd32_loop(struct tg3 *tp, u32 *dst, u32 off, u32 len) -+{ -+ int i; -+ -+ dst = (u32 *)((u8 *)dst + off); -+ for (i = 0; i < len; i += sizeof(u32)) -+ *dst++ = tr32(off + i); -+} -+ -+static void tg3_dump_legacy_regs(struct tg3 *tp, u32 *regs) -+{ -+ tg3_rd32_loop(tp, regs, TG3PCI_VENDOR, 0xb0); -+ tg3_rd32_loop(tp, regs, MAILBOX_INTERRUPT_0, 0x200); -+ tg3_rd32_loop(tp, regs, MAC_MODE, 0x4f0); -+ tg3_rd32_loop(tp, regs, SNDDATAI_MODE, 0xe0); -+ tg3_rd32_loop(tp, regs, SNDDATAC_MODE, 0x04); -+ tg3_rd32_loop(tp, regs, SNDBDS_MODE, 0x80); -+ tg3_rd32_loop(tp, regs, SNDBDI_MODE, 0x48); -+ tg3_rd32_loop(tp, regs, SNDBDC_MODE, 0x04); -+ tg3_rd32_loop(tp, regs, RCVLPC_MODE, 0x20); -+ tg3_rd32_loop(tp, regs, RCVLPC_SELLST_BASE, 0x15c); -+ tg3_rd32_loop(tp, regs, RCVDBDI_MODE, 0x0c); -+ tg3_rd32_loop(tp, regs, RCVDBDI_JUMBO_BD, 0x3c); -+ tg3_rd32_loop(tp, regs, RCVDBDI_BD_PROD_IDX_0, 0x44); -+ tg3_rd32_loop(tp, regs, RCVDCC_MODE, 0x04); -+ tg3_rd32_loop(tp, regs, RCVBDI_MODE, 0x20); -+ tg3_rd32_loop(tp, regs, RCVCC_MODE, 0x14); -+ tg3_rd32_loop(tp, regs, RCVLSC_MODE, 0x08); -+ tg3_rd32_loop(tp, regs, MBFREE_MODE, 0x08); -+ tg3_rd32_loop(tp, regs, HOSTCC_MODE, 0x100); -+ -+ if (tg3_flag(tp, SUPPORT_MSIX)) -+ tg3_rd32_loop(tp, regs, HOSTCC_RXCOL_TICKS_VEC1, 0x180); -+ -+ tg3_rd32_loop(tp, regs, MEMARB_MODE, 0x10); -+ tg3_rd32_loop(tp, regs, BUFMGR_MODE, 0x58); -+ tg3_rd32_loop(tp, regs, RDMAC_MODE, 0x08); -+ tg3_rd32_loop(tp, regs, WDMAC_MODE, 0x08); -+ tg3_rd32_loop(tp, regs, RX_CPU_MODE, 0x04); -+ tg3_rd32_loop(tp, regs, RX_CPU_STATE, 0x04); -+ tg3_rd32_loop(tp, regs, RX_CPU_PGMCTR, 0x04); -+ tg3_rd32_loop(tp, regs, RX_CPU_HWBKPT, 0x04); -+ -+ if (!tg3_flag(tp, 5705_PLUS)) { -+ tg3_rd32_loop(tp, regs, TX_CPU_MODE, 0x04); -+ tg3_rd32_loop(tp, regs, TX_CPU_STATE, 0x04); -+ tg3_rd32_loop(tp, regs, TX_CPU_PGMCTR, 0x04); -+ } -+ -+ tg3_rd32_loop(tp, regs, GRCMBOX_INTERRUPT_0, 0x110); -+ tg3_rd32_loop(tp, regs, FTQ_RESET, 0x120); -+ tg3_rd32_loop(tp, regs, MSGINT_MODE, 0x0c); -+ tg3_rd32_loop(tp, regs, DMAC_MODE, 0x04); -+ tg3_rd32_loop(tp, regs, GRC_MODE, 0x4c); -+ -+ if (tg3_flag(tp, NVRAM)) -+ tg3_rd32_loop(tp, regs, NVRAM_CMD, 0x24); -+} -+ -+static void tg3_dump_state(struct tg3 *tp) -+{ -+ int i; -+ u32 *regs; -+ -+ regs = kzalloc(TG3_REG_BLK_SIZE, GFP_ATOMIC); -+ if (!regs) { -+ netdev_err(tp->dev, "Failed allocating register dump buffer\n"); -+ return; -+ } -+ -+ if (tg3_flag(tp, PCI_EXPRESS)) { -+ /* Read up to but not including private PCI registers */ -+ for (i = 0; i < TG3_PCIE_TLDLPL_PORT; i += sizeof(u32)) -+ regs[i / sizeof(u32)] = tr32(i); -+ } else -+ tg3_dump_legacy_regs(tp, regs); -+ -+ for (i = 0; i < TG3_REG_BLK_SIZE / sizeof(u32); i += 4) { -+ if (!regs[i + 0] && !regs[i + 1] && -+ !regs[i + 2] && !regs[i + 3]) -+ continue; -+ -+ netdev_err(tp->dev, "0x%08x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", -+ i * 4, -+ regs[i + 0], regs[i + 1], regs[i + 2], regs[i + 3]); -+ } -+ -+ kfree(regs); -+ -+ for (i = 0; i < tp->irq_cnt; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ -+ /* SW status block */ -+ netdev_err(tp->dev, -+ "%d: Host status block [%08x:%08x:(%04x:%04x:%04x):(%04x:%04x)]\n", -+ i, -+ tnapi->hw_status->status, -+ tnapi->hw_status->status_tag, -+ tnapi->hw_status->rx_jumbo_consumer, -+ tnapi->hw_status->rx_consumer, -+ tnapi->hw_status->rx_mini_consumer, -+ tnapi->hw_status->idx[0].rx_producer, -+ tnapi->hw_status->idx[0].tx_consumer); -+ -+ netdev_err(tp->dev, -+ "%d: NAPI info [%08x:%08x:(%04x:%04x:%04x):%04x:(%04x:%04x:%04x:%04x)]\n", -+ i, -+ tnapi->last_tag, tnapi->last_irq_tag, -+ tnapi->tx_prod, tnapi->tx_cons, tnapi->tx_pending, -+ tnapi->rx_rcb_ptr, -+ tnapi->prodring.rx_std_prod_idx, -+ tnapi->prodring.rx_std_cons_idx, -+ tnapi->prodring.rx_jmb_prod_idx, -+ tnapi->prodring.rx_jmb_cons_idx); -+ } -+} -+ -+/* This is called whenever we suspect that the system chipset is re- -+ * ordering the sequence of MMIO to the tx send mailbox. The symptom -+ * is bogus tx completions. We try to recover by setting the -+ * TG3_FLAG_MBOX_WRITE_REORDER flag and resetting the chip later -+ * in the workqueue. -+ */ -+static void tg3_tx_recover(struct tg3 *tp) -+{ -+ BUG_ON(tg3_flag(tp, MBOX_WRITE_REORDER) || -+ tp->write32_tx_mbox == tg3_write_indirect_mbox); -+ -+ netdev_warn(tp->dev, -+ "The system may be re-ordering memory-mapped I/O " -+ "cycles to the network device, attempting to recover. " -+ "Please report the problem to the driver maintainer " -+ "and include system chipset information.\n"); -+ -+ tg3_flag_set(tp, TX_RECOVERY_PENDING); -+} -+ -+static inline u32 tg3_tx_avail(struct tg3_napi *tnapi) -+{ -+ /* Tell compiler to fetch tx indices from memory. */ -+ barrier(); -+ return tnapi->tx_pending - -+ ((tnapi->tx_prod - tnapi->tx_cons) & (TG3_TX_RING_SIZE - 1)); -+} -+ -+/* Tigon3 never reports partial packet sends. So we do not -+ * need special logic to handle SKBs that have not had all -+ * of their frags sent yet, like SunGEM does. -+ */ -+static void tg3_tx(struct tg3_napi *tnapi) -+{ -+ struct tg3 *tp = tnapi->tp; -+ u32 hw_idx = tnapi->hw_status->idx[0].tx_consumer; -+ u32 sw_idx = tnapi->tx_cons; -+ struct netdev_queue *txq; -+ int index = tnapi - tp->napi; -+ unsigned int pkts_compl = 0, bytes_compl = 0; -+ -+ if (tg3_flag(tp, ENABLE_TSS)) -+ index--; -+ -+ txq = netdev_get_tx_queue(tp->dev, index); -+ -+ while (sw_idx != hw_idx) { -+ struct tg3_tx_ring_info *ri = &tnapi->tx_buffers[sw_idx]; -+ struct sk_buff *skb = ri->skb; -+ int i, tx_bug = 0; -+ -+ if (unlikely(skb == NULL)) { -+ tg3_tx_recover(tp); -+ return; -+ } -+ -+#ifdef BCM_HAS_IEEE1588_SUPPORT -+ if (tnapi->tx_ring[sw_idx].len_flags & TXD_FLAG_HWTSTAMP) { -+ struct skb_shared_hwtstamps timestamp; -+ u64 hwclock = tr32(TG3_TX_TSTAMP_LSB); -+ hwclock |= (u64)tr32(TG3_TX_TSTAMP_MSB) << 32; -+ -+ tg3_hwclock_to_timestamp(tp, hwclock, ×tamp); -+ -+ skb_tstamp_tx(skb, ×tamp); -+ } -+#endif /* BCM_HAS_IEEE1588_SUPPORT */ -+ -+ pci_unmap_single(tp->pdev, -+ dma_unmap_addr(ri, mapping), -+ skb_headlen(skb), -+ PCI_DMA_TODEVICE); -+ -+ ri->skb = NULL; -+ -+ while (ri->fragmented) { -+ ri->fragmented = false; -+ sw_idx = NEXT_TX(sw_idx); -+ ri = &tnapi->tx_buffers[sw_idx]; -+ } -+ -+ sw_idx = NEXT_TX(sw_idx); -+ -+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { -+ ri = &tnapi->tx_buffers[sw_idx]; -+ if (unlikely(ri->skb != NULL || sw_idx == hw_idx)) -+ tx_bug = 1; -+ -+ pci_unmap_page(tp->pdev, -+ dma_unmap_addr(ri, mapping), -+ skb_frag_size(&skb_shinfo(skb)->frags[i]), -+ PCI_DMA_TODEVICE); -+ -+ while (ri->fragmented) { -+ ri->fragmented = false; -+ sw_idx = NEXT_TX(sw_idx); -+ ri = &tnapi->tx_buffers[sw_idx]; -+ } -+ -+ sw_idx = NEXT_TX(sw_idx); -+ } -+ -+ pkts_compl++; -+ bytes_compl += skb->len; -+ -+ dev_kfree_skb(skb); -+ -+ if (unlikely(tx_bug)) { -+ tg3_tx_recover(tp); -+ return; -+ } -+ } -+ -+ netdev_tx_completed_queue(txq, pkts_compl, bytes_compl); -+ -+ tnapi->tx_cons = sw_idx; -+ -+ /* Need to make the tx_cons update visible to tg3_start_xmit() -+ * before checking for netif_queue_stopped(). Without the -+ * memory barrier, there is a small possibility that tg3_start_xmit() -+ * will miss it and cause the queue to be stopped forever. -+ */ -+ smp_mb(); -+ -+ if (unlikely(netif_tx_queue_stopped(txq) && -+ (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))) { -+ __netif_tx_lock(txq, smp_processor_id()); -+ if (netif_tx_queue_stopped(txq) && -+ (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))) -+ netif_tx_wake_queue(txq); -+ __netif_tx_unlock(txq); -+ } -+} -+ -+static void tg3_frag_free(bool is_frag, void *data) -+{ -+#ifdef BCM_HAS_BUILD_SKB -+ if (is_frag) -+ put_page(virt_to_head_page(data)); -+ else -+ kfree(data); -+#else -+ dev_kfree_skb_any(data); -+#endif -+} -+ -+static void tg3_rx_data_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz) -+{ -+ unsigned int skb_size = SKB_DATA_ALIGN(map_sz + TG3_RX_OFFSET(tp)) + -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+ -+ if (!ri->data) -+ return; -+ -+ pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping), -+ map_sz, PCI_DMA_FROMDEVICE); -+ tg3_frag_free(skb_size <= PAGE_SIZE, ri->data); -+ ri->data = NULL; -+} -+ -+/* Returns size of skb allocated or < 0 on error. -+ * -+ * We only need to fill in the address because the other members -+ * of the RX descriptor are invariant, see tg3_init_rings. -+ * -+ * Note the purposeful assymetry of cpu vs. chip accesses. For -+ * posting buffers we only dirty the first cache line of the RX -+ * descriptor (containing the address). Whereas for the RX status -+ * buffers the cpu only reads the last cacheline of the RX descriptor -+ * (to fetch the error flags, vlan tag, checksum, and opaque cookie). -+ */ -+static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr, -+ u32 opaque_key, u32 dest_idx_unmasked, -+ unsigned int *frag_size) -+{ -+ struct tg3_rx_buffer_desc *desc; -+ struct ring_info *map; -+ u8 *data; -+ dma_addr_t mapping; -+#ifdef BCM_HAS_BUILD_SKB -+ int skb_size; -+#else -+ struct sk_buff *skb; -+#endif -+ int data_size, dest_idx; -+ -+ switch (opaque_key) { -+ case RXD_OPAQUE_RING_STD: -+ dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask; -+ desc = &tpr->rx_std[dest_idx]; -+ map = &tpr->rx_std_buffers[dest_idx]; -+ data_size = tp->rx_pkt_map_sz; -+ break; -+ -+ case RXD_OPAQUE_RING_JUMBO: -+ dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask; -+ desc = &tpr->rx_jmb[dest_idx].std; -+ map = &tpr->rx_jmb_buffers[dest_idx]; -+ data_size = TG3_RX_JMB_MAP_SZ; -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ /* Do not overwrite any of the map or rp information -+ * until we are sure we can commit to a new buffer. -+ * -+ * Callers depend upon this behavior and assume that -+ * we leave everything unchanged if we fail. -+ */ -+#ifdef BCM_HAS_BUILD_SKB -+ skb_size = SKB_DATA_ALIGN(data_size + TG3_RX_OFFSET(tp)) + -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+ if (skb_size <= PAGE_SIZE) { -+ data = netdev_alloc_frag(skb_size); -+ *frag_size = skb_size; -+ } else { -+ data = kmalloc(skb_size, GFP_ATOMIC); -+ *frag_size = 0; -+ } -+ if (!data) -+ return -ENOMEM; -+#else -+ skb = netdev_alloc_skb(tp->dev, data_size + TG3_RX_OFFSET(tp) + -+ TG3_COMPAT_VLAN_ALLOC_LEN); -+ if (skb == NULL) -+ return -ENOMEM; -+ -+ skb_reserve(skb, TG3_RX_OFFSET(tp) + -+ TG3_COMPAT_VLAN_RESERVE(TG3_TO_INT(skb->data))); -+ data = skb->data; -+ -+#endif -+ -+ mapping = pci_map_single(tp->pdev, -+ data + TG3_RX_OFFSET(tp), -+ data_size, -+ PCI_DMA_FROMDEVICE); -+ if (unlikely(pci_dma_mapping_error_(tp->pdev, mapping))) { -+#ifdef BCM_HAS_BUILD_SKB -+ tg3_frag_free(skb_size <= PAGE_SIZE, data); -+#else -+ dev_kfree_skb(skb); -+#endif -+ return -EIO; -+ } -+ -+#ifdef BCM_HAS_BUILD_SKB -+ map->data = data; -+#else -+ map->data = skb; -+#endif -+ dma_unmap_addr_set(map, mapping, mapping); -+ -+ desc->addr_hi = ((u64)mapping >> 32); -+ desc->addr_lo = ((u64)mapping & 0xffffffff); -+ -+ return data_size; -+} -+ -+/* We only need to move over in the address because the other -+ * members of the RX descriptor are invariant. See notes above -+ * tg3_alloc_rx_data for full details. -+ */ -+static void tg3_recycle_rx(struct tg3_napi *tnapi, -+ struct tg3_rx_prodring_set *dpr, -+ u32 opaque_key, int src_idx, -+ u32 dest_idx_unmasked) -+{ -+ struct tg3 *tp = tnapi->tp; -+ struct tg3_rx_buffer_desc *src_desc, *dest_desc; -+ struct ring_info *src_map, *dest_map; -+ struct tg3_rx_prodring_set *spr = tnapi->srcprodring; -+ int dest_idx; -+ -+ switch (opaque_key) { -+ case RXD_OPAQUE_RING_STD: -+ dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask; -+ dest_desc = &dpr->rx_std[dest_idx]; -+ dest_map = &dpr->rx_std_buffers[dest_idx]; -+ src_desc = &spr->rx_std[src_idx]; -+ src_map = &spr->rx_std_buffers[src_idx]; -+ break; -+ -+ case RXD_OPAQUE_RING_JUMBO: -+ dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask; -+ dest_desc = &dpr->rx_jmb[dest_idx].std; -+ dest_map = &dpr->rx_jmb_buffers[dest_idx]; -+ src_desc = &spr->rx_jmb[src_idx].std; -+ src_map = &spr->rx_jmb_buffers[src_idx]; -+ break; -+ -+ default: -+ return; -+ } -+ -+ dest_map->data = src_map->data; -+ dma_unmap_addr_set(dest_map, mapping, -+ dma_unmap_addr(src_map, mapping)); -+ dest_desc->addr_hi = src_desc->addr_hi; -+ dest_desc->addr_lo = src_desc->addr_lo; -+ -+ /* Ensure that the update to the skb happens after the physical -+ * addresses have been transferred to the new BD location. -+ */ -+ smp_wmb(); -+ -+ src_map->data = NULL; -+} -+ -+/* The RX ring scheme is composed of multiple rings which post fresh -+ * buffers to the chip, and one special ring the chip uses to report -+ * status back to the host. -+ * -+ * The special ring reports the status of received packets to the -+ * host. The chip does not write into the original descriptor the -+ * RX buffer was obtained from. The chip simply takes the original -+ * descriptor as provided by the host, updates the status and length -+ * field, then writes this into the next status ring entry. -+ * -+ * Each ring the host uses to post buffers to the chip is described -+ * by a TG3_BDINFO entry in the chips SRAM area. When a packet arrives, -+ * it is first placed into the on-chip ram. When the packet's length -+ * is known, it walks down the TG3_BDINFO entries to select the ring. -+ * Each TG3_BDINFO specifies a MAXLEN field and the first TG3_BDINFO -+ * which is within the range of the new packet's length is chosen. -+ * -+ * The "separate ring for rx status" scheme may sound queer, but it makes -+ * sense from a cache coherency perspective. If only the host writes -+ * to the buffer post rings, and only the chip writes to the rx status -+ * rings, then cache lines never move beyond shared-modified state. -+ * If both the host and chip were to write into the same ring, cache line -+ * eviction could occur since both entities want it in an exclusive state. -+ */ -+static int tg3_rx(struct tg3_napi *tnapi, int budget) -+{ -+ struct tg3 *tp = tnapi->tp; -+ u32 work_mask, rx_std_posted = 0; -+ u32 std_prod_idx, jmb_prod_idx; -+ u32 sw_idx = tnapi->rx_rcb_ptr; -+ u16 hw_idx; -+ int received; -+ struct tg3_rx_prodring_set *tpr = &tnapi->prodring; -+ -+ hw_idx = *(tnapi->rx_rcb_prod_idx); -+ /* -+ * We need to order the read of hw_idx and the read of -+ * the opaque cookie. -+ */ -+ rmb(); -+ work_mask = 0; -+ received = 0; -+ std_prod_idx = tpr->rx_std_prod_idx; -+ jmb_prod_idx = tpr->rx_jmb_prod_idx; -+ while (sw_idx != hw_idx && budget > 0) { -+ struct ring_info *ri; -+ struct tg3_rx_buffer_desc *desc = &tnapi->rx_rcb[sw_idx]; -+ unsigned int len; -+ struct sk_buff *skb; -+ dma_addr_t dma_addr; -+ u32 opaque_key, desc_idx, *post_ptr; -+ u8 *data; -+#ifdef BCM_HAS_IEEE1588_SUPPORT -+ u64 tstamp = 0; -+#endif /* BCM_HAS_IEEE1588_SUPPORT */ -+ -+ desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; -+ opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; -+ if (opaque_key == RXD_OPAQUE_RING_STD) { -+ ri = &tnapi->srcprodring->rx_std_buffers[desc_idx]; -+ dma_addr = dma_unmap_addr(ri, mapping); -+#ifdef BCM_HAS_BUILD_SKB -+ data = ri->data; -+#else -+ skb = ri->data; -+ data = skb->data; -+#endif -+ post_ptr = &std_prod_idx; -+ rx_std_posted++; -+ } else if (opaque_key == RXD_OPAQUE_RING_JUMBO) { -+ ri = &tnapi->srcprodring->rx_jmb_buffers[desc_idx]; -+ dma_addr = dma_unmap_addr(ri, mapping); -+#ifdef BCM_HAS_BUILD_SKB -+ data = ri->data; -+#else -+ skb = ri->data; -+ data = skb->data; -+#endif -+ post_ptr = &jmb_prod_idx; -+ } else -+ goto next_pkt_nopost; -+ -+ work_mask |= opaque_key; -+ -+ if (desc->err_vlan & RXD_ERR_MASK) { -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tnapi->netq.stats.rx_errors_sw++; -+ -+ if (desc->err_vlan & RXD_ERR_BAD_CRC) -+ tnapi->netq.stats.rx_crc_errors++; -+ -+ if (desc->err_vlan & -+ (RXD_ERR_TOO_SMALL | -+ RXD_ERR_HUGE_FRAME)) -+ tnapi->netq.stats.rx_frame_errors++; -+#endif -+ drop_it: -+ tg3_recycle_rx(tnapi, tpr, opaque_key, -+ desc_idx, *post_ptr); -+ drop_it_no_recycle: -+ /* Other statistics kept track of by card. */ -+ tp->rx_dropped++; -+ goto next_pkt; -+ } -+ -+ len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - -+ ETH_FCS_LEN; -+ -+#ifdef BCM_HAS_IEEE1588_SUPPORT -+ if ((desc->type_flags & RXD_FLAG_PTPSTAT_MASK) == -+ RXD_FLAG_PTPSTAT_PTPV1 || -+ (desc->type_flags & RXD_FLAG_PTPSTAT_MASK) == -+ RXD_FLAG_PTPSTAT_PTPV2) { -+ /* Read the timestamp out early, in case we drop the packet. */ -+ tstamp = tr32(TG3_RX_TSTAMP_LSB); -+ tstamp |= (u64)tr32(TG3_RX_TSTAMP_MSB) << 32; -+ } -+#endif /* BCM_HAS_IEEE1588_SUPPORT */ -+ -+ if (len > TG3_RX_COPY_THRESH(tp)) { -+ int skb_size; -+ unsigned int frag_size; -+ -+ skb_size = tg3_alloc_rx_data(tp, tpr, opaque_key, -+ *post_ptr, &frag_size); -+ if (skb_size < 0) -+ goto drop_it; -+ -+ pci_unmap_single(tp->pdev, dma_addr, skb_size, -+ PCI_DMA_FROMDEVICE); -+ -+ /* Ensure that the update to the data happens -+ * after the usage of the old DMA mapping. -+ */ -+ smp_wmb(); -+ -+ ri->data = NULL; -+ -+#ifdef BCM_HAS_BUILD_SKB -+ skb = build_skb(data, frag_size); -+ if (!skb) { -+ tg3_frag_free(frag_size != 0, data); -+ goto drop_it_no_recycle; -+ } -+ skb_reserve(skb, TG3_RX_OFFSET(tp)); -+#endif -+ } else { -+ tg3_recycle_rx(tnapi, tpr, opaque_key, -+ desc_idx, *post_ptr); -+ -+ skb = netdev_alloc_skb(tp->dev, -+ len + TG3_RAW_IP_ALIGN); -+ if (skb == NULL) -+ goto drop_it_no_recycle; -+ -+ skb_reserve(skb, TG3_RAW_IP_ALIGN); -+ pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); -+ memcpy(skb->data, -+ data + TG3_RX_OFFSET(tp), -+ len); -+ pci_dma_sync_single_for_device(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); -+ } -+ -+ skb_put(skb, len); -+#ifdef BCM_HAS_IEEE1588_SUPPORT -+ if (tstamp) -+ tg3_hwclock_to_timestamp(tp, tstamp, -+ skb_hwtstamps(skb)); -+#endif /* BCM_HAS_IEEE1588_SUPPORT */ -+ -+ if ((tp->dev->features & NETIF_F_RXCSUM) && -+ (desc->type_flags & RXD_FLAG_TCPUDP_CSUM) && -+ (((desc->ip_tcp_csum & RXD_TCPCSUM_MASK) -+ >> RXD_TCPCSUM_SHIFT) == 0xffff)) -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ else -+ skb_checksum_none_assert(skb); -+ -+#ifndef BCM_HAS_NEW_VLAN_INTERFACE -+ if (desc->type_flags & RXD_FLAG_VLAN) { -+ if (tp->rx_mode & RX_MODE_KEEP_VLAN_TAG) { -+ desc->type_flags &= ~RXD_FLAG_VLAN; -+ } else if (!tp->vlgrp) { -+ struct vlan_ethhdr *ve = (struct vlan_ethhdr *) -+ __skb_push(skb, VLAN_HLEN); -+ -+ memmove(ve, skb->data + VLAN_HLEN, -+ ETH_ALEN * 2); -+ ve->h_vlan_proto = htons(ETH_P_8021Q); -+ ve->h_vlan_TCI = htons(desc->err_vlan & RXD_VLAN_MASK); -+ -+ desc->type_flags &= ~RXD_FLAG_VLAN; -+ } -+ } -+#endif /* BCM_HAS_NEW_VLAN_INTERFACE */ -+ -+ skb->protocol = eth_type_trans(skb, tp->dev); -+ -+ if (len > (tp->dev->mtu + ETH_HLEN) && -+ skb->protocol != htons(ETH_P_8021Q)) { -+ dev_kfree_skb(skb); -+ goto drop_it_no_recycle; -+ } -+ -+#ifndef BCM_HAS_NEW_VLAN_INTERFACE -+ if (desc->type_flags & RXD_FLAG_VLAN) { -+ vlan_gro_receive(&tnapi->napi, tp->vlgrp, -+ desc->err_vlan & RXD_VLAN_MASK, skb); -+ } else -+#else -+ if (desc->type_flags & RXD_FLAG_VLAN && -+ !(tp->rx_mode & RX_MODE_KEEP_VLAN_TAG)) -+ __vlan_hwaccel_put_tag(skb, -+#ifdef BCM_HWACCEL_HAS_PROTO_ARG -+ htons(ETH_P_8021Q), -+#endif -+ desc->err_vlan & RXD_VLAN_MASK); -+#endif /* BCM_HAS_NEW_VLAN_INTERFACE */ -+ -+ napi_gro_receive(&tnapi->napi, skb); -+ -+#if (LINUX_VERSION_CODE < 0x02061D) /* 2.6.29 */ -+ tp->dev->last_rx = jiffies; -+#endif -+ received++; -+ budget--; -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ /* Update queue specific stats */ -+ tnapi->netq.stats.rx_packets_sw++; -+ tnapi->netq.stats.rx_bytes_sw += len; -+#endif -+ -+next_pkt: -+ (*post_ptr)++; -+ -+ if (unlikely(rx_std_posted >= tp->rx_std_max_post)) { -+ tpr->rx_std_prod_idx = std_prod_idx & -+ tp->rx_std_ring_mask; -+ tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, -+ tpr->rx_std_prod_idx); -+ work_mask &= ~RXD_OPAQUE_RING_STD; -+ rx_std_posted = 0; -+ } -+next_pkt_nopost: -+ sw_idx++; -+ sw_idx &= tp->rx_ret_ring_mask; -+ -+ /* Refresh hw_idx to see if there is new work */ -+ if (sw_idx == hw_idx) { -+ hw_idx = *(tnapi->rx_rcb_prod_idx); -+ rmb(); -+ } -+ } -+ -+ /* ACK the status ring. */ -+ tnapi->rx_rcb_ptr = sw_idx; -+ tw32_rx_mbox(tnapi->consmbox, sw_idx); -+ -+ /* Refill RX ring(s). */ -+ if (!tg3_flag(tp, ENABLE_RSS)) { -+ /* Sync BD data before updating mailbox */ -+ wmb(); -+ -+ if (work_mask & RXD_OPAQUE_RING_STD) { -+ tpr->rx_std_prod_idx = std_prod_idx & -+ tp->rx_std_ring_mask; -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tw32_rx_mbox(tpr->rx_std_mbox, tpr->rx_std_prod_idx); -+#else -+ tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, -+ tpr->rx_std_prod_idx); -+#endif -+ } -+ if (work_mask & RXD_OPAQUE_RING_JUMBO) { -+ tpr->rx_jmb_prod_idx = jmb_prod_idx & -+ tp->rx_jmb_ring_mask; -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tw32_rx_mbox(tpr->rx_jmb_mbox, tpr->rx_jmb_prod_idx); -+#else -+ tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, -+ tpr->rx_jmb_prod_idx); -+#endif -+ } -+ mmiowb(); -+ } else if (work_mask) { -+ /* rx_std_buffers[] and rx_jmb_buffers[] entries must be -+ * updated before the producer indices can be updated. -+ */ -+ smp_wmb(); -+ -+ tpr->rx_std_prod_idx = std_prod_idx & tp->rx_std_ring_mask; -+ tpr->rx_jmb_prod_idx = jmb_prod_idx & tp->rx_jmb_ring_mask; -+ -+ if (tnapi != &tp->napi[1]) { -+ tp->rx_refill = true; -+ napi_schedule_(tp->dev, &tp->napi[1].napi); -+ } -+ } -+ -+ return received; -+} -+ -+static void tg3_poll_link(struct tg3 *tp) -+{ -+ /* handle link change and other phy events */ -+ if (!(tg3_flag(tp, USE_LINKCHG_REG) || tg3_flag(tp, POLL_SERDES))) { -+ struct tg3_hw_status *sblk = tp->napi[0].hw_status; -+ -+ if (sblk->status & SD_STATUS_LINK_CHG) { -+ sblk->status = SD_STATUS_UPDATED | -+ (sblk->status & ~SD_STATUS_LINK_CHG); -+ spin_lock(&tp->lock); -+ if (tg3_flag(tp, USE_PHYLIB)) { -+ tw32_f(MAC_STATUS, -+ (MAC_STATUS_SYNC_CHANGED | -+ MAC_STATUS_CFG_CHANGED | -+ MAC_STATUS_MI_COMPLETION | -+ MAC_STATUS_LNKSTATE_CHANGED)); -+ udelay(40); -+ } else -+ tg3_setup_phy(tp, false); -+ spin_unlock(&tp->lock); -+ } -+ } -+} -+ -+static inline void tg3_reset_task_schedule(struct tg3 *tp) -+{ -+ if (!test_and_set_bit(TG3_FLAG_RESET_TASK_PENDING, tp->tg3_flags)) -+ schedule_work(&tp->reset_task); -+} -+ -+static inline void tg3_reset_task_cancel(struct tg3 *tp) -+{ -+#if (LINUX_VERSION_CODE >= 0x20616) || defined (__VMKLNX__) -+ cancel_work_sync(&tp->reset_task); -+#else -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ schedule_timeout(1); -+#endif -+ tg3_flag_clear(tp, RESET_TASK_PENDING); -+ tg3_flag_clear(tp, TX_RECOVERY_PENDING); -+} -+ -+static void tg3_process_error(struct tg3 *tp) -+{ -+ u32 val; -+ bool real_error = false; -+ -+ if (tg3_flag(tp, ERROR_PROCESSED)) -+ return; -+ -+ /* Check Flow Attention register */ -+ val = tr32(HOSTCC_FLOW_ATTN); -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ /* Shutting down NetQueues cause permissible RCB errors */ -+ val &= ~(HOSTCC_FLOW_ATTN_MBUF_LWM | -+ HOSTCC_FLOW_ATTN_RCB_MISCFG | -+ HOSTCC_FLOW_ATTN_RCV_BDI_ATTN); -+#endif -+ if (val & ~HOSTCC_FLOW_ATTN_MBUF_LWM) { -+ netdev_err(tp->dev, "FLOW Attention error. Resetting chip.\n"); -+ real_error = true; -+ } -+ -+ if (tr32(MSGINT_STATUS) & ~MSGINT_STATUS_MSI_REQ) { -+ netdev_err(tp->dev, "MSI Status error. Resetting chip.\n"); -+ real_error = true; -+ } -+ -+ if (tr32(RDMAC_STATUS) || tr32(WDMAC_STATUS)) { -+ netdev_err(tp->dev, "DMA Status error. Resetting chip.\n"); -+ real_error = true; -+ } -+ -+ if (!real_error) -+ return; -+ -+#if !defined(__VMKLNX__) -+ /* Encounterred real error */ -+ tp->recoverable_err++; -+ -+ /* Check if we received two recoverable error within 10 seconds, if so -+ * set the unrecoverable flag and move this port to close state -+ */ -+ if (time_before(jiffies, -+ tp->recoverable_err_jiffies + -+ tp->recoverable_err_interval)) -+ tp->unrecoverable_err++; -+ -+ tp->recoverable_err_jiffies = jiffies; -+#endif -+ -+ tg3_dump_state(tp); -+ -+ tg3_flag_set(tp, ERROR_PROCESSED); -+ tg3_reset_task_schedule(tp); -+} -+ -+static inline void tg3_send_ape_heartbeat(struct tg3 *tp, -+ unsigned long interval) -+{ -+ /* Check if hb interval has exceeded */ -+ if (!tg3_flag(tp, ENABLE_APE) || -+ time_before(jiffies, tp->ape_hb_jiffies + interval)) -+ return; -+ -+ tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_COUNT, tp->ape_hb++); -+ tp->ape_hb_jiffies = jiffies; -+ return; -+} -+ -+#ifdef TG3_NAPI -+ -+static int tg3_rx_prodring_xfer(struct tg3 *tp, -+ struct tg3_rx_prodring_set *dpr, -+ struct tg3_rx_prodring_set *spr) -+{ -+ u32 si, di, cpycnt, src_prod_idx; -+ int i, err = 0; -+ -+ while (1) { -+ src_prod_idx = spr->rx_std_prod_idx; -+ -+ /* Make sure updates to the rx_std_buffers[] entries and the -+ * standard producer index are seen in the correct order. -+ */ -+ smp_rmb(); -+ -+ if (spr->rx_std_cons_idx == src_prod_idx) -+ break; -+ -+ if (spr->rx_std_cons_idx < src_prod_idx) -+ cpycnt = src_prod_idx - spr->rx_std_cons_idx; -+ else -+ cpycnt = tp->rx_std_ring_mask + 1 - -+ spr->rx_std_cons_idx; -+ -+ cpycnt = min(cpycnt, -+ tp->rx_std_ring_mask + 1 - dpr->rx_std_prod_idx); -+ -+ si = spr->rx_std_cons_idx; -+ di = dpr->rx_std_prod_idx; -+ -+ for (i = di; i < di + cpycnt; i++) { -+ if (dpr->rx_std_buffers[i].data) { -+ cpycnt = i - di; -+ err = -ENOSPC; -+ break; -+ } -+ } -+ -+ if (!cpycnt) -+ break; -+ -+ /* Ensure that updates to the rx_std_buffers ring and the -+ * shadowed hardware producer ring from tg3_recycle_skb() are -+ * ordered correctly WRT the skb check above. -+ */ -+ smp_rmb(); -+ -+ memcpy(&dpr->rx_std_buffers[di], -+ &spr->rx_std_buffers[si], -+ cpycnt * sizeof(struct ring_info)); -+ -+ for (i = 0; i < cpycnt; i++, di++, si++) { -+ struct tg3_rx_buffer_desc *sbd, *dbd; -+ sbd = &spr->rx_std[si]; -+ dbd = &dpr->rx_std[di]; -+ dbd->addr_hi = sbd->addr_hi; -+ dbd->addr_lo = sbd->addr_lo; -+ } -+ -+ spr->rx_std_cons_idx = (spr->rx_std_cons_idx + cpycnt) & -+ tp->rx_std_ring_mask; -+ dpr->rx_std_prod_idx = (dpr->rx_std_prod_idx + cpycnt) & -+ tp->rx_std_ring_mask; -+ } -+ -+ while (1) { -+ src_prod_idx = spr->rx_jmb_prod_idx; -+ -+ /* Make sure updates to the rx_jmb_buffers[] entries and -+ * the jumbo producer index are seen in the correct order. -+ */ -+ smp_rmb(); -+ -+ if (spr->rx_jmb_cons_idx == src_prod_idx) -+ break; -+ -+ if (spr->rx_jmb_cons_idx < src_prod_idx) -+ cpycnt = src_prod_idx - spr->rx_jmb_cons_idx; -+ else -+ cpycnt = tp->rx_jmb_ring_mask + 1 - -+ spr->rx_jmb_cons_idx; -+ -+ cpycnt = min(cpycnt, -+ tp->rx_jmb_ring_mask + 1 - dpr->rx_jmb_prod_idx); -+ -+ si = spr->rx_jmb_cons_idx; -+ di = dpr->rx_jmb_prod_idx; -+ -+ for (i = di; i < di + cpycnt; i++) { -+ if (dpr->rx_jmb_buffers[i].data) { -+ cpycnt = i - di; -+ err = -ENOSPC; -+ break; -+ } -+ } -+ -+ if (!cpycnt) -+ break; -+ -+ /* Ensure that updates to the rx_jmb_buffers ring and the -+ * shadowed hardware producer ring from tg3_recycle_skb() are -+ * ordered correctly WRT the skb check above. -+ */ -+ smp_rmb(); -+ -+ memcpy(&dpr->rx_jmb_buffers[di], -+ &spr->rx_jmb_buffers[si], -+ cpycnt * sizeof(struct ring_info)); -+ -+ for (i = 0; i < cpycnt; i++, di++, si++) { -+ struct tg3_rx_buffer_desc *sbd, *dbd; -+ sbd = &spr->rx_jmb[si].std; -+ dbd = &dpr->rx_jmb[di].std; -+ dbd->addr_hi = sbd->addr_hi; -+ dbd->addr_lo = sbd->addr_lo; -+ } -+ -+ spr->rx_jmb_cons_idx = (spr->rx_jmb_cons_idx + cpycnt) & -+ tp->rx_jmb_ring_mask; -+ dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) & -+ tp->rx_jmb_ring_mask; -+ } -+ -+ return err; -+} -+ -+static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget) -+{ -+ struct tg3 *tp = tnapi->tp; -+ -+ /* run TX completion thread */ -+ if (tnapi->hw_status->idx[0].tx_consumer != tnapi->tx_cons) { -+ tg3_tx(tnapi); -+ if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING))) -+ return work_done; -+ } -+ -+ if (!tnapi->rx_rcb_prod_idx) -+ return work_done; -+ -+ /* run RX thread, within the bounds set by NAPI. -+ * All RX "locking" is done by ensuring outside -+ * code synchronizes with tg3->napi.poll() -+ */ -+ if (*(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr) -+ work_done += tg3_rx(tnapi, budget - work_done); -+ -+ if (tg3_flag(tp, ENABLE_RSS) && tnapi == &tp->napi[1]) { -+ struct tg3_rx_prodring_set *dpr = &tp->napi[0].prodring; -+ int i, err = 0; -+ u32 std_prod_idx = dpr->rx_std_prod_idx; -+ u32 jmb_prod_idx = dpr->rx_jmb_prod_idx; -+ -+ tp->rx_refill = false; -+ for (i = 1; i <= tp->rxq_cnt; i++) -+ err |= tg3_rx_prodring_xfer(tp, dpr, -+ &tp->napi[i].prodring); -+ -+ wmb(); -+ -+ if (std_prod_idx != dpr->rx_std_prod_idx) -+ tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, -+ dpr->rx_std_prod_idx); -+ -+ if (jmb_prod_idx != dpr->rx_jmb_prod_idx) -+ tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, -+ dpr->rx_jmb_prod_idx); -+ -+ mmiowb(); -+ -+ if (err) -+ tw32_f(HOSTCC_MODE, tp->coal_now); -+ } -+ -+ return work_done; -+} -+ -+static int tg3_poll_msix(struct napi_struct *napi, int budget) -+{ -+ struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi); -+ struct tg3 *tp = tnapi->tp; -+ int work_done = 0; -+ struct tg3_hw_status *sblk = tnapi->hw_status; -+ -+ while (1) { -+ work_done = tg3_poll_work(tnapi, work_done, budget); -+ -+ if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING))) -+ goto tx_recovery; -+ -+ if (unlikely(work_done >= budget)) -+ break; -+ -+ /* tp->last_tag is used in tg3_int_reenable() below -+ * to tell the hw how much work has been processed, -+ * so we must read it before checking for more work. -+ */ -+ tnapi->last_tag = sblk->status_tag; -+ tnapi->last_irq_tag = tnapi->last_tag; -+ rmb(); -+ -+ /* check for RX/TX work to do */ -+ if (likely(sblk->idx[0].tx_consumer == tnapi->tx_cons && -+ *(tnapi->rx_rcb_prod_idx) == tnapi->rx_rcb_ptr)) { -+ -+ /* This test here is not race free, but will reduce -+ * the number of interrupts by looping again. -+ */ -+ if (tnapi == &tp->napi[1] && tp->rx_refill) -+ continue; -+ -+ napi_complete_(tp->dev, napi); -+ /* Reenable interrupts. */ -+ tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24); -+ -+ /* This test here is synchronized by napi_schedule() -+ * and napi_complete() to close the race condition. -+ */ -+ if (unlikely(tnapi == &tp->napi[1] && tp->rx_refill)) { -+ tw32(HOSTCC_MODE, tp->coalesce_mode | -+ HOSTCC_MODE_ENABLE | -+ tnapi->coal_now); -+ } -+ mmiowb(); -+ break; -+ } -+ } -+ -+ tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL << 1); -+ return work_done; -+ -+tx_recovery: -+ /* work_done is guaranteed to be less than budget. */ -+ napi_complete_(tp->dev, napi); -+ tg3_reset_task_schedule(tp); -+ return work_done; -+} -+ -+static int tg3_poll(struct napi_struct *napi, int budget) -+{ -+ struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi); -+ struct tg3 *tp = tnapi->tp; -+ int work_done = 0; -+ struct tg3_hw_status *sblk = tnapi->hw_status; -+ -+ while (1) { -+ if (sblk->status & SD_STATUS_ERROR) -+ tg3_process_error(tp); -+ -+ tg3_poll_link(tp); -+ -+ work_done = tg3_poll_work(tnapi, work_done, budget); -+ -+ if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING))) -+ goto tx_recovery; -+ -+ if (unlikely(work_done >= budget)) -+ break; -+ -+ if (tg3_flag(tp, TAGGED_STATUS)) { -+ /* tp->last_tag is used in tg3_int_reenable() below -+ * to tell the hw how much work has been processed, -+ * so we must read it before checking for more work. -+ */ -+ tnapi->last_tag = sblk->status_tag; -+ tnapi->last_irq_tag = tnapi->last_tag; -+ rmb(); -+ } else -+ sblk->status &= ~SD_STATUS_UPDATED; -+ -+ if (likely(!tg3_has_work(tnapi))) { -+ napi_complete_(tp->dev, napi); -+ tg3_int_reenable(tnapi); -+ break; -+ } -+ } -+ -+ tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL << 1); -+ return work_done; -+ -+tx_recovery: -+ /* work_done is guaranteed to be less than budget. */ -+ napi_complete_(tp->dev, napi); -+ tg3_reset_task_schedule(tp); -+ return work_done; -+} -+ -+#else -+ -+static int tg3_poll(struct net_device *netdev, int *budget) -+{ -+ struct tg3 *tp = netdev_priv(netdev); -+ struct tg3_napi *tnapi = &tp->napi[0]; -+ struct tg3_hw_status *sblk = tnapi->hw_status; -+ int done; -+ -+ if (sblk->status & SD_STATUS_ERROR) -+ tg3_process_error(tp); -+ -+ tg3_poll_link(tp); -+ -+ /* run TX completion thread */ -+ if (sblk->idx[0].tx_consumer != tnapi->tx_cons) { -+ tg3_tx(tnapi); -+ if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING))) { -+ netif_rx_complete(netdev); -+ tg3_reset_task_schedule(tp); -+ return 0; -+ } -+ } -+ -+ /* run RX thread, within the bounds set by NAPI. -+ * All RX "locking" is done by ensuring outside -+ * code synchronizes with dev->poll() -+ */ -+ if (sblk->idx[0].rx_producer != tnapi->rx_rcb_ptr) { -+ int orig_budget = *budget; -+ int work_done; -+ -+ if (orig_budget > netdev->quota) -+ orig_budget = netdev->quota; -+ -+ work_done = tg3_rx(tnapi, orig_budget); -+ -+ *budget -= work_done; -+ netdev->quota -= work_done; -+ } -+ -+ if (tg3_flag(tp, TAGGED_STATUS)) { -+ tnapi->last_tag = sblk->status_tag; -+ rmb(); -+ } else -+ sblk->status &= ~SD_STATUS_UPDATED; -+ -+ /* if no more work, tell net stack and NIC we're done */ -+ done = !tg3_has_work(tnapi); -+ if (done) { -+ netif_rx_complete(netdev); -+ tg3_int_reenable(tnapi); -+ } -+ -+ return (done ? 0 : 1); -+} -+ -+#endif /* TG3_NAPI */ -+ -+static void tg3_napi_disable(struct tg3 *tp) -+{ -+#ifdef TG3_NAPI -+ int i; -+ -+ for (i = tp->irq_cnt - 1; i >= 0; i--) -+ napi_disable(&tp->napi[i].napi); -+#else -+ netif_poll_disable(tp->dev); -+#endif -+} -+ -+static void tg3_napi_enable(struct tg3 *tp) -+{ -+#ifdef TG3_NAPI -+ int i; -+ -+ for (i = 0; i < tp->irq_cnt; i++) -+ napi_enable(&tp->napi[i].napi); -+#else -+ netif_poll_enable(tp->dev); -+#endif -+} -+ -+static void tg3_napi_init(struct tg3 *tp) -+{ -+#ifdef TG3_NAPI -+ int i; -+ -+ netif_napi_add(tp->dev, &tp->napi[0].napi, tg3_poll, 64); -+ for (i = 1; i < tp->irq_cnt; i++) -+ netif_napi_add(tp->dev, &tp->napi[i].napi, tg3_poll_msix, 64); -+#else -+ tp->dev->poll = tg3_poll; -+ tp->dev->weight = 64; -+#endif -+} -+ -+static void tg3_napi_fini(struct tg3 *tp) -+{ -+#ifdef TG3_NAPI -+ int i; -+ -+ for (i = 0; i < tp->irq_cnt; i++) -+ netif_napi_del(&tp->napi[i].napi); -+#endif -+} -+ -+static inline void tg3_netif_stop(struct tg3 *tp) -+{ -+ tp->dev->trans_start = jiffies; /* prevent tx timeout */ -+ tg3_napi_disable(tp); -+ netif_carrier_off(tp->dev); /* prevent spurious tx timeout */ -+ netif_tx_disable(tp->dev); -+} -+ -+/* tp->lock must be held */ -+static inline void tg3_netif_start(struct tg3 *tp) -+{ -+ tg3_ptp_resume(tp); -+ -+ /* NOTE: unconditional netif_tx_wake_all_queues is only -+ * appropriate so long as all callers are assured to -+ * have free tx slots (such as after tg3_init_hw) -+ */ -+ netif_tx_wake_all_queues(tp->dev); -+ -+ if (tp->link_up) -+ netif_carrier_on(tp->dev); -+ -+ tg3_napi_enable(tp); -+ tp->napi[0].hw_status->status |= SD_STATUS_UPDATED; -+ tg3_enable_ints(tp); -+} -+ -+static void tg3_irq_quiesce(struct tg3 *tp) -+{ -+#if (LINUX_VERSION_CODE >= 0x2051c) -+ int i; -+#endif -+ -+ BUG_ON(tp->irq_sync); -+ -+ tp->irq_sync = 1; -+ smp_mb(); -+ -+#if (LINUX_VERSION_CODE >= 0x2051c) -+ for (i = 0; i < tp->irq_cnt; i++) -+ synchronize_irq(tp->napi[i].irq_vec); -+#else -+ synchronize_irq(); -+#endif -+} -+ -+/* Fully shutdown all tg3 driver activity elsewhere in the system. -+ * If irq_sync is non-zero, then the IRQ handler must be synchronized -+ * with as well. Most of the time, this is not necessary except when -+ * shutting down the device. -+ */ -+static inline void tg3_full_lock(struct tg3 *tp, int irq_sync) -+{ -+ spin_lock_bh(&tp->lock); -+ if (irq_sync) -+ tg3_irq_quiesce(tp); -+} -+ -+static inline void tg3_full_unlock(struct tg3 *tp) -+{ -+ spin_unlock_bh(&tp->lock); -+} -+ -+/* One-shot MSI handler - Chip automatically disables interrupt -+ * after sending MSI so driver doesn't have to do it. -+ */ -+#ifdef BCM_HAS_NEW_IRQ_SIG -+static irqreturn_t tg3_msi_1shot(int irq, void *dev_id) -+#else -+static irqreturn_t tg3_msi_1shot(int irq, void *dev_id, struct pt_regs *regs) -+#endif -+{ -+ struct tg3_napi *tnapi = dev_id; -+ struct tg3 *tp = tnapi->tp; -+ -+ prefetch(tnapi->hw_status); -+ if (tnapi->rx_rcb) -+ prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]); -+ -+ if (likely(!tg3_irq_sync(tp))) -+ napi_schedule_(tp->dev, &tnapi->napi); -+ -+ return IRQ_HANDLED; -+} -+ -+/* MSI ISR - No need to check for interrupt sharing and no need to -+ * flush status block and interrupt mailbox. PCI ordering rules -+ * guarantee that MSI will arrive after the status block. -+ */ -+#ifdef BCM_HAS_NEW_IRQ_SIG -+static irqreturn_t tg3_msi(int irq, void *dev_id) -+#else -+static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) -+#endif -+{ -+ struct tg3_napi *tnapi = dev_id; -+ struct tg3 *tp = tnapi->tp; -+ -+ prefetch(tnapi->hw_status); -+ if (tnapi->rx_rcb) -+ prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]); -+ /* -+ * Writing any value to intr-mbox-0 clears PCI INTA# and -+ * chip-internal interrupt pending events. -+ * Writing non-zero to intr-mbox-0 additional tells the -+ * NIC to stop sending us irqs, engaging "in-intr-handler" -+ * event coalescing. -+ */ -+ tw32_mailbox(tnapi->int_mbox, 0x00000001); -+ if (likely(!tg3_irq_sync(tp))) -+ napi_schedule_(tp->dev, &tnapi->napi); -+ -+ return IRQ_RETVAL(1); -+} -+ -+#ifdef BCM_HAS_NEW_IRQ_SIG -+static irqreturn_t tg3_interrupt(int irq, void *dev_id) -+#else -+static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) -+#endif -+{ -+ struct tg3_napi *tnapi = dev_id; -+ struct tg3 *tp = tnapi->tp; -+ struct tg3_hw_status *sblk = tnapi->hw_status; -+ unsigned int handled = 1; -+ -+ /* In INTx mode, it is possible for the interrupt to arrive at -+ * the CPU before the status block posted prior to the interrupt. -+ * Reading the PCI State register will confirm whether the -+ * interrupt is ours and will flush the status block. -+ */ -+ if (unlikely(!(sblk->status & SD_STATUS_UPDATED))) { -+ if (tg3_flag(tp, CHIP_RESETTING) || -+ (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { -+ handled = 0; -+ goto out; -+ } -+ } -+ -+ /* -+ * Writing any value to intr-mbox-0 clears PCI INTA# and -+ * chip-internal interrupt pending events. -+ * Writing non-zero to intr-mbox-0 additional tells the -+ * NIC to stop sending us irqs, engaging "in-intr-handler" -+ * event coalescing. -+ * -+ * Flush the mailbox to de-assert the IRQ immediately to prevent -+ * spurious interrupts. The flush impacts performance but -+ * excessive spurious interrupts can be worse in some cases. -+ */ -+ tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); -+ if (tg3_irq_sync(tp)) -+ goto out; -+ sblk->status &= ~SD_STATUS_UPDATED; -+ if (likely(tg3_has_work(tnapi))) { -+ prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]); -+ napi_schedule_(tp->dev, &tnapi->napi); -+ } else { -+ /* No work, shared interrupt perhaps? re-enable -+ * interrupts, and flush that PCI write -+ */ -+ tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, -+ 0x00000000); -+ } -+out: -+ return IRQ_RETVAL(handled); -+} -+ -+#ifdef BCM_HAS_NEW_IRQ_SIG -+static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id) -+#else -+static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *regs) -+#endif -+{ -+ struct tg3_napi *tnapi = dev_id; -+ struct tg3 *tp = tnapi->tp; -+ struct tg3_hw_status *sblk = tnapi->hw_status; -+ unsigned int handled = 1; -+ -+ /* In INTx mode, it is possible for the interrupt to arrive at -+ * the CPU before the status block posted prior to the interrupt. -+ * Reading the PCI State register will confirm whether the -+ * interrupt is ours and will flush the status block. -+ */ -+ if (unlikely(sblk->status_tag == tnapi->last_irq_tag)) { -+ if (tg3_flag(tp, CHIP_RESETTING) || -+ (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { -+ handled = 0; -+ goto out; -+ } -+ } -+ -+ /* -+ * writing any value to intr-mbox-0 clears PCI INTA# and -+ * chip-internal interrupt pending events. -+ * writing non-zero to intr-mbox-0 additional tells the -+ * NIC to stop sending us irqs, engaging "in-intr-handler" -+ * event coalescing. -+ * -+ * Flush the mailbox to de-assert the IRQ immediately to prevent -+ * spurious interrupts. The flush impacts performance but -+ * excessive spurious interrupts can be worse in some cases. -+ */ -+ tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); -+ -+ /* -+ * In a shared interrupt configuration, sometimes other devices' -+ * interrupts will scream. We record the current status tag here -+ * so that the above check can report that the screaming interrupts -+ * are unhandled. Eventually they will be silenced. -+ */ -+ tnapi->last_irq_tag = sblk->status_tag; -+ -+ if (tg3_irq_sync(tp)) -+ goto out; -+ -+ prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]); -+ -+ napi_schedule_(tp->dev, &tnapi->napi); -+ -+out: -+ return IRQ_RETVAL(handled); -+} -+ -+/* ISR for interrupt test */ -+#ifdef BCM_HAS_NEW_IRQ_SIG -+static irqreturn_t tg3_test_isr(int irq, void *dev_id) -+#else -+static irqreturn_t tg3_test_isr(int irq, void *dev_id, struct pt_regs *regs) -+#endif -+{ -+ struct tg3_napi *tnapi = dev_id; -+ struct tg3 *tp = tnapi->tp; -+ struct tg3_hw_status *sblk = tnapi->hw_status; -+ -+ if ((sblk->status & SD_STATUS_UPDATED) || -+ !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { -+ tg3_disable_ints(tp); -+ return IRQ_RETVAL(1); -+ } -+ return IRQ_RETVAL(0); -+} -+ -+#ifdef CONFIG_NET_POLL_CONTROLLER -+static void tg3_poll_controller(struct net_device *dev) -+{ -+#ifdef BCM_HAS_NEW_IRQ_SIG -+ int i; -+#endif -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (tg3_irq_sync(tp)) -+ return; -+ -+#if defined(BCM_HAS_NETDUMP_MODE) && (LINUX_VERSION_CODE < 0x20600) -+ if (netdump_mode) { -+ tg3_interrupt(tp->pdev->irq, dev, NULL); -+ if (dev->poll_list.prev) { -+ int budget = 64; -+ -+ tg3_poll(dev, &budget); -+ } -+ } -+ else -+#endif -+#ifdef BCM_HAS_NEW_IRQ_SIG -+ for (i = 0; i < tp->irq_cnt; i++) -+ tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]); -+#else -+ tg3_interrupt(tp->pdev->irq, dev, NULL); -+#endif -+} -+#endif -+ -+static void tg3_tx_timeout(struct net_device *dev) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (netif_msg_tx_err(tp)) { -+ netdev_err(dev, "transmit timed out, resetting\n"); -+ tg3_dump_state(tp); -+#if defined(__VMKLNX__) -+ if (psod_on_tx_timeout) { -+ msleep(100); -+ BUG_ON(1); -+ return; -+ } -+#endif -+ } -+ -+ tg3_reset_task_schedule(tp); -+} -+ -+/* Test for DMA buffers crossing any 4GB boundaries: 4G, 8G, etc */ -+static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len) -+{ -+ u32 base = (u32) mapping & 0xffffffff; -+ -+ return (base + len + 8 < base); -+} -+ -+/* Test for TSO DMA buffers that cross into regions which are within MSS bytes -+ * of any 4GB boundaries: 4G, 8G, etc -+ */ -+static inline int tg3_4g_tso_overflow_test(struct tg3 *tp, dma_addr_t mapping, -+ u32 len, u32 mss) -+{ -+ if (tg3_asic_rev(tp) == ASIC_REV_5762 && mss) { -+ u32 base = (u32) mapping & 0xffffffff; -+ -+ return ((base + len + (mss & 0x3fff)) < base); -+ } -+ return 0; -+} -+ -+/* Test for DMA addresses > 40-bit */ -+static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, -+ int len) -+{ -+#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64) -+ if (tg3_flag(tp, 40BIT_DMA_BUG)) -+ return ((u64) mapping + len) > DMA_BIT_MASK(40); -+ return 0; -+#else -+ return 0; -+#endif -+} -+ -+static inline void tg3_tx_set_bd(struct tg3_tx_buffer_desc *txbd, -+ dma_addr_t mapping, u32 len, u32 flags, -+ u32 mss, u32 vlan) -+{ -+ txbd->addr_hi = ((u64) mapping >> 32); -+ txbd->addr_lo = ((u64) mapping & 0xffffffff); -+ txbd->len_flags = (len << TXD_LEN_SHIFT) | (flags & 0x0000ffff); -+ txbd->vlan_tag = (mss << TXD_MSS_SHIFT) | (vlan << TXD_VLAN_TAG_SHIFT); -+} -+ -+static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget, -+ dma_addr_t map, u32 len, u32 flags, -+ u32 mss, u32 vlan) -+{ -+ struct tg3 *tp = tnapi->tp; -+ bool hwbug = false; -+ u32 dma_limit = tp->dma_limit; -+ -+ if (tg3_flag(tp, SHORT_DMA_BUG) && len <= 8) -+ hwbug = true; -+ -+ if (tg3_4g_overflow_test(map, len)) { -+ tp->dma_4g_cross++; -+ hwbug = true; -+ } -+ -+ if (tg3_4g_tso_overflow_test(tp, map, len, mss)) -+ hwbug = true; -+ -+ if (tg3_40bit_overflow_test(tp, map, len)) -+ hwbug = true; -+ -+ if (dma_limit) { -+ u32 prvidx = *entry; -+ u32 tmp_flag = flags & ~TXD_FLAG_END; -+ while (len > dma_limit && *budget) { -+ u32 frag_len = dma_limit; -+ len -= dma_limit; -+ -+ /* Avoid the 8byte DMA problem */ -+ if (len <= 8) { -+ len += dma_limit / 2; -+ frag_len = dma_limit / 2; -+ } -+ -+ tnapi->tx_buffers[*entry].fragmented = true; -+ -+ tg3_tx_set_bd(&tnapi->tx_ring[*entry], map, -+ frag_len, tmp_flag, mss, vlan); -+ *budget -= 1; -+ prvidx = *entry; -+ *entry = NEXT_TX(*entry); -+ -+ map += frag_len; -+ } -+ -+ if (len) { -+ if (*budget) { -+ tg3_tx_set_bd(&tnapi->tx_ring[*entry], map, -+ len, flags, mss, vlan); -+ *budget -= 1; -+ *entry = NEXT_TX(*entry); -+ } else { -+ hwbug = true; -+ tnapi->tx_buffers[prvidx].fragmented = false; -+ } -+ } -+ } else { -+ tg3_tx_set_bd(&tnapi->tx_ring[*entry], map, -+ len, flags, mss, vlan); -+ *entry = NEXT_TX(*entry); -+ } -+ -+ return hwbug; -+} -+ -+static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last) -+{ -+ int i; -+ struct sk_buff *skb; -+ struct tg3_tx_ring_info *txb = &tnapi->tx_buffers[entry]; -+ -+ skb = txb->skb; -+ txb->skb = NULL; -+ -+ pci_unmap_single(tnapi->tp->pdev, -+ dma_unmap_addr(txb, mapping), -+ skb_headlen(skb), -+ PCI_DMA_TODEVICE); -+ -+ while (txb->fragmented) { -+ txb->fragmented = false; -+ entry = NEXT_TX(entry); -+ txb = &tnapi->tx_buffers[entry]; -+ } -+ -+ for (i = 0; i <= last; i++) { -+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; -+ -+ entry = NEXT_TX(entry); -+ txb = &tnapi->tx_buffers[entry]; -+ -+ pci_unmap_page(tnapi->tp->pdev, -+ dma_unmap_addr(txb, mapping), -+ skb_frag_size(frag), PCI_DMA_TODEVICE); -+ -+ while (txb->fragmented) { -+ txb->fragmented = false; -+ entry = NEXT_TX(entry); -+ txb = &tnapi->tx_buffers[entry]; -+ } -+ } -+} -+ -+/* Workaround 4GB and 40-bit hardware DMA bugs. */ -+static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, -+ struct sk_buff **pskb, -+ u32 *entry, u32 *budget, -+ u32 base_flags, u32 mss, u32 vlan) -+{ -+ struct tg3 *tp = tnapi->tp; -+ struct sk_buff *new_skb, *skb = *pskb; -+ dma_addr_t new_addr = 0; -+ int ret = 0; -+ -+ if (tg3_asic_rev(tp) != ASIC_REV_5701) -+ new_skb = skb_copy(skb, GFP_ATOMIC); -+ else { -+ int more_headroom = 4 - ((unsigned long)skb->data & 3); -+ -+ new_skb = skb_copy_expand(skb, -+ skb_headroom(skb) + more_headroom, -+ skb_tailroom(skb), GFP_ATOMIC); -+ } -+ -+ if (!new_skb) { -+ ret = -1; -+ } else { -+ /* New SKB is guaranteed to be linear. */ -+ new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len, -+ PCI_DMA_TODEVICE); -+ /* Make sure the mapping succeeded */ -+ if (pci_dma_mapping_error_(tp->pdev, new_addr)) { -+ dev_kfree_skb(new_skb); -+ ret = -1; -+ } else { -+ u32 save_entry = *entry; -+ -+ base_flags |= TXD_FLAG_END; -+ -+ tnapi->tx_buffers[*entry].skb = new_skb; -+ dma_unmap_addr_set(&tnapi->tx_buffers[*entry], -+ mapping, new_addr); -+ -+ if (tg3_tx_frag_set(tnapi, entry, budget, new_addr, -+ new_skb->len, base_flags, -+ mss, vlan)) { -+ tg3_tx_skb_unmap(tnapi, save_entry, -1); -+ dev_kfree_skb(new_skb); -+ ret = -1; -+ } -+ } -+ } -+ -+ dev_kfree_skb(skb); -+ *pskb = new_skb; -+ return ret; -+} -+ -+#if TG3_TSO_SUPPORT != 0 -+static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *); -+ -+/* Use GSO to workaround a rare TSO bug that may be triggered when the -+ * TSO header is greater than 80 bytes. -+ */ -+static netdev_tx_t tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi, -+ struct netdev_queue *txq, struct sk_buff *skb) -+{ -+ struct sk_buff *segs, *nskb; -+ u32 frag_cnt_est = skb_shinfo(skb)->gso_segs * 3; -+ -+ /* Estimate the number of fragments in the worst case */ -+ if (unlikely(tg3_tx_avail(tnapi) <= frag_cnt_est)) { -+ netif_tx_stop_queue(txq); -+ -+ /* netif_tx_stop_queue() must be done before checking -+ * checking tx index in tg3_tx_avail() below, because in -+ * tg3_tx(), we update tx index before checking for -+ * netif_tx_queue_stopped(). -+ */ -+ smp_mb(); -+ if (tg3_tx_avail(tnapi) <= frag_cnt_est) -+ return NETDEV_TX_BUSY; -+ -+ netif_tx_wake_queue(txq); -+ } -+ -+ segs = skb_gso_segment(skb, tp->dev->features & -+ ~(NETIF_F_TSO | NETIF_F_TSO6)); -+ /* VMWare always returns NULL. Linux will only return NULL -+ * when no segments are required. -+ */ -+ if (!segs || IS_ERR(segs)) -+ goto tg3_tso_bug_end; -+ -+ do { -+ nskb = segs; -+ segs = segs->next; -+ nskb->next = NULL; -+ tg3_start_xmit(nskb, tp->dev); -+ } while (segs); -+ -+tg3_tso_bug_end: -+ dev_kfree_skb(skb); -+ -+ return NETDEV_TX_OK; -+} -+#endif /* TG3_TSO_SUPPORT */ -+ -+/* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and -+ * support TG3_FLAG_HW_TSO_1 or firmware TSO only. -+ */ -+static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ u32 len, entry, base_flags, mss, vlan = 0; -+ u32 budget; -+ int i = -1, would_hit_hwbug; -+ dma_addr_t mapping; -+ struct tg3_napi *tnapi; -+ struct netdev_queue *txq; -+ unsigned int last; -+ struct iphdr *iph = NULL; -+ struct tcphdr *tcph = NULL; -+ __sum16 tcp_csum = 0, ip_csum = 0; -+ __be16 ip_tot_len = 0; -+ -+ txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); -+#if defined(__VMKLNX__) && (VMWARE_ESX_DDK_VERSION < 50000) -+ /* For esx4.0/esx4.1u0-u2, the vmkernel doesn't check queue state -+ * before calling start_xmit(). So driver has to check it itself. -+ */ -+ if (unlikely(netif_tx_queue_stopped(txq))) -+ goto drop; -+#endif -+ tnapi = &tp->napi[skb_get_queue_mapping(skb)]; -+ if (tg3_flag(tp, ENABLE_TSS)) -+ tnapi++; -+ -+ budget = tg3_tx_avail(tnapi); -+ -+ /* We are running in BH disabled context with netif_tx_lock -+ * and TX reclaim runs via tp->napi.poll inside of a software -+ * interrupt. Furthermore, IRQ processing runs lockless so we have -+ * no IRQ context deadlocks to worry about either. Rejoice! -+ */ -+ if (unlikely(budget <= (skb_shinfo(skb)->nr_frags + 1))) { -+ if (!netif_tx_queue_stopped(txq)) { -+ netif_tx_stop_queue(txq); -+ -+ /* This is a hard error, log it. */ -+ netdev_err(dev, -+ "BUG! Tx Ring full when queue awake!\n"); -+ } -+ return NETDEV_TX_BUSY; -+ } -+ -+ entry = tnapi->tx_prod; -+ base_flags = 0; -+ if (skb->ip_summed == CHECKSUM_PARTIAL) -+ base_flags |= TXD_FLAG_TCPUDP_CSUM; -+ -+#if TG3_TSO_SUPPORT != 0 -+ mss = skb_shinfo(skb)->gso_size; -+ if (mss) { -+ u32 tcp_opt_len, hdr_len; -+ -+ if (skb_header_cloned(skb) && -+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) -+ goto drop; -+ -+ iph = ip_hdr(skb); -+ tcp_opt_len = tcp_optlen(skb); -+ -+ hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN; -+ -+ if (!skb_is_gso_v6(skb)) { -+ if (unlikely((ETH_HLEN + hdr_len) > 80) && -+ tg3_flag(tp, TSO_BUG)) -+ return tg3_tso_bug(tp, tnapi, txq, skb); -+ -+ ip_csum = iph->check; -+ ip_tot_len = iph->tot_len; -+ iph->check = 0; -+ iph->tot_len = htons(mss + hdr_len); -+ } -+ -+ if (hdr_len + mss >= skb->len - ETH_HLEN) { -+ mss = 0; -+ goto abort_lso; -+ } -+ -+ base_flags |= (TXD_FLAG_CPU_PRE_DMA | -+ TXD_FLAG_CPU_POST_DMA); -+ -+ tcph = tcp_hdr(skb); -+ tcp_csum = tcph->check; -+ -+ if (tg3_flag(tp, HW_TSO_1) || -+ tg3_flag(tp, HW_TSO_2) || -+ tg3_flag(tp, HW_TSO_3)) { -+ tcph->check = 0; -+ base_flags &= ~TXD_FLAG_TCPUDP_CSUM; -+ } else { -+ tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, -+ 0, IPPROTO_TCP, 0); -+ } -+ -+ if (tg3_flag(tp, HW_TSO_3)) { -+ mss |= (hdr_len & 0xc) << 12; -+ if (hdr_len & 0x10) -+ base_flags |= 0x00000010; -+ base_flags |= (hdr_len & 0x3e0) << 5; -+ } else if (tg3_flag(tp, HW_TSO_2)) -+ mss |= hdr_len << 9; -+ else if (tg3_flag(tp, HW_TSO_1) || -+ tg3_asic_rev(tp) == ASIC_REV_5705) { -+ if (tcp_opt_len || iph->ihl > 5) { -+ int tsflags; -+ -+ tsflags = (iph->ihl - 5) + (tcp_opt_len >> 2); -+ mss |= (tsflags << 11); -+ } -+ } else { -+ if (tcp_opt_len || iph->ihl > 5) { -+ int tsflags; -+ -+ tsflags = (iph->ihl - 5) + (tcp_opt_len >> 2); -+ base_flags |= tsflags << 12; -+ } -+ } -+ } -+abort_lso: -+#else -+ mss = 0; -+#endif -+ -+ if (tg3_flag(tp, USE_JUMBO_BDFLAG) && -+ !mss && skb->len > VLAN_ETH_FRAME_LEN) -+ base_flags |= TXD_FLAG_JMB_PKT; -+ -+#ifdef BCM_KERNEL_SUPPORTS_8021Q -+ if (vlan_tx_tag_present(skb)) { -+ base_flags |= TXD_FLAG_VLAN; -+ vlan = vlan_tx_tag_get(skb); -+ } -+#endif -+ -+#ifdef BCM_KERNEL_SUPPORTS_TIMESTAMPING -+ if ((unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) && -+ tg3_flag(tp, TX_TSTAMP_EN)) { -+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; -+ base_flags |= TXD_FLAG_HWTSTAMP; -+ } -+#endif /* BCM_KERNEL_SUPPORTS_TIMESTAMPING */ -+ -+ len = skb_headlen(skb); -+ -+ mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE); -+ if (pci_dma_mapping_error_(tp->pdev, mapping)) -+ goto drop; -+ -+ -+ tnapi->tx_buffers[entry].skb = skb; -+ dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, mapping); -+ -+ would_hit_hwbug = 0; -+ -+ if (tg3_flag(tp, 5701_DMA_BUG)) -+ would_hit_hwbug = 1; -+ -+ if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, len, base_flags | -+ ((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0), -+ mss, vlan)) { -+ would_hit_hwbug = 1; -+ } else if (skb_shinfo(skb)->nr_frags > 0) { -+ u32 tmp_mss = mss; -+ -+ if (!tg3_flag(tp, HW_TSO_1) && -+ !tg3_flag(tp, HW_TSO_2) && -+ !tg3_flag(tp, HW_TSO_3)) -+ tmp_mss = 0; -+ -+ /* Now loop through additional data -+ * fragments, and queue them. -+ */ -+ last = skb_shinfo(skb)->nr_frags - 1; -+ for (i = 0; i <= last; i++) { -+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; -+ -+ len = skb_frag_size(frag); -+ mapping = skb_frag_dma_map(&tp->pdev->dev, frag, 0, -+ len, DMA_TO_DEVICE); -+ -+ tnapi->tx_buffers[entry].skb = NULL; -+ dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, -+ mapping); -+ if (dma_mapping_error_(&tp->pdev->dev, mapping)) -+ goto dma_error; -+ -+ if (!budget || -+ tg3_tx_frag_set(tnapi, &entry, &budget, mapping, -+ len, base_flags | -+ ((i == last) ? TXD_FLAG_END : 0), -+ tmp_mss, vlan)) { -+ would_hit_hwbug = 1; -+ break; -+ } -+ } -+ } -+ -+ if (would_hit_hwbug) { -+ tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i); -+ -+#if !defined(__VMKLNX__) -+ if (mss) { -+ /* If it's a TSO packet, do GSO instead of -+ * allocating and copying to a large linear SKB. -+ */ -+ if (ip_tot_len) { -+ iph->check = ip_csum; -+ iph->tot_len = ip_tot_len; -+ } -+ tcph->check = tcp_csum; -+ return tg3_tso_bug(tp, tnapi, txq, skb); -+ } -+#endif -+ -+ /* If the workaround fails due to memory/mapping -+ * failure, silently drop this packet. -+ */ -+ entry = tnapi->tx_prod; -+ budget = tg3_tx_avail(tnapi); -+ if (tigon3_dma_hwbug_workaround(tnapi, &skb, &entry, &budget, -+ base_flags, mss, vlan)) -+ goto drop_nofree; -+ } -+ -+ skb_tx_timestamp(skb); -+ netdev_tx_sent_queue(txq, skb->len); -+ -+ /* Sync BD data before updating mailbox */ -+ wmb(); -+ -+ /* Packets are ready, update Tx producer idx local and on card. */ -+ tw32_tx_mbox(tnapi->prodmbox, entry); -+ -+ tnapi->tx_prod = entry; -+ if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) { -+ netif_tx_stop_queue(txq); -+ -+ /* netif_tx_stop_queue() must be done before checking -+ * checking tx index in tg3_tx_avail() below, because in -+ * tg3_tx(), we update tx index before checking for -+ * netif_tx_queue_stopped(). -+ */ -+ smp_mb(); -+ if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)) -+ netif_tx_wake_queue(txq); -+ } -+ -+ mmiowb(); -+ -+ tg3_update_trans_start(dev); -+ -+ return NETDEV_TX_OK; -+ -+dma_error: -+ tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, --i); -+ tnapi->tx_buffers[tnapi->tx_prod].skb = NULL; -+drop: -+ dev_kfree_skb(skb); -+drop_nofree: -+ tp->tx_dropped++; -+ return NETDEV_TX_OK; -+} -+ -+static void tg3_mac_loopback(struct tg3 *tp, bool enable) -+{ -+ if (enable) { -+ tp->mac_mode &= ~(MAC_MODE_HALF_DUPLEX | -+ MAC_MODE_PORT_MODE_MASK); -+ -+ tp->mac_mode |= MAC_MODE_PORT_INT_LPBACK; -+ -+ if (!tg3_flag(tp, 5705_PLUS)) -+ tp->mac_mode |= MAC_MODE_LINK_POLARITY; -+ -+ if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) -+ tp->mac_mode |= MAC_MODE_PORT_MODE_MII; -+ else -+ tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; -+ } else { -+ tp->mac_mode &= ~MAC_MODE_PORT_INT_LPBACK; -+ -+ if (tg3_flag(tp, 5705_PLUS) || -+ (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) || -+ tg3_asic_rev(tp) == ASIC_REV_5700) -+ tp->mac_mode &= ~MAC_MODE_LINK_POLARITY; -+ } -+ -+ tw32(MAC_MODE, tp->mac_mode); -+ udelay(40); -+} -+ -+static int tg3_phy_lpbk_set(struct tg3 *tp, u32 speed, bool extlpbk) -+{ -+ u32 val, bmcr, mac_mode, ptest = 0; -+ -+ tg3_phy_toggle_apd(tp, false); -+ tg3_phy_toggle_automdix(tp, false); -+ -+ if (extlpbk && tg3_phy_set_extloopbk(tp)) -+ return -EIO; -+ -+ bmcr = BMCR_FULLDPLX; -+ switch (speed) { -+ case SPEED_10: -+ break; -+ case SPEED_100: -+ bmcr |= BMCR_SPEED100; -+ break; -+ case SPEED_1000: -+ default: -+ if (tp->phy_flags & TG3_PHYFLG_IS_FET) { -+ speed = SPEED_100; -+ bmcr |= BMCR_SPEED100; -+ } else { -+ speed = SPEED_1000; -+ bmcr |= BMCR_SPEED1000; -+ } -+ } -+ -+ if (extlpbk) { -+ if (!(tp->phy_flags & TG3_PHYFLG_IS_FET)) { -+ tg3_readphy(tp, MII_CTRL1000, &val); -+ val |= CTL1000_AS_MASTER | -+ CTL1000_ENABLE_MASTER; -+ tg3_writephy(tp, MII_CTRL1000, val); -+ } else { -+ ptest = MII_TG3_FET_PTEST_TRIM_SEL | -+ MII_TG3_FET_PTEST_TRIM_2; -+ tg3_writephy(tp, MII_TG3_FET_PTEST, ptest); -+ } -+ } else -+ bmcr |= BMCR_LOOPBACK; -+ -+ tg3_writephy(tp, MII_BMCR, bmcr); -+ -+ /* The write needs to be flushed for the FETs */ -+ if (tp->phy_flags & TG3_PHYFLG_IS_FET) -+ tg3_readphy(tp, MII_BMCR, &bmcr); -+ -+ udelay(40); -+ -+ if ((tp->phy_flags & TG3_PHYFLG_IS_FET) && -+ tg3_asic_rev(tp) == ASIC_REV_5785) { -+ tg3_writephy(tp, MII_TG3_FET_PTEST, ptest | -+ MII_TG3_FET_PTEST_FRC_TX_LINK | -+ MII_TG3_FET_PTEST_FRC_TX_LOCK); -+ -+ /* The write needs to be flushed for the AC131 */ -+ tg3_readphy(tp, MII_TG3_FET_PTEST, &val); -+ } -+ -+ /* Reset to prevent losing 1st rx packet intermittently */ -+ if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) && -+ tg3_flag(tp, 5780_CLASS)) { -+ tw32_f(MAC_RX_MODE, RX_MODE_RESET); -+ udelay(10); -+ tw32_f(MAC_RX_MODE, tp->rx_mode); -+ } -+ -+ mac_mode = tp->mac_mode & -+ ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX); -+ if (speed == SPEED_1000) -+ mac_mode |= MAC_MODE_PORT_MODE_GMII; -+ else -+ mac_mode |= MAC_MODE_PORT_MODE_MII; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5700) { -+ u32 masked_phy_id = tp->phy_id & TG3_PHY_ID_MASK; -+ -+ if (masked_phy_id == TG3_PHY_ID_BCM5401) -+ mac_mode &= ~MAC_MODE_LINK_POLARITY; -+ else if (masked_phy_id == TG3_PHY_ID_BCM5411) -+ mac_mode |= MAC_MODE_LINK_POLARITY; -+ -+ tg3_writephy(tp, MII_TG3_EXT_CTRL, -+ MII_TG3_EXT_CTRL_LNK3_LED_MODE); -+ } -+ -+ tw32(MAC_MODE, mac_mode); -+ udelay(40); -+ -+ return 0; -+} -+ -+#ifdef BCM_HAS_FIX_FEATURES -+static void tg3_set_loopback(struct net_device *dev, netdev_features_t features) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (features & NETIF_F_LOOPBACK) { -+ if (tp->mac_mode & MAC_MODE_PORT_INT_LPBACK) -+ return; -+ -+ spin_lock_bh(&tp->lock); -+ tg3_mac_loopback(tp, true); -+ netif_carrier_on(tp->dev); -+ spin_unlock_bh(&tp->lock); -+ netdev_info(dev, "Internal MAC loopback mode enabled.\n"); -+ } else { -+ if (!(tp->mac_mode & MAC_MODE_PORT_INT_LPBACK)) -+ return; -+ -+ spin_lock_bh(&tp->lock); -+ tg3_mac_loopback(tp, false); -+ /* Force link status check */ -+ tg3_setup_phy(tp, true); -+ spin_unlock_bh(&tp->lock); -+ netdev_info(dev, "Internal MAC loopback mode disabled.\n"); -+ } -+} -+ -+#if defined(GET_NETDEV_OP_EXT) -+static u32 tg3_fix_features(struct net_device *dev, u32 features) -+#else -+static netdev_features_t tg3_fix_features(struct net_device *dev, -+ netdev_features_t features) -+#endif -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (dev->mtu > ETH_DATA_LEN && tg3_flag(tp, 5780_CLASS)) -+ features &= ~NETIF_F_ALL_TSO; -+ -+ return features; -+} -+ -+#if defined(GET_NETDEV_OP_EXT) -+static int tg3_set_features(struct net_device *dev, u32 features) -+#else -+static int tg3_set_features(struct net_device *dev, netdev_features_t features) -+#endif -+{ -+ netdev_features_t changed = dev->features ^ features; -+ -+ if ((changed & NETIF_F_LOOPBACK) && netif_running(dev)) -+ tg3_set_loopback(dev, features); -+ -+ return 0; -+} -+#endif /* BCM_HAS_FIX_FEATURES */ -+ -+static void tg3_rx_prodring_free(struct tg3 *tp, -+ struct tg3_rx_prodring_set *tpr) -+{ -+ int i; -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (tg3_flag(tp, ENABLE_RSS)) -+#endif -+ if (tpr != &tp->napi[0].prodring) { -+ for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx; -+ i = (i + 1) & tp->rx_std_ring_mask) -+ tg3_rx_data_free(tp, &tpr->rx_std_buffers[i], -+ tp->rx_pkt_map_sz); -+ -+ if (tg3_flag(tp, JUMBO_CAPABLE)) { -+ for (i = tpr->rx_jmb_cons_idx; -+ i != tpr->rx_jmb_prod_idx; -+ i = (i + 1) & tp->rx_jmb_ring_mask) { -+ tg3_rx_data_free(tp, &tpr->rx_jmb_buffers[i], -+ TG3_RX_JMB_MAP_SZ); -+ } -+ } -+ -+ return; -+ } -+ -+ for (i = 0; i <= tp->rx_std_ring_mask; i++) -+ tg3_rx_data_free(tp, &tpr->rx_std_buffers[i], -+ tp->rx_pkt_map_sz); -+ -+ if (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS)) { -+ for (i = 0; i <= tp->rx_jmb_ring_mask; i++) -+ tg3_rx_data_free(tp, &tpr->rx_jmb_buffers[i], -+ TG3_RX_JMB_MAP_SZ); -+ } -+} -+ -+/* Initialize rx rings for packet processing. -+ * -+ * The chip has been shut down and the driver detached from -+ * the networking, so no interrupts or new tx packets will -+ * end up in the driver. tp->{tx,}lock are held and thus -+ * we may not sleep. -+ */ -+static int tg3_rx_prodring_alloc(struct tg3 *tp, -+ struct tg3_rx_prodring_set *tpr) -+{ -+ u32 i, rx_pkt_dma_sz; -+ -+ tpr->rx_std_cons_idx = 0; -+ tpr->rx_std_prod_idx = 0; -+ tpr->rx_jmb_cons_idx = 0; -+ tpr->rx_jmb_prod_idx = 0; -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (tg3_flag(tp, ENABLE_RSS)) -+#endif -+ if (tpr != &tp->napi[0].prodring) { -+ memset(&tpr->rx_std_buffers[0], 0, -+ TG3_RX_STD_BUFF_RING_SIZE(tp)); -+ if (tpr->rx_jmb_buffers) -+ memset(&tpr->rx_jmb_buffers[0], 0, -+ TG3_RX_JMB_BUFF_RING_SIZE(tp)); -+ goto done; -+ } -+ -+ /* Zero out all descriptors. */ -+ memset(tpr->rx_std, 0, TG3_RX_STD_RING_BYTES(tp)); -+ -+ rx_pkt_dma_sz = TG3_RX_STD_DMA_SZ; -+ if (tg3_flag(tp, 5780_CLASS) && -+ tp->dev->mtu > ETH_DATA_LEN) -+ rx_pkt_dma_sz = TG3_RX_JMB_DMA_SZ; -+ tp->rx_pkt_map_sz = TG3_RX_DMA_TO_MAP_SZ(rx_pkt_dma_sz); -+ -+ /* Initialize invariants of the rings, we only set this -+ * stuff once. This works because the card does not -+ * write into the rx buffer posting rings. -+ */ -+ for (i = 0; i <= tp->rx_std_ring_mask; i++) { -+ struct tg3_rx_buffer_desc *rxd; -+ -+ rxd = &tpr->rx_std[i]; -+ rxd->idx_len = rx_pkt_dma_sz << RXD_LEN_SHIFT; -+ rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT); -+ rxd->opaque = (RXD_OPAQUE_RING_STD | -+ (i << RXD_OPAQUE_INDEX_SHIFT)); -+ } -+ -+ /* Now allocate fresh SKBs for each rx ring. */ -+ for (i = 0; i < tp->rx_pending; i++) { -+ unsigned int frag_size; -+ -+ if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_STD, i, -+ &frag_size) < 0) { -+ netdev_warn(tp->dev, -+ "Using a smaller RX standard ring. Only " -+ "%d out of %d buffers were allocated " -+ "successfully\n", i, tp->rx_pending); -+ if (i == 0) -+ goto initfail; -+ tp->rx_pending = i; -+ break; -+ } -+ } -+ -+ if (!tg3_flag(tp, JUMBO_CAPABLE) || tg3_flag(tp, 5780_CLASS)) -+ goto done; -+ -+ memset(tpr->rx_jmb, 0, TG3_RX_JMB_RING_BYTES(tp)); -+ -+ if (!tg3_flag(tp, JUMBO_RING_ENABLE)) -+ goto done; -+ -+ for (i = 0; i <= tp->rx_jmb_ring_mask; i++) { -+ struct tg3_rx_buffer_desc *rxd; -+ -+ rxd = &tpr->rx_jmb[i].std; -+ rxd->idx_len = TG3_RX_JMB_DMA_SZ << RXD_LEN_SHIFT; -+ rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) | -+ RXD_FLAG_JUMBO; -+ rxd->opaque = (RXD_OPAQUE_RING_JUMBO | -+ (i << RXD_OPAQUE_INDEX_SHIFT)); -+ } -+ -+ for (i = 0; i < tp->rx_jumbo_pending; i++) { -+ unsigned int frag_size; -+ -+ if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_JUMBO, i, -+ &frag_size) < 0) { -+ netdev_warn(tp->dev, -+ "Using a smaller RX jumbo ring. Only %d " -+ "out of %d buffers were allocated " -+ "successfully\n", i, tp->rx_jumbo_pending); -+ if (i == 0) -+ goto initfail; -+ tp->rx_jumbo_pending = i; -+ break; -+ } -+ } -+ -+done: -+ return 0; -+ -+initfail: -+ tg3_rx_prodring_free(tp, tpr); -+ return -ENOMEM; -+} -+ -+static void tg3_rx_prodring_fini(struct tg3 *tp, -+ struct tg3_rx_prodring_set *tpr) -+{ -+ kfree(tpr->rx_std_buffers); -+ tpr->rx_std_buffers = NULL; -+ kfree(tpr->rx_jmb_buffers); -+ tpr->rx_jmb_buffers = NULL; -+ if (tpr->rx_std) { -+ dma_free_coherent(&tp->pdev->dev, TG3_RX_STD_RING_BYTES(tp), -+ tpr->rx_std, tpr->rx_std_mapping); -+ tpr->rx_std = NULL; -+ } -+ if (tpr->rx_jmb) { -+ dma_free_coherent(&tp->pdev->dev, TG3_RX_JMB_RING_BYTES(tp), -+ tpr->rx_jmb, tpr->rx_jmb_mapping); -+ tpr->rx_jmb = NULL; -+ } -+} -+ -+static int tg3_rx_prodring_init(struct tg3 *tp, -+ struct tg3_rx_prodring_set *tpr) -+{ -+ tpr->rx_std_buffers = kzalloc(TG3_RX_STD_BUFF_RING_SIZE(tp), -+ GFP_KERNEL); -+ if (!tpr->rx_std_buffers) -+ return -ENOMEM; -+ -+ tpr->rx_std = dma_alloc_coherent(&tp->pdev->dev, -+ TG3_RX_STD_RING_BYTES(tp), -+ &tpr->rx_std_mapping, -+ GFP_KERNEL); -+ if (!tpr->rx_std) -+ goto err_out; -+ -+ if (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS)) { -+ tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE(tp), -+ GFP_KERNEL); -+ if (!tpr->rx_jmb_buffers) -+ goto err_out; -+ -+ tpr->rx_jmb = dma_alloc_coherent(&tp->pdev->dev, -+ TG3_RX_JMB_RING_BYTES(tp), -+ &tpr->rx_jmb_mapping, -+ GFP_KERNEL); -+ if (!tpr->rx_jmb) -+ goto err_out; -+ } -+ -+ return 0; -+ -+err_out: -+ tg3_rx_prodring_fini(tp, tpr); -+ return -ENOMEM; -+} -+ -+/* Free up pending packets in all rx/tx rings. -+ * -+ * The chip has been shut down and the driver detached from -+ * the networking, so no interrupts or new tx packets will -+ * end up in the driver. tp->{tx,}lock is not held and we are not -+ * in an interrupt context and thus may sleep. -+ */ -+static void tg3_free_rings(struct tg3 *tp) -+{ -+ int i, j; -+ -+ for (j = 0; j < tp->irq_cnt; j++) { -+ struct tg3_napi *tnapi = &tp->napi[j]; -+ -+ tg3_rx_prodring_free(tp, &tnapi->prodring); -+ -+ if (!tnapi->tx_buffers) -+ continue; -+ -+ for (i = 0; i < TG3_TX_RING_SIZE; i++) { -+ struct sk_buff *skb = tnapi->tx_buffers[i].skb; -+ -+ if (!skb) -+ continue; -+ -+ tg3_tx_skb_unmap(tnapi, i, -+ skb_shinfo(skb)->nr_frags - 1); -+ -+ dev_kfree_skb_any(skb); -+ } -+ netdev_tx_reset_queue(netdev_get_tx_queue(tp->dev, j)); -+ } -+} -+ -+/* Initialize tx/rx rings for packet processing. -+ * -+ * The chip has been shut down and the driver detached from -+ * the networking, so no interrupts or new tx packets will -+ * end up in the driver. tp->{tx,}lock are held and thus -+ * we may not sleep. -+ */ -+static int tg3_init_rings(struct tg3 *tp) -+{ -+ int i; -+ -+ /* Free up all the SKBs. */ -+ tg3_free_rings(tp); -+ -+ for (i = 0; i < tp->irq_cnt; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ -+ tnapi->last_tag = 0; -+ tnapi->last_irq_tag = 0; -+ tnapi->hw_status->status = 0; -+ tnapi->hw_status->status_tag = 0; -+ memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE); -+ -+ tnapi->tx_prod = 0; -+ tnapi->tx_cons = 0; -+ if (tnapi->tx_ring) -+ memset(tnapi->tx_ring, 0, TG3_TX_RING_BYTES); -+ -+ tnapi->rx_rcb_ptr = 0; -+ if (tnapi->rx_rcb) -+ memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (!i || (i && tg3_flag(tp, ENABLE_RSS))) -+#endif -+ if (tg3_rx_prodring_alloc(tp, &tnapi->prodring)) { -+ tg3_free_rings(tp); -+ return -ENOMEM; -+ } -+ } -+ -+ return 0; -+} -+ -+static void tg3_mem_tx_release(struct tg3 *tp) -+{ -+ int i; -+ -+ for (i = 0; i < tp->irq_max; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ -+ if (tnapi->tx_ring) { -+ dma_free_coherent(&tp->pdev->dev, TG3_TX_RING_BYTES, -+ tnapi->tx_ring, tnapi->tx_desc_mapping); -+ tnapi->tx_ring = NULL; -+ } -+ -+ kfree(tnapi->tx_buffers); -+ tnapi->tx_buffers = NULL; -+ } -+} -+ -+static int tg3_mem_tx_acquire(struct tg3 *tp) -+{ -+ int i; -+ struct tg3_napi *tnapi = &tp->napi[0]; -+ -+ /* If multivector TSS is enabled, vector 0 does not handle -+ * tx interrupts. Don't allocate any resources for it. -+ */ -+ if (tg3_flag(tp, ENABLE_TSS)) -+ tnapi++; -+ -+ for (i = 0; i < tp->txq_cnt; i++, tnapi++) { -+ tnapi->tx_buffers = kzalloc(sizeof(struct tg3_tx_ring_info) * -+ TG3_TX_RING_SIZE, GFP_KERNEL); -+ if (!tnapi->tx_buffers) -+ goto err_out; -+ -+ tnapi->tx_ring = dma_alloc_coherent(&tp->pdev->dev, -+ TG3_TX_RING_BYTES, -+ &tnapi->tx_desc_mapping, -+ GFP_KERNEL); -+ if (!tnapi->tx_ring) -+ goto err_out; -+ } -+ -+ return 0; -+ -+err_out: -+ tg3_mem_tx_release(tp); -+ return -ENOMEM; -+} -+ -+static void tg3_mem_rx_release(struct tg3 *tp) -+{ -+ int i; -+ -+ for (i = 0; i < tp->irq_max; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ -+ tg3_rx_prodring_fini(tp, &tnapi->prodring); -+ -+ if (!tnapi->rx_rcb) -+ continue; -+ -+ dma_free_coherent(&tp->pdev->dev, -+ TG3_RX_RCB_RING_BYTES(tp), -+ tnapi->rx_rcb, -+ tnapi->rx_rcb_mapping); -+ tnapi->rx_rcb = NULL; -+ } -+} -+ -+static int tg3_mem_rx_acquire(struct tg3 *tp) -+{ -+ unsigned int i, limit; -+ -+ limit = tp->rxq_cnt; -+ -+ /* If RSS is enabled, we need a (dummy) producer ring -+ * set on vector zero. This is the true hw prodring. -+ */ -+ if (tg3_flag(tp, ENABLE_RSS)) -+ limit++; -+ -+ for (i = 0; i < limit; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ -+ if (tg3_rx_prodring_init(tp, &tnapi->prodring)) -+ goto err_out; -+ -+ if (tg3_flag(tp, ENABLE_IOV)) -+ tnapi->srcprodring = &tnapi->prodring; -+ else -+ tnapi->srcprodring = &tp->napi[0].prodring; -+ -+ /* If multivector RSS is enabled, vector 0 -+ * does not handle rx or tx interrupts. -+ * Don't allocate any resources for it. -+ */ -+ if (!i && tg3_flag(tp, ENABLE_RSS)) -+ continue; -+ -+ tnapi->rx_rcb = dma_zalloc_coherent(&tp->pdev->dev, -+ TG3_RX_RCB_RING_BYTES(tp), -+ &tnapi->rx_rcb_mapping, -+ GFP_KERNEL); -+ if (!tnapi->rx_rcb) -+ goto err_out; -+ } -+ -+ return 0; -+ -+err_out: -+ tg3_mem_rx_release(tp); -+ return -ENOMEM; -+} -+ -+/* -+ * Must not be invoked with interrupt sources disabled and -+ * the hardware shutdown down. -+ */ -+static void tg3_free_consistent(struct tg3 *tp) -+{ -+ int i; -+ -+ for (i = 0; i < tp->irq_cnt; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ -+ if (tnapi->hw_status) { -+ dma_free_coherent(&tp->pdev->dev, TG3_HW_STATUS_SIZE, -+ tnapi->hw_status, -+ tnapi->status_mapping); -+ tnapi->hw_status = NULL; -+ } -+ } -+ -+ tg3_mem_rx_release(tp); -+ tg3_mem_tx_release(tp); -+ -+ if (tp->hw_stats) { -+ dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats), -+ tp->hw_stats, tp->stats_mapping); -+ tp->hw_stats = NULL; -+ } -+} -+ -+/* -+ * Must not be invoked with interrupt sources disabled and -+ * the hardware shutdown down. Can sleep. -+ */ -+static int tg3_alloc_consistent(struct tg3 *tp) -+{ -+ int i; -+ -+ tp->hw_stats = dma_zalloc_coherent(&tp->pdev->dev, -+ sizeof(struct tg3_hw_stats), -+ &tp->stats_mapping, GFP_KERNEL); -+ if (!tp->hw_stats) -+ goto err_out; -+ -+ for (i = 0; i < tp->irq_cnt; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ struct tg3_hw_status *sblk; -+ -+ tnapi->hw_status = dma_zalloc_coherent(&tp->pdev->dev, -+ TG3_HW_STATUS_SIZE, -+ &tnapi->status_mapping, -+ GFP_KERNEL); -+ if (!tnapi->hw_status) -+ goto err_out; -+ -+ sblk = tnapi->hw_status; -+ -+ if (tg3_flag(tp, ENABLE_RSS)) { -+ volatile u16 *prodptr = NULL; -+ -+ /* When RSS is enabled, the status block format changes -+ * slightly. The "rx_jumbo_consumer", "reserved", -+ * and "rx_mini_consumer" members get mapped to the -+ * other three rx return ring producer indexes. -+ */ -+ switch (i) { -+ case 1: -+ prodptr = &sblk->idx[0].rx_producer; -+ break; -+ case 2: -+ prodptr = &sblk->rx_jumbo_consumer; -+ break; -+ case 3: -+ prodptr = &sblk->reserved; -+ break; -+ case 4: -+ prodptr = &sblk->rx_mini_consumer; -+ break; -+ } -+ tnapi->rx_rcb_prod_idx = prodptr; -+ } else -+ tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer; -+ } -+ -+ if (tg3_mem_tx_acquire(tp) || tg3_mem_rx_acquire(tp)) -+ goto err_out; -+ -+ return 0; -+ -+err_out: -+ tg3_free_consistent(tp); -+ return -ENOMEM; -+} -+ -+#define MAX_WAIT_CNT 1000 -+ -+/* To stop a block, clear the enable bit and poll till it -+ * clears. tp->lock is held. -+ */ -+static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, bool silent) -+{ -+ unsigned int i; -+ u32 val; -+ -+ if (tg3_flag(tp, 5705_PLUS)) { -+ switch (ofs) { -+ case RCVLSC_MODE: -+ case DMAC_MODE: -+ case MBFREE_MODE: -+ case BUFMGR_MODE: -+ case MEMARB_MODE: -+ /* We can't enable/disable these bits of the -+ * 5705/5750, just say success. -+ */ -+ return 0; -+ -+ default: -+ break; -+ } -+ } -+ -+ val = tr32(ofs); -+ val &= ~enable_bit; -+ tw32_f(ofs, val); -+ -+ for (i = 0; i < MAX_WAIT_CNT; i++) { -+ if (pci_channel_offline(tp->pdev)) { -+ dev_err(&tp->pdev->dev, -+ "tg3_stop_block device offline, " -+ "ofs=%lx enable_bit=%x\n", -+ ofs, enable_bit); -+ return -ENODEV; -+ } -+ -+ udelay(100); -+ val = tr32(ofs); -+ if ((val & enable_bit) == 0) -+ break; -+ } -+ -+ if (i == MAX_WAIT_CNT && !silent) { -+ dev_err(&tp->pdev->dev, -+ "tg3_stop_block timed out, ofs=%lx enable_bit=%x\n", -+ ofs, enable_bit); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+/* tp->lock is held. */ -+static int tg3_abort_hw(struct tg3 *tp, bool silent) -+{ -+ int i, err; -+ -+ tg3_disable_ints(tp); -+ -+ if (pci_channel_offline(tp->pdev)) { -+ tp->rx_mode &= ~(RX_MODE_ENABLE | TX_MODE_ENABLE); -+ tp->mac_mode &= ~MAC_MODE_TDE_ENABLE; -+ err = -ENODEV; -+ goto err_no_dev; -+ } -+ -+ tp->rx_mode &= ~RX_MODE_ENABLE; -+ tw32_f(MAC_RX_MODE, tp->rx_mode); -+ udelay(10); -+ -+ err = tg3_stop_block(tp, RCVBDI_MODE, RCVBDI_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, RCVLPC_MODE, RCVLPC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, RCVLSC_MODE, RCVLSC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, RCVDBDI_MODE, RCVDBDI_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, RCVDCC_MODE, RCVDCC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, RCVCC_MODE, RCVCC_MODE_ENABLE, silent); -+ -+ err |= tg3_stop_block(tp, SNDBDS_MODE, SNDBDS_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, SNDBDI_MODE, SNDBDI_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, SNDDATAI_MODE, SNDDATAI_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, RDMAC_MODE, RDMAC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, SNDDATAC_MODE, SNDDATAC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, DMAC_MODE, DMAC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, SNDBDC_MODE, SNDBDC_MODE_ENABLE, silent); -+ -+ tp->mac_mode &= ~MAC_MODE_TDE_ENABLE; -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ -+ tp->tx_mode &= ~TX_MODE_ENABLE; -+ tw32_f(MAC_TX_MODE, tp->tx_mode); -+ -+ for (i = 0; i < MAX_WAIT_CNT; i++) { -+ udelay(100); -+ if (!(tr32(MAC_TX_MODE) & TX_MODE_ENABLE)) -+ break; -+ } -+ if (i >= MAX_WAIT_CNT) { -+ dev_err(&tp->pdev->dev, -+ "%s timed out, TX_MODE_ENABLE will not clear " -+ "MAC_TX_MODE=%08x\n", __func__, tr32(MAC_TX_MODE)); -+ err |= -ENODEV; -+ } -+ -+ err |= tg3_stop_block(tp, HOSTCC_MODE, HOSTCC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, WDMAC_MODE, WDMAC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, MBFREE_MODE, MBFREE_MODE_ENABLE, silent); -+ -+ tw32(FTQ_RESET, 0xffffffff); -+ tw32(FTQ_RESET, 0x00000000); -+ -+ err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent); -+ -+err_no_dev: -+ for (i = 0; i < tp->irq_cnt; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ if (tnapi->hw_status) -+ memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE); -+ } -+ -+ return err; -+} -+ -+/* Save PCI command register before chip reset */ -+static void tg3_save_pci_state(struct tg3 *tp) -+{ -+ pci_read_config_word(tp->pdev, PCI_COMMAND, &tp->pci_cmd); -+} -+ -+/* Restore PCI state after chip reset */ -+static void tg3_restore_pci_state(struct tg3 *tp) -+{ -+ u32 val; -+ -+ /* Re-enable indirect register accesses. */ -+ pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, -+ tp->misc_host_ctrl); -+ -+ /* Set MAX PCI retry to zero. */ -+ val = (PCISTATE_ROM_ENABLE | PCISTATE_ROM_RETRY_ENABLE); -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5704_A0 && -+ tg3_flag(tp, PCIX_MODE)) -+ val |= PCISTATE_RETRY_SAME_DMA; -+ /* Allow reads and writes to the APE register and memory space. */ -+ if (tg3_flag(tp, ENABLE_APE)) -+ val |= PCISTATE_ALLOW_APE_CTLSPC_WR | -+ PCISTATE_ALLOW_APE_SHMEM_WR | -+ PCISTATE_ALLOW_APE_PSPACE_WR; -+ pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, val); -+ -+ pci_write_config_word(tp->pdev, PCI_COMMAND, tp->pci_cmd); -+ -+ if (!tg3_flag(tp, PCI_EXPRESS)) { -+ pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, -+ tp->pci_cacheline_sz); -+ pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER, -+ tp->pci_lat_timer); -+ } -+ -+ /* Make sure PCI-X relaxed ordering bit is clear. */ -+ if (tg3_flag(tp, PCIX_MODE)) { -+ u16 pcix_cmd; -+ -+ pci_read_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD, -+ &pcix_cmd); -+ pcix_cmd &= ~PCI_X_CMD_ERO; -+ pci_write_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD, -+ pcix_cmd); -+ } -+ -+ if (tg3_flag(tp, 5780_CLASS)) { -+ -+ /* Chip reset on 5780 will reset MSI enable bit, -+ * so need to restore it. -+ */ -+ if (tg3_flag(tp, USING_MSI)) { -+ u16 ctrl; -+ -+ pci_read_config_word(tp->pdev, -+ tp->msi_cap + PCI_MSI_FLAGS, -+ &ctrl); -+ pci_write_config_word(tp->pdev, -+ tp->msi_cap + PCI_MSI_FLAGS, -+ ctrl | PCI_MSI_FLAGS_ENABLE); -+ val = tr32(MSGINT_MODE); -+ tw32(MSGINT_MODE, val | MSGINT_MODE_ENABLE); -+ } -+ } -+ -+ tg3_disable_ints(tp); -+} -+ -+static void tg3_override_clk(struct tg3 *tp) -+{ -+ u32 val; -+ -+ switch (tg3_asic_rev(tp)) { -+ case ASIC_REV_5717: -+ val = tr32(TG3_CPMU_CLCK_ORIDE_ENABLE); -+ tw32(TG3_CPMU_CLCK_ORIDE_ENABLE, val | -+ TG3_CPMU_MAC_ORIDE_ENABLE); -+ break; -+ -+ case ASIC_REV_5719: -+ case ASIC_REV_5720: -+ tw32(TG3_CPMU_CLCK_ORIDE, CPMU_CLCK_ORIDE_MAC_ORIDE_EN); -+ break; -+ -+ default: -+ return; -+ } -+} -+ -+static void tg3_restore_clk(struct tg3 *tp) -+{ -+ u32 val; -+ -+ switch (tg3_asic_rev(tp)) { -+ case ASIC_REV_5717: -+ val = tr32(TG3_CPMU_CLCK_ORIDE_ENABLE); -+ tw32(TG3_CPMU_CLCK_ORIDE_ENABLE, -+ val & ~TG3_CPMU_MAC_ORIDE_ENABLE); -+ break; -+ -+ case ASIC_REV_5719: -+ case ASIC_REV_5720: -+ val = tr32(TG3_CPMU_CLCK_ORIDE); -+ tw32(TG3_CPMU_CLCK_ORIDE, val & ~CPMU_CLCK_ORIDE_MAC_ORIDE_EN); -+ break; -+ -+ default: -+ return; -+ } -+} -+ -+/* tp->lock is held. */ -+static int tg3_chip_reset(struct tg3 *tp) -+{ -+ u32 val; -+ void (*write_op)(struct tg3 *, u32, u32); -+ int i, err; -+ -+ if (!pci_device_is_present(tp->pdev)) -+ return -ENODEV; -+ -+ tg3_nvram_lock(tp); -+ -+ tg3_ape_lock(tp, TG3_APE_LOCK_GRC); -+ -+ /* No matching tg3_nvram_unlock() after this because -+ * chip reset below will undo the nvram lock. -+ */ -+ tp->nvram_lock_cnt = 0; -+ -+ /* GRC_MISC_CFG core clock reset will clear the memory -+ * enable bit in PCI register 4 and the MSI enable bit -+ * on some chips, so we save relevant registers here. -+ */ -+ tg3_save_pci_state(tp); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5752 || -+ tg3_flag(tp, 5755_PLUS)) -+ tw32(GRC_FASTBOOT_PC, 0); -+ -+ /* -+ * We must avoid the readl() that normally takes place. -+ * It locks machines, causes machine checks, and other -+ * fun things. So, temporarily disable the 5701 -+ * hardware workaround, while we do the reset. -+ */ -+ write_op = tp->write32; -+ if (write_op == tg3_write_flush_reg32) -+ tp->write32 = tg3_write32; -+ -+ /* Prevent the irq handler from reading or writing PCI registers -+ * during chip reset when the memory enable bit in the PCI command -+ * register may be cleared. The chip does not generate interrupt -+ * at this time, but the irq handler may still be called due to irq -+ * sharing or irqpoll. -+ */ -+ tg3_flag_set(tp, CHIP_RESETTING); -+ for (i = 0; i < tp->irq_cnt; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ if (tnapi->hw_status) { -+ tnapi->hw_status->status = 0; -+ tnapi->hw_status->status_tag = 0; -+ } -+ tnapi->last_tag = 0; -+ tnapi->last_irq_tag = 0; -+ } -+ smp_mb(); -+ -+#if (LINUX_VERSION_CODE >= 0x2051c) -+ for (i = 0; i < tp->irq_cnt; i++) -+ synchronize_irq(tp->napi[i].irq_vec); -+#else -+ synchronize_irq(); -+#endif -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_57780) { -+ val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN; -+ tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS); -+ } -+ -+ /* do the reset */ -+ val = GRC_MISC_CFG_CORECLK_RESET; -+ -+ if (tg3_flag(tp, PCI_EXPRESS)) { -+ /* Force PCIe 1.0a mode */ -+ if (tg3_asic_rev(tp) != ASIC_REV_5785 && -+ !tg3_flag(tp, 57765_PLUS) && -+ tr32(TG3_PCIE_PHY_TSTCTL) == -+ (TG3_PCIE_PHY_TSTCTL_PCIE10 | TG3_PCIE_PHY_TSTCTL_PSCRAM)) -+ tw32(TG3_PCIE_PHY_TSTCTL, TG3_PCIE_PHY_TSTCTL_PSCRAM); -+ -+ if (tg3_chip_rev_id(tp) != CHIPREV_ID_5750_A0) { -+ tw32(GRC_MISC_CFG, (1 << 29)); -+ val |= (1 << 29); -+ } -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5906) { -+ tw32(VCPU_STATUS, tr32(VCPU_STATUS) | VCPU_STATUS_DRV_RESET); -+ tw32(GRC_VCPU_EXT_CTRL, -+ tr32(GRC_VCPU_EXT_CTRL) & ~GRC_VCPU_EXT_CTRL_HALT_CPU); -+ } -+ -+ /* Set the clock to the highest frequency to avoid timeouts. With link -+ * aware mode, the clock speed could be slow and bootcode does not -+ * complete within the expected time. Override the clock to allow the -+ * bootcode to finish sooner and then restore it. A later bootcode will -+ * implement this workaround at which time this change must be removed -+ * from the driver. -+ */ -+ tg3_override_clk(tp); -+ -+ /* Manage gphy power for all CPMU absent PCIe devices. */ -+ if (tg3_flag(tp, 5705_PLUS) && !tg3_flag(tp, CPMU_PRESENT)) -+ val |= GRC_MISC_CFG_KEEP_GPHY_POWER; -+ -+ tw32(GRC_MISC_CFG, val); -+ -+ /* restore 5701 hardware bug workaround write method */ -+ tp->write32 = write_op; -+ -+ /* Unfortunately, we have to delay before the PCI read back. -+ * Some 575X chips even will not respond to a PCI cfg access -+ * when the reset command is given to the chip. -+ * -+ * How do these hardware designers expect things to work -+ * properly if the PCI write is posted for a long period -+ * of time? It is always necessary to have some method by -+ * which a register read back can occur to push the write -+ * out which does the reset. -+ * -+ * For most tg3 variants the trick below was working. -+ * Ho hum... -+ */ -+ udelay(120); -+ -+ /* Flush PCI posted writes. The normal MMIO registers -+ * are inaccessible at this time so this is the only -+ * way to make this reliably (actually, this is no longer -+ * the case, see above). I tried to use indirect -+ * register read/write but this upset some 5701 variants. -+ */ -+ pci_read_config_dword(tp->pdev, PCI_COMMAND, &val); -+ -+ udelay(120); -+ -+ if (tg3_flag(tp, PCI_EXPRESS) && pci_is_pcie(tp->pdev)) { -+ u16 val16; -+ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5750_A0) { -+ int j; -+ u32 cfg_val; -+ -+ /* Wait for link training to complete. */ -+ for (j = 0; j < 5000; j++) -+ udelay(100); -+ -+ pci_read_config_dword(tp->pdev, 0xc4, &cfg_val); -+ pci_write_config_dword(tp->pdev, 0xc4, -+ cfg_val | (1 << 15)); -+ } -+ -+ /* Clear the "no snoop" and "relaxed ordering" bits. */ -+ val16 = PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN; -+ /* -+ * Older PCIe devices only support the 128 byte -+ * MPS setting. Enforce the restriction. -+ */ -+ if (!tg3_flag(tp, CPMU_PRESENT)) -+ val16 |= PCI_EXP_DEVCTL_PAYLOAD; -+ pcie_capability_clear_word(tp->pdev, PCI_EXP_DEVCTL, val16); -+ -+ /* Clear error status */ -+ pcie_capability_write_word(tp->pdev, PCI_EXP_DEVSTA, -+ PCI_EXP_DEVSTA_CED | -+ PCI_EXP_DEVSTA_NFED | -+ PCI_EXP_DEVSTA_FED | -+ PCI_EXP_DEVSTA_URD); -+ } -+ -+ tg3_restore_pci_state(tp); -+ -+ tg3_flag_clear(tp, CHIP_RESETTING); -+ tg3_flag_clear(tp, ERROR_PROCESSED); -+ -+ val = 0; -+ if (tg3_flag(tp, 5780_CLASS)) -+ val = tr32(MEMARB_MODE); -+ tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE); -+ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5750_A3) { -+ tg3_stop_fw(tp); -+ tw32(0x5000, 0x400); -+ } -+ -+ if (tg3_flag(tp, IS_SSB_CORE)) { -+ /* -+ * BCM4785: In order to avoid repercussions from using -+ * potentially defective internal ROM, stop the Rx RISC CPU, -+ * which is not required. -+ */ -+ tg3_stop_fw(tp); -+ tg3_halt_cpu(tp, RX_CPU_BASE); -+ } -+ -+ err = tg3_poll_fw(tp); -+ if (err) -+ return err; -+ -+ tw32(GRC_MODE, tp->grc_mode); -+ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5705_A0) { -+ val = tr32(0xc4); -+ -+ tw32(0xc4, val | (1 << 15)); -+ } -+ -+ if ((tp->nic_sram_data_cfg & NIC_SRAM_DATA_CFG_MINI_PCI) != 0 && -+ tg3_asic_rev(tp) == ASIC_REV_5705) { -+ tp->pci_clock_ctrl |= CLOCK_CTRL_CLKRUN_OENABLE; -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5705_A0) -+ tp->pci_clock_ctrl |= CLOCK_CTRL_FORCE_CLKRUN; -+ tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); -+ } -+ -+ if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { -+ tp->mac_mode = MAC_MODE_PORT_MODE_TBI; -+ val = tp->mac_mode; -+ } else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) { -+ tp->mac_mode = MAC_MODE_PORT_MODE_GMII; -+ val = tp->mac_mode; -+ } else -+ val = 0; -+ -+ tw32_f(MAC_MODE, val); -+ udelay(40); -+ -+ tg3_ape_unlock(tp, TG3_APE_LOCK_GRC); -+ -+ tg3_mdio_start(tp); -+ -+ if (tg3_flag(tp, PCI_EXPRESS) && -+ tg3_chip_rev_id(tp) != CHIPREV_ID_5750_A0 && -+ tg3_asic_rev(tp) != ASIC_REV_5785 && -+ !tg3_flag(tp, 57765_PLUS)) { -+ val = tr32(0x7c00); -+ -+ tw32(0x7c00, val | (1 << 25)); -+ } -+ -+ tg3_restore_clk(tp); -+ -+ /* Reprobe ASF enable state. */ -+ tg3_flag_clear(tp, ENABLE_ASF); -+ tp->phy_flags &= ~(TG3_PHYFLG_1G_ON_VAUX_OK | -+ TG3_PHYFLG_KEEP_LINK_ON_PWRDN); -+ -+ tg3_flag_clear(tp, ASF_NEW_HANDSHAKE); -+ tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); -+ if (val == NIC_SRAM_DATA_SIG_MAGIC) { -+ u32 nic_cfg; -+ -+ tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); -+ if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { -+ tg3_flag_set(tp, ENABLE_ASF); -+ tp->last_event_jiffies = jiffies; -+ if (tg3_flag(tp, 5750_PLUS)) -+ tg3_flag_set(tp, ASF_NEW_HANDSHAKE); -+ -+ tg3_read_mem(tp, NIC_SRAM_DATA_CFG_3, &nic_cfg); -+ if (nic_cfg & NIC_SRAM_1G_ON_VAUX_OK) -+ tp->phy_flags |= TG3_PHYFLG_1G_ON_VAUX_OK; -+ if (nic_cfg & NIC_SRAM_LNK_FLAP_AVOID) -+ tp->phy_flags |= TG3_PHYFLG_KEEP_LINK_ON_PWRDN; -+ } -+ } -+ -+ return 0; -+} -+ -+static void tg3_get_nstats(struct tg3 *, struct rtnl_link_stats64 *); -+static void tg3_get_estats(struct tg3 *, struct tg3_ethtool_stats *); -+static void __tg3_set_rx_mode(struct net_device *); -+ -+/* tp->lock is held. */ -+static int tg3_halt(struct tg3 *tp, int kind, bool silent) -+{ -+ int err; -+ -+ tg3_stop_fw(tp); -+ -+ tg3_write_sig_pre_reset(tp, kind); -+ -+ tg3_abort_hw(tp, silent); -+ err = tg3_chip_reset(tp); -+ -+ __tg3_set_mac_addr(tp, false); -+ -+ tg3_write_sig_legacy(tp, kind); -+ tg3_write_sig_post_reset(tp, kind); -+ -+ if (tp->hw_stats) { -+ /* Save the stats across chip resets... */ -+ tg3_get_nstats(tp, &tp->net_stats_prev); -+ tg3_get_estats(tp, &tp->estats_prev); -+ -+ /* And make sure the next sample is new data */ -+ memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); -+ } -+ -+ return err; -+} -+ -+static int tg3_set_mac_addr(struct net_device *dev, void *p) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ struct sockaddr *addr = p; -+ int err = 0; -+ bool skip_mac_1 = false; -+ -+ if (!is_valid_ether_addr(addr->sa_data)) -+ return -EADDRNOTAVAIL; -+ -+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); -+ -+ if (!netif_running(dev)) -+ return 0; -+ -+ if (tg3_flag(tp, ENABLE_ASF)) { -+ u32 addr0_high, addr0_low, addr1_high, addr1_low; -+ -+ addr0_high = tr32(MAC_ADDR_0_HIGH); -+ addr0_low = tr32(MAC_ADDR_0_LOW); -+ addr1_high = tr32(MAC_ADDR_1_HIGH); -+ addr1_low = tr32(MAC_ADDR_1_LOW); -+ -+ /* Skip MAC addr 1 if ASF is using it. */ -+ if ((addr0_high != addr1_high || addr0_low != addr1_low) && -+ !(addr1_high == 0 && addr1_low == 0)) -+ skip_mac_1 = true; -+ } -+ spin_lock_bh(&tp->lock); -+ __tg3_set_mac_addr(tp, skip_mac_1); -+ __tg3_set_rx_mode(dev); -+ spin_unlock_bh(&tp->lock); -+ -+ return err; -+} -+ -+/* tp->lock is held. */ -+static void tg3_set_bdinfo(struct tg3 *tp, u32 bdinfo_addr, -+ dma_addr_t mapping, u32 maxlen_flags, -+ u32 nic_addr) -+{ -+ tg3_write_mem(tp, -+ (bdinfo_addr + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH), -+ ((u64) mapping >> 32)); -+ tg3_write_mem(tp, -+ (bdinfo_addr + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW), -+ ((u64) mapping & 0xffffffff)); -+ tg3_write_mem(tp, -+ (bdinfo_addr + TG3_BDINFO_MAXLEN_FLAGS), -+ maxlen_flags); -+ -+ if (!tg3_flag(tp, 5705_PLUS)) -+ tg3_write_mem(tp, -+ (bdinfo_addr + TG3_BDINFO_NIC_ADDR), -+ nic_addr); -+} -+ -+static void tg3_coal_tx_init(struct tg3 *tp, struct ethtool_coalesce *ec) -+{ -+ int i = 0; -+ -+ if (!tg3_flag(tp, ENABLE_TSS)) { -+ tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs); -+ tw32(HOSTCC_TXMAX_FRAMES, ec->tx_max_coalesced_frames); -+ tw32(HOSTCC_TXCOAL_MAXF_INT, ec->tx_max_coalesced_frames_irq); -+ } else { -+ tw32(HOSTCC_TXCOL_TICKS, 0); -+ tw32(HOSTCC_TXMAX_FRAMES, 0); -+ tw32(HOSTCC_TXCOAL_MAXF_INT, 0); -+ -+ for (; i < tp->txq_cnt; i++) { -+ u32 reg; -+ -+ reg = HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18; -+ tw32(reg, ec->tx_coalesce_usecs); -+ reg = HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18; -+ tw32(reg, ec->tx_max_coalesced_frames); -+ reg = HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18; -+ tw32(reg, ec->tx_max_coalesced_frames_irq); -+ } -+ } -+ -+ for (; i < tp->irq_max - 1; i++) { -+ tw32(HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18, 0); -+ tw32(HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18, 0); -+ tw32(HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18, 0); -+ } -+} -+ -+static void tg3_coal_rx_init(struct tg3 *tp, struct ethtool_coalesce *ec) -+{ -+ int i = 0; -+ u32 limit = tp->rxq_cnt; -+ -+ if (!tg3_flag(tp, ENABLE_RSS)) { -+ tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs); -+ tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames); -+ tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq); -+ limit--; -+ } else { -+ tw32(HOSTCC_RXCOL_TICKS, 0); -+ tw32(HOSTCC_RXMAX_FRAMES, 0); -+ tw32(HOSTCC_RXCOAL_MAXF_INT, 0); -+ } -+ -+ for (; i < limit; i++) { -+ u32 reg; -+ -+ reg = HOSTCC_RXCOL_TICKS_VEC1 + i * 0x18; -+ tw32(reg, ec->rx_coalesce_usecs); -+ reg = HOSTCC_RXMAX_FRAMES_VEC1 + i * 0x18; -+ tw32(reg, ec->rx_max_coalesced_frames); -+ reg = HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18; -+ tw32(reg, ec->rx_max_coalesced_frames_irq); -+ } -+ -+ for (; i < tp->irq_max - 1; i++) { -+ tw32(HOSTCC_RXCOL_TICKS_VEC1 + i * 0x18, 0); -+ tw32(HOSTCC_RXMAX_FRAMES_VEC1 + i * 0x18, 0); -+ tw32(HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18, 0); -+ } -+} -+ -+static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec) -+{ -+ tg3_coal_tx_init(tp, ec); -+ tg3_coal_rx_init(tp, ec); -+ -+ if (!tg3_flag(tp, 5705_PLUS)) { -+ u32 val = ec->stats_block_coalesce_usecs; -+ -+ tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq); -+ tw32(HOSTCC_TXCOAL_TICK_INT, ec->tx_coalesce_usecs_irq); -+ -+ if (!tp->link_up) -+ val = 0; -+ -+ tw32(HOSTCC_STAT_COAL_TICKS, val); -+ } -+} -+ -+/* tp->lock is held. */ -+static void tg3_tx_rcbs_disable(struct tg3 *tp) -+{ -+ u32 txrcb, limit; -+ -+ /* Disable all transmit rings but the first. */ -+ if (!tg3_flag(tp, 5705_PLUS)) -+ limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 16; -+ else if (tg3_flag(tp, 5717_PLUS)) -+ limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 4; -+ else if (tg3_flag(tp, 57765_CLASS) || -+ tg3_asic_rev(tp) == ASIC_REV_5762) -+ limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 2; -+ else -+ limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE; -+ -+ for (txrcb = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE; -+ txrcb < limit; txrcb += TG3_BDINFO_SIZE) -+ tg3_write_mem(tp, txrcb + TG3_BDINFO_MAXLEN_FLAGS, -+ BDINFO_FLAGS_DISABLED); -+} -+ -+/* tp->lock is held. */ -+static void tg3_tx_rcbs_init(struct tg3 *tp) -+{ -+ int i = 0; -+ u32 txrcb = NIC_SRAM_SEND_RCB; -+ -+ if (tg3_flag(tp, ENABLE_TSS)) -+ i++; -+ -+ for (; i < tp->irq_max; i++, txrcb += TG3_BDINFO_SIZE) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ -+ if (!tnapi->tx_ring) -+ continue; -+ -+ tg3_set_bdinfo(tp, txrcb, tnapi->tx_desc_mapping, -+ (TG3_TX_RING_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT), -+ NIC_SRAM_TX_BUFFER_DESC); -+ } -+} -+ -+/* tp->lock is held. */ -+static void tg3_rx_ret_rcbs_disable(struct tg3 *tp) -+{ -+ u32 rxrcb, limit; -+ -+ /* Disable all receive return rings but the first. */ -+ if (tg3_flag(tp, 5717_PLUS)) -+ limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 17; -+ else if (!tg3_flag(tp, 5705_PLUS)) -+ limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 16; -+ else if (tg3_asic_rev(tp) == ASIC_REV_5755 || -+ tg3_asic_rev(tp) == ASIC_REV_5762 || -+ tg3_flag(tp, 57765_CLASS)) -+ limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 4; -+ else -+ limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE; -+ -+ for (rxrcb = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE; -+ rxrcb < limit; rxrcb += TG3_BDINFO_SIZE) -+ tg3_write_mem(tp, rxrcb + TG3_BDINFO_MAXLEN_FLAGS, -+ BDINFO_FLAGS_DISABLED); -+} -+ -+/* tp->lock is held. */ -+static void tg3_rx_ret_rcbs_init(struct tg3 *tp) -+{ -+ int i = 0; -+ u32 rxrcb = NIC_SRAM_RCV_RET_RCB; -+ -+ if (tg3_flag(tp, ENABLE_RSS)) -+ i++; -+ -+ for (; i < tp->irq_max; i++, rxrcb += TG3_BDINFO_SIZE) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ -+ if (!tnapi->rx_rcb) -+ continue; -+ -+ tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping, -+ (tp->rx_ret_ring_mask + 1) << -+ BDINFO_FLAGS_MAXLEN_SHIFT, 0); -+ } -+} -+ -+/* tp->lock is held. */ -+static void tg3_rings_reset(struct tg3 *tp) -+{ -+ int i; -+ u32 stblk; -+ struct tg3_napi *tnapi = &tp->napi[0]; -+ -+ tg3_tx_rcbs_disable(tp); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ for (i = 1; i < TG3_IRQ_MAX_VECS_IOV; i++) -+ tg3_disable_prod_rcbs(tp, i); -+#endif -+ -+ tg3_rx_ret_rcbs_disable(tp); -+ -+ /* Disable interrupts */ -+ tw32_mailbox_f(tp->napi[0].int_mbox, 1); -+ tp->napi[0].chk_msi_cnt = 0; -+ tp->napi[0].last_rx_cons = 0; -+ tp->napi[0].last_tx_cons = 0; -+ -+ /* Zero mailbox registers. */ -+ if (tg3_flag(tp, SUPPORT_MSIX)) { -+ for (i = 1; i < tp->irq_max; i++) { -+ tp->napi[i].tx_prod = 0; -+ tp->napi[i].tx_cons = 0; -+ if (tg3_flag(tp, ENABLE_TSS)) -+ tw32_mailbox(tp->napi[i].prodmbox, 0); -+ tw32_rx_mbox(tp->napi[i].consmbox, 0); -+ tw32_mailbox_f(tp->napi[i].int_mbox, 1); -+ tp->napi[i].chk_msi_cnt = 0; -+ tp->napi[i].last_rx_cons = 0; -+ tp->napi[i].last_tx_cons = 0; -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (!tg3_flag(tp, ENABLE_RSS)) { -+ struct tg3_rx_prodring_set *tpr; -+ -+ tpr = &tp->napi[i].prodring; -+ tw32_rx_mbox(tpr->rx_jmb_mbox, 0); -+ tw32_rx_mbox(tpr->rx_std_mbox, 0); -+ } -+#endif -+ } -+ if (!tg3_flag(tp, ENABLE_TSS)) -+ tw32_mailbox(tp->napi[0].prodmbox, 0); -+ } else { -+ tp->napi[0].tx_prod = 0; -+ tp->napi[0].tx_cons = 0; -+ tw32_mailbox(tp->napi[0].prodmbox, 0); -+ tw32_rx_mbox(tp->napi[0].consmbox, 0); -+ } -+ -+ /* Make sure the NIC-based send BD rings are disabled. */ -+ if (!tg3_flag(tp, 5705_PLUS)) { -+ u32 mbox = MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW; -+ for (i = 0; i < 16; i++) -+ tw32_tx_mbox(mbox + i * 8, 0); -+ } -+ -+ /* Clear status block in ram. */ -+ memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE); -+ -+ /* Set status block DMA address */ -+ tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, -+ ((u64) tnapi->status_mapping >> 32)); -+ tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW, -+ ((u64) tnapi->status_mapping & 0xffffffff)); -+ -+ stblk = HOSTCC_STATBLCK_RING1; -+ -+ for (i = 1, tnapi++; i < tp->irq_cnt; i++, tnapi++) { -+ u64 mapping = (u64)tnapi->status_mapping; -+ tw32(stblk + TG3_64BIT_REG_HIGH, mapping >> 32); -+ tw32(stblk + TG3_64BIT_REG_LOW, mapping & 0xffffffff); -+ stblk += 8; -+ -+ /* Clear status block in ram. */ -+ memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE); -+ } -+ -+ tg3_tx_rcbs_init(tp); -+ tg3_rx_ret_rcbs_init(tp); -+} -+ -+static void tg3_setup_rxbd_thresholds(struct tg3 *tp) -+{ -+ u32 val, bdcache_maxcnt, host_rep_thresh, nic_rep_thresh; -+ -+ if (!tg3_flag(tp, 5750_PLUS) || -+ tg3_flag(tp, 5780_CLASS) || -+ tg3_asic_rev(tp) == ASIC_REV_5750 || -+ tg3_asic_rev(tp) == ASIC_REV_5752 || -+ tg3_flag(tp, 57765_PLUS)) -+ bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5700; -+ else if (tg3_asic_rev(tp) == ASIC_REV_5755 || -+ tg3_asic_rev(tp) == ASIC_REV_5787) -+ bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5755; -+ else -+ bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5906; -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ /* In IOV, mode, the std rx BD cache is chopped into 17 pieces. */ -+ if (tg3_flag(tp, ENABLE_IOV)) -+ bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5906; -+#endif /* TG3_VMWARE_NETQ_ENABLE */ -+ -+ nic_rep_thresh = min(bdcache_maxcnt / 2, tp->rx_std_max_post); -+ host_rep_thresh = max_t(u32, tp->rx_pending / 8, 1); -+ -+ val = min(nic_rep_thresh, host_rep_thresh); -+ tw32(RCVBDI_STD_THRESH, val); -+ -+ if (tg3_flag(tp, 57765_PLUS)) -+ tw32(STD_REPLENISH_LWM, bdcache_maxcnt); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (tg3_flag(tp, 5717_PLUS) && tg3_flag(tp, ENABLE_IOV)) -+ tw32(STD_REPLENISH_LWM, bdcache_maxcnt / 2); -+#endif /* TG3_VMWARE_NETQ_ENABLE */ -+ -+ if (!tg3_flag(tp, JUMBO_CAPABLE) || tg3_flag(tp, 5780_CLASS)) -+ return; -+ -+ bdcache_maxcnt = TG3_SRAM_RX_JMB_BDCACHE_SIZE_5700; -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ /* In IOV, mode, the jmb rx BD cache is chopped into 17 pieces. */ -+ if (tg3_flag(tp, ENABLE_IOV)) -+ bdcache_maxcnt = TG3_SRAM_RX_JMB_BDCACHE_SIZE_5717; -+#endif /* TG3_VMWARE_NETQ_ENABLE */ -+ -+ host_rep_thresh = max_t(u32, tp->rx_jumbo_pending / 8, 1); -+ -+ val = min(bdcache_maxcnt / 2, host_rep_thresh); -+ tw32(RCVBDI_JUMBO_THRESH, val); -+ -+ if (tg3_flag(tp, 57765_PLUS)) -+ tw32(JMB_REPLENISH_LWM, bdcache_maxcnt); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (tg3_flag(tp, 5717_PLUS) && tg3_flag(tp, ENABLE_IOV)) -+ tw32(JMB_REPLENISH_LWM, bdcache_maxcnt / 2); -+#endif /* TG3_VMWARE_NETQ_ENABLE */ -+} -+ -+static inline u32 calc_crc(unsigned char *buf, int len) -+{ -+ u32 reg; -+ u32 tmp; -+ int j, k; -+ -+ reg = 0xffffffff; -+ -+ for (j = 0; j < len; j++) { -+ reg ^= buf[j]; -+ -+ for (k = 0; k < 8; k++) { -+ tmp = reg & 0x01; -+ -+ reg >>= 1; -+ -+ if (tmp) -+ reg ^= 0xedb88320; -+ } -+ } -+ -+ return ~reg; -+} -+ -+static void tg3_set_multi(struct tg3 *tp, unsigned int accept_all) -+{ -+ /* accept or reject all multicast frames */ -+ tw32(MAC_HASH_REG_0, accept_all ? 0xffffffff : 0); -+ tw32(MAC_HASH_REG_1, accept_all ? 0xffffffff : 0); -+ tw32(MAC_HASH_REG_2, accept_all ? 0xffffffff : 0); -+ tw32(MAC_HASH_REG_3, accept_all ? 0xffffffff : 0); -+} -+ -+static void __tg3_set_rx_mode(struct net_device *dev) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ u32 rx_mode; -+ -+ rx_mode = tp->rx_mode & ~(RX_MODE_PROMISC | -+ RX_MODE_KEEP_VLAN_TAG); -+ -+ /* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG -+ * flag clear. -+ */ -+#ifndef BCM_HAS_NEW_VLAN_INTERFACE -+ if (!tp->vlgrp) -+#endif -+ if (!tg3_flag(tp, ENABLE_ASF)) -+ rx_mode |= RX_MODE_KEEP_VLAN_TAG; -+ -+ if (dev->flags & IFF_PROMISC) { -+ /* Promiscuous mode. */ -+ rx_mode |= RX_MODE_PROMISC; -+ } else if (dev->flags & IFF_ALLMULTI) { -+ /* Accept all multicast. */ -+ tg3_set_multi(tp, 1); -+ } else if (netdev_mc_empty(dev)) { -+ /* Reject all multicast. */ -+ tg3_set_multi(tp, 0); -+ } else { -+ /* Accept one or more multicast(s). */ -+ struct netdev_hw_addr *ha; -+ u32 mc_filter[4] = { 0, }; -+ u32 regidx; -+ u32 bit; -+ u32 crc; -+ -+ netdev_for_each_mc_addr(ha, dev) { -+ crc = calc_crc(ha->addr, ETH_ALEN); -+ bit = ~crc & 0x7f; -+ regidx = (bit & 0x60) >> 5; -+ bit &= 0x1f; -+ mc_filter[regidx] |= (1 << bit); -+ } -+ -+ tw32(MAC_HASH_REG_0, mc_filter[0]); -+ tw32(MAC_HASH_REG_1, mc_filter[1]); -+ tw32(MAC_HASH_REG_2, mc_filter[2]); -+ tw32(MAC_HASH_REG_3, mc_filter[3]); -+ } -+ -+#ifdef IFF_UNICAST_FLT -+ if (netdev_uc_count(dev) > TG3_MAX_UCAST_ADDR(tp)) { -+ rx_mode |= RX_MODE_PROMISC; -+ } else if (!(dev->flags & IFF_PROMISC)) { -+ /* Add all entries into to the mac addr filter list */ -+ int i = 0; -+ struct netdev_hw_addr *ha; -+ -+ netdev_for_each_uc_addr(ha, dev) { -+ __tg3_set_one_mac_addr(tp, ha->addr, -+ i + TG3_UCAST_ADDR_IDX(tp)); -+ i++; -+ } -+ } -+#endif -+ -+ if (rx_mode != tp->rx_mode) { -+ tp->rx_mode = rx_mode; -+ tw32_f(MAC_RX_MODE, rx_mode); -+ udelay(10); -+ } -+} -+ -+static void tg3_rss_init_dflt_indir_tbl(struct tg3 *tp, u32 qcnt) -+{ -+ int i; -+ -+ for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) -+ tp->rss_ind_tbl[i] = ethtool_rxfh_indir_default(i, qcnt); -+} -+ -+static void tg3_rss_check_indir_tbl(struct tg3 *tp) -+{ -+ int i; -+ -+ if (!tg3_flag(tp, ENABLE_RSS)) -+ return; -+ -+ if (tp->rxq_cnt == 1) { -+ memset(&tp->rss_ind_tbl[0], 0, sizeof(tp->rss_ind_tbl)); -+ return; -+ } -+ -+ /* Validate table against current IRQ count */ -+ for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) { -+ if (tp->rss_ind_tbl[i] >= tp->rxq_cnt) -+ break; -+ } -+ -+ if (i != TG3_RSS_INDIR_TBL_SIZE) -+ tg3_rss_init_dflt_indir_tbl(tp, tp->rxq_cnt); -+} -+ -+static void tg3_rss_write_indir_tbl(struct tg3 *tp) -+{ -+ int i = 0; -+ u32 reg = MAC_RSS_INDIR_TBL_0; -+ -+ while (i < TG3_RSS_INDIR_TBL_SIZE) { -+ u32 val = tp->rss_ind_tbl[i]; -+ i++; -+ for (; i % 8; i++) { -+ val <<= 4; -+ val |= tp->rss_ind_tbl[i]; -+ } -+ tw32(reg, val); -+ reg += 4; -+ } -+} -+ -+static inline u32 tg3_lso_rd_dma_workaround_bit(struct tg3 *tp) -+{ -+ if (tg3_asic_rev(tp) == ASIC_REV_5719) -+ return TG3_LSO_RD_DMA_TX_LENGTH_WA_5719; -+ else -+ return TG3_LSO_RD_DMA_TX_LENGTH_WA_5720; -+} -+ -+/* tp->lock is held. */ -+static int tg3_reset_hw(struct tg3 *tp, bool reset_phy) -+{ -+ u32 val, rdmac_mode; -+ int i, err, limit; -+ struct tg3_rx_prodring_set *tpr = &tp->napi[0].prodring; -+ -+ tg3_disable_ints(tp); -+ -+ tg3_stop_fw(tp); -+ -+ tg3_write_sig_pre_reset(tp, RESET_KIND_INIT); -+ -+ if (tg3_flag(tp, INIT_COMPLETE)) -+ tg3_abort_hw(tp, 1); -+ -+ if ((tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN) && -+ !(tp->phy_flags & TG3_PHYFLG_USER_CONFIGURED)) { -+ tg3_phy_pull_config(tp); -+ -+ /* Pull eee config only if not overridden by module param */ -+ if (tg3_disable_eee == -1) -+ tg3_eee_pull_config(tp, NULL); -+ -+ tp->phy_flags |= TG3_PHYFLG_USER_CONFIGURED; -+ } -+ -+ /* Enable MAC control of LPI */ -+#ifndef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_asic_rev(tp) != ASIC_REV_5785) -+#endif -+ if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) -+ tg3_setup_eee(tp); -+ -+ if (reset_phy) -+ tg3_phy_reset(tp); -+ -+ err = tg3_chip_reset(tp); -+ if (err) -+ return err; -+ -+ tg3_write_sig_legacy(tp, RESET_KIND_INIT); -+ -+ if (tg3_chip_rev(tp) == CHIPREV_5784_AX) { -+ val = tr32(TG3_CPMU_CTRL); -+ val &= ~(CPMU_CTRL_LINK_AWARE_MODE | CPMU_CTRL_LINK_IDLE_MODE); -+ tw32(TG3_CPMU_CTRL, val); -+ -+ val = tr32(TG3_CPMU_LSPD_10MB_CLK); -+ val &= ~CPMU_LSPD_10MB_MACCLK_MASK; -+ val |= CPMU_LSPD_10MB_MACCLK_6_25; -+ tw32(TG3_CPMU_LSPD_10MB_CLK, val); -+ -+ val = tr32(TG3_CPMU_LNK_AWARE_PWRMD); -+ val &= ~CPMU_LNK_AWARE_MACCLK_MASK; -+ val |= CPMU_LNK_AWARE_MACCLK_6_25; -+ tw32(TG3_CPMU_LNK_AWARE_PWRMD, val); -+ -+ val = tr32(TG3_CPMU_HST_ACC); -+ val &= ~CPMU_HST_ACC_MACCLK_MASK; -+ val |= CPMU_HST_ACC_MACCLK_6_25; -+ tw32(TG3_CPMU_HST_ACC, val); -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_57780) { -+ val = tr32(PCIE_PWR_MGMT_THRESH) & ~PCIE_PWR_MGMT_L1_THRESH_MSK; -+ val |= PCIE_PWR_MGMT_EXT_ASPM_TMR_EN | -+ PCIE_PWR_MGMT_L1_THRESH_4MS; -+ tw32(PCIE_PWR_MGMT_THRESH, val); -+ -+ val = tr32(TG3_PCIE_EIDLE_DELAY) & ~TG3_PCIE_EIDLE_DELAY_MASK; -+ tw32(TG3_PCIE_EIDLE_DELAY, val | TG3_PCIE_EIDLE_DELAY_13_CLKS); -+ -+ tw32(TG3_CORR_ERR_STAT, TG3_CORR_ERR_STAT_CLEAR); -+ -+ val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN; -+ tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS); -+ } -+ -+ if (tg3_flag(tp, L1PLLPD_EN)) { -+ u32 grc_mode = tr32(GRC_MODE); -+ -+ /* Access the lower 1K of PL PCIE block registers. */ -+ val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK; -+ tw32(GRC_MODE, val | GRC_MODE_PCIE_PL_SEL); -+ -+ val = tr32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL1); -+ tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL1, -+ val | TG3_PCIE_PL_LO_PHYCTL1_L1PLLPD_EN); -+ -+ tw32(GRC_MODE, grc_mode); -+ } -+ -+ if (tg3_flag(tp, 57765_CLASS)) { -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_57765_A0) { -+ u32 grc_mode = tr32(GRC_MODE); -+ -+ /* Access the lower 1K of PL PCIE block registers. */ -+ val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK; -+ tw32(GRC_MODE, val | GRC_MODE_PCIE_PL_SEL); -+ -+ val = tr32(TG3_PCIE_TLDLPL_PORT + -+ TG3_PCIE_PL_LO_PHYCTL5); -+ tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL5, -+ val | TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ); -+ -+ tw32(GRC_MODE, grc_mode); -+ } -+ -+ if (tg3_chip_rev(tp) != CHIPREV_57765_AX) { -+ u32 grc_mode; -+ -+ /* Fix transmit hangs */ -+ val = tr32(TG3_CPMU_PADRNG_CTL); -+ val |= TG3_CPMU_PADRNG_CTL_RDIV2; -+ tw32(TG3_CPMU_PADRNG_CTL, val); -+ -+ grc_mode = tr32(GRC_MODE); -+ -+ /* Access the lower 1K of DL PCIE block registers. */ -+ val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK; -+ tw32(GRC_MODE, val | GRC_MODE_PCIE_DL_SEL); -+ -+ val = tr32(TG3_PCIE_TLDLPL_PORT + -+ TG3_PCIE_DL_LO_FTSMAX); -+ val &= ~TG3_PCIE_DL_LO_FTSMAX_MSK; -+ tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_DL_LO_FTSMAX, -+ val | TG3_PCIE_DL_LO_FTSMAX_VAL); -+ -+ tw32(GRC_MODE, grc_mode); -+ } -+ -+ val = tr32(TG3_CPMU_LSPD_10MB_CLK); -+ val &= ~CPMU_LSPD_10MB_MACCLK_MASK; -+ val |= CPMU_LSPD_10MB_MACCLK_6_25; -+ tw32(TG3_CPMU_LSPD_10MB_CLK, val); -+ } -+ -+ /* This works around an issue with Athlon chipsets on -+ * B3 tigon3 silicon. This bit has no effect on any -+ * other revision. But do not set this on PCI Express -+ * chips and don't even touch the clocks if the CPMU is present. -+ */ -+ if (!tg3_flag(tp, CPMU_PRESENT)) { -+ if (!tg3_flag(tp, PCI_EXPRESS)) -+ tp->pci_clock_ctrl |= CLOCK_CTRL_DELAY_PCI_GRANT; -+ tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); -+ } -+ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5704_A0 && -+ tg3_flag(tp, PCIX_MODE)) { -+ val = tr32(TG3PCI_PCISTATE); -+ val |= PCISTATE_RETRY_SAME_DMA; -+ tw32(TG3PCI_PCISTATE, val); -+ } -+ -+ if (tg3_flag(tp, ENABLE_APE)) { -+ /* Allow reads and writes to the -+ * APE register and memory space. -+ */ -+ val = tr32(TG3PCI_PCISTATE); -+ val |= PCISTATE_ALLOW_APE_CTLSPC_WR | -+ PCISTATE_ALLOW_APE_SHMEM_WR | -+ PCISTATE_ALLOW_APE_PSPACE_WR; -+ tw32(TG3PCI_PCISTATE, val); -+ } -+ -+ if (tg3_chip_rev(tp) == CHIPREV_5704_BX) { -+ /* Enable some hw fixes. */ -+ val = tr32(TG3PCI_MSI_DATA); -+ val |= (1 << 26) | (1 << 28) | (1 << 29); -+ tw32(TG3PCI_MSI_DATA, val); -+ } -+ -+ /* Descriptor ring init may make accesses to the -+ * NIC SRAM area to setup the TX descriptors, so we -+ * can only do this after the hardware has been -+ * successfully reset. -+ */ -+ err = tg3_init_rings(tp); -+ if (err) -+ return err; -+ -+ if (tg3_flag(tp, 57765_PLUS)) { -+ val = tr32(TG3PCI_DMA_RW_CTRL) & -+ ~DMA_RWCTRL_DIS_CACHE_ALIGNMENT; -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_57765_A0) -+ val &= ~DMA_RWCTRL_CRDRDR_RDMA_MRRS_MSK; -+ if (!tg3_flag(tp, 57765_CLASS) && -+ tg3_asic_rev(tp) != ASIC_REV_5717 && -+ tg3_asic_rev(tp) != ASIC_REV_5762) -+ val |= DMA_RWCTRL_TAGGED_STAT_WA; -+ tw32(TG3PCI_DMA_RW_CTRL, val | tp->dma_rwctrl); -+ } else if (tg3_asic_rev(tp) != ASIC_REV_5784 && -+ tg3_asic_rev(tp) != ASIC_REV_5761) { -+ /* This value is determined during the probe time DMA -+ * engine test, tg3_test_dma. -+ */ -+ tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); -+ } -+ -+ tp->grc_mode &= ~(GRC_MODE_HOST_SENDBDS | -+ GRC_MODE_4X_NIC_SEND_RINGS | -+ GRC_MODE_NO_TX_PHDR_CSUM | -+ GRC_MODE_NO_RX_PHDR_CSUM); -+ tp->grc_mode |= GRC_MODE_HOST_SENDBDS; -+ -+ /* Pseudo-header checksum is done by hardware logic and not -+ * the offload processers, so make the chip do the pseudo- -+ * header checksums on receive. For transmit it is more -+ * convenient to do the pseudo-header checksum in software -+ * as Linux does that on transmit for us in all cases. -+ */ -+ tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM; -+ -+ val = GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP; -+ if (tp->rxptpctl) -+ tw32(TG3_RX_PTP_CTL, -+ tp->rxptpctl | TG3_RX_PTP_CTL_HWTS_INTERLOCK); -+ -+ if (tg3_flag(tp, PTP_CAPABLE)) -+ val |= GRC_MODE_TIME_SYNC_ENABLE; -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (tg3_flag(tp, ENABLE_IOV)) -+ val |= GRC_MODE_IOV_ENABLE; -+#endif -+ -+ tw32(GRC_MODE, tp->grc_mode | val); -+ -+ /* Setup the timer prescalar register. Clock is always 66Mhz. */ -+ val = tr32(GRC_MISC_CFG); -+ val &= ~0xff; -+ val |= (65 << GRC_MISC_CFG_PRESCALAR_SHIFT); -+ tw32(GRC_MISC_CFG, val); -+ -+ /* Initialize MBUF/DESC pool. */ -+ if (tg3_flag(tp, 5750_PLUS)) { -+ /* Do nothing. */ -+ } else if (tg3_asic_rev(tp) != ASIC_REV_5705) { -+ tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE); -+ if (tg3_asic_rev(tp) == ASIC_REV_5704) -+ tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE64); -+ else -+ tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE96); -+ tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE); -+ tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE); -+ } else if (tg3_flag(tp, TSO_CAPABLE)) { -+#if TG3_TSO_SUPPORT != 0 -+ int fw_len; -+ -+ fw_len = (TG3_TSO5_FW_TEXT_LEN + -+ TG3_TSO5_FW_RODATA_LEN + -+ TG3_TSO5_FW_DATA_LEN + -+ TG3_TSO5_FW_SBSS_LEN + -+ TG3_TSO5_FW_BSS_LEN); -+ fw_len = (fw_len + (0x80 - 1)) & ~(0x80 - 1); -+ tw32(BUFMGR_MB_POOL_ADDR, -+ NIC_SRAM_MBUF_POOL_BASE5705 + fw_len); -+ tw32(BUFMGR_MB_POOL_SIZE, -+ NIC_SRAM_MBUF_POOL_SIZE5705 - fw_len - 0xa00); -+#endif -+ } -+ -+ if (tp->dev->mtu <= ETH_DATA_LEN) { -+ tw32(BUFMGR_MB_RDMA_LOW_WATER, -+ tp->bufmgr_config.mbuf_read_dma_low_water); -+ tw32(BUFMGR_MB_MACRX_LOW_WATER, -+ tp->bufmgr_config.mbuf_mac_rx_low_water); -+ tw32(BUFMGR_MB_HIGH_WATER, -+ tp->bufmgr_config.mbuf_high_water); -+ } else { -+ tw32(BUFMGR_MB_RDMA_LOW_WATER, -+ tp->bufmgr_config.mbuf_read_dma_low_water_jumbo); -+ tw32(BUFMGR_MB_MACRX_LOW_WATER, -+ tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo); -+ tw32(BUFMGR_MB_HIGH_WATER, -+ tp->bufmgr_config.mbuf_high_water_jumbo); -+ } -+ tw32(BUFMGR_DMA_LOW_WATER, -+ tp->bufmgr_config.dma_low_water); -+ tw32(BUFMGR_DMA_HIGH_WATER, -+ tp->bufmgr_config.dma_high_water); -+ -+ val = BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE; -+ if (tg3_asic_rev(tp) == ASIC_REV_5719) -+ val |= BUFMGR_MODE_NO_TX_UNDERRUN; -+ if (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_asic_rev(tp) == ASIC_REV_5762 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5719_A0 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5720_A0) -+ val |= BUFMGR_MODE_MBLOW_ATTN_ENAB; -+ tw32(BUFMGR_MODE, val); -+ for (i = 0; i < 2000; i++) { -+ if (tr32(BUFMGR_MODE) & BUFMGR_MODE_ENABLE) -+ break; -+ udelay(10); -+ } -+ if (i >= 2000) { -+ netdev_err(tp->dev, "%s cannot enable BUFMGR\n", __func__); -+ return -ENODEV; -+ } -+ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5906_A1) -+ tw32(ISO_PKT_TX, (tr32(ISO_PKT_TX) & ~0x3) | 0x2); -+ -+ tg3_setup_rxbd_thresholds(tp); -+ -+ /* Initialize TG3_BDINFO's at: -+ * RCVDBDI_STD_BD: standard eth size rx ring -+ * RCVDBDI_JUMBO_BD: jumbo frame rx ring -+ * RCVDBDI_MINI_BD: small frame rx ring (??? does not work) -+ * -+ * like so: -+ * TG3_BDINFO_HOST_ADDR: high/low parts of DMA address of ring -+ * TG3_BDINFO_MAXLEN_FLAGS: (rx max buffer size << 16) | -+ * ring attribute flags -+ * TG3_BDINFO_NIC_ADDR: location of descriptors in nic SRAM -+ * -+ * Standard receive ring @ NIC_SRAM_RX_BUFFER_DESC, 512 entries. -+ * Jumbo receive ring @ NIC_SRAM_RX_JUMBO_BUFFER_DESC, 256 entries. -+ * -+ * The size of each ring is fixed in the firmware, but the location is -+ * configurable. -+ */ -+ tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH, -+ ((u64) tpr->rx_std_mapping >> 32)); -+ tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, -+ ((u64) tpr->rx_std_mapping & 0xffffffff)); -+ if (!tg3_flag(tp, 5717_PLUS)) -+ tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR, -+ NIC_SRAM_RX_BUFFER_DESC); -+ -+ /* Disable the mini ring */ -+ if (!tg3_flag(tp, 5705_PLUS)) -+ tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS, -+ BDINFO_FLAGS_DISABLED); -+ -+ /* Program the jumbo buffer descriptor ring control -+ * blocks on those devices that have them. -+ */ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5719_A0 || -+ (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS))) { -+ -+ if (tg3_flag(tp, JUMBO_RING_ENABLE)) { -+ tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH, -+ ((u64) tpr->rx_jmb_mapping >> 32)); -+ tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, -+ ((u64) tpr->rx_jmb_mapping & 0xffffffff)); -+ val = TG3_RX_JMB_RING_SIZE(tp) << -+ BDINFO_FLAGS_MAXLEN_SHIFT; -+ tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, -+ val | BDINFO_FLAGS_USE_EXT_RECV); -+ if (!tg3_flag(tp, USE_JUMBO_BDFLAG) || -+ tg3_flag(tp, 57765_CLASS) || -+ tg3_asic_rev(tp) == ASIC_REV_5762) -+ tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR, -+ NIC_SRAM_RX_JUMBO_BUFFER_DESC); -+ } else { -+ tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, -+ BDINFO_FLAGS_DISABLED); -+ } -+ -+ if (tg3_flag(tp, 57765_PLUS)) { -+ val = TG3_RX_STD_RING_SIZE(tp); -+ val <<= BDINFO_FLAGS_MAXLEN_SHIFT; -+ val |= (TG3_RX_STD_DMA_SZ << 2); -+ } else -+ val = TG3_RX_STD_DMA_SZ << BDINFO_FLAGS_MAXLEN_SHIFT; -+ } else -+ val = TG3_RX_STD_MAX_SIZE_5700 << BDINFO_FLAGS_MAXLEN_SHIFT; -+ -+ tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, val); -+ -+ tpr->rx_std_prod_idx = tp->rx_pending; -+ tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, tpr->rx_std_prod_idx); -+ -+ tpr->rx_jmb_prod_idx = -+ tg3_flag(tp, JUMBO_RING_ENABLE) ? tp->rx_jumbo_pending : 0; -+ tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx); -+ -+ tg3_rings_reset(tp); -+ -+ /* Initialize MAC address and backoff seed. */ -+ __tg3_set_mac_addr(tp, false); -+ -+ /* MTU + ethernet header + FCS + optional VLAN tag */ -+ tw32(MAC_RX_MTU_SIZE, -+ tp->dev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN); -+ -+ /* The slot time is changed by tg3_setup_phy if we -+ * run at gigabit with half duplex. -+ */ -+ val = (2 << TX_LENGTHS_IPG_CRS_SHIFT) | -+ (6 << TX_LENGTHS_IPG_SHIFT) | -+ (32 << TX_LENGTHS_SLOT_TIME_SHIFT); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5720 || -+ tg3_asic_rev(tp) == ASIC_REV_5762) -+ val |= tr32(MAC_TX_LENGTHS) & -+ (TX_LENGTHS_JMB_FRM_LEN_MSK | -+ TX_LENGTHS_CNT_DWN_VAL_MSK); -+ -+ tw32(MAC_TX_LENGTHS, val); -+ -+ /* Receive rules. */ -+ tw32(MAC_RCV_RULE_CFG, RCV_RULE_CFG_DEFAULT_CLASS); -+ tw32(RCVLPC_CONFIG, 0x0181); -+ -+ /* Calculate RDMAC_MODE setting early, we need it to determine -+ * the RCVLPC_STATE_ENABLE mask. -+ */ -+ rdmac_mode = (RDMAC_MODE_ENABLE | RDMAC_MODE_TGTABORT_ENAB | -+ RDMAC_MODE_MSTABORT_ENAB | RDMAC_MODE_PARITYERR_ENAB | -+ RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB | -+ RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB | -+ RDMAC_MODE_LNGREAD_ENAB); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5717) -+ rdmac_mode |= RDMAC_MODE_MULT_DMA_RD_DIS; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5784 || -+ tg3_asic_rev(tp) == ASIC_REV_5785 || -+ tg3_asic_rev(tp) == ASIC_REV_57780) -+ rdmac_mode |= RDMAC_MODE_BD_SBD_CRPT_ENAB | -+ RDMAC_MODE_MBUF_RBD_CRPT_ENAB | -+ RDMAC_MODE_MBUF_SBD_CRPT_ENAB; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5705 && -+ tg3_chip_rev_id(tp) != CHIPREV_ID_5705_A0) { -+ if (tg3_flag(tp, TSO_CAPABLE) && -+ tg3_asic_rev(tp) == ASIC_REV_5705) { -+ rdmac_mode |= RDMAC_MODE_FIFO_SIZE_128; -+ } else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) && -+ !tg3_flag(tp, IS_5788)) { -+ rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST; -+ } -+ } -+ -+ if (tg3_flag(tp, PCI_EXPRESS)) -+ rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_57766) { -+ tp->dma_limit = 0; -+ -+#if defined(__VMKLNX__) -+ if (tg3_flag(tp, TSO_CAPABLE)) -+ tp->dma_limit = TG3_TX_BD_DMA_MAX_32K; -+#endif -+ if (tp->dev->mtu <= ETH_DATA_LEN) -+ rdmac_mode |= RDMAC_MODE_JMB_2K_MMRR; -+ } -+ -+ /* Enables IPV4 checksum offload as well. */ -+ if (tg3_flag(tp, HW_TSO_1) || -+ tg3_flag(tp, HW_TSO_2) || -+ tg3_flag(tp, HW_TSO_3)) -+ rdmac_mode |= RDMAC_MODE_IPV4_LSO_EN; -+ -+ /* Enables IPV6 checksum offload as well. */ -+ if (tg3_flag(tp, 57765_PLUS) || -+ tg3_asic_rev(tp) == ASIC_REV_5785 || -+ tg3_asic_rev(tp) == ASIC_REV_57780) -+ rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5720 || -+ tg3_asic_rev(tp) == ASIC_REV_5762) -+ rdmac_mode |= tr32(RDMAC_MODE) & RDMAC_MODE_H2BNC_VLAN_DET; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5761 || -+ tg3_asic_rev(tp) == ASIC_REV_5784 || -+ tg3_asic_rev(tp) == ASIC_REV_5785 || -+ tg3_asic_rev(tp) == ASIC_REV_57780 || -+ tg3_flag(tp, 57765_PLUS)) { -+ u32 tgtreg; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5762) -+ tgtreg = TG3_RDMA_RSRVCTRL_REG2; -+ else -+ tgtreg = TG3_RDMA_RSRVCTRL_REG; -+ -+ val = tr32(tgtreg); -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5719_A0 || -+ tg3_asic_rev(tp) == ASIC_REV_5762) { -+ val &= ~(TG3_RDMA_RSRVCTRL_TXMRGN_MASK | -+ TG3_RDMA_RSRVCTRL_FIFO_LWM_MASK | -+ TG3_RDMA_RSRVCTRL_FIFO_HWM_MASK); -+ val |= TG3_RDMA_RSRVCTRL_TXMRGN_320B | -+ TG3_RDMA_RSRVCTRL_FIFO_LWM_1_5K | -+ TG3_RDMA_RSRVCTRL_FIFO_HWM_1_5K; -+ } -+ tw32(tgtreg, val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX); -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_asic_rev(tp) == ASIC_REV_5720 || -+ tg3_asic_rev(tp) == ASIC_REV_5762) { -+ u32 tgtreg; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5762) -+ tgtreg = TG3_LSO_RD_DMA_CRPTEN_CTRL2; -+ else -+ tgtreg = TG3_LSO_RD_DMA_CRPTEN_CTRL; -+ -+ val = tr32(tgtreg); -+ tw32(tgtreg, val | -+ TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K | -+ TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K); -+ } -+ -+ /* Receive/send statistics. */ -+ if (tg3_flag(tp, 5750_PLUS)) { -+ val = tr32(RCVLPC_STATS_ENABLE); -+ val &= ~RCVLPC_STATSENAB_DACK_FIX; -+ tw32(RCVLPC_STATS_ENABLE, val); -+ } else if ((rdmac_mode & RDMAC_MODE_FIFO_SIZE_128) && -+ tg3_flag(tp, TSO_CAPABLE)) { -+ val = tr32(RCVLPC_STATS_ENABLE); -+ val &= ~RCVLPC_STATSENAB_LNGBRST_RFIX; -+ tw32(RCVLPC_STATS_ENABLE, val); -+ } else { -+ tw32(RCVLPC_STATS_ENABLE, 0xffffff); -+ } -+ tw32(RCVLPC_STATSCTRL, RCVLPC_STATSCTRL_ENABLE); -+ tw32(SNDDATAI_STATSENAB, 0xffffff); -+ tw32(SNDDATAI_STATSCTRL, -+ (SNDDATAI_SCTRL_ENABLE | -+ SNDDATAI_SCTRL_FASTUPD)); -+ -+ /* Setup host coalescing engine. */ -+ tw32(HOSTCC_MODE, 0); -+ for (i = 0; i < 2000; i++) { -+ if (!(tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE)) -+ break; -+ udelay(10); -+ } -+ -+ __tg3_set_coalesce(tp, &tp->coal); -+ -+ if (!tg3_flag(tp, 5705_PLUS)) { -+ /* Status/statistics block address. See tg3_timer, -+ * the tg3_periodic_fetch_stats call there, and -+ * tg3_get_stats to see how this works for 5705/5750 chips. -+ */ -+ tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, -+ ((u64) tp->stats_mapping >> 32)); -+ tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW, -+ ((u64) tp->stats_mapping & 0xffffffff)); -+ tw32(HOSTCC_STATS_BLK_NIC_ADDR, NIC_SRAM_STATS_BLK); -+ -+ tw32(HOSTCC_STATUS_BLK_NIC_ADDR, NIC_SRAM_STATUS_BLK); -+ -+ /* Clear statistics and status block memory areas */ -+ for (i = NIC_SRAM_STATS_BLK; -+ i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE; -+ i += sizeof(u32)) { -+ tg3_write_mem(tp, i, 0); -+ udelay(40); -+ } -+ } -+ -+ tw32(HOSTCC_MODE, HOSTCC_MODE_ENABLE | tp->coalesce_mode); -+ -+ tw32(RCVCC_MODE, RCVCC_MODE_ENABLE | RCVCC_MODE_ATTN_ENABLE); -+ tw32(RCVLPC_MODE, RCVLPC_MODE_ENABLE); -+ if (!tg3_flag(tp, 5705_PLUS)) -+ tw32(RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE); -+ -+ if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) { -+ tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; -+ /* reset to prevent losing 1st rx packet intermittently */ -+ tw32_f(MAC_RX_MODE, RX_MODE_RESET); -+ udelay(10); -+ } -+ -+ tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | -+ MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | -+ MAC_MODE_FHDE_ENABLE; -+ if (tg3_flag(tp, ENABLE_APE)) -+ tp->mac_mode |= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; -+ if (!tg3_flag(tp, 5705_PLUS) && -+ !(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && -+ tg3_asic_rev(tp) != ASIC_REV_5700) -+ tp->mac_mode |= MAC_MODE_LINK_POLARITY; -+ tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR); -+ udelay(40); -+ -+ /* tp->grc_local_ctrl is partially set up during tg3_get_invariants(). -+ * If TG3_FLAG_IS_NIC is zero, we should read the -+ * register to preserve the GPIO settings for LOMs. The GPIOs, -+ * whether used as inputs or outputs, are set by boot code after -+ * reset. -+ */ -+ if (!tg3_flag(tp, IS_NIC)) { -+ u32 gpio_mask; -+ -+ gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE1 | -+ GRC_LCLCTRL_GPIO_OE2 | GRC_LCLCTRL_GPIO_OUTPUT0 | -+ GRC_LCLCTRL_GPIO_OUTPUT1 | GRC_LCLCTRL_GPIO_OUTPUT2; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5752) -+ gpio_mask |= GRC_LCLCTRL_GPIO_OE3 | -+ GRC_LCLCTRL_GPIO_OUTPUT3; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5755) -+ gpio_mask |= GRC_LCLCTRL_GPIO_UART_SEL; -+ -+ tp->grc_local_ctrl &= ~gpio_mask; -+ tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask; -+ -+ /* GPIO1 must be driven high for eeprom write protect */ -+ if (tg3_flag(tp, EEPROM_WRITE_PROT)) -+ tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 | -+ GRC_LCLCTRL_GPIO_OUTPUT1); -+ } -+ tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); -+ udelay(100); -+ -+ if (tg3_flag(tp, USING_MSIX)) { -+ val = tr32(MSGINT_MODE); -+ val |= MSGINT_MODE_ENABLE; -+ if (tp->irq_cnt > 1) -+ val |= MSGINT_MODE_MULTIVEC_EN; -+ if (!tg3_flag(tp, 1SHOT_MSI)) -+ val |= MSGINT_MODE_ONE_SHOT_DISABLE; -+ tw32(MSGINT_MODE, val); -+ } -+ -+ if (!tg3_flag(tp, 5705_PLUS)) { -+ tw32_f(DMAC_MODE, DMAC_MODE_ENABLE); -+ udelay(40); -+ } -+ -+ val = (WDMAC_MODE_ENABLE | WDMAC_MODE_TGTABORT_ENAB | -+ WDMAC_MODE_MSTABORT_ENAB | WDMAC_MODE_PARITYERR_ENAB | -+ WDMAC_MODE_ADDROFLOW_ENAB | WDMAC_MODE_FIFOOFLOW_ENAB | -+ WDMAC_MODE_FIFOURUN_ENAB | WDMAC_MODE_FIFOOREAD_ENAB | -+ WDMAC_MODE_LNGREAD_ENAB); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5705 && -+ tg3_chip_rev_id(tp) != CHIPREV_ID_5705_A0) { -+ if (tg3_flag(tp, TSO_CAPABLE) && -+ (tg3_chip_rev_id(tp) == CHIPREV_ID_5705_A1 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5705_A2)) { -+ /* nothing */ -+ } else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) && -+ !tg3_flag(tp, IS_5788)) { -+ val |= WDMAC_MODE_RX_ACCEL; -+ } -+ } -+ -+ /* Enable host coalescing bug fix */ -+ if (tg3_flag(tp, 5755_PLUS)) -+ val |= WDMAC_MODE_STATUS_TAG_FIX; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5785) -+ val |= WDMAC_MODE_BURST_ALL_DATA; -+ -+ tw32_f(WDMAC_MODE, val); -+ udelay(40); -+ -+ if (tg3_flag(tp, PCIX_MODE)) { -+ u16 pcix_cmd; -+ -+ pci_read_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD, -+ &pcix_cmd); -+ if (tg3_asic_rev(tp) == ASIC_REV_5703) { -+ pcix_cmd &= ~PCI_X_CMD_MAX_READ; -+ pcix_cmd |= PCI_X_CMD_READ_2K; -+ } else if (tg3_asic_rev(tp) == ASIC_REV_5704) { -+ pcix_cmd &= ~(PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ); -+ pcix_cmd |= PCI_X_CMD_READ_2K; -+ } -+ pci_write_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD, -+ pcix_cmd); -+ } -+ -+ tw32_f(RDMAC_MODE, rdmac_mode); -+ udelay(40); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_asic_rev(tp) == ASIC_REV_5720) { -+ for (i = 0; i < TG3_NUM_RDMA_CHANNELS; i++) { -+ if (tr32(TG3_RDMA_LENGTH + (i << 2)) > TG3_MAX_MTU(tp)) -+ break; -+ } -+ if (i < TG3_NUM_RDMA_CHANNELS) { -+ val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL); -+ val |= tg3_lso_rd_dma_workaround_bit(tp); -+ tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val); -+ tg3_flag_set(tp, 5719_5720_RDMA_BUG); -+ } -+ } -+ -+ tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE); -+ if (!tg3_flag(tp, 5705_PLUS)) -+ tw32(MBFREE_MODE, MBFREE_MODE_ENABLE); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5761) -+ tw32(SNDDATAC_MODE, -+ SNDDATAC_MODE_ENABLE | SNDDATAC_MODE_CDELAY); -+ else -+ tw32(SNDDATAC_MODE, SNDDATAC_MODE_ENABLE); -+ -+ tw32(SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE); -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ val = RCVBDI_MODE_ENABLE; -+ if (!tg3_flag(tp, ENABLE_IOV)) -+ val |= RCVBDI_MODE_RCB_ATTN_ENAB; -+ tw32(RCVBDI_MODE, val); -+ /* No packet drop if there is no RBDs. H/w will continues to service -+ RX packets for particular VMQ until all packets are drained. */ -+ val = RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ | (2<<13); -+#else -+ tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB); -+ val = RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ; -+#endif -+ if (tg3_flag(tp, LRG_PROD_RING_CAP)) -+ val |= RCVDBDI_MODE_LRG_RING_SZ; -+ tw32(RCVDBDI_MODE, val); -+ tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE); -+#if TG3_TSO_SUPPORT != 0 -+ if (tg3_flag(tp, HW_TSO_1) || -+ tg3_flag(tp, HW_TSO_2) || -+ tg3_flag(tp, HW_TSO_3)) -+ tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8); -+#endif -+ val = SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE; -+ if (tg3_flag(tp, ENABLE_TSS)) -+ val |= SNDBDI_MODE_MULTI_TXQ_EN; -+ tw32(SNDBDI_MODE, val); -+ tw32(SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE); -+ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5701_A0) { -+ err = tg3_load_5701_a0_firmware_fix(tp); -+ if (err) -+ return err; -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_57766) { -+ /* Ignore any errors for the firmware download. If download -+ * fails, the device will operate with EEE disabled -+ */ -+ tg3_load_57766_firmware(tp); -+ } -+ -+#if TG3_TSO_SUPPORT != 0 -+ if (tg3_flag(tp, TSO_CAPABLE)) { -+ err = tg3_load_tso_firmware(tp); -+ if (err) -+ return err; -+ } -+#endif -+ -+ tp->tx_mode = TX_MODE_ENABLE; -+ -+ if (tg3_flag(tp, 5755_PLUS) || -+ tg3_asic_rev(tp) == ASIC_REV_5906) -+ tp->tx_mode |= TX_MODE_MBUF_LOCKUP_FIX; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5720 || -+ tg3_asic_rev(tp) == ASIC_REV_5762) { -+ val = TX_MODE_JMB_FRM_LEN | TX_MODE_CNT_DN_MODE; -+ tp->tx_mode &= ~val; -+ tp->tx_mode |= tr32(MAC_TX_MODE) & val; -+ } -+ -+ tw32_f(MAC_TX_MODE, tp->tx_mode); -+ udelay(100); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tg3_netq_restore(tp); -+#endif -+ -+ if (tg3_flag(tp, ENABLE_RSS)) { -+ tg3_rss_write_indir_tbl(tp); -+ -+ /* Setup the "secret" hash key. */ -+ tw32(MAC_RSS_HASH_KEY_0, 0x5f865437); -+ tw32(MAC_RSS_HASH_KEY_1, 0xe4ac62cc); -+ tw32(MAC_RSS_HASH_KEY_2, 0x50103a45); -+ tw32(MAC_RSS_HASH_KEY_3, 0x36621985); -+ tw32(MAC_RSS_HASH_KEY_4, 0xbf14c0e8); -+ tw32(MAC_RSS_HASH_KEY_5, 0x1bc27a1e); -+ tw32(MAC_RSS_HASH_KEY_6, 0x84f4b556); -+ tw32(MAC_RSS_HASH_KEY_7, 0x094ea6fe); -+ tw32(MAC_RSS_HASH_KEY_8, 0x7dda01e7); -+ tw32(MAC_RSS_HASH_KEY_9, 0xc04d7481); -+ } -+ -+ tp->rx_mode = RX_MODE_ENABLE; -+ if (tg3_flag(tp, 5755_PLUS)) -+ tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5762) -+ tp->rx_mode |= RX_MODE_IPV4_FRAG_FIX; -+ -+ if (tg3_flag(tp, ENABLE_RSS)) -+ tp->rx_mode |= RX_MODE_RSS_ENABLE | -+ RX_MODE_RSS_ITBL_HASH_BITS_7 | -+ RX_MODE_RSS_IPV6_HASH_EN | -+ RX_MODE_RSS_TCP_IPV6_HASH_EN | -+ RX_MODE_RSS_IPV4_HASH_EN | -+ RX_MODE_RSS_TCP_IPV4_HASH_EN; -+ -+ tw32_f(MAC_RX_MODE, tp->rx_mode); -+ udelay(10); -+ -+ tw32(MAC_LED_CTRL, tp->led_ctrl); -+ -+ tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); -+ if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { -+ tw32_f(MAC_RX_MODE, RX_MODE_RESET); -+ udelay(10); -+ } -+ tw32_f(MAC_RX_MODE, tp->rx_mode); -+ udelay(10); -+ -+ if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { -+ if ((tg3_asic_rev(tp) == ASIC_REV_5704) && -+ !(tp->phy_flags & TG3_PHYFLG_SERDES_PREEMPHASIS)) { -+ /* Set drive transmission level to 1.2V */ -+ /* only if the signal pre-emphasis bit is not set */ -+ val = tr32(MAC_SERDES_CFG); -+ val &= 0xfffff000; -+ val |= 0x880; -+ tw32(MAC_SERDES_CFG, val); -+ } -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5703_A1) -+ tw32(MAC_SERDES_CFG, 0x616000); -+ } -+ -+ /* Prevent chip from dropping frames when flow control -+ * is enabled. -+ */ -+ if (tg3_flag(tp, 57765_CLASS)) -+ val = 1; -+ else -+ val = 2; -+ tw32_f(MAC_LOW_WMARK_MAX_RX_FRAME, val); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5704 && -+ (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) { -+ /* Use hardware link auto-negotiation */ -+ tg3_flag_set(tp, HW_AUTONEG); -+ } -+ -+ if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) && -+ tg3_asic_rev(tp) == ASIC_REV_5714) { -+ u32 tmp; -+ -+ tmp = tr32(SERDES_RX_CTRL); -+ tw32(SERDES_RX_CTRL, tmp | SERDES_RX_SIG_DETECT); -+ tp->grc_local_ctrl &= ~GRC_LCLCTRL_USE_EXT_SIG_DETECT; -+ tp->grc_local_ctrl |= GRC_LCLCTRL_USE_SIG_DETECT; -+ tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl); -+ } -+ -+ if (!tg3_flag(tp, USE_PHYLIB)) { -+ if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) -+ tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER; -+ -+ err = tg3_setup_phy(tp, false); -+ if (err) -+ return err; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && -+ !(tp->phy_flags & TG3_PHYFLG_IS_FET)) { -+ u32 tmp; -+ -+ /* Clear CRC stats. */ -+ if (!tg3_readphy(tp, MII_TG3_TEST1, &tmp)) { -+ tg3_writephy(tp, MII_TG3_TEST1, -+ tmp | MII_TG3_TEST1_CRC_EN); -+ tg3_readphy(tp, MII_TG3_RXR_COUNTERS, &tmp); -+ } -+ } -+ } -+ -+ __tg3_set_rx_mode(tp->dev); -+ -+ /* Initialize receive rules. */ -+ tw32(MAC_RCV_RULE_0, 0xc2000000 & RCV_RULE_DISABLE_MASK); -+ tw32(MAC_RCV_VALUE_0, 0xffffffff & RCV_RULE_DISABLE_MASK); -+ tw32(MAC_RCV_RULE_1, 0x86000004 & RCV_RULE_DISABLE_MASK); -+ tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK); -+ -+ if (tg3_flag(tp, 5705_PLUS) && !tg3_flag(tp, 5780_CLASS)) -+ limit = 8; -+ else -+ limit = 16; -+ if (tg3_flag(tp, ENABLE_ASF)) -+ limit -= 4; -+ switch (limit) { -+ case 16: -+ tw32(MAC_RCV_RULE_15, 0); tw32(MAC_RCV_VALUE_15, 0); -+ case 15: -+ tw32(MAC_RCV_RULE_14, 0); tw32(MAC_RCV_VALUE_14, 0); -+ case 14: -+ tw32(MAC_RCV_RULE_13, 0); tw32(MAC_RCV_VALUE_13, 0); -+ case 13: -+ tw32(MAC_RCV_RULE_12, 0); tw32(MAC_RCV_VALUE_12, 0); -+ case 12: -+ tw32(MAC_RCV_RULE_11, 0); tw32(MAC_RCV_VALUE_11, 0); -+ case 11: -+ tw32(MAC_RCV_RULE_10, 0); tw32(MAC_RCV_VALUE_10, 0); -+ case 10: -+ tw32(MAC_RCV_RULE_9, 0); tw32(MAC_RCV_VALUE_9, 0); -+ case 9: -+ tw32(MAC_RCV_RULE_8, 0); tw32(MAC_RCV_VALUE_8, 0); -+ case 8: -+ tw32(MAC_RCV_RULE_7, 0); tw32(MAC_RCV_VALUE_7, 0); -+ case 7: -+ tw32(MAC_RCV_RULE_6, 0); tw32(MAC_RCV_VALUE_6, 0); -+ case 6: -+ tw32(MAC_RCV_RULE_5, 0); tw32(MAC_RCV_VALUE_5, 0); -+ case 5: -+ tw32(MAC_RCV_RULE_4, 0); tw32(MAC_RCV_VALUE_4, 0); -+ case 4: -+ /* tw32(MAC_RCV_RULE_3, 0); tw32(MAC_RCV_VALUE_3, 0); */ -+ case 3: -+ /* tw32(MAC_RCV_RULE_2, 0); tw32(MAC_RCV_VALUE_2, 0); */ -+ case 2: -+ case 1: -+ -+ default: -+ break; -+ } -+ -+ if (tg3_flag(tp, ENABLE_APE)) -+ /* Write our heartbeat update interval to APE. */ -+ tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_INT_MS, -+ APE_HOST_HEARTBEAT_INT_5SEC); -+ -+ tg3_write_sig_post_reset(tp, RESET_KIND_INIT); -+ -+ return 0; -+} -+ -+/* Called at device open time to get the chip ready for -+ * packet processing. Invoked with tp->lock held. -+ */ -+static int tg3_init_hw(struct tg3 *tp, bool reset_phy) -+{ -+ /* Chip may have been just powered on. If so, the boot code may still -+ * be running initialization. Wait for it to finish to avoid races in -+ * accessing the hardware. -+ */ -+ tg3_enable_register_access(tp); -+ tg3_poll_fw(tp); -+ -+ tg3_switch_clocks(tp); -+ -+ tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); -+ -+ return tg3_reset_hw(tp, reset_phy); -+} -+ -+#if IS_ENABLED(CONFIG_HWMON) && !defined(__VMKLNX__) -+static void tg3_sd_scan_scratchpad(struct tg3 *tp, struct tg3_ocir *ocir) -+{ -+ int i; -+ -+ for (i = 0; i < TG3_SD_NUM_RECS; i++, ocir++) { -+ u32 off = i * TG3_OCIR_LEN, len = TG3_OCIR_LEN; -+ -+ tg3_ape_scratchpad_read(tp, (u32 *) ocir, off, len); -+ off += len; -+ -+ if (ocir->signature != TG3_OCIR_SIG_MAGIC || -+ !(ocir->version_flags & TG3_OCIR_FLAG_ACTIVE)) -+ memset(ocir, 0, TG3_OCIR_LEN); -+ } -+} -+ -+/* sysfs attributes for hwmon */ -+static ssize_t tg3_show_temp(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ struct pci_dev *pdev = to_pci_dev(dev); -+ struct net_device *netdev = pci_get_drvdata(pdev); -+ struct tg3 *tp = netdev_priv(netdev); -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ u32 temperature; -+ -+ rtnl_lock(); -+ spin_lock_bh(&tp->lock); -+ tg3_ape_scratchpad_read(tp, &temperature, attr->index, -+ sizeof(temperature)); -+ spin_unlock_bh(&tp->lock); -+ rtnl_unlock(); -+ return sprintf(buf, "%u\n", temperature); -+} -+ -+ -+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tg3_show_temp, NULL, -+ TG3_TEMP_SENSOR_OFFSET); -+static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, tg3_show_temp, NULL, -+ TG3_TEMP_CAUTION_OFFSET); -+static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, tg3_show_temp, NULL, -+ TG3_TEMP_MAX_OFFSET); -+ -+static struct attribute *tg3_attributes[] = { -+ &sensor_dev_attr_temp1_input.dev_attr.attr, -+ &sensor_dev_attr_temp1_crit.dev_attr.attr, -+ &sensor_dev_attr_temp1_max.dev_attr.attr, -+ NULL -+}; -+ -+static const struct attribute_group tg3_group = { -+ .attrs = tg3_attributes, -+}; -+ -+#endif -+ -+static void tg3_hwmon_close(struct tg3 *tp) -+{ -+#if IS_ENABLED(CONFIG_HWMON) && !defined(__VMKLNX__) -+ if (tp->hwmon_dev) { -+ hwmon_device_unregister(tp->hwmon_dev); -+ tp->hwmon_dev = NULL; -+ sysfs_remove_group(&tp->pdev->dev.kobj, &tg3_group); -+ } -+#endif -+} -+ -+static void tg3_hwmon_open(struct tg3 *tp) -+{ -+#if IS_ENABLED(CONFIG_HWMON) && !defined(__VMKLNX__) -+ int i, err; -+ u32 size = 0; -+ struct pci_dev *pdev = tp->pdev; -+ struct tg3_ocir ocirs[TG3_SD_NUM_RECS]; -+ -+ tg3_sd_scan_scratchpad(tp, ocirs); -+ -+ for (i = 0; i < TG3_SD_NUM_RECS; i++) { -+ if (!ocirs[i].src_data_length) -+ continue; -+ -+ size += ocirs[i].src_hdr_length; -+ size += ocirs[i].src_data_length; -+ } -+ -+ if (!size) -+ return; -+ -+ /* Register hwmon sysfs hooks */ -+ err = sysfs_create_group(&pdev->dev.kobj, &tg3_group); -+ if (err) { -+ dev_err(&pdev->dev, "Cannot create sysfs group, aborting\n"); -+ return; -+ } -+ -+ tp->hwmon_dev = hwmon_device_register(&pdev->dev); -+ if (IS_ERR(tp->hwmon_dev)) { -+ tp->hwmon_dev = NULL; -+ dev_err(&pdev->dev, "Cannot register hwmon device, aborting\n"); -+ sysfs_remove_group(&pdev->dev.kobj, &tg3_group); -+ } -+#endif -+} -+ -+#define TG3_STAT_ADD32(PSTAT, REG) \ -+do { u32 __val = tr32(REG); \ -+ (PSTAT)->low += __val; \ -+ if ((PSTAT)->low < __val) \ -+ (PSTAT)->high += 1; \ -+} while (0) -+ -+static void tg3_periodic_fetch_stats(struct tg3 *tp) -+{ -+ struct tg3_hw_stats *sp = tp->hw_stats; -+ -+ if (!tp->link_up) -+ return; -+ -+ TG3_STAT_ADD32(&sp->tx_octets, MAC_TX_STATS_OCTETS); -+ TG3_STAT_ADD32(&sp->tx_collisions, MAC_TX_STATS_COLLISIONS); -+ TG3_STAT_ADD32(&sp->tx_xon_sent, MAC_TX_STATS_XON_SENT); -+ TG3_STAT_ADD32(&sp->tx_xoff_sent, MAC_TX_STATS_XOFF_SENT); -+ TG3_STAT_ADD32(&sp->tx_mac_errors, MAC_TX_STATS_MAC_ERRORS); -+ TG3_STAT_ADD32(&sp->tx_single_collisions, MAC_TX_STATS_SINGLE_COLLISIONS); -+ TG3_STAT_ADD32(&sp->tx_mult_collisions, MAC_TX_STATS_MULT_COLLISIONS); -+ TG3_STAT_ADD32(&sp->tx_deferred, MAC_TX_STATS_DEFERRED); -+ TG3_STAT_ADD32(&sp->tx_excessive_collisions, MAC_TX_STATS_EXCESSIVE_COL); -+ TG3_STAT_ADD32(&sp->tx_late_collisions, MAC_TX_STATS_LATE_COL); -+ TG3_STAT_ADD32(&sp->tx_ucast_packets, MAC_TX_STATS_UCAST); -+ TG3_STAT_ADD32(&sp->tx_mcast_packets, MAC_TX_STATS_MCAST); -+ TG3_STAT_ADD32(&sp->tx_bcast_packets, MAC_TX_STATS_BCAST); -+ if (unlikely(tg3_flag(tp, 5719_5720_RDMA_BUG) && -+ (sp->tx_ucast_packets.low + sp->tx_mcast_packets.low + -+ sp->tx_bcast_packets.low) > TG3_NUM_RDMA_CHANNELS)) { -+ u32 val; -+ -+ val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL); -+ val &= ~tg3_lso_rd_dma_workaround_bit(tp); -+ tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val); -+ tg3_flag_clear(tp, 5719_5720_RDMA_BUG); -+ } -+ -+ TG3_STAT_ADD32(&sp->rx_octets, MAC_RX_STATS_OCTETS); -+ TG3_STAT_ADD32(&sp->rx_fragments, MAC_RX_STATS_FRAGMENTS); -+ TG3_STAT_ADD32(&sp->rx_ucast_packets, MAC_RX_STATS_UCAST); -+ TG3_STAT_ADD32(&sp->rx_mcast_packets, MAC_RX_STATS_MCAST); -+ TG3_STAT_ADD32(&sp->rx_bcast_packets, MAC_RX_STATS_BCAST); -+ TG3_STAT_ADD32(&sp->rx_fcs_errors, MAC_RX_STATS_FCS_ERRORS); -+ TG3_STAT_ADD32(&sp->rx_align_errors, MAC_RX_STATS_ALIGN_ERRORS); -+ TG3_STAT_ADD32(&sp->rx_xon_pause_rcvd, MAC_RX_STATS_XON_PAUSE_RECVD); -+ TG3_STAT_ADD32(&sp->rx_xoff_pause_rcvd, MAC_RX_STATS_XOFF_PAUSE_RECVD); -+ TG3_STAT_ADD32(&sp->rx_mac_ctrl_rcvd, MAC_RX_STATS_MAC_CTRL_RECVD); -+ TG3_STAT_ADD32(&sp->rx_xoff_entered, MAC_RX_STATS_XOFF_ENTERED); -+ TG3_STAT_ADD32(&sp->rx_frame_too_long_errors, MAC_RX_STATS_FRAME_TOO_LONG); -+ TG3_STAT_ADD32(&sp->rx_jabbers, MAC_RX_STATS_JABBERS); -+ TG3_STAT_ADD32(&sp->rx_undersize_packets, MAC_RX_STATS_UNDERSIZE); -+ -+ TG3_STAT_ADD32(&sp->rxbds_empty, RCVLPC_NO_RCV_BD_CNT); -+ if (tg3_asic_rev(tp) != ASIC_REV_5717 && -+ tg3_asic_rev(tp) != ASIC_REV_5762 && -+ tg3_chip_rev_id(tp) != CHIPREV_ID_5719_A0 && -+ tg3_chip_rev_id(tp) != CHIPREV_ID_5720_A0) { -+ TG3_STAT_ADD32(&sp->rx_discards, RCVLPC_IN_DISCARDS_CNT); -+ } else { -+ u32 val = tr32(HOSTCC_FLOW_ATTN); -+ val = (val & HOSTCC_FLOW_ATTN_MBUF_LWM) ? 1 : 0; -+ if (val) { -+ tw32(HOSTCC_FLOW_ATTN, HOSTCC_FLOW_ATTN_MBUF_LWM); -+ sp->rx_discards.low += val; -+ if (sp->rx_discards.low < val) -+ sp->rx_discards.high += 1; -+ } -+ sp->mbuf_lwm_thresh_hit = sp->rx_discards; -+ } -+ TG3_STAT_ADD32(&sp->rx_errors, RCVLPC_IN_ERRORS_CNT); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tg3_vmware_fetch_stats(tp); -+#endif -+} -+ -+static void tg3_chk_missed_msi(struct tg3 *tp) -+{ -+ u32 i; -+ -+ for (i = 0; i < tp->irq_cnt; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (!(tnapi->netq.flags & TG3_NETQ_RXQ_ENABLED) && -+ !(tnapi->netq.flags & TG3_NETQ_TXQ_ALLOCATED)) -+ continue; -+#endif -+ -+ if (tg3_has_work(tnapi)) { -+ if (tnapi->last_rx_cons == tnapi->rx_rcb_ptr && -+ tnapi->last_tx_cons == tnapi->tx_cons) { -+ if (tnapi->chk_msi_cnt < 1) { -+ tnapi->chk_msi_cnt++; -+ return; -+ } -+#ifdef BCM_HAS_NEW_IRQ_SIG -+ tg3_msi(0, tnapi); -+#else -+ tg3_msi(0, tnapi, 0); -+#endif -+ } -+ } -+ tnapi->chk_msi_cnt = 0; -+ tnapi->last_rx_cons = tnapi->rx_rcb_ptr; -+ tnapi->last_tx_cons = tnapi->tx_cons; -+ } -+} -+ -+static void tg3_timer(unsigned long __opaque) -+{ -+ struct tg3 *tp = (struct tg3 *) __opaque; -+ -+ if (tp->irq_sync || tg3_flag(tp, RESET_TASK_PENDING)) -+ goto restart_timer; -+ -+ spin_lock(&tp->lock); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_flag(tp, 57765_CLASS)) -+ tg3_chk_missed_msi(tp); -+ -+ if (tg3_flag(tp, FLUSH_POSTED_WRITES)) { -+ /* BCM4785: Flush posted writes from GbE to host memory. */ -+ tr32(HOSTCC_MODE); -+ } -+ -+#if defined(__VMKLNX__) -+ tg3_vmware_timer(tp); -+#endif -+ -+ if (!tg3_flag(tp, TAGGED_STATUS)) { -+ /* All of this garbage is because when using non-tagged -+ * IRQ status the mailbox/status_block protocol the chip -+ * uses with the cpu is race prone. -+ */ -+ if (tp->napi[0].hw_status->status & SD_STATUS_UPDATED) { -+ tw32(GRC_LOCAL_CTRL, -+ tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); -+ } else { -+ tw32(HOSTCC_MODE, tp->coalesce_mode | -+ HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW); -+ } -+ -+ if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { -+ spin_unlock(&tp->lock); -+ tg3_reset_task_schedule(tp); -+ goto restart_timer; -+ } -+ } -+ -+ /* This part only runs once per second. */ -+ if (!--tp->timer_counter) { -+ if (tg3_flag(tp, 5705_PLUS)) -+ tg3_periodic_fetch_stats(tp); -+ -+ if (tp->setlpicnt && !--tp->setlpicnt) -+ tg3_phy_eee_enable(tp); -+ -+ if (tg3_flag(tp, USE_LINKCHG_REG)) { -+ u32 mac_stat; -+ int phy_event; -+ -+ mac_stat = tr32(MAC_STATUS); -+ -+ phy_event = 0; -+ if (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT) { -+ if (mac_stat & MAC_STATUS_MI_INTERRUPT) -+ phy_event = 1; -+ } else if (mac_stat & MAC_STATUS_LNKSTATE_CHANGED) -+ phy_event = 1; -+ -+ if (phy_event) -+ tg3_setup_phy(tp, false); -+ } else if (tg3_flag(tp, POLL_SERDES)) { -+ u32 mac_stat = tr32(MAC_STATUS); -+ int need_setup = 0; -+ -+ if (tp->link_up && -+ (mac_stat & MAC_STATUS_LNKSTATE_CHANGED)) { -+ need_setup = 1; -+ } -+ if (!tp->link_up && -+ (mac_stat & (MAC_STATUS_PCS_SYNCED | -+ MAC_STATUS_SIGNAL_DET))) { -+ need_setup = 1; -+ } -+ if (need_setup) { -+ if (!tp->serdes_counter) { -+ tw32_f(MAC_MODE, -+ (tp->mac_mode & -+ ~MAC_MODE_PORT_MODE_MASK)); -+ udelay(40); -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ } -+ tg3_setup_phy(tp, false); -+ } -+ } else if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) && -+ tg3_flag(tp, 5780_CLASS)) { -+ tg3_serdes_parallel_detect(tp); -+ } else if (tg3_flag(tp, POLL_CPMU_LINK)) { -+ u32 cpmu = tr32(TG3_CPMU_STATUS); -+ bool link_up = !((cpmu & TG3_CPMU_STATUS_LINK_MASK) == -+ TG3_CPMU_STATUS_LINK_MASK); -+ -+ if (link_up != tp->link_up) -+ tg3_setup_phy(tp, false); -+ } -+ -+ tp->timer_counter = tp->timer_multiplier; -+ } -+ -+ /* Heartbeat is only sent once every 2 seconds. -+ * -+ * The heartbeat is to tell the ASF firmware that the host -+ * driver is still alive. In the event that the OS crashes, -+ * ASF needs to reset the hardware to free up the FIFO space -+ * that may be filled with rx packets destined for the host. -+ * If the FIFO is full, ASF will no longer function properly. -+ * -+ * Unintended resets have been reported on real time kernels -+ * where the timer doesn't run on time. Netpoll will also have -+ * same problem. -+ * -+ * The new FWCMD_NICDRV_ALIVE3 command tells the ASF firmware -+ * to check the ring condition when the heartbeat is expiring -+ * before doing the reset. This will prevent most unintended -+ * resets. -+ */ -+ if (!--tp->asf_counter) { -+ if (tg3_flag(tp, ENABLE_ASF) && !tg3_flag(tp, ENABLE_APE)) { -+ tg3_wait_for_event_ack(tp); -+ -+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, -+ FWCMD_NICDRV_ALIVE3); -+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); -+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, -+ TG3_FW_UPDATE_TIMEOUT_SEC); -+ -+ tg3_generate_fw_event(tp); -+ } -+ tp->asf_counter = tp->asf_multiplier; -+ } -+ -+ /* Update the APE heartbeat every 5 seconds.*/ -+ tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL); -+ -+ spin_unlock(&tp->lock); -+ -+restart_timer: -+ tp->timer.expires = jiffies + tp->timer_offset; -+ add_timer(&tp->timer); -+} -+ -+static void __devinit tg3_timer_init(struct tg3 *tp) -+{ -+ if (tg3_flag(tp, TAGGED_STATUS) && -+ tg3_asic_rev(tp) != ASIC_REV_5717 && -+ !tg3_flag(tp, 57765_CLASS)) -+ tp->timer_offset = HZ; -+ else -+ tp->timer_offset = HZ / 10; -+ -+ BUG_ON(tp->timer_offset > HZ); -+ -+ tp->timer_multiplier = (HZ / tp->timer_offset); -+ tp->asf_multiplier = (HZ / tp->timer_offset) * -+ TG3_FW_UPDATE_FREQ_SEC; -+ -+ init_timer(&tp->timer); -+ tp->timer.data = (unsigned long) tp; -+ tp->timer.function = tg3_timer; -+} -+ -+static void tg3_timer_start(struct tg3 *tp) -+{ -+ tp->asf_counter = tp->asf_multiplier; -+ tp->timer_counter = tp->timer_multiplier; -+ -+ tp->timer.expires = jiffies + tp->timer_offset; -+ add_timer(&tp->timer); -+} -+ -+static void tg3_timer_stop(struct tg3 *tp) -+{ -+ del_timer_sync(&tp->timer); -+} -+ -+/* Restart hardware after configuration changes, self-test, etc. -+ * Invoked with tp->lock held. -+ */ -+static int tg3_restart_hw(struct tg3 *tp, bool reset_phy) -+ __releases(tp->lock) -+ __acquires(tp->lock) -+{ -+ int err; -+ -+ err = tg3_init_hw(tp, reset_phy); -+ if (err) { -+ netdev_err(tp->dev, -+ "Failed to re-initialize device, aborting\n"); -+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); -+ tg3_full_unlock(tp); -+ tg3_timer_stop(tp); -+ tp->irq_sync = 0; -+ tg3_napi_enable(tp); -+ dev_close(tp->dev); -+ tg3_full_lock(tp, 0); -+ } -+ return err; -+} -+ -+#ifdef BCM_HAS_NEW_INIT_WORK -+static void tg3_reset_task(struct work_struct *work) -+#else -+static void tg3_reset_task(void *_data) -+#endif -+{ -+#ifdef BCM_HAS_NEW_INIT_WORK -+ struct tg3 *tp = container_of(work, struct tg3, reset_task); -+#else -+ struct tg3 *tp = _data; -+#endif -+ int err; -+ -+ tg3_full_lock(tp, 0); -+ -+ if (!netif_running(tp->dev)) { -+ tg3_flag_clear(tp, RESET_TASK_PENDING); -+ tg3_full_unlock(tp); -+ return; -+ } -+ -+ tg3_full_unlock(tp); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ /* Prevent any netqueue operations while we are resetting. */ -+ if (tg3_flag(tp, ENABLE_IOV)) -+ rtnl_lock(); -+#endif -+ -+#if !defined(__VMKLNX__) -+ rtnl_lock(); -+ -+ if (tp->unrecoverable_err) { -+ dev_close(tp->dev); -+ netdev_err(tp->dev, "Device moved to closed state due to unrecoverable error\n"); -+ goto out2; -+ } -+#endif -+ -+ tg3_phy_stop(tp); -+ -+ tg3_netif_stop(tp); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tg3_netq_invalidate_state(tp); -+#endif -+ -+ tg3_full_lock(tp, 1); -+ -+ if (tg3_flag(tp, TX_RECOVERY_PENDING)) { -+ tp->write32_tx_mbox = tg3_write32_tx_mbox; -+ tp->write32_rx_mbox = tg3_write_flush_reg32; -+ tg3_flag_set(tp, MBOX_WRITE_REORDER); -+ tg3_flag_clear(tp, TX_RECOVERY_PENDING); -+ } -+ -+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); -+ err = tg3_init_hw(tp, true); -+#if defined(__VMKLNX__) -+ if (err) { -+ if (printk_ratelimit()) { -+ printk(KERN_ERR "tg3_init_hw failed in tg3_init_task\n"); -+ } -+ tp->irq_sync = 0; -+ tg3_napi_enable(tp); -+ goto out; -+ } -+#else /* !defined(__VMKLNX__) */ -+ if (err) -+ goto out; -+#endif /* defined(__VMKLNX__) */ -+ -+ tg3_netif_start(tp); -+ -+out: -+ tg3_full_unlock(tp); -+ -+ if (!err) -+ tg3_phy_start(tp); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (tg3_flag(tp, ENABLE_IOV)) -+ rtnl_unlock(); -+#endif -+ -+#if !defined(__VMKLNX__) -+out2: -+ rtnl_unlock(); -+#endif -+ -+ tg3_flag_clear(tp, RESET_TASK_PENDING); -+} -+ -+static int tg3_request_irq(struct tg3 *tp, int irq_num) -+{ -+#ifdef BCM_HAS_NEW_IRQ_SIG -+ irq_handler_t fn; -+#else -+ irqreturn_t (*fn)(int, void *, struct pt_regs *); -+#endif -+ unsigned long flags; -+ char *name; -+ struct tg3_napi *tnapi = &tp->napi[irq_num]; -+ -+ if (tp->irq_cnt == 1) -+ name = tp->dev->name; -+ else { -+ name = &tnapi->irq_lbl[0]; -+ if (tnapi->tx_buffers && tnapi->rx_rcb) -+ snprintf(name, IFNAMSIZ, -+ "%s-txrx-%d", tp->dev->name, irq_num); -+ else if (tnapi->tx_buffers) -+ snprintf(name, IFNAMSIZ, -+ "%s-tx-%d", tp->dev->name, irq_num); -+ else if (tnapi->rx_rcb) -+ snprintf(name, IFNAMSIZ, -+ "%s-rx-%d", tp->dev->name, irq_num); -+ else -+ snprintf(name, IFNAMSIZ, -+ "%s-%d", tp->dev->name, irq_num); -+ name[IFNAMSIZ-1] = 0; -+ } -+ -+ if (tg3_flag(tp, USING_MSI) || tg3_flag(tp, USING_MSIX)) { -+ fn = tg3_msi; -+ if (tg3_flag(tp, 1SHOT_MSI)) -+ fn = tg3_msi_1shot; -+ flags = 0; -+ } else { -+ fn = tg3_interrupt; -+ if (tg3_flag(tp, TAGGED_STATUS)) -+ fn = tg3_interrupt_tagged; -+ flags = IRQF_SHARED; -+ } -+ -+ return request_irq(tnapi->irq_vec, fn, flags, name, tnapi); -+} -+ -+static int tg3_test_interrupt(struct tg3 *tp) -+{ -+ struct tg3_napi *tnapi = &tp->napi[0]; -+ struct net_device *dev = tp->dev; -+ int err, i, intr_ok = 0; -+ u32 val; -+ -+ if (!netif_running(dev)) -+ return -ENODEV; -+ -+ tg3_disable_ints(tp); -+ -+ free_irq(tnapi->irq_vec, tnapi); -+ -+ /* -+ * Turn off MSI one shot mode. Otherwise this test has no -+ * observable way to know whether the interrupt was delivered. -+ */ -+ if (tg3_flag(tp, 57765_PLUS)) { -+ val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE; -+ tw32(MSGINT_MODE, val); -+ } -+ -+ err = request_irq(tnapi->irq_vec, tg3_test_isr, -+ IRQF_SHARED, dev->name, tnapi); -+ if (err) -+ return err; -+ -+ tnapi->hw_status->status &= ~SD_STATUS_UPDATED; -+ tg3_enable_ints(tp); -+ -+ tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | -+ tnapi->coal_now); -+ -+ for (i = 0; i < 5; i++) { -+ u32 int_mbox, misc_host_ctrl; -+ -+ int_mbox = tr32_mailbox(tnapi->int_mbox); -+ misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL); -+ -+ if ((int_mbox != 0) || -+ (misc_host_ctrl & MISC_HOST_CTRL_MASK_PCI_INT)) { -+ intr_ok = 1; -+ break; -+ } -+ -+ if (tg3_flag(tp, 57765_PLUS) && -+ tnapi->hw_status->status_tag != tnapi->last_tag) -+ tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24); -+ -+ msleep(10); -+ } -+ -+ tg3_disable_ints(tp); -+ -+ free_irq(tnapi->irq_vec, tnapi); -+ -+ err = tg3_request_irq(tp, 0); -+ -+ if (err) -+ return err; -+ -+ if (intr_ok) { -+ /* Reenable MSI one shot mode. */ -+ if (tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, 1SHOT_MSI)) { -+ val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE; -+ tw32(MSGINT_MODE, val); -+ } -+ return 0; -+ } -+ -+ return -EIO; -+} -+ -+#ifdef CONFIG_PCI_MSI -+/* Returns 0 if MSI test succeeds or MSI test fails and INTx mode is -+ * successfully restored -+ */ -+static int tg3_test_msi(struct tg3 *tp) -+{ -+ int err; -+ u16 pci_cmd; -+ -+ if (!tg3_flag(tp, USING_MSI)) -+ return 0; -+ -+ /* Turn off SERR reporting in case MSI terminates with Master -+ * Abort. -+ */ -+ pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd); -+ pci_write_config_word(tp->pdev, PCI_COMMAND, -+ pci_cmd & ~PCI_COMMAND_SERR); -+ -+ err = tg3_test_interrupt(tp); -+ -+ pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); -+ -+ if (!err) -+ return 0; -+ -+ /* other failures */ -+ if (err != -EIO) -+ return err; -+ -+ /* MSI test failed, go back to INTx mode */ -+ netdev_warn(tp->dev, "No interrupt was generated using MSI. Switching " -+ "to INTx mode. Please report this failure to the PCI " -+ "maintainer and include system chipset information\n"); -+ -+ free_irq(tp->napi[0].irq_vec, &tp->napi[0]); -+ -+ pci_disable_msi(tp->pdev); -+ -+ tg3_flag_clear(tp, USING_MSI); -+ tp->napi[0].irq_vec = tp->pdev->irq; -+ -+ err = tg3_request_irq(tp, 0); -+ if (err) -+ return err; -+ -+ /* Need to reset the chip because the MSI cycle may have terminated -+ * with Master Abort. -+ */ -+ tg3_full_lock(tp, 1); -+ -+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); -+ err = tg3_init_hw(tp, true); -+ -+ tg3_full_unlock(tp); -+ -+ if (err) -+ free_irq(tp->napi[0].irq_vec, &tp->napi[0]); -+ -+ return err; -+} -+#endif /* CONFIG_PCI_MSI */ -+ -+static int tg3_request_firmware(struct tg3 *tp) -+{ -+ const struct tg3_firmware_hdr *fw_hdr; -+ -+ if (tg3_priv_request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) { -+ netdev_err(tp->dev, "Failed to load firmware \"%s\"\n", -+ tp->fw_needed); -+ return -ENOENT; -+ } -+ -+ fw_hdr = (struct tg3_firmware_hdr *)tp->fw->data; -+ -+ /* Firmware blob starts with version numbers, followed by -+ * start address and _full_ length including BSS sections -+ * (which must be longer than the actual data, of course -+ */ -+ -+ tp->fw_len = fw_hdr->len; /* includes bss */ -+ if (tp->fw_len < (tp->fw->size - TG3_FW_HDR_LEN)) { -+ netdev_err(tp->dev, "bogus length %d in \"%s\"\n", -+ tp->fw_len, tp->fw_needed); -+ tg3_priv_release_firmware(tp->fw); -+ tp->fw = NULL; -+ return -EINVAL; -+ } -+ -+ /* We no longer need firmware; we have it. */ -+ tp->fw_needed = NULL; -+ return 0; -+} -+ -+#if defined(CONFIG_PCI_MSI) -+static bool tg3_ints_alloc_vectors(struct tg3 *tp) -+{ -+ int i, rc; -+ struct msix_entry msix_ent[TG3_IRQ_MAX_VECS]; -+ -+ for (i = 0; i < tp->irq_max; i++) { -+ msix_ent[i].entry = i; -+ msix_ent[i].vector = 0; -+ } -+ -+ rc = tp->irq_cnt; -+ while (1) { -+ int ret; -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (!tg3_flag(tp, IOV_CAPABLE)) -+#endif -+ /* If the kernel says that only two MSI-X -+ * vectors are available, fallback to a simpler -+ * single queue, single vector MSI-X mode. -+ */ -+ if (rc == 2) -+ rc--; -+ -+ ret = pci_enable_msix(tp->pdev, msix_ent, rc); -+ if (ret < 0) -+ return false; -+ else if (ret == 0) -+ break; -+ rc = ret; -+ } -+ tp->irq_cnt = rc; -+ -+ for (i = 0; i < tp->irq_max; i++) -+ tp->napi[i].irq_vec = msix_ent[i].vector; -+ -+ return true; -+} -+ -+static inline u32 tg3_irq_count(struct tg3 *tp) -+{ -+ u32 irq_cnt = max(tp->rxq_cnt, tp->txq_cnt); -+#if defined(TG3_INBOX) -+ return TG3_IRQ_MAX_VECS; -+#endif -+ if (irq_cnt > 1) { -+ /* We want as many rx rings enabled as there are cpus. -+ * In multiqueue MSI-X mode, the first MSI-X vector -+ * only deals with link interrupts, etc, so we add -+ * one to the number of vectors we are requesting. -+ */ -+ irq_cnt = min_t(unsigned, irq_cnt + 1, tp->irq_max); -+ } -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (tg3_flag(tp, IOV_CAPABLE)) -+ irq_cnt = tg3_netq_tune_vector_count(tp); -+#endif -+ -+ return irq_cnt; -+} -+ -+static bool tg3_enable_msix(struct tg3 *tp) -+{ -+ u32 cpus, irq_cnt; -+ -+ cpus = num_online_cpus(); -+ -+ tp->txq_cnt = tp->txq_req; -+ tp->rxq_cnt = tp->rxq_req; -+ -+ /* Disable multiple TX rings by default. Simple round-robin hardware -+ * scheduling of the TX rings can cause starvation of rings with -+ * small packets when other rings have TSO or jumbo packets. -+ */ -+ if (!tp->txq_cnt) -+ tp->txq_cnt = 1; -+ if (!tp->rxq_cnt) -+ tp->rxq_cnt = min(cpus, tp->rxq_max); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tg3_netq_limit_dflt_queue_counts(tp); -+#endif -+ -+ irq_cnt = tg3_irq_count(tp); -+ -+ tp->irq_cnt = irq_cnt; -+ while (tp->irq_cnt) { -+ u32 rxq_cnt, new_irq_cnt; -+ -+ if (!tg3_ints_alloc_vectors(tp)) -+ return false; -+ -+ /* If the number of interrupts is less than our desired queue -+ * count, adjust the queue count downwards to match. -+ */ -+ rxq_cnt = tp->irq_cnt; -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (!tg3_flag(tp, IOV_CAPABLE)) -+#endif -+ if (tp->irq_cnt > 1) -+ rxq_cnt--; -+ -+ rxq_cnt = min(rxq_cnt, tp->rxq_cnt); -+ tp->rxq_cnt = rxq_cnt; -+ -+#ifdef BCM_HAS_STRUCT_NETDEV_QUEUE -+ while (rxq_cnt) { -+ if (netif_set_real_num_rx_queues(tp->dev, rxq_cnt)) -+ rxq_cnt--; -+ else -+ break; -+ } -+ -+ if (!rxq_cnt) { -+ pci_disable_msix(tp->pdev); -+ return false; -+ } -+#endif /* BCM_HAS_STRUCT_NETDEV_QUEUE */ -+ -+ if (tp->rxq_cnt == rxq_cnt) -+ break; -+ -+ tp->rxq_cnt = rxq_cnt; -+ -+ /* See if we can free up any unused MSI-X vectors. */ -+ new_irq_cnt = tg3_irq_count(tp); -+ -+ /* If the IRQ count is the same, we need -+ * the extra interrupts for the tx side. -+ */ -+ if (irq_cnt == new_irq_cnt) -+ break; -+ -+ /* Free unused interrupts and reallocate the exact amount. */ -+ pci_disable_msix(tp->pdev); -+ tp->irq_cnt = new_irq_cnt; -+ } -+ -+ if (irq_cnt != tp->irq_cnt) -+ netdev_notice(tp->dev, -+ "Requested %d MSI-X vectors, received %d\n", -+ irq_cnt, tp->irq_cnt); -+ -+ if (tp->irq_cnt == 1) -+ return true; -+ -+ /* If more than one interrupt vector is allocated, we _need_ to enable -+ * either IOV mode or RSS mode, even if only one rx queue is desired. -+ * If we don't, TSS will not work. -+ */ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (tg3_flag(tp, IOV_CAPABLE)) { -+ tg3_flag_set(tp, ENABLE_IOV); -+ } else -+#endif -+ tg3_flag_set(tp, ENABLE_RSS); -+ -+ tp->txq_cnt = min(tp->txq_cnt, tp->irq_cnt - 1); -+ if (tp->txq_cnt > 1) -+ tg3_flag_set(tp, ENABLE_TSS); -+ -+#ifdef BCM_HAS_STRUCT_NETDEV_QUEUE -+ netif_set_real_num_tx_queues(tp->dev, tp->txq_cnt); -+#endif -+ -+ return true; -+} -+#endif -+ -+static void tg3_ints_init(struct tg3 *tp) -+{ -+#ifdef CONFIG_PCI_MSI -+ if ((tg3_flag(tp, SUPPORT_MSI) || tg3_flag(tp, SUPPORT_MSIX)) && -+ !tg3_flag(tp, TAGGED_STATUS)) { -+ /* All MSI supporting chips should support tagged -+ * status. Assert that this is the case. -+ */ -+ netdev_warn(tp->dev, -+ "MSI without TAGGED_STATUS? Not using MSI\n"); -+ goto defcfg; -+ } -+ -+ if (tg3_flag(tp, SUPPORT_MSIX) && tg3_enable_msix(tp)) -+ tg3_flag_set(tp, USING_MSIX); -+ else if (tg3_flag(tp, SUPPORT_MSI) && pci_enable_msi(tp->pdev) == 0) -+ tg3_flag_set(tp, USING_MSI); -+ -+ tg3_5780_class_intx_workaround(tp); -+ -+ if (tg3_flag(tp, USING_MSI) || tg3_flag(tp, USING_MSIX)) { -+ u32 msi_mode = tr32(MSGINT_MODE); -+ if (tg3_flag(tp, USING_MSIX) && tp->irq_cnt > 1) -+ msi_mode |= MSGINT_MODE_MULTIVEC_EN; -+ if (!tg3_flag(tp, 1SHOT_MSI)) -+ msi_mode |= MSGINT_MODE_ONE_SHOT_DISABLE; -+ tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE); -+ } -+defcfg: -+#endif -+ -+ if (!tg3_flag(tp, USING_MSIX)) { -+ tp->irq_cnt = 1; -+ tp->napi[0].irq_vec = tp->pdev->irq; -+ } -+ -+ if (tp->irq_cnt == 1) { -+ tp->txq_cnt = 1; -+ tp->rxq_cnt = 1; -+#ifdef BCM_HAS_STRUCT_NETDEV_QUEUE -+ netif_set_real_num_tx_queues(tp->dev, 1); -+ netif_set_real_num_rx_queues(tp->dev, 1); -+#endif -+ } -+} -+ -+static void tg3_ints_fini(struct tg3 *tp) -+{ -+#ifdef CONFIG_PCI_MSI -+ if (tg3_flag(tp, USING_MSIX)) -+ pci_disable_msix(tp->pdev); -+ else if (tg3_flag(tp, USING_MSI)) -+ pci_disable_msi(tp->pdev); -+#endif -+ tg3_flag_clear(tp, USING_MSI); -+ tg3_flag_clear(tp, USING_MSIX); -+ tg3_flag_clear(tp, ENABLE_RSS); -+ tg3_flag_clear(tp, ENABLE_TSS); -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tg3_flag_clear(tp, ENABLE_IOV); -+#endif -+} -+ -+static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq, -+ bool init) -+{ -+ struct net_device *dev = tp->dev; -+ int i, err; -+ -+ /* -+ * Setup interrupts first so we know how -+ * many NAPI resources to allocate -+ */ -+ tg3_ints_init(tp); -+ -+ tg3_rss_check_indir_tbl(tp); -+ -+ /* The placement of this call is tied -+ * to the setup and use of Host TX descriptors. -+ */ -+ err = tg3_alloc_consistent(tp); -+ if (err) -+ goto out_ints_fini; -+ -+ tg3_napi_init(tp); -+ -+ /* napi is disabled by default after init -+ * Assertion may occur when freeing an IRQ vector -+ * that has NAPI scheduled and associated. Thus, -+ * we need to ensure napi is disabled prior to -+ * freeing an irq. -+ */ -+ for (i = 0; i < tp->irq_cnt; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ err = tg3_request_irq(tp, i); -+ if (err) { -+ for (i--; i >= 0; i--) { -+ tnapi = &tp->napi[i]; -+ free_irq(tnapi->irq_vec, tnapi); -+ } -+ goto out_napi_fini; -+ } -+ } -+ -+ if (init) -+ tg3_ape_driver_state_change(tp, RESET_KIND_INIT); -+ -+ tg3_full_lock(tp, 0); -+ -+ err = tg3_init_hw(tp, reset_phy); -+ if (err) { -+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); -+ tg3_free_rings(tp); -+ } -+ -+ tg3_full_unlock(tp); -+ -+ if (err) -+ goto out_free_irq; -+ -+#ifdef CONFIG_PCI_MSI -+ if (test_irq && tg3_flag(tp, USING_MSI)) { -+ err = tg3_test_msi(tp); -+ -+ if (err) { -+ tg3_full_lock(tp, 0); -+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); -+ tg3_free_rings(tp); -+ tg3_full_unlock(tp); -+ -+ goto out_napi_fini; -+ } -+ -+ if (!tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) { -+ u32 val = tr32(PCIE_TRANSACTION_CFG); -+ -+ tw32(PCIE_TRANSACTION_CFG, -+ val | PCIE_TRANS_CFG_1SHOT_MSI); -+ } -+ } -+#endif -+ -+ tg3_napi_enable(tp); -+ -+ tg3_phy_start(tp); -+ -+ tg3_hwmon_open(tp); -+ -+ tg3_full_lock(tp, 0); -+ -+ tg3_timer_start(tp); -+ -+ /* JIRA-20238: This fix is to make sure the first heartbeat -+ * occurs within 5 second interval even if the jiffy value -+ * is very high. When using time_after() check a higher jiffy -+ * value makes it –ve when it is type casted to long on 32 bit -+ * kernel, as long is only 4 bytes. Due to this time_after -+ * check will not provide incorrect result. -+ */ -+ if (tg3_flag(tp, ENABLE_APE)) -+ tp->ape_hb_jiffies = jiffies; -+ -+ tg3_flag_set(tp, INIT_COMPLETE); -+ if (init) -+ tg3_ptp_init(tp); -+ else -+ tg3_ptp_resume(tp); -+ -+ tg3_enable_ints(tp); -+ -+ tg3_full_unlock(tp); -+ -+ netif_tx_start_all_queues(dev); -+ -+#ifdef BCM_HAS_FIX_FEATURES -+ /* -+ * Reset loopback feature if it was turned on while the device was down -+ * make sure that it's installed properly now. -+ */ -+ if (dev->features & NETIF_F_LOOPBACK) -+ tg3_set_loopback(dev, dev->features); -+#endif -+ -+ return 0; -+ -+out_free_irq: -+ for (i = tp->irq_cnt - 1; i >= 0; i--) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ free_irq(tnapi->irq_vec, tnapi); -+ } -+ -+out_napi_fini: -+ tg3_napi_fini(tp); -+ tg3_free_consistent(tp); -+ -+out_ints_fini: -+ tg3_ints_fini(tp); -+ -+ return err; -+} -+ -+static void tg3_stop(struct tg3 *tp) -+{ -+ int i; -+ -+#if !defined(__VMKLNX__) -+ if (!tp->unrecoverable_err) -+ tg3_reset_task_cancel(tp); -+#else -+ tg3_reset_task_cancel(tp); -+#endif -+ -+ tg3_netif_stop(tp); -+ -+ tg3_timer_stop(tp); -+ -+ tg3_hwmon_close(tp); -+ -+ tg3_phy_stop(tp); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tg3_netq_invalidate_state(tp); -+#endif -+ -+ tg3_full_lock(tp, 1); -+ -+ tg3_disable_ints(tp); -+ -+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); -+ tg3_free_rings(tp); -+ tg3_flag_clear(tp, INIT_COMPLETE); -+ -+ tg3_full_unlock(tp); -+ -+ /* napi should be disabled after netif_stop already */ -+ for (i = tp->irq_cnt - 1; i >= 0; i--) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ free_irq(tnapi->irq_vec, tnapi); -+ } -+ -+ tg3_napi_fini(tp); -+ -+ tg3_ints_fini(tp); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tg3_netq_stats_clear(tp); -+#endif -+ -+ tg3_free_consistent(tp); -+} -+ -+static int tg3_open(struct net_device *dev) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ int err; -+ -+ if (tp->fw_needed) { -+ err = tg3_request_firmware(tp); -+ if (tg3_asic_rev(tp) == ASIC_REV_57766) { -+ if (err) { -+ netdev_warn(tp->dev, "EEE capability disabled\n"); -+ tp->phy_flags &= ~TG3_PHYFLG_EEE_CAP; -+ } else if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) { -+ netdev_warn(tp->dev, "EEE capability restored\n"); -+ tp->phy_flags |= TG3_PHYFLG_EEE_CAP; -+ } -+ } else if (tg3_chip_rev_id(tp) == CHIPREV_ID_5701_A0) { -+ if (err) -+ return err; -+ } else if (err) { -+ netdev_warn(tp->dev, "TSO capability disabled\n"); -+ tg3_flag_clear(tp, TSO_CAPABLE); -+ } else if (!tg3_flag(tp, TSO_CAPABLE)) { -+ netdev_notice(tp->dev, "TSO capability restored\n"); -+ tg3_flag_set(tp, TSO_CAPABLE); -+ } -+ } -+ -+ tg3_carrier_off(tp); -+ -+ err = tg3_power_up(tp); -+ if (err) -+ return err; -+ -+ tg3_full_lock(tp, 0); -+ -+ tg3_disable_ints(tp); -+ tg3_flag_clear(tp, INIT_COMPLETE); -+ -+ tg3_full_unlock(tp); -+ -+ err = tg3_start(tp, -+ !(tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN), -+ true, true); -+ if (err) { -+ tg3_frob_aux_power(tp, false); -+ pci_set_power_state(tp->pdev, PCI_D3hot); -+ } -+ -+#if IS_ENABLED(CONFIG_PTP_1588_CLOCK) -+ if (tg3_flag(tp, PTP_CAPABLE)) { -+#ifdef BCM_HAS_PTP_CLOCK_REG_HAS_PARENT -+ tp->ptp_clock = ptp_clock_register(&tp->ptp_info, -+ &tp->pdev->dev); -+#else -+ tp->ptp_clock = ptp_clock_register(&tp->ptp_info); -+#endif -+ if (IS_ERR(tp->ptp_clock)) -+ tp->ptp_clock = NULL; -+ } -+#endif -+ -+ return err; -+} -+ -+static int tg3_close(struct net_device *dev) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ tg3_ptp_fini(tp); -+ -+ tg3_stop(tp); -+ -+ tg3_flag_clear(tp, INIT_COMPLETE); -+ -+ /* Clear stats across close / open calls */ -+ memset(&tp->net_stats_prev, 0, sizeof(tp->net_stats_prev)); -+ memset(&tp->estats_prev, 0, sizeof(tp->estats_prev)); -+ -+ if (pci_device_is_present(tp->pdev)) { -+ tg3_power_down_prepare(tp); -+ -+ tg3_carrier_off(tp); -+ } -+ return 0; -+} -+ -+static inline u64 get_stat64(tg3_stat64_t *val) -+{ -+ return ((u64)val->high << 32) | ((u64)val->low); -+} -+ -+static u64 tg3_calc_crc_errors(struct tg3 *tp) -+{ -+ struct tg3_hw_stats *hw_stats = tp->hw_stats; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && -+ (tg3_asic_rev(tp) == ASIC_REV_5700 || -+ tg3_asic_rev(tp) == ASIC_REV_5701)) { -+ u32 val; -+ -+ if (!tg3_readphy(tp, MII_TG3_TEST1, &val)) { -+ tg3_writephy(tp, MII_TG3_TEST1, -+ val | MII_TG3_TEST1_CRC_EN); -+ tg3_readphy(tp, MII_TG3_RXR_COUNTERS, &val); -+ } else -+ val = 0; -+ -+ tp->phy_crc_errors += val; -+ -+ return tp->phy_crc_errors; -+ } -+ -+ return get_stat64(&hw_stats->rx_fcs_errors); -+} -+ -+#define ESTAT_ADD(member) \ -+ estats->member = old_estats->member + \ -+ get_stat64(&hw_stats->member) -+ -+static void tg3_get_estats(struct tg3 *tp, struct tg3_ethtool_stats *estats) -+{ -+ struct tg3_ethtool_stats *old_estats = &tp->estats_prev; -+ struct tg3_hw_stats *hw_stats = tp->hw_stats; -+ -+ ESTAT_ADD(rx_octets); -+ ESTAT_ADD(rx_fragments); -+ ESTAT_ADD(rx_ucast_packets); -+ ESTAT_ADD(rx_mcast_packets); -+ ESTAT_ADD(rx_bcast_packets); -+ ESTAT_ADD(rx_fcs_errors); -+ ESTAT_ADD(rx_align_errors); -+ ESTAT_ADD(rx_xon_pause_rcvd); -+ ESTAT_ADD(rx_xoff_pause_rcvd); -+ ESTAT_ADD(rx_mac_ctrl_rcvd); -+ ESTAT_ADD(rx_xoff_entered); -+ ESTAT_ADD(rx_frame_too_long_errors); -+ ESTAT_ADD(rx_jabbers); -+ ESTAT_ADD(rx_undersize_packets); -+ ESTAT_ADD(rx_in_length_errors); -+ ESTAT_ADD(rx_out_length_errors); -+ ESTAT_ADD(rx_64_or_less_octet_packets); -+ ESTAT_ADD(rx_65_to_127_octet_packets); -+ ESTAT_ADD(rx_128_to_255_octet_packets); -+ ESTAT_ADD(rx_256_to_511_octet_packets); -+ ESTAT_ADD(rx_512_to_1023_octet_packets); -+ ESTAT_ADD(rx_1024_to_1522_octet_packets); -+ ESTAT_ADD(rx_1523_to_2047_octet_packets); -+ ESTAT_ADD(rx_2048_to_4095_octet_packets); -+ ESTAT_ADD(rx_4096_to_8191_octet_packets); -+ ESTAT_ADD(rx_8192_to_9022_octet_packets); -+ -+ ESTAT_ADD(tx_octets); -+ ESTAT_ADD(tx_collisions); -+ ESTAT_ADD(tx_xon_sent); -+ ESTAT_ADD(tx_xoff_sent); -+ ESTAT_ADD(tx_flow_control); -+ ESTAT_ADD(tx_mac_errors); -+ ESTAT_ADD(tx_single_collisions); -+ ESTAT_ADD(tx_mult_collisions); -+ ESTAT_ADD(tx_deferred); -+ ESTAT_ADD(tx_excessive_collisions); -+ ESTAT_ADD(tx_late_collisions); -+ ESTAT_ADD(tx_collide_2times); -+ ESTAT_ADD(tx_collide_3times); -+ ESTAT_ADD(tx_collide_4times); -+ ESTAT_ADD(tx_collide_5times); -+ ESTAT_ADD(tx_collide_6times); -+ ESTAT_ADD(tx_collide_7times); -+ ESTAT_ADD(tx_collide_8times); -+ ESTAT_ADD(tx_collide_9times); -+ ESTAT_ADD(tx_collide_10times); -+ ESTAT_ADD(tx_collide_11times); -+ ESTAT_ADD(tx_collide_12times); -+ ESTAT_ADD(tx_collide_13times); -+ ESTAT_ADD(tx_collide_14times); -+ ESTAT_ADD(tx_collide_15times); -+ ESTAT_ADD(tx_ucast_packets); -+ ESTAT_ADD(tx_mcast_packets); -+ ESTAT_ADD(tx_bcast_packets); -+ ESTAT_ADD(tx_carrier_sense_errors); -+ ESTAT_ADD(tx_discards); -+ ESTAT_ADD(tx_errors); -+ -+ ESTAT_ADD(dma_writeq_full); -+ ESTAT_ADD(dma_write_prioq_full); -+ ESTAT_ADD(rxbds_empty); -+ ESTAT_ADD(rx_discards); -+ ESTAT_ADD(rx_errors); -+ ESTAT_ADD(rx_threshold_hit); -+ -+ ESTAT_ADD(dma_readq_full); -+ ESTAT_ADD(dma_read_prioq_full); -+ ESTAT_ADD(tx_comp_queue_full); -+ -+ ESTAT_ADD(ring_set_send_prod_index); -+ ESTAT_ADD(ring_status_update); -+ ESTAT_ADD(nic_irqs); -+ ESTAT_ADD(nic_avoided_irqs); -+ ESTAT_ADD(nic_tx_threshold_hit); -+ -+ ESTAT_ADD(mbuf_lwm_thresh_hit); -+ estats->dma_4g_cross = tp->dma_4g_cross; -+#if !defined(__VMKLNX__) -+ estats->recoverable_err = tp->recoverable_err; -+ estats->unrecoverable_err = tp->unrecoverable_err; -+#endif -+} -+ -+static void tg3_get_nstats(struct tg3 *tp, struct rtnl_link_stats64 *stats) -+{ -+ struct rtnl_link_stats64 *old_stats = &tp->net_stats_prev; -+ struct tg3_hw_stats *hw_stats = tp->hw_stats; -+ -+ stats->rx_packets = old_stats->rx_packets + -+ get_stat64(&hw_stats->rx_ucast_packets) + -+ get_stat64(&hw_stats->rx_mcast_packets) + -+ get_stat64(&hw_stats->rx_bcast_packets); -+ -+ stats->tx_packets = old_stats->tx_packets + -+ get_stat64(&hw_stats->tx_ucast_packets) + -+ get_stat64(&hw_stats->tx_mcast_packets) + -+ get_stat64(&hw_stats->tx_bcast_packets); -+ -+ stats->rx_bytes = old_stats->rx_bytes + -+ get_stat64(&hw_stats->rx_octets); -+ stats->tx_bytes = old_stats->tx_bytes + -+ get_stat64(&hw_stats->tx_octets); -+ -+ stats->rx_errors = old_stats->rx_errors + -+ get_stat64(&hw_stats->rx_errors); -+ stats->tx_errors = old_stats->tx_errors + -+ get_stat64(&hw_stats->tx_errors) + -+ get_stat64(&hw_stats->tx_mac_errors) + -+ get_stat64(&hw_stats->tx_carrier_sense_errors) + -+ get_stat64(&hw_stats->tx_discards); -+ -+ stats->multicast = old_stats->multicast + -+ get_stat64(&hw_stats->rx_mcast_packets); -+ stats->collisions = old_stats->collisions + -+ get_stat64(&hw_stats->tx_collisions); -+ -+ stats->rx_length_errors = old_stats->rx_length_errors + -+ get_stat64(&hw_stats->rx_frame_too_long_errors) + -+ get_stat64(&hw_stats->rx_undersize_packets); -+ -+ stats->rx_frame_errors = old_stats->rx_frame_errors + -+ get_stat64(&hw_stats->rx_align_errors); -+ stats->tx_aborted_errors = old_stats->tx_aborted_errors + -+ get_stat64(&hw_stats->tx_discards); -+ stats->tx_carrier_errors = old_stats->tx_carrier_errors + -+ get_stat64(&hw_stats->tx_carrier_sense_errors); -+ -+ stats->rx_crc_errors = old_stats->rx_crc_errors + -+ tg3_calc_crc_errors(tp); -+ -+ stats->rx_missed_errors = old_stats->rx_missed_errors + -+ get_stat64(&hw_stats->rx_discards); -+ -+ stats->rx_dropped = tp->rx_dropped; -+ stats->tx_dropped = tp->tx_dropped; -+} -+ -+static int tg3_get_regs_len(struct net_device *dev) -+{ -+ return TG3_REG_BLK_SIZE; -+} -+ -+static void tg3_get_regs(struct net_device *dev, -+ struct ethtool_regs *regs, void *_p) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ regs->version = 0; -+ -+ memset(_p, 0, TG3_REG_BLK_SIZE); -+ -+ if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) -+ return; -+ -+ tg3_full_lock(tp, 0); -+ -+ tg3_dump_legacy_regs(tp, (u32 *)_p); -+ -+ tg3_full_unlock(tp); -+} -+ -+#if (LINUX_VERSION_CODE >= 0x20418) -+static int tg3_get_eeprom_len(struct net_device *dev) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ return tp->nvram_size; -+} -+#endif -+ -+#ifdef ETHTOOL_GEEPROM -+static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ int ret, cpmu_restore = 0; -+ u8 *pd; -+ u32 i, offset, len, b_offset, b_count, cpmu_val = 0; -+ __be32 val; -+ -+ if (tg3_flag(tp, NO_NVRAM)) -+ return -EINVAL; -+ -+ offset = eeprom->offset; -+ len = eeprom->len; -+ eeprom->len = 0; -+ -+ eeprom->magic = TG3_EEPROM_MAGIC; -+ -+ /* Override clock, link aware and link idle modes */ -+ if (tg3_flag(tp, CPMU_PRESENT)) { -+ cpmu_val = tr32(TG3_CPMU_CTRL); -+ if (cpmu_val & (CPMU_CTRL_LINK_AWARE_MODE | -+ CPMU_CTRL_LINK_IDLE_MODE)) { -+ tw32(TG3_CPMU_CTRL, cpmu_val & -+ ~(CPMU_CTRL_LINK_AWARE_MODE | -+ CPMU_CTRL_LINK_IDLE_MODE)); -+ cpmu_restore = 1; -+ } -+ } -+ tg3_override_clk(tp); -+ -+ if (offset & 3) { -+ /* adjustments to start on required 4 byte boundary */ -+ b_offset = offset & 3; -+ b_count = 4 - b_offset; -+ if (b_count > len) { -+ /* i.e. offset=1 len=2 */ -+ b_count = len; -+ } -+ ret = tg3_nvram_read_be32(tp, offset-b_offset, &val); -+ if (ret) -+ goto eeprom_done; -+ memcpy(data, ((char *)&val) + b_offset, b_count); -+ len -= b_count; -+ offset += b_count; -+ eeprom->len += b_count; -+ } -+ -+ /* read bytes up to the last 4 byte boundary */ -+ pd = &data[eeprom->len]; -+ for (i = 0; i < (len - (len & 3)); i += 4) { -+ ret = tg3_nvram_read_be32(tp, offset + i, &val); -+ if (ret) { -+ if (i) -+ i -= 4; -+ eeprom->len += i; -+ goto eeprom_done; -+ } -+ memcpy(pd + i, &val, 4); -+ if (need_resched()) { -+ if (signal_pending(current)) { -+ eeprom->len += i; -+ ret = -EINTR; -+ goto eeprom_done; -+ } -+ cond_resched(); -+ } -+ } -+ eeprom->len += i; -+ -+ if (len & 3) { -+ /* read last bytes not ending on 4 byte boundary */ -+ pd = &data[eeprom->len]; -+ b_count = len & 3; -+ b_offset = offset + len - b_count; -+ ret = tg3_nvram_read_be32(tp, b_offset, &val); -+ if (ret) -+ goto eeprom_done; -+ memcpy(pd, &val, b_count); -+ eeprom->len += b_count; -+ } -+ ret = 0; -+ -+eeprom_done: -+ /* Restore clock, link aware and link idle modes */ -+ tg3_restore_clk(tp); -+ if (cpmu_restore) -+ tw32(TG3_CPMU_CTRL, cpmu_val); -+ -+ return ret; -+} -+#endif -+ -+#ifdef ETHTOOL_SEEPROM -+static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ int ret; -+ u32 offset, len, b_offset, odd_len; -+ u8 *buf; -+ __be32 start, end; -+ -+ if (tg3_flag(tp, NO_NVRAM) || -+ eeprom->magic != TG3_EEPROM_MAGIC) -+ return -EINVAL; -+ -+ offset = eeprom->offset; -+ len = eeprom->len; -+ -+ if ((b_offset = (offset & 3))) { -+ /* adjustments to start on required 4 byte boundary */ -+ ret = tg3_nvram_read_be32(tp, offset-b_offset, &start); -+ if (ret) -+ return ret; -+ len += b_offset; -+ offset &= ~3; -+ if (len < 4) -+ len = 4; -+ } -+ -+ odd_len = 0; -+ if (len & 3) { -+ /* adjustments to end on required 4 byte boundary */ -+ odd_len = 1; -+ len = (len + 3) & ~3; -+ ret = tg3_nvram_read_be32(tp, offset+len-4, &end); -+ if (ret) -+ return ret; -+ } -+ -+ buf = data; -+ if (b_offset || odd_len) { -+ buf = kmalloc(len, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ if (b_offset) -+ memcpy(buf, &start, 4); -+ if (odd_len) -+ memcpy(buf+len-4, &end, 4); -+ memcpy(buf + b_offset, data, eeprom->len); -+ } -+ -+ ret = tg3_nvram_write_block(tp, offset, len, buf); -+ -+ if (buf != data) -+ kfree(buf); -+ -+ return ret; -+} -+#endif -+ -+static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_flag(tp, USE_PHYLIB)) { -+ struct phy_device *phydev; -+ if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) -+ return -EAGAIN; -+ phydev = tp->mdio_bus->phy_map[tp->phy_addr]; -+ return phy_ethtool_gset(phydev, cmd); -+ } -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+ -+ cmd->supported = (SUPPORTED_Autoneg); -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) -+ cmd->supported |= (SUPPORTED_1000baseT_Half | -+ SUPPORTED_1000baseT_Full); -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) { -+ cmd->supported |= (SUPPORTED_100baseT_Half | -+ SUPPORTED_100baseT_Full | -+ SUPPORTED_10baseT_Half | -+ SUPPORTED_10baseT_Full | -+ SUPPORTED_TP); -+ cmd->port = PORT_TP; -+ } else { -+ cmd->supported |= SUPPORTED_FIBRE; -+ cmd->port = PORT_FIBRE; -+ } -+ -+ cmd->advertising = tp->link_config.advertising; -+ if (tg3_flag(tp, PAUSE_AUTONEG)) { -+ if (tp->link_config.flowctrl & FLOW_CTRL_RX) { -+ if (tp->link_config.flowctrl & FLOW_CTRL_TX) { -+ cmd->advertising |= ADVERTISED_Pause; -+ } else { -+ cmd->advertising |= ADVERTISED_Pause | -+ ADVERTISED_Asym_Pause; -+ } -+ } else if (tp->link_config.flowctrl & FLOW_CTRL_TX) { -+ cmd->advertising |= ADVERTISED_Asym_Pause; -+ } -+ } -+ if (netif_running(dev) && tp->link_up) { -+ ethtool_cmd_speed_set(cmd, tp->link_config.active_speed); -+ cmd->duplex = tp->link_config.active_duplex; -+#ifdef BCM_HAS_LP_ADVERTISING -+ cmd->lp_advertising = tp->link_config.rmt_adv; -+#endif /* BCM_HAS_LP_ADVERTISING */ -+#ifdef BCM_HAS_MDIX_STATUS -+ if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) { -+ if (tp->phy_flags & TG3_PHYFLG_MDIX_STATE) -+ cmd->eth_tp_mdix = ETH_TP_MDI_X; -+ else -+ cmd->eth_tp_mdix = ETH_TP_MDI; -+ } -+#endif /* BCM_HAS_MDIX_STATUS */ -+ } else { -+ ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN); -+ cmd->duplex = DUPLEX_UNKNOWN; -+#ifdef BCM_HAS_MDIX_STATUS -+ cmd->eth_tp_mdix = ETH_TP_MDI_INVALID; -+#endif /* BCM_HAS_MDIX_STATUS */ -+ } -+ cmd->phy_address = tp->phy_addr; -+ cmd->transceiver = XCVR_INTERNAL; -+ cmd->autoneg = tp->link_config.autoneg; -+ cmd->maxtxpkt = 0; -+ cmd->maxrxpkt = 0; -+ return 0; -+} -+ -+static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ u32 speed = ethtool_cmd_speed(cmd); -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_flag(tp, USE_PHYLIB)) { -+ struct phy_device *phydev; -+ if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) -+ return -EAGAIN; -+ phydev = tp->mdio_bus->phy_map[tp->phy_addr]; -+ return phy_ethtool_sset(phydev, cmd); -+ } -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+ -+ if (cmd->autoneg != AUTONEG_ENABLE && -+ cmd->autoneg != AUTONEG_DISABLE) -+ return -EINVAL; -+ -+ if (cmd->autoneg == AUTONEG_DISABLE && -+ cmd->duplex != DUPLEX_FULL && -+ cmd->duplex != DUPLEX_HALF) -+ return -EINVAL; -+ -+ if (cmd->autoneg == AUTONEG_ENABLE) { -+ u32 mask = ADVERTISED_Autoneg | -+ ADVERTISED_Pause | -+ ADVERTISED_Asym_Pause; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) -+ mask |= ADVERTISED_1000baseT_Half | -+ ADVERTISED_1000baseT_Full; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) -+ mask |= ADVERTISED_100baseT_Half | -+ ADVERTISED_100baseT_Full | -+ ADVERTISED_10baseT_Half | -+ ADVERTISED_10baseT_Full | -+ ADVERTISED_TP; -+ else -+ mask |= ADVERTISED_FIBRE; -+ -+ if (cmd->advertising & ~mask) -+ return -EINVAL; -+ -+ mask &= (ADVERTISED_1000baseT_Half | -+ ADVERTISED_1000baseT_Full | -+ ADVERTISED_100baseT_Half | -+ ADVERTISED_100baseT_Full | -+ ADVERTISED_10baseT_Half | -+ ADVERTISED_10baseT_Full); -+ -+ cmd->advertising &= mask; -+ } else { -+ if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) { -+ if (speed != SPEED_1000) -+ return -EINVAL; -+ -+ if (cmd->duplex != DUPLEX_FULL) -+ return -EINVAL; -+ } else { -+ if (speed != SPEED_100 && -+ speed != SPEED_10) -+ return -EINVAL; -+ } -+ } -+ -+ tg3_full_lock(tp, 0); -+ -+ tp->link_config.autoneg = cmd->autoneg; -+ if (cmd->autoneg == AUTONEG_ENABLE) { -+ tp->link_config.advertising = (cmd->advertising | -+ ADVERTISED_Autoneg); -+ tp->link_config.speed = SPEED_UNKNOWN; -+ tp->link_config.duplex = DUPLEX_UNKNOWN; -+ } else { -+ tp->link_config.advertising = 0; -+ tp->link_config.speed = speed; -+ tp->link_config.duplex = cmd->duplex; -+ } -+ -+ tp->phy_flags |= TG3_PHYFLG_USER_CONFIGURED; -+ -+ tg3_warn_mgmt_link_flap(tp); -+ -+ if (netif_running(dev)) -+ tg3_setup_phy(tp, true); -+ -+ tg3_full_unlock(tp); -+ -+ return 0; -+} -+ -+static void tg3_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); -+ strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); -+ strlcpy(info->fw_version, tp->fw_ver, sizeof(info->fw_version)); -+ strlcpy(info->bus_info, pci_name(tp->pdev), sizeof(info->bus_info)); -+} -+ -+static void tg3_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (tg3_flag(tp, WOL_CAP) && device_can_wakeup(&tp->pdev->dev)) -+ wol->supported = WAKE_MAGIC; -+ else -+ wol->supported = 0; -+ wol->wolopts = 0; -+ if (tg3_flag(tp, WOL_ENABLE) && device_can_wakeup(&tp->pdev->dev)) -+ wol->wolopts = WAKE_MAGIC; -+ memset(&wol->sopass, 0, sizeof(wol->sopass)); -+} -+ -+static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+#ifdef BCM_HAS_DEVICE_WAKEUP_API -+ struct device *dp = &tp->pdev->dev; -+#endif -+ -+ if (wol->wolopts & ~WAKE_MAGIC) -+ return -EINVAL; -+ if ((wol->wolopts & WAKE_MAGIC) && -+ !(tg3_flag(tp, WOL_CAP) && device_can_wakeup(dp))) -+ return -EINVAL; -+ -+ device_set_wakeup_enable(dp, wol->wolopts & WAKE_MAGIC); -+ -+ if (wol->wolopts & WAKE_MAGIC) -+ tg3_flag_set(tp, WOL_ENABLE); -+ else -+ tg3_flag_clear(tp, WOL_ENABLE); -+ -+ return 0; -+} -+ -+static u32 tg3_get_msglevel(struct net_device *dev) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ return tp->msg_enable; -+} -+ -+static void tg3_set_msglevel(struct net_device *dev, u32 value) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ tp->msg_enable = value; -+} -+ -+static int tg3_nway_reset(struct net_device *dev) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ int r; -+ -+ if (!netif_running(dev)) -+ return -EAGAIN; -+ -+ if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) -+ return -EINVAL; -+ -+ tg3_warn_mgmt_link_flap(tp); -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_flag(tp, USE_PHYLIB)) { -+ if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) -+ return -EAGAIN; -+ r = phy_start_aneg(tp->mdio_bus->phy_map[tp->phy_addr]); -+ } else -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+ { -+ u32 bmcr; -+ -+ spin_lock_bh(&tp->lock); -+ r = -EINVAL; -+ tg3_readphy(tp, MII_BMCR, &bmcr); -+ if (!tg3_readphy(tp, MII_BMCR, &bmcr) && -+ ((bmcr & BMCR_ANENABLE) || -+ (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT))) { -+ tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART | -+ BMCR_ANENABLE); -+ r = 0; -+ } -+ spin_unlock_bh(&tp->lock); -+ } -+ -+ return r; -+} -+ -+static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ ering->rx_max_pending = tp->rx_std_ring_mask; -+ ering->rx_mini_max_pending = 0; -+ if (tg3_flag(tp, JUMBO_RING_ENABLE)) -+ ering->rx_jumbo_max_pending = tp->rx_jmb_ring_mask; -+ else -+ ering->rx_jumbo_max_pending = 0; -+ -+ ering->tx_max_pending = TG3_TX_RING_SIZE - 1; -+ -+ ering->rx_pending = tp->rx_pending; -+ ering->rx_mini_pending = 0; -+ if (tg3_flag(tp, JUMBO_RING_ENABLE)) -+ ering->rx_jumbo_pending = tp->rx_jumbo_pending; -+ else -+ ering->rx_jumbo_pending = 0; -+ -+ ering->tx_pending = tp->napi[0].tx_pending; -+} -+ -+static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ int i, irq_sync = 0, err = 0; -+ -+ if (!ering->rx_pending || (ering->rx_pending > tp->rx_std_ring_mask) || -+ (tg3_flag(tp, JUMBO_RING_ENABLE) && !ering->rx_jumbo_pending) || -+ (ering->rx_jumbo_pending > tp->rx_jmb_ring_mask) || -+ (ering->tx_pending > TG3_TX_RING_SIZE - 1) || -+ (ering->tx_pending <= MAX_SKB_FRAGS) || -+ (tg3_flag(tp, TSO_BUG) && -+ (ering->tx_pending <= (MAX_SKB_FRAGS * 3)))) -+ return -EINVAL; -+ -+ if (netif_running(dev)) { -+ tg3_phy_stop(tp); -+ tg3_netif_stop(tp); -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tg3_netq_invalidate_state(tp); -+#endif -+ irq_sync = 1; -+ } -+ -+ tg3_full_lock(tp, irq_sync); -+ -+ tp->rx_pending = ering->rx_pending; -+ -+ if (tg3_flag(tp, MAX_RXPEND_64) && -+ tp->rx_pending > 63) -+ tp->rx_pending = 63; -+ tp->rx_jumbo_pending = ering->rx_jumbo_pending; -+ -+ for (i = 0; i < tp->irq_max; i++) -+ tp->napi[i].tx_pending = ering->tx_pending; -+ -+ if (netif_running(dev)) { -+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); -+ err = tg3_restart_hw(tp, false); -+ if (!err) -+ tg3_netif_start(tp); -+ } -+ -+ tg3_full_unlock(tp); -+ -+ if (irq_sync && !err) -+ tg3_phy_start(tp); -+ -+ return err; -+} -+ -+static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ epause->autoneg = !!tg3_flag(tp, PAUSE_AUTONEG); -+ -+ if (tp->link_config.flowctrl & FLOW_CTRL_RX) -+ epause->rx_pause = 1; -+ else -+ epause->rx_pause = 0; -+ -+ if (tp->link_config.flowctrl & FLOW_CTRL_TX) -+ epause->tx_pause = 1; -+ else -+ epause->tx_pause = 0; -+} -+ -+static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ int err = 0; -+ -+ if (tp->link_config.autoneg == AUTONEG_ENABLE) -+ tg3_warn_mgmt_link_flap(tp); -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_flag(tp, USE_PHYLIB)) { -+ u32 newadv; -+ struct phy_device *phydev; -+ -+ phydev = tp->mdio_bus->phy_map[tp->phy_addr]; -+ -+ if (!(phydev->supported & SUPPORTED_Pause) || -+ (!(phydev->supported & SUPPORTED_Asym_Pause) && -+ (epause->rx_pause != epause->tx_pause))) -+ return -EINVAL; -+ -+ tp->link_config.flowctrl = 0; -+ if (epause->rx_pause) { -+ tp->link_config.flowctrl |= FLOW_CTRL_RX; -+ -+ if (epause->tx_pause) { -+ tp->link_config.flowctrl |= FLOW_CTRL_TX; -+ newadv = ADVERTISED_Pause; -+ } else -+ newadv = ADVERTISED_Pause | -+ ADVERTISED_Asym_Pause; -+ } else if (epause->tx_pause) { -+ tp->link_config.flowctrl |= FLOW_CTRL_TX; -+ newadv = ADVERTISED_Asym_Pause; -+ } else -+ newadv = 0; -+ -+ if (epause->autoneg) -+ tg3_flag_set(tp, PAUSE_AUTONEG); -+ else -+ tg3_flag_clear(tp, PAUSE_AUTONEG); -+ -+ if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) { -+ u32 oldadv = phydev->advertising & -+ (ADVERTISED_Pause | ADVERTISED_Asym_Pause); -+ if (oldadv != newadv) { -+ phydev->advertising &= -+ ~(ADVERTISED_Pause | -+ ADVERTISED_Asym_Pause); -+ phydev->advertising |= newadv; -+ if (phydev->autoneg) { -+ /* -+ * Always renegotiate the link to -+ * inform our link partner of our -+ * flow control settings, even if the -+ * flow control is forced. Let -+ * tg3_adjust_link() do the final -+ * flow control setup. -+ */ -+ return phy_start_aneg(phydev); -+ } -+ } -+ -+ if (!epause->autoneg) -+ tg3_setup_flow_control(tp, 0, 0); -+ } else { -+ tp->link_config.advertising &= -+ ~(ADVERTISED_Pause | -+ ADVERTISED_Asym_Pause); -+ tp->link_config.advertising |= newadv; -+ } -+ } else -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+ { -+ int irq_sync = 0; -+ -+ if (netif_running(dev)) { -+ tg3_netif_stop(tp); -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tg3_netq_invalidate_state(tp); -+#endif -+ irq_sync = 1; -+ } -+ -+ tg3_full_lock(tp, irq_sync); -+ -+ if (epause->autoneg) -+ tg3_flag_set(tp, PAUSE_AUTONEG); -+ else -+ tg3_flag_clear(tp, PAUSE_AUTONEG); -+ if (epause->rx_pause) -+ tp->link_config.flowctrl |= FLOW_CTRL_RX; -+ else -+ tp->link_config.flowctrl &= ~FLOW_CTRL_RX; -+ if (epause->tx_pause) -+ tp->link_config.flowctrl |= FLOW_CTRL_TX; -+ else -+ tp->link_config.flowctrl &= ~FLOW_CTRL_TX; -+ -+ if (netif_running(dev)) { -+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); -+ err = tg3_restart_hw(tp, false); -+ if (!err) -+ tg3_netif_start(tp); -+ } -+ -+ tg3_full_unlock(tp); -+ } -+ -+ tp->phy_flags |= TG3_PHYFLG_USER_CONFIGURED; -+ -+ return err; -+} -+ -+static int tg3_get_sset_count(struct net_device *dev, int sset) -+{ -+ switch (sset) { -+ case ETH_SS_TEST: -+ return TG3_NUM_TEST; -+ case ETH_SS_STATS: -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ return tg3_netq_stats_size(netdev_priv(dev)); -+#else -+ return TG3_NUM_STATS; -+#endif -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+#if (LINUX_VERSION_CODE < 0x020618) -+static int tg3_get_stats_count (struct net_device *dev) -+{ -+ return tg3_get_sset_count(dev, ETH_SS_STATS); -+} -+ -+static int tg3_get_test_count (struct net_device *dev) -+{ -+ return tg3_get_sset_count(dev, ETH_SS_TEST); -+} -+#endif -+ -+#if defined(BCM_HAS_GET_RXNFC) && !defined(GET_ETHTOOL_OP_EXT) -+#ifdef BCM_HAS_OLD_GET_RXNFC_SIG -+static int tg3_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, -+ void *rules) -+#else -+static int tg3_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, -+ u32 *rules __always_unused) -+#endif /* BCM_HAS_OLD_GET_RXNFC_SIG */ -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (!tg3_flag(tp, SUPPORT_MSIX)) -+ return -EOPNOTSUPP; -+ -+ switch (info->cmd) { -+ case ETHTOOL_GRXRINGS: -+ if (netif_running(tp->dev)) -+ info->data = tp->rxq_cnt; -+ else { -+ info->data = num_online_cpus(); -+ if (info->data > TG3_RSS_MAX_NUM_QS) -+ info->data = TG3_RSS_MAX_NUM_QS; -+ } -+ return 0; -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+#endif /* BCM_HAS_GET_RXNFC */ -+ -+#if defined(BCM_HAS_GET_RXFH_INDIR_SIZE) && !defined(GET_ETHTOOL_OP_EXT) -+static u32 tg3_get_rxfh_indir_size(struct net_device *dev) -+{ -+ u32 size = 0; -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (tg3_flag(tp, SUPPORT_MSIX)) -+ size = TG3_RSS_INDIR_TBL_SIZE; -+ -+ return size; -+} -+ -+#ifdef BCM_HAS_OLD_RXFH_INDIR -+static int tg3_get_rxfh_indir(struct net_device *dev, u32 *indir) -+#else -+static int tg3_get_rxfh(struct net_device *dev, u32 *indir, u8 *key) -+#endif -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ int i; -+ -+ for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) -+ indir[i] = tp->rss_ind_tbl[i]; -+ -+ return 0; -+} -+#ifdef BCM_HAS_OLD_RXFH_INDIR -+static int tg3_set_rxfh_indir(struct net_device *dev, const u32 *indir) -+#else -+static int tg3_set_rxfh(struct net_device *dev, const u32 *indir, const u8 *key) -+#endif -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ size_t i; -+ -+ for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) -+ tp->rss_ind_tbl[i] = indir[i]; -+ -+ if (!netif_running(dev) || !tg3_flag(tp, ENABLE_RSS)) -+ return 0; -+ -+ /* It is legal to write the indirection -+ * table while the device is running. -+ */ -+ tg3_full_lock(tp, 0); -+ tg3_rss_write_indir_tbl(tp); -+ tg3_full_unlock(tp); -+ -+ return 0; -+} -+#endif /* BCM_HAS_GET_RXFH_INDIR_SIZE */ -+ -+#if defined(ETHTOOL_GCHANNELS) -+static void tg3_get_channels(struct net_device *dev, -+ struct ethtool_channels *channel) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ u32 deflt_qs = netif_get_num_default_rss_queues(); -+ -+ channel->max_rx = tp->rxq_max; -+ channel->max_tx = tp->txq_max; -+ -+ if (netif_running(dev)) { -+ channel->rx_count = tp->rxq_cnt; -+ channel->tx_count = tp->txq_cnt; -+ } else { -+ if (tp->rxq_req) -+ channel->rx_count = tp->rxq_req; -+ else -+ channel->rx_count = min(deflt_qs, tp->rxq_max); -+ -+ if (tp->txq_req) -+ channel->tx_count = tp->txq_req; -+ else -+ channel->tx_count = min(deflt_qs, tp->txq_max); -+ } -+} -+ -+static int tg3_set_channels(struct net_device *dev, -+ struct ethtool_channels *channel) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (!tg3_flag(tp, SUPPORT_MSIX)) -+ return -EOPNOTSUPP; -+ -+ if (channel->rx_count > tp->rxq_max || -+ channel->tx_count > tp->txq_max) -+ return -EINVAL; -+ -+ tp->rxq_req = channel->rx_count; -+ tp->txq_req = channel->tx_count; -+ -+ if (!netif_running(dev)) -+ return 0; -+ -+ tg3_stop(tp); -+ -+ tg3_carrier_off(tp); -+ -+ tg3_start(tp, true, false, false); -+ -+ return 0; -+} -+#endif /* ETHTOOL_GCHANNELS */ -+ -+static void tg3_get_strings(struct net_device *dev, u32 stringset, u8 *buf) -+{ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ struct tg3 *tp = netdev_priv(dev); -+#endif -+ -+ switch (stringset) { -+ case ETH_SS_STATS: -+ memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys)); -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (tg3_flag(tp, ENABLE_IOV)) { -+ buf += sizeof(ethtool_stats_keys); -+ tg3_netq_stats_get_strings(tp, buf); -+ } -+#endif -+ break; -+ case ETH_SS_TEST: -+ memcpy(buf, ðtool_test_keys, sizeof(ethtool_test_keys)); -+ break; -+ default: -+ WARN_ON(1); /* we need a WARN() */ -+ break; -+ } -+} -+ -+static int tg3_set_phys_id(struct net_device *dev, -+ enum ethtool_phys_id_state state) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (!netif_running(tp->dev)) -+ return -EAGAIN; -+ -+ switch (state) { -+ case ETHTOOL_ID_ACTIVE: -+ return 1; /* cycle on/off once per second */ -+ -+ case ETHTOOL_ID_ON: -+ tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | -+ LED_CTRL_1000MBPS_ON | -+ LED_CTRL_100MBPS_ON | -+ LED_CTRL_10MBPS_ON | -+ LED_CTRL_TRAFFIC_OVERRIDE | -+ LED_CTRL_TRAFFIC_BLINK | -+ LED_CTRL_TRAFFIC_LED); -+ break; -+ -+ case ETHTOOL_ID_OFF: -+ tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | -+ LED_CTRL_TRAFFIC_OVERRIDE); -+ break; -+ -+ case ETHTOOL_ID_INACTIVE: -+ tw32(MAC_LED_CTRL, tp->led_ctrl); -+ break; -+ } -+ -+ return 0; -+} -+ -+static void tg3_get_ethtool_stats(struct net_device *dev, -+ struct ethtool_stats *estats, u64 *tmp_stats) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (tp->hw_stats) { -+ tg3_get_estats(tp, (struct tg3_ethtool_stats *)tmp_stats); -+ } -+ else { -+ memset(tmp_stats, 0, sizeof(struct tg3_ethtool_stats)); -+#if !defined(__VMKLNX__) -+ ((struct tg3_ethtool_stats *)tmp_stats)->unrecoverable_err = -+ tp->unrecoverable_err; -+ ((struct tg3_ethtool_stats *)tmp_stats)->recoverable_err = -+ tp->recoverable_err; -+#endif -+ } -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tg3_netq_stats_get(tp, tmp_stats + TG3_NUM_STATS); -+#endif -+} -+ -+static __be32 *tg3_vpd_readblock(struct tg3 *tp, u32 *vpdlen) -+{ -+ int i; -+ __be32 *buf; -+ u32 offset = 0, len = 0; -+ u32 magic, val; -+ -+ if (tg3_flag(tp, NO_NVRAM) || tg3_nvram_read(tp, 0, &magic)) -+ return NULL; -+ -+ if (magic == TG3_EEPROM_MAGIC) { -+ for (offset = TG3_NVM_DIR_START; -+ offset < TG3_NVM_DIR_END; -+ offset += TG3_NVM_DIRENT_SIZE) { -+ if (tg3_nvram_read(tp, offset, &val)) -+ return NULL; -+ -+ if ((val >> TG3_NVM_DIRTYPE_SHIFT) == -+ TG3_NVM_DIRTYPE_EXTVPD) -+ break; -+ } -+ -+ if (offset != TG3_NVM_DIR_END) { -+ len = (val & TG3_NVM_DIRTYPE_LENMSK) * 4; -+ if (tg3_nvram_read(tp, offset + 4, &offset)) -+ return NULL; -+ -+ offset = tg3_nvram_logical_addr(tp, offset); -+ } -+ } -+ -+ if (!offset || !len) { -+ offset = TG3_NVM_VPD_OFF; -+ len = TG3_NVM_VPD_LEN; -+ } -+ -+ buf = kmalloc(len, GFP_KERNEL); -+ if (buf == NULL) -+ return NULL; -+ -+ if (magic == TG3_EEPROM_MAGIC) { -+ for (i = 0; i < len; i += 4) { -+ /* The data is in little-endian format in NVRAM. -+ * Use the big-endian read routines to preserve -+ * the byte order as it exists in NVRAM. -+ */ -+ if (tg3_nvram_read_be32(tp, offset + i, &buf[i/4])) -+ goto error; -+ } -+ } else { -+ u8 *ptr; -+ ssize_t cnt; -+ unsigned int pos = 0; -+ -+ ptr = (u8 *)&buf[0]; -+ for (i = 0; pos < len && i < 3; i++, pos += cnt, ptr += cnt) { -+ cnt = pci_read_vpd(tp->pdev, pos, -+ len - pos, ptr); -+ if (cnt == -ETIMEDOUT || cnt == -EINTR) -+ cnt = 0; -+ else if (cnt < 0) -+ goto error; -+ } -+ if (pos != len) -+ goto error; -+ } -+ -+ *vpdlen = len; -+ -+ return buf; -+ -+error: -+ kfree(buf); -+ return NULL; -+} -+ -+#define NVRAM_TEST_SIZE 0x100 -+#define NVRAM_SELFBOOT_FORMAT1_0_SIZE 0x14 -+#define NVRAM_SELFBOOT_FORMAT1_2_SIZE 0x18 -+#define NVRAM_SELFBOOT_FORMAT1_3_SIZE 0x1c -+#define NVRAM_SELFBOOT_FORMAT1_4_SIZE 0x20 -+#define NVRAM_SELFBOOT_FORMAT1_5_SIZE 0x24 -+#define NVRAM_SELFBOOT_FORMAT1_6_SIZE 0x50 -+#define NVRAM_SELFBOOT_HW_SIZE 0x20 -+#define NVRAM_SELFBOOT_DATA_SIZE 0x1c -+ -+static int tg3_test_nvram(struct tg3 *tp) -+{ -+ u32 csum, magic, len; -+ __be32 *buf; -+ int i, j, k, err = 0, size; -+ -+ if (tg3_flag(tp, NO_NVRAM)) -+ return 0; -+ -+ if (tg3_nvram_read(tp, 0, &magic) != 0) -+ return -EIO; -+ -+ if (magic == TG3_EEPROM_MAGIC) -+ size = NVRAM_TEST_SIZE; -+ else if ((magic & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW) { -+ if ((magic & TG3_EEPROM_SB_FORMAT_MASK) == -+ TG3_EEPROM_SB_FORMAT_1) { -+ switch (magic & TG3_EEPROM_SB_REVISION_MASK) { -+ case TG3_EEPROM_SB_REVISION_0: -+ size = NVRAM_SELFBOOT_FORMAT1_0_SIZE; -+ break; -+ case TG3_EEPROM_SB_REVISION_2: -+ size = NVRAM_SELFBOOT_FORMAT1_2_SIZE; -+ break; -+ case TG3_EEPROM_SB_REVISION_3: -+ size = NVRAM_SELFBOOT_FORMAT1_3_SIZE; -+ break; -+ case TG3_EEPROM_SB_REVISION_4: -+ size = NVRAM_SELFBOOT_FORMAT1_4_SIZE; -+ break; -+ case TG3_EEPROM_SB_REVISION_5: -+ size = NVRAM_SELFBOOT_FORMAT1_5_SIZE; -+ break; -+ case TG3_EEPROM_SB_REVISION_6: -+ size = NVRAM_SELFBOOT_FORMAT1_6_SIZE; -+ break; -+ default: -+ return -EIO; -+ } -+ } else -+ return 0; -+ } else if ((magic & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW) -+ size = NVRAM_SELFBOOT_HW_SIZE; -+ else -+ return -EIO; -+ -+ buf = kmalloc(size, GFP_KERNEL); -+ if (buf == NULL) -+ return -ENOMEM; -+ -+ err = -EIO; -+ for (i = 0, j = 0; i < size; i += 4, j++) { -+ err = tg3_nvram_read_be32(tp, i, &buf[j]); -+ if (err) -+ break; -+ } -+ if (i < size) -+ goto out; -+ -+ /* Selfboot format */ -+ magic = be32_to_cpu(buf[0]); -+ if ((magic & TG3_EEPROM_MAGIC_FW_MSK) == -+ TG3_EEPROM_MAGIC_FW) { -+ u8 *buf8 = (u8 *) buf, csum8 = 0; -+ -+ if ((magic & TG3_EEPROM_SB_REVISION_MASK) == -+ TG3_EEPROM_SB_REVISION_2) { -+ /* For rev 2, the csum doesn't include the MBA. */ -+ for (i = 0; i < TG3_EEPROM_SB_F1R2_MBA_OFF; i++) -+ csum8 += buf8[i]; -+ for (i = TG3_EEPROM_SB_F1R2_MBA_OFF + 4; i < size; i++) -+ csum8 += buf8[i]; -+ } else { -+ for (i = 0; i < size; i++) -+ csum8 += buf8[i]; -+ } -+ -+ if (csum8 == 0) { -+ err = 0; -+ goto out; -+ } -+ -+ err = -EIO; -+ goto out; -+ } -+ -+ if ((magic & TG3_EEPROM_MAGIC_HW_MSK) == -+ TG3_EEPROM_MAGIC_HW) { -+ u8 data[NVRAM_SELFBOOT_DATA_SIZE]; -+ u8 parity[NVRAM_SELFBOOT_DATA_SIZE]; -+ u8 *buf8 = (u8 *) buf; -+ -+ /* Separate the parity bits and the data bytes. */ -+ for (i = 0, j = 0, k = 0; i < NVRAM_SELFBOOT_HW_SIZE; i++) { -+ if ((i == 0) || (i == 8)) { -+ int l; -+ u8 msk; -+ -+ for (l = 0, msk = 0x80; l < 7; l++, msk >>= 1) -+ parity[k++] = buf8[i] & msk; -+ i++; -+ } else if (i == 16) { -+ int l; -+ u8 msk; -+ -+ for (l = 0, msk = 0x20; l < 6; l++, msk >>= 1) -+ parity[k++] = buf8[i] & msk; -+ i++; -+ -+ for (l = 0, msk = 0x80; l < 8; l++, msk >>= 1) -+ parity[k++] = buf8[i] & msk; -+ i++; -+ } -+ data[j++] = buf8[i]; -+ } -+ -+ err = -EIO; -+ for (i = 0; i < NVRAM_SELFBOOT_DATA_SIZE; i++) { -+ u8 hw8 = hweight8(data[i]); -+ -+ if ((hw8 & 0x1) && parity[i]) -+ goto out; -+ else if (!(hw8 & 0x1) && !parity[i]) -+ goto out; -+ } -+ err = 0; -+ goto out; -+ } -+ -+ err = -EIO; -+ -+ /* Bootstrap checksum at offset 0x10 */ -+ csum = calc_crc((unsigned char *) buf, 0x10); -+ if (csum != le32_to_cpu(buf[0x10/4])) -+ goto out; -+ -+ /* Manufacturing block starts at offset 0x74, checksum at 0xfc */ -+ csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88); -+ if (csum != le32_to_cpu(buf[0xfc/4])) -+ goto out; -+ -+ kfree(buf); -+ -+ buf = tg3_vpd_readblock(tp, &len); -+ if (!buf) -+ return -ENOMEM; -+ -+ i = pci_vpd_find_tag((u8 *)buf, 0, len, PCI_VPD_LRDT_RO_DATA); -+ if (i > 0) { -+ j = pci_vpd_lrdt_size(&((u8 *)buf)[i]); -+ if (j < 0) -+ goto out; -+ -+ if (i + PCI_VPD_LRDT_TAG_SIZE + j > len) -+ goto out; -+ -+ i += PCI_VPD_LRDT_TAG_SIZE; -+ j = pci_vpd_find_info_keyword((u8 *)buf, i, j, -+ PCI_VPD_RO_KEYWORD_CHKSUM); -+ if (j > 0) { -+ u8 csum8 = 0; -+ -+ j += PCI_VPD_INFO_FLD_HDR_SIZE; -+ -+ for (i = 0; i <= j; i++) -+ csum8 += ((u8 *)buf)[i]; -+ -+ if (csum8) -+ goto out; -+ } -+ } -+ -+ err = 0; -+ -+out: -+ kfree(buf); -+ return err; -+} -+ -+#define TG3_SERDES_TIMEOUT_SEC 2 -+#define TG3_COPPER_TIMEOUT_SEC 7 -+ -+static int tg3_test_link(struct tg3 *tp) -+{ -+ int i, max; -+ -+ if (!netif_running(tp->dev)) -+ return -ENODEV; -+ -+ if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) -+ max = TG3_SERDES_TIMEOUT_SEC; -+ else -+ max = TG3_COPPER_TIMEOUT_SEC; -+ -+ for (i = 0; i < max; i++) { -+ if (tp->link_up) -+ return 0; -+ -+ if (msleep_interruptible(1000)) -+ break; -+ } -+ -+ return -EIO; -+} -+ -+/* Only test the commonly used registers */ -+static int tg3_test_registers(struct tg3 *tp) -+{ -+ int i, is_5705, is_5750; -+ u32 offset, read_mask, write_mask, val, save_val, read_val; -+ static struct { -+ u16 offset; -+ u16 flags; -+#define TG3_FL_5705 0x1 -+#define TG3_FL_NOT_5705 0x2 -+#define TG3_FL_NOT_5788 0x4 -+#define TG3_FL_NOT_5750 0x8 -+ u32 read_mask; -+ u32 write_mask; -+ } reg_tbl[] = { -+ /* MAC Control Registers */ -+ { MAC_MODE, TG3_FL_NOT_5705, -+ 0x00000000, 0x00ef6f8c }, -+ { MAC_MODE, TG3_FL_5705, -+ 0x00000000, 0x01ef6b8c }, -+ { MAC_STATUS, TG3_FL_NOT_5705, -+ 0x03800107, 0x00000000 }, -+ { MAC_STATUS, TG3_FL_5705, -+ 0x03800100, 0x00000000 }, -+ { MAC_ADDR_0_HIGH, 0x0000, -+ 0x00000000, 0x0000ffff }, -+ { MAC_ADDR_0_LOW, 0x0000, -+ 0x00000000, 0xffffffff }, -+ { MAC_RX_MTU_SIZE, 0x0000, -+ 0x00000000, 0x0000ffff }, -+ { MAC_TX_MODE, 0x0000, -+ 0x00000000, 0x00000070 }, -+ { MAC_TX_LENGTHS, 0x0000, -+ 0x00000000, 0x00003fff }, -+ { MAC_RX_MODE, TG3_FL_NOT_5705, -+ 0x00000000, 0x000007fc }, -+ { MAC_RX_MODE, TG3_FL_5705, -+ 0x00000000, 0x000007dc }, -+ { MAC_HASH_REG_0, 0x0000, -+ 0x00000000, 0xffffffff }, -+ { MAC_HASH_REG_1, 0x0000, -+ 0x00000000, 0xffffffff }, -+ { MAC_HASH_REG_2, 0x0000, -+ 0x00000000, 0xffffffff }, -+ { MAC_HASH_REG_3, 0x0000, -+ 0x00000000, 0xffffffff }, -+ -+ /* Receive Data and Receive BD Initiator Control Registers. */ -+ { RCVDBDI_JUMBO_BD+0, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { RCVDBDI_JUMBO_BD+4, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { RCVDBDI_JUMBO_BD+8, TG3_FL_NOT_5705, -+ 0x00000000, 0x00000003 }, -+ { RCVDBDI_JUMBO_BD+0xc, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { RCVDBDI_STD_BD+0, 0x0000, -+ 0x00000000, 0xffffffff }, -+ { RCVDBDI_STD_BD+4, 0x0000, -+ 0x00000000, 0xffffffff }, -+ { RCVDBDI_STD_BD+8, 0x0000, -+ 0x00000000, 0xffff0002 }, -+ { RCVDBDI_STD_BD+0xc, 0x0000, -+ 0x00000000, 0xffffffff }, -+ -+ /* Receive BD Initiator Control Registers. */ -+ { RCVBDI_STD_THRESH, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { RCVBDI_STD_THRESH, TG3_FL_5705, -+ 0x00000000, 0x000003ff }, -+ { RCVBDI_JUMBO_THRESH, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ -+ /* Host Coalescing Control Registers. */ -+ { HOSTCC_MODE, TG3_FL_NOT_5705, -+ 0x00000000, 0x00000004 }, -+ { HOSTCC_MODE, TG3_FL_5705, -+ 0x00000000, 0x000000f6 }, -+ { HOSTCC_RXCOL_TICKS, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { HOSTCC_RXCOL_TICKS, TG3_FL_5705, -+ 0x00000000, 0x000003ff }, -+ { HOSTCC_TXCOL_TICKS, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { HOSTCC_TXCOL_TICKS, TG3_FL_5705, -+ 0x00000000, 0x000003ff }, -+ { HOSTCC_RXMAX_FRAMES, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { HOSTCC_RXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, -+ 0x00000000, 0x000000ff }, -+ { HOSTCC_TXMAX_FRAMES, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { HOSTCC_TXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, -+ 0x00000000, 0x000000ff }, -+ { HOSTCC_RXCOAL_TICK_INT, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { HOSTCC_TXCOAL_TICK_INT, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, -+ 0x00000000, 0x000000ff }, -+ { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, -+ 0x00000000, 0x000000ff }, -+ { HOSTCC_STAT_COAL_TICKS, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { HOSTCC_STATS_BLK_HOST_ADDR, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { HOSTCC_STATS_BLK_HOST_ADDR+4, TG3_FL_NOT_5705, -+ 0x00000000, 0xffffffff }, -+ { HOSTCC_STATUS_BLK_HOST_ADDR, 0x0000, -+ 0x00000000, 0xffffffff }, -+ { HOSTCC_STATUS_BLK_HOST_ADDR+4, 0x0000, -+ 0x00000000, 0xffffffff }, -+ { HOSTCC_STATS_BLK_NIC_ADDR, 0x0000, -+ 0xffffffff, 0x00000000 }, -+ { HOSTCC_STATUS_BLK_NIC_ADDR, 0x0000, -+ 0xffffffff, 0x00000000 }, -+ -+ /* Buffer Manager Control Registers. */ -+ { BUFMGR_MB_POOL_ADDR, TG3_FL_NOT_5750, -+ 0x00000000, 0x007fff80 }, -+ { BUFMGR_MB_POOL_SIZE, TG3_FL_NOT_5750, -+ 0x00000000, 0x007fffff }, -+ { BUFMGR_MB_RDMA_LOW_WATER, 0x0000, -+ 0x00000000, 0x0000003f }, -+ { BUFMGR_MB_MACRX_LOW_WATER, 0x0000, -+ 0x00000000, 0x000001ff }, -+ { BUFMGR_MB_HIGH_WATER, 0x0000, -+ 0x00000000, 0x000001ff }, -+ { BUFMGR_DMA_DESC_POOL_ADDR, TG3_FL_NOT_5705, -+ 0xffffffff, 0x00000000 }, -+ { BUFMGR_DMA_DESC_POOL_SIZE, TG3_FL_NOT_5705, -+ 0xffffffff, 0x00000000 }, -+ -+ /* Mailbox Registers */ -+ { GRCMBOX_RCVSTD_PROD_IDX+4, 0x0000, -+ 0x00000000, 0x000001ff }, -+ { GRCMBOX_RCVJUMBO_PROD_IDX+4, TG3_FL_NOT_5705, -+ 0x00000000, 0x000001ff }, -+ { GRCMBOX_RCVRET_CON_IDX_0+4, 0x0000, -+ 0x00000000, 0x000007ff }, -+ { GRCMBOX_SNDHOST_PROD_IDX_0+4, 0x0000, -+ 0x00000000, 0x000001ff }, -+ -+ { 0xffff, 0x0000, 0x00000000, 0x00000000 }, -+ }; -+ -+ is_5705 = is_5750 = 0; -+ if (tg3_flag(tp, 5705_PLUS)) { -+ is_5705 = 1; -+ if (tg3_flag(tp, 5750_PLUS)) -+ is_5750 = 1; -+ } -+ -+ for (i = 0; reg_tbl[i].offset != 0xffff; i++) { -+ if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705)) -+ continue; -+ -+ if (!is_5705 && (reg_tbl[i].flags & TG3_FL_5705)) -+ continue; -+ -+ if (tg3_flag(tp, IS_5788) && -+ (reg_tbl[i].flags & TG3_FL_NOT_5788)) -+ continue; -+ -+ if (is_5750 && (reg_tbl[i].flags & TG3_FL_NOT_5750)) -+ continue; -+ -+ offset = (u32) reg_tbl[i].offset; -+ read_mask = reg_tbl[i].read_mask; -+ write_mask = reg_tbl[i].write_mask; -+ -+ /* Save the original register content */ -+ save_val = tr32(offset); -+ -+ /* Determine the read-only value. */ -+ read_val = save_val & read_mask; -+ -+ /* Write zero to the register, then make sure the read-only bits -+ * are not changed and the read/write bits are all zeros. -+ */ -+ tw32(offset, 0); -+ -+ val = tr32(offset); -+ -+ /* Test the read-only and read/write bits. */ -+ if (((val & read_mask) != read_val) || (val & write_mask)) -+ goto out; -+ -+ /* Write ones to all the bits defined by RdMask and WrMask, then -+ * make sure the read-only bits are not changed and the -+ * read/write bits are all ones. -+ */ -+ tw32(offset, read_mask | write_mask); -+ -+ val = tr32(offset); -+ -+ /* Test the read-only bits. */ -+ if ((val & read_mask) != read_val) -+ goto out; -+ -+ /* Test the read/write bits. */ -+ if ((val & write_mask) != write_mask) -+ goto out; -+ -+ tw32(offset, save_val); -+ } -+ -+ return 0; -+ -+out: -+ if (netif_msg_hw(tp)) -+ netdev_err(tp->dev, -+ "Register test failed at offset %x\n", offset); -+ tw32(offset, save_val); -+ return -EIO; -+} -+ -+static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len) -+{ -+ static const u32 test_pattern[] = { 0x00000000, 0xffffffff, 0xaa55a55a }; -+ int i; -+ u32 j; -+ -+ for (i = 0; i < ARRAY_SIZE(test_pattern); i++) { -+ for (j = 0; j < len; j += 4) { -+ u32 val; -+ -+ tg3_write_mem(tp, offset + j, test_pattern[i]); -+ tg3_read_mem(tp, offset + j, &val); -+ if (val != test_pattern[i]) -+ return -EIO; -+ } -+ } -+ return 0; -+} -+ -+static int tg3_test_memory(struct tg3 *tp) -+{ -+ static struct mem_entry { -+ u32 offset; -+ u32 len; -+ } mem_tbl_570x[] = { -+ { 0x00000000, 0x00b50}, -+ { 0x00002000, 0x1c000}, -+ { 0xffffffff, 0x00000} -+ }, mem_tbl_5705[] = { -+ { 0x00000100, 0x0000c}, -+ { 0x00000200, 0x00008}, -+ { 0x00004000, 0x00800}, -+ { 0x00006000, 0x01000}, -+ { 0x00008000, 0x02000}, -+ { 0x00010000, 0x0e000}, -+ { 0xffffffff, 0x00000} -+ }, mem_tbl_5755[] = { -+ { 0x00000200, 0x00008}, -+ { 0x00004000, 0x00800}, -+ { 0x00006000, 0x00800}, -+ { 0x00008000, 0x02000}, -+ { 0x00010000, 0x0c000}, -+ { 0xffffffff, 0x00000} -+ }, mem_tbl_5906[] = { -+ { 0x00000200, 0x00008}, -+ { 0x00004000, 0x00400}, -+ { 0x00006000, 0x00400}, -+ { 0x00008000, 0x01000}, -+ { 0x00010000, 0x01000}, -+ { 0xffffffff, 0x00000} -+ }, mem_tbl_5717[] = { -+ { 0x00000200, 0x00008}, -+ { 0x00010000, 0x0a000}, -+ { 0x00020000, 0x13c00}, -+ { 0xffffffff, 0x00000} -+ }, mem_tbl_57765[] = { -+ { 0x00000200, 0x00008}, -+ { 0x00004000, 0x00800}, -+ { 0x00006000, 0x09800}, -+ { 0x00010000, 0x0a000}, -+ { 0xffffffff, 0x00000} -+ }; -+ struct mem_entry *mem_tbl; -+ int err = 0; -+ int i; -+ -+ if (tg3_flag(tp, 5717_PLUS)) -+ mem_tbl = mem_tbl_5717; -+ else if (tg3_flag(tp, 57765_CLASS) || -+ tg3_asic_rev(tp) == ASIC_REV_5762) -+ mem_tbl = mem_tbl_57765; -+ else if (tg3_flag(tp, 5755_PLUS)) -+ mem_tbl = mem_tbl_5755; -+ else if (tg3_asic_rev(tp) == ASIC_REV_5906) -+ mem_tbl = mem_tbl_5906; -+ else if (tg3_flag(tp, 5705_PLUS)) -+ mem_tbl = mem_tbl_5705; -+ else -+ mem_tbl = mem_tbl_570x; -+ -+ for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) { -+ err = tg3_do_mem_test(tp, mem_tbl[i].offset, mem_tbl[i].len); -+ if (err) -+ break; -+ } -+ -+ return err; -+} -+ -+#define TG3_TSO_MSS 500 -+ -+#define TG3_TSO_IP_HDR_LEN 20 -+#define TG3_TSO_TCP_HDR_LEN 20 -+#define TG3_TSO_TCP_OPT_LEN 12 -+ -+static const u8 tg3_tso_header[] = { -+0x08, 0x00, -+0x45, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x40, 0x00, -+0x40, 0x06, 0x00, 0x00, -+0x0a, 0x00, 0x00, 0x01, -+0x0a, 0x00, 0x00, 0x02, -+0x0d, 0x00, 0xe0, 0x00, -+0x00, 0x00, 0x01, 0x00, -+0x00, 0x00, 0x02, 0x00, -+0x80, 0x10, 0x10, 0x00, -+0x14, 0x09, 0x00, 0x00, -+0x01, 0x01, 0x08, 0x0a, -+0x11, 0x11, 0x11, 0x11, -+0x11, 0x11, 0x11, 0x11, -+}; -+ -+static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, bool tso_loopback) -+{ -+ u32 rx_start_idx, rx_idx, tx_idx, opaque_key; -+ u32 base_flags = 0, mss = 0, desc_idx, coal_now, data_off, val; -+ u32 budget; -+ struct sk_buff *skb; -+#ifndef BCM_HAS_BUILD_SKB -+ struct sk_buff *rx_skb; -+#endif -+ u8 *tx_data, *rx_data; -+ dma_addr_t map; -+ int num_pkts, tx_len, rx_len, i, err; -+ struct tg3_rx_buffer_desc *desc; -+ struct tg3_napi *tnapi, *rnapi; -+ struct tg3_rx_prodring_set *tpr = &tp->napi[0].prodring; -+ -+ tnapi = &tp->napi[0]; -+ rnapi = &tp->napi[0]; -+ if (tg3_flag(tp, ENABLE_RSS)) -+ rnapi = &tp->napi[1]; -+ if (tg3_flag(tp, ENABLE_TSS)) -+ tnapi = &tp->napi[1]; -+ coal_now = tnapi->coal_now | rnapi->coal_now; -+ -+ err = -EIO; -+ -+ tx_len = pktsz; -+ skb = netdev_alloc_skb(tp->dev, tx_len); -+ if (!skb) -+ return -ENOMEM; -+ -+ tx_data = skb_put(skb, tx_len); -+ memcpy(tx_data, tp->dev->dev_addr, ETH_ALEN); -+ memset(tx_data + ETH_ALEN, 0x0, 8); -+ -+ tw32(MAC_RX_MTU_SIZE, tx_len + ETH_FCS_LEN); -+ -+#if TG3_TSO_SUPPORT != 0 -+ if (tso_loopback) { -+ struct iphdr *iph = (struct iphdr *)&tx_data[ETH_HLEN]; -+ -+ u32 hdr_len = TG3_TSO_IP_HDR_LEN + TG3_TSO_TCP_HDR_LEN + -+ TG3_TSO_TCP_OPT_LEN; -+ -+ memcpy(tx_data + ETH_ALEN * 2, tg3_tso_header, -+ sizeof(tg3_tso_header)); -+ mss = TG3_TSO_MSS; -+ -+ val = tx_len - ETH_ALEN * 2 - sizeof(tg3_tso_header); -+ num_pkts = DIV_ROUND_UP(val, TG3_TSO_MSS); -+ -+ /* Set the total length field in the IP header */ -+ iph->tot_len = htons((u16)(mss + hdr_len)); -+ -+ base_flags = (TXD_FLAG_CPU_PRE_DMA | -+ TXD_FLAG_CPU_POST_DMA); -+ -+ if (tg3_flag(tp, HW_TSO_1) || -+ tg3_flag(tp, HW_TSO_2) || -+ tg3_flag(tp, HW_TSO_3)) { -+ struct tcphdr *th; -+ val = ETH_HLEN + TG3_TSO_IP_HDR_LEN; -+ th = (struct tcphdr *)&tx_data[val]; -+ th->check = 0; -+ } else -+ base_flags |= TXD_FLAG_TCPUDP_CSUM; -+ -+ if (tg3_flag(tp, HW_TSO_3)) { -+ mss |= (hdr_len & 0xc) << 12; -+ if (hdr_len & 0x10) -+ base_flags |= 0x00000010; -+ base_flags |= (hdr_len & 0x3e0) << 5; -+ } else if (tg3_flag(tp, HW_TSO_2)) -+ mss |= hdr_len << 9; -+ else if (tg3_flag(tp, HW_TSO_1) || -+ tg3_asic_rev(tp) == ASIC_REV_5705) { -+ mss |= (TG3_TSO_TCP_OPT_LEN << 9); -+ } else { -+ base_flags |= (TG3_TSO_TCP_OPT_LEN << 10); -+ } -+ -+ data_off = ETH_ALEN * 2 + sizeof(tg3_tso_header); -+ } else -+#endif -+ { -+ num_pkts = 1; -+ data_off = ETH_HLEN; -+ -+ if (tg3_flag(tp, USE_JUMBO_BDFLAG) && -+ tx_len > VLAN_ETH_FRAME_LEN) -+ base_flags |= TXD_FLAG_JMB_PKT; -+ } -+ -+ for (i = data_off; i < tx_len; i++) -+ tx_data[i] = (u8) (i & 0xff); -+ -+ map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE); -+ if (pci_dma_mapping_error_(tp->pdev, map)) { -+ dev_kfree_skb(skb); -+ return -EIO; -+ } -+ -+ val = tnapi->tx_prod; -+ tnapi->tx_buffers[val].skb = skb; -+ dma_unmap_addr_set(&tnapi->tx_buffers[val], mapping, map); -+ -+ tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | -+ rnapi->coal_now); -+ -+ udelay(10); -+ -+ rx_start_idx = rnapi->hw_status->idx[0].rx_producer; -+ -+ budget = tg3_tx_avail(tnapi); -+ if (tg3_tx_frag_set(tnapi, &val, &budget, map, tx_len, -+ base_flags | TXD_FLAG_END, mss, 0)) { -+ tnapi->tx_buffers[val].skb = NULL; -+ dev_kfree_skb(skb); -+ return -EIO; -+ } -+ -+ tnapi->tx_prod++; -+ -+ /* Sync BD data before updating mailbox */ -+ wmb(); -+ -+ tw32_tx_mbox(tnapi->prodmbox, tnapi->tx_prod); -+ tr32_mailbox(tnapi->prodmbox); -+ -+ udelay(10); -+ -+ /* 350 usec to allow enough time on some 10/100 Mbps devices. */ -+ for (i = 0; i < 35; i++) { -+ tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | -+ coal_now); -+ -+ udelay(10); -+ -+ tx_idx = tnapi->hw_status->idx[0].tx_consumer; -+ rx_idx = rnapi->hw_status->idx[0].rx_producer; -+ if ((tx_idx == tnapi->tx_prod) && -+ (rx_idx == (rx_start_idx + num_pkts))) -+ break; -+ } -+ -+ tg3_tx_skb_unmap(tnapi, tnapi->tx_prod - 1, -1); -+ dev_kfree_skb(skb); -+ -+ if (tx_idx != tnapi->tx_prod) -+ goto out; -+ -+ if (rx_idx != rx_start_idx + num_pkts) -+ goto out; -+ -+ val = data_off; -+ while (rx_idx != rx_start_idx) { -+ desc = &rnapi->rx_rcb[rx_start_idx++]; -+ desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; -+ opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; -+ -+ if ((desc->err_vlan & RXD_ERR_MASK) != 0 && -+ (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) -+ goto out; -+ -+ rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) -+ - ETH_FCS_LEN; -+ -+ if (!tso_loopback) { -+ if (rx_len != tx_len) -+ goto out; -+ -+ if (pktsz <= TG3_RX_STD_DMA_SZ - ETH_FCS_LEN) { -+ if (opaque_key != RXD_OPAQUE_RING_STD) -+ goto out; -+ } else { -+ if (opaque_key != RXD_OPAQUE_RING_JUMBO) -+ goto out; -+ } -+ } else if ((desc->type_flags & RXD_FLAG_TCPUDP_CSUM) && -+ (desc->ip_tcp_csum & RXD_TCPCSUM_MASK) -+ >> RXD_TCPCSUM_SHIFT != 0xffff) { -+ goto out; -+ } -+ -+ if (opaque_key == RXD_OPAQUE_RING_STD) { -+#ifdef BCM_HAS_BUILD_SKB -+ rx_data = tpr->rx_std_buffers[desc_idx].data; -+#else -+ rx_skb = tpr->rx_std_buffers[desc_idx].data; -+ rx_data = rx_skb->data; -+#endif -+ map = dma_unmap_addr(&tpr->rx_std_buffers[desc_idx], -+ mapping); -+ } else if (opaque_key == RXD_OPAQUE_RING_JUMBO) { -+#ifdef BCM_HAS_BUILD_SKB -+ rx_data = tpr->rx_jmb_buffers[desc_idx].data; -+#else -+ rx_skb = tpr->rx_jmb_buffers[desc_idx].data; -+ rx_data = rx_skb->data; -+#endif -+ map = dma_unmap_addr(&tpr->rx_jmb_buffers[desc_idx], -+ mapping); -+ } else -+ goto out; -+ -+ pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, -+ PCI_DMA_FROMDEVICE); -+ -+ for (i = data_off; i < rx_len; i++, val++) { -+ if (*(rx_data + TG3_RX_OFFSET(tp) + i) != (u8) (val & 0xff)) -+ goto out; -+ } -+ } -+ -+ err = 0; -+ -+ /* tg3_free_rings will unmap and free the rx_data */ -+out: -+ return err; -+} -+ -+#define TG3_STD_LOOPBACK_FAILED 1 -+#define TG3_JMB_LOOPBACK_FAILED 2 -+#define TG3_TSO_LOOPBACK_FAILED 4 -+#define TG3_LOOPBACK_FAILED \ -+ (TG3_STD_LOOPBACK_FAILED | \ -+ TG3_JMB_LOOPBACK_FAILED | \ -+ TG3_TSO_LOOPBACK_FAILED) -+ -+static int tg3_test_loopback(struct tg3 *tp, u64 *data, bool do_extlpbk) -+{ -+ int err = -EIO; -+ u32 eee_cap; -+ u32 jmb_pkt_sz = 9000; -+ -+ if (tp->dma_limit) -+ jmb_pkt_sz = tp->dma_limit - ETH_HLEN; -+ -+ eee_cap = tp->phy_flags & TG3_PHYFLG_EEE_CAP; -+ tp->phy_flags &= ~TG3_PHYFLG_EEE_CAP; -+ -+ if (!netif_running(tp->dev)) { -+ data[TG3_MAC_LOOPB_TEST] = TG3_LOOPBACK_FAILED; -+ data[TG3_PHY_LOOPB_TEST] = TG3_LOOPBACK_FAILED; -+ if (do_extlpbk) -+ data[TG3_EXT_LOOPB_TEST] = TG3_LOOPBACK_FAILED; -+ goto done; -+ } -+ -+ err = tg3_reset_hw(tp, true); -+ if (err) { -+ data[TG3_MAC_LOOPB_TEST] = TG3_LOOPBACK_FAILED; -+ data[TG3_PHY_LOOPB_TEST] = TG3_LOOPBACK_FAILED; -+ if (do_extlpbk) -+ data[TG3_EXT_LOOPB_TEST] = TG3_LOOPBACK_FAILED; -+ goto done; -+ } -+ -+ if (tg3_flag(tp, ENABLE_RSS)) { -+ int i; -+ -+ /* Reroute all rx packets to the 1st queue */ -+ for (i = MAC_RSS_INDIR_TBL_0; -+ i < MAC_RSS_INDIR_TBL_0 + TG3_RSS_INDIR_TBL_SIZE; i += 4) -+ tw32(i, 0x0); -+ } -+ -+ /* HW errata - mac loopback fails in some cases on 5780. -+ * Normal traffic and PHY loopback are not affected by -+ * errata. Also, the MAC loopback test is deprecated for -+ * all newer ASIC revisions. -+ */ -+ if (tg3_asic_rev(tp) != ASIC_REV_5780 && -+ !tg3_flag(tp, CPMU_PRESENT)) { -+ tg3_mac_loopback(tp, true); -+ -+ if (tg3_run_loopback(tp, ETH_FRAME_LEN, false)) -+ data[TG3_MAC_LOOPB_TEST] |= TG3_STD_LOOPBACK_FAILED; -+ -+ if (tg3_flag(tp, JUMBO_RING_ENABLE) && -+ tg3_run_loopback(tp, jmb_pkt_sz + ETH_HLEN, false)) -+ data[TG3_MAC_LOOPB_TEST] |= TG3_JMB_LOOPBACK_FAILED; -+ -+ tg3_mac_loopback(tp, false); -+ } -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && -+ !tg3_flag(tp, USE_PHYLIB)) { -+ int i; -+ -+ tg3_phy_lpbk_set(tp, 0, false); -+ -+ /* Wait for link */ -+ for (i = 0; i < 700; i++) { -+ if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP) -+ break; -+ mdelay(1); -+ } -+ -+ if (i == 700) { -+ netdev_info(tp->dev, "No link for loopback test!\n" ); -+ data[TG3_PHY_LOOPB_TEST] = TG3_LOOPBACK_FAILED; -+ return -EIO; -+ } -+ -+ if (tg3_run_loopback(tp, ETH_FRAME_LEN, false)) -+ data[TG3_PHY_LOOPB_TEST] |= TG3_STD_LOOPBACK_FAILED; -+#if TG3_TSO_SUPPORT != 0 -+ if (tg3_flag(tp, TSO_CAPABLE) && -+ tg3_run_loopback(tp, ETH_FRAME_LEN, true)) -+ data[TG3_PHY_LOOPB_TEST] |= TG3_TSO_LOOPBACK_FAILED; -+#endif -+ if (tg3_flag(tp, JUMBO_RING_ENABLE) && -+ tg3_run_loopback(tp, jmb_pkt_sz + ETH_HLEN, false)) -+ data[TG3_PHY_LOOPB_TEST] |= TG3_JMB_LOOPBACK_FAILED; -+ -+ if (do_extlpbk) { -+ tg3_phy_lpbk_set(tp, 0, true); -+ -+ /* All link indications report up, but the hardware -+ * isn't really ready for about 20 msec. Double it -+ * to be sure. -+ */ -+ mdelay(40); -+ -+ if (tg3_run_loopback(tp, ETH_FRAME_LEN, false)) -+ data[TG3_EXT_LOOPB_TEST] |= -+ TG3_STD_LOOPBACK_FAILED; -+ if (tg3_flag(tp, TSO_CAPABLE) && -+ tg3_run_loopback(tp, ETH_FRAME_LEN, true)) -+ data[TG3_EXT_LOOPB_TEST] |= -+ TG3_TSO_LOOPBACK_FAILED; -+ if (tg3_flag(tp, JUMBO_RING_ENABLE) && -+ tg3_run_loopback(tp, jmb_pkt_sz + ETH_HLEN, false)) -+ data[TG3_EXT_LOOPB_TEST] |= -+ TG3_JMB_LOOPBACK_FAILED; -+ } -+ -+ /* Re-enable gphy autopowerdown. */ -+ if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD) -+ tg3_phy_toggle_apd(tp, true); -+ } -+ -+ err = (data[TG3_MAC_LOOPB_TEST] | data[TG3_PHY_LOOPB_TEST] | -+ data[TG3_EXT_LOOPB_TEST]) ? -EIO : 0; -+ -+done: -+ tp->phy_flags |= eee_cap; -+ -+ return err; -+} -+ -+static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, -+ u64 *data) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ bool doextlpbk = etest->flags & ETH_TEST_FL_EXTERNAL_LB; -+ -+ if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) { -+ if (tg3_power_up(tp)) { -+ etest->flags |= ETH_TEST_FL_FAILED; -+ memset(data, 1, sizeof(u64) * TG3_NUM_TEST); -+ return; -+ } -+ tg3_ape_driver_state_change(tp, RESET_KIND_INIT); -+ } -+ -+ memset(data, 0, sizeof(u64) * TG3_NUM_TEST); -+ -+ if (tg3_test_nvram(tp) != 0) { -+ etest->flags |= ETH_TEST_FL_FAILED; -+ data[TG3_NVRAM_TEST] = 1; -+ } -+ if (!doextlpbk && tg3_test_link(tp)) { -+ etest->flags |= ETH_TEST_FL_FAILED; -+ data[TG3_LINK_TEST] = 1; -+ } -+ if (etest->flags & ETH_TEST_FL_OFFLINE) { -+ int err, err2 = 0, irq_sync = 0; -+ -+ if (netif_running(dev)) { -+ tg3_phy_stop(tp); -+ tg3_netif_stop(tp); -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tg3_netq_invalidate_state(tp); -+#endif -+ irq_sync = 1; -+ } -+ -+ tg3_full_lock(tp, irq_sync); -+ tg3_halt(tp, RESET_KIND_SUSPEND, 1); -+ err = tg3_nvram_lock(tp); -+ tg3_halt_cpu(tp, RX_CPU_BASE); -+ if (!tg3_flag(tp, 5705_PLUS)) -+ tg3_halt_cpu(tp, TX_CPU_BASE); -+ if (!err) -+ tg3_nvram_unlock(tp); -+ -+ if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) -+ tg3_phy_reset(tp); -+ -+ if (tg3_test_registers(tp) != 0) { -+ etest->flags |= ETH_TEST_FL_FAILED; -+ data[TG3_REGISTER_TEST] = 1; -+ } -+ -+ if (tg3_test_memory(tp) != 0) { -+ etest->flags |= ETH_TEST_FL_FAILED; -+ data[TG3_MEMORY_TEST] = 1; -+ } -+ -+ if (doextlpbk) -+ etest->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE; -+ -+ if (tg3_test_loopback(tp, data, doextlpbk)) -+ etest->flags |= ETH_TEST_FL_FAILED; -+ -+ tg3_full_unlock(tp); -+ -+ if (tg3_test_interrupt(tp) != 0) { -+ etest->flags |= ETH_TEST_FL_FAILED; -+ data[TG3_INTERRUPT_TEST] = 1; -+ } -+ -+ tg3_full_lock(tp, 0); -+ -+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); -+ if (netif_running(dev)) { -+ tg3_flag_set(tp, INIT_COMPLETE); -+ err2 = tg3_restart_hw(tp, true); -+ if (!err2) -+ tg3_netif_start(tp); -+ } -+ -+ tg3_full_unlock(tp); -+ -+ if (irq_sync && !err2) -+ tg3_phy_start(tp); -+ } -+ if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) -+ tg3_power_down_prepare(tp); -+ -+} -+ -+#ifdef BCM_HAS_IEEE1588_SUPPORT -+static int tg3_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ struct hwtstamp_config stmpconf; -+ -+ if (!tg3_flag(tp, PTP_CAPABLE)) -+ return -EOPNOTSUPP; -+ -+ if (copy_from_user(&stmpconf, ifr->ifr_data, sizeof(stmpconf))) -+ return -EFAULT; -+ -+ if (stmpconf.flags) -+ return -EINVAL; -+ -+ if (stmpconf.tx_type != HWTSTAMP_TX_ON && -+ stmpconf.tx_type != HWTSTAMP_TX_OFF) -+ return -ERANGE; -+ -+ switch (stmpconf.rx_filter) { -+ case HWTSTAMP_FILTER_NONE: -+ tp->rxptpctl = 0; -+ break; -+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: -+ tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V1_EN | -+ TG3_RX_PTP_CTL_ALL_V1_EVENTS; -+ break; -+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: -+ tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V1_EN | -+ TG3_RX_PTP_CTL_SYNC_EVNT; -+ break; -+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: -+ tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V1_EN | -+ TG3_RX_PTP_CTL_DELAY_REQ; -+ break; -+ case HWTSTAMP_FILTER_PTP_V2_EVENT: -+ tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_EN | -+ TG3_RX_PTP_CTL_ALL_V2_EVENTS; -+ break; -+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: -+ tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | -+ TG3_RX_PTP_CTL_ALL_V2_EVENTS; -+ break; -+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: -+ tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | -+ TG3_RX_PTP_CTL_ALL_V2_EVENTS; -+ break; -+ case HWTSTAMP_FILTER_PTP_V2_SYNC: -+ tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_EN | -+ TG3_RX_PTP_CTL_SYNC_EVNT; -+ break; -+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: -+ tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | -+ TG3_RX_PTP_CTL_SYNC_EVNT; -+ break; -+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: -+ tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | -+ TG3_RX_PTP_CTL_SYNC_EVNT; -+ break; -+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: -+ tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_EN | -+ TG3_RX_PTP_CTL_DELAY_REQ; -+ break; -+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: -+ tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | -+ TG3_RX_PTP_CTL_DELAY_REQ; -+ break; -+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: -+ tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | -+ TG3_RX_PTP_CTL_DELAY_REQ; -+ break; -+ default: -+ return -ERANGE; -+ } -+ -+ if (netif_running(dev) && tp->rxptpctl) -+ tw32(TG3_RX_PTP_CTL, -+ tp->rxptpctl | TG3_RX_PTP_CTL_HWTS_INTERLOCK); -+ -+ if (stmpconf.tx_type == HWTSTAMP_TX_ON) -+ tg3_flag_set(tp, TX_TSTAMP_EN); -+ else -+ tg3_flag_clear(tp, TX_TSTAMP_EN); -+ -+ return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ? -+ -EFAULT : 0; -+} -+ -+static int tg3_hwtstamp_get(struct net_device *dev, struct ifreq *ifr) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ struct hwtstamp_config stmpconf; -+ -+ if (!tg3_flag(tp, PTP_CAPABLE)) -+ return -EOPNOTSUPP; -+ -+ stmpconf.flags = 0; -+ stmpconf.tx_type = (tg3_flag(tp, TX_TSTAMP_EN) ? -+ HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF); -+ -+ switch (tp->rxptpctl) { -+ case 0: -+ stmpconf.rx_filter = HWTSTAMP_FILTER_NONE; -+ break; -+ case TG3_RX_PTP_CTL_RX_PTP_V1_EN | TG3_RX_PTP_CTL_ALL_V1_EVENTS: -+ stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; -+ break; -+ case TG3_RX_PTP_CTL_RX_PTP_V1_EN | TG3_RX_PTP_CTL_SYNC_EVNT: -+ stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC; -+ break; -+ case TG3_RX_PTP_CTL_RX_PTP_V1_EN | TG3_RX_PTP_CTL_DELAY_REQ: -+ stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ; -+ break; -+ case TG3_RX_PTP_CTL_RX_PTP_V2_EN | TG3_RX_PTP_CTL_ALL_V2_EVENTS: -+ stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; -+ break; -+ case TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | TG3_RX_PTP_CTL_ALL_V2_EVENTS: -+ stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; -+ break; -+ case TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | TG3_RX_PTP_CTL_ALL_V2_EVENTS: -+ stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; -+ break; -+ case TG3_RX_PTP_CTL_RX_PTP_V2_EN | TG3_RX_PTP_CTL_SYNC_EVNT: -+ stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC; -+ break; -+ case TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | TG3_RX_PTP_CTL_SYNC_EVNT: -+ stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_SYNC; -+ break; -+ case TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | TG3_RX_PTP_CTL_SYNC_EVNT: -+ stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_SYNC; -+ break; -+ case TG3_RX_PTP_CTL_RX_PTP_V2_EN | TG3_RX_PTP_CTL_DELAY_REQ: -+ stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ; -+ break; -+ case TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | TG3_RX_PTP_CTL_DELAY_REQ: -+ stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ; -+ break; -+ case TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | TG3_RX_PTP_CTL_DELAY_REQ: -+ stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ; -+ break; -+ default: -+ WARN_ON_ONCE(1); -+ return -ERANGE; -+ } -+ -+ return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ? -+ -EFAULT : 0; -+} -+#endif /* BCM_HAS_IEEE1588_SUPPORT */ -+ -+static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+#if (LINUX_VERSION_CODE >= 0x020607) -+ struct mii_ioctl_data *data = if_mii(ifr); -+#else -+ struct mii_ioctl_data *data = (struct mii_ioctl_data *) &ifr->ifr_ifru; -+#endif -+ struct tg3 *tp = netdev_priv(dev); -+ int err; -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_flag(tp, USE_PHYLIB)) { -+ struct phy_device *phydev; -+ if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) -+ return -EAGAIN; -+ phydev = tp->mdio_bus->phy_map[tp->phy_addr]; -+ return phy_mii_ioctl(phydev, ifr, cmd); -+ } -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+ -+ switch (cmd) { -+ case SIOCGMIIPHY: -+ data->phy_id = tp->phy_addr; -+ -+ /* fallthru */ -+ case SIOCGMIIREG: { -+ u32 mii_regval; -+ -+ if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) -+ break; /* We have no PHY */ -+ -+ if (!netif_running(dev)) -+ return -EAGAIN; -+ -+ spin_lock_bh(&tp->lock); -+ err = __tg3_readphy(tp, data->phy_id & 0x1f, -+ data->reg_num & 0x1f, &mii_regval); -+ spin_unlock_bh(&tp->lock); -+ -+ data->val_out = mii_regval; -+ -+ return err; -+ } -+ -+ case SIOCSMIIREG: -+ if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) -+ break; /* We have no PHY */ -+ -+ if (!netif_running(dev)) -+ return -EAGAIN; -+ -+ spin_lock_bh(&tp->lock); -+ err = __tg3_writephy(tp, data->phy_id & 0x1f, -+ data->reg_num & 0x1f, data->val_in); -+ spin_unlock_bh(&tp->lock); -+ -+ return err; -+ -+#if defined(__VMKLNX__) && !defined(TG3_VMWARE_BMAPILNX_DISABLE) -+ case BRCM_VMWARE_CIM_IOCTL: -+ return tg3_vmware_ioctl_cim(dev, ifr); -+#endif /* TG3_VMWARE_BMAPILNX */ -+ -+#ifdef BCM_HAS_IEEE1588_SUPPORT -+ case SIOCSHWTSTAMP: -+ return tg3_hwtstamp_set(dev, ifr); -+ -+ case SIOCGHWTSTAMP: -+ return tg3_hwtstamp_get(dev, ifr); -+#endif /* BCM_HAS_IEEE1588_SUPPORT */ -+ -+ default: -+ /* do nothing */ -+ break; -+ } -+ return -EOPNOTSUPP; -+} -+ -+static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ memcpy(ec, &tp->coal, sizeof(*ec)); -+ return 0; -+} -+ -+static int tg3_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ u32 max_rxcoal_tick_int = 0, max_txcoal_tick_int = 0; -+ u32 max_stat_coal_ticks = 0, min_stat_coal_ticks = 0; -+ -+ if (!tg3_flag(tp, 5705_PLUS)) { -+ max_rxcoal_tick_int = MAX_RXCOAL_TICK_INT; -+ max_txcoal_tick_int = MAX_TXCOAL_TICK_INT; -+ max_stat_coal_ticks = MAX_STAT_COAL_TICKS; -+ min_stat_coal_ticks = MIN_STAT_COAL_TICKS; -+ } -+ -+ if ((ec->rx_coalesce_usecs > MAX_RXCOL_TICKS) || -+ (ec->tx_coalesce_usecs > MAX_TXCOL_TICKS) || -+ (ec->rx_max_coalesced_frames > MAX_RXMAX_FRAMES) || -+ (ec->tx_max_coalesced_frames > MAX_TXMAX_FRAMES) || -+ (ec->rx_coalesce_usecs_irq > max_rxcoal_tick_int) || -+ (ec->tx_coalesce_usecs_irq > max_txcoal_tick_int) || -+ (ec->rx_max_coalesced_frames_irq > MAX_RXCOAL_MAXF_INT) || -+ (ec->tx_max_coalesced_frames_irq > MAX_TXCOAL_MAXF_INT) || -+ (ec->stats_block_coalesce_usecs > max_stat_coal_ticks) || -+ (ec->stats_block_coalesce_usecs < min_stat_coal_ticks)) -+ return -EINVAL; -+ -+ /* No rx interrupts will be generated if both are zero */ -+ if ((ec->rx_coalesce_usecs == 0) && -+ (ec->rx_max_coalesced_frames == 0)) -+ return -EINVAL; -+ -+ /* No tx interrupts will be generated if both are zero */ -+ if ((ec->tx_coalesce_usecs == 0) && -+ (ec->tx_max_coalesced_frames == 0)) -+ return -EINVAL; -+ -+ /* Only copy relevant parameters, ignore all others. */ -+ tp->coal.rx_coalesce_usecs = ec->rx_coalesce_usecs; -+ tp->coal.tx_coalesce_usecs = ec->tx_coalesce_usecs; -+ tp->coal.rx_max_coalesced_frames = ec->rx_max_coalesced_frames; -+ tp->coal.tx_max_coalesced_frames = ec->tx_max_coalesced_frames; -+ tp->coal.rx_coalesce_usecs_irq = ec->rx_coalesce_usecs_irq; -+ tp->coal.tx_coalesce_usecs_irq = ec->tx_coalesce_usecs_irq; -+ tp->coal.rx_max_coalesced_frames_irq = ec->rx_max_coalesced_frames_irq; -+ tp->coal.tx_max_coalesced_frames_irq = ec->tx_max_coalesced_frames_irq; -+ tp->coal.stats_block_coalesce_usecs = ec->stats_block_coalesce_usecs; -+ -+ if (netif_running(dev)) { -+ tg3_full_lock(tp, 0); -+ __tg3_set_coalesce(tp, &tp->coal); -+ tg3_full_unlock(tp); -+ } -+ return 0; -+} -+ -+static u32 tg3_get_link(struct net_device *dev) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (!netif_running(tp->dev)) -+ return 0; -+ -+ if (tg3_flag(tp, POLL_CPMU_LINK)) { -+ u32 cpmu = tr32(TG3_CPMU_STATUS); -+ return !((cpmu & TG3_CPMU_STATUS_LINK_MASK) == -+ TG3_CPMU_STATUS_LINK_MASK); -+ } -+ -+ return tp->link_up; -+} -+ -+#if defined(ETHTOOL_GEEE) -+static int tg3_set_eee(struct net_device *dev, struct ethtool_eee *edata) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) { -+ netdev_warn(tp->dev, "Board does not support EEE!\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (edata->advertised != tp->eee.advertised) { -+ netdev_warn(tp->dev, -+ "Direct manipulation of EEE advertisement is not supported\n"); -+ return -EINVAL; -+ } -+ -+ if (edata->tx_lpi_timer > TG3_CPMU_DBTMR1_LNKIDLE_MAX) { -+ netdev_warn(tp->dev, -+ "Maximal Tx Lpi timer supported is %#x(u)\n", -+ TG3_CPMU_DBTMR1_LNKIDLE_MAX); -+ return -EINVAL; -+ } -+ -+ tp->eee = *edata; -+ -+ tp->phy_flags |= TG3_PHYFLG_USER_CONFIGURED; -+ tg3_warn_mgmt_link_flap(tp); -+ -+ if (netif_running(tp->dev)) { -+ tg3_full_lock(tp, 0); -+ tg3_setup_eee(tp); -+ tg3_phy_reset(tp); -+ tg3_full_unlock(tp); -+ } -+ -+ return 0; -+} -+ -+static int tg3_get_eee(struct net_device *dev, struct ethtool_eee *edata) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) { -+ netdev_warn(tp->dev, -+ "Board does not support EEE!\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ *edata = tp->eee; -+ return 0; -+} -+#endif -+ -+static struct ethtool_ops tg3_ethtool_ops = { -+ .get_settings = tg3_get_settings, -+ .set_settings = tg3_set_settings, -+ .get_drvinfo = tg3_get_drvinfo, -+ .get_regs_len = tg3_get_regs_len, -+ .get_regs = tg3_get_regs, -+ .get_wol = tg3_get_wol, -+ .set_wol = tg3_set_wol, -+ .get_msglevel = tg3_get_msglevel, -+ .set_msglevel = tg3_set_msglevel, -+ .nway_reset = tg3_nway_reset, -+ .get_link = tg3_get_link, -+#if (LINUX_VERSION_CODE >= 0x20418) -+ .get_eeprom_len = tg3_get_eeprom_len, -+#endif -+#ifdef ETHTOOL_GEEPROM -+ .get_eeprom = tg3_get_eeprom, -+#endif -+#ifdef ETHTOOL_SEEPROM -+ .set_eeprom = tg3_set_eeprom, -+#endif -+ .get_ringparam = tg3_get_ringparam, -+ .set_ringparam = tg3_set_ringparam, -+ .get_pauseparam = tg3_get_pauseparam, -+ .set_pauseparam = tg3_set_pauseparam, -+ .self_test = tg3_self_test, -+ .get_strings = tg3_get_strings, -+#if defined(BCM_HAS_SET_PHYS_ID) && !defined(GET_ETHTOOL_OP_EXT) -+ .set_phys_id = tg3_set_phys_id, -+#endif -+ .get_ethtool_stats = tg3_get_ethtool_stats, -+ .get_coalesce = tg3_get_coalesce, -+ .set_coalesce = tg3_set_coalesce, -+#if (LINUX_VERSION_CODE >= 0x20618) || defined (__VMKLNX__) -+ .get_sset_count = tg3_get_sset_count, -+#endif -+#if defined(BCM_HAS_GET_RXNFC) && !defined(GET_ETHTOOL_OP_EXT) -+ .get_rxnfc = tg3_get_rxnfc, -+#endif /* BCM_HAS_GET_RXNFC */ -+#if defined(BCM_HAS_GET_RXFH_INDIR) && !defined(GET_ETHTOOL_OP_EXT) -+#ifdef BCM_HAS_GET_RXFH_INDIR_SIZE -+ .get_rxfh_indir_size = tg3_get_rxfh_indir_size, -+#endif /* BCM_HAS_GET_RXFH_INDIR_SIZE */ -+#ifdef BCM_HAS_OLD_RXFH_INDIR -+ .get_rxfh_indir = tg3_get_rxfh_indir, -+ .set_rxfh_indir = tg3_set_rxfh_indir, -+#else -+ .get_rxfh = tg3_get_rxfh, -+ .set_rxfh = tg3_set_rxfh, -+#endif -+#endif /* BCM_HAS_GET_RXFH_INDIR */ -+#if defined(ETHTOOL_GCHANNELS) && !defined(GET_ETHTOOL_OP_EXT) -+ .get_channels = tg3_get_channels, -+ .set_channels = tg3_set_channels, -+#endif -+ -+#ifndef BCM_HAS_NETDEV_UPDATE_FEATURES -+ .get_rx_csum = tg3_get_rx_csum, -+ .set_rx_csum = tg3_set_rx_csum, -+ .get_tx_csum = ethtool_op_get_tx_csum, -+#ifdef BCM_HAS_SET_TX_CSUM -+ .set_tx_csum = tg3_set_tx_csum, -+#endif -+#if TG3_TSO_SUPPORT != 0 -+ .get_tso = ethtool_op_get_tso, -+ .set_tso = tg3_set_tso, -+#endif -+#endif /* BCM_HAS_NETDEV_UPDATE_FEATURES */ -+#ifdef ETHTOOL_GSG -+#if defined(BCM_HAS_ETHTOOL_OP_SET_SG) && !defined(BCM_HAS_FIX_FEATURES) -+ .get_sg = ethtool_op_get_sg, -+ .set_sg = ethtool_op_set_sg, -+#endif -+#endif -+#if (LINUX_VERSION_CODE < 0x20618) -+ .self_test_count = tg3_get_test_count, -+#endif -+#if !defined(BCM_HAS_SET_PHYS_ID) || defined(GET_ETHTOOL_OP_EXT) -+ .phys_id = tg3_phys_id, -+#endif -+#if (LINUX_VERSION_CODE < 0x20618) -+ .get_stats_count = tg3_get_stats_count, -+#endif -+#if defined(ETHTOOL_GPERMADDR) && (LINUX_VERSION_CODE < 0x020617) -+ .get_perm_addr = ethtool_op_get_perm_addr, -+#endif -+#if IS_ENABLED(CONFIG_PTP_1588_CLOCK) && defined(ETHTOOL_GET_TS_INFO) && !defined(GET_ETHTOOL_OP_EXT) -+ .get_ts_info = tg3_get_ts_info, -+#endif -+#if defined(ETHTOOL_GEEE) && !defined(GET_ETHTOOL_OP_EXT) -+ .get_eee = tg3_get_eee, -+ .set_eee = tg3_set_eee, -+#endif -+}; -+ -+#ifdef GET_ETHTOOL_OP_EXT -+static const struct ethtool_ops_ext tg3_ethtool_ops_ext = { -+ .size = sizeof(struct ethtool_ops_ext), -+ .get_ts_info = tg3_get_ts_info, -+#ifdef ETHTOOL_GEEE -+ .get_eee = tg3_get_eee, -+ .set_eee = tg3_set_eee, -+#endif -+ .get_channels = tg3_get_channels, -+ .set_channels = tg3_set_channels, -+}; -+#endif -+ -+static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ spin_lock_bh(&tp->lock); -+ if (!tp->hw_stats) { -+ spin_unlock_bh(&tp->lock); -+ return &tp->net_stats_prev; -+ } -+ -+ tg3_get_nstats(tp, stats); -+ spin_unlock_bh(&tp->lock); -+ -+ return stats; -+} -+ -+#ifdef GET_NETDEV_OP_EXT -+static const struct net_device_ops_ext tg3_net_device_ops_ext = { -+ .size = sizeof(struct net_device_ops_ext), -+ .ndo_fix_features = tg3_fix_features, -+ .ndo_set_features = tg3_set_features, -+ .ndo_get_stats64 = tg3_get_stats64, -+}; -+#endif -+ -+static void tg3_set_rx_mode(struct net_device *dev) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (!netif_running(dev)) -+ return; -+ -+ tg3_full_lock(tp, 0); -+ __tg3_set_rx_mode(dev); -+ tg3_full_unlock(tp); -+} -+ -+static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp, -+ int new_mtu) -+{ -+ dev->mtu = new_mtu; -+ -+ if (new_mtu > ETH_DATA_LEN) { -+ if (tg3_flag(tp, 5780_CLASS)) { -+ netdev_update_features(dev); -+ tg3_flag_clear(tp, TSO_CAPABLE); -+#if TG3_TSO_SUPPORT != 0 -+#ifdef BCM_HAS_ETHTOOL_OP_SET_TSO -+ ethtool_op_set_tso(dev, 0); -+#endif -+#endif -+ } else { -+ tg3_flag_set(tp, JUMBO_RING_ENABLE); -+ } -+ } else { -+ if (tg3_flag(tp, 5780_CLASS)) { -+ tg3_flag_set(tp, TSO_CAPABLE); -+ netdev_update_features(dev); -+ } -+ tg3_flag_clear(tp, JUMBO_RING_ENABLE); -+ } -+} -+ -+static int tg3_change_mtu(struct net_device *dev, int new_mtu) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ int err; -+ bool reset_phy = false; -+ -+ if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp)) -+ return -EINVAL; -+ -+ if (!netif_running(dev)) { -+ /* We'll just catch it later when the -+ * device is up'd. -+ */ -+ tg3_set_mtu(dev, tp, new_mtu); -+ return 0; -+ } -+ -+#if defined(__VMKLNX__) && (VMWARE_ESX_DDK_VERSION < 50000) -+ /* There is no need to hold rtnl_lock -+ * when calling change MTU into driver -+ * from VMkernel ESX 5.0 onwards. -+ */ -+ rtnl_lock(); -+#endif -+ -+ tg3_phy_stop(tp); -+ -+ tg3_netif_stop(tp); -+ -+ tg3_set_mtu(dev, tp, new_mtu); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tg3_netq_invalidate_state(tp); -+#endif -+ -+ tg3_full_lock(tp, 1); -+ -+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); -+ -+ /* Reset PHY, otherwise the read DMA engine will be in a mode that -+ * breaks all requests to 256 bytes. -+ */ -+ if (tg3_asic_rev(tp) == ASIC_REV_57766) -+ reset_phy = true; -+ -+ err = tg3_restart_hw(tp, reset_phy); -+ -+ if (!err) -+ tg3_netif_start(tp); -+ -+ tg3_full_unlock(tp); -+ -+ if (!err) -+ tg3_phy_start(tp); -+ -+#if defined(__VMKLNX__) && (VMWARE_ESX_DDK_VERSION < 50000) -+ rtnl_unlock(); -+#endif -+ -+ return err; -+} -+ -+#ifdef BCM_HAS_NET_DEVICE_OPS -+static const struct net_device_ops tg3_netdev_ops = { -+ .ndo_open = tg3_open, -+ .ndo_stop = tg3_close, -+ .ndo_start_xmit = tg3_start_xmit, -+#if defined(BCM_HAS_GET_STATS64) -+#if !defined(GET_NETDEV_OP_EXT) -+ .ndo_get_stats64 = tg3_get_stats64, -+#endif -+#else -+ .ndo_get_stats = tg3_get_stats, -+#endif -+ .ndo_validate_addr = eth_validate_addr, -+#ifdef BCM_HAS_SET_MULTICAST_LIST -+ .ndo_set_multicast_list = tg3_set_rx_mode, -+#else -+ .ndo_set_rx_mode = tg3_set_rx_mode, -+#endif -+ .ndo_set_mac_address = tg3_set_mac_addr, -+ .ndo_do_ioctl = tg3_ioctl, -+ .ndo_tx_timeout = tg3_tx_timeout, -+ .ndo_change_mtu = tg3_change_mtu, -+#if defined(BCM_HAS_FIX_FEATURES) && !defined(GET_NETDEV_OP_EXT) -+ .ndo_fix_features = tg3_fix_features, -+ .ndo_set_features = tg3_set_features, -+#endif -+#if defined(BCM_KERNEL_SUPPORTS_8021Q) && !defined(BCM_HAS_NEW_VLAN_INTERFACE) -+ .ndo_vlan_rx_register = tg3_vlan_rx_register, -+#endif -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ .ndo_poll_controller = tg3_poll_controller, -+#endif -+}; -+#endif /* BCM_HAS_NET_DEVICE_OPS */ -+ -+static void __devinit tg3_get_eeprom_size(struct tg3 *tp) -+{ -+ u32 cursize, val, magic; -+ -+ tp->nvram_size = EEPROM_CHIP_SIZE; -+ -+ if (tg3_nvram_read(tp, 0, &magic) != 0) -+ return; -+ -+ if ((magic != TG3_EEPROM_MAGIC) && -+ ((magic & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW) && -+ ((magic & TG3_EEPROM_MAGIC_HW_MSK) != TG3_EEPROM_MAGIC_HW)) -+ return; -+ -+ /* -+ * Size the chip by reading offsets at increasing powers of two. -+ * When we encounter our validation signature, we know the addressing -+ * has wrapped around, and thus have our chip size. -+ */ -+ cursize = 0x10; -+ -+ while (cursize < tp->nvram_size) { -+ if (tg3_nvram_read(tp, cursize, &val) != 0) -+ return; -+ -+ if (val == magic) -+ break; -+ -+ cursize <<= 1; -+ } -+ -+ tp->nvram_size = cursize; -+} -+ -+static void __devinit tg3_get_nvram_size(struct tg3 *tp) -+{ -+ u32 val; -+ -+ if (tg3_flag(tp, NO_NVRAM) || tg3_nvram_read(tp, 0, &val) != 0) -+ return; -+ -+ /* Selfboot format */ -+ if (val != TG3_EEPROM_MAGIC) { -+ tg3_get_eeprom_size(tp); -+ return; -+ } -+ -+ if (tg3_nvram_read(tp, 0xf0, &val) == 0) { -+ if (val != 0) { -+ /* This is confusing. We want to operate on the -+ * 16-bit value at offset 0xf2. The tg3_nvram_read() -+ * call will read from NVRAM and byteswap the data -+ * according to the byteswapping settings for all -+ * other register accesses. This ensures the data we -+ * want will always reside in the lower 16-bits. -+ * However, the data in NVRAM is in LE format, which -+ * means the data from the NVRAM read will always be -+ * opposite the endianness of the CPU. The 16-bit -+ * byteswap then brings the data to CPU endianness. -+ */ -+ tp->nvram_size = swab16((u16)(val & 0x0000ffff)) * 1024; -+ return; -+ } -+ } -+ tp->nvram_size = TG3_NVRAM_SIZE_512KB; -+} -+ -+static void __devinit tg3_get_nvram_info(struct tg3 *tp) -+{ -+ u32 nvcfg1; -+ -+ nvcfg1 = tr32(NVRAM_CFG1); -+ if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) { -+ tg3_flag_set(tp, FLASH); -+ } else { -+ nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; -+ tw32(NVRAM_CFG1, nvcfg1); -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5750 || -+ tg3_flag(tp, 5780_CLASS)) { -+ switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) { -+ case FLASH_VENDOR_ATMEL_FLASH_BUFFERED: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ break; -+ case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tp->nvram_pagesize = ATMEL_AT25F512_PAGE_SIZE; -+ break; -+ case FLASH_VENDOR_ATMEL_EEPROM: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ break; -+ case FLASH_VENDOR_ST: -+ tp->nvram_jedecnum = JEDEC_ST; -+ tp->nvram_pagesize = ST_M45PEX0_PAGE_SIZE; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ break; -+ case FLASH_VENDOR_SAIFUN: -+ tp->nvram_jedecnum = JEDEC_SAIFUN; -+ tp->nvram_pagesize = SAIFUN_SA25F0XX_PAGE_SIZE; -+ break; -+ case FLASH_VENDOR_SST_SMALL: -+ case FLASH_VENDOR_SST_LARGE: -+ tp->nvram_jedecnum = JEDEC_SST; -+ tp->nvram_pagesize = SST_25VF0X0_PAGE_SIZE; -+ break; -+ } -+ } else { -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ } -+} -+ -+static void __devinit tg3_nvram_get_pagesize(struct tg3 *tp, u32 nvmcfg1) -+{ -+ switch (nvmcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) { -+ case FLASH_5752PAGE_SIZE_256: -+ tp->nvram_pagesize = 256; -+ break; -+ case FLASH_5752PAGE_SIZE_512: -+ tp->nvram_pagesize = 512; -+ break; -+ case FLASH_5752PAGE_SIZE_1K: -+ tp->nvram_pagesize = 1024; -+ break; -+ case FLASH_5752PAGE_SIZE_2K: -+ tp->nvram_pagesize = 2048; -+ break; -+ case FLASH_5752PAGE_SIZE_4K: -+ tp->nvram_pagesize = 4096; -+ break; -+ case FLASH_5752PAGE_SIZE_264: -+ tp->nvram_pagesize = 264; -+ break; -+ case FLASH_5752PAGE_SIZE_528: -+ tp->nvram_pagesize = 528; -+ break; -+ } -+} -+ -+static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp) -+{ -+ u32 nvcfg1; -+ -+ nvcfg1 = tr32(NVRAM_CFG1); -+ -+ /* NVRAM protection for TPM */ -+ if (nvcfg1 & (1 << 27)) -+ tg3_flag_set(tp, PROTECTED_NVRAM); -+ -+ switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { -+ case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ: -+ case FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ break; -+ case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ break; -+ case FLASH_5752VENDOR_ST_M45PE10: -+ case FLASH_5752VENDOR_ST_M45PE20: -+ case FLASH_5752VENDOR_ST_M45PE40: -+ tp->nvram_jedecnum = JEDEC_ST; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ break; -+ } -+ -+ if (tg3_flag(tp, FLASH)) { -+ tg3_nvram_get_pagesize(tp, nvcfg1); -+ } else { -+ /* For eeprom, set pagesize to maximum eeprom size */ -+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; -+ -+ nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; -+ tw32(NVRAM_CFG1, nvcfg1); -+ } -+} -+ -+static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp) -+{ -+ u32 nvcfg1, protect = 0; -+ -+ nvcfg1 = tr32(NVRAM_CFG1); -+ -+ /* NVRAM protection for TPM */ -+ if (nvcfg1 & (1 << 27)) { -+ tg3_flag_set(tp, PROTECTED_NVRAM); -+ protect = 1; -+ } -+ -+ nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK; -+ switch (nvcfg1) { -+ case FLASH_5755VENDOR_ATMEL_FLASH_1: -+ case FLASH_5755VENDOR_ATMEL_FLASH_2: -+ case FLASH_5755VENDOR_ATMEL_FLASH_3: -+ case FLASH_5755VENDOR_ATMEL_FLASH_5: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ tp->nvram_pagesize = 264; -+ if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 || -+ nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5) -+ tp->nvram_size = (protect ? 0x3e200 : -+ TG3_NVRAM_SIZE_512KB); -+ else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2) -+ tp->nvram_size = (protect ? 0x1f200 : -+ TG3_NVRAM_SIZE_256KB); -+ else -+ tp->nvram_size = (protect ? 0x1f200 : -+ TG3_NVRAM_SIZE_128KB); -+ break; -+ case FLASH_5752VENDOR_ST_M45PE10: -+ case FLASH_5752VENDOR_ST_M45PE20: -+ case FLASH_5752VENDOR_ST_M45PE40: -+ tp->nvram_jedecnum = JEDEC_ST; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ tp->nvram_pagesize = 256; -+ if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10) -+ tp->nvram_size = (protect ? -+ TG3_NVRAM_SIZE_64KB : -+ TG3_NVRAM_SIZE_128KB); -+ else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20) -+ tp->nvram_size = (protect ? -+ TG3_NVRAM_SIZE_64KB : -+ TG3_NVRAM_SIZE_256KB); -+ else -+ tp->nvram_size = (protect ? -+ TG3_NVRAM_SIZE_128KB : -+ TG3_NVRAM_SIZE_512KB); -+ break; -+ } -+} -+ -+static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp) -+{ -+ u32 nvcfg1; -+ -+ nvcfg1 = tr32(NVRAM_CFG1); -+ -+ switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { -+ case FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ: -+ case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ: -+ case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ: -+ case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; -+ -+ nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; -+ tw32(NVRAM_CFG1, nvcfg1); -+ break; -+ case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED: -+ case FLASH_5755VENDOR_ATMEL_FLASH_1: -+ case FLASH_5755VENDOR_ATMEL_FLASH_2: -+ case FLASH_5755VENDOR_ATMEL_FLASH_3: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ tp->nvram_pagesize = 264; -+ break; -+ case FLASH_5752VENDOR_ST_M45PE10: -+ case FLASH_5752VENDOR_ST_M45PE20: -+ case FLASH_5752VENDOR_ST_M45PE40: -+ tp->nvram_jedecnum = JEDEC_ST; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ tp->nvram_pagesize = 256; -+ break; -+ } -+} -+ -+static void __devinit tg3_get_5761_nvram_info(struct tg3 *tp) -+{ -+ u32 nvcfg1, protect = 0; -+ -+ nvcfg1 = tr32(NVRAM_CFG1); -+ -+ /* NVRAM protection for TPM */ -+ if (nvcfg1 & (1 << 27)) { -+ tg3_flag_set(tp, PROTECTED_NVRAM); -+ protect = 1; -+ } -+ -+ nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK; -+ switch (nvcfg1) { -+ case FLASH_5761VENDOR_ATMEL_ADB021D: -+ case FLASH_5761VENDOR_ATMEL_ADB041D: -+ case FLASH_5761VENDOR_ATMEL_ADB081D: -+ case FLASH_5761VENDOR_ATMEL_ADB161D: -+ case FLASH_5761VENDOR_ATMEL_MDB021D: -+ case FLASH_5761VENDOR_ATMEL_MDB041D: -+ case FLASH_5761VENDOR_ATMEL_MDB081D: -+ case FLASH_5761VENDOR_ATMEL_MDB161D: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS); -+ tp->nvram_pagesize = 256; -+ break; -+ case FLASH_5761VENDOR_ST_A_M45PE20: -+ case FLASH_5761VENDOR_ST_A_M45PE40: -+ case FLASH_5761VENDOR_ST_A_M45PE80: -+ case FLASH_5761VENDOR_ST_A_M45PE16: -+ case FLASH_5761VENDOR_ST_M_M45PE20: -+ case FLASH_5761VENDOR_ST_M_M45PE40: -+ case FLASH_5761VENDOR_ST_M_M45PE80: -+ case FLASH_5761VENDOR_ST_M_M45PE16: -+ tp->nvram_jedecnum = JEDEC_ST; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ tp->nvram_pagesize = 256; -+ break; -+ } -+ -+ if (protect) { -+ tp->nvram_size = tr32(NVRAM_ADDR_LOCKOUT); -+ } else { -+ switch (nvcfg1) { -+ case FLASH_5761VENDOR_ATMEL_ADB161D: -+ case FLASH_5761VENDOR_ATMEL_MDB161D: -+ case FLASH_5761VENDOR_ST_A_M45PE16: -+ case FLASH_5761VENDOR_ST_M_M45PE16: -+ tp->nvram_size = TG3_NVRAM_SIZE_2MB; -+ break; -+ case FLASH_5761VENDOR_ATMEL_ADB081D: -+ case FLASH_5761VENDOR_ATMEL_MDB081D: -+ case FLASH_5761VENDOR_ST_A_M45PE80: -+ case FLASH_5761VENDOR_ST_M_M45PE80: -+ tp->nvram_size = TG3_NVRAM_SIZE_1MB; -+ break; -+ case FLASH_5761VENDOR_ATMEL_ADB041D: -+ case FLASH_5761VENDOR_ATMEL_MDB041D: -+ case FLASH_5761VENDOR_ST_A_M45PE40: -+ case FLASH_5761VENDOR_ST_M_M45PE40: -+ tp->nvram_size = TG3_NVRAM_SIZE_512KB; -+ break; -+ case FLASH_5761VENDOR_ATMEL_ADB021D: -+ case FLASH_5761VENDOR_ATMEL_MDB021D: -+ case FLASH_5761VENDOR_ST_A_M45PE20: -+ case FLASH_5761VENDOR_ST_M_M45PE20: -+ tp->nvram_size = TG3_NVRAM_SIZE_256KB; -+ break; -+ } -+ } -+} -+ -+static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp) -+{ -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; -+} -+ -+static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp) -+{ -+ u32 nvcfg1; -+ -+ nvcfg1 = tr32(NVRAM_CFG1); -+ -+ switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { -+ case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ: -+ case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; -+ -+ nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; -+ tw32(NVRAM_CFG1, nvcfg1); -+ return; -+ case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED: -+ case FLASH_57780VENDOR_ATMEL_AT45DB011D: -+ case FLASH_57780VENDOR_ATMEL_AT45DB011B: -+ case FLASH_57780VENDOR_ATMEL_AT45DB021D: -+ case FLASH_57780VENDOR_ATMEL_AT45DB021B: -+ case FLASH_57780VENDOR_ATMEL_AT45DB041D: -+ case FLASH_57780VENDOR_ATMEL_AT45DB041B: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ -+ switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { -+ case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED: -+ case FLASH_57780VENDOR_ATMEL_AT45DB011D: -+ case FLASH_57780VENDOR_ATMEL_AT45DB011B: -+ tp->nvram_size = TG3_NVRAM_SIZE_128KB; -+ break; -+ case FLASH_57780VENDOR_ATMEL_AT45DB021D: -+ case FLASH_57780VENDOR_ATMEL_AT45DB021B: -+ tp->nvram_size = TG3_NVRAM_SIZE_256KB; -+ break; -+ case FLASH_57780VENDOR_ATMEL_AT45DB041D: -+ case FLASH_57780VENDOR_ATMEL_AT45DB041B: -+ tp->nvram_size = TG3_NVRAM_SIZE_512KB; -+ break; -+ } -+ break; -+ case FLASH_5752VENDOR_ST_M45PE10: -+ case FLASH_5752VENDOR_ST_M45PE20: -+ case FLASH_5752VENDOR_ST_M45PE40: -+ tp->nvram_jedecnum = JEDEC_ST; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ -+ switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { -+ case FLASH_5752VENDOR_ST_M45PE10: -+ tp->nvram_size = TG3_NVRAM_SIZE_128KB; -+ break; -+ case FLASH_5752VENDOR_ST_M45PE20: -+ tp->nvram_size = TG3_NVRAM_SIZE_256KB; -+ break; -+ case FLASH_5752VENDOR_ST_M45PE40: -+ tp->nvram_size = TG3_NVRAM_SIZE_512KB; -+ break; -+ } -+ break; -+ default: -+ tg3_flag_set(tp, NO_NVRAM); -+ return; -+ } -+ -+ tg3_nvram_get_pagesize(tp, nvcfg1); -+ if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528) -+ tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS); -+} -+ -+ -+static void __devinit tg3_get_5717_nvram_info(struct tg3 *tp) -+{ -+ u32 nvcfg1; -+ -+ nvcfg1 = tr32(NVRAM_CFG1); -+ -+ switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { -+ case FLASH_5717VENDOR_ATMEL_EEPROM: -+ case FLASH_5717VENDOR_MICRO_EEPROM: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; -+ -+ nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; -+ tw32(NVRAM_CFG1, nvcfg1); -+ return; -+ case FLASH_5717VENDOR_ATMEL_MDB011D: -+ case FLASH_5717VENDOR_ATMEL_ADB011B: -+ case FLASH_5717VENDOR_ATMEL_ADB011D: -+ case FLASH_5717VENDOR_ATMEL_MDB021D: -+ case FLASH_5717VENDOR_ATMEL_ADB021B: -+ case FLASH_5717VENDOR_ATMEL_ADB021D: -+ case FLASH_5717VENDOR_ATMEL_45USPT: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ -+ switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { -+ case FLASH_5717VENDOR_ATMEL_MDB021D: -+ /* Detect size with tg3_nvram_get_size() */ -+ break; -+ case FLASH_5717VENDOR_ATMEL_ADB021B: -+ case FLASH_5717VENDOR_ATMEL_ADB021D: -+ tp->nvram_size = TG3_NVRAM_SIZE_256KB; -+ break; -+ default: -+ tp->nvram_size = TG3_NVRAM_SIZE_128KB; -+ break; -+ } -+ break; -+ case FLASH_5717VENDOR_ST_M_M25PE10: -+ case FLASH_5717VENDOR_ST_A_M25PE10: -+ case FLASH_5717VENDOR_ST_M_M45PE10: -+ case FLASH_5717VENDOR_ST_A_M45PE10: -+ case FLASH_5717VENDOR_ST_M_M25PE20: -+ case FLASH_5717VENDOR_ST_A_M25PE20: -+ case FLASH_5717VENDOR_ST_M_M45PE20: -+ case FLASH_5717VENDOR_ST_A_M45PE20: -+ case FLASH_5717VENDOR_ST_25USPT: -+ case FLASH_5717VENDOR_ST_45USPT: -+ tp->nvram_jedecnum = JEDEC_ST; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ -+ switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { -+ case FLASH_5717VENDOR_ST_M_M25PE20: -+ case FLASH_5717VENDOR_ST_M_M45PE20: -+ /* Detect size with tg3_nvram_get_size() */ -+ break; -+ case FLASH_5717VENDOR_ST_A_M25PE20: -+ case FLASH_5717VENDOR_ST_A_M45PE20: -+ tp->nvram_size = TG3_NVRAM_SIZE_256KB; -+ break; -+ default: -+ tp->nvram_size = TG3_NVRAM_SIZE_128KB; -+ break; -+ } -+ break; -+ default: -+ tg3_flag_set(tp, NO_NVRAM); -+ return; -+ } -+ -+ tg3_nvram_get_pagesize(tp, nvcfg1); -+ if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528) -+ tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS); -+} -+ -+static void __devinit tg3_get_5720_nvram_info(struct tg3 *tp) -+{ -+ u32 nvcfg1, nvmpinstrp, nv_status; -+ -+ nvcfg1 = tr32(NVRAM_CFG1); -+ nvmpinstrp = nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5762) { -+ if (!(nvcfg1 & NVRAM_CFG1_5762VENDOR_MASK)) { -+ tg3_flag_set(tp, NO_NVRAM); -+ return; -+ } -+ -+ switch (nvmpinstrp) { -+ case FLASH_5762_MX25L_100: -+ case FLASH_5762_MX25L_200: -+ case FLASH_5762_MX25L_400: -+ case FLASH_5762_MX25L_800: -+ case FLASH_5762_MX25L_160_320: -+ tp->nvram_pagesize = 4096; -+ tp->nvram_jedecnum = JEDEC_MACRONIX; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS); -+ tg3_flag_set(tp, FLASH); -+ nv_status = tr32(NVRAM_AUTOSENSE_STATUS); -+ tp->nvram_size = -+ (1 << (nv_status >> AUTOSENSE_DEVID & -+ AUTOSENSE_DEVID_MASK) -+ << AUTOSENSE_SIZE_IN_MB); -+ return; -+ -+ case FLASH_5762_EEPROM_HD: -+ nvmpinstrp = FLASH_5720_EEPROM_HD; -+ break; -+ case FLASH_5762_EEPROM_LD: -+ nvmpinstrp = FLASH_5720_EEPROM_LD; -+ break; -+ case FLASH_5720VENDOR_M_ST_M45PE20: -+ /* This pinstrap supports multiple sizes, so force it -+ * to read the actual size from location 0xf0. -+ */ -+ nvmpinstrp = FLASH_5720VENDOR_ST_45USPT; -+ break; -+ } -+ } -+ -+ switch (nvmpinstrp) { -+ case FLASH_5720_EEPROM_HD: -+ case FLASH_5720_EEPROM_LD: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ -+ nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; -+ tw32(NVRAM_CFG1, nvcfg1); -+ if (nvmpinstrp == FLASH_5720_EEPROM_HD) -+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; -+ else -+ tp->nvram_pagesize = ATMEL_AT24C02_CHIP_SIZE; -+ return; -+ case FLASH_5720VENDOR_M_ATMEL_DB011D: -+ case FLASH_5720VENDOR_A_ATMEL_DB011B: -+ case FLASH_5720VENDOR_A_ATMEL_DB011D: -+ case FLASH_5720VENDOR_M_ATMEL_DB021D: -+ case FLASH_5720VENDOR_A_ATMEL_DB021B: -+ case FLASH_5720VENDOR_A_ATMEL_DB021D: -+ case FLASH_5720VENDOR_M_ATMEL_DB041D: -+ case FLASH_5720VENDOR_A_ATMEL_DB041B: -+ case FLASH_5720VENDOR_A_ATMEL_DB041D: -+ case FLASH_5720VENDOR_M_ATMEL_DB081D: -+ case FLASH_5720VENDOR_A_ATMEL_DB081D: -+ case FLASH_5720VENDOR_ATMEL_45USPT: -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ -+ switch (nvmpinstrp) { -+ case FLASH_5720VENDOR_M_ATMEL_DB021D: -+ case FLASH_5720VENDOR_A_ATMEL_DB021B: -+ case FLASH_5720VENDOR_A_ATMEL_DB021D: -+ tp->nvram_size = TG3_NVRAM_SIZE_256KB; -+ break; -+ case FLASH_5720VENDOR_M_ATMEL_DB041D: -+ case FLASH_5720VENDOR_A_ATMEL_DB041B: -+ case FLASH_5720VENDOR_A_ATMEL_DB041D: -+ tp->nvram_size = TG3_NVRAM_SIZE_512KB; -+ break; -+ case FLASH_5720VENDOR_M_ATMEL_DB081D: -+ case FLASH_5720VENDOR_A_ATMEL_DB081D: -+ tp->nvram_size = TG3_NVRAM_SIZE_1MB; -+ break; -+ default: -+ if (tg3_asic_rev(tp) != ASIC_REV_5762) -+ tp->nvram_size = TG3_NVRAM_SIZE_128KB; -+ break; -+ } -+ break; -+ case FLASH_5720VENDOR_M_ST_M25PE10: -+ case FLASH_5720VENDOR_M_ST_M45PE10: -+ case FLASH_5720VENDOR_A_ST_M25PE10: -+ case FLASH_5720VENDOR_A_ST_M45PE10: -+ case FLASH_5720VENDOR_M_ST_M25PE20: -+ case FLASH_5720VENDOR_M_ST_M45PE20: -+ case FLASH_5720VENDOR_A_ST_M25PE20: -+ case FLASH_5720VENDOR_A_ST_M45PE20: -+ case FLASH_5720VENDOR_M_ST_M25PE40: -+ case FLASH_5720VENDOR_M_ST_M45PE40: -+ case FLASH_5720VENDOR_A_ST_M25PE40: -+ case FLASH_5720VENDOR_A_ST_M45PE40: -+ case FLASH_5720VENDOR_M_ST_M25PE80: -+ case FLASH_5720VENDOR_M_ST_M45PE80: -+ case FLASH_5720VENDOR_A_ST_M25PE80: -+ case FLASH_5720VENDOR_A_ST_M45PE80: -+ case FLASH_5720VENDOR_ST_25USPT: -+ case FLASH_5720VENDOR_ST_45USPT: -+ tp->nvram_jedecnum = JEDEC_ST; -+ tg3_flag_set(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, FLASH); -+ -+ switch (nvmpinstrp) { -+ case FLASH_5720VENDOR_M_ST_M25PE20: -+ case FLASH_5720VENDOR_M_ST_M45PE20: -+ case FLASH_5720VENDOR_A_ST_M25PE20: -+ case FLASH_5720VENDOR_A_ST_M45PE20: -+ tp->nvram_size = TG3_NVRAM_SIZE_256KB; -+ break; -+ case FLASH_5720VENDOR_M_ST_M25PE40: -+ case FLASH_5720VENDOR_M_ST_M45PE40: -+ case FLASH_5720VENDOR_A_ST_M25PE40: -+ case FLASH_5720VENDOR_A_ST_M45PE40: -+ tp->nvram_size = TG3_NVRAM_SIZE_512KB; -+ break; -+ case FLASH_5720VENDOR_M_ST_M25PE80: -+ case FLASH_5720VENDOR_M_ST_M45PE80: -+ case FLASH_5720VENDOR_A_ST_M25PE80: -+ case FLASH_5720VENDOR_A_ST_M45PE80: -+ tp->nvram_size = TG3_NVRAM_SIZE_1MB; -+ break; -+ default: -+ if (tg3_asic_rev(tp) != ASIC_REV_5762) -+ tp->nvram_size = TG3_NVRAM_SIZE_128KB; -+ break; -+ } -+ break; -+ default: -+ tg3_flag_set(tp, NO_NVRAM); -+ return; -+ } -+ -+ tg3_nvram_get_pagesize(tp, nvcfg1); -+ if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528) -+ tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5762) { -+ u32 val; -+ -+ if (tg3_nvram_read(tp, 0, &val)) -+ return; -+ -+ if (val != TG3_EEPROM_MAGIC && -+ (val & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW) -+ tg3_flag_set(tp, NO_NVRAM); -+ } -+} -+ -+/* Chips other than 5700/5701 use the NVRAM for fetching info. */ -+static void __devinit tg3_nvram_init(struct tg3 *tp) -+{ -+ if (tg3_flag(tp, IS_SSB_CORE)) { -+ /* No NVRAM and EEPROM on the SSB Broadcom GigE core. */ -+ tg3_flag_clear(tp, NVRAM); -+ tg3_flag_clear(tp, NVRAM_BUFFERED); -+ tg3_flag_set(tp, NO_NVRAM); -+ return; -+ } -+ -+ tw32_f(GRC_EEPROM_ADDR, -+ (EEPROM_ADDR_FSM_RESET | -+ (EEPROM_DEFAULT_CLOCK_PERIOD << -+ EEPROM_ADDR_CLKPERD_SHIFT))); -+ -+ msleep(1); -+ -+ /* Enable seeprom accesses. */ -+ tw32_f(GRC_LOCAL_CTRL, -+ tr32(GRC_LOCAL_CTRL) | GRC_LCLCTRL_AUTO_SEEPROM); -+ udelay(100); -+ -+ if (tg3_asic_rev(tp) != ASIC_REV_5700 && -+ tg3_asic_rev(tp) != ASIC_REV_5701) { -+ tg3_flag_set(tp, NVRAM); -+ -+ if (tg3_nvram_lock(tp)) { -+ netdev_warn(tp->dev, -+ "Cannot get nvram lock, %s failed\n", -+ __func__); -+ return; -+ } -+ tg3_enable_nvram_access(tp); -+ -+ tp->nvram_size = 0; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5752) -+ tg3_get_5752_nvram_info(tp); -+ else if (tg3_asic_rev(tp) == ASIC_REV_5755) -+ tg3_get_5755_nvram_info(tp); -+ else if (tg3_asic_rev(tp) == ASIC_REV_5787 || -+ tg3_asic_rev(tp) == ASIC_REV_5784 || -+ tg3_asic_rev(tp) == ASIC_REV_5785) -+ tg3_get_5787_nvram_info(tp); -+ else if (tg3_asic_rev(tp) == ASIC_REV_5761) -+ tg3_get_5761_nvram_info(tp); -+ else if (tg3_asic_rev(tp) == ASIC_REV_5906) -+ tg3_get_5906_nvram_info(tp); -+ else if (tg3_asic_rev(tp) == ASIC_REV_57780 || -+ tg3_flag(tp, 57765_CLASS)) -+ tg3_get_57780_nvram_info(tp); -+ else if (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_asic_rev(tp) == ASIC_REV_5719) -+ tg3_get_5717_nvram_info(tp); -+ else if (tg3_asic_rev(tp) == ASIC_REV_5720 || -+ tg3_asic_rev(tp) == ASIC_REV_5762) -+ tg3_get_5720_nvram_info(tp); -+ else -+ tg3_get_nvram_info(tp); -+ -+ if (tp->nvram_size == 0) -+ tg3_get_nvram_size(tp); -+ -+ tg3_disable_nvram_access(tp); -+ tg3_nvram_unlock(tp); -+ -+ } else { -+ tg3_flag_clear(tp, NVRAM); -+ tg3_flag_clear(tp, NVRAM_BUFFERED); -+ -+ tg3_get_eeprom_size(tp); -+ } -+} -+ -+struct subsys_tbl_ent { -+ u16 subsys_vendor, subsys_devid; -+ u32 phy_id; -+}; -+ -+static struct subsys_tbl_ent subsys_id_to_phy_id[] __devinitdata = { -+ /* Broadcom boards. */ -+ { TG3PCI_SUBVENDOR_ID_BROADCOM, -+ TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6, TG3_PHY_ID_BCM5401 }, -+ { TG3PCI_SUBVENDOR_ID_BROADCOM, -+ TG3PCI_SUBDEVICE_ID_BROADCOM_95701A5, TG3_PHY_ID_BCM5701 }, -+ { TG3PCI_SUBVENDOR_ID_BROADCOM, -+ TG3PCI_SUBDEVICE_ID_BROADCOM_95700T6, TG3_PHY_ID_BCM8002 }, -+ { TG3PCI_SUBVENDOR_ID_BROADCOM, -+ TG3PCI_SUBDEVICE_ID_BROADCOM_95700A9, 0 }, -+ { TG3PCI_SUBVENDOR_ID_BROADCOM, -+ TG3PCI_SUBDEVICE_ID_BROADCOM_95701T1, TG3_PHY_ID_BCM5701 }, -+ { TG3PCI_SUBVENDOR_ID_BROADCOM, -+ TG3PCI_SUBDEVICE_ID_BROADCOM_95701T8, TG3_PHY_ID_BCM5701 }, -+ { TG3PCI_SUBVENDOR_ID_BROADCOM, -+ TG3PCI_SUBDEVICE_ID_BROADCOM_95701A7, 0 }, -+ { TG3PCI_SUBVENDOR_ID_BROADCOM, -+ TG3PCI_SUBDEVICE_ID_BROADCOM_95701A10, TG3_PHY_ID_BCM5701 }, -+ { TG3PCI_SUBVENDOR_ID_BROADCOM, -+ TG3PCI_SUBDEVICE_ID_BROADCOM_95701A12, TG3_PHY_ID_BCM5701 }, -+ { TG3PCI_SUBVENDOR_ID_BROADCOM, -+ TG3PCI_SUBDEVICE_ID_BROADCOM_95703AX1, TG3_PHY_ID_BCM5703 }, -+ { TG3PCI_SUBVENDOR_ID_BROADCOM, -+ TG3PCI_SUBDEVICE_ID_BROADCOM_95703AX2, TG3_PHY_ID_BCM5703 }, -+ -+ /* 3com boards. */ -+ { TG3PCI_SUBVENDOR_ID_3COM, -+ TG3PCI_SUBDEVICE_ID_3COM_3C996T, TG3_PHY_ID_BCM5401 }, -+ { TG3PCI_SUBVENDOR_ID_3COM, -+ TG3PCI_SUBDEVICE_ID_3COM_3C996BT, TG3_PHY_ID_BCM5701 }, -+ { TG3PCI_SUBVENDOR_ID_3COM, -+ TG3PCI_SUBDEVICE_ID_3COM_3C996SX, 0 }, -+ { TG3PCI_SUBVENDOR_ID_3COM, -+ TG3PCI_SUBDEVICE_ID_3COM_3C1000T, TG3_PHY_ID_BCM5701 }, -+ { TG3PCI_SUBVENDOR_ID_3COM, -+ TG3PCI_SUBDEVICE_ID_3COM_3C940BR01, TG3_PHY_ID_BCM5701 }, -+ -+ /* DELL boards. */ -+ { TG3PCI_SUBVENDOR_ID_DELL, -+ TG3PCI_SUBDEVICE_ID_DELL_VIPER, TG3_PHY_ID_BCM5401 }, -+ { TG3PCI_SUBVENDOR_ID_DELL, -+ TG3PCI_SUBDEVICE_ID_DELL_JAGUAR, TG3_PHY_ID_BCM5401 }, -+ { TG3PCI_SUBVENDOR_ID_DELL, -+ TG3PCI_SUBDEVICE_ID_DELL_MERLOT, TG3_PHY_ID_BCM5411 }, -+ { TG3PCI_SUBVENDOR_ID_DELL, -+ TG3PCI_SUBDEVICE_ID_DELL_SLIM_MERLOT, TG3_PHY_ID_BCM5411 }, -+ -+ /* Compaq boards. */ -+ { TG3PCI_SUBVENDOR_ID_COMPAQ, -+ TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE, TG3_PHY_ID_BCM5701 }, -+ { TG3PCI_SUBVENDOR_ID_COMPAQ, -+ TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE_2, TG3_PHY_ID_BCM5701 }, -+ { TG3PCI_SUBVENDOR_ID_COMPAQ, -+ TG3PCI_SUBDEVICE_ID_COMPAQ_CHANGELING, 0 }, -+ { TG3PCI_SUBVENDOR_ID_COMPAQ, -+ TG3PCI_SUBDEVICE_ID_COMPAQ_NC7780, TG3_PHY_ID_BCM5701 }, -+ { TG3PCI_SUBVENDOR_ID_COMPAQ, -+ TG3PCI_SUBDEVICE_ID_COMPAQ_NC7780_2, TG3_PHY_ID_BCM5701 }, -+ -+ /* IBM boards. */ -+ { TG3PCI_SUBVENDOR_ID_IBM, -+ TG3PCI_SUBDEVICE_ID_IBM_5703SAX2, 0 } -+}; -+ -+static struct subsys_tbl_ent * __devinit tg3_lookup_by_subsys(struct tg3 *tp) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(subsys_id_to_phy_id); i++) { -+ if ((subsys_id_to_phy_id[i].subsys_vendor == -+ tp->pdev->subsystem_vendor) && -+ (subsys_id_to_phy_id[i].subsys_devid == -+ tp->pdev->subsystem_device)) -+ return &subsys_id_to_phy_id[i]; -+ } -+ return NULL; -+} -+ -+static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) -+{ -+ u32 val; -+ -+ tp->phy_id = TG3_PHY_ID_INVALID; -+ tp->led_ctrl = LED_CTRL_MODE_PHY_1; -+ -+ /* Assume an onboard device and WOL capable by default. */ -+ tg3_flag_set(tp, EEPROM_WRITE_PROT); -+ tg3_flag_set(tp, WOL_CAP); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5906) { -+ if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM)) { -+ tg3_flag_clear(tp, EEPROM_WRITE_PROT); -+ tg3_flag_set(tp, IS_NIC); -+ } -+ val = tr32(VCPU_CFGSHDW); -+ if (val & VCPU_CFGSHDW_ASPM_DBNC) -+ tg3_flag_set(tp, ASPM_WORKAROUND); -+ if ((val & VCPU_CFGSHDW_WOL_ENABLE) && -+ (val & VCPU_CFGSHDW_WOL_MAGPKT)) -+ tg3_flag_set(tp, WOL_ENABLE); -+ goto done; -+ } -+ -+ tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); -+ if (val == NIC_SRAM_DATA_SIG_MAGIC) { -+ u32 nic_cfg, led_cfg; -+ u32 cfg2 = 0, cfg4 = 0, cfg5 = 0; -+ u32 nic_phy_id, ver, eeprom_phy_id; -+ int eeprom_phy_serdes = 0; -+ -+ tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); -+ tp->nic_sram_data_cfg = nic_cfg; -+ -+ tg3_read_mem(tp, NIC_SRAM_DATA_VER, &ver); -+ ver >>= NIC_SRAM_DATA_VER_SHIFT; -+ if (tg3_asic_rev(tp) != ASIC_REV_5700 && -+ tg3_asic_rev(tp) != ASIC_REV_5701 && -+ tg3_asic_rev(tp) != ASIC_REV_5703 && -+ (ver > 0) && (ver < 0x100)) -+ tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &cfg2); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5785) -+ tg3_read_mem(tp, NIC_SRAM_DATA_CFG_4, &cfg4); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_asic_rev(tp) == ASIC_REV_5720) -+ tg3_read_mem(tp, NIC_SRAM_DATA_CFG_5, &cfg5); -+ -+ if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) == -+ NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER) -+ eeprom_phy_serdes = 1; -+ -+ tg3_read_mem(tp, NIC_SRAM_DATA_PHY_ID, &nic_phy_id); -+ if (nic_phy_id != 0) { -+ u32 id1 = nic_phy_id & NIC_SRAM_DATA_PHY_ID1_MASK; -+ u32 id2 = nic_phy_id & NIC_SRAM_DATA_PHY_ID2_MASK; -+ -+ eeprom_phy_id = (id1 >> 16) << 10; -+ eeprom_phy_id |= (id2 & 0xfc00) << 16; -+ eeprom_phy_id |= (id2 & 0x03ff) << 0; -+ } else -+ eeprom_phy_id = 0; -+ -+ tp->phy_id = eeprom_phy_id; -+ if (eeprom_phy_serdes) { -+ if (!tg3_flag(tp, 5705_PLUS)) -+ tp->phy_flags |= TG3_PHYFLG_PHY_SERDES; -+ else -+ tp->phy_flags |= TG3_PHYFLG_MII_SERDES; -+ } -+ -+ if (tg3_flag(tp, 5750_PLUS)) -+ led_cfg = cfg2 & (NIC_SRAM_DATA_CFG_LED_MODE_MASK | -+ SHASTA_EXT_LED_MODE_MASK); -+ else -+ led_cfg = nic_cfg & NIC_SRAM_DATA_CFG_LED_MODE_MASK; -+ -+ switch (led_cfg) { -+ default: -+ case NIC_SRAM_DATA_CFG_LED_MODE_PHY_1: -+ tp->led_ctrl = LED_CTRL_MODE_PHY_1; -+ break; -+ -+ case NIC_SRAM_DATA_CFG_LED_MODE_PHY_2: -+ tp->led_ctrl = LED_CTRL_MODE_PHY_2; -+ break; -+ -+ case NIC_SRAM_DATA_CFG_LED_MODE_MAC: -+ tp->led_ctrl = LED_CTRL_MODE_MAC; -+ -+ /* Default to PHY_1_MODE if 0 (MAC_MODE) is -+ * read on some older 5700/5701 bootcode. -+ */ -+ if (tg3_asic_rev(tp) == ASIC_REV_5700 || -+ tg3_asic_rev(tp) == ASIC_REV_5701) -+ tp->led_ctrl = LED_CTRL_MODE_PHY_1; -+ -+ break; -+ -+ case SHASTA_EXT_LED_SHARED: -+ tp->led_ctrl = LED_CTRL_MODE_SHARED; -+ if (tg3_chip_rev_id(tp) != CHIPREV_ID_5750_A0 && -+ tg3_chip_rev_id(tp) != CHIPREV_ID_5750_A1) -+ tp->led_ctrl |= (LED_CTRL_MODE_PHY_1 | -+ LED_CTRL_MODE_PHY_2); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_asic_rev(tp) == ASIC_REV_5720 || -+ tg3_asic_rev(tp) == ASIC_REV_5762) -+ tp->led_ctrl |= 0xfff80000; -+ -+ break; -+ -+ case SHASTA_EXT_LED_MAC: -+ tp->led_ctrl = LED_CTRL_MODE_SHASTA_MAC; -+ break; -+ -+ case SHASTA_EXT_LED_COMBO: -+ tp->led_ctrl = LED_CTRL_MODE_COMBO; -+ if (tg3_chip_rev_id(tp) != CHIPREV_ID_5750_A0) -+ tp->led_ctrl |= (LED_CTRL_MODE_PHY_1 | -+ LED_CTRL_MODE_PHY_2); -+ break; -+ -+ } -+ -+ if ((tg3_asic_rev(tp) == ASIC_REV_5700 || -+ tg3_asic_rev(tp) == ASIC_REV_5701) && -+ tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) -+ tp->led_ctrl = LED_CTRL_MODE_PHY_2; -+ -+ if (tg3_chip_rev(tp) == CHIPREV_5784_AX) -+ tp->led_ctrl = LED_CTRL_MODE_PHY_1; -+ -+ if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) { -+ tg3_flag_set(tp, EEPROM_WRITE_PROT); -+ if ((tp->pdev->subsystem_vendor == -+ PCI_VENDOR_ID_ARIMA) && -+ (tp->pdev->subsystem_device == 0x205a || -+ tp->pdev->subsystem_device == 0x2063)) -+ tg3_flag_clear(tp, EEPROM_WRITE_PROT); -+ } else { -+ tg3_flag_clear(tp, EEPROM_WRITE_PROT); -+ tg3_flag_set(tp, IS_NIC); -+ } -+ -+ if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { -+ tg3_flag_set(tp, ENABLE_ASF); -+ if (tg3_flag(tp, 5750_PLUS)) -+ tg3_flag_set(tp, ASF_NEW_HANDSHAKE); -+ } -+ -+ if ((nic_cfg & NIC_SRAM_DATA_CFG_APE_ENABLE) && -+ tg3_flag(tp, 5750_PLUS)) -+ tg3_flag_set(tp, ENABLE_APE); -+ -+ if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES && -+ !(nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL)) -+ tg3_flag_clear(tp, WOL_CAP); -+ -+ if (tg3_flag(tp, WOL_CAP) && -+ (nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE)) -+ tg3_flag_set(tp, WOL_ENABLE); -+ -+ if (cfg2 & (1 << 17)) -+ tp->phy_flags |= TG3_PHYFLG_CAPACITIVE_COUPLING; -+ -+ /* serdes signal pre-emphasis in register 0x590 set by */ -+ /* bootcode if bit 18 is set */ -+ if (cfg2 & (1 << 18)) -+ tp->phy_flags |= TG3_PHYFLG_SERDES_PREEMPHASIS; -+ -+ if ((tg3_flag(tp, 57765_PLUS) || -+ tg3_asic_rev(tp) == ASIC_REV_5785 || -+ (tg3_asic_rev(tp) == ASIC_REV_5784 && -+ tg3_chip_rev(tp) != CHIPREV_5784_AX)) && -+ (cfg2 & NIC_SRAM_DATA_CFG_2_APD_EN)) -+ tp->phy_flags |= TG3_PHYFLG_ENABLE_APD; -+ -+ if (tg3_flag(tp, PCI_EXPRESS)) { -+ u32 cfg3; -+ -+ tg3_read_mem(tp, NIC_SRAM_DATA_CFG_3, &cfg3); -+ if (tg3_asic_rev(tp) != ASIC_REV_5785 && -+ !tg3_flag(tp, 57765_PLUS) && -+ (cfg3 & NIC_SRAM_ASPM_DEBOUNCE)) -+ tg3_flag_set(tp, ASPM_WORKAROUND); -+ if (cfg3 & NIC_SRAM_LNK_FLAP_AVOID) -+ tp->phy_flags |= TG3_PHYFLG_KEEP_LINK_ON_PWRDN; -+ if (cfg3 & NIC_SRAM_1G_ON_VAUX_OK) -+ tp->phy_flags |= TG3_PHYFLG_1G_ON_VAUX_OK; -+ } -+ -+ if (cfg4 & NIC_SRAM_RGMII_INBAND_DISABLE) -+ tg3_flag_set(tp, RGMII_INBAND_DISABLE); -+ if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_RX_EN) -+ tg3_flag_set(tp, RGMII_EXT_IBND_RX_EN); -+ if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_TX_EN) -+ tg3_flag_set(tp, RGMII_EXT_IBND_TX_EN); -+ -+ if (cfg5 & NIC_SRAM_DISABLE_1G_HALF_ADV) -+ tp->phy_flags |= TG3_PHYFLG_DISABLE_1G_HD_ADV; -+ } -+done: -+ -+#ifndef BCM_HAS_DEVICE_SET_WAKEUP_CAPABLE -+ device_init_wakeup(&tp->pdev->dev, tg3_flag(tp, WOL_CAP)); -+#endif -+ -+ if (tg3_flag(tp, WOL_CAP)) -+ device_set_wakeup_enable(&tp->pdev->dev, -+ tg3_flag(tp, WOL_ENABLE)); -+ else -+ device_set_wakeup_capable(&tp->pdev->dev, false); -+} -+ -+static int __devinit tg3_ape_otp_read(struct tg3 *tp, u32 offset, u32 *val) -+{ -+ int i, err; -+ u32 val2, off = offset * 8; -+ -+ err = tg3_nvram_lock(tp); -+ if (err) -+ return err; -+ -+ tg3_ape_write32(tp, TG3_APE_OTP_ADDR, off | APE_OTP_ADDR_CPU_ENABLE); -+ tg3_ape_write32(tp, TG3_APE_OTP_CTRL, APE_OTP_CTRL_PROG_EN | -+ APE_OTP_CTRL_CMD_RD | APE_OTP_CTRL_START); -+ tg3_ape_read32(tp, TG3_APE_OTP_CTRL); -+ udelay(10); -+ -+ for (i = 0; i < 100; i++) { -+ val2 = tg3_ape_read32(tp, TG3_APE_OTP_STATUS); -+ if (val2 & APE_OTP_STATUS_CMD_DONE) { -+ *val = tg3_ape_read32(tp, TG3_APE_OTP_RD_DATA); -+ break; -+ } -+ udelay(10); -+ } -+ -+ tg3_ape_write32(tp, TG3_APE_OTP_CTRL, 0); -+ -+ tg3_nvram_unlock(tp); -+ if (val2 & APE_OTP_STATUS_CMD_DONE) -+ return 0; -+ -+ return -EBUSY; -+} -+ -+static int __devinit tg3_issue_otp_command(struct tg3 *tp, u32 cmd) -+{ -+ int i; -+ u32 val; -+ -+ tw32(OTP_CTRL, cmd | OTP_CTRL_OTP_CMD_START); -+ tw32(OTP_CTRL, cmd); -+ -+ /* Wait for up to 1 ms for command to execute. */ -+ for (i = 0; i < 100; i++) { -+ val = tr32(OTP_STATUS); -+ if (val & OTP_STATUS_CMD_DONE) -+ break; -+ udelay(10); -+ } -+ -+ return (val & OTP_STATUS_CMD_DONE) ? 0 : -EBUSY; -+} -+ -+/* Read the gphy configuration from the OTP region of the chip. The gphy -+ * configuration is a 32-bit value that straddles the alignment boundary. -+ * We do two 32-bit reads and then shift and merge the results. -+ */ -+static u32 __devinit tg3_read_otp_phycfg(struct tg3 *tp) -+{ -+ u32 bhalf_otp, thalf_otp; -+ -+ tw32(OTP_MODE, OTP_MODE_OTP_THRU_GRC); -+ -+ if (tg3_issue_otp_command(tp, OTP_CTRL_OTP_CMD_INIT)) -+ return 0; -+ -+ tw32(OTP_ADDRESS, OTP_ADDRESS_MAGIC1); -+ -+ if (tg3_issue_otp_command(tp, OTP_CTRL_OTP_CMD_READ)) -+ return 0; -+ -+ thalf_otp = tr32(OTP_READ_DATA); -+ -+ tw32(OTP_ADDRESS, OTP_ADDRESS_MAGIC2); -+ -+ if (tg3_issue_otp_command(tp, OTP_CTRL_OTP_CMD_READ)) -+ return 0; -+ -+ bhalf_otp = tr32(OTP_READ_DATA); -+ -+ return ((thalf_otp & 0x0000ffff) << 16) | (bhalf_otp >> 16); -+} -+ -+static void __devinit tg3_phy_init_link_config(struct tg3 *tp) -+{ -+ u32 adv = ADVERTISED_Autoneg; -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) { -+ if (!(tp->phy_flags & TG3_PHYFLG_DISABLE_1G_HD_ADV)) -+ adv |= ADVERTISED_1000baseT_Half; -+ adv |= ADVERTISED_1000baseT_Full; -+ } -+ -+ if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) -+ adv |= ADVERTISED_100baseT_Half | -+ ADVERTISED_100baseT_Full | -+ ADVERTISED_10baseT_Half | -+ ADVERTISED_10baseT_Full | -+ ADVERTISED_TP; -+ else -+ adv |= ADVERTISED_FIBRE; -+ -+ tp->link_config.advertising = adv; -+ tp->link_config.speed = SPEED_UNKNOWN; -+ tp->link_config.duplex = DUPLEX_UNKNOWN; -+ tp->link_config.autoneg = AUTONEG_ENABLE; -+ tp->link_config.active_speed = SPEED_UNKNOWN; -+ tp->link_config.active_duplex = DUPLEX_UNKNOWN; -+ -+ tp->old_link = -1; -+} -+ -+static int __devinit tg3_phy_probe(struct tg3 *tp) -+{ -+ u32 hw_phy_id_1, hw_phy_id_2; -+ u32 hw_phy_id, hw_phy_id_masked; -+ int err; -+ -+ /* flow control autonegotiation is default behavior */ -+ tg3_flag_set(tp, PAUSE_AUTONEG); -+ tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX; -+ -+ if (tg3_flag(tp, ENABLE_APE)) { -+ switch (tp->pci_fn) { -+ case 0: -+ tp->phy_ape_lock = TG3_APE_LOCK_PHY0; -+ break; -+ case 1: -+ tp->phy_ape_lock = TG3_APE_LOCK_PHY1; -+ break; -+ case 2: -+ tp->phy_ape_lock = TG3_APE_LOCK_PHY2; -+ break; -+ case 3: -+ tp->phy_ape_lock = TG3_APE_LOCK_PHY3; -+ break; -+ } -+ } -+ -+ if (!tg3_flag(tp, ENABLE_ASF) && -+ !(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && -+ !(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) -+ tp->phy_flags &= ~(TG3_PHYFLG_1G_ON_VAUX_OK | -+ TG3_PHYFLG_KEEP_LINK_ON_PWRDN); -+ -+ if (tg3_flag(tp, USE_PHYLIB)) -+ return tg3_phy_init(tp); -+ -+ /* Reading the PHY ID register can conflict with ASF -+ * firmware access to the PHY hardware. -+ */ -+ err = 0; -+ if (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE)) { -+ hw_phy_id = hw_phy_id_masked = TG3_PHY_ID_INVALID; -+ } else { -+ /* Now read the physical PHY_ID from the chip and verify -+ * that it is sane. If it doesn't look good, we fall back -+ * to either the hard-coded table based PHY_ID and failing -+ * that the value found in the eeprom area. -+ */ -+ err |= tg3_readphy(tp, MII_PHYSID1, &hw_phy_id_1); -+ err |= tg3_readphy(tp, MII_PHYSID2, &hw_phy_id_2); -+ -+ hw_phy_id = (hw_phy_id_1 & 0xffff) << 10; -+ hw_phy_id |= (hw_phy_id_2 & 0xfc00) << 16; -+ hw_phy_id |= (hw_phy_id_2 & 0x03ff) << 0; -+ -+ hw_phy_id_masked = hw_phy_id & TG3_PHY_ID_MASK; -+ } -+ -+ if (!err && TG3_KNOWN_PHY_ID(hw_phy_id_masked)) { -+ tp->phy_id = hw_phy_id; -+ if (hw_phy_id_masked == TG3_PHY_ID_BCM8002) -+ tp->phy_flags |= TG3_PHYFLG_PHY_SERDES; -+ else -+ tp->phy_flags &= ~TG3_PHYFLG_PHY_SERDES; -+ } else { -+ if (tp->phy_id != TG3_PHY_ID_INVALID) { -+ /* Do nothing, phy ID already set up in -+ * tg3_get_eeprom_hw_cfg(). -+ */ -+ } else { -+ struct subsys_tbl_ent *p; -+ -+ /* No eeprom signature? Try the hardcoded -+ * subsys device table. -+ */ -+ p = tg3_lookup_by_subsys(tp); -+ if (p) { -+ tp->phy_id = p->phy_id; -+ } else if (!tg3_flag(tp, IS_SSB_CORE)) { -+ /* For now we saw the IDs 0xbc050cd0, -+ * 0xbc050f80 and 0xbc050c30 on devices -+ * connected to an BCM4785 and there are -+ * probably more. Just assume that the phy is -+ * supported when it is connected to a SSB core -+ * for now. -+ */ -+ return -ENODEV; -+ } -+ -+ if (!tp->phy_id || -+ tp->phy_id == TG3_PHY_ID_BCM8002) -+ tp->phy_flags |= TG3_PHYFLG_PHY_SERDES; -+ } -+ } -+ -+ /* A0 */ -+ if (tg3_asic_rev(tp) == ASIC_REV_5785 && -+ tp->phy_id == TG3_PHY_ID_BCM50612E) { -+ tp->phy_flags &= ~TG3_PHYFLG_ENABLE_APD; -+ tg3_flag_clear(tp, RGMII_INBAND_DISABLE); -+ tg3_flag_clear(tp, RGMII_EXT_IBND_RX_EN); -+ tg3_flag_clear(tp, RGMII_EXT_IBND_TX_EN); -+ } -+ -+#ifndef TG3_DISABLE_EEE_SUPPORT -+ if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && -+ (tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_asic_rev(tp) == ASIC_REV_5720 || -+ tg3_asic_rev(tp) == ASIC_REV_57766 || -+ tg3_asic_rev(tp) == ASIC_REV_5762 || -+ (tg3_asic_rev(tp) == ASIC_REV_5717 && -+ tg3_chip_rev_id(tp) != CHIPREV_ID_5717_A0) || -+ (tg3_asic_rev(tp) == ASIC_REV_57765 && -+ tg3_chip_rev_id(tp) != CHIPREV_ID_57765_A0))) { -+ tp->phy_flags |= TG3_PHYFLG_EEE_CAP; -+ -+ tp->eee.supported = SUPPORTED_100baseT_Full | -+ SUPPORTED_1000baseT_Full; -+ tp->eee.advertised = ADVERTISED_100baseT_Full | -+ ADVERTISED_1000baseT_Full; -+ tp->eee.eee_enabled = !tg3_disable_eee; -+ tp->eee.tx_lpi_enabled = 1; -+ tp->eee.tx_lpi_timer = TG3_CPMU_DBTMR1_LNKIDLE_2047US; -+ } -+#endif /* TG3_DISABLE_EEE_SUPPORT */ -+ -+ tg3_phy_init_link_config(tp); -+ -+ /* Bring the phy out of its low-power state. */ -+ if (!(tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN) && -+ !(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && -+ !tg3_flag(tp, ENABLE_APE) && !tg3_flag(tp, ENABLE_ASF)) -+ err = tg3_phy_reset(tp); -+ -+ return err; -+} -+ -+static void __devinit tg3_read_vpd(struct tg3 *tp) -+{ -+ u8 *vpd_data; -+ unsigned int block_end, rosize, len; -+ u32 vpdlen; -+ int j, i = 0; -+ -+ vpd_data = (u8 *)tg3_vpd_readblock(tp, &vpdlen); -+ if (!vpd_data) -+ goto out_no_vpd; -+ -+ i = pci_vpd_find_tag(vpd_data, 0, vpdlen, PCI_VPD_LRDT_RO_DATA); -+ if (i < 0) -+ goto out_not_found; -+ -+ rosize = pci_vpd_lrdt_size(&vpd_data[i]); -+ block_end = i + PCI_VPD_LRDT_TAG_SIZE + rosize; -+ i += PCI_VPD_LRDT_TAG_SIZE; -+ -+ if (block_end > vpdlen) -+ goto out_not_found; -+ -+ j = pci_vpd_find_info_keyword(vpd_data, i, rosize, -+ PCI_VPD_RO_KEYWORD_MFR_ID); -+ if (j > 0) { -+ len = pci_vpd_info_field_size(&vpd_data[j]); -+ -+ j += PCI_VPD_INFO_FLD_HDR_SIZE; -+ if (j + len > block_end || len != 4 || -+ memcmp(&vpd_data[j], "1028", 4)) -+ goto partno; -+ -+ j = pci_vpd_find_info_keyword(vpd_data, i, rosize, -+ PCI_VPD_RO_KEYWORD_VENDOR0); -+ if (j < 0) -+ goto partno; -+ -+ len = pci_vpd_info_field_size(&vpd_data[j]); -+ -+ j += PCI_VPD_INFO_FLD_HDR_SIZE; -+ if (j + len > block_end) -+ goto partno; -+ -+ if (len >= sizeof(tp->fw_ver)) -+ len = sizeof(tp->fw_ver) - 1; -+ memset(tp->fw_ver, 0, sizeof(tp->fw_ver)); -+ snprintf(tp->fw_ver, sizeof(tp->fw_ver), "%.*s bc ", len, -+ &vpd_data[j]); -+ } -+ -+partno: -+ i = pci_vpd_find_info_keyword(vpd_data, i, rosize, -+ PCI_VPD_RO_KEYWORD_PARTNO); -+ if (i < 0) -+ goto out_not_found; -+ -+ len = pci_vpd_info_field_size(&vpd_data[i]); -+ -+ i += PCI_VPD_INFO_FLD_HDR_SIZE; -+ if (len > TG3_BPN_SIZE || -+ (len + i) > vpdlen) -+ goto out_not_found; -+ -+ memcpy(tp->board_part_number, &vpd_data[i], len); -+ -+out_not_found: -+ kfree(vpd_data); -+ if (tp->board_part_number[0]) -+ return; -+ -+out_no_vpd: -+ if (tg3_asic_rev(tp) == ASIC_REV_5717) { -+ if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717_C) -+ strcpy(tp->board_part_number, "BCM5717"); -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718) -+ strcpy(tp->board_part_number, "BCM5718"); -+ else -+ goto nomatch; -+ } else if (tg3_asic_rev(tp) == ASIC_REV_57780) { -+ if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780) -+ strcpy(tp->board_part_number, "BCM57780"); -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760) -+ strcpy(tp->board_part_number, "BCM57760"); -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790) -+ strcpy(tp->board_part_number, "BCM57790"); -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57788) -+ strcpy(tp->board_part_number, "BCM57788"); -+ else -+ goto nomatch; -+ } else if (tg3_asic_rev(tp) == ASIC_REV_57765) { -+ if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761) -+ strcpy(tp->board_part_number, "BCM57761"); -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765) -+ strcpy(tp->board_part_number, "BCM57765"); -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781) -+ strcpy(tp->board_part_number, "BCM57781"); -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785) -+ strcpy(tp->board_part_number, "BCM57785"); -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791) -+ strcpy(tp->board_part_number, "BCM57791"); -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795) -+ strcpy(tp->board_part_number, "BCM57795"); -+ else -+ goto nomatch; -+ } else if (tg3_asic_rev(tp) == ASIC_REV_57766) { -+ if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57762) -+ strcpy(tp->board_part_number, "BCM57762"); -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57766) -+ strcpy(tp->board_part_number, "BCM57766"); -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57782) -+ strcpy(tp->board_part_number, "BCM57782"); -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57786) -+ strcpy(tp->board_part_number, "BCM57786"); -+ else -+ goto nomatch; -+ } else if (tg3_asic_rev(tp) == ASIC_REV_5906) { -+ strcpy(tp->board_part_number, "BCM95906"); -+ } else { -+nomatch: -+ strcpy(tp->board_part_number, "none"); -+ } -+} -+ -+static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset) -+{ -+ u32 val; -+ -+ if (tg3_nvram_read(tp, offset, &val) || -+ (val & 0xfc000000) != 0x0c000000 || -+ tg3_nvram_read(tp, offset + 4, &val) || -+ val != 0) -+ return 0; -+ -+ return 1; -+} -+ -+static void __devinit tg3_read_bc_ver(struct tg3 *tp) -+{ -+ u32 val, offset, start, ver_offset; -+ int i, dst_off; -+ bool newver = false; -+ -+ if (tg3_nvram_read(tp, 0xc, &offset) || -+ tg3_nvram_read(tp, 0x4, &start)) -+ return; -+ -+ offset = tg3_nvram_logical_addr(tp, offset); -+ -+ if (tg3_nvram_read(tp, offset, &val)) -+ return; -+ -+ if ((val & 0xfc000000) == 0x0c000000) { -+ if (tg3_nvram_read(tp, offset + 4, &val)) -+ return; -+ -+ if (val == 0) -+ newver = true; -+ } -+ -+ dst_off = strlen(tp->fw_ver); -+ -+ if (newver) { -+ if (TG3_VER_SIZE - dst_off < 16 || -+ tg3_nvram_read(tp, offset + 8, &ver_offset)) -+ return; -+ -+ offset = offset + ver_offset - start; -+ for (i = 0; i < 16; i += 4) { -+ __be32 v; -+ if (tg3_nvram_read_be32(tp, offset + i, &v)) -+ return; -+ -+ memcpy(tp->fw_ver + dst_off + i, &v, sizeof(v)); -+ } -+ } else { -+ u32 major, minor; -+ -+ if (tg3_nvram_read(tp, TG3_NVM_PTREV_BCVER, &ver_offset)) -+ return; -+ -+ major = (ver_offset & TG3_NVM_BCVER_MAJMSK) >> -+ TG3_NVM_BCVER_MAJSFT; -+ minor = ver_offset & TG3_NVM_BCVER_MINMSK; -+ snprintf(&tp->fw_ver[dst_off], TG3_VER_SIZE - dst_off, -+ "v%d.%02d", major, minor); -+ } -+} -+ -+static void __devinit tg3_read_hwsb_ver(struct tg3 *tp) -+{ -+ u32 val, major, minor; -+ -+ /* Use native endian representation */ -+ if (tg3_nvram_read(tp, TG3_NVM_HWSB_CFG1, &val)) -+ return; -+ -+ major = (val & TG3_NVM_HWSB_CFG1_MAJMSK) >> -+ TG3_NVM_HWSB_CFG1_MAJSFT; -+ minor = (val & TG3_NVM_HWSB_CFG1_MINMSK) >> -+ TG3_NVM_HWSB_CFG1_MINSFT; -+ -+ snprintf(&tp->fw_ver[0], 32, "sb v%d.%02d", major, minor); -+} -+ -+static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val) -+{ -+ u32 offset, major, minor, build; -+ -+ strncat(tp->fw_ver, "sb", TG3_VER_SIZE - strlen(tp->fw_ver) - 1); -+ -+ if ((val & TG3_EEPROM_SB_FORMAT_MASK) != TG3_EEPROM_SB_FORMAT_1) -+ return; -+ -+ switch (val & TG3_EEPROM_SB_REVISION_MASK) { -+ case TG3_EEPROM_SB_REVISION_0: -+ offset = TG3_EEPROM_SB_F1R0_EDH_OFF; -+ break; -+ case TG3_EEPROM_SB_REVISION_2: -+ offset = TG3_EEPROM_SB_F1R2_EDH_OFF; -+ break; -+ case TG3_EEPROM_SB_REVISION_3: -+ offset = TG3_EEPROM_SB_F1R3_EDH_OFF; -+ break; -+ case TG3_EEPROM_SB_REVISION_4: -+ offset = TG3_EEPROM_SB_F1R4_EDH_OFF; -+ break; -+ case TG3_EEPROM_SB_REVISION_5: -+ offset = TG3_EEPROM_SB_F1R5_EDH_OFF; -+ break; -+ case TG3_EEPROM_SB_REVISION_6: -+ offset = TG3_EEPROM_SB_F1R6_EDH_OFF; -+ break; -+ default: -+ return; -+ } -+ -+ if (tg3_nvram_read(tp, offset, &val)) -+ return; -+ -+ build = (val & TG3_EEPROM_SB_EDH_BLD_MASK) >> -+ TG3_EEPROM_SB_EDH_BLD_SHFT; -+ major = (val & TG3_EEPROM_SB_EDH_MAJ_MASK) >> -+ TG3_EEPROM_SB_EDH_MAJ_SHFT; -+ minor = val & TG3_EEPROM_SB_EDH_MIN_MASK; -+ -+ if (minor > 99 || build > 26) -+ return; -+ -+ offset = strlen(tp->fw_ver); -+ snprintf(&tp->fw_ver[offset], TG3_VER_SIZE - offset, -+ " v%d.%02d", major, minor); -+ -+ if (build > 0) { -+ offset = strlen(tp->fw_ver); -+ if (offset < TG3_VER_SIZE - 1) -+ tp->fw_ver[offset] = 'a' + build - 1; -+ } -+} -+ -+static void __devinit tg3_read_mgmtfw_ver(struct tg3 *tp) -+{ -+ u32 val, offset, start; -+ int i, vlen; -+ -+ for (offset = TG3_NVM_DIR_START; -+ offset < TG3_NVM_DIR_END; -+ offset += TG3_NVM_DIRENT_SIZE) { -+ if (tg3_nvram_read(tp, offset, &val)) -+ return; -+ -+ if ((val >> TG3_NVM_DIRTYPE_SHIFT) == TG3_NVM_DIRTYPE_ASFINI) -+ break; -+ } -+ -+ if (offset == TG3_NVM_DIR_END) -+ return; -+ -+ if (!tg3_flag(tp, 5705_PLUS)) -+ start = 0x08000000; -+ else if (tg3_nvram_read(tp, offset - 4, &start)) -+ return; -+ -+ if (tg3_nvram_read(tp, offset + 4, &offset) || -+ !tg3_fw_img_is_valid(tp, offset) || -+ tg3_nvram_read(tp, offset + 8, &val)) -+ return; -+ -+ offset += val - start; -+ -+ vlen = strlen(tp->fw_ver); -+ -+ tp->fw_ver[vlen++] = ','; -+ tp->fw_ver[vlen++] = ' '; -+ -+ for (i = 0; i < 4; i++) { -+ __be32 v; -+ if (tg3_nvram_read_be32(tp, offset, &v)) -+ return; -+ -+ offset += sizeof(v); -+ -+ if (vlen > TG3_VER_SIZE - sizeof(v)) { -+ memcpy(&tp->fw_ver[vlen], &v, TG3_VER_SIZE - vlen); -+ break; -+ } -+ -+ memcpy(&tp->fw_ver[vlen], &v, sizeof(v)); -+ vlen += sizeof(v); -+ } -+} -+ -+static void __devinit tg3_probe_ncsi(struct tg3 *tp) -+{ -+ u32 apedata; -+ -+ apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG); -+ if (apedata != APE_SEG_SIG_MAGIC) -+ return; -+ -+ apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS); -+ if (!(apedata & APE_FW_STATUS_READY)) -+ return; -+ -+ if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) -+ tg3_flag_set(tp, APE_HAS_NCSI); -+} -+ -+static void __devinit tg3_read_dash_ver(struct tg3 *tp) -+{ -+ int vlen; -+ u32 apedata; -+ char *fwtype; -+ -+ apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION); -+ -+ if (tg3_flag(tp, APE_HAS_NCSI)) -+ fwtype = "NCSI"; -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725) -+ fwtype = "SMASH"; -+ else -+ fwtype = "DASH"; -+ -+ vlen = strlen(tp->fw_ver); -+ -+ snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " %s v%d.%d.%d.%d", -+ fwtype, -+ (apedata & APE_FW_VERSION_MAJMSK) >> APE_FW_VERSION_MAJSFT, -+ (apedata & APE_FW_VERSION_MINMSK) >> APE_FW_VERSION_MINSFT, -+ (apedata & APE_FW_VERSION_REVMSK) >> APE_FW_VERSION_REVSFT, -+ (apedata & APE_FW_VERSION_BLDMSK)); -+} -+ -+static void __devinit tg3_read_otp_ver(struct tg3 *tp) -+{ -+ u32 val, val2; -+ -+ if (tg3_asic_rev(tp) != ASIC_REV_5762) -+ return; -+ -+ if (!tg3_ape_otp_read(tp, OTP_ADDRESS_MAGIC0, &val) && -+ !tg3_ape_otp_read(tp, OTP_ADDRESS_MAGIC0 + 4, &val2) && -+ TG3_OTP_MAGIC0_VALID(val)) { -+ u64 val64 = (u64) val << 32 | val2; -+ u32 ver = 0; -+ int i, vlen; -+ -+ for (i = 0; i < 7; i++) { -+ if ((val64 & 0xff) == 0) -+ break; -+ ver = val64 & 0xff; -+ val64 >>= 8; -+ } -+ vlen = strlen(tp->fw_ver); -+ snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " .%02d", ver); -+ } -+} -+ -+static void __devinit tg3_read_fw_ver(struct tg3 *tp) -+{ -+ u32 val; -+ bool vpd_vers = false; -+ -+ if (tp->fw_ver[0] != 0) -+ vpd_vers = true; -+ -+ if (tg3_flag(tp, NO_NVRAM)) { -+ strcat(tp->fw_ver, "sb"); -+ tg3_read_otp_ver(tp); -+ return; -+ } -+ -+ if (tg3_nvram_read(tp, 0, &val)) -+ return; -+ -+ if (val == TG3_EEPROM_MAGIC) -+ tg3_read_bc_ver(tp); -+ else if ((val & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW) -+ tg3_read_sb_ver(tp, val); -+ else if ((val & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW) -+ tg3_read_hwsb_ver(tp); -+ -+ if (tg3_flag(tp, ENABLE_ASF)) { -+ if (tg3_flag(tp, ENABLE_APE)) { -+ tg3_probe_ncsi(tp); -+ if (!vpd_vers) -+ tg3_read_dash_ver(tp); -+ } else if (!vpd_vers) { -+ tg3_read_mgmtfw_ver(tp); -+ } -+ } -+ -+ tp->fw_ver[TG3_VER_SIZE - 1] = 0; -+} -+ -+static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp) -+{ -+ if (tg3_flag(tp, LRG_PROD_RING_CAP)) -+ return TG3_RX_RET_MAX_SIZE_5717; -+ else if (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS)) -+ return TG3_RX_RET_MAX_SIZE_5700; -+ else -+ return TG3_RX_RET_MAX_SIZE_5705; -+} -+ -+#if (LINUX_VERSION_CODE >= 0x2060a) -+static DEFINE_PCI_DEVICE_TABLE(tg3_write_reorder_chipsets) = { -+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8385_0) }, -+ { }, -+}; -+#endif -+ -+static struct pci_dev * __devinit tg3_find_peer(struct tg3 *tp) -+{ -+ struct pci_dev *peer; -+ unsigned int func, devnr = tp->pdev->devfn & ~7; -+ -+ for (func = 0; func < 8; func++) { -+ peer = pci_get_slot(tp->pdev->bus, devnr | func); -+ if (peer && peer != tp->pdev) -+ break; -+ pci_dev_put(peer); -+ } -+ /* 5704 can be configured in single-port mode, set peer to -+ * tp->pdev in that case. -+ */ -+ if (!peer) { -+ peer = tp->pdev; -+ return peer; -+ } -+ -+ /* -+ * We don't need to keep the refcount elevated; there's no way -+ * to remove one half of this device without removing the other -+ */ -+ pci_dev_put(peer); -+ -+ return peer; -+} -+ -+static void __devinit tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg) -+{ -+ tp->pci_chip_rev_id = misc_ctrl_reg >> MISC_HOST_CTRL_CHIPREV_SHIFT; -+ if (tg3_asic_rev(tp) == ASIC_REV_USE_PROD_ID_REG) { -+ u32 reg; -+ -+ /* All devices that use the alternate -+ * ASIC REV location have a CPMU. -+ */ -+ tg3_flag_set(tp, CPMU_PRESENT); -+ -+ if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717_C || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57767 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57764 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57787) -+ reg = TG3PCI_GEN2_PRODID_ASICREV; -+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57762 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57766 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57782 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57786) -+ reg = TG3PCI_GEN15_PRODID_ASICREV; -+ else -+ reg = TG3PCI_PRODID_ASICREV; -+ -+ pci_read_config_dword(tp->pdev, reg, &tp->pci_chip_rev_id); -+ } -+ -+ /* Wrong chip ID in 5752 A0. This code can be removed later -+ * as A0 is not in production. -+ */ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5752_A0_HW) -+ tp->pci_chip_rev_id = CHIPREV_ID_5752_A0; -+ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5717_C0) -+ tp->pci_chip_rev_id = CHIPREV_ID_5720_A0; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_asic_rev(tp) == ASIC_REV_5720) -+ tg3_flag_set(tp, 5717_PLUS); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_57765 || -+ tg3_asic_rev(tp) == ASIC_REV_57766) -+ tg3_flag_set(tp, 57765_CLASS); -+ -+ if (tg3_flag(tp, 57765_CLASS) || tg3_flag(tp, 5717_PLUS) || -+ tg3_asic_rev(tp) == ASIC_REV_5762) -+ tg3_flag_set(tp, 57765_PLUS); -+ -+ /* Intentionally exclude ASIC_REV_5906 */ -+ if (tg3_asic_rev(tp) == ASIC_REV_5755 || -+ tg3_asic_rev(tp) == ASIC_REV_5787 || -+ tg3_asic_rev(tp) == ASIC_REV_5784 || -+ tg3_asic_rev(tp) == ASIC_REV_5761 || -+ tg3_asic_rev(tp) == ASIC_REV_5785 || -+ tg3_asic_rev(tp) == ASIC_REV_57780 || -+ tg3_flag(tp, 57765_PLUS)) -+ tg3_flag_set(tp, 5755_PLUS); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5780 || -+ tg3_asic_rev(tp) == ASIC_REV_5714) -+ tg3_flag_set(tp, 5780_CLASS); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5750 || -+ tg3_asic_rev(tp) == ASIC_REV_5752 || -+ tg3_asic_rev(tp) == ASIC_REV_5906 || -+ tg3_flag(tp, 5755_PLUS) || -+ tg3_flag(tp, 5780_CLASS)) -+ tg3_flag_set(tp, 5750_PLUS); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5705 || -+ tg3_flag(tp, 5750_PLUS)) -+ tg3_flag_set(tp, 5705_PLUS); -+} -+ -+static bool tg3_10_100_only_device(struct tg3 *tp, -+ const struct pci_device_id *ent) -+{ -+ u32 grc_misc_cfg = tr32(GRC_MISC_CFG) & GRC_MISC_CFG_BOARD_ID_MASK; -+ -+ if ((tg3_asic_rev(tp) == ASIC_REV_5703 && -+ (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) || -+ (tp->phy_flags & TG3_PHYFLG_IS_FET)) -+ return true; -+ -+ if (ent->driver_data & TG3_DRV_DATA_FLAG_10_100_ONLY) { -+ if (tg3_asic_rev(tp) == ASIC_REV_5705) { -+ if (ent->driver_data & TG3_DRV_DATA_FLAG_5705_10_100) -+ return true; -+ } else -+ return true; -+ } -+ -+ return false; -+} -+ -+static int __devinit tg3_get_invariants(struct tg3 *tp, -+ const struct pci_device_id *ent) -+{ -+ u32 misc_ctrl_reg; -+ u32 pci_state_reg, grc_misc_cfg; -+ u32 val; -+ u16 pci_cmd; -+ int err; -+ -+ /* Force memory write invalidate off. If we leave it on, -+ * then on 5700_BX chips we have to enable a workaround. -+ * The workaround is to set the TG3PCI_DMA_RW_CTRL boundary -+ * to match the cacheline size. The Broadcom driver have this -+ * workaround but turns MWI off all the times so never uses -+ * it. This seems to suggest that the workaround is insufficient. -+ */ -+ pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd); -+ pci_cmd &= ~PCI_COMMAND_INVALIDATE; -+ pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); -+ -+ /* Important! -- Make sure register accesses are byteswapped -+ * correctly. Also, for those chips that require it, make -+ * sure that indirect register accesses are enabled before -+ * the first operation. -+ */ -+ pci_read_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, -+ &misc_ctrl_reg); -+ tp->misc_host_ctrl |= (misc_ctrl_reg & -+ MISC_HOST_CTRL_CHIPREV); -+ pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, -+ tp->misc_host_ctrl); -+ -+ tg3_detect_asic_rev(tp, misc_ctrl_reg); -+ -+ /* Fix for CTRL-20413(Huawei)/19887 in KVM PCI Pass-thru mode -+ * Qemu is dropping the pci config space writes to -+ * 0x68, but it is 'not dropping' the BAR space access, -+ * since BAR registers is setup properly in KVM environment. -+ * This redundent write fixes the issue for KVM hypervisor -+ * in SUSE 11.3 reported by Huawei. -+ */ -+ if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717_C || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720) -+ tg3_write32(tp, TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl); -+ /*Fix for CTRL-20413 ends*/ -+ -+ /* If we have 5702/03 A1 or A2 on certain ICH chipsets, -+ * we need to disable memory and use config. cycles -+ * only to access all registers. The 5702/03 chips -+ * can mistakenly decode the special cycles from the -+ * ICH chipsets as memory write cycles, causing corruption -+ * of register and memory space. Only certain ICH bridges -+ * will drive special cycles with non-zero data during the -+ * address phase which can fall within the 5703's address -+ * range. This is not an ICH bug as the PCI spec allows -+ * non-zero address during special cycles. However, only -+ * these ICH bridges are known to drive non-zero addresses -+ * during special cycles. -+ * -+ * Since special cycles do not cross PCI bridges, we only -+ * enable this workaround if the 5703 is on the secondary -+ * bus of these ICH bridges. -+ */ -+ if ((tg3_chip_rev_id(tp) == CHIPREV_ID_5703_A1) || -+ (tg3_chip_rev_id(tp) == CHIPREV_ID_5703_A2)) { -+ static struct tg3_dev_id { -+ u32 vendor; -+ u32 device; -+ u32 rev; -+ } ich_chipsets[] = { -+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_8, -+ PCI_ANY_ID }, -+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_8, -+ PCI_ANY_ID }, -+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_11, -+ 0xa }, -+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_6, -+ PCI_ANY_ID }, -+ { }, -+ }; -+ struct tg3_dev_id *pci_id = &ich_chipsets[0]; -+ struct pci_dev *bridge = NULL; -+ -+ while (pci_id->vendor != 0) { -+ bridge = pci_get_device(pci_id->vendor, pci_id->device, -+ bridge); -+ if (!bridge) { -+ pci_id++; -+ continue; -+ } -+ if (pci_id->rev != PCI_ANY_ID) { -+ u8 rev; -+ -+ pci_read_config_byte(bridge, PCI_REVISION_ID, -+ &rev); -+ if (rev > pci_id->rev) -+ continue; -+ } -+ if (bridge->subordinate && -+ (bridge->subordinate->number == -+ tp->pdev->bus->number)) { -+ tg3_flag_set(tp, ICH_WORKAROUND); -+ pci_dev_put(bridge); -+ break; -+ } -+ } -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5701) { -+ static struct tg3_dev_id { -+ u32 vendor; -+ u32 device; -+ } bridge_chipsets[] = { -+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_0 }, -+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_1 }, -+ { }, -+ }; -+ struct tg3_dev_id *pci_id = &bridge_chipsets[0]; -+ struct pci_dev *bridge = NULL; -+ -+ while (pci_id->vendor != 0) { -+ bridge = pci_get_device(pci_id->vendor, -+ pci_id->device, -+ bridge); -+ if (!bridge) { -+ pci_id++; -+ continue; -+ } -+ if (bridge->subordinate && -+ (bridge->subordinate->number <= -+ tp->pdev->bus->number) && -+ (bridge->subordinate->busn_res_end >= -+ tp->pdev->bus->number)) { -+ tg3_flag_set(tp, 5701_DMA_BUG); -+ pci_dev_put(bridge); -+ break; -+ } -+ } -+ } -+ -+ /* The EPB bridge inside 5714, 5715, and 5780 cannot support -+ * DMA addresses > 40-bit. This bridge may have other additional -+ * 57xx devices behind it in some 4-port NIC designs for example. -+ * Any tg3 device found behind the bridge will also need the 40-bit -+ * DMA workaround. -+ */ -+ if (tg3_flag(tp, 5780_CLASS)) { -+ tg3_flag_set(tp, 40BIT_DMA_BUG); -+ tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI); -+ } else { -+ struct pci_dev *bridge = NULL; -+ -+ do { -+ bridge = pci_get_device(PCI_VENDOR_ID_SERVERWORKS, -+ PCI_DEVICE_ID_SERVERWORKS_EPB, -+ bridge); -+ if (bridge && bridge->subordinate && -+ (bridge->subordinate->number <= -+ tp->pdev->bus->number) && -+ (bridge->subordinate->busn_res_end >= -+ tp->pdev->bus->number)) { -+ tg3_flag_set(tp, 40BIT_DMA_BUG); -+ pci_dev_put(bridge); -+ break; -+ } -+ } while (bridge); -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5704 || -+ tg3_asic_rev(tp) == ASIC_REV_5714) -+ tp->pdev_peer = tg3_find_peer(tp); -+ -+ /* Determine TSO capabilities */ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5719_A0) -+ ; /* Do nothing. HW bug. */ -+ else if (tg3_flag(tp, 57765_PLUS)) -+ tg3_flag_set(tp, HW_TSO_3); -+ else if (tg3_flag(tp, 5755_PLUS) || -+ tg3_asic_rev(tp) == ASIC_REV_5906) -+ tg3_flag_set(tp, HW_TSO_2); -+ else if (tg3_flag(tp, 5750_PLUS)) { -+ tg3_flag_set(tp, HW_TSO_1); -+ tg3_flag_set(tp, TSO_BUG); -+ if (tg3_asic_rev(tp) == ASIC_REV_5750 && -+ tg3_chip_rev_id(tp) >= CHIPREV_ID_5750_C2) -+ tg3_flag_clear(tp, TSO_BUG); -+ } else if (tg3_asic_rev(tp) != ASIC_REV_5700 && -+ tg3_asic_rev(tp) != ASIC_REV_5701 && -+ tg3_chip_rev_id(tp) != CHIPREV_ID_5705_A0) { -+ tg3_flag_set(tp, FW_TSO); -+ tg3_flag_set(tp, TSO_BUG); -+ if (tg3_asic_rev(tp) == ASIC_REV_5705) -+ tp->fw_needed = FIRMWARE_TG3TSO5; -+ else -+ tp->fw_needed = FIRMWARE_TG3TSO; -+ } -+ -+ /* Selectively allow TSO based on operating conditions */ -+ if (tg3_flag(tp, HW_TSO_1) || -+ tg3_flag(tp, HW_TSO_2) || -+ tg3_flag(tp, HW_TSO_3) || -+ tg3_flag(tp, FW_TSO)) { -+ /* For firmware TSO, assume ASF is disabled. -+ * We'll disable TSO later if we discover ASF -+ * is enabled in tg3_get_eeprom_hw_cfg(). -+ */ -+ tg3_flag_set(tp, TSO_CAPABLE); -+ } else { -+ tg3_flag_clear(tp, TSO_CAPABLE); -+ tg3_flag_clear(tp, TSO_BUG); -+ tp->fw_needed = NULL; -+ } -+ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5701_A0) -+ tp->fw_needed = FIRMWARE_TG3; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_57766) -+ tp->fw_needed = FIRMWARE_TG357766; -+ -+ tp->irq_max = 1; -+ -+ if (tg3_flag(tp, 5750_PLUS)) { -+ tg3_flag_set(tp, SUPPORT_MSI); -+ if (tg3_chip_rev(tp) == CHIPREV_5750_AX || -+ tg3_chip_rev(tp) == CHIPREV_5750_BX || -+ (tg3_asic_rev(tp) == ASIC_REV_5714 && -+ tg3_chip_rev_id(tp) <= CHIPREV_ID_5714_A2 && -+ tp->pdev_peer == tp->pdev)) -+ tg3_flag_clear(tp, SUPPORT_MSI); -+ -+ if (tg3_flag(tp, 5755_PLUS) || -+ tg3_asic_rev(tp) == ASIC_REV_5906) { -+ tg3_flag_set(tp, 1SHOT_MSI); -+ } -+ -+ if (tg3_flag(tp, 57765_PLUS)) { -+ tg3_flag_set(tp, SUPPORT_MSIX); -+#ifdef TG3_NAPI -+ tp->irq_max = TG3_IRQ_MAX_VECS_RSS; -+#endif -+ } -+#if defined(__VMKLNX__) -+ tp->irq_max = 1; -+#if defined(TG3_VMWARE_NETQ_ENABLE) && !defined(TG3_INBOX) -+ if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || -+ tg3_asic_rev(tp) == ASIC_REV_5719 || -+ (tg3_asic_rev(tp) == ASIC_REV_5720 && -+ tp->pdev->device != TG3PCI_DEVICE_TIGON3_5717_C)) { -+ tp->vmware.netq.index = tg3_netq_index++; -+ tg3_flag_set(tp, IOV_CAPABLE); -+ tg3_flag_clear(tp, 1SHOT_MSI); -+ tp->irq_max = min(TG3_IRQ_MAX_VECS, TG3_IRQ_MAX_VECS_IOV); -+ } -+#endif /* TG3_VMWARE_NETQ_ENABLE && !TG3_INBOX */ -+#endif /* __VMKLNX__ */ -+ } -+ -+ tp->txq_max = 1; -+ tp->rxq_max = 1; -+ if (tp->irq_max > 1) { -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (tg3_flag(tp, IOV_CAPABLE)) -+ tp->rxq_max = tp->irq_max; -+ else -+ tp->rxq_max = 1; -+#else -+ tp->rxq_max = TG3_RSS_MAX_NUM_QS; -+ tg3_rss_init_dflt_indir_tbl(tp, TG3_RSS_MAX_NUM_QS); -+#endif -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_asic_rev(tp) == ASIC_REV_5720) -+ tp->txq_max = tp->irq_max - 1; -+ } -+ -+ if (tg3_flag(tp, 5755_PLUS) || -+ tg3_asic_rev(tp) == ASIC_REV_5906) -+ tg3_flag_set(tp, SHORT_DMA_BUG); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_asic_rev(tp) == ASIC_REV_5762) -+ tp->dma_limit = TG3_TX_BD_DMA_MAX_4K; -+#if defined(__VMKLNX__) -+ else if (tg3_flag(tp, TSO_CAPABLE)) -+ tp->dma_limit = TG3_TX_BD_DMA_MAX_32K; -+#endif -+ if (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_asic_rev(tp) == ASIC_REV_5720 || -+ tg3_asic_rev(tp) == ASIC_REV_5762) -+ tg3_flag_set(tp, LRG_PROD_RING_CAP); -+ -+ if (tg3_flag(tp, 57765_PLUS) && -+ tg3_chip_rev_id(tp) != CHIPREV_ID_5719_A0) -+ tg3_flag_set(tp, USE_JUMBO_BDFLAG); -+ -+ if (!tg3_flag(tp, 5705_PLUS) || -+ tg3_flag(tp, 5780_CLASS) || -+ tg3_flag(tp, USE_JUMBO_BDFLAG)) -+ tg3_flag_set(tp, JUMBO_CAPABLE); -+ -+ pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, -+ &pci_state_reg); -+ -+#ifndef BCM_HAS_PCI_PCIE_CAP -+ tp->pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP); -+#endif -+ -+ if (pci_is_pcie(tp->pdev)) { -+ u16 lnkctl; -+ -+ tg3_flag_set(tp, PCI_EXPRESS); -+ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5719_A0) { -+ int readrq = pcie_get_readrq(tp->pdev); -+ if (readrq > 2048) -+ pcie_set_readrq(tp->pdev, 2048); -+ } -+ -+ pcie_capability_read_word(tp->pdev, PCI_EXP_LNKCTL, &lnkctl); -+ if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) { -+ if (tg3_asic_rev(tp) == ASIC_REV_5906) { -+ tg3_flag_clear(tp, HW_TSO_2); -+ tg3_flag_clear(tp, TSO_CAPABLE); -+ } -+ if (tg3_asic_rev(tp) == ASIC_REV_5784 || -+ tg3_asic_rev(tp) == ASIC_REV_5761 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_57780_A0 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_57780_A1) -+ tg3_flag_set(tp, CLKREQ_BUG); -+ } else if (tg3_chip_rev_id(tp) == CHIPREV_ID_5717_A0) { -+ tg3_flag_set(tp, L1PLLPD_EN); -+ } -+ } else if (tg3_asic_rev(tp) == ASIC_REV_5785) { -+ /* BCM5785 devices are effectively PCIe devices, and should -+ * follow PCIe codepaths, but do not have a PCIe capabilities -+ * section. -+ */ -+ tg3_flag_set(tp, PCI_EXPRESS); -+ } else if (!tg3_flag(tp, 5705_PLUS) || -+ tg3_flag(tp, 5780_CLASS)) { -+ tp->pcix_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_PCIX); -+ if (!tp->pcix_cap) { -+ dev_err(&tp->pdev->dev, -+ "Cannot find PCI-X capability, aborting\n"); -+ return -EIO; -+ } -+ -+ if (!(pci_state_reg & PCISTATE_CONV_PCI_MODE)) -+ tg3_flag_set(tp, PCIX_MODE); -+ } -+ -+ /* If we have an AMD 762 or VIA K8T800 chipset, write -+ * reordering to the mailbox registers done by the host -+ * controller can cause major troubles. We read back from -+ * every mailbox register write to force the writes to be -+ * posted to the chip in order. -+ */ -+#if (LINUX_VERSION_CODE < 0x2060a) -+ if ((pci_find_device(PCI_VENDOR_ID_AMD, -+ PCI_DEVICE_ID_AMD_FE_GATE_700C, NULL) || -+ pci_find_device(PCI_VENDOR_ID_AMD, -+ PCI_DEVICE_ID_AMD_8131_BRIDGE, NULL) || -+ pci_find_device(PCI_VENDOR_ID_VIA, -+ PCI_DEVICE_ID_VIA_8385_0, NULL)) && -+#else -+ if (pci_dev_present(tg3_write_reorder_chipsets) && -+#endif -+ !tg3_flag(tp, PCI_EXPRESS)) -+ tg3_flag_set(tp, MBOX_WRITE_REORDER); -+ -+ pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, -+ &tp->pci_cacheline_sz); -+ pci_read_config_byte(tp->pdev, PCI_LATENCY_TIMER, -+ &tp->pci_lat_timer); -+ if (tg3_asic_rev(tp) == ASIC_REV_5703 && -+ tp->pci_lat_timer < 64) { -+ tp->pci_lat_timer = 64; -+ pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER, -+ tp->pci_lat_timer); -+ } -+ -+ /* Important! -- It is critical that the PCI-X hw workaround -+ * situation is decided before the first MMIO register access. -+ */ -+ if (tg3_chip_rev(tp) == CHIPREV_5700_BX) { -+ /* 5700 BX chips need to have their TX producer index -+ * mailboxes written twice to workaround a bug. -+ */ -+ tg3_flag_set(tp, TXD_MBOX_HWBUG); -+ -+ /* If we are in PCI-X mode, enable register write workaround. -+ * -+ * The workaround is to use indirect register accesses -+ * for all chip writes not to mailbox registers. -+ */ -+ if (tg3_flag(tp, PCIX_MODE)) { -+ u32 pm_reg; -+ -+ tg3_flag_set(tp, PCIX_TARGET_HWBUG); -+ -+ /* The chip can have it's power management PCI config -+ * space registers clobbered due to this bug. -+ * So explicitly force the chip into D0 here. -+ */ -+ pci_read_config_dword(tp->pdev, -+ tp->pm_cap + PCI_PM_CTRL, -+ &pm_reg); -+ pm_reg &= ~PCI_PM_CTRL_STATE_MASK; -+ pm_reg |= PCI_PM_CTRL_PME_ENABLE | 0 /* D0 */; -+ pci_write_config_dword(tp->pdev, -+ tp->pm_cap + PCI_PM_CTRL, -+ pm_reg); -+ -+ /* Also, force SERR#/PERR# in PCI command. */ -+ pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd); -+ pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR; -+ pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); -+ } -+ } -+ -+ if ((pci_state_reg & PCISTATE_BUS_SPEED_HIGH) != 0) -+ tg3_flag_set(tp, PCI_HIGH_SPEED); -+ if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0) -+ tg3_flag_set(tp, PCI_32BIT); -+ -+ /* Chip-specific fixup from Broadcom driver */ -+ if ((tg3_chip_rev_id(tp) == CHIPREV_ID_5704_A0) && -+ (!(pci_state_reg & PCISTATE_RETRY_SAME_DMA))) { -+ pci_state_reg |= PCISTATE_RETRY_SAME_DMA; -+ pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg); -+ } -+ -+ /* Default fast path register access methods */ -+ tp->read32 = tg3_read32; -+ tp->write32 = tg3_write32; -+ tp->read32_mbox = tg3_read32; -+ tp->write32_mbox = tg3_write32; -+ tp->write32_tx_mbox = tg3_write32; -+ tp->write32_rx_mbox = tg3_write32; -+ -+ /* Various workaround register access methods */ -+ if (tg3_flag(tp, PCIX_TARGET_HWBUG)) -+ tp->write32 = tg3_write_indirect_reg32; -+ else if (tg3_asic_rev(tp) == ASIC_REV_5701 || -+ (tg3_flag(tp, PCI_EXPRESS) && -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5750_A0)) { -+ /* -+ * Back to back register writes can cause problems on these -+ * chips, the workaround is to read back all reg writes -+ * except those to mailbox regs. -+ * -+ * See tg3_write_indirect_reg32(). -+ */ -+ tp->write32 = tg3_write_flush_reg32; -+ } -+ -+ if (tg3_flag(tp, TXD_MBOX_HWBUG) || tg3_flag(tp, MBOX_WRITE_REORDER)) { -+ tp->write32_tx_mbox = tg3_write32_tx_mbox; -+ if (tg3_flag(tp, MBOX_WRITE_REORDER)) -+ tp->write32_rx_mbox = tg3_write_flush_reg32; -+ } -+ -+ if (tg3_flag(tp, ICH_WORKAROUND)) { -+ tp->read32 = tg3_read_indirect_reg32; -+ tp->write32 = tg3_write_indirect_reg32; -+ tp->read32_mbox = tg3_read_indirect_mbox; -+ tp->write32_mbox = tg3_write_indirect_mbox; -+ tp->write32_tx_mbox = tg3_write_indirect_mbox; -+ tp->write32_rx_mbox = tg3_write_indirect_mbox; -+ -+ iounmap(tp->regs); -+ tp->regs = NULL; -+ -+ pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd); -+ pci_cmd &= ~PCI_COMMAND_MEMORY; -+ pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); -+ } -+ if (tg3_asic_rev(tp) == ASIC_REV_5906) { -+ tp->read32_mbox = tg3_read32_mbox_5906; -+ tp->write32_mbox = tg3_write32_mbox_5906; -+ tp->write32_tx_mbox = tg3_write32_mbox_5906; -+ tp->write32_rx_mbox = tg3_write32_mbox_5906; -+ } -+ -+ if (tp->write32 == tg3_write_indirect_reg32 || -+ (tg3_flag(tp, PCIX_MODE) && -+ (tg3_asic_rev(tp) == ASIC_REV_5700 || -+ tg3_asic_rev(tp) == ASIC_REV_5701))) -+ tg3_flag_set(tp, SRAM_USE_CONFIG); -+ -+ /* The memory arbiter has to be enabled in order for SRAM accesses -+ * to succeed. Normally on powerup the tg3 chip firmware will make -+ * sure it is enabled, but other entities such as system netboot -+ * code might disable it. -+ */ -+ val = tr32(MEMARB_MODE); -+ tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE); -+ -+ tp->pci_fn = PCI_FUNC(tp->pdev->devfn) & 3; -+ if (tg3_asic_rev(tp) == ASIC_REV_5704 || -+ tg3_flag(tp, 5780_CLASS)) { -+ if (tg3_flag(tp, PCIX_MODE)) { -+ pci_read_config_dword(tp->pdev, -+ tp->pcix_cap + PCI_X_STATUS, -+ &val); -+ tp->pci_fn = val & 0x7; -+ } -+ } else if (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_asic_rev(tp) == ASIC_REV_5719 || -+ tg3_asic_rev(tp) == ASIC_REV_5720) { -+ tg3_read_mem(tp, NIC_SRAM_CPMU_STATUS, &val); -+ if ((val & NIC_SRAM_CPMUSTAT_SIG_MSK) != NIC_SRAM_CPMUSTAT_SIG) -+ val = tr32(TG3_CPMU_STATUS); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5717) -+ tp->pci_fn = (val & TG3_CPMU_STATUS_FMSK_5717) ? 1 : 0; -+ else -+ tp->pci_fn = (val & TG3_CPMU_STATUS_FMSK_5719) >> -+ TG3_CPMU_STATUS_FSHFT_5719; -+ } -+ -+ if (tg3_flag(tp, FLUSH_POSTED_WRITES)) { -+ tp->write32_tx_mbox = tg3_write_flush_reg32; -+ tp->write32_rx_mbox = tg3_write_flush_reg32; -+ } -+ -+ /* Get eeprom hw config before calling tg3_set_power_state(). -+ * In particular, the TG3_FLAG_IS_NIC flag must be -+ * determined before calling tg3_set_power_state() so that -+ * we know whether or not to switch out of Vaux power. -+ * When the flag is set, it means that GPIO1 is used for eeprom -+ * write protect and also implies that it is a LOM where GPIOs -+ * are not used to switch power. -+ */ -+ tg3_get_eeprom_hw_cfg(tp); -+ -+ if (tg3_flag(tp, FW_TSO) && tg3_flag(tp, ENABLE_ASF)) { -+ tg3_flag_clear(tp, TSO_CAPABLE); -+ tg3_flag_clear(tp, TSO_BUG); -+ tp->fw_needed = NULL; -+ } -+ -+ if (tg3_flag(tp, ENABLE_APE)) { -+ /* Allow reads and writes to the -+ * APE register and memory space. -+ */ -+ pci_state_reg |= PCISTATE_ALLOW_APE_CTLSPC_WR | -+ PCISTATE_ALLOW_APE_SHMEM_WR | -+ PCISTATE_ALLOW_APE_PSPACE_WR; -+ pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, -+ pci_state_reg); -+ -+ tg3_ape_lock_init(tp); -+ tp->ape_hb_interval = -+ msecs_to_jiffies(APE_HOST_HEARTBEAT_INT_5SEC); -+ } -+ -+#if !defined(__VMKLNX__) -+ tp->recoverable_err_interval = msecs_to_jiffies(RECOVERABLE_ERR_10SEC); -+#endif -+ -+ /* Set up tp->grc_local_ctrl before calling -+ * tg3_pwrsrc_switch_to_vmain(). GPIO1 driven high -+ * will bring 5700's external PHY out of reset. -+ * It is also used as eeprom write protect on LOMs. -+ */ -+ tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_AUTO_SEEPROM; -+ if (tg3_asic_rev(tp) == ASIC_REV_5700 || -+ tg3_flag(tp, EEPROM_WRITE_PROT)) -+ tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 | -+ GRC_LCLCTRL_GPIO_OUTPUT1); -+ /* Unused GPIO3 must be driven as output on 5752 because there -+ * are no pull-up resistors on unused GPIO pins. -+ */ -+ else if (tg3_asic_rev(tp) == ASIC_REV_5752) -+ tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5755 || -+ tg3_asic_rev(tp) == ASIC_REV_57780 || -+ tg3_flag(tp, 57765_CLASS)) -+ tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL; -+ -+ if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) { -+ /* Turn off the debug UART. */ -+ tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL; -+ if (tg3_flag(tp, IS_NIC)) -+ /* Keep VMain power. */ -+ tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 | -+ GRC_LCLCTRL_GPIO_OUTPUT0; -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5762) -+ tp->grc_local_ctrl |= -+ tr32(GRC_LOCAL_CTRL) & GRC_LCLCTRL_GPIO_UART_SEL; -+ -+ /* Switch out of Vaux if it is a NIC */ -+ tg3_pwrsrc_switch_to_vmain(tp); -+ -+ /* Derive initial jumbo mode from MTU assigned in -+ * ether_setup() via the alloc_etherdev() call -+ */ -+ if (tp->dev->mtu > ETH_DATA_LEN && !tg3_flag(tp, 5780_CLASS)) -+ tg3_flag_set(tp, JUMBO_RING_ENABLE); -+ -+ /* Determine WakeOnLan speed to use. */ -+ if (tg3_asic_rev(tp) == ASIC_REV_5700 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5701_A0 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5701_B0 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5701_B2) { -+ tg3_flag_clear(tp, WOL_SPEED_100MB); -+ } else { -+ tg3_flag_set(tp, WOL_SPEED_100MB); -+ } -+ -+#ifndef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_asic_rev(tp) == ASIC_REV_5906 || -+ (tg3_asic_rev(tp) == ASIC_REV_5785 && -+ (tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCMAC131)) -+ tp->phy_flags |= TG3_PHYFLG_IS_FET; -+#else -+ if (tg3_asic_rev(tp) == ASIC_REV_5906) -+ tp->phy_flags |= TG3_PHYFLG_IS_FET; -+#endif -+ -+ /* A few boards don't want Ethernet@WireSpeed phy feature */ -+ if (tg3_asic_rev(tp) == ASIC_REV_5700 || -+ (tg3_asic_rev(tp) == ASIC_REV_5705 && -+ (tg3_chip_rev_id(tp) != CHIPREV_ID_5705_A0) && -+ (tg3_chip_rev_id(tp) != CHIPREV_ID_5705_A1)) || -+ (tp->phy_flags & TG3_PHYFLG_IS_FET) || -+ (tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) -+ tp->phy_flags |= TG3_PHYFLG_NO_ETH_WIRE_SPEED; -+ -+ if (tg3_chip_rev(tp) == CHIPREV_5703_AX || -+ tg3_chip_rev(tp) == CHIPREV_5704_AX) -+ tp->phy_flags |= TG3_PHYFLG_ADC_BUG; -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5704_A0) -+ tp->phy_flags |= TG3_PHYFLG_5704_A0_BUG; -+ -+ if (tg3_flag(tp, 5705_PLUS) && -+ !(tp->phy_flags & TG3_PHYFLG_IS_FET) && -+ tg3_asic_rev(tp) != ASIC_REV_5785 && -+ tg3_asic_rev(tp) != ASIC_REV_57780 && -+ !tg3_flag(tp, 57765_PLUS)) { -+ if (tg3_asic_rev(tp) == ASIC_REV_5755 || -+ tg3_asic_rev(tp) == ASIC_REV_5787 || -+ tg3_asic_rev(tp) == ASIC_REV_5784 || -+ tg3_asic_rev(tp) == ASIC_REV_5761) { -+ if (tp->pdev->device != PCI_DEVICE_ID_TIGON3_5756 && -+ tp->pdev->device != PCI_DEVICE_ID_TIGON3_5722) -+ tp->phy_flags |= TG3_PHYFLG_JITTER_BUG; -+ if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5755M) -+ tp->phy_flags |= TG3_PHYFLG_ADJUST_TRIM; -+ } else -+ tp->phy_flags |= TG3_PHYFLG_BER_BUG; -+ } -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5784 && -+ tg3_chip_rev(tp) != CHIPREV_5784_AX) { -+ tp->phy_otp = tg3_read_otp_phycfg(tp); -+ if (tp->phy_otp == 0) -+ tp->phy_otp = TG3_OTP_DEFAULT; -+ } -+ -+ if (tg3_flag(tp, CPMU_PRESENT)) -+ tp->mi_mode = MAC_MI_MODE_500KHZ_CONST; -+ else -+ tp->mi_mode = MAC_MI_MODE_BASE; -+ -+ tp->coalesce_mode = 0; -+ if (tg3_chip_rev(tp) != CHIPREV_5700_AX && -+ tg3_chip_rev(tp) != CHIPREV_5700_BX) -+ tp->coalesce_mode |= HOSTCC_MODE_32BYTE; -+ -+ /* Set these bits to enable statistics workaround. */ -+ if (tg3_asic_rev(tp) == ASIC_REV_5717 || -+ tg3_asic_rev(tp) == ASIC_REV_5762 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5719_A0 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5720_A0) { -+ tp->coalesce_mode |= HOSTCC_MODE_ATTN; -+ tp->grc_mode |= GRC_MODE_IRQ_ON_FLOW_ATTN; -+ } -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tg3_asic_rev(tp) == ASIC_REV_5785 || -+ tg3_asic_rev(tp) == ASIC_REV_57780) -+ tg3_flag_set(tp, USE_PHYLIB); -+#endif -+ -+ err = tg3_mdio_init(tp); -+ if (err) -+ return err; -+ -+ /* Initialize data/descriptor byte/word swapping. */ -+ val = tr32(GRC_MODE); -+ if (tg3_asic_rev(tp) == ASIC_REV_5720 || -+ tg3_asic_rev(tp) == ASIC_REV_5762) -+ val &= (GRC_MODE_BYTE_SWAP_B2HRX_DATA | -+ GRC_MODE_WORD_SWAP_B2HRX_DATA | -+ GRC_MODE_B2HRX_ENABLE | -+ GRC_MODE_HTX2B_ENABLE | -+ GRC_MODE_HOST_STACKUP); -+ else -+ val &= GRC_MODE_HOST_STACKUP; -+ -+ tw32(GRC_MODE, val | tp->grc_mode); -+ -+ tg3_switch_clocks(tp); -+ -+ /* Clear this out for sanity. */ -+ tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); -+ -+ /* Clear TG3PCI_REG_BASE_ADDR to prevent hangs. */ -+ tw32(TG3PCI_REG_BASE_ADDR, 0); -+ -+ pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, -+ &pci_state_reg); -+ if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0 && -+ !tg3_flag(tp, PCIX_TARGET_HWBUG)) { -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5701_A0 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5701_B0 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5701_B2 || -+ tg3_chip_rev_id(tp) == CHIPREV_ID_5701_B5) { -+ void __iomem *sram_base; -+ -+ /* Write some dummy words into the SRAM status block -+ * area, see if it reads back correctly. If the return -+ * value is bad, force enable the PCIX workaround. -+ */ -+ sram_base = tp->regs + NIC_SRAM_WIN_BASE + NIC_SRAM_STATS_BLK; -+ -+ writel(0x00000000, sram_base); -+ writel(0x00000000, sram_base + 4); -+ writel(0xffffffff, sram_base + 4); -+ if (readl(sram_base) != 0x00000000) -+ tg3_flag_set(tp, PCIX_TARGET_HWBUG); -+ } -+ } -+ -+ udelay(50); -+ tg3_nvram_init(tp); -+ -+ /* If the device has an NVRAM, no need to load patch firmware */ -+ if (tg3_asic_rev(tp) == ASIC_REV_57766 && -+ !tg3_flag(tp, NO_NVRAM)) -+ tp->fw_needed = NULL; -+ -+ grc_misc_cfg = tr32(GRC_MISC_CFG); -+ grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5705 && -+ (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 || -+ grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M)) -+ tg3_flag_set(tp, IS_5788); -+ -+ if (!tg3_flag(tp, IS_5788) && -+ tg3_asic_rev(tp) != ASIC_REV_5700) -+ tg3_flag_set(tp, TAGGED_STATUS); -+ if (tg3_flag(tp, TAGGED_STATUS)) { -+ tp->coalesce_mode |= (HOSTCC_MODE_CLRTICK_RXBD | -+ HOSTCC_MODE_CLRTICK_TXBD); -+ -+ tp->misc_host_ctrl |= MISC_HOST_CTRL_TAGGED_STATUS; -+ pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, -+ tp->misc_host_ctrl); -+ } -+ -+ /* Preserve the APE MAC_MODE bits */ -+ if (tg3_flag(tp, ENABLE_APE)) -+ tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; -+ else -+ tp->mac_mode = 0; -+ -+ if (tg3_10_100_only_device(tp, ent)) -+ tp->phy_flags |= TG3_PHYFLG_10_100_ONLY; -+ -+ err = tg3_phy_probe(tp); -+ if (err) { -+ dev_err(&tp->pdev->dev, "phy probe failed, err %d\n", err); -+ /* ... but do not return immediately ... */ -+ tg3_mdio_fini(tp); -+ } -+ -+ tg3_read_vpd(tp); -+ tg3_read_fw_ver(tp); -+ -+ if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { -+ tp->phy_flags &= ~TG3_PHYFLG_USE_MI_INTERRUPT; -+ } else { -+ if (tg3_asic_rev(tp) == ASIC_REV_5700) -+ tp->phy_flags |= TG3_PHYFLG_USE_MI_INTERRUPT; -+ else -+ tp->phy_flags &= ~TG3_PHYFLG_USE_MI_INTERRUPT; -+ } -+ -+ /* 5700 {AX,BX} chips have a broken status block link -+ * change bit implementation, so we must use the -+ * status register in those cases. -+ */ -+ if (tg3_asic_rev(tp) == ASIC_REV_5700) -+ tg3_flag_set(tp, USE_LINKCHG_REG); -+ else -+ tg3_flag_clear(tp, USE_LINKCHG_REG); -+ -+ /* The led_ctrl is set during tg3_phy_probe, here we might -+ * have to force the link status polling mechanism based -+ * upon subsystem IDs. -+ */ -+ if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL && -+ tg3_asic_rev(tp) == ASIC_REV_5701 && -+ !(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) { -+ tp->phy_flags |= TG3_PHYFLG_USE_MI_INTERRUPT; -+ tg3_flag_set(tp, USE_LINKCHG_REG); -+ } -+ -+ /* For all SERDES we poll the MAC status register. */ -+ if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) -+ tg3_flag_set(tp, POLL_SERDES); -+ else -+ tg3_flag_clear(tp, POLL_SERDES); -+ -+ if (tg3_flag(tp, ENABLE_APE) && tg3_flag(tp, ENABLE_ASF)) -+ tg3_flag_set(tp, POLL_CPMU_LINK); -+ -+ tp->rx_offset = NET_IP_ALIGN; -+ tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD; -+ if (tg3_asic_rev(tp) == ASIC_REV_5701 && -+ tg3_flag(tp, PCIX_MODE)) { -+ tp->rx_offset = 0; -+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS -+ tp->rx_copy_thresh = ~(u16)0; -+#endif -+ } -+ -+ tp->rx_std_ring_mask = TG3_RX_STD_RING_SIZE(tp) - 1; -+ tp->rx_jmb_ring_mask = TG3_RX_JMB_RING_SIZE(tp) - 1; -+ tp->rx_ret_ring_mask = tg3_rx_ret_ring_size(tp) - 1; -+ -+ tp->rx_std_max_post = tp->rx_std_ring_mask + 1; -+ -+ /* Increment the rx prod index on the rx std ring by at most -+ * 8 for these chips to workaround hw errata. -+ */ -+ if (tg3_asic_rev(tp) == ASIC_REV_5750 || -+ tg3_asic_rev(tp) == ASIC_REV_5752 || -+ tg3_asic_rev(tp) == ASIC_REV_5755) -+ tp->rx_std_max_post = 8; -+ -+ if (tg3_flag(tp, ASPM_WORKAROUND)) -+ tp->pwrmgmt_thresh = tr32(PCIE_PWR_MGMT_THRESH) & -+ PCIE_PWR_MGMT_L1_THRESH_MSK; -+ -+ return err; -+} -+ -+#ifdef CONFIG_SPARC -+static int __devinit tg3_get_macaddr_sparc(struct tg3 *tp) -+{ -+ struct net_device *dev = tp->dev; -+ struct pci_dev *pdev = tp->pdev; -+ struct device_node *dp = pci_device_to_OF_node(pdev); -+ const unsigned char *addr; -+ int len; -+ -+ addr = of_get_property(dp, "local-mac-address", &len); -+ if (addr && len == ETH_ALEN) { -+ memcpy(dev->dev_addr, addr, 6); -+ memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN); -+ return 0; -+ } -+ return -ENODEV; -+} -+ -+static int __devinit tg3_get_default_macaddr_sparc(struct tg3 *tp) -+{ -+ struct net_device *dev = tp->dev; -+ -+ memcpy(dev->dev_addr, idprom->id_ethaddr, ETH_ALEN); -+ memcpy(dev->perm_addr, idprom->id_ethaddr, ETH_ALEN); -+ return 0; -+} -+#endif -+ -+static int __devinit tg3_get_device_address(struct tg3 *tp) -+{ -+ struct net_device *dev = tp->dev; -+ u32 hi, lo, mac_offset; -+ int addr_ok = 0; -+ int err; -+ -+#ifdef CONFIG_SPARC -+ if (!tg3_get_macaddr_sparc(tp)) -+ return 0; -+#endif -+ -+ if (tg3_flag(tp, IS_SSB_CORE)) { -+ err = ssb_gige_get_macaddr(tp->pdev, &dev->dev_addr[0]); -+ if (!err && is_valid_ether_addr(&dev->dev_addr[0])) -+ return 0; -+ } -+ -+ mac_offset = 0x7c; -+ if (tg3_asic_rev(tp) == ASIC_REV_5704 || -+ tg3_flag(tp, 5780_CLASS)) { -+ if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID) -+ mac_offset = 0xcc; -+ if (tg3_nvram_lock(tp)) -+ tw32_f(NVRAM_CMD, NVRAM_CMD_RESET); -+ else -+ tg3_nvram_unlock(tp); -+ } else if (tg3_flag(tp, 5717_PLUS)) { -+ if (tp->pci_fn & 1) -+ mac_offset = 0xcc; -+ if (tp->pci_fn > 1) -+ mac_offset += 0x18c; -+ } else if (tg3_asic_rev(tp) == ASIC_REV_5906) -+ mac_offset = 0x10; -+ -+ /* First try to get it from MAC address mailbox. */ -+ tg3_read_mem(tp, NIC_SRAM_MAC_ADDR_HIGH_MBOX, &hi); -+ if ((hi >> 16) == 0x484b) { -+ dev->dev_addr[0] = (hi >> 8) & 0xff; -+ dev->dev_addr[1] = (hi >> 0) & 0xff; -+ -+ tg3_read_mem(tp, NIC_SRAM_MAC_ADDR_LOW_MBOX, &lo); -+ dev->dev_addr[2] = (lo >> 24) & 0xff; -+ dev->dev_addr[3] = (lo >> 16) & 0xff; -+ dev->dev_addr[4] = (lo >> 8) & 0xff; -+ dev->dev_addr[5] = (lo >> 0) & 0xff; -+ -+ /* Some old bootcode may report a 0 MAC address in SRAM */ -+ addr_ok = is_valid_ether_addr(&dev->dev_addr[0]); -+ } -+ if (!addr_ok) { -+ /* Next, try NVRAM. */ -+ if (!tg3_flag(tp, NO_NVRAM) && -+ !tg3_nvram_read_be32(tp, mac_offset + 0, &hi) && -+ !tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) { -+ memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2); -+ memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo)); -+ } -+ /* Finally just fetch it out of the MAC control regs. */ -+ else { -+ hi = tr32(MAC_ADDR_0_HIGH); -+ lo = tr32(MAC_ADDR_0_LOW); -+ -+ dev->dev_addr[5] = lo & 0xff; -+ dev->dev_addr[4] = (lo >> 8) & 0xff; -+ dev->dev_addr[3] = (lo >> 16) & 0xff; -+ dev->dev_addr[2] = (lo >> 24) & 0xff; -+ dev->dev_addr[1] = hi & 0xff; -+ dev->dev_addr[0] = (hi >> 8) & 0xff; -+ } -+ } -+ -+ if (!is_valid_ether_addr(&dev->dev_addr[0])) { -+#ifdef CONFIG_SPARC -+ if (!tg3_get_default_macaddr_sparc(tp)) -+ return 0; -+#endif -+ return -EINVAL; -+ } -+#ifdef ETHTOOL_GPERMADDR -+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); -+#endif -+ return 0; -+} -+ -+#define BOUNDARY_SINGLE_CACHELINE 1 -+#define BOUNDARY_MULTI_CACHELINE 2 -+ -+static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val) -+{ -+ int cacheline_size; -+ u8 byte; -+ int goal; -+ -+ pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, &byte); -+ if (byte == 0) -+ cacheline_size = 1024; -+ else -+ cacheline_size = (int) byte * 4; -+ -+ /* On 5703 and later chips, the boundary bits have no -+ * effect. -+ */ -+ if (tg3_asic_rev(tp) != ASIC_REV_5700 && -+ tg3_asic_rev(tp) != ASIC_REV_5701 && -+ !tg3_flag(tp, PCI_EXPRESS)) -+ goto out; -+ -+#if defined(CONFIG_PPC64) || defined(CONFIG_IA64) || defined(CONFIG_PARISC) -+ goal = BOUNDARY_MULTI_CACHELINE; -+#else -+#if defined(CONFIG_SPARC64) || defined(CONFIG_ALPHA) -+ goal = BOUNDARY_SINGLE_CACHELINE; -+#else -+ goal = 0; -+#endif -+#endif -+ -+ if (tg3_flag(tp, 57765_PLUS)) { -+ val = goal ? 0 : DMA_RWCTRL_DIS_CACHE_ALIGNMENT; -+ goto out; -+ } -+ -+ if (!goal) -+ goto out; -+ -+ /* PCI controllers on most RISC systems tend to disconnect -+ * when a device tries to burst across a cache-line boundary. -+ * Therefore, letting tg3 do so just wastes PCI bandwidth. -+ * -+ * Unfortunately, for PCI-E there are only limited -+ * write-side controls for this, and thus for reads -+ * we will still get the disconnects. We'll also waste -+ * these PCI cycles for both read and write for chips -+ * other than 5700 and 5701 which do not implement the -+ * boundary bits. -+ */ -+ if (tg3_flag(tp, PCIX_MODE) && !tg3_flag(tp, PCI_EXPRESS)) { -+ switch (cacheline_size) { -+ case 16: -+ case 32: -+ case 64: -+ case 128: -+ if (goal == BOUNDARY_SINGLE_CACHELINE) { -+ val |= (DMA_RWCTRL_READ_BNDRY_128_PCIX | -+ DMA_RWCTRL_WRITE_BNDRY_128_PCIX); -+ } else { -+ val |= (DMA_RWCTRL_READ_BNDRY_384_PCIX | -+ DMA_RWCTRL_WRITE_BNDRY_384_PCIX); -+ } -+ break; -+ -+ case 256: -+ val |= (DMA_RWCTRL_READ_BNDRY_256_PCIX | -+ DMA_RWCTRL_WRITE_BNDRY_256_PCIX); -+ break; -+ -+ default: -+ val |= (DMA_RWCTRL_READ_BNDRY_384_PCIX | -+ DMA_RWCTRL_WRITE_BNDRY_384_PCIX); -+ break; -+ } -+ } else if (tg3_flag(tp, PCI_EXPRESS)) { -+ switch (cacheline_size) { -+ case 16: -+ case 32: -+ case 64: -+ if (goal == BOUNDARY_SINGLE_CACHELINE) { -+ val &= ~DMA_RWCTRL_WRITE_BNDRY_DISAB_PCIE; -+ val |= DMA_RWCTRL_WRITE_BNDRY_64_PCIE; -+ break; -+ } -+ /* fallthrough */ -+ case 128: -+ default: -+ val &= ~DMA_RWCTRL_WRITE_BNDRY_DISAB_PCIE; -+ val |= DMA_RWCTRL_WRITE_BNDRY_128_PCIE; -+ break; -+ } -+ } else { -+ switch (cacheline_size) { -+ case 16: -+ if (goal == BOUNDARY_SINGLE_CACHELINE) { -+ val |= (DMA_RWCTRL_READ_BNDRY_16 | -+ DMA_RWCTRL_WRITE_BNDRY_16); -+ break; -+ } -+ /* fallthrough */ -+ case 32: -+ if (goal == BOUNDARY_SINGLE_CACHELINE) { -+ val |= (DMA_RWCTRL_READ_BNDRY_32 | -+ DMA_RWCTRL_WRITE_BNDRY_32); -+ break; -+ } -+ /* fallthrough */ -+ case 64: -+ if (goal == BOUNDARY_SINGLE_CACHELINE) { -+ val |= (DMA_RWCTRL_READ_BNDRY_64 | -+ DMA_RWCTRL_WRITE_BNDRY_64); -+ break; -+ } -+ /* fallthrough */ -+ case 128: -+ if (goal == BOUNDARY_SINGLE_CACHELINE) { -+ val |= (DMA_RWCTRL_READ_BNDRY_128 | -+ DMA_RWCTRL_WRITE_BNDRY_128); -+ break; -+ } -+ /* fallthrough */ -+ case 256: -+ val |= (DMA_RWCTRL_READ_BNDRY_256 | -+ DMA_RWCTRL_WRITE_BNDRY_256); -+ break; -+ case 512: -+ val |= (DMA_RWCTRL_READ_BNDRY_512 | -+ DMA_RWCTRL_WRITE_BNDRY_512); -+ break; -+ case 1024: -+ default: -+ val |= (DMA_RWCTRL_READ_BNDRY_1024 | -+ DMA_RWCTRL_WRITE_BNDRY_1024); -+ break; -+ } -+ } -+ -+out: -+ return val; -+} -+ -+static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dma, -+ int size, bool to_device) -+{ -+ struct tg3_internal_buffer_desc test_desc; -+ u32 sram_dma_descs; -+ int i, ret; -+ -+ sram_dma_descs = NIC_SRAM_DMA_DESC_POOL_BASE; -+ -+ tw32(FTQ_RCVBD_COMP_FIFO_ENQDEQ, 0); -+ tw32(FTQ_RCVDATA_COMP_FIFO_ENQDEQ, 0); -+ tw32(RDMAC_STATUS, 0); -+ tw32(WDMAC_STATUS, 0); -+ -+ tw32(BUFMGR_MODE, 0); -+ tw32(FTQ_RESET, 0); -+ -+ test_desc.addr_hi = ((u64) buf_dma) >> 32; -+ test_desc.addr_lo = buf_dma & 0xffffffff; -+ test_desc.nic_mbuf = 0x00002100; -+ test_desc.len = size; -+ -+ /* -+ * HP ZX1 was seeing test failures for 5701 cards running at 33Mhz -+ * the *second* time the tg3 driver was getting loaded after an -+ * initial scan. -+ * -+ * Broadcom tells me: -+ * ...the DMA engine is connected to the GRC block and a DMA -+ * reset may affect the GRC block in some unpredictable way... -+ * The behavior of resets to individual blocks has not been tested. -+ * -+ * Broadcom noted the GRC reset will also reset all sub-components. -+ */ -+ if (to_device) { -+ test_desc.cqid_sqid = (13 << 8) | 2; -+ -+ tw32_f(RDMAC_MODE, RDMAC_MODE_ENABLE); -+ udelay(40); -+ } else { -+ test_desc.cqid_sqid = (16 << 8) | 7; -+ -+ tw32_f(WDMAC_MODE, WDMAC_MODE_ENABLE); -+ udelay(40); -+ } -+ test_desc.flags = 0x00000005; -+ -+ for (i = 0; i < (sizeof(test_desc) / sizeof(u32)); i++) { -+ u32 val; -+ -+ val = *(((u32 *)&test_desc) + i); -+ pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, -+ sram_dma_descs + (i * sizeof(u32))); -+ pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); -+ } -+ pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); -+ -+ if (to_device) -+ tw32(FTQ_DMA_HIGH_READ_FIFO_ENQDEQ, sram_dma_descs); -+ else -+ tw32(FTQ_DMA_HIGH_WRITE_FIFO_ENQDEQ, sram_dma_descs); -+ -+ ret = -ENODEV; -+ for (i = 0; i < 40; i++) { -+ u32 val; -+ -+ if (to_device) -+ val = tr32(FTQ_RCVBD_COMP_FIFO_ENQDEQ); -+ else -+ val = tr32(FTQ_RCVDATA_COMP_FIFO_ENQDEQ); -+ if ((val & 0xffff) == sram_dma_descs) { -+ ret = 0; -+ break; -+ } -+ -+ udelay(100); -+ } -+ -+ return ret; -+} -+ -+#define TEST_BUFFER_SIZE 0x2000 -+ -+#if (LINUX_VERSION_CODE >= 0x2060a) -+static DEFINE_PCI_DEVICE_TABLE(tg3_dma_wait_state_chipsets) = { -+ { PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_PCI15) }, -+ { }, -+}; -+#endif -+ -+static int __devinit tg3_test_dma(struct tg3 *tp) -+{ -+ dma_addr_t buf_dma; -+ u32 *buf, saved_dma_rwctrl; -+ int ret = 0; -+ -+ buf = dma_alloc_coherent(&tp->pdev->dev, TEST_BUFFER_SIZE, -+ &buf_dma, GFP_KERNEL); -+ if (!buf) { -+ ret = -ENOMEM; -+ goto out_nofree; -+ } -+ -+ tp->dma_rwctrl = ((0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) | -+ (0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT)); -+ -+ tp->dma_rwctrl = tg3_calc_dma_bndry(tp, tp->dma_rwctrl); -+ -+ if (tg3_flag(tp, 57765_PLUS)) -+ goto out; -+ -+ if (tg3_flag(tp, PCI_EXPRESS)) { -+ /* DMA read watermark not used on PCIE */ -+ tp->dma_rwctrl |= 0x00180000; -+ } else if (!tg3_flag(tp, PCIX_MODE)) { -+ if (tg3_asic_rev(tp) == ASIC_REV_5705 || -+ tg3_asic_rev(tp) == ASIC_REV_5750) -+ tp->dma_rwctrl |= 0x003f0000; -+ else -+ tp->dma_rwctrl |= 0x003f000f; -+ } else { -+ if (tg3_asic_rev(tp) == ASIC_REV_5703 || -+ tg3_asic_rev(tp) == ASIC_REV_5704) { -+ u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f); -+ u32 read_water = 0x7; -+ -+ /* If the 5704 is behind the EPB bridge, we can -+ * do the less restrictive ONE_DMA workaround for -+ * better performance. -+ */ -+ if (tg3_flag(tp, 40BIT_DMA_BUG) && -+ tg3_asic_rev(tp) == ASIC_REV_5704) -+ tp->dma_rwctrl |= 0x8000; -+ else if (ccval == 0x6 || ccval == 0x7) -+ tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5703) -+ read_water = 4; -+ /* Set bit 23 to enable PCIX hw bug fix */ -+ tp->dma_rwctrl |= -+ (read_water << DMA_RWCTRL_READ_WATER_SHIFT) | -+ (0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) | -+ (1 << 23); -+ } else if (tg3_asic_rev(tp) == ASIC_REV_5780) { -+ /* 5780 always in PCIX mode */ -+ tp->dma_rwctrl |= 0x00144000; -+ } else if (tg3_asic_rev(tp) == ASIC_REV_5714) { -+ /* 5714 always in PCIX mode */ -+ tp->dma_rwctrl |= 0x00148000; -+ } else { -+ tp->dma_rwctrl |= 0x001b000f; -+ } -+ } -+ if (tg3_flag(tp, ONE_DMA_AT_ONCE)) -+ tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5703 || -+ tg3_asic_rev(tp) == ASIC_REV_5704) -+ tp->dma_rwctrl &= 0xfffffff0; -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5700 || -+ tg3_asic_rev(tp) == ASIC_REV_5701) { -+ /* Remove this if it causes problems for some boards. */ -+ tp->dma_rwctrl |= DMA_RWCTRL_USE_MEM_READ_MULT; -+ -+ /* On 5700/5701 chips, we need to set this bit. -+ * Otherwise the chip will issue cacheline transactions -+ * to streamable DMA memory with not all the byte -+ * enables turned on. This is an error on several -+ * RISC PCI controllers, in particular sparc64. -+ * -+ * On 5703/5704 chips, this bit has been reassigned -+ * a different meaning. In particular, it is used -+ * on those chips to enable a PCI-X workaround. -+ */ -+ tp->dma_rwctrl |= DMA_RWCTRL_ASSERT_ALL_BE; -+ } -+ -+ tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); -+ -+#if 0 -+ /* Unneeded, already done by tg3_get_invariants. */ -+ tg3_switch_clocks(tp); -+#endif -+ -+ if (tg3_asic_rev(tp) != ASIC_REV_5700 && -+ tg3_asic_rev(tp) != ASIC_REV_5701) -+ goto out; -+ -+ /* It is best to perform DMA test with maximum write burst size -+ * to expose the 5700/5701 write DMA bug. -+ */ -+ saved_dma_rwctrl = tp->dma_rwctrl; -+ tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK; -+ tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); -+ -+ while (1) { -+ u32 *p = buf, i; -+ -+ for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) -+ p[i] = i; -+ -+ /* Send the buffer to the chip. */ -+ ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, true); -+ if (ret) { -+ dev_err(&tp->pdev->dev, -+ "%s: Buffer write failed. err = %d\n", -+ __func__, ret); -+ break; -+ } -+ -+#if 0 -+ /* validate data reached card RAM correctly. */ -+ for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) { -+ u32 val; -+ tg3_read_mem(tp, 0x2100 + (i*4), &val); -+ if (le32_to_cpu(val) != p[i]) { -+ dev_err(&tp->pdev->dev, -+ "%s: Buffer corrupted on device! " -+ "(%d != %d)\n", __func__, val, i); -+ /* ret = -ENODEV here? */ -+ } -+ p[i] = 0; -+ } -+#endif -+ /* Now read it back. */ -+ ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, false); -+ if (ret) { -+ dev_err(&tp->pdev->dev, "%s: Buffer read failed. " -+ "err = %d\n", __func__, ret); -+ break; -+ } -+ -+ /* Verify it. */ -+ for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) { -+ if (p[i] == i) -+ continue; -+ -+ if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) != -+ DMA_RWCTRL_WRITE_BNDRY_16) { -+ tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK; -+ tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16; -+ tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); -+ break; -+ } else { -+ dev_err(&tp->pdev->dev, -+ "%s: Buffer corrupted on read back! " -+ "(%d != %d)\n", __func__, p[i], i); -+ ret = -ENODEV; -+ goto out; -+ } -+ } -+ -+ if (i == (TEST_BUFFER_SIZE / sizeof(u32))) { -+ /* Success. */ -+ ret = 0; -+ break; -+ } -+ } -+ if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) != -+ DMA_RWCTRL_WRITE_BNDRY_16) { -+ /* DMA test passed without adjusting DMA boundary, -+ * now look for chipsets that are known to expose the -+ * DMA bug without failing the test. -+ */ -+#if (LINUX_VERSION_CODE < 0x2060a) -+ if (pci_find_device(PCI_VENDOR_ID_APPLE, -+ PCI_DEVICE_ID_APPLE_UNI_N_PCI15, NULL)) -+#else -+ if (pci_dev_present(tg3_dma_wait_state_chipsets)) -+#endif -+ { -+ tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK; -+ tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16; -+ } else { -+ /* Safe to use the calculated DMA boundary. */ -+ tp->dma_rwctrl = saved_dma_rwctrl; -+ } -+ -+ tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); -+ } -+ -+out: -+ dma_free_coherent(&tp->pdev->dev, TEST_BUFFER_SIZE, buf, buf_dma); -+out_nofree: -+ return ret; -+} -+ -+static void __devinit tg3_init_bufmgr_config(struct tg3 *tp) -+{ -+ if (tg3_flag(tp, 57765_PLUS)) { -+ tp->bufmgr_config.mbuf_read_dma_low_water = -+ DEFAULT_MB_RDMA_LOW_WATER_5705; -+ tp->bufmgr_config.mbuf_mac_rx_low_water = -+ DEFAULT_MB_MACRX_LOW_WATER_57765; -+ tp->bufmgr_config.mbuf_high_water = -+ DEFAULT_MB_HIGH_WATER_57765; -+ -+ tp->bufmgr_config.mbuf_read_dma_low_water_jumbo = -+ DEFAULT_MB_RDMA_LOW_WATER_5705; -+ tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo = -+ DEFAULT_MB_MACRX_LOW_WATER_JUMBO_57765; -+ tp->bufmgr_config.mbuf_high_water_jumbo = -+ DEFAULT_MB_HIGH_WATER_JUMBO_57765; -+ } else if (tg3_flag(tp, 5705_PLUS)) { -+ tp->bufmgr_config.mbuf_read_dma_low_water = -+ DEFAULT_MB_RDMA_LOW_WATER_5705; -+ tp->bufmgr_config.mbuf_mac_rx_low_water = -+ DEFAULT_MB_MACRX_LOW_WATER_5705; -+ tp->bufmgr_config.mbuf_high_water = -+ DEFAULT_MB_HIGH_WATER_5705; -+ if (tg3_asic_rev(tp) == ASIC_REV_5906) { -+ tp->bufmgr_config.mbuf_mac_rx_low_water = -+ DEFAULT_MB_MACRX_LOW_WATER_5906; -+ tp->bufmgr_config.mbuf_high_water = -+ DEFAULT_MB_HIGH_WATER_5906; -+ } -+ -+ tp->bufmgr_config.mbuf_read_dma_low_water_jumbo = -+ DEFAULT_MB_RDMA_LOW_WATER_JUMBO_5780; -+ tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo = -+ DEFAULT_MB_MACRX_LOW_WATER_JUMBO_5780; -+ tp->bufmgr_config.mbuf_high_water_jumbo = -+ DEFAULT_MB_HIGH_WATER_JUMBO_5780; -+ } else { -+ tp->bufmgr_config.mbuf_read_dma_low_water = -+ DEFAULT_MB_RDMA_LOW_WATER; -+ tp->bufmgr_config.mbuf_mac_rx_low_water = -+ DEFAULT_MB_MACRX_LOW_WATER; -+ tp->bufmgr_config.mbuf_high_water = -+ DEFAULT_MB_HIGH_WATER; -+ -+ tp->bufmgr_config.mbuf_read_dma_low_water_jumbo = -+ DEFAULT_MB_RDMA_LOW_WATER_JUMBO; -+ tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo = -+ DEFAULT_MB_MACRX_LOW_WATER_JUMBO; -+ tp->bufmgr_config.mbuf_high_water_jumbo = -+ DEFAULT_MB_HIGH_WATER_JUMBO; -+ } -+ -+ tp->bufmgr_config.dma_low_water = DEFAULT_DMA_LOW_WATER; -+ tp->bufmgr_config.dma_high_water = DEFAULT_DMA_HIGH_WATER; -+} -+ -+static char * __devinit tg3_phy_string(struct tg3 *tp) -+{ -+ switch (tp->phy_id & TG3_PHY_ID_MASK) { -+ case TG3_PHY_ID_BCM5400: return "5400"; -+ case TG3_PHY_ID_BCM5401: return "5401"; -+ case TG3_PHY_ID_BCM5411: return "5411"; -+ case TG3_PHY_ID_BCM5701: return "5701"; -+ case TG3_PHY_ID_BCM5703: return "5703"; -+ case TG3_PHY_ID_BCM5704: return "5704"; -+ case TG3_PHY_ID_BCM5705: return "5705"; -+ case TG3_PHY_ID_BCM5750: return "5750"; -+ case TG3_PHY_ID_BCM5752: return "5752"; -+ case TG3_PHY_ID_BCM5714: return "5714"; -+ case TG3_PHY_ID_BCM5780: return "5780"; -+ case TG3_PHY_ID_BCM5755: return "5755"; -+ case TG3_PHY_ID_BCM5787: return "5787"; -+ case TG3_PHY_ID_BCM5784: return "5784"; -+ case TG3_PHY_ID_BCM5756: return "5722/5756"; -+ case TG3_PHY_ID_BCM5906: return "5906"; -+ case TG3_PHY_ID_BCM5761: return "5761"; -+#ifndef BCM_INCLUDE_PHYLIB_SUPPORT -+ case TG3_PHY_ID_BCM50610: return "50610"; -+ case TG3_PHY_ID_BCM50610M: return "50610M"; -+ case TG3_PHY_ID_BCM50612E: return "50612E"; -+ case TG3_PHY_ID_BCMAC131: return "AC131"; -+ case TG3_PHY_ID_BCM57780: return "57780"; -+#endif -+ case TG3_PHY_ID_BCM5718C: return "5718C"; -+ case TG3_PHY_ID_BCM5718S: return "5718S"; -+ case TG3_PHY_ID_BCM57765: return "57765"; -+ case TG3_PHY_ID_BCM5719C: return "5719C"; -+ case TG3_PHY_ID_BCM5720C: return "5720C"; -+ case TG3_PHY_ID_BCM5762: return "5762C"; -+ case TG3_PHY_ID_BCM8002: return "8002/serdes"; -+ case 0: return "serdes"; -+ default: return "unknown"; -+ } -+} -+ -+static char * __devinit tg3_bus_string(struct tg3 *tp, char *str) -+{ -+ if (tg3_flag(tp, PCI_EXPRESS)) { -+ strcpy(str, "PCI Express"); -+ return str; -+ } else if (tg3_flag(tp, PCIX_MODE)) { -+ u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL) & 0x1f; -+ -+ strcpy(str, "PCIX:"); -+ -+ if ((clock_ctrl == 7) || -+ ((tr32(GRC_MISC_CFG) & GRC_MISC_CFG_BOARD_ID_MASK) == -+ GRC_MISC_CFG_BOARD_ID_5704CIOBE)) -+ strcat(str, "133MHz"); -+ else if (clock_ctrl == 0) -+ strcat(str, "33MHz"); -+ else if (clock_ctrl == 2) -+ strcat(str, "50MHz"); -+ else if (clock_ctrl == 4) -+ strcat(str, "66MHz"); -+ else if (clock_ctrl == 6) -+ strcat(str, "100MHz"); -+ } else { -+ strcpy(str, "PCI:"); -+ if (tg3_flag(tp, PCI_HIGH_SPEED)) -+ strcat(str, "66MHz"); -+ else -+ strcat(str, "33MHz"); -+ } -+ if (tg3_flag(tp, PCI_32BIT)) -+ strcat(str, ":32-bit"); -+ else -+ strcat(str, ":64-bit"); -+ return str; -+} -+ -+static void __devinit tg3_init_coal(struct tg3 *tp) -+{ -+ struct ethtool_coalesce *ec = &tp->coal; -+ -+ memset(ec, 0, sizeof(*ec)); -+ ec->cmd = ETHTOOL_GCOALESCE; -+ ec->rx_coalesce_usecs = LOW_RXCOL_TICKS; -+ ec->tx_coalesce_usecs = LOW_TXCOL_TICKS; -+ ec->rx_max_coalesced_frames = LOW_RXMAX_FRAMES; -+ ec->tx_max_coalesced_frames = LOW_TXMAX_FRAMES; -+ ec->rx_coalesce_usecs_irq = DEFAULT_RXCOAL_TICK_INT; -+ ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT; -+ ec->rx_max_coalesced_frames_irq = DEFAULT_RXCOAL_MAXF_INT; -+ ec->tx_max_coalesced_frames_irq = DEFAULT_TXCOAL_MAXF_INT; -+ ec->stats_block_coalesce_usecs = DEFAULT_STAT_COAL_TICKS; -+ -+ if (tp->coalesce_mode & (HOSTCC_MODE_CLRTICK_RXBD | -+ HOSTCC_MODE_CLRTICK_TXBD)) { -+ ec->rx_coalesce_usecs = LOW_RXCOL_TICKS_CLRTCKS; -+ ec->rx_coalesce_usecs_irq = DEFAULT_RXCOAL_TICK_INT_CLRTCKS; -+ ec->tx_coalesce_usecs = LOW_TXCOL_TICKS_CLRTCKS; -+ ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT_CLRTCKS; -+ } -+ -+ if (tg3_flag(tp, 5705_PLUS)) { -+ ec->rx_coalesce_usecs_irq = 0; -+ ec->tx_coalesce_usecs_irq = 0; -+ ec->stats_block_coalesce_usecs = 0; -+ } -+} -+ -+static int __devinit tg3_init_one(struct pci_dev *pdev, -+ const struct pci_device_id *ent) -+{ -+ struct net_device *dev; -+ struct tg3 *tp; -+ int i, err, pm_cap; -+ u32 sndmbx, rcvmbx, intmbx; -+ char str[40]; -+ u64 dma_mask, persist_dma_mask; -+ DECLARE_MAC_BUF(mac); -+ netdev_features_t features = 0; -+ -+ printk_once(KERN_INFO "%s\n", version); -+ -+ err = pci_enable_device(pdev); -+ if (err) { -+ dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n"); -+ return err; -+ } -+ -+ err = pci_request_regions(pdev, DRV_MODULE_NAME); -+ if (err) { -+ dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting\n"); -+ goto err_out_disable_pdev; -+ } -+ -+ pci_set_master(pdev); -+ -+ /* Find power-management capability. */ -+ pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); -+ if (pm_cap == 0) { -+ dev_err(&pdev->dev, -+ "Cannot find Power Management capability, aborting\n"); -+ err = -EIO; -+ goto err_out_free_res; -+ } -+ -+ err = pci_set_power_state(pdev, PCI_D0); -+ if (err) { -+ dev_err(&pdev->dev, "Transition to D0 failed, aborting\n"); -+ goto err_out_free_res; -+ } -+ -+ dev = alloc_etherdev_mq(sizeof(*tp), TG3_IRQ_MAX_VECS); -+ if (!dev) { -+ dev_err(&pdev->dev, "Etherdev alloc failed, aborting\n"); -+ err = -ENOMEM; -+ goto err_out_power_down; -+ } -+ -+ SET_MODULE_OWNER(dev); -+#if (LINUX_VERSION_CODE >= 0x20419) -+ SET_NETDEV_DEV(dev, &pdev->dev); -+#endif -+ -+ pci_set_drvdata(pdev, dev); -+ -+ tp = netdev_priv(dev); -+ tp->pdev = pdev; -+ tp->dev = dev; -+ tp->pm_cap = pm_cap; -+ tp->rx_mode = TG3_DEF_RX_MODE; -+ tp->tx_mode = TG3_DEF_TX_MODE; -+ tp->irq_sync = 1; -+ -+ if (tg3_debug > 0) -+ tp->msg_enable = tg3_debug; -+ else -+ tp->msg_enable = TG3_DEF_MSG_ENABLE; -+ -+ if (pdev_is_ssb_gige_core(pdev)) { -+ tg3_flag_set(tp, IS_SSB_CORE); -+ if (ssb_gige_must_flush_posted_writes(pdev)) -+ tg3_flag_set(tp, FLUSH_POSTED_WRITES); -+ if (ssb_gige_one_dma_at_once(pdev)) -+ tg3_flag_set(tp, ONE_DMA_AT_ONCE); -+ if (ssb_gige_have_roboswitch(pdev)) { -+ tg3_flag_set(tp, USE_PHYLIB); -+ tg3_flag_set(tp, ROBOSWITCH); -+ } -+ if (ssb_gige_is_rgmii(pdev)) -+ tg3_flag_set(tp, RGMII_MODE); -+ } -+ -+ /* The word/byte swap controls here control register access byte -+ * swapping. DMA data byte swapping is controlled in the GRC_MODE -+ * setting below. -+ */ -+ tp->misc_host_ctrl = -+ MISC_HOST_CTRL_MASK_PCI_INT | -+ MISC_HOST_CTRL_WORD_SWAP | -+ MISC_HOST_CTRL_INDIR_ACCESS | -+ MISC_HOST_CTRL_PCISTATE_RW; -+ -+ /* The NONFRM (non-frame) byte/word swap controls take effect -+ * on descriptor entries, anything which isn't packet data. -+ * -+ * The StrongARM chips on the board (one for tx, one for rx) -+ * are running in big-endian mode. -+ */ -+ tp->grc_mode = (GRC_MODE_WSWAP_DATA | GRC_MODE_BSWAP_DATA | -+ GRC_MODE_WSWAP_NONFRM_DATA); -+#ifdef __BIG_ENDIAN -+ tp->grc_mode |= GRC_MODE_BSWAP_NONFRM_DATA; -+#endif -+ spin_lock_init(&tp->lock); -+ spin_lock_init(&tp->indirect_lock); -+#ifdef BCM_HAS_NEW_INIT_WORK -+ INIT_WORK(&tp->reset_task, tg3_reset_task); -+#else -+ INIT_WORK(&tp->reset_task, tg3_reset_task, tp); -+#endif -+ -+ tp->regs = pci_ioremap_bar(pdev, BAR_0); -+ if (!tp->regs) { -+ dev_err(&pdev->dev, "Cannot map device registers, aborting\n"); -+ err = -ENOMEM; -+ goto err_out_free_dev; -+ } -+ -+ if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 || -+ tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761E || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761SE || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717_C || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57767 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57764 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727 || -+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57787) { -+ tg3_flag_set(tp, ENABLE_APE); -+ tp->aperegs = pci_ioremap_bar(pdev, BAR_2); -+ if (!tp->aperegs) { -+ dev_err(&pdev->dev, -+ "Cannot map APE registers, aborting\n"); -+ err = -ENOMEM; -+ goto err_out_iounmap; -+ } -+ } -+ -+ tp->rx_pending = TG3_DEF_RX_RING_PENDING; -+ tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING; -+ -+ dev->ethtool_ops = &tg3_ethtool_ops; -+#ifdef GET_ETHTOOL_OP_EXT -+ set_ethtool_ops_ext(dev, &tg3_ethtool_ops_ext); -+#endif -+ -+#ifdef GET_NETDEV_OP_EXT -+ set_netdev_ops_ext(dev, &tg3_net_device_ops_ext); -+#endif -+ -+ dev->watchdog_timeo = TG3_TX_TIMEOUT; -+ dev->irq = pdev->irq; -+ -+ err = tg3_get_invariants(tp, ent); -+ if (err) { -+ dev_err(&pdev->dev, -+ "Problem fetching invariants of chip, aborting\n"); -+ goto err_out_apeunmap; -+ } -+ -+#ifdef BCM_HAS_NET_DEVICE_OPS -+ dev->netdev_ops = &tg3_netdev_ops; -+#else -+ dev->open = tg3_open; -+ dev->stop = tg3_close; -+ dev->get_stats = tg3_get_stats; -+ dev->set_multicast_list = tg3_set_rx_mode; -+ dev->set_mac_address = tg3_set_mac_addr; -+ dev->do_ioctl = tg3_ioctl; -+ dev->tx_timeout = tg3_tx_timeout; -+ dev->change_mtu = tg3_change_mtu; -+#ifndef BCM_HAS_NEW_VLAN_INTERFACE -+ dev->vlan_rx_register = tg3_vlan_rx_register; -+ dev->vlan_rx_kill_vid = tg3_vlan_rx_kill_vid; -+#endif -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ dev->poll_controller = tg3_poll_controller; -+#endif -+ -+ tp->dev->hard_start_xmit = tg3_start_xmit; -+#endif -+ -+ /* The EPB bridge inside 5714, 5715, and 5780 and any -+ * device behind the EPB cannot support DMA addresses > 40-bit. -+ * On 64-bit systems with IOMMU, use 40-bit dma_mask. -+ * On 64-bit systems without IOMMU, use 64-bit dma_mask and -+ * do DMA address check in tg3_start_xmit(). -+ */ -+ if (tg3_flag(tp, IS_5788)) -+ persist_dma_mask = dma_mask = DMA_BIT_MASK(32); -+ else if (tg3_flag(tp, 40BIT_DMA_BUG)) { -+ persist_dma_mask = dma_mask = DMA_BIT_MASK(40); -+#ifdef CONFIG_HIGHMEM -+ dma_mask = DMA_BIT_MASK(64); -+#endif -+ } else -+ persist_dma_mask = dma_mask = DMA_BIT_MASK(64); -+ -+ /* Configure DMA attributes. */ -+ if (dma_mask > DMA_BIT_MASK(32)) { -+ err = pci_set_dma_mask(pdev, dma_mask); -+ if (!err) { -+ features |= NETIF_F_HIGHDMA; -+ err = pci_set_consistent_dma_mask(pdev, -+ persist_dma_mask); -+ if (err < 0) { -+ dev_err(&pdev->dev, "Unable to obtain " -+ "DMA for consistent allocations\n"); -+ goto err_out_apeunmap; -+ } -+ } -+ } -+ if (err || dma_mask == DMA_BIT_MASK(32)) { -+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); -+ if (err) { -+ dev_err(&pdev->dev, -+ "No usable DMA configuration, aborting\n"); -+ goto err_out_apeunmap; -+ } -+ } -+ -+ tg3_init_bufmgr_config(tp); -+ -+ /* 5700 B0 chips do not support checksumming correctly due -+ * to hardware bugs. -+ */ -+ if (tg3_chip_rev_id(tp) != CHIPREV_ID_5700_B0) { -+ features |= NETIF_F_SG | NETIF_F_GRO | NETIF_F_RXCSUM; -+ -+#ifndef BCM_NO_IPV6_CSUM -+ features |= NETIF_F_IP_CSUM; -+ if (tg3_flag(tp, 5755_PLUS)) -+ features |= NETIF_F_IPV6_CSUM; -+#else -+ if (tg3_flag(tp, 5755_PLUS)) -+ features |= NETIF_F_HW_CSUM; -+ else -+ features |= NETIF_F_IP_CSUM; -+#endif -+ } -+ -+#if TG3_TSO_SUPPORT != 0 -+ /* TSO is on by default on chips that support hardware TSO. -+ * Firmware TSO on older chips gives lower performance, so it -+ * is off by default, but can be enabled using ethtool. -+ */ -+ if ((tg3_flag(tp, HW_TSO_1) || -+ tg3_flag(tp, HW_TSO_2) || -+ tg3_flag(tp, HW_TSO_3)) && -+ (features & (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM))) -+ features |= NETIF_F_TSO; -+ if (tg3_flag(tp, HW_TSO_2) || tg3_flag(tp, HW_TSO_3)) { -+ if (features & NETIF_F_IPV6_CSUM) -+ features |= NETIF_F_TSO6; -+ if (tg3_flag(tp, HW_TSO_3) || -+ tg3_asic_rev(tp) == ASIC_REV_5761 || -+ (tg3_asic_rev(tp) == ASIC_REV_5784 && -+ tg3_chip_rev(tp) != CHIPREV_5784_AX) || -+ tg3_asic_rev(tp) == ASIC_REV_5785 || -+ tg3_asic_rev(tp) == ASIC_REV_57780) -+ features |= NETIF_F_TSO_ECN; -+ } -+ -+#if defined(__VMKLNX__) -+ features = tg3_vmware_tune_tso(tp, features); -+#endif /* __VMKLNX__ */ -+#endif /* TG3_TSO_SUPPORT != 0 */ -+ -+ dev->features |= features | NETIF_F_HW_VLAN_CTAG_TX | -+ NETIF_F_HW_VLAN_CTAG_RX; -+ dev->vlan_features |= features; -+ -+#ifdef BCM_HAS_FIX_FEATURES -+ /* -+ * Add loopback capability only for a subset of devices that support -+ * MAC-LOOPBACK. Eventually this need to be enhanced to allow INT-PHY -+ * loopback for the remaining devices. -+ */ -+ if (tg3_asic_rev(tp) != ASIC_REV_5780 && -+ !tg3_flag(tp, CPMU_PRESENT)) -+ /* Add the loopback capability */ -+ features |= NETIF_F_LOOPBACK; -+#endif -+ -+#if defined(GET_NETDEV_OP_EXT) -+ set_netdev_hw_features(dev, get_netdev_hw_features(dev) | features); -+#else -+ dev->hw_features |= features; -+#endif -+ -+#ifdef IFF_UNICAST_FLT -+ dev->priv_flags |= IFF_UNICAST_FLT; -+#endif -+ -+ if (tg3_chip_rev_id(tp) == CHIPREV_ID_5705_A1 && -+ !tg3_flag(tp, TSO_CAPABLE) && -+ !(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) { -+ tg3_flag_set(tp, MAX_RXPEND_64); -+ tp->rx_pending = 63; -+ } -+ -+ err = tg3_get_device_address(tp); -+ if (err) { -+ dev_err(&pdev->dev, -+ "Could not obtain valid ethernet address, aborting\n"); -+ goto err_out_apeunmap; -+ } -+ -+ intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW; -+ rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW; -+ sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW; -+ for (i = 0; i < tp->irq_max; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ -+ tnapi->tp = tp; -+ tnapi->tx_pending = TG3_DEF_TX_RING_PENDING; -+ -+ tnapi->int_mbox = intmbx; -+ if (i <= 4) -+ intmbx += 0x8; -+ else { -+ if (intmbx & 0x4) -+ intmbx -= 0x4; -+ else -+ intmbx += 0xc; -+ } -+ -+ tnapi->consmbox = rcvmbx; -+ tnapi->prodmbox = sndmbx; -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ tg3_setup_prod_mboxes(tp, i); -+#endif -+ -+ if (i) -+ tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1); -+ else -+ tnapi->coal_now = HOSTCC_MODE_NOW; -+ -+ if (!tg3_flag(tp, SUPPORT_MSIX)) -+ break; -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ /* -+ * If we support NETQ, the first interrupt vector is the default -+ * rx queue. The first four queues follow the legacy RSS mailbox -+ * enumeration scheme. Then, the enumerations follow the quirky -+ * new way. -+ */ -+ if(tg3_flag(tp, IOV_CAPABLE)) { -+ if (i > 3) { -+ if (rcvmbx & 0x4) -+ rcvmbx -= 0x4; -+ else -+ rcvmbx += 0xc; -+ } else -+ rcvmbx += 0x8; -+ } -+ -+ if (!i) -+ continue; -+ -+ if (!tg3_flag(tp, IOV_CAPABLE)) -+ rcvmbx += 0x8; -+#else -+ /* -+ * If we support MSIX, we'll be using RSS. If we're using -+ * RSS, the first vector only handles link interrupts and the -+ * remaining vectors handle rx and tx interrupts. Reuse the -+ * mailbox values for the next iteration. The values we setup -+ * above are still useful for the single vectored mode. -+ */ -+ if (!i) -+ continue; -+ -+ rcvmbx += 0x8; -+#endif -+ -+ if (sndmbx & 0x4) -+ sndmbx -= 0x4; -+ else -+ sndmbx += 0xc; -+ } -+ -+ /* -+ * Reset chip in case UNDI or EFI driver did not shutdown -+ * DMA self test will enable WDMAC and we'll see (spurious) -+ * pending DMA on the PCI bus at that point. -+ */ -+ if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) || -+ (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { -+ tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); -+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); -+ } -+ -+ err = tg3_test_dma(tp); -+ if (err) { -+ dev_err(&pdev->dev, "DMA engine test failed, aborting\n"); -+ goto err_out_apeunmap; -+ } -+ -+ tg3_init_coal(tp); -+ -+ if (tg3_asic_rev(tp) == ASIC_REV_5719 || -+ (tg3_asic_rev(tp) == ASIC_REV_5720 && -+ tp->pdev->device != TG3PCI_DEVICE_TIGON3_5717_C) || -+ tg3_asic_rev(tp) != ASIC_REV_5762) -+ tg3_flag_set(tp, PTP_CAPABLE); -+ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if (tg3_flag(tp, IOV_CAPABLE)) -+ tg3_netq_init(tp); -+#endif -+ -+ tg3_timer_init(tp); -+ -+ err = register_netdev(dev); -+ if (err) { -+ dev_err(&pdev->dev, "Cannot register net device, aborting\n"); -+ goto err_out_apeunmap; -+ } -+ -+ netdev_info(dev, "Tigon3 [partno(%s) rev %04x] (%s) MAC address %s\n", -+ tp->board_part_number, -+ tg3_chip_rev_id(tp), -+ tg3_bus_string(tp, str), -+ print_mac(mac, dev->dev_addr)); -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) { -+ struct phy_device *phydev; -+ phydev = tp->mdio_bus->phy_map[tp->phy_addr]; -+ netdev_info(dev, -+ "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", -+ phydev->drv->name, dev_name(&phydev->dev)); -+ } else -+#endif -+ { -+ char *ethtype; -+ -+ if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) -+ ethtype = "10/100Base-TX"; -+ else if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) -+ ethtype = "1000Base-SX"; -+ else -+ ethtype = "10/100/1000Base-T"; -+ -+ netdev_info(dev, "attached PHY is %s (%s Ethernet) " -+ "(WireSpeed[%d], EEE[%d])\n", -+ tg3_phy_string(tp), ethtype, -+ (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED) == 0, -+ (tp->phy_flags & TG3_PHYFLG_EEE_CAP) != 0); -+ } -+ -+ netdev_info(dev, "RXcsums[%d] LinkChgREG[%d] MIirq[%d] ASF[%d] TSOcap[%d]\n", -+ (dev->features & NETIF_F_RXCSUM) != 0, -+ tg3_flag(tp, USE_LINKCHG_REG) != 0, -+ (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT) != 0, -+ tg3_flag(tp, ENABLE_ASF) != 0, -+ tg3_flag(tp, TSO_CAPABLE) != 0); -+ netdev_info(dev, "dma_rwctrl[%08x] dma_mask[%d-bit]\n", -+ tp->dma_rwctrl, -+ pdev->dma_mask == DMA_BIT_MASK(32) ? 32 : -+ ((u64)pdev->dma_mask) == DMA_BIT_MASK(40) ? 40 : 64); -+ -+#if defined(__VMKLNX__) -+ netdev_info(dev, "Jumbo Frames capable[%d]\n", -+ tg3_flag(tp, JUMBO_CAPABLE) != 0); -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ if(tg3_flag(tp, IOV_CAPABLE)) -+ netdev_info(dev, "NetQueue module parameter index [%d]\n", -+ tp->vmware.netq.index); -+#endif -+#endif -+ -+#ifdef BCM_HAS_PCI_EEH_SUPPORT -+ pci_save_state(pdev); -+#endif -+ -+ -+#if defined(__VMKLNX__) && (VMWARE_ESX_DDK_VERSION >= 55000) -+ if (!disable_fw_dmp) { -+ static int nic_idx; -+ -+ /* sanity check the force_netq parameter */ -+ if (nic_idx >= TG3_MAX_NIC) { -+ dev_err(&pdev->dev, -+ "Invalid number of dev(%d)\n", -+ nic_idx); -+ return -EINVAL; -+ } -+ tp->nic_idx = nic_idx; -+ /* allow fw dmp for newer chip only */ -+ if (tg3_asic_rev(tp) > ASIC_REV_5906) -+ fwdmp_tp_ptr[tp->nic_idx] = tp; -+ else -+ netdev_info(dev, "No FW dump support in legacy chip\n" -+ ); -+ nic_idx++; -+ } -+#endif /*defined(__VMKLNX__) && (VMWARE_ESX_DDK_VERSION >= 55000) */ -+ return 0; -+ -+err_out_apeunmap: -+ if (tp->aperegs) { -+ iounmap(tp->aperegs); -+ tp->aperegs = NULL; -+ } -+ -+err_out_iounmap: -+ if (tp->regs) { -+ iounmap(tp->regs); -+ tp->regs = NULL; -+ } -+ -+err_out_free_dev: -+#if (LINUX_VERSION_CODE >= 0x20418) -+ free_netdev(dev); -+#else -+ kfree(dev); -+#endif -+ -+err_out_power_down: -+ pci_set_power_state(pdev, PCI_D3hot); -+ -+err_out_free_res: -+ pci_release_regions(pdev); -+ -+err_out_disable_pdev: -+ if (pci_is_enabled(pdev)) -+ pci_disable_device(pdev); -+ pci_set_drvdata(pdev, NULL); -+ return err; -+} -+ -+static void __devexit tg3_remove_one(struct pci_dev *pdev) -+{ -+ struct net_device *dev = pci_get_drvdata(pdev); -+ -+ if (dev) { -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (tp->fw) -+ tg3_priv_release_firmware(tp->fw); -+ -+ tg3_reset_task_cancel(tp); -+ -+ if (tg3_flag(tp, USE_PHYLIB)) { -+ tg3_phy_fini(tp); -+ tg3_mdio_fini(tp); -+ } -+ -+ unregister_netdev(dev); -+ -+ if (tp->aperegs) { -+ iounmap(tp->aperegs); -+ tp->aperegs = NULL; -+ } -+ if (tp->regs) { -+ iounmap(tp->regs); -+ tp->regs = NULL; -+ } -+#if (LINUX_VERSION_CODE >= 0x20418) -+ free_netdev(dev); -+#else -+ kfree(dev); -+#endif -+ pci_release_regions(pdev); -+ pci_disable_device(pdev); -+ pci_set_drvdata(pdev, NULL); -+ } -+} -+ -+#undef SIMPLE_DEV_PM_OPS -+#ifdef SIMPLE_DEV_PM_OPS -+static int tg3_suspend(struct device *device) -+#else -+static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) -+#endif -+{ -+#ifdef SIMPLE_DEV_PM_OPS -+ struct pci_dev *pdev = to_pci_dev(device); -+#endif -+ struct net_device *dev = pci_get_drvdata(pdev); -+ struct tg3 *tp = netdev_priv(dev); -+ int err = 0; -+ -+ if (tg3_invalid_pci_state(tp, state)) -+ return -EINVAL; -+ -+ tg3_pci_save_state(tp); -+ -+ rtnl_lock(); -+ -+ if (!netif_running(dev)) -+ goto power_down; -+ -+ tg3_reset_task_cancel(tp); -+ tg3_phy_stop(tp); -+ tg3_netif_stop(tp); -+ -+ tg3_timer_stop(tp); -+ -+ tg3_full_lock(tp, 1); -+ tg3_disable_ints(tp); -+ tg3_full_unlock(tp); -+ -+ netif_device_detach(dev); -+ -+ tg3_full_lock(tp, 0); -+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); -+ tg3_flag_clear(tp, INIT_COMPLETE); -+ tg3_full_unlock(tp); -+ -+ err = tg3_power_down_prepare(tp); -+ if (err) { -+ int err2; -+ -+ tg3_full_lock(tp, 0); -+ -+ tg3_flag_set(tp, INIT_COMPLETE); -+ err2 = tg3_restart_hw(tp, true); -+ if (err2) -+ goto out; -+ -+ tg3_timer_start(tp); -+ -+ netif_device_attach(dev); -+ tg3_netif_start(tp); -+ -+out: -+ tg3_full_unlock(tp); -+ -+ if (!err2) -+ tg3_phy_start(tp); -+ } -+ -+power_down: -+#ifndef SIMPLE_DEV_PM_OPS -+ if (!err) -+ tg3_power_down(tp); -+#endif -+ -+ rtnl_unlock(); -+ return err; -+} -+ -+#ifdef SIMPLE_DEV_PM_OPS -+static int tg3_resume(struct device *device) -+#else -+static int tg3_resume(struct pci_dev *pdev) -+#endif -+{ -+#ifdef SIMPLE_DEV_PM_OPS -+ struct pci_dev *pdev = to_pci_dev(device); -+#endif -+ struct net_device *dev = pci_get_drvdata(pdev); -+ struct tg3 *tp = netdev_priv(dev); -+ int err = 0; -+ -+ tg3_pci_restore_state(tp); -+ -+ rtnl_lock(); -+ -+ if (!netif_running(dev)) -+ goto unlock; -+ -+ err = tg3_power_up(tp); -+ if (err) -+ goto unlock; -+ -+ tg3_5780_class_intx_workaround(tp); -+ -+ netif_device_attach(dev); -+ -+ tg3_ape_driver_state_change(tp, RESET_KIND_INIT); -+ tg3_full_lock(tp, 0); -+ -+ tg3_flag_set(tp, INIT_COMPLETE); -+ err = tg3_restart_hw(tp, -+ !(tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN)); -+ if (err) -+ goto out; -+ -+ tg3_timer_start(tp); -+ -+ tg3_netif_start(tp); -+ -+out: -+ tg3_full_unlock(tp); -+ -+ if (!err) -+ tg3_phy_start(tp); -+ -+unlock: -+ rtnl_unlock(); -+ return err; -+} -+#ifdef BCM_HAS_PCI_PMOPS_SHUTDOWN -+#ifdef SIMPLE_DEV_PM_OPS -+static void tg3_shutdown(struct device *device) -+#else -+static void tg3_shutdown(struct pci_dev *pdev) -+#endif -+{ -+#ifdef SIMPLE_DEV_PM_OPS -+ struct pci_dev *pdev = to_pci_dev(device); -+#endif -+ struct net_device *dev = pci_get_drvdata(pdev); -+ struct tg3 *tp = netdev_priv(dev); -+ -+ rtnl_lock(); -+ netif_device_detach(dev); -+ -+ if (netif_running(dev)) -+#ifdef __VMKLNX__ /* ! BNX2X_UPSTREAM */ -+ if (dev->flags & IFF_UP) -+#endif -+ dev_close(dev); -+ -+ if (system_state == SYSTEM_POWER_OFF) -+ tg3_power_down(tp); -+ -+ rtnl_unlock(); -+} -+#endif /*BCM_HAS_PCI_PMOPS_SHUTDOWN*/ -+ -+#ifdef SIMPLE_DEV_PM_OPS -+#ifdef CONFIG_PM_SLEEP -+static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume); -+#define TG3_PM_OPS (&tg3_pm_ops) -+ -+#else -+ -+#define TG3_PM_OPS NULL -+ -+#endif /* CONFIG_PM_SLEEP */ -+#endif -+ -+#ifdef BCM_HAS_PCI_EEH_SUPPORT -+/** -+ * tg3_io_error_detected - called when PCI error is detected -+ * @pdev: Pointer to PCI device -+ * @state: The current pci connection state -+ * -+ * This function is called after a PCI bus error affecting -+ * this device has been detected. -+ */ -+static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev, -+ pci_channel_state_t state) -+{ -+ struct net_device *netdev = pci_get_drvdata(pdev); -+ struct tg3 *tp = netdev_priv(netdev); -+ pci_ers_result_t err = PCI_ERS_RESULT_NEED_RESET; -+ -+ netdev_info(netdev, "PCI I/O error detected\n"); -+ -+ rtnl_lock(); -+ -+ /* We probably don't have netdev yet */ -+ if (!netdev || !netif_running(netdev)) -+ goto done; -+ -+ tg3_phy_stop(tp); -+ -+ tg3_netif_stop(tp); -+ -+ tg3_timer_stop(tp); -+ -+ /* Want to make sure that the reset task doesn't run */ -+ tg3_reset_task_cancel(tp); -+ -+ netif_device_detach(netdev); -+ -+ /* Clean up software state, even if MMIO is blocked */ -+ tg3_full_lock(tp, 0); -+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); -+ tg3_full_unlock(tp); -+ -+done: -+ if (state == pci_channel_io_perm_failure) { -+ if (netdev) { -+ tg3_napi_enable(tp); -+ dev_close(netdev); -+ } -+ err = PCI_ERS_RESULT_DISCONNECT; -+ } else { -+ pci_disable_device(pdev); -+ } -+ -+ rtnl_unlock(); -+ -+ return err; -+} -+ -+/** -+ * tg3_io_slot_reset - called after the pci bus has been reset. -+ * @pdev: Pointer to PCI device -+ * -+ * Restart the card from scratch, as if from a cold-boot. -+ * At this point, the card has exprienced a hard reset, -+ * followed by fixups by BIOS, and has its config space -+ * set up identically to what it was at cold boot. -+ */ -+static pci_ers_result_t tg3_io_slot_reset(struct pci_dev *pdev) -+{ -+ struct net_device *netdev = pci_get_drvdata(pdev); -+ struct tg3 *tp = netdev_priv(netdev); -+ pci_ers_result_t rc = PCI_ERS_RESULT_DISCONNECT; -+ int err; -+ -+ rtnl_lock(); -+ -+ if (pci_enable_device(pdev)) { -+ dev_err(&pdev->dev, -+ "Cannot re-enable PCI device after reset.\n"); -+ goto done; -+ } -+ -+ pci_set_master(pdev); -+ pci_restore_state(pdev); -+ pci_save_state(pdev); -+ -+ if (!netdev || !netif_running(netdev)) { -+ rc = PCI_ERS_RESULT_RECOVERED; -+ goto done; -+ } -+ -+ err = tg3_power_up(tp); -+ if (err) -+ goto done; -+ -+ rc = PCI_ERS_RESULT_RECOVERED; -+ -+done: -+ if (rc != PCI_ERS_RESULT_RECOVERED && netdev && netif_running(netdev)) { -+ tg3_napi_enable(tp); -+ dev_close(netdev); -+ } -+ rtnl_unlock(); -+ -+ return rc; -+} -+ -+/** -+ * tg3_io_resume - called when traffic can start flowing again. -+ * @pdev: Pointer to PCI device -+ * -+ * This callback is called when the error recovery driver tells -+ * us that its OK to resume normal operation. -+ */ -+static void tg3_io_resume(struct pci_dev *pdev) -+{ -+ struct net_device *netdev = pci_get_drvdata(pdev); -+ struct tg3 *tp = netdev_priv(netdev); -+ int err; -+ -+ rtnl_lock(); -+ -+ if (!netif_running(netdev)) -+ goto done; -+ -+ tg3_ape_driver_state_change(tp, RESET_KIND_INIT); -+ tg3_full_lock(tp, 0); -+ tg3_flag_set(tp, INIT_COMPLETE); -+ err = tg3_restart_hw(tp, true); -+ if (err) { -+ tg3_full_unlock(tp); -+ netdev_err(netdev, "Cannot restart hardware after reset.\n"); -+ goto done; -+ } -+ -+ netif_device_attach(netdev); -+ -+ tg3_timer_start(tp); -+ -+ tg3_netif_start(tp); -+ -+ tg3_full_unlock(tp); -+ -+ tg3_phy_start(tp); -+ -+done: -+ rtnl_unlock(); -+} -+ -+static struct pci_error_handlers tg3_err_handler = { -+ .error_detected = tg3_io_error_detected, -+ .slot_reset = tg3_io_slot_reset, -+ .resume = tg3_io_resume -+}; -+#endif /* BCM_HAS_PCI_EEH_SUPPORT */ -+ -+static struct pci_driver tg3_driver = { -+ .name = DRV_MODULE_NAME, -+ .id_table = tg3_pci_tbl, -+ .probe = tg3_init_one, -+ .remove = __devexit_p(tg3_remove_one), -+#ifdef BCM_HAS_PCI_EEH_SUPPORT -+ .err_handler = &tg3_err_handler, -+#endif -+#ifdef SIMPLE_DEV_PM_OPS -+ .driver.pm = TG3_PM_OPS, -+#else -+ .suspend = tg3_suspend, -+ .resume = tg3_resume, -+#endif -+#ifdef BCM_HAS_PCI_PMOPS_SHUTDOWN -+ .shutdown = tg3_shutdown, -+#endif -+}; -+ -+static int __init tg3_init(void) -+{ -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ int i; -+ for (i = 0; i < TG3_MAX_NIC; i++) { -+ if (tg3_netq_force[i] < TG3_OPTION_UNSET || -+ tg3_netq_force[i] >= TG3_IRQ_MAX_VECS_IOV) { -+ dev_err(&pdev->dev, -+ "Invalid force_netq module parameter " -+ "value for index %d (%d)\n", -+ i, tg3_netq_force[i]); -+ return -EINVAL; -+ } -+ } -+#endif -+#if (LINUX_VERSION_CODE < 0x020613) && !defined (__VMKLNX__) -+ return pci_module_init(&tg3_driver); -+#else -+#if defined(__VMKLNX__) && (VMWARE_ESX_DDK_VERSION >= 55000) -+ if (!disable_fw_dmp) { -+ VMK_ReturnStatus status; -+ tg3_fwdmp_va_ptr = kzalloc(TG3_FWDMP_SIZE, GFP_KERNEL); -+ -+ if (!tg3_fwdmp_va_ptr) -+ dev_err(&pdev->dev, -+ "tg3: Unable to allocate memory " -+ "for fw dump handler!\n"); -+ status = vmklnx_dump_add_callback(TG3_DUMPNAME, -+ tg3_fwdmp_callback, -+ NULL, -+ TG3_DUMPNAME, -+ &tg3_fwdmp_dh); -+ if (status != VMK_OK) -+ dev_err(&pdev->dev, "tg3: Unable to register fw " -+ "dump handler (rc = 0x%x!)\n", status); -+ } -+#endif /*defined(__VMKLNX__) && (VMWARE_ESX_DDK_VERSION >= 55000) */ -+ -+ return pci_register_driver(&tg3_driver); -+#endif -+} -+ -+static void __exit tg3_cleanup(void) -+{ -+#if (defined(__VMKLNX__) && VMWARE_ESX_DDK_VERSION >= 55000) -+ if (tg3_fwdmp_dh) { -+ VMK_ReturnStatus status = -+ vmklnx_dump_delete_callback(tg3_fwdmp_dh); -+ if (status != VMK_OK) -+ VMK_ASSERT(0); -+ } -+ kfree(tg3_fwdmp_va_ptr); -+ tg3_fwdmp_va_ptr = NULL; -+#endif /* defined(__VMKLNX__) && (VMWARE_ESX_DDK_VERSION >= 55000) */ -+ pci_unregister_driver(&tg3_driver); -+} -+ -+#if defined(__VMKLNX__) -+#include "tg3_vmware.c" -+#endif -+ -+module_init(tg3_init); -+module_exit(tg3_cleanup); -diff --git a/drivers/net/ethernet/broadcom/tg3/tg3.h b/drivers/net/ethernet/broadcom/tg3/tg3.h -new file mode 100644 -index 0000000..0dd1a61 ---- /dev/null -+++ b/drivers/net/ethernet/broadcom/tg3/tg3.h -@@ -0,0 +1,3596 @@ -+/* $Id$ -+ * tg3.h: Definitions for Broadcom Tigon3 ethernet driver. -+ * -+ * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) -+ * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com) -+ * Copyright (C) 2004 Sun Microsystems Inc. -+ * Copyright (C) 2007-2015 Broadcom Corporation. -+ */ -+ -+#ifndef _T3_H -+#define _T3_H -+ -+#include "tg3_compat.h" -+ -+#define TG3_64BIT_REG_HIGH 0x00UL -+#define TG3_64BIT_REG_LOW 0x04UL -+ -+/* Descriptor block info. */ -+#define TG3_BDINFO_HOST_ADDR 0x0UL /* 64-bit */ -+#define TG3_BDINFO_MAXLEN_FLAGS 0x8UL /* 32-bit */ -+#define BDINFO_FLAGS_USE_EXT_RECV 0x00000001 /* ext rx_buffer_desc */ -+#define BDINFO_FLAGS_DISABLED 0x00000002 -+#define BDINFO_FLAGS_MAXLEN_MASK 0xffff0000 -+#define BDINFO_FLAGS_MAXLEN_SHIFT 16 -+#define TG3_BDINFO_NIC_ADDR 0xcUL /* 32-bit */ -+#define TG3_BDINFO_SIZE 0x10UL -+ -+#define TG3_RX_STD_MAX_SIZE_5700 512 -+#define TG3_RX_STD_MAX_SIZE_5717 2048 -+#define TG3_RX_JMB_MAX_SIZE_5700 256 -+#define TG3_RX_JMB_MAX_SIZE_5717 1024 -+#define TG3_RX_RET_MAX_SIZE_5700 1024 -+#define TG3_RX_RET_MAX_SIZE_5705 512 -+#define TG3_RX_RET_MAX_SIZE_5717 4096 -+ -+#define TG3_RSS_INDIR_TBL_SIZE 128 -+ -+/* First 256 bytes are a mirror of PCI config space. */ -+#define TG3PCI_VENDOR 0x00000000 -+#define TG3PCI_VENDOR_BROADCOM 0x14e4 -+#define TG3PCI_DEVICE 0x00000002 -+#define TG3PCI_DEVICE_TIGON3_1 0x1644 /* BCM5700 */ -+#define TG3PCI_DEVICE_TIGON3_2 0x1645 /* BCM5701 */ -+#define TG3PCI_DEVICE_TIGON3_3 0x1646 /* BCM5702 */ -+#define TG3PCI_DEVICE_TIGON3_4 0x1647 /* BCM5703 */ -+#define TG3PCI_DEVICE_TIGON3_5761S 0x1688 -+#define TG3PCI_DEVICE_TIGON3_5761SE 0x1689 -+#define TG3PCI_DEVICE_TIGON3_57780 0x1692 -+#define TG3PCI_DEVICE_TIGON3_5787M 0x1693 -+#define TG3PCI_DEVICE_TIGON3_57760 0x1690 -+#define TG3PCI_DEVICE_TIGON3_57790 0x1694 -+#define TG3PCI_DEVICE_TIGON3_57788 0x1691 -+#define TG3PCI_DEVICE_TIGON3_5785_G 0x1699 /* GPHY */ -+#define TG3PCI_DEVICE_TIGON3_5785_F 0x16a0 /* 10/100 only */ -+#define TG3PCI_DEVICE_TIGON3_5717 0x1655 -+#define TG3PCI_DEVICE_TIGON3_5717_C 0x1665 -+#define TG3PCI_DEVICE_TIGON3_5718 0x1656 -+#define TG3PCI_DEVICE_TIGON3_57781 0x16b1 -+#define TG3PCI_DEVICE_TIGON3_57785 0x16b5 -+#define TG3PCI_DEVICE_TIGON3_57761 0x16b0 -+#define TG3PCI_DEVICE_TIGON3_57765 0x16b4 -+#define TG3PCI_DEVICE_TIGON3_57791 0x16b2 -+#define TG3PCI_DEVICE_TIGON3_57795 0x16b6 -+#define TG3PCI_DEVICE_TIGON3_5719 0x1657 -+#define TG3PCI_DEVICE_TIGON3_5720 0x165f -+#define TG3PCI_DEVICE_TIGON3_57762 0x1682 -+#define TG3PCI_DEVICE_TIGON3_57766 0x1686 -+#define TG3PCI_DEVICE_TIGON3_57786 0x16b3 -+#define TG3PCI_DEVICE_TIGON3_57782 0x16b7 -+#define TG3PCI_DEVICE_TIGON3_5762 0x1687 -+#define TG3PCI_DEVICE_TIGON3_5725 0x1643 -+#define TG3PCI_DEVICE_TIGON3_5727 0x16f3 -+#define TG3PCI_DEVICE_TIGON3_57764 0x1642 -+#define TG3PCI_DEVICE_TIGON3_57767 0x1683 -+#define TG3PCI_DEVICE_TIGON3_57787 0x1641 -+/* 0x04 --> 0x2c unused */ -+#define TG3PCI_SUBVENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM -+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6 0x1644 -+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95701A5 0x0001 -+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95700T6 0x0002 -+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A9 0x0003 -+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95701T1 0x0005 -+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95701T8 0x0006 -+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95701A7 0x0007 -+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95701A10 0x0008 -+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95701A12 0x8008 -+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95703AX1 0x0009 -+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95703AX2 0x8009 -+#define TG3PCI_SUBVENDOR_ID_3COM PCI_VENDOR_ID_3COM -+#define TG3PCI_SUBDEVICE_ID_3COM_3C996T 0x1000 -+#define TG3PCI_SUBDEVICE_ID_3COM_3C996BT 0x1006 -+#define TG3PCI_SUBDEVICE_ID_3COM_3C996SX 0x1004 -+#define TG3PCI_SUBDEVICE_ID_3COM_3C1000T 0x1007 -+#define TG3PCI_SUBDEVICE_ID_3COM_3C940BR01 0x1008 -+#define TG3PCI_SUBVENDOR_ID_DELL PCI_VENDOR_ID_DELL -+#define TG3PCI_SUBDEVICE_ID_DELL_VIPER 0x00d1 -+#define TG3PCI_SUBDEVICE_ID_DELL_JAGUAR 0x0106 -+#define TG3PCI_SUBDEVICE_ID_DELL_MERLOT 0x0109 -+#define TG3PCI_SUBDEVICE_ID_DELL_SLIM_MERLOT 0x010a -+#define TG3PCI_SUBVENDOR_ID_COMPAQ PCI_VENDOR_ID_COMPAQ -+#define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE 0x007c -+#define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE_2 0x009a -+#define TG3PCI_SUBDEVICE_ID_COMPAQ_CHANGELING 0x007d -+#define TG3PCI_SUBDEVICE_ID_COMPAQ_NC7780 0x0085 -+#define TG3PCI_SUBDEVICE_ID_COMPAQ_NC7780_2 0x0099 -+#define TG3PCI_SUBVENDOR_ID_IBM PCI_VENDOR_ID_IBM -+#define TG3PCI_SUBDEVICE_ID_IBM_5703SAX2 0x0281 -+#define TG3PCI_SUBDEVICE_ID_ACER_57780_A 0x0601 -+#define TG3PCI_SUBDEVICE_ID_ACER_57780_B 0x0612 -+#define TG3PCI_SUBDEVICE_ID_LENOVO_5787M 0x3056 -+ -+/* 0x30 --> 0x64 unused */ -+#define TG3PCI_MSI_DATA 0x00000064 -+/* 0x66 --> 0x68 unused */ -+#define TG3PCI_MISC_HOST_CTRL 0x00000068 -+#define MISC_HOST_CTRL_CLEAR_INT 0x00000001 -+#define MISC_HOST_CTRL_MASK_PCI_INT 0x00000002 -+#define MISC_HOST_CTRL_BYTE_SWAP 0x00000004 -+#define MISC_HOST_CTRL_WORD_SWAP 0x00000008 -+#define MISC_HOST_CTRL_PCISTATE_RW 0x00000010 -+#define MISC_HOST_CTRL_CLKREG_RW 0x00000020 -+#define MISC_HOST_CTRL_REGWORD_SWAP 0x00000040 -+#define MISC_HOST_CTRL_INDIR_ACCESS 0x00000080 -+#define MISC_HOST_CTRL_IRQ_MASK_MODE 0x00000100 -+#define MISC_HOST_CTRL_TAGGED_STATUS 0x00000200 -+#define MISC_HOST_CTRL_CHIPREV 0xffff0000 -+#define MISC_HOST_CTRL_CHIPREV_SHIFT 16 -+ -+#define CHIPREV_ID_5700_A0 0x7000 -+#define CHIPREV_ID_5700_A1 0x7001 -+#define CHIPREV_ID_5700_B0 0x7100 -+#define CHIPREV_ID_5700_B1 0x7101 -+#define CHIPREV_ID_5700_B3 0x7102 -+#define CHIPREV_ID_5700_ALTIMA 0x7104 -+#define CHIPREV_ID_5700_C0 0x7200 -+#define CHIPREV_ID_5701_A0 0x0000 -+#define CHIPREV_ID_5701_B0 0x0100 -+#define CHIPREV_ID_5701_B2 0x0102 -+#define CHIPREV_ID_5701_B5 0x0105 -+#define CHIPREV_ID_5703_A0 0x1000 -+#define CHIPREV_ID_5703_A1 0x1001 -+#define CHIPREV_ID_5703_A2 0x1002 -+#define CHIPREV_ID_5703_A3 0x1003 -+#define CHIPREV_ID_5704_A0 0x2000 -+#define CHIPREV_ID_5704_A1 0x2001 -+#define CHIPREV_ID_5704_A2 0x2002 -+#define CHIPREV_ID_5704_A3 0x2003 -+#define CHIPREV_ID_5705_A0 0x3000 -+#define CHIPREV_ID_5705_A1 0x3001 -+#define CHIPREV_ID_5705_A2 0x3002 -+#define CHIPREV_ID_5705_A3 0x3003 -+#define CHIPREV_ID_5750_A0 0x4000 -+#define CHIPREV_ID_5750_A1 0x4001 -+#define CHIPREV_ID_5750_A3 0x4003 -+#define CHIPREV_ID_5750_C2 0x4202 -+#define CHIPREV_ID_5752_A0_HW 0x5000 -+#define CHIPREV_ID_5752_A0 0x6000 -+#define CHIPREV_ID_5752_A1 0x6001 -+#define CHIPREV_ID_5714_A2 0x9002 -+#define CHIPREV_ID_5906_A1 0xc001 -+#define CHIPREV_ID_57780_A0 0x57780000 -+#define CHIPREV_ID_57780_A1 0x57780001 -+#define CHIPREV_ID_5717_A0 0x05717000 -+#define CHIPREV_ID_5717_C0 0x05717200 -+#define CHIPREV_ID_57765_A0 0x57785000 -+#define CHIPREV_ID_5719_A0 0x05719000 -+#define CHIPREV_ID_5720_A0 0x05720000 -+#define CHIPREV_ID_5762_A0 0x05762000 -+ -+#define ASIC_REV_5700 0x07 -+#define ASIC_REV_5701 0x00 -+#define ASIC_REV_5703 0x01 -+#define ASIC_REV_5704 0x02 -+#define ASIC_REV_5705 0x03 -+#define ASIC_REV_5750 0x04 -+#define ASIC_REV_5752 0x06 -+#define ASIC_REV_5780 0x08 -+#define ASIC_REV_5714 0x09 -+#define ASIC_REV_5755 0x0a -+#define ASIC_REV_5787 0x0b -+#define ASIC_REV_5906 0x0c -+#define ASIC_REV_USE_PROD_ID_REG 0x0f -+#define ASIC_REV_5784 0x5784 -+#define ASIC_REV_5761 0x5761 -+#define ASIC_REV_5785 0x5785 -+#define ASIC_REV_57780 0x57780 -+#define ASIC_REV_5717 0x5717 -+#define ASIC_REV_57765 0x57785 -+#define ASIC_REV_5719 0x5719 -+#define ASIC_REV_5720 0x5720 -+#define ASIC_REV_57766 0x57766 -+#define ASIC_REV_5762 0x5762 -+#define CHIPREV_5700_AX 0x70 -+#define CHIPREV_5700_BX 0x71 -+#define CHIPREV_5700_CX 0x72 -+#define CHIPREV_5701_AX 0x00 -+#define CHIPREV_5703_AX 0x10 -+#define CHIPREV_5704_AX 0x20 -+#define CHIPREV_5704_BX 0x21 -+#define CHIPREV_5750_AX 0x40 -+#define CHIPREV_5750_BX 0x41 -+#define CHIPREV_5784_AX 0x57840 -+#define CHIPREV_5761_AX 0x57610 -+#define CHIPREV_57765_AX 0x577650 -+#define METAL_REV_A0 0x00 -+#define METAL_REV_A1 0x01 -+#define METAL_REV_B0 0x00 -+#define METAL_REV_B1 0x01 -+#define METAL_REV_B2 0x02 -+#define TG3PCI_DMA_RW_CTRL 0x0000006c -+#define DMA_RWCTRL_DIS_CACHE_ALIGNMENT 0x00000001 -+#define DMA_RWCTRL_TAGGED_STAT_WA 0x00000080 -+#define DMA_RWCTRL_CRDRDR_RDMA_MRRS_MSK 0x00000380 -+#define DMA_RWCTRL_READ_BNDRY_MASK 0x00000700 -+#define DMA_RWCTRL_READ_BNDRY_DISAB 0x00000000 -+#define DMA_RWCTRL_READ_BNDRY_16 0x00000100 -+#define DMA_RWCTRL_READ_BNDRY_128_PCIX 0x00000100 -+#define DMA_RWCTRL_READ_BNDRY_32 0x00000200 -+#define DMA_RWCTRL_READ_BNDRY_256_PCIX 0x00000200 -+#define DMA_RWCTRL_READ_BNDRY_64 0x00000300 -+#define DMA_RWCTRL_READ_BNDRY_384_PCIX 0x00000300 -+#define DMA_RWCTRL_READ_BNDRY_128 0x00000400 -+#define DMA_RWCTRL_READ_BNDRY_256 0x00000500 -+#define DMA_RWCTRL_READ_BNDRY_512 0x00000600 -+#define DMA_RWCTRL_READ_BNDRY_1024 0x00000700 -+#define DMA_RWCTRL_WRITE_BNDRY_MASK 0x00003800 -+#define DMA_RWCTRL_WRITE_BNDRY_DISAB 0x00000000 -+#define DMA_RWCTRL_WRITE_BNDRY_16 0x00000800 -+#define DMA_RWCTRL_WRITE_BNDRY_128_PCIX 0x00000800 -+#define DMA_RWCTRL_WRITE_BNDRY_32 0x00001000 -+#define DMA_RWCTRL_WRITE_BNDRY_256_PCIX 0x00001000 -+#define DMA_RWCTRL_WRITE_BNDRY_64 0x00001800 -+#define DMA_RWCTRL_WRITE_BNDRY_384_PCIX 0x00001800 -+#define DMA_RWCTRL_WRITE_BNDRY_128 0x00002000 -+#define DMA_RWCTRL_WRITE_BNDRY_256 0x00002800 -+#define DMA_RWCTRL_WRITE_BNDRY_512 0x00003000 -+#define DMA_RWCTRL_WRITE_BNDRY_1024 0x00003800 -+#define DMA_RWCTRL_ONE_DMA 0x00004000 -+#define DMA_RWCTRL_READ_WATER 0x00070000 -+#define DMA_RWCTRL_READ_WATER_SHIFT 16 -+#define DMA_RWCTRL_WRITE_WATER 0x00380000 -+#define DMA_RWCTRL_WRITE_WATER_SHIFT 19 -+#define DMA_RWCTRL_USE_MEM_READ_MULT 0x00400000 -+#define DMA_RWCTRL_ASSERT_ALL_BE 0x00800000 -+#define DMA_RWCTRL_PCI_READ_CMD 0x0f000000 -+#define DMA_RWCTRL_PCI_READ_CMD_SHIFT 24 -+#define DMA_RWCTRL_PCI_WRITE_CMD 0xf0000000 -+#define DMA_RWCTRL_PCI_WRITE_CMD_SHIFT 28 -+#define DMA_RWCTRL_WRITE_BNDRY_64_PCIE 0x10000000 -+#define DMA_RWCTRL_WRITE_BNDRY_128_PCIE 0x30000000 -+#define DMA_RWCTRL_WRITE_BNDRY_DISAB_PCIE 0x70000000 -+#define TG3PCI_PCISTATE 0x00000070 -+#define PCISTATE_FORCE_RESET 0x00000001 -+#define PCISTATE_INT_NOT_ACTIVE 0x00000002 -+#define PCISTATE_CONV_PCI_MODE 0x00000004 -+#define PCISTATE_BUS_SPEED_HIGH 0x00000008 -+#define PCISTATE_BUS_32BIT 0x00000010 -+#define PCISTATE_ROM_ENABLE 0x00000020 -+#define PCISTATE_ROM_RETRY_ENABLE 0x00000040 -+#define PCISTATE_FLAT_VIEW 0x00000100 -+#define PCISTATE_RETRY_SAME_DMA 0x00002000 -+#define PCISTATE_ALLOW_APE_CTLSPC_WR 0x00010000 -+#define PCISTATE_ALLOW_APE_SHMEM_WR 0x00020000 -+#define PCISTATE_ALLOW_APE_PSPACE_WR 0x00040000 -+#define TG3PCI_CLOCK_CTRL 0x00000074 -+#define CLOCK_CTRL_CORECLK_DISABLE 0x00000200 -+#define CLOCK_CTRL_RXCLK_DISABLE 0x00000400 -+#define CLOCK_CTRL_TXCLK_DISABLE 0x00000800 -+#define CLOCK_CTRL_ALTCLK 0x00001000 -+#define CLOCK_CTRL_PWRDOWN_PLL133 0x00008000 -+#define CLOCK_CTRL_44MHZ_CORE 0x00040000 -+#define CLOCK_CTRL_625_CORE 0x00100000 -+#define CLOCK_CTRL_FORCE_CLKRUN 0x00200000 -+#define CLOCK_CTRL_CLKRUN_OENABLE 0x00400000 -+#define CLOCK_CTRL_DELAY_PCI_GRANT 0x80000000 -+#define TG3PCI_REG_BASE_ADDR 0x00000078 -+#define TG3PCI_MEM_WIN_BASE_ADDR 0x0000007c -+#define TG3PCI_REG_DATA 0x00000080 -+#define TG3PCI_MEM_WIN_DATA 0x00000084 -+#define TG3PCI_MISC_LOCAL_CTRL 0x00000090 -+/* 0x94 --> 0x98 unused */ -+#define TG3PCI_STD_RING_PROD_IDX 0x00000098 /* 64-bit */ -+#define TG3PCI_RCV_RET_RING_CON_IDX 0x000000a0 /* 64-bit */ -+/* 0xa8 --> 0xb8 unused */ -+#define TG3PCI_DUAL_MAC_CTRL 0x000000b8 -+#define DUAL_MAC_CTRL_CH_MASK 0x00000003 -+#define DUAL_MAC_CTRL_ID 0x00000004 -+#define TG3PCI_PRODID_ASICREV 0x000000bc -+#define PROD_ID_ASIC_REV_MASK 0x0fffffff -+/* 0xc0 --> 0xf4 unused */ -+ -+#define TG3PCI_GEN2_PRODID_ASICREV 0x000000f4 -+#define TG3PCI_GEN15_PRODID_ASICREV 0x000000fc -+/* 0xf8 --> 0x200 unused */ -+ -+#define TG3_CORR_ERR_STAT 0x00000110 -+#define TG3_CORR_ERR_STAT_CLEAR 0xffffffff -+/* 0x114 --> 0x200 unused */ -+ -+/* Mailbox registers */ -+#define MAILBOX_INTERRUPT_0 0x00000200 /* 64-bit */ -+#define MAILBOX_INTERRUPT_1 0x00000208 /* 64-bit */ -+#define MAILBOX_INTERRUPT_2 0x00000210 /* 64-bit */ -+#define MAILBOX_INTERRUPT_3 0x00000218 /* 64-bit */ -+#define MAILBOX_GENERAL_0 0x00000220 /* 64-bit */ -+#define MAILBOX_GENERAL_1 0x00000228 /* 64-bit */ -+#define MAILBOX_GENERAL_2 0x00000230 /* 64-bit */ -+#define MAILBOX_GENERAL_3 0x00000238 /* 64-bit */ -+#define MAILBOX_GENERAL_4 0x00000240 /* 64-bit */ -+#define MAILBOX_GENERAL_5 0x00000248 /* 64-bit */ -+#define MAILBOX_GENERAL_6 0x00000250 /* 64-bit */ -+#define MAILBOX_GENERAL_7 0x00000258 /* 64-bit */ -+#define MAILBOX_RELOAD_STAT 0x00000260 /* 64-bit */ -+#define MAILBOX_RCV_STD_PROD_IDX 0x00000268 /* 64-bit */ -+#define TG3_RX_STD_PROD_IDX_REG (MAILBOX_RCV_STD_PROD_IDX + \ -+ TG3_64BIT_REG_LOW) -+#define MAILBOX_RCV_JUMBO_PROD_IDX 0x00000270 /* 64-bit */ -+#define TG3_RX_JMB_PROD_IDX_REG (MAILBOX_RCV_JUMBO_PROD_IDX + \ -+ TG3_64BIT_REG_LOW) -+#define MAILBOX_RCV_MINI_PROD_IDX 0x00000278 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_0 0x00000280 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_1 0x00000288 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_2 0x00000290 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_3 0x00000298 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_4 0x000002a0 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_5 0x000002a8 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_6 0x000002b0 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_7 0x000002b8 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_8 0x000002c0 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_9 0x000002c8 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_10 0x000002d0 /* 64-bit */ -+#define MAILBOX_RCV_JUMBO_PROD_IDX_RING1 0x000002d4 /* 32-bit */ -+#define MAILBOX_RCVRET_CON_IDX_11 0x000002d8 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_12 0x000002e0 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_13 0x000002e8 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_14 0x000002f0 /* 64-bit */ -+#define MAILBOX_RCVRET_CON_IDX_15 0x000002f8 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_0 0x00000300 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_1 0x00000308 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_2 0x00000310 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_3 0x00000318 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_4 0x00000320 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_5 0x00000328 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_6 0x00000330 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_7 0x00000338 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_8 0x00000340 /* 64-bit */ -+#define MAILBOX_RCV_JMB_PROD_IDX_RING12 0x00000340 /* 32-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_9 0x00000348 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_10 0x00000350 /* 64-bit */ -+#define MAILBOX_RCV_STD_PROD_IDX_RING1 0x00000354 /* 32-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_11 0x00000358 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_12 0x00000360 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_13 0x00000368 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_14 0x00000370 /* 64-bit */ -+#define MAILBOX_SNDHOST_PROD_IDX_15 0x00000378 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_0 0x00000380 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_1 0x00000388 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_2 0x00000390 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_3 0x00000398 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_4 0x000003a0 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_5 0x000003a8 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_6 0x000003b0 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_7 0x000003b8 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_8 0x000003c0 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_9 0x000003c8 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_10 0x000003d0 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_11 0x000003d8 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_12 0x000003e0 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_13 0x000003e8 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_14 0x000003f0 /* 64-bit */ -+#define MAILBOX_SNDNIC_PROD_IDX_15 0x000003f8 /* 64-bit */ -+ -+/* MAC control registers */ -+#define MAC_MODE 0x00000400 -+#define MAC_MODE_RESET 0x00000001 -+#define MAC_MODE_HALF_DUPLEX 0x00000002 -+#define MAC_MODE_PORT_MODE_MASK 0x0000000c -+#define MAC_MODE_PORT_MODE_TBI 0x0000000c -+#define MAC_MODE_PORT_MODE_GMII 0x00000008 -+#define MAC_MODE_PORT_MODE_MII 0x00000004 -+#define MAC_MODE_PORT_MODE_NONE 0x00000000 -+#define MAC_MODE_PORT_INT_LPBACK 0x00000010 -+#define MAC_MODE_TAGGED_MAC_CTRL 0x00000080 -+#define MAC_MODE_TX_BURSTING 0x00000100 -+#define MAC_MODE_MAX_DEFER 0x00000200 -+#define MAC_MODE_LINK_POLARITY 0x00000400 -+#define MAC_MODE_RXSTAT_ENABLE 0x00000800 -+#define MAC_MODE_RXSTAT_CLEAR 0x00001000 -+#define MAC_MODE_RXSTAT_FLUSH 0x00002000 -+#define MAC_MODE_TXSTAT_ENABLE 0x00004000 -+#define MAC_MODE_TXSTAT_CLEAR 0x00008000 -+#define MAC_MODE_TXSTAT_FLUSH 0x00010000 -+#define MAC_MODE_SEND_CONFIGS 0x00020000 -+#define MAC_MODE_MAGIC_PKT_ENABLE 0x00040000 -+#define MAC_MODE_ACPI_ENABLE 0x00080000 -+#define MAC_MODE_MIP_ENABLE 0x00100000 -+#define MAC_MODE_TDE_ENABLE 0x00200000 -+#define MAC_MODE_RDE_ENABLE 0x00400000 -+#define MAC_MODE_FHDE_ENABLE 0x00800000 -+#define MAC_MODE_KEEP_FRAME_IN_WOL 0x01000000 -+#define MAC_MODE_APE_RX_EN 0x08000000 -+#define MAC_MODE_APE_TX_EN 0x10000000 -+#define MAC_STATUS 0x00000404 -+#define MAC_STATUS_PCS_SYNCED 0x00000001 -+#define MAC_STATUS_SIGNAL_DET 0x00000002 -+#define MAC_STATUS_RCVD_CFG 0x00000004 -+#define MAC_STATUS_CFG_CHANGED 0x00000008 -+#define MAC_STATUS_SYNC_CHANGED 0x00000010 -+#define MAC_STATUS_PORT_DEC_ERR 0x00000400 -+#define MAC_STATUS_LNKSTATE_CHANGED 0x00001000 -+#define MAC_STATUS_MI_COMPLETION 0x00400000 -+#define MAC_STATUS_MI_INTERRUPT 0x00800000 -+#define MAC_STATUS_AP_ERROR 0x01000000 -+#define MAC_STATUS_ODI_ERROR 0x02000000 -+#define MAC_STATUS_RXSTAT_OVERRUN 0x04000000 -+#define MAC_STATUS_TXSTAT_OVERRUN 0x08000000 -+#define MAC_EVENT 0x00000408 -+#define MAC_EVENT_PORT_DECODE_ERR 0x00000400 -+#define MAC_EVENT_LNKSTATE_CHANGED 0x00001000 -+#define MAC_EVENT_MI_COMPLETION 0x00400000 -+#define MAC_EVENT_MI_INTERRUPT 0x00800000 -+#define MAC_EVENT_AP_ERROR 0x01000000 -+#define MAC_EVENT_ODI_ERROR 0x02000000 -+#define MAC_EVENT_RXSTAT_OVERRUN 0x04000000 -+#define MAC_EVENT_TXSTAT_OVERRUN 0x08000000 -+#define MAC_LED_CTRL 0x0000040c -+#define LED_CTRL_LNKLED_OVERRIDE 0x00000001 -+#define LED_CTRL_1000MBPS_ON 0x00000002 -+#define LED_CTRL_100MBPS_ON 0x00000004 -+#define LED_CTRL_10MBPS_ON 0x00000008 -+#define LED_CTRL_TRAFFIC_OVERRIDE 0x00000010 -+#define LED_CTRL_TRAFFIC_BLINK 0x00000020 -+#define LED_CTRL_TRAFFIC_LED 0x00000040 -+#define LED_CTRL_1000MBPS_STATUS 0x00000080 -+#define LED_CTRL_100MBPS_STATUS 0x00000100 -+#define LED_CTRL_10MBPS_STATUS 0x00000200 -+#define LED_CTRL_TRAFFIC_STATUS 0x00000400 -+#define LED_CTRL_MODE_MAC 0x00000000 -+#define LED_CTRL_MODE_PHY_1 0x00000800 -+#define LED_CTRL_MODE_PHY_2 0x00001000 -+#define LED_CTRL_MODE_SHASTA_MAC 0x00002000 -+#define LED_CTRL_MODE_SHARED 0x00004000 -+#define LED_CTRL_MODE_COMBO 0x00008000 -+#define LED_CTRL_BLINK_RATE_MASK 0x7ff80000 -+#define LED_CTRL_BLINK_RATE_SHIFT 19 -+#define LED_CTRL_BLINK_PER_OVERRIDE 0x00080000 -+#define LED_CTRL_BLINK_RATE_OVERRIDE 0x80000000 -+#define MAC_ADDR_0_HIGH 0x00000410 /* upper 2 bytes */ -+#define MAC_ADDR_0_LOW 0x00000414 /* lower 4 bytes */ -+#define MAC_ADDR_1_HIGH 0x00000418 /* upper 2 bytes */ -+#define MAC_ADDR_1_LOW 0x0000041c /* lower 4 bytes */ -+#define MAC_ADDR_2_HIGH 0x00000420 /* upper 2 bytes */ -+#define MAC_ADDR_2_LOW 0x00000424 /* lower 4 bytes */ -+#define MAC_ADDR_3_HIGH 0x00000428 /* upper 2 bytes */ -+#define MAC_ADDR_3_LOW 0x0000042c /* lower 4 bytes */ -+#define MAC_ACPI_MBUF_PTR 0x00000430 -+#define MAC_ACPI_LEN_OFFSET 0x00000434 -+#define ACPI_LENOFF_LEN_MASK 0x0000ffff -+#define ACPI_LENOFF_LEN_SHIFT 0 -+#define ACPI_LENOFF_OFF_MASK 0x0fff0000 -+#define ACPI_LENOFF_OFF_SHIFT 16 -+#define MAC_TX_BACKOFF_SEED 0x00000438 -+#define TX_BACKOFF_SEED_MASK 0x000003ff -+#define MAC_RX_MTU_SIZE 0x0000043c -+#define RX_MTU_SIZE_MASK 0x0000ffff -+#define MAC_PCS_TEST 0x00000440 -+#define PCS_TEST_PATTERN_MASK 0x000fffff -+#define PCS_TEST_PATTERN_SHIFT 0 -+#define PCS_TEST_ENABLE 0x00100000 -+#define MAC_TX_AUTO_NEG 0x00000444 -+#define TX_AUTO_NEG_MASK 0x0000ffff -+#define TX_AUTO_NEG_SHIFT 0 -+#define MAC_RX_AUTO_NEG 0x00000448 -+#define RX_AUTO_NEG_MASK 0x0000ffff -+#define RX_AUTO_NEG_SHIFT 0 -+#define MAC_MI_COM 0x0000044c -+#define MI_COM_CMD_MASK 0x0c000000 -+#define MI_COM_CMD_WRITE 0x04000000 -+#define MI_COM_CMD_READ 0x08000000 -+#define MI_COM_READ_FAILED 0x10000000 -+#define MI_COM_START 0x20000000 -+#define MI_COM_BUSY 0x20000000 -+#define MI_COM_PHY_ADDR_MASK 0x03e00000 -+#define MI_COM_PHY_ADDR_SHIFT 21 -+#define MI_COM_REG_ADDR_MASK 0x001f0000 -+#define MI_COM_REG_ADDR_SHIFT 16 -+#define MI_COM_DATA_MASK 0x0000ffff -+#define MAC_MI_STAT 0x00000450 -+#define MAC_MI_STAT_LNKSTAT_ATTN_ENAB 0x00000001 -+#define MAC_MI_STAT_10MBPS_MODE 0x00000002 -+#define MAC_MI_MODE 0x00000454 -+#define MAC_MI_MODE_CLK_10MHZ 0x00000001 -+#define MAC_MI_MODE_SHORT_PREAMBLE 0x00000002 -+#define MAC_MI_MODE_AUTO_POLL 0x00000010 -+#define MAC_MI_MODE_500KHZ_CONST 0x00008000 -+#define MAC_MI_MODE_BASE 0x000c0000 /* XXX magic values XXX */ -+#define MAC_AUTO_POLL_STATUS 0x00000458 -+#define MAC_AUTO_POLL_ERROR 0x00000001 -+#define MAC_TX_MODE 0x0000045c -+#define TX_MODE_RESET 0x00000001 -+#define TX_MODE_ENABLE 0x00000002 -+#define TX_MODE_FLOW_CTRL_ENABLE 0x00000010 -+#define TX_MODE_BIG_BCKOFF_ENABLE 0x00000020 -+#define TX_MODE_LONG_PAUSE_ENABLE 0x00000040 -+#define TX_MODE_MBUF_LOCKUP_FIX 0x00000100 -+#define TX_MODE_JMB_FRM_LEN 0x00400000 -+#define TX_MODE_CNT_DN_MODE 0x00800000 -+#define MAC_TX_STATUS 0x00000460 -+#define TX_STATUS_XOFFED 0x00000001 -+#define TX_STATUS_SENT_XOFF 0x00000002 -+#define TX_STATUS_SENT_XON 0x00000004 -+#define TX_STATUS_LINK_UP 0x00000008 -+#define TX_STATUS_ODI_UNDERRUN 0x00000010 -+#define TX_STATUS_ODI_OVERRUN 0x00000020 -+#define MAC_TX_LENGTHS 0x00000464 -+#define TX_LENGTHS_SLOT_TIME_MASK 0x000000ff -+#define TX_LENGTHS_SLOT_TIME_SHIFT 0 -+#define TX_LENGTHS_IPG_MASK 0x00000f00 -+#define TX_LENGTHS_IPG_SHIFT 8 -+#define TX_LENGTHS_IPG_CRS_MASK 0x00003000 -+#define TX_LENGTHS_IPG_CRS_SHIFT 12 -+#define TX_LENGTHS_JMB_FRM_LEN_MSK 0x00ff0000 -+#define TX_LENGTHS_CNT_DWN_VAL_MSK 0xff000000 -+#define MAC_RX_MODE 0x00000468 -+#define RX_MODE_RESET 0x00000001 -+#define RX_MODE_ENABLE 0x00000002 -+#define RX_MODE_FLOW_CTRL_ENABLE 0x00000004 -+#define RX_MODE_KEEP_MAC_CTRL 0x00000008 -+#define RX_MODE_KEEP_PAUSE 0x00000010 -+#define RX_MODE_ACCEPT_OVERSIZED 0x00000020 -+#define RX_MODE_ACCEPT_RUNTS 0x00000040 -+#define RX_MODE_LEN_CHECK 0x00000080 -+#define RX_MODE_PROMISC 0x00000100 -+#define RX_MODE_NO_CRC_CHECK 0x00000200 -+#define RX_MODE_KEEP_VLAN_TAG 0x00000400 -+#define RX_MODE_RSS_IPV4_HASH_EN 0x00010000 -+#define RX_MODE_RSS_TCP_IPV4_HASH_EN 0x00020000 -+#define RX_MODE_RSS_IPV6_HASH_EN 0x00040000 -+#define RX_MODE_RSS_TCP_IPV6_HASH_EN 0x00080000 -+#define RX_MODE_RSS_ITBL_HASH_BITS_7 0x00700000 -+#define RX_MODE_RSS_ENABLE 0x00800000 -+#define RX_MODE_IPV6_CSUM_ENABLE 0x01000000 -+#define RX_MODE_IPV4_FRAG_FIX 0x02000000 -+#define MAC_RX_STATUS 0x0000046c -+#define RX_STATUS_REMOTE_TX_XOFFED 0x00000001 -+#define RX_STATUS_XOFF_RCVD 0x00000002 -+#define RX_STATUS_XON_RCVD 0x00000004 -+#define MAC_HASH_REG_0 0x00000470 -+#define MAC_HASH_REG_1 0x00000474 -+#define MAC_HASH_REG_2 0x00000478 -+#define MAC_HASH_REG_3 0x0000047c -+#define MAC_RCV_RULE_0 0x00000480 -+#define MAC_RCV_VALUE_0 0x00000484 -+#define MAC_RCV_RULE_1 0x00000488 -+#define MAC_RCV_VALUE_1 0x0000048c -+#define MAC_RCV_RULE_2 0x00000490 -+#define MAC_RCV_VALUE_2 0x00000494 -+#define MAC_RCV_RULE_3 0x00000498 -+#define MAC_RCV_VALUE_3 0x0000049c -+#define MAC_RCV_RULE_4 0x000004a0 -+#define MAC_RCV_VALUE_4 0x000004a4 -+#define MAC_RCV_RULE_5 0x000004a8 -+#define MAC_RCV_VALUE_5 0x000004ac -+#define MAC_RCV_RULE_6 0x000004b0 -+#define MAC_RCV_VALUE_6 0x000004b4 -+#define MAC_RCV_RULE_7 0x000004b8 -+#define MAC_RCV_VALUE_7 0x000004bc -+#define MAC_RCV_RULE_8 0x000004c0 -+#define MAC_RCV_VALUE_8 0x000004c4 -+#define MAC_RCV_RULE_9 0x000004c8 -+#define MAC_RCV_VALUE_9 0x000004cc -+#define MAC_RCV_RULE_10 0x000004d0 -+#define MAC_RCV_VALUE_10 0x000004d4 -+#define MAC_RCV_RULE_11 0x000004d8 -+#define MAC_RCV_VALUE_11 0x000004dc -+#define MAC_RCV_RULE_12 0x000004e0 -+#define MAC_RCV_VALUE_12 0x000004e4 -+#define MAC_RCV_RULE_13 0x000004e8 -+#define MAC_RCV_VALUE_13 0x000004ec -+#define MAC_RCV_RULE_14 0x000004f0 -+#define MAC_RCV_VALUE_14 0x000004f4 -+#define MAC_RCV_RULE_15 0x000004f8 -+#define MAC_RCV_VALUE_15 0x000004fc -+#define RCV_RULE_DISABLE_MASK 0x7fffffff -+#define MAC_RCV_RULE_CFG 0x00000500 -+#define RCV_RULE_CFG_DEFAULT_CLASS 0x00000008 -+#define MAC_LOW_WMARK_MAX_RX_FRAME 0x00000504 -+/* 0x508 --> 0x520 unused */ -+#define MAC_HASHREGU_0 0x00000520 -+#define MAC_HASHREGU_1 0x00000524 -+#define MAC_HASHREGU_2 0x00000528 -+#define MAC_HASHREGU_3 0x0000052c -+#define MAC_EXTADDR_0_HIGH 0x00000530 -+#define MAC_EXTADDR_0_LOW 0x00000534 -+#define MAC_EXTADDR_1_HIGH 0x00000538 -+#define MAC_EXTADDR_1_LOW 0x0000053c -+#define MAC_EXTADDR_2_HIGH 0x00000540 -+#define MAC_EXTADDR_2_LOW 0x00000544 -+#define MAC_EXTADDR_3_HIGH 0x00000548 -+#define MAC_EXTADDR_3_LOW 0x0000054c -+#define MAC_EXTADDR_4_HIGH 0x00000550 -+#define MAC_EXTADDR_4_LOW 0x00000554 -+#define MAC_EXTADDR_5_HIGH 0x00000558 -+#define MAC_EXTADDR_5_LOW 0x0000055c -+#define MAC_EXTADDR_6_HIGH 0x00000560 -+#define MAC_VRQ_ENABLE 0x00000560 -+#define MAC_VRQ_ENABLE_DFLT_VRQ 0x00000001 -+#define MAC_EXTADDR_6_LOW 0x00000564 -+#define MAC_EXTADDR_7_HIGH 0x00000568 -+#define MAC_EXTADDR_7_LOW 0x0000056c -+#define MAC_EXTADDR_8_HIGH 0x00000570 -+#define MAC_EXTADDR_8_LOW 0x00000574 -+#define MAC_EXTADDR_9_HIGH 0x00000578 -+#define MAC_EXTADDR_9_LOW 0x0000057c -+#define MAC_EXTADDR_10_HIGH 0x00000580 -+#define MAC_EXTADDR_10_LOW 0x00000584 -+#define MAC_EXTADDR_11_HIGH 0x00000588 -+#define MAC_EXTADDR_11_LOW 0x0000058c -+#define MAC_SERDES_CFG 0x00000590 -+#define MAC_SERDES_CFG_EDGE_SELECT 0x00001000 -+#define MAC_SERDES_STAT 0x00000594 -+/* 0x598 --> 0x5a0 unused */ -+#define MAC_PHYCFG1 0x000005a0 -+#define MAC_PHYCFG1_RGMII_INT 0x00000001 -+#define MAC_PHYCFG1_RXCLK_TO_MASK 0x00001ff0 -+#define MAC_PHYCFG1_RXCLK_TIMEOUT 0x00001000 -+#define MAC_PHYCFG1_TXCLK_TO_MASK 0x01ff0000 -+#define MAC_PHYCFG1_TXCLK_TIMEOUT 0x01000000 -+#define MAC_PHYCFG1_RGMII_EXT_RX_DEC 0x02000000 -+#define MAC_PHYCFG1_RGMII_SND_STAT_EN 0x04000000 -+#define MAC_PHYCFG1_TXC_DRV 0x20000000 -+#define MAC_PHYCFG2 0x000005a4 -+#define MAC_PHYCFG2_INBAND_ENABLE 0x00000001 -+#define MAC_PHYCFG2_EMODE_MASK_MASK 0x000001c0 -+#define MAC_PHYCFG2_EMODE_MASK_AC131 0x000000c0 -+#define MAC_PHYCFG2_EMODE_MASK_50610 0x00000100 -+#define MAC_PHYCFG2_EMODE_MASK_RT8211 0x00000000 -+#define MAC_PHYCFG2_EMODE_MASK_RT8201 0x000001c0 -+#define MAC_PHYCFG2_EMODE_COMP_MASK 0x00000e00 -+#define MAC_PHYCFG2_EMODE_COMP_AC131 0x00000600 -+#define MAC_PHYCFG2_EMODE_COMP_50610 0x00000400 -+#define MAC_PHYCFG2_EMODE_COMP_RT8211 0x00000800 -+#define MAC_PHYCFG2_EMODE_COMP_RT8201 0x00000000 -+#define MAC_PHYCFG2_FMODE_MASK_MASK 0x00007000 -+#define MAC_PHYCFG2_FMODE_MASK_AC131 0x00006000 -+#define MAC_PHYCFG2_FMODE_MASK_50610 0x00004000 -+#define MAC_PHYCFG2_FMODE_MASK_RT8211 0x00000000 -+#define MAC_PHYCFG2_FMODE_MASK_RT8201 0x00007000 -+#define MAC_PHYCFG2_FMODE_COMP_MASK 0x00038000 -+#define MAC_PHYCFG2_FMODE_COMP_AC131 0x00030000 -+#define MAC_PHYCFG2_FMODE_COMP_50610 0x00008000 -+#define MAC_PHYCFG2_FMODE_COMP_RT8211 0x00038000 -+#define MAC_PHYCFG2_FMODE_COMP_RT8201 0x00000000 -+#define MAC_PHYCFG2_GMODE_MASK_MASK 0x001c0000 -+#define MAC_PHYCFG2_GMODE_MASK_AC131 0x001c0000 -+#define MAC_PHYCFG2_GMODE_MASK_50610 0x00100000 -+#define MAC_PHYCFG2_GMODE_MASK_RT8211 0x00000000 -+#define MAC_PHYCFG2_GMODE_MASK_RT8201 0x001c0000 -+#define MAC_PHYCFG2_GMODE_COMP_MASK 0x00e00000 -+#define MAC_PHYCFG2_GMODE_COMP_AC131 0x00e00000 -+#define MAC_PHYCFG2_GMODE_COMP_50610 0x00000000 -+#define MAC_PHYCFG2_GMODE_COMP_RT8211 0x00200000 -+#define MAC_PHYCFG2_GMODE_COMP_RT8201 0x00000000 -+#define MAC_PHYCFG2_ACT_MASK_MASK 0x03000000 -+#define MAC_PHYCFG2_ACT_MASK_AC131 0x03000000 -+#define MAC_PHYCFG2_ACT_MASK_50610 0x01000000 -+#define MAC_PHYCFG2_ACT_MASK_RT8211 0x03000000 -+#define MAC_PHYCFG2_ACT_MASK_RT8201 0x01000000 -+#define MAC_PHYCFG2_ACT_COMP_MASK 0x0c000000 -+#define MAC_PHYCFG2_ACT_COMP_AC131 0x00000000 -+#define MAC_PHYCFG2_ACT_COMP_50610 0x00000000 -+#define MAC_PHYCFG2_ACT_COMP_RT8211 0x00000000 -+#define MAC_PHYCFG2_ACT_COMP_RT8201 0x08000000 -+#define MAC_PHYCFG2_QUAL_MASK_MASK 0x30000000 -+#define MAC_PHYCFG2_QUAL_MASK_AC131 0x30000000 -+#define MAC_PHYCFG2_QUAL_MASK_50610 0x30000000 -+#define MAC_PHYCFG2_QUAL_MASK_RT8211 0x30000000 -+#define MAC_PHYCFG2_QUAL_MASK_RT8201 0x30000000 -+#define MAC_PHYCFG2_QUAL_COMP_MASK 0xc0000000 -+#define MAC_PHYCFG2_QUAL_COMP_AC131 0x00000000 -+#define MAC_PHYCFG2_QUAL_COMP_50610 0x00000000 -+#define MAC_PHYCFG2_QUAL_COMP_RT8211 0x00000000 -+#define MAC_PHYCFG2_QUAL_COMP_RT8201 0x00000000 -+#define MAC_PHYCFG2_50610_LED_MODES \ -+ (MAC_PHYCFG2_EMODE_MASK_50610 | \ -+ MAC_PHYCFG2_EMODE_COMP_50610 | \ -+ MAC_PHYCFG2_FMODE_MASK_50610 | \ -+ MAC_PHYCFG2_FMODE_COMP_50610 | \ -+ MAC_PHYCFG2_GMODE_MASK_50610 | \ -+ MAC_PHYCFG2_GMODE_COMP_50610 | \ -+ MAC_PHYCFG2_ACT_MASK_50610 | \ -+ MAC_PHYCFG2_ACT_COMP_50610 | \ -+ MAC_PHYCFG2_QUAL_MASK_50610 | \ -+ MAC_PHYCFG2_QUAL_COMP_50610) -+#define MAC_PHYCFG2_AC131_LED_MODES \ -+ (MAC_PHYCFG2_EMODE_MASK_AC131 | \ -+ MAC_PHYCFG2_EMODE_COMP_AC131 | \ -+ MAC_PHYCFG2_FMODE_MASK_AC131 | \ -+ MAC_PHYCFG2_FMODE_COMP_AC131 | \ -+ MAC_PHYCFG2_GMODE_MASK_AC131 | \ -+ MAC_PHYCFG2_GMODE_COMP_AC131 | \ -+ MAC_PHYCFG2_ACT_MASK_AC131 | \ -+ MAC_PHYCFG2_ACT_COMP_AC131 | \ -+ MAC_PHYCFG2_QUAL_MASK_AC131 | \ -+ MAC_PHYCFG2_QUAL_COMP_AC131) -+#define MAC_PHYCFG2_RTL8211C_LED_MODES \ -+ (MAC_PHYCFG2_EMODE_MASK_RT8211 | \ -+ MAC_PHYCFG2_EMODE_COMP_RT8211 | \ -+ MAC_PHYCFG2_FMODE_MASK_RT8211 | \ -+ MAC_PHYCFG2_FMODE_COMP_RT8211 | \ -+ MAC_PHYCFG2_GMODE_MASK_RT8211 | \ -+ MAC_PHYCFG2_GMODE_COMP_RT8211 | \ -+ MAC_PHYCFG2_ACT_MASK_RT8211 | \ -+ MAC_PHYCFG2_ACT_COMP_RT8211 | \ -+ MAC_PHYCFG2_QUAL_MASK_RT8211 | \ -+ MAC_PHYCFG2_QUAL_COMP_RT8211) -+#define MAC_PHYCFG2_RTL8201E_LED_MODES \ -+ (MAC_PHYCFG2_EMODE_MASK_RT8201 | \ -+ MAC_PHYCFG2_EMODE_COMP_RT8201 | \ -+ MAC_PHYCFG2_FMODE_MASK_RT8201 | \ -+ MAC_PHYCFG2_FMODE_COMP_RT8201 | \ -+ MAC_PHYCFG2_GMODE_MASK_RT8201 | \ -+ MAC_PHYCFG2_GMODE_COMP_RT8201 | \ -+ MAC_PHYCFG2_ACT_MASK_RT8201 | \ -+ MAC_PHYCFG2_ACT_COMP_RT8201 | \ -+ MAC_PHYCFG2_QUAL_MASK_RT8201 | \ -+ MAC_PHYCFG2_QUAL_COMP_RT8201) -+#define MAC_EXT_RGMII_MODE 0x000005a8 -+#define MAC_RGMII_MODE_TX_ENABLE 0x00000001 -+#define MAC_RGMII_MODE_TX_LOWPWR 0x00000002 -+#define MAC_RGMII_MODE_TX_RESET 0x00000004 -+#define MAC_RGMII_MODE_RX_INT_B 0x00000100 -+#define MAC_RGMII_MODE_RX_QUALITY 0x00000200 -+#define MAC_RGMII_MODE_RX_ACTIVITY 0x00000400 -+#define MAC_RGMII_MODE_RX_ENG_DET 0x00000800 -+/* 0x5ac --> 0x5b0 unused */ -+#define SERDES_RX_CTRL 0x000005b0 /* 5780/5714 only */ -+#define SERDES_RX_SIG_DETECT 0x00000400 -+#define SG_DIG_CTRL 0x000005b0 -+#define SG_DIG_USING_HW_AUTONEG 0x80000000 -+#define SG_DIG_SOFT_RESET 0x40000000 -+#define SG_DIG_DISABLE_LINKRDY 0x20000000 -+#define SG_DIG_CRC16_CLEAR_N 0x01000000 -+#define SG_DIG_EN10B 0x00800000 -+#define SG_DIG_CLEAR_STATUS 0x00400000 -+#define SG_DIG_LOCAL_DUPLEX_STATUS 0x00200000 -+#define SG_DIG_LOCAL_LINK_STATUS 0x00100000 -+#define SG_DIG_SPEED_STATUS_MASK 0x000c0000 -+#define SG_DIG_SPEED_STATUS_SHIFT 18 -+#define SG_DIG_JUMBO_PACKET_DISABLE 0x00020000 -+#define SG_DIG_RESTART_AUTONEG 0x00010000 -+#define SG_DIG_FIBER_MODE 0x00008000 -+#define SG_DIG_REMOTE_FAULT_MASK 0x00006000 -+#define SG_DIG_PAUSE_MASK 0x00001800 -+#define SG_DIG_PAUSE_CAP 0x00000800 -+#define SG_DIG_ASYM_PAUSE 0x00001000 -+#define SG_DIG_GBIC_ENABLE 0x00000400 -+#define SG_DIG_CHECK_END_ENABLE 0x00000200 -+#define SG_DIG_SGMII_AUTONEG_TIMER 0x00000100 -+#define SG_DIG_CLOCK_PHASE_SELECT 0x00000080 -+#define SG_DIG_GMII_INPUT_SELECT 0x00000040 -+#define SG_DIG_MRADV_CRC16_SELECT 0x00000020 -+#define SG_DIG_COMMA_DETECT_ENABLE 0x00000010 -+#define SG_DIG_AUTONEG_TIMER_REDUCE 0x00000008 -+#define SG_DIG_AUTONEG_LOW_ENABLE 0x00000004 -+#define SG_DIG_REMOTE_LOOPBACK 0x00000002 -+#define SG_DIG_LOOPBACK 0x00000001 -+#define SG_DIG_COMMON_SETUP (SG_DIG_CRC16_CLEAR_N | \ -+ SG_DIG_LOCAL_DUPLEX_STATUS | \ -+ SG_DIG_LOCAL_LINK_STATUS | \ -+ (0x2 << SG_DIG_SPEED_STATUS_SHIFT) | \ -+ SG_DIG_FIBER_MODE | SG_DIG_GBIC_ENABLE) -+#define SG_DIG_STATUS 0x000005b4 -+#define SG_DIG_CRC16_BUS_MASK 0xffff0000 -+#define SG_DIG_PARTNER_FAULT_MASK 0x00600000 /* If !MRADV_CRC16_SELECT */ -+#define SG_DIG_PARTNER_ASYM_PAUSE 0x00100000 /* If !MRADV_CRC16_SELECT */ -+#define SG_DIG_PARTNER_PAUSE_CAPABLE 0x00080000 /* If !MRADV_CRC16_SELECT */ -+#define SG_DIG_PARTNER_HALF_DUPLEX 0x00040000 /* If !MRADV_CRC16_SELECT */ -+#define SG_DIG_PARTNER_FULL_DUPLEX 0x00020000 /* If !MRADV_CRC16_SELECT */ -+#define SG_DIG_PARTNER_NEXT_PAGE 0x00010000 /* If !MRADV_CRC16_SELECT */ -+#define SG_DIG_AUTONEG_STATE_MASK 0x00000ff0 -+#define SG_DIG_IS_SERDES 0x00000100 -+#define SG_DIG_COMMA_DETECTOR 0x00000008 -+#define SG_DIG_MAC_ACK_STATUS 0x00000004 -+#define SG_DIG_AUTONEG_COMPLETE 0x00000002 -+#define SG_DIG_AUTONEG_ERROR 0x00000001 -+#define TG3_TX_TSTAMP_LSB 0x000005c0 -+#define TG3_TX_TSTAMP_MSB 0x000005c4 -+#define TG3_TSTAMP_MASK 0x7fffffffffffffff -+/* 0x5c8 --> 0x600 unused */ -+#define MAC_TX_MAC_STATE_BASE 0x00000600 /* 16 bytes */ -+#define MAC_RX_MAC_STATE_BASE 0x00000610 /* 20 bytes */ -+/* 0x624 --> 0x670 unused */ -+ -+#define MAC_RSS_INDIR_TBL_0 0x00000630 -+ -+#define MAC_RSS_HASH_KEY_0 0x00000670 -+#define MAC_RSS_HASH_KEY_1 0x00000674 -+#define MAC_RSS_HASH_KEY_2 0x00000678 -+#define MAC_RSS_HASH_KEY_3 0x0000067c -+#define MAC_RSS_HASH_KEY_4 0x00000680 -+#define MAC_RSS_HASH_KEY_5 0x00000684 -+#define MAC_RSS_HASH_KEY_6 0x00000688 -+#define MAC_RSS_HASH_KEY_7 0x0000068c -+#define MAC_RSS_HASH_KEY_8 0x00000690 -+#define MAC_RSS_HASH_KEY_9 0x00000694 -+/* 0x698 --> 0x6b0 unused */ -+ -+#define TG3_RX_TSTAMP_LSB 0x000006b0 -+#define TG3_RX_TSTAMP_MSB 0x000006b4 -+/* 0x6b8 --> 0x6c8 unused */ -+ -+#define TG3_RX_PTP_CTL 0x000006c8 -+#define TG3_RX_PTP_CTL_SYNC_EVNT 0x00000001 -+#define TG3_RX_PTP_CTL_DELAY_REQ 0x00000002 -+#define TG3_RX_PTP_CTL_PDLAY_REQ 0x00000004 -+#define TG3_RX_PTP_CTL_PDLAY_RES 0x00000008 -+#define TG3_RX_PTP_CTL_ALL_V1_EVENTS (TG3_RX_PTP_CTL_SYNC_EVNT | \ -+ TG3_RX_PTP_CTL_DELAY_REQ) -+#define TG3_RX_PTP_CTL_ALL_V2_EVENTS (TG3_RX_PTP_CTL_SYNC_EVNT | \ -+ TG3_RX_PTP_CTL_DELAY_REQ | \ -+ TG3_RX_PTP_CTL_PDLAY_REQ | \ -+ TG3_RX_PTP_CTL_PDLAY_RES) -+#define TG3_RX_PTP_CTL_FOLLOW_UP 0x00000100 -+#define TG3_RX_PTP_CTL_DELAY_RES 0x00000200 -+#define TG3_RX_PTP_CTL_PDRES_FLW_UP 0x00000400 -+#define TG3_RX_PTP_CTL_ANNOUNCE 0x00000800 -+#define TG3_RX_PTP_CTL_SIGNALING 0x00001000 -+#define TG3_RX_PTP_CTL_MANAGEMENT 0x00002000 -+#define TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN 0x00800000 -+#define TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN 0x01000000 -+#define TG3_RX_PTP_CTL_RX_PTP_V2_EN (TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | \ -+ TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN) -+#define TG3_RX_PTP_CTL_RX_PTP_V1_EN 0x02000000 -+#define TG3_RX_PTP_CTL_HWTS_INTERLOCK 0x04000000 -+/* 0x6cc --> 0x800 unused */ -+ -+#define MAC_TX_STATS_OCTETS 0x00000800 -+#define MAC_TX_STATS_RESV1 0x00000804 -+#define MAC_TX_STATS_COLLISIONS 0x00000808 -+#define MAC_TX_STATS_XON_SENT 0x0000080c -+#define MAC_TX_STATS_XOFF_SENT 0x00000810 -+#define MAC_TX_STATS_RESV2 0x00000814 -+#define MAC_TX_STATS_MAC_ERRORS 0x00000818 -+#define MAC_TX_STATS_SINGLE_COLLISIONS 0x0000081c -+#define MAC_TX_STATS_MULT_COLLISIONS 0x00000820 -+#define MAC_TX_STATS_DEFERRED 0x00000824 -+#define MAC_TX_STATS_RESV3 0x00000828 -+#define MAC_TX_STATS_EXCESSIVE_COL 0x0000082c -+#define MAC_TX_STATS_LATE_COL 0x00000830 -+#define MAC_TX_STATS_RESV4_1 0x00000834 -+#define MAC_TX_STATS_RESV4_2 0x00000838 -+#define MAC_TX_STATS_RESV4_3 0x0000083c -+#define MAC_TX_STATS_RESV4_4 0x00000840 -+#define MAC_TX_STATS_RESV4_5 0x00000844 -+#define MAC_TX_STATS_RESV4_6 0x00000848 -+#define MAC_TX_STATS_RESV4_7 0x0000084c -+#define MAC_TX_STATS_RESV4_8 0x00000850 -+#define MAC_TX_STATS_RESV4_9 0x00000854 -+#define MAC_TX_STATS_RESV4_10 0x00000858 -+#define MAC_TX_STATS_RESV4_11 0x0000085c -+#define MAC_TX_STATS_RESV4_12 0x00000860 -+#define MAC_TX_STATS_RESV4_13 0x00000864 -+#define MAC_TX_STATS_RESV4_14 0x00000868 -+#define MAC_TX_STATS_UCAST 0x0000086c -+#define MAC_TX_STATS_MCAST 0x00000870 -+#define MAC_TX_STATS_BCAST 0x00000874 -+#define MAC_TX_STATS_RESV5_1 0x00000878 -+#define MAC_TX_STATS_RESV5_2 0x0000087c -+#define MAC_RX_STATS_OCTETS 0x00000880 -+#define MAC_RX_STATS_RESV1 0x00000884 -+#define MAC_RX_STATS_FRAGMENTS 0x00000888 -+#define MAC_RX_STATS_UCAST 0x0000088c -+#define MAC_RX_STATS_MCAST 0x00000890 -+#define MAC_RX_STATS_BCAST 0x00000894 -+#define MAC_RX_STATS_FCS_ERRORS 0x00000898 -+#define MAC_RX_STATS_ALIGN_ERRORS 0x0000089c -+#define MAC_RX_STATS_XON_PAUSE_RECVD 0x000008a0 -+#define MAC_RX_STATS_XOFF_PAUSE_RECVD 0x000008a4 -+#define MAC_RX_STATS_MAC_CTRL_RECVD 0x000008a8 -+#define MAC_RX_STATS_XOFF_ENTERED 0x000008ac -+#define MAC_RX_STATS_FRAME_TOO_LONG 0x000008b0 -+#define MAC_RX_STATS_JABBERS 0x000008b4 -+#define MAC_RX_STATS_UNDERSIZE 0x000008b8 -+/* 0x8bc --> 0xc00 unused */ -+ -+/* Send data initiator control registers */ -+#define SNDDATAI_MODE 0x00000c00 -+#define SNDDATAI_MODE_RESET 0x00000001 -+#define SNDDATAI_MODE_ENABLE 0x00000002 -+#define SNDDATAI_MODE_STAT_OFLOW_ENAB 0x00000004 -+#define SNDDATAI_STATUS 0x00000c04 -+#define SNDDATAI_STATUS_STAT_OFLOW 0x00000004 -+#define SNDDATAI_STATSCTRL 0x00000c08 -+#define SNDDATAI_SCTRL_ENABLE 0x00000001 -+#define SNDDATAI_SCTRL_FASTUPD 0x00000002 -+#define SNDDATAI_SCTRL_CLEAR 0x00000004 -+#define SNDDATAI_SCTRL_FLUSH 0x00000008 -+#define SNDDATAI_SCTRL_FORCE_ZERO 0x00000010 -+#define SNDDATAI_STATSENAB 0x00000c0c -+#define SNDDATAI_STATSINCMASK 0x00000c10 -+#define ISO_PKT_TX 0x00000c20 -+/* 0xc24 --> 0xc80 unused */ -+#define SNDDATAI_COS_CNT_0 0x00000c80 -+#define SNDDATAI_COS_CNT_1 0x00000c84 -+#define SNDDATAI_COS_CNT_2 0x00000c88 -+#define SNDDATAI_COS_CNT_3 0x00000c8c -+#define SNDDATAI_COS_CNT_4 0x00000c90 -+#define SNDDATAI_COS_CNT_5 0x00000c94 -+#define SNDDATAI_COS_CNT_6 0x00000c98 -+#define SNDDATAI_COS_CNT_7 0x00000c9c -+#define SNDDATAI_COS_CNT_8 0x00000ca0 -+#define SNDDATAI_COS_CNT_9 0x00000ca4 -+#define SNDDATAI_COS_CNT_10 0x00000ca8 -+#define SNDDATAI_COS_CNT_11 0x00000cac -+#define SNDDATAI_COS_CNT_12 0x00000cb0 -+#define SNDDATAI_COS_CNT_13 0x00000cb4 -+#define SNDDATAI_COS_CNT_14 0x00000cb8 -+#define SNDDATAI_COS_CNT_15 0x00000cbc -+#define SNDDATAI_DMA_RDQ_FULL_CNT 0x00000cc0 -+#define SNDDATAI_DMA_PRIO_RDQ_FULL_CNT 0x00000cc4 -+#define SNDDATAI_SDCQ_FULL_CNT 0x00000cc8 -+#define SNDDATAI_NICRNG_SSND_PIDX_CNT 0x00000ccc -+#define SNDDATAI_STATS_UPDATED_CNT 0x00000cd0 -+#define SNDDATAI_INTERRUPTS_CNT 0x00000cd4 -+#define SNDDATAI_AVOID_INTERRUPTS_CNT 0x00000cd8 -+#define SNDDATAI_SND_THRESH_HIT_CNT 0x00000cdc -+/* 0xce0 --> 0x1000 unused */ -+ -+/* Send data completion control registers */ -+#define SNDDATAC_MODE 0x00001000 -+#define SNDDATAC_MODE_RESET 0x00000001 -+#define SNDDATAC_MODE_ENABLE 0x00000002 -+#define SNDDATAC_MODE_CDELAY 0x00000010 -+/* 0x1004 --> 0x1400 unused */ -+ -+/* Send BD ring selector */ -+#define SNDBDS_MODE 0x00001400 -+#define SNDBDS_MODE_RESET 0x00000001 -+#define SNDBDS_MODE_ENABLE 0x00000002 -+#define SNDBDS_MODE_ATTN_ENABLE 0x00000004 -+#define SNDBDS_STATUS 0x00001404 -+#define SNDBDS_STATUS_ERROR_ATTN 0x00000004 -+#define SNDBDS_HWDIAG 0x00001408 -+/* 0x140c --> 0x1440 */ -+#define SNDBDS_SEL_CON_IDX_0 0x00001440 -+#define SNDBDS_SEL_CON_IDX_1 0x00001444 -+#define SNDBDS_SEL_CON_IDX_2 0x00001448 -+#define SNDBDS_SEL_CON_IDX_3 0x0000144c -+#define SNDBDS_SEL_CON_IDX_4 0x00001450 -+#define SNDBDS_SEL_CON_IDX_5 0x00001454 -+#define SNDBDS_SEL_CON_IDX_6 0x00001458 -+#define SNDBDS_SEL_CON_IDX_7 0x0000145c -+#define SNDBDS_SEL_CON_IDX_8 0x00001460 -+#define SNDBDS_SEL_CON_IDX_9 0x00001464 -+#define SNDBDS_SEL_CON_IDX_10 0x00001468 -+#define SNDBDS_SEL_CON_IDX_11 0x0000146c -+#define SNDBDS_SEL_CON_IDX_12 0x00001470 -+#define SNDBDS_SEL_CON_IDX_13 0x00001474 -+#define SNDBDS_SEL_CON_IDX_14 0x00001478 -+#define SNDBDS_SEL_CON_IDX_15 0x0000147c -+/* 0x1480 --> 0x1800 unused */ -+ -+/* Send BD initiator control registers */ -+#define SNDBDI_MODE 0x00001800 -+#define SNDBDI_MODE_RESET 0x00000001 -+#define SNDBDI_MODE_ENABLE 0x00000002 -+#define SNDBDI_MODE_ATTN_ENABLE 0x00000004 -+#define SNDBDI_MODE_MULTI_TXQ_EN 0x00000020 -+#define SNDBDI_STATUS 0x00001804 -+#define SNDBDI_STATUS_ERROR_ATTN 0x00000004 -+#define SNDBDI_IN_PROD_IDX_0 0x00001808 -+#define SNDBDI_IN_PROD_IDX_1 0x0000180c -+#define SNDBDI_IN_PROD_IDX_2 0x00001810 -+#define SNDBDI_IN_PROD_IDX_3 0x00001814 -+#define SNDBDI_IN_PROD_IDX_4 0x00001818 -+#define SNDBDI_IN_PROD_IDX_5 0x0000181c -+#define SNDBDI_IN_PROD_IDX_6 0x00001820 -+#define SNDBDI_IN_PROD_IDX_7 0x00001824 -+#define SNDBDI_IN_PROD_IDX_8 0x00001828 -+#define SNDBDI_IN_PROD_IDX_9 0x0000182c -+#define SNDBDI_IN_PROD_IDX_10 0x00001830 -+#define SNDBDI_IN_PROD_IDX_11 0x00001834 -+#define SNDBDI_IN_PROD_IDX_12 0x00001838 -+#define SNDBDI_IN_PROD_IDX_13 0x0000183c -+#define SNDBDI_IN_PROD_IDX_14 0x00001840 -+#define SNDBDI_IN_PROD_IDX_15 0x00001844 -+/* 0x1848 --> 0x1c00 unused */ -+ -+/* Send BD completion control registers */ -+#define SNDBDC_MODE 0x00001c00 -+#define SNDBDC_MODE_RESET 0x00000001 -+#define SNDBDC_MODE_ENABLE 0x00000002 -+#define SNDBDC_MODE_ATTN_ENABLE 0x00000004 -+/* 0x1c04 --> 0x2000 unused */ -+ -+/* Receive list placement control registers */ -+#define RCVLPC_MODE 0x00002000 -+#define RCVLPC_MODE_RESET 0x00000001 -+#define RCVLPC_MODE_ENABLE 0x00000002 -+#define RCVLPC_MODE_CLASS0_ATTN_ENAB 0x00000004 -+#define RCVLPC_MODE_MAPOOR_AATTN_ENAB 0x00000008 -+#define RCVLPC_MODE_STAT_OFLOW_ENAB 0x00000010 -+#define RCVLPC_STATUS 0x00002004 -+#define RCVLPC_STATUS_CLASS0 0x00000004 -+#define RCVLPC_STATUS_MAPOOR 0x00000008 -+#define RCVLPC_STATUS_STAT_OFLOW 0x00000010 -+#define RCVLPC_LOCK 0x00002008 -+#define RCVLPC_LOCK_REQ_MASK 0x0000ffff -+#define RCVLPC_LOCK_REQ_SHIFT 0 -+#define RCVLPC_LOCK_GRANT_MASK 0xffff0000 -+#define RCVLPC_LOCK_GRANT_SHIFT 16 -+#define RCVLPC_NON_EMPTY_BITS 0x0000200c -+#define RCVLPC_NON_EMPTY_BITS_MASK 0x0000ffff -+#define RCVLPC_CONFIG 0x00002010 -+#define RCVLPC_STATSCTRL 0x00002014 -+#define RCVLPC_STATSCTRL_ENABLE 0x00000001 -+#define RCVLPC_STATSCTRL_FASTUPD 0x00000002 -+#define RCVLPC_STATS_ENABLE 0x00002018 -+#define RCVLPC_STATSENAB_ASF_FIX 0x00000002 -+#define RCVLPC_STATSENAB_DACK_FIX 0x00040000 -+#define RCVLPC_STATSENAB_LNGBRST_RFIX 0x00400000 -+#define RCVLPC_STATS_INCMASK 0x0000201c -+/* 0x2020 --> 0x2100 unused */ -+#define RCVLPC_SELLST_BASE 0x00002100 /* 16 16-byte entries */ -+#define SELLST_TAIL 0x00000004 -+#define SELLST_CONT 0x00000008 -+#define SELLST_UNUSED 0x0000000c -+#define RCVLPC_COS_CNTL_BASE 0x00002200 /* 16 4-byte entries */ -+#define RCVLPC_DROP_FILTER_CNT 0x00002240 -+#define RCVLPC_DMA_WQ_FULL_CNT 0x00002244 -+#define RCVLPC_DMA_HIPRIO_WQ_FULL_CNT 0x00002248 -+#define RCVLPC_NO_RCV_BD_CNT 0x0000224c -+#define RCVLPC_IN_DISCARDS_CNT 0x00002250 -+#define RCVLPC_IN_ERRORS_CNT 0x00002254 -+#define RCVLPC_RCV_THRESH_HIT_CNT 0x00002258 -+/* 0x225c --> 0x2400 unused */ -+ -+/* Receive Data and Receive BD Initiator Control */ -+#define RCVDBDI_MODE 0x00002400 -+#define RCVDBDI_MODE_RESET 0x00000001 -+#define RCVDBDI_MODE_ENABLE 0x00000002 -+#define RCVDBDI_MODE_JUMBOBD_NEEDED 0x00000004 -+#define RCVDBDI_MODE_FRM_TOO_BIG 0x00000008 -+#define RCVDBDI_MODE_INV_RING_SZ 0x00000010 -+#define RCVDBDI_MODE_LRG_RING_SZ 0x00010000 -+#define RCVDBDI_STATUS 0x00002404 -+#define RCVDBDI_STATUS_JUMBOBD_NEEDED 0x00000004 -+#define RCVDBDI_STATUS_FRM_TOO_BIG 0x00000008 -+#define RCVDBDI_STATUS_INV_RING_SZ 0x00000010 -+#define RCVDBDI_SPLIT_FRAME_MINSZ 0x00002408 -+#define VRQ_STATUS 0x0000240c -+#define VRQ_FLUSH_CTRL 0x00002410 -+#define VRQ_FLUSH_ENABLE 0x00000001 -+#define VRQ_FLUSH_RESET_ENABLE 0x00000002 -+#define VRQ_FLUSH_STATUPDT_INT_ENABLE 0x00000004 -+#define VRQ_FLUSH_DISCARD_PKT_ENABLE 0x00000008 -+#define VRQ_FLUSH_SW_FLUSH 0x00000100 -+/* 0x2414 --> 0x2440 unused */ -+ -+#define RCVDBDI_JUMBO_BD 0x00002440 /* TG3_BDINFO_... */ -+#define RCVDBDI_STD_BD 0x00002450 /* TG3_BDINFO_... */ -+#define RCVDBDI_MINI_BD 0x00002460 /* TG3_BDINFO_... */ -+#define RCVDBDI_JUMBO_CON_IDX 0x00002470 -+#define RCVDBDI_STD_CON_IDX 0x00002474 -+#define RCVDBDI_MINI_CON_IDX 0x00002478 -+/* 0x247c --> 0x2480 unused */ -+#define RCVDBDI_BD_PROD_IDX_0 0x00002480 -+#define RCVDBDI_BD_PROD_IDX_1 0x00002484 -+#define RCVDBDI_BD_PROD_IDX_2 0x00002488 -+#define RCVDBDI_BD_PROD_IDX_3 0x0000248c -+#define RCVDBDI_BD_PROD_IDX_4 0x00002490 -+#define RCVDBDI_BD_PROD_IDX_5 0x00002494 -+#define RCVDBDI_BD_PROD_IDX_6 0x00002498 -+#define RCVDBDI_BD_PROD_IDX_7 0x0000249c -+#define RCVDBDI_BD_PROD_IDX_8 0x000024a0 -+#define RCVDBDI_BD_PROD_IDX_9 0x000024a4 -+#define RCVDBDI_BD_PROD_IDX_10 0x000024a8 -+#define RCVDBDI_BD_PROD_IDX_11 0x000024ac -+#define RCVDBDI_BD_PROD_IDX_12 0x000024b0 -+#define RCVDBDI_BD_PROD_IDX_13 0x000024b4 -+#define RCVDBDI_BD_PROD_IDX_14 0x000024b8 -+#define RCVDBDI_BD_PROD_IDX_15 0x000024bc -+#define RCVDBDI_HWDIAG 0x000024c0 -+/* 0x24c4 --> 0x2800 unused */ -+ -+#define RCVDBDI_JMB_BD_RING1 0x00002500 -+/* 0x2504 --> 0x2800 unused */ -+ -+/* Receive Data Completion Control */ -+#define RCVDCC_MODE 0x00002800 -+#define RCVDCC_MODE_RESET 0x00000001 -+#define RCVDCC_MODE_ENABLE 0x00000002 -+#define RCVDCC_MODE_ATTN_ENABLE 0x00000004 -+/* 0x2804 --> 0x2c00 unused */ -+ -+/* Receive BD Initiator Control Registers */ -+#define RCVBDI_MODE 0x00002c00 -+#define RCVBDI_MODE_RESET 0x00000001 -+#define RCVBDI_MODE_ENABLE 0x00000002 -+#define RCVBDI_MODE_RCB_ATTN_ENAB 0x00000004 -+#define RCVBDI_STATUS 0x00002c04 -+#define RCVBDI_STATUS_RCB_ATTN 0x00000004 -+#define RCVBDI_JUMBO_PROD_IDX 0x00002c08 -+#define RCVBDI_STD_PROD_IDX 0x00002c0c -+#define RCVBDI_MINI_PROD_IDX 0x00002c10 -+#define RCVBDI_MINI_THRESH 0x00002c14 -+#define RCVBDI_STD_THRESH 0x00002c18 -+#define RCVBDI_JUMBO_THRESH 0x00002c1c -+/* 0x2c20 --> 0x2d00 unused */ -+ -+#define STD_REPLENISH_LWM 0x00002d00 -+#define JMB_REPLENISH_LWM 0x00002d04 -+/* 0x2d08 --> 0x3000 unused */ -+ -+/* Receive BD Completion Control Registers */ -+#define RCVCC_MODE 0x00003000 -+#define RCVCC_MODE_RESET 0x00000001 -+#define RCVCC_MODE_ENABLE 0x00000002 -+#define RCVCC_MODE_ATTN_ENABLE 0x00000004 -+#define RCVCC_STATUS 0x00003004 -+#define RCVCC_STATUS_ERROR_ATTN 0x00000004 -+#define RCVCC_JUMP_PROD_IDX 0x00003008 -+#define RCVCC_STD_PROD_IDX 0x0000300c -+#define RCVCC_MINI_PROD_IDX 0x00003010 -+/* 0x3014 --> 0x3400 unused */ -+ -+/* Receive list selector control registers */ -+#define RCVLSC_MODE 0x00003400 -+#define RCVLSC_MODE_RESET 0x00000001 -+#define RCVLSC_MODE_ENABLE 0x00000002 -+#define RCVLSC_MODE_ATTN_ENABLE 0x00000004 -+#define RCVLSC_STATUS 0x00003404 -+#define RCVLSC_STATUS_ERROR_ATTN 0x00000004 -+/* 0x3408 --> 0x3600 unused */ -+ -+#define TG3_CPMU_DRV_STATUS 0x0000344c -+ -+/* CPMU registers */ -+#define TG3_CPMU_CTRL 0x00003600 -+#define CPMU_CTRL_LINK_IDLE_MODE 0x00000200 -+#define CPMU_CTRL_LINK_AWARE_MODE 0x00000400 -+#define CPMU_CTRL_LINK_SPEED_MODE 0x00004000 -+#define CPMU_CTRL_GPHY_10MB_RXONLY 0x00010000 -+#define TG3_CPMU_LSPD_10MB_CLK 0x00003604 -+#define CPMU_LSPD_10MB_MACCLK_MASK 0x001f0000 -+#define CPMU_LSPD_10MB_MACCLK_6_25 0x00130000 -+/* 0x3608 --> 0x360c unused */ -+ -+#define TG3_CPMU_LSPD_1000MB_CLK 0x0000360c -+#define CPMU_LSPD_1000MB_MACCLK_62_5 0x00000000 -+#define CPMU_LSPD_1000MB_MACCLK_12_5 0x00110000 -+#define CPMU_LSPD_1000MB_MACCLK_MASK 0x001f0000 -+#define TG3_CPMU_LNK_AWARE_PWRMD 0x00003610 -+#define CPMU_LNK_AWARE_MACCLK_MASK 0x001f0000 -+#define CPMU_LNK_AWARE_MACCLK_6_25 0x00130000 -+/* 0x3614 --> 0x361c unused */ -+ -+#define TG3_CPMU_HST_ACC 0x0000361c -+#define CPMU_HST_ACC_MACCLK_MASK 0x001f0000 -+#define CPMU_HST_ACC_MACCLK_6_25 0x00130000 -+/* 0x3620 --> 0x3630 unused */ -+ -+#define TG3_CPMU_CLCK_ORIDE 0x00003624 -+#define CPMU_CLCK_ORIDE_MAC_ORIDE_EN 0x80000000 -+ -+#define TG3_CPMU_CLCK_ORIDE_ENABLE 0x00003628 -+#define TG3_CPMU_MAC_ORIDE_ENABLE (1 << 13) -+ -+#define TG3_CPMU_STATUS 0x0000362c -+#define TG3_CPMU_STATUS_FMSK_5717 0x20000000 -+#define TG3_CPMU_STATUS_FMSK_5719 0xc0000000 -+#define TG3_CPMU_STATUS_FSHFT_5719 30 -+#define TG3_CPMU_STATUS_LINK_MASK 0x180000 -+ -+#define TG3_CPMU_CLCK_STAT 0x00003630 -+#define CPMU_CLCK_STAT_MAC_CLCK_MASK 0x001f0000 -+#define CPMU_CLCK_STAT_MAC_CLCK_62_5 0x00000000 -+#define CPMU_CLCK_STAT_MAC_CLCK_12_5 0x00110000 -+#define CPMU_CLCK_STAT_MAC_CLCK_6_25 0x00130000 -+/* 0x3634 --> 0x365c unused */ -+ -+#define TG3_CPMU_MUTEX_REQ 0x0000365c -+#define CPMU_MUTEX_REQ_DRIVER 0x00001000 -+#define TG3_CPMU_MUTEX_GNT 0x00003660 -+#define CPMU_MUTEX_GNT_DRIVER 0x00001000 -+#define TG3_CPMU_PHY_STRAP 0x00003664 -+#define TG3_CPMU_PHY_STRAP_IS_SERDES 0x00000020 -+#define TG3_CPMU_PADRNG_CTL 0x00003668 -+#define TG3_CPMU_PADRNG_CTL_RDIV2 0x00040000 -+/* 0x3664 --> 0x36b0 unused */ -+ -+#define TG3_CPMU_EEE_MODE 0x000036b0 -+#define TG3_CPMU_EEEMD_APE_TX_DET_EN 0x00000004 -+#define TG3_CPMU_EEEMD_ERLY_L1_XIT_DET 0x00000008 -+#define TG3_CPMU_EEEMD_SND_IDX_DET_EN 0x00000040 -+#define TG3_CPMU_EEEMD_LPI_ENABLE 0x00000080 -+#define TG3_CPMU_EEEMD_LPI_IN_TX 0x00000100 -+#define TG3_CPMU_EEEMD_LPI_IN_RX 0x00000200 -+#define TG3_CPMU_EEEMD_EEE_ENABLE 0x00100000 -+#define TG3_CPMU_EEE_DBTMR1 0x000036b4 -+#define TG3_CPMU_DBTMR1_PCIEXIT_2047US 0x07ff0000 -+#define TG3_CPMU_DBTMR1_LNKIDLE_2047US 0x000007ff -+#define TG3_CPMU_DBTMR1_LNKIDLE_MAX 0x0000ffff -+#define TG3_CPMU_EEE_DBTMR2 0x000036b8 -+#define TG3_CPMU_DBTMR2_APE_TX_2047US 0x07ff0000 -+#define TG3_CPMU_DBTMR2_TXIDXEQ_2047US 0x000007ff -+#define TG3_CPMU_EEE_LNKIDL_CTRL 0x000036bc -+#define TG3_CPMU_EEE_LNKIDL_PCIE_NL0 0x01000000 -+#define TG3_CPMU_EEE_LNKIDL_UART_IDL 0x00000004 -+#define TG3_CPMU_EEE_LNKIDL_APE_TX_MT 0x00000002 -+/* 0x36c0 --> 0x36d0 unused */ -+ -+#define TG3_CPMU_EEE_CTRL 0x000036d0 -+#define TG3_CPMU_EEE_CTRL_EXIT_16_5_US 0x0000019d -+#define TG3_CPMU_EEE_CTRL_EXIT_36_US 0x00000384 -+#define TG3_CPMU_EEE_CTRL_EXIT_20_1_US 0x000001f8 -+/* 0x36d4 --> 0x3800 unused */ -+ -+/* Mbuf cluster free registers */ -+#define MBFREE_MODE 0x00003800 -+#define MBFREE_MODE_RESET 0x00000001 -+#define MBFREE_MODE_ENABLE 0x00000002 -+#define MBFREE_STATUS 0x00003804 -+/* 0x3808 --> 0x3c00 unused */ -+ -+/* Host coalescing control registers */ -+#define HOSTCC_MODE 0x00003c00 -+#define HOSTCC_MODE_RESET 0x00000001 -+#define HOSTCC_MODE_ENABLE 0x00000002 -+#define HOSTCC_MODE_ATTN 0x00000004 -+#define HOSTCC_MODE_NOW 0x00000008 -+#define HOSTCC_MODE_FULL_STATUS 0x00000000 -+#define HOSTCC_MODE_64BYTE 0x00000080 -+#define HOSTCC_MODE_32BYTE 0x00000100 -+#define HOSTCC_MODE_CLRTICK_RXBD 0x00000200 -+#define HOSTCC_MODE_CLRTICK_TXBD 0x00000400 -+#define HOSTCC_MODE_NOINT_ON_NOW 0x00000800 -+#define HOSTCC_MODE_NOINT_ON_FORCE 0x00001000 -+#define HOSTCC_MODE_COAL_VEC1_NOW 0x00002000 -+#define HOSTCC_STATUS 0x00003c04 -+#define HOSTCC_STATUS_ERROR_ATTN 0x00000004 -+#define HOSTCC_RXCOL_TICKS 0x00003c08 -+#define LOW_RXCOL_TICKS 0x00000032 -+#if defined(__VMKLNX__) -+#define LOW_RXCOL_TICKS_CLRTCKS 0x00000012 -+#else -+#define LOW_RXCOL_TICKS_CLRTCKS 0x00000014 -+#endif -+#define DEFAULT_RXCOL_TICKS 0x00000048 -+#define HIGH_RXCOL_TICKS 0x00000096 -+#define MAX_RXCOL_TICKS 0x000003ff -+#define HOSTCC_TXCOL_TICKS 0x00003c0c -+#define LOW_TXCOL_TICKS 0x00000096 -+#define LOW_TXCOL_TICKS_CLRTCKS 0x00000048 -+#define DEFAULT_TXCOL_TICKS 0x0000012c -+#define HIGH_TXCOL_TICKS 0x00000145 -+#define MAX_TXCOL_TICKS 0x000003ff -+#define HOSTCC_RXMAX_FRAMES 0x00003c10 -+#if defined(__VMKLNX__) -+#define LOW_RXMAX_FRAMES 0x0000000f -+#else -+#define LOW_RXMAX_FRAMES 0x00000005 -+#endif -+#define DEFAULT_RXMAX_FRAMES 0x00000008 -+#define HIGH_RXMAX_FRAMES 0x00000012 -+#define MAX_RXMAX_FRAMES 0x000000ff -+#define HOSTCC_TXMAX_FRAMES 0x00003c14 -+#define LOW_TXMAX_FRAMES 0x00000035 -+#define DEFAULT_TXMAX_FRAMES 0x0000004b -+#define HIGH_TXMAX_FRAMES 0x00000052 -+#define MAX_TXMAX_FRAMES 0x000000ff -+#define HOSTCC_RXCOAL_TICK_INT 0x00003c18 -+#define DEFAULT_RXCOAL_TICK_INT 0x00000019 -+#define DEFAULT_RXCOAL_TICK_INT_CLRTCKS 0x00000014 -+#define MAX_RXCOAL_TICK_INT 0x000003ff -+#define HOSTCC_TXCOAL_TICK_INT 0x00003c1c -+#define DEFAULT_TXCOAL_TICK_INT 0x00000019 -+#define DEFAULT_TXCOAL_TICK_INT_CLRTCKS 0x00000014 -+#define MAX_TXCOAL_TICK_INT 0x000003ff -+#define HOSTCC_RXCOAL_MAXF_INT 0x00003c20 -+#define DEFAULT_RXCOAL_MAXF_INT 0x00000005 -+#define MAX_RXCOAL_MAXF_INT 0x000000ff -+#define HOSTCC_TXCOAL_MAXF_INT 0x00003c24 -+#define DEFAULT_TXCOAL_MAXF_INT 0x00000005 -+#define MAX_TXCOAL_MAXF_INT 0x000000ff -+#define HOSTCC_STAT_COAL_TICKS 0x00003c28 -+#define DEFAULT_STAT_COAL_TICKS 0x000f4240 -+#define MAX_STAT_COAL_TICKS 0xd693d400 -+#define MIN_STAT_COAL_TICKS 0x00000064 -+#define HOSTCC_PARAM_SET_RESET 0x00003c28 -+/* 0x3c2c --> 0x3c30 unused */ -+#define HOSTCC_STATS_BLK_HOST_ADDR 0x00003c30 /* 64-bit */ -+#define HOSTCC_STATUS_BLK_HOST_ADDR 0x00003c38 /* 64-bit */ -+#define HOSTCC_STATS_BLK_NIC_ADDR 0x00003c40 -+#define HOSTCC_STATUS_BLK_NIC_ADDR 0x00003c44 -+#define HOSTCC_FLOW_ATTN 0x00003c48 -+#define HOSTCC_FLOW_ATTN_MBUF_LWM 0x00000040 -+#define HOSTCC_FLOW_ATTN_RCB_MISCFG 0x00020000 -+#define HOSTCC_FLOW_ATTN_RCV_BDI_ATTN 0x00800000 -+/* 0x3c4c --> 0x3c50 unused */ -+#define HOSTCC_JUMBO_CON_IDX 0x00003c50 -+#define HOSTCC_STD_CON_IDX 0x00003c54 -+#define HOSTCC_MINI_CON_IDX 0x00003c58 -+/* 0x3c5c --> 0x3c80 unused */ -+#define HOSTCC_RET_PROD_IDX_0 0x00003c80 -+#define HOSTCC_RET_PROD_IDX_1 0x00003c84 -+#define HOSTCC_RET_PROD_IDX_2 0x00003c88 -+#define HOSTCC_RET_PROD_IDX_3 0x00003c8c -+#define HOSTCC_RET_PROD_IDX_4 0x00003c90 -+#define HOSTCC_RET_PROD_IDX_5 0x00003c94 -+#define HOSTCC_RET_PROD_IDX_6 0x00003c98 -+#define HOSTCC_RET_PROD_IDX_7 0x00003c9c -+#define HOSTCC_RET_PROD_IDX_8 0x00003ca0 -+#define HOSTCC_RET_PROD_IDX_9 0x00003ca4 -+#define HOSTCC_RET_PROD_IDX_10 0x00003ca8 -+#define HOSTCC_RET_PROD_IDX_11 0x00003cac -+#define HOSTCC_RET_PROD_IDX_12 0x00003cb0 -+#define HOSTCC_RET_PROD_IDX_13 0x00003cb4 -+#define HOSTCC_RET_PROD_IDX_14 0x00003cb8 -+#define HOSTCC_RET_PROD_IDX_15 0x00003cbc -+#define HOSTCC_SND_CON_IDX_0 0x00003cc0 -+#define HOSTCC_SND_CON_IDX_1 0x00003cc4 -+#define HOSTCC_SND_CON_IDX_2 0x00003cc8 -+#define HOSTCC_SND_CON_IDX_3 0x00003ccc -+#define HOSTCC_SND_CON_IDX_4 0x00003cd0 -+#define HOSTCC_SND_CON_IDX_5 0x00003cd4 -+#define HOSTCC_SND_CON_IDX_6 0x00003cd8 -+#define HOSTCC_SND_CON_IDX_7 0x00003cdc -+#define HOSTCC_SND_CON_IDX_8 0x00003ce0 -+#define HOSTCC_SND_CON_IDX_9 0x00003ce4 -+#define HOSTCC_SND_CON_IDX_10 0x00003ce8 -+#define HOSTCC_SND_CON_IDX_11 0x00003cec -+#define HOSTCC_SND_CON_IDX_12 0x00003cf0 -+#define HOSTCC_SND_CON_IDX_13 0x00003cf4 -+#define HOSTCC_SND_CON_IDX_14 0x00003cf8 -+#define HOSTCC_SND_CON_IDX_15 0x00003cfc -+#define HOSTCC_STATBLCK_RING1 0x00003d00 -+/* 0x3d00 --> 0x3d80 unused */ -+ -+#define HOSTCC_RXCOL_TICKS_VEC1 0x00003d80 -+#define HOSTCC_TXCOL_TICKS_VEC1 0x00003d84 -+#define HOSTCC_RXMAX_FRAMES_VEC1 0x00003d88 -+#define HOSTCC_TXMAX_FRAMES_VEC1 0x00003d8c -+#define HOSTCC_RXCOAL_MAXF_INT_VEC1 0x00003d90 -+#define HOSTCC_TXCOAL_MAXF_INT_VEC1 0x00003d94 -+/* 0x3d98 --> 0x4000 unused */ -+ -+/* Memory arbiter control registers */ -+#define MEMARB_MODE 0x00004000 -+#define MEMARB_MODE_RESET 0x00000001 -+#define MEMARB_MODE_ENABLE 0x00000002 -+#define MEMARB_STATUS 0x00004004 -+#define MEMARB_TRAP_ADDR_LOW 0x00004008 -+#define MEMARB_TRAP_ADDR_HIGH 0x0000400c -+/* 0x4010 --> 0x4400 unused */ -+ -+/* Buffer manager control registers */ -+#define BUFMGR_MODE 0x00004400 -+#define BUFMGR_MODE_RESET 0x00000001 -+#define BUFMGR_MODE_ENABLE 0x00000002 -+#define BUFMGR_MODE_ATTN_ENABLE 0x00000004 -+#define BUFMGR_MODE_BM_TEST 0x00000008 -+#define BUFMGR_MODE_MBLOW_ATTN_ENAB 0x00000010 -+#define BUFMGR_MODE_NO_TX_UNDERRUN 0x80000000 -+#define BUFMGR_STATUS 0x00004404 -+#define BUFMGR_STATUS_ERROR 0x00000004 -+#define BUFMGR_STATUS_MBLOW 0x00000010 -+#define BUFMGR_MB_POOL_ADDR 0x00004408 -+#define BUFMGR_MB_POOL_SIZE 0x0000440c -+#define BUFMGR_MB_RDMA_LOW_WATER 0x00004410 -+#define DEFAULT_MB_RDMA_LOW_WATER 0x00000050 -+#define DEFAULT_MB_RDMA_LOW_WATER_5705 0x00000000 -+#define DEFAULT_MB_RDMA_LOW_WATER_JUMBO 0x00000130 -+#define DEFAULT_MB_RDMA_LOW_WATER_JUMBO_5780 0x00000000 -+#define BUFMGR_MB_MACRX_LOW_WATER 0x00004414 -+#define DEFAULT_MB_MACRX_LOW_WATER 0x00000020 -+#define DEFAULT_MB_MACRX_LOW_WATER_5705 0x00000010 -+#define DEFAULT_MB_MACRX_LOW_WATER_5906 0x00000004 -+#define DEFAULT_MB_MACRX_LOW_WATER_57765 0x0000002a -+#define DEFAULT_MB_MACRX_LOW_WATER_JUMBO 0x00000098 -+#define DEFAULT_MB_MACRX_LOW_WATER_JUMBO_5780 0x0000004b -+#define DEFAULT_MB_MACRX_LOW_WATER_JUMBO_57765 0x0000007e -+#define BUFMGR_MB_HIGH_WATER 0x00004418 -+#define DEFAULT_MB_HIGH_WATER 0x00000060 -+#define DEFAULT_MB_HIGH_WATER_5705 0x00000060 -+#define DEFAULT_MB_HIGH_WATER_5906 0x00000010 -+#define DEFAULT_MB_HIGH_WATER_57765 0x000000a0 -+#define DEFAULT_MB_HIGH_WATER_JUMBO 0x0000017c -+#define DEFAULT_MB_HIGH_WATER_JUMBO_5780 0x00000096 -+#define DEFAULT_MB_HIGH_WATER_JUMBO_57765 0x000000ea -+#define BUFMGR_RX_MB_ALLOC_REQ 0x0000441c -+#define BUFMGR_MB_ALLOC_BIT 0x10000000 -+#define BUFMGR_RX_MB_ALLOC_RESP 0x00004420 -+#define BUFMGR_TX_MB_ALLOC_REQ 0x00004424 -+#define BUFMGR_TX_MB_ALLOC_RESP 0x00004428 -+#define BUFMGR_DMA_DESC_POOL_ADDR 0x0000442c -+#define BUFMGR_DMA_DESC_POOL_SIZE 0x00004430 -+#define BUFMGR_DMA_LOW_WATER 0x00004434 -+#define DEFAULT_DMA_LOW_WATER 0x00000005 -+#define BUFMGR_DMA_HIGH_WATER 0x00004438 -+#define DEFAULT_DMA_HIGH_WATER 0x0000000a -+#define BUFMGR_RX_DMA_ALLOC_REQ 0x0000443c -+#define BUFMGR_RX_DMA_ALLOC_RESP 0x00004440 -+#define BUFMGR_TX_DMA_ALLOC_REQ 0x00004444 -+#define BUFMGR_TX_DMA_ALLOC_RESP 0x00004448 -+#define BUFMGR_HWDIAG_0 0x0000444c -+#define BUFMGR_HWDIAG_1 0x00004450 -+#define BUFMGR_HWDIAG_2 0x00004454 -+/* 0x4458 --> 0x4800 unused */ -+ -+/* Read DMA control registers */ -+#define RDMAC_MODE 0x00004800 -+#define RDMAC_MODE_RESET 0x00000001 -+#define RDMAC_MODE_ENABLE 0x00000002 -+#define RDMAC_MODE_TGTABORT_ENAB 0x00000004 -+#define RDMAC_MODE_MSTABORT_ENAB 0x00000008 -+#define RDMAC_MODE_PARITYERR_ENAB 0x00000010 -+#define RDMAC_MODE_ADDROFLOW_ENAB 0x00000020 -+#define RDMAC_MODE_FIFOOFLOW_ENAB 0x00000040 -+#define RDMAC_MODE_FIFOURUN_ENAB 0x00000080 -+#define RDMAC_MODE_FIFOOREAD_ENAB 0x00000100 -+#define RDMAC_MODE_LNGREAD_ENAB 0x00000200 -+#define RDMAC_MODE_SPLIT_ENABLE 0x00000800 -+#define RDMAC_MODE_BD_SBD_CRPT_ENAB 0x00000800 -+#define RDMAC_MODE_SPLIT_RESET 0x00001000 -+#define RDMAC_MODE_MBUF_RBD_CRPT_ENAB 0x00001000 -+#define RDMAC_MODE_MBUF_SBD_CRPT_ENAB 0x00002000 -+#define RDMAC_MODE_FIFO_SIZE_128 0x00020000 -+#define RDMAC_MODE_FIFO_LONG_BURST 0x00030000 -+#define RDMAC_MODE_JMB_2K_MMRR 0x00800000 -+#define RDMAC_MODE_MULT_DMA_RD_DIS 0x01000000 -+#define RDMAC_MODE_IPV4_LSO_EN 0x08000000 -+#define RDMAC_MODE_IPV6_LSO_EN 0x10000000 -+#define RDMAC_MODE_H2BNC_VLAN_DET 0x20000000 -+#define RDMAC_STATUS 0x00004804 -+#define RDMAC_STATUS_TGTABORT 0x00000004 -+#define RDMAC_STATUS_MSTABORT 0x00000008 -+#define RDMAC_STATUS_PARITYERR 0x00000010 -+#define RDMAC_STATUS_ADDROFLOW 0x00000020 -+#define RDMAC_STATUS_FIFOOFLOW 0x00000040 -+#define RDMAC_STATUS_FIFOURUN 0x00000080 -+#define RDMAC_STATUS_FIFOOREAD 0x00000100 -+#define RDMAC_STATUS_LNGREAD 0x00000200 -+/* 0x4808 --> 0x4900 unused */ -+ -+#define TG3_RDMA_RSRVCTRL_REG2 0x00004890 -+#define TG3_LSO_RD_DMA_CRPTEN_CTRL2 0x000048a0 -+ -+#define TG3_RDMA_RSRVCTRL_REG 0x00004900 -+#define TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004 -+#define TG3_RDMA_RSRVCTRL_FIFO_LWM_1_5K 0x00000c00 -+#define TG3_RDMA_RSRVCTRL_FIFO_LWM_MASK 0x00000ff0 -+#define TG3_RDMA_RSRVCTRL_FIFO_HWM_1_5K 0x000c0000 -+#define TG3_RDMA_RSRVCTRL_FIFO_HWM_MASK 0x000ff000 -+#define TG3_RDMA_RSRVCTRL_TXMRGN_320B 0x28000000 -+#define TG3_RDMA_RSRVCTRL_TXMRGN_MASK 0xffe00000 -+/* 0x4904 --> 0x4910 unused */ -+ -+#define TG3_LSO_RD_DMA_CRPTEN_CTRL 0x00004910 -+#define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K 0x00030000 -+#define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K 0x000c0000 -+#define TG3_LSO_RD_DMA_TX_LENGTH_WA_5719 0x02000000 -+#define TG3_LSO_RD_DMA_TX_LENGTH_WA_5720 0x00200000 -+/* 0x4914 --> 0x4be0 unused */ -+ -+#define TG3_NUM_RDMA_CHANNELS 4 -+#define TG3_RDMA_LENGTH 0x00004be0 -+ -+/* Write DMA control registers */ -+#define WDMAC_MODE 0x00004c00 -+#define WDMAC_MODE_RESET 0x00000001 -+#define WDMAC_MODE_ENABLE 0x00000002 -+#define WDMAC_MODE_TGTABORT_ENAB 0x00000004 -+#define WDMAC_MODE_MSTABORT_ENAB 0x00000008 -+#define WDMAC_MODE_PARITYERR_ENAB 0x00000010 -+#define WDMAC_MODE_ADDROFLOW_ENAB 0x00000020 -+#define WDMAC_MODE_FIFOOFLOW_ENAB 0x00000040 -+#define WDMAC_MODE_FIFOURUN_ENAB 0x00000080 -+#define WDMAC_MODE_FIFOOREAD_ENAB 0x00000100 -+#define WDMAC_MODE_LNGREAD_ENAB 0x00000200 -+#define WDMAC_MODE_RX_ACCEL 0x00000400 -+#define WDMAC_MODE_STATUS_TAG_FIX 0x20000000 -+#define WDMAC_MODE_BURST_ALL_DATA 0xc0000000 -+#define WDMAC_STATUS 0x00004c04 -+#define WDMAC_STATUS_TGTABORT 0x00000004 -+#define WDMAC_STATUS_MSTABORT 0x00000008 -+#define WDMAC_STATUS_PARITYERR 0x00000010 -+#define WDMAC_STATUS_ADDROFLOW 0x00000020 -+#define WDMAC_STATUS_FIFOOFLOW 0x00000040 -+#define WDMAC_STATUS_FIFOURUN 0x00000080 -+#define WDMAC_STATUS_FIFOOREAD 0x00000100 -+#define WDMAC_STATUS_LNGREAD 0x00000200 -+/* 0x4c08 --> 0x5000 unused */ -+ -+/* Per-cpu register offsets (arm9) */ -+#define CPU_MODE 0x00000000 -+#define CPU_MODE_RESET 0x00000001 -+#define CPU_MODE_HALT 0x00000400 -+#define CPU_STATE 0x00000004 -+#define CPU_EVTMASK 0x00000008 -+/* 0xc --> 0x1c reserved */ -+#define CPU_PC 0x0000001c -+#define CPU_INSN 0x00000020 -+#define CPU_SPAD_UFLOW 0x00000024 -+#define CPU_WDOG_CLEAR 0x00000028 -+#define CPU_WDOG_VECTOR 0x0000002c -+#define CPU_WDOG_PC 0x00000030 -+#define CPU_HW_BP 0x00000034 -+/* 0x38 --> 0x44 unused */ -+#define CPU_WDOG_SAVED_STATE 0x00000044 -+#define CPU_LAST_BRANCH_ADDR 0x00000048 -+#define CPU_SPAD_UFLOW_SET 0x0000004c -+/* 0x50 --> 0x200 unused */ -+#define CPU_R0 0x00000200 -+#define CPU_R1 0x00000204 -+#define CPU_R2 0x00000208 -+#define CPU_R3 0x0000020c -+#define CPU_R4 0x00000210 -+#define CPU_R5 0x00000214 -+#define CPU_R6 0x00000218 -+#define CPU_R7 0x0000021c -+#define CPU_R8 0x00000220 -+#define CPU_R9 0x00000224 -+#define CPU_R10 0x00000228 -+#define CPU_R11 0x0000022c -+#define CPU_R12 0x00000230 -+#define CPU_R13 0x00000234 -+#define CPU_R14 0x00000238 -+#define CPU_R15 0x0000023c -+#define CPU_R16 0x00000240 -+#define CPU_R17 0x00000244 -+#define CPU_R18 0x00000248 -+#define CPU_R19 0x0000024c -+#define CPU_R20 0x00000250 -+#define CPU_R21 0x00000254 -+#define CPU_R22 0x00000258 -+#define CPU_R23 0x0000025c -+#define CPU_R24 0x00000260 -+#define CPU_R25 0x00000264 -+#define CPU_R26 0x00000268 -+#define CPU_R27 0x0000026c -+#define CPU_R28 0x00000270 -+#define CPU_R29 0x00000274 -+#define CPU_R30 0x00000278 -+#define CPU_R31 0x0000027c -+/* 0x280 --> 0x400 unused */ -+ -+#define RX_CPU_BASE 0x00005000 -+#define RX_CPU_MODE 0x00005000 -+#define RX_CPU_STATE 0x00005004 -+#define RX_CPU_PGMCTR 0x0000501c -+#define RX_CPU_HWBKPT 0x00005034 -+#define TX_CPU_BASE 0x00005400 -+#define TX_CPU_MODE 0x00005400 -+#define TX_CPU_STATE 0x00005404 -+#define TX_CPU_PGMCTR 0x0000541c -+ -+#define VCPU_STATUS 0x00005100 -+#define VCPU_STATUS_INIT_DONE 0x04000000 -+#define VCPU_STATUS_DRV_RESET 0x08000000 -+ -+#define VCPU_CFGSHDW 0x00005104 -+#define VCPU_CFGSHDW_WOL_ENABLE 0x00000001 -+#define VCPU_CFGSHDW_WOL_MAGPKT 0x00000004 -+#define VCPU_CFGSHDW_ASPM_DBNC 0x00001000 -+ -+#define MAC_VRQFLT_CFG 0x00005400 -+#define MAC_VRQFLT_ELEM_EN 0x80000000 -+#define MAC_VRQFLT_HDR_VLAN 0x0000e000 -+#define MAC_VRQFLT_PTRN 0x00005480 -+#define MAC_VRQFLT_PTRN_VLANID 0x0000ffff -+#define MAC_VRQFLT_FLTSET 0x00005500 -+ -+/* Mailboxes */ -+#define GRCMBOX_BASE 0x00005600 -+#define MAC_VRQMAP_1H 0x00005600 -+#define MAC_VRQMAP_1H_PTA_PFEN 0x00000020 -+#define MAC_VRQMAP_2H 0x00005604 -+#define MAC_VRQMAP_2H_PTA_VFEN 0x00000020 -+#define MAC_VRQMAP_2H_PTA_AND 0x00000000 -+#define MAC_VRQMAP_2H_PTA_OR 0x00000040 -+#define MAC_VRQMAP_2H_PTA_EN 0x00000080 -+#define MAC_VRQ_PMATCH_HI_5 0x00005690 -+#define MAC_VRQ_PMATCH_LO_5 0x00005694 -+#define GRCMBOX_INTERRUPT_0 0x00005800 /* 64-bit */ -+#define GRCMBOX_INTERRUPT_1 0x00005808 /* 64-bit */ -+#define GRCMBOX_INTERRUPT_2 0x00005810 /* 64-bit */ -+#define GRCMBOX_INTERRUPT_3 0x00005818 /* 64-bit */ -+#define GRCMBOX_GENERAL_0 0x00005820 /* 64-bit */ -+#define GRCMBOX_GENERAL_1 0x00005828 /* 64-bit */ -+#define GRCMBOX_GENERAL_2 0x00005830 /* 64-bit */ -+#define GRCMBOX_GENERAL_3 0x00005838 /* 64-bit */ -+#define GRCMBOX_GENERAL_4 0x00005840 /* 64-bit */ -+#define GRCMBOX_GENERAL_5 0x00005848 /* 64-bit */ -+#define GRCMBOX_GENERAL_6 0x00005850 /* 64-bit */ -+#define GRCMBOX_GENERAL_7 0x00005858 /* 64-bit */ -+#define GRCMBOX_RELOAD_STAT 0x00005860 /* 64-bit */ -+#define GRCMBOX_RCVSTD_PROD_IDX 0x00005868 /* 64-bit */ -+#define GRCMBOX_RCVJUMBO_PROD_IDX 0x00005870 /* 64-bit */ -+#define GRCMBOX_RCVMINI_PROD_IDX 0x00005878 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_0 0x00005880 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_1 0x00005888 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_2 0x00005890 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_3 0x00005898 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_4 0x000058a0 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_5 0x000058a8 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_6 0x000058b0 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_7 0x000058b8 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_8 0x000058c0 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_9 0x000058c8 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_10 0x000058d0 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_11 0x000058d8 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_12 0x000058e0 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_13 0x000058e8 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_14 0x000058f0 /* 64-bit */ -+#define GRCMBOX_RCVRET_CON_IDX_15 0x000058f8 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_0 0x00005900 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_1 0x00005908 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_2 0x00005910 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_3 0x00005918 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_4 0x00005920 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_5 0x00005928 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_6 0x00005930 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_7 0x00005938 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_8 0x00005940 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_9 0x00005948 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_10 0x00005950 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_11 0x00005958 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_12 0x00005960 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_13 0x00005968 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_14 0x00005970 /* 64-bit */ -+#define GRCMBOX_SNDHOST_PROD_IDX_15 0x00005978 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_0 0x00005980 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_1 0x00005988 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_2 0x00005990 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_3 0x00005998 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_4 0x000059a0 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_5 0x000059a8 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_6 0x000059b0 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_7 0x000059b8 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_8 0x000059c0 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_9 0x000059c8 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_10 0x000059d0 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_11 0x000059d8 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_12 0x000059e0 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_13 0x000059e8 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_14 0x000059f0 /* 64-bit */ -+#define GRCMBOX_SNDNIC_PROD_IDX_15 0x000059f8 /* 64-bit */ -+#define GRCMBOX_HIGH_PRIO_EV_VECTOR 0x00005a00 -+#define GRCMBOX_HIGH_PRIO_EV_MASK 0x00005a04 -+#define GRCMBOX_LOW_PRIO_EV_VEC 0x00005a08 -+#define GRCMBOX_LOW_PRIO_EV_MASK 0x00005a0c -+/* 0x5a10 --> 0x5c00 */ -+ -+/* Flow Through queues */ -+#define FTQ_RESET 0x00005c00 -+/* 0x5c04 --> 0x5c10 unused */ -+#define FTQ_DMA_NORM_READ_CTL 0x00005c10 -+#define FTQ_DMA_NORM_READ_FULL_CNT 0x00005c14 -+#define FTQ_DMA_NORM_READ_FIFO_ENQDEQ 0x00005c18 -+#define FTQ_DMA_NORM_READ_WRITE_PEEK 0x00005c1c -+#define FTQ_DMA_HIGH_READ_CTL 0x00005c20 -+#define FTQ_DMA_HIGH_READ_FULL_CNT 0x00005c24 -+#define FTQ_DMA_HIGH_READ_FIFO_ENQDEQ 0x00005c28 -+#define FTQ_DMA_HIGH_READ_WRITE_PEEK 0x00005c2c -+#define FTQ_DMA_COMP_DISC_CTL 0x00005c30 -+#define FTQ_DMA_COMP_DISC_FULL_CNT 0x00005c34 -+#define FTQ_DMA_COMP_DISC_FIFO_ENQDEQ 0x00005c38 -+#define FTQ_DMA_COMP_DISC_WRITE_PEEK 0x00005c3c -+#define FTQ_SEND_BD_COMP_CTL 0x00005c40 -+#define FTQ_SEND_BD_COMP_FULL_CNT 0x00005c44 -+#define FTQ_SEND_BD_COMP_FIFO_ENQDEQ 0x00005c48 -+#define FTQ_SEND_BD_COMP_WRITE_PEEK 0x00005c4c -+#define FTQ_SEND_DATA_INIT_CTL 0x00005c50 -+#define FTQ_SEND_DATA_INIT_FULL_CNT 0x00005c54 -+#define FTQ_SEND_DATA_INIT_FIFO_ENQDEQ 0x00005c58 -+#define FTQ_SEND_DATA_INIT_WRITE_PEEK 0x00005c5c -+#define FTQ_DMA_NORM_WRITE_CTL 0x00005c60 -+#define FTQ_DMA_NORM_WRITE_FULL_CNT 0x00005c64 -+#define FTQ_DMA_NORM_WRITE_FIFO_ENQDEQ 0x00005c68 -+#define FTQ_DMA_NORM_WRITE_WRITE_PEEK 0x00005c6c -+#define FTQ_DMA_HIGH_WRITE_CTL 0x00005c70 -+#define FTQ_DMA_HIGH_WRITE_FULL_CNT 0x00005c74 -+#define FTQ_DMA_HIGH_WRITE_FIFO_ENQDEQ 0x00005c78 -+#define FTQ_DMA_HIGH_WRITE_WRITE_PEEK 0x00005c7c -+#define FTQ_SWTYPE1_CTL 0x00005c80 -+#define FTQ_SWTYPE1_FULL_CNT 0x00005c84 -+#define FTQ_SWTYPE1_FIFO_ENQDEQ 0x00005c88 -+#define FTQ_SWTYPE1_WRITE_PEEK 0x00005c8c -+#define FTQ_SEND_DATA_COMP_CTL 0x00005c90 -+#define FTQ_SEND_DATA_COMP_FULL_CNT 0x00005c94 -+#define FTQ_SEND_DATA_COMP_FIFO_ENQDEQ 0x00005c98 -+#define FTQ_SEND_DATA_COMP_WRITE_PEEK 0x00005c9c -+#define FTQ_HOST_COAL_CTL 0x00005ca0 -+#define FTQ_HOST_COAL_FULL_CNT 0x00005ca4 -+#define FTQ_HOST_COAL_FIFO_ENQDEQ 0x00005ca8 -+#define FTQ_HOST_COAL_WRITE_PEEK 0x00005cac -+#define FTQ_MAC_TX_CTL 0x00005cb0 -+#define FTQ_MAC_TX_FULL_CNT 0x00005cb4 -+#define FTQ_MAC_TX_FIFO_ENQDEQ 0x00005cb8 -+#define FTQ_MAC_TX_WRITE_PEEK 0x00005cbc -+#define FTQ_MB_FREE_CTL 0x00005cc0 -+#define FTQ_MB_FREE_FULL_CNT 0x00005cc4 -+#define FTQ_MB_FREE_FIFO_ENQDEQ 0x00005cc8 -+#define FTQ_MB_FREE_WRITE_PEEK 0x00005ccc -+#define FTQ_RCVBD_COMP_CTL 0x00005cd0 -+#define FTQ_RCVBD_COMP_FULL_CNT 0x00005cd4 -+#define FTQ_RCVBD_COMP_FIFO_ENQDEQ 0x00005cd8 -+#define FTQ_RCVBD_COMP_WRITE_PEEK 0x00005cdc -+#define FTQ_RCVLST_PLMT_CTL 0x00005ce0 -+#define FTQ_RCVLST_PLMT_FULL_CNT 0x00005ce4 -+#define FTQ_RCVLST_PLMT_FIFO_ENQDEQ 0x00005ce8 -+#define FTQ_RCVLST_PLMT_WRITE_PEEK 0x00005cec -+#define FTQ_RCVDATA_INI_CTL 0x00005cf0 -+#define FTQ_RCVDATA_INI_FULL_CNT 0x00005cf4 -+#define FTQ_RCVDATA_INI_FIFO_ENQDEQ 0x00005cf8 -+#define FTQ_RCVDATA_INI_WRITE_PEEK 0x00005cfc -+#define FTQ_RCVDATA_COMP_CTL 0x00005d00 -+#define FTQ_RCVDATA_COMP_FULL_CNT 0x00005d04 -+#define FTQ_RCVDATA_COMP_FIFO_ENQDEQ 0x00005d08 -+#define FTQ_RCVDATA_COMP_WRITE_PEEK 0x00005d0c -+#define FTQ_SWTYPE2_CTL 0x00005d10 -+#define FTQ_SWTYPE2_FULL_CNT 0x00005d14 -+#define FTQ_SWTYPE2_FIFO_ENQDEQ 0x00005d18 -+#define FTQ_SWTYPE2_WRITE_PEEK 0x00005d1c -+/* 0x5d20 --> 0x6000 unused */ -+ -+/* Message signaled interrupt registers */ -+#define MSGINT_MODE 0x00006000 -+#define MSGINT_MODE_RESET 0x00000001 -+#define MSGINT_MODE_ENABLE 0x00000002 -+#define MSGINT_MODE_ONE_SHOT_DISABLE 0x00000020 -+#define MSGINT_MODE_MULTIVEC_EN 0x00000080 -+#define MSGINT_STATUS 0x00006004 -+#define MSGINT_STATUS_MSI_REQ 0x00000001 -+#define MSGINT_FIFO 0x00006008 -+/* 0x600c --> 0x6400 unused */ -+ -+/* DMA completion registers */ -+#define DMAC_MODE 0x00006400 -+#define DMAC_MODE_RESET 0x00000001 -+#define DMAC_MODE_ENABLE 0x00000002 -+/* 0x6404 --> 0x6800 unused */ -+ -+/* GRC registers */ -+#define GRC_MODE 0x00006800 -+#define GRC_MODE_UPD_ON_COAL 0x00000001 -+#define GRC_MODE_BSWAP_NONFRM_DATA 0x00000002 -+#define GRC_MODE_WSWAP_NONFRM_DATA 0x00000004 -+#define GRC_MODE_BSWAP_DATA 0x00000010 -+#define GRC_MODE_WSWAP_DATA 0x00000020 -+#define GRC_MODE_BYTE_SWAP_B2HRX_DATA 0x00000040 -+#define GRC_MODE_WORD_SWAP_B2HRX_DATA 0x00000080 -+#define GRC_MODE_IOV_ENABLE 0x00000100 -+#define GRC_MODE_SPLITHDR 0x00000100 -+#define GRC_MODE_NOFRM_CRACKING 0x00000200 -+#define GRC_MODE_INCL_CRC 0x00000400 -+#define GRC_MODE_ALLOW_BAD_FRMS 0x00000800 -+#define GRC_MODE_NOIRQ_ON_SENDS 0x00002000 -+#define GRC_MODE_NOIRQ_ON_RCV 0x00004000 -+#define GRC_MODE_FORCE_PCI32BIT 0x00008000 -+#define GRC_MODE_B2HRX_ENABLE 0x00008000 -+#define GRC_MODE_HOST_STACKUP 0x00010000 -+#define GRC_MODE_HOST_SENDBDS 0x00020000 -+#define GRC_MODE_HTX2B_ENABLE 0x00040000 -+#define GRC_MODE_TIME_SYNC_ENABLE 0x00080000 -+#define GRC_MODE_NO_TX_PHDR_CSUM 0x00100000 -+#define GRC_MODE_NVRAM_WR_ENABLE 0x00200000 -+#define GRC_MODE_PCIE_TL_SEL 0x00000000 -+#define GRC_MODE_PCIE_PL_SEL 0x00400000 -+#define GRC_MODE_NO_RX_PHDR_CSUM 0x00800000 -+#define GRC_MODE_IRQ_ON_TX_CPU_ATTN 0x01000000 -+#define GRC_MODE_IRQ_ON_RX_CPU_ATTN 0x02000000 -+#define GRC_MODE_IRQ_ON_MAC_ATTN 0x04000000 -+#define GRC_MODE_IRQ_ON_DMA_ATTN 0x08000000 -+#define GRC_MODE_IRQ_ON_FLOW_ATTN 0x10000000 -+#define GRC_MODE_4X_NIC_SEND_RINGS 0x20000000 -+#define GRC_MODE_PCIE_DL_SEL 0x20000000 -+#define GRC_MODE_MCAST_FRM_ENABLE 0x40000000 -+#define GRC_MODE_PCIE_HI_1K_EN 0x80000000 -+#define GRC_MODE_PCIE_PORT_MASK (GRC_MODE_PCIE_TL_SEL | \ -+ GRC_MODE_PCIE_PL_SEL | \ -+ GRC_MODE_PCIE_DL_SEL | \ -+ GRC_MODE_PCIE_HI_1K_EN) -+#define GRC_MISC_CFG 0x00006804 -+#define GRC_MISC_CFG_CORECLK_RESET 0x00000001 -+#define GRC_MISC_CFG_PRESCALAR_MASK 0x000000fe -+#define GRC_MISC_CFG_PRESCALAR_SHIFT 1 -+#define GRC_MISC_CFG_BOARD_ID_MASK 0x0001e000 -+#define GRC_MISC_CFG_BOARD_ID_5700 0x0001e000 -+#define GRC_MISC_CFG_BOARD_ID_5701 0x00000000 -+#define GRC_MISC_CFG_BOARD_ID_5702FE 0x00004000 -+#define GRC_MISC_CFG_BOARD_ID_5703 0x00000000 -+#define GRC_MISC_CFG_BOARD_ID_5703S 0x00002000 -+#define GRC_MISC_CFG_BOARD_ID_5704 0x00000000 -+#define GRC_MISC_CFG_BOARD_ID_5704CIOBE 0x00004000 -+#define GRC_MISC_CFG_BOARD_ID_5704_A2 0x00008000 -+#define GRC_MISC_CFG_BOARD_ID_5788 0x00010000 -+#define GRC_MISC_CFG_BOARD_ID_5788M 0x00018000 -+#define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000 -+#define GRC_MISC_CFG_EPHY_IDDQ 0x00200000 -+#define GRC_MISC_CFG_KEEP_GPHY_POWER 0x04000000 -+#define GRC_LOCAL_CTRL 0x00006808 -+#define GRC_LCLCTRL_INT_ACTIVE 0x00000001 -+#define GRC_LCLCTRL_CLEARINT 0x00000002 -+#define GRC_LCLCTRL_SETINT 0x00000004 -+#define GRC_LCLCTRL_INT_ON_ATTN 0x00000008 -+#define GRC_LCLCTRL_GPIO_UART_SEL 0x00000010 /* 5755 only */ -+#define GRC_LCLCTRL_USE_SIG_DETECT 0x00000010 /* 5714/5780 only */ -+#define GRC_LCLCTRL_USE_EXT_SIG_DETECT 0x00000020 /* 5714/5780 only */ -+#define GRC_LCLCTRL_GPIO_INPUT3 0x00000020 -+#define GRC_LCLCTRL_GPIO_OE3 0x00000040 -+#define GRC_LCLCTRL_GPIO_OUTPUT3 0x00000080 -+#define GRC_LCLCTRL_GPIO_INPUT0 0x00000100 -+#define GRC_LCLCTRL_GPIO_INPUT1 0x00000200 -+#define GRC_LCLCTRL_GPIO_INPUT2 0x00000400 -+#define GRC_LCLCTRL_GPIO_OE0 0x00000800 -+#define GRC_LCLCTRL_GPIO_OE1 0x00001000 -+#define GRC_LCLCTRL_GPIO_OE2 0x00002000 -+#define GRC_LCLCTRL_GPIO_OUTPUT0 0x00004000 -+#define GRC_LCLCTRL_GPIO_OUTPUT1 0x00008000 -+#define GRC_LCLCTRL_GPIO_OUTPUT2 0x00010000 -+#define GRC_LCLCTRL_EXTMEM_ENABLE 0x00020000 -+#define GRC_LCLCTRL_MEMSZ_MASK 0x001c0000 -+#define GRC_LCLCTRL_MEMSZ_256K 0x00000000 -+#define GRC_LCLCTRL_MEMSZ_512K 0x00040000 -+#define GRC_LCLCTRL_MEMSZ_1M 0x00080000 -+#define GRC_LCLCTRL_MEMSZ_2M 0x000c0000 -+#define GRC_LCLCTRL_MEMSZ_4M 0x00100000 -+#define GRC_LCLCTRL_MEMSZ_8M 0x00140000 -+#define GRC_LCLCTRL_MEMSZ_16M 0x00180000 -+#define GRC_LCLCTRL_BANK_SELECT 0x00200000 -+#define GRC_LCLCTRL_SSRAM_TYPE 0x00400000 -+#define GRC_LCLCTRL_AUTO_SEEPROM 0x01000000 -+#define GRC_TIMER 0x0000680c -+#define GRC_RX_CPU_EVENT 0x00006810 -+#define GRC_RX_CPU_DRIVER_EVENT 0x00004000 -+#define GRC_RX_TIMER_REF 0x00006814 -+#define GRC_RX_CPU_SEM 0x00006818 -+#define GRC_REMOTE_RX_CPU_ATTN 0x0000681c -+#define GRC_TX_CPU_EVENT 0x00006820 -+#define GRC_TX_TIMER_REF 0x00006824 -+#define GRC_TX_CPU_SEM 0x00006828 -+#define GRC_REMOTE_TX_CPU_ATTN 0x0000682c -+#define GRC_MEM_POWER_UP 0x00006830 /* 64-bit */ -+#define GRC_EEPROM_ADDR 0x00006838 -+#define EEPROM_ADDR_WRITE 0x00000000 -+#define EEPROM_ADDR_READ 0x80000000 -+#define EEPROM_ADDR_COMPLETE 0x40000000 -+#define EEPROM_ADDR_FSM_RESET 0x20000000 -+#define EEPROM_ADDR_DEVID_MASK 0x1c000000 -+#define EEPROM_ADDR_DEVID_SHIFT 26 -+#define EEPROM_ADDR_START 0x02000000 -+#define EEPROM_ADDR_CLKPERD_SHIFT 16 -+#define EEPROM_ADDR_ADDR_MASK 0x0000ffff -+#define EEPROM_ADDR_ADDR_SHIFT 0 -+#define EEPROM_DEFAULT_CLOCK_PERIOD 0x60 -+#define EEPROM_CHIP_SIZE (64 * 1024) -+#define GRC_EEPROM_DATA 0x0000683c -+#define GRC_EEPROM_CTRL 0x00006840 -+#define GRC_MDI_CTRL 0x00006844 -+#define GRC_SEEPROM_DELAY 0x00006848 -+/* 0x684c --> 0x6890 unused */ -+#define GRC_VCPU_EXT_CTRL 0x00006890 -+#define GRC_VCPU_EXT_CTRL_HALT_CPU 0x00400000 -+#define GRC_VCPU_EXT_CTRL_DISABLE_WOL 0x20000000 -+#define GRC_FASTBOOT_PC 0x00006894 /* 5752, 5755, 5787 */ -+ -+#define TG3_EAV_REF_CLCK_LSB 0x00006900 -+#define TG3_EAV_REF_CLCK_MSB 0x00006904 -+#define TG3_EAV_REF_CLCK_CTL 0x00006908 -+#define TG3_EAV_REF_CLCK_CTL_STOP 0x00000002 -+#define TG3_EAV_REF_CLCK_CTL_RESUME 0x00000004 -+#define TG3_EAV_CTL_TSYNC_GPIO_MASK (0x3 << 16) -+#define TG3_EAV_CTL_TSYNC_WDOG0 (1 << 17) -+#define TG3_EAV_REF_CLK_CORRECT_CTL 0x00006928 -+#define TG3_EAV_REF_CLK_CORRECT_EN (1 << 31) -+#define TG3_EAV_REF_CLK_CORRECT_NEG (1 << 30) -+ -+#define TG3_EAV_REF_CLK_CORRECT_MASK 0xffffff -+ -+#define TG3_EAV_WATCHDOG0_LSB 0x00006918 -+#define TG3_EAV_WATCHDOG0_MSB 0x0000691c -+#define TG3_EAV_WATCHDOG0_EN (1 << 31) -+#define TG3_EAV_WATCHDOG_MSB_MASK 0x7fffffff -+/* 0x690c --> 0x7000 unused */ -+ -+/* NVRAM Control registers */ -+#define NVRAM_CMD 0x00007000 -+#define NVRAM_CMD_RESET 0x00000001 -+#define NVRAM_CMD_DONE 0x00000008 -+#define NVRAM_CMD_GO 0x00000010 -+#define NVRAM_CMD_WR 0x00000020 -+#define NVRAM_CMD_RD 0x00000000 -+#define NVRAM_CMD_ERASE 0x00000040 -+#define NVRAM_CMD_FIRST 0x00000080 -+#define NVRAM_CMD_LAST 0x00000100 -+#define NVRAM_CMD_WREN 0x00010000 -+#define NVRAM_CMD_WRDI 0x00020000 -+#define NVRAM_STAT 0x00007004 -+#define NVRAM_WRDATA 0x00007008 -+#define NVRAM_ADDR 0x0000700c -+#define NVRAM_ADDR_MSK 0x07ffffff -+#define NVRAM_RDDATA 0x00007010 -+#define NVRAM_CFG1 0x00007014 -+#define NVRAM_CFG1_FLASHIF_ENAB 0x00000001 -+#define NVRAM_CFG1_BUFFERED_MODE 0x00000002 -+#define NVRAM_CFG1_PASS_THRU 0x00000004 -+#define NVRAM_CFG1_STATUS_BITS 0x00000070 -+#define NVRAM_CFG1_BIT_BANG 0x00000008 -+#define NVRAM_CFG1_FLASH_SIZE 0x02000000 -+#define NVRAM_CFG1_COMPAT_BYPASS 0x80000000 -+#define NVRAM_CFG1_VENDOR_MASK 0x03000003 -+#define FLASH_VENDOR_ATMEL_EEPROM 0x02000000 -+#define FLASH_VENDOR_ATMEL_FLASH_BUFFERED 0x02000003 -+#define FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED 0x00000003 -+#define FLASH_VENDOR_ST 0x03000001 -+#define FLASH_VENDOR_SAIFUN 0x01000003 -+#define FLASH_VENDOR_SST_SMALL 0x00000001 -+#define FLASH_VENDOR_SST_LARGE 0x02000001 -+#define NVRAM_CFG1_5752VENDOR_MASK 0x03c00003 -+#define NVRAM_CFG1_5762VENDOR_MASK 0x03e00003 -+#define FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ 0x00000000 -+#define FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ 0x02000000 -+#define FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED 0x02000003 -+#define FLASH_5752VENDOR_ST_M45PE10 0x02400000 -+#define FLASH_5752VENDOR_ST_M45PE20 0x02400002 -+#define FLASH_5752VENDOR_ST_M45PE40 0x02400001 -+#define FLASH_5755VENDOR_ATMEL_FLASH_1 0x03400001 -+#define FLASH_5755VENDOR_ATMEL_FLASH_2 0x03400002 -+#define FLASH_5755VENDOR_ATMEL_FLASH_3 0x03400000 -+#define FLASH_5755VENDOR_ATMEL_FLASH_4 0x00000003 -+#define FLASH_5755VENDOR_ATMEL_FLASH_5 0x02000003 -+#define FLASH_5755VENDOR_ATMEL_EEPROM_64KHZ 0x03c00003 -+#define FLASH_5755VENDOR_ATMEL_EEPROM_376KHZ 0x03c00002 -+#define FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ 0x03000003 -+#define FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ 0x03000002 -+#define FLASH_5787VENDOR_MICRO_EEPROM_64KHZ 0x03000000 -+#define FLASH_5787VENDOR_MICRO_EEPROM_376KHZ 0x02000000 -+#define FLASH_5761VENDOR_ATMEL_MDB021D 0x00800003 -+#define FLASH_5761VENDOR_ATMEL_MDB041D 0x00800000 -+#define FLASH_5761VENDOR_ATMEL_MDB081D 0x00800002 -+#define FLASH_5761VENDOR_ATMEL_MDB161D 0x00800001 -+#define FLASH_5761VENDOR_ATMEL_ADB021D 0x00000003 -+#define FLASH_5761VENDOR_ATMEL_ADB041D 0x00000000 -+#define FLASH_5761VENDOR_ATMEL_ADB081D 0x00000002 -+#define FLASH_5761VENDOR_ATMEL_ADB161D 0x00000001 -+#define FLASH_5761VENDOR_ST_M_M45PE20 0x02800001 -+#define FLASH_5761VENDOR_ST_M_M45PE40 0x02800000 -+#define FLASH_5761VENDOR_ST_M_M45PE80 0x02800002 -+#define FLASH_5761VENDOR_ST_M_M45PE16 0x02800003 -+#define FLASH_5761VENDOR_ST_A_M45PE20 0x02000001 -+#define FLASH_5761VENDOR_ST_A_M45PE40 0x02000000 -+#define FLASH_5761VENDOR_ST_A_M45PE80 0x02000002 -+#define FLASH_5761VENDOR_ST_A_M45PE16 0x02000003 -+#define FLASH_57780VENDOR_ATMEL_AT45DB011D 0x00400000 -+#define FLASH_57780VENDOR_ATMEL_AT45DB011B 0x03400000 -+#define FLASH_57780VENDOR_ATMEL_AT45DB021D 0x00400002 -+#define FLASH_57780VENDOR_ATMEL_AT45DB021B 0x03400002 -+#define FLASH_57780VENDOR_ATMEL_AT45DB041D 0x00400001 -+#define FLASH_57780VENDOR_ATMEL_AT45DB041B 0x03400001 -+#define FLASH_5717VENDOR_ATMEL_EEPROM 0x02000001 -+#define FLASH_5717VENDOR_MICRO_EEPROM 0x02000003 -+#define FLASH_5717VENDOR_ATMEL_MDB011D 0x01000001 -+#define FLASH_5717VENDOR_ATMEL_MDB021D 0x01000003 -+#define FLASH_5717VENDOR_ST_M_M25PE10 0x02000000 -+#define FLASH_5717VENDOR_ST_M_M25PE20 0x02000002 -+#define FLASH_5717VENDOR_ST_M_M45PE10 0x00000001 -+#define FLASH_5717VENDOR_ST_M_M45PE20 0x00000003 -+#define FLASH_5717VENDOR_ATMEL_ADB011B 0x01400000 -+#define FLASH_5717VENDOR_ATMEL_ADB021B 0x01400002 -+#define FLASH_5717VENDOR_ATMEL_ADB011D 0x01400001 -+#define FLASH_5717VENDOR_ATMEL_ADB021D 0x01400003 -+#define FLASH_5717VENDOR_ST_A_M25PE10 0x02400000 -+#define FLASH_5717VENDOR_ST_A_M25PE20 0x02400002 -+#define FLASH_5717VENDOR_ST_A_M45PE10 0x02400001 -+#define FLASH_5717VENDOR_ST_A_M45PE20 0x02400003 -+#define FLASH_5717VENDOR_ATMEL_45USPT 0x03400000 -+#define FLASH_5717VENDOR_ST_25USPT 0x03400002 -+#define FLASH_5717VENDOR_ST_45USPT 0x03400001 -+#define FLASH_5720_EEPROM_HD 0x00000001 -+#define FLASH_5720_EEPROM_LD 0x00000003 -+#define FLASH_5762_EEPROM_HD 0x02000001 -+#define FLASH_5762_EEPROM_LD 0x02000003 -+#define FLASH_5762_MX25L_100 0x00800000 -+#define FLASH_5762_MX25L_200 0x00800002 -+#define FLASH_5762_MX25L_400 0x00800001 -+#define FLASH_5762_MX25L_800 0x00800003 -+#define FLASH_5762_MX25L_160_320 0x03800002 -+#define FLASH_5720VENDOR_M_ATMEL_DB011D 0x01000000 -+#define FLASH_5720VENDOR_M_ATMEL_DB021D 0x01000002 -+#define FLASH_5720VENDOR_M_ATMEL_DB041D 0x01000001 -+#define FLASH_5720VENDOR_M_ATMEL_DB081D 0x01000003 -+#define FLASH_5720VENDOR_M_ST_M25PE10 0x02000000 -+#define FLASH_5720VENDOR_M_ST_M25PE20 0x02000002 -+#define FLASH_5720VENDOR_M_ST_M25PE40 0x02000001 -+#define FLASH_5720VENDOR_M_ST_M25PE80 0x02000003 -+#define FLASH_5720VENDOR_M_ST_M45PE10 0x03000000 -+#define FLASH_5720VENDOR_M_ST_M45PE20 0x03000002 -+#define FLASH_5720VENDOR_M_ST_M45PE40 0x03000001 -+#define FLASH_5720VENDOR_M_ST_M45PE80 0x03000003 -+#define FLASH_5720VENDOR_A_ATMEL_DB011B 0x01800000 -+#define FLASH_5720VENDOR_A_ATMEL_DB021B 0x01800002 -+#define FLASH_5720VENDOR_A_ATMEL_DB041B 0x01800001 -+#define FLASH_5720VENDOR_A_ATMEL_DB011D 0x01c00000 -+#define FLASH_5720VENDOR_A_ATMEL_DB021D 0x01c00002 -+#define FLASH_5720VENDOR_A_ATMEL_DB041D 0x01c00001 -+#define FLASH_5720VENDOR_A_ATMEL_DB081D 0x01c00003 -+#define FLASH_5720VENDOR_A_ST_M25PE10 0x02800000 -+#define FLASH_5720VENDOR_A_ST_M25PE20 0x02800002 -+#define FLASH_5720VENDOR_A_ST_M25PE40 0x02800001 -+#define FLASH_5720VENDOR_A_ST_M25PE80 0x02800003 -+#define FLASH_5720VENDOR_A_ST_M45PE10 0x02c00000 -+#define FLASH_5720VENDOR_A_ST_M45PE20 0x02c00002 -+#define FLASH_5720VENDOR_A_ST_M45PE40 0x02c00001 -+#define FLASH_5720VENDOR_A_ST_M45PE80 0x02c00003 -+#define FLASH_5720VENDOR_ATMEL_45USPT 0x03c00000 -+#define FLASH_5720VENDOR_ST_25USPT 0x03c00002 -+#define FLASH_5720VENDOR_ST_45USPT 0x03c00001 -+#define NVRAM_CFG1_5752PAGE_SIZE_MASK 0x70000000 -+#define FLASH_5752PAGE_SIZE_256 0x00000000 -+#define FLASH_5752PAGE_SIZE_512 0x10000000 -+#define FLASH_5752PAGE_SIZE_1K 0x20000000 -+#define FLASH_5752PAGE_SIZE_2K 0x30000000 -+#define FLASH_5752PAGE_SIZE_4K 0x40000000 -+#define FLASH_5752PAGE_SIZE_264 0x50000000 -+#define FLASH_5752PAGE_SIZE_528 0x60000000 -+#define NVRAM_CFG2 0x00007018 -+#define NVRAM_CFG3 0x0000701c -+#define NVRAM_SWARB 0x00007020 -+#define SWARB_REQ_SET0 0x00000001 -+#define SWARB_REQ_SET1 0x00000002 -+#define SWARB_REQ_SET2 0x00000004 -+#define SWARB_REQ_SET3 0x00000008 -+#define SWARB_REQ_CLR0 0x00000010 -+#define SWARB_REQ_CLR1 0x00000020 -+#define SWARB_REQ_CLR2 0x00000040 -+#define SWARB_REQ_CLR3 0x00000080 -+#define SWARB_GNT0 0x00000100 -+#define SWARB_GNT1 0x00000200 -+#define SWARB_GNT2 0x00000400 -+#define SWARB_GNT3 0x00000800 -+#define SWARB_REQ0 0x00001000 -+#define SWARB_REQ1 0x00002000 -+#define SWARB_REQ2 0x00004000 -+#define SWARB_REQ3 0x00008000 -+#define NVRAM_ACCESS 0x00007024 -+#define ACCESS_ENABLE 0x00000001 -+#define ACCESS_WR_ENABLE 0x00000002 -+#define NVRAM_WRITE1 0x00007028 -+/* 0x702c unused */ -+ -+#define NVRAM_ADDR_LOCKOUT 0x00007030 -+#define NVRAM_AUTOSENSE_STATUS 0x00007038 -+#define AUTOSENSE_DEVID 0x00000010 -+#define AUTOSENSE_DEVID_MASK 0x00000007 -+#define AUTOSENSE_SIZE_IN_MB 17 -+/* 0x703c --> 0x7500 unused */ -+ -+#define OTP_MODE 0x00007500 -+#define OTP_MODE_OTP_THRU_GRC 0x00000001 -+#define OTP_CTRL 0x00007504 -+#define OTP_CTRL_OTP_PROG_ENABLE 0x00200000 -+#define OTP_CTRL_OTP_CMD_READ 0x00000000 -+#define OTP_CTRL_OTP_CMD_INIT 0x00000008 -+#define OTP_CTRL_OTP_CMD_START 0x00000001 -+#define OTP_STATUS 0x00007508 -+#define OTP_STATUS_CMD_DONE 0x00000001 -+#define OTP_ADDRESS 0x0000750c -+#define OTP_ADDRESS_MAGIC1 0x000000a0 -+#define OTP_ADDRESS_MAGIC2 0x00000080 -+/* 0x7510 unused */ -+ -+#define OTP_READ_DATA 0x00007514 -+/* 0x7518 --> 0x7c04 unused */ -+ -+#define PCIE_TRANSACTION_CFG 0x00007c04 -+#define PCIE_TRANS_CFG_1SHOT_MSI 0x20000000 -+#define PCIE_TRANS_CFG_LOM 0x00000020 -+/* 0x7c08 --> 0x7d28 unused */ -+ -+#define PCIE_PWR_MGMT_THRESH 0x00007d28 -+#define PCIE_PWR_MGMT_L1_THRESH_MSK 0x0000ff00 -+#define PCIE_PWR_MGMT_L1_THRESH_4MS 0x0000ff00 -+#define PCIE_PWR_MGMT_EXT_ASPM_TMR_EN 0x01000000 -+/* 0x7d2c --> 0x7d54 unused */ -+ -+#define TG3_PCIE_LNKCTL 0x00007d54 -+#define TG3_PCIE_LNKCTL_L1_PLL_PD_EN 0x00000008 -+#define TG3_PCIE_LNKCTL_L1_PLL_PD_DIS 0x00000080 -+/* 0x7d58 --> 0x7e70 unused */ -+ -+#define TG3_PCIE_PHY_TSTCTL 0x00007e2c -+#define TG3_PCIE_PHY_TSTCTL_PCIE10 0x00000040 -+#define TG3_PCIE_PHY_TSTCTL_PSCRAM 0x00000020 -+ -+#define TG3_PCIE_EIDLE_DELAY 0x00007e70 -+#define TG3_PCIE_EIDLE_DELAY_MASK 0x0000001f -+#define TG3_PCIE_EIDLE_DELAY_13_CLKS 0x0000000c -+/* 0x7e74 --> 0x8000 unused */ -+ -+/* Alternate PCIE definitions */ -+#define TG3_PCIE_TLDLPL_PORT 0x00007c00 -+#define TG3_PCIE_DL_LO_FTSMAX 0x0000000c -+#define TG3_PCIE_DL_LO_FTSMAX_MSK 0x000000ff -+#define TG3_PCIE_DL_LO_FTSMAX_VAL 0x0000002c -+#define TG3_PCIE_PL_LO_PHYCTL1 0x00000004 -+#define TG3_PCIE_PL_LO_PHYCTL1_L1PLLPD_EN 0x00001000 -+#define TG3_PCIE_PL_LO_PHYCTL5 0x00000014 -+#define TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ 0x80000000 -+ -+#define TG3_REG_BLK_SIZE 0x00008000 -+ -+/* OTP bit definitions */ -+#define TG3_OTP_AGCTGT_MASK 0x000000e0 -+#define TG3_OTP_AGCTGT_SHIFT 1 -+#define TG3_OTP_HPFFLTR_MASK 0x00000300 -+#define TG3_OTP_HPFFLTR_SHIFT 1 -+#define TG3_OTP_HPFOVER_MASK 0x00000400 -+#define TG3_OTP_HPFOVER_SHIFT 1 -+#define TG3_OTP_LPFDIS_MASK 0x00000800 -+#define TG3_OTP_LPFDIS_SHIFT 11 -+#define TG3_OTP_VDAC_MASK 0xff000000 -+#define TG3_OTP_VDAC_SHIFT 24 -+#define TG3_OTP_10BTAMP_MASK 0x0000f000 -+#define TG3_OTP_10BTAMP_SHIFT 8 -+#define TG3_OTP_ROFF_MASK 0x00e00000 -+#define TG3_OTP_ROFF_SHIFT 11 -+#define TG3_OTP_RCOFF_MASK 0x001c0000 -+#define TG3_OTP_RCOFF_SHIFT 16 -+ -+#define TG3_OTP_DEFAULT 0x286c1640 -+ -+ -+/* Hardware Legacy NVRAM layout */ -+#define TG3_NVM_VPD_OFF 0x100 -+#define TG3_NVM_VPD_LEN 256 -+ -+/* Hardware Selfboot NVRAM layout */ -+#define TG3_NVM_HWSB_CFG1 0x00000004 -+#define TG3_NVM_HWSB_CFG1_MAJMSK 0xf8000000 -+#define TG3_NVM_HWSB_CFG1_MAJSFT 27 -+#define TG3_NVM_HWSB_CFG1_MINMSK 0x07c00000 -+#define TG3_NVM_HWSB_CFG1_MINSFT 22 -+ -+#define TG3_EEPROM_MAGIC 0x669955aa -+#define TG3_EEPROM_MAGIC_FW 0xa5000000 -+#define TG3_EEPROM_MAGIC_FW_MSK 0xff000000 -+#define TG3_EEPROM_SB_FORMAT_MASK 0x00e00000 -+#define TG3_EEPROM_SB_FORMAT_1 0x00200000 -+#define TG3_EEPROM_SB_REVISION_MASK 0x001f0000 -+#define TG3_EEPROM_SB_REVISION_0 0x00000000 -+#define TG3_EEPROM_SB_REVISION_2 0x00020000 -+#define TG3_EEPROM_SB_REVISION_3 0x00030000 -+#define TG3_EEPROM_SB_REVISION_4 0x00040000 -+#define TG3_EEPROM_SB_REVISION_5 0x00050000 -+#define TG3_EEPROM_SB_REVISION_6 0x00060000 -+#define TG3_EEPROM_MAGIC_HW 0xabcd -+#define TG3_EEPROM_MAGIC_HW_MSK 0xffff -+ -+#define TG3_NVM_DIR_START 0x18 -+#define TG3_NVM_DIR_END 0x78 -+#define TG3_NVM_DIRENT_SIZE 0xc -+#define TG3_NVM_DIRTYPE_SHIFT 24 -+#define TG3_NVM_DIRTYPE_LENMSK 0x003fffff -+#define TG3_NVM_DIRTYPE_ASFINI 1 -+#define TG3_NVM_DIRTYPE_EXTVPD 20 -+#define TG3_NVM_PTREV_BCVER 0x94 -+#define TG3_NVM_BCVER_MAJMSK 0x0000ff00 -+#define TG3_NVM_BCVER_MAJSFT 8 -+#define TG3_NVM_BCVER_MINMSK 0x000000ff -+ -+#define TG3_EEPROM_SB_F1R0_EDH_OFF 0x10 -+#define TG3_EEPROM_SB_F1R2_EDH_OFF 0x14 -+#define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10 -+#define TG3_EEPROM_SB_F1R3_EDH_OFF 0x18 -+#define TG3_EEPROM_SB_F1R4_EDH_OFF 0x1c -+#define TG3_EEPROM_SB_F1R5_EDH_OFF 0x20 -+#define TG3_EEPROM_SB_F1R6_EDH_OFF 0x4c -+#define TG3_EEPROM_SB_EDH_MAJ_MASK 0x00000700 -+#define TG3_EEPROM_SB_EDH_MAJ_SHFT 8 -+#define TG3_EEPROM_SB_EDH_MIN_MASK 0x000000ff -+#define TG3_EEPROM_SB_EDH_BLD_MASK 0x0000f800 -+#define TG3_EEPROM_SB_EDH_BLD_SHFT 11 -+ -+ -+/* 32K Window into NIC internal memory */ -+#define NIC_SRAM_WIN_BASE 0x00008000 -+ -+/* Offsets into first 32k of NIC internal memory. */ -+#define NIC_SRAM_PAGE_ZERO 0x00000000 -+#define NIC_SRAM_SEND_RCB 0x00000100 /* 16 * TG3_BDINFO_... */ -+#define NIC_SRAM_RCV_RET_RCB 0x00000200 /* 16 * TG3_BDINFO_... */ -+#define NIC_SRAM_STATS_BLK 0x00000300 -+#define NIC_SRAM_STATUS_BLK 0x00000b00 -+ -+#define NIC_SRAM_FIRMWARE_MBOX 0x00000b50 -+#define NIC_SRAM_FIRMWARE_MBOX_MAGIC1 0x4B657654 -+#define NIC_SRAM_FIRMWARE_MBOX_MAGIC2 0x4861764b /* !dma on linkchg */ -+ -+#define NIC_SRAM_DATA_SIG 0x00000b54 -+#define NIC_SRAM_DATA_SIG_MAGIC 0x4b657654 /* ascii for 'KevT' */ -+ -+#define NIC_SRAM_DATA_CFG 0x00000b58 -+#define NIC_SRAM_DATA_CFG_LED_MODE_MASK 0x0000000c -+#define NIC_SRAM_DATA_CFG_LED_MODE_MAC 0x00000000 -+#define NIC_SRAM_DATA_CFG_LED_MODE_PHY_1 0x00000004 -+#define NIC_SRAM_DATA_CFG_LED_MODE_PHY_2 0x00000008 -+#define NIC_SRAM_DATA_CFG_PHY_TYPE_MASK 0x00000030 -+#define NIC_SRAM_DATA_CFG_PHY_TYPE_UNKNOWN 0x00000000 -+#define NIC_SRAM_DATA_CFG_PHY_TYPE_COPPER 0x00000010 -+#define NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER 0x00000020 -+#define NIC_SRAM_DATA_CFG_WOL_ENABLE 0x00000040 -+#define NIC_SRAM_DATA_CFG_ASF_ENABLE 0x00000080 -+#define NIC_SRAM_DATA_CFG_EEPROM_WP 0x00000100 -+#define NIC_SRAM_DATA_CFG_MINI_PCI 0x00001000 -+#define NIC_SRAM_DATA_CFG_FIBER_WOL 0x00004000 -+#define NIC_SRAM_DATA_CFG_NO_GPIO2 0x00100000 -+#define NIC_SRAM_DATA_CFG_APE_ENABLE 0x00200000 -+ -+#define NIC_SRAM_DATA_VER 0x00000b5c -+#define NIC_SRAM_DATA_VER_SHIFT 16 -+ -+#define NIC_SRAM_DATA_PHY_ID 0x00000b74 -+#define NIC_SRAM_DATA_PHY_ID1_MASK 0xffff0000 -+#define NIC_SRAM_DATA_PHY_ID2_MASK 0x0000ffff -+ -+#define NIC_SRAM_FW_CMD_MBOX 0x00000b78 -+#define FWCMD_NICDRV_ALIVE 0x00000001 -+#define FWCMD_NICDRV_PAUSE_FW 0x00000002 -+#define FWCMD_NICDRV_IPV4ADDR_CHG 0x00000003 -+#define FWCMD_NICDRV_IPV6ADDR_CHG 0x00000004 -+#define FWCMD_NICDRV_FIX_DMAR 0x00000005 -+#define FWCMD_NICDRV_FIX_DMAW 0x00000006 -+#define FWCMD_NICDRV_LINK_UPDATE 0x0000000c -+#define FWCMD_NICDRV_ALIVE2 0x0000000d -+#define FWCMD_NICDRV_ALIVE3 0x0000000e -+#define NIC_SRAM_FW_CMD_LEN_MBOX 0x00000b7c -+#define NIC_SRAM_FW_CMD_DATA_MBOX 0x00000b80 -+#define NIC_SRAM_FW_ASF_STATUS_MBOX 0x00000c00 -+#define NIC_SRAM_FW_DRV_STATE_MBOX 0x00000c04 -+#define DRV_STATE_START 0x00000001 -+#define DRV_STATE_START_DONE 0x80000001 -+#define DRV_STATE_UNLOAD 0x00000002 -+#define DRV_STATE_UNLOAD_DONE 0x80000002 -+#define DRV_STATE_WOL 0x00000003 -+#define DRV_STATE_SUSPEND 0x00000004 -+ -+#define NIC_SRAM_FW_RESET_TYPE_MBOX 0x00000c08 -+ -+#define NIC_SRAM_MAC_ADDR_HIGH_MBOX 0x00000c14 -+#define NIC_SRAM_MAC_ADDR_LOW_MBOX 0x00000c18 -+ -+#define NIC_SRAM_WOL_MBOX 0x00000d30 -+#define WOL_SIGNATURE 0x474c0000 -+#define WOL_DRV_STATE_SHUTDOWN 0x00000001 -+#define WOL_DRV_WOL 0x00000002 -+#define WOL_SET_MAGIC_PKT 0x00000004 -+ -+#define NIC_SRAM_DATA_CFG_2 0x00000d38 -+ -+#define NIC_SRAM_DATA_CFG_2_APD_EN 0x00004000 -+#define SHASTA_EXT_LED_MODE_MASK 0x00018000 -+#define SHASTA_EXT_LED_LEGACY 0x00000000 -+#define SHASTA_EXT_LED_SHARED 0x00008000 -+#define SHASTA_EXT_LED_MAC 0x00010000 -+#define SHASTA_EXT_LED_COMBO 0x00018000 -+ -+#define NIC_SRAM_DATA_CFG_3 0x00000d3c -+#define NIC_SRAM_ASPM_DEBOUNCE 0x00000002 -+#define NIC_SRAM_LNK_FLAP_AVOID 0x00400000 -+#define NIC_SRAM_1G_ON_VAUX_OK 0x00800000 -+ -+#define NIC_SRAM_DATA_CFG_4 0x00000d60 -+#define NIC_SRAM_GMII_MODE 0x00000002 -+#define NIC_SRAM_RGMII_INBAND_DISABLE 0x00000004 -+#define NIC_SRAM_RGMII_EXT_IBND_RX_EN 0x00000008 -+#define NIC_SRAM_RGMII_EXT_IBND_TX_EN 0x00000010 -+ -+#define NIC_SRAM_CPMU_STATUS 0x00000e00 -+#define NIC_SRAM_CPMUSTAT_SIG 0x0000362c -+#define NIC_SRAM_CPMUSTAT_SIG_MSK 0x0000ffff -+ -+#define NIC_SRAM_DATA_CFG_5 0x00000e0c -+#define NIC_SRAM_DISABLE_1G_HALF_ADV 0x00000002 -+ -+#define NIC_SRAM_RX_MINI_BUFFER_DESC 0x00001000 -+ -+#define NIC_SRAM_DMA_DESC_POOL_BASE 0x00002000 -+#define NIC_SRAM_DMA_DESC_POOL_SIZE 0x00002000 -+#define NIC_SRAM_TX_BUFFER_DESC 0x00004000 /* 512 entries */ -+#define NIC_SRAM_RX_BUFFER_DESC 0x00006000 /* 256 entries */ -+#define NIC_SRAM_RX_JUMBO_BUFFER_DESC 0x00007000 /* 256 entries */ -+#define NIC_SRAM_MBUF_POOL_BASE 0x00008000 -+#define NIC_SRAM_MBUF_POOL_SIZE96 0x00018000 -+#define NIC_SRAM_MBUF_POOL_SIZE64 0x00010000 -+#define NIC_SRAM_MBUF_POOL_BASE5705 0x00010000 -+#define NIC_SRAM_MBUF_POOL_SIZE5705 0x0000e000 -+ -+#define TG3_SRAM_RXCPU_SCRATCH_BASE_57766 0x00030000 -+#define TG3_SRAM_RXCPU_SCRATCH_SIZE_57766 0x00010000 -+#define TG3_SBROM_IN_SERVICE_LOOP 0x51 -+ -+#define TG3_SRAM_RX_STD_BDCACHE_SIZE_5700 128 -+#define TG3_SRAM_RX_STD_BDCACHE_SIZE_5755 64 -+#define TG3_SRAM_RX_STD_BDCACHE_SIZE_5906 32 -+ -+#define TG3_SRAM_RX_JMB_BDCACHE_SIZE_5700 64 -+#define TG3_SRAM_RX_JMB_BDCACHE_SIZE_5717 16 -+ -+ -+/* Currently this is fixed. */ -+#define TG3_PHY_PCIE_ADDR 0x00 -+#define TG3_PHY_MII_ADDR 0x01 -+ -+ -+/*** Tigon3 specific PHY MII registers. ***/ -+#define MII_TG3_MMD_CTRL 0x0d /* MMD Access Control register */ -+#define MII_TG3_MMD_CTRL_DATA_NOINC 0x4000 -+#define MII_TG3_MMD_ADDRESS 0x0e /* MMD Address Data register */ -+ -+#define MII_TG3_EXT_CTRL 0x10 /* Extended control register */ -+#define MII_TG3_EXT_CTRL_FIFO_ELASTIC 0x0001 -+#define MII_TG3_EXT_CTRL_LNK3_LED_MODE 0x0002 -+#define MII_TG3_EXT_CTRL_FORCE_LED_OFF 0x0008 -+#define MII_TG3_EXT_CTRL_TBI 0x8000 -+ -+#define MII_TG3_EXT_STAT 0x11 /* Extended status register */ -+#define MII_TG3_EXT_STAT_MDIX 0x2000 -+#define MII_TG3_EXT_STAT_LPASS 0x0100 -+ -+#define MII_TG3_RXR_COUNTERS 0x14 /* Local/Remote Receiver Counts */ -+#define MII_TG3_DSP_RW_PORT 0x15 /* DSP coefficient read/write port */ -+#define MII_TG3_DSP_CONTROL 0x16 /* DSP control register */ -+#define MII_TG3_DSP_ADDRESS 0x17 /* DSP address register */ -+ -+#define MII_TG3_DSP_TAP1 0x0001 -+#define MII_TG3_DSP_TAP1_AGCTGT_DFLT 0x0007 -+#define MII_TG3_DSP_TAP26 0x001a -+#define MII_TG3_DSP_TAP26_ALNOKO 0x0001 -+#define MII_TG3_DSP_TAP26_RMRXSTO 0x0002 -+#define MII_TG3_DSP_TAP26_OPCSINPT 0x0004 -+#define MII_TG3_DSP_AADJ1CH0 0x001f -+#define MII_TG3_DSP_CH34TP2 0x4022 -+#define MII_TG3_DSP_CH34TP2_HIBW01 0x01ff -+#define MII_TG3_DSP_AADJ1CH3 0x601f -+#define MII_TG3_DSP_AADJ1CH3_ADCCKADJ 0x0002 -+#define MII_TG3_DSP_TLER 0x0d40 /* Top Level Expansion reg */ -+#define MII_TG3_DSP_TLER_AUTOGREEEN_EN 0x0001 -+#define MII_TG3_DSP_EXP1_INT_STAT 0x0f01 -+#define MII_TG3_DSP_EXP8 0x0f08 -+#define MII_TG3_DSP_EXP8_REJ2MHz 0x0001 -+#define MII_TG3_DSP_EXP8_AEDW 0x0200 -+#define MII_TG3_DSP_EXP75 0x0f75 -+#define MII_TG3_DSP_EXP75_SUP_CM_OSC 0x0001 -+#define MII_TG3_DSP_EXP96 0x0f96 -+#define MII_TG3_DSP_EXP97 0x0f97 -+ -+#define MII_TG3_AUX_CTRL 0x18 /* auxilliary control register */ -+ -+#define MII_TG3_AUXCTL_SHDWSEL_AUXCTL 0x0000 -+#define MII_TG3_AUXCTL_ACTL_TX_6DB 0x0400 -+#define MII_TG3_AUXCTL_ACTL_SMDSP_ENA 0x0800 -+#define MII_TG3_AUXCTL_ACTL_EXTPKTLEN 0x4000 -+#define MII_TG3_AUXCTL_ACTL_EXTLOOPBK 0x8000 -+ -+#define MII_TG3_AUXCTL_SHDWSEL_PWRCTL 0x0002 -+#define MII_TG3_AUXCTL_PCTL_WOL_EN 0x0008 -+#define MII_TG3_AUXCTL_PCTL_100TX_LPWR 0x0010 -+#define MII_TG3_AUXCTL_PCTL_SPR_ISOLATE 0x0020 -+#define MII_TG3_AUXCTL_PCTL_CL_AB_TXDAC 0x0040 -+#define MII_TG3_AUXCTL_PCTL_VREG_11V 0x0180 -+ -+#define MII_TG3_AUXCTL_SHDWSEL_MISCTEST 0x0004 -+ -+#define MII_TG3_AUXCTL_SHDWSEL_MISC 0x0007 -+#define MII_TG3_AUXCTL_MISC_WIRESPD_EN 0x0010 -+#define MII_TG3_AUXCTL_MISC_RGMII_OOBSC 0x0020 -+#define MII_TG3_AUXCTL_MISC_FORCE_AMDIX 0x0200 -+#define MII_TG3_AUXCTL_MISC_RDSEL_SHIFT 12 -+#define MII_TG3_AUXCTL_MISC_WREN 0x8000 -+ -+#define MII_TG3_AUX_STAT 0x19 /* auxilliary status register */ -+#define MII_TG3_AUX_STAT_LPASS 0x0004 -+#define MII_TG3_AUX_STAT_SPDMASK 0x0700 -+#define MII_TG3_AUX_STAT_10HALF 0x0100 -+#define MII_TG3_AUX_STAT_10FULL 0x0200 -+#define MII_TG3_AUX_STAT_100HALF 0x0300 -+#define MII_TG3_AUX_STAT_100_4 0x0400 -+#define MII_TG3_AUX_STAT_100FULL 0x0500 -+#define MII_TG3_AUX_STAT_1000HALF 0x0600 -+#define MII_TG3_AUX_STAT_1000FULL 0x0700 -+#define MII_TG3_AUX_STAT_100 0x0008 -+#define MII_TG3_AUX_STAT_FULL 0x0001 -+ -+#define MII_TG3_ISTAT 0x1a /* IRQ status register */ -+#define MII_TG3_IMASK 0x1b /* IRQ mask register */ -+ -+/* ISTAT/IMASK event bits */ -+#define MII_TG3_INT_LINKCHG 0x0002 -+#define MII_TG3_INT_SPEEDCHG 0x0004 -+#define MII_TG3_INT_DUPLEXCHG 0x0008 -+#define MII_TG3_INT_ANEG_PAGE_RX 0x0400 -+ -+#define MII_TG3_MISC_SHDW 0x1c /* Misc shadow register */ -+#define MII_TG3_MISC_SHDW_WREN 0x8000 -+ -+#define MII_TG3_MISC_SHDW_SCR5_C125OE 0x0001 -+#define MII_TG3_MISC_SHDW_SCR5_DLLAPD 0x0002 -+#define MII_TG3_MISC_SHDW_SCR5_SDTL 0x0004 -+#define MII_TG3_MISC_SHDW_SCR5_DLPTLM 0x0008 -+#define MII_TG3_MISC_SHDW_SCR5_LPED 0x0010 -+#define MII_TG3_MISC_SHDW_SCR5_TRDDAPD 0x0100 -+#define MII_TG3_MISC_SHDW_SCR5_SEL 0x1400 -+ -+#define MII_TG3_MISC_SHDW_APD_WKTM_84MS 0x0001 -+#define MII_TG3_MISC_SHDW_APD_ENABLE 0x0020 -+#define MII_TG3_MISC_SHDW_APD_SEL 0x2800 -+ -+#define MII_TG3_MISC_SHDW_RGMII_MODESEL0 0x0008 -+#define MII_TG3_MISC_SHDW_RGMII_MODESEL1 0x0010 -+#define MII_TG3_MISC_SHDW_RGMII_SEL 0x2c00 -+ -+#define MII_TG3_TEST1 0x1e -+#define MII_TG3_TEST1_TRIM_EN 0x0010 -+#define MII_TG3_TEST1_CRC_EN 0x8000 -+ -+/* Clause 45 expansion registers */ -+#define TG3_CL45_D7_EEEADV_CAP 0x003c -+#define TG3_CL45_D7_EEEADV_CAP_100TX 0x0002 -+#define TG3_CL45_D7_EEEADV_CAP_1000T 0x0004 -+#define TG3_CL45_D7_EEERES_STAT 0x803e -+#define TG3_CL45_D7_EEERES_STAT_LP_100TX 0x0002 -+#define TG3_CL45_D7_EEERES_STAT_LP_1000T 0x0004 -+ -+ -+/* Fast Ethernet Tranceiver definitions */ -+#define MII_TG3_FET_PTEST 0x17 -+#define MII_TG3_FET_PTEST_TRIM_SEL 0x0010 -+#define MII_TG3_FET_PTEST_TRIM_2 0x0002 -+#define MII_TG3_FET_PTEST_FRC_TX_LINK 0x1000 -+#define MII_TG3_FET_PTEST_FRC_TX_LOCK 0x0800 -+ -+#define MII_TG3_FET_GEN_STAT 0x1c -+#define MII_TG3_FET_GEN_STAT_MDIXSTAT 0x2000 -+ -+#define MII_TG3_FET_TEST 0x1f -+#define MII_TG3_FET_SHADOW_EN 0x0080 -+ -+#define MII_TG3_FET_SHDW_MISCCTRL 0x10 -+#define MII_TG3_FET_SHDW_MISCCTRL_ELBK 0x1000 -+#define MII_TG3_FET_SHDW_MISCCTRL_MDIX 0x4000 -+ -+#define MII_TG3_FET_SHDW_AUXMODE4 0x1a -+#define MII_TG3_FET_SHDW_AM4_LED_MODE1 0x0001 -+#define MII_TG3_FET_SHDW_AM4_LED_MASK 0x0003 -+#define MII_TG3_FET_SHDW_AUXMODE4_SBPD 0x0008 -+ -+#define MII_TG3_FET_SHDW_AUXSTAT2 0x1b -+#define MII_TG3_FET_SHDW_AUXSTAT2_APD 0x0020 -+ -+/* Serdes PHY Register Definitions */ -+#define SERDES_TG3_1000X_STATUS 0x14 -+#define SERDES_TG3_SGMII_MODE 0x0001 -+#define SERDES_TG3_LINK_UP 0x0002 -+#define SERDES_TG3_FULL_DUPLEX 0x0004 -+#define SERDES_TG3_SPEED_100 0x0008 -+#define SERDES_TG3_SPEED_1000 0x0010 -+ -+/* APE registers. Accessible through BAR1 */ -+#define TG3_APE_GPIO_MSG 0x0008 -+#define TG3_APE_GPIO_MSG_SHIFT 4 -+#define TG3_APE_EVENT 0x000c -+#define APE_EVENT_1 0x00000001 -+#define TG3_APE_LOCK_REQ 0x002c -+#define APE_LOCK_REQ_DRIVER 0x00001000 -+#define TG3_APE_LOCK_GRANT 0x004c -+#define APE_LOCK_GRANT_DRIVER 0x00001000 -+#define TG3_APE_STICKY_TMR 0x00b0 -+#define TG3_APE_OTP_CTRL 0x00e8 -+#define APE_OTP_CTRL_PROG_EN 0x200000 -+#define APE_OTP_CTRL_CMD_RD 0x000000 -+#define APE_OTP_CTRL_START 0x000001 -+#define TG3_APE_OTP_STATUS 0x00ec -+#define APE_OTP_STATUS_CMD_DONE 0x000001 -+#define TG3_APE_OTP_ADDR 0x00f0 -+#define APE_OTP_ADDR_CPU_ENABLE 0x80000000 -+#define TG3_APE_OTP_RD_DATA 0x00f8 -+ -+#define OTP_ADDRESS_MAGIC0 0x00000050 -+#define TG3_OTP_MAGIC0_VALID(val) \ -+ ((((val) & 0xf0000000) == 0xa0000000) ||\ -+ (((val) & 0x0f000000) == 0x0a000000)) -+ -+/* APE shared memory. Accessible through BAR1 */ -+#define TG3_APE_SHMEM_BASE 0x4000 -+#define TG3_APE_SEG_SIG 0x4000 -+#define APE_SEG_SIG_MAGIC 0x41504521 -+#define TG3_APE_FW_STATUS 0x400c -+#define APE_FW_STATUS_READY 0x00000100 -+#define TG3_APE_FW_FEATURES 0x4010 -+#define TG3_APE_FW_FEATURE_NCSI 0x00000002 -+#define TG3_APE_FW_VERSION 0x4018 -+#define APE_FW_VERSION_MAJMSK 0xff000000 -+#define APE_FW_VERSION_MAJSFT 24 -+#define APE_FW_VERSION_MINMSK 0x00ff0000 -+#define APE_FW_VERSION_MINSFT 16 -+#define APE_FW_VERSION_REVMSK 0x0000ff00 -+#define APE_FW_VERSION_REVSFT 8 -+#define APE_FW_VERSION_BLDMSK 0x000000ff -+#define TG3_APE_SEG_MSG_BUF_OFF 0x401c -+#define TG3_APE_SEG_MSG_BUF_LEN 0x4020 -+#define TG3_APE_HOST_SEG_SIG 0x4200 -+#define APE_HOST_SEG_SIG_MAGIC 0x484f5354 -+#define TG3_APE_HOST_SEG_LEN 0x4204 -+#define APE_HOST_SEG_LEN_MAGIC 0x00000020 -+#define TG3_APE_HOST_INIT_COUNT 0x4208 -+#define TG3_APE_HOST_DRIVER_ID 0x420c -+#define APE_HOST_DRIVER_ID_LINUX 0xf0000000 -+#define APE_HOST_DRIVER_ID_ESX 0xfa000000 -+#if !defined(__VMKLNX__) -+#define APE_HOST_DRIVER_ID_MAGIC(maj, min, rev) \ -+ (APE_HOST_DRIVER_ID_LINUX | (maj & 0xff) << 16 | (min & 0xff) << 8 |\ -+ (rev & 0xff)) -+#else -+#define APE_HOST_DRIVER_ID_MAGIC(maj, min, rev) \ -+ (APE_HOST_DRIVER_ID_ESX | (maj & 0xff) << 16 | (min & 0xff) << 8 |\ -+ (rev & 0xff)) -+#endif -+#define TG3_APE_HOST_BEHAVIOR 0x4210 -+#define APE_HOST_BEHAV_NO_PHYLOCK 0x00000001 -+#define TG3_APE_HOST_HEARTBEAT_INT_MS 0x4214 -+#define APE_HOST_HEARTBEAT_INT_DISABLE 0 -+#define APE_HOST_HEARTBEAT_INT_5SEC 5000 -+#define TG3_APE_HOST_HEARTBEAT_COUNT 0x4218 -+#define TG3_APE_HOST_DRVR_STATE 0x421c -+#define TG3_APE_HOST_DRVR_STATE_START 0x00000001 -+#define TG3_APE_HOST_DRVR_STATE_UNLOAD 0x00000002 -+#define TG3_APE_HOST_DRVR_STATE_WOL 0x00000003 -+#define TG3_APE_HOST_WOL_SPEED 0x4224 -+#define TG3_APE_HOST_WOL_SPEED_AUTO 0x00008000 -+ -+#define TG3_APE_EVENT_STATUS 0x4300 -+ -+#define APE_EVENT_STATUS_DRIVER_EVNT 0x00000010 -+#define APE_EVENT_STATUS_STATE_CHNGE 0x00000500 -+#define APE_EVENT_STATUS_SCRTCHPD_READ 0x00001600 -+#define APE_EVENT_STATUS_SCRTCHPD_WRITE 0x00001700 -+#define APE_EVENT_STATUS_STATE_START 0x00010000 -+#define APE_EVENT_STATUS_STATE_UNLOAD 0x00020000 -+#define APE_EVENT_STATUS_STATE_WOL 0x00030000 -+#define APE_EVENT_STATUS_STATE_SUSPEND 0x00040000 -+#define APE_EVENT_STATUS_EVENT_PENDING 0x80000000 -+ -+#define TG3_APE_PER_LOCK_REQ 0x8400 -+#define APE_LOCK_PER_REQ_DRIVER 0x00001000 -+#define TG3_APE_PER_LOCK_GRANT 0x8420 -+#define APE_PER_LOCK_GRANT_DRIVER 0x00001000 -+ -+/* APE convenience enumerations. */ -+#define TG3_APE_LOCK_PHY0 0 -+#define TG3_APE_LOCK_GRC 1 -+#define TG3_APE_LOCK_PHY1 2 -+#define TG3_APE_LOCK_PHY2 3 -+#define TG3_APE_LOCK_MEM 4 -+#define TG3_APE_LOCK_PHY3 5 -+#define TG3_APE_LOCK_GPIO 7 -+#define TG3_APE_HB_INTERVAL (tp->ape_hb_interval) -+ -+/* There are two ways to manage the TX descriptors on the tigon3. -+ * Either the descriptors are in host DMA'able memory, or they -+ * exist only in the cards on-chip SRAM. All 16 send bds are under -+ * the same mode, they may not be configured individually. -+ * -+ * This driver always uses host memory TX descriptors. -+ * -+ * To use host memory TX descriptors: -+ * 1) Set GRC_MODE_HOST_SENDBDS in GRC_MODE register. -+ * Make sure GRC_MODE_4X_NIC_SEND_RINGS is clear. -+ * 2) Allocate DMA'able memory. -+ * 3) In NIC_SRAM_SEND_RCB (of desired index) of on-chip SRAM: -+ * a) Set TG3_BDINFO_HOST_ADDR to DMA address of memory -+ * obtained in step 2 -+ * b) Set TG3_BDINFO_NIC_ADDR to NIC_SRAM_TX_BUFFER_DESC. -+ * c) Set len field of TG3_BDINFO_MAXLEN_FLAGS to number -+ * of TX descriptors. Leave flags field clear. -+ * 4) Access TX descriptors via host memory. The chip -+ * will refetch into local SRAM as needed when producer -+ * index mailboxes are updated. -+ * -+ * To use on-chip TX descriptors: -+ * 1) Set GRC_MODE_4X_NIC_SEND_RINGS in GRC_MODE register. -+ * Make sure GRC_MODE_HOST_SENDBDS is clear. -+ * 2) In NIC_SRAM_SEND_RCB (of desired index) of on-chip SRAM: -+ * a) Set TG3_BDINFO_HOST_ADDR to zero. -+ * b) Set TG3_BDINFO_NIC_ADDR to NIC_SRAM_TX_BUFFER_DESC -+ * c) TG3_BDINFO_MAXLEN_FLAGS is don't care. -+ * 3) Access TX descriptors directly in on-chip SRAM -+ * using normal {read,write}l(). (and not using -+ * pointer dereferencing of ioremap()'d memory like -+ * the broken Broadcom driver does) -+ * -+ * Note that BDINFO_FLAGS_DISABLED should be set in the flags field of -+ * TG3_BDINFO_MAXLEN_FLAGS of all unused SEND_RCB indices. -+ */ -+struct tg3_tx_buffer_desc { -+ u32 addr_hi; -+ u32 addr_lo; -+ -+ u32 len_flags; -+#define TXD_FLAG_TCPUDP_CSUM 0x0001 -+#define TXD_FLAG_IP_CSUM 0x0002 -+#define TXD_FLAG_END 0x0004 -+#define TXD_FLAG_IP_FRAG 0x0008 -+#define TXD_FLAG_JMB_PKT 0x0008 -+#define TXD_FLAG_IP_FRAG_END 0x0010 -+#define TXD_FLAG_HWTSTAMP 0x0020 -+#define TXD_FLAG_VLAN 0x0040 -+#define TXD_FLAG_COAL_NOW 0x0080 -+#define TXD_FLAG_CPU_PRE_DMA 0x0100 -+#define TXD_FLAG_CPU_POST_DMA 0x0200 -+#define TXD_FLAG_ADD_SRC_ADDR 0x1000 -+#define TXD_FLAG_CHOOSE_SRC_ADDR 0x6000 -+#define TXD_FLAG_NO_CRC 0x8000 -+#define TXD_LEN_SHIFT 16 -+ -+ u32 vlan_tag; -+#define TXD_VLAN_TAG_SHIFT 0 -+#define TXD_MSS_SHIFT 16 -+}; -+ -+#define TXD_ADDR 0x00UL /* 64-bit */ -+#define TXD_LEN_FLAGS 0x08UL /* 32-bit (upper 16-bits are len) */ -+#define TXD_VLAN_TAG 0x0cUL /* 32-bit (upper 16-bits are tag) */ -+#define TXD_SIZE 0x10UL -+ -+struct tg3_rx_buffer_desc { -+ u32 addr_hi; -+ u32 addr_lo; -+ -+ u32 idx_len; -+#define RXD_IDX_MASK 0xffff0000 -+#define RXD_IDX_SHIFT 16 -+#define RXD_LEN_MASK 0x0000ffff -+#define RXD_LEN_SHIFT 0 -+ -+ u32 type_flags; -+#define RXD_TYPE_SHIFT 16 -+#define RXD_FLAGS_SHIFT 0 -+ -+#define RXD_FLAG_END 0x0004 -+#define RXD_FLAG_MINI 0x0800 -+#define RXD_FLAG_JUMBO 0x0020 -+#define RXD_FLAG_VLAN 0x0040 -+#define RXD_FLAG_ERROR 0x0400 -+#define RXD_FLAG_IP_CSUM 0x1000 -+#define RXD_FLAG_TCPUDP_CSUM 0x2000 -+#define RXD_FLAG_IS_TCP 0x4000 -+#define RXD_FLAG_PTPSTAT_MASK 0x0210 -+#define RXD_FLAG_PTPSTAT_PTPV1 0x0010 -+#define RXD_FLAG_PTPSTAT_PTPV2 0x0200 -+ -+ u32 ip_tcp_csum; -+#define RXD_IPCSUM_MASK 0xffff0000 -+#define RXD_IPCSUM_SHIFT 16 -+#define RXD_TCPCSUM_MASK 0x0000ffff -+#define RXD_TCPCSUM_SHIFT 0 -+ -+ u32 err_vlan; -+ -+#define RXD_VLAN_MASK 0x0000ffff -+ -+#define RXD_ERR_BAD_CRC 0x00010000 -+#define RXD_ERR_COLLISION 0x00020000 -+#define RXD_ERR_LINK_LOST 0x00040000 -+#define RXD_ERR_PHY_DECODE 0x00080000 -+#define RXD_ERR_ODD_NIBBLE_RCVD_MII 0x00100000 -+#define RXD_ERR_MAC_ABRT 0x00200000 -+#define RXD_ERR_TOO_SMALL 0x00400000 -+#define RXD_ERR_NO_RESOURCES 0x00800000 -+#define RXD_ERR_HUGE_FRAME 0x01000000 -+ -+#define RXD_ERR_MASK (RXD_ERR_BAD_CRC | RXD_ERR_COLLISION | \ -+ RXD_ERR_LINK_LOST | RXD_ERR_PHY_DECODE | \ -+ RXD_ERR_MAC_ABRT | RXD_ERR_TOO_SMALL | \ -+ RXD_ERR_NO_RESOURCES | RXD_ERR_HUGE_FRAME) -+ -+ u32 reserved; -+ u32 opaque; -+#define RXD_OPAQUE_INDEX_MASK 0x0000ffff -+#define RXD_OPAQUE_INDEX_SHIFT 0 -+#define RXD_OPAQUE_RING_STD 0x00010000 -+#define RXD_OPAQUE_RING_JUMBO 0x00020000 -+#define RXD_OPAQUE_RING_MINI 0x00040000 -+#define RXD_OPAQUE_RING_MASK 0x00070000 -+}; -+ -+struct tg3_ext_rx_buffer_desc { -+ struct { -+ u32 addr_hi; -+ u32 addr_lo; -+ } addrlist[3]; -+ u32 len2_len1; -+ u32 resv_len3; -+ struct tg3_rx_buffer_desc std; -+}; -+ -+/* We only use this when testing out the DMA engine -+ * at probe time. This is the internal format of buffer -+ * descriptors used by the chip at NIC_SRAM_DMA_DESCS. -+ */ -+struct tg3_internal_buffer_desc { -+ u32 addr_hi; -+ u32 addr_lo; -+ u32 nic_mbuf; -+ /* XXX FIX THIS */ -+#ifdef __BIG_ENDIAN -+ u16 cqid_sqid; -+ u16 len; -+#else -+ u16 len; -+ u16 cqid_sqid; -+#endif -+ u32 flags; -+ u32 __cookie1; -+ u32 __cookie2; -+ u32 __cookie3; -+}; -+ -+#define TG3_HW_STATUS_SIZE 0x50 -+struct tg3_hw_status { -+ volatile u32 status; -+#define SD_STATUS_UPDATED 0x00000001 -+#define SD_STATUS_LINK_CHG 0x00000002 -+#define SD_STATUS_ERROR 0x00000004 -+ -+ volatile u32 status_tag; -+ -+#ifdef __BIG_ENDIAN -+ volatile u16 rx_consumer; -+ volatile u16 rx_jumbo_consumer; -+#else -+ volatile u16 rx_jumbo_consumer; -+ volatile u16 rx_consumer; -+#endif -+ -+#ifdef __BIG_ENDIAN -+ volatile u16 reserved; -+ volatile u16 rx_mini_consumer; -+#else -+ volatile u16 rx_mini_consumer; -+ volatile u16 reserved; -+#endif -+ struct { -+#ifdef __BIG_ENDIAN -+ volatile u16 tx_consumer; -+ volatile u16 rx_producer; -+#else -+ volatile u16 rx_producer; -+ volatile u16 tx_consumer; -+#endif -+ } idx[16]; -+}; -+ -+typedef struct { -+ u32 high, low; -+} tg3_stat64_t; -+ -+struct tg3_hw_stats { -+ u8 __reserved0[0x400-0x300]; -+ -+ /* Statistics maintained by Receive MAC. */ -+ tg3_stat64_t rx_octets; -+ u64 __reserved1; -+ tg3_stat64_t rx_fragments; -+ tg3_stat64_t rx_ucast_packets; -+ tg3_stat64_t rx_mcast_packets; -+ tg3_stat64_t rx_bcast_packets; -+ tg3_stat64_t rx_fcs_errors; -+ tg3_stat64_t rx_align_errors; -+ tg3_stat64_t rx_xon_pause_rcvd; -+ tg3_stat64_t rx_xoff_pause_rcvd; -+ tg3_stat64_t rx_mac_ctrl_rcvd; -+ tg3_stat64_t rx_xoff_entered; -+ tg3_stat64_t rx_frame_too_long_errors; -+ tg3_stat64_t rx_jabbers; -+ tg3_stat64_t rx_undersize_packets; -+ tg3_stat64_t rx_in_length_errors; -+ tg3_stat64_t rx_out_length_errors; -+ tg3_stat64_t rx_64_or_less_octet_packets; -+ tg3_stat64_t rx_65_to_127_octet_packets; -+ tg3_stat64_t rx_128_to_255_octet_packets; -+ tg3_stat64_t rx_256_to_511_octet_packets; -+ tg3_stat64_t rx_512_to_1023_octet_packets; -+ tg3_stat64_t rx_1024_to_1522_octet_packets; -+ tg3_stat64_t rx_1523_to_2047_octet_packets; -+ tg3_stat64_t rx_2048_to_4095_octet_packets; -+ tg3_stat64_t rx_4096_to_8191_octet_packets; -+ tg3_stat64_t rx_8192_to_9022_octet_packets; -+ -+ u64 __unused0[37]; -+ -+ /* Statistics maintained by Transmit MAC. */ -+ tg3_stat64_t tx_octets; -+ u64 __reserved2; -+ tg3_stat64_t tx_collisions; -+ tg3_stat64_t tx_xon_sent; -+ tg3_stat64_t tx_xoff_sent; -+ tg3_stat64_t tx_flow_control; -+ tg3_stat64_t tx_mac_errors; -+ tg3_stat64_t tx_single_collisions; -+ tg3_stat64_t tx_mult_collisions; -+ tg3_stat64_t tx_deferred; -+ u64 __reserved3; -+ tg3_stat64_t tx_excessive_collisions; -+ tg3_stat64_t tx_late_collisions; -+ tg3_stat64_t tx_collide_2times; -+ tg3_stat64_t tx_collide_3times; -+ tg3_stat64_t tx_collide_4times; -+ tg3_stat64_t tx_collide_5times; -+ tg3_stat64_t tx_collide_6times; -+ tg3_stat64_t tx_collide_7times; -+ tg3_stat64_t tx_collide_8times; -+ tg3_stat64_t tx_collide_9times; -+ tg3_stat64_t tx_collide_10times; -+ tg3_stat64_t tx_collide_11times; -+ tg3_stat64_t tx_collide_12times; -+ tg3_stat64_t tx_collide_13times; -+ tg3_stat64_t tx_collide_14times; -+ tg3_stat64_t tx_collide_15times; -+ tg3_stat64_t tx_ucast_packets; -+ tg3_stat64_t tx_mcast_packets; -+ tg3_stat64_t tx_bcast_packets; -+ tg3_stat64_t tx_carrier_sense_errors; -+ tg3_stat64_t tx_discards; -+ tg3_stat64_t tx_errors; -+ -+ u64 __unused1[31]; -+ -+ /* Statistics maintained by Receive List Placement. */ -+ tg3_stat64_t COS_rx_packets[16]; -+ tg3_stat64_t COS_rx_filter_dropped; -+ tg3_stat64_t dma_writeq_full; -+ tg3_stat64_t dma_write_prioq_full; -+ tg3_stat64_t rxbds_empty; -+ tg3_stat64_t rx_discards; -+ tg3_stat64_t rx_errors; -+ tg3_stat64_t rx_threshold_hit; -+ -+ u64 __unused2[9]; -+ -+ /* Statistics maintained by Send Data Initiator. */ -+ tg3_stat64_t COS_out_packets[16]; -+ tg3_stat64_t dma_readq_full; -+ tg3_stat64_t dma_read_prioq_full; -+ tg3_stat64_t tx_comp_queue_full; -+ -+ /* Statistics maintained by Host Coalescing. */ -+ tg3_stat64_t ring_set_send_prod_index; -+ tg3_stat64_t ring_status_update; -+ tg3_stat64_t nic_irqs; -+ tg3_stat64_t nic_avoided_irqs; -+ tg3_stat64_t nic_tx_threshold_hit; -+ -+ /* NOT a part of the hardware statistics block format. -+ * These stats are here as storage for tg3_periodic_fetch_stats(). -+ */ -+ tg3_stat64_t mbuf_lwm_thresh_hit; -+ -+ u8 __reserved4[0xb00-0x9c8]; -+}; -+ -+#define TG3_SD_NUM_RECS 3 -+#define TG3_OCIR_LEN (sizeof(struct tg3_ocir)) -+#define TG3_OCIR_SIG_MAGIC 0x5253434f -+#define TG3_OCIR_FLAG_ACTIVE 0x00000001 -+ -+#define TG3_TEMP_CAUTION_OFFSET 0xc8 -+#define TG3_TEMP_MAX_OFFSET 0xcc -+#define TG3_TEMP_SENSOR_OFFSET 0xd4 -+ -+#define TG3_OCIR_DRVR_FEAT_CSUM 0x00000001 -+#define TG3_OCIR_DRVR_FEAT_TSO 0x00000002 -+#define TG3_OCIR_DRVR_FEAT_MASK 0xff -+ -+#define TG3_OCIR_REFRESH_TMR_OFF 0x00000008 -+#define TG3_OCIR_UPDATE_TMR_OFF 0x0000000c -+#define TG3_OCIR_PORT0_FLGS_OFF 0x0000002c -+ -+ -+ -+struct tg3_ocir { -+ u32 signature; -+ u16 version_flags; -+ u16 refresh_int; -+ u32 refresh_tmr; -+ u32 update_tmr; -+ u32 dst_base_addr; -+ u16 src_hdr_offset; -+ u16 src_hdr_length; -+ u16 src_data_offset; -+ u16 src_data_length; -+ u16 dst_hdr_offset; -+ u16 dst_data_offset; -+ u16 dst_reg_upd_offset; -+ u16 dst_sem_offset; -+ u32 reserved1[2]; -+ u32 port0_flags; -+ u32 port1_flags; -+ u32 port2_flags; -+ u32 port3_flags; -+ u32 reserved2[1]; -+}; -+ -+/* 'mapping' is superfluous as the chip does not write into -+ * the tx/rx post rings so we could just fetch it from there. -+ * But the cache behavior is better how we are doing it now. -+ */ -+struct ring_info { -+#ifdef BCM_HAS_BUILD_SKB -+ u8 *data; -+#else -+ struct sk_buff *data; -+#endif -+ DEFINE_DMA_UNMAP_ADDR(mapping); -+}; -+ -+struct tg3_tx_ring_info { -+ struct sk_buff *skb; -+ DEFINE_DMA_UNMAP_ADDR(mapping); -+ bool fragmented; -+}; -+ -+struct tg3_link_config { -+ /* Describes what we're trying to get. */ -+ u32 advertising; -+ u16 speed; -+ u8 duplex; -+ u8 autoneg; -+ u8 flowctrl; -+ -+ /* Describes what we actually have. */ -+ u8 active_flowctrl; -+ -+ u8 active_duplex; -+ u16 active_speed; -+ u32 rmt_adv; -+}; -+ -+struct tg3_bufmgr_config { -+ u32 mbuf_read_dma_low_water; -+ u32 mbuf_mac_rx_low_water; -+ u32 mbuf_high_water; -+ -+ u32 mbuf_read_dma_low_water_jumbo; -+ u32 mbuf_mac_rx_low_water_jumbo; -+ u32 mbuf_high_water_jumbo; -+ -+ u32 dma_low_water; -+ u32 dma_high_water; -+}; -+ -+struct tg3_ethtool_stats { -+ /* Statistics maintained by Receive MAC. */ -+ u64 rx_octets; -+ u64 rx_fragments; -+ u64 rx_ucast_packets; -+ u64 rx_mcast_packets; -+ u64 rx_bcast_packets; -+ u64 rx_fcs_errors; -+ u64 rx_align_errors; -+ u64 rx_xon_pause_rcvd; -+ u64 rx_xoff_pause_rcvd; -+ u64 rx_mac_ctrl_rcvd; -+ u64 rx_xoff_entered; -+ u64 rx_frame_too_long_errors; -+ u64 rx_jabbers; -+ u64 rx_undersize_packets; -+ u64 rx_in_length_errors; -+ u64 rx_out_length_errors; -+ u64 rx_64_or_less_octet_packets; -+ u64 rx_65_to_127_octet_packets; -+ u64 rx_128_to_255_octet_packets; -+ u64 rx_256_to_511_octet_packets; -+ u64 rx_512_to_1023_octet_packets; -+ u64 rx_1024_to_1522_octet_packets; -+ u64 rx_1523_to_2047_octet_packets; -+ u64 rx_2048_to_4095_octet_packets; -+ u64 rx_4096_to_8191_octet_packets; -+ u64 rx_8192_to_9022_octet_packets; -+ -+ /* Statistics maintained by Transmit MAC. */ -+ u64 tx_octets; -+ u64 tx_collisions; -+ u64 tx_xon_sent; -+ u64 tx_xoff_sent; -+ u64 tx_flow_control; -+ u64 tx_mac_errors; -+ u64 tx_single_collisions; -+ u64 tx_mult_collisions; -+ u64 tx_deferred; -+ u64 tx_excessive_collisions; -+ u64 tx_late_collisions; -+ u64 tx_collide_2times; -+ u64 tx_collide_3times; -+ u64 tx_collide_4times; -+ u64 tx_collide_5times; -+ u64 tx_collide_6times; -+ u64 tx_collide_7times; -+ u64 tx_collide_8times; -+ u64 tx_collide_9times; -+ u64 tx_collide_10times; -+ u64 tx_collide_11times; -+ u64 tx_collide_12times; -+ u64 tx_collide_13times; -+ u64 tx_collide_14times; -+ u64 tx_collide_15times; -+ u64 tx_ucast_packets; -+ u64 tx_mcast_packets; -+ u64 tx_bcast_packets; -+ u64 tx_carrier_sense_errors; -+ u64 tx_discards; -+ u64 tx_errors; -+ -+ /* Statistics maintained by Receive List Placement. */ -+ u64 dma_writeq_full; -+ u64 dma_write_prioq_full; -+ u64 rxbds_empty; -+ u64 rx_discards; -+ u64 rx_errors; -+ u64 rx_threshold_hit; -+ -+ /* Statistics maintained by Send Data Initiator. */ -+ u64 dma_readq_full; -+ u64 dma_read_prioq_full; -+ u64 tx_comp_queue_full; -+ -+ /* Statistics maintained by Host Coalescing. */ -+ u64 ring_set_send_prod_index; -+ u64 ring_status_update; -+ u64 nic_irqs; -+ u64 nic_avoided_irqs; -+ u64 nic_tx_threshold_hit; -+ -+ u64 mbuf_lwm_thresh_hit; -+ u64 dma_4g_cross; -+#if !defined(__VMKLNX__) -+ u64 recoverable_err; -+ u64 unrecoverable_err; -+#endif -+}; -+ -+#if defined(__VMKLNX__) -+#include "tg3_vmware.h" -+#endif -+ -+struct tg3_rx_prodring_set { -+#ifdef TG3_VMWARE_NETQ_ENABLE -+ u32 rx_std_mbox; -+ u32 rx_jmb_mbox; -+#endif -+ u32 rx_std_prod_idx; -+ u32 rx_std_cons_idx; -+ u32 rx_jmb_prod_idx; -+ u32 rx_jmb_cons_idx; -+ struct tg3_rx_buffer_desc *rx_std; -+ struct tg3_ext_rx_buffer_desc *rx_jmb; -+ struct ring_info *rx_std_buffers; -+ struct ring_info *rx_jmb_buffers; -+ dma_addr_t rx_std_mapping; -+ dma_addr_t rx_jmb_mapping; -+}; -+ -+#define TG3_RSS_MAX_NUM_QS 4 -+#define TG3_IRQ_MAX_VECS_RSS TG3_RSS_MAX_NUM_QS + 1 -+ -+#if defined(__VMKLNX__) -+#if defined(TG3_INBOX) -+ #define TG3_IRQ_MAX_VECS 1 -+#elif defined(TG3_VMWARE_NETQ_ENABLE) -+ #define TG3_IRQ_MAX_VECS_IOV 17 -+ #define TG3_IRQ_MAX_VECS TG3_IRQ_MAX_VECS_IOV -+#endif -+#endif /* __VMKLNX__ */ -+ -+#ifndef TG3_IRQ_MAX_VECS -+#define TG3_IRQ_MAX_VECS TG3_IRQ_MAX_VECS_RSS -+#endif -+ -+struct tg3_napi { -+#ifdef TG3_NAPI -+ struct napi_struct napi ____cacheline_aligned; -+#endif -+ struct tg3 *tp; -+ struct tg3_hw_status *hw_status; -+ -+ u32 chk_msi_cnt; -+ u32 last_tag; -+ u32 last_irq_tag; -+ u32 int_mbox; -+ u32 coal_now; -+ -+ u32 consmbox ____cacheline_aligned; -+ u32 rx_rcb_ptr; -+ u32 last_rx_cons; -+ volatile u16 *rx_rcb_prod_idx; -+ struct tg3_rx_prodring_set *srcprodring; -+ struct tg3_rx_prodring_set prodring; -+ struct tg3_rx_buffer_desc *rx_rcb; -+ -+ u32 tx_prod ____cacheline_aligned; -+ u32 tx_cons; -+ u32 tx_pending; -+ u32 last_tx_cons; -+ u32 prodmbox; -+ struct tg3_tx_buffer_desc *tx_ring; -+ struct tg3_tx_ring_info *tx_buffers; -+ -+ dma_addr_t status_mapping; -+ dma_addr_t rx_rcb_mapping; -+ dma_addr_t tx_desc_mapping; -+ -+ char irq_lbl[IFNAMSIZ]; -+ unsigned int irq_vec; -+ -+#if defined(__VMKLNX__) && !defined(TG3_VMWARE_NETQ_DISABLE) -+ struct tg3_netq_napi netq; -+#endif -+}; -+ -+enum TG3_FLAGS { -+ TG3_FLAG_TAGGED_STATUS = 0, -+ TG3_FLAG_TXD_MBOX_HWBUG, -+ TG3_FLAG_USE_LINKCHG_REG, -+ TG3_FLAG_ERROR_PROCESSED, -+ TG3_FLAG_ENABLE_ASF, -+ TG3_FLAG_ASPM_WORKAROUND, -+ TG3_FLAG_POLL_SERDES, -+ TG3_FLAG_POLL_CPMU_LINK, -+ TG3_FLAG_MBOX_WRITE_REORDER, -+ TG3_FLAG_PCIX_TARGET_HWBUG, -+ TG3_FLAG_WOL_SPEED_100MB, -+ TG3_FLAG_WOL_ENABLE, -+ TG3_FLAG_EEPROM_WRITE_PROT, -+ TG3_FLAG_NVRAM, -+ TG3_FLAG_NVRAM_BUFFERED, -+ TG3_FLAG_SUPPORT_MSI, -+ TG3_FLAG_SUPPORT_MSIX, -+ TG3_FLAG_PCIX_MODE, -+ TG3_FLAG_PCI_HIGH_SPEED, -+ TG3_FLAG_PCI_32BIT, -+ TG3_FLAG_SRAM_USE_CONFIG, -+ TG3_FLAG_TX_RECOVERY_PENDING, -+ TG3_FLAG_WOL_CAP, -+ TG3_FLAG_JUMBO_RING_ENABLE, -+ TG3_FLAG_PAUSE_AUTONEG, -+ TG3_FLAG_CPMU_PRESENT, -+ TG3_FLAG_40BIT_DMA_BUG, -+ TG3_FLAG_BROKEN_CHECKSUMS, -+ TG3_FLAG_JUMBO_CAPABLE, -+ TG3_FLAG_CHIP_RESETTING, -+ TG3_FLAG_INIT_COMPLETE, -+ TG3_FLAG_MAX_RXPEND_64, -+ TG3_FLAG_PCI_EXPRESS, /* BCM5785 + pci_is_pcie() */ -+ TG3_FLAG_ASF_NEW_HANDSHAKE, -+ TG3_FLAG_HW_AUTONEG, -+ TG3_FLAG_IS_NIC, -+ TG3_FLAG_FLASH, -+ TG3_FLAG_FW_TSO, -+ TG3_FLAG_HW_TSO_1, -+ TG3_FLAG_HW_TSO_2, -+ TG3_FLAG_HW_TSO_3, -+ TG3_FLAG_TSO_CAPABLE, -+ TG3_FLAG_TSO_BUG, -+ TG3_FLAG_USING_MSI, -+ TG3_FLAG_USING_MSIX, -+ TG3_FLAG_ICH_WORKAROUND, -+ TG3_FLAG_1SHOT_MSI, -+ TG3_FLAG_NO_FWARE_REPORTED, -+ TG3_FLAG_NO_NVRAM_ADDR_TRANS, -+ TG3_FLAG_ENABLE_APE, -+ TG3_FLAG_PROTECTED_NVRAM, -+ TG3_FLAG_5701_DMA_BUG, -+ TG3_FLAG_USE_PHYLIB, -+ TG3_FLAG_MDIOBUS_INITED, -+ TG3_FLAG_LRG_PROD_RING_CAP, -+ TG3_FLAG_RGMII_INBAND_DISABLE, -+ TG3_FLAG_RGMII_EXT_IBND_RX_EN, -+ TG3_FLAG_RGMII_EXT_IBND_TX_EN, -+ TG3_FLAG_CLKREQ_BUG, -+ TG3_FLAG_NO_NVRAM, -+ TG3_FLAG_ENABLE_RSS, -+ TG3_FLAG_ENABLE_TSS, -+ TG3_FLAG_SHORT_DMA_BUG, -+ TG3_FLAG_USE_JUMBO_BDFLAG, -+ TG3_FLAG_L1PLLPD_EN, -+ TG3_FLAG_APE_HAS_NCSI, -+ TG3_FLAG_TX_TSTAMP_EN, -+ TG3_FLAG_4K_FIFO_LIMIT, -+ TG3_FLAG_NO_TSO_BD_LIMIT, -+ TG3_FLAG_5719_5720_RDMA_BUG, -+ TG3_FLAG_RESET_TASK_PENDING, -+ TG3_FLAG_USER_INDIR_TBL, -+ TG3_FLAG_PTP_CAPABLE, -+ TG3_FLAG_5705_PLUS, -+ TG3_FLAG_IS_5788, -+ TG3_FLAG_5750_PLUS, -+ TG3_FLAG_5780_CLASS, -+ TG3_FLAG_5755_PLUS, -+ TG3_FLAG_57765_PLUS, -+ TG3_FLAG_57765_CLASS, -+ TG3_FLAG_5717_PLUS, -+ TG3_FLAG_IS_SSB_CORE, -+ TG3_FLAG_FLUSH_POSTED_WRITES, -+ TG3_FLAG_ROBOSWITCH, -+ TG3_FLAG_ONE_DMA_AT_ONCE, -+ TG3_FLAG_RGMII_MODE, -+ -+ TG3_FLAG_IOV_CAPABLE, -+ TG3_FLAG_ENABLE_IOV, -+ -+ /* Add new flags before this comment and TG3_FLAG_NUMBER_OF_FLAGS */ -+ TG3_FLAG_NUMBER_OF_FLAGS, /* Last entry in enum TG3_FLAGS */ -+}; -+ -+struct tg3 { -+ /* begin "general, frequently-used members" cacheline section */ -+ -+ /* If the IRQ handler (which runs lockless) needs to be -+ * quiesced, the following bitmask state is used. The -+ * SYNC flag is set by non-IRQ context code to initiate -+ * the quiescence. -+ * -+ * When the IRQ handler notices that SYNC is set, it -+ * disables interrupts and returns. -+ * -+ * When all outstanding IRQ handlers have returned after -+ * the SYNC flag has been set, the setter can be assured -+ * that interrupts will no longer get run. -+ * -+ * In this way all SMP driver locks are never acquired -+ * in hw IRQ context, only sw IRQ context or lower. -+ */ -+ unsigned int irq_sync; -+ -+ /* SMP locking strategy: -+ * -+ * lock: Held during reset, PHY access, timer, and when -+ * updating tg3_flags. -+ * -+ * netif_tx_lock: Held during tg3_start_xmit. tg3_tx holds -+ * netif_tx_lock when it needs to call -+ * netif_wake_queue. -+ * -+ * Both of these locks are to be held with BH safety. -+ * -+ * Because the IRQ handler, tg3_poll, and tg3_start_xmit -+ * are running lockless, it is necessary to completely -+ * quiesce the chip with tg3_netif_stop and tg3_full_lock -+ * before reconfiguring the device. -+ * -+ * indirect_lock: Held when accessing registers indirectly -+ * with IRQ disabling. -+ */ -+ spinlock_t lock; -+ spinlock_t indirect_lock; -+ -+ u32 (*read32) (struct tg3 *, u32); -+ void (*write32) (struct tg3 *, u32, u32); -+ u32 (*read32_mbox) (struct tg3 *, u32); -+ void (*write32_mbox) (struct tg3 *, u32, -+ u32); -+ void __iomem *regs; -+ void __iomem *aperegs; -+ struct net_device *dev; -+ struct pci_dev *pdev; -+ -+ u32 coal_now; -+ u32 msg_enable; -+ -+#ifdef BCM_HAS_IEEE1588_SUPPORT -+#if IS_ENABLED(CONFIG_PTP_1588_CLOCK) -+ struct ptp_clock_info ptp_info; -+ struct ptp_clock *ptp_clock; -+ s64 ptp_adjust; -+#else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */ -+ struct cyclecounter cycles; -+ struct timecounter clock; -+ struct timecompare compare; -+#endif /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */ -+#endif /* BCM_HAS_IEEE1588_SUPPORT */ -+ -+ /* begin "tx thread" cacheline section */ -+ void (*write32_tx_mbox) (struct tg3 *, u32, -+ u32); -+ u32 dma_limit; -+ u32 txq_req; -+ u32 txq_cnt; -+ u32 txq_max; -+ -+ /* begin "rx thread" cacheline section */ -+ struct tg3_napi napi[TG3_IRQ_MAX_VECS]; -+ void (*write32_rx_mbox) (struct tg3 *, u32, -+ u32); -+ u32 rx_copy_thresh; -+ u32 rx_std_ring_mask; -+ u32 rx_jmb_ring_mask; -+ u32 rx_ret_ring_mask; -+ u32 rx_pending; -+ u32 rx_jumbo_pending; -+ u32 rx_std_max_post; -+ u32 rx_offset; -+ u32 rx_pkt_map_sz; -+ u32 rxq_req; -+ u32 rxq_cnt; -+ u32 rxq_max; -+#ifndef BCM_HAS_NEW_VLAN_INTERFACE -+ struct vlan_group *vlgrp; -+#endif -+ -+ bool rx_refill; -+ -+ /* begin "everything else" cacheline(s) section */ -+ unsigned long rx_dropped; -+ unsigned long tx_dropped; -+ struct rtnl_link_stats64 net_stats_prev; -+ struct tg3_ethtool_stats estats_prev; -+ -+ DECLARE_BITMAP(tg3_flags, TG3_FLAG_NUMBER_OF_FLAGS); -+ -+ union { -+ unsigned long phy_crc_errors; -+ unsigned long last_event_jiffies; -+ }; -+ -+ struct timer_list timer; -+ u16 timer_counter; -+ u16 timer_multiplier; -+ u32 timer_offset; -+ u16 asf_counter; -+ u16 asf_multiplier; -+ -+ /* 1 second counter for transient serdes link events */ -+ u32 serdes_counter; -+#define SERDES_AN_TIMEOUT_5704S 2 -+#define SERDES_PARALLEL_DET_TIMEOUT 1 -+#define SERDES_AN_TIMEOUT_5714S 1 -+ -+ struct tg3_link_config link_config; -+ struct tg3_bufmgr_config bufmgr_config; -+ -+ /* cache h/w values, often passed straight to h/w */ -+ u32 rx_mode; -+ u32 tx_mode; -+ u32 mac_mode; -+ u32 mi_mode; -+ u32 misc_host_ctrl; -+ u32 grc_mode; -+ u32 grc_local_ctrl; -+ u32 dma_rwctrl; -+ u32 coalesce_mode; -+ u32 pwrmgmt_thresh; -+ u32 rxptpctl; -+ -+ /* PCI block */ -+ u32 pci_chip_rev_id; -+ u16 pci_cmd; -+ u8 pci_cacheline_sz; -+ u8 pci_lat_timer; -+ -+ int pci_fn; -+ int pm_cap; -+ int msi_cap; -+ int pcix_cap; -+ int pcie_readrq; -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ struct mii_bus *mdio_bus; -+ int mdio_irq[PHY_MAX_ADDR]; -+#endif -+ int old_link; -+ -+ u8 phy_addr; -+ u8 phy_ape_lock; -+ -+ /* PHY info */ -+ u32 phy_id; -+#define TG3_PHY_ID_MASK 0xfffffff0 -+#define TG3_PHY_ID_BCM5400 0x60008040 -+#define TG3_PHY_ID_BCM5401 0x60008050 -+#define TG3_PHY_ID_BCM5411 0x60008070 -+#define TG3_PHY_ID_BCM5701 0x60008110 -+#define TG3_PHY_ID_BCM5703 0x60008160 -+#define TG3_PHY_ID_BCM5704 0x60008190 -+#define TG3_PHY_ID_BCM5705 0x600081a0 -+#define TG3_PHY_ID_BCM5750 0x60008180 -+#define TG3_PHY_ID_BCM5752 0x60008100 -+#define TG3_PHY_ID_BCM5714 0x60008340 -+#define TG3_PHY_ID_BCM5780 0x60008350 -+#define TG3_PHY_ID_BCM5755 0xbc050cc0 -+#define TG3_PHY_ID_BCM5787 0xbc050ce0 -+#define TG3_PHY_ID_BCM5756 0xbc050ed0 -+#define TG3_PHY_ID_BCM5784 0xbc050fa0 -+#define TG3_PHY_ID_BCM5761 0xbc050fd0 -+#define TG3_PHY_ID_BCM5718C 0x5c0d8a00 -+#define TG3_PHY_ID_BCM5718S 0xbc050ff0 -+#define TG3_PHY_ID_BCM57765 0x5c0d8a40 -+#define TG3_PHY_ID_BCM5719C 0x5c0d8a20 -+#define TG3_PHY_ID_BCM5720C 0x5c0d8b60 -+#define TG3_PHY_ID_BCM5762 0x85803780 -+#define TG3_PHY_ID_BCM5906 0xdc00ac40 -+#define TG3_PHY_ID_BCM8002 0x60010140 -+#ifndef BCM_INCLUDE_PHYLIB_SUPPORT -+#define TG3_PHY_ID_BCM50610 0xbc050d60 -+#define TG3_PHY_ID_BCM50610M 0xbc050d70 -+#define TG3_PHY_ID_BCM50612E 0x5c0d8a60 -+#define TG3_PHY_ID_BCMAC131 0xbc050c70 -+#define TG3_PHY_ID_RTL8211C 0xc8007110 -+#define TG3_PHY_ID_RTL8201E 0xc800aaa0 -+#define TG3_PHY_ID_BCM57780 0x5c0d8990 -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+#define TG3_PHY_ID_INVALID 0xffffffff -+ -+#define PHY_ID_RTL8211C 0x001cc910 -+#define PHY_ID_RTL8201E 0x00008200 -+ -+#define TG3_PHY_ID_REV_MASK 0x0000000f -+#define TG3_PHY_REV_BCM5401_B0 0x1 -+ -+ /* This macro assumes the passed PHY ID is -+ * already masked with TG3_PHY_ID_MASK. -+ */ -+#define TG3_KNOWN_PHY_ID(X) \ -+ ((X) == TG3_PHY_ID_BCM5400 || (X) == TG3_PHY_ID_BCM5401 || \ -+ (X) == TG3_PHY_ID_BCM5411 || (X) == TG3_PHY_ID_BCM5701 || \ -+ (X) == TG3_PHY_ID_BCM5703 || (X) == TG3_PHY_ID_BCM5704 || \ -+ (X) == TG3_PHY_ID_BCM5705 || (X) == TG3_PHY_ID_BCM5750 || \ -+ (X) == TG3_PHY_ID_BCM5752 || (X) == TG3_PHY_ID_BCM5714 || \ -+ (X) == TG3_PHY_ID_BCM5780 || (X) == TG3_PHY_ID_BCM5787 || \ -+ (X) == TG3_PHY_ID_BCM5755 || (X) == TG3_PHY_ID_BCM5756 || \ -+ (X) == TG3_PHY_ID_BCM5906 || (X) == TG3_PHY_ID_BCM5761 || \ -+ (X) == TG3_PHY_ID_BCM5718C || (X) == TG3_PHY_ID_BCM5718S || \ -+ (X) == TG3_PHY_ID_BCM57765 || (X) == TG3_PHY_ID_BCM5719C || \ -+ (X) == TG3_PHY_ID_BCM5720C || (X) == TG3_PHY_ID_BCM5762 || \ -+ (X) == TG3_PHY_ID_BCM8002 || \ -+ (X) == TG3_PHY_ID_BCM50610 || (X) == TG3_PHY_ID_BCM50610M || \ -+ (X) == TG3_PHY_ID_BCM50612E || (X) == TG3_PHY_ID_BCMAC131 || \ -+ (X) == TG3_PHY_ID_BCM57780) -+ -+ u32 phy_flags; -+#define TG3_PHYFLG_USER_CONFIGURED 0x00000001 -+#define TG3_PHYFLG_IS_LOW_POWER 0x00000002 -+#define TG3_PHYFLG_IS_CONNECTED 0x00000004 -+#define TG3_PHYFLG_USE_MI_INTERRUPT 0x00000008 -+#define TG3_PHYFLG_PHY_SERDES 0x00000010 -+#define TG3_PHYFLG_MII_SERDES 0x00000020 -+#define TG3_PHYFLG_ANY_SERDES (TG3_PHYFLG_PHY_SERDES | \ -+ TG3_PHYFLG_MII_SERDES) -+#define TG3_PHYFLG_IS_FET 0x00000040 -+#define TG3_PHYFLG_10_100_ONLY 0x00000080 -+#define TG3_PHYFLG_ENABLE_APD 0x00000100 -+#define TG3_PHYFLG_CAPACITIVE_COUPLING 0x00000200 -+#define TG3_PHYFLG_NO_ETH_WIRE_SPEED 0x00000400 -+#define TG3_PHYFLG_JITTER_BUG 0x00000800 -+#define TG3_PHYFLG_ADJUST_TRIM 0x00001000 -+#define TG3_PHYFLG_ADC_BUG 0x00002000 -+#define TG3_PHYFLG_5704_A0_BUG 0x00004000 -+#define TG3_PHYFLG_BER_BUG 0x00008000 -+#define TG3_PHYFLG_SERDES_PREEMPHASIS 0x00010000 -+#define TG3_PHYFLG_PARALLEL_DETECT 0x00020000 -+#define TG3_PHYFLG_EEE_CAP 0x00040000 -+#define TG3_PHYFLG_1G_ON_VAUX_OK 0x00080000 -+#define TG3_PHYFLG_KEEP_LINK_ON_PWRDN 0x00100000 -+#define TG3_PHYFLG_MDIX_STATE 0x00200000 -+#define TG3_PHYFLG_DISABLE_1G_HD_ADV 0x00400000 -+ -+ u32 led_ctrl; -+ u32 phy_otp; -+ u32 setlpicnt; -+ u8 rss_ind_tbl[TG3_RSS_INDIR_TBL_SIZE]; -+ -+#define TG3_BPN_SIZE 24 -+ char board_part_number[TG3_BPN_SIZE]; -+#define TG3_VER_SIZE ETHTOOL_FWVERS_LEN -+ char fw_ver[TG3_VER_SIZE]; -+ u32 nic_sram_data_cfg; -+ u32 pci_clock_ctrl; -+ struct pci_dev *pdev_peer; -+ -+ struct tg3_hw_stats *hw_stats; -+ dma_addr_t stats_mapping; -+ struct work_struct reset_task; -+ -+ int nvram_lock_cnt; -+ u32 nvram_size; -+#define TG3_NVRAM_SIZE_2KB 0x00000800 -+#define TG3_NVRAM_SIZE_64KB 0x00010000 -+#define TG3_NVRAM_SIZE_128KB 0x00020000 -+#define TG3_NVRAM_SIZE_256KB 0x00040000 -+#define TG3_NVRAM_SIZE_512KB 0x00080000 -+#define TG3_NVRAM_SIZE_1MB 0x00100000 -+#define TG3_NVRAM_SIZE_2MB 0x00200000 -+ -+ u32 nvram_pagesize; -+ u32 nvram_jedecnum; -+ -+#define JEDEC_ATMEL 0x1f -+#define JEDEC_ST 0x20 -+#define JEDEC_SAIFUN 0x4f -+#define JEDEC_SST 0xbf -+#define JEDEC_MACRONIX 0xc2 -+ -+#define ATMEL_AT24C02_CHIP_SIZE TG3_NVRAM_SIZE_2KB -+#define ATMEL_AT24C02_PAGE_SIZE (8) -+ -+#define ATMEL_AT24C64_CHIP_SIZE TG3_NVRAM_SIZE_64KB -+#define ATMEL_AT24C64_PAGE_SIZE (32) -+ -+#define ATMEL_AT24C512_CHIP_SIZE TG3_NVRAM_SIZE_512KB -+#define ATMEL_AT24C512_PAGE_SIZE (128) -+ -+#define ATMEL_AT45DB0X1B_PAGE_POS 9 -+#define ATMEL_AT45DB0X1B_PAGE_SIZE 264 -+ -+#define ATMEL_AT25F512_PAGE_SIZE 256 -+ -+#define ST_M45PEX0_PAGE_SIZE 256 -+ -+#define SAIFUN_SA25F0XX_PAGE_SIZE 256 -+ -+#define SST_25VF0X0_PAGE_SIZE 4098 -+ -+ unsigned int irq_max; -+ unsigned int irq_cnt; -+ -+ struct ethtool_coalesce coal; -+ struct ethtool_eee eee; -+ -+ /* firmware info */ -+ const char *fw_needed; -+ const struct tg3_firmware *fw; -+ u32 fw_len; /* includes BSS */ -+ -+#if defined(__VMKLNX__) -+ struct tg3_vmware vmware; -+#endif -+#ifndef BCM_HAS_PCI_PCIE_CAP -+ int pcie_cap; -+#endif -+#if (LINUX_VERSION_CODE < 0x2060a) -+ u32 pci_cfg_state[64 / sizeof(u32)]; -+#endif -+#ifndef BCM_HAS_GET_STATS64 -+ struct rtnl_link_stats64 net_stats; -+#endif -+#if IS_ENABLED(CONFIG_HWMON) && !defined(__VMKLNX__) -+#if (LINUX_VERSION_CODE > 0x20618) -+ struct device *hwmon_dev; -+#else -+ struct class_device *hwmon_dev; -+#endif -+#endif -+ -+ bool link_up; -+#if defined(__VMKLNX__) && VMWARE_ESX_DDK_VERSION >= 55000 -+ int nic_idx; -+#endif -+ u32 ape_hb; -+ unsigned long ape_hb_interval; -+ unsigned long ape_hb_jiffies; -+ unsigned long dma_4g_cross; -+#if !defined(__VMKLNX__) -+ unsigned long recoverable_err_jiffies; -+#define RECOVERABLE_ERR_10SEC 10000 -+ unsigned long recoverable_err_interval; -+ u64 recoverable_err; -+ u64 unrecoverable_err; -+#endif -+}; -+ -+/* Accessor macros for chip and asic attributes -+ * -+ * nb: Using static inlines equivalent to the accessor macros generates -+ * larger object code with gcc 4.7. -+ * Using statement expression macros to check tp with -+ * typecheck(struct tg3 *, tp) also creates larger objects. -+ */ -+#define tg3_chip_rev_id(tp) \ -+ ((tp)->pci_chip_rev_id) -+#define tg3_asic_rev(tp) \ -+ ((tp)->pci_chip_rev_id >> 12) -+#define tg3_chip_rev(tp) \ -+ ((tp)->pci_chip_rev_id >> 8) -+ -+#endif /* !(_T3_H) */ -diff --git a/drivers/net/ethernet/broadcom/tg3/tg3_compat.h b/drivers/net/ethernet/broadcom/tg3/tg3_compat.h -new file mode 100644 -index 0000000..40cc207 ---- /dev/null -+++ b/drivers/net/ethernet/broadcom/tg3/tg3_compat.h -@@ -0,0 +1,2172 @@ -+/* Copyright (C) 2008-2015 Broadcom Corporation. */ -+ -+#ifdef CONFIG_X86 -+#undef NET_IP_ALIGN -+#define NET_IP_ALIGN 0 -+#endif -+ -+#if !defined(__maybe_unused) -+#define __maybe_unused /* unimplemented */ -+#endif -+ -+#if !defined(__iomem) -+#define __iomem -+#endif -+ -+#ifndef __always_unused -+#define __always_unused -+#endif -+ -+#ifndef __acquires -+#define __acquires(x) -+#endif -+ -+#ifndef __releases -+#define __releases(x) -+#endif -+ -+#ifndef mmiowb -+#define mmiowb() -+#endif -+ -+#ifndef WARN_ON -+#define WARN_ON(x) -+#endif -+ -+#ifndef MODULE_VERSION -+#define MODULE_VERSION(version) -+#endif -+ -+#ifndef SET_MODULE_OWNER -+#define SET_MODULE_OWNER(dev) do { } while (0) -+#endif -+ -+#ifndef ARRAY_SIZE -+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -+#endif -+ -+#ifndef DIV_ROUND_UP -+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) -+#endif -+ -+#ifndef __ALIGN_MASK -+#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) -+#endif -+ -+#ifndef ALIGN -+#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) -+#endif -+ -+#ifndef BCM_HAS_BOOL -+typedef int bool; -+#define false 0 -+#define true 1 -+#endif -+ -+#ifndef BCM_HAS_LE32 -+typedef u32 __le32; -+typedef u32 __be32; -+#endif -+ -+#ifndef BCM_HAS_RESOURCE_SIZE_T -+typedef unsigned long resource_size_t; -+#endif -+ -+#ifndef IRQ_RETVAL -+typedef void irqreturn_t; -+#define IRQ_RETVAL(x) -+#define IRQ_HANDLED -+#define IRQ_NONE -+#endif -+ -+#ifndef IRQF_SHARED -+#define IRQF_SHARED SA_SHIRQ -+#endif -+ -+#ifndef IRQF_SAMPLE_RANDOM -+#define IRQF_SAMPLE_RANDOM SA_SAMPLE_RANDOM -+#endif -+ -+#if (LINUX_VERSION_CODE <= 0x020600) -+#define schedule_work(x) schedule_task(x) -+#define work_struct tq_struct -+#define INIT_WORK(x, y, z) INIT_TQUEUE(x, y, z) -+#endif -+ -+#ifndef BCM_HAS_KZALLOC -+static inline void *kzalloc(size_t size, int flags) -+{ -+ void * memptr = kmalloc(size, flags); -+ if (memptr) -+ memset(memptr, 0, size); -+ -+ return memptr; -+} -+#endif -+ -+#ifndef USEC_PER_SEC -+#define USEC_PER_SEC 1000000 -+#endif -+ -+#ifndef MSEC_PER_SEC -+#define MSEC_PER_SEC 1000 -+#endif -+ -+#ifndef MAX_JIFFY_OFFSET -+#define MAX_JIFFY_OFFSET ((LONG_MAX >> 1)-1) -+#endif -+ -+#ifndef BCM_HAS_JIFFIES_TO_USECS -+static unsigned int inline jiffies_to_usecs(const unsigned long j) -+{ -+#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) -+ return (USEC_PER_SEC / HZ) * j; -+#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC) -+ return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC); -+#else -+ return (j * USEC_PER_SEC) / HZ; -+#endif -+} -+#endif /* BCM_HAS_JIFFIES_TO_USECS */ -+ -+#ifndef BCM_HAS_USECS_TO_JIFFIES -+static unsigned long usecs_to_jiffies(const unsigned int u) -+{ -+ if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET)) -+ return MAX_JIFFY_OFFSET; -+#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) -+ return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ); -+#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC) -+ return u * (HZ / USEC_PER_SEC); -+#else -+ return (u * HZ + USEC_PER_SEC - 1) / USEC_PER_SEC; -+#endif -+} -+#endif /* BCM_HAS_USECS_TO_JIFFIES */ -+ -+#ifndef BCM_HAS_MSECS_TO_JIFFIES -+static unsigned long msecs_to_jiffies(const unsigned int m) -+{ -+#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) -+ /* -+ * HZ is equal to or smaller than 1000, and 1000 is a nice -+ * round multiple of HZ, divide with the factor between them, -+ * but round upwards: -+ */ -+ return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ); -+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) -+ /* -+ * HZ is larger than 1000, and HZ is a nice round multiple of -+ * 1000 - simply multiply with the factor between them. -+ * -+ * But first make sure the multiplication result cannot -+ * overflow: -+ */ -+ if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) -+ return MAX_JIFFY_OFFSET; -+ -+ return m * (HZ / MSEC_PER_SEC); -+#else -+ /* -+ * Generic case - multiply, round and divide. But first -+ * check that if we are doing a net multiplication, that -+ * we wouldn't overflow: -+ */ -+ if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) -+ return MAX_JIFFY_OFFSET; -+ -+ return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC; -+#endif -+} -+#endif /* BCM_HAS_MSECS_TO_JIFFIES */ -+ -+#ifndef BCM_HAS_MSLEEP -+static void msleep(unsigned int msecs) -+{ -+ unsigned long timeout = msecs_to_jiffies(msecs) + 1; -+ -+ while (timeout) { -+ __set_current_state(TASK_UNINTERRUPTIBLE); -+ timeout = schedule_timeout(timeout); -+ } -+} -+#endif /* BCM_HAS_MSLEEP */ -+ -+#ifndef BCM_HAS_MSLEEP_INTERRUPTIBLE -+static unsigned long msleep_interruptible(unsigned int msecs) -+{ -+ unsigned long timeout = msecs_to_jiffies(msecs) + 1; -+ -+ while (timeout) { -+ __set_current_state(TASK_UNINTERRUPTIBLE); -+ timeout = schedule_timeout(timeout); -+ } -+ -+ return 0; -+} -+#endif /* BCM_HAS_MSLEEP_INTERRUPTIBLE */ -+ -+#ifndef printk_once -+#define printk_once(x...) ({ \ -+ static bool tg3___print_once = false; \ -+ \ -+ if (!tg3___print_once) { \ -+ tg3___print_once = true; \ -+ printk(x); \ -+ } \ -+}) -+#endif -+ -+#if !defined(BCM_HAS_DEV_DRIVER_STRING) || defined(__VMKLNX__) -+#define dev_driver_string(dev) "tg3" -+#endif -+ -+#if !defined(BCM_HAS_DEV_NAME) || defined(__VMKLNX__) -+#define dev_name(dev) "" -+#endif -+ -+#if defined(dev_printk) && ((LINUX_VERSION_CODE < 0x020609) || defined(__VMKLNX__)) -+/* -+ * SLES 9 and VMWare do not populate the pdev->dev.bus_id string soon -+ * enough for driver use during boot. Use our own format instead. -+ */ -+#undef dev_printk -+#endif -+ -+#ifndef dev_printk -+#define dev_printk(level, dev, format, arg...) \ -+ printk(level "%s %s: " format , dev_driver_string(dev) , \ -+ dev_name(dev) , ## arg) -+#endif -+ -+#ifndef dev_err -+#define dev_err(dev, format, arg...) \ -+ dev_printk(KERN_ERR , dev , format , ## arg) -+#endif -+ -+#ifndef dev_warn -+#define dev_warn(dev, format, arg...) \ -+ dev_printk(KERN_WARNING , dev , format , ## arg) -+#endif -+ -+#ifndef BCM_HAS_PCI_IOREMAP_BAR -+static inline void * pci_ioremap_bar(struct pci_dev *pdev, int bar) -+{ -+ resource_size_t base, size; -+ -+ if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { -+ printk(KERN_ERR -+ "Cannot find proper PCI device base address for BAR %d.\n", -+ bar); -+ return NULL; -+ } -+ -+ base = pci_resource_start(pdev, bar); -+ size = pci_resource_len(pdev, bar); -+ -+ return ioremap_nocache(base, size); -+} -+#endif -+ -+#ifndef DEFINE_PCI_DEVICE_TABLE -+#define DEFINE_PCI_DEVICE_TABLE(x) struct pci_device_id x[] -+#endif -+ -+#if (LINUX_VERSION_CODE < 0x020547) -+#define pci_set_consistent_dma_mask(pdev, mask) (0) -+#endif -+ -+#if (LINUX_VERSION_CODE < 0x020600) -+#define pci_get_device(x, y, z) pci_find_device(x, y, z) -+#define pci_get_slot(x, y) pci_find_slot((x)->number, y) -+#define pci_dev_put(x) -+#endif -+ -+#if (LINUX_VERSION_CODE < 0x020605) -+#define pci_dma_sync_single_for_cpu(pdev, map, len, dir) \ -+ pci_dma_sync_single(pdev, map, len, dir) -+#define pci_dma_sync_single_for_device(pdev, map, len, dir) -+#endif -+ -+#ifndef PCI_DEVICE -+#define PCI_DEVICE(vend,dev) \ -+ .vendor = (vend), .device = (dev), \ -+ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID -+#endif -+ -+#ifndef PCI_DEVICE_SUB -+#define PCI_DEVICE_SUB(vend, dev, subvend, subdev) \ -+ .vendor = (vend), .device = (dev), \ -+ .subvendor = (subvend), .subdevice = (subdev) -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5704S_2 -+#define PCI_DEVICE_ID_TIGON3_5704S_2 0x1649 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5705F -+#define PCI_DEVICE_ID_TIGON3_5705F 0x166e -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5720 -+#define PCI_DEVICE_ID_TIGON3_5720 0x1658 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5721 -+#define PCI_DEVICE_ID_TIGON3_5721 0x1659 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5750 -+#define PCI_DEVICE_ID_TIGON3_5750 0x1676 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5751 -+#define PCI_DEVICE_ID_TIGON3_5751 0x1677 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5750M -+#define PCI_DEVICE_ID_TIGON3_5750M 0x167c -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5751M -+#define PCI_DEVICE_ID_TIGON3_5751M 0x167d -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5751F -+#define PCI_DEVICE_ID_TIGON3_5751F 0x167e -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5789 -+#define PCI_DEVICE_ID_TIGON3_5789 0x169d -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5753 -+#define PCI_DEVICE_ID_TIGON3_5753 0x16f7 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5753M -+#define PCI_DEVICE_ID_TIGON3_5753M 0x16fd -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5753F -+#define PCI_DEVICE_ID_TIGON3_5753F 0x16fe -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5781 -+#define PCI_DEVICE_ID_TIGON3_5781 0x16dd -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5752 -+#define PCI_DEVICE_ID_TIGON3_5752 0x1600 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5752M -+#define PCI_DEVICE_ID_TIGON3_5752M 0x1601 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5714 -+#define PCI_DEVICE_ID_TIGON3_5714 0x1668 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5714S -+#define PCI_DEVICE_ID_TIGON3_5714S 0x1669 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5780 -+#define PCI_DEVICE_ID_TIGON3_5780 0x166a -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5780S -+#define PCI_DEVICE_ID_TIGON3_5780S 0x166b -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5715 -+#define PCI_DEVICE_ID_TIGON3_5715 0x1678 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5715S -+#define PCI_DEVICE_ID_TIGON3_5715S 0x1679 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5756 -+#define PCI_DEVICE_ID_TIGON3_5756 0x1674 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5754 -+#define PCI_DEVICE_ID_TIGON3_5754 0x167a -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5754M -+#define PCI_DEVICE_ID_TIGON3_5754M 0x1672 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5755 -+#define PCI_DEVICE_ID_TIGON3_5755 0x167b -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5755M -+#define PCI_DEVICE_ID_TIGON3_5755M 0x1673 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5722 -+#define PCI_DEVICE_ID_TIGON3_5722 0x165a -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5786 -+#define PCI_DEVICE_ID_TIGON3_5786 0x169a -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5787M -+#define PCI_DEVICE_ID_TIGON3_5787M 0x1693 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5787 -+#define PCI_DEVICE_ID_TIGON3_5787 0x169b -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5787F -+#define PCI_DEVICE_ID_TIGON3_5787F 0x167f -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5906 -+#define PCI_DEVICE_ID_TIGON3_5906 0x1712 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5906M -+#define PCI_DEVICE_ID_TIGON3_5906M 0x1713 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5784 -+#define PCI_DEVICE_ID_TIGON3_5784 0x1698 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5764 -+#define PCI_DEVICE_ID_TIGON3_5764 0x1684 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5723 -+#define PCI_DEVICE_ID_TIGON3_5723 0x165b -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5761 -+#define PCI_DEVICE_ID_TIGON3_5761 0x1681 -+#endif -+ -+#ifndef PCI_DEVICE_ID_TIGON3_5761E -+#define PCI_DEVICE_ID_TIGON3_5761E 0x1680 -+#endif -+ -+#ifndef PCI_DEVICE_ID_APPLE_TIGON3 -+#define PCI_DEVICE_ID_APPLE_TIGON3 0x1645 -+#endif -+ -+#ifndef PCI_DEVICE_ID_APPLE_UNI_N_PCI15 -+#define PCI_DEVICE_ID_APPLE_UNI_N_PCI15 0x002e -+#endif -+ -+#ifndef PCI_DEVICE_ID_VIA_8385_0 -+#define PCI_DEVICE_ID_VIA_8385_0 0x3188 -+#endif -+ -+#ifndef PCI_DEVICE_ID_AMD_8131_BRIDGE -+#define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450 -+#endif -+ -+#ifndef PCI_DEVICE_ID_SERVERWORKS_EPB -+#define PCI_DEVICE_ID_SERVERWORKS_EPB 0x0103 -+#endif -+ -+#ifndef PCI_VENDOR_ID_ARIMA -+#define PCI_VENDOR_ID_ARIMA 0x161f -+#endif -+ -+#ifndef PCI_DEVICE_ID_INTEL_PXH_0 -+#define PCI_DEVICE_ID_INTEL_PXH_0 0x0329 -+#endif -+ -+#ifndef PCI_DEVICE_ID_INTEL_PXH_1 -+#define PCI_DEVICE_ID_INTEL_PXH_1 0x032A -+#endif -+ -+#ifndef PCI_VENDOR_ID_LENOVO -+#define PCI_VENDOR_ID_LENOVO 0x17aa -+#endif -+ -+#ifndef PCI_D0 -+typedef u32 pm_message_t; -+typedef u32 pci_power_t; -+#define PCI_D0 0 -+#define PCI_D1 1 -+#define PCI_D2 2 -+#define PCI_D3hot 3 -+#endif -+ -+#ifndef PCI_D3cold -+#define PCI_D3cold 4 -+#endif -+ -+#ifndef DMA_64BIT_MASK -+#define DMA_64BIT_MASK ((u64) 0xffffffffffffffffULL) -+#endif -+ -+#ifndef DMA_40BIT_MASK -+#define DMA_40BIT_MASK ((u64) 0x000000ffffffffffULL) -+#endif -+ -+#ifndef DMA_32BIT_MASK -+#define DMA_32BIT_MASK ((u64) 0x00000000ffffffffULL) -+#endif -+ -+#ifndef DMA_BIT_MASK -+#define DMA_BIT_MASK(n) DMA_ ##n ##BIT_MASK -+#endif -+ -+#ifndef DEFINE_DMA_UNMAP_ADDR -+#define DEFINE_DMA_UNMAP_ADDR DECLARE_PCI_UNMAP_ADDR -+#endif -+ -+#if !defined(BCM_HAS_DMA_UNMAP_ADDR) -+#define dma_unmap_addr pci_unmap_addr -+#endif -+ -+#if !defined(BCM_HAS_DMA_UNMAP_ADDR_SET) -+#define dma_unmap_addr_set pci_unmap_addr_set -+#endif -+ -+#if !defined(BCM_HAS_PCI_TARGET_STATE) && !defined(BCM_HAS_PCI_CHOOSE_STATE) -+static inline pci_power_t pci_choose_state(struct pci_dev *dev, -+ pm_message_t state) -+{ -+ return state; -+} -+#endif -+ -+#ifndef BCM_HAS_PCI_ENABLE_WAKE -+static int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) -+{ -+ int pm_cap; -+ u16 pmcsr; -+ -+ pm_cap = pci_find_capability(dev, PCI_CAP_ID_PM); -+ if (pm_cap == 0) -+ return -EIO; -+ -+ pci_read_config_word(dev, pm_cap + PCI_PM_CTRL, &pmcsr); -+ -+ /* Clear PME_Status by writing 1 to it */ -+ pmcsr |= PCI_PM_CTRL_PME_STATUS; -+ -+ if (enable) -+ pmcsr |= PCI_PM_CTRL_PME_ENABLE; -+ else -+ pmcsr &= ~PCI_PM_CTRL_PME_ENABLE; -+ -+ pci_write_config_word(dev, pm_cap + PCI_PM_CTRL, pmcsr); -+ -+ return 0; -+} -+#endif /* BCM_HAS_PCI_ENABLE_WAKE */ -+ -+#ifndef BCM_HAS_PCI_WAKE_FROM_D3 -+#ifndef BCM_HAS_PCI_PME_CAPABLE -+static bool pci_pme_capable(struct pci_dev *dev, pci_power_t state) -+{ -+ int pm_cap; -+ u16 caps; -+ bool ret = false; -+ -+ pm_cap = pci_find_capability(dev, PCI_CAP_ID_PM); -+ if (pm_cap == 0) -+ goto done; -+ -+ pci_read_config_word(dev, pm_cap + PCI_PM_PMC, &caps); -+ -+ if (state == PCI_D3cold && -+ (caps & PCI_PM_CAP_PME_D3cold)) -+ ret = true; -+ -+done: -+ return ret; -+} -+#endif /* BCM_HAS_PCI_PME_CAPABLE */ -+ -+static int pci_wake_from_d3(struct pci_dev *dev, bool enable) -+{ -+ return pci_pme_capable(dev, PCI_D3cold) ? -+ pci_enable_wake(dev, PCI_D3cold, enable) : -+ pci_enable_wake(dev, PCI_D3hot, enable); -+} -+#endif /* BCM_HAS_PCI_WAKE_FROM_D3 */ -+ -+#ifndef BCM_HAS_PCI_SET_POWER_STATE -+static int pci_set_power_state(struct pci_dev *dev, pci_power_t state) -+{ -+ int pm_cap; -+ u16 pmcsr; -+ -+ if (state < PCI_D0 || state > PCI_D3hot) -+ return -EINVAL; -+ -+ pm_cap = pci_find_capability(dev, PCI_CAP_ID_PM); -+ if (pm_cap == 0) -+ return -EIO; -+ -+ pci_read_config_word(dev, pm_cap + PCI_PM_CTRL, &pmcsr); -+ -+ pmcsr &= ~(PCI_PM_CTRL_STATE_MASK); -+ pmcsr |= state; -+ -+ pci_write_config_word(dev, pm_cap + PCI_PM_CTRL, pmcsr); -+ -+ msleep(10); -+ -+ return 0; -+} -+#endif /* BCM_HAS_PCI_SET_POWER_STATE */ -+ -+#ifdef __VMKLNX__ -+/* VMWare disables CONFIG_PM in their kernel configs. -+ * This renders WOL inop, because device_may_wakeup() always returns false. -+ */ -+#undef BCM_HAS_DEVICE_WAKEUP_API -+#endif -+ -+#ifndef BCM_HAS_DEVICE_WAKEUP_API -+#undef device_init_wakeup -+#define device_init_wakeup(dev, val) -+#undef device_can_wakeup -+#define device_can_wakeup(dev) 1 -+#undef device_set_wakeup_enable -+#define device_set_wakeup_enable(dev, val) -+#undef device_may_wakeup -+#define device_may_wakeup(dev) 1 -+#endif /* BCM_HAS_DEVICE_WAKEUP_API */ -+ -+#ifndef BCM_HAS_DEVICE_SET_WAKEUP_CAPABLE -+#define device_set_wakeup_capable(dev, val) -+#endif /* BCM_HAS_DEVICE_SET_WAKEUP_CAPABLE */ -+ -+ -+#ifndef PCI_X_CMD_READ_2K -+#define PCI_X_CMD_READ_2K 0x0008 -+#endif -+#ifndef PCI_CAP_ID_EXP -+#define PCI_CAP_ID_EXP 0x10 -+#endif -+#ifndef PCI_EXP_LNKCTL -+#define PCI_EXP_LNKCTL 16 -+#endif -+#ifndef PCI_EXP_LNKCTL_CLKREQ_EN -+#define PCI_EXP_LNKCTL_CLKREQ_EN 0x100 -+#endif -+ -+#ifndef PCI_EXP_DEVCTL_NOSNOOP_EN -+#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 -+#endif -+ -+#ifndef PCI_EXP_DEVCTL_RELAX_EN -+#define PCI_EXP_DEVCTL_RELAX_EN 0x0010 -+#endif -+ -+#ifndef PCI_EXP_DEVCTL_PAYLOAD -+#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 -+#endif -+ -+#ifndef PCI_EXP_DEVSTA -+#define PCI_EXP_DEVSTA 10 -+#define PCI_EXP_DEVSTA_CED 0x01 -+#define PCI_EXP_DEVSTA_NFED 0x02 -+#define PCI_EXP_DEVSTA_FED 0x04 -+#define PCI_EXP_DEVSTA_URD 0x08 -+#endif -+ -+#ifndef PCI_EXP_LNKSTA -+#define PCI_EXP_LNKSTA 18 -+#endif -+ -+#ifndef PCI_EXP_LNKSTA_CLS -+#define PCI_EXP_LNKSTA_CLS 0x000f -+#endif -+ -+#ifndef PCI_EXP_LNKSTA_CLS_2_5GB -+#define PCI_EXP_LNKSTA_CLS_2_5GB 0x01 -+#endif -+ -+#ifndef PCI_EXP_LNKSTA_CLS_5_0GB -+#define PCI_EXP_LNKSTA_CLS_5_0GB 0x02 -+#endif -+ -+#ifndef PCI_EXP_LNKSTA_NLW -+#define PCI_EXP_LNKSTA_NLW 0x03f0 -+#endif -+ -+#ifndef PCI_EXP_LNKSTA_NLW_SHIFT -+#define PCI_EXP_LNKSTA_NLW_SHIFT 4 -+#endif -+ -+#ifndef PCI_EXP_DEVCTL -+#define PCI_EXP_DEVCTL 8 -+#endif -+#ifndef PCI_EXP_DEVCTL_READRQ -+#define PCI_EXP_DEVCTL_READRQ 0x7000 -+#endif -+ -+#ifndef BCM_HAS_PCIE_GET_READRQ -+int pcie_get_readrq(struct pci_dev *dev) -+{ -+ int ret, cap; -+ u16 ctl; -+ -+ cap = pci_find_capability(dev, PCI_CAP_ID_EXP); -+ if (!cap) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl); -+ if (!ret) -+ ret = 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12); -+ -+out: -+ return ret; -+} -+#endif /* BCM_HAS_PCIE_GET_READRQ */ -+ -+#ifndef BCM_HAS_PCIE_SET_READRQ -+static inline int pcie_set_readrq(struct pci_dev *dev, int rq) -+{ -+ int cap, err = -EINVAL; -+ u16 ctl, v; -+ -+ if (rq < 128 || rq > 4096 || (rq & (rq-1))) -+ goto out; -+ -+ v = (ffs(rq) - 8) << 12; -+ -+ cap = pci_find_capability(dev, PCI_CAP_ID_EXP); -+ if (!cap) -+ goto out; -+ -+ err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl); -+ if (err) -+ goto out; -+ -+ if ((ctl & PCI_EXP_DEVCTL_READRQ) != v) { -+ ctl &= ~PCI_EXP_DEVCTL_READRQ; -+ ctl |= v; -+ err = pci_write_config_dword(dev, cap + PCI_EXP_DEVCTL, ctl); -+ } -+ -+out: -+ return err; -+} -+#endif /* BCM_HAS_PCIE_SET_READRQ */ -+ -+#ifndef BCM_HAS_PCI_READ_VPD -+#if !defined(PCI_CAP_ID_VPD) -+#define PCI_CAP_ID_VPD 0x03 -+#endif -+#if !defined(PCI_VPD_ADDR) -+#define PCI_VPD_ADDR 2 -+#endif -+#if !defined(PCI_VPD_DATA) -+#define PCI_VPD_DATA 4 -+#endif -+static inline ssize_t -+pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, u8 *buf) -+{ -+ int i, vpd_cap; -+ -+ vpd_cap = pci_find_capability(dev, PCI_CAP_ID_VPD); -+ if (!vpd_cap) -+ return -ENODEV; -+ -+ for (i = 0; i < count; i += 4) { -+ u32 tmp, j = 0; -+ __le32 v; -+ u16 tmp16; -+ -+ pci_write_config_word(dev, vpd_cap + PCI_VPD_ADDR, i); -+ while (j++ < 100) { -+ pci_read_config_word(dev, vpd_cap + -+ PCI_VPD_ADDR, &tmp16); -+ if (tmp16 & 0x8000) -+ break; -+ msleep(1); -+ } -+ if (!(tmp16 & 0x8000)) -+ break; -+ -+ pci_read_config_dword(dev, vpd_cap + PCI_VPD_DATA, &tmp); -+ v = cpu_to_le32(tmp); -+ memcpy(&buf[i], &v, sizeof(v)); -+ } -+ -+ return i; -+} -+#endif /* BCM_HAS_PCI_READ_VPD */ -+ -+#ifndef PCI_VPD_RO_KEYWORD_CHKSUM -+#define PCI_VPD_RO_KEYWORD_CHKSUM "RV" -+#endif -+ -+#ifndef PCI_VPD_LRDT -+#define PCI_VPD_LRDT 0x80 /* Large Resource Data Type */ -+#define PCI_VPD_LRDT_ID(x) (x | PCI_VPD_LRDT) -+ -+/* Large Resource Data Type Tag Item Names */ -+#define PCI_VPD_LTIN_ID_STRING 0x02 /* Identifier String */ -+#define PCI_VPD_LTIN_RO_DATA 0x10 /* Read-Only Data */ -+#define PCI_VPD_LTIN_RW_DATA 0x11 /* Read-Write Data */ -+ -+#define PCI_VPD_LRDT_ID_STRING PCI_VPD_LRDT_ID(PCI_VPD_LTIN_ID_STRING) -+#define PCI_VPD_LRDT_RO_DATA PCI_VPD_LRDT_ID(PCI_VPD_LTIN_RO_DATA) -+#define PCI_VPD_LRDT_RW_DATA PCI_VPD_LRDT_ID(PCI_VPD_LTIN_RW_DATA) -+ -+/* Small Resource Data Type Tag Item Names */ -+#define PCI_VPD_STIN_END 0x78 /* End */ -+ -+#define PCI_VPD_SRDT_END PCI_VPD_STIN_END -+ -+#define PCI_VPD_SRDT_TIN_MASK 0x78 -+#define PCI_VPD_SRDT_LEN_MASK 0x07 -+ -+#define PCI_VPD_LRDT_TAG_SIZE 3 -+#define PCI_VPD_SRDT_TAG_SIZE 1 -+ -+#define PCI_VPD_INFO_FLD_HDR_SIZE 3 -+ -+#define PCI_VPD_RO_KEYWORD_PARTNO "PN" -+#define PCI_VPD_RO_KEYWORD_MFR_ID "MN" -+#define PCI_VPD_RO_KEYWORD_VENDOR0 "V0" -+ -+/** -+ * pci_vpd_lrdt_size - Extracts the Large Resource Data Type length -+ * @lrdt: Pointer to the beginning of the Large Resource Data Type tag -+ * -+ * Returns the extracted Large Resource Data Type length. -+ */ -+static inline u16 pci_vpd_lrdt_size(const u8 *lrdt) -+{ -+ return (u16)lrdt[1] + ((u16)lrdt[2] << 8); -+} -+ -+/** -+ * pci_vpd_srdt_size - Extracts the Small Resource Data Type length -+ * @lrdt: Pointer to the beginning of the Small Resource Data Type tag -+ * -+ * Returns the extracted Small Resource Data Type length. -+ */ -+static inline u8 pci_vpd_srdt_size(const u8 *srdt) -+{ -+ return (*srdt) & PCI_VPD_SRDT_LEN_MASK; -+} -+ -+/** -+ * pci_vpd_info_field_size - Extracts the information field length -+ * @lrdt: Pointer to the beginning of an information field header -+ * -+ * Returns the extracted information field length. -+ */ -+static inline u8 pci_vpd_info_field_size(const u8 *info_field) -+{ -+ return info_field[2]; -+} -+ -+static int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt) -+{ -+ int i; -+ -+ for (i = off; i < len; ) { -+ u8 val = buf[i]; -+ -+ if (val & PCI_VPD_LRDT) { -+ /* Don't return success of the tag isn't complete */ -+ if (i + PCI_VPD_LRDT_TAG_SIZE > len) -+ break; -+ -+ if (val == rdt) -+ return i; -+ -+ i += PCI_VPD_LRDT_TAG_SIZE + -+ pci_vpd_lrdt_size(&buf[i]); -+ } else { -+ u8 tag = val & ~PCI_VPD_SRDT_LEN_MASK; -+ -+ if (tag == rdt) -+ return i; -+ -+ if (tag == PCI_VPD_SRDT_END) -+ break; -+ -+ i += PCI_VPD_SRDT_TAG_SIZE + -+ pci_vpd_srdt_size(&buf[i]); -+ } -+ } -+ -+ return -ENOENT; -+} -+ -+static int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off, -+ unsigned int len, const char *kw) -+{ -+ int i; -+ -+ for (i = off; i + PCI_VPD_INFO_FLD_HDR_SIZE <= off + len;) { -+ if (buf[i + 0] == kw[0] && -+ buf[i + 1] == kw[1]) -+ return i; -+ -+ i += PCI_VPD_INFO_FLD_HDR_SIZE + -+ pci_vpd_info_field_size(&buf[i]); -+ } -+ -+ return -ENOENT; -+} -+#endif -+ -+#ifndef BCM_HAS_INTX_MSI_WORKAROUND -+static inline void tg3_enable_intx(struct pci_dev *pdev) -+{ -+#if (LINUX_VERSION_CODE < 0x2060e) -+ u16 pci_command; -+ -+ pci_read_config_word(pdev, PCI_COMMAND, &pci_command); -+ if (pci_command & PCI_COMMAND_INTX_DISABLE) -+ pci_write_config_word(pdev, PCI_COMMAND, -+ pci_command & ~PCI_COMMAND_INTX_DISABLE); -+#else -+ pci_intx(pdev, 1); -+#endif -+} -+#endif /* BCM_HAS_INTX_MSI_WORKAROUND */ -+ -+ -+#if (LINUX_VERSION_CODE >= 0x20613) || \ -+ (defined(__VMKLNX__) && defined(__USE_COMPAT_LAYER_2_6_18_PLUS__)) -+#define BCM_HAS_NEW_IRQ_SIG -+#endif -+ -+#if defined(INIT_DELAYED_WORK_DEFERRABLE) || \ -+ defined(INIT_DEFERRABLE_WORK) || \ -+ defined(INIT_WORK_NAR) || \ -+ (defined(__VMKLNX__) && defined(__USE_COMPAT_LAYER_2_6_18_PLUS__)) -+#define BCM_HAS_NEW_INIT_WORK -+#endif -+ -+#ifndef ETH_FCS_LEN -+#define ETH_FCS_LEN 4 -+#endif -+ -+#ifndef BCM_HAS_PRINT_MAC -+ -+#ifndef DECLARE_MAC_BUF -+#define DECLARE_MAC_BUF(_mac) char _mac[18] -+#endif -+ -+#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -+ -+static char *print_mac(char * buf, const u8 *addr) -+{ -+ sprintf(buf, MAC_FMT, -+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); -+ return buf; -+} -+#endif -+ -+ -+#ifndef NET_IP_ALIGN -+#define NET_IP_ALIGN 2 -+#endif -+ -+ -+#if !defined(BCM_HAS_ETHTOOL_OP_SET_TX_IPV6_CSUM) && \ -+ !defined(BCM_HAS_ETHTOOL_OP_SET_TX_HW_CSUM) && \ -+ defined(BCM_HAS_SET_TX_CSUM) -+static int tg3_set_tx_hw_csum(struct net_device *dev, u32 data) -+{ -+ if (data) -+ dev->features |= NETIF_F_HW_CSUM; -+ else -+ dev->features &= ~NETIF_F_HW_CSUM; -+ -+ return 0; -+} -+#endif -+ -+#ifndef NETDEV_TX_OK -+#define NETDEV_TX_OK 0 -+#endif -+ -+#ifndef NETDEV_TX_BUSY -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,32) -+#define NETDEV_TX_BUSY 0x1 -+#else -+#define NETDEV_TX_BUSY 0x10 -+#endif -+#endif -+ -+#ifndef NETDEV_TX_LOCKED -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,32) -+#define NETDEV_TX_LOCKED -1 -+#else -+#define NETDEV_TX_LOCKED 0x20 -+#endif -+#endif -+ -+#ifndef CHECKSUM_PARTIAL -+#define CHECKSUM_PARTIAL CHECKSUM_HW -+#endif -+ -+#ifndef NETIF_F_IPV6_CSUM -+#define NETIF_F_IPV6_CSUM 16 -+#define BCM_NO_IPV6_CSUM 1 -+#endif -+ -+#ifndef NETIF_F_RXCSUM -+#define NETIF_F_RXCSUM (1 << 29) -+#endif -+ -+#ifndef NETIF_F_GRO -+#define NETIF_F_GRO 16384 -+#endif -+ -+#ifndef NETIF_F_LOOPBACK -+#define NETIF_F_LOOPBACK (1 << 31) -+#endif -+ -+#ifdef NETIF_F_TSO -+#ifndef NETIF_F_GSO -+#define gso_size tso_size -+#define gso_segs tso_segs -+#endif -+#ifndef NETIF_F_TSO6 -+#define NETIF_F_TSO6 0 -+#define BCM_NO_TSO6 1 -+#endif -+#ifndef NETIF_F_TSO_ECN -+#define NETIF_F_TSO_ECN 0 -+#endif -+ -+#ifndef NETIF_F_ALL_TSO -+#define NETIF_F_ALL_TSO (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) -+#endif -+ -+#ifndef BCM_HAS_SKB_TX_TIMESTAMP -+#define skb_tx_timestamp(skb) -+#endif -+ -+#ifdef BCM_HAS_SKB_SHARED_TX_UNION -+#define tx_flags tx_flags.flags -+ -+/* Definitions for tx_flags in struct skb_shared_info */ -+enum { -+ /* generate hardware time stamp */ -+ SKBTX_HW_TSTAMP = 1 << 0, -+ -+ /* device driver is going to provide hardware time stamp */ -+ SKBTX_IN_PROGRESS = 1 << 2, -+}; -+#endif -+ -+#ifndef BCM_HAS_SKB_FRAG_SIZE -+#define skb_frag_size(skb_frag) ((skb_frag)->size) -+#endif -+ -+#if (LINUX_VERSION_CODE < 0x2060c) -+static inline int skb_header_cloned(struct sk_buff *skb) { return 0; } -+#endif -+ -+#ifndef BCM_HAS_SKB_TRANSPORT_OFFSET -+static inline int skb_transport_offset(const struct sk_buff *skb) -+{ -+ return (int) (skb->h.raw - skb->data); -+} -+#endif -+ -+#ifndef BCM_HAS_IP_HDR -+static inline struct iphdr *ip_hdr(const struct sk_buff *skb) -+{ -+ return skb->nh.iph; -+} -+#endif -+ -+#ifndef BCM_HAS_IP_HDRLEN -+static inline unsigned int ip_hdrlen(const struct sk_buff *skb) -+{ -+ return ip_hdr(skb)->ihl * 4; -+} -+#endif -+ -+#ifndef BCM_HAS_TCP_HDR -+static inline struct tcphdr *tcp_hdr(const struct sk_buff *skb) -+{ -+ return skb->h.th; -+} -+#endif -+ -+#ifndef BCM_HAS_TCP_HDRLEN -+static inline unsigned int tcp_hdrlen(const struct sk_buff *skb) -+{ -+ return tcp_hdr(skb)->doff * 4; -+} -+#endif -+ -+#ifndef BCM_HAS_TCP_OPTLEN -+static inline unsigned int tcp_optlen(const struct sk_buff *skb) -+{ -+ return (tcp_hdr(skb)->doff - 5) * 4; -+} -+#endif -+ -+#ifndef NETIF_F_GSO -+static struct sk_buff *skb_segment(struct sk_buff *skb, int features) -+{ -+ struct sk_buff *segs = NULL; -+ struct sk_buff *tail = NULL; -+ unsigned int mss = skb_shinfo(skb)->gso_size; -+ unsigned int doffset = skb->data - skb->mac.raw; -+ unsigned int offset = doffset; -+ unsigned int headroom; -+ unsigned int len; -+ int nfrags = skb_shinfo(skb)->nr_frags; -+ int err = -ENOMEM; -+ int i = 0; -+ int pos; -+ -+ __skb_push(skb, doffset); -+ headroom = skb_headroom(skb); -+ pos = skb_headlen(skb); -+ -+ do { -+ struct sk_buff *nskb; -+ skb_frag_t *frag; -+ int hsize; -+ int k; -+ int size; -+ -+ len = skb->len - offset; -+ if (len > mss) -+ len = mss; -+ -+ hsize = skb_headlen(skb) - offset; -+ if (hsize < 0) -+ hsize = 0; -+ if (hsize > len) -+ hsize = len; -+ -+ nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC); -+ if (unlikely(!nskb)) -+ goto err; -+ -+ if (segs) -+ tail->next = nskb; -+ else -+ segs = nskb; -+ tail = nskb; -+ -+ nskb->dev = skb->dev; -+ nskb->priority = skb->priority; -+ nskb->protocol = skb->protocol; -+ nskb->dst = dst_clone(skb->dst); -+ memcpy(nskb->cb, skb->cb, sizeof(skb->cb)); -+ nskb->pkt_type = skb->pkt_type; -+ nskb->mac_len = skb->mac_len; -+ -+ skb_reserve(nskb, headroom); -+ nskb->mac.raw = nskb->data; -+ nskb->nh.raw = nskb->data + skb->mac_len; -+ nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw); -+ memcpy(skb_put(nskb, doffset), skb->data, doffset); -+ -+ frag = skb_shinfo(nskb)->frags; -+ k = 0; -+ -+ nskb->ip_summed = CHECKSUM_PARTIAL; -+ nskb->csum = skb->csum; -+ memcpy(skb_put(nskb, hsize), skb->data + offset, hsize); -+ -+ while (pos < offset + len) { -+ BUG_ON(i >= nfrags); -+ -+ *frag = skb_shinfo(skb)->frags[i]; -+ get_page(frag->page); -+ size = frag->size; -+ -+ if (pos < offset) { -+ frag->page_offset += offset - pos; -+ frag->size -= offset - pos; -+ } -+ -+ k++; -+ -+ if (pos + size <= offset + len) { -+ i++; -+ pos += size; -+ } else { -+ frag->size -= pos + size - (offset + len); -+ break; -+ } -+ -+ frag++; -+ } -+ -+ skb_shinfo(nskb)->nr_frags = k; -+ nskb->data_len = len - hsize; -+ nskb->len += nskb->data_len; -+ nskb->truesize += nskb->data_len; -+ } while ((offset += len) < skb->len); -+ -+ return segs; -+ -+err: -+ while ((skb = segs)) { -+ segs = skb->next; -+ kfree(skb); -+ } -+ return ERR_PTR(err); -+} -+ -+static struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features) -+{ -+ struct sk_buff *segs = ERR_PTR(-EINVAL); -+ struct tcphdr *th; -+ unsigned thlen; -+ unsigned int seq; -+ u32 delta; -+ unsigned int oldlen; -+ unsigned int len; -+ -+ if (!pskb_may_pull(skb, sizeof(*th))) -+ goto out; -+ -+ th = skb->h.th; -+ thlen = th->doff * 4; -+ if (thlen < sizeof(*th)) -+ goto out; -+ -+ if (!pskb_may_pull(skb, thlen)) -+ goto out; -+ -+ oldlen = (u16)~skb->len; -+ __skb_pull(skb, thlen); -+ -+ segs = skb_segment(skb, features); -+ if (IS_ERR(segs)) -+ goto out; -+ -+ len = skb_shinfo(skb)->gso_size; -+ delta = htonl(oldlen + (thlen + len)); -+ -+ skb = segs; -+ th = skb->h.th; -+ seq = ntohl(th->seq); -+ -+ do { -+ th->fin = th->psh = 0; -+ -+ th->check = ~csum_fold((u32)((u32)th->check + -+ (u32)delta)); -+ seq += len; -+ skb = skb->next; -+ th = skb->h.th; -+ -+ th->seq = htonl(seq); -+ th->cwr = 0; -+ } while (skb->next); -+ -+ delta = htonl(oldlen + (skb->tail - skb->h.raw) + skb->data_len); -+ th->check = ~csum_fold((u32)((u32)th->check + -+ (u32)delta)); -+out: -+ return segs; -+} -+ -+static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) -+{ -+ struct sk_buff *segs = ERR_PTR(-EINVAL); -+ struct iphdr *iph; -+ int ihl; -+ int id; -+ -+ if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) -+ goto out; -+ -+ iph = skb->nh.iph; -+ ihl = iph->ihl * 4; -+ if (ihl < sizeof(*iph)) -+ goto out; -+ -+ if (unlikely(!pskb_may_pull(skb, ihl))) -+ goto out; -+ -+ skb->h.raw = __skb_pull(skb, ihl); -+ iph = skb->nh.iph; -+ id = ntohs(iph->id); -+ segs = ERR_PTR(-EPROTONOSUPPORT); -+ -+ segs = tcp_tso_segment(skb, features); -+ -+ if (!segs || IS_ERR(segs)) -+ goto out; -+ -+ skb = segs; -+ do { -+ iph = skb->nh.iph; -+ iph->id = htons(id++); -+ iph->tot_len = htons(skb->len - skb->mac_len); -+ iph->check = 0; -+ iph->check = ip_fast_csum(skb->nh.raw, iph->ihl); -+ } while ((skb = skb->next)); -+ -+out: -+ return segs; -+} -+ -+static struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) -+{ -+ struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); -+ -+ skb->mac.raw = skb->data; -+ skb->mac_len = skb->nh.raw - skb->data; -+ __skb_pull(skb, skb->mac_len); -+ -+ segs = inet_gso_segment(skb, features); -+ -+ __skb_push(skb, skb->data - skb->mac.raw); -+ return segs; -+} -+#endif /* NETIF_F_GSO */ -+ -+#endif /* NETIF_F_TSO */ -+ -+#ifndef BCM_HAS_SKB_COPY_FROM_LINEAR_DATA -+static inline void skb_copy_from_linear_data(const struct sk_buff *skb, -+ void *to, -+ const unsigned int len) -+{ -+ memcpy(to, skb->data, len); -+} -+#endif -+ -+#if TG3_TSO_SUPPORT != 0 -+#if defined(BCM_NO_TSO6) -+static inline int skb_is_gso_v6(const struct sk_buff *skb) -+{ -+ return 0; -+} -+#else -+#if !defined(BCM_HAS_SKB_IS_GSO_V6) -+static inline int skb_is_gso_v6(const struct sk_buff *skb) -+{ -+ return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6; -+} -+#endif -+#endif -+#endif -+ -+#ifndef BCM_HAS_SKB_CHECKSUM_NONE_ASSERT -+static inline void skb_checksum_none_assert(struct sk_buff *skb) -+{ -+ skb->ip_summed = CHECKSUM_NONE; -+} -+#endif -+ -+#ifndef BCM_HAS_NETDEV_TX_T -+typedef int netdev_tx_t; -+#endif -+ -+#ifndef BCM_HAS_NETDEV_FEATURES_T -+typedef u32 netdev_features_t; -+#endif -+ -+#ifndef BCM_HAS_NETDEV_NAME -+#define netdev_name(netdev) netdev->name -+#endif -+ -+#if defined(netdev_printk) && (LINUX_VERSION_CODE < 0x020609) -+/* SLES 9.X provides their own print routines, but they are not compatible -+ * with the versions found in the latest upstream kernel. The kernel -+ * version check above was picked out of the air as a value greater than -+ * 2.6.5-7.308, but any number that preserves this boundary should be -+ * acceptable. -+ */ -+#undef netdev_printk -+#undef netdev_info -+#undef netdev_err -+#undef netdev_warn -+#endif -+ -+#ifndef netdev_printk -+#define netdev_printk(level, netdev, format, args...) \ -+ dev_printk(level, tp->pdev->dev.parent, \ -+ "%s: " format, \ -+ netdev_name(tp->dev), ##args) -+#endif -+ -+#ifndef netif_printk -+#define netif_printk(priv, type, level, dev, fmt, args...) \ -+do { \ -+ if (netif_msg_##type(priv)) \ -+ netdev_printk(level, (dev), fmt, ##args); \ -+} while (0) -+#endif -+ -+#ifndef netif_info -+#define netif_info(priv, type, dev, fmt, args...) \ -+ netif_printk(priv, type, KERN_INFO, (dev), fmt, ##args) -+#endif -+ -+#ifndef netdev_err -+#define netdev_err(dev, format, args...) \ -+ netdev_printk(KERN_ERR, dev, format, ##args) -+#endif -+ -+#ifndef netdev_warn -+#define netdev_warn(dev, format, args...) \ -+ netdev_printk(KERN_WARNING, dev, format, ##args) -+#endif -+ -+#ifndef netdev_notice -+#define netdev_notice(dev, format, args...) \ -+ netdev_printk(KERN_NOTICE, dev, format, ##args) -+#endif -+ -+#ifndef netdev_info -+#define netdev_info(dev, format, args...) \ -+ netdev_printk(KERN_INFO, dev, format, ##args) -+#endif -+ -+#ifndef BCM_HAS_NETIF_TX_LOCK -+static inline void netif_tx_lock(struct net_device *dev) -+{ -+ spin_lock(&dev->xmit_lock); -+ dev->xmit_lock_owner = smp_processor_id(); -+} -+ -+static inline void netif_tx_unlock(struct net_device *dev) -+{ -+ dev->xmit_lock_owner = -1; -+ spin_unlock(&dev->xmit_lock); -+} -+#endif /* BCM_HAS_NETIF_TX_LOCK */ -+ -+#if defined(BCM_HAS_STRUCT_NETDEV_QUEUE) || \ -+ (defined(__VMKLNX__) && defined(__USE_COMPAT_LAYER_2_6_18_PLUS__)) -+ -+#define TG3_NAPI -+#define napi_complete_(dev, napi) napi_complete((napi)) -+#define napi_schedule_(dev, napi) napi_schedule((napi)) -+#define tg3_netif_rx_schedule_prep(dev, napi) napi_schedule_prep((napi)) -+ -+#else /* BCM_HAS_STRUCT_NETDEV_QUEUE */ -+ -+#define netdev_queue net_device -+#define netdev_get_tx_queue(dev, i) (dev) -+#define netif_tx_start_queue(dev) netif_start_queue((dev)) -+#define netif_tx_start_all_queues(dev) netif_start_queue((dev)) -+#define netif_tx_stop_queue(dev) netif_stop_queue((dev)) -+#define netif_tx_stop_all_queues(dev) netif_stop_queue((dev)) -+#define netif_tx_queue_stopped(dev) netif_queue_stopped((dev)) -+#define netif_tx_wake_queue(dev) netif_wake_queue((dev)) -+#define netif_tx_wake_all_queues(dev) netif_wake_queue((dev)) -+#define __netif_tx_lock(txq, procid) netif_tx_lock((txq)) -+#define __netif_tx_unlock(txq) netif_tx_unlock((txq)) -+ -+#if defined(BCM_HAS_NEW_NETIF_INTERFACE) -+#define TG3_NAPI -+#define napi_complete_(dev, napi) netif_rx_complete((dev), (napi)) -+#define napi_schedule_(dev, napi) netif_rx_schedule((dev), (napi)) -+#define tg3_netif_rx_schedule_prep(dev, napi) netif_rx_schedule_prep((dev), (napi)) -+#else /* BCM_HAS_NEW_NETIF_INTERFACE */ -+#define napi_complete_(dev, napi) netif_rx_complete((dev)) -+#define napi_schedule_(dev, napi) netif_rx_schedule((dev)) -+#define tg3_netif_rx_schedule_prep(dev, napi) netif_rx_schedule_prep((dev)) -+#endif /* BCM_HAS_NEW_NETIF_INTERFACE */ -+ -+#endif /* BCM_HAS_STRUCT_NETDEV_QUEUE */ -+ -+#if !defined(BCM_HAS_ALLOC_ETHERDEV_MQ) || !defined(TG3_NAPI) -+#define alloc_etherdev_mq(size, numqs) alloc_etherdev((size)) -+#endif -+ -+#if !defined(TG3_NAPI) || !defined(BCM_HAS_VLAN_GRO_RECEIVE) -+#define vlan_gro_receive(nap, grp, tag, skb) \ -+ vlan_hwaccel_receive_skb((skb), (grp), (tag)) -+#endif -+ -+#ifndef NETIF_F_HW_VLAN_CTAG_TX -+#define NETIF_F_HW_VLAN_CTAG_TX NETIF_F_HW_VLAN_TX -+#else -+#define BCM_HWACCEL_HAS_PROTO_ARG -+#endif -+ -+#ifndef NETIF_F_HW_VLAN_CTAG_RX -+#define NETIF_F_HW_VLAN_CTAG_RX NETIF_F_HW_VLAN_RX -+#endif -+#if !defined(TG3_NAPI) || !defined(BCM_HAS_NAPI_GRO_RECEIVE) -+#define napi_gro_receive(nap, skb) \ -+ netif_receive_skb((skb)) -+#endif -+ -+#if !defined(BCM_HAS_SKB_GET_QUEUE_MAPPING) || !defined(TG3_NAPI) -+#define skb_get_queue_mapping(skb) 0 -+#endif -+ -+#ifdef TG3_NAPI -+#if (LINUX_VERSION_CODE < 0x02061b) && !defined(__VMKLNX__) -+ -+static inline void netif_napi_del(struct napi_struct *napi) -+{ -+#ifdef CONFIG_NETPOLL -+ list_del(&napi->dev_list); -+#endif -+} -+#endif -+ -+#endif -+#if (LINUX_VERSION_CODE < 0x020612) -+static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev, -+ unsigned int length) -+{ -+ struct sk_buff *skb = dev_alloc_skb(length); -+ if (skb) -+ skb->dev = dev; -+ return skb; -+} -+#endif -+ -+#ifndef BCM_HAS_NETDEV_PRIV -+static inline void *netdev_priv(struct net_device *dev) -+{ -+ return dev->priv; -+} -+#endif -+ -+#ifdef OLD_NETIF -+static inline void netif_poll_disable(struct net_device *dev) -+{ -+ while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) { -+ /* No hurry. */ -+ current->state = TASK_INTERRUPTIBLE; -+ schedule_timeout(1); -+ } -+} -+ -+static inline void netif_poll_enable(struct net_device *dev) -+{ -+ clear_bit(__LINK_STATE_RX_SCHED, &dev->state); -+} -+ -+static inline void netif_tx_disable(struct net_device *dev) -+{ -+ spin_lock_bh(&dev->xmit_lock); -+ netif_stop_queue(dev); -+ spin_unlock_bh(&dev->xmit_lock); -+} -+#endif /* OLD_NETIF */ -+ -+#ifndef BCM_HAS_NETDEV_SENT_QUEUE -+#define netdev_sent_queue(dev, bytes) -+#endif -+ -+#ifndef BCM_HAS_NETDEV_TX_SENT_QUEUE -+#define netdev_tx_sent_queue(q, bytes) \ -+ netdev_sent_queue(tp->dev, bytes) -+#endif -+ -+#ifndef BCM_HAS_NETDEV_COMPLETED_QUEUE -+#define netdev_completed_queue(dev, pkts, bytes) -+#endif -+ -+#ifndef BCM_HAS_NETDEV_TX_COMPLETED_QUEUE -+#define netdev_tx_completed_queue(q, pkt_cnt, byte_cnt) \ -+ netdev_completed_queue(tp->dev, pkt_cnt, byte_cnt) -+#endif -+ -+#ifndef BCM_HAS_NETDEV_RESET_QUEUE -+#define netdev_reset_queue(dev_queue) -+#endif -+ -+#ifndef BCM_HAS_NETDEV_TX_RESET_QUEUE -+#define netdev_tx_reset_queue(q) \ -+ netdev_reset_queue(tp->dev) -+#endif -+ -+#ifndef BCM_HAS_NETIF_SET_REAL_NUM_TX_QUEUES -+#define netif_set_real_num_tx_queues(dev, nq) ((dev)->real_num_tx_queues = (nq)) -+#endif -+ -+#ifndef BCM_HAS_NETIF_SET_REAL_NUM_RX_QUEUES -+#define netif_set_real_num_rx_queues(dev, nq) 0 -+#endif -+ -+#ifndef netdev_mc_count -+#define netdev_mc_count(dev) ((dev)->mc_count) -+#endif -+ -+#ifndef netdev_mc_empty -+#define netdev_mc_empty(dev) (netdev_mc_count(dev) == 0) -+#endif -+ -+/* -+ * Commit ID 22bedad3ce112d5ca1eaf043d4990fa2ed698c87 is the patch that -+ * undefines dmi_addr and pivots the code to use netdev_hw_addr rather -+ * than dev_mc_list. Commit ID 6683ece36e3531fc8c75f69e7165c5f20930be88 -+ * is the patch that introduces netdev_for_each_mc_addr. Commit ID -+ * f001fde5eadd915f4858d22ed70d7040f48767cf is the patch that introduces -+ * netdev_hw_addr. These features are presented in reverse chronological -+ * order. -+ */ -+#ifdef BCM_HAS_NETDEV_HW_ADDR -+#ifdef dmi_addr -+#undef netdev_for_each_mc_addr -+#define netdev_for_each_mc_addr(ha, dev) \ -+ struct dev_mc_list * oldmclist; \ -+ struct netdev_hw_addr foo; \ -+ ha = &foo; \ -+ for (oldmclist = dev->mc_list; oldmclist && memcpy(foo.addr, oldmclist->dmi_addr, 6); oldmclist = oldmclist->next) -+#endif -+#else /* BCM_HAS_NETDEV_HW_ADDR */ -+struct netdev_hw_addr { -+ u8 * addr; -+ struct dev_mc_list * curr; -+}; -+#undef netdev_for_each_mc_addr -+#define netdev_for_each_mc_addr(ha, dev) \ -+ struct netdev_hw_addr mclist; \ -+ ha = &mclist; \ -+ for (mclist.curr = dev->mc_list; mclist.curr && (mclist.addr = &mclist.curr->dmi_addr[0]); mclist.curr = mclist.curr->next) -+#endif /* BCM_HAS_NETDEV_HW_ADDR */ -+ -+#ifndef BCM_HAS_GET_STATS64 -+#define rtnl_link_stats64 net_device_stats -+#endif /* BCM_HAS_GET_STATS64 */ -+ -+#ifndef BCM_HAS_EXTERNAL_LB_DONE -+#define ETH_TEST_FL_EXTERNAL_LB (1 << 2) -+#define ETH_TEST_FL_EXTERNAL_LB_DONE (1 << 3) -+#endif -+ -+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -+#define BCM_KERNEL_SUPPORTS_8021Q -+#endif -+ -+#ifndef ETH_SS_TEST -+#define ETH_SS_TEST 0 -+#endif -+#ifndef ETH_SS_STATS -+#define ETH_SS_STATS 1 -+#endif -+#ifndef ADVERTISED_Pause -+#define ADVERTISED_Pause (1 << 13) -+#endif -+#ifndef ADVERTISED_Asym_Pause -+#define ADVERTISED_Asym_Pause (1 << 14) -+#endif -+ -+#ifndef ADVERTISED_1000baseKX_Full -+#define ADVERTISED_1000baseKX_Full (1 << 17) -+#endif -+ -+#ifndef MII_CTRL1000 -+#define MII_CTRL1000 0x09 -+#endif -+#ifndef ADVERTISE_1000HALF -+#define ADVERTISE_1000HALF 0x0100 -+#endif -+#ifndef ADVERTISE_1000FULL -+#define ADVERTISE_1000FULL 0x0200 -+#endif -+#ifndef CTL1000_AS_MASTER -+#define CTL1000_AS_MASTER 0x0800 -+#endif -+#ifndef CTL1000_ENABLE_MASTER -+#define CTL1000_ENABLE_MASTER 0x1000 -+#endif -+#ifndef MII_STAT1000 -+#define MII_STAT1000 0x0a -+#endif -+#ifndef BMCR_SPEED1000 -+#define BMCR_SPEED1000 0x0040 -+#endif -+#ifndef ADVERTISE_1000XFULL -+#define ADVERTISE_1000XFULL 0x0020 -+#endif -+#ifndef ADVERTISE_1000XHALF -+#define ADVERTISE_1000XHALF 0x0040 -+#endif -+#ifndef ADVERTISE_1000XPAUSE -+#define ADVERTISE_1000XPAUSE 0x0080 -+#endif -+#ifndef ADVERTISE_1000XPSE_ASYM -+#define ADVERTISE_1000XPSE_ASYM 0x0100 -+#endif -+#ifndef ADVERTISE_PAUSE -+#define ADVERTISE_PAUSE_CAP 0x0400 -+#endif -+#ifndef ADVERTISE_PAUSE_ASYM -+#define ADVERTISE_PAUSE_ASYM 0x0800 -+#endif -+#ifndef LPA_1000XFULL -+#define LPA_1000XFULL 0x0020 -+#endif -+#ifndef LPA_1000XHALF -+#define LPA_1000XHALF 0x0040 -+#endif -+#ifndef LPA_1000XPAUSE -+#define LPA_1000XPAUSE 0x0080 -+#endif -+#ifndef LPA_1000XPAUSE_ASYM -+#define LPA_1000XPAUSE_ASYM 0x0100 -+#endif -+#ifndef LPA_PAUSE -+#define LPA_PAUSE_CAP 0x0400 -+#endif -+#ifndef LPA_PAUSE_ASYM -+#define LPA_PAUSE_ASYM 0x0800 -+#endif -+#ifndef LPA_1000FULL -+#define LPA_1000FULL 0x0800 -+#endif -+#ifndef LPA_1000HALF -+#define LPA_1000HALF 0x0400 -+#endif -+ -+#ifndef ETHTOOL_FWVERS_LEN -+#define ETHTOOL_FWVERS_LEN 32 -+#endif -+ -+#ifndef MDIO_MMD_AN -+#define MDIO_MMD_AN 7 -+#endif -+ -+#ifndef MDIO_AN_EEE_ADV -+#define MDIO_AN_EEE_ADV 60 -+#endif -+ -+#ifndef MDIO_AN_EEE_ADV_100TX -+#define MDIO_AN_EEE_ADV_100TX 0x0002 -+#endif -+ -+#ifndef MDIO_AN_EEE_ADV_1000T -+#define MDIO_AN_EEE_ADV_1000T 0x0004 -+#endif -+ -+#ifndef MDIO_AN_EEE_LPABLE -+#define MDIO_AN_EEE_LPABLE 61 -+#endif -+ -+#ifndef MDIO_EEE_100TX -+#define MDIO_EEE_100TX MDIO_AN_EEE_ADV_100TX /* 100TX EEE cap */ -+#endif -+ -+#ifndef MDIO_EEE_1000T -+#define MDIO_EEE_1000T MDIO_AN_EEE_ADV_1000T /* 1000T EEE cap */ -+#endif -+ -+#ifndef MDIO_EEE_1000KX -+#define MDIO_EEE_1000KX 0x0010 /* 1000KX EEE cap */ -+#endif -+ -+#ifndef BCM_HAS_MMD_EEE_ADV_TO_ETHTOOL -+/** -+ * mmd_eee_adv_to_ethtool_adv_t -+ * @eee_adv: value of the MMD EEE Advertisement/Link Partner Ability registers -+ * -+ * A small helper function that translates the MMD EEE Advertisment (7.60) -+ * and MMD EEE Link Partner Ability (7.61) bits to ethtool advertisement -+ * settings. -+ */ -+static inline u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv) -+{ -+ u32 adv = 0; -+ -+ if (eee_adv & MDIO_EEE_100TX) -+ adv |= ADVERTISED_100baseT_Full; -+ if (eee_adv & MDIO_EEE_1000T) -+ adv |= ADVERTISED_1000baseT_Full; -+ if (eee_adv & MDIO_EEE_1000KX) -+ adv |= ADVERTISED_1000baseKX_Full; -+ -+ return adv; -+} -+#endif -+ -+#ifndef SPEED_UNKNOWN -+#define SPEED_UNKNOWN -1 -+#endif -+ -+#ifndef DUPLEX_UNKNOWN -+#define DUPLEX_UNKNOWN 0xff -+#endif -+ -+#ifndef BCM_HAS_ETHTOOL_ADV_TO_MII_ADV_T -+static inline u32 ethtool_adv_to_mii_adv_t(u32 ethadv) -+{ -+ u32 result = 0; -+ -+ if (ethadv & ADVERTISED_10baseT_Half) -+ result |= ADVERTISE_10HALF; -+ if (ethadv & ADVERTISED_10baseT_Full) -+ result |= ADVERTISE_10FULL; -+ if (ethadv & ADVERTISED_100baseT_Half) -+ result |= ADVERTISE_100HALF; -+ if (ethadv & ADVERTISED_100baseT_Full) -+ result |= ADVERTISE_100FULL; -+ if (ethadv & ADVERTISED_Pause) -+ result |= ADVERTISE_PAUSE_CAP; -+ if (ethadv & ADVERTISED_Asym_Pause) -+ result |= ADVERTISE_PAUSE_ASYM; -+ -+ return result; -+} -+ -+static inline u32 mii_adv_to_ethtool_adv_t(u32 adv) -+{ -+ u32 result = 0; -+ -+ if (adv & ADVERTISE_10HALF) -+ result |= ADVERTISED_10baseT_Half; -+ if (adv & ADVERTISE_10FULL) -+ result |= ADVERTISED_10baseT_Full; -+ if (adv & ADVERTISE_100HALF) -+ result |= ADVERTISED_100baseT_Half; -+ if (adv & ADVERTISE_100FULL) -+ result |= ADVERTISED_100baseT_Full; -+ if (adv & ADVERTISE_PAUSE_CAP) -+ result |= ADVERTISED_Pause; -+ if (adv & ADVERTISE_PAUSE_ASYM) -+ result |= ADVERTISED_Asym_Pause; -+ -+ return result; -+} -+ -+static inline u32 ethtool_adv_to_mii_ctrl1000_t(u32 ethadv) -+{ -+ u32 result = 0; -+ -+ if (ethadv & ADVERTISED_1000baseT_Half) -+ result |= ADVERTISE_1000HALF; -+ if (ethadv & ADVERTISED_1000baseT_Full) -+ result |= ADVERTISE_1000FULL; -+ -+ return result; -+} -+ -+static inline u32 mii_ctrl1000_to_ethtool_adv_t(u32 adv) -+{ -+ u32 result = 0; -+ -+ if (adv & ADVERTISE_1000HALF) -+ result |= ADVERTISED_1000baseT_Half; -+ if (adv & ADVERTISE_1000FULL) -+ result |= ADVERTISED_1000baseT_Full; -+ -+ return result; -+} -+ -+static inline u32 mii_lpa_to_ethtool_lpa_t(u32 lpa) -+{ -+ u32 result = 0; -+ -+ if (lpa & LPA_LPACK) -+ result |= ADVERTISED_Autoneg; -+ -+ return result | mii_adv_to_ethtool_adv_t(lpa); -+} -+ -+static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa) -+{ -+ u32 result = 0; -+ -+ if (lpa & LPA_1000HALF) -+ result |= ADVERTISED_1000baseT_Half; -+ if (lpa & LPA_1000FULL) -+ result |= ADVERTISED_1000baseT_Full; -+ -+ return result; -+} -+ -+static inline u32 ethtool_adv_to_mii_adv_x(u32 ethadv) -+{ -+ u32 result = 0; -+ -+ if (ethadv & ADVERTISED_1000baseT_Half) -+ result |= ADVERTISE_1000XHALF; -+ if (ethadv & ADVERTISED_1000baseT_Full) -+ result |= ADVERTISE_1000XFULL; -+ if (ethadv & ADVERTISED_Pause) -+ result |= ADVERTISE_1000XPAUSE; -+ if (ethadv & ADVERTISED_Asym_Pause) -+ result |= ADVERTISE_1000XPSE_ASYM; -+ -+ return result; -+} -+ -+static inline u32 mii_adv_to_ethtool_adv_x(u32 adv) -+{ -+ u32 result = 0; -+ -+ if (adv & ADVERTISE_1000XHALF) -+ result |= ADVERTISED_1000baseT_Half; -+ if (adv & ADVERTISE_1000XFULL) -+ result |= ADVERTISED_1000baseT_Full; -+ if (adv & ADVERTISE_1000XPAUSE) -+ result |= ADVERTISED_Pause; -+ if (adv & ADVERTISE_1000XPSE_ASYM) -+ result |= ADVERTISED_Asym_Pause; -+ -+ return result; -+} -+ -+static inline u32 mii_lpa_to_ethtool_lpa_x(u32 lpa) -+{ -+ u32 result = 0; -+ -+ if (lpa & LPA_LPACK) -+ result |= ADVERTISED_Autoneg; -+ -+ return result | mii_adv_to_ethtool_adv_x(lpa); -+} -+#endif /* BCM_HAS_ETHTOOL_ADV_TO_MII_100BT */ -+ -+#ifndef BCM_HAS_ETHTOOL_RXFH_INDIR_DEFAULT -+static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings) -+{ -+ return index % n_rx_rings; -+} -+#endif /* BCM_HAS_ETHTOOL_RXFH_INDIR_DEFAULT */ -+ -+#ifndef BCM_HAS_MII_RESOLVE_FLOWCTRL_FDX -+#ifndef FLOW_CTRL_TX -+#define FLOW_CTRL_TX 0x01 -+#endif -+#ifndef FLOW_CTRL_RX -+#define FLOW_CTRL_RX 0x02 -+#endif -+static u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv) -+{ -+ u8 cap = 0; -+ -+ if (lcladv & rmtadv & ADVERTISE_PAUSE_CAP) { -+ cap = FLOW_CTRL_TX | FLOW_CTRL_RX; -+ } else if (lcladv & ADVERTISE_PAUSE_ASYM) { -+ if (lcladv & LPA_PAUSE_CAP) -+ cap = FLOW_CTRL_RX; -+ if (rmtadv & LPA_PAUSE_CAP) -+ cap = FLOW_CTRL_TX; -+ } -+ -+ return cap; -+} -+#endif /* BCM_HAS_MII_RESOLVE_FLOWCTRL_FDX */ -+ -+#ifndef BCM_HAS_MII_ADVERTISE_FLOWCTRL -+static u16 mii_advertise_flowctrl(u8 flow_ctrl) -+{ -+ u16 miireg; -+ -+ if ((flow_ctrl & FLOW_CTRL_TX) && (flow_ctrl & FLOW_CTRL_RX)) -+ miireg = ADVERTISE_PAUSE_CAP; -+ else if (flow_ctrl & FLOW_CTRL_TX) -+ miireg = ADVERTISE_PAUSE_ASYM; -+ else if (flow_ctrl & FLOW_CTRL_RX) -+ miireg = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; -+ else -+ miireg = 0; -+ -+ return miireg; -+} -+#endif /* BCM_HAS_MII_ADVERTISE_FLOWCTRL */ -+ -+#ifdef BCM_INCLUDE_PHYLIB_SUPPORT -+ -+#ifndef PHY_ID_BCM50610 -+#define PHY_ID_BCM50610 0x0143bd60 -+#endif -+#ifndef PHY_ID_BCM50610M -+#define PHY_ID_BCM50610M 0x0143bd70 -+#endif -+#ifndef PHY_ID_BCM50612E -+#define PHY_ID_BCM50612E 0x03625e20 -+#endif -+#ifndef PHY_ID_BCMAC131 -+#define PHY_ID_BCMAC131 0x0143bc70 -+#endif -+#ifndef PHY_ID_BCM57780 -+#define PHY_ID_BCM57780 0x03625d90 -+#endif -+#ifndef PHY_BCM_OUI_MASK -+#define PHY_BCM_OUI_MASK 0xfffffc00 -+#endif -+#ifndef PHY_BCM_OUI_1 -+#define PHY_BCM_OUI_1 0x00206000 -+#endif -+#ifndef PHY_BCM_OUI_2 -+#define PHY_BCM_OUI_2 0x0143bc00 -+#endif -+#ifndef PHY_BCM_OUI_3 -+#define PHY_BCM_OUI_3 0x03625c00 -+#endif -+ -+#ifndef PHY_BRCM_STD_IBND_DISABLE -+#define PHY_BRCM_STD_IBND_DISABLE 0x00000800 -+#define PHY_BRCM_EXT_IBND_RX_ENABLE 0x00001000 -+#define PHY_BRCM_EXT_IBND_TX_ENABLE 0x00002000 -+#endif -+ -+#ifndef PHY_BRCM_RX_REFCLK_UNUSED -+#define PHY_BRCM_RX_REFCLK_UNUSED 0x00000400 -+#endif -+ -+#ifndef PHY_BRCM_CLEAR_RGMII_MODE -+#define PHY_BRCM_CLEAR_RGMII_MODE 0x00004000 -+#endif -+ -+#ifndef PHY_BRCM_DIS_TXCRXC_NOENRGY -+#define PHY_BRCM_DIS_TXCRXC_NOENRGY 0x00008000 -+#endif -+ -+#ifndef BCM_HAS_MDIOBUS_ALLOC -+static struct mii_bus *mdiobus_alloc(void) -+{ -+ struct mii_bus *bus; -+ -+ bus = kzalloc(sizeof(*bus), GFP_KERNEL); -+ -+ return bus; -+} -+ -+void mdiobus_free(struct mii_bus *bus) -+{ -+ kfree(bus); -+} -+#endif -+ -+#endif /* BCM_INCLUDE_PHYLIB_SUPPORT */ -+ -+#ifndef BCM_HAS_ETHTOOL_CMD_SPEED -+static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep) -+{ -+ return ep->speed; -+} -+#endif /* BCM_HAS_ETHTOOL_CMD_SPEED */ -+ -+#ifndef BCM_HAS_ETHTOOL_CMD_SPEED_SET -+static inline __u32 ethtool_cmd_speed_set(struct ethtool_cmd *ep, __u32 speed) -+{ -+ ep->speed = speed; -+ return 0; -+} -+#endif /* BCM_HAS_ETHTOOL_CMD_SPEED_SET */ -+ -+#ifdef BCM_HAS_PCI_BUSN_RES -+#define busn_res_end busn_res.end -+#else -+#define busn_res_end subordinate -+#endif -+ -+#ifndef __devinit -+#define __devinit -+#endif -+ -+#ifndef __devinitdata -+#define __devinitdata -+#endif -+ -+#ifndef __devexit -+#define __devexit -+#endif -+ -+#ifndef __devexit_p -+#define __devexit_p(x) (x) -+#endif -+ -+#ifndef CONFIG_SSB_DRIVER_GIGE -+#define ssb_gige_get_macaddr(a, b) (0) -+#define ssb_gige_get_phyaddr(a) (0) -+#define pdev_is_ssb_gige_core(a) (0) -+#define ssb_gige_must_flush_posted_writes(a) (0) -+#define ssb_gige_one_dma_at_once(a) (0) -+#define ssb_gige_have_roboswitch(a) (0) -+#define ssb_gige_is_rgmii(a) (0) -+#else -+#include -+#endif -+ -+#ifndef ETHTOOL_GEEE -+struct ethtool_eee { -+ __u32 cmd; -+ __u32 supported; -+ __u32 advertised; -+ __u32 lp_advertised; -+ __u32 eee_active; -+ __u32 eee_enabled; -+ __u32 tx_lpi_enabled; -+ __u32 tx_lpi_timer; -+ __u32 reserved[2]; -+}; -+#endif -+ -+#ifdef __VMKLNX__ -+#ifndef SYSTEM_POWER_OFF -+#define SYSTEM_POWER_OFF (3) -+#endif -+ -+#define system_state SYSTEM_POWER_OFF -+#endif -+ -+#ifndef BCM_HAS_PCI_CHANNEL_OFFLINE -+static inline int pci_channel_offline(struct pci_dev *pdev) -+{ -+#ifdef BCM_HAS_PCI_CHANNEL_IO_NORMAL_ENUM -+ return (pdev->error_state != pci_channel_io_normal); -+#else -+ return 0; -+#endif -+} -+#endif /*BCM_HAS_PCI_CHANNEL_OFFLINE*/ -+ -+#ifndef BCM_HAS_PCI_IS_ENABLED -+static inline int pci_is_enabled(struct pci_dev *pdev) -+{ -+ return 1; -+} -+#endif -+ -+#ifndef BCM_HAS_PCI_DEV_IS_PRESENT -+static inline int pci_device_is_present(struct pci_dev *pdev) -+{ -+ return 1; -+} -+#endif -+#ifndef BCM_HAS_DMA_ZALLOC_COHERENT -+#ifndef __GFP_ZERO -+ #define ___GFP_ZERO 0x8000u -+ #define __GFP_ZERO ((__force unsigned)___GFP_ZERO) /* Return zeroed page on success */ -+#endif -+ -+static inline void *dma_zalloc_coherent(struct device *dev, size_t size, -+ dma_addr_t *dma_handle, unsigned flag) -+{ -+ void *ret = dma_alloc_coherent(dev, size, dma_handle, -+ flag | __GFP_ZERO); -+ return ret; -+} -+#endif -+ -+#ifndef DEFAULT_MAX_NUM_RSS_QUEUES -+#define DEFAULT_MAX_NUM_RSS_QUEUES (8) -+#endif -+ -+#ifndef BCM_HAS_GET_NUM_DFLT_RSS_QS -+int netif_get_num_default_rss_queues(void) -+{ -+ return min_t(int, DEFAULT_MAX_NUM_RSS_QUEUES, num_online_cpus()); -+} -+#endif -+ -+#ifndef SIOCGHWTSTAMP -+#define SIOCGHWTSTAMP 0x89b1 -+#endif -diff --git a/drivers/net/ethernet/broadcom/tg3/tg3_compat2.h b/drivers/net/ethernet/broadcom/tg3/tg3_compat2.h -new file mode 100644 -index 0000000..07c968d ---- /dev/null -+++ b/drivers/net/ethernet/broadcom/tg3/tg3_compat2.h -@@ -0,0 +1,518 @@ -+/* Copyright (C) 2009-2015 Broadcom Corporation. */ -+ -+#ifndef BCM_HAS_PCI_PCIE_CAP -+static inline int pci_pcie_cap(struct pci_dev *pdev) -+{ -+ struct net_device *dev = pci_get_drvdata(pdev); -+ struct tg3 *tp = netdev_priv(dev); -+ -+ return tp->pcie_cap; -+} -+#endif -+ -+#ifndef BCM_HAS_PCI_IS_PCIE -+static inline bool pci_is_pcie(struct pci_dev *dev) -+{ -+ return !!pci_pcie_cap(dev); -+} -+#endif -+ -+#ifndef BCM_HAS_PCIE_CAP_RW -+static inline int pcie_capability_set_word(struct pci_dev *dev, int pos, -+ u16 set) -+{ -+ u16 val; -+ int rval; -+ -+ rval = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, &val); -+ -+ if (!rval) { -+ val |= set; -+ rval = pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val); -+ } -+ -+ return rval; -+} -+ -+static inline int pcie_capability_clear_word(struct pci_dev *dev, int pos, -+ u16 clear) -+{ -+ u16 val; -+ int rval; -+ -+ rval = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, &val); -+ -+ if (!rval) { -+ val &= ~clear; -+ rval = pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val); -+ } -+ -+ return rval; -+} -+ -+static int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val) -+{ -+ return pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val); -+} -+ -+static int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) -+{ -+ return pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val); -+} -+#endif -+ -+#ifndef BCM_HAS_SKB_FRAG_DMA_MAP -+#define skb_frag_dma_map(x, frag, y, len, z) \ -+ pci_map_page(tp->pdev, (frag)->page, \ -+ (frag)->page_offset, (len), PCI_DMA_TODEVICE) -+#endif -+ -+#ifdef SIMPLE_DEV_PM_OPS -+ -+#define tg3_invalid_pci_state(tp, state) false -+#define tg3_pci_save_state(tp) -+#define tg3_pci_restore_state(tp) -+ -+#else /* SIMPLE_DEV_PM_OPS */ -+ -+#if (LINUX_VERSION_CODE < 0x2060b) -+static bool tg3_invalid_pci_state(struct tg3 *tp, u32 state) -+{ -+ bool ret = true; -+ pci_power_t target_state; -+ -+ target_state = pci_choose_state(tp->pdev, state); -+ if (target_state != PCI_D3hot || target_state != PCI_D3cold) -+ ret = false; -+ -+ return ret; -+} -+#else -+static bool tg3_invalid_pci_state(struct tg3 *tp, pm_message_t state) -+{ -+ bool ret = true; -+ pci_power_t target_state; -+ -+#ifdef BCM_HAS_PCI_TARGET_STATE -+ target_state = tp->pdev->pm_cap ? pci_target_state(tp->pdev) : PCI_D3hot; -+#else -+ target_state = pci_choose_state(tp->pdev, state); -+#endif -+ if (target_state != PCI_D3hot || target_state != PCI_D3cold) -+ ret = false; -+ -+ return ret; -+} -+#endif -+ -+#if (LINUX_VERSION_CODE < 0x2060a) -+#define tg3_pci_save_state(tp) pci_save_state(tp->pdev, tp->pci_cfg_state) -+#define tg3_pci_restore_state(tp) pci_restore_state(tp->pdev, tp->pci_cfg_state) -+#else -+#define tg3_pci_save_state(tp) pci_save_state(tp->pdev) -+#define tg3_pci_restore_state(tp) pci_restore_state(tp->pdev) -+#endif -+ -+#endif /* SIMPLE_DEV_PM_OPS */ -+ -+ -+#ifdef BCM_HAS_NEW_PCI_DMA_MAPPING_ERROR -+#define pci_dma_mapping_error_(pdev, mapping) pci_dma_mapping_error((pdev), (mapping)) -+#define dma_mapping_error_(pdev, mapping) dma_mapping_error((pdev), (mapping)) -+#elif defined(BCM_HAS_PCI_DMA_MAPPING_ERROR) -+#define pci_dma_mapping_error_(pdev, mapping) pci_dma_mapping_error((mapping)) -+#define dma_mapping_error_(pdev, mapping) dma_mapping_error((mapping)) -+#else -+#define pci_dma_mapping_error_(pdev, mapping) 0 -+#define dma_mapping_error_(pdev, mapping) 0 -+#endif -+ -+#ifndef BCM_HAS_HW_FEATURES -+#define hw_features features -+#endif -+ -+#ifndef BCM_HAS_VLAN_FEATURES -+#define vlan_features features -+#endif -+ -+#ifdef HAVE_POLL_CONTROLLER -+#define CONFIG_NET_POLL_CONTROLLER -+#endif -+ -+static inline void tg3_5780_class_intx_workaround(struct tg3 *tp) -+{ -+#ifndef BCM_HAS_INTX_MSI_WORKAROUND -+ if (tg3_flag(tp, 5780_CLASS) && -+ tg3_flag(tp, USING_MSI)) -+ tg3_enable_intx(tp->pdev); -+#endif -+} -+ -+#ifdef BCM_HAS_TXQ_TRANS_UPDATE -+#define tg3_update_trans_start(dev) -+#else -+#define tg3_update_trans_start(dev) ((dev)->trans_start = jiffies) -+#endif -+ -+#ifndef BCM_HAS_NEW_VLAN_INTERFACE -+#define TG3_TO_INT(Y) ((int)((ptrdiff_t)(Y) & (SMP_CACHE_BYTES - 1))) -+#define TG3_COMPAT_VLAN_ALLOC_LEN (SMP_CACHE_BYTES + VLAN_HLEN) -+#define TG3_COMPAT_VLAN_RESERVE(addr) (SKB_DATA_ALIGN((addr) + VLAN_HLEN) - (addr)) -+#else -+#define TG3_COMPAT_VLAN_ALLOC_LEN 0 -+#define TG3_COMPAT_VLAN_RESERVE(addr) 0 -+#endif -+ -+#ifdef BCM_KERNEL_SUPPORTS_8021Q -+ -+#ifndef BCM_HAS_NEW_VLAN_INTERFACE -+#undef TG3_RAW_IP_ALIGN -+#define TG3_RAW_IP_ALIGN (2 + VLAN_HLEN) -+#endif /* BCM_HAS_NEW_VLAN_INTERFACE */ -+ -+#ifndef BCM_HAS_NEW_VLAN_INTERFACE -+static void __tg3_set_rx_mode(struct net_device *); -+static inline void tg3_netif_start(struct tg3 *tp); -+static inline void tg3_netif_stop(struct tg3 *tp); -+static inline void tg3_full_lock(struct tg3 *tp, int irq_sync); -+static inline void tg3_full_unlock(struct tg3 *tp); -+ -+static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (!netif_running(dev)) { -+ tp->vlgrp = grp; -+ return; -+ } -+ -+ tg3_netif_stop(tp); -+ -+ tg3_full_lock(tp, 0); -+ -+ tp->vlgrp = grp; -+ -+ /* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */ -+ __tg3_set_rx_mode(dev); -+ -+ tg3_netif_start(tp); -+ -+ tg3_full_unlock(tp); -+} -+ -+#ifndef BCM_HAS_NET_DEVICE_OPS -+#ifndef BCM_HAS_VLAN_GROUP_SET_DEVICE -+static inline void vlan_group_set_device(struct vlan_group *vg, int vlan_id, -+ struct net_device *dev) -+{ -+ if (vg) -+ vg->vlan_devices[vlan_id] = dev; -+} -+#endif -+ -+static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (netif_running(dev)) -+ tg3_netif_stop(tp); -+ -+ tg3_full_lock(tp, 0); -+ vlan_group_set_device(tp->vlgrp, vid, NULL); -+ tg3_full_unlock(tp); -+ -+ if (netif_running(dev)) -+ tg3_netif_start(tp); -+} -+#endif /* BCM_HAS_NET_DEVICE_OPS */ -+#endif /* BCM_USE_OLD_VLAN_INTERFACE */ -+#endif /* BCM_KERNEL_SUPPORTS_8021Q */ -+ -+ -+#ifndef BCM_HAS_NETDEV_UPDATE_FEATURES -+static u32 tg3_get_rx_csum(struct net_device *dev) -+{ -+ return (dev->features & NETIF_F_RXCSUM) != 0; -+} -+ -+static int tg3_set_rx_csum(struct net_device *dev, u32 data) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ /* BROKEN_CHECKSUMS */ -+ if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0) { -+ if (data != 0) -+ return -EINVAL; -+ return 0; -+ } -+ -+ spin_lock_bh(&tp->lock); -+ if (data) -+ dev->features |= NETIF_F_RXCSUM; -+ else -+ dev->features &= ~NETIF_F_RXCSUM; -+ spin_unlock_bh(&tp->lock); -+ -+ return 0; -+} -+ -+#ifdef BCM_HAS_SET_TX_CSUM -+static int tg3_set_tx_csum(struct net_device *dev, u32 data) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ /* BROKEN_CHECKSUMS */ -+ if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0) { -+ if (data != 0) -+ return -EINVAL; -+ return 0; -+ } -+ -+ if (tg3_flag(tp, 5755_PLUS)) -+#if defined(BCM_HAS_ETHTOOL_OP_SET_TX_IPV6_CSUM) -+ ethtool_op_set_tx_ipv6_csum(dev, data); -+#elif defined(BCM_HAS_ETHTOOL_OP_SET_TX_HW_CSUM) -+ ethtool_op_set_tx_hw_csum(dev, data); -+#else -+ tg3_set_tx_hw_csum(dev, data); -+#endif -+ else -+ ethtool_op_set_tx_csum(dev, data); -+ -+ return 0; -+} -+#endif -+ -+#if TG3_TSO_SUPPORT != 0 -+static int tg3_set_tso(struct net_device *dev, u32 value) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (!tg3_flag(tp, TSO_CAPABLE)) { -+ if (value) -+ return -EINVAL; -+ return 0; -+ } -+ if ((dev->features & NETIF_F_IPV6_CSUM) && -+ (tg3_flag(tp, HW_TSO_2) || -+ tg3_flag(tp, HW_TSO_3))) { -+ if (value) { -+ dev->features |= NETIF_F_TSO6; -+ if (tg3_flag(tp, HW_TSO_3) || -+ tg3_asic_rev(tp) == ASIC_REV_5761 || -+ (tg3_asic_rev(tp) == ASIC_REV_5784 && -+ tg3_chip_rev(tp) != CHIPREV_5784_AX) || -+ tg3_asic_rev(tp) == ASIC_REV_5785 || -+ tg3_asic_rev(tp) == ASIC_REV_57780) -+ dev->features |= NETIF_F_TSO_ECN; -+ } else -+ dev->features &= ~(NETIF_F_TSO6 | NETIF_F_TSO_ECN); -+ } -+ return ethtool_op_set_tso(dev, value); -+} -+#endif -+ -+static void netdev_update_features(struct net_device *dev) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ -+ if (dev->mtu > ETH_DATA_LEN) { -+ if (tg3_flag(tp, 5780_CLASS)) { -+#if TG3_TSO_SUPPORT != 0 -+ ethtool_op_set_tso(dev, 0); -+#endif -+ } -+ } -+} -+#endif /* BCM_HAS_NETDEV_UPDATE_FEATURES */ -+ -+#if !defined(BCM_HAS_SET_PHYS_ID) || defined(GET_ETHTOOL_OP_EXT) -+ -+#if !defined(BCM_HAS_SET_PHYS_ID) -+enum ethtool_phys_id_state { -+ ETHTOOL_ID_INACTIVE, -+ ETHTOOL_ID_ACTIVE, -+ ETHTOOL_ID_ON, -+ ETHTOOL_ID_OFF -+}; -+#endif -+ -+static int tg3_set_phys_id(struct net_device *dev, -+ enum ethtool_phys_id_state state); -+static int tg3_phys_id(struct net_device *dev, u32 data) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ int i; -+ -+ if (!netif_running(tp->dev)) -+ return -EAGAIN; -+ -+ if (data == 0) -+ data = UINT_MAX / 2; -+ -+ for (i = 0; i < (data * 2); i++) { -+ if ((i % 2) == 0) -+ tg3_set_phys_id(dev, ETHTOOL_ID_ON); -+ else -+ tg3_set_phys_id(dev, ETHTOOL_ID_OFF); -+ -+ if (msleep_interruptible(500)) -+ break; -+ } -+ tg3_set_phys_id(dev, ETHTOOL_ID_INACTIVE); -+ return 0; -+} -+#endif /* BCM_HAS_SET_PHYS_ID */ -+ -+#ifndef BCM_HAS_GET_STATS64 -+static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); -+static struct rtnl_link_stats64 *tg3_get_stats(struct net_device *dev) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ return tg3_get_stats64(dev, &tp->net_stats); -+} -+#endif /* BCM_HAS_GET_STATS64 */ -+ -+#ifdef BCM_HAS_GET_RXFH_INDIR -+#ifndef BCM_HAS_GET_RXFH_INDIR_SIZE -+static int tg3_get_rxfh_indir(struct net_device *dev, -+ struct ethtool_rxfh_indir *indir) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ int i; -+ -+ if (!tg3_flag(tp, SUPPORT_MSIX)) -+ return -EINVAL; -+ -+ if (!indir->size) { -+ indir->size = TG3_RSS_INDIR_TBL_SIZE; -+ return 0; -+ } -+ -+ if (indir->size != TG3_RSS_INDIR_TBL_SIZE) -+ return -EINVAL; -+ -+ for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) -+ indir->ring_index[i] = tp->rss_ind_tbl[i]; -+ -+ return 0; -+} -+ -+static void tg3_rss_init_dflt_indir_tbl(struct tg3 *tp, u32 qcnt); -+static void tg3_rss_write_indir_tbl(struct tg3 *tp); -+static inline void tg3_full_lock(struct tg3 *tp, int irq_sync); -+static inline void tg3_full_unlock(struct tg3 *tp); -+ -+static int tg3_set_rxfh_indir(struct net_device *dev, -+ const struct ethtool_rxfh_indir *indir) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ size_t i; -+ -+ if (!tg3_flag(tp, SUPPORT_MSIX)) -+ return -EINVAL; -+ -+ if (!indir->size) { -+ tg3_flag_clear(tp, USER_INDIR_TBL); -+ tg3_rss_init_dflt_indir_tbl(tp, tp->rxq_cnt); -+ } else { -+ int limit; -+ -+ /* Validate size and indices */ -+ if (indir->size != TG3_RSS_INDIR_TBL_SIZE) -+ return -EINVAL; -+ -+ if (netif_running(dev)) -+ limit = tp->irq_cnt; -+ else { -+ limit = num_online_cpus(); -+ if (limit > TG3_IRQ_MAX_VECS_RSS) -+ limit = TG3_IRQ_MAX_VECS_RSS; -+ } -+ -+ /* The first interrupt vector only -+ * handles link interrupts. -+ */ -+ limit -= 1; -+ -+ /* Check the indices in the table. -+ * Leave the existing table unmodified -+ * if an error is detected. -+ */ -+ for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) -+ if (indir->ring_index[i] >= limit) -+ return -EINVAL; -+ -+ tg3_flag_set(tp, USER_INDIR_TBL); -+ -+ for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) -+ tp->rss_ind_tbl[i] = indir->ring_index[i]; -+ } -+ -+ if (!netif_running(dev) || !tg3_flag(tp, ENABLE_RSS)) -+ return 0; -+ -+ /* It is legal to write the indirection -+ * table while the device is running. -+ */ -+ tg3_full_lock(tp, 0); -+ tg3_rss_write_indir_tbl(tp); -+ tg3_full_unlock(tp); -+ -+ return 0; -+} -+#endif /* !BCM_HAS_GET_RXFH_INDIR_SIZE */ -+#endif /* BCM_HAS_GET_RXFH_INDIR */ -+ -+#ifdef __VMKLNX__ -+ -+/** -+ * skb_copy_expand - copy and expand sk_buff -+ * @skb: buffer to copy -+ * @newheadroom: new free bytes at head -+ * @newtailroom: new free bytes at tail -+ * @gfp_mask: allocation priority -+ * -+ * Make a copy of both an &sk_buff and its data and while doing so -+ * allocate additional space. -+ * -+ * This is used when the caller wishes to modify the data and needs a -+ * private copy of the data to alter as well as more space for new fields. -+ * Returns %NULL on failure or the pointer to the buffer -+ * on success. The returned buffer has a reference count of 1. -+ * -+ * You must pass %GFP_ATOMIC as the allocation priority if this function -+ * is called from an interrupt. -+ */ -+struct sk_buff *skb_copy_expand(const struct sk_buff *skb, -+ int newheadroom, int newtailroom, -+ gfp_t gfp_mask) -+{ -+ int rc; -+ struct sk_buff *new_skb = skb_copy((struct sk_buff *) skb, gfp_mask); -+ -+ if(new_skb == NULL) -+ return NULL; -+ -+ rc = pskb_expand_head(new_skb, newheadroom, newtailroom, gfp_mask); -+ -+ if(rc != 0) -+ return NULL; -+ -+ return new_skb; -+} -+ -+void *memmove(void *dest, const void *src, size_t count) -+{ -+ if (dest < src) { -+ return memcpy(dest, src, count); -+ } else { -+ char *p = dest + count; -+ const char *s = src + count; -+ while (count--) -+ *--p = *--s; -+ } -+ return dest; -+} -+#endif -diff --git a/drivers/net/ethernet/broadcom/tg3/tg3_firmware.h b/drivers/net/ethernet/broadcom/tg3/tg3_firmware.h -new file mode 100644 -index 0000000..a5a4928 ---- /dev/null -+++ b/drivers/net/ethernet/broadcom/tg3/tg3_firmware.h -@@ -0,0 +1,1012 @@ -+/* Copyright (C) 2009-2015 Broadcom Corporation. */ -+ -+#ifdef NETIF_F_TSO -+#define TG3_TSO_SUPPORT 1 -+#else -+#define TG3_TSO_SUPPORT 0 -+#endif -+ -+#ifndef BCM_HAS_REQUEST_FIRMWARE -+ -+struct tg3_firmware { -+ size_t size; -+ const u8 *data; -+}; -+ -+struct tg3_firmware_hdr { -+ u32 version; /* unused for fragments */ -+ u32 base_addr; -+ u32 len; -+}; -+#define TG3_FW_HDR_LEN (sizeof(struct tg3_firmware_hdr)) -+ -+#ifndef MODULE_FIRMWARE -+#define MODULE_FIRMWARE(x) -+#endif -+ -+#define TG3_FW_RELEASE_MAJOR 0x0 -+#define TG3_FW_RELASE_MINOR 0x0 -+#define TG3_FW_RELEASE_FIX 0x0 -+#define TG3_FW_START_ADDR 0x08000000 -+#define TG3_FW_TEXT_ADDR 0x08000000 -+#define TG3_FW_TEXT_LEN 0x9c0 -+#define TG3_FW_RODATA_ADDR 0x080009c0 -+#define TG3_FW_RODATA_LEN 0x60 -+#define TG3_FW_DATA_ADDR 0x08000a40 -+#define TG3_FW_DATA_LEN 0x20 -+#define TG3_FW_SBSS_ADDR 0x08000a60 -+#define TG3_FW_SBSS_LEN 0xc -+#define TG3_FW_BSS_ADDR 0x08000a70 -+#define TG3_FW_BSS_LEN 0x10 -+ -+#define TG3_5701_RLS_FW_LEN (TG3_FW_TEXT_LEN + TG3_FW_RODATA_LEN) -+ -+static const u32 tg3FwText[] = { -+0x00000000, (u32)TG3_FW_TEXT_ADDR, (u32)TG3_5701_RLS_FW_LEN, -+0x00000000, 0x10000003, 0x00000000, 0x0000000d, -+0x0000000d, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, -+0x3c100800, 0x26100000, 0x0e000018, 0x00000000, -+0x0000000d, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, -+0x3c100800, 0x26100034, 0x0e00021c, 0x00000000, -+0x0000000d, 0x00000000, 0x00000000, 0x00000000, -+0x27bdffe0, 0x3c1cc000, 0xafbf0018, 0xaf80680c, -+0x0e00004c, 0x241b2105, 0x97850000, 0x97870002, -+0x9782002c, 0x9783002e, 0x3c040800, 0x248409c0, -+0xafa00014, 0x00021400, 0x00621825, 0x00052c00, -+0xafa30010, 0x8f860010, 0x00e52825, 0x0e000060, -+0x24070102, 0x3c02ac00, 0x34420100, 0x3c03ac01, -+0x34630100, 0xaf820490, 0x3c02ffff, 0xaf820494, -+0xaf830498, 0xaf82049c, 0x24020001, 0xaf825ce0, -+0x0e00003f, 0xaf825d00, 0x0e000140, 0x00000000, -+0x8fbf0018, 0x03e00008, 0x27bd0020, 0x2402ffff, -+0xaf825404, 0x8f835400, 0x34630400, 0xaf835400, -+0xaf825404, 0x3c020800, 0x24420034, 0xaf82541c, -+0x03e00008, 0xaf805400, 0x00000000, 0x00000000, -+0x3c020800, 0x34423000, 0x3c030800, 0x34633000, -+0x3c040800, 0x348437ff, 0x3c010800, 0xac220a64, -+0x24020040, 0x3c010800, 0xac220a68, 0x3c010800, -+0xac200a60, 0xac600000, 0x24630004, 0x0083102b, -+0x5040fffd, 0xac600000, 0x03e00008, 0x00000000, -+0x00804821, 0x8faa0010, 0x3c020800, 0x8c420a60, -+0x3c040800, 0x8c840a68, 0x8fab0014, 0x24430001, -+0x0044102b, 0x3c010800, 0xac230a60, 0x14400003, -+0x00004021, 0x3c010800, 0xac200a60, 0x3c020800, -+0x8c420a60, 0x3c030800, 0x8c630a64, 0x91240000, -+0x00021140, 0x00431021, 0x00481021, 0x25080001, -+0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, -+0x3c020800, 0x8c420a60, 0x3c030800, 0x8c630a64, -+0x8f84680c, 0x00021140, 0x00431021, 0xac440008, -+0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, -+0x03e00008, 0xac4b001c, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x02000008, 0x00000000, 0x0a0001e3, 0x3c0a0001, -+0x0a0001e3, 0x3c0a0002, 0x0a0001e3, 0x00000000, -+0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, -+0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, -+0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, -+0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, -+0x0a0001e3, 0x3c0a0007, 0x0a0001e3, 0x3c0a0008, -+0x0a0001e3, 0x3c0a0009, 0x0a0001e3, 0x00000000, -+0x0a0001e3, 0x00000000, 0x0a0001e3, 0x3c0a000b, -+0x0a0001e3, 0x3c0a000c, 0x0a0001e3, 0x3c0a000d, -+0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, -+0x0a0001e3, 0x3c0a000e, 0x0a0001e3, 0x00000000, -+0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, -+0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, -+0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, -+0x0a0001e3, 0x00000000, 0x0a0001e3, 0x3c0a0013, -+0x0a0001e3, 0x3c0a0014, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x27bdffe0, 0x00001821, 0x00001021, 0xafbf0018, -+0xafb10014, 0xafb00010, 0x3c010800, 0x00220821, -+0xac200a70, 0x3c010800, 0x00220821, 0xac200a74, -+0x3c010800, 0x00220821, 0xac200a78, 0x24630001, -+0x1860fff5, 0x2442000c, 0x24110001, 0x8f906810, -+0x32020004, 0x14400005, 0x24040001, 0x3c020800, -+0x8c420a78, 0x18400003, 0x00002021, 0x0e000182, -+0x00000000, 0x32020001, 0x10400003, 0x00000000, -+0x0e000169, 0x00000000, 0x0a000153, 0xaf915028, -+0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, -+0x27bd0020, 0x3c050800, 0x8ca50a70, 0x3c060800, -+0x8cc60a80, 0x3c070800, 0x8ce70a78, 0x27bdffe0, -+0x3c040800, 0x248409d0, 0xafbf0018, 0xafa00010, -+0x0e000060, 0xafa00014, 0x0e00017b, 0x00002021, -+0x8fbf0018, 0x03e00008, 0x27bd0020, 0x24020001, -+0x8f836810, 0x00821004, 0x00021027, 0x00621824, -+0x03e00008, 0xaf836810, 0x27bdffd8, 0xafbf0024, -+0x1080002e, 0xafb00020, 0x8f825cec, 0xafa20018, -+0x8f825cec, 0x3c100800, 0x26100a78, 0xafa2001c, -+0x34028000, 0xaf825cec, 0x8e020000, 0x18400016, -+0x00000000, 0x3c020800, 0x94420a74, 0x8fa3001c, -+0x000221c0, 0xac830004, 0x8fa2001c, 0x3c010800, -+0x0e000201, 0xac220a74, 0x10400005, 0x00000000, -+0x8e020000, 0x24420001, 0x0a0001df, 0xae020000, -+0x3c020800, 0x8c420a70, 0x00021c02, 0x000321c0, -+0x0a0001c5, 0xafa2001c, 0x0e000201, 0x00000000, -+0x1040001f, 0x00000000, 0x8e020000, 0x8fa3001c, -+0x24420001, 0x3c010800, 0xac230a70, 0x3c010800, -+0xac230a74, 0x0a0001df, 0xae020000, 0x3c100800, -+0x26100a78, 0x8e020000, 0x18400028, 0x00000000, -+0x0e000201, 0x00000000, 0x14400024, 0x00000000, -+0x8e020000, 0x3c030800, 0x8c630a70, 0x2442ffff, -+0xafa3001c, 0x18400006, 0xae020000, 0x00031402, -+0x000221c0, 0x8c820004, 0x3c010800, 0xac220a70, -+0x97a2001e, 0x2442ff00, 0x2c420300, 0x1440000b, -+0x24024000, 0x3c040800, 0x248409dc, 0xafa00010, -+0xafa00014, 0x8fa6001c, 0x24050008, 0x0e000060, -+0x00003821, 0x0a0001df, 0x00000000, 0xaf825cf8, -+0x3c020800, 0x8c420a40, 0x8fa3001c, 0x24420001, -+0xaf835cf8, 0x3c010800, 0xac220a40, 0x8fbf0024, -+0x8fb00020, 0x03e00008, 0x27bd0028, 0x27bdffe0, -+0x3c040800, 0x248409e8, 0x00002821, 0x00003021, -+0x00003821, 0xafbf0018, 0xafa00010, 0x0e000060, -+0xafa00014, 0x8fbf0018, 0x03e00008, 0x27bd0020, -+0x8f82680c, 0x8f85680c, 0x00021827, 0x0003182b, -+0x00031823, 0x00431024, 0x00441021, 0x00a2282b, -+0x10a00006, 0x00000000, 0x00401821, 0x8f82680c, -+0x0043102b, 0x1440fffd, 0x00000000, 0x03e00008, -+0x00000000, 0x3c040800, 0x8c840000, 0x3c030800, -+0x8c630a40, 0x0064102b, 0x54400002, 0x00831023, -+0x00641023, 0x2c420008, 0x03e00008, 0x38420001, -+0x27bdffe0, 0x00802821, 0x3c040800, 0x24840a00, -+0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, -+0x0e000060, 0xafa00014, 0x0a000216, 0x00000000, -+0x8fbf0018, 0x03e00008, 0x27bd0020, 0x00000000, -+0x27bdffe0, 0x3c1cc000, 0xafbf0018, 0x0e00004c, -+0xaf80680c, 0x3c040800, 0x24840a10, 0x03802821, -+0x00003021, 0x00003821, 0xafa00010, 0x0e000060, -+0xafa00014, 0x2402ffff, 0xaf825404, 0x3c0200aa, -+0x0e000234, 0xaf825434, 0x8fbf0018, 0x03e00008, -+0x27bd0020, 0x00000000, 0x00000000, 0x00000000, -+0x27bdffe8, 0xafb00010, 0x24100001, 0xafbf0014, -+0x3c01c003, 0xac200000, 0x8f826810, 0x30422000, -+0x10400003, 0x00000000, 0x0e000246, 0x00000000, -+0x0a00023a, 0xaf905428, 0x8fbf0014, 0x8fb00010, -+0x03e00008, 0x27bd0018, 0x27bdfff8, 0x8f845d0c, -+0x3c0200ff, 0x3c030800, 0x8c630a50, 0x3442fff8, -+0x00821024, 0x1043001e, 0x3c0500ff, 0x34a5fff8, -+0x3c06c003, 0x3c074000, 0x00851824, 0x8c620010, -+0x3c010800, 0xac230a50, 0x30420008, 0x10400005, -+0x00871025, 0x8cc20000, 0x24420001, 0xacc20000, -+0x00871025, 0xaf825d0c, 0x8fa20000, 0x24420001, -+0xafa20000, 0x8fa20000, 0x8fa20000, 0x24420001, -+0xafa20000, 0x8fa20000, 0x8f845d0c, 0x3c030800, -+0x8c630a50, 0x00851024, 0x1443ffe8, 0x00851824, -+0x27bd0008, 0x03e00008, 0x00000000, 0x00000000, -+0x35373031, 0x726c7341, 0x00000000, 0x00000000, -+0x53774576, 0x656e7430, 0x00000000, 0x726c7045, -+0x76656e74, 0x31000000, 0x556e6b6e, 0x45766e74, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x66617461, 0x6c457272, 0x00000000, 0x00000000, -+0x4d61696e, 0x43707542, 0x00000000, 0x00000000, -+}; -+ -+static const struct tg3_firmware tg3_5701_fw = { -+ .size = TG3_5701_RLS_FW_LEN, -+ .data = (u8 *)&tg3FwText[0], -+}; -+ -+#define TG3_57766_FW_BASE_ADDR 0x00030000 -+#define TG3_57766_FW_HANDSHAKE 0x0003fccc -+#define TG3_57766_FW_TEXT_ADDR 0x00030000 -+#define TG3_57766_FW_TEXT_LEN (0x58 + TG3_FW_HDR_LEN) -+#define TG3_57766_FW_PRIV1_ADDR 0x0003fd00 -+#define TG3_57766_FW_PRIV1_SIZE (0x4 + TG3_FW_HDR_LEN) -+#define TG3_57766_FW_PRIV2_ADDR 0x0003fccc -+#define TG3_57766_FW_PRIV2_SIZE (0x4 + TG3_FW_HDR_LEN) -+#define TG3_57766_FW_RESERVED 0xdecafbad -+ -+static const u32 tg3_57766_fwdata[] = { -+0x00000000, TG3_57766_FW_BASE_ADDR, 0xffffffff, -+TG3_57766_FW_RESERVED, TG3_57766_FW_TEXT_ADDR, TG3_57766_FW_TEXT_LEN, -+0x27800001, 0xf7f0403e, 0xcd283674, 0x11001100, -+0xf7ff1064, 0x376e0001, 0x27600000, 0xf7f07fea, -+0xf7f00004, 0xf7f00018, 0xcc10362c, 0x00180018, -+0x17800000, 0xf7f00008, 0xc33836b0, 0xf7f00004, -+0xc43836b0, 0xc62036bc, 0x00000009, 0xcb3836b0, -+0x17800001, 0x1760000a, -+TG3_57766_FW_RESERVED, TG3_57766_FW_PRIV1_ADDR, TG3_57766_FW_PRIV1_SIZE, -+0xd044d816, -+TG3_57766_FW_RESERVED, TG3_57766_FW_PRIV2_ADDR, TG3_57766_FW_PRIV2_SIZE, -+0x02300202, -+}; -+ -+static const struct tg3_firmware tg3_57766_fw = { -+ .size = sizeof(tg3_57766_fwdata), -+ .data = (u8 *)&tg3_57766_fwdata[0], -+}; -+ -+#if TG3_TSO_SUPPORT != 0 -+ -+#define TG3_TSO_FW_RELEASE_MAJOR 0x1 -+#define TG3_TSO_FW_RELASE_MINOR 0x6 -+#define TG3_TSO_FW_RELEASE_FIX 0x0 -+#define TG3_TSO_FW_START_ADDR 0x08000000 -+#define TG3_TSO_FW_TEXT_ADDR 0x08000000 -+#define TG3_TSO_FW_TEXT_LEN 0x1aa0 -+#define TG3_TSO_FW_RODATA_ADDR 0x08001aa0 -+#define TG3_TSO_FW_RODATA_LEN 0x60 -+#define TG3_TSO_FW_DATA_ADDR 0x08001b20 -+#define TG3_TSO_FW_DATA_LEN 0x30 -+#define TG3_TSO_FW_SBSS_ADDR 0x08001b50 -+#define TG3_TSO_FW_SBSS_LEN 0x2c -+#define TG3_TSO_FW_BSS_ADDR 0x08001b80 -+#define TG3_TSO_FW_BSS_LEN 0x894 -+ -+#define TG3_LGCY_TSO_FW_LEN \ -+ (TG3_TSO_FW_TEXT_LEN + \ -+ TG3_TSO_FW_RODATA_LEN + \ -+ 0x20 + \ -+ TG3_TSO_FW_DATA_LEN) -+ -+static const u32 tg3TsoFwText[] = { -+0x00010600, (u32)TG3_TSO_FW_TEXT_ADDR, (u32)TG3_LGCY_TSO_FW_LEN, -+0x0e000003, 0x00000000, 0x08001b24, 0x00000000, -+0x10000003, 0x00000000, 0x0000000d, 0x0000000d, -+0x3c1d0800, 0x37bd4000, 0x03a0f021, 0x3c100800, -+0x26100000, 0x0e000010, 0x00000000, 0x0000000d, -+0x27bdffe0, 0x3c04fefe, 0xafbf0018, 0x0e0005d8, -+0x34840002, 0x0e000668, 0x00000000, 0x3c030800, -+0x90631b68, 0x24020002, 0x3c040800, 0x24841aac, -+0x14620003, 0x24050001, 0x3c040800, 0x24841aa0, -+0x24060006, 0x00003821, 0xafa00010, 0x0e00067c, -+0xafa00014, 0x8f625c50, 0x34420001, 0xaf625c50, -+0x8f625c90, 0x34420001, 0xaf625c90, 0x2402ffff, -+0x0e000034, 0xaf625404, 0x8fbf0018, 0x03e00008, -+0x27bd0020, 0x00000000, 0x00000000, 0x00000000, -+0x27bdffe0, 0xafbf001c, 0xafb20018, 0xafb10014, -+0x0e00005b, 0xafb00010, 0x24120002, 0x24110001, -+0x8f706820, 0x32020100, 0x10400003, 0x00000000, -+0x0e0000bb, 0x00000000, 0x8f706820, 0x32022000, -+0x10400004, 0x32020001, 0x0e0001f0, 0x24040001, -+0x32020001, 0x10400003, 0x00000000, 0x0e0000a3, -+0x00000000, 0x3c020800, 0x90421b98, 0x14520003, -+0x00000000, 0x0e0004c0, 0x00000000, 0x0a00003c, -+0xaf715028, 0x8fbf001c, 0x8fb20018, 0x8fb10014, -+0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe0, -+0x3c040800, 0x24841ac0, 0x00002821, 0x00003021, -+0x00003821, 0xafbf0018, 0xafa00010, 0x0e00067c, -+0xafa00014, 0x3c040800, 0x248423d8, 0xa4800000, -+0x3c010800, 0xa0201b98, 0x3c010800, 0xac201b9c, -+0x3c010800, 0xac201ba0, 0x3c010800, 0xac201ba4, -+0x3c010800, 0xac201bac, 0x3c010800, 0xac201bb8, -+0x3c010800, 0xac201bbc, 0x8f624434, 0x3c010800, -+0xac221b88, 0x8f624438, 0x3c010800, 0xac221b8c, -+0x8f624410, 0xac80f7a8, 0x3c010800, 0xac201b84, -+0x3c010800, 0xac2023e0, 0x3c010800, 0xac2023c8, -+0x3c010800, 0xac2023cc, 0x3c010800, 0xac202400, -+0x3c010800, 0xac221b90, 0x8f620068, 0x24030007, -+0x00021702, 0x10430005, 0x00000000, 0x8f620068, -+0x00021702, 0x14400004, 0x24020001, 0x3c010800, -+0x0a000097, 0xac20240c, 0xac820034, 0x3c040800, -+0x24841acc, 0x3c050800, 0x8ca5240c, 0x00003021, -+0x00003821, 0xafa00010, 0x0e00067c, 0xafa00014, -+0x8fbf0018, 0x03e00008, 0x27bd0020, 0x27bdffe0, -+0x3c040800, 0x24841ad8, 0x00002821, 0x00003021, -+0x00003821, 0xafbf0018, 0xafa00010, 0x0e00067c, -+0xafa00014, 0x0e00005b, 0x00000000, 0x0e0000b4, -+0x00002021, 0x8fbf0018, 0x03e00008, 0x27bd0020, -+0x24020001, 0x8f636820, 0x00821004, 0x00021027, -+0x00621824, 0x03e00008, 0xaf636820, 0x27bdffd0, -+0xafbf002c, 0xafb60028, 0xafb50024, 0xafb40020, -+0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, -+0x8f675c5c, 0x3c030800, 0x24631bbc, 0x8c620000, -+0x14470005, 0x3c0200ff, 0x3c020800, 0x90421b98, -+0x14400119, 0x3c0200ff, 0x3442fff8, 0x00e28824, -+0xac670000, 0x00111902, 0x306300ff, 0x30e20003, -+0x000211c0, 0x00622825, 0x00a04021, 0x00071602, -+0x3c030800, 0x90631b98, 0x3044000f, 0x14600036, -+0x00804821, 0x24020001, 0x3c010800, 0xa0221b98, -+0x00051100, 0x00821025, 0x3c010800, 0xac201b9c, -+0x3c010800, 0xac201ba0, 0x3c010800, 0xac201ba4, -+0x3c010800, 0xac201bac, 0x3c010800, 0xac201bb8, -+0x3c010800, 0xac201bb0, 0x3c010800, 0xac201bb4, -+0x3c010800, 0xa42223d8, 0x9622000c, 0x30437fff, -+0x3c010800, 0xa4222410, 0x30428000, 0x3c010800, -+0xa4231bc6, 0x10400005, 0x24020001, 0x3c010800, -+0xac2223f4, 0x0a000102, 0x2406003e, 0x24060036, -+0x3c010800, 0xac2023f4, 0x9622000a, 0x3c030800, -+0x94631bc6, 0x3c010800, 0xac2023f0, 0x3c010800, -+0xac2023f8, 0x00021302, 0x00021080, 0x00c21021, -+0x00621821, 0x3c010800, 0xa42223d0, 0x3c010800, -+0x0a000115, 0xa4231b96, 0x9622000c, 0x3c010800, -+0xa42223ec, 0x3c040800, 0x24841b9c, 0x8c820000, -+0x00021100, 0x3c010800, 0x00220821, 0xac311bc8, -+0x8c820000, 0x00021100, 0x3c010800, 0x00220821, -+0xac271bcc, 0x8c820000, 0x25030001, 0x306601ff, -+0x00021100, 0x3c010800, 0x00220821, 0xac261bd0, -+0x8c820000, 0x00021100, 0x3c010800, 0x00220821, -+0xac291bd4, 0x96230008, 0x3c020800, 0x8c421bac, -+0x00432821, 0x3c010800, 0xac251bac, 0x9622000a, -+0x30420004, 0x14400018, 0x00061100, 0x8f630c14, -+0x3063000f, 0x2c620002, 0x1440000b, 0x3c02c000, -+0x8f630c14, 0x3c020800, 0x8c421b40, 0x3063000f, -+0x24420001, 0x3c010800, 0xac221b40, 0x2c620002, -+0x1040fff7, 0x3c02c000, 0x00e21825, 0xaf635c5c, -+0x8f625c50, 0x30420002, 0x10400014, 0x00000000, -+0x0a000147, 0x00000000, 0x3c030800, 0x8c631b80, -+0x3c040800, 0x94841b94, 0x01221025, 0x3c010800, -+0xa42223da, 0x24020001, 0x3c010800, 0xac221bb8, -+0x24630001, 0x0085202a, 0x3c010800, 0x10800003, -+0xac231b80, 0x3c010800, 0xa4251b94, 0x3c060800, -+0x24c61b9c, 0x8cc20000, 0x24420001, 0xacc20000, -+0x28420080, 0x14400005, 0x00000000, 0x0e000656, -+0x24040002, 0x0a0001e6, 0x00000000, 0x3c020800, -+0x8c421bb8, 0x10400078, 0x24020001, 0x3c050800, -+0x90a51b98, 0x14a20072, 0x00000000, 0x3c150800, -+0x96b51b96, 0x3c040800, 0x8c841bac, 0x32a3ffff, -+0x0083102a, 0x1440006c, 0x00000000, 0x14830003, -+0x00000000, 0x3c010800, 0xac2523f0, 0x1060005c, -+0x00009021, 0x24d60004, 0x0060a021, 0x24d30014, -+0x8ec20000, 0x00028100, 0x3c110800, 0x02308821, -+0x0e000625, 0x8e311bc8, 0x00402821, 0x10a00054, -+0x00000000, 0x9628000a, 0x31020040, 0x10400005, -+0x2407180c, 0x8e22000c, 0x2407188c, 0x00021400, -+0xaca20018, 0x3c030800, 0x00701821, 0x8c631bd0, -+0x3c020800, 0x00501021, 0x8c421bd4, 0x00031d00, -+0x00021400, 0x00621825, 0xaca30014, 0x8ec30004, -+0x96220008, 0x00432023, 0x3242ffff, 0x3083ffff, -+0x00431021, 0x0282102a, 0x14400002, 0x02b23023, -+0x00803021, 0x8e620000, 0x30c4ffff, 0x00441021, -+0xae620000, 0x8e220000, 0xaca20000, 0x8e220004, -+0x8e63fff4, 0x00431021, 0xaca20004, 0xa4a6000e, -+0x8e62fff4, 0x00441021, 0xae62fff4, 0x96230008, -+0x0043102a, 0x14400005, 0x02469021, 0x8e62fff0, -+0xae60fff4, 0x24420001, 0xae62fff0, 0xaca00008, -+0x3242ffff, 0x14540008, 0x24020305, 0x31020080, -+0x54400001, 0x34e70010, 0x24020905, 0xa4a2000c, -+0x0a0001cb, 0x34e70020, 0xa4a2000c, 0x3c020800, -+0x8c4223f0, 0x10400003, 0x3c024b65, 0x0a0001d3, -+0x34427654, 0x3c02b49a, 0x344289ab, 0xaca2001c, -+0x30e2ffff, 0xaca20010, 0x0e0005a2, 0x00a02021, -+0x3242ffff, 0x0054102b, 0x1440ffa9, 0x00000000, -+0x24020002, 0x3c010800, 0x0a0001e6, 0xa0221b98, -+0x8ec2083c, 0x24420001, 0x0a0001e6, 0xaec2083c, -+0x0e0004c0, 0x00000000, 0x8fbf002c, 0x8fb60028, -+0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, -+0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0030, -+0x27bdffd0, 0xafbf0028, 0xafb30024, 0xafb20020, -+0xafb1001c, 0xafb00018, 0x8f725c9c, 0x3c0200ff, -+0x3442fff8, 0x3c070800, 0x24e71bb4, 0x02428824, -+0x9623000e, 0x8ce20000, 0x00431021, 0xace20000, -+0x8e220010, 0x30420020, 0x14400011, 0x00809821, -+0x0e00063b, 0x02202021, 0x3c02c000, 0x02421825, -+0xaf635c9c, 0x8f625c90, 0x30420002, 0x1040011e, -+0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, -+0x10400119, 0x00000000, 0x0a00020d, 0x00000000, -+0x8e240008, 0x8e230014, 0x00041402, 0x000231c0, -+0x00031502, 0x304201ff, 0x2442ffff, 0x3042007f, -+0x00031942, 0x30637800, 0x00021100, 0x24424000, -+0x00624821, 0x9522000a, 0x3084ffff, 0x30420008, -+0x104000b0, 0x000429c0, 0x3c020800, 0x8c422400, -+0x14400024, 0x24c50008, 0x94c20014, 0x3c010800, -+0xa42223d0, 0x8cc40010, 0x00041402, 0x3c010800, -+0xa42223d2, 0x3c010800, 0xa42423d4, 0x94c2000e, -+0x3083ffff, 0x00431023, 0x3c010800, 0xac222408, -+0x94c2001a, 0x3c010800, 0xac262400, 0x3c010800, -+0xac322404, 0x3c010800, 0xac2223fc, 0x3c02c000, -+0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, -+0x104000e5, 0x00000000, 0xaf635c9c, 0x8f625c90, -+0x30420002, 0x104000e0, 0x00000000, 0x0a000246, -+0x00000000, 0x94c2000e, 0x3c030800, 0x946323d4, -+0x00434023, 0x3103ffff, 0x2c620008, 0x1040001c, -+0x00000000, 0x94c20014, 0x24420028, 0x00a22821, -+0x00031042, 0x1840000b, 0x00002021, 0x24e60848, -+0x00403821, 0x94a30000, 0x8cc20000, 0x24840001, -+0x00431021, 0xacc20000, 0x0087102a, 0x1440fff9, -+0x24a50002, 0x31020001, 0x1040001f, 0x3c024000, -+0x3c040800, 0x248423fc, 0xa0a00001, 0x94a30000, -+0x8c820000, 0x00431021, 0x0a000285, 0xac820000, -+0x8f626800, 0x3c030010, 0x00431024, 0x10400009, -+0x00000000, 0x94c2001a, 0x3c030800, 0x8c6323fc, -+0x00431021, 0x3c010800, 0xac2223fc, 0x0a000286, -+0x3c024000, 0x94c2001a, 0x94c4001c, 0x3c030800, -+0x8c6323fc, 0x00441023, 0x00621821, 0x3c010800, -+0xac2323fc, 0x3c024000, 0x02421825, 0xaf635c9c, -+0x8f625c90, 0x30420002, 0x1440fffc, 0x00000000, -+0x9522000a, 0x30420010, 0x1040009b, 0x00000000, -+0x3c030800, 0x946323d4, 0x3c070800, 0x24e72400, -+0x8ce40000, 0x8f626800, 0x24630030, 0x00832821, -+0x3c030010, 0x00431024, 0x1440000a, 0x00000000, -+0x94a20004, 0x3c040800, 0x8c842408, 0x3c030800, -+0x8c6323fc, 0x00441023, 0x00621821, 0x3c010800, -+0xac2323fc, 0x3c040800, 0x8c8423fc, 0x00041c02, -+0x3082ffff, 0x00622021, 0x00041402, 0x00822021, -+0x00041027, 0xa4a20006, 0x3c030800, 0x8c632404, -+0x3c0200ff, 0x3442fff8, 0x00628824, 0x96220008, -+0x24050001, 0x24034000, 0x000231c0, 0x00801021, -+0xa4c2001a, 0xa4c0001c, 0xace00000, 0x3c010800, -+0xac251b60, 0xaf635cb8, 0x8f625cb0, 0x30420002, -+0x10400003, 0x00000000, 0x3c010800, 0xac201b60, -+0x8e220008, 0xaf625cb8, 0x8f625cb0, 0x30420002, -+0x10400003, 0x00000000, 0x3c010800, 0xac201b60, -+0x3c020800, 0x8c421b60, 0x1040ffec, 0x00000000, -+0x3c040800, 0x0e00063b, 0x8c842404, 0x0a00032a, -+0x00000000, 0x3c030800, 0x90631b98, 0x24020002, -+0x14620003, 0x3c034b65, 0x0a0002e1, 0x00008021, -+0x8e22001c, 0x34637654, 0x10430002, 0x24100002, -+0x24100001, 0x00c02021, 0x0e000350, 0x02003021, -+0x24020003, 0x3c010800, 0xa0221b98, 0x24020002, -+0x1202000a, 0x24020001, 0x3c030800, 0x8c6323f0, -+0x10620006, 0x00000000, 0x3c020800, 0x944223d8, -+0x00021400, 0x0a00031f, 0xae220014, 0x3c040800, -+0x248423da, 0x94820000, 0x00021400, 0xae220014, -+0x3c020800, 0x8c421bbc, 0x3c03c000, 0x3c010800, -+0xa0201b98, 0x00431025, 0xaf625c5c, 0x8f625c50, -+0x30420002, 0x10400009, 0x00000000, 0x2484f7e2, -+0x8c820000, 0x00431025, 0xaf625c5c, 0x8f625c50, -+0x30420002, 0x1440fffa, 0x00000000, 0x3c020800, -+0x24421b84, 0x8c430000, 0x24630001, 0xac430000, -+0x8f630c14, 0x3063000f, 0x2c620002, 0x1440000c, -+0x3c024000, 0x8f630c14, 0x3c020800, 0x8c421b40, -+0x3063000f, 0x24420001, 0x3c010800, 0xac221b40, -+0x2c620002, 0x1040fff7, 0x00000000, 0x3c024000, -+0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, -+0x1440fffc, 0x00000000, 0x12600003, 0x00000000, -+0x0e0004c0, 0x00000000, 0x8fbf0028, 0x8fb30024, -+0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x03e00008, -+0x27bd0030, 0x8f634450, 0x3c040800, 0x24841b88, -+0x8c820000, 0x00031c02, 0x0043102b, 0x14400007, -+0x3c038000, 0x8c840004, 0x8f624450, 0x00021c02, -+0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, -+0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, -+0x8f624448, 0x03e00008, 0x3042ffff, 0x3c024000, -+0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, -+0x1440fffc, 0x00000000, 0x03e00008, 0x00000000, -+0x27bdffe0, 0x00805821, 0x14c00011, 0x256e0008, -+0x3c020800, 0x8c4223f4, 0x10400007, 0x24020016, -+0x3c010800, 0xa42223d2, 0x2402002a, 0x3c010800, -+0x0a000364, 0xa42223d4, 0x8d670010, 0x00071402, -+0x3c010800, 0xa42223d2, 0x3c010800, 0xa42723d4, -+0x3c040800, 0x948423d4, 0x3c030800, 0x946323d2, -+0x95cf0006, 0x3c020800, 0x944223d0, 0x00832023, -+0x01e2c023, 0x3065ffff, 0x24a20028, 0x01c24821, -+0x3082ffff, 0x14c0001a, 0x01226021, 0x9582000c, -+0x3042003f, 0x3c010800, 0xa42223d6, 0x95820004, -+0x95830006, 0x3c010800, 0xac2023e4, 0x3c010800, -+0xac2023e8, 0x00021400, 0x00431025, 0x3c010800, -+0xac221bc0, 0x95220004, 0x3c010800, 0xa4221bc4, -+0x95230002, 0x01e51023, 0x0043102a, 0x10400010, -+0x24020001, 0x3c010800, 0x0a000398, 0xac2223f8, -+0x3c030800, 0x8c6323e8, 0x3c020800, 0x94421bc4, -+0x00431021, 0xa5220004, 0x3c020800, 0x94421bc0, -+0xa5820004, 0x3c020800, 0x8c421bc0, 0xa5820006, -+0x3c020800, 0x8c4223f0, 0x3c0d0800, 0x8dad23e4, -+0x3c0a0800, 0x144000e5, 0x8d4a23e8, 0x3c020800, -+0x94421bc4, 0x004a1821, 0x3063ffff, 0x0062182b, -+0x24020002, 0x10c2000d, 0x01435023, 0x3c020800, -+0x944223d6, 0x30420009, 0x10400008, 0x00000000, -+0x9582000c, 0x3042fff6, 0xa582000c, 0x3c020800, -+0x944223d6, 0x30420009, 0x01a26823, 0x3c020800, -+0x8c4223f8, 0x1040004a, 0x01203821, 0x3c020800, -+0x944223d2, 0x00004021, 0xa520000a, 0x01e21023, -+0xa5220002, 0x3082ffff, 0x00021042, 0x18400008, -+0x00003021, 0x00401821, 0x94e20000, 0x25080001, -+0x00c23021, 0x0103102a, 0x1440fffb, 0x24e70002, -+0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, -+0x00c23021, 0x00c02821, 0x00061027, 0xa522000a, -+0x00003021, 0x2527000c, 0x00004021, 0x94e20000, -+0x25080001, 0x00c23021, 0x2d020004, 0x1440fffb, -+0x24e70002, 0x95220002, 0x00004021, 0x91230009, -+0x00442023, 0x01803821, 0x3082ffff, 0xa4e00010, -+0x00621821, 0x00021042, 0x18400010, 0x00c33021, -+0x00404821, 0x94e20000, 0x24e70002, 0x00c23021, -+0x30e2007f, 0x14400006, 0x25080001, 0x8d630000, -+0x3c02007f, 0x3442ff80, 0x00625824, 0x25670008, -+0x0109102a, 0x1440fff3, 0x00000000, 0x30820001, -+0x10400005, 0x00061c02, 0xa0e00001, 0x94e20000, -+0x00c23021, 0x00061c02, 0x30c2ffff, 0x00623021, -+0x00061402, 0x00c23021, 0x0a00047d, 0x30c6ffff, -+0x24020002, 0x14c20081, 0x00000000, 0x3c020800, -+0x8c42240c, 0x14400007, 0x00000000, 0x3c020800, -+0x944223d2, 0x95230002, 0x01e21023, 0x10620077, -+0x00000000, 0x3c020800, 0x944223d2, 0x01e21023, -+0xa5220002, 0x3c020800, 0x8c42240c, 0x1040001a, -+0x31e3ffff, 0x8dc70010, 0x3c020800, 0x94421b96, -+0x00e04021, 0x00072c02, 0x00aa2021, 0x00431023, -+0x00823823, 0x00072402, 0x30e2ffff, 0x00823821, -+0x00071027, 0xa522000a, 0x3102ffff, 0x3c040800, -+0x948423d4, 0x00453023, 0x00e02821, 0x00641823, -+0x006d1821, 0x00c33021, 0x00061c02, 0x30c2ffff, -+0x0a00047d, 0x00623021, 0x01203821, 0x00004021, -+0x3082ffff, 0x00021042, 0x18400008, 0x00003021, -+0x00401821, 0x94e20000, 0x25080001, 0x00c23021, -+0x0103102a, 0x1440fffb, 0x24e70002, 0x00061c02, -+0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, -+0x00c02821, 0x00061027, 0xa522000a, 0x00003021, -+0x2527000c, 0x00004021, 0x94e20000, 0x25080001, -+0x00c23021, 0x2d020004, 0x1440fffb, 0x24e70002, -+0x95220002, 0x00004021, 0x91230009, 0x00442023, -+0x01803821, 0x3082ffff, 0xa4e00010, 0x3c040800, -+0x948423d4, 0x00621821, 0x00c33021, 0x00061c02, -+0x30c2ffff, 0x00623021, 0x00061c02, 0x3c020800, -+0x944223d0, 0x00c34821, 0x00441023, 0x00021fc2, -+0x00431021, 0x00021043, 0x18400010, 0x00003021, -+0x00402021, 0x94e20000, 0x24e70002, 0x00c23021, -+0x30e2007f, 0x14400006, 0x25080001, 0x8d630000, -+0x3c02007f, 0x3442ff80, 0x00625824, 0x25670008, -+0x0104102a, 0x1440fff3, 0x00000000, 0x3c020800, -+0x944223ec, 0x00c23021, 0x3122ffff, 0x00c23021, -+0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, -+0x00c23021, 0x00c04021, 0x00061027, 0xa5820010, -+0xadc00014, 0x0a00049d, 0xadc00000, 0x8dc70010, -+0x00e04021, 0x11400007, 0x00072c02, 0x00aa3021, -+0x00061402, 0x30c3ffff, 0x00433021, 0x00061402, -+0x00c22821, 0x00051027, 0xa522000a, 0x3c030800, -+0x946323d4, 0x3102ffff, 0x01e21021, 0x00433023, -+0x00cd3021, 0x00061c02, 0x30c2ffff, 0x00623021, -+0x00061402, 0x00c23021, 0x00c04021, 0x00061027, -+0xa5820010, 0x3102ffff, 0x00051c00, 0x00431025, -+0xadc20010, 0x3c020800, 0x8c4223f4, 0x10400005, -+0x2de205eb, 0x14400002, 0x25e2fff2, 0x34028870, -+0xa5c20034, 0x3c030800, 0x246323e8, 0x8c620000, -+0x24420001, 0xac620000, 0x3c040800, 0x8c8423e4, -+0x3c020800, 0x8c421bc0, 0x3303ffff, 0x00832021, -+0x00431821, 0x0062102b, 0x3c010800, 0xac2423e4, -+0x10400003, 0x2482ffff, 0x3c010800, 0xac2223e4, -+0x3c010800, 0xac231bc0, 0x03e00008, 0x27bd0020, -+0x27bdffb8, 0x3c050800, 0x24a51b96, 0xafbf0044, -+0xafbe0040, 0xafb7003c, 0xafb60038, 0xafb50034, -+0xafb40030, 0xafb3002c, 0xafb20028, 0xafb10024, -+0xafb00020, 0x94a90000, 0x3c020800, 0x944223d0, -+0x3c030800, 0x8c631bb0, 0x3c040800, 0x8c841bac, -+0x01221023, 0x0064182a, 0xa7a9001e, 0x106000be, -+0xa7a20016, 0x24be0022, 0x97b6001e, 0x24b3001a, -+0x24b70016, 0x8fc20000, 0x14400008, 0x00000000, -+0x8fc2fff8, 0x97a30016, 0x8fc4fff4, 0x00431021, -+0x0082202a, 0x148000b0, 0x00000000, 0x97d50818, -+0x32a2ffff, 0x104000a3, 0x00009021, 0x0040a021, -+0x00008821, 0x0e000625, 0x00000000, 0x00403021, -+0x14c00007, 0x00000000, 0x3c020800, 0x8c4223dc, -+0x24420001, 0x3c010800, 0x0a000596, 0xac2223dc, -+0x3c100800, 0x02118021, 0x8e101bc8, 0x9608000a, -+0x31020040, 0x10400005, 0x2407180c, 0x8e02000c, -+0x2407188c, 0x00021400, 0xacc20018, 0x31020080, -+0x54400001, 0x34e70010, 0x3c020800, 0x00511021, -+0x8c421bd0, 0x3c030800, 0x00711821, 0x8c631bd4, -+0x00021500, 0x00031c00, 0x00431025, 0xacc20014, -+0x96040008, 0x3242ffff, 0x00821021, 0x0282102a, -+0x14400002, 0x02b22823, 0x00802821, 0x8e020000, -+0x02459021, 0xacc20000, 0x8e020004, 0x00c02021, -+0x26310010, 0xac820004, 0x30e2ffff, 0xac800008, -+0xa485000e, 0xac820010, 0x24020305, 0x0e0005a2, -+0xa482000c, 0x3242ffff, 0x0054102b, 0x1440ffc5, -+0x3242ffff, 0x0a00058e, 0x00000000, 0x8e620000, -+0x8e63fffc, 0x0043102a, 0x10400067, 0x00000000, -+0x8e62fff0, 0x00028900, 0x3c100800, 0x02118021, -+0x0e000625, 0x8e101bc8, 0x00403021, 0x14c00005, -+0x00000000, 0x8e62082c, 0x24420001, 0x0a000596, -+0xae62082c, 0x9608000a, 0x31020040, 0x10400005, -+0x2407180c, 0x8e02000c, 0x2407188c, 0x00021400, -+0xacc20018, 0x3c020800, 0x00511021, 0x8c421bd0, -+0x3c030800, 0x00711821, 0x8c631bd4, 0x00021500, -+0x00031c00, 0x00431025, 0xacc20014, 0x8e63fff4, -+0x96020008, 0x00432023, 0x3242ffff, 0x3083ffff, -+0x00431021, 0x02c2102a, 0x10400003, 0x00802821, -+0x97a9001e, 0x01322823, 0x8e620000, 0x30a4ffff, -+0x00441021, 0xae620000, 0xa4c5000e, 0x8e020000, -+0xacc20000, 0x8e020004, 0x8e63fff4, 0x00431021, -+0xacc20004, 0x8e63fff4, 0x96020008, 0x00641821, -+0x0062102a, 0x14400006, 0x02459021, 0x8e62fff0, -+0xae60fff4, 0x24420001, 0x0a000571, 0xae62fff0, -+0xae63fff4, 0xacc00008, 0x3242ffff, 0x10560003, -+0x31020004, 0x10400006, 0x24020305, 0x31020080, -+0x54400001, 0x34e70010, 0x34e70020, 0x24020905, -+0xa4c2000c, 0x8ee30000, 0x8ee20004, 0x14620007, -+0x3c02b49a, 0x8ee20860, 0x54400001, 0x34e70400, -+0x3c024b65, 0x0a000588, 0x34427654, 0x344289ab, -+0xacc2001c, 0x30e2ffff, 0xacc20010, 0x0e0005a2, -+0x00c02021, 0x3242ffff, 0x0056102b, 0x1440ff9b, -+0x00000000, 0x8e620000, 0x8e63fffc, 0x0043102a, -+0x1440ff48, 0x00000000, 0x8fbf0044, 0x8fbe0040, -+0x8fb7003c, 0x8fb60038, 0x8fb50034, 0x8fb40030, -+0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, -+0x03e00008, 0x27bd0048, 0x27bdffe8, 0xafbf0014, -+0xafb00010, 0x8f624450, 0x8f634410, 0x0a0005b1, -+0x00808021, 0x8f626820, 0x30422000, 0x10400003, -+0x00000000, 0x0e0001f0, 0x00002021, 0x8f624450, -+0x8f634410, 0x3042ffff, 0x0043102b, 0x1440fff5, -+0x00000000, 0x8f630c14, 0x3063000f, 0x2c620002, -+0x1440000b, 0x00000000, 0x8f630c14, 0x3c020800, -+0x8c421b40, 0x3063000f, 0x24420001, 0x3c010800, -+0xac221b40, 0x2c620002, 0x1040fff7, 0x00000000, -+0xaf705c18, 0x8f625c10, 0x30420002, 0x10400009, -+0x00000000, 0x8f626820, 0x30422000, 0x1040fff8, -+0x00000000, 0x0e0001f0, 0x00002021, 0x0a0005c4, -+0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008, -+0x27bd0018, 0x00000000, 0x00000000, 0x00000000, -+0x27bdffe8, 0x3c1bc000, 0xafbf0014, 0xafb00010, -+0xaf60680c, 0x8f626804, 0x34420082, 0xaf626804, -+0x8f634000, 0x24020b50, 0x3c010800, 0xac221b54, -+0x24020b78, 0x3c010800, 0xac221b64, 0x34630002, -+0xaf634000, 0x0e000605, 0x00808021, 0x3c010800, -+0xa0221b68, 0x304200ff, 0x24030002, 0x14430005, -+0x00000000, 0x3c020800, 0x8c421b54, 0x0a0005f8, -+0xac5000c0, 0x3c020800, 0x8c421b54, 0xac5000bc, -+0x8f624434, 0x8f634438, 0x8f644410, 0x3c010800, -+0xac221b5c, 0x3c010800, 0xac231b6c, 0x3c010800, -+0xac241b58, 0x8fbf0014, 0x8fb00010, 0x03e00008, -+0x27bd0018, 0x3c040800, 0x8c870000, 0x3c03aa55, -+0x3463aa55, 0x3c06c003, 0xac830000, 0x8cc20000, -+0x14430007, 0x24050002, 0x3c0355aa, 0x346355aa, -+0xac830000, 0x8cc20000, 0x50430001, 0x24050001, -+0x3c020800, 0xac470000, 0x03e00008, 0x00a01021, -+0x27bdfff8, 0x18800009, 0x00002821, 0x8f63680c, -+0x8f62680c, 0x1043fffe, 0x00000000, 0x24a50001, -+0x00a4102a, 0x1440fff9, 0x00000000, 0x03e00008, -+0x27bd0008, 0x8f634450, 0x3c020800, 0x8c421b5c, -+0x00031c02, 0x0043102b, 0x14400008, 0x3c038000, -+0x3c040800, 0x8c841b6c, 0x8f624450, 0x00021c02, -+0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, -+0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, -+0x8f624448, 0x03e00008, 0x3042ffff, 0x3082ffff, -+0x2442e000, 0x2c422001, 0x14400003, 0x3c024000, -+0x0a000648, 0x2402ffff, 0x00822025, 0xaf645c38, -+0x8f625c30, 0x30420002, 0x1440fffc, 0x00001021, -+0x03e00008, 0x00000000, 0x8f624450, 0x3c030800, -+0x8c631b58, 0x0a000651, 0x3042ffff, 0x8f624450, -+0x3042ffff, 0x0043102b, 0x1440fffc, 0x00000000, -+0x03e00008, 0x00000000, 0x27bdffe0, 0x00802821, -+0x3c040800, 0x24841af0, 0x00003021, 0x00003821, -+0xafbf0018, 0xafa00010, 0x0e00067c, 0xafa00014, -+0x0a000660, 0x00000000, 0x8fbf0018, 0x03e00008, -+0x27bd0020, 0x00000000, 0x00000000, 0x00000000, -+0x3c020800, 0x34423000, 0x3c030800, 0x34633000, -+0x3c040800, 0x348437ff, 0x3c010800, 0xac221b74, -+0x24020040, 0x3c010800, 0xac221b78, 0x3c010800, -+0xac201b70, 0xac600000, 0x24630004, 0x0083102b, -+0x5040fffd, 0xac600000, 0x03e00008, 0x00000000, -+0x00804821, 0x8faa0010, 0x3c020800, 0x8c421b70, -+0x3c040800, 0x8c841b78, 0x8fab0014, 0x24430001, -+0x0044102b, 0x3c010800, 0xac231b70, 0x14400003, -+0x00004021, 0x3c010800, 0xac201b70, 0x3c020800, -+0x8c421b70, 0x3c030800, 0x8c631b74, 0x91240000, -+0x00021140, 0x00431021, 0x00481021, 0x25080001, -+0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, -+0x3c020800, 0x8c421b70, 0x3c030800, 0x8c631b74, -+0x8f64680c, 0x00021140, 0x00431021, 0xac440008, -+0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, -+0x03e00008, 0xac4b001c, 0x00000000, 0x00000000, -+0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, -+0x43707541, 0x00000000, 0x00000000, 0x00000000, -+0x73746b6f, 0x66666c64, 0x496e0000, 0x73746b6f, -+0x66662a2a, 0x00000000, 0x53774576, 0x656e7430, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x66617461, 0x6c457272, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, -+0x362e3000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+}; -+ -+static const struct tg3_firmware tg3_lgcy_tso_fw = { -+ .size = TG3_LGCY_TSO_FW_LEN, -+ .data = (u8 *)&tg3TsoFwText[0], -+}; -+ -+/* 5705 needs a special version of the TSO firmware. */ -+#define TG3_TSO5_FW_RELEASE_MAJOR 0x1 -+#define TG3_TSO5_FW_RELASE_MINOR 0x2 -+#define TG3_TSO5_FW_RELEASE_FIX 0x0 -+#define TG3_TSO5_FW_START_ADDR 0x00010000 -+#define TG3_TSO5_FW_TEXT_ADDR 0x00010000 -+#define TG3_TSO5_FW_TEXT_LEN 0xe90 -+#define TG3_TSO5_FW_RODATA_ADDR 0x00010e90 -+#define TG3_TSO5_FW_RODATA_LEN 0x50 -+#define TG3_TSO5_FW_DATA_ADDR 0x00010f00 -+#define TG3_TSO5_FW_DATA_LEN 0x20 -+#define TG3_TSO5_FW_SBSS_ADDR 0x00010f20 -+#define TG3_TSO5_FW_SBSS_LEN 0x28 -+#define TG3_TSO5_FW_BSS_ADDR 0x00010f50 -+#define TG3_TSO5_FW_BSS_LEN 0x88 -+ -+#define TG3_5705_TSO_FW_LEN \ -+ (TG3_TSO5_FW_TEXT_LEN + \ -+ TG3_TSO5_FW_RODATA_LEN + \ -+ 0x20 + \ -+ TG3_TSO5_FW_DATA_LEN) -+ -+static const u32 tg3Tso5FwText[] = { -+0x00010200, (u32)TG3_TSO5_FW_TEXT_ADDR, (u32)TG3_5705_TSO_FW_LEN, -+0x0c004003, 0x00000000, 0x00010f04, 0x00000000, -+0x10000003, 0x00000000, 0x0000000d, 0x0000000d, -+0x3c1d0001, 0x37bde000, 0x03a0f021, 0x3c100001, -+0x26100000, 0x0c004010, 0x00000000, 0x0000000d, -+0x27bdffe0, 0x3c04fefe, 0xafbf0018, 0x0c0042e8, -+0x34840002, 0x0c004364, 0x00000000, 0x3c030001, -+0x90630f34, 0x24020002, 0x3c040001, 0x24840e9c, -+0x14620003, 0x24050001, 0x3c040001, 0x24840e90, -+0x24060002, 0x00003821, 0xafa00010, 0x0c004378, -+0xafa00014, 0x0c00402c, 0x00000000, 0x8fbf0018, -+0x03e00008, 0x27bd0020, 0x00000000, 0x00000000, -+0x27bdffe0, 0xafbf001c, 0xafb20018, 0xafb10014, -+0x0c0042d4, 0xafb00010, 0x3c128000, 0x24110001, -+0x8f706810, 0x32020400, 0x10400007, 0x00000000, -+0x8f641008, 0x00921024, 0x14400003, 0x00000000, -+0x0c004064, 0x00000000, 0x3c020001, 0x90420f56, -+0x10510003, 0x32020200, 0x1040fff1, 0x00000000, -+0x0c0041b4, 0x00000000, 0x08004034, 0x00000000, -+0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, -+0x03e00008, 0x27bd0020, 0x27bdffe0, 0x3c040001, -+0x24840eb0, 0x00002821, 0x00003021, 0x00003821, -+0xafbf0018, 0xafa00010, 0x0c004378, 0xafa00014, -+0x0000d021, 0x24020130, 0xaf625000, 0x3c010001, -+0xa4200f50, 0x3c010001, 0xa0200f57, 0x8fbf0018, -+0x03e00008, 0x27bd0020, 0x00000000, 0x00000000, -+0x3c030001, 0x24630f60, 0x90620000, 0x27bdfff0, -+0x14400003, 0x0080c021, 0x08004073, 0x00004821, -+0x3c022000, 0x03021024, 0x10400003, 0x24090002, -+0x08004073, 0xa0600000, 0x24090001, 0x00181040, -+0x30431f80, 0x346f8008, 0x1520004b, 0x25eb0028, -+0x3c040001, 0x00832021, 0x8c848010, 0x3c050001, -+0x24a50f7a, 0x00041402, 0xa0a20000, 0x3c010001, -+0xa0240f7b, 0x3c020001, 0x00431021, 0x94428014, -+0x3c010001, 0xa0220f7c, 0x3c0c0001, 0x01836021, -+0x8d8c8018, 0x304200ff, 0x24420008, 0x000220c3, -+0x24020001, 0x3c010001, 0xa0220f60, 0x0124102b, -+0x1040000c, 0x00003821, 0x24a6000e, 0x01602821, -+0x8ca20000, 0x8ca30004, 0x24a50008, 0x24e70001, -+0xacc20000, 0xacc30004, 0x00e4102b, 0x1440fff8, -+0x24c60008, 0x00003821, 0x3c080001, 0x25080f7b, -+0x91060000, 0x3c020001, 0x90420f7c, 0x2503000d, -+0x00c32821, 0x00461023, 0x00021fc2, 0x00431021, -+0x00021043, 0x1840000c, 0x00002021, 0x91020001, -+0x00461023, 0x00021fc2, 0x00431021, 0x00021843, -+0x94a20000, 0x24e70001, 0x00822021, 0x00e3102a, -+0x1440fffb, 0x24a50002, 0x00041c02, 0x3082ffff, -+0x00622021, 0x00041402, 0x00822021, 0x3c02ffff, -+0x01821024, 0x3083ffff, 0x00431025, 0x3c010001, -+0x080040fa, 0xac220f80, 0x3c050001, 0x24a50f7c, -+0x90a20000, 0x3c0c0001, 0x01836021, 0x8d8c8018, -+0x000220c2, 0x1080000e, 0x00003821, 0x01603021, -+0x24a5000c, 0x8ca20000, 0x8ca30004, 0x24a50008, -+0x24e70001, 0xacc20000, 0xacc30004, 0x00e4102b, -+0x1440fff8, 0x24c60008, 0x3c050001, 0x24a50f7c, -+0x90a20000, 0x30430007, 0x24020004, 0x10620011, -+0x28620005, 0x10400005, 0x24020002, 0x10620008, -+0x000710c0, 0x080040fa, 0x00000000, 0x24020006, -+0x1062000e, 0x000710c0, 0x080040fa, 0x00000000, -+0x00a21821, 0x9463000c, 0x004b1021, 0x080040fa, -+0xa4430000, 0x000710c0, 0x00a21821, 0x8c63000c, -+0x004b1021, 0x080040fa, 0xac430000, 0x00a21821, -+0x8c63000c, 0x004b2021, 0x00a21021, 0xac830000, -+0x94420010, 0xa4820004, 0x95e70006, 0x3c020001, -+0x90420f7c, 0x3c030001, 0x90630f7a, 0x00e2c823, -+0x3c020001, 0x90420f7b, 0x24630028, 0x01e34021, -+0x24420028, 0x15200012, 0x01e23021, 0x94c2000c, -+0x3c010001, 0xa4220f78, 0x94c20004, 0x94c30006, -+0x3c010001, 0xa4200f76, 0x3c010001, 0xa4200f72, -+0x00021400, 0x00431025, 0x3c010001, 0xac220f6c, -+0x95020004, 0x3c010001, 0x08004124, 0xa4220f70, -+0x3c020001, 0x94420f70, 0x3c030001, 0x94630f72, -+0x00431021, 0xa5020004, 0x3c020001, 0x94420f6c, -+0xa4c20004, 0x3c020001, 0x8c420f6c, 0xa4c20006, -+0x3c040001, 0x94840f72, 0x3c020001, 0x94420f70, -+0x3c0a0001, 0x954a0f76, 0x00441821, 0x3063ffff, -+0x0062182a, 0x24020002, 0x1122000b, 0x00832023, -+0x3c030001, 0x94630f78, 0x30620009, 0x10400006, -+0x3062fff6, 0xa4c2000c, 0x3c020001, 0x94420f78, -+0x30420009, 0x01425023, 0x24020001, 0x1122001b, -+0x29220002, 0x50400005, 0x24020002, 0x11200007, -+0x31a2ffff, 0x08004197, 0x00000000, 0x1122001d, -+0x24020016, 0x08004197, 0x31a2ffff, 0x3c0e0001, -+0x95ce0f80, 0x10800005, 0x01806821, 0x01c42021, -+0x00041c02, 0x3082ffff, 0x00627021, 0x000e1027, -+0xa502000a, 0x3c030001, 0x90630f7b, 0x31a2ffff, -+0x00e21021, 0x0800418d, 0x00432023, 0x3c020001, -+0x94420f80, 0x00442021, 0x00041c02, 0x3082ffff, -+0x00622021, 0x00807021, 0x00041027, 0x08004185, -+0xa502000a, 0x3c050001, 0x24a50f7a, 0x90a30000, -+0x14620002, 0x24e2fff2, 0xa5e20034, 0x90a20000, -+0x00e21023, 0xa5020002, 0x3c030001, 0x94630f80, -+0x3c020001, 0x94420f5a, 0x30e5ffff, 0x00641821, -+0x00451023, 0x00622023, 0x00041c02, 0x3082ffff, -+0x00622021, 0x00041027, 0xa502000a, 0x3c030001, -+0x90630f7c, 0x24620001, 0x14a20005, 0x00807021, -+0x01631021, 0x90420000, 0x08004185, 0x00026200, -+0x24620002, 0x14a20003, 0x306200fe, 0x004b1021, -+0x944c0000, 0x3c020001, 0x94420f82, 0x3183ffff, -+0x3c040001, 0x90840f7b, 0x00431021, 0x00e21021, -+0x00442023, 0x008a2021, 0x00041c02, 0x3082ffff, -+0x00622021, 0x00041402, 0x00822021, 0x00806821, -+0x00041027, 0xa4c20010, 0x31a2ffff, 0x000e1c00, -+0x00431025, 0x3c040001, 0x24840f72, 0xade20010, -+0x94820000, 0x3c050001, 0x94a50f76, 0x3c030001, -+0x8c630f6c, 0x24420001, 0x00b92821, 0xa4820000, -+0x3322ffff, 0x00622021, 0x0083182b, 0x3c010001, -+0xa4250f76, 0x10600003, 0x24a2ffff, 0x3c010001, -+0xa4220f76, 0x3c024000, 0x03021025, 0x3c010001, -+0xac240f6c, 0xaf621008, 0x03e00008, 0x27bd0010, -+0x3c030001, 0x90630f56, 0x27bdffe8, 0x24020001, -+0xafbf0014, 0x10620026, 0xafb00010, 0x8f620cf4, -+0x2442ffff, 0x3042007f, 0x00021100, 0x8c434000, -+0x3c010001, 0xac230f64, 0x8c434008, 0x24444000, -+0x8c5c4004, 0x30620040, 0x14400002, 0x24020088, -+0x24020008, 0x3c010001, 0xa4220f68, 0x30620004, -+0x10400005, 0x24020001, 0x3c010001, 0xa0220f57, -+0x080041d5, 0x00031402, 0x3c010001, 0xa0200f57, -+0x00031402, 0x3c010001, 0xa4220f54, 0x9483000c, -+0x24020001, 0x3c010001, 0xa4200f50, 0x3c010001, -+0xa0220f56, 0x3c010001, 0xa4230f62, 0x24020001, -+0x1342001e, 0x00000000, 0x13400005, 0x24020003, -+0x13420067, 0x00000000, 0x080042cf, 0x00000000, -+0x3c020001, 0x94420f62, 0x241a0001, 0x3c010001, -+0xa4200f5e, 0x3c010001, 0xa4200f52, 0x304407ff, -+0x00021bc2, 0x00031823, 0x3063003e, 0x34630036, -+0x00021242, 0x3042003c, 0x00621821, 0x3c010001, -+0xa4240f58, 0x00832021, 0x24630030, 0x3c010001, -+0xa4240f5a, 0x3c010001, 0xa4230f5c, 0x3c060001, -+0x24c60f52, 0x94c50000, 0x94c30002, 0x3c040001, -+0x94840f5a, 0x00651021, 0x0044102a, 0x10400013, -+0x3c108000, 0x00a31021, 0xa4c20000, 0x3c02a000, -+0xaf620cf4, 0x3c010001, 0xa0200f56, 0x8f641008, -+0x00901024, 0x14400003, 0x00000000, 0x0c004064, -+0x00000000, 0x8f620cf4, 0x00501024, 0x104000b7, -+0x00000000, 0x0800420f, 0x00000000, 0x3c030001, -+0x94630f50, 0x00851023, 0xa4c40000, 0x00621821, -+0x3042ffff, 0x3c010001, 0xa4230f50, 0xaf620ce8, -+0x3c020001, 0x94420f68, 0x34420024, 0xaf620cec, -+0x94c30002, 0x3c020001, 0x94420f50, 0x14620012, -+0x3c028000, 0x3c108000, 0x3c02a000, 0xaf620cf4, -+0x3c010001, 0xa0200f56, 0x8f641008, 0x00901024, -+0x14400003, 0x00000000, 0x0c004064, 0x00000000, -+0x8f620cf4, 0x00501024, 0x1440fff7, 0x00000000, -+0x080042cf, 0x241a0003, 0xaf620cf4, 0x3c108000, -+0x8f641008, 0x00901024, 0x14400003, 0x00000000, -+0x0c004064, 0x00000000, 0x8f620cf4, 0x00501024, -+0x1440fff7, 0x00000000, 0x080042cf, 0x241a0003, -+0x3c070001, 0x24e70f50, 0x94e20000, 0x03821021, -+0xaf620ce0, 0x3c020001, 0x8c420f64, 0xaf620ce4, -+0x3c050001, 0x94a50f54, 0x94e30000, 0x3c040001, -+0x94840f58, 0x3c020001, 0x94420f5e, 0x00a32823, -+0x00822023, 0x30a6ffff, 0x3083ffff, 0x00c3102b, -+0x14400043, 0x00000000, 0x3c020001, 0x94420f5c, -+0x00021400, 0x00621025, 0xaf620ce8, 0x94e20000, -+0x3c030001, 0x94630f54, 0x00441021, 0xa4e20000, -+0x3042ffff, 0x14430021, 0x3c020008, 0x3c020001, -+0x90420f57, 0x10400006, 0x3c03000c, 0x3c020001, -+0x94420f68, 0x34630624, 0x0800427c, 0x0000d021, -+0x3c020001, 0x94420f68, 0x3c030008, 0x34630624, -+0x00431025, 0xaf620cec, 0x3c108000, 0x3c02a000, -+0xaf620cf4, 0x3c010001, 0xa0200f56, 0x8f641008, -+0x00901024, 0x14400003, 0x00000000, 0x0c004064, -+0x00000000, 0x8f620cf4, 0x00501024, 0x10400015, -+0x00000000, 0x08004283, 0x00000000, 0x3c030001, -+0x94630f68, 0x34420624, 0x3c108000, 0x00621825, -+0x3c028000, 0xaf630cec, 0xaf620cf4, 0x8f641008, -+0x00901024, 0x14400003, 0x00000000, 0x0c004064, -+0x00000000, 0x8f620cf4, 0x00501024, 0x1440fff7, -+0x00000000, 0x3c010001, 0x080042cf, 0xa4200f5e, -+0x3c020001, 0x94420f5c, 0x00021400, 0x00c21025, -+0xaf620ce8, 0x3c020001, 0x90420f57, 0x10400009, -+0x3c03000c, 0x3c020001, 0x94420f68, 0x34630624, -+0x0000d021, 0x00431025, 0xaf620cec, 0x080042c1, -+0x3c108000, 0x3c020001, 0x94420f68, 0x3c030008, -+0x34630604, 0x00431025, 0xaf620cec, 0x3c020001, -+0x94420f5e, 0x00451021, 0x3c010001, 0xa4220f5e, -+0x3c108000, 0x3c02a000, 0xaf620cf4, 0x3c010001, -+0xa0200f56, 0x8f641008, 0x00901024, 0x14400003, -+0x00000000, 0x0c004064, 0x00000000, 0x8f620cf4, -+0x00501024, 0x1440fff7, 0x00000000, 0x8fbf0014, -+0x8fb00010, 0x03e00008, 0x27bd0018, 0x00000000, -+0x27bdffe0, 0x3c040001, 0x24840ec0, 0x00002821, -+0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, -+0x0c004378, 0xafa00014, 0x0000d021, 0x24020130, -+0xaf625000, 0x3c010001, 0xa4200f50, 0x3c010001, -+0xa0200f57, 0x8fbf0018, 0x03e00008, 0x27bd0020, -+0x27bdffe8, 0x3c1bc000, 0xafbf0014, 0xafb00010, -+0xaf60680c, 0x8f626804, 0x34420082, 0xaf626804, -+0x8f634000, 0x24020b50, 0x3c010001, 0xac220f20, -+0x24020b78, 0x3c010001, 0xac220f30, 0x34630002, -+0xaf634000, 0x0c004315, 0x00808021, 0x3c010001, -+0xa0220f34, 0x304200ff, 0x24030002, 0x14430005, -+0x00000000, 0x3c020001, 0x8c420f20, 0x08004308, -+0xac5000c0, 0x3c020001, 0x8c420f20, 0xac5000bc, -+0x8f624434, 0x8f634438, 0x8f644410, 0x3c010001, -+0xac220f28, 0x3c010001, 0xac230f38, 0x3c010001, -+0xac240f24, 0x8fbf0014, 0x8fb00010, 0x03e00008, -+0x27bd0018, 0x03e00008, 0x24020001, 0x27bdfff8, -+0x18800009, 0x00002821, 0x8f63680c, 0x8f62680c, -+0x1043fffe, 0x00000000, 0x24a50001, 0x00a4102a, -+0x1440fff9, 0x00000000, 0x03e00008, 0x27bd0008, -+0x8f634450, 0x3c020001, 0x8c420f28, 0x00031c02, -+0x0043102b, 0x14400008, 0x3c038000, 0x3c040001, -+0x8c840f38, 0x8f624450, 0x00021c02, 0x0083102b, -+0x1040fffc, 0x3c038000, 0xaf634444, 0x8f624444, -+0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, -+0x03e00008, 0x3042ffff, 0x3082ffff, 0x2442e000, -+0x2c422001, 0x14400003, 0x3c024000, 0x08004347, -+0x2402ffff, 0x00822025, 0xaf645c38, 0x8f625c30, -+0x30420002, 0x1440fffc, 0x00001021, 0x03e00008, -+0x00000000, 0x8f624450, 0x3c030001, 0x8c630f24, -+0x08004350, 0x3042ffff, 0x8f624450, 0x3042ffff, -+0x0043102b, 0x1440fffc, 0x00000000, 0x03e00008, -+0x00000000, 0x27bdffe0, 0x00802821, 0x3c040001, -+0x24840ed0, 0x00003021, 0x00003821, 0xafbf0018, -+0xafa00010, 0x0c004378, 0xafa00014, 0x0800435f, -+0x00000000, 0x8fbf0018, 0x03e00008, 0x27bd0020, -+0x3c020001, 0x3442d600, 0x3c030001, 0x3463d600, -+0x3c040001, 0x3484ddff, 0x3c010001, 0xac220f40, -+0x24020040, 0x3c010001, 0xac220f44, 0x3c010001, -+0xac200f3c, 0xac600000, 0x24630004, 0x0083102b, -+0x5040fffd, 0xac600000, 0x03e00008, 0x00000000, -+0x00804821, 0x8faa0010, 0x3c020001, 0x8c420f3c, -+0x3c040001, 0x8c840f44, 0x8fab0014, 0x24430001, -+0x0044102b, 0x3c010001, 0xac230f3c, 0x14400003, -+0x00004021, 0x3c010001, 0xac200f3c, 0x3c020001, -+0x8c420f3c, 0x3c030001, 0x8c630f40, 0x91240000, -+0x00021140, 0x00431021, 0x00481021, 0x25080001, -+0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, -+0x3c020001, 0x8c420f3c, 0x3c030001, 0x8c630f40, -+0x8f64680c, 0x00021140, 0x00431021, 0xac440008, -+0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, -+0x03e00008, 0xac4b001c, 0x00000000, 0x00000000, -+0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, -+0x43707541, 0x00000000, 0x00000000, 0x00000000, -+0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, -+0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, -+0x66617461, 0x6c457272, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x00000000, 0x00000000, 0x00000000, -+0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, -+0x322e3000, 0x00000000, 0x00000000, 0x00000000, -+}; -+ -+static const struct tg3_firmware tg3_5705_tso_fw = { -+ .size = TG3_5705_TSO_FW_LEN, -+ .data = (u8 *)&tg3Tso5FwText[0], -+}; -+ -+#endif /* TG3_TSO_SUPPORT != 0 */ -+ -+static int tg3_hidden_request_firmware(const struct tg3_firmware **fw, -+ const char *name) -+{ -+ *fw = 0; -+ -+ if (strcmp(name, "tigon/tg3.bin") == 0) -+ *fw = &tg3_5701_fw; -+ else if (strcmp(name, "tigon/tg357766.bin") == 0) -+ *fw = &tg3_57766_fw; -+#if TG3_TSO_SUPPORT != 0 -+ else if (strcmp(name, "tigon/tg3_tso.bin") == 0) -+ *fw = &tg3_lgcy_tso_fw; -+ else if (strcmp(name, "tigon/tg3_tso5.bin") == 0) -+ *fw = &tg3_5705_tso_fw; -+#endif -+ -+ return *fw ? 0 : -EINVAL; -+} -+ -+#define tg3_priv_request_firmware(x, y, z) tg3_hidden_request_firmware((x), (y)) -+ -+#define tg3_priv_release_firmware(x) -+ -+#endif /* BCM_HAS_REQUEST_FIRMWARE */ -diff --git a/drivers/net/ethernet/broadcom/tg3/tg3_flags.h b/drivers/net/ethernet/broadcom/tg3/tg3_flags.h -new file mode 100644 -index 0000000..6788434 ---- /dev/null -+++ b/drivers/net/ethernet/broadcom/tg3/tg3_flags.h -@@ -0,0 +1,95 @@ -+#define BCM_HAS_BOOL -+#define BCM_HAS_LE32 -+#define BCM_HAS_RESOURCE_SIZE_T -+#define BCM_HAS_KZALLOC -+#define BCM_HAS_JIFFIES_TO_USECS -+#define BCM_HAS_USECS_TO_JIFFIES -+#define BCM_HAS_MSECS_TO_JIFFIES -+#define BCM_HAS_MSLEEP -+#define BCM_HAS_MSLEEP_INTERRUPTIBLE -+#define BCM_HAS_SKB_COPY_FROM_LINEAR_DATA -+#define BCM_HAS_SKB_IS_GSO_V6 -+#define BCM_HAS_SKB_CHECKSUM_NONE_ASSERT -+#define BCM_KERNEL_SUPPORTS_TIMESTAMPING -+#define BCM_HAS_SKB_TX_TIMESTAMP -+#define BCM_HAS_SKB_FRAG_SIZE -+#define BCM_HAS_SKB_FRAG_DMA_MAP -+#define BCM_HAS_PCI_PCIE_CAP -+#define BCM_HAS_PCIE_CAP_RW -+#define BCM_HAS_PCI_IS_PCIE -+#define BCM_HAS_PCI_IOREMAP_BAR -+#define BCM_HAS_PCI_READ_VPD -+#define BCM_HAS_INTX_MSI_WORKAROUND -+#define BCM_HAS_PCI_TARGET_STATE -+#define BCM_HAS_PCI_CHOOSE_STATE -+#define BCM_HAS_PCI_PME_CAPABLE -+#define BCM_HAS_PCI_ENABLE_WAKE -+#define BCM_HAS_PCI_WAKE_FROM_D3 -+#define BCM_HAS_PCI_SET_POWER_STATE -+#define BCM_HAS_PCI_EEH_SUPPORT -+#define BCM_HAS_PCI_IS_ENABLED -+#define BCM_HAS_DEVICE_WAKEUP_API -+#define BCM_HAS_DEVICE_SET_WAKEUP_CAPABLE -+#define BCM_HAS_NEW_PCI_DMA_MAPPING_ERROR -+#define BCM_HAS_PCIE_GET_READRQ -+#define BCM_HAS_PCIE_SET_READRQ -+#define BCM_HAS_ETHTOOL_OP_SET_TX_IPV6_CSUM -+#define BCM_HAS_ETHTOOL_OP_SET_TX_HW_CSUM -+#define BCM_HAS_ETHTOOL_OP_SET_SG -+#define BCM_HAS_ETHTOOL_OP_SET_TSO -+#define BCM_HAS_MDIX_STATUS -+#define BCM_HAS_SET_PHYS_ID -+#define BCM_HAS_SET_TX_CSUM -+#define BCM_HAS_ETHTOOL_CMD_SPEED_SET -+#define BCM_HAS_ETHTOOL_CMD_SPEED -+#define BCM_HAS_EXTERNAL_LB_DONE -+#define BCM_HAS_GET_RXNFC -+#define BCM_HAS_GET_RXFH_INDIR -+#define BCM_HAS_LP_ADVERTISING -+#define BCM_HAS_SKB_TRANSPORT_OFFSET -+#define BCM_HAS_SKB_GET_QUEUE_MAPPING -+#define BCM_HAS_IP_HDR -+#define BCM_HAS_IP_HDRLEN -+#define BCM_HAS_TCP_HDR -+#define BCM_HAS_TCP_HDRLEN -+#define BCM_HAS_TCP_OPTLEN -+#define BCM_HAS_STRUCT_NETDEV_QUEUE -+#define BCM_HAS_NETIF_SET_REAL_NUM_TX_QUEUES -+#define BCM_HAS_NETIF_SET_REAL_NUM_RX_QUEUES -+#define BCM_HAS_NETDEV_PRIV -+#define BCM_HAS_NETDEV_TX_T -+#define BCM_HAS_NETDEV_HW_ADDR -+#define BCM_HAS_NETDEV_NAME -+#define BCM_HAS_NETDEV_SENT_QUEUE -+#define BCM_HAS_NETDEV_TX_SENT_QUEUE -+#define BCM_HAS_NETDEV_COMPLETED_QUEUE -+#define BCM_HAS_NETDEV_TX_COMPLETED_QUEUE -+#define BCM_HAS_NETDEV_RESET_QUEUE -+#define BCM_HAS_NETDEV_TX_RESET_QUEUE -+#define BCM_HAS_NET_DEVICE_OPS -+#define BCM_HAS_GET_STATS64 -+#define BCM_HAS_FIX_FEATURES -+#define BCM_HAS_HW_FEATURES -+#define BCM_HAS_VLAN_FEATURES -+#define BCM_HAS_NETDEV_UPDATE_FEATURES -+#define BCM_HAS_ALLOC_ETHERDEV_MQ -+#define BCM_HAS_NAPI_GRO_RECEIVE -+#define BCM_HAS_NETIF_TX_LOCK -+#define BCM_HAS_TXQ_TRANS_UPDATE -+#define BCM_HAS_NETDEV_FEATURES_T -+#define BCM_HAS_NEW_VLAN_INTERFACE -+#define BCM_HAS_DEV_DRIVER_STRING -+#define BCM_HAS_DEV_NAME -+#define BCM_HAS_MDIO_H -+#define BCM_HAS_MII_RESOLVE_FLOWCTRL_FDX -+#define BCM_HAS_MII_ADVERTISE_FLOWCTRL -+#define BCM_HAS_MDIOBUS_ALLOC -+#define BCM_HAS_DMA_DATA_DIRECTION -+#define BCM_HAS_DMA_UNMAP_ADDR -+#define BCM_HAS_DMA_UNMAP_ADDR_SET -+#define BCM_HAS_DMA_ZALLOC_COHERENT -+#define BCM_HAS_IEEE1588_SUPPORT -+#define BCM_HAS_PCI_PMOPS_SHUTDOWN -+#define BCM_HAS_OLD_RXFH_INDIR -+#define BCM_HAS_PCI_CHANNEL_OFFLINE -+#define BCM_HAS_PCI_CHANNEL_IO_NORMAL_ENUM diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-cy8c3245-hwmon.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-cy8c3245-hwmon.patch deleted file mode 100644 index b8e955f9..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-cy8c3245-hwmon.patch +++ /dev/null @@ -1,1126 +0,0 @@ -Add a hwmon style driver for the CY8C3XX family - -diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig -index 0c248ec..7e7cdf6 100644 ---- a/drivers/hwmon/Kconfig -+++ b/drivers/hwmon/Kconfig -@@ -293,6 +293,17 @@ config SENSORS_ATXP1 - This driver can also be built as a module. If so, the module - will be called atxp1. - -+config SENSORS_CY8CXX -+ tristate "Cypress Semiconductor CY8Cxx" -+ depends on I2C -+ help -+ If you say yes here you get support for Cypress Semiconductor -+ CY8C series sensor chips. -+ -+ This driver can also be built as a module. If so, the module -+ will be called cy8cxx. -+ -+ - config SENSORS_DS620 - tristate "Dallas Semiconductor DS620" - depends on I2C -diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile -index 8251ce8..5e22567 100644 ---- a/drivers/hwmon/Makefile -+++ b/drivers/hwmon/Makefile -@@ -42,6 +42,7 @@ obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o - obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o - obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o - obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o -+obj-$(CONFIG_SENSORS_CY8CXX) += cy8cxx.o - obj-$(CONFIG_SENSORS_DME1737) += dme1737.o - obj-$(CONFIG_SENSORS_DS620) += ds620.o - obj-$(CONFIG_SENSORS_DS1621) += ds1621.o -diff --git a/drivers/hwmon/cy8cxx.c b/drivers/hwmon/cy8cxx.c -new file mode 100644 -index 0000000..3edfbe7 ---- /dev/null -+++ b/drivers/hwmon/cy8cxx.c -@@ -0,0 +1,1084 @@ -+/* -+ * A hwmon driver for the Cypress Semiconductor C3245 -+ * Copyright (C) 2013 Cumulus Networks -+ * -+ * Author: Shrijeet Mukherjee -+ * -+ * Based on the adt7470 driver -+ * -+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Addresses to scan */ -+static const unsigned short normal_i2c[] = { 0x2E, I2C_CLIENT_END }; -+ -+/* CY8C3XX registers */ -+#define CY8C3XX_REG_BASE_ADDR 0x00 -+#define CY8C3XX_REG_DEV_ID 0x04 -+#define CY8C3XX_REG_COMPANY_ID 0x05 -+#define CY8C3XX_REG_FW_REV_MAJ 0x06 -+#define CY8C3XX_REG_FW_REV_MIN 0x07 -+#define CY8C3XX_REG_RESET 0x08 -+ -+/* -+ * Fan PWM / RPM Profile control registers -+ * -+ * These registers consist of two-bytes each -+ */ -+#define CY8C3XX_REG_FAN_PROFILE_BASE_ADDR 0x10 -+#define CY8C3XX_REG_FAN_PROFILE(x) (CY8C3XX_REG_FAN_PROFILE_BASE_ADDR + ((x) * 2)) -+enum { -+ CY8C3XX_FAN_PROFILE_LOW_DUTY = 0, -+ CY8C3XX_FAN_PROFILE_LOW_RPM, -+ CY8C3XX_FAN_PROFILE_HIGH_DUTY, -+ CY8C3XX_FAN_PROFILE_HIGH_RPM, -+ CY8C3XX_FAN_PROFILE_SPEED_0_DUTY, -+ CY8C3XX_FAN_PROFILE_SPEED_100_DUTY, -+ CY8C3XX_FAN_PROFILE_MAX -+}; -+ -+/* skipping over regs to set */ -+ -+#define CY8C3XX_REG_TEMP_BASE_ADDR 0x30 -+ -+#define CY8C3XX_REG_FAN_BASE_ADDR 0x80 -+#define CY8C3XX_REG_FAN_TARGET_BASE_ADDR 0xA0 -+ -+#define CY8C3XX_REG_PWM_BASE_ADDR 0x60 -+ -+#define CY8C3XX_REG_PWM_MAX_BASE_ADDR 0x38 -+ -+#define CY8C3XX_REG_TEMP_LIMITS_BASE_ADDR 0x30 -+#define CY8C3XX_REG_TEMP_LIMITS_MAX_ADDR 0x40 -+ -+#define CY8C3XX_REG_FAN_MAX_BASE_ADDR 0x16 -+ -+#define CY8C3XX_REG_PWM_CFG_BASE_ADDR 0x55 -+ -+#define CY8C3XX_TEMP_COUNT 5 -+#define CY8C3XX_TEMP_REG(x) (CY8C3XX_REG_TEMP_BASE_ADDR + (x)) -+#define CY8C3XX_TEMP_MAX_REG(x) (CY8C3XX_REG_TEMP_LIMITS_MAX_ADDR + (x)) -+ -+#define CY8C3XX_FAN_COUNT 8 -+#define CY8C3XX_REG_FAN(x) (CY8C3XX_REG_FAN_BASE_ADDR + ((x) * 2)) -+ -+#define CY8C3XX_REG_FAN_MIN(x) (CY8C3XX_REG_FAN_MIN_BASE_ADDR + ((x) * 2)) -+#define CY8C3XX_REG_FAN_MAX(x) (CY8C3XX_REG_FAN_MAX_BASE_ADDR) -+#define CY8C3XX_REG_FAN_TARGET(x) (CY8C3XX_REG_FAN_TARGET_BASE_ADDR + \ -+ ((x) * 2)) -+ -+#define CY8C3XX_PWM_COUNT 8 -+#define CY8C3XX_REG_PWM(x) (CY8C3XX_REG_PWM_BASE_ADDR + ((x) * 2)) -+ -+#define CY8C3XX_COMPANY_ID 0xCC -+#define CY8C3XX_DEV_ID 0x02 -+#define CY8C3XX_FW_REV_MAJ 0x01 -+ -+/* "all temps" according to hwmon sysfs interface spec */ -+#define CY8C3XX_PWM_ALL_TEMPS 0x3FF -+ -+/* How often do we reread sensors values? (In jiffies) */ -+#define SENSOR_REFRESH_INTERVAL (5 * HZ) -+ -+/* How often do we reread sensor limit values? (In jiffies) */ -+#define LIMIT_REFRESH_INTERVAL (60 * HZ) -+ -+/* Wait at least 200ms per sensor for 10 sensors */ -+#define TEMP_COLLECTION_TIME 2000 -+ -+/* auto update thing won't fire more than every 2s */ -+#define AUTO_UPDATE_INTERVAL 2000 -+ -+/* datasheet says to divide this number by the fan reading to get fan rpm */ -+#define FAN_PERIOD_INVALID 65535 -+#define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) -+ -+struct cy8c3xx_data { -+ struct device *hwmon_dev; -+ struct attribute_group attrs; -+ struct mutex lock; -+ char sensors_valid; -+ char limits_valid; -+ unsigned long sensors_last_updated; /* In jiffies */ -+ unsigned long limits_last_updated; /* In jiffies */ -+ -+ int num_temp_sensors; /* -1 = probe */ -+ int temperatures_probed; -+ -+ s8 temp[CY8C3XX_TEMP_COUNT]; -+ s8 temp_max[CY8C3XX_TEMP_COUNT]; -+ u16 fan[CY8C3XX_FAN_COUNT]; -+ u16 fan_max[CY8C3XX_FAN_COUNT]; -+ u16 fan_min[CY8C3XX_FAN_COUNT]; -+ u16 fan_tgt[CY8C3XX_FAN_COUNT]; -+ u16 fan_profile[CY8C3XX_FAN_PROFILE_MAX]; -+ u8 fan_alarm; -+ u8 temp_alarm; -+ u8 force_pwm_max; -+ u8 pwm[CY8C3XX_PWM_COUNT]; -+ u8 pwm_automatic; -+ struct task_struct *auto_update; -+ struct completion auto_update_stop; -+ unsigned int auto_update_interval; -+}; -+ -+static int cy8c3xx_probe(struct i2c_client *client, -+ const struct i2c_device_id *id); -+static int cy8c3xx_detect(struct i2c_client *client, -+ struct i2c_board_info *info); -+static int cy8c3xx_remove(struct i2c_client *client); -+ -+static const struct i2c_device_id cy8c3xx_id[] = { -+ { "CY8C3245", 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, cy8c3xx_id); -+ -+static struct i2c_driver cy8c3xx_driver = { -+ .class = I2C_CLASS_HWMON, -+ .driver = { -+ .name = "cy8c3xx", -+ }, -+ .probe = cy8c3xx_probe, -+ .remove = cy8c3xx_remove, -+ .id_table = cy8c3xx_id, -+ .detect = cy8c3xx_detect, -+ .address_list = normal_i2c, -+}; -+ -+/* -+ * 16-bit registers on the CY8C3XX are high-byte first. -+ */ -+static inline int cy8c3xx_read_word_data(struct i2c_client *client, u8 reg) -+{ -+ s32 rc; -+ u16 val; -+ -+ /* read high byte */ -+ rc = i2c_smbus_read_byte_data(client, reg); -+ if (rc < 0) { -+ dev_warn(&client->dev, "i2c read failed: 0x%02x, errno %d\n", -+ reg, -rc); -+ return rc; -+ } -+ val = ((u16)rc & 0xFF) << 8; -+ -+ /* read low byte */ -+ rc = i2c_smbus_read_byte_data(client, reg + 1); -+ if (rc < 0) { -+ dev_warn(&client->dev, "i2c read failed: 0x%02x, errno %d\n", -+ reg + 1, -rc); -+ return rc; -+ } -+ val |= (u16)rc & 0xFF; -+ -+ return val; -+} -+ -+static inline int cy8c3xx_write_word_data(struct i2c_client *client, -+ u8 reg, -+ u16 value) -+{ -+ s32 rc; -+ -+ /* write high byte */ -+ rc = i2c_smbus_write_byte_data(client, reg, value >> 8); -+ if (rc < 0) { -+ dev_warn(&client->dev, -+ "i2c write failed: 0x%02x: 0x%02x, errno %d\n", -+ reg, value >> 8, -rc); -+ return rc; -+ } -+ -+ /* write low byte */ -+ rc = i2c_smbus_write_byte_data(client, reg + 1, value & 0xFF); -+ if (rc < 0) { -+ dev_warn(&client->dev, -+ "i2c write failed: 0x%02x: 0x%02x, errno %d\n", -+ reg + 1, value & 0xFF, -rc); -+ return rc; -+ } -+ -+ return rc; -+} -+ -+/* Probe for temperature sensors. Assumes lock is held */ -+static int cy8c3xx_read_temperatures(struct i2c_client *client, -+ struct cy8c3xx_data *data) -+{ -+ int i; -+ -+ /* Only count fans if we have to */ -+ if (data->num_temp_sensors >= 0) -+ return 0; -+ -+ for (i = 0; i < CY8C3XX_TEMP_COUNT; i++) { -+ data->temp[i] = i2c_smbus_read_byte_data(client, -+ CY8C3XX_TEMP_REG(i)); -+ if (data->temp[i]) -+ data->num_temp_sensors = i + 1; -+ } -+ data->temperatures_probed = 1; -+ return 0; -+} -+ -+static int cy8c3xx_update_thread(void *p) -+{ -+ struct i2c_client *client = p; -+ struct cy8c3xx_data *data = i2c_get_clientdata(client); -+ -+ while (!kthread_should_stop()) { -+ mutex_lock(&data->lock); -+ cy8c3xx_read_temperatures(client, data); -+ mutex_unlock(&data->lock); -+ if (kthread_should_stop()) -+ break; -+ msleep_interruptible(data->auto_update_interval); -+ } -+ -+ complete_all(&data->auto_update_stop); -+ return 0; -+} -+ -+static struct cy8c3xx_data *cy8c3xx_update_device(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3xx_data *data = i2c_get_clientdata(client); -+ unsigned long local_jiffies = jiffies; -+ int i; -+ int need_sensors = 1; -+ int need_limits = 1; -+ -+ /* -+ * Figure out if we need to update the shadow registers. -+ * Lockless means that we may occasionally report out of -+ * date data. -+ */ -+ if (time_before(local_jiffies, data->sensors_last_updated + -+ SENSOR_REFRESH_INTERVAL) && -+ data->sensors_valid) -+ need_sensors = 0; -+ -+ if (time_before(local_jiffies, data->limits_last_updated + -+ LIMIT_REFRESH_INTERVAL) && -+ data->limits_valid) -+ need_limits = 0; -+ -+ if (!need_sensors && !need_limits) -+ return data; -+ -+ mutex_lock(&data->lock); -+ if (!need_sensors) -+ goto no_sensor_update; -+ -+ if (!data->temperatures_probed) -+ cy8c3xx_read_temperatures(client, data); -+ else -+ for (i = 0; i < CY8C3XX_TEMP_COUNT; i++) -+ data->temp[i] = i2c_smbus_read_byte_data(client, -+ CY8C3XX_TEMP_REG(i)); -+ -+ for (i = 0; i < CY8C3XX_FAN_COUNT; i++) { -+ data->fan[i] = cy8c3xx_read_word_data(client, -+ CY8C3XX_REG_FAN(i)); -+ } -+ -+ for (i = 0; i < CY8C3XX_PWM_COUNT; i++) { -+ data->pwm[i] = i2c_smbus_read_byte_data(client, -+ CY8C3XX_REG_PWM(i)); -+ } -+ -+ data->sensors_last_updated = local_jiffies; -+ data->sensors_valid = 1; -+ -+no_sensor_update: -+ if (!need_limits) -+ goto out; -+ -+ for (i = 0; i < CY8C3XX_TEMP_COUNT; i++) { -+ data->temp_max[i] = i2c_smbus_read_byte_data(client, -+ CY8C3XX_TEMP_MAX_REG(i)); -+ } -+ -+ for (i = 0; i < CY8C3XX_FAN_COUNT; i++) { -+ data->fan_max[i] = cy8c3xx_read_word_data(client, -+ CY8C3XX_REG_FAN_MAX(i)); -+ data->fan_tgt[i] = cy8c3xx_read_word_data(client, -+ CY8C3XX_REG_FAN_TARGET(i)); -+ } -+ -+ for (i = 0; i < CY8C3XX_FAN_PROFILE_MAX; i++) { -+ data->fan_profile[i] = cy8c3xx_read_word_data(client, -+ CY8C3XX_REG_FAN_PROFILE(i)); -+ } -+ -+ data->limits_last_updated = local_jiffies; -+ data->limits_valid = 1; -+ -+out: -+ mutex_unlock(&data->lock); -+ return data; -+} -+ -+static ssize_t show_auto_update_interval(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ return sprintf(buf, "%d\n", data->auto_update_interval); -+} -+ -+static ssize_t set_auto_update_interval(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, -+ size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3xx_data *data = i2c_get_clientdata(client); -+ long temp; -+ -+ if (strict_strtol(buf, 10, &temp)) -+ return -EINVAL; -+ -+ temp = SENSORS_LIMIT(temp, 0, 60000); -+ -+ mutex_lock(&data->lock); -+ data->auto_update_interval = temp; -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+static ssize_t show_num_temp_sensors(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ return sprintf(buf, "%d\n", data->num_temp_sensors); -+} -+ -+static ssize_t set_num_temp_sensors(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, -+ size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3xx_data *data = i2c_get_clientdata(client); -+ long temp; -+ -+ if (strict_strtol(buf, 10, &temp)) -+ return -EINVAL; -+ -+ temp = SENSORS_LIMIT(temp, -1, 10); -+ -+ mutex_lock(&data->lock); -+ data->num_temp_sensors = temp; -+ if (temp < 0) -+ data->temperatures_probed = 0; -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+static ssize_t show_temp_max(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ return sprintf(buf, "%d\n", 1000 * data->temp_max[attr->index]); -+} -+ -+static ssize_t set_temp_max(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, -+ size_t count) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3xx_data *data = i2c_get_clientdata(client); -+ long temp; -+ -+ if (strict_strtol(buf, 10, &temp)) -+ return -EINVAL; -+ -+ temp = DIV_ROUND_CLOSEST(temp, 1000); -+ temp = SENSORS_LIMIT(temp, -128, 127); -+ -+ mutex_lock(&data->lock); -+ data->temp_max[attr->index] = temp; -+ i2c_smbus_write_byte_data(client, CY8C3XX_TEMP_MAX_REG(attr->index), -+ temp); -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ return sprintf(buf, "%d\n", 1000 * data->temp[attr->index]); -+} -+ -+static ssize_t show_fan_max(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ -+ if (FAN_DATA_VALID(data->fan_max[attr->index])) -+ return sprintf(buf, "%d\n", -+ data->fan_max[attr->index]); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t set_fan_max(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, size_t count) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3xx_data *data = i2c_get_clientdata(client); -+ long rpm; -+ -+ if (strict_strtol(buf, 10, &rpm) || !rpm) -+ return -EINVAL; -+ -+ rpm = SENSORS_LIMIT(rpm, 1, 65534); -+ -+ mutex_lock(&data->lock); -+ data->fan_max[attr->index] = rpm; -+ cy8c3xx_write_word_data(client, CY8C3XX_REG_FAN_MAX(attr->index), rpm); -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+/* -+ * fan_min is a pure software concept, not implemented by hardware. -+ * It is used to compute the alarm status. -+ */ -+static ssize_t show_fan_min(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ -+ return sprintf(buf, "%d\n", data->fan_min[attr->index]); -+} -+ -+static ssize_t set_fan_min(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, size_t count) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3xx_data *data = i2c_get_clientdata(client); -+ long rpm; -+ -+ if (strict_strtol(buf, 10, &rpm) || !rpm) -+ return -EINVAL; -+ -+ rpm = SENSORS_LIMIT(rpm, 1, 65534); -+ -+ mutex_lock(&data->lock); -+ data->fan_min[attr->index] = rpm; -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+static ssize_t show_fan_target(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ -+ if (FAN_DATA_VALID(data->fan_tgt[attr->index])) -+ return sprintf(buf, "%d\n", -+ data->fan_tgt[attr->index]); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t set_fan_target(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, size_t count) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3xx_data *data = i2c_get_clientdata(client); -+ long rpm; -+ -+ if (strict_strtol(buf, 10, &rpm) || !rpm) -+ return -EINVAL; -+ -+ rpm = SENSORS_LIMIT(rpm, 1, 65534); -+ -+ mutex_lock(&data->lock); -+ data->fan_tgt[attr->index] = rpm; -+ cy8c3xx_write_word_data(client, CY8C3XX_REG_FAN_TARGET(attr->index), rpm); -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+/* -+ * Show Fan Profile Settings -+ */ -+static ssize_t show_fan_profile(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ -+ return sprintf(buf, "%u\n", -+ data->fan_profile[attr->index]); -+} -+ -+/* -+ * Set Fan Profile Settings -+ */ -+static ssize_t set_fan_profile(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, size_t count) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3xx_data *data = i2c_get_clientdata(client); -+ long parm; -+ -+ if (strict_strtoul(buf, 10, &parm)) -+ return -EINVAL; -+ -+ parm = SENSORS_LIMIT(parm, 1, 65534); -+ -+ mutex_lock(&data->lock); -+ data->fan_profile[attr->index] = parm; -+ cy8c3xx_write_word_data(client, CY8C3XX_REG_FAN_PROFILE(attr->index), parm); -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ -+ if (FAN_DATA_VALID(data->fan[attr->index])) -+ return sprintf(buf, "%d\n", data->fan[attr->index]); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ return sprintf(buf, "%d\n", data->pwm[attr->index]); -+} -+ -+static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, -+ const char *buf, size_t count) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3xx_data *data = i2c_get_clientdata(client); -+ long temp; -+ -+ if (strict_strtol(buf, 10, &temp)) -+ return -EINVAL; -+ -+ temp = SENSORS_LIMIT(temp, 0, 255); -+ -+ mutex_lock(&data->lock); -+ data->pwm[attr->index] = temp; -+ i2c_smbus_write_byte_data(client, CY8C3XX_REG_PWM(attr->index), temp); -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+static ssize_t show_fan_alarm_mask(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ int i; -+ u32 alarm_mask = 0; -+ -+ for (i = 0; i < CY8C3XX_FAN_COUNT; i++) -+ if ((data->fan[i] < data->fan_min[i]) || -+ (data->fan[i] >= data->fan_max[i])) -+ alarm_mask |= 0x1 << i; -+ -+ return sprintf(buf, "%x\n", alarm_mask); -+} -+ -+static ssize_t show_temp_alarm_mask(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ int i; -+ u32 alarm_mask = 0; -+ -+ for (i = 0; i < CY8C3XX_TEMP_COUNT; i++) -+ if (data->temp[i] >= data->temp_max[i]) -+ alarm_mask |= 0x1 << i; -+ -+ return sprintf(buf, "%x\n", alarm_mask); -+} -+ -+static ssize_t show_fan_alarm(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ -+ if ((data->fan[attr->index] < data->fan_min[attr->index]) || -+ (data->fan[attr->index] >= data->fan_max[attr->index])) -+ return sprintf(buf, "1\n"); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t show_temp_alarm(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ -+ if (data->temp[attr->index] >= data->temp_max[attr->index]) -+ return sprintf(buf, "1\n"); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t set_pwm_auto(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, -+ size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3xx_data *data = i2c_get_clientdata(client); -+ long temp; -+ -+ if (strict_strtol(buf, 10, &temp)) -+ return -EINVAL; -+ -+ if (!(temp > 0 && temp < 3)) -+ return -EINVAL; -+ -+ mutex_lock(&data->lock); -+ data->pwm_automatic = temp; -+ i2c_smbus_write_byte_data(client, CY8C3XX_REG_PWM_CFG_BASE_ADDR, temp); -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+static ssize_t show_pwm_auto(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct cy8c3xx_data *data = cy8c3xx_update_device(dev); -+ -+ return sprintf(buf, "%d\n", data->pwm_automatic); -+} -+ -+#define CY8C3XX_REG_MIN 0x00 -+#define CY8C3XX_REG_MAX 0xe0 -+ -+static ssize_t show_debug(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ -+ int len = 0, i, j; -+ u8 val; -+ for (i = 0; i < (CY8C3XX_REG_MAX - CY8C3XX_REG_MIN) / 16; i++) { -+ len += sprintf(buf+len, "0x%02x: ", CY8C3XX_REG_MIN + (i * 16)); -+ for (j = 0; j < 16; j++) { -+ val = i2c_smbus_read_byte_data(client, CY8C3XX_REG_MIN + (i * 16) + j); -+ len += sprintf(buf+len, "%02x ", val); -+ } -+ len += sprintf(buf+len, "\n"); -+ } -+ return len; -+} -+ -+static DEVICE_ATTR(fan_alarm_mask, S_IRUGO, show_fan_alarm_mask, NULL); -+static DEVICE_ATTR(temp_alarm_mask, S_IRUGO, show_temp_alarm_mask, NULL); -+static DEVICE_ATTR(num_temp_sensors, S_IWUSR | S_IRUGO, show_num_temp_sensors, -+ set_num_temp_sensors); -+static DEVICE_ATTR(auto_update_interval, S_IWUSR | S_IRUGO, -+ show_auto_update_interval, set_auto_update_interval); -+ -+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, -+ set_temp_max, 0); -+static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, -+ set_temp_max, 1); -+static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max, -+ set_temp_max, 2); -+static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp_max, -+ set_temp_max, 3); -+static SENSOR_DEVICE_ATTR(temp5_max, S_IWUSR | S_IRUGO, show_temp_max, -+ set_temp_max, 4); -+ -+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); -+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); -+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); -+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); -+static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp, NULL, 4); -+ -+static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0); -+static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1); -+static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2); -+static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_temp_alarm, NULL, 3); -+static SENSOR_DEVICE_ATTR(temp5_alarm, S_IRUGO, show_temp_alarm, NULL, 4); -+ -+static SENSOR_DEVICE_ATTR(fan1_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 0); -+static SENSOR_DEVICE_ATTR(fan2_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 1); -+static SENSOR_DEVICE_ATTR(fan3_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 2); -+static SENSOR_DEVICE_ATTR(fan4_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 3); -+static SENSOR_DEVICE_ATTR(fan5_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 4); -+static SENSOR_DEVICE_ATTR(fan6_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 5); -+static SENSOR_DEVICE_ATTR(fan7_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 6); -+static SENSOR_DEVICE_ATTR(fan8_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 7); -+ -+static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 0); -+static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 1); -+static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 2); -+static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 3); -+static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 4); -+static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 5); -+static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 6); -+static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 7); -+ -+static SENSOR_DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 0); -+static SENSOR_DEVICE_ATTR(fan2_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 1); -+static SENSOR_DEVICE_ATTR(fan3_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 2); -+static SENSOR_DEVICE_ATTR(fan4_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 3); -+static SENSOR_DEVICE_ATTR(fan5_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 4); -+static SENSOR_DEVICE_ATTR(fan6_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 5); -+static SENSOR_DEVICE_ATTR(fan7_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 6); -+static SENSOR_DEVICE_ATTR(fan8_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 7); -+ -+#define FAN_PROFILE_ATTR(_name, _index) \ -+ SENSOR_DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, \ -+ show_fan_profile, set_fan_profile, _index) -+ -+static FAN_PROFILE_ATTR(fan_low_duty, CY8C3XX_FAN_PROFILE_LOW_DUTY); -+static FAN_PROFILE_ATTR(fan_low_rpm, CY8C3XX_FAN_PROFILE_LOW_RPM); -+static FAN_PROFILE_ATTR(fan_high_duty, CY8C3XX_FAN_PROFILE_HIGH_DUTY); -+static FAN_PROFILE_ATTR(fan_high_rpm, CY8C3XX_FAN_PROFILE_HIGH_RPM); -+static FAN_PROFILE_ATTR(fan_speed_0_duty, CY8C3XX_FAN_PROFILE_SPEED_0_DUTY); -+static FAN_PROFILE_ATTR(fan_speed_100_duty,CY8C3XX_FAN_PROFILE_SPEED_100_DUTY); -+ -+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); -+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); -+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); -+static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); -+static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4); -+static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5); -+static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6); -+static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7); -+ -+static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0); -+static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1); -+static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2); -+static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3); -+static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_fan_alarm, NULL, 4); -+static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_fan_alarm, NULL, 5); -+static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_fan_alarm, NULL, 6); -+static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_fan_alarm, NULL, 7); -+ -+static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); -+static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); -+static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); -+static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); -+static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 4); -+static SENSOR_DEVICE_ATTR(pwm6, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 5); -+static SENSOR_DEVICE_ATTR(pwm7, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 6); -+static SENSOR_DEVICE_ATTR(pwm8, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 7); -+ -+static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm6_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm7_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm8_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+ -+static SENSOR_DEVICE_ATTR(debug, S_IRUGO, show_debug, NULL, 0); -+ -+static struct attribute *cy8c3xx_attr[] = -+{ -+ &dev_attr_fan_alarm_mask.attr, -+ &dev_attr_temp_alarm_mask.attr, -+ &dev_attr_num_temp_sensors.attr, -+ &dev_attr_auto_update_interval.attr, -+ &sensor_dev_attr_temp1_max.dev_attr.attr, -+ &sensor_dev_attr_temp2_max.dev_attr.attr, -+ &sensor_dev_attr_temp3_max.dev_attr.attr, -+ &sensor_dev_attr_temp4_max.dev_attr.attr, -+ &sensor_dev_attr_temp5_max.dev_attr.attr, -+ &sensor_dev_attr_temp1_input.dev_attr.attr, -+ &sensor_dev_attr_temp2_input.dev_attr.attr, -+ &sensor_dev_attr_temp3_input.dev_attr.attr, -+ &sensor_dev_attr_temp4_input.dev_attr.attr, -+ &sensor_dev_attr_temp5_input.dev_attr.attr, -+ &sensor_dev_attr_temp1_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp2_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp3_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp4_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp5_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan1_max.dev_attr.attr, -+ &sensor_dev_attr_fan2_max.dev_attr.attr, -+ &sensor_dev_attr_fan3_max.dev_attr.attr, -+ &sensor_dev_attr_fan4_max.dev_attr.attr, -+ &sensor_dev_attr_fan5_max.dev_attr.attr, -+ &sensor_dev_attr_fan6_max.dev_attr.attr, -+ &sensor_dev_attr_fan7_max.dev_attr.attr, -+ &sensor_dev_attr_fan8_max.dev_attr.attr, -+ &sensor_dev_attr_fan1_min.dev_attr.attr, -+ &sensor_dev_attr_fan2_min.dev_attr.attr, -+ &sensor_dev_attr_fan3_min.dev_attr.attr, -+ &sensor_dev_attr_fan4_min.dev_attr.attr, -+ &sensor_dev_attr_fan5_min.dev_attr.attr, -+ &sensor_dev_attr_fan6_min.dev_attr.attr, -+ &sensor_dev_attr_fan7_min.dev_attr.attr, -+ &sensor_dev_attr_fan8_min.dev_attr.attr, -+ &sensor_dev_attr_fan1_target.dev_attr.attr, -+ &sensor_dev_attr_fan2_target.dev_attr.attr, -+ &sensor_dev_attr_fan3_target.dev_attr.attr, -+ &sensor_dev_attr_fan4_target.dev_attr.attr, -+ &sensor_dev_attr_fan5_target.dev_attr.attr, -+ &sensor_dev_attr_fan6_target.dev_attr.attr, -+ &sensor_dev_attr_fan7_target.dev_attr.attr, -+ &sensor_dev_attr_fan8_target.dev_attr.attr, -+ &sensor_dev_attr_fan1_input.dev_attr.attr, -+ &sensor_dev_attr_fan2_input.dev_attr.attr, -+ &sensor_dev_attr_fan3_input.dev_attr.attr, -+ &sensor_dev_attr_fan4_input.dev_attr.attr, -+ &sensor_dev_attr_fan5_input.dev_attr.attr, -+ &sensor_dev_attr_fan6_input.dev_attr.attr, -+ &sensor_dev_attr_fan7_input.dev_attr.attr, -+ &sensor_dev_attr_fan8_input.dev_attr.attr, -+ &sensor_dev_attr_fan1_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan2_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan3_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan4_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan5_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan6_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan7_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan8_alarm.dev_attr.attr, -+ &sensor_dev_attr_pwm1.dev_attr.attr, -+ &sensor_dev_attr_pwm2.dev_attr.attr, -+ &sensor_dev_attr_pwm3.dev_attr.attr, -+ &sensor_dev_attr_pwm4.dev_attr.attr, -+ &sensor_dev_attr_pwm5.dev_attr.attr, -+ &sensor_dev_attr_pwm6.dev_attr.attr, -+ &sensor_dev_attr_pwm7.dev_attr.attr, -+ &sensor_dev_attr_pwm8.dev_attr.attr, -+ &sensor_dev_attr_pwm1_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm2_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm3_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm4_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm5_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm6_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm7_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm8_enable.dev_attr.attr, -+ &sensor_dev_attr_fan_low_duty.dev_attr.attr, -+ &sensor_dev_attr_fan_low_rpm.dev_attr.attr, -+ &sensor_dev_attr_fan_high_duty.dev_attr.attr, -+ &sensor_dev_attr_fan_high_rpm.dev_attr.attr, -+ &sensor_dev_attr_fan_speed_0_duty.dev_attr.attr, -+ &sensor_dev_attr_fan_speed_100_duty.dev_attr.attr, -+ &sensor_dev_attr_debug.dev_attr.attr, -+ NULL -+}; -+ -+/* Return 0 if detection is successful, -ENODEV otherwise */ -+static int cy8c3xx_detect(struct i2c_client *client, -+ struct i2c_board_info *info) -+{ -+ struct i2c_adapter *adapter = client->adapter; -+ int vendor, device, revision; -+ -+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) -+ return -ENODEV; -+ -+ vendor = i2c_smbus_read_byte_data(client, CY8C3XX_REG_COMPANY_ID); -+ printk(KERN_INFO "vendor = %u\n", vendor); -+ if (vendor != CY8C3XX_COMPANY_ID) -+ return -ENODEV; -+ -+ device = i2c_smbus_read_byte_data(client, CY8C3XX_REG_DEV_ID); -+ printk(KERN_INFO "device = %u\n", device); -+ if (device != CY8C3XX_DEV_ID) -+ return -ENODEV; -+ -+ revision = i2c_smbus_read_byte_data(client, CY8C3XX_REG_FW_REV_MAJ); -+ printk(KERN_INFO "rev = %u\n", revision); -+ if (revision != CY8C3XX_FW_REV_MAJ) -+ return -ENODEV; -+ -+ strlcpy(info->type, "cy8c3xx", I2C_NAME_SIZE); -+ -+ printk(KERN_INFO "cy8c3xx detected\n"); -+ return 0; -+} -+ -+static int cy8c3xx_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct cy8c3xx_data *data; -+ int err; -+ -+ data = kzalloc(sizeof(struct cy8c3xx_data), GFP_KERNEL); -+ if (!data) { -+ err = -ENOMEM; -+ goto exit; -+ } -+ -+ data->num_temp_sensors = -1; -+ data->auto_update_interval = AUTO_UPDATE_INTERVAL; -+ -+ i2c_set_clientdata(client, data); -+ mutex_init(&data->lock); -+ -+ dev_info(&client->dev, "%s chip found\n", client->name); -+ -+ /* Register sysfs hooks */ -+ data->attrs.attrs = cy8c3xx_attr; -+ if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) -+ goto exit_free; -+ -+ data->hwmon_dev = hwmon_device_register(&client->dev); -+ if (IS_ERR(data->hwmon_dev)) { -+ err = PTR_ERR(data->hwmon_dev); -+ goto exit_remove; -+ } -+ -+ init_completion(&data->auto_update_stop); -+ data->auto_update = kthread_run(cy8c3xx_update_thread, client, -+ dev_name(data->hwmon_dev)); -+ if (IS_ERR(data->auto_update)) { -+ err = PTR_ERR(data->auto_update); -+ goto exit_unregister; -+ } -+ -+ return 0; -+ -+exit_unregister: -+ hwmon_device_unregister(data->hwmon_dev); -+exit_remove: -+ sysfs_remove_group(&client->dev.kobj, &data->attrs); -+exit_free: -+ kfree(data); -+exit: -+ return err; -+} -+ -+static int cy8c3xx_remove(struct i2c_client *client) -+{ -+ struct cy8c3xx_data *data = i2c_get_clientdata(client); -+ -+ kthread_stop(data->auto_update); -+ wait_for_completion(&data->auto_update_stop); -+ hwmon_device_unregister(data->hwmon_dev); -+ sysfs_remove_group(&client->dev.kobj, &data->attrs); -+ kfree(data); -+ return 0; -+} -+ -+static int __init cy8c3xx_init(void) -+{ -+ return i2c_add_driver(&cy8c3xx_driver); -+} -+ -+static void __exit cy8c3xx_exit(void) -+{ -+ i2c_del_driver(&cy8c3xx_driver); -+} -+ -+MODULE_AUTHOR("Shrijeet Mukherjee "); -+MODULE_DESCRIPTION("CY8C3XX driver"); -+MODULE_LICENSE("GPL"); -+ -+module_init(cy8c3xx_init); -+module_exit(cy8c3xx_exit); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-cy8c3245r1-hwmon.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-cy8c3245r1-hwmon.patch deleted file mode 100644 index 7009f35c..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-cy8c3245r1-hwmon.patch +++ /dev/null @@ -1,1127 +0,0 @@ -Driver for updated PSoc CY8C3245 on Quanta LY6 - -diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig -index 7e7cdf6..fe87335 100644 ---- a/drivers/hwmon/Kconfig -+++ b/drivers/hwmon/Kconfig -@@ -303,6 +303,15 @@ config SENSORS_CY8CXX - This driver can also be built as a module. If so, the module - will be called cy8cxx. - -+config SENSORS_CY8C3245R1 -+ tristate "Cypress Semiconductor CY8C3245R1" -+ depends on I2C -+ help -+ If you say yes here you get support for Cypress Semiconductor -+ CY8C3245 first revision sensor chips. -+ -+ This driver can also be built as a module. If so, the module -+ will be called cy8c3245r1. - - config SENSORS_DS620 - tristate "Dallas Semiconductor DS620" -diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile -index 5e22567..cf7f0b8 100644 ---- a/drivers/hwmon/Makefile -+++ b/drivers/hwmon/Makefile -@@ -43,6 +43,7 @@ obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o - obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o - obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o - obj-$(CONFIG_SENSORS_CY8CXX) += cy8cxx.o -+obj-$(CONFIG_SENSORS_CY8C3245R1) += cy8c3245r1.o - obj-$(CONFIG_SENSORS_DME1737) += dme1737.o - obj-$(CONFIG_SENSORS_DS620) += ds620.o - obj-$(CONFIG_SENSORS_DS1621) += ds1621.o -diff --git a/drivers/hwmon/cy8c3245r1.c b/drivers/hwmon/cy8c3245r1.c -new file mode 100644 -index 0000000..0f4f4d1 ---- /dev/null -+++ b/drivers/hwmon/cy8c3245r1.c -@@ -0,0 +1,1087 @@ -+/* -+ * A hwmon driver for the Cypress Semiconductor C3245 -+ * Copyright (C) 2014 Cumulus Networks -+ * -+ * Author: Shrijeet Mukherjee -+ * Author: Vidya Ravipati -+ * -+ * Based on the adt7470 driver -+ * -+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* cy8c3245r1 registers */ -+#define CY8C3245R1_REG_BASE_ADDR 0x00 -+#define CY8C3245R1_REG_DEV_ID 0x09 -+#define CY8C3245R1_REG_COMPANY_ID 0x05 -+#define CY8C3245R1_REG_FW_REV_MAJ 0x06 -+#define CY8C3245R1_REG_FW_REV_MIN 0x07 -+#define CY8C3245R1_REG_RESET 0x08 -+ -+/* -+ * Fan PWM / RPM Profile control registers -+ * -+ * These registers consist of two-bytes each -+ */ -+#define CY8C3245R1_REG_FAN_PROFILE_BASE_ADDR 0x10 -+#define CY8C3245R1_REG_FAN_PROFILE(x) (CY8C3245R1_REG_FAN_PROFILE_BASE_ADDR + ((x) * 2)) -+enum { -+ CY8C3245R1_FAN_PROFILE_LOW_DUTY = 0, -+ CY8C3245R1_FAN_PROFILE_LOW_RPM, -+ CY8C3245R1_FAN_PROFILE_HIGH_DUTY, -+ CY8C3245R1_FAN_PROFILE_HIGH_RPM, -+ CY8C3245R1_FAN_PROFILE_SPEED_0_DUTY, -+ CY8C3245R1_FAN_PROFILE_SPEED_100_DUTY, -+ CY8C3245R1_FAN_PROFILE_MAX -+}; -+ -+/* skipping over regs to set */ -+ -+#define CY8C3245R1_REG_TEMP_BASE_ADDR 0x20 -+ -+#define CY8C3245R1_REG_FAN_BASE_ADDR 0x40 -+#define CY8C3245R1_REG_FAN_TARGET_BASE_ADDR 0x3E -+ -+#define CY8C3245R1_REG_PWM_BASE_ADDR 0x3C -+ -+#define CY8C3245R1_REG_TEMP_LIMITS_BASE_ADDR 0x20 -+#define CY8C3245R1_REG_TEMP_LIMITS_MAX_ADDR 0x28 -+ -+#define CY8C3245R1_REG_FAN_MAX_BASE_ADDR 0x16 -+ -+#define CY8C3245R1_REG_PWM_CFG_BASE_ADDR 0x33 -+ -+#define CY8C3245R1_TEMP_COUNT 8 -+#define CY8C3245R1_TEMP_REG(x) (CY8C3245R1_REG_TEMP_BASE_ADDR + (x)) -+#define CY8C3245R1_TEMP_MAX_REG(x) (CY8C3245R1_REG_TEMP_LIMITS_MAX_ADDR + (x)) -+ -+#define CY8C3245R1_FAN_COUNT 8 -+#define CY8C3245R1_REG_FAN(x) (CY8C3245R1_REG_FAN_BASE_ADDR + ((x) * 2)) -+ -+#define CY8C3245R1_REG_FAN_MIN(x) (CY8C3245R1_REG_FAN_MIN_BASE_ADDR + ((x) * 2)) -+#define CY8C3245R1_REG_FAN_MAX(x) (CY8C3245R1_REG_FAN_MAX_BASE_ADDR) -+#define CY8C3245R1_REG_FAN_TARGET (CY8C3245R1_REG_FAN_TARGET_BASE_ADDR) -+ -+#define CY8C3245R1_PWM_COUNT 1 -+#define CY8C3245R1_REG_PWM (CY8C3245R1_REG_PWM_BASE_ADDR) -+ -+#define CY8C3245R1_COMPANY_ID 0xCC -+#define CY8C3245R1_DEV_ID 0x09 -+#define CY8C3245R1_FW_REV_MAJ 0x02 -+#define CY8C3245R1_FW_REV_MIN 0x03 -+ -+/* "all temps" according to hwmon sysfs interface spec */ -+#define CY8C3245R1_PWM_ALL_TEMPS 0x3FF -+ -+/* How often do we reread sensors values? (In jiffies) */ -+#define SENSOR_REFRESH_INTERVAL (5 * HZ) -+ -+/* How often do we reread sensor limit values? (In jiffies) */ -+#define LIMIT_REFRESH_INTERVAL (60 * HZ) -+ -+/* Wait at least 200ms per sensor for 10 sensors */ -+#define TEMP_COLLECTION_TIME 2000 -+ -+/* auto update thing won't fire more than every 2s */ -+#define AUTO_UPDATE_INTERVAL 2000 -+ -+/* datasheet says to divide this number by the fan reading to get fan rpm */ -+#define FAN_PERIOD_INVALID 65535 -+#define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) -+ -+struct cy8c3245r1_data { -+ struct device *hwmon_dev; -+ struct attribute_group attrs; -+ struct mutex lock; -+ char sensors_valid; -+ char limits_valid; -+ unsigned long sensors_last_updated; /* In jiffies */ -+ unsigned long limits_last_updated; /* In jiffies */ -+ -+ int num_temp_sensors; /* -1 = probe */ -+ int temperatures_probed; -+ -+ s8 temp[CY8C3245R1_TEMP_COUNT]; -+ s8 temp_max[CY8C3245R1_TEMP_COUNT]; -+ u16 fan[CY8C3245R1_FAN_COUNT]; -+ u16 fan_max[CY8C3245R1_FAN_COUNT]; -+ u16 fan_min[CY8C3245R1_FAN_COUNT]; -+ u16 fan_tgt; -+ u16 fan_profile[CY8C3245R1_FAN_PROFILE_MAX]; -+ u8 fan_alarm; -+ u8 temp_alarm; -+ u8 force_pwm_max; -+ u8 pwm; -+ u8 pwm_automatic; -+ struct task_struct *auto_update; -+ struct completion auto_update_stop; -+ unsigned int auto_update_interval; -+}; -+ -+static int cy8c3245r1_probe(struct i2c_client *client, -+ const struct i2c_device_id *id); -+static int cy8c3245r1_remove(struct i2c_client *client); -+ -+static const struct i2c_device_id cy8c3245r1_id[] = { -+ { "CY8C3245R1", 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, cy8c3245r1_id); -+ -+static struct i2c_driver cy8c3245r1_driver = { -+ .class = I2C_CLASS_HWMON, -+ .driver = { -+ .name = "cy8c3245r1", -+ }, -+ .probe = cy8c3245r1_probe, -+ .remove = cy8c3245r1_remove, -+ .id_table = cy8c3245r1_id, -+}; -+ -+/* -+ * 16-bit registers on the CY8C3245R1 are high-byte first. -+ */ -+static inline int cy8c3245r1_read_word_data(struct i2c_client *client, u8 reg) -+{ -+ s32 rc; -+ u16 val; -+ -+ /* read high byte */ -+ rc = i2c_smbus_read_byte_data(client, reg); -+ if (rc < 0) { -+ dev_warn(&client->dev, "i2c read failed: 0x%02x, errno %d\n", -+ reg, -rc); -+ return rc; -+ } -+ val = ((u16)rc & 0xFF) << 8; -+ -+ /* read low byte */ -+ rc = i2c_smbus_read_byte_data(client, reg + 1); -+ if (rc < 0) { -+ dev_warn(&client->dev, "i2c read failed: 0x%02x, errno %d\n", -+ reg + 1, -rc); -+ return rc; -+ } -+ val |= (u16)rc & 0xFF; -+ -+ return val; -+} -+ -+static inline int cy8c3245r1_write_word_data(struct i2c_client *client, -+ u8 reg, -+ u16 value) -+{ -+ s32 rc; -+ -+ /* write high byte */ -+ rc = i2c_smbus_write_byte_data(client, reg, value >> 8); -+ if (rc < 0) { -+ dev_warn(&client->dev, -+ "i2c write failed: 0x%02x: 0x%02x, errno %d\n", -+ reg, value >> 8, -rc); -+ return rc; -+ } -+ -+ /* write low byte */ -+ rc = i2c_smbus_write_byte_data(client, reg + 1, value & 0xFF); -+ if (rc < 0) { -+ dev_warn(&client->dev, -+ "i2c write failed: 0x%02x: 0x%02x, errno %d\n", -+ reg + 1, value & 0xFF, -rc); -+ return rc; -+ } -+ -+ return rc; -+} -+ -+static void cy8c3245r1_init_client(struct i2c_client *client) -+{ -+ int reg = i2c_smbus_read_byte_data(client, CY8C3245R1_REG_PWM_CFG_BASE_ADDR); -+ -+ if (reg < 0) { -+ dev_err(&client->dev, "cannot read configuration register\n"); -+ } else { -+ i2c_smbus_write_byte_data(client, CY8C3245R1_REG_PWM_CFG_BASE_ADDR, 0); -+ } -+} -+ -+/* Probe for temperature sensors. Assumes lock is held */ -+static int cy8c3245r1_read_temperatures(struct i2c_client *client, -+ struct cy8c3245r1_data *data) -+{ -+ int i; -+ -+ /* Only count fans if we have to */ -+ if (data->num_temp_sensors >= 0) -+ return 0; -+ -+ for (i = 0; i < CY8C3245R1_TEMP_COUNT; i++) { -+ data->temp[i] = i2c_smbus_read_byte_data(client, -+ CY8C3245R1_TEMP_REG(i)); -+ if (data->temp[i]) -+ data->num_temp_sensors = i + 1; -+ } -+ data->temperatures_probed = 1; -+ return 0; -+} -+ -+static int cy8c3245r1_update_thread(void *p) -+{ -+ struct i2c_client *client = p; -+ struct cy8c3245r1_data *data = i2c_get_clientdata(client); -+ -+ while (!kthread_should_stop()) { -+ mutex_lock(&data->lock); -+ cy8c3245r1_read_temperatures(client, data); -+ mutex_unlock(&data->lock); -+ if (kthread_should_stop()) -+ break; -+ msleep_interruptible(data->auto_update_interval); -+ } -+ -+ complete_all(&data->auto_update_stop); -+ return 0; -+} -+ -+static struct cy8c3245r1_data *cy8c3245r1_update_device(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3245r1_data *data = i2c_get_clientdata(client); -+ unsigned long local_jiffies = jiffies; -+ int i; -+ int need_sensors = 1; -+ int need_limits = 1; -+ -+ /* -+ * Figure out if we need to update the shadow registers. -+ * Lockless means that we may occasionally report out of -+ * date data. -+ */ -+ if (time_before(local_jiffies, data->sensors_last_updated + -+ SENSOR_REFRESH_INTERVAL) && -+ data->sensors_valid) -+ need_sensors = 0; -+ -+ if (time_before(local_jiffies, data->limits_last_updated + -+ LIMIT_REFRESH_INTERVAL) && -+ data->limits_valid) -+ need_limits = 0; -+ -+ if (!need_sensors && !need_limits) -+ return data; -+ -+ mutex_lock(&data->lock); -+ if (!need_sensors) -+ goto no_sensor_update; -+ -+ if (!data->temperatures_probed) -+ cy8c3245r1_read_temperatures(client, data); -+ else -+ for (i = 0; i < CY8C3245R1_TEMP_COUNT; i++) -+ data->temp[i] = i2c_smbus_read_byte_data(client, -+ CY8C3245R1_TEMP_REG(i)); -+ -+ for (i = 0; i < CY8C3245R1_FAN_COUNT; i++) { -+ data->fan[i] = cy8c3245r1_read_word_data(client, -+ CY8C3245R1_REG_FAN(i)); -+ } -+ -+ data->pwm = i2c_smbus_read_byte_data(client, -+ CY8C3245R1_REG_PWM); -+ -+ data->sensors_last_updated = local_jiffies; -+ data->sensors_valid = 1; -+ -+no_sensor_update: -+ if (!need_limits) -+ goto out; -+ -+ for (i = 0; i < CY8C3245R1_TEMP_COUNT; i++) { -+ data->temp_max[i] = i2c_smbus_read_byte_data(client, -+ CY8C3245R1_TEMP_MAX_REG(i)); -+ } -+ -+ for (i = 0; i < CY8C3245R1_FAN_COUNT; i++) { -+ data->fan_max[i] = cy8c3245r1_read_word_data(client, -+ CY8C3245R1_REG_FAN_MAX(i)); -+ } -+ data->fan_tgt = cy8c3245r1_read_word_data(client, -+ CY8C3245R1_REG_FAN_TARGET); -+ -+ for (i = 0; i < CY8C3245R1_FAN_PROFILE_MAX; i++) { -+ data->fan_profile[i] = cy8c3245r1_read_word_data(client, -+ CY8C3245R1_REG_FAN_PROFILE(i)); -+ } -+ -+ data->limits_last_updated = local_jiffies; -+ data->limits_valid = 1; -+ -+out: -+ mutex_unlock(&data->lock); -+ return data; -+} -+ -+static ssize_t show_auto_update_interval(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ return sprintf(buf, "%d\n", data->auto_update_interval); -+} -+ -+static ssize_t set_auto_update_interval(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, -+ size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3245r1_data *data = i2c_get_clientdata(client); -+ long temp; -+ -+ if (strict_strtol(buf, 10, &temp)) -+ return -EINVAL; -+ -+ temp = SENSORS_LIMIT(temp, 0, 60000); -+ -+ mutex_lock(&data->lock); -+ data->auto_update_interval = temp; -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+static ssize_t show_num_temp_sensors(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ return sprintf(buf, "%d\n", data->num_temp_sensors); -+} -+ -+static ssize_t set_num_temp_sensors(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, -+ size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3245r1_data *data = i2c_get_clientdata(client); -+ long temp; -+ -+ if (strict_strtol(buf, 10, &temp)) -+ return -EINVAL; -+ -+ temp = SENSORS_LIMIT(temp, -1, 10); -+ -+ mutex_lock(&data->lock); -+ data->num_temp_sensors = temp; -+ if (temp < 0) -+ data->temperatures_probed = 0; -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+static ssize_t show_temp_max(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ return sprintf(buf, "%d\n", 1000 * data->temp_max[attr->index]); -+} -+ -+static ssize_t set_temp_max(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, -+ size_t count) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3245r1_data *data = i2c_get_clientdata(client); -+ long temp; -+ -+ if (strict_strtol(buf, 10, &temp)) -+ return -EINVAL; -+ -+ temp = DIV_ROUND_CLOSEST(temp, 1000); -+ temp = SENSORS_LIMIT(temp, -128, 127); -+ -+ mutex_lock(&data->lock); -+ data->temp_max[attr->index] = temp; -+ i2c_smbus_write_byte_data(client, CY8C3245R1_TEMP_MAX_REG(attr->index), -+ temp); -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ return sprintf(buf, "%d\n", 1000 * data->temp[attr->index]); -+} -+ -+static ssize_t show_fan_max(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ -+ if (FAN_DATA_VALID(data->fan_max[attr->index])) -+ return sprintf(buf, "%d\n", -+ data->fan_max[attr->index]); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t set_fan_max(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, size_t count) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3245r1_data *data = i2c_get_clientdata(client); -+ long rpm; -+ -+ if (strict_strtol(buf, 10, &rpm) || !rpm) -+ return -EINVAL; -+ -+ rpm = SENSORS_LIMIT(rpm, 1, 65534); -+ -+ mutex_lock(&data->lock); -+ data->fan_max[attr->index] = rpm; -+ cy8c3245r1_write_word_data(client, CY8C3245R1_REG_FAN_MAX(attr->index), rpm); -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+/* -+ * fan_min is a pure software concept, not implemented by hardware. -+ * It is used to compute the alarm status. -+ */ -+static ssize_t show_fan_min(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ -+ return sprintf(buf, "%d\n", data->fan_min[attr->index]); -+} -+ -+static ssize_t set_fan_min(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, size_t count) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3245r1_data *data = i2c_get_clientdata(client); -+ long rpm; -+ -+ if (strict_strtol(buf, 10, &rpm) || !rpm) -+ return -EINVAL; -+ -+ rpm = SENSORS_LIMIT(rpm, 1, 65534); -+ -+ mutex_lock(&data->lock); -+ data->fan_min[attr->index] = rpm; -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+static ssize_t show_fan_target(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ -+ if (FAN_DATA_VALID(data->fan_tgt)) -+ return sprintf(buf, "%d\n", -+ data->fan_tgt); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t set_fan_target(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, size_t count) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3245r1_data *data = i2c_get_clientdata(client); -+ long rpm; -+ -+ if (strict_strtol(buf, 10, &rpm) || !rpm) -+ return -EINVAL; -+ -+ rpm = SENSORS_LIMIT(rpm, 1, 65534); -+ -+ mutex_lock(&data->lock); -+ data->fan_tgt = rpm; -+ cy8c3245r1_write_word_data(client, CY8C3245R1_REG_FAN_TARGET, rpm); -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+/* -+ * Show Fan Profile Settings -+ */ -+static ssize_t show_fan_profile(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ -+ return sprintf(buf, "%u\n", -+ data->fan_profile[attr->index]); -+} -+ -+/* -+ * Set Fan Profile Settings -+ */ -+static ssize_t set_fan_profile(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, size_t count) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3245r1_data *data = i2c_get_clientdata(client); -+ long parm; -+ -+ if (strict_strtoul(buf, 10, &parm)) -+ return -EINVAL; -+ -+ parm = SENSORS_LIMIT(parm, 1, 65534); -+ -+ mutex_lock(&data->lock); -+ data->fan_profile[attr->index] = parm; -+ cy8c3245r1_write_word_data(client, CY8C3245R1_REG_FAN_PROFILE(attr->index), parm); -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ -+ if (FAN_DATA_VALID(data->fan[attr->index])) -+ return sprintf(buf, "%d\n", data->fan[attr->index]); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ return sprintf(buf, "%d\n", data->pwm); -+} -+ -+static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, -+ const char *buf, size_t count) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3245r1_data *data = i2c_get_clientdata(client); -+ long temp; -+ -+ if (strict_strtol(buf, 10, &temp)) -+ return -EINVAL; -+ -+ temp = SENSORS_LIMIT(temp, 0, 255); -+ -+ mutex_lock(&data->lock); -+ data->pwm = temp; -+ i2c_smbus_write_byte_data(client, CY8C3245R1_REG_PWM, temp); -+ mutex_unlock(&data->lock); -+ -+ return count; -+} -+ -+static ssize_t show_fan_alarm_mask(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ int i; -+ u32 alarm_mask = 0; -+ -+ for (i = 0; i < CY8C3245R1_FAN_COUNT; i++) -+ if ((data->fan[i] < data->fan_min[i]) || -+ (data->fan[i] >= data->fan_max[i])) -+ alarm_mask |= 0x1 << i; -+ -+ return sprintf(buf, "%x\n", alarm_mask); -+} -+ -+static ssize_t show_temp_alarm_mask(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ int i; -+ u32 alarm_mask = 0; -+ -+ for (i = 0; i < CY8C3245R1_TEMP_COUNT; i++) -+ if (data->temp[i] >= data->temp_max[i]) -+ alarm_mask |= 0x1 << i; -+ -+ return sprintf(buf, "%x\n", alarm_mask); -+} -+ -+static ssize_t show_fan_alarm(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ -+ if ((data->fan[attr->index] < data->fan_min[attr->index]) || -+ (data->fan[attr->index] >= data->fan_max[attr->index])) -+ return sprintf(buf, "1\n"); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t show_temp_alarm(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ -+ if (data->temp[attr->index] >= data->temp_max[attr->index]) -+ return sprintf(buf, "1\n"); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t set_pwm_auto(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, -+ size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cy8c3245r1_data *data = i2c_get_clientdata(client); -+ long temp; -+ -+ if (strict_strtol(buf, 10, &temp)) -+ return -EINVAL; -+ -+ if (!(temp >= 0 && temp <= 3)) -+ return -EINVAL; -+ -+ return count; -+} -+ -+static ssize_t show_pwm_auto(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct cy8c3245r1_data *data = cy8c3245r1_update_device(dev); -+ -+ return sprintf(buf, "%d\n", data->pwm_automatic); -+} -+ -+#define CY8C3245R1_REG_MIN 0x00 -+#define CY8C3245R1_REG_MAX 0xe0 -+ -+static ssize_t show_debug(struct device *dev, -+ struct device_attribute *devattr, -+ char *buf) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ -+ int len = 0, i, j; -+ u8 val; -+ for (i = 0; i < (CY8C3245R1_REG_MAX - CY8C3245R1_REG_MIN) / 16; i++) { -+ len += sprintf(buf+len, "0x%02x: ", CY8C3245R1_REG_MIN + (i * 16)); -+ for (j = 0; j < 16; j++) { -+ val = i2c_smbus_read_byte_data(client, CY8C3245R1_REG_MIN + (i * 16) + j); -+ len += sprintf(buf+len, "%02x ", val); -+ } -+ len += sprintf(buf+len, "\n"); -+ } -+ return len; -+} -+ -+static DEVICE_ATTR(fan_alarm_mask, S_IRUGO, show_fan_alarm_mask, NULL); -+static DEVICE_ATTR(temp_alarm_mask, S_IRUGO, show_temp_alarm_mask, NULL); -+static DEVICE_ATTR(num_temp_sensors, S_IWUSR | S_IRUGO, show_num_temp_sensors, -+ set_num_temp_sensors); -+static DEVICE_ATTR(auto_update_interval, S_IWUSR | S_IRUGO, -+ show_auto_update_interval, set_auto_update_interval); -+ -+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, -+ set_temp_max, 0); -+static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, -+ set_temp_max, 1); -+static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max, -+ set_temp_max, 2); -+static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp_max, -+ set_temp_max, 3); -+static SENSOR_DEVICE_ATTR(temp5_max, S_IWUSR | S_IRUGO, show_temp_max, -+ set_temp_max, 4); -+static SENSOR_DEVICE_ATTR(temp6_max, S_IWUSR | S_IRUGO, show_temp_max, -+ set_temp_max, 5); -+static SENSOR_DEVICE_ATTR(temp7_max, S_IWUSR | S_IRUGO, show_temp_max, -+ set_temp_max, 6); -+static SENSOR_DEVICE_ATTR(temp8_max, S_IWUSR | S_IRUGO, show_temp_max, -+ set_temp_max, 7); -+ -+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); -+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); -+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); -+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); -+static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp, NULL, 4); -+static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_temp, NULL, 5); -+static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_temp, NULL, 6); -+static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_temp, NULL, 7); -+ -+static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0); -+static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1); -+static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2); -+static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_temp_alarm, NULL, 3); -+static SENSOR_DEVICE_ATTR(temp5_alarm, S_IRUGO, show_temp_alarm, NULL, 4); -+static SENSOR_DEVICE_ATTR(temp6_alarm, S_IRUGO, show_temp_alarm, NULL, 4); -+static SENSOR_DEVICE_ATTR(temp7_alarm, S_IRUGO, show_temp_alarm, NULL, 4); -+static SENSOR_DEVICE_ATTR(temp8_alarm, S_IRUGO, show_temp_alarm, NULL, 4); -+ -+static SENSOR_DEVICE_ATTR(fan1_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 0); -+static SENSOR_DEVICE_ATTR(fan2_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 1); -+static SENSOR_DEVICE_ATTR(fan3_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 2); -+static SENSOR_DEVICE_ATTR(fan4_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 3); -+static SENSOR_DEVICE_ATTR(fan5_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 4); -+static SENSOR_DEVICE_ATTR(fan6_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 5); -+static SENSOR_DEVICE_ATTR(fan7_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 6); -+static SENSOR_DEVICE_ATTR(fan8_max, S_IWUSR | S_IRUGO, show_fan_max, -+ set_fan_max, 7); -+ -+static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 0); -+static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 1); -+static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 2); -+static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 3); -+static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 4); -+static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 5); -+static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 6); -+static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO, show_fan_min, -+ set_fan_min, 7); -+ -+static SENSOR_DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 0); -+static SENSOR_DEVICE_ATTR(fan2_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 1); -+static SENSOR_DEVICE_ATTR(fan3_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 2); -+static SENSOR_DEVICE_ATTR(fan4_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 3); -+static SENSOR_DEVICE_ATTR(fan5_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 4); -+static SENSOR_DEVICE_ATTR(fan6_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 5); -+static SENSOR_DEVICE_ATTR(fan7_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 6); -+static SENSOR_DEVICE_ATTR(fan8_target, S_IWUSR | S_IRUGO, show_fan_target, -+ set_fan_target, 7); -+ -+#define FAN_PROFILE_ATTR(_name, _index) \ -+ SENSOR_DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, \ -+ show_fan_profile, set_fan_profile, _index) -+ -+static FAN_PROFILE_ATTR(fan_low_duty, CY8C3245R1_FAN_PROFILE_LOW_DUTY); -+static FAN_PROFILE_ATTR(fan_low_rpm, CY8C3245R1_FAN_PROFILE_LOW_RPM); -+static FAN_PROFILE_ATTR(fan_high_duty, CY8C3245R1_FAN_PROFILE_HIGH_DUTY); -+static FAN_PROFILE_ATTR(fan_high_rpm, CY8C3245R1_FAN_PROFILE_HIGH_RPM); -+static FAN_PROFILE_ATTR(fan_speed_0_duty, CY8C3245R1_FAN_PROFILE_SPEED_0_DUTY); -+static FAN_PROFILE_ATTR(fan_speed_100_duty,CY8C3245R1_FAN_PROFILE_SPEED_100_DUTY); -+ -+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); -+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); -+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); -+static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); -+static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4); -+static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5); -+static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6); -+static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7); -+ -+static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0); -+static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1); -+static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2); -+static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3); -+static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_fan_alarm, NULL, 4); -+static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_fan_alarm, NULL, 5); -+static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_fan_alarm, NULL, 6); -+static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_fan_alarm, NULL, 7); -+ -+static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); -+static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); -+static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); -+static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); -+static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 4); -+static SENSOR_DEVICE_ATTR(pwm6, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 5); -+static SENSOR_DEVICE_ATTR(pwm7, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 6); -+static SENSOR_DEVICE_ATTR(pwm8, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 7); -+ -+static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm6_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm7_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+static SENSOR_DEVICE_ATTR(pwm8_enable, S_IWUSR | S_IRUGO, show_pwm_auto, -+ set_pwm_auto, 0); -+ -+static SENSOR_DEVICE_ATTR(debug, S_IRUGO, show_debug, NULL, 0); -+ -+static struct attribute *cy8c3245r1_attr[] = -+{ -+ &dev_attr_fan_alarm_mask.attr, -+ &dev_attr_temp_alarm_mask.attr, -+ &dev_attr_num_temp_sensors.attr, -+ &dev_attr_auto_update_interval.attr, -+ &sensor_dev_attr_temp1_max.dev_attr.attr, -+ &sensor_dev_attr_temp2_max.dev_attr.attr, -+ &sensor_dev_attr_temp3_max.dev_attr.attr, -+ &sensor_dev_attr_temp4_max.dev_attr.attr, -+ &sensor_dev_attr_temp5_max.dev_attr.attr, -+ &sensor_dev_attr_temp6_max.dev_attr.attr, -+ &sensor_dev_attr_temp7_max.dev_attr.attr, -+ &sensor_dev_attr_temp8_max.dev_attr.attr, -+ &sensor_dev_attr_temp1_input.dev_attr.attr, -+ &sensor_dev_attr_temp2_input.dev_attr.attr, -+ &sensor_dev_attr_temp3_input.dev_attr.attr, -+ &sensor_dev_attr_temp4_input.dev_attr.attr, -+ &sensor_dev_attr_temp5_input.dev_attr.attr, -+ &sensor_dev_attr_temp6_input.dev_attr.attr, -+ &sensor_dev_attr_temp7_input.dev_attr.attr, -+ &sensor_dev_attr_temp8_input.dev_attr.attr, -+ &sensor_dev_attr_temp1_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp2_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp3_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp4_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp5_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp6_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp7_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp8_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan1_max.dev_attr.attr, -+ &sensor_dev_attr_fan2_max.dev_attr.attr, -+ &sensor_dev_attr_fan3_max.dev_attr.attr, -+ &sensor_dev_attr_fan4_max.dev_attr.attr, -+ &sensor_dev_attr_fan5_max.dev_attr.attr, -+ &sensor_dev_attr_fan6_max.dev_attr.attr, -+ &sensor_dev_attr_fan7_max.dev_attr.attr, -+ &sensor_dev_attr_fan8_max.dev_attr.attr, -+ &sensor_dev_attr_fan1_min.dev_attr.attr, -+ &sensor_dev_attr_fan2_min.dev_attr.attr, -+ &sensor_dev_attr_fan3_min.dev_attr.attr, -+ &sensor_dev_attr_fan4_min.dev_attr.attr, -+ &sensor_dev_attr_fan5_min.dev_attr.attr, -+ &sensor_dev_attr_fan6_min.dev_attr.attr, -+ &sensor_dev_attr_fan7_min.dev_attr.attr, -+ &sensor_dev_attr_fan8_min.dev_attr.attr, -+ &sensor_dev_attr_fan1_target.dev_attr.attr, -+ &sensor_dev_attr_fan2_target.dev_attr.attr, -+ &sensor_dev_attr_fan3_target.dev_attr.attr, -+ &sensor_dev_attr_fan4_target.dev_attr.attr, -+ &sensor_dev_attr_fan5_target.dev_attr.attr, -+ &sensor_dev_attr_fan6_target.dev_attr.attr, -+ &sensor_dev_attr_fan7_target.dev_attr.attr, -+ &sensor_dev_attr_fan8_target.dev_attr.attr, -+ &sensor_dev_attr_fan1_input.dev_attr.attr, -+ &sensor_dev_attr_fan2_input.dev_attr.attr, -+ &sensor_dev_attr_fan3_input.dev_attr.attr, -+ &sensor_dev_attr_fan4_input.dev_attr.attr, -+ &sensor_dev_attr_fan5_input.dev_attr.attr, -+ &sensor_dev_attr_fan6_input.dev_attr.attr, -+ &sensor_dev_attr_fan7_input.dev_attr.attr, -+ &sensor_dev_attr_fan8_input.dev_attr.attr, -+ &sensor_dev_attr_fan1_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan2_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan3_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan4_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan5_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan6_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan7_alarm.dev_attr.attr, -+ &sensor_dev_attr_fan8_alarm.dev_attr.attr, -+ &sensor_dev_attr_pwm1.dev_attr.attr, -+ &sensor_dev_attr_pwm2.dev_attr.attr, -+ &sensor_dev_attr_pwm3.dev_attr.attr, -+ &sensor_dev_attr_pwm4.dev_attr.attr, -+ &sensor_dev_attr_pwm5.dev_attr.attr, -+ &sensor_dev_attr_pwm6.dev_attr.attr, -+ &sensor_dev_attr_pwm7.dev_attr.attr, -+ &sensor_dev_attr_pwm8.dev_attr.attr, -+ &sensor_dev_attr_pwm1_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm2_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm3_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm4_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm5_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm6_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm7_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm8_enable.dev_attr.attr, -+ &sensor_dev_attr_fan_low_duty.dev_attr.attr, -+ &sensor_dev_attr_fan_low_rpm.dev_attr.attr, -+ &sensor_dev_attr_fan_high_duty.dev_attr.attr, -+ &sensor_dev_attr_fan_high_rpm.dev_attr.attr, -+ &sensor_dev_attr_fan_speed_0_duty.dev_attr.attr, -+ &sensor_dev_attr_fan_speed_100_duty.dev_attr.attr, -+ &sensor_dev_attr_debug.dev_attr.attr, -+ NULL -+}; -+ -+static int cy8c3245r1_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct cy8c3245r1_data *data; -+ int err; -+ int minor_revision, major_revision; -+ -+ data = kzalloc(sizeof(struct cy8c3245r1_data), GFP_KERNEL); -+ if (!data) { -+ err = -ENOMEM; -+ goto exit; -+ } -+ -+ data->num_temp_sensors = -1; -+ data->auto_update_interval = AUTO_UPDATE_INTERVAL; -+ -+ i2c_set_clientdata(client, data); -+ mutex_init(&data->lock); -+ -+ dev_info(&client->dev, "%s chip found\n", client->name); -+ -+ /* Initialize the CY8C3245R1 chip */ -+ cy8c3245r1_init_client(client); -+ -+ minor_revision = i2c_smbus_read_byte_data(client, CY8C3245R1_REG_FW_REV_MIN); -+ major_revision = i2c_smbus_read_byte_data(client, CY8C3245R1_REG_FW_REV_MAJ); -+ if ((minor_revision < CY8C3245R1_FW_REV_MIN) || -+ (major_revision != CY8C3245R1_FW_REV_MAJ)) { -+ dev_err(&client->dev, -+ "PSoC Supported Version >= %u.%u, Current version %u.%u\n", -+ CY8C3245R1_FW_REV_MAJ, CY8C3245R1_FW_REV_MIN, major_revision, -+ minor_revision); -+ err = -ENODEV; -+ goto exit_free; -+ } -+ -+ /* Register sysfs hooks */ -+ data->attrs.attrs = cy8c3245r1_attr; -+ if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) -+ goto exit_free; -+ -+ data->hwmon_dev = hwmon_device_register(&client->dev); -+ if (IS_ERR(data->hwmon_dev)) { -+ err = PTR_ERR(data->hwmon_dev); -+ goto exit_remove; -+ } -+ -+ init_completion(&data->auto_update_stop); -+ data->auto_update = kthread_run(cy8c3245r1_update_thread, client, -+ dev_name(data->hwmon_dev)); -+ if (IS_ERR(data->auto_update)) { -+ err = PTR_ERR(data->auto_update); -+ goto exit_unregister; -+ } -+ -+ return 0; -+ -+exit_unregister: -+ hwmon_device_unregister(data->hwmon_dev); -+exit_remove: -+ sysfs_remove_group(&client->dev.kobj, &data->attrs); -+exit_free: -+ kfree(data); -+exit: -+ return err; -+} -+ -+static int cy8c3245r1_remove(struct i2c_client *client) -+{ -+ struct cy8c3245r1_data *data = i2c_get_clientdata(client); -+ -+ kthread_stop(data->auto_update); -+ wait_for_completion(&data->auto_update_stop); -+ hwmon_device_unregister(data->hwmon_dev); -+ sysfs_remove_group(&client->dev.kobj, &data->attrs); -+ kfree(data); -+ return 0; -+} -+ -+static int __init cy8c3245r1_init(void) -+{ -+ return i2c_add_driver(&cy8c3245r1_driver); -+} -+ -+static void __exit cy8c3245r1_exit(void) -+{ -+ i2c_del_driver(&cy8c3245r1_driver); -+} -+ -+MODULE_AUTHOR("Shrijeet Mukherjee "); -+MODULE_AUTHOR("Vidya Ravipati "); -+MODULE_DESCRIPTION("CY8C3245R1 driver"); -+MODULE_LICENSE("GPL"); -+ -+module_init(cy8c3245r1_init); -+module_exit(cy8c3245r1_exit); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-ds100df410-retimer.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-ds100df410-retimer.patch deleted file mode 100644 index e5841f8b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-ds100df410-retimer.patch +++ /dev/null @@ -1,546 +0,0 @@ -Driver for DS100DF410 Low Power 10GbE Quad Channel Retimer/Equalizer - -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 846aab1..41989b0 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -527,6 +527,27 @@ config EDA_DEF_ALIGN - help - Default alignment of the memory region. Default is 1MB. - -+config RETIMER_CLASS -+ tristate "Retimer Class support" -+ depends on SYSFS -+ default y -+ help -+ Creates a hardware class in sysfs called "retimer_dev", -+ providing a common place to register RETIMER devices. -+ -+ This support can also be built as a module. If so, the module -+ will be called retimer_class. -+ -+config DS100DF410 -+ tristate "DS100DF410 Low Power 10GbE Quad Channel Retimer" -+ depends on I2C && SYSFS -+ help -+ If you say yes here you get support for the DS100DF410 -+ Low Power 10GbE Quad Channel Retimer. -+ -+ This driver can also be built as a module. If so, the module -+ will be called ds100df410. -+ - source "drivers/misc/c2port/Kconfig" - source "drivers/misc/eeprom/Kconfig" - source "drivers/misc/cb710/Kconfig" -diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index cf09aa8..ad70876 100644 ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -49,3 +49,5 @@ obj-y += carma/ - obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o - obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ - obj-$(CONFIG_EARLY_DMA_ALLOC) += early_dma_alloc.o -+obj-$(CONFIG_RETIMER_CLASS) += retimer_class.o -+obj-$(CONFIG_DS100DF410) += ds100df410.o -diff --git a/drivers/misc/ds100df410.c b/drivers/misc/ds100df410.c -new file mode 100644 -index 0000000..b626111 ---- /dev/null -+++ b/drivers/misc/ds100df410.c -@@ -0,0 +1,290 @@ -+/* -+ * ds100df410.c - I2c client driver to manage DS100DF410 -+ * DS100DF410 Low Power 10GbE Quad Channel Retimer -+ * -+ * Copyright (C) 2014 Cumulus Networks, Inc. -+ * Author: Puneet Shenoy -+ * -+ * Ideas and structure regarding introducing the class device graciously borrowed -+ * from the eeprom sysfs/class support by: -+ * Copyright (C) 2013 CumulusNetworks, Inc. -+ * Author: Curt Brune -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_RETIMER_CLASS -+#include -+#endif -+ -+#define DS100DF410_DRV_NAME "ds100df410" -+#define DRIVER_VERSION "1.0" -+ -+#define DS100DF410_CDR_RST_REG 0x0a -+#define DS100DF410_TAP_DEM_REG 0x15 -+#define DS100DF410_PFD_PRBS_DFE_REG 0x1e -+#define DS100DF410_DRV_SEL_VOD_REG 0x2d -+#define DS100DF410_ADAPT_EQ_SM_REG 0x31 -+#define DS100DF410_VEO_CLK_CDR_CAP_REG 0x36 -+#define DS100DF410_CHANNELS_REG 0xff -+ -+struct ds100df410_data { -+ struct i2c_client *client; -+ -+#ifdef CONFIG_RETIMER_CLASS -+ struct device *retimer_dev; -+#endif -+ struct mutex lock; -+}; -+ -+static u32 ds100df410_read(struct device *dev, u8 reg, char *buf) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ u32 ret = i2c_smbus_read_byte_data(client, reg); -+ -+ return sprintf(buf, "%d\n", ret); -+} -+ -+static u32 ds100df410_write(struct device *dev, u8 reg, const char *buf, -+ size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ unsigned long val; -+ int ret; -+ -+ if (strict_strtoul(buf, 0, &val) < 0) -+ return -EINVAL; -+ -+ ret = i2c_smbus_write_byte_data(client, reg, (u8)val); -+ if (ret < 0) -+ return ret; -+ -+ return count; -+} -+ -+static ssize_t ds100df410_show_cdr_rst(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ return ds100df410_read(dev, DS100DF410_CDR_RST_REG, buf); -+} -+ -+static ssize_t ds100df410_store_cdr_rst(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ return ds100df410_write(dev, DS100DF410_CDR_RST_REG, buf, count); -+} -+ -+static ssize_t ds100df410_show_tap_dem(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ return ds100df410_read(dev, DS100DF410_TAP_DEM_REG, buf); -+} -+ -+static ssize_t ds100df410_store_tap_dem(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ return ds100df410_write(dev, DS100DF410_TAP_DEM_REG, buf, count); -+} -+ -+static ssize_t ds100df410_show_pfd_prbs_dfe(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ return ds100df410_read(dev, DS100DF410_PFD_PRBS_DFE_REG, buf); -+} -+ -+static ssize_t ds100df410_store_pfd_prbs_dfe(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ return ds100df410_write(dev, DS100DF410_PFD_PRBS_DFE_REG, buf, count); -+} -+ -+static ssize_t ds100df410_show_drv_sel_vod(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ return ds100df410_read(dev, DS100DF410_DRV_SEL_VOD_REG, buf); -+} -+ -+static ssize_t ds100df410_store_drv_sel_vod(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ return ds100df410_write(dev, DS100DF410_DRV_SEL_VOD_REG, buf, count); -+} -+ -+static ssize_t ds100df410_show_adapt_eq_sm(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ return ds100df410_read(dev, DS100DF410_ADAPT_EQ_SM_REG, buf); -+} -+ -+static ssize_t ds100df410_store_adapt_eq_sm(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ return ds100df410_write(dev, DS100DF410_ADAPT_EQ_SM_REG, buf, count); -+} -+ -+static ssize_t ds100df410_show_veo_clk_cdr_cap(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ return ds100df410_read(dev, DS100DF410_VEO_CLK_CDR_CAP_REG, buf); -+} -+ -+static ssize_t ds100df410_store_veo_clk_cdr_cap(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ return ds100df410_write(dev, DS100DF410_VEO_CLK_CDR_CAP_REG, buf, count); -+} -+ -+static ssize_t ds100df410_show_channels(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ return ds100df410_read(dev, DS100DF410_CHANNELS_REG, buf); -+} -+ -+static ssize_t ds100df410_store_channels(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ return ds100df410_write(dev, DS100DF410_CHANNELS_REG, buf, count); -+} -+ -+static DEVICE_ATTR(cdr_rst, S_IWUSR | S_IRUGO, -+ ds100df410_show_cdr_rst, ds100df410_store_cdr_rst); -+static DEVICE_ATTR(tap_dem, S_IWUSR | S_IRUGO, -+ ds100df410_show_tap_dem, ds100df410_store_tap_dem); -+static DEVICE_ATTR(pfd_prbs_dfe, S_IWUSR | S_IRUGO, -+ ds100df410_show_pfd_prbs_dfe, ds100df410_store_pfd_prbs_dfe); -+static DEVICE_ATTR(drv_sel_vod, S_IWUSR | S_IRUGO, -+ ds100df410_show_drv_sel_vod, ds100df410_store_drv_sel_vod); -+static DEVICE_ATTR(adapt_eq_sm, S_IWUSR | S_IRUGO, -+ ds100df410_show_adapt_eq_sm, ds100df410_store_adapt_eq_sm); -+static DEVICE_ATTR(veo_clk_cdr_cap, S_IWUSR | S_IRUGO, -+ ds100df410_show_veo_clk_cdr_cap, -+ ds100df410_store_veo_clk_cdr_cap); -+static DEVICE_ATTR(channels, S_IWUSR | S_IRUGO, -+ ds100df410_show_channels, ds100df410_store_channels); -+ -+static struct attribute *ds100df410_attributes[] = { -+ &dev_attr_cdr_rst.attr, -+ &dev_attr_tap_dem.attr, -+ &dev_attr_pfd_prbs_dfe.attr, -+ &dev_attr_drv_sel_vod.attr, -+ &dev_attr_adapt_eq_sm.attr, -+ &dev_attr_veo_clk_cdr_cap.attr, -+ &dev_attr_channels.attr, -+ NULL -+}; -+ -+static const struct attribute_group ds100df410_attr_group = { -+ .attrs = ds100df410_attributes, -+}; -+ -+static int __devinit ds100df410_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); -+ struct ds100df410_data *data; -+ int err = 0; -+ -+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) { -+ return -EIO; -+ } -+ -+ data = kzalloc(sizeof(struct ds100df410_data), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ data->client = client; -+ mutex_init(&data->lock); -+ -+ /* register sysfs hooks */ -+ err = sysfs_create_group(&client->dev.kobj, &ds100df410_attr_group); -+ if (err) -+ goto exit_kfree; -+ -+ -+#ifdef CONFIG_RETIMER_CLASS -+ data->retimer_dev = retimer_device_register(&client->dev); -+ if (IS_ERR(data->retimer_dev)) { -+ dev_err(&client->dev, "error registering retimer device.\n"); -+ err = PTR_ERR(data->retimer_dev); -+ goto exit_kfree; -+ } -+#endif -+ -+ i2c_set_clientdata(client, data); -+ return 0; -+exit_kfree: -+ kfree(data); -+ return err; -+} -+ -+static int __devexit ds100df410_remove(struct i2c_client *client) -+{ -+ struct ds100df410_data *data; -+ -+ data = i2c_get_clientdata(client); -+ sysfs_remove_group(&client->dev.kobj, &ds100df410_attr_group); -+ -+#ifdef CONFIG_RETIMER_CLASS -+ retimer_device_unregister(data->retimer_dev); -+#endif -+ -+ kfree(data); -+ return 0; -+} -+ -+static const struct i2c_device_id ds100df410_id[] = { -+ { "ds100df410", 0 }, -+ {} -+}; -+MODULE_DEVICE_TABLE(i2c, ds100df410_id); -+ -+static struct i2c_driver ds100df410_driver = { -+ .driver = { -+ .name = DS100DF410_DRV_NAME, -+ }, -+ .probe = ds100df410_probe, -+ .remove = __devexit_p(ds100df410_remove), -+ .id_table = ds100df410_id, -+}; -+ -+module_i2c_driver(ds100df410_driver); -+MODULE_AUTHOR("Puneet Shenoy "); -+MODULE_DESCRIPTION("I2C client for DS100DF410 10GE Quad Core Retimer"); -+MODULE_LICENSE("GPL v2"); -+MODULE_VERSION(DRIVER_VERSION); -diff --git a/drivers/misc/retimer_class.c b/drivers/misc/retimer_class.c -new file mode 100644 -index 0000000..176df29 ---- /dev/null -+++ b/drivers/misc/retimer_class.c -@@ -0,0 +1,159 @@ -+/* -+ * retimer_class.c -+ * -+ * This file defines the sysfs class "retimer", for use by RETIMER -+ * drivers. -+ * -+ * Copyright (C) 2014 Cumulus Networks, Inc. -+ * Author: Puneet Shenoy -+ * -+ * Ideas and structure graciously borrowed from the eeprom_class class: -+ * Copyright (C) 2013 Curt Brune -+ * -+ * 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; version 2 of the License. -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Root retimer "class" object (corresponds to '//class/retimer_dev/') */ -+static struct class *retimer_class; -+ -+#define RETIMER_CLASS_NAME "retimer_dev" -+#define RETIMER_ID_PREFIX "retimer" -+#define RETIMER_ID_FORMAT RETIMER_ID_PREFIX "%d" -+ -+static DEFINE_IDA(retimer_ida); -+ -+/** -+ * retimer_device_register - register w/ retimer class -+ * @dev: the device to register -+ * -+ * retimer_device_unregister() must be called when the device is no -+ * longer needed. -+ * -+ * Creates a new retimer class device that is a child of @dev. Also -+ * creates a symlink in //class/retimer_dev/retimer[N] pointing -+ * to the new device. -+ * -+ * Returns the pointer to the new device. -+ */ -+struct device *retimer_device_register(struct device *dev) -+{ -+ struct device *retimer_dev; -+ int id; -+ -+ id = ida_simple_get(&retimer_ida, 0, 0, GFP_KERNEL); -+ if (id < 0) -+ return ERR_PTR(id); -+ -+ retimer_dev = device_create(retimer_class, dev, MKDEV(0, 0), NULL, -+ RETIMER_ID_FORMAT, id); -+ -+ if (IS_ERR(retimer_dev)) -+ ida_simple_remove(&retimer_ida, id); -+ -+ return retimer_dev; -+} -+ -+/** -+ * retimer_device_unregister - removes the previously registered class device -+ * -+ * @dev: the class device to destroy -+ */ -+void retimer_device_unregister(struct device *dev) -+{ -+ int id; -+ -+ if (likely(sscanf(dev_name(dev), RETIMER_ID_FORMAT, &id) == 1)) { -+ device_unregister(dev); -+ ida_simple_remove(&retimer_ida, id); -+ } else -+ dev_dbg(dev->parent, -+ "retimer_device_unregister() failed: bad class ID!\n"); -+} -+ -+/** -+ * Each member of the retimer class exports a sysfs file called -+ * "label", containing the label property from the corresponding -+ * device tree node. -+ * -+ * Userspace can use the label to identify what the RETIMER is for. -+ */ -+static ssize_t label_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ const char* cp = NULL; -+ int len = 0; -+ -+ /* -+ * The class device is a child of the original device, -+ * i.e. dev->parent points to the original device. -+ */ -+ if (dev->parent && dev->parent->of_node) -+ cp = of_get_property(dev->parent->of_node, "label", &len); -+ -+ if ((cp == NULL) || (len == 0)) { -+ cp = "unknown"; -+ len = strlen(cp) + 1; -+ } -+ -+ strncpy(buf, cp, len - 1); -+ buf[len - 1] = '\n'; -+ buf[len] = '\0'; -+ -+ return len; -+} -+ -+struct device_attribute retimer_class_dev_attrs[] = { -+ __ATTR_RO(label), -+ __ATTR_NULL, -+}; -+ -+static int __init retimer_init(void) -+{ -+ retimer_class = class_create(THIS_MODULE, RETIMER_CLASS_NAME); -+ if (IS_ERR(retimer_class)) { -+ pr_err("couldn't create sysfs class\n"); -+ return PTR_ERR(retimer_class); -+ } -+ -+ retimer_class->dev_attrs = retimer_class_dev_attrs; -+ -+ return 0; -+} -+ -+static void __exit retimer_exit(void) -+{ -+ class_destroy(retimer_class); -+} -+ -+subsys_initcall(retimer_init); -+module_exit(retimer_exit); -+ -+EXPORT_SYMBOL_GPL(retimer_device_register); -+EXPORT_SYMBOL_GPL(retimer_device_unregister); -+ -+MODULE_AUTHOR("Puneet Shenoy "); -+MODULE_DESCRIPTION("retimer sysfs/class support"); -+MODULE_LICENSE("GPL v2"); -diff --git a/include/linux/retimer_class.h b/include/linux/retimer_class.h -new file mode 100644 -index 0000000..6f37318 ---- /dev/null -+++ b/include/linux/retimer_class.h -@@ -0,0 +1,35 @@ -+/* -+ * retimer_class.c -+ * -+ * This file exports interface functions for the sysfs class "retimer", -+ * for use by RETIMER drivers. -+ * -+ * Copyright (C) 2014 Cumulus Networks, Inc. -+ * Author: Puneet Shenoy -+ * -+ * 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; version 2 of the License. -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ */ -+ -+#ifndef RETIMER_CLASS_H__ -+#define RETIMER_CLASS_H__ -+ -+#include -+#include -+ -+struct device *retimer_device_register(struct device *dev); -+ -+void retimer_device_unregister(struct device *dev); -+ -+#endif /* RETIMER_CLASS_H__ */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-early-dma-allocator.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-early-dma-allocator.patch deleted file mode 100644 index 5e1d0484..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-early-dma-allocator.patch +++ /dev/null @@ -1,357 +0,0 @@ -early dma allocator patch - -Add a tiny driver called "Early DMA Allocator (EDA)" that allocates -memory using the early boot alloc_bootmem() interface. The platform -dependent kernel code (dni_7448.c for example) would call this -driver's init at boot time. - -The size and alignment of the DMA memory region are specified in any -one of a kernel command line option, device tree node (compatible with -"early-dma-alloc"), or a Kbuild configurable compiled in default. - -The driver also publishes an interface for other kernel drivers -to call that returns the physical offset and size of the allocated -region. - -diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index b506f41..cfaf677 100644 ---- a/arch/x86/kernel/setup.c -+++ b/arch/x86/kernel/setup.c -@@ -50,6 +50,9 @@ - #include - #include - #include -+#ifdef CONFIG_EARLY_DMA_ALLOC -+#include -+#endif - - #include - #include -@@ -1144,6 +1147,9 @@ void __init setup_arch(char **cmdline_p) - mcheck_init(); - - arch_init_ideal_nops(); -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif - } - - #ifdef CONFIG_X86_32 -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 5664696..846aab1 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -500,6 +500,33 @@ config USB_SWITCH_FSA9480 - stereo and mono audio, video, microphone and UART data to use - a common connector port. - -+config EARLY_DMA_ALLOC -+ bool "Early DMA Memory Allocator" -+ depends on HAS_DMA -+ -+ ---help--- -+ This driver locks down a region of DMA accessible memory -+ early in the boot process. This memory can be used by other -+ drivers that might rmmod/insmod, insuring the memory region -+ does not become fragmented. -+ -+config EDA_DEF_SIZE -+ hex "EDA Default Region Size" -+ depends on EARLY_DMA_ALLOC -+ default 0x04000000 -+ help -+ Default size of the reserved memory pool, if not altered by the -+ open firmware interface or kernel boot parameter. This memory -+ will not be accessable to the rest of the system. Default is -+ 64MB. -+ -+config EDA_DEF_ALIGN -+ hex "EDA Default Alignment" -+ depends on EARLY_DMA_ALLOC -+ default 0x00100000 -+ help -+ Default alignment of the memory region. Default is 1MB. -+ - source "drivers/misc/c2port/Kconfig" - source "drivers/misc/eeprom/Kconfig" - source "drivers/misc/cb710/Kconfig" -diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index b26495a..cf09aa8 100644 ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -48,3 +48,4 @@ obj-y += lis3lv02d/ - obj-y += carma/ - obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o - obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ -+obj-$(CONFIG_EARLY_DMA_ALLOC) += early_dma_alloc.o -diff --git a/drivers/misc/early_dma_alloc.c b/drivers/misc/early_dma_alloc.c -new file mode 100644 -index 0000000..ab3ac32 ---- /dev/null -+++ b/drivers/misc/early_dma_alloc.c -@@ -0,0 +1,223 @@ -+/* -+ * Early DMA Memory Allocator -+ * -+ * Copyright © 2013,2014 Cumulus Networks, Inc. -+ * -+ * Author: Curt Brune -+ * Modified: Jonathan Toppins -+ * -+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ */ -+ -+/* -+ * This driver allocates a region of DMA accessible memory, making it -+ * available to one other device driver. -+ * -+ * The client device driver may be unloaded and reloaded over time. -+ * This driver keeps the DMA region from becoming fragmented across -+ * module reloads. -+ * -+ * Memory Region Restrictions -+ * -------------------------- -+ * The memory region allocated by EDA MUST exist below a 4GB limit. This -+ * is because EDA's primary (only at time of writing) user is the -+ * Broadcom BDE driver wich assumes a 32-bit physical address space and -+ * assumes paddr is no more than 32-bits wide. Furthermore, before porting -+ * the BDE driver to use EDA the BDE driver specifically checked if the -+ * memory region provided by highmem was less than 4GB. We assume Broadcom -+ * knew what they were doing and there is a specific reason why this 4GB -+ * limit is needed, so we enforce this limit by checking the physical address -+ * after allocation. -+ * -+ * Memory Region Size and Alignment -+ * -------------------------------- -+ * This driver allows three ways for the user to define the DMA memory -+ * that will be created, listed in order of preference. -+ * 1. The user may specify on the kernel command line in the boot loader -+ * the "eda_mem" option, this option has the format "size@alignment", -+ * example: eda_mem=0x04000000@0x00100000 -+ * 2. This driver looks for a device tree node compatible with -+ * "early-dma-alloc". The "region_size" property of the node contains -+ * the size, in bytes, of the desired DMA memory region. The -+ * "alignment" property contains the desired memory alignment of the -+ * region. -+ * 3. Finally if neither of the above are provided the Kbuild changable, -+ * compiled in default size and alignment will be used. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if (!defined CONFIG_EDA_DEF_SIZE) || \ -+ (!defined CONFIG_EDA_DEF_ALIGN) -+#error incorrect kernel config - fix it -+#endif -+ -+// #define DEBUG -+#if (defined DEBUG) -+#define eda_debug(fmt, ... ) \ -+ printk(KERN_ERR "eda-debug:%s(): " fmt "\n", __func__ , \ -+ ##__VA_ARGS__) -+#else -+#define eda_debug(fmt, ... ) -+#endif -+ -+#define eda_info(fmt, ... ) \ -+ printk(KERN_INFO "eda: " fmt "\n", ##__VA_ARGS__) -+ -+static uint32_t dma_size; -+static void *dma_vaddr; -+static u32 dma_align __initdata; -+static bool eda_cmdline __initdata; -+ -+static int __init setup_eda_mem(char *str) -+{ -+ char *endp; -+ -+ dma_size = memparse(str, &endp) & PAGE_MASK; -+ if (*endp == '@') -+ dma_align = memparse(endp + 1, NULL) & PAGE_MASK; -+ eda_cmdline = true; -+ return 0; -+} -+early_param("eda_mem", setup_eda_mem); -+ -+static int __init of_eda_init(uint32_t *size, u32 *align) -+#ifdef CONFIG_OF_FLATTREE -+{ -+ int rc = -ENODEV; -+ struct device_node *np = NULL; -+ const u32 *region_sz_p = NULL; -+ const u32 *align_p = NULL; -+ u32 prop_sz = 0; -+ -+ eda_debug("entry"); -+ -+ /* is a programming error make it really painful so it gets fixed */ -+ BUG_ON(NULL == size || NULL == align); -+ -+ np = of_find_compatible_node(NULL, NULL, "early-dma-alloc"); -+ if (!np) { -+ printk(KERN_WARNING "WARN: Can not find `early-dma-alloc'" -+ " device tree node.\n"); -+ goto cleanup; -+ } -+ -+ region_sz_p = of_get_property(np, "region_size", &prop_sz); -+ if (!region_sz_p || (prop_sz != sizeof(*region_sz_p))) { -+ printk(KERN_ERR "ERROR: Can not find `region_size' property" -+ " in early-dma-alloc device tree node.\n"); -+ goto cleanup; -+ } -+ *size = *region_sz_p; -+ -+ align_p = of_get_property(np, "alignment", &prop_sz); -+ if (!align_p || (prop_sz != sizeof(*align_p))) { -+ printk(KERN_ERR "ERROR: Can not find `alignment' property in" -+ "early-dma-alloc device tree node.\n"); -+ goto cleanup; -+ } -+ *align = *align_p; -+ rc = 0; -+ -+ eda_debug("cleanup"); -+ -+cleanup: -+ of_node_put(np); -+ return rc; -+ -+} -+#else -+{ -+ return -ENODEV; -+} -+#endif -+ -+int eda_dma_info_get(void **vaddr, uint32_t *paddr, uint32_t *size) -+{ -+ eda_debug("entry"); -+ -+ if (!dma_vaddr) -+ return -ENOMEM; -+ -+ if (!vaddr || !paddr || !size) -+ return -EINVAL; -+ -+ *vaddr = dma_vaddr; -+ *paddr = (uint32_t) virt_to_phys(dma_vaddr); -+ *size = dma_size; -+ -+ eda_debug("returning -- dma_vaddr: 0x%pK, dma_paddr: 0x%08x," -+ " size: 0x%08x", *vaddr, *paddr, *size); -+ -+ return 0; -+} -+EXPORT_SYMBOL(eda_dma_info_get); -+ -+int __init eda_init(void) -+{ -+ int rc = 0; -+ -+ if (eda_cmdline) { -+ if (!dma_align) -+ dma_align = CONFIG_EDA_DEF_ALIGN; -+ if (!dma_size) -+ dma_size = CONFIG_EDA_DEF_SIZE; -+ eda_debug("size & alignment came from: kernel cmdline"); -+ } else if (!of_eda_init(&dma_size, &dma_align)) { -+ eda_debug("size & alignment came from: open firmware entry"); -+ } else { -+ dma_align = CONFIG_EDA_DEF_ALIGN; -+ dma_size = CONFIG_EDA_DEF_SIZE; -+ eda_debug("size & alignment came from: compiled in defaults"); -+ } -+ -+ dma_vaddr = __alloc_bootmem_low(dma_size, dma_align, 0); -+ /* -+ * enforce EDA's requirement to allocate the memory region below a -+ * 32-bit limit. -+ */ -+ if (virt_to_phys(dma_vaddr) > 0xFFFFFFFFULL) { -+ rc = -ENOMEM; -+ printk(KERN_ERR "ERROR: DMA memory beyond 32-bit address" -+ " space not supported.\n"); -+ goto cleanup; -+ } -+ -+ eda_info("dma_vaddr: 0x%pK, dma_paddr: 0x%016llx, size: 0x%08x," -+ " alignment: 0x%08x", -+ dma_vaddr, (unsigned long long) virt_to_phys(dma_vaddr), -+ dma_size, dma_align); -+cleanup: -+ if (rc && dma_vaddr) { -+ free_bootmem(dma_vaddr, dma_size); -+ } -+ if (rc) { -+ dma_vaddr = NULL; -+ dma_size = 0; -+ } -+ return rc; -+} -+EXPORT_SYMBOL(eda_init); -diff --git a/include/linux/early_dma_alloc.h b/include/linux/early_dma_alloc.h -new file mode 100644 -index 0000000..a6d87ec ---- /dev/null -+++ b/include/linux/early_dma_alloc.h -@@ -0,0 +1,36 @@ -+/* -+ * Early DMA Memory Allocator -+ * -+ * Copyright © 2013 Cumulus Networks, Inc. -+ * -+ * Author: Curt Brune -+ * -+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ */ -+ -+#ifndef EARLY_DMA_ALLOC_H__ -+#define EARLY_DMA_ALLOC_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+extern int eda_init(void); -+extern int eda_dma_info_get(void** vaddr, uint32_t* paddr, uint32_t* size); -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* EARLY_DMA_ALLOC_H__ */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-eeprom-class.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-eeprom-class.patch deleted file mode 100644 index 629493a8..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-eeprom-class.patch +++ /dev/null @@ -1,345 +0,0 @@ -Create eeprom_dev hardware class for EEPROM devices - -Create a new hardware class under /sys/class/eeprom_dev - -EEPROM drivers can register their devices with the eeprom_dev class -during instantiation. - -The registered devices show up as: - - /sys/class/eeprom_dev/eeprom0 - /sys/class/eeprom_dev/eeprom1 - ... - /sys/class/eeprom_dev/eeprom[N] - -Each member of the eeprom class exports a sysfs file called "label", -containing the label property from the corresponding device tree node. - -Example: - - /sys/class/eeprom_dev/eeprom0/label - -If the device tree node property "label" does not exist the value -"unknown" is used. - -Userspace can use the label to identify what the EEPROM is for. - -The real device is available from the class device via the "device" -link: - - /sys/class/eeprom_dev/eeprom0/device - -diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig -index 701edf6..08c7a23 100644 ---- a/drivers/misc/eeprom/Kconfig -+++ b/drivers/misc/eeprom/Kconfig -@@ -1,5 +1,16 @@ - menu "EEPROM support" - -+config EEPROM_CLASS -+ tristate "EEPROM Hardware Class support" -+ depends on SYSFS -+ default y -+ help -+ Creates a hardware class in sysfs called "eeprom_dev", -+ providing a common place to register EEPROM devices. -+ -+ This support can also be built as a module. If so, the module -+ will be called eeprom_class. -+ - config EEPROM_AT24 - tristate "I2C EEPROMs from most vendors" - depends on I2C && SYSFS -diff --git a/drivers/misc/eeprom/Makefile b/drivers/misc/eeprom/Makefile -index fc1e81d..eabb373 100644 ---- a/drivers/misc/eeprom/Makefile -+++ b/drivers/misc/eeprom/Makefile -@@ -1,3 +1,4 @@ -+obj-$(CONFIG_EEPROM_CLASS) += eeprom_class.o - obj-$(CONFIG_EEPROM_AT24) += at24.o - obj-$(CONFIG_EEPROM_AT25) += at25.o - obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o -diff --git a/drivers/misc/eeprom/eeprom_class.c b/drivers/misc/eeprom/eeprom_class.c -new file mode 100644 -index 0000000..aecb778 ---- /dev/null -+++ b/drivers/misc/eeprom/eeprom_class.c -@@ -0,0 +1,193 @@ -+/* -+ * eeprom_class.c -+ * -+ * This file defines the sysfs class "eeprom", for use by EEPROM -+ * drivers. -+ * -+ * Copyright (C) 2013 Cumulus Networks, Inc. -+ * Author: Curt Brune -+ * -+ * Ideas and structure graciously borrowed from the hwmon class: -+ * Copyright (C) 2005 Mark M. Hoffman -+ * -+ * 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; version 2 of the License. -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Root eeprom "class" object (corresponds to '//class/eeprom_dev/') */ -+static struct class *eeprom_class; -+ -+#define EEPROM_CLASS_NAME "eeprom_dev" -+#define EEPROM_ID_PREFIX "eeprom" -+#define EEPROM_ID_FORMAT EEPROM_ID_PREFIX "%d" -+ -+static DEFINE_IDA(eeprom_ida); -+ -+/** -+ * eeprom_device_register - register w/ eeprom class -+ * @dev: the device to register -+ * @data: platform data to use for the device -+ * -+ * eeprom_device_unregister() must be called when the device is no -+ * longer needed. -+ * -+ * Creates a new eeprom class device that is a child of @dev. Also -+ * creates a symlink in //class/eeprom_dev/eeprom[N] pointing -+ * to the new device. -+ * -+ * Returns the pointer to the new device. -+ */ -+struct eeprom_device *eeprom_device_register(struct device *dev, struct eeprom_platform_data *data) -+{ -+ struct eeprom_device *eeprom_dev; -+ int id; -+ int ret; -+ -+ id = ida_simple_get(&eeprom_ida, 0, 0, GFP_KERNEL); -+ if (id < 0) -+ return ERR_PTR(id); -+ -+ eeprom_dev = kzalloc(sizeof(struct eeprom_device), GFP_KERNEL); -+ if (!eeprom_dev) { -+ ret = -ENOMEM; -+ goto err_ida; -+ } -+ -+ eeprom_dev->dev = device_create(eeprom_class, dev, MKDEV(0, 0), -+ eeprom_dev, EEPROM_ID_FORMAT, id); -+ if (IS_ERR(eeprom_dev->dev)) { -+ ret = PTR_ERR(eeprom_dev->dev); -+ goto err_eeprom_dev_free; -+ } -+ -+ eeprom_dev->data = data; -+ -+ return eeprom_dev; -+ -+err_eeprom_dev_free: -+ kfree(eeprom_dev); -+ -+err_ida: -+ ida_simple_remove(&eeprom_ida, id); -+ return ERR_PTR(ret); -+} -+ -+/** -+ * eeprom_device_unregister - removes the previously registered class device -+ * -+ * @eeprom: the eeprom class device to destroy -+ */ -+void eeprom_device_unregister(struct eeprom_device *eeprom_dev) -+{ -+ int id; -+ -+ if (likely(sscanf(dev_name(eeprom_dev->dev), EEPROM_ID_FORMAT, &id) == 1)) { -+ device_unregister(eeprom_dev->dev); -+ kfree(eeprom_dev); -+ ida_simple_remove(&eeprom_ida, id); -+ } else -+ dev_dbg(eeprom_dev->dev->parent, -+ "eeprom_device_unregister() failed: bad class ID!\n"); -+} -+ -+/** -+ * Each member of the eeprom class exports a sysfs file called -+ * "label", containing the label property from the corresponding -+ * device tree node. -+ * -+ * Userspace can use the label to identify what the EEPROM is for. -+ */ -+static ssize_t label_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct eeprom_device *eeprom_dev = (struct eeprom_device *)dev_get_drvdata(dev); -+ const char* cp = NULL; -+ int len = 0; -+ -+ /* Check if the eeprom device has an explicit label: -+ * - explicitly passed in to eeprom_device_register() -+ * - explicitly passed via the device tree node -+ * -+ * Otherwise use "unknown". -+ */ -+ if (eeprom_dev->data && eeprom_dev->data->label) { -+ cp = eeprom_dev->data->label; -+ len = strlen(cp) + 1; -+ } else { -+ /* -+ * Check for a device tree property. -+ * -+ * The class device is a child of the original device, -+ * i.e. dev->parent points to the original device. -+ */ -+ if (dev->parent && dev->parent->of_node) -+ cp = of_get_property(dev->parent->of_node, "label", &len); -+ } -+ -+ if ((cp == NULL) || (len == 0)) { -+ cp = "unknown"; -+ len = strlen(cp) + 1; -+ } -+ -+ strncpy(buf, cp, len - 1); -+ buf[len - 1] = '\n'; -+ buf[len] = '\0'; -+ -+ return len; -+} -+ -+struct device_attribute eeprom_class_dev_attrs[] = { -+ __ATTR_RO(label), -+ __ATTR_NULL, -+}; -+ -+static int __init eeprom_init(void) -+{ -+ eeprom_class = class_create(THIS_MODULE, EEPROM_CLASS_NAME); -+ if (IS_ERR(eeprom_class)) { -+ pr_err("couldn't create sysfs class\n"); -+ return PTR_ERR(eeprom_class); -+ } -+ -+ eeprom_class->dev_attrs = eeprom_class_dev_attrs; -+ -+ return 0; -+} -+ -+static void __exit eeprom_exit(void) -+{ -+ class_destroy(eeprom_class); -+} -+ -+subsys_initcall(eeprom_init); -+module_exit(eeprom_exit); -+ -+EXPORT_SYMBOL_GPL(eeprom_device_register); -+EXPORT_SYMBOL_GPL(eeprom_device_unregister); -+ -+MODULE_AUTHOR("Curt Brune "); -+MODULE_DESCRIPTION("eeprom sysfs/class support"); -+MODULE_LICENSE("GPL v2"); -diff --git a/include/linux/eeprom_class.h b/include/linux/eeprom_class.h -new file mode 100644 -index 0000000..d21d350 ---- /dev/null -+++ b/include/linux/eeprom_class.h -@@ -0,0 +1,79 @@ -+/* -+ * eeprom_class.h -+ * -+ * This file exports interface functions for the sysfs class "eeprom", -+ * for use by EEPROM drivers. -+ * -+ * Copyright (C) 2013 Cumulus Networks, Inc. -+ * Author: Curt Brune -+ * -+ * 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; version 2 of the License. -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ */ -+ -+#ifndef EEPROM_CLASS_H__ -+#define EEPROM_CLASS_H__ -+ -+#include -+#include -+ -+/* -+ * Extra platform data used by the eeprom class -+ * -+ * An eeprom device can include this structure in its own platform -+ * data structure. -+ * -+ * A specific platform can set the values in this structure to values -+ * suitable for that platform. -+ * -+ */ -+struct eeprom_platform_data { -+ char *label; /* device label to use with the eeprom class */ -+}; -+ -+/* -+ * EEPROM device structure -+ * -+ * This structure is used by the eeprom_class driver to manage the -+ * state of the class device. -+ * -+ */ -+struct eeprom_device { -+ struct device *dev; -+ struct eeprom_platform_data *data; -+}; -+ -+#if defined(CONFIG_EEPROM_CLASS) || defined (CONFIG_EEPROM_CLASS_MODULE) -+ -+extern struct eeprom_device * -+eeprom_device_register(struct device *dev, struct eeprom_platform_data *data); -+extern void -+eeprom_device_unregister(struct eeprom_device *eeprom_dev); -+ -+#else -+ -+static inline struct eeprom_device * -+eeprom_device_register(struct device *dev, char *label) -+{ -+ return NULL; -+} -+ -+static inline void -+eeprom_device_unregister(struct eeprom_device *eeprom_dev) -+{ -+} -+ -+#endif -+ -+#endif /* EEPROM_CLASS_H__ */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-esdhc-p2020-broken-timeout.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-esdhc-p2020-broken-timeout.patch deleted file mode 100644 index 8d8591ff..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-esdhc-p2020-broken-timeout.patch +++ /dev/null @@ -1,16 +0,0 @@ -The P2020 platforms have a broken timeout for the ESDHC device. -This patch forces the driver to use the maximum value. - -diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c -index 01e5f62..92c86bf 100644 ---- a/drivers/mmc/host/sdhci-of-esdhc.c -+++ b/drivers/mmc/host/sdhci-of-esdhc.c -@@ -98,7 +98,7 @@ static struct sdhci_ops sdhci_esdhc_ops = { - static struct sdhci_pltfm_data sdhci_esdhc_pdata = { - /* card detection could be handled via GPIO */ - .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION -- | SDHCI_QUIRK_NO_CARD_NO_RESET, -+ | SDHCI_QUIRK_NO_CARD_NO_RESET | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, - .ops = &sdhci_esdhc_ops, - }; - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-fsl-dpaa_eth.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-fsl-dpaa_eth.patch deleted file mode 100644 index db04de90..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-fsl-dpaa_eth.patch +++ /dev/null @@ -1,154125 +0,0 @@ -Freescale DPAA Ethernet Support - -diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig -index 491fa33..ca5290a 100644 ---- a/arch/powerpc/Kconfig -+++ b/arch/powerpc/Kconfig -@@ -693,6 +693,42 @@ config FSL_GTM - help - Freescale General-purpose Timers support - -+config HAS_FSL_PAMU -+ bool -+ default n -+ -+config FSL_PAMU -+ bool "PAMU/IOMMU support" -+ depends on HAS_FSL_PAMU -+ help -+ Freescale PAMU/IOMMU support -+ -+config FSL_PAMU_ERRATUM_A_004510 -+ bool "Enable PAMU work-around for erratum A-004510" -+ depends on FSL_PAMU -+ # For now, enable this by default, so that we don't have to update -+ # defconfigs. All current PAMU-enabled SOCs have the erratum. -+ default y -+ help -+ Select this option to enable a work-around for erratum A-004510 -+ in the Freescale PAMU device driver. Erratum A-004510 says that -+ under certain load conditions, modified cache lines can be discarded, -+ causing data corruption. This option enables the PAMU portion of -+ the work-around. -+ -+config FSL_FMAN_CPC_STASH -+ bool "Enable stashing of FMAN write transactions for ethernet ports" -+ depends on FSL_PAMU -+ default n -+ help -+ Select this option to enable stashing of incoming ethernet frames -+ from FMAN ports into platform cache. -+ -+config HAS_FSL_QBMAN -+ bool "Datapath Acceleration Queue and Buffer management" -+ help -+ Datapath Acceleration Queue and Buffer management -+ - # Yes MCA RS/6000s exist but Linux-PPC does not currently support any - config MCA - bool -diff --git a/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi -new file mode 100644 -index 0000000..0d13641 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi -@@ -0,0 +1,292 @@ -+/* -+ * B4420 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&ifc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,ifc", "simple-bus"; -+ interrupts = <25 2 0 0>; -+}; -+ -+/* controller at 0x200000 */ -+&pci0 { -+ compatible = "fsl,b4420-pcie", "fsl,qoriq-pcie-v2.4"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ interrupts = <20 2 0 0>; -+ pcie@0 { -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <20 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 40 1 0 0 -+ 0000 0 0 2 &mpic 1 1 0 0 -+ 0000 0 0 3 &mpic 2 1 0 0 -+ 0000 0 0 4 &mpic 3 1 0 0 -+ >; -+ }; -+}; -+ -+&bportals { -+/include/ "qoriq-bman2-portals.dtsi" -+}; -+&qportals { -+/include/ "qoriq-qman2-portals.dtsi" -+}; -+ -+&dcsr { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,dcsr", "simple-bus"; -+ -+ dcsr-epu@0 { -+ compatible = "fsl,b4420-dcsr-epu", "fsl,dcsr-epu"; -+ interrupts = <52 2 0 0 -+ 84 2 0 0 -+ 85 2 0 0 -+ 94 2 0 0 -+ 95 2 0 0>; -+ reg = <0x0 0x1000>; -+ }; -+ dcsr-npc { -+ compatible = "fsl,b4420-dcsr-cnpc", "fsl,dcsr-cnpc"; -+ reg = <0x1000 0x1000 0x1002000 0x10000>; -+ }; -+ dcsr-nxc@2000 { -+ compatible = "fsl,dcsr-nxc"; -+ reg = <0x2000 0x1000>; -+ }; -+ dcsr-corenet { -+ compatible = "fsl,dcsr-corenet"; -+ reg = <0x8000 0x1000 0x1A000 0x1000>; -+ }; -+ dcsr-dpaa@9000 { -+ compatible = "fsl,b4420-dcsr-dpaa", "fsl,dcsr-dpaa"; -+ reg = <0x9000 0x1000>; -+ }; -+ dcsr-ocn@11000 { -+ compatible = "fsl,b4420-dcsr-ocn", "fsl,dcsr-ocn"; -+ reg = <0x11000 0x1000>; -+ }; -+ dcsr-ddr@12000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr1>; -+ reg = <0x12000 0x1000>; -+ }; -+ dcsr-nal@18000 { -+ compatible = "fsl,b4420-dcsr-nal", "fsl,dcsr-nal"; -+ reg = <0x18000 0x1000>; -+ }; -+ dcsr-rcpm@22000 { -+ compatible = "fsl,b4420-dcsr-rcpm", "fsl,dcsr-rcpm"; -+ reg = <0x22000 0x1000>; -+ }; -+ dcsr-snpc@30000 { -+ compatible = "fsl,b4420-dcsr-snpc", "fsl,dcsr-snpc"; -+ reg = <0x30000 0x1000 0x1022000 0x10000>; -+ }; -+ dcsr-snpc@31000 { -+ compatible = "fsl,b4420-dcsr-snpc", "fsl,dcsr-snpc"; -+ reg = <0x31000 0x1000 0x1042000 0x10000>; -+ }; -+ dcsr-cpu-sb-proxy@100000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu0>; -+ reg = <0x100000 0x1000 0x101000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@108000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu1>; -+ reg = <0x108000 0x1000 0x109000 0x1000>; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "simple-bus"; -+ -+ soc-sram-error { -+ compatible = "fsl,soc-sram-error"; -+ interrupts = <16 2 1 2>; -+ }; -+ -+ corenet-law@0 { -+ compatible = "fsl,corenet-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <32>; -+ }; -+ -+ ddr1: memory-controller@8000 { -+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; -+ reg = <0x8000 0x1000>; -+ interrupts = <16 2 1 8>; -+ }; -+ -+ cpc: l3-cache-controller@10000 { -+ compatible = "fsl,p5020-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache"; -+ reg = <0x10000 0x1000>; -+ interrupts = <16 2 1 4>; -+ }; -+ -+ corenet-cf@18000 { -+ compatible = "fsl,corenet-cf"; -+ reg = <0x18000 0x1000>; -+ interrupts = <16 2 1 0>; -+ fsl,ccf-num-csdids = <32>; -+ fsl,ccf-num-snoopids = <32>; -+ }; -+ -+ iommu@20000 { -+ compatible = "fsl,pamu"; -+ reg = <0x20000 0x4000>; -+ interrupts = < -+ 24 2 0 0 -+ 16 2 1 1>; -+ }; -+ -+/include/ "qoriq-qman1.dtsi" -+ -+ qman: qman@318000 { -+ interrupts = <16 2 1 28>; -+ }; -+ -+/include/ "qoriq-bman1.dtsi" -+ -+ bman: bman@31a000 { -+ interrupts = <16 2 1 29>; -+ }; -+ -+/include/ "qoriq-fman3-0.dtsi" -+/include/ "qoriq-fman3-0-1g-0.dtsi" -+/include/ "qoriq-fman3-0-1g-1.dtsi" -+/include/ "qoriq-fman3-0-1g-2.dtsi" -+/include/ "qoriq-fman3-0-1g-3.dtsi" -+ fman0: fman@400000 { -+ interrupts = < -+ 96 2 0 0 -+ 16 2 1 30>; -+ -+ /* tx - 1g - 0 */ -+ port@a8000 { -+ fsl,qman-channel-id = <0x802>; -+ }; -+ /* tx - 1g - 1 */ -+ port@a9000 { -+ fsl,qman-channel-id = <0x803>; -+ }; -+ /* tx - 1g - 2 */ -+ port@aa000 { -+ fsl,qman-channel-id = <0x804>; -+ }; -+ /* tx - 1g - 3 */ -+ port@ab000 { -+ fsl,qman-channel-id = <0x805>; -+ }; -+ -+ /* offline - 0 is not usable on B4420 */ -+ /* offline - 1 */ -+ port@82000 { -+ fsl,qman-channel-id = <0x809>; -+ }; -+ /* offline - 2 */ -+ port@83000 { -+ fsl,qman-channel-id = <0x80a>; -+ }; -+ /* offline - 3 */ -+ port@84000 { -+ fsl,qman-channel-id = <0x80b>; -+ }; -+ /* offline - 4 */ -+ port@85000 { -+ fsl,qman-channel-id = <0x80c>; -+ }; -+ /* offline - 5 */ -+ port@86000 { -+ fsl,qman-channel-id = <0x80d>; -+ }; -+ /* offline - 6 */ -+ port@87000 { -+ fsl,qman-channel-id = <0x80e>; -+ }; -+ }; -+ -+/include/ "qoriq-mpic.dtsi" -+ -+ guts: global-utilities@e0000 { -+ compatible = "fsl,b4420-device-config"; -+ reg = <0xe0000 0xe00>; -+ fsl,has-rstcr; -+ fsl,liodn-bits = <12>; -+ }; -+ -+ rcpm: global-utilities@e2000 { -+ compatible = "fsl,b4420-rcpm", "fsl,qoriq-rcpm-2"; -+ reg = <0xe2000 0x1000>; -+ }; -+ -+/include/ "qoriq-dma-0.dtsi" -+/include/ "qoriq-dma-1.dtsi" -+ -+/include/ "qonverge-usb2-dr-0.dtsi" -+ usb0: usb@210000 { -+ compatible = "fsl-usb2-dr-v2.4", "fsl-usb2-dr"; -+ }; -+ -+/include/ "qoriq-espi-0.dtsi" -+ spi@110000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "qoriq-esdhc-0.dtsi" -+ sdhc@114000 { -+ sdhci,auto-cmd12; -+ }; -+/include/ "qoriq-i2c-0.dtsi" -+/include/ "qoriq-i2c-1.dtsi" -+/include/ "qoriq-duart-0.dtsi" -+/include/ "qoriq-duart-1.dtsi" -+/include/ "qoriq-sec5.3-0.dtsi" -+ -+ L2: l2-cache-controller@c20000 { -+ next-level-cache = <&cpc>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi -new file mode 100644 -index 0000000..9493fb0 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi -@@ -0,0 +1,83 @@ -+/* -+ * B4420 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+/ { -+ compatible = "fsl,B4420"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ ccsr = &soc; -+ dcsr = &dcsr; -+ -+ serial0 = &serial0; -+ serial1 = &serial1; -+ serial2 = &serial2; -+ serial3 = &serial3; -+ pci0 = &pci0; -+ dma0 = &dma0; -+ dma1 = &dma1; -+ sdhc = &sdhc; -+ -+ fman0 = &fman0; -+ crypto = &crypto; -+ sec_jr0 = &sec_jr0; -+ sec_jr1 = &sec_jr1; -+ sec_jr2 = &sec_jr2; -+ sec_jr3 = &sec_jr3; -+ rtic_a = &rtic_a; -+ rtic_b = &rtic_b; -+ rtic_c = &rtic_c; -+ rtic_d = &rtic_d; -+ sec_mon = &sec_mon; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu0: PowerPC,e6500@0 { -+ device_type = "cpu"; -+ reg = <0 1>; -+ next-level-cache = <&L2>; -+ }; -+ cpu1: PowerPC,e6500@1 { -+ device_type = "cpu"; -+ reg = <2 3>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi -new file mode 100644 -index 0000000..818f652 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi -@@ -0,0 +1,356 @@ -+/* -+ * B4860 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&ifc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,ifc", "simple-bus"; -+ interrupts = <25 2 0 0>; -+}; -+ -+/* controller at 0x200000 */ -+&pci0 { -+ compatible = "fsl,b4860-pcie", "fsl,qoriq-pcie-v2.4"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ interrupts = <20 2 0 0>; -+ pcie@0 { -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <20 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 40 1 0 0 -+ 0000 0 0 2 &mpic 1 1 0 0 -+ 0000 0 0 3 &mpic 2 1 0 0 -+ 0000 0 0 4 &mpic 3 1 0 0 -+ >; -+ }; -+}; -+ -+&rio { -+ compatible = "fsl,srio"; -+ interrupts = <16 2 1 11>; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ port1 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <1>; -+ }; -+ -+ port2 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <2>; -+ }; -+}; -+ -+&bportals { -+/include/ "qoriq-bman2-portals.dtsi" -+}; -+&qportals { -+/include/ "qoriq-qman2-portals.dtsi" -+}; -+ -+&dcsr { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,dcsr", "simple-bus"; -+ -+ dcsr-epu@0 { -+ compatible = "fsl,b4860-dcsr-epu", "fsl,dcsr-epu"; -+ interrupts = <52 2 0 0 -+ 84 2 0 0 -+ 85 2 0 0 -+ 94 2 0 0 -+ 95 2 0 0>; -+ reg = <0x0 0x1000>; -+ }; -+ dcsr-npc { -+ compatible = "fsl,b4860-dcsr-cnpc", "fsl,dcsr-cnpc"; -+ reg = <0x1000 0x1000 0x1002000 0x10000>; -+ }; -+ dcsr-nxc@2000 { -+ compatible = "fsl,dcsr-nxc"; -+ reg = <0x2000 0x1000>; -+ }; -+ dcsr-corenet { -+ compatible = "fsl,dcsr-corenet"; -+ reg = <0x8000 0x1000 0x1A000 0x1000>; -+ }; -+ dcsr-dpaa@9000 { -+ compatible = "fsl,b4860-dcsr-dpaa", "fsl,dcsr-dpaa"; -+ reg = <0x9000 0x1000>; -+ }; -+ dcsr-ocn@11000 { -+ compatible = "fsl,b4860-dcsr-ocn", "fsl,dcsr-ocn"; -+ reg = <0x11000 0x1000>; -+ }; -+ dcsr-ddr@12000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr1>; -+ reg = <0x12000 0x1000>; -+ }; -+ dcsr-ddr@13000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr2>; -+ reg = <0x13000 0x1000>; -+ }; -+ dcsr-nal@18000 { -+ compatible = "fsl,b4860-dcsr-nal", "fsl,dcsr-nal"; -+ reg = <0x18000 0x1000>; -+ }; -+ dcsr-rcpm@22000 { -+ compatible = "fsl,b4860-dcsr-rcpm", "fsl,dcsr-rcpm"; -+ reg = <0x22000 0x1000>; -+ }; -+ dcsr-snpc@30000 { -+ compatible = "fsl,b4860-dcsr-snpc", "fsl,dcsr-snpc"; -+ reg = <0x30000 0x1000 0x1022000 0x10000>; -+ }; -+ dcsr-snpc@31000 { -+ compatible = "fsl,b4860-dcsr-snpc", "fsl,dcsr-snpc"; -+ reg = <0x31000 0x1000 0x1042000 0x10000>; -+ }; -+ dcsr-cpu-sb-proxy@100000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu0>; -+ reg = <0x100000 0x1000 0x101000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@108000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu1>; -+ reg = <0x108000 0x1000 0x109000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@110000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu2>; -+ reg = <0x110000 0x1000 0x111000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@118000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu3>; -+ reg = <0x118000 0x1000 0x119000 0x1000>; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "simple-bus"; -+ -+ soc-sram-error { -+ compatible = "fsl,soc-sram-error"; -+ interrupts = <16 2 1 2>; -+ }; -+ -+ corenet-law@0 { -+ compatible = "fsl,corenet-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <32>; -+ }; -+ -+ ddr1: memory-controller@8000 { -+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; -+ reg = <0x8000 0x1000>; -+ interrupts = <16 2 1 8>; -+ }; -+ -+ ddr2: memory-controller@9000 { -+ compatible = "fsl,qoriq-memory-controller-v4.5","fsl,qoriq-memory-controller"; -+ reg = <0x9000 0x1000>; -+ interrupts = <16 2 1 9>; -+ }; -+ -+ cpc: l3-cache-controller@10000 { -+ compatible = "fsl,p5020-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache"; -+ reg = <0x10000 0x1000 -+ 0x11000 0x1000>; -+ interrupts = <16 2 1 4 -+ 16 2 1 5>; -+ }; -+ -+ corenet-cf@18000 { -+ compatible = "fsl,corenet-cf"; -+ reg = <0x18000 0x1000>; -+ interrupts = <16 2 1 0>; -+ fsl,ccf-num-csdids = <32>; -+ fsl,ccf-num-snoopids = <32>; -+ }; -+ -+ iommu@20000 { -+ compatible = "fsl,pamu-v1.0", "fsl,pamu"; -+ reg = <0x20000 0x4000>; -+ interrupts = < -+ 24 2 0 0 -+ 16 2 1 1>; -+ }; -+ -+/include/ "qoriq-qman1.dtsi" -+ -+ qman: qman@318000 { -+ interrupts = <16 2 1 28>; -+ }; -+ -+/include/ "qoriq-bman1.dtsi" -+ -+ bman: bman@31a000 { -+ interrupts = <16 2 1 29>; -+ }; -+ -+/include/ "qoriq-rman-0.dtsi" -+ rman: rman@1e0000 { -+ fsl,qman-channels-id = <0x820 0x821>; -+ }; -+ -+/include/ "qoriq-fman3-0.dtsi" -+/include/ "qoriq-fman3-0-1g-0.dtsi" -+/include/ "qoriq-fman3-0-1g-1.dtsi" -+/include/ "qoriq-fman3-0-1g-2.dtsi" -+/include/ "qoriq-fman3-0-1g-3.dtsi" -+/include/ "qoriq-fman3-0-1g-4.dtsi" -+/include/ "qoriq-fman3-0-1g-5.dtsi" -+/include/ "qoriq-fman3-0-10g-0.dtsi" -+/include/ "qoriq-fman3-0-10g-1.dtsi" -+ fman0: fman@400000 { -+ interrupts = < -+ 96 2 0 0 -+ 16 2 1 30>; -+ -+ /* tx - 1g - 0 */ -+ port@a8000 { -+ fsl,qman-channel-id = <0x802>; -+ }; -+ /* tx - 1g - 1 */ -+ port@a9000 { -+ fsl,qman-channel-id = <0x803>; -+ }; -+ /* tx - 1g - 2 */ -+ port@aa000 { -+ fsl,qman-channel-id = <0x804>; -+ }; -+ /* tx - 1g - 3 */ -+ port@ab000 { -+ fsl,qman-channel-id = <0x805>; -+ }; -+ /* tx - 1g - 4 */ -+ port@ac000 { -+ fsl,qman-channel-id = <0x806>; -+ }; -+ /* tx - 1g - 5 */ -+ port@ad000 { -+ fsl,qman-channel-id = <0x807>; -+ }; -+ /* offline - 0 is not usable on B4860 */ -+ /* offline - 1 */ -+ port@82000 { -+ fsl,qman-channel-id = <0x809>; -+ }; -+ /* offline - 2 */ -+ port@83000 { -+ fsl,qman-channel-id = <0x80a>; -+ }; -+ /* offline - 3 */ -+ port@84000 { -+ fsl,qman-channel-id = <0x80b>; -+ }; -+ /* offline - 4 */ -+ port@85000 { -+ fsl,qman-channel-id = <0x80c>; -+ }; -+ /* offline - 5 */ -+ port@86000 { -+ fsl,qman-channel-id = <0x80d>; -+ }; -+ /* offline - 6 */ -+ port@87000 { -+ fsl,qman-channel-id = <0x80e>; -+ }; -+ }; -+ -+/include/ "qoriq-mpic.dtsi" -+ -+ guts: global-utilities@e0000 { -+ compatible = "fsl,b4860-device-config"; -+ reg = <0xe0000 0xe00>; -+ fsl,has-rstcr; -+ fsl,liodn-bits = <12>; -+ }; -+ -+ clockgen: global-utilities@e1000 { -+ compatible = "fsl,b4860-clockgen", "fsl,qoriq-clockgen-2"; -+ reg = <0xe1000 0x1000>; -+ }; -+ -+ rcpm: global-utilities@e2000 { -+ compatible = "fsl,b4860-rcpm", "fsl,qoriq-rcpm-2"; -+ reg = <0xe2000 0x1000>; -+ }; -+ -+/include/ "qoriq-dma-0.dtsi" -+/include/ "qoriq-dma-1.dtsi" -+ -+/include/ "qonverge-usb2-dr-0.dtsi" -+ usb0: usb@210000 { -+ compatible = "fsl-usb2-dr-v2.4", "fsl-usb2-dr"; -+ }; -+ -+/include/ "qoriq-espi-0.dtsi" -+ spi@110000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "qoriq-esdhc-0.dtsi" -+ sdhc@114000 { -+ sdhci,auto-cmd12; -+ }; -+/include/ "qoriq-i2c-0.dtsi" -+/include/ "qoriq-i2c-1.dtsi" -+/include/ "qoriq-duart-0.dtsi" -+/include/ "qoriq-duart-1.dtsi" -+/include/ "qoriq-sec5.3-0.dtsi" -+ -+ L2: l2-cache-controller@c20000 { -+ next-level-cache = <&cpc>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi -new file mode 100644 -index 0000000..eb441da ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi -@@ -0,0 +1,93 @@ -+/* -+ * B4860 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+/ { -+ compatible = "fsl,B4860"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ ccsr = &soc; -+ dcsr = &dcsr; -+ -+ serial0 = &serial0; -+ serial1 = &serial1; -+ serial2 = &serial2; -+ serial3 = &serial3; -+ pci0 = &pci0; -+ dma0 = &dma0; -+ dma1 = &dma1; -+ sdhc = &sdhc; -+ -+ fman0 = &fman0; -+ crypto = &crypto; -+ sec_jr0 = &sec_jr0; -+ sec_jr1 = &sec_jr1; -+ sec_jr2 = &sec_jr2; -+ sec_jr3 = &sec_jr3; -+ rtic_a = &rtic_a; -+ rtic_b = &rtic_b; -+ rtic_c = &rtic_c; -+ rtic_d = &rtic_d; -+ sec_mon = &sec_mon; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu0: PowerPC,e6500@0 { -+ device_type = "cpu"; -+ reg = <0 1>; -+ next-level-cache = <&L2>; -+ }; -+ cpu1: PowerPC,e6500@1 { -+ device_type = "cpu"; -+ reg = <2 3>; -+ next-level-cache = <&L2>; -+ }; -+ cpu2: PowerPC,e6500@2 { -+ device_type = "cpu"; -+ reg = <4 5>; -+ next-level-cache = <&L2>; -+ }; -+ cpu3: PowerPC,e6500@3 { -+ device_type = "cpu"; -+ reg = <6 7>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/bsc9131si-post.dtsi b/arch/powerpc/boot/dts/fsl/bsc9131si-post.dtsi -new file mode 100644 -index 0000000..5180d9d ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/bsc9131si-post.dtsi -@@ -0,0 +1,193 @@ -+/* -+ * BSC9131 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&ifc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,ifc", "simple-bus"; -+ interrupts = <16 2 0 0 20 2 0 0>; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,bsc9131-immr", "simple-bus"; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,bsc9131-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,bsc9131-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-i2c-0.dtsi" -+ i2c@3000 { -+ interrupts = <17 2 0 0>; -+ }; -+ -+/include/ "pq3-i2c-1.dtsi" -+ i2c@3100 { -+ interrupts = <17 2 0 0>; -+ }; -+ -+/include/ "pq3-duart-0.dtsi" -+ serial0: serial@4500 { -+ interrupts = <18 2 0 0>; -+ }; -+ -+ serial1: serial@4600 { -+ interrupts = <18 2 0 0 >; -+ }; -+/include/ "pq3-espi-0.dtsi" -+ spi0: spi@7000 { -+ fsl,espi-num-chipselects = <1>; -+ interrupts = <22 0x2 0 0>; -+ }; -+ -+/include/ "pq3-gpio-0.dtsi" -+ gpio-controller@f000 { -+ interrupts = <19 0x2 0 0>; -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,bsc9131-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x40000>; // L2,256K -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-dma-0.dtsi" -+ -+dma@21300 { -+ -+ dma-channel@0 { -+ interrupts = <62 2 0 0>; -+ }; -+ -+ dma-channel@80 { -+ interrupts = <63 2 0 0>; -+ }; -+ -+ dma-channel@100 { -+ interrupts = <64 2 0 0>; -+ }; -+ -+ dma-channel@180 { -+ interrupts = <65 2 0 0>; -+ }; -+}; -+ -+/include/ "pq3-usb2-dr-0.dtsi" -+usb@22000 { -+ compatible = "fsl-usb2-dr","fsl-usb2-dr-v2.2"; -+ interrupts = <40 0x2 0 0>; -+}; -+ -+/include/ "pq3-esdhc-0.dtsi" -+ sdhc@2e000 { -+ fsl,sdhci-auto-cmd12; -+ interrupts = <41 0x2 0 0>; -+ }; -+ -+/include/ "pq3-sec4.4-0.dtsi" -+crypto@30000 { -+ interrupts = <57 2 0 0>; -+ -+ sec_jr0: jr@1000 { -+ interrupts = <58 2 0 0>; -+ }; -+ -+ sec_jr1: jr@2000 { -+ interrupts = <59 2 0 0>; -+ }; -+ -+ sec_jr2: jr@3000 { -+ interrupts = <60 2 0 0>; -+ }; -+ -+ sec_jr3: jr@4000 { -+ interrupts = <61 2 0 0>; -+ }; -+}; -+ -+/include/ "pq3-mpic.dtsi" -+ -+timer@41100 { -+ compatible = "fsl,mpic-v1.2-msgr", "fsl,mpic-msg"; -+ reg = <0x41400 0x200>; -+ interrupts = < -+ 0xb0 2 -+ 0xb1 2 -+ 0xb2 2 -+ 0xb3 2>; -+}; -+ -+/include/ "pq3-etsec2-0.dtsi" -+enet0: ethernet@b0000 { -+ queue-group@b0000 { -+ fsl,rx-bit-map = <0xff>; -+ fsl,tx-bit-map = <0xff>; -+ interrupts = <26 2 0 0 27 2 0 0 28 2 0 0>; -+ }; -+}; -+ -+/include/ "pq3-etsec2-1.dtsi" -+enet1: ethernet@b1000 { -+ queue-group@b1000 { -+ fsl,rx-bit-map = <0xff>; -+ fsl,tx-bit-map = <0xff>; -+ interrupts = <33 2 0 0 34 2 0 0 35 2 0 0>; -+ }; -+}; -+ -+global-utilities@e0000 { -+ compatible = "fsl,bsc9131-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/bsc9131si-pre.dtsi b/arch/powerpc/boot/dts/fsl/bsc9131si-pre.dtsi -new file mode 100644 -index 0000000..743e4ae ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/bsc9131si-pre.dtsi -@@ -0,0 +1,59 @@ -+/* -+ * BSC9131 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+/ { -+ compatible = "fsl,BSC9131"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ serial0 = &serial0; -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,BSC9131@0 { -+ device_type = "cpu"; -+ compatible = "fsl,e500v2"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi b/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi -new file mode 100644 -index 0000000..870c653 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi -@@ -0,0 +1,58 @@ -+/* -+ * e500mc Power ISA Device Tree Source (include) -+ * -+ * 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. -+ */ -+ -+/ { -+ cpus { -+ power-isa-version = "2.06"; -+ power-isa-b; // Base -+ power-isa-e; // Embedded -+ power-isa-atb; // Alternate Time Base -+ power-isa-cs; // Cache Specification -+ power-isa-ds; // Decorated Storage -+ power-isa-e.ed; // Embedded.Enhanced Debug -+ power-isa-e.pd; // Embedded.External PID -+ power-isa-e.hv; // Embedded.Hypervisor -+ power-isa-e.le; // Embedded.Little-Endian -+ power-isa-e.pm; // Embedded.Performance Monitor -+ power-isa-e.pc; // Embedded.Processor Control -+ power-isa-ecl; // Embedded Cache Locking -+ power-isa-exp; // External Proxy -+ power-isa-fp; // Floating Point -+ power-isa-fp.r; // Floating Point.Record -+ power-isa-mmc; // Memory Coherence -+ power-isa-scpm; // Store Conditional Page Mobility -+ power-isa-wt; // Wait -+ mmu-type = "power-embedded"; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/e500v2_power_isa.dtsi b/arch/powerpc/boot/dts/fsl/e500v2_power_isa.dtsi -new file mode 100644 -index 0000000..f492814 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/e500v2_power_isa.dtsi -@@ -0,0 +1,52 @@ -+/* -+ * e500v2 Power ISA Device Tree Source (include) -+ * -+ * 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. -+ */ -+ -+/ { -+ cpus { -+ power-isa-version = "2.03"; -+ power-isa-b; // Base -+ power-isa-e; // Embedded -+ power-isa-atb; // Alternate Time Base -+ power-isa-cs; // Cache Specification -+ power-isa-e.le; // Embedded.Little-Endian -+ power-isa-e.pm; // Embedded.Performance Monitor -+ power-isa-ecl; // Embedded Cache Locking -+ power-isa-mmc; // Memory Coherence -+ power-isa-sp; // Signal Processing Engine -+ power-isa-sp.fd; // SPE.Embedded Float Scalar Double -+ power-isa-sp.fs; // SPE.Embedded Float Scalar Single -+ power-isa-sp.fv; // SPE.Embedded Float Vector -+ mmu-type = "power-embedded"; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi b/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi -new file mode 100644 -index 0000000..3230212 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi -@@ -0,0 +1,59 @@ -+/* -+ * e5500 Power ISA Device Tree Source (include) -+ * -+ * 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. -+ */ -+ -+/ { -+ cpus { -+ power-isa-version = "2.06"; -+ power-isa-b; // Base -+ power-isa-e; // Embedded -+ power-isa-atb; // Alternate Time Base -+ power-isa-cs; // Cache Specification -+ power-isa-ds; // Decorated Storage -+ power-isa-e.ed; // Embedded.Enhanced Debug -+ power-isa-e.pd; // Embedded.External PID -+ power-isa-e.hv; // Embedded.Hypervisor -+ power-isa-e.le; // Embedded.Little-Endian -+ power-isa-e.pm; // Embedded.Performance Monitor -+ power-isa-e.pc; // Embedded.Processor Control -+ power-isa-ecl; // Embedded Cache Locking -+ power-isa-exp; // External Proxy -+ power-isa-fp; // Floating Point -+ power-isa-fp.r; // Floating Point.Record -+ power-isa-mmc; // Memory Coherence -+ power-isa-scpm; // Store Conditional Page Mobility -+ power-isa-wt; // Wait -+ power-isa-64; // 64-bit -+ mmu-type = "power-embedded"; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/interlaken-lac-portals.dtsi b/arch/powerpc/boot/dts/fsl/interlaken-lac-portals.dtsi -new file mode 100644 -index 0000000..9cffccf ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/interlaken-lac-portals.dtsi -@@ -0,0 +1,156 @@ -+/* T4240 Interlaken LAC Portal device tree stub with 24 portals. -+ * -+ * 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. -+ */ -+ -+#address-cells = <0x1>; -+#size-cells = <0x1>; -+compatible = "fsl,interlaken-lac-portals"; -+ -+lportal0: lac-portal@0 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x0 0x1000>; -+}; -+ -+lportal1: lac-portal@1000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x1000 0x1000>; -+}; -+ -+lportal2: lac-portal@2000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x2000 0x1000>; -+}; -+ -+lportal3: lac-portal@3000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x3000 0x1000>; -+}; -+ -+lportal4: lac-portal@4000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x4000 0x1000>; -+}; -+ -+lportal5: lac-portal@5000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x5000 0x1000>; -+}; -+ -+lportal6: lac-portal@6000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x6000 0x1000>; -+}; -+ -+lportal7: lac-portal@7000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x7000 0x1000>; -+}; -+ -+lportal8: lac-portal@8000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x8000 0x1000>; -+}; -+ -+lportal9: lac-portal@9000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x9000 0x1000>; -+}; -+ -+lportal10: lac-portal@A000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0xA000 0x1000>; -+}; -+ -+lportal11: lac-portal@B000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0xB000 0x1000>; -+}; -+ -+lportal12: lac-portal@C000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0xC000 0x1000>; -+}; -+ -+lportal13: lac-portal@D000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0xD000 0x1000>; -+}; -+ -+lportal14: lac-portal@E000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0xE000 0x1000>; -+}; -+ -+lportal15: lac-portal@F000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0xF000 0x1000>; -+}; -+ -+lportal16: lac-portal@10000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x10000 0x1000>; -+}; -+ -+lportal17: lac-portal@11000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x11000 0x1000>; -+}; -+ -+lportal18: lac-portal@1200 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x12000 0x1000>; -+}; -+ -+lportal19: lac-portal@13000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x13000 0x1000>; -+}; -+ -+lportal20: lac-portal@14000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x14000 0x1000>; -+}; -+ -+lportal21: lac-portal@15000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x15000 0x1000>; -+}; -+ -+lportal22: lac-portal@16000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x16000 0x1000>; -+}; -+ -+lportal23: lac-portal@17000 { -+ compatible = "fsl,interlaken-lac-portal-v1.0"; -+ reg = <0x17000 0x1000>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/interlaken-lac.dtsi b/arch/powerpc/boot/dts/fsl/interlaken-lac.dtsi -new file mode 100644 -index 0000000..e820872 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/interlaken-lac.dtsi -@@ -0,0 +1,45 @@ -+/* -+ * T4 Interlaken Look-aside Controller (LAC) device tree stub -+ * -+ * 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. -+ */ -+ -+lac: lac@229000 { -+ compatible = "fsl,interlaken-lac"; -+ reg = <0x229000 0x1000>; -+ interrupts = <16 2 1 18>; -+}; -+ -+lac-hv@228000 { -+ compatible = "fsl,interlaken-lac-hv"; -+ reg = <0x228000 0x1000>; -+ fsl,non-hv-node = <&lac>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi -new file mode 100644 -index 0000000..900f117 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi -@@ -0,0 +1,262 @@ -+/* -+ * MPC8536 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8536-elbc", "fsl,elbc", "simple-bus"; -+ interrupts = <19 2 0 0>; -+}; -+ -+/* controller at 0x8000 */ -+&pci0 { -+ compatible = "fsl,mpc8540-pci"; -+ device_type = "pci"; -+ interrupts = <24 0x2 0 0>; -+ bus-range = <0 0xff>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+}; -+ -+/* controller at 0x9000 */ -+&pci1 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <25 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <25 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x4 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x5 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+/* controller at 0xa000 */ -+&pci2 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <26 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <26 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+/* controller at 0xb000 */ -+&pci3 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <27 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <27 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x8 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x9 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0xa 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0xb 0x1 0x0 0x0 -+ >; -+ }; -+}; -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,mpc8536-immr", "simple-bus"; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,mpc8536-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2 0 0>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,mpc8536-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <18 2 0 0>; -+ }; -+ -+/include/ "pq3-i2c-0.dtsi" -+/include/ "pq3-i2c-1.dtsi" -+/include/ "pq3-duart-0.dtsi" -+ -+/include/ "pq3-espi-0.dtsi" -+ spi@7000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "pq3-gpio-0.dtsi" -+ -+ /* mark compat w/8572 to get some erratum treatment */ -+ gpio-controller@f000 { -+ compatible = "fsl,mpc8572-gpio", "fsl,pq3-gpio"; -+ }; -+ -+ sata@18000 { -+ compatible = "fsl,mpc8536-sata", "fsl,pq-sata"; -+ reg = <0x18000 0x1000>; -+ cell-index = <1>; -+ interrupts = <74 0x2 0 0>; -+ }; -+ -+ sata@19000 { -+ compatible = "fsl,mpc8536-sata", "fsl,pq-sata"; -+ reg = <0x19000 0x1000>; -+ cell-index = <2>; -+ interrupts = <41 0x2 0 0>; -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,mpc8536-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x80000>; // L2, 512K -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-dma-0.dtsi" -+/include/ "pq3-etsec1-0.dtsi" -+ enet0: ethernet@24000 { -+ fsl,wake-on-filer; -+ fsl,pmc-handle = <&etsec1_clk>; -+ }; -+/include/ "pq3-etsec1-timer-0.dtsi" -+ -+ usb@22000 { -+ compatible = "fsl-usb2-mph-v1.2", "fsl,mpc8536-usb2-mph", "fsl-usb2-mph"; -+ reg = <0x22000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = <28 0x2 0 0>; -+ }; -+ -+ usb@23000 { -+ compatible = "fsl-usb2-mph-v1.2", "fsl,mpc8536-usb2-mph", "fsl-usb2-mph"; -+ reg = <0x23000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = <46 0x2 0 0>; -+ }; -+ -+ ptp_clock@24e00 { -+ interrupts = <68 2 0 0 69 2 0 0 70 2 0 0 71 2 0 0>; -+ }; -+ -+/include/ "pq3-etsec1-2.dtsi" -+ enet2: ethernet@26000 { -+ cell-index = <1>; -+ fsl,wake-on-filer; -+ fsl,pmc-handle = <&etsec3_clk>; -+ }; -+ -+ usb@2b000 { -+ compatible = "fsl,mpc8536-usb2-dr", "fsl-usb2-dr"; -+ reg = <0x2b000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = <60 0x2 0 0>; -+ }; -+ -+/include/ "pq3-esdhc-0.dtsi" -+ sdhc@2e000 { -+ compatible = "fsl,mpc8536-esdhc", "fsl,esdhc"; -+ }; -+ -+/include/ "pq3-sec3.0-0.dtsi" -+/include/ "pq3-mpic.dtsi" -+/include/ "pq3-mpic-timer-B.dtsi" -+ -+ global-utilities@e0000 { -+ compatible = "fsl,mpc8536-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ -+/include/ "pq3-power.dtsi" -+ power@e0070 { -+ compatible = "fsl,mpc8536-pmc", "fsl,mpc8548-pmc"; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/mpc8536si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536si-pre.dtsi -new file mode 100644 -index 0000000..152906f ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/mpc8536si-pre.dtsi -@@ -0,0 +1,66 @@ -+/* -+ * MPC8536 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500v2_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,MPC8536"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ ethernet0 = &enet0; -+ ethernet1 = &enet2; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ pci3 = &pci3; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8536@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi -new file mode 100644 -index 0000000..ea7416a ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi -@@ -0,0 +1,193 @@ -+/* -+ * MPC8544 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8544-lbc", "fsl,pq3-localbus", "simple-bus"; -+ interrupts = <19 2 0 0>; -+}; -+ -+/* controller at 0x8000 */ -+&pci0 { -+ compatible = "fsl,mpc8540-pci"; -+ device_type = "pci"; -+ interrupts = <24 0x2 0 0>; -+ bus-range = <0 0xff>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+}; -+ -+/* controller at 0x9000 */ -+&pci1 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <25 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <25 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x4 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x5 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+/* controller at 0xa000 */ -+&pci2 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <26 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <26 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+/* controller at 0xb000 */ -+&pci3 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <27 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <27 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x8 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x9 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0xa 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0xb 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,mpc8544-immr", "simple-bus"; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <10>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,mpc8544-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2 0 0>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,mpc8544-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <18 2 0 0>; -+ }; -+ -+/include/ "pq3-i2c-0.dtsi" -+/include/ "pq3-i2c-1.dtsi" -+/include/ "pq3-duart-0.dtsi" -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,mpc8544-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x40000>; // L2, 256K -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-dma-0.dtsi" -+/include/ "pq3-etsec1-0.dtsi" -+/include/ "pq3-etsec1-2.dtsi" -+ -+ ethernet@26000 { -+ cell-index = <1>; -+ }; -+ -+/include/ "pq3-sec2.1-0.dtsi" -+/include/ "pq3-mpic.dtsi" -+ -+ global-utilities@e0000 { -+ compatible = "fsl,mpc8544-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ -+/include/ "pq3-power.dtsi" -+}; -diff --git a/arch/powerpc/boot/dts/fsl/mpc8544si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8544si-pre.dtsi -new file mode 100644 -index 0000000..5a69baf ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/mpc8544si-pre.dtsi -@@ -0,0 +1,66 @@ -+/* -+ * MPC8544 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500v2_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,MPC8544"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ ethernet0 = &enet0; -+ ethernet1 = &enet2; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ pci3 = &pci3; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8544@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi -new file mode 100644 -index 0000000..dddb737 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi -@@ -0,0 +1,161 @@ -+/* -+ * MPC8548 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8548-lbc", "fsl,pq3-localbus", "simple-bus"; -+ interrupts = <19 2 0 0>; -+}; -+ -+/* controller at 0x8000 */ -+&pci0 { -+ compatible = "fsl,mpc8540-pcix", "fsl,mpc8540-pci"; -+ device_type = "pci"; -+ interrupts = <24 0x2 0 0>; -+ bus-range = <0 0xff>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+}; -+ -+/* controller at 0x9000 */ -+&pci1 { -+ compatible = "fsl,mpc8540-pci"; -+ device_type = "pci"; -+ interrupts = <25 0x2 0 0>; -+ bus-range = <0 0xff>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+}; -+ -+/* controller at 0xa000 */ -+&pci2 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <26 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <26 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+&rio { -+ compatible = "fsl,srio"; -+ interrupts = <48 2 0 0>; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ fsl,srio-rmu-handle = <&rmu>; -+ ranges; -+ -+ port1 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <1>; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,mpc8548-immr", "simple-bus"; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <10>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,mpc8548-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2 0 0>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,mpc8548-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <18 2 0 0>; -+ }; -+ -+/include/ "pq3-i2c-0.dtsi" -+/include/ "pq3-i2c-1.dtsi" -+/include/ "pq3-duart-0.dtsi" -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,mpc8548-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x80000>; // L2, 512K -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-dma-0.dtsi" -+/include/ "pq3-etsec1-0.dtsi" -+/include/ "pq3-etsec1-1.dtsi" -+/include/ "pq3-etsec1-2.dtsi" -+/include/ "pq3-etsec1-3.dtsi" -+ -+/include/ "pq3-sec2.1-0.dtsi" -+/include/ "pq3-mpic.dtsi" -+/include/ "pq3-rmu-0.dtsi" -+ -+ global-utilities@e0000 { -+ compatible = "fsl,mpc8548-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ -+/include/ "pq3-power.dtsi" -+}; -diff --git a/arch/powerpc/boot/dts/fsl/mpc8548si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8548si-pre.dtsi -new file mode 100644 -index 0000000..fc1ce97 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/mpc8548si-pre.dtsi -@@ -0,0 +1,67 @@ -+/* -+ * MPC8548 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500v2_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,MPC8548"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ ethernet3 = &enet3; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8548@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/mpc8568si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8568si-post.dtsi -new file mode 100644 -index 0000000..64e7075 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/mpc8568si-post.dtsi -@@ -0,0 +1,270 @@ -+/* -+ * MPC8568 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8568-localbus", "fsl,pq3-localbus", "simple-bus"; -+ interrupts = <19 2 0 0>; -+ sleep = <&pmc 0x08000000>; -+}; -+ -+/* controller at 0x8000 */ -+&pci0 { -+ compatible = "fsl,mpc8540-pci"; -+ device_type = "pci"; -+ interrupts = <24 0x2 0 0>; -+ bus-range = <0 0xff>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ sleep = <&pmc 0x80000000>; -+}; -+ -+/* controller at 0xa000 */ -+&pci1 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <26 2 0 0>; -+ sleep = <&pmc 0x20000000>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <26 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+&rio { -+ compatible = "fsl,srio"; -+ interrupts = <48 2 0 0>; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ fsl,srio-rmu-handle = <&rmu>; -+ sleep = <&pmc 0x00080000>; -+ ranges; -+ -+ port1 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <1>; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,mpc8568-immr", "simple-bus"; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <10>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,mpc8568-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2 0 0>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,mpc8568-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <18 2 0 0>; -+ }; -+ -+ i2c-sleep-nexus { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "simple-bus"; -+ sleep = <&pmc 0x00000004>; -+ ranges; -+ -+/include/ "pq3-i2c-0.dtsi" -+/include/ "pq3-i2c-1.dtsi" -+ -+ }; -+ -+ duart-sleep-nexus { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "simple-bus"; -+ sleep = <&pmc 0x00000002>; -+ ranges; -+ -+/include/ "pq3-duart-0.dtsi" -+ -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,mpc8568-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x80000>; // L2, 512K -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-dma-0.dtsi" -+ dma@21300 { -+ sleep = <&pmc 0x00000400>; -+ }; -+ -+/include/ "pq3-etsec1-0.dtsi" -+ ethernet@24000 { -+ sleep = <&pmc 0x00000080>; -+ }; -+ -+/include/ "pq3-etsec1-1.dtsi" -+ ethernet@25000 { -+ sleep = <&pmc 0x00000040>; -+ }; -+ -+ par_io@e0100 { -+ reg = <0xe0100 0x100>; -+ device_type = "par_io"; -+ }; -+ -+/include/ "pq3-sec2.1-0.dtsi" -+ crypto@30000 { -+ sleep = <&pmc 0x01000000>; -+ }; -+ -+/include/ "pq3-mpic.dtsi" -+/include/ "pq3-rmu-0.dtsi" -+ rmu@d3000 { -+ sleep = <&pmc 0x00040000>; -+ }; -+ -+ global-utilities@e0000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8568-guts", "fsl,mpc8548-guts"; -+ reg = <0xe0000 0x1000>; -+ ranges = <0 0xe0000 0x1000>; -+ fsl,has-rstcr; -+ -+ pmc: power@70 { -+ compatible = "fsl,mpc8568-pmc", -+ "fsl,mpc8548-pmc"; -+ reg = <0x70 0x20>; -+ }; -+ }; -+}; -+ -+&qe { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "qe"; -+ compatible = "fsl,qe"; -+ sleep = <&pmc 0x00000800>; -+ brg-frequency = <0>; -+ bus-frequency = <396000000>; -+ fsl,qe-num-riscs = <2>; -+ fsl,qe-num-snums = <28>; -+ -+ qeic: interrupt-controller@80 { -+ interrupt-controller; -+ compatible = "fsl,qe-ic"; -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ reg = <0x80 0x80>; -+ interrupts = <46 2 0 0 46 2 0 0>; //high:30 low:30 -+ interrupt-parent = <&mpic>; -+ }; -+ -+ spi@4c0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,spi"; -+ reg = <0x4c0 0x40>; -+ cell-index = <0>; -+ interrupts = <2>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ spi@500 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl,spi"; -+ reg = <0x500 0x40>; -+ interrupts = <1>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ ucc@2000 { -+ cell-index = <1>; -+ reg = <0x2000 0x200>; -+ interrupts = <32>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ ucc@3000 { -+ cell-index = <2>; -+ reg = <0x3000 0x200>; -+ interrupts = <33>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ muram@10000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,qe-muram", "fsl,cpm-muram"; -+ ranges = <0x0 0x10000 0x10000>; -+ -+ data-only@0 { -+ compatible = "fsl,qe-muram-data", -+ "fsl,cpm-muram-data"; -+ reg = <0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/mpc8568si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8568si-pre.dtsi -new file mode 100644 -index 0000000..122ca3b ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/mpc8568si-pre.dtsi -@@ -0,0 +1,68 @@ -+/* -+ * MPC8568 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500v2_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,MPC8568"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ ethernet3 = &enet3; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8568@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ sleep = <&pmc 0x00008000 // core -+ &pmc 0x00004000>; // timebase -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/mpc8569si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8569si-post.dtsi -new file mode 100644 -index 0000000..3e6346a ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/mpc8569si-post.dtsi -@@ -0,0 +1,304 @@ -+/* -+ * MPC8569 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8569-elbc", "fsl,elbc", "simple-bus"; -+ interrupts = <19 2 0 0>; -+ sleep = <&pmc 0x08000000>; -+}; -+ -+/* controller at 0xa000 */ -+&pci1 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <26 2 0 0>; -+ sleep = <&pmc 0x20000000>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <26 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+&rio { -+ compatible = "fsl,srio"; -+ interrupts = <48 2 0 0>; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ fsl,srio-rmu-handle = <&rmu>; -+ sleep = <&pmc 0x00080000>; -+ ranges; -+ -+ port1 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <1>; -+ }; -+ -+ port2 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <2>; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,mpc8569-immr", "simple-bus"; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <10>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,mpc8569-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2 0 0>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,mpc8569-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <18 2 0 0>; -+ }; -+ -+ i2c-sleep-nexus { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "simple-bus"; -+ sleep = <&pmc 0x00000004>; -+ ranges; -+ -+/include/ "pq3-i2c-0.dtsi" -+/include/ "pq3-i2c-1.dtsi" -+ -+ }; -+ -+ duart-sleep-nexus { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "simple-bus"; -+ sleep = <&pmc 0x00000002>; -+ ranges; -+ -+/include/ "pq3-duart-0.dtsi" -+ -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,mpc8569-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x80000>; // L2, 512K -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-dma-0.dtsi" -+/include/ "pq3-esdhc-0.dtsi" -+ sdhc@2e000 { -+ sleep = <&pmc 0x00200000>; -+ }; -+ -+ par_io@e0100 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0xe0100 0x100>; -+ ranges = <0x0 0xe0100 0x100>; -+ device_type = "par_io"; -+ }; -+ -+/include/ "pq3-sec3.1-0.dtsi" -+ crypto@30000 { -+ sleep = <&pmc 0x01000000>; -+ }; -+ -+/include/ "pq3-mpic.dtsi" -+/include/ "pq3-rmu-0.dtsi" -+ rmu@d3000 { -+ sleep = <&pmc 0x00040000>; -+ }; -+ -+ global-utilities@e0000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8569-guts", "fsl,mpc8548-guts"; -+ reg = <0xe0000 0x1000>; -+ ranges = <0 0xe0000 0x1000>; -+ fsl,has-rstcr; -+ -+ pmc: power@70 { -+ compatible = "fsl,mpc8569-pmc", -+ "fsl,mpc8548-pmc"; -+ reg = <0x70 0x20>; -+ }; -+ }; -+}; -+ -+&qe { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "qe"; -+ compatible = "fsl,qe"; -+ sleep = <&pmc 0x00000800>; -+ brg-frequency = <0>; -+ bus-frequency = <0>; -+ fsl,qe-num-riscs = <4>; -+ fsl,qe-num-snums = <46>; -+ -+ qeic: interrupt-controller@80 { -+ interrupt-controller; -+ compatible = "fsl,qe-ic"; -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ reg = <0x80 0x80>; -+ interrupts = <46 2 0 0 46 2 0 0>; //high:30 low:30 -+ interrupt-parent = <&mpic>; -+ }; -+ -+ timer@440 { -+ compatible = "fsl,mpc8569-qe-gtm", -+ "fsl,qe-gtm", "fsl,gtm"; -+ reg = <0x440 0x40>; -+ interrupts = <12 13 14 15>; -+ interrupt-parent = <&qeic>; -+ /* Filled in by U-Boot */ -+ clock-frequency = <0>; -+ }; -+ -+ spi@4c0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,mpc8569-qe-spi", "fsl,spi"; -+ reg = <0x4c0 0x40>; -+ cell-index = <0>; -+ interrupts = <2>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ spi@500 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl,spi"; -+ reg = <0x500 0x40>; -+ interrupts = <1>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ usb@6c0 { -+ compatible = "fsl,mpc8569-qe-usb", -+ "fsl,mpc8323-qe-usb"; -+ reg = <0x6c0 0x40 0x8b00 0x100>; -+ interrupts = <11>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ 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>; -+ }; -+ -+ ucc@3000 { -+ cell-index = <2>; -+ reg = <0x3000 0x200>; -+ interrupts = <33>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ ucc@3200 { -+ cell-index = <4>; -+ reg = <0x3200 0x200>; -+ interrupts = <35>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ ucc@3400 { -+ cell-index = <6>; -+ reg = <0x3400 0x200>; -+ interrupts = <41>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ ucc@3600 { -+ cell-index = <8>; -+ reg = <0x3600 0x200>; -+ interrupts = <43>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ muram@10000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,qe-muram", "fsl,cpm-muram"; -+ ranges = <0x0 0x10000 0x20000>; -+ -+ data-only@0 { -+ compatible = "fsl,qe-muram-data", -+ "fsl,cpm-muram-data"; -+ reg = <0x0 0x20000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/mpc8569si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8569si-pre.dtsi -new file mode 100644 -index 0000000..2cd15a2 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/mpc8569si-pre.dtsi -@@ -0,0 +1,67 @@ -+/* -+ * MPC8569 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500v2_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,MPC8569"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ ethernet3 = &enet3; -+ pci1 = &pci1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8569@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ sleep = <&pmc 0x00008000 // core -+ &pmc 0x00004000>; // timebase -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi -new file mode 100644 -index 0000000..7313351 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi -@@ -0,0 +1,198 @@ -+/* -+ * MPC8572 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8572-elbc", "fsl,elbc", "simple-bus"; -+ interrupts = <19 2 0 0>; -+}; -+ -+/* controller at 0x8000 */ -+&pci0 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <24 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <24 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x8 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x9 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0xa 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0xb 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+/* controller at 0x9000 */ -+&pci1 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <25 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <25 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x4 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x5 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+/* controller at 0xa000 */ -+&pci2 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <26 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <26 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,mpc8572-immr", "simple-bus"; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,mpc8572-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2 0 0>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,mpc8572-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <18 2 0 0>; -+ }; -+ -+ memory-controller@6000 { -+ compatible = "fsl,mpc8572-memory-controller"; -+ reg = <0x6000 0x1000>; -+ interrupts = <18 2 0 0>; -+ }; -+ -+/include/ "pq3-i2c-0.dtsi" -+/include/ "pq3-i2c-1.dtsi" -+/include/ "pq3-duart-0.dtsi" -+/include/ "pq3-dma-1.dtsi" -+/include/ "pq3-gpio-0.dtsi" -+ gpio-controller@f000 { -+ compatible = "fsl,mpc8572-gpio", "fsl,pq3-gpio"; -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,mpc8572-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x100000>; // L2,1M -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-dma-0.dtsi" -+/include/ "pq3-etsec1-0.dtsi" -+/include/ "pq3-etsec1-timer-0.dtsi" -+ -+ ptp_clock@24e00 { -+ interrupts = <68 2 0 0 69 2 0 0 70 2 0 0 71 2 0 0>; -+ }; -+ -+/include/ "pq3-etsec1-1.dtsi" -+/include/ "pq3-etsec1-2.dtsi" -+/include/ "pq3-etsec1-3.dtsi" -+/include/ "pq3-sec3.0-0.dtsi" -+/include/ "pq3-mpic.dtsi" -+/include/ "pq3-mpic-timer-B.dtsi" -+ -+ global-utilities@e0000 { -+ compatible = "fsl,mpc8572-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ -+/include/ "pq3-power.dtsi" -+}; -diff --git a/arch/powerpc/boot/dts/fsl/mpc8572si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8572si-pre.dtsi -new file mode 100644 -index 0000000..28c2a86 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/mpc8572si-pre.dtsi -@@ -0,0 +1,73 @@ -+/* -+ * MPC8572 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500v2_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,MPC8572"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ ethernet3 = &enet3; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8572@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ }; -+ -+ PowerPC,8572@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi -new file mode 100644 -index 0000000..e949c47 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi -@@ -0,0 +1,211 @@ -+/* -+ * P1010/P1014 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&ifc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,ifc", "simple-bus"; -+ interrupts = <16 2 0 0 19 2 0 0>; -+}; -+ -+/* controller at 0x9000 */ -+&pci0 { -+ compatible = "fsl,p1010-pcie", "fsl,qoriq-pcie-v2.3", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x4 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x5 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+/* controller at 0xa000 */ -+&pci1 { -+ compatible = "fsl,p1010-pcie", "fsl,qoriq-pcie-v2.3", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,p1010-immr", "simple-bus"; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,p1010-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,p1010-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-i2c-0.dtsi" -+/include/ "pq3-i2c-1.dtsi" -+/include/ "pq3-duart-0.dtsi" -+/include/ "pq3-espi-0.dtsi" -+ spi0: spi@7000 { -+ fsl,espi-num-chipselects = <1>; -+ }; -+ -+/include/ "pq3-gpio-0.dtsi" -+/include/ "pq3-sata2-0.dtsi" -+/include/ "pq3-sata2-1.dtsi" -+/include/ "pq3-tdm1.0-0.dtsi" -+ -+ can0: can@1c000 { -+ compatible = "fsl,p1010-flexcan"; -+ reg = <0x1c000 0x1000>; -+ interrupts = <48 0x2 0 0>; -+ }; -+ -+ can1: can@1d000 { -+ compatible = "fsl,p1010-flexcan"; -+ reg = <0x1d000 0x1000>; -+ interrupts = <61 0x2 0 0>; -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,p1010-l2-cache-controller", -+ "fsl,p1014-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x40000>; // L2,256K -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-dma-0.dtsi" -+/include/ "pq3-usb2-dr-0.dtsi" -+ usb@22000 { -+ compatible = "fsl-usb2-dr-v1.6", "fsl-usb2-dr"; -+ }; -+/include/ "pq3-esdhc-0.dtsi" -+ sdhc@2e000 { -+ compatible = "fsl,p1010-esdhc", "fsl,esdhc"; -+ sdhci,auto-cmd12; -+ }; -+ -+/include/ "pq3-sec4.4-0.dtsi" -+/include/ "pq3-mpic.dtsi" -+/include/ "pq3-mpic-timer-B.dtsi" -+ -+/include/ "pq3-etsec2-0.dtsi" -+ enet0: ethernet@b0000 { -+ fsl,pmc-handle = <&etsec1_clk>; -+ -+ queue-group@b0000 { -+ fsl,rx-bit-map = <0xff>; -+ fsl,tx-bit-map = <0xff>; -+ }; -+ }; -+ -+/include/ "pq3-etsec2-1.dtsi" -+ enet1: ethernet@b1000 { -+ fsl,pmc-handle = <&etsec2_clk>; -+ -+ queue-group@b1000 { -+ fsl,rx-bit-map = <0xff>; -+ fsl,tx-bit-map = <0xff>; -+ }; -+ }; -+ -+/include/ "pq3-etsec2-2.dtsi" -+ enet2: ethernet@b2000 { -+ fsl,pmc-handle = <&etsec3_clk>; -+ -+ queue-group@b2000 { -+ fsl,rx-bit-map = <0xff>; -+ fsl,tx-bit-map = <0xff>; -+ }; -+ -+ }; -+ -+ global-utilities@e0000 { -+ compatible = "fsl,p1010-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ -+/include/ "pq3-power.dtsi" -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p1010si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p1010si-pre.dtsi -new file mode 100644 -index 0000000..6e76f9b ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p1010si-pre.dtsi -@@ -0,0 +1,67 @@ -+/* -+ * P1010/P1014 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500v2_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,P1010"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ can0 = &can0; -+ can1 = &can1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,P1010@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi -new file mode 100644 -index 0000000..5af0aae ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi -@@ -0,0 +1,201 @@ -+/* -+ * P1020/P1011 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,p1020-elbc", "fsl,elbc", "simple-bus"; -+ interrupts = <19 2 0 0>; -+}; -+ -+/* controller at 0x9000 */ -+&pci0 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x4 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x5 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+/* controller at 0xa000 */ -+&pci1 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,p1020-immr", "simple-bus"; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,p1020-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,p1020-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-i2c-0.dtsi" -+/include/ "pq3-i2c-1.dtsi" -+/include/ "pq3-duart-0.dtsi" -+ -+/include/ "pq3-espi-0.dtsi" -+ spi@7000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "pq3-gpio-0.dtsi" -+/include/ "pq3-tdm1.0-0.dtsi" -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,p1020-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x40000>; // L2,256K -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-dma-0.dtsi" -+/include/ "pq3-usb2-dr-0.dtsi" -+ usb@22000 { -+ compatible = "fsl-usb2-dr-v1.6", "fsl-usb2-dr"; -+ }; -+/include/ "pq3-usb2-dr-1.dtsi" -+ usb@23000 { -+ compatible = "fsl-usb2-dr-v1.6", "fsl-usb2-dr"; -+ }; -+ -+/include/ "pq3-esdhc-0.dtsi" -+ sdhc@2e000 { -+ compatible = "fsl,p1020-esdhc", "fsl,esdhc"; -+ sdhci,auto-cmd12; -+ }; -+/include/ "pq3-sec3.3-0.dtsi" -+ -+/include/ "pq3-mpic.dtsi" -+/include/ "pq3-mpic-timer-B.dtsi" -+ -+ ptp_timer: ptimer@b0e00 { -+ compatible = "fsl,gianfar-ptp-timer"; -+ reg = <0xb0e00 0xb0>; -+ fsl,ts-to-buffer; -+ fsl,tmr-prsc = <0x2>; -+ fsl,clock-source-select = <1>; -+ }; -+ -+/include/ "pq3-etsec2-0.dtsi" -+ enet0: enet0_grp2: ethernet@b0000 { -+ fsl,pmc-handle = <&etsec1_clk>; -+ ptimer-handle = <&ptp_timer>; -+ }; -+ -+/include/ "pq3-etsec2-1.dtsi" -+ enet1: enet1_grp2: ethernet@b1000 { -+ fsl,pmc-handle = <&etsec2_clk>; -+ ptimer-handle = <&ptp_timer>; -+ }; -+ -+/include/ "pq3-etsec2-2.dtsi" -+ enet2: enet2_grp2: ethernet@b2000 { -+ fsl,pmc-handle = <&etsec3_clk>; -+ ptimer-handle = <&ptp_timer>; -+ }; -+ -+ global-utilities@e0000 { -+ compatible = "fsl,p1020-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ -+/include/ "pq3-power.dtsi" -+}; -+ -+/include/ "pq3-etsec2-grp2-0.dtsi" -+/include/ "pq3-etsec2-grp2-1.dtsi" -+/include/ "pq3-etsec2-grp2-2.dtsi" -diff --git a/arch/powerpc/boot/dts/fsl/p1020si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p1020si-pre.dtsi -new file mode 100644 -index 0000000..fed9c4c ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p1020si-pre.dtsi -@@ -0,0 +1,71 @@ -+/* -+ * P1020/P1011 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500v2_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,P1020"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,P1020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ }; -+ -+ PowerPC,P1020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p1021si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1021si-post.dtsi -new file mode 100644 -index 0000000..cbdf47f ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p1021si-post.dtsi -@@ -0,0 +1,262 @@ -+/* -+ * P1021/P1012 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,p1021-elbc", "fsl,elbc", "simple-bus"; -+ interrupts = <19 2 0 0>; -+}; -+ -+/* controller at 0x9000 */ -+&pci0 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x4 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x5 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+/* controller at 0xa000 */ -+&pci1 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,p1021-immr", "simple-bus"; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,p1021-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,p1021-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-i2c-0.dtsi" -+/include/ "pq3-i2c-1.dtsi" -+/include/ "pq3-duart-0.dtsi" -+ -+/include/ "pq3-espi-0.dtsi" -+ spi@7000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "pq3-gpio-0.dtsi" -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,p1021-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x40000>; // L2,256K -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-dma-0.dtsi" -+/include/ "pq3-usb2-dr-0.dtsi" -+ usb@22000 { -+ compatible = "fsl-usb2-dr-v1.6", "fsl-usb2-dr"; -+ }; -+ -+/include/ "pq3-esdhc-0.dtsi" -+ sdhc@2e000 { -+ sdhci,auto-cmd12; -+ }; -+ -+/include/ "pq3-sec3.3-0.dtsi" -+ -+/include/ "pq3-mpic.dtsi" -+/include/ "pq3-mpic-timer-B.dtsi" -+ -+ ptp_timer: ptimer@b0e00 { -+ compatible = "fsl,gianfar-ptp-timer"; -+ reg = <0xb0e00 0xb0>; -+ fsl,ts-to-buffer; -+ fsl,tmr-prsc = <0x2>; -+ fsl,clock-source-select = <1>; -+ }; -+ -+/include/ "pq3-etsec2-0.dtsi" -+ enet0: enet0_grp2: ethernet@b0000 { -+ fsl,pmc-handle = <&etsec1_clk>; -+ ptimer-handle = <&ptp_timer>; -+ }; -+ -+/include/ "pq3-etsec2-1.dtsi" -+ enet1: enet1_grp2: ethernet@b1000 { -+ fsl,pmc-handle = <&etsec2_clk>; -+ ptimer-handle = <&ptp_timer>; -+ }; -+ -+/include/ "pq3-etsec2-2.dtsi" -+ enet2: enet2_grp2: ethernet@b2000 { -+ fsl,pmc-handle = <&etsec3_clk>; -+ ptimer-handle = <&ptp_timer>; -+ }; -+ -+ global-utilities@e0000 { -+ compatible = "fsl,p1021-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ -+/include/ "pq3-power.dtsi" -+}; -+ -+&qe { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "qe"; -+ compatible = "fsl,qe"; -+ fsl,qe-num-riscs = <1>; -+ fsl,qe-num-snums = <28>; -+ -+ qeic: interrupt-controller@80 { -+ interrupt-controller; -+ compatible = "fsl,qe-ic"; -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ reg = <0x80 0x80>; -+ interrupts = <63 2 0 0 60 2 0 0>; //high:47 low:44 -+ }; -+ -+ ucc@2000 { -+ cell-index = <1>; -+ reg = <0x2000 0x200>; -+ interrupts = <32>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ mdio@2120 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x2120 0x18>; -+ compatible = "fsl,ucc-mdio"; -+ }; -+ -+ ucc@2400 { -+ cell-index = <5>; -+ reg = <0x2400 0x200>; -+ interrupts = <40>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ ucc@2600 { -+ cell-index = <7>; -+ reg = <0x2600 0x200>; -+ interrupts = <42>; -+ 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>; -+ }; -+ }; -+}; -+ -+/include/ "pq3-etsec2-grp2-0.dtsi" -+/include/ "pq3-etsec2-grp2-1.dtsi" -+/include/ "pq3-etsec2-grp2-2.dtsi" -diff --git a/arch/powerpc/boot/dts/fsl/p1021si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p1021si-pre.dtsi -new file mode 100644 -index 0000000..36161b5 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p1021si-pre.dtsi -@@ -0,0 +1,71 @@ -+/* -+ * P1021/P1012 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500v2_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,P1021"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,P1021@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ }; -+ -+ PowerPC,P1021@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi -new file mode 100644 -index 0000000..3f3fc1e ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi -@@ -0,0 +1,252 @@ -+/* -+ * P1022/P1013 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ /* -+ * The localbus on the P1022 is not a simple-bus because of the eLBC -+ * pin muxing when the DIU is enabled. -+ */ -+ compatible = "fsl,p1022-elbc", "fsl,elbc"; -+ interrupts = <19 2 0 0>; -+}; -+ -+/* controller at 0x9000 */ -+&pci0 { -+ compatible = "fsl,p1022-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x4 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x5 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+/* controller at 0xa000 */ -+&pci1 { -+ compatible = "fsl,p1022-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+/* controller at 0xb000 */ -+&pci2 { -+ compatible = "fsl,p1022-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x8 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x9 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0xa 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0xb 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,p1022-immr", "simple-bus"; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,p1022-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,p1022-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-i2c-0.dtsi" -+/include/ "pq3-i2c-1.dtsi" -+/include/ "pq3-duart-0.dtsi" -+/include/ "pq3-espi-0.dtsi" -+ spi@7000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "pq3-dma-1.dtsi" -+ dma@c300 { -+ dma00: dma-channel@0 { -+ compatible = "fsl,ssi-dma-channel"; -+ }; -+ dma01: dma-channel@80 { -+ compatible = "fsl,ssi-dma-channel"; -+ }; -+ }; -+ -+/include/ "pq3-gpio-0.dtsi" -+ -+ display@10000 { -+ compatible = "fsl,diu", "fsl,p1022-diu"; -+ reg = <0x10000 1000>; -+ interrupts = <64 2 0 0>; -+ }; -+ -+ ssi@15000 { -+ compatible = "fsl,mpc8610-ssi"; -+ cell-index = <0>; -+ reg = <0x15000 0x100>; -+ interrupts = <75 2 0 0>; -+ fsl,playback-dma = <&dma00>; -+ fsl,capture-dma = <&dma01>; -+ fsl,fifo-depth = <15>; -+ }; -+ -+/include/ "pq3-tdm1.0-0.dtsi" -+/include/ "pq3-sata2-0.dtsi" -+/include/ "pq3-sata2-1.dtsi" -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,p1022-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x40000>; // L2,256K -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-dma-0.dtsi" -+/include/ "pq3-usb2-dr-0.dtsi" -+ usb@22000 { -+ compatible = "fsl-usb2-dr-v1.6", "fsl-usb2-dr"; -+ }; -+/include/ "pq3-usb2-dr-1.dtsi" -+ usb@23000 { -+ compatible = "fsl-usb2-dr-v1.6", "fsl-usb2-dr"; -+ }; -+ -+/include/ "pq3-esdhc-0.dtsi" -+ sdhc@2e000 { -+ compatible = "fsl,p1022-esdhc", "fsl,esdhc"; -+ sdhci,auto-cmd12; -+ }; -+ -+/include/ "pq3-sec3.3-0.dtsi" -+/include/ "pq3-mpic.dtsi" -+/include/ "pq3-mpic-timer-B.dtsi" -+ -+/include/ "pq3-etsec2-0.dtsi" -+ enet0: enet0_grp2: ethernet@b0000 { -+ fsl,wake-on-filer; -+ fsl,pmc-handle = <&etsec1_clk>; -+ }; -+ -+/include/ "pq3-etsec2-1.dtsi" -+ enet1: enet1_grp2: ethernet@b1000 { -+ fsl,wake-on-filer; -+ fsl,pmc-handle = <&etsec2_clk>; -+ }; -+ -+ global-utilities@e0000 { -+ compatible = "fsl,p1022-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ -+/include/ "pq3-power.dtsi" -+ power@e0070 { -+ compatible = "fsl,p1022-pmc", "fsl,mpc8536-pmc", -+ "fsl,mpc8548-pmc"; -+ }; -+ -+}; -+ -+/include/ "pq3-etsec2-grp2-0.dtsi" -+/include/ "pq3-etsec2-grp2-1.dtsi" -diff --git a/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi -new file mode 100644 -index 0000000..1956dea ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi -@@ -0,0 +1,71 @@ -+/* -+ * P1022/P1013 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500v2_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,P1022"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,P1022@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ }; -+ -+ PowerPC,P1022@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p1023si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1023si-post.dtsi -new file mode 100644 -index 0000000..7bb575a ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p1023si-post.dtsi -@@ -0,0 +1,413 @@ -+/* -+ * P1023/P1017 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,p1023-elbc", "fsl,elbc", "simple-bus"; -+ interrupts = <19 2 0 0>; -+}; -+ -+/* controller at 0xa000 */ -+&pci0 { -+ compatible = "fsl,p1023-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 0 0>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 0 0>; -+ }; -+}; -+ -+/* controller at 0x9000 */ -+&pci1 { -+ compatible = "fsl,p1023-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 0 0>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 0 0>; -+ }; -+}; -+ -+/* controller at 0xb000 */ -+&pci2 { -+ compatible = "fsl,p1023-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 0 0>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 0 0>; -+ }; -+}; -+ -+&qportals { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ compatible = "simple-bus"; -+ qportal0: qman-portal@0 { -+ cell-index = <0x0>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x0 0x4000 0x100000 0x1000>; -+ interrupts = <29 2 0 0>; -+ fsl,qman-channel-id = <0x0>; -+ }; -+ -+ qportal1: qman-portal@4000 { -+ cell-index = <0x1>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x4000 0x4000 0x101000 0x1000>; -+ interrupts = <31 2 0 0>; -+ fsl,qman-channel-id = <0x1>; -+ }; -+ -+ qportal2: qman-portal@8000 { -+ cell-index = <0x2>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x8000 0x4000 0x102000 0x1000>; -+ interrupts = <33 2 0 0>; -+ fsl,qman-channel-id = <0x2>; -+ }; -+}; -+ -+&bportals { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ compatible = "simple-bus"; -+ bman-portal@0 { -+ cell-index = <0x0>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x0 0x4000 0x100000 0x1000>; -+ interrupts = <30 2 0 0>; -+ }; -+ bman-portal@4000 { -+ cell-index = <0x1>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x4000 0x4000 0x101000 0x1000>; -+ interrupts = <32 2 0 0>; -+ }; -+ bman-portal@8000 { -+ cell-index = <2>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x8000 0x4000 0x102000 0x1000>; -+ interrupts = <34 2 0 0>; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,p1023-immr", "simple-bus"; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,p1023-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,p1023-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-i2c-0.dtsi" -+/include/ "pq3-i2c-1.dtsi" -+/include/ "pq3-duart-0.dtsi" -+ -+/include/ "pq3-espi-0.dtsi" -+ spi@7000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "pq3-gpio-0.dtsi" -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,p1023-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x40000>; // L2,256K -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-dma-0.dtsi" -+/include/ "pq3-usb2-dr-0.dtsi" -+ usb@22000 { -+ compatible = "fsl-usb2-dr-v1.6", "fsl-usb2-dr"; -+ }; -+ -+ crypto: crypto@300000 { -+ compatible = "fsl,sec-v4.2", "fsl,sec-v4.0"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x30000 0x10000>; -+ ranges = <0 0x30000 0x10000>; -+ interrupts = <58 2 0 0>; -+ -+ sec_jr0: jr@1000 { -+ compatible = "fsl,sec-v4.2-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x1000 0x1000>; -+ interrupts = <45 2 0 0>; -+ }; -+ -+ sec_jr1: jr@2000 { -+ compatible = "fsl,sec-v4.2-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x2000 0x1000>; -+ interrupts = <45 2 0 0>; -+ }; -+ -+ sec_jr2: jr@3000 { -+ compatible = "fsl,sec-v4.2-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x3000 0x1000>; -+ interrupts = <57 2 0 0>; -+ }; -+ -+ sec_jr3: jr@4000 { -+ compatible = "fsl,sec-v4.2-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x4000 0x1000>; -+ interrupts = <57 2 0 0>; -+ }; -+ -+ rtic@6000 { -+ compatible = "fsl,sec-v4.2-rtic", -+ "fsl,sec-v4.0-rtic"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x6000 0x100>; -+ ranges = <0x0 0x6100 0xe00>; -+ -+ rtic_a: rtic-a@0 { -+ compatible = "fsl,sec-v4.2-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x00 0x20 0x100 0x80>; -+ }; -+ -+ rtic_b: rtic-b@20 { -+ compatible = "fsl,sec-v4.2-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x20 0x20 0x200 0x80>; -+ }; -+ -+ rtic_c: rtic-c@40 { -+ compatible = "fsl,sec-v4.2-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x40 0x20 0x300 0x80>; -+ }; -+ -+ rtic_d: rtic-d@60 { -+ compatible = "fsl,sec-v4.2-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x60 0x20 0x500 0x80>; -+ }; -+ }; -+ }; -+ -+/include/ "pq3-mpic.dtsi" -+/include/ "pq3-mpic-timer-B.dtsi" -+ -+ qman: qman@88000 { -+ compatible = "fsl,qman"; -+ reg = <0x88000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+ bman: bman@8a000 { -+ compatible = "fsl,bman"; -+ reg = <0x8a000 0x1000>; -+ interrupts = <16 2 0 0>; -+ }; -+ -+ global-utilities@e0000 { -+ compatible = "fsl,p1023-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ -+ fman0: fman@100000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <0>; -+ compatible = "fsl,fman", "simple-bus"; -+ ranges = <0 0x100000 0x100000>; -+ reg = <0x100000 0x100000>; -+ clock-frequency = <0>; -+ interrupts = < -+ 24 2 0 0 -+ 16 2 0 0>; -+ cc@0 { -+ compatible = "fsl,fman-cc"; -+ }; -+ muram@0 { -+ compatible = "fsl,fman-muram"; -+ reg = <0x0 0x10000>; -+ }; -+ bmi@80000 { -+ compatible = "fsl,fman-bmi"; -+ reg = <0x80000 0x400>; -+ }; -+ qmi@80400 { -+ compatible = "fsl,fman-qmi"; -+ reg = <0x80400 0x400>; -+ }; -+ 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>; -+ }; -+ fman0_rx0: port@88000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x88000 0x1000>; -+ }; -+ fman0_rx1: port@89000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x89000 0x1000>; -+ }; -+ fman0_tx0: port@a8000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xa8000 0x1000>; -+ fsl,qman-channel-id = <0x40>; -+ }; -+ fman0_tx1: port@a9000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xa9000 0x1000>; -+ fsl,qman-channel-id = <0x41>; -+ }; -+ fman0_oh1: port@82000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x82000 0x1000>; -+ fsl,qman-channel-id = <0x43>; -+ }; -+ fman0_oh2: port@83000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x83000 0x1000>; -+ fsl,qman-channel-id = <0x44>; -+ }; -+ fman0_oh3: port@84000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x84000 0x1000>; -+ fsl,qman-channel-id = <0x45>; -+ }; -+ fman0_oh4: port@85000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x85000 0x1000>; -+ fsl,qman-channel-id = <0x46>; -+ }; -+ enet0: ethernet@e0000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-1g-mac"; -+ reg = <0xe0000 0x1000>; -+ fsl,port-handles = <&fman0_rx0 &fman0_tx0>; -+ ptimer-handle = <&ptp_timer0>; -+ }; -+ enet1: ethernet@e2000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-1g-mac"; -+ reg = <0xe2000 0x1000>; -+ fsl,port-handles = <&fman0_rx1 &fman0_tx1>; -+ ptimer-handle = <&ptp_timer0>; -+ }; -+ mdio0: mdio@e1120 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-mdio"; -+ reg = <0xe1120 0xee0>; -+ interrupts = <26 1 0 0>; -+ }; -+ -+ ptp_timer0: rtc@fe000 { -+ compatible = "fsl,fman-rtc"; -+ reg = <0xfe000 0x1000>; -+ }; -+ }; -+ -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p1023si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p1023si-pre.dtsi -new file mode 100644 -index 0000000..6cfff45 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p1023si-pre.dtsi -@@ -0,0 +1,83 @@ -+/* -+ * P1023/P1017 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500v2_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,P1023"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ -+ crypto = &crypto; -+ sec_jr0 = &sec_jr0; -+ sec_jr1 = &sec_jr1; -+ sec_jr2 = &sec_jr2; -+ sec_jr3 = &sec_jr3; -+ rtic_a = &rtic_a; -+ rtic_b = &rtic_b; -+ rtic_c = &rtic_c; -+ rtic_d = &rtic_d; -+ -+ bman = &bman; -+ qman = &qman; -+ fman0 = &fman0; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu0: PowerPC,P1023@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ }; -+ -+ cpu1: PowerPC,P1023@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi -new file mode 100644 -index 0000000..7d155b3 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi -@@ -0,0 +1,215 @@ -+/* -+ * P2020/P2010 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus"; -+ interrupts = <19 2 0 0>; -+}; -+ -+/* controller at 0xa000 */ -+&pci0 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <26 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <26 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+/* controller at 0x9000 */ -+&pci1 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <25 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <25 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x4 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x5 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+/* controller at 0x8000 */ -+&pci2 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 255>; -+ clock-frequency = <33333333>; -+ interrupts = <24 2 0 0>; -+ -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <24 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x8 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x2 &mpic 0x9 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x3 &mpic 0xa 0x1 0x0 0x0 -+ 0000 0x0 0x0 0x4 &mpic 0xb 0x1 0x0 0x0 -+ >; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,p2020-immr", "simple-bus"; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,p2020-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2 0 0>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,p2020-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <18 2 0 0>; -+ }; -+ -+/include/ "pq3-i2c-0.dtsi" -+/include/ "pq3-i2c-1.dtsi" -+/include/ "pq3-duart-0.dtsi" -+/include/ "pq3-espi-0.dtsi" -+ spi0: spi@7000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "pq3-dma-1.dtsi" -+/include/ "pq3-gpio-0.dtsi" -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,p2020-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x80000>; // L2,512K -+ interrupts = <16 2 0 0>; -+ }; -+ -+/include/ "pq3-dma-0.dtsi" -+/include/ "pq3-usb2-dr-0.dtsi" -+ usb@22000 { -+ compatible = "fsl-usb2-dr-v1.6", "fsl-usb2-dr"; -+ }; -+/include/ "pq3-etsec1-0.dtsi" -+ enet0: ethernet@24000 { -+ fsl,pmc-handle = <&etsec1_clk>; -+ -+ }; -+/include/ "pq3-etsec1-timer-0.dtsi" -+ -+ ptp_clock@24e00 { -+ interrupts = <68 2 0 0 69 2 0 0 70 2 0 0>; -+ }; -+ -+ -+/include/ "pq3-etsec1-1.dtsi" -+ enet1: ethernet@25000 { -+ fsl,pmc-handle = <&etsec2_clk>; -+ }; -+ -+/include/ "pq3-etsec1-2.dtsi" -+ enet2: ethernet@26000 { -+ fsl,pmc-handle = <&etsec3_clk>; -+ }; -+ -+/include/ "pq3-esdhc-0.dtsi" -+ sdhc@2e000 { -+ compatible = "fsl,p2020-esdhc", "fsl,esdhc"; -+ }; -+ -+/include/ "pq3-sec3.1-0.dtsi" -+/include/ "pq3-mpic.dtsi" -+/include/ "pq3-mpic-timer-B.dtsi" -+ -+ global-utilities@e0000 { -+ compatible = "fsl,p2020-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ -+/include/ "pq3-power.dtsi" -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p2020si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p2020si-pre.dtsi -new file mode 100644 -index 0000000..42bf3c6 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p2020si-pre.dtsi -@@ -0,0 +1,72 @@ -+/* -+ * P2020/P2010 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500v2_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,P2020"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,P2020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ }; -+ -+ PowerPC,P2020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi -new file mode 100644 -index 0000000..d9a9bf4 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi -@@ -0,0 +1,407 @@ -+/* -+ * P2041/P2040 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ compatible = "fsl,p2041-elbc", "fsl,elbc", "simple-bus"; -+ interrupts = <25 2 0 0>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+}; -+ -+/* controller at 0x200000 */ -+&pci0 { -+ compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 15>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 15>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 40 1 0 0 -+ 0000 0 0 2 &mpic 1 1 0 0 -+ 0000 0 0 3 &mpic 2 1 0 0 -+ 0000 0 0 4 &mpic 3 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x201000 */ -+&pci1 { -+ compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 14>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 14>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 41 1 0 0 -+ 0000 0 0 2 &mpic 5 1 0 0 -+ 0000 0 0 3 &mpic 6 1 0 0 -+ 0000 0 0 4 &mpic 7 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x202000 */ -+&pci2 { -+ compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 13>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 13>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 42 1 0 0 -+ 0000 0 0 2 &mpic 9 1 0 0 -+ 0000 0 0 3 &mpic 10 1 0 0 -+ 0000 0 0 4 &mpic 11 1 0 0 -+ >; -+ }; -+}; -+ -+&rio { -+ compatible = "fsl,srio"; -+ interrupts = <16 2 1 11>; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ port1 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <1>; -+ }; -+ -+ port2 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <2>; -+ }; -+}; -+ -+&dcsr { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,dcsr", "simple-bus"; -+ -+ dcsr-epu@0 { -+ compatible = "fsl,p2041-dcsr-epu", "fsl,dcsr-epu"; -+ interrupts = <52 2 0 0 -+ 84 2 0 0 -+ 85 2 0 0>; -+ reg = <0x0 0x1000>; -+ }; -+ dcsr-npc { -+ compatible = "fsl,dcsr-npc"; -+ reg = <0x1000 0x1000 0x1000000 0x8000>; -+ }; -+ dcsr-nxc@2000 { -+ compatible = "fsl,dcsr-nxc"; -+ reg = <0x2000 0x1000>; -+ }; -+ dcsr-corenet { -+ compatible = "fsl,dcsr-corenet"; -+ reg = <0x8000 0x1000 0xB0000 0x1000>; -+ }; -+ dcsr-dpaa@9000 { -+ compatible = "fsl,p2041-dcsr-dpaa", "fsl,dcsr-dpaa"; -+ reg = <0x9000 0x1000>; -+ }; -+ dcsr-ocn@11000 { -+ compatible = "fsl,p2041-dcsr-ocn", "fsl,dcsr-ocn"; -+ reg = <0x11000 0x1000>; -+ }; -+ dcsr-ddr@12000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr1>; -+ reg = <0x12000 0x1000>; -+ }; -+ dcsr-nal@18000 { -+ compatible = "fsl,p2041-dcsr-nal", "fsl,dcsr-nal"; -+ reg = <0x18000 0x1000>; -+ }; -+ dcsr-rcpm@22000 { -+ compatible = "fsl,p2041-dcsr-rcpm", "fsl,dcsr-rcpm"; -+ reg = <0x22000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@40000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu0>; -+ reg = <0x40000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@41000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu1>; -+ reg = <0x41000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@42000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu2>; -+ reg = <0x42000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@43000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu3>; -+ reg = <0x43000 0x1000>; -+ }; -+}; -+ -+&bportals { -+/include/ "qoriq-bman1-portals.dtsi" -+}; -+ -+&qportals { -+/include/ "qoriq-qman1-portals.dtsi" -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "simple-bus"; -+ -+ soc-sram-error { -+ compatible = "fsl,soc-sram-error"; -+ interrupts = <16 2 1 29>; -+ }; -+ -+ corenet-law@0 { -+ compatible = "fsl,corenet-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <32>; -+ }; -+ -+ ddr1: memory-controller@8000 { -+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; -+ reg = <0x8000 0x1000>; -+ interrupts = <16 2 1 23>; -+ }; -+ -+ cpc: l3-cache-controller@10000 { -+ compatible = "fsl,p2041-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache"; -+ reg = <0x10000 0x1000>; -+ interrupts = <16 2 1 27>; -+ }; -+ -+ corenet-cf@18000 { -+ compatible = "fsl,corenet-cf"; -+ reg = <0x18000 0x1000>; -+ interrupts = <16 2 1 31>; -+ fsl,ccf-num-csdids = <32>; -+ fsl,ccf-num-snoopids = <32>; -+ }; -+ -+ iommu@20000 { -+ compatible = "fsl,pamu-v1.0", "fsl,pamu"; -+ reg = <0x20000 0x4000>; -+ interrupts = < -+ 24 2 0 0 -+ 16 2 1 30>; -+ }; -+ -+/include/ "qoriq-mpic.dtsi" -+ -+ guts: global-utilities@e0000 { -+ compatible = "fsl,qoriq-device-config-1.0"; -+ reg = <0xe0000 0xe00>; -+ fsl,has-rstcr; -+ #sleep-cells = <1>; -+ fsl,liodn-bits = <12>; -+ }; -+ -+ pins: global-utilities@e0e00 { -+ compatible = "fsl,qoriq-pin-control-1.0"; -+ reg = <0xe0e00 0x200>; -+ #sleep-cells = <2>; -+ }; -+ -+ clockgen: global-utilities@e1000 { -+ compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0"; -+ reg = <0xe1000 0x1000>; -+ clock-frequency = <0>; -+ }; -+ -+ rcpm: global-utilities@e2000 { -+ compatible = "fsl,qoriq-rcpm-1.0"; -+ reg = <0xe2000 0x1000>; -+ #sleep-cells = <1>; -+ }; -+ -+ sfp: sfp@e8000 { -+ compatible = "fsl,p2041-sfp", "fsl,qoriq-sfp-1.0"; -+ reg = <0xe8000 0x1000>; -+ }; -+ -+ serdes: serdes@ea000 { -+ compatible = "fsl,p2041-serdes"; -+ reg = <0xea000 0x1000>; -+ }; -+ -+/include/ "qoriq-dma-0.dtsi" -+/include/ "qoriq-dma-1.dtsi" -+/include/ "qoriq-espi-0.dtsi" -+ spi@110000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "qoriq-esdhc-0.dtsi" -+ sdhc@114000 { -+ sdhci,auto-cmd12; -+ }; -+ -+/include/ "qoriq-i2c-0.dtsi" -+/include/ "qoriq-i2c-1.dtsi" -+/include/ "qoriq-duart-0.dtsi" -+/include/ "qoriq-duart-1.dtsi" -+/include/ "qoriq-gpio-0.dtsi" -+/include/ "qoriq-usb2-mph-0.dtsi" -+ usb0: usb@210000 { -+ compatible = "fsl-usb2-mph-v1.6", "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph"; -+ phy_type = "utmi"; -+ port0; -+ }; -+ -+/include/ "qoriq-usb2-dr-0.dtsi" -+ usb1: usb@211000 { -+ compatible = "fsl-usb2-dr-v1.6", "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr"; -+ dr_mode = "host"; -+ phy_type = "utmi"; -+ }; -+ -+/include/ "qoriq-sata2-0.dtsi" -+ sata@220000 { -+ compatible = "fsl,p2041-sata", "fsl,pq-sata-v2"; -+ }; -+/include/ "qoriq-sata2-1.dtsi" -+ sata@221000 { -+ compatible = "fsl,p2041-sata", "fsl,pq-sata-v2"; -+ }; -+/include/ "qoriq-sec4.2-0.dtsi" -+/include/ "qoriq-pme-0.dtsi" -+/include/ "qoriq-rman-0.dtsi" -+ rman: rman@1e0000 { -+ fsl,qman-channels-id = <0x62 0x63>; -+ }; -+ -+/include/ "qoriq-qman1.dtsi" -+/include/ "qoriq-bman1.dtsi" -+ -+/include/ "qoriq-fman-0.dtsi" -+/include/ "qoriq-fman-0-1g-0.dtsi" -+/include/ "qoriq-fman-0-1g-1.dtsi" -+/include/ "qoriq-fman-0-1g-2.dtsi" -+/include/ "qoriq-fman-0-1g-3.dtsi" -+/include/ "qoriq-fman-0-1g-4.dtsi" -+/include/ "qoriq-fman-0-10g-0.dtsi" -+ fman0: fman@400000 { -+ /* tx - 1g - 0 */ -+ port@a8000 { -+ fsl,qman-channel-id = <0x41>; -+ }; -+ /* tx - 1g - 1 */ -+ port@a9000 { -+ fsl,qman-channel-id = <0x42>; -+ }; -+ /* tx - 1g - 2 */ -+ port@aa000 { -+ fsl,qman-channel-id = <0x43>; -+ }; -+ /* tx - 1g - 3 */ -+ port@ab000 { -+ fsl,qman-channel-id = <0x44>; -+ }; -+ /* tx - 1g - 4 */ -+ port@ac000 { -+ fsl,qman-channel-id = <0x45>; -+ }; -+ /* tx - 10g - 0 */ -+ port@b0000 { -+ fsl,qman-channel-id = <0x40>; -+ }; -+ /* offline 0 */ -+ port@81000 { -+ fsl,qman-channel-id = <0x46>; -+ }; -+ /* offline 1 */ -+ port@82000 { -+ fsl,qman-channel-id = <0x47>; -+ }; -+ /* offline 2 */ -+ port@83000 { -+ fsl,qman-channel-id = <0x48>; -+ }; -+ /* offline 3 */ -+ port@84000 { -+ fsl,qman-channel-id = <0x49>; -+ }; -+ /* offline 4 */ -+ port@85000 { -+ fsl,qman-channel-id = <0x4a>; -+ }; -+ /* offline 5 */ -+ port@86000 { -+ fsl,qman-channel-id = <0x4b>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi -new file mode 100644 -index 0000000..c463a0b ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi -@@ -0,0 +1,120 @@ -+/* -+ * P2041 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500mc_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,P2041"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ ccsr = &soc; -+ dcsr = &dcsr; -+ -+ serial0 = &serial0; -+ serial1 = &serial1; -+ serial2 = &serial2; -+ serial3 = &serial3; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ usb0 = &usb0; -+ usb1 = &usb1; -+ dma0 = &dma0; -+ dma1 = &dma1; -+ sdhc = &sdhc; -+ msi0 = &msi0; -+ msi1 = &msi1; -+ msi2 = &msi2; -+ -+ crypto = &crypto; -+ sec_jr0 = &sec_jr0; -+ sec_jr1 = &sec_jr1; -+ sec_jr2 = &sec_jr2; -+ sec_jr3 = &sec_jr3; -+ rtic_a = &rtic_a; -+ rtic_b = &rtic_b; -+ rtic_c = &rtic_c; -+ rtic_d = &rtic_d; -+ sec_mon = &sec_mon; -+ -+ bman = &bman; -+ qman = &qman; -+ pme = &pme; -+ rman = &rman; -+ fman0 = &fman0; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu0: PowerPC,e500mc@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ next-level-cache = <&L2_0>; -+ L2_0: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu1: PowerPC,e500mc@1 { -+ device_type = "cpu"; -+ reg = <1>; -+ next-level-cache = <&L2_1>; -+ L2_1: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu2: PowerPC,e500mc@2 { -+ device_type = "cpu"; -+ reg = <2>; -+ next-level-cache = <&L2_2>; -+ L2_2: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu3: PowerPC,e500mc@3 { -+ device_type = "cpu"; -+ reg = <3>; -+ next-level-cache = <&L2_3>; -+ L2_3: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi -new file mode 100644 -index 0000000..5a8c7e3 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi -@@ -0,0 +1,434 @@ -+/* -+ * P3041 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ compatible = "fsl,p3041-elbc", "fsl,elbc", "simple-bus"; -+ interrupts = <25 2 0 0>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+}; -+ -+/* controller at 0x200000 */ -+&pci0 { -+ compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 15>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 15>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 40 1 0 0 -+ 0000 0 0 2 &mpic 1 1 0 0 -+ 0000 0 0 3 &mpic 2 1 0 0 -+ 0000 0 0 4 &mpic 3 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x201000 */ -+&pci1 { -+ compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 14>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 14>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 41 1 0 0 -+ 0000 0 0 2 &mpic 5 1 0 0 -+ 0000 0 0 3 &mpic 6 1 0 0 -+ 0000 0 0 4 &mpic 7 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x202000 */ -+&pci2 { -+ compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 13>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 13>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 42 1 0 0 -+ 0000 0 0 2 &mpic 9 1 0 0 -+ 0000 0 0 3 &mpic 10 1 0 0 -+ 0000 0 0 4 &mpic 11 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x203000 */ -+&pci3 { -+ compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 12>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 12>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 43 1 0 0 -+ 0000 0 0 2 &mpic 0 1 0 0 -+ 0000 0 0 3 &mpic 4 1 0 0 -+ 0000 0 0 4 &mpic 8 1 0 0 -+ >; -+ }; -+}; -+ -+&rio { -+ compatible = "fsl,srio"; -+ interrupts = <16 2 1 11>; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ port1 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <1>; -+ }; -+ -+ port2 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <2>; -+ }; -+}; -+ -+&dcsr { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,dcsr", "simple-bus"; -+ -+ dcsr-epu@0 { -+ compatible = "fsl,p3041-dcsr-epu", "fsl,dcsr-epu"; -+ interrupts = <52 2 0 0 -+ 84 2 0 0 -+ 85 2 0 0>; -+ reg = <0x0 0x1000>; -+ }; -+ dcsr-npc { -+ compatible = "fsl,dcsr-npc"; -+ reg = <0x1000 0x1000 0x1000000 0x8000>; -+ }; -+ dcsr-nxc@2000 { -+ compatible = "fsl,dcsr-nxc"; -+ reg = <0x2000 0x1000>; -+ }; -+ dcsr-corenet { -+ compatible = "fsl,dcsr-corenet"; -+ reg = <0x8000 0x1000 0xB0000 0x1000>; -+ }; -+ dcsr-dpaa@9000 { -+ compatible = "fsl,p3041-dcsr-dpaa", "fsl,dcsr-dpaa"; -+ reg = <0x9000 0x1000>; -+ }; -+ dcsr-ocn@11000 { -+ compatible = "fsl,p3041-dcsr-ocn", "fsl,dcsr-ocn"; -+ reg = <0x11000 0x1000>; -+ }; -+ dcsr-ddr@12000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr1>; -+ reg = <0x12000 0x1000>; -+ }; -+ dcsr-nal@18000 { -+ compatible = "fsl,p3041-dcsr-nal", "fsl,dcsr-nal"; -+ reg = <0x18000 0x1000>; -+ }; -+ dcsr-rcpm@22000 { -+ compatible = "fsl,p3041-dcsr-rcpm", "fsl,dcsr-rcpm"; -+ reg = <0x22000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@40000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu0>; -+ reg = <0x40000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@41000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu1>; -+ reg = <0x41000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@42000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu2>; -+ reg = <0x42000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@43000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu3>; -+ reg = <0x43000 0x1000>; -+ }; -+}; -+ -+&bportals { -+/include/ "qoriq-bman1-portals.dtsi" -+}; -+ -+&qportals { -+/include/ "qoriq-qman1-portals.dtsi" -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "simple-bus"; -+ -+ soc-sram-error { -+ compatible = "fsl,soc-sram-error"; -+ interrupts = <16 2 1 29>; -+ }; -+ -+ corenet-law@0 { -+ compatible = "fsl,corenet-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <32>; -+ }; -+ -+ ddr1: memory-controller@8000 { -+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; -+ reg = <0x8000 0x1000>; -+ interrupts = <16 2 1 23>; -+ }; -+ -+ cpc: l3-cache-controller@10000 { -+ compatible = "fsl,p3041-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache"; -+ reg = <0x10000 0x1000>; -+ interrupts = <16 2 1 27>; -+ }; -+ -+ corenet-cf@18000 { -+ compatible = "fsl,corenet-cf"; -+ reg = <0x18000 0x1000>; -+ interrupts = <16 2 1 31>; -+ fsl,ccf-num-csdids = <32>; -+ fsl,ccf-num-snoopids = <32>; -+ }; -+ -+ iommu@20000 { -+ compatible = "fsl,pamu-v1.0", "fsl,pamu"; -+ reg = <0x20000 0x4000>; -+ interrupts = < -+ 24 2 0 0 -+ 16 2 1 30>; -+ }; -+ -+/include/ "qoriq-mpic.dtsi" -+ -+ guts: global-utilities@e0000 { -+ compatible = "fsl,qoriq-device-config-1.0"; -+ reg = <0xe0000 0xe00>; -+ fsl,has-rstcr; -+ #sleep-cells = <1>; -+ fsl,liodn-bits = <12>; -+ }; -+ -+ pins: global-utilities@e0e00 { -+ compatible = "fsl,qoriq-pin-control-1.0"; -+ reg = <0xe0e00 0x200>; -+ #sleep-cells = <2>; -+ }; -+ -+ clockgen: global-utilities@e1000 { -+ compatible = "fsl,p3041-clockgen", "fsl,qoriq-clockgen-1.0"; -+ reg = <0xe1000 0x1000>; -+ clock-frequency = <0>; -+ }; -+ -+ rcpm: global-utilities@e2000 { -+ compatible = "fsl,qoriq-rcpm-1.0"; -+ reg = <0xe2000 0x1000>; -+ #sleep-cells = <1>; -+ }; -+ -+ sfp: sfp@e8000 { -+ compatible = "fsl,p3041-sfp", "fsl,qoriq-sfp-1.0"; -+ reg = <0xe8000 0x1000>; -+ }; -+ -+ serdes: serdes@ea000 { -+ compatible = "fsl,p3041-serdes"; -+ reg = <0xea000 0x1000>; -+ }; -+ -+/include/ "qoriq-dma-0.dtsi" -+/include/ "qoriq-dma-1.dtsi" -+/include/ "qoriq-espi-0.dtsi" -+ spi@110000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "qoriq-esdhc-0.dtsi" -+ sdhc@114000 { -+ sdhci,auto-cmd12; -+ }; -+ -+/include/ "qoriq-i2c-0.dtsi" -+/include/ "qoriq-i2c-1.dtsi" -+/include/ "qoriq-duart-0.dtsi" -+/include/ "qoriq-duart-1.dtsi" -+/include/ "qoriq-gpio-0.dtsi" -+/include/ "qoriq-usb2-mph-0.dtsi" -+ usb0: usb@210000 { -+ compatible = "fsl-usb2-mph-v1.6", "fsl-usb2-mph"; -+ phy_type = "utmi"; -+ port0; -+ }; -+ -+/include/ "qoriq-usb2-dr-0.dtsi" -+ usb1: usb@211000 { -+ compatible = "fsl-usb2-dr-v1.6", "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr"; -+ dr_mode = "host"; -+ phy_type = "utmi"; -+ }; -+ -+/include/ "qoriq-sata2-0.dtsi" -+ sata@220000 { -+ compatible = "fsl,p3041-sata", "fsl,pq-sata-v2"; -+ }; -+/include/ "qoriq-sata2-1.dtsi" -+ sata@221000 { -+ compatible = "fsl,p3041-sata", "fsl,pq-sata-v2"; -+ }; -+/include/ "qoriq-sec4.2-0.dtsi" -+/include/ "qoriq-pme-0.dtsi" -+/include/ "qoriq-rman-0.dtsi" -+ rman: rman@1e0000 { -+ fsl,qman-channels-id = <0x62 0x63>; -+ }; -+ -+/include/ "qoriq-qman1.dtsi" -+/include/ "qoriq-bman1.dtsi" -+ -+/include/ "qoriq-fman-0.dtsi" -+/include/ "qoriq-fman-0-1g-0.dtsi" -+/include/ "qoriq-fman-0-1g-1.dtsi" -+/include/ "qoriq-fman-0-1g-2.dtsi" -+/include/ "qoriq-fman-0-1g-3.dtsi" -+/include/ "qoriq-fman-0-1g-4.dtsi" -+/include/ "qoriq-fman-0-10g-0.dtsi" -+ fman0: fman@400000 { -+ /* tx - 1g - 0 */ -+ port@a8000 { -+ fsl,qman-channel-id = <0x41>; -+ }; -+ /* tx - 1g - 1 */ -+ port@a9000 { -+ fsl,qman-channel-id = <0x42>; -+ }; -+ /* tx - 1g - 2 */ -+ port@aa000 { -+ fsl,qman-channel-id = <0x43>; -+ }; -+ /* tx - 1g - 3 */ -+ port@ab000 { -+ fsl,qman-channel-id = <0x44>; -+ }; -+ /* tx - 1g - 4 */ -+ port@ac000 { -+ fsl,qman-channel-id = <0x45>; -+ }; -+ /* tx - 10g - 0 */ -+ port@b0000 { -+ fsl,qman-channel-id = <0x40>; -+ }; -+ /* offline 0 */ -+ port@81000 { -+ fsl,qman-channel-id = <0x46>; -+ }; -+ /* offline 1 */ -+ port@82000 { -+ fsl,qman-channel-id = <0x47>; -+ }; -+ /* offline 2 */ -+ port@83000 { -+ fsl,qman-channel-id = <0x48>; -+ }; -+ /* offline 3 */ -+ port@84000 { -+ fsl,qman-channel-id = <0x49>; -+ }; -+ /* offline 4 */ -+ port@85000 { -+ fsl,qman-channel-id = <0x4a>; -+ }; -+ /* offline 5 */ -+ port@86000 { -+ fsl,qman-channel-id = <0x4b>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi -new file mode 100644 -index 0000000..18ba76f ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi -@@ -0,0 +1,121 @@ -+/* -+ * P3041 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500mc_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,P3041"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ ccsr = &soc; -+ dcsr = &dcsr; -+ -+ serial0 = &serial0; -+ serial1 = &serial1; -+ serial2 = &serial2; -+ serial3 = &serial3; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ pci3 = &pci3; -+ usb0 = &usb0; -+ usb1 = &usb1; -+ dma0 = &dma0; -+ dma1 = &dma1; -+ sdhc = &sdhc; -+ msi0 = &msi0; -+ msi1 = &msi1; -+ msi2 = &msi2; -+ -+ crypto = &crypto; -+ sec_jr0 = &sec_jr0; -+ sec_jr1 = &sec_jr1; -+ sec_jr2 = &sec_jr2; -+ sec_jr3 = &sec_jr3; -+ rtic_a = &rtic_a; -+ rtic_b = &rtic_b; -+ rtic_c = &rtic_c; -+ rtic_d = &rtic_d; -+ sec_mon = &sec_mon; -+ -+ bman = &bman; -+ qman = &qman; -+ pme = &pme; -+ rman = &rman; -+ fman0 = &fman0; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu0: PowerPC,e500mc@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ next-level-cache = <&L2_0>; -+ L2_0: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu1: PowerPC,e500mc@1 { -+ device_type = "cpu"; -+ reg = <1>; -+ next-level-cache = <&L2_1>; -+ L2_1: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu2: PowerPC,e500mc@2 { -+ device_type = "cpu"; -+ reg = <2>; -+ next-level-cache = <&L2_2>; -+ L2_2: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu3: PowerPC,e500mc@3 { -+ device_type = "cpu"; -+ reg = <3>; -+ next-level-cache = <&L2_3>; -+ L2_3: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi -new file mode 100644 -index 0000000..01ce97e ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi -@@ -0,0 +1,481 @@ -+/* -+ * P4080/P4040 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ compatible = "fsl,p4080-elbc", "fsl,elbc", "simple-bus"; -+ interrupts = <25 2 0 0>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+}; -+ -+/* controller at 0x200000 */ -+&pci0 { -+ compatible = "fsl,p4080-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 15>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 15>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 40 1 0 0 -+ 0000 0 0 2 &mpic 1 1 0 0 -+ 0000 0 0 3 &mpic 2 1 0 0 -+ 0000 0 0 4 &mpic 3 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x201000 */ -+&pci1 { -+ compatible = "fsl,p4080-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 14>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 14>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 41 1 0 0 -+ 0000 0 0 2 &mpic 5 1 0 0 -+ 0000 0 0 3 &mpic 6 1 0 0 -+ 0000 0 0 4 &mpic 7 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x202000 */ -+&pci2 { -+ compatible = "fsl,p4080-pcie"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 13>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 13>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 42 1 0 0 -+ 0000 0 0 2 &mpic 9 1 0 0 -+ 0000 0 0 3 &mpic 10 1 0 0 -+ 0000 0 0 4 &mpic 11 1 0 0 -+ >; -+ }; -+}; -+ -+&rio { -+ compatible = "fsl,srio"; -+ interrupts = <16 2 1 11>; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ fsl,srio-rmu-handle = <&rmu>; -+ ranges; -+ -+ port1 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <1>; -+ }; -+ -+ port2 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <2>; -+ }; -+}; -+ -+&dcsr { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,dcsr", "simple-bus"; -+ -+ dcsr-epu@0 { -+ compatible = "fsl,p4080-dcsr-epu", "fsl,dcsr-epu"; -+ interrupts = <52 2 0 0 -+ 84 2 0 0 -+ 85 2 0 0>; -+ reg = <0x0 0x1000>; -+ }; -+ dcsr-npc { -+ compatible = "fsl,dcsr-npc"; -+ reg = <0x1000 0x1000 0x1000000 0x8000>; -+ }; -+ dcsr-nxc@2000 { -+ compatible = "fsl,dcsr-nxc"; -+ reg = <0x2000 0x1000>; -+ }; -+ dcsr-corenet { -+ compatible = "fsl,dcsr-corenet"; -+ reg = <0x8000 0x1000 0xB0000 0x1000>; -+ }; -+ dcsr-dpaa@9000 { -+ compatible = "fsl,p4080-dcsr-dpaa", "fsl,dcsr-dpaa"; -+ reg = <0x9000 0x1000>; -+ }; -+ dcsr-ocn@11000 { -+ compatible = "fsl,p4080-dcsr-ocn", "fsl,dcsr-ocn"; -+ reg = <0x11000 0x1000>; -+ }; -+ dcsr-ddr@12000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr1>; -+ reg = <0x12000 0x1000>; -+ }; -+ dcsr-ddr@13000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr2>; -+ reg = <0x13000 0x1000>; -+ }; -+ dcsr-nal@18000 { -+ compatible = "fsl,p4080-dcsr-nal", "fsl,dcsr-nal"; -+ reg = <0x18000 0x1000>; -+ }; -+ dcsr-rcpm@22000 { -+ compatible = "fsl,p4080-dcsr-rcpm", "fsl,dcsr-rcpm"; -+ reg = <0x22000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@40000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu0>; -+ reg = <0x40000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@41000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu1>; -+ reg = <0x41000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@42000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu2>; -+ reg = <0x42000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@43000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu3>; -+ reg = <0x43000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@44000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu4>; -+ reg = <0x44000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@45000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu5>; -+ reg = <0x45000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@46000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu6>; -+ reg = <0x46000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@47000 { -+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu7>; -+ reg = <0x47000 0x1000>; -+ }; -+ -+}; -+ -+&bportals { -+/include/ "qoriq-bman1-portals.dtsi" -+}; -+ -+&qportals { -+/include/ "qoriq-qman1-portals.dtsi" -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "simple-bus"; -+ -+ soc-sram-error { -+ compatible = "fsl,soc-sram-error"; -+ interrupts = <16 2 1 29>; -+ }; -+ -+ corenet-law@0 { -+ compatible = "fsl,corenet-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <32>; -+ }; -+ -+ ddr1: memory-controller@8000 { -+ compatible = "fsl,qoriq-memory-controller-v4.4", "fsl,qoriq-memory-controller"; -+ reg = <0x8000 0x1000>; -+ interrupts = <16 2 1 23>; -+ }; -+ -+ ddr2: memory-controller@9000 { -+ compatible = "fsl,qoriq-memory-controller-v4.4","fsl,qoriq-memory-controller"; -+ reg = <0x9000 0x1000>; -+ interrupts = <16 2 1 22>; -+ }; -+ -+ cpc: l3-cache-controller@10000 { -+ compatible = "fsl,p4080-l3-cache-controller", "cache"; -+ reg = <0x10000 0x1000 -+ 0x11000 0x1000>; -+ interrupts = <16 2 1 27 -+ 16 2 1 26>; -+ }; -+ -+ corenet-cf@18000 { -+ compatible = "fsl,corenet-cf"; -+ reg = <0x18000 0x1000>; -+ interrupts = <16 2 1 31>; -+ fsl,ccf-num-csdids = <32>; -+ fsl,ccf-num-snoopids = <32>; -+ }; -+ -+ iommu@20000 { -+ compatible = "fsl,pamu-v1.0", "fsl,pamu"; -+ reg = <0x20000 0x5000>; -+ interrupts = < -+ 24 2 0 0 -+ 16 2 1 30>; -+ }; -+ -+/include/ "qoriq-rmu-0.dtsi" -+/include/ "qoriq-mpic.dtsi" -+ -+ guts: global-utilities@e0000 { -+ compatible = "fsl,qoriq-device-config-1.0"; -+ reg = <0xe0000 0xe00>; -+ fsl,has-rstcr; -+ #sleep-cells = <1>; -+ fsl,liodn-bits = <12>; -+ }; -+ -+ pins: global-utilities@e0e00 { -+ compatible = "fsl,qoriq-pin-control-1.0"; -+ reg = <0xe0e00 0x200>; -+ #sleep-cells = <2>; -+ }; -+ -+ clockgen: global-utilities@e1000 { -+ compatible = "fsl,p4080-clockgen", "fsl,qoriq-clockgen-1.0"; -+ reg = <0xe1000 0x1000>; -+ clock-frequency = <0>; -+ }; -+ -+ rcpm: global-utilities@e2000 { -+ compatible = "fsl,qoriq-rcpm-1.0"; -+ reg = <0xe2000 0x1000>; -+ #sleep-cells = <1>; -+ }; -+ -+ sfp: sfp@e8000 { -+ compatible = "fsl,p4080-sfp", "fsl,qoriq-sfp-1.0"; -+ reg = <0xe8000 0x1000>; -+ }; -+ -+ serdes: serdes@ea000 { -+ compatible = "fsl,p4080-serdes"; -+ reg = <0xea000 0x1000>; -+ }; -+ -+/include/ "qoriq-dma-0.dtsi" -+/include/ "qoriq-dma-1.dtsi" -+/include/ "qoriq-espi-0.dtsi" -+ spi@110000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "qoriq-esdhc-0.dtsi" -+ sdhc@114000 { -+ voltage-ranges = <3300 3300>; -+ sdhci,auto-cmd12; -+ }; -+ -+/include/ "qoriq-i2c-0.dtsi" -+/include/ "qoriq-i2c-1.dtsi" -+/include/ "qoriq-duart-0.dtsi" -+/include/ "qoriq-duart-1.dtsi" -+/include/ "qoriq-gpio-0.dtsi" -+/include/ "qoriq-usb2-mph-0.dtsi" -+ usb@210000 { -+ compatible = "fsl-usb2-mph-v1.6", "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph"; -+ port0; -+ }; -+/include/ "qoriq-usb2-dr-0.dtsi" -+ usb@211000 { -+ compatible = "fsl-usb2-dr-v1.6", "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr"; -+ }; -+/include/ "qoriq-sec4.0-0.dtsi" -+/include/ "qoriq-pme-0.dtsi" -+/include/ "qoriq-qman1.dtsi" -+/include/ "qoriq-bman1.dtsi" -+/include/ "qoriq-fman-0.dtsi" -+/include/ "qoriq-fman-0-1g-0.dtsi" -+/include/ "qoriq-fman-0-1g-1.dtsi" -+/include/ "qoriq-fman-0-1g-2.dtsi" -+/include/ "qoriq-fman-0-1g-3.dtsi" -+/include/ "qoriq-fman-0-10g-0.dtsi" -+ fman0: fman@400000 { -+ /* tx - 1g - 0 */ -+ port@a8000 { -+ fsl,qman-channel-id = <0x41>; -+ }; -+ /* tx - 1g - 1 */ -+ port@a9000 { -+ fsl,qman-channel-id = <0x42>; -+ }; -+ /* tx - 1g - 2 */ -+ port@aa000 { -+ fsl,qman-channel-id = <0x43>; -+ }; -+ /* tx - 1g - 3 */ -+ port@ab000 { -+ fsl,qman-channel-id = <0x44>; -+ }; -+ /* tx - 10g - 0 */ -+ port@b0000 { -+ fsl,qman-channel-id = <0x40>; -+ }; -+ /* offline 0 */ -+ port@81000 { -+ fsl,qman-channel-id = <0x45>; -+ }; -+ /* offline 1 */ -+ port@82000 { -+ fsl,qman-channel-id = <0x46>; -+ }; -+ /* offline 2 */ -+ port@83000 { -+ fsl,qman-channel-id = <0x47>; -+ }; -+ /* offline 3 */ -+ port@84000 { -+ fsl,qman-channel-id = <0x48>; -+ }; -+ /* offline 4 */ -+ port@85000 { -+ fsl,qman-channel-id = <0x49>; -+ }; -+ /* offline 5 */ -+ port@86000 { -+ fsl,qman-channel-id = <0x4a>; -+ }; -+ /* offline 6 */ -+ port@87000 { -+ fsl,qman-channel-id = <0x4b>; -+ }; -+ }; -+ -+/include/ "qoriq-fman-1.dtsi" -+/include/ "qoriq-fman-1-1g-0.dtsi" -+/include/ "qoriq-fman-1-1g-1.dtsi" -+/include/ "qoriq-fman-1-1g-2.dtsi" -+/include/ "qoriq-fman-1-1g-3.dtsi" -+/include/ "qoriq-fman-1-10g-0.dtsi" -+ fman1: fman@500000 { -+ /* tx - 1g - 0 */ -+ port@a8000 { -+ fsl,qman-channel-id = <0x61>; -+ }; -+ /* tx - 1g - 1 */ -+ port@a9000 { -+ fsl,qman-channel-id = <0x62>; -+ }; -+ /* tx - 1g - 2 */ -+ port@aa000 { -+ fsl,qman-channel-id = <0x63>; -+ }; -+ /* tx - 1g - 3 */ -+ port@ab000 { -+ fsl,qman-channel-id = <0x64>; -+ }; -+ /* tx - 10g - 0 */ -+ port@b0000 { -+ fsl,qman-channel-id = <0x60>; -+ }; -+ /* offline 0 */ -+ port@81000 { -+ fsl,qman-channel-id = <0x65>; -+ }; -+ /* offline 1 */ -+ port@82000 { -+ fsl,qman-channel-id = <0x66>; -+ }; -+ /* offline 2 */ -+ port@83000 { -+ fsl,qman-channel-id = <0x67>; -+ }; -+ /* offline 3 */ -+ port@84000 { -+ fsl,qman-channel-id = <0x68>; -+ }; -+ /* offline 4 */ -+ port@85000 { -+ fsl,qman-channel-id = <0x69>; -+ }; -+ /* offline 5 */ -+ port@86000 { -+ fsl,qman-channel-id = <0x6a>; -+ }; -+ /* offline 6 */ -+ port@87000 { -+ fsl,qman-channel-id = <0x6b>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi -new file mode 100644 -index 0000000..aea2e14 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi -@@ -0,0 +1,152 @@ -+/* -+ * P4080/P4040 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e500mc_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,P4080"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ ccsr = &soc; -+ dcsr = &dcsr; -+ -+ serial0 = &serial0; -+ serial1 = &serial1; -+ serial2 = &serial2; -+ serial3 = &serial3; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ usb0 = &usb0; -+ usb1 = &usb1; -+ dma0 = &dma0; -+ dma1 = &dma1; -+ sdhc = &sdhc; -+ msi0 = &msi0; -+ msi1 = &msi1; -+ msi2 = &msi2; -+ -+ crypto = &crypto; -+ sec_jr0 = &sec_jr0; -+ sec_jr1 = &sec_jr1; -+ sec_jr2 = &sec_jr2; -+ sec_jr3 = &sec_jr3; -+ rtic_a = &rtic_a; -+ rtic_b = &rtic_b; -+ rtic_c = &rtic_c; -+ rtic_d = &rtic_d; -+ sec_mon = &sec_mon; -+ -+ bman = &bman; -+ qman = &qman; -+ pme = &pme; -+ fman0 = &fman0; -+ fman1 = &fman1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu0: PowerPC,e500mc@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ next-level-cache = <&L2_0>; -+ L2_0: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu1: PowerPC,e500mc@1 { -+ device_type = "cpu"; -+ reg = <1>; -+ next-level-cache = <&L2_1>; -+ L2_1: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu2: PowerPC,e500mc@2 { -+ device_type = "cpu"; -+ reg = <2>; -+ next-level-cache = <&L2_2>; -+ L2_2: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu3: PowerPC,e500mc@3 { -+ device_type = "cpu"; -+ reg = <3>; -+ next-level-cache = <&L2_3>; -+ L2_3: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu4: PowerPC,e500mc@4 { -+ device_type = "cpu"; -+ reg = <4>; -+ next-level-cache = <&L2_4>; -+ L2_4: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu5: PowerPC,e500mc@5 { -+ device_type = "cpu"; -+ reg = <5>; -+ next-level-cache = <&L2_5>; -+ L2_5: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu6: PowerPC,e500mc@6 { -+ device_type = "cpu"; -+ reg = <6>; -+ next-level-cache = <&L2_6>; -+ L2_6: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu7: PowerPC,e500mc@7 { -+ device_type = "cpu"; -+ reg = <7>; -+ next-level-cache = <&L2_7>; -+ L2_7: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi -new file mode 100644 -index 0000000..3a330c1 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi -@@ -0,0 +1,439 @@ -+/* -+ * P5020/5010 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ compatible = "fsl,p5020-elbc", "fsl,elbc", "simple-bus"; -+ interrupts = <25 2 0 0>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+}; -+ -+/* controller at 0x200000 */ -+&pci0 { -+ compatible = "fsl,p5020-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 15>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 15>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 40 1 0 0 -+ 0000 0 0 2 &mpic 1 1 0 0 -+ 0000 0 0 3 &mpic 2 1 0 0 -+ 0000 0 0 4 &mpic 3 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x201000 */ -+&pci1 { -+ compatible = "fsl,p5020-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 14>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 14>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 41 1 0 0 -+ 0000 0 0 2 &mpic 5 1 0 0 -+ 0000 0 0 3 &mpic 6 1 0 0 -+ 0000 0 0 4 &mpic 7 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x202000 */ -+&pci2 { -+ compatible = "fsl,p5020-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 13>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 13>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 42 1 0 0 -+ 0000 0 0 2 &mpic 9 1 0 0 -+ 0000 0 0 3 &mpic 10 1 0 0 -+ 0000 0 0 4 &mpic 11 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x203000 */ -+&pci3 { -+ compatible = "fsl,p5020-pcie", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 12>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 12>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 43 1 0 0 -+ 0000 0 0 2 &mpic 0 1 0 0 -+ 0000 0 0 3 &mpic 4 1 0 0 -+ 0000 0 0 4 &mpic 8 1 0 0 -+ >; -+ }; -+}; -+ -+&rio { -+ compatible = "fsl,srio"; -+ interrupts = <16 2 1 11>; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ port1 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <1>; -+ }; -+ -+ port2 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <2>; -+ }; -+}; -+ -+&dcsr { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,dcsr", "simple-bus"; -+ -+ dcsr-epu@0 { -+ compatible = "fsl,p5020-dcsr-epu", "fsl,dcsr-epu"; -+ interrupts = <52 2 0 0 -+ 84 2 0 0 -+ 85 2 0 0>; -+ reg = <0x0 0x1000>; -+ }; -+ dcsr-npc { -+ compatible = "fsl,dcsr-npc"; -+ reg = <0x1000 0x1000 0x1000000 0x8000>; -+ }; -+ dcsr-nxc@2000 { -+ compatible = "fsl,dcsr-nxc"; -+ reg = <0x2000 0x1000>; -+ }; -+ dcsr-corenet { -+ compatible = "fsl,dcsr-corenet"; -+ reg = <0x8000 0x1000 0xB0000 0x1000>; -+ }; -+ dcsr-dpaa@9000 { -+ compatible = "fsl,p5020-dcsr-dpaa", "fsl,dcsr-dpaa"; -+ reg = <0x9000 0x1000>; -+ }; -+ dcsr-ocn@11000 { -+ compatible = "fsl,p5020-dcsr-ocn", "fsl,dcsr-ocn"; -+ reg = <0x11000 0x1000>; -+ }; -+ dcsr-ddr@12000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr1>; -+ reg = <0x12000 0x1000>; -+ }; -+ dcsr-ddr@13000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr2>; -+ reg = <0x13000 0x1000>; -+ }; -+ dcsr-nal@18000 { -+ compatible = "fsl,p5020-dcsr-nal", "fsl,dcsr-nal"; -+ reg = <0x18000 0x1000>; -+ }; -+ dcsr-rcpm@22000 { -+ compatible = "fsl,p5020-dcsr-rcpm", "fsl,dcsr-rcpm"; -+ reg = <0x22000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@40000 { -+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu0>; -+ reg = <0x40000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@41000 { -+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu1>; -+ reg = <0x41000 0x1000>; -+ }; -+}; -+ -+&bportals { -+/include/ "qoriq-bman1-portals.dtsi" -+}; -+ -+&qportals { -+/include/ "qoriq-qman1-portals.dtsi" -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "simple-bus"; -+ -+ soc-sram-error { -+ compatible = "fsl,soc-sram-error"; -+ interrupts = <16 2 1 29>; -+ }; -+ -+ corenet-law@0 { -+ compatible = "fsl,corenet-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <32>; -+ }; -+ -+ ddr1: memory-controller@8000 { -+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; -+ reg = <0x8000 0x1000>; -+ interrupts = <16 2 1 23>; -+ }; -+ -+ ddr2: memory-controller@9000 { -+ compatible = "fsl,qoriq-memory-controller-v4.5","fsl,qoriq-memory-controller"; -+ reg = <0x9000 0x1000>; -+ interrupts = <16 2 1 22>; -+ }; -+ -+ cpc: l3-cache-controller@10000 { -+ compatible = "fsl,p5020-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache"; -+ reg = <0x10000 0x1000 -+ 0x11000 0x1000>; -+ interrupts = <16 2 1 27 -+ 16 2 1 26>; -+ }; -+ -+ corenet-cf@18000 { -+ compatible = "fsl,corenet-cf"; -+ reg = <0x18000 0x1000>; -+ interrupts = <16 2 1 31>; -+ fsl,ccf-num-csdids = <32>; -+ fsl,ccf-num-snoopids = <32>; -+ }; -+ -+ iommu@20000 { -+ compatible = "fsl,pamu-v1.0", "fsl,pamu"; -+ reg = <0x20000 0x4000>; -+ interrupts = < -+ 24 2 0 0 -+ 16 2 1 30>; -+ }; -+ -+/include/ "qoriq-mpic.dtsi" -+ -+ guts: global-utilities@e0000 { -+ compatible = "fsl,qoriq-device-config-1.0"; -+ reg = <0xe0000 0xe00>; -+ fsl,has-rstcr; -+ #sleep-cells = <1>; -+ fsl,liodn-bits = <12>; -+ }; -+ -+ pins: global-utilities@e0e00 { -+ compatible = "fsl,qoriq-pin-control-1.0"; -+ reg = <0xe0e00 0x200>; -+ #sleep-cells = <2>; -+ }; -+ -+ clockgen: global-utilities@e1000 { -+ compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0"; -+ reg = <0xe1000 0x1000>; -+ clock-frequency = <0>; -+ }; -+ -+ rcpm: global-utilities@e2000 { -+ compatible = "fsl,qoriq-rcpm-1.0"; -+ reg = <0xe2000 0x1000>; -+ #sleep-cells = <1>; -+ }; -+ -+ sfp: sfp@e8000 { -+ compatible = "fsl,p5020-sfp", "fsl,qoriq-sfp-1.0"; -+ reg = <0xe8000 0x1000>; -+ }; -+ -+ serdes: serdes@ea000 { -+ compatible = "fsl,p5020-serdes"; -+ reg = <0xea000 0x1000>; -+ }; -+ -+/include/ "qoriq-dma-0.dtsi" -+/include/ "qoriq-dma-1.dtsi" -+/include/ "qoriq-espi-0.dtsi" -+ spi@110000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "qoriq-esdhc-0.dtsi" -+ sdhc@114000 { -+ sdhci,auto-cmd12; -+ }; -+ -+/include/ "qoriq-i2c-0.dtsi" -+/include/ "qoriq-i2c-1.dtsi" -+/include/ "qoriq-duart-0.dtsi" -+/include/ "qoriq-duart-1.dtsi" -+/include/ "qoriq-gpio-0.dtsi" -+/include/ "qoriq-usb2-mph-0.dtsi" -+ usb0: usb@210000 { -+ compatible = "fsl-usb2-mph-v1.6", "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph"; -+ phy_type = "utmi"; -+ port0; -+ }; -+ -+/include/ "qoriq-usb2-dr-0.dtsi" -+ usb1: usb@211000 { -+ compatible = "fsl-usb2-dr-v1.6", "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr"; -+ dr_mode = "host"; -+ phy_type = "utmi"; -+ }; -+ -+/include/ "qoriq-sata2-0.dtsi" -+ sata@220000 { -+ compatible = "fsl,p5020-sata", "fsl,pq-sata-v2"; -+ }; -+/include/ "qoriq-sata2-1.dtsi" -+ sata@221000 { -+ compatible = "fsl,p5020-sata", "fsl,pq-sata-v2"; -+ }; -+/include/ "qoriq-sec4.2-0.dtsi" -+/include/ "qoriq-pme-0.dtsi" -+/include/ "qoriq-rman-0.dtsi" -+ rman: rman@1e0000 { -+ fsl,qman-channels-id = <0x62 0x63>; -+ }; -+ -+/include/ "qoriq-qman1.dtsi" -+/include/ "qoriq-bman1.dtsi" -+ -+/include/ "qoriq-fman-0.dtsi" -+/include/ "qoriq-fman-0-1g-0.dtsi" -+/include/ "qoriq-fman-0-1g-1.dtsi" -+/include/ "qoriq-fman-0-1g-2.dtsi" -+/include/ "qoriq-fman-0-1g-3.dtsi" -+/include/ "qoriq-fman-0-1g-4.dtsi" -+/include/ "qoriq-fman-0-10g-0.dtsi" -+ fman0: fman@400000 { -+ /* tx - 1g - 0 */ -+ port@a8000 { -+ fsl,qman-channel-id = <0x41>; -+ }; -+ /* tx - 1g - 1 */ -+ port@a9000 { -+ fsl,qman-channel-id = <0x42>; -+ }; -+ /* tx - 1g - 2 */ -+ port@aa000 { -+ fsl,qman-channel-id = <0x43>; -+ }; -+ /* tx - 1g - 3 */ -+ port@ab000 { -+ fsl,qman-channel-id = <0x44>; -+ }; -+ /* tx - 1g - 4 */ -+ port@ac000 { -+ fsl,qman-channel-id = <0x45>; -+ }; -+ /* tx - 10g - 0 */ -+ port@b0000 { -+ fsl,qman-channel-id = <0x40>; -+ }; -+ /* offline 0 */ -+ port@81000 { -+ fsl,qman-channel-id = <0x46>; -+ }; -+ /* offline 1 */ -+ port@82000 { -+ fsl,qman-channel-id = <0x47>; -+ }; -+ /* offline 2 */ -+ port@83000 { -+ fsl,qman-channel-id = <0x48>; -+ }; -+ /* offline 3 */ -+ port@84000 { -+ fsl,qman-channel-id = <0x49>; -+ }; -+ /* offline 4 */ -+ port@85000 { -+ fsl,qman-channel-id = <0x4a>; -+ }; -+ /* offline 5 */ -+ port@86000 { -+ fsl,qman-channel-id = <0x4b>; -+ }; -+ }; -+ -+/include/ "qoriq-raid1.0-0.dtsi" -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi -new file mode 100644 -index 0000000..8cda17b ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi -@@ -0,0 +1,111 @@ -+/* -+ * P5020/P5010 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e5500_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,P5020"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ ccsr = &soc; -+ dcsr = &dcsr; -+ -+ serial0 = &serial0; -+ serial1 = &serial1; -+ serial2 = &serial2; -+ serial3 = &serial3; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ pci3 = &pci3; -+ usb0 = &usb0; -+ usb1 = &usb1; -+ dma0 = &dma0; -+ dma1 = &dma1; -+ sdhc = &sdhc; -+ msi0 = &msi0; -+ msi1 = &msi1; -+ msi2 = &msi2; -+ -+ crypto = &crypto; -+ sec_jr0 = &sec_jr0; -+ sec_jr1 = &sec_jr1; -+ sec_jr2 = &sec_jr2; -+ sec_jr3 = &sec_jr3; -+ rtic_a = &rtic_a; -+ rtic_b = &rtic_b; -+ rtic_c = &rtic_c; -+ rtic_d = &rtic_d; -+ sec_mon = &sec_mon; -+ -+ raideng = &raideng; -+ raideng_jr0 = &raideng_jr0; -+ raideng_jr1 = &raideng_jr1; -+ raideng_jr2 = &raideng_jr2; -+ raideng_jr3 = &raideng_jr3; -+ -+ bman = &bman; -+ qman = &qman; -+ pme = &pme; -+ rman = &rman; -+ fman0 = &fman0; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu0: PowerPC,e5500@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ next-level-cache = <&L2_0>; -+ L2_0: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu1: PowerPC,e5500@1 { -+ device_type = "cpu"; -+ reg = <1>; -+ next-level-cache = <&L2_1>; -+ L2_1: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi -new file mode 100644 -index 0000000..7eee08c ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi -@@ -0,0 +1,448 @@ -+/* -+ * P5040 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&lbc { -+ compatible = "fsl,p5040-elbc", "fsl,elbc", "simple-bus"; -+ interrupts = <25 2 0 0>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+}; -+ -+/* controller at 0x200000 */ -+&pci0 { -+ compatible = "fsl,p5040-pcie", "fsl,qoriq-pcie-v2.4", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 15>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 15>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 40 1 0 0 -+ 0000 0 0 2 &mpic 1 1 0 0 -+ 0000 0 0 3 &mpic 2 1 0 0 -+ 0000 0 0 4 &mpic 3 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x201000 */ -+&pci1 { -+ compatible = "fsl,p5040-pcie", "fsl,qoriq-pcie-v2.4", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 14>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 14>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 41 1 0 0 -+ 0000 0 0 2 &mpic 5 1 0 0 -+ 0000 0 0 3 &mpic 6 1 0 0 -+ 0000 0 0 4 &mpic 7 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x202000 */ -+&pci2 { -+ compatible = "fsl,p5040-pcie", "fsl,qoriq-pcie-v2.4", "fsl,qoriq-pcie-v2.2"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <16 2 1 13>; -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <16 2 1 13>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 42 1 0 0 -+ 0000 0 0 2 &mpic 9 1 0 0 -+ 0000 0 0 3 &mpic 10 1 0 0 -+ 0000 0 0 4 &mpic 11 1 0 0 -+ >; -+ }; -+}; -+ -+&dcsr { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,dcsr", "simple-bus"; -+ -+ dcsr-epu@0 { -+ compatible = "fsl,p5040-dcsr-epu", "fsl,dcsr-epu"; -+ interrupts = <52 2 0 0 -+ 84 2 0 0 -+ 85 2 0 0>; -+ reg = <0x0 0x1000>; -+ }; -+ dcsr-npc { -+ compatible = "fsl,dcsr-npc"; -+ reg = <0x1000 0x1000 0x1000000 0x8000>; -+ }; -+ dcsr-nxc@2000 { -+ compatible = "fsl,dcsr-nxc"; -+ reg = <0x2000 0x1000>; -+ }; -+ dcsr-corenet { -+ compatible = "fsl,dcsr-corenet"; -+ reg = <0x8000 0x1000 0xB0000 0x1000>; -+ }; -+ dcsr-dpaa@9000 { -+ compatible = "fsl,p5040-dcsr-dpaa", "fsl,dcsr-dpaa"; -+ reg = <0x9000 0x1000>; -+ }; -+ dcsr-ocn@11000 { -+ compatible = "fsl,p5040-dcsr-ocn", "fsl,dcsr-ocn"; -+ reg = <0x11000 0x1000>; -+ }; -+ dcsr-ddr@12000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr1>; -+ reg = <0x12000 0x1000>; -+ }; -+ dcsr-ddr@13000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr2>; -+ reg = <0x13000 0x1000>; -+ }; -+ dcsr-nal@18000 { -+ compatible = "fsl,p5040-dcsr-nal", "fsl,dcsr-nal"; -+ reg = <0x18000 0x1000>; -+ }; -+ dcsr-rcpm@22000 { -+ compatible = "fsl,p5040-dcsr-rcpm", "fsl,dcsr-rcpm"; -+ reg = <0x22000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@40000 { -+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu0>; -+ reg = <0x40000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@41000 { -+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu1>; -+ reg = <0x41000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@42000 { -+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu2>; -+ reg = <0x42000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@43000 { -+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu3>; -+ reg = <0x43000 0x1000>; -+ }; -+}; -+ -+&bportals { -+/include/ "qoriq-bman1-portals.dtsi" -+}; -+ -+&qportals { -+/include/ "qoriq-qman1-portals.dtsi" -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "simple-bus"; -+ -+ soc-sram-error { -+ compatible = "fsl,soc-sram-error"; -+ interrupts = <16 2 1 29>; -+ }; -+ -+ corenet-law@0 { -+ compatible = "fsl,corenet-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <32>; -+ }; -+ -+ ddr1: memory-controller@8000 { -+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; -+ reg = <0x8000 0x1000>; -+ interrupts = <16 2 1 23>; -+ }; -+ -+ ddr2: memory-controller@9000 { -+ compatible = "fsl,qoriq-memory-controller-v4.5","fsl,qoriq-memory-controller"; -+ reg = <0x9000 0x1000>; -+ interrupts = <16 2 1 22>; -+ }; -+ -+ cpc: l3-cache-controller@10000 { -+ compatible = "fsl,p5040-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache"; -+ reg = <0x10000 0x1000 -+ 0x11000 0x1000>; -+ interrupts = <16 2 1 27 -+ 16 2 1 26>; -+ }; -+ -+ corenet-cf@18000 { -+ compatible = "fsl,corenet-cf"; -+ reg = <0x18000 0x1000>; -+ interrupts = <16 2 1 31>; -+ fsl,ccf-num-csdids = <32>; -+ fsl,ccf-num-snoopids = <32>; -+ }; -+ -+ iommu@20000 { -+ compatible = "fsl,pamu-v1.0", "fsl,pamu"; -+ reg = <0x20000 0x5000>; -+ interrupts = < -+ 24 2 0 0 -+ 16 2 1 30>; -+ }; -+ -+/include/ "qoriq-mpic.dtsi" -+ -+ guts: global-utilities@e0000 { -+ compatible = "fsl,p5040-device-config", "fsl,qoriq-device-config-1.0"; -+ reg = <0xe0000 0xe00>; -+ fsl,has-rstcr; -+ #sleep-cells = <1>; -+ fsl,liodn-bits = <12>; -+ }; -+ -+ pins: global-utilities@e0e00 { -+ compatible = "fsl,p5040-pin-control", "fsl,qoriq-pin-control-1.0"; -+ reg = <0xe0e00 0x200>; -+ #sleep-cells = <2>; -+ }; -+ -+ clockgen: global-utilities@e1000 { -+ compatible = "fsl,p5040-clockgen", "fsl,qoriq-clockgen-1.0"; -+ reg = <0xe1000 0x1000>; -+ clock-frequency = <0>; -+ }; -+ -+ rcpm: global-utilities@e2000 { -+ compatible = "fsl,p5040-rcpm", "fsl,qoriq-rcpm-1.0"; -+ reg = <0xe2000 0x1000>; -+ #sleep-cells = <1>; -+ }; -+ -+ sfp: sfp@e8000 { -+ compatible = "fsl,p5040-sfp", "fsl,qoriq-sfp-1.0"; -+ reg = <0xe8000 0x1000>; -+ }; -+ -+ serdes: serdes@ea000 { -+ compatible = "fsl,p5040-serdes"; -+ reg = <0xea000 0x1000>; -+ }; -+ -+/include/ "qoriq-dma-0.dtsi" -+/include/ "qoriq-dma-1.dtsi" -+/include/ "qoriq-espi-0.dtsi" -+ spi@110000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "qoriq-esdhc-0.dtsi" -+ sdhc@114000 { -+ sdhci,auto-cmd12; -+ }; -+ -+/include/ "qoriq-i2c-0.dtsi" -+/include/ "qoriq-i2c-1.dtsi" -+/include/ "qoriq-duart-0.dtsi" -+/include/ "qoriq-duart-1.dtsi" -+/include/ "qoriq-gpio-0.dtsi" -+/include/ "qoriq-usb2-mph-0.dtsi" -+ usb0: usb@210000 { -+ compatible = "fsl-usb2-mph-v1.6", "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph"; -+ phy_type = "utmi"; -+ port0; -+ }; -+ -+/include/ "qoriq-usb2-dr-0.dtsi" -+ usb1: usb@211000 { -+ compatible = "fsl-usb2-dr-v1.6", "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr"; -+ dr_mode = "host"; -+ phy_type = "utmi"; -+ }; -+ -+/include/ "qoriq-sata2-0.dtsi" -+/include/ "qoriq-sata2-1.dtsi" -+/include/ "qoriq-sec5.2-0.dtsi" -+/include/ "qoriq-qman1.dtsi" -+/include/ "qoriq-bman1.dtsi" -+ -+/include/ "qoriq-fman-0.dtsi" -+/include/ "qoriq-fman-0-1g-0.dtsi" -+/include/ "qoriq-fman-0-1g-1.dtsi" -+/include/ "qoriq-fman-0-1g-2.dtsi" -+/include/ "qoriq-fman-0-1g-3.dtsi" -+/include/ "qoriq-fman-0-1g-4.dtsi" -+/include/ "qoriq-fman-0-10g-0.dtsi" -+ fman0: fman@400000 { -+ /* tx - 1g - 0 */ -+ port@a8000 { -+ fsl,qman-channel-id = <0x41>; -+ }; -+ /* tx - 1g - 1 */ -+ port@a9000 { -+ fsl,qman-channel-id = <0x42>; -+ }; -+ /* tx - 1g - 2 */ -+ port@aa000 { -+ fsl,qman-channel-id = <0x43>; -+ }; -+ /* tx - 1g - 3 */ -+ port@ab000 { -+ fsl,qman-channel-id = <0x44>; -+ }; -+ /* tx - 1g - 4 */ -+ port@ac000 { -+ fsl,qman-channel-id = <0x45>; -+ }; -+ /* tx - 10g - 0 */ -+ port@b0000 { -+ fsl,qman-channel-id = <0x40>; -+ }; -+ /* offline 0 */ -+ port@81000 { -+ fsl,qman-channel-id = <0x46>; -+ }; -+ /* offline 1 */ -+ port@82000 { -+ fsl,qman-channel-id = <0x47>; -+ }; -+ /* offline 2 */ -+ port@83000 { -+ fsl,qman-channel-id = <0x48>; -+ }; -+ /* offline 3 */ -+ port@84000 { -+ fsl,qman-channel-id = <0x49>; -+ }; -+ /* offline 4 */ -+ port@85000 { -+ fsl,qman-channel-id = <0x4a>; -+ }; -+ /* offline 5 */ -+ port@86000 { -+ fsl,qman-channel-id = <0x4b>; -+ }; -+ }; -+ -+/include/ "qoriq-fman-1.dtsi" -+/include/ "qoriq-fman-1-1g-0.dtsi" -+/include/ "qoriq-fman-1-1g-1.dtsi" -+/include/ "qoriq-fman-1-1g-2.dtsi" -+/include/ "qoriq-fman-1-1g-3.dtsi" -+/include/ "qoriq-fman-1-1g-4.dtsi" -+/include/ "qoriq-fman-1-10g-0.dtsi" -+ fman1: fman@500000 { -+ /* tx - 1g - 0 */ -+ port@a8000 { -+ fsl,qman-channel-id = <0x61>; -+ }; -+ /* tx - 1g - 1 */ -+ port@a9000 { -+ fsl,qman-channel-id = <0x62>; -+ }; -+ /* tx - 1g - 2 */ -+ port@aa000 { -+ fsl,qman-channel-id = <0x63>; -+ }; -+ /* tx - 1g - 3 */ -+ port@ab000 { -+ fsl,qman-channel-id = <0x64>; -+ }; -+ /* tx - 1g - 4 */ -+ port@ac000 { -+ fsl,qman-channel-id = <0x65>; -+ }; -+ /* tx - 10g - 0 */ -+ port@b0000 { -+ fsl,qman-channel-id = <0x60>; -+ }; -+ /* offline 0 */ -+ port@81000 { -+ fsl,qman-channel-id = <0x66>; -+ }; -+ /* offline 1 */ -+ port@82000 { -+ fsl,qman-channel-id = <0x67>; -+ }; -+ /* offline 2 */ -+ port@83000 { -+ fsl,qman-channel-id = <0x68>; -+ }; -+ /* offline 3 */ -+ port@84000 { -+ fsl,qman-channel-id = <0x69>; -+ }; -+ /* offline 4 */ -+ port@85000 { -+ fsl,qman-channel-id = <0x6a>; -+ }; -+ /* offline 5 */ -+ port@86000 { -+ fsl,qman-channel-id = <0x6b>; -+ }; -+ }; -+ -+/include/ "qoriq-raid1.0-0.dtsi" -+}; -diff --git a/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi -new file mode 100644 -index 0000000..64edbf1 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi -@@ -0,0 +1,125 @@ -+/* -+ * P5040 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+ -+/include/ "e5500_power_isa.dtsi" -+ -+/ { -+ compatible = "fsl,P5040"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ ccsr = &soc; -+ dcsr = &dcsr; -+ -+ serial0 = &serial0; -+ serial1 = &serial1; -+ serial2 = &serial2; -+ serial3 = &serial3; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ usb0 = &usb0; -+ usb1 = &usb1; -+ dma0 = &dma0; -+ dma1 = &dma1; -+ sdhc = &sdhc; -+ msi0 = &msi0; -+ msi1 = &msi1; -+ msi2 = &msi2; -+ -+ crypto = &crypto; -+ sec_jr0 = &sec_jr0; -+ sec_jr1 = &sec_jr1; -+ sec_jr2 = &sec_jr2; -+ sec_jr3 = &sec_jr3; -+ rtic_a = &rtic_a; -+ rtic_b = &rtic_b; -+ rtic_c = &rtic_c; -+ rtic_d = &rtic_d; -+ sec_mon = &sec_mon; -+ -+ raideng = &raideng; -+ raideng_jr0 = &raideng_jr0; -+ raideng_jr1 = &raideng_jr1; -+ raideng_jr2 = &raideng_jr2; -+ raideng_jr3 = &raideng_jr3; -+ -+ bman = &bman; -+ qman = &qman; -+ fman0 = &fman0; -+ fman1 = &fman1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu0: PowerPC,e5500@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ next-level-cache = <&L2_0>; -+ L2_0: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu1: PowerPC,e5500@1 { -+ device_type = "cpu"; -+ reg = <1>; -+ next-level-cache = <&L2_1>; -+ L2_1: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu2: PowerPC,e5500@2 { -+ device_type = "cpu"; -+ reg = <2>; -+ next-level-cache = <&L2_2>; -+ L2_2: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ cpu3: PowerPC,e5500@3 { -+ device_type = "cpu"; -+ reg = <3>; -+ next-level-cache = <&L2_3>; -+ L2_3: l2-cache { -+ next-level-cache = <&cpc>; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-dma-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-dma-0.dtsi -new file mode 100644 -index 0000000..b5b37ad ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-dma-0.dtsi -@@ -0,0 +1,66 @@ -+/* -+ * PQ3 DMA device tree stub [ controller @ offset 0x21000 ] -+ * -+ * 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. -+ */ -+ -+dma@21300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0x21300 0x4>; -+ ranges = <0x0 0x21100 0x200>; -+ cell-index = <0>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupts = <20 2 0 0>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupts = <21 2 0 0>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupts = <22 2 0 0>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupts = <23 2 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-dma-1.dtsi b/arch/powerpc/boot/dts/fsl/pq3-dma-1.dtsi -new file mode 100644 -index 0000000..28cb8a5 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-dma-1.dtsi -@@ -0,0 +1,66 @@ -+/* -+ * PQ3 DMA device tree stub [ controller @ offset 0xc300 ] -+ * -+ * 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. -+ */ -+ -+dma@c300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0xc300 0x4>; -+ ranges = <0x0 0xc100 0x200>; -+ cell-index = <1>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupts = <76 2 0 0>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupts = <77 2 0 0>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupts = <78 2 0 0>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupts = <79 2 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-duart-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-duart-0.dtsi -new file mode 100644 -index 0000000..5e268fd ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-duart-0.dtsi -@@ -0,0 +1,51 @@ -+/* -+ * PQ3 DUART device tree stub [ controller @ offset 0x4000 ] -+ * -+ * 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. -+ */ -+ -+serial0: serial@4500 { -+ cell-index = <0>; -+ device_type = "serial"; -+ compatible = "fsl,ns16550", "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 2 0 0>; -+}; -+ -+serial1: serial@4600 { -+ cell-index = <1>; -+ device_type = "serial"; -+ compatible = "fsl,ns16550", "ns16550"; -+ reg = <0x4600 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-esdhc-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-esdhc-0.dtsi -new file mode 100644 -index 0000000..5743433 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-esdhc-0.dtsi -@@ -0,0 +1,41 @@ -+/* -+ * PQ3 eSDHC device tree stub [ controller @ offset 0x2e000 ] -+ * -+ * 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. -+ */ -+ -+sdhc@2e000 { -+ compatible = "fsl,esdhc"; -+ reg = <0x2e000 0x1000>; -+ interrupts = <72 0x2 0 0>; -+ /* Filled in by U-Boot */ -+ clock-frequency = <0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-espi-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-espi-0.dtsi -new file mode 100644 -index 0000000..75854b2 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-espi-0.dtsi -@@ -0,0 +1,41 @@ -+/* -+ * PQ3 eSPI device tree stub [ controller @ offset 0x7000 ] -+ * -+ * 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. -+ */ -+ -+spi@7000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,mpc8536-espi"; -+ reg = <0x7000 0x1000>; -+ interrupts = <59 0x2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-etsec1-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-etsec1-0.dtsi -new file mode 100644 -index 0000000..3b0650a ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-etsec1-0.dtsi -@@ -0,0 +1,54 @@ -+/* -+ * PQ3 eTSEC device tree stub [ @ offsets 0x24000 ] -+ * -+ * 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. -+ */ -+ -+ethernet@24000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <0>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x24000 0x1000>; -+ ranges = <0x0 0x24000 0x1000>; -+ fsl,magic-packet; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <29 2 0 0 30 2 0 0 34 2 0 0>; -+}; -+ -+mdio@24520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-etsec1-1.dtsi b/arch/powerpc/boot/dts/fsl/pq3-etsec1-1.dtsi -new file mode 100644 -index 0000000..96693b4 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-etsec1-1.dtsi -@@ -0,0 +1,54 @@ -+/* -+ * PQ3 eTSEC device tree stub [ @ offsets 0x25000 ] -+ * -+ * 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. -+ */ -+ -+ethernet@25000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x25000 0x1000>; -+ ranges = <0x0 0x25000 0x1000>; -+ fsl,magic-packet; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <35 2 0 0 36 2 0 0 40 2 0 0>; -+}; -+ -+mdio@25520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-tbi"; -+ reg = <0x25520 0x20>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-etsec1-2.dtsi b/arch/powerpc/boot/dts/fsl/pq3-etsec1-2.dtsi -new file mode 100644 -index 0000000..6b3fab1 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-etsec1-2.dtsi -@@ -0,0 +1,54 @@ -+/* -+ * PQ3 eTSEC device tree stub [ @ offsets 0x26000 ] -+ * -+ * 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. -+ */ -+ -+ethernet@26000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <2>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x26000 0x1000>; -+ ranges = <0x0 0x26000 0x1000>; -+ fsl,magic-packet; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <31 2 0 0 32 2 0 0 33 2 0 0>; -+}; -+ -+mdio@26520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-tbi"; -+ reg = <0x26520 0x20>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-etsec1-3.dtsi b/arch/powerpc/boot/dts/fsl/pq3-etsec1-3.dtsi -new file mode 100644 -index 0000000..0da592d ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-etsec1-3.dtsi -@@ -0,0 +1,54 @@ -+/* -+ * PQ3 eTSEC device tree stub [ @ offsets 0x27000 ] -+ * -+ * 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. -+ */ -+ -+ethernet@27000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <3>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x27000 0x1000>; -+ ranges = <0x0 0x27000 0x1000>; -+ fsl,magic-packet; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <37 2 0 0 38 2 0 0 39 2 0 0>; -+}; -+ -+mdio@27520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-tbi"; -+ reg = <0x27520 0x20>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-etsec1-timer-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-etsec1-timer-0.dtsi -new file mode 100644 -index 0000000..efe2ca0 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-etsec1-timer-0.dtsi -@@ -0,0 +1,39 @@ -+/* -+ * PQ3 eTSEC Timer (IEEE 1588) device tree stub [ @ offsets 0x24e00 ] -+ * -+ * 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. -+ */ -+ -+ptp_clock@24e00 { -+ compatible = "fsl,etsec-ptp"; -+ reg = <0x24e00 0xb0>; -+ interrupts = <68 2 0 0 69 2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi -new file mode 100644 -index 0000000..1382fec ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi -@@ -0,0 +1,60 @@ -+/* -+ * PQ3 eTSEC2 device tree stub [ @ offsets 0x24000/0xb0000 ] -+ * -+ * 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. -+ */ -+ -+ -+mdio@24000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,etsec2-mdio"; -+ reg = <0x24000 0x1000 0xb0030 0x4>; -+}; -+ -+ethernet@b0000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "fsl,etsec2"; -+ fsl,num_rx_queues = <0x8>; -+ fsl,num_tx_queues = <0x8>; -+ fsl,magic-packet; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ -+ queue-group@b0000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0xb0000 0x1000>; -+ interrupts = <29 2 0 0 30 2 0 0 34 2 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-etsec2-1.dtsi b/arch/powerpc/boot/dts/fsl/pq3-etsec2-1.dtsi -new file mode 100644 -index 0000000..221cd2e ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-etsec2-1.dtsi -@@ -0,0 +1,60 @@ -+/* -+ * PQ3 eTSEC2 device tree stub [ @ offsets 0x25000/0xb1000 ] -+ * -+ * 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. -+ */ -+ -+ -+mdio@25000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,etsec2-tbi"; -+ reg = <0x25000 0x1000 0xb1030 0x4>; -+}; -+ -+ethernet@b1000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "fsl,etsec2"; -+ fsl,num_rx_queues = <0x8>; -+ fsl,num_tx_queues = <0x8>; -+ fsl,magic-packet; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ -+ queue-group@b1000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0xb1000 0x1000>; -+ interrupts = <35 2 0 0 36 2 0 0 40 2 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-etsec2-2.dtsi b/arch/powerpc/boot/dts/fsl/pq3-etsec2-2.dtsi -new file mode 100644 -index 0000000..61456c3 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-etsec2-2.dtsi -@@ -0,0 +1,59 @@ -+/* -+ * PQ3 eTSEC2 device tree stub [ @ offsets 0x26000/0xb2000 ] -+ * -+ * 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. -+ */ -+ -+mdio@26000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,etsec2-tbi"; -+ reg = <0x26000 0x1000 0xb1030 0x4>; -+}; -+ -+ethernet@b2000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "fsl,etsec2"; -+ fsl,num_rx_queues = <0x8>; -+ fsl,num_tx_queues = <0x8>; -+ fsl,magic-packet; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ -+ queue-group@b2000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0xb2000 0x1000>; -+ interrupts = <31 2 0 0 32 2 0 0 33 2 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-etsec2-grp2-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-etsec2-grp2-0.dtsi -new file mode 100644 -index 0000000..034ab8f ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-etsec2-grp2-0.dtsi -@@ -0,0 +1,42 @@ -+/* -+ * PQ3 eTSEC2 Group 2 device tree stub [ @ offsets 0xb4000 ] -+ * -+ * 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. -+ */ -+ -+&enet0_grp2 { -+ queue-group@b4000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0xb4000 0x1000>; -+ interrupts = <17 2 0 0 18 2 0 0 24 2 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-etsec2-grp2-1.dtsi b/arch/powerpc/boot/dts/fsl/pq3-etsec2-grp2-1.dtsi -new file mode 100644 -index 0000000..3be9ba3 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-etsec2-grp2-1.dtsi -@@ -0,0 +1,42 @@ -+/* -+ * PQ3 eTSEC2 Group 2 device tree stub [ @ offsets 0xb5000 ] -+ * -+ * 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. -+ */ -+ -+&enet1_grp2 { -+ queue-group@b5000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0xb5000 0x1000>; -+ interrupts = <51 2 0 0 52 2 0 0 67 2 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-etsec2-grp2-2.dtsi b/arch/powerpc/boot/dts/fsl/pq3-etsec2-grp2-2.dtsi -new file mode 100644 -index 0000000..02a3345 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-etsec2-grp2-2.dtsi -@@ -0,0 +1,42 @@ -+/* -+ * PQ3 eTSEC2 Group 2 device tree stub [ @ offsets 0xb6000 ] -+ * -+ * 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. -+ */ -+ -+&enet2_grp2 { -+ queue-group@b6000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0xb6000 0x1000>; -+ interrupts = <25 2 0 0 26 2 0 0 27 2 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-gpio-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-gpio-0.dtsi -new file mode 100644 -index 0000000..72a3ef5 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-gpio-0.dtsi -@@ -0,0 +1,41 @@ -+/* -+ * PQ3 GPIO device tree stub [ controller @ offset 0xf000 ] -+ * -+ * 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. -+ */ -+ -+gpio-controller@f000 { -+ #gpio-cells = <2>; -+ compatible = "fsl,pq3-gpio"; -+ reg = <0xf000 0x100>; -+ interrupts = <47 0x2 0 0>; -+ gpio-controller; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-i2c-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-i2c-0.dtsi -new file mode 100644 -index 0000000..d1dd6fb ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-i2c-0.dtsi -@@ -0,0 +1,43 @@ -+/* -+ * PQ3 I2C device tree stub [ controller @ offset 0x3000 ] -+ * -+ * 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. -+ */ -+ -+i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <43 2 0 0>; -+ dfsrr; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-i2c-1.dtsi b/arch/powerpc/boot/dts/fsl/pq3-i2c-1.dtsi -new file mode 100644 -index 0000000..a9bd803 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-i2c-1.dtsi -@@ -0,0 +1,43 @@ -+/* -+ * PQ3 I2C device tree stub [ controller @ offset 0x3100 ] -+ * -+ * 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. -+ */ -+ -+i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <43 2 0 0>; -+ dfsrr; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-mpic-timer-B.dtsi b/arch/powerpc/boot/dts/fsl/pq3-mpic-timer-B.dtsi -new file mode 100644 -index 0000000..8734cff ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-mpic-timer-B.dtsi -@@ -0,0 +1,42 @@ -+/* -+ * PQ3 MPIC Timer (Group B) device tree stub [ controller @ offset 0x42100 ] -+ * -+ * 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. -+ */ -+ -+timer@42100 { -+ compatible = "fsl,mpic-global-timer"; -+ reg = <0x42100 0x100 0x42300 4>; -+ interrupts = <4 0 3 0 -+ 5 0 3 0 -+ 6 0 3 0 -+ 7 0 3 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi b/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi -new file mode 100644 -index 0000000..5c80460 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi -@@ -0,0 +1,66 @@ -+/* -+ * PQ3 MPIC device tree stub [ controller @ offset 0x40000 ] -+ * -+ * 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. -+ */ -+ -+mpic: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <4>; -+ reg = <0x40000 0x40000>; -+ compatible = "fsl,mpic"; -+ device_type = "open-pic"; -+}; -+ -+timer@41100 { -+ compatible = "fsl,mpic-global-timer"; -+ reg = <0x41100 0x100 0x41300 4>; -+ interrupts = <0 0 3 0 -+ 1 0 3 0 -+ 2 0 3 0 -+ 3 0 3 0>; -+}; -+ -+msi@41600 { -+ compatible = "fsl,mpic-msi"; -+ reg = <0x41600 0x80>; -+ msi-available-ranges = <0 0x100>; -+ interrupts = < -+ 0xe0 0 0 0 -+ 0xe1 0 0 0 -+ 0xe2 0 0 0 -+ 0xe3 0 0 0 -+ 0xe4 0 0 0 -+ 0xe5 0 0 0 -+ 0xe6 0 0 0 -+ 0xe7 0 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-power.dtsi b/arch/powerpc/boot/dts/fsl/pq3-power.dtsi -new file mode 100644 -index 0000000..5aa854c ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-power.dtsi -@@ -0,0 +1,48 @@ -+/* -+ * PQ3 Power Management device tree stub -+ * -+ * 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. -+ */ -+ -+power@e0070 { -+ compatible = "fsl,mpc8548-pmc"; -+ reg = <0xe0070 0x20>; -+ -+ etsec1_clk: soc-clk@24 { -+ fsl,pmcdr-mask = <0x00000080>; -+ }; -+ etsec2_clk: soc-clk@25 { -+ fsl,pmcdr-mask = <0x00000040>; -+ }; -+ etsec3_clk: soc-clk@26 { -+ fsl,pmcdr-mask = <0x00000020>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-rmu-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-rmu-0.dtsi -new file mode 100644 -index 0000000..587ca9f ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-rmu-0.dtsi -@@ -0,0 +1,68 @@ -+/* -+ * PQ3 RIO Message Unit device tree stub [ controller @ offset 0xd3000 ] -+ * -+ * 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. -+ */ -+ -+rmu: rmu@d3000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,srio-rmu"; -+ reg = <0xd3000 0x500>; -+ ranges = <0x0 0xd3000 0x500>; -+ -+ message-unit@0 { -+ compatible = "fsl,srio-msg-unit"; -+ reg = <0x0 0x100>; -+ interrupts = < -+ 53 2 0 0 /* msg1_tx_irq */ -+ 54 2 0 0>;/* msg1_rx_irq */ -+ }; -+ message-unit@100 { -+ compatible = "fsl,srio-msg-unit"; -+ reg = <0x100 0x100>; -+ interrupts = < -+ 55 2 0 0 /* msg2_tx_irq */ -+ 56 2 0 0>;/* msg2_rx_irq */ -+ }; -+ doorbell-unit@400 { -+ compatible = "fsl,srio-dbell-unit"; -+ reg = <0x400 0x80>; -+ interrupts = < -+ 49 2 0 0 /* bell_outb_irq */ -+ 50 2 0 0>;/* bell_inb_irq */ -+ }; -+ port-write-unit@4e0 { -+ compatible = "fsl,srio-port-write-unit"; -+ reg = <0x4e0 0x20>; -+ interrupts = <48 2 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-sata2-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-sata2-0.dtsi -new file mode 100644 -index 0000000..3c28dd0 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-sata2-0.dtsi -@@ -0,0 +1,40 @@ -+/* -+ * PQ3 SATAv2 device tree stub [ controller @ offset 0x18000 ] -+ * -+ * 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. -+ */ -+ -+sata@18000 { -+ compatible = "fsl,pq-sata-v2"; -+ reg = <0x18000 0x1000>; -+ cell-index = <1>; -+ interrupts = <74 0x2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-sata2-1.dtsi b/arch/powerpc/boot/dts/fsl/pq3-sata2-1.dtsi -new file mode 100644 -index 0000000..eefaf28 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-sata2-1.dtsi -@@ -0,0 +1,40 @@ -+/* -+ * PQ3 SATAv2 device tree stub [ controller @ offset 0x19000 ] -+ * -+ * 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. -+ */ -+ -+sata@19000 { -+ compatible = "fsl,pq-sata-v2"; -+ reg = <0x19000 0x1000>; -+ cell-index = <2>; -+ interrupts = <41 0x2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-sec2.1-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-sec2.1-0.dtsi -new file mode 100644 -index 0000000..02a5c7a ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-sec2.1-0.dtsi -@@ -0,0 +1,43 @@ -+/* -+ * PQ3 Sec/Crypto 2.1 device tree stub [ controller @ offset 0x30000 ] -+ * -+ * 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. -+ */ -+ -+crypto@30000 { -+ compatible = "fsl,sec2.1", "fsl,sec2.0"; -+ reg = <0x30000 0x10000>; -+ interrupts = <45 2 0 0>; -+ fsl,num-channels = <4>; -+ fsl,channel-fifo-len = <24>; -+ fsl,exec-units-mask = <0xfe>; -+ fsl,descriptor-types-mask = <0x12b0ebf>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-sec3.0-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-sec3.0-0.dtsi -new file mode 100644 -index 0000000..bba1ba4 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-sec3.0-0.dtsi -@@ -0,0 +1,45 @@ -+/* -+ * PQ3 Sec/Crypto 3.0 device tree stub [ controller @ offset 0x30000 ] -+ * -+ * 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. -+ */ -+ -+crypto@30000 { -+ compatible = "fsl,sec3.0", -+ "fsl,sec2.4", "fsl,sec2.2", "fsl,sec2.1", -+ "fsl,sec2.0"; -+ reg = <0x30000 0x10000>; -+ interrupts = <45 2 0 0 58 2 0 0>; -+ fsl,num-channels = <4>; -+ fsl,channel-fifo-len = <24>; -+ fsl,exec-units-mask = <0x9fe>; -+ fsl,descriptor-types-mask = <0x3ab0ebf>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-sec3.1-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-sec3.1-0.dtsi -new file mode 100644 -index 0000000..8f0a566 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-sec3.1-0.dtsi -@@ -0,0 +1,45 @@ -+/* -+ * PQ3 Sec/Crypto 3.1 device tree stub [ controller @ offset 0x30000 ] -+ * -+ * 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. -+ */ -+ -+crypto@30000 { -+ compatible = "fsl,sec3.1", "fsl,sec3.0", -+ "fsl,sec2.4", "fsl,sec2.2", "fsl,sec2.1", -+ "fsl,sec2.0"; -+ reg = <0x30000 0x10000>; -+ interrupts = <45 2 0 0 58 2 0 0>; -+ fsl,num-channels = <4>; -+ fsl,channel-fifo-len = <24>; -+ fsl,exec-units-mask = <0xbfe>; -+ fsl,descriptor-types-mask = <0x3ab0ebf>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-sec3.3-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-sec3.3-0.dtsi -new file mode 100644 -index 0000000..c227f27 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-sec3.3-0.dtsi -@@ -0,0 +1,45 @@ -+/* -+ * PQ3 Sec/Crypto 3.3 device tree stub [ controller @ offset 0x30000 ] -+ * -+ * 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. -+ */ -+ -+crypto@30000 { -+ compatible = "fsl,sec3.3", "fsl,sec3.1", "fsl,sec3.0", -+ "fsl,sec2.4", "fsl,sec2.2", "fsl,sec2.1", -+ "fsl,sec2.0"; -+ reg = <0x30000 0x10000>; -+ interrupts = <45 2 0 0 58 2 0 0>; -+ fsl,num-channels = <4>; -+ fsl,channel-fifo-len = <24>; -+ fsl,exec-units-mask = <0x97c>; -+ fsl,descriptor-types-mask = <0x3a30abf>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-sec4.4-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-sec4.4-0.dtsi -new file mode 100644 -index 0000000..ffadcb5 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-sec4.4-0.dtsi -@@ -0,0 +1,66 @@ -+/* -+ * PQ3 Sec/Crypto 4.4 device tree stub [ controller @ offset 0x30000 ] -+ * -+ * 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. -+ */ -+ -+crypto@30000 { -+ compatible = "fsl,sec-v4.4", "fsl,sec-v4.0"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x0 0x30000 0x10000>; -+ reg = <0x30000 0x10000>; -+ interrupts = <58 2 0 0>; -+ -+ sec_jr0: jr@1000 { -+ compatible = "fsl,sec-v4.4-job-ring", "fsl,sec-v4.0-job-ring"; -+ reg = <0x1000 0x1000>; -+ interrupts = <45 2 0 0>; -+ }; -+ -+ sec_jr1: jr@2000 { -+ compatible = "fsl,sec-v4.4-job-ring", "fsl,sec-v4.0-job-ring"; -+ reg = <0x2000 0x1000>; -+ interrupts = <45 2 0 0>; -+ }; -+ -+ sec_jr2: jr@3000 { -+ compatible = "fsl,sec-v4.4-job-ring", "fsl,sec-v4.0-job-ring"; -+ reg = <0x3000 0x1000>; -+ interrupts = <45 2 0 0>; -+ }; -+ -+ sec_jr3: jr@4000 { -+ compatible = "fsl,sec-v4.4-job-ring", "fsl,sec-v4.0-job-ring"; -+ reg = <0x4000 0x1000>; -+ interrupts = <45 2 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-tdm1.0-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-tdm1.0-0.dtsi -new file mode 100644 -index 0000000..d4bdd5d ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-tdm1.0-0.dtsi -@@ -0,0 +1,41 @@ -+/* -+ * PQ3 TDM device tree stub [ controller @ offset 0x16000 ] -+ * -+ * 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. -+ */ -+ -+tdm@16000 { -+ compatible = "fsl,tdm1.0"; -+ reg = <0x16000 0x200 0x2c000 0x2000>; -+ clock-frequency = <0>; -+ interrupts = <62 8 0 0>; -+ fsl,max-time-slots = <128>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-usb2-dr-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-usb2-dr-0.dtsi -new file mode 100644 -index 0000000..185ab9d ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-usb2-dr-0.dtsi -@@ -0,0 +1,41 @@ -+/* -+ * PQ3 USB DR device tree stub [ controller @ offset 0x22000 ] -+ * -+ * 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. -+ */ -+ -+usb@22000 { -+ compatible = "fsl-usb2-dr"; -+ reg = <0x22000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = <28 0x2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/pq3-usb2-dr-1.dtsi b/arch/powerpc/boot/dts/fsl/pq3-usb2-dr-1.dtsi -new file mode 100644 -index 0000000..fe24cd6 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/pq3-usb2-dr-1.dtsi -@@ -0,0 +1,41 @@ -+/* -+ * PQ3 USB DR device tree stub [ controller @ offset 0x23000 ] -+ * -+ * 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. -+ */ -+ -+usb@23000 { -+ compatible = "fsl-usb2-dr"; -+ reg = <0x23000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = <46 0x2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi b/arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi -new file mode 100644 -index 0000000..8bf4a72 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi -@@ -0,0 +1,41 @@ -+/* -+ * QorIQ Qonverge USB Host device tree stub [ controller @ offset 0x210000 ] -+ * -+ * 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. -+ */ -+ -+usb@210000 { -+ compatible = "fsl-usb2-dr"; -+ reg = <0x210000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = <44 0x2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-bman1-portals.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-bman1-portals.dtsi -new file mode 100644 -index 0000000..88ccba4 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-bman1-portals.dtsi -@@ -0,0 +1,97 @@ -+/* -+ * QorIQ BMan Portal device tree stub for 10 portals -+ * -+ * 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. -+ */ -+ -+#address-cells = <0x1>; -+#size-cells = <0x1>; -+compatible = "simple-bus"; -+bman-portal@0 { -+ cell-index = <0x0>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x0 0x4000 0x100000 0x1000>; -+ interrupts = <105 2 0 0>; -+}; -+bman-portal@4000 { -+ cell-index = <0x1>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x4000 0x4000 0x101000 0x1000>; -+ interrupts = <107 2 0 0>; -+}; -+bman-portal@8000 { -+ cell-index = <2>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x8000 0x4000 0x102000 0x1000>; -+ interrupts = <109 2 0 0>; -+}; -+bman-portal@c000 { -+ cell-index = <0x3>; -+ compatible = "fsl,bman-portal"; -+ reg = <0xc000 0x4000 0x103000 0x1000>; -+ interrupts = <111 2 0 0>; -+}; -+bman-portal@10000 { -+ cell-index = <0x4>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x10000 0x4000 0x104000 0x1000>; -+ interrupts = <113 2 0 0>; -+}; -+bman-portal@14000 { -+ cell-index = <0x5>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x14000 0x4000 0x105000 0x1000>; -+ interrupts = <115 2 0 0>; -+}; -+bman-portal@18000 { -+ cell-index = <0x6>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x18000 0x4000 0x106000 0x1000>; -+ interrupts = <117 2 0 0>; -+}; -+bman-portal@1c000 { -+ cell-index = <0x7>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x1c000 0x4000 0x107000 0x1000>; -+ interrupts = <119 2 0 0>; -+}; -+bman-portal@20000 { -+ cell-index = <0x8>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x20000 0x4000 0x108000 0x1000>; -+ interrupts = <121 2 0 0>; -+}; -+bman-portal@24000 { -+ cell-index = <0x9>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x24000 0x4000 0x109000 0x1000>; -+ interrupts = <123 2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-bman1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-bman1.dtsi -new file mode 100644 -index 0000000..b05be1c ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-bman1.dtsi -@@ -0,0 +1,39 @@ -+/* -+ * QorIQ BMan device tree stub [ controller @ offset 0x31a000 ] -+ * -+ * 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. -+ */ -+ -+bman: bman@31a000 { -+ compatible = "fsl,bman"; -+ reg = <0x31a000 0x1000>; -+ interrupts = <16 2 1 2>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-bman2-portals.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-bman2-portals.dtsi -new file mode 100644 -index 0000000..8c0ced5 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-bman2-portals.dtsi -@@ -0,0 +1,338 @@ -+/* -+ * QorIQ BMan Portal device tree stub for 50 portals -+ * i.e BMan2.1 -+ * -+ * 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. -+ */ -+ -+#address-cells = <0x1>; -+#size-cells = <0x1>; -+compatible = "simple-bus"; -+bman-portal@0 { -+ cell-index = <0x0>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x0 0x4000 0x1000000 0x1000>; -+ interrupts = <105 2 0 0>; -+}; -+bman-portal@4000 { -+ cell-index = <0x1>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x4000 0x4000 0x1001000 0x1000>; -+ interrupts = <107 2 0 0>; -+}; -+bman-portal@8000 { -+ cell-index = <2>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x8000 0x4000 0x1002000 0x1000>; -+ interrupts = <109 2 0 0>; -+}; -+bman-portal@c000 { -+ cell-index = <0x3>; -+ compatible = "fsl,bman-portal"; -+ reg = <0xc000 0x4000 0x1003000 0x1000>; -+ interrupts = <111 2 0 0>; -+}; -+bman-portal@10000 { -+ cell-index = <0x4>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x10000 0x4000 0x1004000 0x1000>; -+ interrupts = <113 2 0 0>; -+}; -+bman-portal@14000 { -+ cell-index = <0x5>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x14000 0x4000 0x1005000 0x1000>; -+ interrupts = <115 2 0 0>; -+}; -+bman-portal@18000 { -+ cell-index = <0x6>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x18000 0x4000 0x1006000 0x1000>; -+ interrupts = <117 2 0 0>; -+}; -+bman-portal@1c000 { -+ cell-index = <0x7>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x1c000 0x4000 0x1007000 0x1000>; -+ interrupts = <119 2 0 0>; -+}; -+bman-portal@20000 { -+ cell-index = <0x8>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x20000 0x4000 0x1008000 0x1000>; -+ interrupts = <121 2 0 0>; -+}; -+bman-portal@24000 { -+ cell-index = <0x9>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x24000 0x4000 0x1009000 0x1000>; -+ interrupts = <123 2 0 0>; -+}; -+bman-portal@28000 { -+ cell-index = <0xa>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x28000 0x4000 0x100a000 0x1000>; -+ interrupts = <125 2 0 0>; -+}; -+bman-portal@2c000 { -+ cell-index = <0xb>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x2c000 0x4000 0x100b000 0x1000>; -+ interrupts = <127 2 0 0>; -+}; -+bman-portal@30000 { -+ cell-index = <0xc>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x30000 0x4000 0x100c000 0x1000>; -+ interrupts = <129 2 0 0>; -+}; -+bman-portal@34000 { -+ cell-index = <0xd>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x34000 0x4000 0x100d000 0x1000>; -+ interrupts = <131 2 0 0>; -+}; -+bman-portal@38000 { -+ cell-index = <0xe>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x38000 0x4000 0x100e000 0x1000>; -+ interrupts = <133 2 0 0>; -+}; -+bman-portal@3c000 { -+ cell-index = <0xf>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x3c000 0x4000 0x100f000 0x1000>; -+ interrupts = <135 2 0 0>; -+}; -+bman-portal@40000 { -+ cell-index = <0x10>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x40000 0x4000 0x1010000 0x1000>; -+ interrupts = <137 2 0 0>; -+}; -+bman-portal@44000 { -+ cell-index = <0x11>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x44000 0x4000 0x1011000 0x1000>; -+ interrupts = <139 2 0 0>; -+}; -+bman-portal@48000 { -+ cell-index = <0x12>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x48000 0x4000 0x1012000 0x1000>; -+ interrupts = <141 2 0 0>; -+}; -+bman-portal@4c000 { -+ cell-index = <0x13>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x4c000 0x4000 0x1013000 0x1000>; -+ interrupts = <143 2 0 0>; -+}; -+bman-portal@50000 { -+ cell-index = <0x14>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x50000 0x4000 0x1014000 0x1000>; -+ interrupts = <145 2 0 0>; -+}; -+bman-portal@54000 { -+ cell-index = <0x15>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x54000 0x4000 0x1015000 0x1000>; -+ interrupts = <147 2 0 0>; -+}; -+bman-portal@58000 { -+ cell-index = <0x16>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x58000 0x4000 0x1016000 0x1000>; -+ interrupts = <149 2 0 0>; -+}; -+bman-portal@5c000 { -+ cell-index = <0x17>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x5c000 0x4000 0x1017000 0x1000>; -+ interrupts = <151 2 0 0>; -+}; -+bman-portal@60000 { -+ cell-index = <0x18>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x60000 0x4000 0x1018000 0x1000>; -+ interrupts = <153 2 0 0>; -+}; -+bman-portal@64000 { -+ cell-index = <0x19>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x64000 0x4000 0x1019000 0x1000>; -+ interrupts = <155 2 0 0>; -+}; -+bman-portal@68000 { -+ cell-index = <0x1a>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x68000 0x4000 0x101a000 0x1000>; -+ interrupts = <157 2 0 0>; -+}; -+bman-portal@6c000 { -+ cell-index = <0x1b>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x6c000 0x4000 0x101b000 0x1000>; -+ interrupts = <159 2 0 0>; -+}; -+bman-portal@70000 { -+ cell-index = <0x1c>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x70000 0x4000 0x101c000 0x1000>; -+ interrupts = <161 2 0 0>; -+}; -+bman-portal@74000 { -+ cell-index = <0x1d>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x74000 0x4000 0x101d000 0x1000>; -+ interrupts = <163 2 0 0>; -+}; -+bman-portal@78000 { -+ cell-index = <0x1e>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x78000 0x4000 0x101e000 0x1000>; -+ interrupts = <165 2 0 0>; -+}; -+bman-portal@7c000 { -+ cell-index = <0x1f>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x7c000 0x4000 0x101f000 0x1000>; -+ interrupts = <167 2 0 0>; -+}; -+bman-portal@80000 { -+ cell-index = <0x20>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x80000 0x4000 0x1020000 0x1000>; -+ interrupts = <169 2 0 0>; -+}; -+bman-portal@84000 { -+ cell-index = <0x21>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x84000 0x4000 0x1021000 0x1000>; -+ interrupts = <171 2 0 0>; -+}; -+bman-portal@88000 { -+ cell-index = <0x22>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x88000 0x4000 0x1022000 0x1000>; -+ interrupts = <173 2 0 0>; -+}; -+bman-portal@8c000 { -+ cell-index = <0x23>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x8c000 0x4000 0x1023000 0x1000>; -+ interrupts = <175 2 0 0>; -+}; -+bman-portal@90000 { -+ cell-index = <0x24>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x90000 0x4000 0x1024000 0x1000>; -+ interrupts = <385 2 0 0>; -+}; -+bman-portal@94000 { -+ cell-index = <0x25>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x94000 0x4000 0x1025000 0x1000>; -+ interrupts = <387 2 0 0>; -+}; -+bman-portal@98000 { -+ cell-index = <0x26>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x98000 0x4000 0x1026000 0x1000>; -+ interrupts = <389 2 0 0>; -+}; -+bman-portal@9c000 { -+ cell-index = <0x27>; -+ compatible = "fsl,bman-portal"; -+ reg = <0x9c000 0x4000 0x1027000 0x1000>; -+ interrupts = <391 2 0 0>; -+}; -+bman-portal@a0000 { -+ cell-index = <0x28>; -+ compatible = "fsl,bman-portal"; -+ reg = <0xa0000 0x4000 0x1028000 0x1000>; -+ interrupts = <393 2 0 0>; -+}; -+bman-portal@a4000 { -+ cell-index = <0x29>; -+ compatible = "fsl,bman-portal"; -+ reg = <0xa4000 0x4000 0x1029000 0x1000>; -+ interrupts = <395 2 0 0>; -+}; -+bman-portal@a8000 { -+ cell-index = <0x2a>; -+ compatible = "fsl,bman-portal"; -+ reg = <0xa8000 0x4000 0x102a000 0x1000>; -+ interrupts = <397 2 0 0>; -+}; -+bman-portal@ac000 { -+ cell-index = <0x2b>; -+ compatible = "fsl,bman-portal"; -+ reg = <0xac000 0x4000 0x102b000 0x1000>; -+ interrupts = <399 2 0 0>; -+}; -+bman-portal@b0000 { -+ cell-index = <0x2c>; -+ compatible = "fsl,bman-portal"; -+ reg = <0xb0000 0x4000 0x102c000 0x1000>; -+ interrupts = <401 2 0 0>; -+}; -+bman-portal@b4000 { -+ cell-index = <0x2d>; -+ compatible = "fsl,bman-portal"; -+ reg = <0xb4000 0x4000 0x102d000 0x1000>; -+ interrupts = <403 2 0 0>; -+}; -+bman-portal@b8000 { -+ cell-index = <0x2e>; -+ compatible = "fsl,bman-portal"; -+ reg = <0xb8000 0x4000 0x102e000 0x1000>; -+ interrupts = <405 2 0 0>; -+}; -+bman-portal@bc000 { -+ cell-index = <0x2f>; -+ compatible = "fsl,bman-portal"; -+ reg = <0xbc000 0x4000 0x102f000 0x1000>; -+ interrupts = <407 2 0 0>; -+}; -+bman-portal@c0000 { -+ cell-index = <0x30>; -+ compatible = "fsl,bman-portal"; -+ reg = <0xc0000 0x4000 0x1030000 0x1000>; -+ interrupts = <409 2 0 0>; -+}; -+bman-portal@c4000 { -+ cell-index = <0x31>; -+ compatible = "fsl,bman-portal"; -+ reg = <0xc4000 0x4000 0x1031000 0x1000>; -+ interrupts = <411 2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-dce-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-dce-0.dtsi -new file mode 100644 -index 0000000..9b747ba ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-dce-0.dtsi -@@ -0,0 +1,39 @@ -+/* -+ * QorIQ DCE device tree stub [ controller @ offset 0x312000 ] -+ * -+ * 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. -+ */ -+ -+dce: dce@312000 { -+ compatible = "fsl,dce"; -+ reg = <0x312000 0x10000>; -+ interrupts = <16 2 1 4>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-dma-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-dma-0.dtsi -new file mode 100644 -index 0000000..1aebf3e ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-dma-0.dtsi -@@ -0,0 +1,66 @@ -+/* -+ * QorIQ DMA device tree stub [ controller @ offset 0x100000 ] -+ * -+ * 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. -+ */ -+ -+dma0: dma@100300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0x100300 0x4>; -+ ranges = <0x0 0x100100 0x200>; -+ cell-index = <0>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupts = <28 2 0 0>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupts = <29 2 0 0>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupts = <30 2 0 0>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupts = <31 2 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-dma-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-dma-1.dtsi -new file mode 100644 -index 0000000..ecf5e18 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-dma-1.dtsi -@@ -0,0 +1,66 @@ -+/* -+ * QorIQ DMA device tree stub [ controller @ offset 0x101000 ] -+ * -+ * 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. -+ */ -+ -+dma1: dma@101300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0x101300 0x4>; -+ ranges = <0x0 0x101100 0x200>; -+ cell-index = <1>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupts = <32 2 0 0>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupts = <33 2 0 0>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupts = <34 2 0 0>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupts = <35 2 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-dpaa-res1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-dpaa-res1.dtsi -new file mode 100644 -index 0000000..6c6f7d7 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-dpaa-res1.dtsi -@@ -0,0 +1,84 @@ -+/* -+ * QorIQ DPAA resources device tree stub [ FQIDs, BPIDs ] -+ * -+ * 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. -+ */ -+ -+/* These stubs are required to alloc qbman drivers to determine what ranges of -+ * resources are available for dynamic allocation, primarily because there are -+ * some legacy "a priori" assumptions in certain subsystems (eg. networking) -+ * that certain resources are reserved for their use. When those drivers (and in -+ * some cases, their corresponding device-tree nodes) are updated to dynamically -+ * allocate their resources, then *all* resources can be managed by the -+ * allocators and there may be no further need to define these stubs. -+ * -+ * A couple of qualifiers to the above statement though: -+ * -+ * - Some resource ranges are hardware-specific, rather than being defined by -+ * software memory allocation choices. Eg. the number of available BPIDs is -+ * baked into silicon and so will probably always need to be expressed in the -+ * device-tree, though in that case it will express all BPIDs, not just those -+ * available for dynamic allocation. -+ * -+ * - Even for memory-backed resources that are software determined (FQIDs), this -+ * information may only be configured and available on the control-plane -+ * partition that manages the device, so in AMP or hypervised scenarios there -+ * may still be need to a way to provide allocation ranges. Ie. for O/S -+ * instances that don't know how many resources are available to hardware, and -+ * possibly even for O/S instances that do know how many are available but -+ * that should not "own" all of them. -+ */ -+ -+&bportals { -+ bman-bpids@0 { -+ compatible = "fsl,bpid-range"; -+ fsl,bpid-range = <32 32>; -+ }; -+}; -+ -+&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 = <0x21 0xf>; -+ }; -+ qman-cgrids@0 { -+ compatible = "fsl,cgrid-range"; -+ fsl,cgrid-range = <0 256>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-dpaa-res2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-dpaa-res2.dtsi -new file mode 100644 -index 0000000..73ee049 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-dpaa-res2.dtsi -@@ -0,0 +1,63 @@ -+/* -+ * QorIQ DPAA resources device tree stub [ FQIDs, BPIDs ] -+ * -+ * 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. -+ */ -+ -+/* The comments in qoriq-dpaa-res1.dtsi apply here too so will not be repeated. -+ * This alternative file is to support p1023 which does not have the same -+ * resource ranges as other SoCs to date. */ -+ -+&bportals { -+ bman-bpids@0 { -+ compatible = "fsl,bpid-range"; -+ fsl,bpid-range = <1 7>; -+ }; -+}; -+ -+&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 = <0x21 0x3>; -+ }; -+ qman-cgrids@0 { -+ compatible = "fsl,cgrid-range"; -+ fsl,cgrid-range = <0 64>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-dpaa-res3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-dpaa-res3.dtsi -new file mode 100644 -index 0000000..1bc5af9 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-dpaa-res3.dtsi -@@ -0,0 +1,84 @@ -+/* -+ * QorIQ DPAA resources device tree stub [ FQIDs, BPIDs ] -+ * -+ * 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. -+ */ -+ -+/* These stubs are required to alloc qbman drivers to determine what ranges of -+ * resources are available for dynamic allocation, primarily because there are -+ * some legacy "a priori" assumptions in certain subsystems (eg. networking) -+ * that certain resources are reserved for their use. When those drivers (and in -+ * some cases, their corresponding device-tree nodes) are updated to dynamically -+ * allocate their resources, then *all* resources can be managed by the -+ * allocators and there may be no further need to define these stubs. -+ * -+ * A couple of qualifiers to the above statement though: -+ * -+ * - Some resource ranges are hardware-specific, rather than being defined by -+ * software memory allocation choices. Eg. the number of available BPIDs is -+ * baked into silicon and so will probably always need to be expressed in the -+ * device-tree, though in that case it will express all BPIDs, not just those -+ * available for dynamic allocation. -+ * -+ * - Even for memory-backed resources that are software determined (FQIDs), this -+ * information may only be configured and available on the control-plane -+ * partition that manages the device, so in AMP or hypervised scenarios there -+ * may still be need to a way to provide allocation ranges. Ie. for O/S -+ * instances that don't know how many resources are available to hardware, and -+ * possibly even for O/S instances that do know how many are available but -+ * that should not "own" all of them. -+ */ -+ -+&bportals { -+ bman-bpids@0 { -+ compatible = "fsl,bpid-range"; -+ fsl,bpid-range = <32 32>; -+ }; -+}; -+ -+&qportals { -+ qman-fqids@0 { -+ compatible = "fsl,fqid-range"; -+ fsl,fqid-range = <256 512>; -+ }; -+ 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>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-duart-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-duart-0.dtsi -new file mode 100644 -index 0000000..225c07b ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-duart-0.dtsi -@@ -0,0 +1,51 @@ -+/* -+ * QorIQ DUART device tree stub [ controller @ offset 0x11c000 ] -+ * -+ * 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. -+ */ -+ -+serial0: serial@11c500 { -+ cell-index = <0>; -+ device_type = "serial"; -+ compatible = "fsl,ns16550", "ns16550"; -+ reg = <0x11c500 0x100>; -+ clock-frequency = <0>; -+ interrupts = <36 2 0 0>; -+}; -+ -+serial1: serial@11c600 { -+ cell-index = <1>; -+ device_type = "serial"; -+ compatible = "fsl,ns16550", "ns16550"; -+ reg = <0x11c600 0x100>; -+ clock-frequency = <0>; -+ interrupts = <36 2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-duart-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-duart-1.dtsi -new file mode 100644 -index 0000000..d23233a ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-duart-1.dtsi -@@ -0,0 +1,51 @@ -+/* -+ * QorIQ DUART device tree stub [ controller @ offset 0x11d000 ] -+ * -+ * 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. -+ */ -+ -+serial2: serial@11d500 { -+ cell-index = <2>; -+ device_type = "serial"; -+ compatible = "fsl,ns16550", "ns16550"; -+ reg = <0x11d500 0x100>; -+ clock-frequency = <0>; -+ interrupts = <37 2 0 0>; -+}; -+ -+serial3: serial@11d600 { -+ cell-index = <3>; -+ device_type = "serial"; -+ compatible = "fsl,ns16550", "ns16550"; -+ reg = <0x11d600 0x100>; -+ clock-frequency = <0>; -+ interrupts = <37 2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-esdhc-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-esdhc-0.dtsi -new file mode 100644 -index 0000000..20835ae ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-esdhc-0.dtsi -@@ -0,0 +1,40 @@ -+/* -+ * QorIQ eSDHC device tree stub [ controller @ offset 0x114000 ] -+ * -+ * 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. -+ */ -+ -+sdhc: sdhc@114000 { -+ compatible = "fsl,esdhc"; -+ reg = <0x114000 0x1000>; -+ interrupts = <48 2 0 0>; -+ clock-frequency = <0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-espi-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-espi-0.dtsi -new file mode 100644 -index 0000000..6db0697 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-espi-0.dtsi -@@ -0,0 +1,41 @@ -+/* -+ * QorIQ eSPI device tree stub [ controller @ offset 0x110000 ] -+ * -+ * 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. -+ */ -+ -+spi@110000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,mpc8536-espi"; -+ reg = <0x110000 0x1000>; -+ interrupts = <53 0x2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-10g-0.dtsi -new file mode 100644 -index 0000000..c5c5086 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-10g-0.dtsi -@@ -0,0 +1,63 @@ -+/* -+ * QorIQ FMan 10g port #0 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_10g_rx0: port@90000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-10g-rx"; -+ reg = <0x90000 0x1000>; -+ }; -+ -+ fman0_10g_tx0: port@b0000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-10g-tx"; -+ reg = <0xb0000 0x1000>; -+ fsl,qman-channel-id = <0x40>; -+ }; -+ -+ ethernet@f0000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-10g-mac"; -+ reg = <0xf0000 0x1000>; -+ fsl,port-handles = <&fman0_10g_rx0 &fman0_10g_tx0>; -+ }; -+ -+ xmdio0: mdio@f1000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-xmdio"; -+ reg = <0xf1000 0x1000>; -+ interrupts = <100 1 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-0.dtsi -new file mode 100644 -index 0000000..e52cb1f ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-0.dtsi -@@ -0,0 +1,63 @@ -+/* -+ * QorIQ FMan 1g port #0 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_rx0: port@88000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x88000 0x1000>; -+ }; -+ -+ fman0_tx0: port@a8000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xa8000 0x1000>; -+ }; -+ -+ ethernet@e0000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-1g-mac"; -+ reg = <0xe0000 0x1000>; -+ fsl,port-handles = <&fman0_rx0 &fman0_tx0>; -+ ptimer-handle = <&ptp_timer0>; -+ }; -+ -+ mdio0: mdio@e1120 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-mdio"; -+ reg = <0xe1120 0xee0>; -+ interrupts = <100 1 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-1.dtsi -new file mode 100644 -index 0000000..a500a84 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-1.dtsi -@@ -0,0 +1,63 @@ -+/* -+ * QorIQ FMan 1g port #1 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_rx1: port@89000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x89000 0x1000>; -+ }; -+ -+ fman0_tx1: port@a9000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xa9000 0x1000>; -+ }; -+ -+ ethernet@e2000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-1g-mac"; -+ reg = <0xe2000 0x1000>; -+ fsl,port-handles = <&fman0_rx1 &fman0_tx1>; -+ ptimer-handle = <&ptp_timer0>; -+ }; -+ -+ mdio@e3120 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-tbi"; -+ reg = <0xe3120 0xee0>; -+ interrupts = <100 1 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-2.dtsi -new file mode 100644 -index 0000000..14a8d22 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-2.dtsi -@@ -0,0 +1,63 @@ -+/* -+ * QorIQ FMan 1g port #2 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_rx2: port@8a000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8a000 0x1000>; -+ }; -+ -+ fman0_tx2: port@aa000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xaa000 0x1000>; -+ }; -+ -+ ethernet@e4000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-1g-mac"; -+ reg = <0xe4000 0x1000>; -+ fsl,port-handles = <&fman0_rx2 &fman0_tx2>; -+ ptimer-handle = <&ptp_timer0>; -+ }; -+ -+ mdio@e5120 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-tbi"; -+ reg = <0xe5120 0xee0>; -+ interrupts = <100 1 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-3.dtsi -new file mode 100644 -index 0000000..fbd5887 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-3.dtsi -@@ -0,0 +1,63 @@ -+/* -+ * QorIQ FMan 1g port #3 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_rx3: port@8b000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8b000 0x1000>; -+ }; -+ -+ fman0_tx3: port@ab000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xab000 0x1000>; -+ }; -+ -+ ethernet@e6000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-1g-mac"; -+ reg = <0xe6000 0x1000>; -+ fsl,port-handles = <&fman0_rx3 &fman0_tx3>; -+ ptimer-handle = <&ptp_timer0>; -+ }; -+ -+ mdio@e7120 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-tbi"; -+ reg = <0xe7120 0xee0>; -+ interrupts = <100 1 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-4.dtsi -new file mode 100644 -index 0000000..1c27647 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-4.dtsi -@@ -0,0 +1,63 @@ -+/* -+ * QorIQ FMan 1g port #4 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_rx4: port@8c000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8c000 0x1000>; -+ }; -+ -+ fman0_tx4: port@ac000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xac000 0x1000>; -+ }; -+ -+ ethernet@e8000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-1g-mac"; -+ reg = <0xe8000 0x1000>; -+ fsl,port-handles = <&fman0_rx4 &fman0_tx4>; -+ ptimer-handle = <&ptp_timer0>; -+ }; -+ -+ mdio@e9120 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-tbi"; -+ reg = <0xe9120 0xee0>; -+ interrupts = <100 1 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi -new file mode 100644 -index 0000000..b074d13 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi -@@ -0,0 +1,140 @@ -+/* -+ * QorIQ FMan device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman0: fman@400000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <0>; -+ compatible = "fsl,fman", "simple-bus"; -+ ranges = <0 0x400000 0x100000>; -+ reg = <0x400000 0x100000>; -+ clock-frequency = <0>; -+ interrupts = < -+ 96 2 0 0 -+ 16 2 1 1>; -+ -+ cc { -+ compatible = "fsl,fman-cc"; -+ }; -+ -+ muram@0 { -+ compatible = "fsl,fman-muram"; -+ reg = <0x0 0x28000>; -+ }; -+ -+ bmi@80000 { -+ compatible = "fsl,fman-bmi"; -+ reg = <0x80000 0x400>; -+ }; -+ -+ qmi@80400 { -+ compatible = "fsl,fman-qmi"; -+ reg = <0x80400 0x400>; -+ }; -+ -+ fman0_oh0: port@81000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x81000 0x1000>; -+ }; -+ -+ fman0_oh1: port@82000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x82000 0x1000>; -+ }; -+ -+ fman0_oh2: port@83000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x83000 0x1000>; -+ }; -+ -+ fman0_oh3: port@84000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x84000 0x1000>; -+ }; -+ -+ fman0_oh4: port@85000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x85000 0x1000>; -+ status = "disabled"; -+ }; -+ -+ fman0_oh5: port@86000 { -+ cell-index = <5>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x86000 0x1000>; -+ status = "disabled"; -+ }; -+ -+ fman0_oh6: port@87000 { -+ cell-index = <6>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x87000 0x1000>; -+ status = "disabled"; -+ }; -+ -+ 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>; -+ }; -+ -+ ptp_timer0: rtc@fe000 { -+ compatible = "fsl,fman-rtc"; -+ reg = <0xfe000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-10g-0.dtsi -new file mode 100644 -index 0000000..dcaf84a ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-10g-0.dtsi -@@ -0,0 +1,54 @@ -+/* -+ * QorIQ FMan 10g port #0 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_10g_rx0: port@90000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-10g-rx"; -+ reg = <0x90000 0x1000>; -+ }; -+ -+ fman1_10g_tx0: port@b0000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-10g-tx"; -+ reg = <0xb0000 0x1000>; -+ }; -+ -+ ethernet@f0000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-10g-mac"; -+ reg = <0xf0000 0x1000>; -+ fsl,port-handles = <&fman1_10g_rx0 &fman1_10g_tx0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-0.dtsi -new file mode 100644 -index 0000000..5280661 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-0.dtsi -@@ -0,0 +1,63 @@ -+/* -+ * QorIQ FMan 1g port #0 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_rx0: port@88000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x88000 0x1000>; -+ }; -+ -+ fman1_tx0: port@a8000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xa8000 0x1000>; -+ }; -+ -+ ethernet@e0000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-1g-mac"; -+ reg = <0xe0000 0x1000>; -+ fsl,port-handles = <&fman1_rx0 &fman1_tx0>; -+ ptimer-handle = <&ptp_timer1>; -+ }; -+ -+ mdio@e1120 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-tbi"; -+ reg = <0xe1120 0xee0>; -+ interrupts = <101 1 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-1.dtsi -new file mode 100644 -index 0000000..1d5fcde ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-1.dtsi -@@ -0,0 +1,63 @@ -+/* -+ * QorIQ FMan 1g port #1 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_rx1: port@89000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x89000 0x1000>; -+ }; -+ -+ fman1_tx1: port@a9000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xa9000 0x1000>; -+ }; -+ -+ ethernet@e2000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-1g-mac"; -+ reg = <0xe2000 0x1000>; -+ fsl,port-handles = <&fman1_rx1 &fman1_tx1>; -+ ptimer-handle = <&ptp_timer1>; -+ }; -+ -+ mdio@e3120 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-tbi"; -+ reg = <0xe3120 0xee0>; -+ interrupts = <101 1 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-2.dtsi -new file mode 100644 -index 0000000..cf6cab1 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-2.dtsi -@@ -0,0 +1,63 @@ -+/* -+ * QorIQ FMan 1g port #2 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_rx2: port@8a000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8a000 0x1000>; -+ }; -+ -+ fman1_tx2: port@aa000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xaa000 0x1000>; -+ }; -+ -+ ethernet@e4000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-1g-mac"; -+ reg = <0xe4000 0x1000>; -+ fsl,port-handles = <&fman1_rx2 &fman1_tx2>; -+ ptimer-handle = <&ptp_timer1>; -+ }; -+ -+ mdio@e5120 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-tbi"; -+ reg = <0xe5120 0xee0>; -+ interrupts = <101 1 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-3.dtsi -new file mode 100644 -index 0000000..0d85b37 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-3.dtsi -@@ -0,0 +1,63 @@ -+/* -+ * QorIQ FMan 1g port #3 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_rx3: port@8b000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8b000 0x1000>; -+ }; -+ -+ fman1_tx3: port@ab000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xab000 0x1000>; -+ }; -+ -+ ethernet@e6000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-1g-mac"; -+ reg = <0xe6000 0x1000>; -+ fsl,port-handles = <&fman1_rx3 &fman1_tx3>; -+ ptimer-handle = <&ptp_timer1>; -+ }; -+ -+ mdio@e7120 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-tbi"; -+ reg = <0xe7120 0xee0>; -+ interrupts = <101 1 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-4.dtsi -new file mode 100644 -index 0000000..ed0f504 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-4.dtsi -@@ -0,0 +1,63 @@ -+/* -+ * QorIQ FMan 1g port #4 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_rx4: port@8c000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8c000 0x1000>; -+ }; -+ -+ fman1_tx4: port@ac000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xac000 0x1000>; -+ }; -+ -+ ethernet@e8000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-1g-mac"; -+ reg = <0xe8000 0x1000>; -+ fsl,port-handles = <&fman1_rx4 &fman1_tx4>; -+ ptimer-handle = <&ptp_timer1>; -+ }; -+ -+ mdio@e9120 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-tbi"; -+ reg = <0xe9120 0xee0>; -+ interrupts = <101 1 0 0>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi -new file mode 100644 -index 0000000..d94f6cc ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi -@@ -0,0 +1,140 @@ -+/* -+ * QorIQ FMan device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman1: fman@500000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <1>; -+ compatible = "fsl,fman", "simple-bus"; -+ ranges = <0 0x500000 0x100000>; -+ reg = <0x500000 0x100000>; -+ clock-frequency = <0>; -+ interrupts = < -+ 97 2 0 0 -+ 16 2 1 0>; -+ -+ cc { -+ compatible = "fsl,fman-cc"; -+ }; -+ -+ muram@0 { -+ compatible = "fsl,fman-muram"; -+ reg = <0x0 0x28000>; -+ }; -+ -+ bmi@80000 { -+ compatible = "fsl,fman-bmi"; -+ reg = <0x80000 0x400>; -+ }; -+ -+ qmi@80400 { -+ compatible = "fsl,fman-qmi"; -+ reg = <0x80400 0x400>; -+ }; -+ -+ fman1_oh0: port@81000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x81000 0x1000>; -+ }; -+ -+ fman1_oh1: port@82000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x82000 0x1000>; -+ }; -+ -+ fman1_oh2: port@83000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x83000 0x1000>; -+ }; -+ -+ fman1_oh3: port@84000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x84000 0x1000>; -+ }; -+ -+ fman1_oh4: port@85000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x85000 0x1000>; -+ status = "disabled"; -+ }; -+ -+ fman1_oh5: port@86000 { -+ cell-index = <5>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x86000 0x1000>; -+ status = "disabled"; -+ }; -+ -+ fman1_oh6: port@87000 { -+ cell-index = <6>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x87000 0x1000>; -+ status = "disabled"; -+ }; -+ -+ 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>; -+ }; -+ -+ ptp_timer1: rtc@fe000 { -+ compatible = "fsl,fman-rtc"; -+ reg = <0xfe000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi -new file mode 100644 -index 0000000..72c306c ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 10g port #0 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_10g_rx0: port@90000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-10g-rx"; -+ reg = <0x90000 0x1000>; -+ }; -+ -+ fman0_10g_tx0: port@b0000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-10g-tx"; -+ reg = <0xb0000 0x1000>; -+ fsl,qman-channel-id = <0x800>; -+ }; -+ -+ ethernet@f0000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xf0000 0x1000>; -+ fsl,port-handles = <&fman0_10g_rx0 &fman0_10g_tx0>; -+ }; -+ -+ mdio@f1000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xf1000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi -new file mode 100644 -index 0000000..c53dadc ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 10g port #1 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_10g_rx1: port@91000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-10g-rx"; -+ reg = <0x91000 0x1000>; -+ }; -+ -+ fman0_10g_tx1: port@b1000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-10g-tx"; -+ reg = <0xb1000 0x1000>; -+ fsl,qman-channel-id = <0x801>; -+ }; -+ -+ ethernet@f2000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xf2000 0x1000>; -+ fsl,port-handles = <&fman0_10g_rx1 &fman0_10g_tx1>; -+ }; -+ -+ mdio@f3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xf3000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi -new file mode 100644 -index 0000000..5d34959 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 1g port #0 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_rx0: port@88000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x88000 0x1000>; -+ }; -+ -+ fman0_tx0: port@a8000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xa8000 0x1000>; -+ }; -+ -+ ethernet@e0000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xe0000 0x1000>; -+ fsl,port-handles = <&fman0_rx0 &fman0_tx0>; -+ ptimer-handle = <&ptp_timer0>; -+ }; -+ -+ mdio@e1000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xe1000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi -new file mode 100644 -index 0000000..39620a3 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 1g port #1 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_rx1: port@89000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x89000 0x1000>; -+ }; -+ -+ fman0_tx1: port@a9000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xa9000 0x1000>; -+ }; -+ -+ ethernet@e2000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xe2000 0x1000>; -+ fsl,port-handles = <&fman0_rx1 &fman0_tx1>; -+ ptimer-handle = <&ptp_timer0>; -+ }; -+ -+ mdio@e3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xe3000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi -new file mode 100644 -index 0000000..9c1fb1a ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 1g port #2 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_rx2: port@8a000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8a000 0x1000>; -+ }; -+ -+ fman0_tx2: port@aa000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xaa000 0x1000>; -+ }; -+ -+ ethernet@e4000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xe4000 0x1000>; -+ fsl,port-handles = <&fman0_rx2 &fman0_tx2>; -+ ptimer-handle = <&ptp_timer0>; -+ }; -+ -+ mdio@e5000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xe5000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi -new file mode 100644 -index 0000000..5d2ba1a ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 1g port #3 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_rx3: port@8b000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8b000 0x1000>; -+ }; -+ -+ fman0_tx3: port@ab000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xab000 0x1000>; -+ }; -+ -+ ethernet@e6000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xe6000 0x1000>; -+ fsl,port-handles = <&fman0_rx3 &fman0_tx3>; -+ ptimer-handle = <&ptp_timer0>; -+ }; -+ -+ mdio@e7000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xe7000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi -new file mode 100644 -index 0000000..4b1820b ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 1g port #4 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_rx4: port@8c000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8c000 0x1000>; -+ }; -+ -+ fman0_tx4: port@ac000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xac000 0x1000>; -+ }; -+ -+ ethernet@e8000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xe8000 0x1000>; -+ fsl,port-handles = <&fman0_rx4 &fman0_tx4>; -+ ptimer-handle = <&ptp_timer0>; -+ }; -+ -+ mdio@e9000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xe9000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi -new file mode 100644 -index 0000000..aa06d13 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 1g port #5 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman@400000 { -+ fman0_rx5: port@8d000 { -+ cell-index = <5>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8d000 0x1000>; -+ }; -+ -+ fman0_tx5: port@ad000 { -+ cell-index = <5>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xad000 0x1000>; -+ }; -+ -+ ethernet@ea000 { -+ cell-index = <5>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xea000 0x1000>; -+ fsl,port-handles = <&fman0_rx5 &fman0_tx5>; -+ ptimer-handle = <&ptp_timer0>; -+ }; -+ -+ mdio@eb000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xeb000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi -new file mode 100644 -index 0000000..28f38b9 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi -@@ -0,0 +1,150 @@ -+/* -+ * QorIQ FMan v3 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * 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. -+ */ -+ -+fman0: fman@400000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <0>; -+ compatible = "fsl,fman", "simple-bus"; -+ ranges = <0 0x400000 0x100000>; -+ reg = <0x400000 0x100000>; -+ clock-frequency = <0>; -+ interrupts = < -+ 96 2 0 0 -+ 16 2 1 1>; -+ -+ 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_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>; -+ }; -+ -+ 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>; -+ }; -+ -+ mdio@fc000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0xfc000 0x1000>; -+ }; -+ -+ mdio@fd000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0xfd000 0x1000>; -+ }; -+ -+ ptp_timer0: rtc@fe000 { -+ compatible = "fsl,fman-rtc"; -+ reg = <0xfe000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi -new file mode 100644 -index 0000000..b63fb54 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 10g port #0 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_10g_rx0: port@90000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-10g-rx"; -+ reg = <0x90000 0x1000>; -+ }; -+ -+ fman1_10g_tx0: port@b0000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-10g-tx"; -+ reg = <0xb0000 0x1000>; -+ fsl,qman-channel-id = <0x820>; -+ }; -+ -+ ethernet@f0000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xf0000 0x1000>; -+ fsl,port-handles = <&fman1_10g_rx0 &fman1_10g_tx0>; -+ }; -+ -+ mdio@f1000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xf1000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi -new file mode 100644 -index 0000000..56cb7b1 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 10g port #1 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_10g_rx1: port@91000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-10g-rx"; -+ reg = <0x91000 0x1000>; -+ }; -+ -+ fman1_10g_tx1: port@b1000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-10g-tx"; -+ reg = <0xb1000 0x1000>; -+ fsl,qman-channel-id = <0x821>; -+ }; -+ -+ ethernet@f2000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xf2000 0x1000>; -+ fsl,port-handles = <&fman1_10g_rx1 &fman1_10g_tx1>; -+ }; -+ -+ mdio@f3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xf3000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi -new file mode 100644 -index 0000000..6a4fea5 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 1g port #0 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_rx0: port@88000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x88000 0x1000>; -+ }; -+ -+ fman1_tx0: port@a8000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xa8000 0x1000>; -+ }; -+ -+ ethernet@e0000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xe0000 0x1000>; -+ fsl,port-handles = <&fman1_rx0 &fman1_tx0>; -+ ptimer-handle = <&ptp_timer1>; -+ }; -+ -+ mdio@e1000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xe1000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi -new file mode 100644 -index 0000000..80f0cd9 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 1g port #1 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_rx1: port@89000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x89000 0x1000>; -+ }; -+ -+ fman1_tx1: port@a9000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xa9000 0x1000>; -+ }; -+ -+ ethernet@e2000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xe2000 0x1000>; -+ fsl,port-handles = <&fman1_rx1 &fman1_tx1>; -+ ptimer-handle = <&ptp_timer1>; -+ }; -+ -+ mdio@e3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xe3000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi -new file mode 100644 -index 0000000..a0cbf96 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 1g port #2 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_rx2: port@8a000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8a000 0x1000>; -+ }; -+ -+ fman1_tx2: port@aa000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xaa000 0x1000>; -+ }; -+ -+ ethernet@e4000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xe4000 0x1000>; -+ fsl,port-handles = <&fman1_rx2 &fman1_tx2>; -+ ptimer-handle = <&ptp_timer1>; -+ }; -+ -+ mdio@e5000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xe5000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi -new file mode 100644 -index 0000000..636ff3e ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 1g port #3 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_rx3: port@8b000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8b000 0x1000>; -+ }; -+ -+ fman1_tx3: port@ab000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xab000 0x1000>; -+ }; -+ -+ ethernet@e6000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xe6000 0x1000>; -+ fsl,port-handles = <&fman1_rx3 &fman1_tx3>; -+ ptimer-handle = <&ptp_timer1>; -+ }; -+ -+ mdio@e7000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xe7000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi -new file mode 100644 -index 0000000..ba12e35 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 1g port #4 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_rx4: port@8c000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8c000 0x1000>; -+ }; -+ -+ fman1_tx4: port@ac000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xac000 0x1000>; -+ }; -+ -+ ethernet@e8000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xe8000 0x1000>; -+ fsl,port-handles = <&fman1_rx4 &fman1_tx4>; -+ ptimer-handle = <&ptp_timer1>; -+ }; -+ -+ mdio@e9000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xe9000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi -new file mode 100644 -index 0000000..c8d145e ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi -@@ -0,0 +1,62 @@ -+/* -+ * QorIQ FMan v3 1g port #5 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman@500000 { -+ fman1_rx5: port@8d000 { -+ cell-index = <5>; -+ compatible = "fsl,fman-port-1g-rx"; -+ reg = <0x8d000 0x1000>; -+ }; -+ -+ fman1_tx5: port@ad000 { -+ cell-index = <5>; -+ compatible = "fsl,fman-port-1g-tx"; -+ reg = <0xad000 0x1000>; -+ }; -+ -+ ethernet@ea000 { -+ cell-index = <5>; -+ compatible = "fsl,fman-memac"; -+ reg = <0xea000 0x1000>; -+ fsl,port-handles = <&fman1_rx5 &fman1_tx5>; -+ ptimer-handle = <&ptp_timer1>; -+ }; -+ -+ mdio@eb000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-tbi"; -+ reg = <0xeb000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi -new file mode 100644 -index 0000000..4eeb060 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi -@@ -0,0 +1,150 @@ -+/* -+ * QorIQ FMan v3 device tree stub [ controller @ offset 0x500000 ] -+ * -+ * 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. -+ */ -+ -+fman1: fman@500000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <1>; -+ compatible = "fsl,fman", "simple-bus"; -+ ranges = <0 0x500000 0x100000>; -+ reg = <0x500000 0x100000>; -+ clock-frequency = <0>; -+ interrupts = < -+ 97 2 0 0 -+ 16 2 1 0>; -+ -+ 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>; -+ }; -+ -+ fman1_oh1: port@82000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x82000 0x1000>; -+ }; -+ -+ fman1_oh2: port@83000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x83000 0x1000>; -+ }; -+ -+ fman1_oh3: port@84000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x84000 0x1000>; -+ }; -+ -+ fman1_oh4: port@85000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x85000 0x1000>; -+ }; -+ -+ fman1_oh5: port@86000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x86000 0x1000>; -+ }; -+ -+ fman1_oh6: port@87000 { -+ cell-index = <5>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x87000 0x1000>; -+ }; -+ -+ 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>; -+ }; -+ -+ mdio@fc000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0xfc000 0x1000>; -+ }; -+ -+ mdio@fd000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0xfd000 0x1000>; -+ }; -+ -+ ptp_timer1: rtc@fe000 { -+ compatible = "fsl,fman-rtc"; -+ reg = <0xfe000 0x1000>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-gpio-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-gpio-0.dtsi -new file mode 100644 -index 0000000..cf714f5 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-gpio-0.dtsi -@@ -0,0 +1,41 @@ -+/* -+ * QorIQ GPIO device tree stub [ controller @ offset 0x130000 ] -+ * -+ * 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. -+ */ -+ -+gpio0: gpio@130000 { -+ compatible = "fsl,qoriq-gpio"; -+ reg = <0x130000 0x1000>; -+ interrupts = <55 2 0 0>; -+ #gpio-cells = <2>; -+ gpio-controller; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-i2c-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-i2c-0.dtsi -new file mode 100644 -index 0000000..5f9bf7d ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-i2c-0.dtsi -@@ -0,0 +1,53 @@ -+/* -+ * QorIQ I2C device tree stub [ controller @ offset 0x118000 ] -+ * -+ * 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. -+ */ -+ -+i2c@118000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x118000 0x100>; -+ interrupts = <38 2 0 0>; -+ dfsrr; -+}; -+ -+i2c@118100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x118100 0x100>; -+ interrupts = <38 2 0 0>; -+ dfsrr; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-i2c-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-i2c-1.dtsi -new file mode 100644 -index 0000000..7989bf5 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-i2c-1.dtsi -@@ -0,0 +1,53 @@ -+/* -+ * QorIQ I2C device tree stub [ controller @ offset 0x119000 ] -+ * -+ * 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. -+ */ -+ -+i2c@119000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <2>; -+ compatible = "fsl-i2c"; -+ reg = <0x119000 0x100>; -+ interrupts = <39 2 0 0>; -+ dfsrr; -+}; -+ -+i2c@119100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <3>; -+ compatible = "fsl-i2c"; -+ reg = <0x119100 0x100>; -+ interrupts = <39 2 0 0>; -+ dfsrr; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-mpic.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-mpic.dtsi -new file mode 100644 -index 0000000..08f4227 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-mpic.dtsi -@@ -0,0 +1,106 @@ -+/* -+ * QorIQ MPIC device tree stub [ controller @ offset 0x40000 ] -+ * -+ * 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. -+ */ -+ -+mpic: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <4>; -+ reg = <0x40000 0x40000>; -+ compatible = "fsl,mpic", "chrp,open-pic"; -+ device_type = "open-pic"; -+ clock-frequency = <0x0>; -+}; -+ -+timer@41100 { -+ compatible = "fsl,mpic-global-timer"; -+ reg = <0x41100 0x100 0x41300 4>; -+ interrupts = <0 0 3 0 -+ 1 0 3 0 -+ 2 0 3 0 -+ 3 0 3 0>; -+}; -+ -+msi0: msi@41600 { -+ compatible = "fsl,mpic-msi"; -+ reg = <0x41600 0x200 0x44140 4>; -+ msi-available-ranges = <0 0x100>; -+ interrupts = < -+ 0xe0 0 0 0 -+ 0xe1 0 0 0 -+ 0xe2 0 0 0 -+ 0xe3 0 0 0 -+ 0xe4 0 0 0 -+ 0xe5 0 0 0 -+ 0xe6 0 0 0 -+ 0xe7 0 0 0>; -+}; -+ -+msi1: msi@41800 { -+ compatible = "fsl,mpic-msi"; -+ reg = <0x41800 0x200 0x45140 4>; -+ msi-available-ranges = <0 0x100>; -+ interrupts = < -+ 0xe8 0 0 0 -+ 0xe9 0 0 0 -+ 0xea 0 0 0 -+ 0xeb 0 0 0 -+ 0xec 0 0 0 -+ 0xed 0 0 0 -+ 0xee 0 0 0 -+ 0xef 0 0 0>; -+}; -+ -+msi2: msi@41a00 { -+ compatible = "fsl,mpic-msi"; -+ reg = <0x41a00 0x200 0x46140 4>; -+ msi-available-ranges = <0 0x100>; -+ interrupts = < -+ 0xf0 0 0 0 -+ 0xf1 0 0 0 -+ 0xf2 0 0 0 -+ 0xf3 0 0 0 -+ 0xf4 0 0 0 -+ 0xf5 0 0 0 -+ 0xf6 0 0 0 -+ 0xf7 0 0 0>; -+}; -+ -+timer@42100 { -+ compatible = "fsl,mpic-global-timer"; -+ reg = <0x42100 0x100 0x42300 4>; -+ interrupts = <4 0 3 0 -+ 5 0 3 0 -+ 6 0 3 0 -+ 7 0 3 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-pme-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-pme-0.dtsi -new file mode 100644 -index 0000000..8789df1 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-pme-0.dtsi -@@ -0,0 +1,39 @@ -+/* -+ * QorIQ PME device tree stub [ controller @ offset 0x316000 ] -+ * -+ * 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. -+ */ -+ -+pme: pme@316000 { -+ compatible = "fsl,pme"; -+ reg = <0x316000 0x10000>; -+ interrupts = <16 2 1 5>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-qman-ceetm0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-qman-ceetm0.dtsi -new file mode 100644 -index 0000000..9d3cf3e ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-qman-ceetm0.dtsi -@@ -0,0 +1,43 @@ -+/* -+ * QorIQ QMan CEETM stub -+ * -+ * 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. -+ */ -+ -+&qportals { -+ qman-ceetm@0 { -+ compatible = "fsl,qman-ceetm"; -+ fsl,ceetm-lfqid-range = <0xf00000 0x1000>; -+ fsl,ceetm-sp-range = <0 12>; -+ fsl,ceetm-lni-range = <0 8>; -+ fsl,ceetm-channel-range = <0 32>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-qman-ceetm1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-qman-ceetm1.dtsi -new file mode 100644 -index 0000000..4028542 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-qman-ceetm1.dtsi -@@ -0,0 +1,43 @@ -+/* -+ * QorIQ QMan CEETM stub -+ * -+ * 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. -+ */ -+ -+&qportals { -+ qman-ceetm@1 { -+ compatible = "fsl,qman-ceetm"; -+ fsl,ceetm-lfqid-range = <0xf10000 0x1000>; -+ fsl,ceetm-sp-range = <0 12>; -+ fsl,ceetm-lni-range = <0 8>; -+ fsl,ceetm-channel-range = <0 32>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-qman1-portals.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-qman1-portals.dtsi -new file mode 100644 -index 0000000..8476b32 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-qman1-portals.dtsi -@@ -0,0 +1,116 @@ -+/* -+ * QorIQ QMan Portal device tree stub for 10 portals & 15 pool channels -+ * -+ * 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. -+ */ -+ -+#address-cells = <0x1>; -+#size-cells = <0x1>; -+compatible = "simple-bus"; -+qportal0: qman-portal@0 { -+ cell-index = <0x0>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x0 0x4000 0x100000 0x1000>; -+ interrupts = <104 0x2 0 0>; -+ fsl,qman-channel-id = <0x0>; -+}; -+ -+qportal1: qman-portal@4000 { -+ cell-index = <0x1>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x4000 0x4000 0x101000 0x1000>; -+ interrupts = <106 0x2 0 0>; -+ fsl,qman-channel-id = <0x1>; -+}; -+ -+qportal2: qman-portal@8000 { -+ cell-index = <0x2>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x8000 0x4000 0x102000 0x1000>; -+ interrupts = <108 0x2 0 0>; -+ fsl,qman-channel-id = <0x2>; -+}; -+ -+qportal3: qman-portal@c000 { -+ cell-index = <0x3>; -+ compatible = "fsl,qman-portal"; -+ reg = <0xc000 0x4000 0x103000 0x1000>; -+ interrupts = <110 0x2 0 0>; -+ fsl,qman-channel-id = <0x3>; -+}; -+ -+qportal4: qman-portal@10000 { -+ cell-index = <0x4>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x10000 0x4000 0x104000 0x1000>; -+ interrupts = <112 0x2 0 0>; -+ fsl,qman-channel-id = <0x4>; -+}; -+ -+qportal5: qman-portal@14000 { -+ cell-index = <0x5>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x14000 0x4000 0x105000 0x1000>; -+ interrupts = <114 0x2 0 0>; -+ fsl,qman-channel-id = <0x5>; -+}; -+ -+qportal6: qman-portal@18000 { -+ cell-index = <0x6>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x18000 0x4000 0x106000 0x1000>; -+ interrupts = <116 0x2 0 0>; -+ fsl,qman-channel-id = <0x6>; -+}; -+ -+qportal7: qman-portal@1c000 { -+ cell-index = <0x7>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x1c000 0x4000 0x107000 0x1000>; -+ interrupts = <118 0x2 0 0>; -+ fsl,qman-channel-id = <0x7>; -+}; -+ -+qportal8: qman-portal@20000 { -+ cell-index = <0x8>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x20000 0x4000 0x108000 0x1000>; -+ interrupts = <120 0x2 0 0>; -+ fsl,qman-channel-id = <0x8>; -+}; -+ -+qportal9: qman-portal@24000 { -+ cell-index = <0x9>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x24000 0x4000 0x109000 0x1000>; -+ interrupts = <122 0x2 0 0>; -+ fsl,qman-channel-id = <0x9>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-qman1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-qman1.dtsi -new file mode 100644 -index 0000000..8edd2c0 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-qman1.dtsi -@@ -0,0 +1,39 @@ -+/* -+ * QorIQ QMan device tree stub [ controller @ offset 0x318000 ] -+ * -+ * 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. -+ */ -+ -+qman: qman@318000 { -+ compatible = "fsl,qman"; -+ reg = <0x318000 0x2000>; -+ interrupts = <16 2 1 3>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-qman2-portals.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-qman2-portals.dtsi -new file mode 100644 -index 0000000..6c6010d ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-qman2-portals.dtsi -@@ -0,0 +1,436 @@ -+/* -+ * QorIQ QMan Portal device tree stub for QMan 3.0 with maximum 50 portals. -+ * -+ * 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. -+ */ -+ -+#address-cells = <0x1>; -+#size-cells = <0x1>; -+compatible = "simple-bus"; -+qportal0: qman-portal@0 { -+ cell-index = <0x0>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x0 0x4000 0x1000000 0x1000>; -+ interrupts = <104 0x2 0 0>; -+ fsl,qman-channel-id = <0x0>; -+}; -+ -+qportal1: qman-portal@4000 { -+ cell-index = <0x1>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x4000 0x4000 0x1001000 0x1000>; -+ interrupts = <106 0x2 0 0>; -+ fsl,qman-channel-id = <0x1>; -+}; -+ -+qportal2: qman-portal@8000 { -+ cell-index = <0x2>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x8000 0x4000 0x1002000 0x1000>; -+ interrupts = <108 0x2 0 0>; -+ fsl,qman-channel-id = <0x2>; -+}; -+ -+qportal3: qman-portal@c000 { -+ cell-index = <0x3>; -+ compatible = "fsl,qman-portal"; -+ reg = <0xc000 0x4000 0x1003000 0x1000>; -+ interrupts = <110 0x2 0 0>; -+ fsl,qman-channel-id = <0x3>; -+}; -+ -+qportal4: qman-portal@10000 { -+ cell-index = <0x4>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x10000 0x4000 0x1004000 0x1000>; -+ interrupts = <112 0x2 0 0>; -+ fsl,qman-channel-id = <0x4>; -+}; -+ -+qportal5: qman-portal@14000 { -+ cell-index = <0x5>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x14000 0x4000 0x1005000 0x1000>; -+ interrupts = <114 0x2 0 0>; -+ fsl,qman-channel-id = <0x5>; -+}; -+ -+qportal6: qman-portal@18000 { -+ cell-index = <0x6>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x18000 0x4000 0x1006000 0x1000>; -+ interrupts = <116 0x2 0 0>; -+ fsl,qman-channel-id = <0x6>; -+}; -+ -+qportal7: qman-portal@1c000 { -+ cell-index = <0x7>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x1c000 0x4000 0x1007000 0x1000>; -+ interrupts = <118 0x2 0 0>; -+ fsl,qman-channel-id = <0x7>; -+}; -+ -+qportal8: qman-portal@20000 { -+ cell-index = <0x8>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x20000 0x4000 0x1008000 0x1000>; -+ interrupts = <120 0x2 0 0>; -+ fsl,qman-channel-id = <0x8>; -+}; -+ -+qportal9: qman-portal@24000 { -+ cell-index = <0x9>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x24000 0x4000 0x1009000 0x1000>; -+ interrupts = <122 0x2 0 0>; -+ fsl,qman-channel-id = <0x9>; -+}; -+ -+qportal10: qman-portal@28000 { -+ cell-index = <0xa>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x28000 0x4000 0x100a000 0x1000>; -+ interrupts = <124 0x2 0 0>; -+ fsl,qman-channel-id = <0xa>; -+}; -+ -+qportal11: qman-portal@2c000 { -+ cell-index = <0xb>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x2c000 0x4000 0x100b000 0x1000>; -+ interrupts = <126 0x2 0 0>; -+ fsl,qman-channel-id = <0xb>; -+}; -+ -+qportal12: qman-portal@30000 { -+ cell-index = <0xc>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x30000 0x4000 0x100c000 0x1000>; -+ interrupts = <128 0x2 0 0>; -+ fsl,qman-channel-id = <0xc>; -+}; -+ -+qportal13: qman-portal@34000 { -+ cell-index = <0xd>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x34000 0x4000 0x100d000 0x1000>; -+ interrupts = <130 0x2 0 0>; -+ fsl,qman-channel-id = <0xd>; -+}; -+ -+qportal14: qman-portal@38000 { -+ cell-index = <0xe>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x38000 0x4000 0x100e000 0x1000>; -+ interrupts = <132 0x2 0 0>; -+ fsl,qman-channel-id = <0xe>; -+}; -+ -+qportal15: qman-portal@3c000 { -+ cell-index = <0xf>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x3c000 0x4000 0x100f000 0x1000>; -+ interrupts = <134 0x2 0 0>; -+ fsl,qman-channel-id = <0xf>; -+}; -+ -+qportal16: qman-portal@40000 { -+ cell-index = <0x10>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x40000 0x4000 0x1010000 0x1000>; -+ interrupts = <136 0x2 0 0>; -+ fsl,qman-channel-id = <0x10>; -+}; -+ -+qportal17: qman-portal@44000 { -+ cell-index = <0x11>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x44000 0x4000 0x1011000 0x1000>; -+ interrupts = <138 0x2 0 0>; -+ fsl,qman-channel-id = <0x11>; -+}; -+ -+qportal18: qman-portal@48000 { -+ cell-index = <0x12>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x48000 0x4000 0x1012000 0x1000>; -+ interrupts = <140 0x2 0 0>; -+ fsl,qman-channel-id = <0x12>; -+}; -+ -+qportal19: qman-portal@4c000 { -+ cell-index = <0x13>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x4c000 0x4000 0x1013000 0x1000>; -+ interrupts = <142 0x2 0 0>; -+ fsl,qman-channel-id = <0x13>; -+}; -+ -+qportal20: qman-portal@50000 { -+ cell-index = <0x14>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x50000 0x4000 0x1014000 0x1000>; -+ interrupts = <144 0x2 0 0>; -+ fsl,qman-channel-id = <0x14>; -+}; -+ -+qportal21: qman-portal@54000 { -+ cell-index = <0x15>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x54000 0x4000 0x1015000 0x1000>; -+ interrupts = <146 0x2 0 0>; -+ fsl,qman-channel-id = <0x15>; -+}; -+ -+qportal22: qman-portal@58000 { -+ cell-index = <0x16>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x58000 0x4000 0x1016000 0x1000>; -+ interrupts = <148 0x2 0 0>; -+ fsl,qman-channel-id = <0x16>; -+}; -+ -+qportal23: qman-portal@5c000 { -+ cell-index = <0x17>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x5c000 0x4000 0x1017000 0x1000>; -+ interrupts = <150 0x2 0 0>; -+ fsl,qman-channel-id = <0x17>; -+}; -+ -+qportal24: qman-portal@60000 { -+ cell-index = <0x18>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x60000 0x4000 0x1018000 0x1000>; -+ interrupts = <152 0x2 0 0>; -+ fsl,qman-channel-id = <0x18>; -+}; -+ -+qportal25: qman-portal@64000 { -+ cell-index = <0x19>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x64000 0x4000 0x1019000 0x1000>; -+ interrupts = <154 0x2 0 0>; -+ fsl,qman-channel-id = <0x19>; -+}; -+ -+qportal26: qman-portal@68000 { -+ cell-index = <0x1a>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x68000 0x4000 0x101a000 0x1000>; -+ interrupts = <156 0x2 0 0>; -+ fsl,qman-channel-id = <0x1a>; -+}; -+ -+qportal27: qman-portal@6c000 { -+ cell-index = <0x1b>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x6c000 0x4000 0x101b000 0x1000>; -+ interrupts = <158 0x2 0 0>; -+ fsl,qman-channel-id = <0x1b>; -+}; -+ -+qportal28: qman-portal@70000 { -+ cell-index = <0x1c>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x70000 0x4000 0x101c000 0x1000>; -+ interrupts = <160 0x2 0 0>; -+ fsl,qman-channel-id = <0x1c>; -+}; -+ -+qportal29: qman-portal@74000 { -+ cell-index = <0x1d>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x74000 0x4000 0x101d000 0x1000>; -+ interrupts = <162 0x2 0 0>; -+ fsl,qman-channel-id = <0x1d>; -+}; -+ -+qportal30: qman-portal@78000 { -+ cell-index = <0x1e>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x78000 0x4000 0x101e000 0x1000>; -+ interrupts = <164 0x2 0 0>; -+ fsl,qman-channel-id = <0x1e>; -+}; -+ -+qportal31: qman-portal@7c000 { -+ cell-index = <0x1f>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x7c000 0x4000 0x101f000 0x1000>; -+ interrupts = <166 0x2 0 0>; -+ fsl,qman-channel-id = <0x1f>; -+}; -+ -+qportal32: qman-portal@80000 { -+ cell-index = <0x20>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x80000 0x4000 0x1020000 0x1000>; -+ interrupts = <168 0x2 0 0>; -+ fsl,qman-channel-id = <0x20>; -+}; -+ -+qportal33: qman-portal@84000 { -+ cell-index = <0x21>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x84000 0x4000 0x1021000 0x1000>; -+ interrupts = <170 0x2 0 0>; -+ fsl,qman-channel-id = <0x21>; -+}; -+ -+qportal34: qman-portal@88000 { -+ cell-index = <0x22>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x88000 0x4000 0x1022000 0x1000>; -+ interrupts = <172 0x2 0 0>; -+ fsl,qman-channel-id = <0x22>; -+}; -+ -+qportal35: qman-portal@8c000 { -+ cell-index = <0x23>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x8c000 0x4000 0x1023000 0x1000>; -+ interrupts = <174 0x2 0 0>; -+ fsl,qman-channel-id = <0x23>; -+}; -+ -+qportal36: qman-portal@90000 { -+ cell-index = <0x24>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x90000 0x4000 0x1024000 0x1000>; -+ interrupts = <384 0x2 0 0>; -+ fsl,qman-channel-id = <0x24>; -+}; -+ -+qportal37: qman-portal@94000 { -+ cell-index = <0x25>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x94000 0x4000 0x1025000 0x1000>; -+ interrupts = <386 0x2 0 0>; -+ fsl,qman-channel-id = <0x25>; -+}; -+ -+qportal38: qman-portal@98000 { -+ cell-index = <0x26>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x98000 0x4000 0x1026000 0x1000>; -+ interrupts = <388 0x2 0 0>; -+ fsl,qman-channel-id = <0x26>; -+}; -+ -+qportal39: qman-portal@9c000 { -+ cell-index = <0x27>; -+ compatible = "fsl,qman-portal"; -+ reg = <0x9c000 0x4000 0x1027000 0x1000>; -+ interrupts = <390 0x2 0 0>; -+ fsl,qman-channel-id = <0x27>; -+}; -+ -+qportal40: qman-portal@a0000 { -+ cell-index = <0x28>; -+ compatible = "fsl,qman-portal"; -+ reg = <0xa0000 0x4000 0x1028000 0x1000>; -+ interrupts = <392 0x2 0 0>; -+ fsl,qman-channel-id = <0x28>; -+}; -+ -+qportal41: qman-portal@a4000 { -+ cell-index = <0x29>; -+ compatible = "fsl,qman-portal"; -+ reg = <0xa4000 0x4000 0x1029000 0x1000>; -+ interrupts = <394 0x2 0 0>; -+ fsl,qman-channel-id = <0x29>; -+}; -+ -+qportal42: qman-portal@a8000 { -+ cell-index = <0x2a>; -+ compatible = "fsl,qman-portal"; -+ reg = <0xa8000 0x4000 0x102a000 0x1000>; -+ interrupts = <396 0x2 0 0>; -+ fsl,qman-channel-id = <0x2a>; -+}; -+ -+qportal43: qman-portal@ac000 { -+ cell-index = <0x2b>; -+ compatible = "fsl,qman-portal"; -+ reg = <0xac000 0x4000 0x102b000 0x1000>; -+ interrupts = <398 0x2 0 0>; -+ fsl,qman-channel-id = <0x2b>; -+}; -+ -+qportal44: qman-portal@b0000 { -+ cell-index = <0x2c>; -+ compatible = "fsl,qman-portal"; -+ reg = <0xb0000 0x4000 0x102c000 0x1000>; -+ interrupts = <400 0x2 0 0>; -+ fsl,qman-channel-id = <0x2c>; -+}; -+ -+qportal45: qman-portal@b4000 { -+ cell-index = <0x2d>; -+ compatible = "fsl,qman-portal"; -+ reg = <0xb4000 0x4000 0x102d000 0x1000>; -+ interrupts = <402 0x2 0 0>; -+ fsl,qman-channel-id = <0x2d>; -+}; -+ -+qportal46: qman-portal@b8000 { -+ cell-index = <0x2e>; -+ compatible = "fsl,qman-portal"; -+ reg = <0xb8000 0x4000 0x102e000 0x1000>; -+ interrupts = <404 0x2 0 0>; -+ fsl,qman-channel-id = <0x2e>; -+}; -+ -+qportal47: qman-portal@bc000 { -+ cell-index = <0x2f>; -+ compatible = "fsl,qman-portal"; -+ reg = <0xbc000 0x4000 0x102f000 0x1000>; -+ interrupts = <406 0x2 0 0>; -+ fsl,qman-channel-id = <0x2f>; -+}; -+ -+qportal48: qman-portal@c0000 { -+ cell-index = <0x30>; -+ compatible = "fsl,qman-portal"; -+ reg = <0xc0000 0x4000 0x1030000 0x1000>; -+ interrupts = <408 0x2 0 0>; -+ fsl,qman-channel-id = <0x30>; -+}; -+ -+qportal49: qman-portal@c4000 { -+ cell-index = <0x31>; -+ compatible = "fsl,qman-portal"; -+ reg = <0xc4000 0x4000 0x1031000 0x1000>; -+ interrupts = <410 0x2 0 0>; -+ fsl,qman-channel-id = <0x31>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi -new file mode 100644 -index 0000000..d2f1315 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi -@@ -0,0 +1,85 @@ -+/* -+ * QorIQ RAID 1.0 device tree stub [ controller @ offset 0x320000 ] -+ * -+ * 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. -+ */ -+ -+raideng: raideng@320000 { -+ compatible = "fsl,raideng-v1.0"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x320000 0x10000>; -+ ranges = <0 0x320000 0x10000>; -+ -+ raideng_jq0@1000 { -+ compatible = "fsl,raideng-v1.0-job-queue"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x1000 0x1000>; -+ ranges = <0x0 0x1000 0x1000>; -+ -+ raideng_jr0: jr@0 { -+ compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-hp-ring"; -+ reg = <0x0 0x400>; -+ interrupts = <139 2 0 0>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ raideng_jr1: jr@400 { -+ compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-lp-ring"; -+ reg = <0x400 0x400>; -+ interrupts = <140 2 0 0>; -+ interrupt-parent = <&mpic>; -+ }; -+ }; -+ -+ raideng_jq1@2000 { -+ compatible = "fsl,raideng-v1.0-job-queue"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x2000 0x1000>; -+ ranges = <0x0 0x2000 0x1000>; -+ -+ raideng_jr2: jr@0 { -+ compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-hp-ring"; -+ reg = <0x0 0x400>; -+ interrupts = <141 2 0 0>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ raideng_jr3: jr@400 { -+ compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-lp-ring"; -+ reg = <0x400 0x400>; -+ interrupts = <142 2 0 0>; -+ interrupt-parent = <&mpic>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-rman-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-rman-0.dtsi -new file mode 100644 -index 0000000..3fcfdde ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-rman-0.dtsi -@@ -0,0 +1,63 @@ -+/* -+ * QorIQ RMan device tree stub [ controller @ offset 0x1e0000 ] -+ * -+ * 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. -+ */ -+ -+rman: rman@1e0000 { -+ compatible = "fsl,rman"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x0 0x1e0000 0x20000>; -+ reg = <0x1e0000 0x20000>; -+ interrupts = <16 2 1 11>; /* err_irq */ -+ -+ inbound-block@0 { -+ compatible = "fsl,rman-inbound-block"; -+ reg = <0x0 0x800>; -+ }; -+ global-cfg@b00 { -+ compatible = "fsl,rman-global-cfg"; -+ reg = <0xb00 0x500>; -+ }; -+ inbound-block@1000 { -+ compatible = "fsl,rman-inbound-block"; -+ reg = <0x1000 0x800>; -+ }; -+ inbound-block@2000 { -+ compatible = "fsl,rman-inbound-block"; -+ reg = <0x2000 0x800>; -+ }; -+ inbound-block@3000 { -+ compatible = "fsl,rman-inbound-block"; -+ reg = <0x3000 0x800>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-rmu-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-rmu-0.dtsi -new file mode 100644 -index 0000000..ca7fec7 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-rmu-0.dtsi -@@ -0,0 +1,68 @@ -+/* -+ * QorIQ RIO Message Unit device tree stub [ controller @ offset 0xd3000 ] -+ * -+ * 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. -+ */ -+ -+rmu: rmu@d3000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,srio-rmu"; -+ reg = <0xd3000 0x500>; -+ ranges = <0x0 0xd3000 0x500>; -+ -+ message-unit@0 { -+ compatible = "fsl,srio-msg-unit"; -+ reg = <0x0 0x100>; -+ interrupts = < -+ 60 2 0 0 /* msg1_tx_irq */ -+ 61 2 0 0>;/* msg1_rx_irq */ -+ }; -+ message-unit@100 { -+ compatible = "fsl,srio-msg-unit"; -+ reg = <0x100 0x100>; -+ interrupts = < -+ 62 2 0 0 /* msg2_tx_irq */ -+ 63 2 0 0>;/* msg2_rx_irq */ -+ }; -+ doorbell-unit@400 { -+ compatible = "fsl,srio-dbell-unit"; -+ reg = <0x400 0x80>; -+ interrupts = < -+ 56 2 0 0 /* bell_outb_irq */ -+ 57 2 0 0>;/* bell_inb_irq */ -+ }; -+ port-write-unit@4e0 { -+ compatible = "fsl,srio-port-write-unit"; -+ reg = <0x4e0 0x20>; -+ interrupts = <16 2 1 11>; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sata2-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sata2-0.dtsi -new file mode 100644 -index 0000000..b642047 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-sata2-0.dtsi -@@ -0,0 +1,39 @@ -+/* -+ * QorIQ SATAv2 device tree stub [ controller @ offset 0x220000 ] -+ * -+ * 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. -+ */ -+ -+sata@220000 { -+ compatible = "fsl,pq-sata-v2"; -+ reg = <0x220000 0x1000>; -+ interrupts = <68 0x2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sata2-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sata2-1.dtsi -new file mode 100644 -index 0000000..c573702 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-sata2-1.dtsi -@@ -0,0 +1,39 @@ -+/* -+ * QorIQ SATAv2 device tree stub [ controller @ offset 0x221000 ] -+ * -+ * 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. -+ */ -+ -+sata@221000 { -+ compatible = "fsl,pq-sata-v2"; -+ reg = <0x221000 0x1000>; -+ interrupts = <69 0x2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sec4.0-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sec4.0-0.dtsi -new file mode 100644 -index 0000000..0cbbac3 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-sec4.0-0.dtsi -@@ -0,0 +1,100 @@ -+/* -+ * QorIQ Sec/Crypto 4.0 device tree stub [ controller @ offset 0x300000 ] -+ * -+ * 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. -+ */ -+ -+crypto: crypto@300000 { -+ compatible = "fsl,sec-v4.0"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x300000 0x10000>; -+ ranges = <0 0x300000 0x10000>; -+ interrupts = <92 2 0 0>; -+ -+ sec_jr0: jr@1000 { -+ compatible = "fsl,sec-v4.0-job-ring"; -+ reg = <0x1000 0x1000>; -+ interrupts = <88 2 0 0>; -+ }; -+ -+ sec_jr1: jr@2000 { -+ compatible = "fsl,sec-v4.0-job-ring"; -+ reg = <0x2000 0x1000>; -+ interrupts = <89 2 0 0>; -+ }; -+ -+ sec_jr2: jr@3000 { -+ compatible = "fsl,sec-v4.0-job-ring"; -+ reg = <0x3000 0x1000>; -+ interrupts = <90 2 0 0>; -+ }; -+ -+ sec_jr3: jr@4000 { -+ compatible = "fsl,sec-v4.0-job-ring"; -+ reg = <0x4000 0x1000>; -+ interrupts = <91 2 0 0>; -+ }; -+ -+ rtic@6000 { -+ compatible = "fsl,sec-v4.0-rtic"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x6000 0x100>; -+ ranges = <0x0 0x6100 0xe00>; -+ -+ rtic_a: rtic-a@0 { -+ compatible = "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x00 0x20 0x100 0x80>; -+ }; -+ -+ rtic_b: rtic-b@20 { -+ compatible = "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x20 0x20 0x200 0x80>; -+ }; -+ -+ rtic_c: rtic-c@40 { -+ compatible = "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x40 0x20 0x300 0x80>; -+ }; -+ -+ rtic_d: rtic-d@60 { -+ compatible = "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x60 0x20 0x500 0x80>; -+ }; -+ }; -+}; -+ -+sec_mon: sec_mon@314000 { -+ compatible = "fsl,sec-v4.0-mon"; -+ reg = <0x314000 0x1000>; -+ interrupts = <93 2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sec4.1-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sec4.1-0.dtsi -new file mode 100644 -index 0000000..3308986 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-sec4.1-0.dtsi -@@ -0,0 +1,109 @@ -+/* -+ * QorIQ Sec/Crypto 4.1 device tree stub [ controller @ offset 0x300000 ] -+ * -+ * 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. -+ */ -+ -+crypto: crypto@300000 { -+ compatible = "fsl,sec-v4.1", "fsl,sec-v4.0"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x300000 0x10000>; -+ ranges = <0 0x300000 0x10000>; -+ interrupts = <92 2 0 0>; -+ -+ sec_jr0: jr@1000 { -+ compatible = "fsl,sec-v4.1-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x1000 0x1000>; -+ interrupts = <88 2 0 0>; -+ }; -+ -+ sec_jr1: jr@2000 { -+ compatible = "fsl,sec-v4.1-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x2000 0x1000>; -+ interrupts = <89 2 0 0>; -+ }; -+ -+ sec_jr2: jr@3000 { -+ compatible = "fsl,sec-v4.1-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x3000 0x1000>; -+ interrupts = <90 2 0 0>; -+ }; -+ -+ sec_jr3: jr@4000 { -+ compatible = "fsl,sec-v4.1-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x4000 0x1000>; -+ interrupts = <91 2 0 0>; -+ }; -+ -+ rtic@6000 { -+ compatible = "fsl,sec-v4.1-rtic", -+ "fsl,sec-v4.0-rtic"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x6000 0x100>; -+ ranges = <0x0 0x6100 0xe00>; -+ -+ rtic_a: rtic-a@0 { -+ compatible = "fsl,sec-v4.1-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x00 0x20 0x100 0x80>; -+ }; -+ -+ rtic_b: rtic-b@20 { -+ compatible = "fsl,sec-v4.1-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x20 0x20 0x200 0x80>; -+ }; -+ -+ rtic_c: rtic-c@40 { -+ compatible = "fsl,sec-v4.1-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x40 0x20 0x300 0x80>; -+ }; -+ -+ rtic_d: rtic-d@60 { -+ compatible = "fsl,sec-v4.1-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x60 0x20 0x500 0x80>; -+ }; -+ }; -+}; -+ -+sec_mon: sec_mon@314000 { -+ compatible = "fsl,sec-v4.1-mon", "fsl,sec-v4.0-mon"; -+ reg = <0x314000 0x1000>; -+ interrupts = <93 2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sec4.2-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sec4.2-0.dtsi -new file mode 100644 -index 0000000..7990e0d ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-sec4.2-0.dtsi -@@ -0,0 +1,109 @@ -+/* -+ * QorIQ Sec/Crypto 4.2 device tree stub [ controller @ offset 0x300000 ] -+ * -+ * 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. -+ */ -+ -+crypto: crypto@300000 { -+ compatible = "fsl,sec-v4.2", "fsl,sec-v4.0"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x300000 0x10000>; -+ ranges = <0 0x300000 0x10000>; -+ interrupts = <92 2 0 0>; -+ -+ sec_jr0: jr@1000 { -+ compatible = "fsl,sec-v4.2-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x1000 0x1000>; -+ interrupts = <88 2 0 0>; -+ }; -+ -+ sec_jr1: jr@2000 { -+ compatible = "fsl,sec-v4.2-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x2000 0x1000>; -+ interrupts = <89 2 0 0>; -+ }; -+ -+ sec_jr2: jr@3000 { -+ compatible = "fsl,sec-v4.2-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x3000 0x1000>; -+ interrupts = <90 2 0 0>; -+ }; -+ -+ sec_jr3: jr@4000 { -+ compatible = "fsl,sec-v4.2-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x4000 0x1000>; -+ interrupts = <91 2 0 0>; -+ }; -+ -+ rtic@6000 { -+ compatible = "fsl,sec-v4.2-rtic", -+ "fsl,sec-v4.0-rtic"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x6000 0x100>; -+ ranges = <0x0 0x6100 0xe00>; -+ -+ rtic_a: rtic-a@0 { -+ compatible = "fsl,sec-v4.2-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x00 0x20 0x100 0x80>; -+ }; -+ -+ rtic_b: rtic-b@20 { -+ compatible = "fsl,sec-v4.2-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x20 0x20 0x200 0x80>; -+ }; -+ -+ rtic_c: rtic-c@40 { -+ compatible = "fsl,sec-v4.2-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x40 0x20 0x300 0x80>; -+ }; -+ -+ rtic_d: rtic-d@60 { -+ compatible = "fsl,sec-v4.2-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x60 0x20 0x500 0x80>; -+ }; -+ }; -+}; -+ -+sec_mon: sec_mon@314000 { -+ compatible = "fsl,sec-v4.2-mon", "fsl,sec-v4.0-mon"; -+ reg = <0x314000 0x1000>; -+ interrupts = <93 2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sec5.0-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sec5.0-0.dtsi -new file mode 100644 -index 0000000..ffd458f ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-sec5.0-0.dtsi -@@ -0,0 +1,109 @@ -+/* -+ * QorIQ Sec/Crypto 5.0 device tree stub [ controller @ offset 0x300000 ] -+ * -+ * 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. -+ */ -+ -+crypto: crypto@300000 { -+ compatible = "fsl,sec-v5.0", "fsl,sec-v4.0"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x300000 0x10000>; -+ ranges = <0 0x300000 0x10000>; -+ interrupts = <92 2 0 0>; -+ -+ sec_jr0: jr@1000 { -+ compatible = "fsl,sec-v5.0-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x1000 0x1000>; -+ interrupts = <88 2 0 0>; -+ }; -+ -+ sec_jr1: jr@2000 { -+ compatible = "fsl,sec-v5.0-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x2000 0x1000>; -+ interrupts = <89 2 0 0>; -+ }; -+ -+ sec_jr2: jr@3000 { -+ compatible = "fsl,sec-v5.0-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x3000 0x1000>; -+ interrupts = <90 2 0 0>; -+ }; -+ -+ sec_jr3: jr@4000 { -+ compatible = "fsl,sec-v5.0-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x4000 0x1000>; -+ interrupts = <91 2 0 0>; -+ }; -+ -+ rtic@6000 { -+ compatible = "fsl,sec-v5.0-rtic", -+ "fsl,sec-v4.0-rtic"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x6000 0x100>; -+ ranges = <0x0 0x6100 0xe00>; -+ -+ rtic_a: rtic-a@0 { -+ compatible = "fsl,sec-v5.0-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x00 0x20 0x100 0x80>; -+ }; -+ -+ rtic_b: rtic-b@20 { -+ compatible = "fsl,sec-v5.0-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x20 0x20 0x200 0x80>; -+ }; -+ -+ rtic_c: rtic-c@40 { -+ compatible = "fsl,sec-v5.0-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x40 0x20 0x300 0x80>; -+ }; -+ -+ rtic_d: rtic-d@60 { -+ compatible = "fsl,sec-v5.0-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x60 0x20 0x500 0x80>; -+ }; -+ }; -+}; -+ -+sec_mon: sec_mon@314000 { -+ compatible = "fsl,sec-v5.0-mon", "fsl,sec-v4.0-mon"; -+ reg = <0x314000 0x1000>; -+ interrupts = <93 2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi -new file mode 100644 -index 0000000..7b2ab8a ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi -@@ -0,0 +1,118 @@ -+/* -+ * QorIQ Sec/Crypto 5.2 device tree stub [ controller @ offset 0x300000 ] -+ * -+ * 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. -+ */ -+ -+crypto: crypto@300000 { -+ compatible = "fsl,sec-v5.2", "fsl,sec-v5.0", "fsl,sec-v4.0"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x300000 0x10000>; -+ ranges = <0 0x300000 0x10000>; -+ interrupts = <92 2 0 0>; -+ -+ sec_jr0: jr@1000 { -+ compatible = "fsl,sec-v5.2-job-ring", -+ "fsl,sec-v5.0-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x1000 0x1000>; -+ interrupts = <88 2 0 0>; -+ }; -+ -+ sec_jr1: jr@2000 { -+ compatible = "fsl,sec-v5.2-job-ring", -+ "fsl,sec-v5.0-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x2000 0x1000>; -+ interrupts = <89 2 0 0>; -+ }; -+ -+ sec_jr2: jr@3000 { -+ compatible = "fsl,sec-v5.2-job-ring", -+ "fsl,sec-v5.0-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x3000 0x1000>; -+ interrupts = <90 2 0 0>; -+ }; -+ -+ sec_jr3: jr@4000 { -+ compatible = "fsl,sec-v5.2-job-ring", -+ "fsl,sec-v5.0-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x4000 0x1000>; -+ interrupts = <91 2 0 0>; -+ }; -+ -+ rtic@6000 { -+ compatible = "fsl,sec-v5.2-rtic", -+ "fsl,sec-v5.0-rtic", -+ "fsl,sec-v4.0-rtic"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x6000 0x100>; -+ ranges = <0x0 0x6100 0xe00>; -+ -+ rtic_a: rtic-a@0 { -+ compatible = "fsl,sec-v5.2-rtic-memory", -+ "fsl,sec-v5.0-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x00 0x20 0x100 0x80>; -+ }; -+ -+ rtic_b: rtic-b@20 { -+ compatible = "fsl,sec-v5.2-rtic-memory", -+ "fsl,sec-v5.0-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x20 0x20 0x200 0x80>; -+ }; -+ -+ rtic_c: rtic-c@40 { -+ compatible = "fsl,sec-v5.2-rtic-memory", -+ "fsl,sec-v5.0-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x40 0x20 0x300 0x80>; -+ }; -+ -+ rtic_d: rtic-d@60 { -+ compatible = "fsl,sec-v5.2-rtic-memory", -+ "fsl,sec-v5.0-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x60 0x20 0x500 0x80>; -+ }; -+ }; -+}; -+ -+sec_mon: sec_mon@314000 { -+ compatible = "fsl,sec-v5.2-mon", "fsl,sec-v5.0-mon", "fsl,sec-v4.0-mon"; -+ reg = <0x314000 0x1000>; -+ interrupts = <93 2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sec5.3-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sec5.3-0.dtsi -new file mode 100644 -index 0000000..0339825 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-sec5.3-0.dtsi -@@ -0,0 +1,118 @@ -+/* -+ * QorIQ Sec/Crypto 5.3 device tree stub [ controller @ offset 0x300000 ] -+ * -+ * 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. -+ */ -+ -+crypto: crypto@300000 { -+ compatible = "fsl,sec-v5.3", "fsl,sec-v5.0", "fsl,sec-v4.0"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x300000 0x10000>; -+ ranges = <0 0x300000 0x10000>; -+ interrupts = <92 2 0 0>; -+ -+ sec_jr0: jr@1000 { -+ compatible = "fsl,sec-v5.3-job-ring", -+ "fsl,sec-v5.0-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x1000 0x1000>; -+ interrupts = <88 2 0 0>; -+ }; -+ -+ sec_jr1: jr@2000 { -+ compatible = "fsl,sec-v5.3-job-ring", -+ "fsl,sec-v5.0-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x2000 0x1000>; -+ interrupts = <89 2 0 0>; -+ }; -+ -+ sec_jr2: jr@3000 { -+ compatible = "fsl,sec-v5.3-job-ring", -+ "fsl,sec-v5.0-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x3000 0x1000>; -+ interrupts = <90 2 0 0>; -+ }; -+ -+ sec_jr3: jr@4000 { -+ compatible = "fsl,sec-v5.3-job-ring", -+ "fsl,sec-v5.0-job-ring", -+ "fsl,sec-v4.0-job-ring"; -+ reg = <0x4000 0x1000>; -+ interrupts = <91 2 0 0>; -+ }; -+ -+ rtic@6000 { -+ compatible = "fsl,sec-v5.3-rtic", -+ "fsl,sec-v5.0-rtic", -+ "fsl,sec-v4.0-rtic"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x6000 0x100>; -+ ranges = <0x0 0x6100 0xe00>; -+ -+ rtic_a: rtic-a@0 { -+ compatible = "fsl,sec-v5.3-rtic-memory", -+ "fsl,sec-v5.0-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x00 0x20 0x100 0x80>; -+ }; -+ -+ rtic_b: rtic-b@20 { -+ compatible = "fsl,sec-v5.3-rtic-memory", -+ "fsl,sec-v5.0-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x20 0x20 0x200 0x80>; -+ }; -+ -+ rtic_c: rtic-c@40 { -+ compatible = "fsl,sec-v5.3-rtic-memory", -+ "fsl,sec-v5.0-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x40 0x20 0x300 0x80>; -+ }; -+ -+ rtic_d: rtic-d@60 { -+ compatible = "fsl,sec-v5.3-rtic-memory", -+ "fsl,sec-v5.0-rtic-memory", -+ "fsl,sec-v4.0-rtic-memory"; -+ reg = <0x60 0x20 0x500 0x80>; -+ }; -+ }; -+}; -+ -+sec_mon: sec_mon@314000 { -+ compatible = "fsl,sec-v5.3-mon", "fsl,sec-v5.0-mon", "fsl,sec-v4.0-mon"; -+ reg = <0x314000 0x1000>; -+ interrupts = <93 2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-usb2-dr-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-usb2-dr-0.dtsi -new file mode 100644 -index 0000000..4dd6f84 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-usb2-dr-0.dtsi -@@ -0,0 +1,41 @@ -+/* -+ * QorIQ USB DR device tree stub [ controller @ offset 0x211000 ] -+ * -+ * 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. -+ */ -+ -+usb@211000 { -+ compatible = "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr"; -+ reg = <0x211000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = <45 0x2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-usb2-mph-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-usb2-mph-0.dtsi -new file mode 100644 -index 0000000..f053835 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/qoriq-usb2-mph-0.dtsi -@@ -0,0 +1,41 @@ -+/* -+ * QorIQ USB Host device tree stub [ controller @ offset 0x210000 ] -+ * -+ * 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. -+ */ -+ -+usb@210000 { -+ compatible = "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph"; -+ reg = <0x210000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = <44 0x2 0 0>; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi -new file mode 100644 -index 0000000..b27fb24 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi -@@ -0,0 +1,599 @@ -+/* -+ * T4240 Silicon/SoC Device Tree Source (post include) -+ * -+ * 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. -+ */ -+ -+&ifc { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,ifc", "simple-bus"; -+ interrupts = <25 2 0 0>; -+}; -+ -+&lportals { -+/include/ "interlaken-lac-portals.dtsi" -+}; -+ -+&bportals { -+/include/ "qoriq-bman2-portals.dtsi" -+}; -+ -+&qportals { -+/include/ "qoriq-qman2-portals.dtsi" -+}; -+ -+/* controller at 0x240000 */ -+&pci0 { -+ compatible = "fsl,t4240-pcie", "fsl,qoriq-pcie-v3.0"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <20 2 0 0>; -+ pcie@0 { -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <20 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 40 1 0 0 -+ 0000 0 0 2 &mpic 1 1 0 0 -+ 0000 0 0 3 &mpic 2 1 0 0 -+ 0000 0 0 4 &mpic 3 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x250000 */ -+&pci1 { -+ compatible = "fsl,t4240-pcie", "fsl,qoriq-pcie-v3.0"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <21 2 0 0>; -+ pcie@0 { -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <21 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 41 1 0 0 -+ 0000 0 0 2 &mpic 5 1 0 0 -+ 0000 0 0 3 &mpic 6 1 0 0 -+ 0000 0 0 4 &mpic 7 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x260000 */ -+&pci2 { -+ compatible = "fsl,t4240-pcie", "fsl,qoriq-pcie-v3.0"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <22 2 0 0>; -+ pcie@0 { -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <22 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 42 1 0 0 -+ 0000 0 0 2 &mpic 9 1 0 0 -+ 0000 0 0 3 &mpic 10 1 0 0 -+ 0000 0 0 4 &mpic 11 1 0 0 -+ >; -+ }; -+}; -+ -+/* controller at 0x270000 */ -+&pci3 { -+ compatible = "fsl,t4240-pcie", "fsl,qoriq-pcie-v3.0"; -+ device_type = "pci"; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ bus-range = <0x0 0xff>; -+ clock-frequency = <33333333>; -+ interrupts = <23 2 0 0>; -+ pcie@0 { -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ interrupts = <23 2 0 0>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &mpic 43 1 0 0 -+ 0000 0 0 2 &mpic 0 1 0 0 -+ 0000 0 0 3 &mpic 4 1 0 0 -+ 0000 0 0 4 &mpic 8 1 0 0 -+ >; -+ }; -+}; -+ -+&rio { -+ compatible = "fsl,srio"; -+ interrupts = <16 2 1 11>; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ port1 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <1>; -+ }; -+ -+ port2 { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ cell-index = <2>; -+ }; -+}; -+ -+&dcsr { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,dcsr", "simple-bus"; -+ -+ dcsr-epu@0 { -+ compatible = "fsl,t4240-dcsr-epu", "fsl,dcsr-epu"; -+ interrupts = <52 2 0 0 -+ 84 2 0 0 -+ 85 2 0 0 -+ 94 2 0 0 -+ 95 2 0 0>; -+ reg = <0x0 0x1000>; -+ }; -+ dcsr-npc { -+ compatible = "fsl,t4240-dcsr-cnpc", "fsl,dcsr-cnpc"; -+ reg = <0x1000 0x1000 0x1002000 0x10000>; -+ }; -+ dcsr-nxc@2000 { -+ compatible = "fsl,dcsr-nxc"; -+ reg = <0x2000 0x1000>; -+ }; -+ dcsr-corenet { -+ compatible = "fsl,dcsr-corenet"; -+ reg = <0x8000 0x1000 0x1A000 0x1000>; -+ }; -+ dcsr-dpaa@9000 { -+ compatible = "fsl,t4240-dcsr-dpaa", "fsl,dcsr-dpaa"; -+ reg = <0x9000 0x1000>; -+ }; -+ dcsr-ocn@11000 { -+ compatible = "fsl,t4240-dcsr-ocn", "fsl,dcsr-ocn"; -+ reg = <0x11000 0x1000>; -+ }; -+ dcsr-ddr@12000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr1>; -+ reg = <0x12000 0x1000>; -+ }; -+ dcsr-ddr@13000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr2>; -+ reg = <0x13000 0x1000>; -+ }; -+ dcsr-ddr@14000 { -+ compatible = "fsl,dcsr-ddr"; -+ dev-handle = <&ddr3>; -+ reg = <0x14000 0x1000>; -+ }; -+ dcsr-nal@18000 { -+ compatible = "fsl,t4240-dcsr-nal", "fsl,dcsr-nal"; -+ reg = <0x18000 0x1000>; -+ }; -+ dcsr-rcpm@22000 { -+ compatible = "fsl,t4240-dcsr-rcpm", "fsl,dcsr-rcpm"; -+ reg = <0x22000 0x1000>; -+ }; -+ dcsr-snpc@30000 { -+ compatible = "fsl,t4240-dcsr-snpc", "fsl,dcsr-snpc"; -+ reg = <0x30000 0x1000 0x1022000 0x10000>; -+ }; -+ dcsr-snpc@31000 { -+ compatible = "fsl,t4240-dcsr-snpc", "fsl,dcsr-snpc"; -+ reg = <0x31000 0x1000 0x1042000 0x10000>; -+ }; -+ dcsr-snpc@32000 { -+ compatible = "fsl,t4240-dcsr-snpc", "fsl,dcsr-snpc"; -+ reg = <0x32000 0x1000 0x1062000 0x10000>; -+ }; -+ dcsr-cpu-sb-proxy@100000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu0>; -+ reg = <0x100000 0x1000 0x101000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@108000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu1>; -+ reg = <0x108000 0x1000 0x109000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@110000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu2>; -+ reg = <0x110000 0x1000 0x111000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@118000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu3>; -+ reg = <0x118000 0x1000 0x119000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@120000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu4>; -+ reg = <0x120000 0x1000 0x121000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@128000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu5>; -+ reg = <0x128000 0x1000 0x129000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@130000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu6>; -+ reg = <0x130000 0x1000 0x131000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@138000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu7>; -+ reg = <0x138000 0x1000 0x139000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@140000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu8>; -+ reg = <0x140000 0x1000 0x141000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@148000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu9>; -+ reg = <0x148000 0x1000 0x149000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@150000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu10>; -+ reg = <0x150000 0x1000 0x151000 0x1000>; -+ }; -+ dcsr-cpu-sb-proxy@158000 { -+ compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; -+ cpu-handle = <&cpu11>; -+ reg = <0x158000 0x1000 0x159000 0x1000>; -+ }; -+}; -+ -+&soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "simple-bus"; -+ -+ soc-sram-error { -+ compatible = "fsl,soc-sram-error"; -+ interrupts = <16 2 1 29>; -+ }; -+ -+ corenet-law@0 { -+ compatible = "fsl,corenet-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <32>; -+ }; -+ -+ ddr1: memory-controller@8000 { -+ compatible = "fsl,qoriq-memory-controller-v4.7", -+ "fsl,qoriq-memory-controller"; -+ reg = <0x8000 0x1000>; -+ interrupts = <16 2 1 23>; -+ }; -+ -+ ddr2: memory-controller@9000 { -+ compatible = "fsl,qoriq-memory-controller-v4.7", -+ "fsl,qoriq-memory-controller"; -+ reg = <0x9000 0x1000>; -+ interrupts = <16 2 1 22>; -+ }; -+ -+ ddr3: memory-controller@a000 { -+ compatible = "fsl,qoriq-memory-controller-v4.7", -+ "fsl,qoriq-memory-controller"; -+ reg = <0xa000 0x1000>; -+ interrupts = <16 2 1 21>; -+ }; -+ -+ cpc: l3-cache-controller@10000 { -+ compatible = "fsl,p5020-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache"; -+ reg = <0x10000 0x1000 -+ 0x11000 0x1000>; -+ interrupts = <16 2 1 27 -+ 16 2 1 26>; -+ }; -+ -+ corenet-cf@18000 { -+ compatible = "fsl,corenet-cf"; -+ reg = <0x18000 0x1000>; -+ interrupts = <16 2 1 31>; -+ fsl,ccf-num-csdids = <32>; -+ fsl,ccf-num-snoopids = <32>; -+ }; -+ -+ iommu@20000 { -+ compatible = "fsl,pamu-v1.0", "fsl,pamu"; -+ reg = <0x20000 0x6000>; -+ interrupts = < -+ 24 2 0 0 -+ 16 2 1 30>; -+ }; -+ -+/include/ "qoriq-mpic.dtsi" -+ -+ guts: global-utilities@e0000 { -+ compatible = "fsl,t4240-device-config"; -+ reg = <0xe0000 0xe00>; -+ fsl,has-rstcr; -+ fsl,liodn-bits = <12>; -+ }; -+ -+ clockgen: global-utilities@e1000 { -+ compatible = "fsl,t4240-clockgen", "fsl,qoriq-clockgen-2"; -+ reg = <0xe1000 0x1000>; -+ }; -+ -+/include/ "interlaken-lac.dtsi" -+ -+ rcpm: global-utilities@e2000 { -+ compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2"; -+ reg = <0xe2000 0x1000>; -+ }; -+ -+/include/ "qoriq-dma-0.dtsi" -+/include/ "qoriq-dma-1.dtsi" -+ -+/include/ "qoriq-espi-0.dtsi" -+ spi@110000 { -+ fsl,espi-num-chipselects = <4>; -+ }; -+ -+/include/ "qoriq-esdhc-0.dtsi" -+ sdhc@114000 { -+ compatible = "fsl,t4240-esdhc", "fsl,esdhc"; -+ sdhci,auto-cmd12; -+ }; -+/include/ "qoriq-i2c-0.dtsi" -+/include/ "qoriq-i2c-1.dtsi" -+/include/ "qoriq-duart-0.dtsi" -+/include/ "qoriq-duart-1.dtsi" -+/include/ "qoriq-sec5.0-0.dtsi" -+ -+ -+ /* -+ * Temporarily define cluster 1/2/3's L2 cache nodes in order to pass -+ * next-level-cache info to uboot to do L3 cache fixup. This can be -+ * removed once u-boot can create cpu node with cache info. -+ */ -+ L2_1: l2-cache-controller@c20000 { -+ compatible = "fsl,t4240-l2-cache-controller"; -+ reg = <0xc20000 0x40000>; -+ next-level-cache = <&cpc>; -+ }; -+ L2_2: l2-cache-controller@c60000 { -+ compatible = "fsl,t4240-l2-cache-controller"; -+ reg = <0xc60000 0x40000>; -+ next-level-cache = <&cpc>; -+ }; -+ L2_3: l2-cache-controller@ca0000 { -+ compatible = "fsl,t4240-l2-cache-controller"; -+ reg = <0xca0000 0x40000>; -+ next-level-cache = <&cpc>; -+ }; -+ -+/include/ "qoriq-qman1.dtsi" -+/include/ "qoriq-bman1.dtsi" -+ -+/include/ "qoriq-rman-0.dtsi" -+ rman: rman@1e0000 { -+ fsl,qman-channels-id = <0x880 0x881>; -+ }; -+ -+/include/ "qoriq-usb2-mph-0.dtsi" -+ usb0: usb@210000 { -+ compatible = "fsl-usb2-mph-v2.4", "fsl-usb2-mph"; -+ phy_type = "utmi"; -+ port0; -+ }; -+/include/ "qoriq-usb2-dr-0.dtsi" -+ usb1: usb@211000 { -+ compatible = "fsl-usb2-dr-v2.4", "fsl-usb2-dr"; -+ dr_mode = "host"; -+ phy_type = "utmi"; -+ }; -+/include/ "qoriq-sata2-0.dtsi" -+ sata0: sata@220000 { -+ compatible = "fsl,t4240-rev1.0-sata", "fsl,pq-sata-v2"; -+ }; -+/include/ "qoriq-sata2-1.dtsi" -+ sata1: sata@221000 { -+ compatible = "fsl,t4240-rev1.0-sata", "fsl,pq-sata-v2"; -+ }; -+/include/ "qoriq-dce-0.dtsi" -+/include/ "qoriq-pme-0.dtsi" -+ -+/include/ "qoriq-fman3-0.dtsi" -+/include/ "qoriq-fman3-0-1g-0.dtsi" -+/include/ "qoriq-fman3-0-1g-1.dtsi" -+/include/ "qoriq-fman3-0-1g-2.dtsi" -+/include/ "qoriq-fman3-0-1g-3.dtsi" -+/include/ "qoriq-fman3-0-1g-4.dtsi" -+/include/ "qoriq-fman3-0-1g-5.dtsi" -+/include/ "qoriq-fman3-0-10g-0.dtsi" -+/include/ "qoriq-fman3-0-10g-1.dtsi" -+ fman0: fman@400000 { -+ /* tx - 1g - 0 */ -+ port@a8000 { -+ fsl,qman-channel-id = <0x802>; -+ }; -+ /* tx - 1g - 1 */ -+ port@a9000 { -+ fsl,qman-channel-id = <0x803>; -+ }; -+ /* tx - 1g - 2 */ -+ port@aa000 { -+ fsl,qman-channel-id = <0x804>; -+ }; -+ /* tx - 1g - 3 */ -+ port@ab000 { -+ fsl,qman-channel-id = <0x805>; -+ }; -+ /* tx - 1g - 4 */ -+ port@ac000 { -+ fsl,qman-channel-id = <0x806>; -+ }; -+ /* tx - 1g - 5 */ -+ port@ad000 { -+ fsl,qman-channel-id = <0x807>; -+ }; -+ /* tx - 10g - 0 */ -+ port@b0000 { -+ fsl,qman-channel-id = <0x800>; -+ }; -+ /* tx - 10g - 1 */ -+ port@b1000 { -+ fsl,qman-channel-id = <0x801>; -+ }; -+ /* offline - 1 */ -+ port@82000 { -+ fsl,qman-channel-id = <0x809>; -+ }; -+ /* offline - 2 */ -+ port@83000 { -+ fsl,qman-channel-id = <0x80a>; -+ }; -+ /* offline - 3 */ -+ port@84000 { -+ fsl,qman-channel-id = <0x80b>; -+ }; -+ /* offline - 4 */ -+ port@85000 { -+ fsl,qman-channel-id = <0x80c>; -+ }; -+ /* offline - 5 */ -+ port@86000 { -+ fsl,qman-channel-id = <0x80d>; -+ }; -+ /* offline - 6 */ -+ port@87000 { -+ fsl,qman-channel-id = <0x80e>; -+ }; -+ }; -+ -+/include/ "qoriq-fman3-1.dtsi" -+/include/ "qoriq-fman3-1-1g-0.dtsi" -+/include/ "qoriq-fman3-1-1g-1.dtsi" -+/include/ "qoriq-fman3-1-1g-2.dtsi" -+/include/ "qoriq-fman3-1-1g-3.dtsi" -+/include/ "qoriq-fman3-1-1g-4.dtsi" -+/include/ "qoriq-fman3-1-1g-5.dtsi" -+/include/ "qoriq-fman3-1-10g-0.dtsi" -+/include/ "qoriq-fman3-1-10g-1.dtsi" -+ fman1: fman@500000 { -+ /* tx - 1g - 0 */ -+ port@a8000 { -+ fsl,qman-channel-id = <0x822>; -+ }; -+ /* tx - 1g - 1 */ -+ port@a9000 { -+ fsl,qman-channel-id = <0x823>; -+ }; -+ /* tx - 1g - 2 */ -+ port@aa000 { -+ fsl,qman-channel-id = <0x824>; -+ }; -+ /* tx - 1g - 3 */ -+ port@ab000 { -+ fsl,qman-channel-id = <0x825>; -+ }; -+ /* tx - 1g - 4 */ -+ port@ac000 { -+ fsl,qman-channel-id = <0x826>; -+ }; -+ /* tx - 1g - 5 */ -+ port@ad000 { -+ fsl,qman-channel-id = <0x827>; -+ }; -+ /* tx - 10g - 0 */ -+ port@b0000 { -+ fsl,qman-channel-id = <0x820>; -+ }; -+ /* tx - 10g - 1 */ -+ port@b1000 { -+ fsl,qman-channel-id = <0x821>; -+ }; -+ /* offline - 1 */ -+ port@82000 { -+ fsl,qman-channel-id = <0x829>; -+ }; -+ /* offline - 2 */ -+ port@83000 { -+ fsl,qman-channel-id = <0x82a>; -+ }; -+ /* offline - 3 */ -+ port@84000 { -+ fsl,qman-channel-id = <0x82b>; -+ }; -+ /* offline - 4 */ -+ port@85000 { -+ fsl,qman-channel-id = <0x82c>; -+ }; -+ /* offline - 5 */ -+ port@86000 { -+ fsl,qman-channel-id = <0x82d>; -+ }; -+ /* offline - 6 */ -+ port@87000 { -+ fsl,qman-channel-id = <0x82e>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi -new file mode 100644 -index 0000000..0997ef1 ---- /dev/null -+++ b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi -@@ -0,0 +1,156 @@ -+/* -+ * T4240 Silicon/SoC Device Tree Source (pre include) -+ * -+ * 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. -+ */ -+ -+/dts-v1/; -+/ { -+ compatible = "fsl,T4240"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ ccsr = &soc; -+ dcsr = &dcsr; -+ -+ serial0 = &serial0; -+ serial1 = &serial1; -+ serial2 = &serial2; -+ serial3 = &serial3; -+ lac = &lac; -+ bman = &bman; -+ qman = &qman; -+ pme = &pme; -+ dce = &dce; -+ crypto = &crypto; -+ fman0 = &fman0; -+ fman1 = &fman1; -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ ethernet3 = &enet3; -+ ethernet4 = &enet4; -+ ethernet5 = &enet5; -+ ethernet6 = &enet6; -+ ethernet7 = &enet7; -+ ethernet8 = &enet8; -+ ethernet9 = &enet9; -+ ethernet10 = &enet10; -+ ethernet11 = &enet11; -+ ethernet12 = &enet12; -+ ethernet13 = &enet13; -+ ethernet14 = &enet14; -+ ethernet15 = &enet15; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ pci3 = &pci3; -+ rman = &rman; -+ dma0 = &dma0; -+ dma1 = &dma1; -+ sdhc = &sdhc; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* -+ * Temporarily add next-level-cache info in each cpu node so -+ * that uboot can do L2 cache fixup. This can be removed once -+ * u-boot can create cpu node with cache info. -+ */ -+ cpu0: PowerPC,e6500@0 { -+ device_type = "cpu"; -+ reg = <0 1>; -+ next-level-cache = <&L2_1>; -+ }; -+ cpu1: PowerPC,e6500@1 { -+ device_type = "cpu"; -+ reg = <2 3>; -+ next-level-cache = <&L2_1>; -+ }; -+ cpu2: PowerPC,e6500@2 { -+ device_type = "cpu"; -+ reg = <4 5>; -+ next-level-cache = <&L2_1>; -+ }; -+ cpu3: PowerPC,e6500@3 { -+ device_type = "cpu"; -+ reg = <6 7>; -+ next-level-cache = <&L2_1>; -+ }; -+ -+ cpu4: PowerPC,e6500@4 { -+ device_type = "cpu"; -+ reg = <8 9>; -+ next-level-cache = <&L2_2>; -+ }; -+ cpu5: PowerPC,e6500@5 { -+ device_type = "cpu"; -+ reg = <10 11>; -+ next-level-cache = <&L2_2>; -+ }; -+ cpu6: PowerPC,e6500@6 { -+ device_type = "cpu"; -+ reg = <12 13>; -+ next-level-cache = <&L2_2>; -+ }; -+ cpu7: PowerPC,e6500@7 { -+ device_type = "cpu"; -+ reg = <14 15>; -+ next-level-cache = <&L2_2>; -+ }; -+ -+ cpu8: PowerPC,e6500@8 { -+ device_type = "cpu"; -+ reg = <16 17>; -+ next-level-cache = <&L2_3>; -+ }; -+ cpu9: PowerPC,e6500@9 { -+ device_type = "cpu"; -+ reg = <18 19>; -+ next-level-cache = <&L2_3>; -+ }; -+ cpu10: PowerPC,e6500@10 { -+ device_type = "cpu"; -+ reg = <20 21>; -+ next-level-cache = <&L2_3>; -+ }; -+ cpu11: PowerPC,e6500@11 { -+ device_type = "cpu"; -+ reg = <22 23>; -+ next-level-cache = <&L2_3>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/p2041rdb-usdpaa.dts b/arch/powerpc/boot/dts/p2041rdb-usdpaa.dts -new file mode 100644 -index 0000000..2557614 ---- /dev/null -+++ b/arch/powerpc/boot/dts/p2041rdb-usdpaa.dts -@@ -0,0 +1,110 @@ -+/* -+ * P2041RDB Device Tree Source -+ * -+ * 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. -+ */ -+ -+/include/ "p2041rdb.dts" -+ -+/ { -+ /* NB: "bpool-ethernet-seeds" is not set to avoid buffer seeding, -+ * because apps seed these pools with buffers allocated at -+ * run-time. -+ * HOWEVER, the kernel driver requires the buffer-size so -+ * "fsl,bpool-ethernet-cfg" is set. It also mis-interprets -+ * things if the base-address is zero (hence the 0xdeadbeef -+ * values). -+ */ -+ bp7: buffer-pool@7 { -+ compatible = "fsl,p2041-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,p2041-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,p2041-bpool", "fsl,bpool"; -+ fsl,bpid = <9>; -+ fsl,bpool-ethernet-cfg = <0 0 0 1728 0 0xfeedabba>; -+ fsl,bpool-thresholds = <0x100 0x300 0x0 0x0>; -+ }; -+ -+ fsl,dpaa { -+ ethernet@0 { -+ compatible = "fsl,p2041-dpa-ethernet-init", "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,p2041-dpa-ethernet-init", "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,p2041-dpa-ethernet-init", "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,p2041-dpa-ethernet-init", "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,p2041-dpa-ethernet-init", "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,p2041-dpa-ethernet-init", "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>; -+ }; -+ dpa-fman0-oh@1 { -+ compatible = "fsl,dpa-oh"; -+ /* Define frame queues for the OH port*/ -+ /* */ -+ fsl,qman-frame-queues-oh = <0x68 1 0x69 1>; -+ fsl,fman-oh-port = <&fman0_oh1>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/p2041rdb.dts b/arch/powerpc/boot/dts/p2041rdb.dts -index 79b6895..c712717 100644 ---- a/arch/powerpc/boot/dts/p2041rdb.dts -+++ b/arch/powerpc/boot/dts/p2041rdb.dts -@@ -1,7 +1,7 @@ - /* - * P2041RDB Device Tree Source - * -- * Copyright 2011 Freescale Semiconductor Inc. -+ * 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: -@@ -32,7 +32,7 @@ - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - --/include/ "p2041si.dtsi" -+/include/ "fsl/p2041si-pre.dtsi" - - / { - model = "fsl,P2041RDB"; -@@ -41,6 +41,25 @@ - #size-cells = <2>; - interrupt-parent = <&mpic>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ ethernet3 = &enet3; -+ ethernet4 = &enet4; -+ ethernet5 = &enet5; -+ phy_rgmii_0 = &phy_rgmii_0; -+ phy_rgmii_1 = &phy_rgmii_1; -+ phy_sgmii_2 = &phy_sgmii_2; -+ phy_sgmii_3 = &phy_sgmii_3; -+ phy_sgmii_4 = &phy_sgmii_4; -+ phy_sgmii_1c = &phy_sgmii_1c; -+ phy_sgmii_1d = &phy_sgmii_1d; -+ phy_sgmii_1e = &phy_sgmii_1e; -+ phy_sgmii_1f = &phy_sgmii_1f; -+ phy_xgmii_2 = &phy_xgmii_2; -+ }; -+ - memory { - device_type = "memory"; - }; -@@ -49,7 +68,17 @@ - ranges = <0x00000000 0xf 0x00000000 0x01008000>; - }; - -+ bportals: bman-portals@ff4000000 { -+ ranges = <0x0 0xf 0xf4000000 0x200000>; -+ }; -+ -+ qportals: qman-portals@ff4200000 { -+ ranges = <0x0 0xf 0xf4200000 0x200000>; -+ }; -+ - soc: soc@ffe000000 { -+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>; -+ reg = <0xf 0xfe000000 0 0x00001000>; - spi@110000 { - flash@0 { - #address-cells = <1>; -@@ -92,6 +121,10 @@ - compatible = "pericom,pt7c4338"; - reg = <0x68>; - }; -+ adt7461@4c { -+ compatible = "adi,adt7461"; -+ reg = <0x4c>; -+ }; - }; - - i2c@118100 { -@@ -104,11 +137,134 @@ - usb1: usb@211000 { - dr_mode = "host"; - }; -+ -+ fman0: fman@400000 { -+ enet0: ethernet@e0000 { -+ tbi-handle = <&tbi0>; -+ phy-handle = <&phy_sgmii_2>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ mdio0: mdio@e1120 { -+ tbi0: tbi-phy@8 { -+ reg = <0x8>; -+ device_type = "tbi-phy"; -+ }; -+ -+ phy_rgmii_0: ethernet-phy@0 { -+ reg = <0x0>; -+ }; -+ phy_rgmii_1: ethernet-phy@1 { -+ reg = <0x1>; -+ }; -+ phy_sgmii_2: ethernet-phy@2 { -+ reg = <0x2>; -+ }; -+ phy_sgmii_3: ethernet-phy@3 { -+ reg = <0x3>; -+ }; -+ phy_sgmii_4: ethernet-phy@4 { -+ reg = <0x4>; -+ }; -+ phy_sgmii_1c: ethernet-phy@1c { -+ reg = <0x1c>; -+ }; -+ phy_sgmii_1d: ethernet-phy@1d { -+ reg = <0x1d>; -+ }; -+ phy_sgmii_1e: ethernet-phy@1e { -+ reg = <0x1e>; -+ }; -+ phy_sgmii_1f: ethernet-phy@1f { -+ reg = <0x1f>; -+ }; -+ }; -+ -+ enet1: ethernet@e2000 { -+ tbi-handle = <&tbi1>; -+ phy-handle = <&phy_sgmii_3>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ mdio@e3120 { -+ tbi1: tbi-phy@8 { -+ reg = <8>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ enet2: ethernet@e4000 { -+ tbi-handle = <&tbi2>; -+ phy-handle = <&phy_sgmii_4>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ mdio@e5120 { -+ tbi2: tbi-phy@8 { -+ reg = <8>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ enet3: ethernet@e6000 { -+ tbi-handle = <&tbi3>; -+ phy-handle = <&phy_rgmii_1>; -+ phy-connection-type = "rgmii"; -+ }; -+ -+ mdio@e7120 { -+ tbi3: tbi-phy@8 { -+ reg = <8>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ enet4: ethernet@e8000 { -+ tbi-handle = <&tbi4>; -+ phy-handle = <&phy_rgmii_0>; -+ phy-connection-type = "rgmii"; -+ }; -+ -+ mdio@e9120 { -+ tbi4: tbi-phy@8 { -+ reg = <8>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ enet5: ethernet@f0000 { -+ /* -+ * phy-handle will be updated by U-Boot to -+ * reflect the actual slot the XAUI card is in. -+ */ -+ phy-handle = <&phy_xgmii_2>; -+ phy-connection-type = "xgmii"; -+ }; -+ -+ mdio@f1000 { -+ /* XAUI card in slot 2 */ -+ phy_xgmii_2: ethernet-phy@0 { -+ reg = <0x0>; -+ }; -+ }; -+ }; -+ }; -+ -+ rio: rapidio@ffe0c0000 { -+ reg = <0xf 0xfe0c0000 0 0x11000>; -+ -+ port1 { -+ ranges = <0 0 0xc 0x20000000 0 0x10000000>; -+ }; -+ port2 { -+ ranges = <0 0 0xc 0x30000000 0 0x10000000>; -+ }; - }; - -- localbus@ffe124000 { -+ lbc: localbus@ffe124000 { - reg = <0xf 0xfe124000 0 0x1000>; -- ranges = <0 0 0xf 0xe8000000 0x08000000>; -+ ranges = <0 0 0xf 0xe8000000 0x08000000 -+ 1 0 0xf 0xffa00000 0x00040000>; - - flash@0,0 { - compatible = "cfi-flash"; -@@ -116,6 +272,44 @@ - bank-width = <2>; - device-width = <2>; - }; -+ -+ nand@1,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,elbc-fcm-nand"; -+ reg = <0x1 0x0 0x40000>; -+ -+ partition@0 { -+ label = "NAND U-Boot Image"; -+ reg = <0x0 0x02000000>; -+ read-only; -+ }; -+ -+ partition@2000000 { -+ label = "NAND Root File System"; -+ reg = <0x02000000 0x10000000>; -+ }; -+ -+ partition@12000000 { -+ label = "NAND Compressed RFS Image"; -+ reg = <0x12000000 0x08000000>; -+ }; -+ -+ partition@1a000000 { -+ label = "NAND Linux Kernel Image"; -+ reg = <0x1a000000 0x04000000>; -+ }; -+ -+ partition@1e000000 { -+ label = "NAND DTB Image"; -+ reg = <0x1e000000 0x01000000>; -+ }; -+ -+ partition@1f000000 { -+ label = "NAND Writable User area"; -+ reg = <0x1f000000 0x01000000>; -+ }; -+ }; - }; - - pci0: pcie@ffe200000 { -@@ -162,4 +356,37 @@ - 0 0x00010000>; - }; - }; -+ -+ fsl,dpaa { -+ compatible = "fsl,p2041-dpaa", "fsl,dpaa"; -+ -+ ethernet@0 { -+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet0>; -+ }; -+ ethernet@1 { -+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet1>; -+ }; -+ ethernet@2 { -+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet2>; -+ }; -+ ethernet@3 { -+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet3>; -+ }; -+ ethernet@4 { -+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet4>; -+ }; -+ ethernet@5 { -+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet5>; -+ }; -+ }; - }; -+ -+/include/ "fsl/p2041si-post.dtsi" -+ -+/include/ "fsl/qoriq-dpaa-res1.dtsi" -diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig -index f087de6..fc5ece3 100644 ---- a/arch/powerpc/configs/corenet32_smp_defconfig -+++ b/arch/powerpc/configs/corenet32_smp_defconfig -@@ -26,17 +26,21 @@ CONFIG_P3041_DS=y - CONFIG_P3060_QDS=y - CONFIG_P4080_DS=y - CONFIG_P5020_DS=y -+CONFIG_P5040_DS=y - CONFIG_HIGHMEM=y - CONFIG_NO_HZ=y - CONFIG_HIGH_RES_TIMERS=y - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set - CONFIG_BINFMT_MISC=m - CONFIG_KEXEC=y -+CONFIG_IRQ_ALL_CPUS=y - CONFIG_FORCE_MAX_ZONEORDER=13 - CONFIG_FSL_LBC=y -+CONFIG_FSL_PAMU=y - CONFIG_PCI=y - CONFIG_PCIEPORTBUS=y - # CONFIG_PCIEASPM is not set -+CONFIG_PCI_MSI=y - CONFIG_NET=y - CONFIG_PACKET=y - CONFIG_UNIX=y -@@ -67,6 +71,7 @@ CONFIG_INET_IPCOMP=y - CONFIG_IPV6=y - CONFIG_IP_SCTP=m - CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_DEVTMPFS=y - CONFIG_MTD=y - CONFIG_MTD_CMDLINE_PARTS=y - CONFIG_MTD_CHAR=y -@@ -78,7 +83,7 @@ CONFIG_MTD_M25P80=y - CONFIG_PROC_DEVICETREE=y - CONFIG_BLK_DEV_LOOP=y - CONFIG_BLK_DEV_RAM=y --CONFIG_BLK_DEV_RAM_SIZE=131072 -+CONFIG_BLK_DEV_RAM_SIZE=262144 - CONFIG_MISC_DEVICES=y - CONFIG_BLK_DEV_SD=y - CONFIG_CHR_DEV_ST=y -@@ -93,13 +98,18 @@ CONFIG_SATA_FSL=y - CONFIG_SATA_SIL24=y - CONFIG_SATA_SIL=y - CONFIG_PATA_SIL680=y -+CONFIG_MD=y -+CONFIG_BLK_DEV_MD=y -+# CONFIG_MD_AUTODETECT is not set -+CONFIG_MD_RAID456=y -+CONFIG_MULTICORE_RAID456=y - CONFIG_NETDEVICES=y --CONFIG_VITESSE_PHY=y - CONFIG_FIXED_PHY=y - CONFIG_NET_ETHERNET=y - CONFIG_E1000=y - CONFIG_E1000E=y - CONFIG_FSL_PQ_MDIO=y -+CONFIG_DPA=y - # CONFIG_INPUT_MOUSEDEV is not set - # CONFIG_INPUT_KEYBOARD is not set - # CONFIG_INPUT_MOUSE is not set -@@ -133,16 +143,25 @@ CONFIG_USB_OHCI_HCD_PPC_OF_LE=y - CONFIG_USB_STORAGE=y - CONFIG_MMC=y - CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_OF=y -+CONFIG_MMC_SDHCI_OF_ESDHC=y - CONFIG_EDAC=y - CONFIG_EDAC_MM_EDAC=y - CONFIG_EDAC_MPC85XX=y - CONFIG_RTC_CLASS=y -+CONFIG_RTC_DRV_DS1307=y - CONFIG_RTC_DRV_DS3232=y - CONFIG_RTC_DRV_CMOS=y -+CONFIG_DMADEVICES=y -+CONFIG_FSL_RAID=y -+CONFIG_ASYNC_TX_DMA=y - CONFIG_UIO=y -+CONFIG_UIO_FSL_SRIO=y -+CONFIG_UIO_FSL_DMA=y - CONFIG_STAGING=y - CONFIG_VIRT_DRIVERS=y - CONFIG_FSL_HV_MANAGER=y -+CONFIG_FMAN_RESOURCE_ALLOCATION_ALGORITHM=y - CONFIG_EXT2_FS=y - CONFIG_EXT3_FS=y - # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -@@ -167,6 +186,7 @@ CONFIG_MAC_PARTITION=y - CONFIG_NLS_ISO8859_1=y - CONFIG_NLS_UTF8=m - CONFIG_MAGIC_SYSRQ=y -+CONFIG_DEBUG_KERNEL=y - CONFIG_DEBUG_SHIRQ=y - CONFIG_DETECT_HUNG_TASK=y - CONFIG_DEBUG_INFO=y -diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h -index bebd124..a9a85ef 100644 ---- a/arch/powerpc/include/asm/fsl_guts.h -+++ b/arch/powerpc/include/asm/fsl_guts.h -@@ -85,7 +85,9 @@ struct ccsr_guts_86xx { - u8 res0c4[0x224 - 0xc4]; - __be32 iodelay1; /* 0x.0224 - IO delay control register 1 */ - __be32 iodelay2; /* 0x.0228 - IO delay control register 2 */ -- u8 res22c[0x800 - 0x22c]; -+ u8 res22c[0x604 - 0x22c]; -+ __be32 pamubypenr; /* 0x.0604 - PAMU bypass enable register */ -+ u8 res608[0x800 - 0x608]; - __be32 clkdvdr; /* 0x.0800 - Clock Divide Register */ - u8 res804[0x900 - 0x804]; - __be32 ircr; /* 0x.0900 - Infrared Control Register */ -diff --git a/arch/powerpc/include/asm/fsl_hcalls.h b/arch/powerpc/include/asm/fsl_hcalls.h -index 922d9b5..7e0b5b7 100644 ---- a/arch/powerpc/include/asm/fsl_hcalls.h -+++ b/arch/powerpc/include/asm/fsl_hcalls.h -@@ -45,7 +45,7 @@ - #include - #include - --#define FH_API_VERSION 1 -+#define FH_API_VERSION 3 - - #define FH_ERR_GET_INFO 1 - #define FH_PARTITION_GET_DTPROP 2 -@@ -65,6 +65,8 @@ - #define FH_EXIT_NAP 16 - #define FH_CLAIM_DEVICE 17 - #define FH_PARTITION_STOP_DMA 18 -+#define FH_DMA_ATTR_SET 19 -+#define FH_DMA_ATTR_GET 20 - - /* vendor ID: Freescale Semiconductor */ - #define FH_HCALL_TOKEN(num) _EV_HCALL_TOKEN(EV_FSL_VENDOR_ID, num) -@@ -652,4 +654,80 @@ static inline unsigned int fh_partition_stop_dma(unsigned int handle) - - return r3; - } -+ -+#define FSL_PAMU_ATTR_STASH 2 -+ -+struct fh_dma_attr_stash { -+ uint32_t vcpu; /* vcpu number */ -+ uint32_t cache; /* cache to stash to: 1=L1, 2=L2, 3=L3 */ -+}; -+ -+/** -+ * fh_dma_attr_set - configure a DMA window -+ * @handle: value from fsl,hv-device-handle property -+ * @attr_name: the FSL_PAMU_ATTR_xxx attribute to change -+ * @attr_address: the physical address of the attribute structure -+ * -+ * FSL_PAMU_ATTR_STASH: Configure the target CPU and cache level for stashing -+ * -+ * Returns 0 for success, or an error code. -+ */ -+static inline unsigned int fh_dma_attr_set(unsigned int handle, -+ unsigned int attr_name, phys_addr_t attr_address) -+{ -+ register uintptr_t r11 __asm__("r11"); -+ register uintptr_t r3 __asm__("r3"); -+ register uintptr_t r4 __asm__("r4"); -+ register uintptr_t r5 __asm__("r5"); -+ register uintptr_t r6 __asm__("r6"); -+ -+ r11 = FH_HCALL_TOKEN(FH_DMA_ATTR_SET); -+ r3 = handle; -+ r4 = attr_name; -+ r5 = (uint64_t)attr_address >> 32; -+ r6 = (uint32_t)attr_address; -+ -+ __asm__ __volatile__ ("sc 1" -+ : "+r" (r11), -+ "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6) -+ : : EV_HCALL_CLOBBERS4 -+ ); -+ -+ return r3; -+} -+ -+/** -+ * fh_dma_attr_get - query the DMA window configuration -+ * @handle: value from fsl,hv-device-handle property -+ * @attr_name: the FSL_PAMU_ATTR_xxx attribute to change -+ * @attr_address: the physical address of the attribute structure -+ * -+ * FSL_PAMU_ATTR_STASH: Query the target CPU and cache level for stashing -+ * -+ * Returns 0 for success, or an error code. -+ */ -+static inline unsigned int fh_dma_attr_get(unsigned int handle, -+ unsigned int attr_name, phys_addr_t attr_address) -+{ -+ register uintptr_t r11 __asm__("r11"); -+ register uintptr_t r3 __asm__("r3"); -+ register uintptr_t r4 __asm__("r4"); -+ register uintptr_t r5 __asm__("r5"); -+ register uintptr_t r6 __asm__("r6"); -+ -+ r11 = FH_HCALL_TOKEN(FH_DMA_ATTR_GET); -+ r3 = handle; -+ r4 = attr_name; -+ r5 = (uint64_t)attr_address >> 32; -+ r6 = (uint32_t)attr_address; -+ -+ __asm__ __volatile__ ("sc 1" -+ : "+r" (r11), -+ "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6) -+ : : EV_HCALL_CLOBBERS4 -+ ); -+ -+ return r3; -+} -+ - #endif -diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h -index 88b0bd9..bc52378 100644 ---- a/arch/powerpc/include/asm/pgtable.h -+++ b/arch/powerpc/include/asm/pgtable.h -@@ -172,6 +172,9 @@ extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addre - - #define pgprot_writecombine pgprot_noncached_wc - -+#define pgprot_cached_noncoherent(prot) \ -+ (__pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL)) -+ - struct file; - extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, - unsigned long size, pgprot_t vma_prot); -diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig -index d7946be..b9a2559 100644 ---- a/arch/powerpc/platforms/85xx/Kconfig -+++ b/arch/powerpc/platforms/85xx/Kconfig -@@ -181,6 +181,8 @@ config P2041_RDB - select GPIO_MPC8XXX - select HAS_RAPIDIO - select PPC_EPAPR_HV_PIC -+ select HAS_FSL_PAMU -+ select HAS_FSL_QBMAN - help - This option enables support for the P2041 RDB board - -@@ -194,6 +196,9 @@ config P3041_DS - select GPIO_MPC8XXX - select HAS_RAPIDIO - select PPC_EPAPR_HV_PIC -+ select HAS_FSL_PAMU -+ select HAS_FSL_QBMAN -+ select FSL_HYDRA_DS_MDIO if PHYLIB - help - This option enables support for the P3041 DS board - -@@ -235,6 +240,9 @@ config P5020_DS - select GPIO_MPC8XXX - select HAS_RAPIDIO - select PPC_EPAPR_HV_PIC -+ select HAS_FSL_PAMU -+ select HAS_FSL_QBMAN -+ select FSL_HYDRA_DS_MDIO if PHYLIB - help - This option enables support for the P5020 DS board - -diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c -index 802ad11..5b6aebf 100644 ---- a/arch/powerpc/platforms/85xx/corenet_ds.c -+++ b/arch/powerpc/platforms/85xx/corenet_ds.c -@@ -112,6 +112,12 @@ static const struct of_device_id of_device_ids[] __devinitconst = { - .compatible = "simple-bus" - }, - { -+ .compatible = "fsl,dpaa" -+ }, -+ { -+ .compatible = "fsl,srio" -+ }, -+ { - .compatible = "fsl,rapidio-delta", - }, - { -@@ -134,3 +140,32 @@ int __init corenet_ds_publish_devices(void) - { - return of_platform_bus_probe(NULL, of_device_ids, NULL); - } -+ -+/* Early setup is required for large chunks of contiguous (and coarsely-aligned) -+ * memory. The following shoe-horns Qman/Bman "init_early" calls into the -+ * platform setup to let them parse their CCSR nodes early on. */ -+#ifdef CONFIG_FSL_QMAN_CONFIG -+void __init qman_init_early(void); -+#endif -+#ifdef CONFIG_FSL_BMAN_CONFIG -+void __init bman_init_early(void); -+#endif -+#ifdef CONFIG_FSL_PME2_CTRL -+void __init pme2_init_early(void); -+#endif -+ -+__init void corenet_ds_init_early(void) -+{ -+#ifdef CONFIG_FSL_QMAN_CONFIG -+ qman_init_early(); -+#endif -+#ifdef CONFIG_FSL_BMAN_CONFIG -+ bman_init_early(); -+#endif -+#ifdef CONFIG_FSL_PME2_CTRL -+ pme2_init_early(); -+#endif -+#ifdef CONFIG_FSL_USDPAA -+ fsl_usdpaa_init_early(); -+#endif -+} -diff --git a/arch/powerpc/platforms/85xx/corenet_ds.h b/arch/powerpc/platforms/85xx/corenet_ds.h -index ddd700b..a5b63c6 100644 ---- a/arch/powerpc/platforms/85xx/corenet_ds.h -+++ b/arch/powerpc/platforms/85xx/corenet_ds.h -@@ -15,5 +15,6 @@ - extern void __init corenet_ds_pic_init(void); - extern void __init corenet_ds_setup_arch(void); - extern int __init corenet_ds_publish_devices(void); -+extern void __init corenet_ds_init_early(void); - - #endif -diff --git a/arch/powerpc/platforms/85xx/p2041_rdb.c b/arch/powerpc/platforms/85xx/p2041_rdb.c -index eda6ed5..595670e 100644 ---- a/arch/powerpc/platforms/85xx/p2041_rdb.c -+++ b/arch/powerpc/platforms/85xx/p2041_rdb.c -@@ -79,6 +79,7 @@ define_machine(p2041_rdb) { - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, - .power_save = e500_idle, -+ .init_early = corenet_ds_init_early, - }; - - machine_device_initcall(p2041_rdb, corenet_ds_publish_devices); -diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile -index 84e1325..94aa06f 100644 ---- a/arch/powerpc/sysdev/Makefile -+++ b/arch/powerpc/sysdev/Makefile -@@ -18,6 +18,7 @@ obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) - obj-$(CONFIG_FSL_PMC) += fsl_pmc.o - obj-$(CONFIG_FSL_LBC) += fsl_lbc.o - obj-$(CONFIG_FSL_GTM) += fsl_gtm.o -+obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o - obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o - obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o - obj-$(CONFIG_FSL_RIO) += fsl_rio.o -diff --git a/arch/powerpc/sysdev/fsl_pamu.c b/arch/powerpc/sysdev/fsl_pamu.c -new file mode 100644 -index 0000000..a9e9fc7 ---- /dev/null -+++ b/arch/powerpc/sysdev/fsl_pamu.c -@@ -0,0 +1,1431 @@ -+/* 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. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* PAMU CCSR space */ -+#define PAMU_PGC 0x00000000 /* Allows all peripheral accesses */ -+#define PAMU_PE 0x40000000 /* enable PAMU */ -+ -+/* PAMU_OFFSET to the next pamu space in ccsr */ -+#define PAMU_OFFSET 0x1000 -+ -+#define PAMU_MMAP_REGS_BASE 0 -+ -+struct pamu_mmap_regs { -+ u32 ppbah; -+ u32 ppbal; -+ u32 pplah; -+ u32 pplal; -+ u32 spbah; -+ u32 spbal; -+ u32 splah; -+ u32 splal; -+ u32 obah; -+ u32 obal; -+ u32 olah; -+ u32 olal; -+}; -+ -+/* PAMU Error Registers */ -+#define PAMU_POES1 0x0040 -+#define PAMU_POES2 0x0044 -+#define PAMU_POEAH 0x0048 -+#define PAMU_POEAL 0x004C -+#define PAMU_AVS1 0x0050 -+#define PAMU_AVS1_AV 0x1 -+#define PAMU_AVS1_OTV 0x6 -+#define PAMU_AVS1_APV 0x78 -+#define PAMU_AVS1_WAV 0x380 -+#define PAMU_AVS1_LAV 0x1c00 -+#define PAMU_AVS1_GCV 0x2000 -+#define PAMU_AVS1_PDV 0x4000 -+#define PAMU_AV_MASK (PAMU_AVS1_AV | PAMU_AVS1_OTV | PAMU_AVS1_APV | \ -+ PAMU_AVS1_WAV | PAMU_AVS1_LAV | PAMU_AVS1_GCV | \ -+ PAMU_AVS1_PDV) -+#define PAMU_AVS1_LIODN_SHIFT 16 -+#define PAMU_LAV_LIODN_NOT_IN_PPAACT 0x400 -+ -+#define PAMU_AVS2 0x0054 -+#define PAMU_AVAH 0x0058 -+#define PAMU_AVAL 0x005C -+#define PAMU_EECTL 0x0060 -+#define PAMU_EEDIS 0x0064 -+#define PAMU_EEINTEN 0x0068 -+#define PAMU_EEDET 0x006C -+#define PAMU_EEATTR 0x0070 -+#define PAMU_EEAHI 0x0074 -+#define PAMU_EEALO 0x0078 -+#define PAMU_EEDHI 0X007C -+#define PAMU_EEDLO 0x0080 -+#define PAMU_EECC 0x0084 -+#define PAMU_UDAD 0x0090 -+ -+/* PAMU Revision Registers */ -+#define PAMU_PR1 0x0BF8 -+#define PAMU_PR2 0x0BFC -+ -+/* PAMU Capabilities Registers */ -+#define PAMU_PC1 0x0C00 -+#define PAMU_PC2 0x0C04 -+#define PAMU_PC3 0x0C08 -+#define PAMU_PC4 0x0C0C -+ -+/* PAMU Control Register */ -+#define PAMU_PC 0x0C10 -+ -+/* PAMU control defs */ -+#define PAMU_CONTROL 0x0C10 -+#define PAMU_PC_PGC 0x80000000 /* 1 = PAMU Gate Closed : block all -+peripheral access, 0 : may allow peripheral access */ -+ -+#define PAMU_PC_PE 0x40000000 /* 0 = PAMU disabled, 1 = PAMU enabled */ -+#define PAMU_PC_SPCC 0x00000010 /* sPAACE cache enable */ -+#define PAMU_PC_PPCC 0x00000001 /* pPAACE cache enable */ -+#define PAMU_PC_OCE 0x00001000 /* OMT cache enable */ -+ -+#define PAMU_PFA1 0x0C14 -+#define PAMU_PFA2 0x0C18 -+ -+/* PAMU Interrupt control and Status Register */ -+#define PAMU_PICS 0x0C1C -+#define PAMU_ACCESS_VIOLATION_STAT 0x8 -+#define PAMU_ACCESS_VIOLATION_ENABLE 0x4 -+ -+/* PAMU Debug Registers */ -+#define PAMU_PD1 0x0F00 -+#define PAMU_PD2 0x0F04 -+#define PAMU_PD3 0x0F08 -+#define PAMU_PD4 0x0F0C -+ -+#define PAACE_AP_PERMS_DENIED 0x0 -+#define PAACE_AP_PERMS_QUERY 0x1 -+#define PAACE_AP_PERMS_UPDATE 0x2 -+#define PAACE_AP_PERMS_ALL 0x3 -+#define PAACE_DD_TO_HOST 0x0 -+#define PAACE_DD_TO_IO 0x1 -+#define PAACE_PT_PRIMARY 0x0 -+#define PAACE_PT_SECONDARY 0x1 -+#define PAACE_V_INVALID 0x0 -+#define PAACE_V_VALID 0x1 -+#define PAACE_MW_SUBWINDOWS 0x1 -+ -+#define PAACE_WSE_4K 0xB -+#define PAACE_WSE_8K 0xC -+#define PAACE_WSE_16K 0xD -+#define PAACE_WSE_32K 0xE -+#define PAACE_WSE_64K 0xF -+#define PAACE_WSE_128K 0x10 -+#define PAACE_WSE_256K 0x11 -+#define PAACE_WSE_512K 0x12 -+#define PAACE_WSE_1M 0x13 -+#define PAACE_WSE_2M 0x14 -+#define PAACE_WSE_4M 0x15 -+#define PAACE_WSE_8M 0x16 -+#define PAACE_WSE_16M 0x17 -+#define PAACE_WSE_32M 0x18 -+#define PAACE_WSE_64M 0x19 -+#define PAACE_WSE_128M 0x1A -+#define PAACE_WSE_256M 0x1B -+#define PAACE_WSE_512M 0x1C -+#define PAACE_WSE_1G 0x1D -+#define PAACE_WSE_2G 0x1E -+#define PAACE_WSE_4G 0x1F -+ -+#define PAACE_DID_PCI_EXPRESS_1 0x00 -+#define PAACE_DID_PCI_EXPRESS_2 0x01 -+#define PAACE_DID_PCI_EXPRESS_3 0x02 -+#define PAACE_DID_PCI_EXPRESS_4 0x03 -+#define PAACE_DID_LOCAL_BUS 0x04 -+#define PAACE_DID_SRIO 0x0C -+#define PAACE_DID_MEM_1 0x10 -+#define PAACE_DID_MEM_2 0x11 -+#define PAACE_DID_MEM_3 0x12 -+#define PAACE_DID_MEM_4 0x13 -+#define PAACE_DID_MEM_1_2 0x14 -+#define PAACE_DID_MEM_3_4 0x15 -+#define PAACE_DID_MEM_1_4 0x16 -+#define PAACE_DID_BM_SW_PORTAL 0x18 -+#define PAACE_DID_PAMU 0x1C -+#define PAACE_DID_CAAM 0x21 -+#define PAACE_DID_QM_SW_PORTAL 0x3C -+#define PAACE_DID_CORE0_INST 0x80 -+#define PAACE_DID_CORE0_DATA 0x81 -+#define PAACE_DID_CORE1_INST 0x82 -+#define PAACE_DID_CORE1_DATA 0x83 -+#define PAACE_DID_CORE2_INST 0x84 -+#define PAACE_DID_CORE2_DATA 0x85 -+#define PAACE_DID_CORE3_INST 0x86 -+#define PAACE_DID_CORE3_DATA 0x87 -+#define PAACE_DID_CORE4_INST 0x88 -+#define PAACE_DID_CORE4_DATA 0x89 -+#define PAACE_DID_CORE5_INST 0x8A -+#define PAACE_DID_CORE5_DATA 0x8B -+#define PAACE_DID_CORE6_INST 0x8C -+#define PAACE_DID_CORE6_DATA 0x8D -+#define PAACE_DID_CORE7_INST 0x8E -+#define PAACE_DID_CORE7_DATA 0x8F -+#define PAACE_DID_BROADCAST 0xFF -+ -+#define PAACE_ATM_NO_XLATE 0x00 -+#define PAACE_ATM_WINDOW_XLATE 0x01 -+#define PAACE_ATM_PAGE_XLATE 0x02 -+#define PAACE_ATM_WIN_PG_XLATE (PAACE_ATM_WINDOW_XLATE | PAACE_ATM_PAGE_XLATE) -+#define PAACE_OTM_NO_XLATE 0x00 -+#define PAACE_OTM_IMMEDIATE 0x01 -+#define PAACE_OTM_INDEXED 0x02 -+#define PAACE_OTM_RESERVED 0x03 -+ -+#define PAACE_M_COHERENCE_REQ 0x01 -+ -+#define PAACE_TCEF_FORMAT0_8B 0x00 -+#define PAACE_TCEF_FORMAT1_RSVD 0x01 -+ -+#define PAACE_NUMBER_ENTRIES 0x500 -+ -+#define OME_NUMBER_ENTRIES 16 /* based on P4080 2.0 silicon plan */ -+ -+/* PAMU Data Structures */ -+ -+struct ppaace { -+ /* PAACE Offset 0x00 */ -+ /* Window Base Address */ -+ u32 wbah; -+ unsigned int wbal:20; -+ /* Window Size, 2^(N+1), N must be > 10 */ -+ unsigned int wse:6; -+ /* 1 Means there are secondary windows, wce is count */ -+ unsigned int mw:1; -+ /* Permissions, see PAACE_AP_PERMS_* defines */ -+ unsigned int ap:2; -+ /* -+ * Destination Domain, see PAACE_DD_* defines, -+ * defines data structure reference for ingress ops into -+ * host/coherency domain or ingress ops into I/O domain -+ */ -+ unsigned int dd:1; -+ /* PAACE Type, see PAACE_PT_* defines */ -+ unsigned int pt:1; -+ /* PAACE Valid, 0 is invalid */ -+ unsigned int v:1; -+ -+ /* PAACE Offset 0x08 */ -+ /* Interpretation of first 32 bits dependent on DD above */ -+ union { -+ struct { -+ /* Destination ID, see PAACE_DID_* defines */ -+ u8 did; -+ /* Partition ID */ -+ u8 pid; -+ /* Snoop ID */ -+ u8 snpid; -+ unsigned int coherency_required:1; -+ unsigned int reserved:7; -+ } to_host; -+ struct { -+ /* Destination ID, see PAACE_DID_* defines */ -+ u8 did; -+ unsigned int __reserved:24; -+ } to_io; -+ } __packed domain_attr; -+ /* Implementation attributes */ -+ struct { -+ unsigned int reserved1:8; -+ unsigned int cid:8; -+ unsigned int reserved2:8; -+ } __packed impl_attr; -+ /* Window Count; 2^(N+1) sub-windows; only valid for primary PAACE */ -+ unsigned int wce:4; -+ /* Address translation mode, see PAACE_ATM_* defines */ -+ unsigned int atm:2; -+ /* Operation translation mode, see PAACE_OTM_* defines */ -+ unsigned int otm:2; -+ -+ /* PAACE Offset 0x10 */ -+ /* Translated window base address */ -+ u32 twbah; -+ unsigned int twbal:20; -+ /* Subwindow size encoding; 2^(N+1), N > 10 */ -+ unsigned int swse:6; -+ unsigned int reserved4:6; -+ -+ /* PAACE Offset 0x18 */ -+ u32 fspi; -+ union { -+ struct { -+ u8 ioea; -+ u8 moea; -+ u8 ioeb; -+ u8 moeb; -+ } immed_ot; -+ struct { -+ u16 reserved; -+ u16 omi; -+ } index_ot; -+ } __packed op_encode; -+ -+ /* PAACE Offset 0x20 */ -+ u32 sbah; -+ unsigned int sbal:20; -+ unsigned int sse:6; -+ unsigned int reserved5:6; -+ -+ /* PAACE Offset 0x28 */ -+ u32 tctbah; -+ unsigned int tctbal:20; -+ unsigned int pse:6; -+ unsigned int tcef:1; -+ unsigned int reserved6:5; -+ -+ /* PAACE Offset 0x30 */ -+ u32 reserved7[2]; -+ -+ /* PAACE Offset 0x38 */ -+ u32 reserved8[2]; -+} __packed ppaace; -+ -+/* MOE : Mapped Operation Encodings */ -+#define NUM_MOE 128 -+struct ome { -+ u8 moe[NUM_MOE]; -+} __packed ome; -+ -+/* -+ * The Primary Peripheral Access Authorization and Control Table -+ * -+ * To keep things simple, we use one shared PPAACT for all PAMUs. This means -+ * that LIODNs must be unique across all PAMUs. -+ */ -+static struct ppaace *ppaact; -+static phys_addr_t ppaact_phys; -+ -+/* TRUE if we're running under the Freescale hypervisor */ -+bool has_fsl_hypervisor; -+ -+#define PAACT_SIZE (sizeof(struct ppaace) * PAACE_NUMBER_ENTRIES) -+#define OMT_SIZE (sizeof(struct ome) * OME_NUMBER_ENTRIES) -+ -+#define IOE_READ 0x00 -+#define IOE_READ_IDX 0x00 -+#define IOE_WRITE 0x81 -+#define IOE_WRITE_IDX 0x01 -+#define IOE_EREAD0 0x82 /* Enhanced read type 0 */ -+#define IOE_EREAD0_IDX 0x02 /* Enhanced read type 0 */ -+#define IOE_EWRITE0 0x83 /* Enhanced write type 0 */ -+#define IOE_EWRITE0_IDX 0x03 /* Enhanced write type 0 */ -+#define IOE_DIRECT0 0x84 /* Directive type 0 */ -+#define IOE_DIRECT0_IDX 0x04 /* Directive type 0 */ -+#define IOE_EREAD1 0x85 /* Enhanced read type 1 */ -+#define IOE_EREAD1_IDX 0x05 /* Enhanced read type 1 */ -+#define IOE_EWRITE1 0x86 /* Enhanced write type 1 */ -+#define IOE_EWRITE1_IDX 0x06 /* Enhanced write type 1 */ -+#define IOE_DIRECT1 0x87 /* Directive type 1 */ -+#define IOE_DIRECT1_IDX 0x07 /* Directive type 1 */ -+#define IOE_RAC 0x8c /* Read with Atomic clear */ -+#define IOE_RAC_IDX 0x0c /* Read with Atomic clear */ -+#define IOE_RAS 0x8d /* Read with Atomic set */ -+#define IOE_RAS_IDX 0x0d /* Read with Atomic set */ -+#define IOE_RAD 0x8e /* Read with Atomic decrement */ -+#define IOE_RAD_IDX 0x0e /* Read with Atomic decrement */ -+#define IOE_RAI 0x8f /* Read with Atomic increment */ -+#define IOE_RAI_IDX 0x0f /* Read with Atomic increment */ -+ -+#define EOE_READ 0x00 -+#define EOE_WRITE 0x01 -+#define EOE_RAC 0x0c /* Read with Atomic clear */ -+#define EOE_RAS 0x0d /* Read with Atomic set */ -+#define EOE_RAD 0x0e /* Read with Atomic decrement */ -+#define EOE_RAI 0x0f /* Read with Atomic increment */ -+#define EOE_LDEC 0x10 /* Load external cache */ -+#define EOE_LDECL 0x11 /* Load external cache with stash lock */ -+#define EOE_LDECPE 0x12 /* Load ext. cache with preferred exclusive */ -+#define EOE_LDECPEL 0x13 /* Load ext. cache w/ preferred excl. & lock */ -+#define EOE_LDECFE 0x14 /* Load external cache with forced exclusive */ -+#define EOE_LDECFEL 0x15 /* Load ext. cache w/ forced excl. & lock */ -+#define EOE_RSA 0x16 /* Read with stash allocate */ -+#define EOE_RSAU 0x17 /* Read with stash allocate and unlock */ -+#define EOE_READI 0x18 /* Read with invalidate */ -+#define EOE_RWNITC 0x19 /* Read with no intention to cache */ -+#define EOE_WCI 0x1a /* Write cache inhibited */ -+#define EOE_WWSA 0x1b /* Write with stash allocate */ -+#define EOE_WWSAL 0x1c /* Write with stash allocate and lock */ -+#define EOE_WWSAO 0x1d /* Write with stash allocate only */ -+#define EOE_WWSAOL 0x1e /* Write with stash allocate only and lock */ -+#define EOE_VALID 0x80 -+ -+/* define indexes for each operation mapping scenario */ -+#define OMI_QMAN 0x00 -+#define OMI_FMAN 0x01 -+#define OMI_QMAN_PRIV 0x02 -+#define OMI_CAAM 0x03 -+ -+/* -+ * Return the Nth integer of a given property in a given node -+ * -+ * 'index' is the index into the property (e.g. 'N'). -+ * 'property' is the name of the property. -+ * -+ * This function assumes the value of the property is <= INT_MAX. A negative -+ * return value indicates an error. -+ */ -+static int of_read_indexed_number(struct device_node *node, -+ const char *property, unsigned int index) -+{ -+ const u32 *prop; -+ int value; -+ int len; -+ -+ prop = of_get_property(node, property, &len); -+ if (!prop || (len % sizeof(uint32_t))) -+ return -ENODEV; -+ -+ if (index >= (len / sizeof(uint32_t))) -+ return -EINVAL; -+ -+ value = be32_to_cpu(prop[index]); -+ -+ return value; -+} -+ -+/** -+ * pamu_set_stash_dest() - set the stash target for a given LIODN -+ * @liodn: LIODN to set -+ * @cache_level: target cache level (1, 2, or 3) -+ * @cpu: target CPU (0, 1, 2, etc) -+ * -+ * This function sets the stash target for a given LIODN, assuming that the -+ * PAACE entry for that LIODN is already configured. -+ * -+ * The function returns 0 on success, or a negative error code on failure. -+ */ -+int pamu_set_stash_dest(struct device_node *node, unsigned int index, -+ unsigned int cpu, unsigned int cache_level) -+{ -+ int liodn; -+ const u32 *prop; -+ unsigned int i; -+ int psize; -+ -+#ifdef CONFIG_FSL_PAMU_ERRATUM_A_004510 -+ /* -+ * The work-around says that we cannot have multiple writes to the -+ * PAACT in flight simultaneously, which could happen if multiple -+ * cores try to update CID simultaneously. To prevent that, we wrap -+ * the write in a mutex, which will force the cores to perform their -+ * updates in sequence. -+ */ -+ static DEFINE_SPINLOCK(pamu_lock); -+#endif -+ -+ -+ /* If we're running under a support hypervisor, make an hcall instead */ -+ if (has_fsl_hypervisor) { -+ struct fh_dma_attr_stash attr; -+ phys_addr_t paddr = virt_to_phys(&attr); -+ int handle; -+ -+ handle = of_read_indexed_number(node, "fsl,hv-dma-handle", -+ index); -+ -+ if (handle < 0) -+ return -EINVAL; -+ -+ attr.vcpu = cpu; -+ attr.cache = cache_level; -+ -+ if (fh_dma_attr_set(handle, FSL_PAMU_ATTR_STASH, paddr)) -+ return -EINVAL; -+ -+ return 0; -+ } -+ -+ liodn = of_read_indexed_number(node, "fsl,liodn", index); -+ if (liodn < 0) -+ return liodn; -+ -+ for_each_node_by_type(node, "cpu") { -+ prop = of_get_property(node, "reg", &psize); -+ if (prop) { -+ psize /= 4; -+ for (i = 0; i < psize; i++) -+ if (be32_to_cpup(prop++) == cpu) -+ goto found_cpu; -+ } -+ } -+ -+ pr_err("fsl-pamu: could not find 'cpu' node %u\n", cpu); -+ return -EINVAL; -+ -+found_cpu: -+ /* -+ * Traverse the list of caches until we find the one we want. The CPU -+ * node is also the L1 cache node -+ */ -+ for (i = 1; i < cache_level; i++) { -+ node = of_parse_phandle(node, "next-level-cache", 0); -+ if (!node) { -+ pr_err("fsl-pamu: cache level %u invalid for cpu %u\n", -+ i, cpu); -+ return -EINVAL; -+ } -+ } -+ -+ prop = of_get_property(node, "cache-stash-id", NULL); -+ if (!prop) { -+ pr_err("fsl-pamu: missing 'cache-stash-id' in %s\n", -+ node->full_name); -+ return -EINVAL; -+ } -+ -+#ifdef CONFIG_FSL_PAMU_ERRATUM_A_004510 -+ spin_lock(&pamu_lock); -+#endif -+ -+ ppaact[liodn].impl_attr.cid = be32_to_cpup(prop); -+ mb(); -+ -+#ifdef CONFIG_FSL_PAMU_ERRATUM_A_004510 -+ spin_unlock(&pamu_lock); -+#endif -+ -+ return 0; -+} -+EXPORT_SYMBOL(pamu_set_stash_dest); -+ -+/** -+ * pamu_get_liodn_count() - returns the number of LIODNs for a given node -+ * @node: the node to query -+ * -+ * This function returns the number of LIODNs in a given node. -+ * -+ * The function returns the number >= 0 on success, or a negative error code -+ * on failure. Currently, an error code cannot be returned, but that may -+ * change in the future. Callers are still expected to test for an error. -+ */ -+int pamu_get_liodn_count(struct device_node *node) -+{ -+ const u32 *prop; -+ int len; -+ -+ /* -+ * Under the hypervisor, use the "fsl,hv-dma-handle". Otherwise, -+ * use the "fsl,liodn" property. -+ */ -+ if (has_fsl_hypervisor) -+ prop = of_get_property(node, "fsl,hv-dma-handle", &len); -+ else -+ prop = of_get_property(node, "fsl,liodn", &len); -+ -+ if (!prop) -+ /* -+ * KVM sets up default stashing but does not provide an -+ * interface to the PAMU, so there are no PAMU nodes or LIODN -+ * properties in the guest device tree. Therefore, if the -+ * LIODN property is missing, that doesn't mean that 'node' is -+ * invalid. -+ */ -+ return 0; -+ -+ return len / sizeof(uint32_t); -+} -+EXPORT_SYMBOL(pamu_get_liodn_count); -+ -+ -+static void __init setup_omt(struct ome *omt) -+{ -+ struct ome *ome; -+ -+ /* Configure OMI_QMAN */ -+ ome = &omt[OMI_QMAN]; -+ -+ ome->moe[IOE_READ_IDX] = EOE_VALID | EOE_READ; -+ ome->moe[IOE_EREAD0_IDX] = EOE_VALID | EOE_RSA; -+ ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE; -+ ome->moe[IOE_EWRITE0_IDX] = EOE_VALID | EOE_WWSAO; -+ -+ /* -+ * When it comes to stashing DIRECTIVEs, the QMan BG says -+ * (1.5.6.7.1: FQD Context_A field used for dequeued etc. -+ * etc. stashing control): -+ * - AE/DE/CE == 0: don't stash exclusive. Use DIRECT0, -+ * which should be a non-PE LOADEC. -+ * - AE/DE/CE == 1: stash exclusive via DIRECT1, i.e. -+ * LOADEC-PE -+ * If one desires to alter how the three different types of -+ * stashing are done, please alter rx_conf.exclusive in -+ * ipfwd_a.c (that specifies the 3-bit AE/DE/CE field), and -+ * do not alter the settings here. - bgrayson -+ */ -+ ome->moe[IOE_DIRECT0_IDX] = EOE_VALID | EOE_LDEC; -+ ome->moe[IOE_DIRECT1_IDX] = EOE_VALID | EOE_LDECPE; -+ -+ /* Configure OMI_FMAN */ -+ ome = &omt[OMI_FMAN]; -+ ome->moe[IOE_READ_IDX] = EOE_VALID | EOE_READI; -+ ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WWSA; -+ -+ /* Configure OMI_QMAN private */ -+ ome = &omt[OMI_QMAN_PRIV]; -+ ome->moe[IOE_READ_IDX] = EOE_VALID | EOE_READ; -+ ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE; -+ ome->moe[IOE_EREAD0_IDX] = EOE_VALID | EOE_RSA; -+ ome->moe[IOE_EWRITE0_IDX] = EOE_VALID | EOE_WWSA; -+ -+ /* Configure OMI_CAAM */ -+ ome = &omt[OMI_CAAM]; -+ ome->moe[IOE_READ_IDX] = EOE_VALID | EOE_READI; -+ ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE; -+} -+ -+static u32 __init get_stash_id(unsigned int stash_dest_hint, -+ struct device_node *portal_dn) -+{ -+ const u32 *prop; -+ struct device_node *node; -+ unsigned int cache_level; -+ -+ /* Fastpath, exit early if 3/CPC cache is target for stashing */ -+ if (stash_dest_hint == 3) { -+ node = of_find_compatible_node(NULL, NULL, -+ "fsl,p4080-l3-cache-controller"); -+ if (node) { -+ prop = of_get_property(node, "cache-stash-id", 0); -+ if (!prop) { -+ pr_err("fsl-pamu: missing cache-stash-id in " -+ " %s\n", node->full_name); -+ of_node_put(node); -+ return ~(u32)0; -+ } -+ of_node_put(node); -+ return *prop; -+ } -+ return ~(u32)0; -+ } -+ -+ prop = of_get_property(portal_dn, "cpu-handle", 0); -+ /* if no cpu-phandle assume that this is not a per-cpu portal */ -+ if (!prop) -+ return ~(u32)0; -+ -+ node = of_find_node_by_phandle(*prop); -+ if (!node) { -+ pr_err("fsl-pamu: bad cpu-handle reference in %s\n", -+ portal_dn->full_name); -+ return ~(u32)0; -+ } -+ -+ /* find the hwnode that represents the cache */ -+ for (cache_level = 1; cache_level <= 3; cache_level++) { -+ if (stash_dest_hint == cache_level) { -+ prop = of_get_property(node, "cache-stash-id", 0); -+ of_node_put(node); -+ if (!prop) { -+ pr_err("fsl-pamu: missing cache-stash-id in " -+ "%s\n", node->full_name); -+ return ~(u32)0; -+ } -+ return *prop; -+ } -+ -+ prop = of_get_property(node, "next-level-cache", 0); -+ if (!prop) { -+ pr_err("fsl-pamu: can't find next-level-cache in %s\n", -+ node->full_name); -+ of_node_put(node); -+ return ~(u32)0; /* can't traverse any further */ -+ } -+ of_node_put(node); -+ -+ /* advance to next node in cache hierarchy */ -+ node = of_find_node_by_phandle(*prop); -+ if (!node) { -+ pr_err("fsl-pamu: bad cpu phandle reference in %s\n", -+ portal_dn->full_name); -+ return ~(u32)0; -+ } -+ } -+ -+ pr_err("fsl-pamu: stash destination not found for cache level %d " -+ "on portal node %s\n", stash_dest_hint, portal_dn->full_name); -+ -+ return ~(u32)0; -+} -+ -+#ifdef CONFIG_FSL_FMAN_CPC_STASH -+static void __init enable_fman_io_stashing(struct device_node *dn) -+{ -+ const u32 *prop; -+ struct ppaace *ppaace; -+ u32 cache_id; -+ -+ prop = of_get_property(dn, "fsl,liodn", NULL); -+ if (prop) { -+ ppaace = &ppaact[*prop]; -+ ppaace->otm = PAACE_OTM_INDEXED; -+ ppaace->domain_attr.to_host.coherency_required = 1; -+ ppaace->op_encode.index_ot.omi = OMI_FMAN; -+ cache_id = get_stash_id(3, NULL); -+ pr_debug("%s cache_stash_id = %d\n", dn->full_name, cache_id); -+ if (~cache_id != 0) -+ ppaace->impl_attr.cid = cache_id; -+ } else { -+ pr_err("fsl-pamu: missing fsl,liodn property in %s\n", -+ dn->full_name); -+ } -+} -+#endif -+ -+static void __init setup_liodns(void) -+{ -+ int i, len; -+ struct ppaace *ppaace; -+ struct device_node *qman_portal_dn = NULL; -+ struct device_node *qman_dn = NULL; -+ struct device_node *bman_dn; -+ const u32 *prop; -+ u32 cache_id, prop_cnt; -+#ifdef CONFIG_FSL_FMAN_CPC_STASH -+ struct device_node *port_dn; -+#endif -+ -+ for (i = 0; i < PAACE_NUMBER_ENTRIES; i++) { -+ ppaace = &ppaact[i]; -+ ppaace->pt = PAACE_PT_PRIMARY; -+ ppaace->domain_attr.to_host.coherency_required = -+ PAACE_M_COHERENCE_REQ; -+ /* window size is 2^(WSE+1) bytes */ -+ ppaace->wse = 35; /* 36-bit phys. addr space */ -+ ppaace->wbah = ppaace->wbal = 0; -+ ppaace->atm = PAACE_ATM_NO_XLATE; -+ ppaace->ap = PAACE_AP_PERMS_ALL; -+ mb(); -+ ppaace->v = 1; -+ } -+ -+ /* -+ * Now, do specific stashing setup for qman portals. -+ * We need stashing setup for LIODNs for qman portal(s) dqrr stashing -+ * (DLIODNs), qman portal(s) data stashing (FLIODNs) -+ */ -+ -+ for_each_compatible_node(qman_portal_dn, NULL, "fsl,qman-portal") { -+ pr_debug("qman portal %s found\n", qman_portal_dn->full_name); -+ -+ prop = of_get_property(qman_portal_dn, "fsl,liodn", &len); -+ if (prop) { -+ prop_cnt = len / sizeof(u32); -+ do { -+ pr_debug("liodn = %d\n", *prop); -+ ppaace = &ppaact[*prop++]; -+ ppaace->otm = PAACE_OTM_INDEXED; -+ ppaace->op_encode.index_ot.omi = OMI_QMAN; -+ cache_id = get_stash_id(3, qman_portal_dn); -+ pr_debug("cache_stash_id = %d\n", cache_id); -+ if (~cache_id != 0) -+ ppaace->impl_attr.cid = cache_id; -+ } while (--prop_cnt); -+ } else { -+ pr_err("fsl-pamu: missing fsl,liodn property in %s\n", -+ qman_portal_dn->full_name); -+ } -+ } -+ -+ /* -+ * Next, do stashing setups for qman private memory access -+ */ -+ -+ qman_dn = of_find_compatible_node(NULL, NULL, "fsl,qman"); -+ if (qman_dn) { -+ prop = of_get_property(qman_dn, "fsl,liodn", NULL); -+ if (prop) { -+ ppaace = &ppaact[*prop]; -+ ppaace->otm = PAACE_OTM_INDEXED; -+ ppaace->domain_attr.to_host.coherency_required = 0; -+ ppaace->op_encode.index_ot.omi = OMI_QMAN_PRIV; -+ cache_id = get_stash_id(3, qman_dn); -+ pr_debug("cache_stash_id = %d\n", cache_id); -+ if (~cache_id != 0) -+ ppaace->impl_attr.cid = cache_id; -+ } else { -+ pr_err("fsl-pamu: missing fsl,liodn property in %s\n", -+ qman_dn->full_name); -+ } -+ of_node_put(qman_dn); -+ } -+ -+#ifdef CONFIG_FSL_FMAN_CPC_STASH -+ port_dn = NULL; -+ for_each_compatible_node(port_dn, NULL, "fsl,fman-port-10g-rx") -+ enable_fman_io_stashing(port_dn); -+ -+ port_dn = NULL; -+ for_each_compatible_node(port_dn, NULL, "fsl,fman-port-1g-rx") -+ enable_fman_io_stashing(port_dn); -+#endif -+ /* -+ * For liodn used by BMAN for its private memory accesses, -+ * turn the 'coherency required' off. This saves snoops to cores. -+ */ -+ -+ bman_dn = of_find_compatible_node(NULL, NULL, "fsl,bman"); -+ if (bman_dn) { -+ prop = of_get_property(bman_dn, "fsl,liodn", NULL); -+ if (prop) { -+ ppaace = &ppaact[*prop]; -+ ppaace->domain_attr.to_host.coherency_required = 0; -+ } else { -+ pr_err("fsl-pamu: missing fsl,liodn property in %s\n", -+ bman_dn->full_name); -+ } -+ of_node_put(bman_dn); -+ } -+} -+ -+static int __init setup_one_pamu(void *pamu_reg_base, struct ome *omt) -+{ -+ struct pamu_mmap_regs *pamu_regs = pamu_reg_base + PAMU_MMAP_REGS_BASE; -+ phys_addr_t phys; -+ -+ /* set up pointers to corenet control blocks */ -+ -+ phys = ppaact_phys; -+ out_be32(&pamu_regs->ppbah, upper_32_bits(phys)); -+ out_be32(&pamu_regs->ppbal, lower_32_bits(phys)); -+ -+ phys = ppaact_phys + PAACE_NUMBER_ENTRIES * sizeof(struct ppaace); -+ out_be32(&pamu_regs->pplah, upper_32_bits(phys)); -+ out_be32(&pamu_regs->pplal, lower_32_bits(phys)); -+ -+ phys = virt_to_phys(omt); -+ out_be32(&pamu_regs->obah, upper_32_bits(phys)); -+ out_be32(&pamu_regs->obal, lower_32_bits(phys)); -+ -+ phys = virt_to_phys(omt + OME_NUMBER_ENTRIES); -+ out_be32(&pamu_regs->olah, upper_32_bits(phys)); -+ out_be32(&pamu_regs->olal, lower_32_bits(phys)); -+ -+ -+ /* -+ * set PAMU enable bit, -+ * allow ppaact & omt to be cached -+ * & enable PAMU access violation interrupts. -+ */ -+ -+ out_be32(pamu_reg_base + PAMU_PICS, PAMU_ACCESS_VIOLATION_ENABLE); -+ out_be32(pamu_reg_base + PAMU_PC, -+ PAMU_PC_PE | PAMU_PC_OCE | PAMU_PC_SPCC | PAMU_PC_PPCC); -+ -+ return 0; -+} -+ -+#define make64(high, low) (((u64)(high) << 32) | (low)) -+ -+struct pamu_isr_data { -+ void __iomem *pamu_reg_base; /* Base address of PAMU regs*/ -+ unsigned int count; /* The number of PAMUs */ -+}; -+ -+static irqreturn_t pamu_av_isr(int irq, void *arg) -+{ -+ struct pamu_isr_data *data = arg; -+ phys_addr_t phys; -+ unsigned int i, j; -+ -+ pr_emerg("fsl-pamu: access violation interrupt\n"); -+ -+ for (i = 0; i < data->count; i++) { -+ void __iomem *p = data->pamu_reg_base + i * PAMU_OFFSET; -+ u32 pics = in_be32(p + PAMU_PICS); -+ -+ if (pics & PAMU_ACCESS_VIOLATION_STAT) { -+ pr_emerg("POES1=%08x\n", in_be32(p + PAMU_POES1)); -+ pr_emerg("POES2=%08x\n", in_be32(p + PAMU_POES2)); -+ pr_emerg("AVS1=%08x\n", in_be32(p + PAMU_AVS1)); -+ pr_emerg("AVS2=%08x\n", in_be32(p + PAMU_AVS2)); -+ pr_emerg("AVA=%016llx\n", make64(in_be32(p + PAMU_AVAH), -+ in_be32(p + PAMU_AVAL))); -+ pr_emerg("UDAD=%08x\n", in_be32(p + PAMU_UDAD)); -+ pr_emerg("POEA=%016llx\n", make64(in_be32(p + PAMU_POEAH), -+ in_be32(p + PAMU_POEAL))); -+ -+ phys = make64(in_be32(p + PAMU_POEAH), -+ in_be32(p + PAMU_POEAL)); -+ -+ /* Assume that POEA points to a PAACE */ -+ if (phys) { -+ u32 *paace = phys_to_virt(phys); -+ -+ /* Only the first four words are relevant */ -+ for (j = 0; j < 4; j++) -+ pr_emerg("PAACE[%u]=%08x\n", j, in_be32(paace + j)); -+ } -+ } -+ } -+ -+ panic("\n"); -+ -+ /* NOT REACHED */ -+ return IRQ_HANDLED; -+} -+ -+#ifdef CONFIG_FSL_PAMU_ERRATUM_A_004510 -+ -+/* -+ * The work-around for erratum A-004510 says we need to create a coherency -+ * subdomain (CSD), which means we need to create a LAW (local access window) -+ * just for the PAACT and OMT, and then give it a unique CSD ID. Linux -+ * normally doesn't touch the LAWs, so we define everything here. -+ */ -+ -+#define LAWAR_EN 0x80000000 -+#define LAWAR_TARGET_MASK 0x0FF00000 -+#define LAWAR_TARGET_SHIFT 20 -+#define LAWAR_SIZE_MASK 0x0000003F -+#define LAWAR_CSDID_MASK 0x000FF000 -+#define LAWAR_CSDID_SHIFT 12 -+ -+#define LAW_SIZE_4K 0xb -+ -+struct ccsr_law { -+ u32 lawbarh; /* LAWn base address high */ -+ u32 lawbarl; /* LAWn base address low */ -+ u32 lawar; /* LAWn attributes */ -+ u32 reserved; -+}; -+ -+/* -+ * Create a coherence subdomain for a given memory block. -+ */ -+static int __init create_csd(phys_addr_t phys, size_t size, u32 csd_port_id) -+{ -+ struct device_node *np; -+ const __be32 *iprop; -+ void __iomem *lac = NULL; /* Local Access Control registers */ -+ struct ccsr_law __iomem *law; -+ void __iomem *ccm = NULL; -+ u32 __iomem *csdids; -+ unsigned int i, num_laws, num_csds; -+ u32 law_target = 0; -+ u32 csd_id = 0; -+ int ret = 0; -+ -+ np = of_find_compatible_node(NULL, NULL, "fsl,corenet-law"); -+ if (!np) -+ return -ENODEV; -+ -+ iprop = of_get_property(np, "fsl,num-laws", NULL); -+ if (!iprop) { -+ ret = -ENODEV; -+ goto error; -+ } -+ -+ num_laws = be32_to_cpup(iprop); -+ if (!num_laws) { -+ ret = -ENODEV; -+ goto error; -+ } -+ -+ lac = of_iomap(np, 0); -+ if (!lac) { -+ ret = -ENODEV; -+ goto error; -+ } -+ -+ /* LAW registers are at offset 0xC00 */ -+ law = lac + 0xC00; -+ -+ of_node_put(np); -+ -+ np = of_find_compatible_node(NULL, NULL, "fsl,corenet-cf"); -+ if (!np) { -+ ret = -ENODEV; -+ goto error; -+ } -+ -+ iprop = of_get_property(np, "fsl,ccf-num-csdids", NULL); -+ if (!iprop) { -+ ret = -ENODEV; -+ goto error; -+ } -+ -+ num_csds = be32_to_cpup(iprop); -+ if (!num_csds) { -+ ret = -ENODEV; -+ goto error; -+ } -+ -+ ccm = of_iomap(np, 0); -+ if (!ccm) { -+ ret = -ENOMEM; -+ goto error; -+ } -+ -+ /* The undocumented CSDID registers are at offset 0x600 */ -+ csdids = ccm + 0x600; -+ -+ of_node_put(np); -+ np = NULL; -+ -+ /* Find an unused coherence subdomain ID */ -+ for (csd_id = 0; csd_id < num_csds; csd_id++) { -+ if (!csdids[csd_id]) -+ break; -+ } -+ -+ /* Store the Port ID in the (undocumented) proper CIDMRxx register */ -+ csdids[csd_id] = csd_port_id; -+ -+ /* Find the DDR LAW that maps to our buffer. */ -+ for (i = 0; i < num_laws; i++) { -+ if (law[i].lawar & LAWAR_EN) { -+ phys_addr_t law_start, law_end; -+ -+ law_start = make64(law[i].lawbarh, law[i].lawbarl); -+ law_end = law_start + -+ (2ULL << (law[i].lawar & LAWAR_SIZE_MASK)); -+ -+ if (law_start <= phys && phys < law_end) { -+ law_target = law[i].lawar & LAWAR_TARGET_MASK; -+ break; -+ } -+ } -+ } -+ -+ if (i == 0 || i == num_laws) { -+ /* This should never happen*/ -+ ret = -ENOENT; -+ goto error; -+ } -+ -+ /* Find a free LAW entry */ -+ while (law[--i].lawar & LAWAR_EN) { -+ if (i == 0) { -+ /* No higher priority LAW slots available */ -+ ret = -ENOENT; -+ goto error; -+ } -+ } -+ -+ law[i].lawbarh = upper_32_bits(phys); -+ law[i].lawbarl = lower_32_bits(phys); -+ wmb(); -+ law[i].lawar = LAWAR_EN | law_target | (csd_id << LAWAR_CSDID_SHIFT) | -+ (LAW_SIZE_4K + get_order(size)); -+ wmb(); -+ -+error: -+ if (ccm) -+ iounmap(ccm); -+ -+ if (lac) -+ iounmap(lac); -+ -+ if (np) -+ of_node_put(np); -+ -+ return ret; -+} -+#endif -+ -+/* -+ * Table of SVRs and the corresponding PORT_ID values. -+ * -+ * All future CoreNet-enabled SOCs will have this erratum fixed, so this table -+ * should never need to be updated. SVRs are guaranteed to be unique, so -+ * there is no worry that a future SOC will inadvertently have one of these -+ * values. -+ */ -+static const struct { -+ u32 svr; -+ u32 port_id; -+} port_id_map[] = { -+ {0x82100010, 0xFF000000}, /* P2040 1.0 */ -+ {0x82100011, 0xFF000000}, /* P2040 1.1 */ -+ {0x82100110, 0xFF000000}, /* P2041 1.0 */ -+ {0x82100111, 0xFF000000}, /* P2041 1.1 */ -+ {0x82110310, 0xFF000000}, /* P3041 1.0 */ -+ {0x82110311, 0xFF000000}, /* P3041 1.1 */ -+ {0x82010020, 0xFFF80000}, /* P4040 2.0 */ -+ {0x82000020, 0xFFF80000}, /* P4080 2.0 */ -+ {0x82210010, 0xFC000000}, /* P5010 1.0 */ -+ {0x82210020, 0xFC000000}, /* P5010 2.0 */ -+ {0x82200010, 0xFC000000}, /* P5020 1.0 */ -+ {0x82050010, 0xFF800000}, /* P5021 1.0 */ -+ {0x82040010, 0xFF800000}, /* P5040 1.0 */ -+}; -+ -+#define SVR_SECURITY 0x80000 /* The Security (E) bit */ -+ -+static struct of_device_id qoriq_device_config[] = { -+ { -+ .compatible = "fsl,qoriq-device-config-1.0", -+ }, -+ { -+ .compatible = "fsl,t4240-device-config", -+ }, -+ { -+ .compatible = "fsl,b4860-device-config", -+ }, -+ { -+ .compatible = "fsl,b4420-device-config", -+ }, -+ {} -+}; -+ -+static int __init fsl_pamu_probe(struct platform_device *pdev) -+{ -+ void __iomem *pamu_regs = NULL; -+ struct ccsr_guts_85xx __iomem *guts_regs = NULL; -+ u32 pamubypenr, pamu_counter; -+ unsigned long pamu_reg_off; -+ struct device_node *guts_node; -+ struct pamu_isr_data *data; -+ u64 size; -+ struct page *p; -+ int ret = 0; -+ struct ome *omt = NULL; -+ int irq; -+#ifdef CONFIG_FSL_PAMU_ERRATUM_A_004510 -+ size_t mem_size = 0; -+ unsigned int order = 0; -+ u32 csd_port_id = 0; -+ unsigned i; -+#endif -+ -+ /* -+ * enumerate all PAMUs and allocate and setup PAMU tables -+ * for each of them, -+ * NOTE : All PAMUs share the same LIODN tables. -+ */ -+ -+ pamu_regs = of_iomap(pdev->dev.of_node, 0); -+ if (!pamu_regs) { -+ dev_err(&pdev->dev, "ioremap of PAMU node failed\n"); -+ return -ENOMEM; -+ } -+ of_get_address(pdev->dev.of_node, 0, &size, NULL); -+ -+ data = kzalloc(sizeof(struct pamu_isr_data), GFP_KERNEL); -+ if (!data) { -+ iounmap(pamu_regs); -+ return -ENOMEM; -+ } -+ data->pamu_reg_base = pamu_regs; -+ data->count = size / PAMU_OFFSET; -+ -+ irq = irq_of_parse_and_map(pdev->dev.of_node, 0); -+ if (irq == NO_IRQ) { -+ dev_warn(&pdev->dev, "no interrupts listed in PAMU node\n"); -+ goto error; -+ } -+ -+ /* The ISR needs access to the regs, so we won't iounmap them */ -+ ret = request_irq(irq, pamu_av_isr, 0, "pamu", data); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "error %i installing ISR for irq %i\n", -+ ret, irq); -+ goto error; -+ } -+ -+ guts_node = of_find_matching_node(NULL, qoriq_device_config); -+ if (!guts_node) { -+ dev_err(&pdev->dev, "could not find GUTS node %s\n", -+ pdev->dev.of_node->full_name); -+ ret = -ENODEV; -+ goto error; -+ } -+ -+ guts_regs = of_iomap(guts_node, 0); -+ of_node_put(guts_node); -+ if (!guts_regs) { -+ dev_err(&pdev->dev, "ioremap of GUTS node failed\n"); -+ ret = -ENODEV; -+ goto error; -+ } -+ -+#ifdef CONFIG_FSL_PAMU_ERRATUM_A_004510 -+ /* -+ * To simplify the allocation of a coherency domain, we allocate the -+ * PAACT and the OMT in the same memory buffer. Unfortunately, this -+ * wastes more memory compared to allocating the buffers separately. -+ */ -+ -+ /* Determine how much memory we need */ -+ mem_size = (PAGE_SIZE << get_order(PAACT_SIZE)) + -+ (PAGE_SIZE << get_order(OMT_SIZE)); -+ order = get_order(mem_size); -+ -+ p = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); -+ if (!p) { -+ dev_err(&pdev->dev, "unable to allocate PAACT/OMT block\n"); -+ ret = -ENOMEM; -+ goto error; -+ } -+ -+ ppaact = page_address(p); -+ ppaact_phys = page_to_phys(p); -+ -+ /* Make sure the memory is naturally aligned */ -+ if (ppaact_phys & ((PAGE_SIZE << order) - 1)) { -+ dev_err(&pdev->dev, "PAACT/OMT block is unaligned\n"); -+ ret = -ENOMEM; -+ goto error; -+ } -+ -+ /* This assumes that PAACT_SIZE is larger than OMT_SIZE */ -+ omt = (void *)ppaact + (PAGE_SIZE << get_order(PAACT_SIZE)); -+ -+ dev_dbg(&pdev->dev, "ppaact virt=%p phys=0x%llx\n", ppaact, -+ (unsigned long long) ppaact_phys); -+ -+ dev_dbg(&pdev->dev, "omt virt=%p phys=0x%llx\n", omt, -+ (unsigned long long) virt_to_phys(omt)); -+ -+ /* Check to see if we need to implement the work-around on this SOC */ -+ -+ /* Determine the Port ID for our coherence subdomain */ -+ for (i = 0; i < ARRAY_SIZE(port_id_map); i++) { -+ if (port_id_map[i].svr == (mfspr(SPRN_SVR) & ~SVR_SECURITY)) { -+ csd_port_id = port_id_map[i].port_id; -+ dev_dbg(&pdev->dev, "found matching SVR %08x\n", -+ port_id_map[i].svr); -+ break; -+ } -+ } -+ -+ if (csd_port_id) { -+ dev_info(&pdev->dev, "implementing work-around for erratum " -+ "A-004510\n"); -+ dev_dbg(&pdev->dev, "creating coherency subdomain at address " -+ "0x%llx, size %zu, port id 0x%08x", ppaact_phys, -+ mem_size, csd_port_id); -+ -+ ret = create_csd(ppaact_phys, mem_size, csd_port_id); -+ if (ret) { -+ dev_err(&pdev->dev, "could not create coherence " -+ "subdomain\n"); -+ return ret; -+ } -+ } -+#else -+ p = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(PAACT_SIZE)); -+ if (!p) { -+ dev_err(&pdev->dev, "unable to allocate PAACT table\n"); -+ ret = -ENOMEM; -+ goto error; -+ } -+ ppaact = page_address(p); -+ ppaact_phys = page_to_phys(p); -+ -+ dev_dbg(&pdev->dev, "ppaact virt=%p phys=0x%llx\n", ppaact, -+ (unsigned long long) ppaact_phys); -+ -+ p = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(OMT_SIZE)); -+ if (!p) { -+ dev_err(&pdev->dev, "unable to allocate OMT table\n"); -+ ret = -ENOMEM; -+ goto error; -+ } -+ omt = page_address(p); -+ -+ dev_dbg(&pdev->dev, "omt virt=%p phys=0x%llx\n", omt, -+ (unsigned long long) page_to_phys(p)); -+#endif -+ -+ pamubypenr = in_be32(&guts_regs->pamubypenr); -+ -+ for (pamu_reg_off = 0, pamu_counter = 0x80000000; pamu_reg_off < size; -+ pamu_reg_off += PAMU_OFFSET, pamu_counter >>= 1) { -+ setup_one_pamu(pamu_regs + pamu_reg_off, omt); -+ -+ /* Disable PAMU bypass for this PAMU */ -+ pamubypenr &= ~pamu_counter; -+ } -+ -+ setup_omt(omt); -+ -+ /* -+ * setup all LIODNS(s) to define a 1:1 mapping for the entire -+ * 36-bit physical address space -+ */ -+ setup_liodns(); -+ mb(); -+ -+ /* Enable all relevant PAMU(s) */ -+ out_be32(&guts_regs->pamubypenr, pamubypenr); -+ -+ iounmap(guts_regs); -+ -+ return 0; -+ -+error: -+ if (irq != NO_IRQ) -+ free_irq(irq, 0); -+ -+ if (pamu_regs) -+ iounmap(pamu_regs); -+ -+ if (guts_regs) -+ iounmap(guts_regs); -+ -+#ifdef CONFIG_FSL_PAMU_ERRATUM_A_004510 -+ if (ppaact) -+ free_pages((unsigned long)ppaact, order); -+#else -+ if (ppaact) -+ free_pages((unsigned long)ppaact, get_order(PAACT_SIZE)); -+ -+ if (omt) -+ free_pages((unsigned long)omt, get_order(OMT_SIZE)); -+#endif -+ -+ ppaact = NULL; -+ ppaact_phys = 0; -+ -+ return ret; -+} -+ -+static struct platform_driver fsl_of_pamu_driver = { -+ .driver = { -+ .name = "fsl-of-pamu", -+ .owner = THIS_MODULE, -+ }, -+ .probe = fsl_pamu_probe, -+}; -+ -+static bool is_fsl_hypervisor(void) -+{ -+ struct device_node *np; -+ struct property *prop; -+ -+ np = of_find_node_by_path("/hypervisor"); -+ if (!np) -+ return false; -+ -+ prop = of_find_property(np, "fsl,has-stash-attr-hcall", NULL); -+ of_node_put(np); -+ -+ if (!prop) -+ pr_notice("fsl-pamu: this hypervisor does not support the " -+ "stash attribute hypercall\n"); -+ -+ return !!prop; -+} -+ -+static __init int fsl_pamu_init(void) -+{ -+ struct platform_device *pdev = NULL; -+ struct device_node *np; -+ int ret; -+ -+ /* -+ * The normal OF process calls the probe function at some -+ * indeterminate later time, after most drivers have loaded. This is -+ * too late for us, because PAMU clients (like the Qman driver) -+ * depend on PAMU being initialized early. -+ * -+ * So instead, we "manually" call our probe function by creating the -+ * platform devices ourselves. -+ */ -+ -+ /* -+ * We assume that there is only one PAMU node in the device tree. A -+ * single PAMU node represents all of the PAMU devices in the SOC -+ * already. Everything else already makes that assumption, and the -+ * binding for the PAMU nodes doesn't allow for any parent-child -+ * relationships anyway. In other words, support for more than one -+ * PAMU node would require significant changes to a lot of code. -+ */ -+ -+ np = of_find_compatible_node(NULL, NULL, "fsl,pamu"); -+ if (!np) { -+ /* No PAMU nodes, so check for a hypervisor */ -+ if (is_fsl_hypervisor()) { -+ has_fsl_hypervisor = true; -+ /* Remain resident, but we don't need a platform */ -+ return 0; -+ } -+ -+ pr_err("fsl-pamu: could not find a PAMU node\n"); -+ return -ENODEV; -+ } -+ -+ ret = platform_driver_register(&fsl_of_pamu_driver); -+ if (ret) { -+ pr_err("fsl-pamu: could not register driver (err=%i)\n", ret); -+ goto error_driver_register; -+ } -+ -+ pdev = platform_device_alloc("fsl-of-pamu", 0); -+ if (!pdev) { -+ pr_err("fsl-pamu: could not allocate device %s\n", -+ np->full_name); -+ ret = -ENOMEM; -+ goto error_device_alloc; -+ } -+ pdev->dev.of_node = of_node_get(np); -+ -+ ret = platform_device_add(pdev); -+ if (ret) { -+ pr_err("fsl-pamu: could not add device %s (err=%i)\n", -+ np->full_name, ret); -+ goto error_device_add; -+ } -+ -+ return 0; -+ -+error_device_add: -+ of_node_put(pdev->dev.of_node); -+ pdev->dev.of_node = NULL; -+ -+ platform_device_put(pdev); -+ -+error_device_alloc: -+ platform_driver_unregister(&fsl_of_pamu_driver); -+ -+error_driver_register: -+ of_node_put(np); -+ -+ return ret; -+} -+ -+arch_initcall(fsl_pamu_init); -diff --git a/arch/powerpc/sysdev/fsl_pamu.h b/arch/powerpc/sysdev/fsl_pamu.h -new file mode 100644 -index 0000000..b816812 ---- /dev/null -+++ b/arch/powerpc/sysdev/fsl_pamu.h -@@ -0,0 +1,58 @@ -+/* Copyright (c) 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_PAMU_H -+#define FSL_PAMU_H -+ -+#ifdef CONFIG_FSL_PAMU -+ -+/* Set the stash target for a given LIODN */ -+int pamu_set_stash_dest(struct device_node *node, unsigned int index, -+ unsigned int cpu, unsigned int cache_level); -+ -+int pamu_get_liodn_count(struct device_node *node); -+ -+#else -+ -+static inline int pamu_set_stash_dest(struct device_node *node, unsigned int index, -+ unsigned int cpu, unsigned int cache_level) -+{ -+ return -ENOSYS; -+} -+ -+static inline int pamu_get_liodn_count(struct device_node *node) -+{ -+ return 0; -+} -+ -+#endif -+ -+#endif -diff --git a/drivers/Kconfig b/drivers/Kconfig -index b5e6f24..e458b8e 100644 ---- a/drivers/Kconfig -+++ b/drivers/Kconfig -@@ -136,4 +136,6 @@ source "drivers/hv/Kconfig" - - source "drivers/devfreq/Kconfig" - -+source "drivers/net/dpa/NetCommSw/Kconfig" -+ - endmenu -diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c -new file mode 100644 -index 0000000..74de0b5 ---- /dev/null -+++ b/drivers/mmc/host/sdhci-of-core.c -@@ -0,0 +1,274 @@ -+/* -+ * OpenFirmware bindings for Secure Digital Host Controller Interface. -+ * -+ * Copyright (c) 2007, 2011 Freescale Semiconductor, Inc. -+ * Copyright (c) 2009 MontaVista Software, Inc. -+ * -+ * Authors: Xiaobo Xie -+ * Anton Vorontsov -+ * -+ * 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 -+#ifdef CONFIG_PPC -+#include -+#endif -+#include "sdhci-of.h" -+#include "sdhci.h" -+ -+#ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER -+ -+/* -+ * These accessors are designed for big endian hosts doing I/O to -+ * little endian controllers incorporating a 32-bit hardware byte swapper. -+ */ -+ -+u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg) -+{ -+ return in_be32(host->ioaddr + reg); -+} -+ -+u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg) -+{ -+ return in_be16(host->ioaddr + (reg ^ 0x2)); -+} -+ -+u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg) -+{ -+ return in_8(host->ioaddr + (reg ^ 0x3)); -+} -+ -+void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg) -+{ -+ out_be32(host->ioaddr + reg, val); -+} -+ -+void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg) -+{ -+ struct sdhci_of_host *of_host = sdhci_priv(host); -+ int base = reg & ~0x3; -+ int shift = (reg & 0x2) * 8; -+ -+ switch (reg) { -+ case SDHCI_TRANSFER_MODE: -+ /* -+ * Postpone this write, we must do it together with a -+ * command write that is down below. -+ */ -+ of_host->xfer_mode_shadow = val; -+ return; -+ case SDHCI_COMMAND: -+ sdhci_be32bs_writel(host, val << 16 | of_host->xfer_mode_shadow, -+ SDHCI_TRANSFER_MODE); -+ return; -+ } -+ clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift); -+} -+ -+void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg) -+{ -+ int base = reg & ~0x3; -+ int shift = (reg & 0x3) * 8; -+ -+ clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift); -+} -+#endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */ -+ -+#ifdef CONFIG_PM -+ -+static int sdhci_of_suspend(struct platform_device *ofdev, pm_message_t state) -+{ -+ struct sdhci_host *host = dev_get_drvdata(&ofdev->dev); -+ -+ return mmc_suspend_host(host->mmc); -+} -+ -+static int sdhci_of_resume(struct platform_device *ofdev) -+{ -+ struct sdhci_host *host = dev_get_drvdata(&ofdev->dev); -+ -+ return mmc_resume_host(host->mmc); -+} -+ -+#else -+ -+#define sdhci_of_suspend NULL -+#define sdhci_of_resume NULL -+ -+#endif -+ -+static bool __devinit sdhci_of_wp_inverted(struct device_node *np) -+{ -+ if (of_get_property(np, "sdhci,wp-inverted", NULL)) -+ return true; -+ -+ /* Old device trees don't have the wp-inverted property. */ -+#ifdef CONFIG_PPC -+ return machine_is(mpc837x_rdb) || machine_is(mpc837x_mds); -+#else -+ return false; -+#endif -+} -+ -+static const struct of_device_id sdhci_of_match[]; -+static int __devinit sdhci_of_probe(struct platform_device *ofdev) -+{ -+ const struct of_device_id *match; -+ struct device_node *np = ofdev->dev.of_node; -+ struct sdhci_of_data *sdhci_of_data; -+ struct sdhci_host *host; -+ struct sdhci_of_host *of_host; -+ const __be32 *clk; -+ int size; -+ int ret; -+ -+ match = of_match_device(sdhci_of_match, &ofdev->dev); -+ if (!match) -+ return -EINVAL; -+ sdhci_of_data = match->data; -+ -+ if (!of_device_is_available(np)) -+ return -ENODEV; -+ -+ host = sdhci_alloc_host(&ofdev->dev, sizeof(*of_host)); -+ if (IS_ERR(host)) -+ return -ENOMEM; -+ -+ of_host = sdhci_priv(host); -+ dev_set_drvdata(&ofdev->dev, host); -+ -+ host->ioaddr = of_iomap(np, 0); -+ if (!host->ioaddr) { -+ ret = -ENOMEM; -+ goto err_addr_map; -+ } -+ -+ host->irq = irq_of_parse_and_map(np, 0); -+ if (!host->irq) { -+ ret = -EINVAL; -+ goto err_no_irq; -+ } -+ -+ host->hw_name = dev_name(&ofdev->dev); -+ if (sdhci_of_data) { -+ host->quirks = sdhci_of_data->quirks; -+ host->ops = &sdhci_of_data->ops; -+ } -+ -+ if (of_get_property(np, "sdhci,auto-cmd12", NULL)) -+ host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; -+ -+ -+ if (of_get_property(np, "sdhci,1-bit-only", NULL)) -+ host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; -+ -+ if (sdhci_of_wp_inverted(np)) -+ host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT; -+ -+ if (of_device_is_compatible(np, "fsl,esdhc")) -+ host->quirks |= SDHCI_QUIRK_QORIQ_PROCTL_WEIRD; -+ -+ if (of_device_is_compatible(np, "fsl,p4080-esdhc")) -+ host->quirks |= SDHCI_QUIRK_QORIQ_HOSTCAPBLT_ONLY_VS33; -+ -+ if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc")) -+ host->quirks |= SDHCI_QUIRK_BROKEN_DMA; -+ -+ if (of_device_is_compatible(np, "fsl,p2020-esdhc") || -+ of_device_is_compatible(np, "fsl,p1010-esdhc") || -+ of_device_is_compatible(np, "fsl,t4240-esdhc") || -+ of_device_is_compatible(np, "fsl,mpc8536-esdhc")) -+ host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; -+ -+ if (of_device_is_compatible(np, "fsl,t4240-esdhc")) { -+ host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; -+ host->quirks |= SDHCI_QUIRK_QORIQ_CIRCUIT_SUPPORT_VS33; -+ host->quirks |= SDHCI_QUIRK_LONG_TIME_CMD_COMPLETE_IRQ; -+ } -+ -+ clk = of_get_property(np, "clock-frequency", &size); -+ if (clk && size == sizeof(*clk) && *clk) -+ of_host->clock = be32_to_cpup(clk); -+ -+ ret = sdhci_add_host(host); -+ if (ret) -+ goto err_add_host; -+ -+ return 0; -+ -+err_add_host: -+ irq_dispose_mapping(host->irq); -+err_no_irq: -+ iounmap(host->ioaddr); -+err_addr_map: -+ sdhci_free_host(host); -+ return ret; -+} -+ -+static int __devexit sdhci_of_remove(struct platform_device *ofdev) -+{ -+ struct sdhci_host *host = dev_get_drvdata(&ofdev->dev); -+ -+ sdhci_remove_host(host, 0); -+ sdhci_free_host(host); -+ irq_dispose_mapping(host->irq); -+ iounmap(host->ioaddr); -+ return 0; -+} -+ -+static const struct of_device_id sdhci_of_match[] = { -+#ifdef CONFIG_MMC_SDHCI_OF_ESDHC -+ { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, }, -+ { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, }, -+ { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, }, -+#endif -+#ifdef CONFIG_MMC_SDHCI_OF_HLWD -+ { .compatible = "nintendo,hollywood-sdhci", .data = &sdhci_hlwd, }, -+#endif -+ { .compatible = "generic-sdhci", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, sdhci_of_match); -+ -+static struct platform_driver sdhci_of_driver = { -+ .driver = { -+ .name = "sdhci-of", -+ .owner = THIS_MODULE, -+ .of_match_table = sdhci_of_match, -+ }, -+ .probe = sdhci_of_probe, -+ .remove = __devexit_p(sdhci_of_remove), -+ .suspend = sdhci_of_suspend, -+ .resume = sdhci_of_resume, -+}; -+ -+static int __init sdhci_of_init(void) -+{ -+ return platform_driver_register(&sdhci_of_driver); -+} -+module_init(sdhci_of_init); -+ -+static void __exit sdhci_of_exit(void) -+{ -+ platform_driver_unregister(&sdhci_of_driver); -+} -+module_exit(sdhci_of_exit); -+ -+MODULE_DESCRIPTION("Secure Digital Host Controller Interface OF driver"); -+MODULE_AUTHOR("Xiaobo Xie , " -+ "Anton Vorontsov "); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig -index 99aa7fa..c1384c7 100644 ---- a/drivers/net/Kconfig -+++ b/drivers/net/Kconfig -@@ -340,4 +340,99 @@ config VMXNET3 - - source "drivers/net/hyperv/Kconfig" - -+config DPA -+ bool "Freescale Data Path Frame Manager Ethernet" -+ depends on FSL_SOC && FSL_BMAN && FSL_QMAN && FSL_FMAN && LIBFCOE=n -+ select PHYLIB -+ -+config DPA_OFFLINE_PORTS -+ bool "Offline Ports support" -+ depends on DPA -+ 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 DPAA_ETH_SG_SUPPORT -+ bool -+ -+choice DPAA_ETH_OPTIMIZE -+ prompt "Optimization choices for the DPAA Ethernet driver" -+ depends on DPA -+ default DPAA_ETH_OPTIMIZE_FOR_IPFWD -+ -+ ---help--- -+ Compile-time switch between driver optimizations for forwarding use-cases and -+ termination scenarios. -+ -+ config DPAA_ETH_OPTIMIZE_FOR_IPFWD -+ bool "Optimize for forwarding" -+ select DPA_TX_RECYCLE if FMAN_T4240 -+ help -+ Optimize the DPAA-Ethernet driver for IP/IPSec forwarding use-cases. -+ -+ config DPAA_ETH_OPTIMIZE_FOR_TERM -+ bool "Optimize for termination" -+ select DPAA_ETH_SG_SUPPORT -+ help -+ Optimize the DPAA-Ethernet driver for termination (TCP, UDP) use-cases. -+ In particular, this choice enables Scatter-Gather (SG) support -+ in the driver, which is momentarily not accessible otherwise. -+ -+endchoice -+ -+config DPA_TX_RECYCLE -+ bool -+ depends on FMAN_T4240 -+ -+config FSL_DPA_1588 -+ tristate "IEEE 1588-compliant timestamping" -+ depends on DPA -+ default n -+ -+choice DPA_ETH_WQ_ASSIGN -+ prompt "WorkQueue assignment scheme for FrameQueues" -+ depends on DPA -+ default DPA_ETH_WQ_MULTI -+ help -+ Selects the FrameQueue to WorkQueue assignment scheme. -+ -+ config DPA_ETH_WQ_LEGACY -+ bool "Legacy WQ assignment" -+ help -+ Statically-defined FQIDs are round-robin assigned to all WQs (0..7). PCD queues are always -+ in this category. Other frame queues may be those used for "MAC-less" or "shared MAC" configurations -+ of the driver. -+ Dynamically-defined FQIDs all go to WQ7. -+ config DPA_ETH_WQ_MULTI -+ bool "Multi-WQ assignment" -+ help -+ Tx Confirmation FQs go to WQ1. -+ Rx Default, Tx and PCD FQs go to WQ3. -+ Rx Error and Tx Error FQs go to WQ2. -+endchoice -+ -+config DPAA_ETH_USE_NDO_SELECT_QUEUE -+ bool "Use driver's Tx queue selection mechanism" -+ default y -+ ---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 DPAA_ETH_UNIT_TESTS -+ bool "Run Unit Tests for DPAA Ethernet" -+ depends on DPA -+ default y -+ - endif # NETDEVICES -diff --git a/drivers/net/Makefile b/drivers/net/Makefile -index a81192b..435771c 100644 ---- a/drivers/net/Makefile -+++ b/drivers/net/Makefile -@@ -57,6 +57,8 @@ obj-$(CONFIG_VMXNET3) += vmxnet3/ - obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o - obj-$(CONFIG_XEN_NETDEV_BACKEND) += xen-netback/ - -+obj-$(if $(CONFIG_DPA),y) += dpa/ -+ - obj-$(CONFIG_USB_CATC) += usb/ - obj-$(CONFIG_USB_KAWETH) += usb/ - obj-$(CONFIG_USB_PEGASUS) += usb/ -diff --git a/drivers/net/dpa/Makefile b/drivers/net/dpa/Makefile -new file mode 100644 -index 0000000..0e59076 ---- /dev/null -+++ b/drivers/net/dpa/Makefile -@@ -0,0 +1,21 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+ -+EXTRA_CFLAGS += -I$(NET_DPA) -+ -+#Netcomm SW tree -+obj-$(CONFIG_FSL_FMAN) += NetCommSw/ -+obj-$(CONFIG_FSL_DPA_1588) += dpaa_1588.o -+obj-$(CONFIG_DPAA_ETH_SG_SUPPORT) += fsl-dpa-sg.o -+obj-$(CONFIG_DPA) += fsl-mac.o fsl-dpa.o -+obj-$(CONFIG_DPA_OFFLINE_PORTS) += fsl-oh.o -+ -+fsl-dpa-objs := dpa-ethtool.o dpaa_eth.o dpaa_eth_sysfs.o xgmac_mdio.o memac_mdio.o -+fsl-dpa-sg-objs := dpaa_eth_sg.o -+fsl-mac-objs := mac.o mac-api.o -+fsl-oh-objs := offline_port.o -diff --git a/drivers/net/dpa/NetCommSw/Kconfig b/drivers/net/dpa/NetCommSw/Kconfig -new file mode 100644 -index 0000000..e640465 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Kconfig -@@ -0,0 +1,112 @@ -+menu "Frame Manager support" -+ -+menuconfig FSL_FMAN -+ bool "Freescale Frame Manager (datapath) support" -+ # depends on PPC_E500MC -+ default y -+ ---help--- -+ If unsure, say Y. -+ -+if FSL_FMAN -+ -+config FSL_FMAN_TEST -+ bool "FMan test module" -+ default n -+ ---help--- -+ This option compiles test code for FMan. -+ -+menu "FMAN Processor support" -+choice -+ depends on FSL_FMAN -+ prompt "Processor Type" -+ -+config FMAN_P3040_P4080_P5020 -+ bool "P3040 P4080 5020" -+ -+config FMAN_P1023 -+ bool "P1023" -+ -+config FMAN_T4240 -+ bool "T4240" -+ -+endchoice -+endmenu -+ -+config FMAN_RESOURCE_ALLOCATION_ALGORITHM -+ bool "Enable FMan dynamic resource allocation algorithm" -+ default n -+ ---help--- -+ Enables algorithm for dynamic resource allocation -+ -+config FMAN_DISABLE_OH_TO_REUSE_RESOURCES -+ depends on FMAN_RESOURCE_ALLOCATION_ALGORITHM -+ bool "Disable offline parsing ports to reuse resources" -+ default n -+ ---help--- -+ Redistributes FMan OH's resources to all other ports, -+ thus enabling other configurations. -+ -+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_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 accomodate 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_FMAN -+ range 0 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 option does not affect in any way the layout of -+ transmitted buffers. You may be required to enable the config -+ option FMAN_RESOURCE_ALLOCATION_ALGORITHM and also -+ FMAN_DISABLE_OH_TO_REUSE_RESOURCES to have enough resources -+ when using this option and also supporting jumbo frames. -+ -+ 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. -+ -+endif # FSL_FMAN -+ -+endmenu -diff --git a/drivers/net/dpa/NetCommSw/Makefile b/drivers/net/dpa/NetCommSw/Makefile -new file mode 100644 -index 0000000..c21d5a5 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Makefile -@@ -0,0 +1,11 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+# -+obj-y += etc/ -+obj-y += Peripherals/FM/ -+obj-y += src/ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/HC/Makefile b/drivers/net/dpa/NetCommSw/Peripherals/FM/HC/Makefile -new file mode 100644 -index 0000000..3ec3824 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/HC/Makefile -@@ -0,0 +1,15 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+ -+NCSW_FM_INC = $(srctree)/drivers/net/dpa/NetCommSw/Peripherals/FM/inc -+ -+EXTRA_CFLAGS += -I$(NCSW_FM_INC) -+ -+obj-y += fsl-ncsw-Hc.o -+ -+fsl-ncsw-Hc-objs := hc.o -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/HC/hc.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/HC/hc.c -new file mode 100644 -index 0000000..dca9478 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/HC/hc.c -@@ -0,0 +1,1191 @@ -+/* -+ * 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_CAPWAP_REASSM_TIMEOUT 0x5 -+#define HC_HCOR_OPCODE_CC_IP_REASSM_TIMEOUT 0x10 -+#define HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION 0x11 -+#define HC_HCOR_ACTION_REG_IP_REASSM_TIMEOUT_ACTIVE_SHIFT 24 -+#define HC_HCOR_EXTRA_REG_IP_REASSM_TIMEOUT_TSBS_SHIFT 24 -+#define HC_HCOR_ACTION_REG_IP_REASSM_TIMEOUT_RES_SHIFT 16 -+#define HC_HCOR_ACTION_REG_IP_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 _Packed struct t_FmPcdKgPortRegs { -+ volatile uint32_t spReg; -+ volatile uint32_t cppReg; -+} _PackedType t_FmPcdKgPortRegs; -+ -+typedef _Packed 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_FmPcdCcIpReassmTimeoutParams ccIpReassmTimeout; -+ } hcSpecificData; -+} _PackedType 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; -+ } -+ -+ /* 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; -+} -+ -+t_Handle FmGcGetHcPortDevH(t_Handle h_FmHc) -+{ -+ t_FmHc *p_FmHc = (t_FmHc *)h_FmHc; -+ -+ return (p_FmHc) ? p_FmHc->h_HcPortDev : NULL; -+} -+ -+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); -+} -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+t_Error FmHcDumpRegs(t_Handle h_FmHc) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmHc->h_HcPortDev, E_INVALID_HANDLE); -+ -+ return FM_PORT_DumpRegs(p_FmHc->h_HcPortDev); -+ -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+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 (!FmPcdKgGetPointedOwners(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; -+ uint32_t i; -+ 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; -+ memcpy((void*)&p_HcFrame->hcSpecificData.clsPlanEntries, (void *)&p_Set->vectors[i-p_Set->baseEntry], 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) -+ 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 FmHcPcdCcIpTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcIpReassmTimeoutParams *p_CcIpReassmTimeoutParams, 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_IP_REASSM_TIMEOUT); -+ p_HcFrame->actionReg = (uint32_t)((p_CcIpReassmTimeoutParams->activate ? 0 : 1) << HC_HCOR_ACTION_REG_IP_REASSM_TIMEOUT_ACTIVE_SHIFT); -+ p_HcFrame->extraReg = (p_CcIpReassmTimeoutParams->tsbs << HC_HCOR_EXTRA_REG_IP_REASSM_TIMEOUT_TSBS_SHIFT) | p_CcIpReassmTimeoutParams->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_IP_REASSM_TIMEOUT_RES_SHIFT) & HC_HCOR_ACTION_REG_IP_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, pointedOwnersTmp; -+ 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); -+ pointedOwnersTmp = FmPcdPlcrGetPointedOwners(p_FmHc->h_FmPcd, absoluteProfileId); -+ -+ if (!pointedOwnersTmp || !(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; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/Makefile b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/Makefile -new file mode 100644 -index 0000000..629949c ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/Makefile -@@ -0,0 +1,20 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+NCSW_FM_INC = $(srctree)/drivers/net/dpa/NetCommSw/Peripherals/FM/inc -+ -+EXTRA_CFLAGS += -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_T4240),y) -+fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o -+endif -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/dtsec.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/dtsec.c -new file mode 100644 -index 0000000..e4cb509 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/dtsec.c -@@ -0,0 +1,1513 @@ -+/* -+ * 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 dtsec.c -+ -+ @Description FM dTSEC ... -+*//***************************************************************************/ -+ -+#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" -+ -+ -+/*****************************************************************************/ -+/* 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; -+ -+ 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 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 = dtsec_get_event(p_DtsecMemMap, (uint32_t)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN))); -+ -+ event &= dtsec_get_interrupt_mask(p_DtsecMemMap); -+ -+ 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 = 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) -+{ -+ /*TODO - need to ask why with mdioIrq != 0*/ -+ if ((p_Dtsec->mdioIrq != 0) && (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) -+ { -+ 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 */ -+ 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) -+ dtsec_start_tx(p_MemMap); -+ -+ if (mode & e_COMM_MODE_RX) -+ 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")); -+ switch (exception){ -+ case (e_FM_MAC_EX_1G_1588_TS_RX_ERR): -+ if (enable) -+ p_Dtsec->enTsuErrExeption = TRUE; -+ else -+ p_Dtsec->enTsuErrExeption = FALSE; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ } -+ } -+ 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); -+ -+ 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); -+ -+ 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 (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 */ -+ -+ dtsec_set_tx_pause_time(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); -+ -+ 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; -+ 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; -+ 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 = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR64) -+ + p_Dtsec->internalStatistics.tr64; -+ p_Statistics->eStatPkts65to127 = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR127) -+ + p_Dtsec->internalStatistics.tr127; -+ p_Statistics->eStatPkts128to255 = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR255) -+ + p_Dtsec->internalStatistics.tr255; -+ p_Statistics->eStatPkts256to511 = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR511) -+ + p_Dtsec->internalStatistics.tr511; -+ p_Statistics->eStatPkts512to1023 = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR1K) -+ + p_Dtsec->internalStatistics.tr1k; -+ p_Statistics->eStatPkts1024to1518 = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMAX) -+ + p_Dtsec->internalStatistics.trmax; -+ p_Statistics->eStatPkts1519to1522 = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMGV) -+ + p_Dtsec->internalStatistics.trmgv; -+ -+ /* MIB II */ -+ p_Statistics->ifInOctets = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBYT) -+ + p_Dtsec->internalStatistics.rbyt; -+ p_Statistics->ifInPkts = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RPKT) -+ + p_Dtsec->internalStatistics.rpkt; -+ p_Statistics->ifInUcastPkts = 0; -+ p_Statistics->ifInMcastPkts = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RMCA) -+ + p_Dtsec->internalStatistics.rmca; -+ p_Statistics->ifInBcastPkts = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBCA) -+ + p_Dtsec->internalStatistics.rbca; -+ p_Statistics->ifOutOctets = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBYT) -+ + p_Dtsec->internalStatistics.tbyt; -+ p_Statistics->ifOutPkts = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TPKT) -+ + p_Dtsec->internalStatistics.tpkt; -+ p_Statistics->ifOutUcastPkts = 0; -+ p_Statistics->ifOutMcastPkts = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TMCA) -+ + p_Dtsec->internalStatistics.tmca; -+ p_Statistics->ifOutBcastPkts = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBCA) -+ + p_Dtsec->internalStatistics.tbca; -+ } -+ -+ p_Statistics->eStatFragments = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RFRG) -+ + p_Dtsec->internalStatistics.rfrg; -+ p_Statistics->eStatJabbers = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RJBR) -+ + p_Dtsec->internalStatistics.rjbr; -+ p_Statistics->eStatsDropEvents = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RDRP) -+ + p_Dtsec->internalStatistics.rdrp; -+ p_Statistics->eStatCRCAlignErrors = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RALN) -+ + p_Dtsec->internalStatistics.raln; -+ p_Statistics->eStatUndersizePkts = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RUND) -+ + p_Dtsec->internalStatistics.rund; -+ p_Statistics->eStatOversizePkts = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_ROVR) -+ + p_Dtsec->internalStatistics.rovr; -+ p_Statistics->reStatPause = dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RXPF) -+ + p_Dtsec->internalStatistics.rxpf; -+ p_Statistics->teStatPause = 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 -+ + dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RFLR) + p_Dtsec->internalStatistics.rflr -+ + dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCDE) + p_Dtsec->internalStatistics.rcde -+ + dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCSE) + p_Dtsec->internalStatistics.rcse; -+ -+ p_Statistics->ifOutDiscards = 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: */ -+ + 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); -+ 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 */ -+ 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 */ -+ 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 */ -+ 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)((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; -+ } -+ -+ 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)((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])) -+ 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])) -+ dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE); -+ } -+ -+ /* address does not exist */ -+ ASSERT_COND(p_HashEntry != NULL); -+ -+ return E_OK; -+} -+ -+void DtsecRestartTbiAN(t_Handle h_Dtsec) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ if (!p_Dtsec) -+ return; -+ -+ DTSEC_MII_WritePhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, -+ PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1); -+} -+ -+/* .............................................................................. */ -+ -+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); -+ -+ dtsec_set_uc_promisc(p_Dtsec->p_MemMap, newVal); -+ 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)dtsec_set_stat_level(p_Dtsec->p_MemMap, -+ (enum mac_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 DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ t_Error 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 = (t_Error)dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex); -+ -+ if (err == E_CONFLICT) -+ RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode")); -+ -+ return 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_RESET_AN); -+ 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 = 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) -+ dtsec_enable_interrupt(p_Dtsec->p_MemMap, bitMask); -+ else -+ dtsec_disable_interrupt(p_Dtsec->p_MemMap, bitMask); -+ } -+ else -+ { -+ if (!p_Dtsec->ptpTsuEnabled) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only")); -+ switch (exception) -+ { -+ case (e_FM_MAC_EX_1G_1588_TS_RX_ERR): -+ if (enable) -+ { -+ p_Dtsec->enTsuErrExeption = TRUE; -+ dtsec_enable_tmr_interrupt(p_Dtsec->p_MemMap); -+ } else { -+ p_Dtsec->enTsuErrExeption = FALSE; -+ dtsec_disable_tmr_interrupt(p_Dtsec->p_MemMap); -+ } -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ } -+ } -+ -+ return E_OK; -+} -+ -+ -+ -+/* ........................................................................... */ -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+static t_Error DtsecDumpRegs(t_Handle h_Dtsec) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ int i = 0; -+ -+ DECLARE_DUMP; -+ -+ if (p_Dtsec->p_MemMap) -+ { -+ -+ DUMP_TITLE(p_Dtsec->p_MemMap, ("dTSEC %d: ", p_Dtsec->macId)); -+ DUMP_VAR(p_Dtsec->p_MemMap, tsec_id); -+ DUMP_VAR(p_Dtsec->p_MemMap, tsec_id2); -+ DUMP_VAR(p_Dtsec->p_MemMap, ievent); -+ DUMP_VAR(p_Dtsec->p_MemMap, imask); -+ DUMP_VAR(p_Dtsec->p_MemMap, ecntrl); -+ DUMP_VAR(p_Dtsec->p_MemMap, ptv); -+ DUMP_VAR(p_Dtsec->p_MemMap, tmr_ctrl); -+ DUMP_VAR(p_Dtsec->p_MemMap, tmr_pevent); -+ DUMP_VAR(p_Dtsec->p_MemMap, tmr_pemask); -+ DUMP_VAR(p_Dtsec->p_MemMap, tctrl); -+ DUMP_VAR(p_Dtsec->p_MemMap, rctrl); -+ DUMP_VAR(p_Dtsec->p_MemMap, maccfg1); -+ DUMP_VAR(p_Dtsec->p_MemMap, maccfg2); -+ DUMP_VAR(p_Dtsec->p_MemMap, ipgifg); -+ DUMP_VAR(p_Dtsec->p_MemMap, hafdup); -+ DUMP_VAR(p_Dtsec->p_MemMap, maxfrm); -+ -+ DUMP_VAR(p_Dtsec->p_MemMap, macstnaddr1); -+ DUMP_VAR(p_Dtsec->p_MemMap, macstnaddr2); -+ -+ DUMP_SUBSTRUCT_ARRAY(i, 8) -+ { -+ DUMP_VAR(p_Dtsec->p_MemMap, macaddr[i].exact_match1); -+ DUMP_VAR(p_Dtsec->p_MemMap, macaddr[i].exact_match2); -+ } -+ DUMP_VAR(p_Dtsec->p_MemMap, car1); -+ DUMP_VAR(p_Dtsec->p_MemMap, car2); -+ } -+ -+ return E_OK; -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ -+/*****************************************************************************/ -+/* 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)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")); -+ } -+ -+ DTSEC_MII_Init(h_Dtsec); -+ -+ 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 = 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); -+ -+ 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); -+ -+ FreeInitResources(p_Dtsec); -+ -+ if (p_Dtsec->p_DtsecDriverParam) -+ { -+ XX_Free(p_Dtsec->p_DtsecDriverParam); -+ p_Dtsec->p_DtsecDriverParam = NULL; -+ } -+ XX_Free (h_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_SetException = DtsecSetException; -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous; -+ p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink; -+ 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; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ p_FmMacControllerDriver->f_FM_MAC_DumpRegs = DtsecDumpRegs; -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+} -+ -+ -+/*****************************************************************************/ -+/* 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; -+ -+ 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; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/dtsec.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/dtsec.h -new file mode 100644 -index 0000000..01296dd ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/dtsec.h -@@ -0,0 +1,245 @@ -+/* -+ * 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 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 -+ -+/* 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_CLK_SEL 0x0020 -+ -+#define PHY_TBIANA_SGMII 0x4001 -+#define PHY_TBIANA_1000X 0x01a0 -+ -+ -+/* 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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/dtsec_mii_acc.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/dtsec_mii_acc.c -new file mode 100644 -index 0000000..371e1f9 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/dtsec_mii_acc.c -@@ -0,0 +1,109 @@ -+/* -+ * 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 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; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE); -+ -+ miiregs = p_Dtsec->p_MiiMemMap; -+ -+ err = (t_Error)dtsec_mii_write_reg(miiregs, phyAddr, reg, data); -+ -+ 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; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE); -+ -+ miiregs = p_Dtsec->p_MiiMemMap; -+ -+ err = (t_Error)dtsec_mii_read_reg(miiregs, phyAddr, reg, p_Data); -+ -+ 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, err, NO_MSG); -+ -+ return err; -+} -+ -+t_Error DTSEC_MII_Init(t_Handle h_Dtsec) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ struct dtsec_mii_reg *miiregs; -+ uint16_t dtsec_freq; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE); -+ -+ miiregs = p_Dtsec->p_MiiMemMap; -+ dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1); -+ -+ dtsec_mii_init(miiregs, dtsec_freq); -+ -+ return E_OK; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/dtsec_mii_acc.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/dtsec_mii_acc.h -new file mode 100644 -index 0000000..d5dd39a ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/dtsec_mii_acc.h -@@ -0,0 +1,45 @@ -+/* -+ * 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 __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); -+t_Error DTSEC_MII_Init(t_Handle h_Dtsec); -+ -+ -+#endif /* __DTSEC_MII_ACC_H */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fm_mac.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fm_mac.c -new file mode 100644 -index 0000000..e2deaa2 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fm_mac.c -@@ -0,0 +1,628 @@ -+/* -+ * 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; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_INVALID_HANDLE, 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; -+ -+ if ((p_FmMacControllerDriver->clkFreq = FmGetClockFreq(p_FmMacControllerDriver->h_Fm)) == 0) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Can't get clock for MAC!")); -+ return NULL; -+ } -+ -+ 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_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(MINOR, 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_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) && ... */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fm_mac.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fm_mac.h -new file mode 100644 -index 0000000..94f7b09 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fm_mac.h -@@ -0,0 +1,222 @@ -+/* -+ * 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_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_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(size*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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_crc32.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_crc32.c -new file mode 100644 -index 0000000..b6a4ca2 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_crc32.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_crc32.h -new file mode 100644 -index 0000000..6e32fdc ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_dtsec.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_dtsec.c -new file mode 100644 -index 0000000..2ba8554 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_dtsec.c -@@ -0,0 +1,818 @@ -+/* -+ * 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 dtsec_stop_rx(struct dtsec_regs *regs) -+{ -+ /* Assert the graceful stop bit */ -+ iowrite32be(ioread32be(®s->rctrl) | RCTRL_GRS, ®s->rctrl); -+} -+ -+void dtsec_stop_tx(struct dtsec_regs *regs) -+{ -+ /* Assert the graceful stop bit */ -+ iowrite32be(ioread32be(®s->tctrl) | DTSEC_TCTRL_GTS, ®s->tctrl); -+} -+ -+void dtsec_start_tx(struct dtsec_regs *regs) -+{ -+ /* clear the graceful stop bit */ -+ iowrite32be(ioread32be(®s->tctrl) & ~DTSEC_TCTRL_GTS, ®s->tctrl); -+} -+ -+void dtsec_start_rx(struct dtsec_regs *regs) -+{ -+ /* clear the graceful stop bit */ -+ iowrite32be(ioread32be(®s->rctrl) & ~RCTRL_GRS, ®s->rctrl); -+} -+ -+void 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; -+} -+ -+int 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 = 0; -+ 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]); -+ } -+ -+ dtsec_reset_stat(regs); -+ -+ return 0; -+} -+ -+uint16_t dtsec_get_max_frame_len(struct dtsec_regs *regs) -+{ -+ return (uint16_t)ioread32be(®s->maxfrm); -+} -+ -+void dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length) -+{ -+ iowrite32be(length, ®s->maxfrm); -+} -+ -+void 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 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 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 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 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; -+} -+ -+int dtsec_adjust_link(struct dtsec_regs *regs, -+ enum enet_interface iface_mode, -+ enum enet_speed speed, bool full_dx) -+{ -+ uint32_t tmp; -+ -+ 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 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 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 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 dtsec_reset_stat(struct dtsec_regs *regs) -+{ -+ /* clear HW counters */ -+ iowrite32be(ioread32be(®s->ecntrl) | -+ DTSEC_ECNTRL_CLRCNT, ®s->ecntrl); -+} -+ -+int dtsec_set_stat_level(struct dtsec_regs *regs, enum mac_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 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 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 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 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 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 dtsec_set_tx_pause_time(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 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 dtsec_get_rctrl(struct dtsec_regs *regs) -+{ -+ return ioread32be(®s->rctrl); -+} -+ -+uint32_t dtsec_get_revision(struct dtsec_regs *regs) -+{ -+ return ioread32be(®s->tsec_id); -+} -+ -+uint32_t dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask) -+{ -+ return ioread32be(®s->ievent) & ev_mask; -+} -+ -+void dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ev_mask, ®s->ievent); -+} -+ -+uint32_t dtsec_get_interrupt_mask(struct dtsec_regs *regs) -+{ -+ return ioread32be(®s->imask); -+} -+ -+uint32_t 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 dtsec_enable_tmr_interrupt(struct dtsec_regs *regs) -+{ -+ iowrite32be(ioread32be(®s->tmr_pemask) | TMR_PEMASK_TSREEN, -+ ®s->tmr_pemask); -+} -+ -+void dtsec_disable_tmr_interrupt(struct dtsec_regs *regs) -+{ -+ iowrite32be(ioread32be(®s->tmr_pemask) & ~TMR_PEMASK_TSREEN, -+ ®s->tmr_pemask); -+} -+ -+void dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ioread32be(®s->imask) | ev_mask, ®s->imask); -+} -+ -+void dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ioread32be(®s->imask) & ~ev_mask, ®s->imask); -+} -+ -+uint32_t 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; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_dtsec_mii_acc.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_dtsec_mii_acc.c -new file mode 100644 -index 0000000..82f4997 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_dtsec_mii_acc.c -@@ -0,0 +1,148 @@ -+/* -+ * 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 "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 can work in the range of 2.5 to 12.5 Mhz. -+ * 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 -+ * [80..159] 0 (1/4)(1/8) [2.5 to 5.0] -+ * [160..319] 1 (1/4)(1/8) [5.0 to 10.0] -+ * [320..479] 2 (1/6)(1/8) [6.7 to 10.0] -+ * [480..639] 3 (1/8)(1/8) [7.5 to 10.0] -+ * [640..799] 4 (1/10)(1/8) [8.0 to 10.0] -+ * [800..959] 5 (1/14)(1/8) [7.1 to 8.5] -+ * [960..1119] 6 (1/20)(1/8) [6.0 to 7.0] -+ * [1120..1279] 7 (1/28)(1/8) [5.0 to 5.7] -+ * [1280..2800] 7 (1/28)(1/8) [5.7 to 12.5] -+ * -+ * Returns: the MIIMCFG[MgmtClk] appropriate value -+ */ -+ -+static uint8_t dtsec_mii_get_div(uint16_t dtsec_freq) -+{ -+ uint16_t mgmt_clk = (uint16_t)(dtsec_freq / 160); -+ -+ if (mgmt_clk > 7) -+ mgmt_clk = 7; -+ -+ return (uint8_t)mgmt_clk; -+} -+ -+void 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); -+} -+ -+void dtsec_mii_init(struct dtsec_mii_reg *regs, uint16_t dtsec_freq) -+{ -+ /* Setup the MII Mgmt clock speed */ -+ iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), ®s->miimcfg); -+} -+ -+int dtsec_mii_write_reg(struct dtsec_mii_reg *regs, uint8_t addr, -+ uint8_t reg, uint16_t data) -+{ -+ uint32_t tmp; -+ -+ /* Stop the MII management read cycle */ -+ iowrite32be(0, ®s->miimcom); -+ /* Dummy read to make sure MIIMCOM is written */ -+ tmp = ioread32be(®s->miimcom); -+ -+ /* Setting up MII Management Address Register */ -+ tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg); -+ iowrite32be(tmp, ®s->miimadd); -+ -+ /* 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); -+ -+ /* Wait untill MII management write is complete */ -+ /* todo: a timeout could be useful here */ -+ while ((ioread32be(®s->miimind)) & MIIMIND_BUSY) -+ /* busy wait */; -+ -+ return 0; -+} -+ -+int dtsec_mii_read_reg(struct dtsec_mii_reg *regs, uint8_t addr, -+ uint8_t reg, uint16_t *data) -+{ -+ uint32_t tmp; -+ -+ /* Setting up the MII Management Address Register */ -+ tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg); -+ iowrite32be(tmp, ®s->miimadd); -+ -+ /* Perform an MII management read cycle */ -+ iowrite32be(MIIMCOM_READ_CYCLE, ®s->miimcom); -+ /* Dummy read to make sure MIIMCOM is written */ -+ tmp = ioread32be(®s->miimcom); -+ -+ /* 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); -+ -+ iowrite32be(0, ®s->miimcom); -+ /* Dummy read to make sure MIIMCOM is written */ -+ tmp = ioread32be(®s->miimcom); -+ -+ if (*data == 0xffff) -+ return -ENXIO; -+ -+ return 0; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_memac.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_memac.c -new file mode 100644 -index 0000000..a63d06a ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_memac.c -@@ -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. -+ */ -+ -+ -+#include "fsl_fman_memac.h" -+ -+ -+uint32_t memac_get_event(struct memac_regs *regs, uint32_t ev_mask) -+{ -+ return ioread32be(®s->ievent) & ev_mask; -+} -+ -+uint32_t memac_get_interrupt_mask(struct memac_regs *regs) -+{ -+ return ioread32be(®s->imask); -+} -+ -+void memac_ack_event(struct memac_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ev_mask, ®s->ievent); -+} -+ -+void 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 memac_hardware_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 memac_hardware_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 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 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 memac_reset_counter(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 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); -+} -+ -+void memac_init(struct memac_regs *regs, -+ struct memac_cfg *cfg, -+ enum enet_interface enet_interface, -+ enum enet_speed enet_speed, -+ 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; -+ -+ 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(cfg->pause_quanta, ®s->pause_quanta[0]); -+ iowrite32be(0, ®s->pause_thresh[0]); -+ -+ /* interrupts */ -+ iowrite32be(MEMAC_EVENTS_MASK, ®s->ievent); -+ iowrite32be(exceptions, ®s->imask); -+ -+ /* 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) -+ tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO; -+ } -+ iowrite32be(tmp, ®s->if_mode); -+} -+ -+void 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 memac_set_hash_table(struct memac_regs *regs, uint32_t val) -+{ -+ iowrite32be(val, ®s->hashtable_ctrl); -+} -+ -+uint16_t memac_get_max_frame_length(struct memac_regs *regs) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->maxfrm); -+ -+ return(uint16_t)tmp; -+} -+ -+ -+void 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->command_config); -+ if (priority == 0xff) { -+ tmp &= ~CMD_CFG_PFC_MODE; -+ priority = 0; -+ } -+ else -+ 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 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 memac_set_loopback(struct memac_regs *regs, bool enable) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->command_config); -+ -+ if (enable) -+ tmp |= CMD_CFG_LOOPBACK_EN; -+ else -+ tmp &= ~CMD_CFG_LOOPBACK_EN; -+ -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+ -+#define GET_MEMAC_CNTR_64(bn) \ -+ (ioread32be(®s->bn ## _l) | \ -+ ((uint64_t)ioread32be(®s->bn ## _u) << 32)) -+ -+uint64_t 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 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; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_tgec.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_tgec.c -new file mode 100644 -index 0000000..fa80a36 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fman_tgec.c -@@ -0,0 +1,355 @@ -+/* -+ * 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 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 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 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 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 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 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 tgec_set_hash_table(struct tgec_regs *regs, uint32_t value) -+{ -+ iowrite32be(value, ®s->hashtable_ctrl); -+} -+ -+void tgec_tx_mac_pause(struct tgec_regs *regs, uint16_t pause_time) -+{ -+ iowrite32be((uint32_t)pause_time, ®s->pause_quant); -+} -+ -+void tgec_rx_ignore_mac_pause(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 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 tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask) -+{ -+ return ioread32be(®s->ievent) & ev_mask; -+} -+ -+void tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ev_mask, ®s->ievent); -+} -+ -+uint32_t tgec_get_interrupt_mask(struct tgec_regs *regs) -+{ -+ return ioread32be(®s->imask); -+} -+ -+void 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 tgec_clear_addr_in_paddr(struct tgec_regs *regs) -+{ -+ iowrite32be(0, ®s->mac_addr_2); -+ iowrite32be(0, ®s->mac_addr_3); -+} -+ -+uint32_t tgec_get_revision(struct tgec_regs *regs) -+{ -+ return ioread32be(®s->tgec_id); -+} -+ -+void tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ioread32be(®s->imask) | ev_mask, ®s->imask); -+} -+ -+void tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ioread32be(®s->imask) & ~ev_mask, ®s->imask); -+} -+ -+uint16_t tgec_get_max_frame_len(struct tgec_regs *regs) -+{ -+ return (uint16_t) ioread32be(®s->maxfrm); -+} -+ -+void 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 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 */ -+ tgec_ack_event(regs, 0xffffffff); -+ tgec_enable_interrupt(regs, exception_mask); -+ return 0; -+} -+ -+void tgec_fm_tx_fifo_corruption_errata_10gmac_a007(struct tgec_regs *regs) -+{ -+ uint32_t tmp; -+ -+ /* restore the default tx ipg Length */ -+ tmp = (ioread32be(®s->tx_ipg_len) & ~TX_IPG_LENGTH_MASK) | 12; -+ -+ iowrite32be(tmp, ®s->tx_ipg_len); -+ -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fsl_fman_dtsec_mii_acc.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fsl_fman_dtsec_mii_acc.h -new file mode 100644 -index 0000000..2d74b6a ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/fsl_fman_dtsec_mii_acc.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_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_LOOPBACK 0x4000 -+#define PHY_CR_SPEED0 0x2000 -+#define PHY_CR_ANE 0x1000 -+#define PHY_CR_FULLDUPLEX 0x0100 -+#define PHY_CR_SPEED1 0x0040 -+ -+#define PHY_TBICON_SRESET 0x8000 -+#define PHY_TBICON_SPEED2 0x0020 -+ -+/* 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 dtsec_mii_reset(struct dtsec_mii_reg *regs); -+/* frequency is in MHz. -+ * note that dtsec clock is 1/2 of fman clock */ -+void dtsec_mii_init(struct dtsec_mii_reg *regs, uint16_t dtsec_freq); -+int dtsec_mii_write_reg(struct dtsec_mii_reg *regs, -+ uint8_t addr, -+ uint8_t reg, -+ uint16_t data); -+ -+int dtsec_mii_read_reg(struct dtsec_mii_reg *regs, -+ uint8_t addr, -+ uint8_t reg, -+ uint16_t *data); -+ -+#endif /* __FSL_FMAN_DTSEC_MII_ACC_H */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/memac.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/memac.c -new file mode 100644 -index 0000000..6e5440d ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/memac.c -@@ -0,0 +1,1036 @@ -+/* -+ * 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 xor = 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; -+ } -+ xor |= (mask1 << (5-i)); -+ } -+ -+ return xor; -+} -+ -+ -+/* ......................................................................... */ -+ -+static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr) -+{ -+ uint16_t tmpReg16; -+ -+ /* SGMII mode + AN enable */ -+ tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII; -+ 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); -+} -+ -+/* ......................................................................... */ -+ -+static void SetupSgmiiInternalPhyBaseX(t_Memac *p_Memac, uint8_t phyAddr) -+{ -+ uint16_t tmpReg16; -+ -+ /* 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); -+} -+ -+/* ......................................................................... */ -+ -+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; -+ struct memac_regs *regs = p_Memac->p_MemMap; -+ uint32_t event, imsk; -+ -+ event = memac_get_event(regs, 0xffffffff); -+ -+ /* -+ * Apparently the imask bits are shifted by 16 bits offset from -+ * their corresponding bits in the ievent - hence the >> 16 -+ */ -+ imsk = memac_get_interrupt_mask(regs) >> 16;; -+ -+ /* -+ * Extract all event bits plus the pending interrupts according to -+ * their imask -+ */ -+ event = (event & ~(MEMAC_ALL_IMASKS >> 16)) | (event & imsk); -+ -+ /* Ignoring the status bits */ -+ event = event & ~(MEMAC_IEVNT_RX_EMPTY | -+ MEMAC_IEVNT_TX_EMPTY | -+ MEMAC_IEVNT_RX_LOWP | -+ MEMAC_IEVNT_PHY_LOS); -+ -+ memac_ack_event(regs, event); -+ -+ if (event & MEMAC_IEVNT_RX_FIFO_OVFL) -+ p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL); -+ if (event & MEMAC_IEVNT_TX_FIFO_UNFL) -+ p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL); -+ if (event & MEMAC_IEVNT_TX_FIFO_OVFL) -+ p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL); -+ 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); -+ if (event & MEMAC_IEVNT_REM_FAULT) -+ p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_REM_FAULT); -+ if (event & MEMAC_IEVNT_LOC_FAULT) -+ p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_LOC_FAULT); -+} -+ -+ -+/* ......................................................................... */ -+ -+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); -+ -+ 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); -+ -+ 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); -+ -+ 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); -+UNUSED(p_Memac); -+DBG(WARNING, ("mEMAC works in automatic-mode; therefore, adjust-link is not needed!")); -+ -+ 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); -+ -+ 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); -+ -+ memac_set_rx_ignore_pause_frames(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 = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64); -+ p_Statistics->eStatPkts65to127 = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127); -+ p_Statistics->eStatPkts128to255 = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255); -+ p_Statistics->eStatPkts256to511 = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511); -+ p_Statistics->eStatPkts512to1023 = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023); -+ p_Statistics->eStatPkts1024to1518 = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518); -+ p_Statistics->eStatPkts1519to1522 = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X); -+/* */ -+ p_Statistics->eStatFragments = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RFRG); -+ p_Statistics->eStatJabbers = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RJBR); -+ -+ p_Statistics->eStatsDropEvents = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RDRP); -+ p_Statistics->eStatCRCAlignErrors = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RALN); -+ -+ p_Statistics->eStatUndersizePkts = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUND); -+ p_Statistics->eStatOversizePkts = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROVR); -+/* Pause */ -+ p_Statistics->reStatPause = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RXPF); -+ p_Statistics->teStatPause = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TXPF); -+ -+/* MIB II */ -+ p_Statistics->ifInOctets = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROCT); -+ p_Statistics->ifInUcastPkts = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RUCA); -+ p_Statistics->ifInMcastPkts = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RMCA); -+ p_Statistics->ifInBcastPkts = 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 = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RERR); -+ -+ p_Statistics->ifOutOctets = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TOCT); -+ p_Statistics->ifOutUcastPkts = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUCA); -+ p_Statistics->ifOutMcastPkts = memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TMCA); -+ p_Statistics->ifOutBcastPkts = 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 = 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); -+ -+ memac_hardware_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); -+ -+ memac_reset_counter(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 */ -+ memac_hardware_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 */ -+ memac_hardware_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 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])); -+ 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])) -+ 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")); -+ -+ 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 memac_get_max_frame_length(p_Memac->p_MemMap); -+} -+ -+/* ......................................................................... */ -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+static t_Error MemacDumpRegs(t_Handle h_Memac) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ int i = 0; -+ -+ DECLARE_DUMP; -+ -+ if (p_Memac->p_MemMap) -+ { -+ DUMP_TITLE(p_Memac->p_MemMap, ("mEMAC %d: ", p_Memac->macId)); -+ DUMP_VAR(p_Memac->p_MemMap, command_config); -+ DUMP_VAR(p_Memac->p_MemMap, mac_addr0.mac_addr_l); -+ DUMP_VAR(p_Memac->p_MemMap, mac_addr0.mac_addr_u); -+ DUMP_VAR(p_Memac->p_MemMap, maxfrm); -+ DUMP_VAR(p_Memac->p_MemMap, hashtable_ctrl); -+ DUMP_VAR(p_Memac->p_MemMap, ievent); -+ DUMP_VAR(p_Memac->p_MemMap, tx_ipg_length); -+ DUMP_VAR(p_Memac->p_MemMap, imask); -+ -+ DUMP_SUBSTRUCT_ARRAY(i, 4) -+ { -+ DUMP_VAR(p_Memac->p_MemMap, pause_quanta[i]); -+ } -+ DUMP_SUBSTRUCT_ARRAY(i, 4) -+ { -+ DUMP_VAR(p_Memac->p_MemMap, pause_thresh[i]); -+ } -+ -+ DUMP_VAR(p_Memac->p_MemMap, rx_pause_status); -+ -+ DUMP_SUBSTRUCT_ARRAY(i, MEMAC_NUM_OF_PADDRS) -+ { -+ DUMP_VAR(p_Memac->p_MemMap, mac_addr[i].mac_addr_l); -+ DUMP_VAR(p_Memac->p_MemMap, mac_addr[i].mac_addr_u); -+ } -+ -+ DUMP_VAR(p_Memac->p_MemMap, lpwake_timer); -+ DUMP_VAR(p_Memac->p_MemMap, sleep_timer); -+ DUMP_VAR(p_Memac->p_MemMap, statn_config); -+ DUMP_VAR(p_Memac->p_MemMap, if_mode); -+ DUMP_VAR(p_Memac->p_MemMap, if_status); -+ DUMP_VAR(p_Memac->p_MemMap, hg_config); -+ DUMP_VAR(p_Memac->p_MemMap, hg_pause_quanta); -+ DUMP_VAR(p_Memac->p_MemMap, hg_pause_thresh); -+ DUMP_VAR(p_Memac->p_MemMap, hgrx_pause_status); -+ DUMP_VAR(p_Memac->p_MemMap, hg_fifos_status); -+ DUMP_VAR(p_Memac->p_MemMap, rhm); -+ DUMP_VAR(p_Memac->p_MemMap, thm); -+ } -+ -+ return E_OK; -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ -+/*****************************************************************************/ -+/* mEMAC Init & Free API */ -+/*****************************************************************************/ -+ -+/* ......................................................................... */ -+ -+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; -+ uint8_t i, phyAddr; -+ t_EnetAddr ethAddr; -+ e_FmMacType portType; -+ t_Error err; -+ -+ 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); -+ -+ /* not needed! */ -+ /*FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);*/ -+ -+ 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) -+ memac_reset(p_Memac->p_MemMap); -+ -+ /* MAC Address */ -+ MAKE_ENET_ADDR_FROM_UINT64(p_Memac->addr, ethAddr); -+ memac_hardware_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); -+ -+ memac_init(p_Memac->p_MemMap, -+ p_Memac->p_MemacDriverParam, -+ enet_interface, -+ enet_speed, -+ p_Memac->exceptions); -+ -+ 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); -+ } -+ } -+ -+ /* 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); -+ -+ -+ 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); -+ -+ FreeInitResources(p_Memac); -+ -+ if (p_Memac->p_MemacDriverParam) -+ { -+ XX_Free(p_Memac->p_MemacDriverParam); -+ p_Memac->p_MemacDriverParam = NULL; -+ } -+ 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_SetTxAutoPauseFrames = MemacSetTxAutoPauseFrames; -+ p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = MemacSetTxPauseFrames; -+ p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = MemacSetRxIgnorePauseFrames; -+ -+ 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 = NULL; -+ 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; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ p_FmMacControllerDriver->f_FM_MAC_DumpRegs = MemacDumpRegs; -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+} -+ -+ -+/*****************************************************************************/ -+/* 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")); -+ MemacFree(p_Memac); -+ return NULL; -+ } -+ memset(p_MemacDriverParam, 0, sizeof(struct memac_cfg)); -+ -+ /* Plant parameter structure pointer */ -+ p_Memac->p_MemacDriverParam = p_MemacDriverParam; -+ -+ 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 = (t_MemacMiiAccessMemMap *)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; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/memac.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/memac.h -new file mode 100644 -index 0000000..e1c4c53 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/memac.h -@@ -0,0 +1,104 @@ -+/* -+ * 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 "memac_mii_acc.h" -+#include "fm_mac.h" -+#include "fsl_fman_memac.h" -+ -+ -+#define MEMAC_default_exceptions ((uint32_t)(MEMAC_IMASK_TECC_ER | MEMAC_IMASK_RECC_ER)) -+ -+#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; \ -+ 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 */ -+ t_MemacMiiAccessMemMap *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_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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/memac_mii_acc.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/memac_mii_acc.c -new file mode 100644 -index 0000000..be5b867 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/memac_mii_acc.c -@@ -0,0 +1,240 @@ -+/* -+ * 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" -+ -+ -+static void WritePhyReg10G(t_MemacMiiAccessMemMap *p_MiiAccess, -+ uint8_t phyAddr, -+ uint8_t reg, -+ uint16_t data) -+{ -+ uint32_t tmpReg; -+ -+ tmpReg = GET_UINT32(p_MiiAccess->mdio_cfg); -+ /* Leave only MDIO_CLK_DIV bits set on */ -+ tmpReg &= MDIO_CFG_CLK_DIV_MASK; -+ /* Set maximum MDIO_HOLD value to allow phy to see -+ change of data signal */ -+ tmpReg |= MDIO_CFG_HOLD_MASK; -+ /* Add 10G interface mode */ -+ tmpReg |= MDIO_CFG_ENC45; -+ WRITE_UINT32(p_MiiAccess->mdio_cfg, tmpReg); -+ -+ /* Wait for command completion */ -+ while ((GET_UINT32(p_MiiAccess->mdio_cfg)) & MDIO_CFG_BSY) -+ XX_UDelay(1); -+ -+ /* Specify phy and register to be accessed */ -+ WRITE_UINT32(p_MiiAccess->mdio_ctrl, phyAddr); -+ WRITE_UINT32(p_MiiAccess->mdio_addr, reg); -+ CORE_MemoryBarrier(); -+ -+ while ((GET_UINT32(p_MiiAccess->mdio_cfg)) & MDIO_CFG_BSY) -+ XX_UDelay(1); -+ -+ /* Write data */ -+ WRITE_UINT32(p_MiiAccess->mdio_data, data); -+ CORE_MemoryBarrier(); -+ -+ /* Wait for write transaction end */ -+ while ((GET_UINT32(p_MiiAccess->mdio_data)) & MDIO_DATA_BSY) -+ XX_UDelay(1); -+} -+ -+static uint32_t ReadPhyReg10G(t_MemacMiiAccessMemMap *p_MiiAccess, -+ uint8_t phyAddr, -+ uint8_t reg, -+ uint16_t *p_Data) -+{ -+ uint32_t tmpReg; -+ -+ tmpReg = GET_UINT32(p_MiiAccess->mdio_cfg); -+ /* Leave only MDIO_CLK_DIV bits set on */ -+ tmpReg &= MDIO_CFG_CLK_DIV_MASK; -+ /* Set maximum MDIO_HOLD value to allow phy to see -+ change of data signal */ -+ tmpReg |= MDIO_CFG_HOLD_MASK; -+ /* Add 10G interface mode */ -+ tmpReg |= MDIO_CFG_ENC45; -+ WRITE_UINT32(p_MiiAccess->mdio_cfg, tmpReg); -+ -+ /* Wait for command completion */ -+ while ((GET_UINT32(p_MiiAccess->mdio_cfg)) & MDIO_CFG_BSY) -+ XX_UDelay(1); -+ -+ /* Specify phy and register to be accessed */ -+ WRITE_UINT32(p_MiiAccess->mdio_ctrl, phyAddr); -+ WRITE_UINT32(p_MiiAccess->mdio_addr, reg); -+ CORE_MemoryBarrier(); -+ -+ while ((GET_UINT32(p_MiiAccess->mdio_cfg)) & MDIO_CFG_BSY) -+ XX_UDelay(1); -+ -+ /* Read cycle */ -+ tmpReg = phyAddr; -+ tmpReg |= MDIO_CTL_READ; -+ WRITE_UINT32(p_MiiAccess->mdio_ctrl, tmpReg); -+ CORE_MemoryBarrier(); -+ -+ /* Wait for data to be available */ -+ while ((GET_UINT32(p_MiiAccess->mdio_data)) & MDIO_DATA_BSY) -+ XX_UDelay(1); -+ -+ *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->mdio_data); -+ -+ /* Check if there was an error */ -+ return GET_UINT32(p_MiiAccess->mdio_cfg); -+} -+ -+static void WritePhyReg1G(t_MemacMiiAccessMemMap *p_MiiAccess, -+ uint8_t phyAddr, -+ uint8_t reg, -+ uint16_t data) -+{ -+ uint32_t tmpReg; -+ -+ /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */ -+ tmpReg = GET_UINT32(p_MiiAccess->mdio_cfg); -+ tmpReg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK); -+ WRITE_UINT32(p_MiiAccess->mdio_cfg, tmpReg); -+ -+ /* Wait for command completion */ -+ while ((GET_UINT32(p_MiiAccess->mdio_cfg)) & MDIO_CFG_BSY) -+ XX_UDelay(1); -+ -+ /* Write transaction */ -+ tmpReg = (phyAddr << MDIO_CTL_PHY_ADDR_SHIFT); -+ tmpReg |= reg; -+ WRITE_UINT32(p_MiiAccess->mdio_ctrl, tmpReg); -+ -+ while ((GET_UINT32(p_MiiAccess->mdio_cfg)) & MDIO_CFG_BSY) -+ XX_UDelay(1); -+ -+ WRITE_UINT32(p_MiiAccess->mdio_data, data); -+ -+ CORE_MemoryBarrier(); -+ -+ /* Wait for write transaction to end */ -+ while ((GET_UINT32(p_MiiAccess->mdio_data)) & MDIO_DATA_BSY) -+ XX_UDelay(1); -+} -+ -+static uint32_t ReadPhyReg1G(t_MemacMiiAccessMemMap *p_MiiAccess, -+ uint8_t phyAddr, -+ uint8_t reg, -+ uint16_t *p_Data) -+{ -+ uint32_t tmpReg; -+ -+ /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */ -+ tmpReg = GET_UINT32(p_MiiAccess->mdio_cfg); -+ tmpReg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK); -+ WRITE_UINT32(p_MiiAccess->mdio_cfg, tmpReg); -+ -+ /* Wait for command completion */ -+ while ((GET_UINT32(p_MiiAccess->mdio_cfg)) & MDIO_CFG_BSY) -+ XX_UDelay(1); -+ -+ /* Read transaction */ -+ tmpReg = (phyAddr << MDIO_CTL_PHY_ADDR_SHIFT); -+ tmpReg |= reg; -+ tmpReg |= MDIO_CTL_READ; -+ WRITE_UINT32(p_MiiAccess->mdio_ctrl, tmpReg); -+ -+ while ((GET_UINT32(p_MiiAccess->mdio_cfg)) & MDIO_CFG_BSY) -+ XX_UDelay(1); -+ -+ /* Wait for data to be available */ -+ while ((GET_UINT32(p_MiiAccess->mdio_data)) & MDIO_DATA_BSY) -+ XX_UDelay(1); -+ -+ *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->mdio_data); -+ -+ /* Check error */ -+ return GET_UINT32(p_MiiAccess->mdio_cfg); -+} -+ -+/*****************************************************************************/ -+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); -+ -+ /* Figure out interface type - 10G vs 1G. -+ In 10G interface both phyAddr and devAddr present. */ -+ if (ENET_SPEED_FROM_MODE(p_Memac->enetMode) == e_ENET_SPEED_10000) -+ WritePhyReg10G(p_Memac->p_MiiMemMap, phyAddr, reg, data); -+ else -+ WritePhyReg1G(p_Memac->p_MiiMemMap, phyAddr, reg, data); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+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; -+ uint32_t ans; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE); -+ -+ /* Figure out interface type - 10G vs 1G. -+ In 10G interface both phyAddr and devAddr present. */ -+ if (ENET_SPEED_FROM_MODE(p_Memac->enetMode) == e_ENET_SPEED_10000) -+ ans = ReadPhyReg10G(p_Memac->p_MiiMemMap, phyAddr, reg, p_Data); -+ else -+ ans = ReadPhyReg1G(p_Memac->p_MiiMemMap, phyAddr, reg, p_Data); -+ -+ if (ans & MDIO_CFG_READ_ERR) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, -+ ("Read Error: phyAddr 0x%x, dev 0x%x, reg 0x%x, cfgReg 0x%x", -+ ((phyAddr & 0xe0) >> 5), (phyAddr & 0x1f), reg, ans)); -+ -+ return E_OK; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/memac_mii_acc.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/memac_mii_acc.h -new file mode 100644 -index 0000000..dab4360 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 0x0000ff80 -+#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 _Packed 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 */ -+} _PackedType t_MemacMiiAccessMemMap ; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+#endif /* __MEMAC_MII_ACC_H */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/tgec.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/tgec.c -new file mode 100644 -index 0000000..522d64b ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/tgec.c -@@ -0,0 +1,1018 @@ -+/* -+ * 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 = tgec_get_event(p_TgecMemMap, ~(TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL)); -+ event &= tgec_get_interrupt_mask(p_TgecMemMap); -+ -+ 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 = tgec_get_event(p_TgecMemMap, (TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL)); -+ event &= tgec_get_interrupt_mask(p_TgecMemMap); -+ -+ 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 != 0) && (p_Tgec->mdioIrq != NO_IRQ)) -+ { -+ XX_DisableIntr(p_Tgec->mdioIrq); -+ XX_FreeIntr(p_Tgec->mdioIrq); -+ } -+ else if (p_Tgec->mdioIrq == 0) -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+ 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); -+ -+ 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); -+ -+ 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); -+ -+ 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); -+ tgec_tx_mac_pause(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); -+ -+ tgec_tx_mac_pause(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); -+ -+ tgec_rx_ignore_mac_pause(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 = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64); -+ p_Statistics->eStatPkts65to127 = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127); -+ p_Statistics->eStatPkts128to255 = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255); -+ p_Statistics->eStatPkts256to511 = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511); -+ p_Statistics->eStatPkts512to1023 = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023); -+ p_Statistics->eStatPkts1024to1518 = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518); -+ p_Statistics->eStatPkts1519to1522 = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X); -+/* */ -+ p_Statistics->eStatFragments = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRFRG); -+ p_Statistics->eStatJabbers = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRJBR); -+ -+ p_Statistics->eStatsDropEvents = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RDRP); -+ p_Statistics->eStatCRCAlignErrors = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RALN); -+ -+ p_Statistics->eStatUndersizePkts = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRUND); -+ p_Statistics->eStatOversizePkts = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TROVR); -+/* Pause */ -+ p_Statistics->reStatPause = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RXPF); -+ p_Statistics->teStatPause = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TXPF); -+ -+/* MIB II */ -+ p_Statistics->ifInOctets = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_ROCT); -+ p_Statistics->ifInUcastPkts = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RUCA); -+ p_Statistics->ifInMcastPkts = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RMCA); -+ p_Statistics->ifInBcastPkts = 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 = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RERR); -+ -+ p_Statistics->ifOutOctets = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TOCT); -+ p_Statistics->ifOutUcastPkts = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TUCA); -+ p_Statistics->ifOutMcastPkts = tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TMCA); -+ p_Statistics->ifOutBcastPkts = 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 = 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); -+ -+ 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); -+ -+ 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); -+ 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); -+ -+ 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 */ -+ 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 */ -+ 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])); -+ 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])) -+ 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 = 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) -+ tgec_enable_interrupt(p_Tgec->p_MemMap, bitMask); -+ else -+ 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 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 */ -+ tgec_enable(p_Tgec->p_MemMap, TRUE, TRUE); -+ tgec_set_promiscuous(p_Tgec->p_MemMap, TRUE); -+ err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId); -+ /* disable */ -+ tgec_set_promiscuous(p_Tgec->p_MemMap, FALSE); -+ tgec_enable(p_Tgec->p_MemMap, FALSE, FALSE); -+#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0) -+ if (err) -+ XX_Print("FAILED!\n"); -+ else -+ XX_Print("done.\n"); -+#endif /* (DEBUG_ERRORS > 0) */ -+ tgec_reset_stat(p_Tgec->p_MemMap); -+ -+ return err; -+} -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+ -+/* ......................................................................... */ -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+static t_Error TgecDumpRegs(t_Handle h_Tgec) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ DECLARE_DUMP; -+ -+ if (p_Tgec->p_MemMap) -+ { -+ DUMP_TITLE(p_Tgec->p_MemMap, ("10G MAC %d: ", p_Tgec->macId)); -+ DUMP_VAR(p_Tgec->p_MemMap, tgec_id); -+ DUMP_VAR(p_Tgec->p_MemMap, command_config); -+ DUMP_VAR(p_Tgec->p_MemMap, mac_addr_0); -+ DUMP_VAR(p_Tgec->p_MemMap, mac_addr_1); -+ DUMP_VAR(p_Tgec->p_MemMap, maxfrm); -+ DUMP_VAR(p_Tgec->p_MemMap, pause_quant); -+ DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_sections); -+ DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_sections); -+ DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_almost_f_e); -+ DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_almost_f_e); -+ DUMP_VAR(p_Tgec->p_MemMap, hashtable_ctrl); -+ DUMP_VAR(p_Tgec->p_MemMap, mdio_cfg_status); -+ DUMP_VAR(p_Tgec->p_MemMap, mdio_command); -+ DUMP_VAR(p_Tgec->p_MemMap, mdio_data); -+ DUMP_VAR(p_Tgec->p_MemMap, mdio_regaddr); -+ DUMP_VAR(p_Tgec->p_MemMap, status); -+ DUMP_VAR(p_Tgec->p_MemMap, tx_ipg_len); -+ DUMP_VAR(p_Tgec->p_MemMap, mac_addr_2); -+ DUMP_VAR(p_Tgec->p_MemMap, mac_addr_3); -+ DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_ptr_rd); -+ DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_ptr_wr); -+ DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_ptr_rd); -+ DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_ptr_wr); -+ DUMP_VAR(p_Tgec->p_MemMap, imask); -+ DUMP_VAR(p_Tgec->p_MemMap, ievent); -+ } -+ -+ return E_OK; -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ -+/*****************************************************************************/ -+/* 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); -+ 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->fmMacControllerDriver.fmRevInfo.majorRev <= 6 /*fixed for rev3 */) -+ { -+ 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 = 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); -+ /* we consider having no IPC a non crasher... */ -+ -+#ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 -+ if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev == 2) -+ tgec_fm_tx_fifo_corruption_errata_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 != 0) && (p_Tgec->mdioIrq != NO_IRQ)) -+ { -+ XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec); -+ XX_EnableIntr(p_Tgec->mdioIrq); -+ } -+ else if (p_Tgec->mdioIrq == 0) -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, (NO_MSG)); -+ -+ 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); -+ -+ FreeInitResources(p_Tgec); -+ -+ if (p_Tgec->p_TgecDriverParam) -+ { -+ XX_Free(p_Tgec->p_TgecDriverParam); -+ p_Tgec->p_TgecDriverParam = NULL; -+ } -+ 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_RestartAutoneg = NULL; -+ -+ p_FmMacControllerDriver->f_FM_MAC_Enable = TgecEnable; -+ p_FmMacControllerDriver->f_FM_MAC_Disable = TgecDisable; -+ -+ 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; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ p_FmMacControllerDriver->f_FM_MAC_DumpRegs = TgecDumpRegs; -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+} -+ -+ -+/*****************************************************************************/ -+/* 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")); -+ TgecFree(p_Tgec); -+ return NULL; -+ } -+ memset(p_TgecDriverParam, 0, sizeof(struct tgec_cfg)); -+ -+ /* Plant parameter structure pointer */ -+ p_Tgec->p_TgecDriverParam = p_TgecDriverParam; -+ -+ 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; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/tgec.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/tgec.h -new file mode 100644 -index 0000000..2aa3923 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/tgec_mii_acc.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/tgec_mii_acc.c -new file mode 100644 -index 0000000..e0fafd1 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/tgec_mii_acc.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/MAC/tgec_mii_acc.h -new file mode 100644 -index 0000000..645cdde ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Makefile b/drivers/net/dpa/NetCommSw/Peripherals/FM/Makefile -new file mode 100644 -index 0000000..67d6e21 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Makefile -@@ -0,0 +1,22 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+NCSW_FM_INC = $(srctree)/drivers/net/dpa/NetCommSw/Peripherals/FM/inc -+ -+EXTRA_CFLAGS += -I$(NCSW_FM_INC) -+ -+ -+obj-y += fsl-ncsw-PFM1.o -+ -+fsl-ncsw-PFM1-objs := fm.o fm_muram.o -+ -+obj-y += MAC/ -+obj-y += Pcd/ -+obj-y += SP/ -+obj-y += Port/ -+obj-y += HC/ -+obj-y += Rtc/ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/Makefile b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/Makefile -new file mode 100644 -index 0000000..72c921d ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/Makefile -@@ -0,0 +1,19 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+ -+NCSW_FM_INC = $(srctree)/drivers/net/dpa/NetCommSw/Peripherals/FM/inc -+ -+EXTRA_CFLAGS += -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_T4240),y) -+fsl-ncsw-Pcd-objs += fm_replic.o -+endif -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/crc64.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/crc64.h -new file mode 100644 -index 0000000..335ee68 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_cc.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_cc.c -new file mode 100644 -index 0000000..85810a9 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_cc.c -@@ -0,0 +1,6940 @@ -+/* -+ * 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 "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); -+ } -+ 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; -+ } -+ IOMemSet32(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; -+ } -+ IOMemSet32(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) -+ { -+ /* Nullify counters */ -+ IOMemSet32(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize); -+ -+ 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); -+ -+ Mem2IOCpy32((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) -+ { -+ 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")); -+ -+ IOMemSet32(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 SetRequiredAction(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)) -+ { -+ -+ ASSERT_COND(LIST_NumOfObjs(&p_CcNode->ccTreesLst) == 0); -+ if (p_CcNode->shadowAction & UPDATE_CC_WITH_DELETE_TREE) -+ p_CcNode->shadowAction &= ~UPDATE_CC_WITH_DELETE_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_WITH_DELETE_TREE) && !(p_CcNode->shadowAction & UPDATE_CC_WITH_DELETE_TREE)) -+ { -+ ASSERT_COND(LIST_NumOfObjs(&p_CcNode->ccTreesLst) == 1); -+ if (p_CcNode->shadowAction & UPDATE_CC_WITH_TREE) -+ p_CcNode->shadowAction &= ~UPDATE_CC_WITH_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 = SetRequiredAction(h_FmPcd, -+ requiredAction, -+ p_CcNode->keyAndNextEngineParams, -+ p_CcNode->h_AdTable, -+ tmp, -+ h_Tree); -+ if (err != E_OK) -+ return err; -+ 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 ReleaseModifiedDataStructure(t_Handle h_FmPcd, -+ t_List *h_FmPcdOldPointersLst, -+ t_List *h_FmPcdNewPointersLst, -+ uint16_t numOfGoodChanges, -+ 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; -+ t_List *p_UpdateLst; -+ uint32_t intFlags; -+ -+ UNUSED(numOfGoodChanges); -+ -+ 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); -+ SANITY_CHECK_RETURN_ERROR((numOfGoodChanges == LIST_NumOfObjs(h_FmPcdOldPointersLst)),E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR((1 == LIST_NumOfObjs(h_FmPcdNewPointersLst)),E_INVALID_STATE); -+ -+ /* 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; -+ -+ while (!LIST_IsEmpty(&p_FmPcdCcNextNode->ccTreesLst)) -+ { -+ p_Pos = LIST_NEXT(&p_FmPcdCcNextNode->ccTreesLst); -+ 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 */ -+ p_Pos = LIST_FIRST(h_FmPcdNewPointersLst); -+ 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; -+ -+ 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) -+ { -+ if (AllocAndFillAdForContLookupManip(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)!= E_OK) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ return NULL; -+ } -+ } -+ FillAdOfTypeContLookup(h_Ad, -+ NULL, -+ p_CcNode->h_FmPcd, -+ p_FmPcdCcNodeTmp, -+ 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); -+ -+ 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, -+ 0, -+ p_AdditionalParams, -+ useShadowStructs); -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("New AD address")); -+ } -+ -+ for (i=0; ih_Hc, oldAdAddrOffset, newAdAddrOffset); -+ if (err) -+ { -+ ReleaseModifiedDataStructure(h_FmPcd, -+ h_OldPointersLst, -+ h_NewPointersLst, -+ i, -+ 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); -+ -+ SANITY_CHECK_RETURN_ERROR((LIST_NumOfObjs(h_OldPointersLst) >= 1),E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR((LIST_NumOfObjs(h_NewPointersLst) == 1),E_INVALID_STATE); -+ -+ memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams)); -+ -+ numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst); -+ -+ 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; -+ -+ IO2IOCpy32(p_AdditionalParams->p_KeysMatchTableOld, -+ p_AdditionalParams->p_KeysMatchTableNew, -+ p_CcNode->maxNumOfKeys * keySize * sizeof (uint8_t)); -+ -+ IO2IOCpy32(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, -+ numOfModifiedPtr, -+ 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 (numOfEntries) -+ { -+ for (i=0; ikeyAndNextEngineParams[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; -+ } -+ -+ 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; -+ } -+ -+ /* 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->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, -+ e_FmPcdHdrIndex index, -+ t_FmPcdFields field, -+ uint8_t *parseCodeRealSize) -+{ -+ UNUSED(index); -+ 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 of this match table")); -+ -+ 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(t_Handle h_FmPcd, -+ e_FmPcdExtractFrom src, -+ uint32_t offset, -+ bool glblMask, -+ uint8_t *parseArrayOffset, -+ bool fromIc, -+ ccPrivateInfo_t icCode) -+{ -+ UNUSED(h_FmPcd); -+ -+ 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); -+ 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; -+ -+ /* 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): -+ tmp = 0; -+ 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; -+ FmPcdPlcrGetAbsoluteIdByProfileParams((t_Handle)p_FmPcd, -+ e_FM_PCD_PLCR_SHARED, -+ NULL, -+ p_CcNextEngineParams->params.plcrParams.newRelativeProfileId, -+ &profileId); -+ } -+ 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) -+ { -+ 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")); -+ } -+ -+ IOMemSet32((uint8_t*)p_AdditionalInfo->p_AdTableNew, 0, (uint32_t)((p_AdditionalInfo->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE)); -+ IOMemSet32((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); -+ -+ IOMemSet32((uint8_t*)p_AdditionalInfo->p_AdTableNew, 0, (uint32_t)((p_CcNode->maxNumOfKeys + 1) * FM_PCD_CC_AD_ENTRY_SIZE)); -+ IOMemSet32((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)); -+ -+ Mem2IOCpy32((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) -+ { -+ Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ p_KeyParams->p_Mask, -+ p_CcNode->userSizeOfExtraction); -+ } -+ else if (p_CcNode->ccKeySizeAccExtraction > 4) -+ { -+ IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ 0xff, -+ p_CcNode->userSizeOfExtraction); -+ } -+ else -+ { -+ Mem2IOCpy32(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); -+ IO2IOCpy32(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) -+ { -+ IO2IOCpy32(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 * p_CcNode->ccKeySizeAccExtraction*sizeof(uint8_t)); -+ -+ if (p_CcNode->ccKeySizeAccExtraction > 4) -+ { -+ IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ 0xff, -+ p_CcNode->userSizeOfExtraction); -+ } -+ else -+ { -+ IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ p_CcNode->p_GlblMask, -+ p_CcNode->userSizeOfExtraction); -+ } -+ } -+ } -+ -+ IO2IOCpy32(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); -+ IO2IOCpy32(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; jnumOfKeys; i++, j++) -+ { -+ if (j == keyIndex) -+ { -+ p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE); -+ 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); -+ IO2IOCpy32(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)); -+ IO2IOCpy32(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); -+ IO2IOCpy32(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; jnumOfKeys; 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); -+ -+ IO2IOCpy32(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)); -+ -+ Mem2IOCpy32(p_KeysMatchTableNewTmp, p_Key, p_CcNode->userSizeOfExtraction); -+ -+ if (p_CcNode->lclMask) -+ { -+ if (p_Mask) -+ Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ p_Mask, -+ p_CcNode->userSizeOfExtraction); -+ else if (p_CcNode->ccKeySizeAccExtraction > 4) -+ IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ 0xff, -+ p_CcNode->userSizeOfExtraction); -+ else -+ Mem2IOCpy32(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) -+ IO2IOCpy32(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 * p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)); -+ -+ if (p_CcNode->ccKeySizeAccExtraction > 4) -+ IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ 0xff, -+ p_CcNode->userSizeOfExtraction); -+ else -+ IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction), -+ p_CcNode->p_GlblMask, -+ p_CcNode->userSizeOfExtraction); -+ } -+ } -+ IO2IOCpy32((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); -+ -+ IO2IOCpy32(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")); -+ IOMemSet32((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* ModifyKeyCommonPart1(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); -+ -+ p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(sizeof(t_FmPcdCcKeyAndNextEngineParams)*CC_MAX_NUM_OF_KEYS); -+ if (!p_KeyAndNextEngineParams) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure")); -+ return NULL; -+ } -+ memset(p_KeyAndNextEngineParams, 0, sizeof(t_FmPcdCcKeyAndNextEngineParams)*CC_MAX_NUM_OF_KEYS); -+ -+ if (!tree) -+ { -+ p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree; -+ numOfKeys = p_CcNode->numOfKeys; -+ -+ /* node has to be pointed by another node or tree */ -+ if (!LIST_NumOfObjs(&p_CcNode->ccPrevNodesLst) && -+ !LIST_NumOfObjs(&p_CcNode->ccTreeIdLst)) -+ { -+ XX_Free(p_KeyAndNextEngineParams); -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("node has to be pointed by node or tree")); -+ return NULL; -+ } -+ -+ if (!LIST_NumOfObjs(&p_CcNode->ccTreesLst) || -+ (LIST_NumOfObjs(&p_CcNode->ccTreesLst) != 1)) -+ { -+ XX_Free(p_KeyAndNextEngineParams); -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("node has to be belonging to some tree and only to one tree")); -+ return NULL; -+ } -+ -+ memcpy(p_KeyAndNextEngineParams, -+ p_CcNode->keyAndNextEngineParams, -+ CC_MAX_NUM_OF_KEYS * 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; -+ 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++; -+ else if (modifyState == e_MODIFY_STATE_REMOVE) -+ i++; -+ } -+ -+ 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; -+ -+ /* 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*/ -+ ASSERT_COND(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); -+ IOMemSet32(h_NewAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ BuildNewAd(h_NewAd, -+ p_FmPcdModifyCcKeyAdditionalParams, -+ p_CcNode, -+ p_NextEngineParams); -+ -+ ccNodeInfo.h_CcNode = h_NewAd; -+ EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL); -+ -+ 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; -+ -+ UNUSED(p_CcNodeParam); -+ -+ switch (statisticsMode) -+ { -+ case e_FM_PCD_CC_STATS_MODE_NONE: -+ 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; -+ 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 = ModifyKeyCommonPart1(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) -+ { -+ if (!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); -+ -+ 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); -+ REPORT_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")); -+ } -+ IOMemSet32(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")); -+ } -+ IOMemSet32(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 (keyIndex >= p_CcNode->numOfKeys) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in 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; -+} -+ -+ -+/*****************************************************************************/ -+/* 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_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 = ModifyKeyCommonPart1(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) -+ if (!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); -+ -+ 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->numOfKeys) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("keyIndex you asked > numOfKeys of relevant node that was initialized")); -+ -+ 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 = ModifyKeyCommonPart1(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); -+ -+ 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 = ModifyKeyCommonPart1(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); -+ -+ 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 = ModifyKeyCommonPart1(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) -+ { -+ if (!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); -+ -+ 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(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 = ModifyKeyCommonPart1(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); -+ -+ 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 = ModifyKeyCommonPart1(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); -+ -+ 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); -+ -+ if (LIST_IsEmpty(&p_CcNode->ccTreesLst)) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("asked for more nodes in CC than MAX")); -+ -+ 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; -+ } -+ IOMemSet32(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); -+ -+ j = 0; -+ 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 reassembly schemes if exist */ -+ if (p_CcTree->h_IpReassemblyManip) -+ { -+ FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip); -+ FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE); -+ } -+ -+ for (i = 0; i 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_FmPcd *p_FmPcd = (t_FmPcd *) h_FmPcd; -+ t_FmPcdCcNode *p_CcNode, *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; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,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)); -+ -+ 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) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM")); -+ return NULL; -+ } -+ -+ 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); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock")); -+ return NULL; -+ } -+ -+ 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)) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0")); -+ return NULL; -+ } -+ -+ icCode = IcDefineCode(p_CcNodeParam); -+ fromIc = TRUE; -+ if (icCode == CC_PRIVATE_INFO_NONE) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, -+ ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way")); -+ return NULL; -+ } -+ -+ 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); -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return NULL; -+ } -+ -+ 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.hdrIndex, -+ 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_MPLS1) && -+ (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); -+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ return NULL; -+ } -+ 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(h_FmPcd, -+ 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); -+ REPORT_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)")); -+ return NULL; -+ } -+ } -+ 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); -+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ return NULL; -+ } -+ -+ if (p_CcNode->parseCode == CC_PC_ILLEGAL) -+ { -+ DeleteNode(p_CcNode); -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type")); -+ return NULL; -+ } -+ -+ if ((p_CcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY) || -+ !p_CcNode->sizeOfExtraction) -+ { -+ DeleteNode(p_CcNode); -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("sizeOfExatrction can not be greater than 56 and not 0")); -+ return NULL; -+ } -+ -+ if (p_CcNodeParam->keysParams.keySize != p_CcNode->sizeOfExtraction) -+ { -+ DeleteNode(p_CcNode); -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction")); -+ return NULL; -+ } -+ -+ 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); -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction")); -+ return NULL; -+ } -+ -+ /* 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); -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return NULL; -+ } -+ -+ 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); -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return NULL; -+ } -+ } -+ -+ /* 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_Ad = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, -+ FM_PCD_CC_AD_ENTRY_SIZE, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_CcNode->h_Ad) -+ { -+ DeleteNode(p_CcNode); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC action descriptor")); -+ return NULL; -+ } -+ } -+ 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); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC frame length ranges array")); -+ return NULL; -+ } -+ -+ /* Initialize using value received from the user */ -+ for (tmp = 0; tmp < p_CcNode->numOfStatsFLRs; tmp++) -+ { -+ h_StatsFLRs = PTR_MOVE(p_CcNode->h_StatsFLRs, tmp * FM_PCD_CC_STATS_FLR_SIZE); -+ -+ Mem2IOCpy32(h_StatsFLRs, -+ &(p_CcNodeParam->keysParams.frameLengthRanges[tmp]), -+ 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); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node key match table")); -+ return NULL; -+ } -+ IOMemSet32((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); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptors table")); -+ return NULL; -+ } -+ IOMemSet32((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 */ -+ Mem2IOCpy32((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) -+ { -+ Mem2IOCpy32(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) -+ { -+ IOMemSet32(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); -+ -+ 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 NULL; -+ } -+ -+ /* 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); -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return NULL; -+ } -+ p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE); -+ } -+ } -+ -+ FmPcdLockUnlockAll(h_FmPcd); -+ return p_CcNode; -+} -+ -+t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ int i = 0; -+ -+ 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); -+ -+ 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_List h_List; -+ 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); -+ -+ 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 = FmPcdCcModifyKey(p_FmPcd, -+ p_CcNode, -+ keyIndex, -+ keySize, -+ p_Key, -+ p_Mask); -+ -+ 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_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); -+ -+ 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_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")); -+ } -+ -+ 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); -+ -+ 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_Handle h_CcNode; -+ t_FmPcdCcKeyParams *p_HashKeyParams; -+ int i; -+ uint16_t numOfSets, numOfWays, countMask, onesCount = 0; -+ -+ 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; -+ } -+ -+#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")); -+ -+ /* 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++) -+ { -+ h_CcNode = FM_PCD_MatchTableSet(h_FmPcd, p_ExactMatchCcNodeParam); -+ if (!h_CcNode) -+ break; -+ -+ p_HashKeyParams[i].ccNextEngineParams.nextEngine = e_FM_PCD_CC; -+ p_HashKeyParams[i].ccNextEngineParams.statisticsEn = FALSE; -+ p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode = h_CcNode; -+ } -+ -+ if (i < numOfSets) -+ { -+ for (i = i-1; i >=0; i--) -+ FM_PCD_MatchTableDelete(p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode); -+ -+ 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; -+ p_IndxHashCcNodeParam->keysParams.numOfKeys = numOfSets; /* Number of keys of this node is number of sets of the hash */ -+ p_IndxHashCcNodeParam->keysParams.keySize = 2; -+ -+ p_CcNodeHashTbl = FM_PCD_MatchTableSet(h_FmPcd, p_IndxHashCcNodeParam); -+ -+ 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 *p_HashBuckets; -+ uint16_t i, numOfBuckets; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); -+ -+ 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; -+ -+ err = FM_PCD_MatchTableDelete(p_HashTbl); -+ -+ for (i = 0; i < numOfBuckets; i++) -+ err |= FM_PCD_MatchTableDelete(p_HashBuckets[i]); -+ -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ XX_Free(p_HashBuckets); -+ -+ 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->userOffset, -+ &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->userOffset, -+ &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->userOffset, -+ &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; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(h_HashTbl, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); -+ -+ 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); -+ } -+ -+ 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->userOffset, -+ &h_HashBucket, -+ &bucketIndex, -+ &lastIndex); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return FM_PCD_MatchTableFindNGetKeyStatistics(h_HashBucket, -+ keySize, -+ p_Key, -+ NULL, -+ p_KeyStatistics); -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_cc.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_cc.h -new file mode 100644 -index 0000000..9efe721 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_cc.h -@@ -0,0 +1,390 @@ -+/* -+ * 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 MAX(FM_PCD_MAX_NUM_OF_KEYS + 1, FM_PCD_MAX_NUM_OF_FLOWS) -+ -+#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_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 -+ -+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 -+ -+/***********************************************************************/ -+/* Memory map */ -+/***********************************************************************/ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+typedef _Packed struct -+{ -+ volatile uint32_t fqid; -+ volatile uint32_t plcrProfile; -+ volatile uint32_t nia; -+ volatile uint32_t res; -+} _PackedType t_AdOfTypeResult; -+ -+typedef _Packed struct -+{ -+ volatile uint32_t ccAdBase; -+ volatile uint32_t matchTblPtr; -+ volatile uint32_t pcAndOffsets; -+ volatile uint32_t gmask; -+} _PackedType t_AdOfTypeContLookup; -+ -+typedef _Packed struct -+{ -+ volatile uint32_t profileTableAddr; -+ volatile uint32_t reserved; -+ volatile uint32_t nextActionIndx; -+ volatile uint32_t statsTableAddr; -+} _PackedType t_AdOfTypeStats; -+ -+typedef _Packed union -+{ -+ volatile t_AdOfTypeResult adResult; -+ volatile t_AdOfTypeContLookup adContLookup; -+} _PackedType t_Ad; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+/***********************************************************************/ -+/* Driver's internal structures */ -+/***********************************************************************/ -+ -+typedef enum e_ModifyState -+{ -+ e_MODIFY_STATE_ADD = 0, -+ e_MODIFY_STATE_REMOVE, -+ e_MODIFY_STATE_CHANGE -+} e_ModifyState; -+ -+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 glblMaskUpdated; -+ t_Handle p_GlblMask; -+ bool lclMask; -+ uint8_t parseCode; -+ uint8_t offset; -+ uint8_t prsArrayOffset; -+ bool ctrlFlow; -+ uint8_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_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; -+ -+ t_Handle h_Spinlock; -+ -+ t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS]; -+} t_FmPcdCcNode; -+ -+typedef struct -+{ -+ t_FmPcdCcNode *p_FmPcdCcNode; -+ bool occupied; -+ uint8_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; -+ uint8_t owners; -+ t_Handle h_FmPcdCcSavedManipParams; -+ bool modifiedState; -+ uint32_t requiredAction; -+ t_Handle h_IpReassemblyManip; -+ -+ t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[FM_PCD_MAX_NUM_OF_CC_GROUPS]; -+} t_FmPcdCcTree; -+ -+ -+bool FmPcdManipIsManipNode(t_Handle h_Ad); -+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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_kg.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_kg.c -new file mode 100644 -index 0000000..bdbc8ae ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_kg.c -@@ -0,0 +1,3263 @@ -+/* -+ * 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; -+ 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: -+ 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 UpateSchemePointedOwner(t_FmPcdKgScheme *p_Scheme, bool add) -+{ -+ /* this routine is locked by the calling routine */ -+ ASSERT_COND(p_Scheme); -+ ASSERT_COND(p_Scheme->valid); -+ -+ if (add) -+ p_Scheme->pointedOwners++; -+ else -+ p_Scheme->pointedOwners--; -+} -+ -+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); -+} -+ -+static uint32_t 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))); -+ */ -+} -+ -+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; -+ } -+ } -+ else -+ ppcTmp = KG_SCH_PP_NO_GEN; -+ } -+ 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; -+ -+ tmpReg = 0; -+ 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) -+ { -+ -+#ifdef FM_CAPWAP_SUPPORT -+ case (HEADER_TYPE_UDP_LITE): -+ p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; -+ break; -+#endif -+ 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.size = p_Extract->extractByHdr.extractByHdrType.fromField.size; -+ /*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.size = p_Extract->extractByHdr.extractByHdrType.fromField.size; -+ 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 */ -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported")); -+ } -+ break; -+ default: -+ 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) -+ RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used")); -+ if (!code) -+ 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)) -+ 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")); -+ -+ 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) -+ 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) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT)); -+ if (p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT) -+ 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))) -+ 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); -+ p_LocalExtractsArray = NULL; -+ -+ } -+ 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) -+ { -+ walking1Mask = 0x80000000; -+ 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, p_Scheme->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 FmPcdKgGetPointedOwners(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].pointedOwners; -+} -+ -+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_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); -+ -+ UpateSchemePointedOwner(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].pointedOwners || -+ !(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); -+ } -+ } -+ -+ UpateSchemePointedOwner(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; -+ } -+ -+ 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); -+ -+ /* 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; -+} -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ int i = 0, j = 0; -+ uint8_t hardwarePortId = 0; -+ uint32_t tmpKgarReg, intFlags; -+ t_Error err = E_OK; -+ -+ DECLARE_DUMP; -+ -+ 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); -+ SANITY_CHECK_RETURN_ERROR(((p_FmPcd->guestId == NCSW_MASTER_ID) || -+ p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs), E_INVALID_OPERATION); -+ -+ DUMP_SUBTITLE(("\n")); -+ DUMP_TITLE(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, ("FmPcdKgRegs Regs")); -+ -+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,fmkg_gcr); -+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,fmkg_eer); -+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,fmkg_eeer); -+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,fmkg_seer); -+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,fmkg_seeer); -+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,fmkg_gsr); -+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,fmkg_tpc); -+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,fmkg_serc); -+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,fmkg_fdor); -+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,fmkg_gdv0r); -+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,fmkg_gdv1r); -+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,fmkg_feer); -+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,fmkg_ar); -+ -+ DUMP_SUBTITLE(("\n")); -+ intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); -+ for (j = 0;jp_FmPcdKg->p_IndirectAccessRegs->schemeRegs, ("FmPcdKgIndirectAccessSchemeRegs Scheme %d Regs", j)); -+ -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs,kgse_mode); -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs,kgse_ekfc); -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs,kgse_ekdv); -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs,kgse_bmch); -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs,kgse_bmcl); -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs,kgse_fqb); -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs,kgse_hc); -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs,kgse_ppc); -+ -+ DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_gec, ("kgse_gec")); -+ DUMP_SUBSTRUCT_ARRAY(i, FM_KG_NUM_OF_GENERIC_REGS) -+ { -+ DUMP_MEMORY(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_gec[i], sizeof(uint32_t)); -+ } -+ -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs,kgse_spc); -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs,kgse_dv0); -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs,kgse_dv1); -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs,kgse_ccbs); -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs,kgse_mv); -+ } -+ DUMP_SUBTITLE(("\n")); -+ -+ for (i=0;ip_FmPcdKg->p_IndirectAccessRegs->portRegs, ("FmPcdKgIndirectAccessPortRegs PCD Port %d regs", hardwarePortId)); -+ -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->portRegs, fmkg_pe_sp); -+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->portRegs, fmkg_pe_cpp); -+ } -+ -+ DUMP_SUBTITLE(("\n")); -+ for (j=0;jp_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs, ("FmPcdKgIndirectAccessClsPlanRegs Regs group %d", j)); -+ DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs.kgcpe, ("kgcpe")); -+ -+ tmpKgarReg = ReadClsPlanBlockActionReg((uint8_t)j); -+ err = WriteKgarWait(p_FmPcd, tmpKgarReg); -+ if (err) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ DUMP_SUBSTRUCT_ARRAY(i, 8) -+ DUMP_MEMORY(&p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs.kgcpe[i], sizeof(uint32_t)); -+ } -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ -+ return E_OK; -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_kg.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_kg.h -new file mode 100644 -index 0000000..cb7521a ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_manip.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_manip.c -new file mode 100644 -index 0000000..e6c8d2d ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_manip.c -@@ -0,0 +1,4193 @@ -+/* -+ * 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): -+ case (e_FM_PCD_MANIP_RMV_BY_HDR): -+ /* As long as the only rmv command is the L2, no check on type is required */ -+ tableSize += HMCD_BASIC_SIZE; -+ 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): -+ /* As long as the only insert command is the internal L2, no check on type is required */ -+ tableSize += HMCD_BASIC_SIZE+HMCD_PTR_SIZE; -+ if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type == e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2) -+ switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2) -+ { -+ case (e_FM_PCD_MANIP_HDR_INSRT_MPLS): -+ dataSize += p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+ } -+ 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; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("Unknown customParams.type")); -+ } -+ } -+ -+ *p_TableSize = tableSize; -+ *p_DataSize = dataSize; -+ -+ 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; -+ 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) -+ { -+ uint8_t hmcdOpt; -+ if (!p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type == e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+ -+ /* 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; -+ default: -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+ } -+ tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT; -+ } -+ else -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("manip header remove 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 */ -+ for (i = 0; iu.hdr.insrtParams.type == e_FM_PCD_MANIP_INSRT_BY_HDR) -+ { -+ uint8_t hmcdOpt; -+ if (!p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type == e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+ -+ /* 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; -+ 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); -+ Mem2IOCpy32(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; -+ } -+ else -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("manip header insert 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; iu.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) -+ { -+ WRITE_UINT32(*p_TmpHmct, *(uint32_t*)&p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i]); -+ 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) -+ { -+ WRITE_UINT32(*p_TmpHmct, *(uint32_t*)&p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i]); -+ 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); -+ Mem2IOCpy32(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; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("Unknown customParams.type")); -+ } -+ } -+ -+ -+ /* If this node has a nextManip, and no parsing is required after it, the old table must be copied to the new table -+ the old table and should be freed */ -+ if (p_FmPcdManipParams->h_NextManip && -+ (MANIP_DONT_REPARSE(p_FmPcdManipParams->h_NextManip))) -+ { -+ 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; -+ -+ /* 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; -+ -+ /* advance pointer */ -+ p_TmpHmct += MANIP_GET_HMCT_SIZE(p_FmPcdManipParams->h_NextManip)/4; -+ } -+ } -+ 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 */ -+ if (p_FmPcdManipParams->h_NextManip) -+ { -+ if (MANIP_DONT_REPARSE(p_FmPcdManipParams->h_NextManip)) -+ nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip) + GetDataSize(p_FmPcdManipParams->h_NextManip)); -+ else -+ p_Manip->cascadedNext = TRUE; -+ } -+ p_Manip->dontParseAfterManip = p_FmPcdManipParams->u.hdr.dontParseAfterManip; -+ -+ /* 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 && -+ (MANIP_DONT_REPARSE(p_FmPcdManipParams->h_NextManip))) -+ { -+ 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_FmPcdManipParams->h_NextManip)) -+ { -+ /* indicate that there's another HM table descriptor */ -+ tmpReg |= HMTD_CFG_NEXT_AD_EN; -+ WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, -+ (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - -+ (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4)); -+ } -+ -+ 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); -+ -+ 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, *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; -+} -+ -+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; -+#ifdef FM_CAPWAP_SUPPORT -+ 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; -+#endif /* FM_CAPWAP_SUPPORT */ -+ } -+ -+ 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; -+} -+ -+#ifdef FM_CAPWAP_SUPPORT -+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->fragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset; -+ -+ tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets); -+ tmpReg32 |= ((uint32_t)p_Manip->fragParams.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->fragParams.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_FRAG | 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_FRAG | 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->fragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; -+ } -+ else if (validate) -+ { -+ if (p_Manip->fragParams.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_FRAG | 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_FRAG | 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->fragParams.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->fragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks; -+ -+ /*p_ReassmFrmDescrIndxPoolTbl*/ -+ p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl = -+ (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ (uint32_t)(size + 1), -+ 4); -+ if (!p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table")); -+ -+ IOMemSet32(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1)); -+ -+ for ( i = 0; i < size; i++) -+ WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1)); -+ -+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase); -+ -+ WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32); -+ -+ /*p_ReassmFrmDescrPoolTbl*/ -+ p_Manip->fragParams.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->fragParams.p_ReassmFrmDescrPoolTbl) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table")); -+ -+ IOMemSet32(p_Manip->fragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE)); -+ -+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase); -+ -+ WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32); -+ -+ /*p_TimeOutTbl*/ -+ -+ p_Manip->fragParams.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->fragParams.p_TimeOutTbl) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table")); -+ -+ IOMemSet32(p_Manip->fragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE)); -+ -+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.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->fragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; -+ tmpReg32 = GET_UINT32(p_ReassmTbl->mode); -+ tmpReg32|= p_Manip->fragParams.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->fragParams.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->fragParams.prOffset << 24; -+ WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32); -+ p_Manip->updateParams &= ~OFFSET_OF_PR; -+ p_Manip->shadowUpdateParams |= OFFSET_OF_PR; -+ } -+ else -+ { -+ p_Manip->fragParams.prOffset = 0xff; -+ p_Manip->updateParams &= ~OFFSET_OF_PR; -+ p_Manip->shadowUpdateParams |= OFFSET_OF_PR; -+ } -+ -+ p_Manip->fragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId; -+ p_Manip->updateParams &= ~HW_PORT_ID; -+ p_Manip->shadowUpdateParams |= HW_PORT_ID; -+ -+ /*timeout hc */ -+ ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->fragParams.fqidForTimeOutFrames; -+ ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->fragParams.hwPortId << 24; -+ ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase)); -+ ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<fragParams.bitFor1Micro) * p_Manip->fragParams.timeoutRoutineRequestTime)/2; -+ return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams); -+ } -+ -+ else if (validate) -+ { -+ if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->fragParams.hwPortId) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port")); -+ if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->fragParams.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->fragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value ")); -+ } -+ else -+ { -+ if (p_Manip->fragParams.prOffset != 0xff) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value ")); -+ } -+ if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->fragParams.dataOffset) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value ")); -+ } -+ -+ return E_OK; -+} -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_FmPcdCcIpReassmTimeoutParams ccIpReassmTimeoutParams = {0}; -+ t_Error err = E_OK; -+ uint8_t result; -+ uint32_t bitFor1Micro, tsbs, log2num; -+ -+ ASSERT_COND(p_FmPcd); -+ ASSERT_COND(h_IpReasmCommonPramTbl); -+ -+ bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); -+ bitFor1Micro = 32 - bitFor1Micro; -+ LOG2(FM_PCD_MANIP_IP_REASSM_TIMEOUT_THREAD_THRESH, log2num); -+ tsbs = bitFor1Micro - log2num; -+ -+ ccIpReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(h_IpReasmCommonPramTbl) - p_FmPcd->physicalMuramBase); -+ ccIpReassmTimeoutParams.tsbs = (uint8_t)tsbs; -+ ccIpReassmTimeoutParams.activate = TRUE; -+ if ((err = FmHcPcdCcIpTimeoutReassm(p_FmPcd->h_Hc, &ccIpReassmTimeoutParams, &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")); -+ 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 CreateIpReassCommonTable(t_FmPcdManip *p_Manip) -+{ -+ uint32_t tmpReg32 = 0, i; -+ uint64_t tmpReg64, size; -+ t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; -+ t_Error err = E_OK; -+ -+ /* Allocation of the IP 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. -+ It contains parameters that are common to both the IPv4 reassembly function and IPv6 -+ reassembly function.*/ -+ p_Manip->ipReassmParams.p_IpReassCommonTbl = -+ (t_IpReassCommonTbl *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_SIZE, -+ FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_ALIGN); -+ -+ if (!p_Manip->ipReassmParams.p_IpReassCommonTbl) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Reassembly common parameters table")); -+ -+ IOMemSet32(p_Manip->ipReassmParams.p_IpReassCommonTbl, 0, FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_SIZE); -+ -+ /* Setting the TimeOut Mode.*/ -+ tmpReg32 = 0; -+ if (p_Manip->ipReassmParams.timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES) -+ tmpReg32 |= FM_PCD_MANIP_IP_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->ipReassmParams.fqidForTimeOutFrames; -+ WRITE_UINT32(p_Manip->ipReassmParams.p_IpReassCommonTbl->timeoutModeAndFqid, tmpReg32); -+ -+ /* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/ -+ size = p_Manip->ipReassmParams.maxNumFramesInProcess + 129; -+ -+ /*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */ -+ p_Manip->ipReassmParams.reassFrmDescrIndxPoolTblAddr = -+ PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ (uint32_t)(size * 2), -+ 256)); -+ if (!p_Manip->ipReassmParams.reassFrmDescrIndxPoolTblAddr) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Reassembly frame descriptor indexes pool")); -+ -+ IOMemSet32(UINT_TO_PTR(p_Manip->ipReassmParams.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->ipReassmParams.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->ipReassmParams.reassFrmDescrIndxPoolTblAddr)) - p_FmPcd->physicalMuramBase); -+ WRITE_UINT32(p_Manip->ipReassmParams.p_IpReassCommonTbl->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->ipReassmParams.reassFrmDescrPoolTblAddr = -+ PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->ipReassmParams.dataMemId, 64)); -+ -+ if (!p_Manip->ipReassmParams.reassFrmDescrPoolTblAddr) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED")); -+ -+ IOMemSet32(UINT_TO_PTR(p_Manip->ipReassmParams.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->ipReassmParams.reassFrmDescrPoolTblAddr))); -+ tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.dataLiodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT); -+ tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.dataLiodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT); -+ WRITE_UINT32(p_Manip->ipReassmParams.p_IpReassCommonTbl->liodnAndReassFrmDescPoolPtrHi, (uint32_t)(tmpReg64 >> 32)); -+ WRITE_UINT32(p_Manip->ipReassmParams.p_IpReassCommonTbl->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->ipReassmParams.timeOutTblAddr = -+ PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8)); -+ -+ if (!p_Manip->ipReassmParams.timeOutTblAddr) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Reassembly timeout table")); -+ -+ IOMemSet32(UINT_TO_PTR(p_Manip->ipReassmParams.timeOutTblAddr), 0, (uint16_t)(size * 8)); -+ -+ /* Sets the TimeOut table offset from MURAM */ -+ tmpReg32 = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->ipReassmParams.timeOutTblAddr)) - p_FmPcd->physicalMuramBase); -+ WRITE_UINT32(p_Manip->ipReassmParams.p_IpReassCommonTbl->timeOutTblPtr, tmpReg32); -+ -+ /* Sets the Expiration Delay */ -+ tmpReg32 = 0; -+ tmpReg32 |= (((uint32_t)(1 << FmGetTimeStampScale(p_FmPcd->h_Fm))) * p_Manip->ipReassmParams.timeoutThresholdForReassmProcess); -+ WRITE_UINT32(p_Manip->ipReassmParams.p_IpReassCommonTbl->expirationDelay, tmpReg32); -+ -+ err = FmPcdRegisterReassmPort(p_FmPcd, p_Manip->ipReassmParams.p_IpReassCommonTbl); -+ if (err != E_OK) -+ { -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.p_IpReassCommonTbl); -+ RETURN_ERROR(MAJOR, err, ("port registration")); -+ } -+ -+ return err; -+} -+ -+static t_Error CreateIpReassTable(t_FmPcdManip *p_Manip, bool ipv4) -+{ -+ 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; -+ uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr; -+ t_IpReassTbl **p_IpReassTbl; -+ -+ if (ipv4) -+ { -+ p_IpReassTbl = &p_Manip->ipReassmParams.p_Ipv4ReassTbl; -+ p_AutoLearnHashTblAddr = &p_Manip->ipReassmParams.ipv4AutoLearnHashTblAddr; -+ p_AutoLearnSetLockTblAddr = &p_Manip->ipReassmParams.ipv4AutoLearnSetLockTblAddr; -+ minFragSize = p_Manip->ipReassmParams.minFragSize[0]; -+ numOfWays = p_Manip->ipReassmParams.numOfFramesPerHashEntry[0]; -+ keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */ -+ } -+ else -+ { -+ p_IpReassTbl = &p_Manip->ipReassmParams.p_Ipv6ReassTbl; -+ p_AutoLearnHashTblAddr = &p_Manip->ipReassmParams.ipv6AutoLearnHashTblAddr; -+ p_AutoLearnSetLockTblAddr = &p_Manip->ipReassmParams.ipv6AutoLearnSetLockTblAddr; -+ minFragSize = p_Manip->ipReassmParams.minFragSize[1]; -+ numOfWays = p_Manip->ipReassmParams.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")); -+ } -+ 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 IP Reassembly Parameters Table - This table is located in the MURAM.*/ -+ *p_IpReassTbl = (t_IpReassTbl *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ FM_PCD_MANIP_IP_REASM_TABLE_SIZE, -+ FM_PCD_MANIP_IP_REASM_TABLE_ALIGN); -+ if (!*p_IpReassTbl) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Reassembly IPv4/IPv6 specific parameters table")); -+ memset(*p_IpReassTbl, 0, sizeof(t_IpReassTbl)); -+ -+ /* Sets the IP Reassembly common Parameters table offset from MURAM in the IP Reassembly Table descriptor*/ -+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->ipReassmParams.p_IpReassCommonTbl) - p_FmPcd->physicalMuramBase); -+ WRITE_UINT32((*p_IpReassTbl)->ipReassCommonPrmTblPtr, 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_IpReassTbl)->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->ipReassmParams.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_IpReassTbl)->autoLearnHashKeyMask, (uint16_t)(numOfSets - 1)); -+ -+ /* Allocation of IP 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->ipReassmParams.dataMemId, setSize)); -+ if (!*p_AutoLearnHashTblAddr) -+ { -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_IpReassTbl); -+ *p_IpReassTbl = NULL; -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED")); -+ } -+ IOMemSet32(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize); -+ -+ /* Sets the IP Reassembly Automatic Learning Hash Table and liodn offset */ -+ tmpReg64 = ((uint64_t)(p_Manip->ipReassmParams.dataLiodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT); -+ tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.dataLiodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT); -+ tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr)); -+ WRITE_UINT32((*p_IpReassTbl)->liodnAlAndAutoLearnHashTblPtrHi, (uint32_t)(tmpReg64 >> 32)); -+ WRITE_UINT32((*p_IpReassTbl)->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 IP 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->ipReassmParams.dataMemId, 4)); -+ if (!*p_AutoLearnSetLockTblAddr) -+ { -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_IpReassTbl); -+ *p_IpReassTbl = NULL; -+ XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr)); -+ *p_AutoLearnHashTblAddr = 0; -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED")); -+ } -+ IOMemSet32(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4)); -+ -+ /* sets Set Lock table pointer and liodn offset*/ -+ tmpReg64 = ((uint64_t)(p_Manip->ipReassmParams.dataLiodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT); -+ tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.dataLiodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT); -+ tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr)); -+ WRITE_UINT32((*p_IpReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi, (uint32_t)(tmpReg64 >> 32)); -+ WRITE_UINT32((*p_IpReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64); -+ -+ /* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */ -+ WRITE_UINT16((*p_IpReassTbl)->minFragSize, minFragSize); -+ -+ return E_OK; -+} -+ -+static t_Error UpdateInitIpReasm(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) -+ uint8_t *p_Ptr; -+#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), 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))) || -+ ((p_Manip->shadowUpdateParams & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS)))) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); -+ -+ fmPortGetSetCcParams.setCcParams.type = 0; -+ fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams; -+ 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)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously")); -+ } -+ else if (validate) -+ { -+ if ((!(p_Manip->shadowUpdateParams & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS))) || -+ ((p_Manip->updateParams & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS)))) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated")); -+ -+ fmPortGetSetCcParams.setCcParams.type = 0; -+ fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams; -+ 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)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously")); -+ } -+ -+ if (p_Manip->updateParams) -+ { -+ if (p_Manip->updateParams & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS)) -+ { -+ 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->ipReassmParams.internalBufferPoolAddr = -+ PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS), -+ BMI_FIFO_UNITS)); -+ if (!p_Manip->ipReassmParams.internalBufferPoolAddr) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Reassembly internal buffers pool")); -+ IOMemSet32(UINT_TO_PTR(p_Manip->ipReassmParams.internalBufferPoolAddr), -+ 0, -+ (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS)); -+ -+ p_Manip->ipReassmParams.internalBufferPoolManagementIndexAddr = -+ PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ (uint32_t)(5 + totalNumOfTnums), -+ 4)); -+ if (!p_Manip->ipReassmParams.internalBufferPoolManagementIndexAddr) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Reassembly internal buffers management")); -+ -+ p_Ptr = (uint8_t*)UINT_TO_PTR(p_Manip->ipReassmParams.internalBufferPoolManagementIndexAddr); -+ WRITE_UINT32(*(uint32_t*)p_Ptr, (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->ipReassmParams.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_IP_REASM_COMMON_INT_BUFFER_IDX_SHIFT) | -+ ((uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->ipReassmParams.internalBufferPoolManagementIndexAddr)) - p_FmPcd->physicalMuramBase)); -+ WRITE_UINT32(p_Manip->ipReassmParams.p_IpReassCommonTbl->internalBufferManagement, tmpReg32); -+ -+ p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS); -+ p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS); -+ } -+ } -+ -+ if (p_Manip->ipReassmParams.h_Ipv4Scheme) -+ { -+ p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] = p_Manip->ipReassmParams.h_Ipv4Scheme; -+ p_PcdParams->p_KgParams->numOfSchemes++; -+ } -+ if (p_Manip->ipReassmParams.h_Ipv6Scheme) -+ { -+ p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] = p_Manip->ipReassmParams.h_Ipv6Scheme; -+ p_PcdParams->p_KgParams->numOfSchemes++; -+ } -+ -+#if (DPAA_VERSION >= 11) -+ memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); -+ fmPortGetSetCcParams.setCcParams.type = 0; -+ fmPortGetSetCcParams.getCcParams.type = FM_REV; -+ if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6) -+ { -+ if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE, (void**)&p_Ptr)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ tmpReg32 = NIA_ENG_KG; -+ if (p_Manip->ipReassmParams.h_Ipv4Scheme) -+ { -+ tmpReg32 |= NIA_KG_DIRECT; -+ tmpReg32 |= NIA_KG_CC_EN; -+ tmpReg32 |= FmPcdKgGetSchemeId(p_Manip->ipReassmParams.h_Ipv4Scheme); -+ WRITE_UINT32(*(uint32_t*)PTR_MOVE(p_Ptr, NIA_IPR_DIRECT_SCHEME_IPV4_OFFSET), tmpReg32); -+ } -+ if (p_Manip->ipReassmParams.h_Ipv6Scheme) -+ { -+ tmpReg32 &= ~NIA_AC_MASK; -+ tmpReg32 |= NIA_KG_DIRECT; -+ tmpReg32 |= NIA_KG_CC_EN; -+ tmpReg32 |= FmPcdKgGetSchemeId(p_Manip->ipReassmParams.h_Ipv6Scheme); -+ WRITE_UINT32(*(uint32_t*)PTR_MOVE(p_Ptr, NIA_IPR_DIRECT_SCHEME_IPV6_OFFSET), tmpReg32); -+ } -+ } -+#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 (p_Manip->h_Frag) -+ { -+ if (p_Manip->fragParams.p_AutoLearnHashTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_AutoLearnHashTbl); -+ if (p_Manip->fragParams.p_ReassmFrmDescrPoolTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_ReassmFrmDescrPoolTbl); -+ if (p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl); -+ if (p_Manip->fragParams.p_TimeOutTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_TimeOutTbl); -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag); -+ -+ } -+ if (p_Manip->frag) -+ { -+ if (p_Manip->ipFragParams.p_Frag) -+ { -+#if (DPAA_VERSION == 10) -+ FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->ipFragParams.scratchBpid); -+#endif /* (DPAA_VERSION == 10) */ -+ -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipFragParams.p_Frag); -+ } -+ } -+ else if (p_Manip->reassm) -+ { -+ FmPcdUnregisterReassmPort(p_FmPcd, p_Manip->ipReassmParams.p_IpReassCommonTbl); -+ -+ if (p_Manip->ipReassmParams.timeOutTblAddr) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_Manip->ipReassmParams.timeOutTblAddr)); -+ if (p_Manip->ipReassmParams.reassFrmDescrPoolTblAddr) -+ XX_FreeSmart(UINT_TO_PTR(p_Manip->ipReassmParams.reassFrmDescrPoolTblAddr)); -+ -+ if (p_Manip->ipReassmParams.ipv4AutoLearnHashTblAddr) -+ XX_FreeSmart(UINT_TO_PTR(p_Manip->ipReassmParams.ipv4AutoLearnHashTblAddr)); -+ if (p_Manip->ipReassmParams.ipv6AutoLearnHashTblAddr) -+ XX_FreeSmart(UINT_TO_PTR(p_Manip->ipReassmParams.ipv6AutoLearnHashTblAddr)); -+ if (p_Manip->ipReassmParams.ipv4AutoLearnSetLockTblAddr) -+ XX_FreeSmart(UINT_TO_PTR(p_Manip->ipReassmParams.ipv4AutoLearnSetLockTblAddr)); -+ if (p_Manip->ipReassmParams.ipv6AutoLearnSetLockTblAddr) -+ XX_FreeSmart(UINT_TO_PTR(p_Manip->ipReassmParams.ipv6AutoLearnSetLockTblAddr)); -+ if (p_Manip->ipReassmParams.p_Ipv4ReassTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.p_Ipv4ReassTbl); -+ if (p_Manip->ipReassmParams.p_Ipv6ReassTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.p_Ipv6ReassTbl); -+ if (p_Manip->ipReassmParams.p_IpReassCommonTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.p_IpReassCommonTbl); -+ if (p_Manip->ipReassmParams.reassFrmDescrIndxPoolTblAddr) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_Manip->ipReassmParams.reassFrmDescrIndxPoolTblAddr)); -+ if (p_Manip->ipReassmParams.internalBufferPoolManagementIndexAddr) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_Manip->ipReassmParams.internalBufferPoolManagementIndexAddr)); -+ if (p_Manip->ipReassmParams.internalBufferPoolAddr) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_Manip->ipReassmParams.internalBufferPoolAddr)); -+ -+ if (p_Manip->ipReassmParams.h_Ipv6Ad) -+ XX_FreeSmart(p_Manip->ipReassmParams.h_Ipv6Ad); -+ if (p_Manip->ipReassmParams.h_Ipv4Ad) -+ XX_FreeSmart(p_Manip->ipReassmParams.h_Ipv4Ad); -+ } -+ -+ if (p_Manip->p_StatsTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl); -+} -+ -+#ifdef FM_CAPWAP_SUPPORT -+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 FM_CAPWAP_SUPPORT */ -+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) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation.")); -+ } -+ -+ 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) : -+ p_Manip->opcode = HMAN_OC; -+ p_Manip->muramAllocate = TRUE; -+ break; -+ default : -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation")); -+ } -+ break; -+ case (e_FM_PCD_MANIP_RMV_GENERIC): -+ p_Manip->opcode = HMAN_OC; -+ p_Manip->muramAllocate = TRUE; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation")); -+ } -+ 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) : -+ case (e_FM_PCD_MANIP_INSRT_GENERIC): -+ p_Manip->opcode = HMAN_OC; -+ p_Manip->muramAllocate = TRUE; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type")); -+ } -+ 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) -+ { -+ 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->ipReassmParams.hdr = HEADER_TYPE_IPv4; -+ break; -+ case (HEADER_TYPE_IPv6): -+ p_Manip->ipReassmParams.hdr = HEADER_TYPE_IPv6; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header for reassembly")); -+ } -+ p_Manip->opcode = HMAN_OC_IP_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): -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header for fragmentation")); -+ } -+ p_Manip->opcode = HMAN_OC_IP_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; -+ 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 FM_CAPWAP_SUPPORT */ -+ -+#ifdef FM_CAPWAP_SUPPORT -+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")); -+ -+ IOMemSet32(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; -+} -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+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_FmPcd); -+ UNUSED(h_FmTree); -+ -+ switch (p_Manip->opcode) -+ { -+ case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): -+ err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort, p_Manip, h_Ad, validate); -+ break; -+#ifdef FM_CAPWAP_SUPPORT -+ 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 /* FM_CAPWAP_SUPPORT */ -+ case (HMAN_OC_IP_REASSEMBLY): -+ err = UpdateInitIpReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad, validate); -+ break; -+ 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) -+ { -+ 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; -+#ifdef FM_CAPWAP_SUPPORT -+ 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 /* FM_CAPWAP_SUPPORT */ -+ default: -+ return E_OK; -+ } -+ -+ return err; -+} -+ -+#ifdef FM_CAPWAP_SUPPORT -+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 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; -+} -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+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; -+} -+ -+#ifdef FM_CAPWAP_SUPPORT -+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; -+ -+ 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")); -+ } -+ -+ 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")); -+ -+ IOMemSet32(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE); -+ -+ p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag; -+ -+ p_Manip->fragParams.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->fragParams.p_AutoLearnHashTbl) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table")); -+ -+ IOMemSet32(p_Manip->fragParams.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->fragParams.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->fragParams.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->fragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess; -+ -+ p_Manip->fragParams.sgBpid = poolId; -+ -+ p_Manip->fragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames; -+ p_Manip->fragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime; -+ p_Manip->fragParams.bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); -+ -+ tmpReg32 = 0; -+ tmpReg32 |= (((uint32_t)1<fragParams.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")); -+ -+ IOMemSet32(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->fragParams.sgBpid = poolId; -+ -+ return E_OK; -+} -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, bool ipv4) -+{ -+ t_AdOfTypeContLookup *p_Ad; -+ t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; -+ uint32_t tmpReg32; -+ t_Error err = E_OK; -+ -+ /* Creates the IP 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 = CreateIpReassTable(p_Manip, ipv4)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ /* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the IP Reassembly Parameters Table offset from MURAM*/ -+ tmpReg32 = 0; -+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; -+ -+ /* Gets the required Action descriptor table pointer */ -+ if (ipv4) -+ { -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->ipReassmParams.h_Ipv4Ad; -+ tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->ipReassmParams.p_Ipv4ReassTbl) - (p_FmPcd->physicalMuramBase)); -+ } -+ else -+ { -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->ipReassmParams.h_Ipv6Ad; -+ tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->ipReassmParams.p_Ipv6ReassTbl) - (p_FmPcd->physicalMuramBase)); -+ } -+ -+ 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); -+ -+#if (DPAA_VERSION == 10) -+ tmpReg32 = (uint32_t)(p_Manip->ipReassmParams.sgBpid << 8); -+ WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32); -+#endif /* (DPAA_VERSION == 10) */ -+#if (DPAA_VERSION >= 11) -+ if (p_Manip->ipReassmParams.nonConsistentSpFqid != 0) -+ { -+ tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK | (uint32_t)(p_Manip->ipReassmParams.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; -+ 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->ipReassmParams.h_Ipv4Ad = -+ (t_Handle)XX_MallocSmart(FM_PCD_CC_AD_ENTRY_SIZE, -+ p_Manip->ipReassmParams.dataMemId, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_Manip->ipReassmParams.h_Ipv4Ad) -+ { -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of IPv4 table descriptor")); -+ } -+ -+ memset(p_Manip->ipReassmParams.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */ -+ return FillReassmManipParams(p_Manip, TRUE); -+} -+ -+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->ipReassmParams.h_Ipv6Ad = -+ (t_Handle)XX_MallocSmart(FM_PCD_CC_AD_ENTRY_SIZE, -+ p_Manip->ipReassmParams.dataMemId, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_Manip->ipReassmParams.h_Ipv6Ad) -+ { -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of IPv6 table descriptor")); -+ } -+ -+ memset(p_Manip->ipReassmParams.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */ -+ return FillReassmManipParams(p_Manip, FALSE); -+} -+ -+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->ipReassmParams.relativeSchemeId[0] = reassmManipParams.relativeSchemeId[0]; -+ p_Manip->ipReassmParams.relativeSchemeId[1] = reassmManipParams.relativeSchemeId[1]; -+ p_Manip->ipReassmParams.numOfFramesPerHashEntry[0] = reassmManipParams.numOfFramesPerHashEntry[0]; -+ p_Manip->ipReassmParams.numOfFramesPerHashEntry[1] = reassmManipParams.numOfFramesPerHashEntry[1]; -+ p_Manip->ipReassmParams.minFragSize[0] = reassmManipParams.minFragSize[0]; -+ p_Manip->ipReassmParams.minFragSize[1] = reassmManipParams.minFragSize[1]; -+ p_Manip->ipReassmParams.maxNumFramesInProcess = reassmManipParams.maxNumFramesInProcess; -+ p_Manip->ipReassmParams.timeOutMode = reassmManipParams.timeOutMode; -+ p_Manip->ipReassmParams.fqidForTimeOutFrames = reassmManipParams.fqidForTimeOutFrames; -+ p_Manip->ipReassmParams.timeoutThresholdForReassmProcess = reassmManipParams.timeoutThresholdForReassmProcess; -+ p_Manip->ipReassmParams.dataMemId = reassmManipParams.dataMemId; -+ p_Manip->ipReassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset; -+#if (DPAA_VERSION == 10) -+ p_Manip->ipReassmParams.sgBpid = reassmManipParams.sgBpid; -+#endif /* (DPAA_VERSION == 10) */ -+#if (DPAA_VERSION >= 11) -+ if (reassmManipParams.nonConsistentSpFqid != 0) -+ { -+ p_Manip->ipReassmParams.nonConsistentSpFqid = reassmManipParams.nonConsistentSpFqid; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ /* Creates and initializes the IP Reassembly common parameter table */ -+ CreateIpReassCommonTable(p_Manip); -+ -+ /* Creation of IPv4 reassembly manipulation */ -+ if ((p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv6) || (p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv4)) -+ { -+ res = SetIpv4ReassmManip(p_Manip); -+ if (res != E_OK) -+ return res; -+ } -+ -+ /* Creation of IPv6 reassembly manipulation */ -+ if (p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv6) -+ { -+ res = SetIpv6ReassmManip(p_Manip); -+ if (res != E_OK) -+ return res; -+ } -+ -+ return E_OK; -+} -+ -+static void setReassmSchemeParams(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; jkeyExtractAndHashParams.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->ipReassmParams.p_IpReassCommonTbl); -+ -+ p_Stats->timeout = GET_UINT32(p_Manip->ipReassmParams.p_IpReassCommonTbl->totalTimeOutCounter); -+ p_Stats->rfdPoolBusy = GET_UINT32(p_Manip->ipReassmParams.p_IpReassCommonTbl->totalRfdPoolBusyCounter); -+ p_Stats->internalBufferBusy = GET_UINT32(p_Manip->ipReassmParams.p_IpReassCommonTbl->totalInternalBufferBusy); -+ p_Stats->externalBufferBusy = GET_UINT32(p_Manip->ipReassmParams.p_IpReassCommonTbl->totalExternalBufferBusy); -+ p_Stats->sgFragments = GET_UINT32(p_Manip->ipReassmParams.p_IpReassCommonTbl->totalSgFragmentCounter); -+ p_Stats->dmaSemaphoreDepletion = GET_UINT32(p_Manip->ipReassmParams.p_IpReassCommonTbl->totalDmaSemaphoreDepletionCounter); -+ -+ if (p_Manip->ipReassmParams.p_Ipv4ReassTbl) -+ { -+ p_Stats->specificHdrStatistics[0].successfullyReassembled = GET_UINT32(p_Manip->ipReassmParams.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter); -+ p_Stats->specificHdrStatistics[0].validFragments = GET_UINT32(p_Manip->ipReassmParams.p_Ipv4ReassTbl->totalValidFragmentCounter); -+ p_Stats->specificHdrStatistics[0].processedFragments = GET_UINT32(p_Manip->ipReassmParams.p_Ipv4ReassTbl->totalProcessedFragCounter); -+ p_Stats->specificHdrStatistics[0].malformedFragments = GET_UINT32(p_Manip->ipReassmParams.p_Ipv4ReassTbl->totalMalformdFragCounter); -+ p_Stats->specificHdrStatistics[0].autoLearnBusy = GET_UINT32(p_Manip->ipReassmParams.p_Ipv4ReassTbl->totalSetBusyCounter); -+ p_Stats->specificHdrStatistics[0].discardedFragments = GET_UINT32(p_Manip->ipReassmParams.p_Ipv4ReassTbl->totalDiscardedFragsCounter); -+ p_Stats->specificHdrStatistics[0].moreThan16Fragments = GET_UINT32(p_Manip->ipReassmParams.p_Ipv4ReassTbl->totalMoreThan16FramesCounter); -+ } -+ if (p_Manip->ipReassmParams.p_Ipv6ReassTbl) -+ { -+ p_Stats->specificHdrStatistics[1].successfullyReassembled = GET_UINT32(p_Manip->ipReassmParams.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter); -+ p_Stats->specificHdrStatistics[1].validFragments = GET_UINT32(p_Manip->ipReassmParams.p_Ipv6ReassTbl->totalValidFragmentCounter); -+ p_Stats->specificHdrStatistics[1].processedFragments = GET_UINT32(p_Manip->ipReassmParams.p_Ipv6ReassTbl->totalProcessedFragCounter); -+ p_Stats->specificHdrStatistics[1].malformedFragments = GET_UINT32(p_Manip->ipReassmParams.p_Ipv6ReassTbl->totalMalformdFragCounter); -+ p_Stats->specificHdrStatistics[1].autoLearnBusy = GET_UINT32(p_Manip->ipReassmParams.p_Ipv6ReassTbl->totalSetBusyCounter); -+ p_Stats->specificHdrStatistics[1].discardedFragments = GET_UINT32(p_Manip->ipReassmParams.p_Ipv6ReassTbl->totalDiscardedFragsCounter); -+ p_Stats->specificHdrStatistics[1].moreThan16Fragments = GET_UINT32(p_Manip->ipReassmParams.p_Ipv6ReassTbl->totalMoreThan16FramesCounter); -+ } -+ return E_OK; -+} -+ -+#ifdef FM_CAPWAP_SUPPORT -+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; -+ } -+ -+ Mem2IOCpy32(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; -+} -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+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->ipFragParams.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->ipFragParams.p_Frag->ccAdBase) & 0x00ffffff; -+ p_Stats->generatedFragments = GET_UINT32(p_Manip->ipFragParams.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->ipFragParams.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->ipFragParams.p_Frag) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Fragmentation table descriptor")); -+ IOMemSet32( p_Manip->ipFragParams.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->ipFragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg); -+ WRITE_UINT32(p_Manip->ipFragParams.p_Frag->ccAdBase, ccAdBaseReg); -+ WRITE_UINT32(p_Manip->ipFragParams.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->ipFragParams.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->ipFragParams.p_Frag); -+ p_Manip->ipFragParams.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->ipFragParams.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 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; -+ -+ 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); -+ -+ 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; -+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); -+ -+ tmpReg32 = HMAN_OC_IPSEC_MANIP; -+ tmpReg32 |= p_IPSecParams->outerIPHdrLen << FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT; -+ 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_IPSEC_NADEN; -+ } -+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); -+ -+ return err; -+} -+ -+#ifdef FM_CAPWAP_SUPPORT -+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 /* FM_CAPWAP_SUPPORT */ -+ -+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); -+#ifdef FM_CAPWAP_SUPPORT -+ else -+ err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params); -+#else -+ else -+ { -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!")); -+ return NULL; -+ } -+#endif /* FM_CAPWAP_SUPPORT */ -+ if (err) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("INVALID HEADER MANIPULATION TYPE")); -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+ -+ if (p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) -+ { -+ /* In Case of IP reassembly manipulation the IPv4/IPv6 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; -+ } -+ -+ IOMemSet32(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 */ -+ IO2IOCpy32(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.")); -+} -+ -+/*****************************************************************************/ -+/* 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; -+} -+ -+uint32_t FmPcdManipGetRequiredAction (t_Handle h_Manip) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; -+ -+ ASSERT_COND(h_Manip); -+ -+ switch (p_Manip->opcode) -+ { -+ case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): -+ case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): -+ return UPDATE_NIA_ENQ_WITHOUT_DMA; -+ default: -+ return 0; -+ } -+} -+ -+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; -+ t_Error err; -+ 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) -+ { -+ 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; -+ case (HMAN_OC_IP_FRAGMENTATION): -+#if (DPAA_VERSION == 10) -+ 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")); -+#else -+ if (!((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_DONE) || -+ (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_PLCR))) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("For this type of header manipulation has to be nextEngine " -+ "e_FM_PCD_DONE or e_FM_PCD_PLCR")); -+#endif /* (DPAA_VERSION == 10) */ -+ p_Manip->ownerTmp++; -+ break; -+ case (HMAN_OC_IP_REASSEMBLY): -+ 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): -+ p_Manip->ownerTmp++; -+ break; -+ case (HMAN_OC): -+ if (( p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC) && MANIP_IS_CASCADE_NEXT(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) -+ { -+ 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; -+ 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) -+ { -+ 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_IPSEC_MANIP): -+ *p_AdNewPtr = p_Manip->h_Ad; -+ break; -+ case (HMAN_OC_IP_FRAGMENTATION): -+ 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->ipReassmParams.ipv6Assigned) -+ { -+ *p_AdNewPtr = p_Manip->ipReassmParams.h_Ipv6Ad; -+ p_Manip->ipReassmParams.ipv6Assigned = TRUE; -+ FmPcdManipUpdateOwner(h_Manip, FALSE); -+ } -+ else -+ { -+ *p_AdNewPtr = p_Manip->ipReassmParams.h_Ipv4Ad; -+ p_Manip->ipReassmParams.ipv6Assigned = FALSE; -+ } -+ } -+ else -+ *p_AdNewPtr = p_Manip->ipReassmParams.h_Ipv4Ad; -+ memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr, sizeof(t_AdOfTypeContLookup)); -+ *p_AdNewPtr = NULL; -+ 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; -+ 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) -+ { -+ 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; -+ -+ case (HMAN_OC): -+ /* Initialize HMTD within the match table*/ -+ IOMemSet32(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; -+ -+ 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->ipReassmParams.h_Ipv4Scheme) -+ 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->ipReassmParams.relativeSchemeId[0] : -+ p_Manip->ipReassmParams.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) */ -+ -+ setReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId); -+ -+ /* Sets the new scheme */ -+ if (isIpv4) -+ p_Manip->ipReassmParams.h_Ipv4Scheme = FM_PCD_KgSchemeSet(p_FmPcd, p_SchemeParams); -+ else -+ p_Manip->ipReassmParams.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->ipReassmParams.h_Ipv4Scheme) -+ FM_PCD_KgSchemeDelete(p_Manip->ipReassmParams.h_Ipv4Scheme); -+ -+ if (p_Manip->ipReassmParams.h_Ipv6Scheme) -+ FM_PCD_KgSchemeDelete(p_Manip->ipReassmParams.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->ipReassmParams.hdr == HEADER_TYPE_IPv6); -+} -+ -+#ifdef FM_CAPWAP_SUPPORT -+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 /* FM_CAPWAP_SUPPORT */ -+/*********************** 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_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX) || -+ (p_Manip->opcode == HMAN_OC) || -+ (p_Manip->opcode == HMAN_OC_IPSEC_MANIP)) && -+ (!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; -+#ifdef FM_CAPWAP_SUPPORT -+ 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; -+#endif /* FM_CAPWAP_SUPPORT */ -+ case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): -+ /*Application Specific type 1*/ -+ err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE); -+ break; -+ 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-next" 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)) -+ 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); -+ default: -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("no statistics to this type of manip")); -+ } -+ -+ return E_OK; -+} -+ -+#ifdef FM_CAPWAP_SUPPORT -+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 /* FM_CAPWAP_SUPPORT */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_manip.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_manip.h -new file mode 100644 -index 0000000..390ca6e ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_manip.h -@@ -0,0 +1,480 @@ -+/* -+ * 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!!*/ -+ -+#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_CAPWAP_FRAGMENTATION 0x33 -+#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_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 0x35 -+ -+#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 -+ -+#define FM_PCD_MANIP_IP_REASM_TABLE_SIZE 0x40 -+#define FM_PCD_MANIP_IP_REASM_TABLE_ALIGN 8 -+ -+#define FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_SIZE 64 -+#define FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_ALIGN 8 -+#define FM_PCD_MANIP_IP_REASM_TIME_OUT_BETWEEN_FRAMES 0x80000000 -+#define FM_PCD_MANIP_IP_REASM_COUPLING_ENABLE 0x40000000 -+#define FM_PCD_MANIP_IP_REASM_COUPLING_MASK 0xFF000000 -+#define FM_PCD_MANIP_IP_REASM_COUPLING_SHIFT 24 -+#define FM_PCD_MANIP_IP_REASM_LIODN_MASK 0x0000003F -+#define FM_PCD_MANIP_IP_REASM_LIODN_SHIFT 56 -+#define FM_PCD_MANIP_IP_REASM_ELIODN_MASK 0x000003c0 -+#define FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT 38 -+#define FM_PCD_MANIP_IP_REASM_COMMON_INT_BUFFER_IDX_MASK 0x000000FF -+#define FM_PCD_MANIP_IP_REASM_COMMON_INT_BUFFER_IDX_SHIFT 24 -+ -+#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_REASSM_TIMEOUT_THREAD_THRESH 1024 -+#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 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_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_LAST 0x00800000 -+ -+#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_INSRT_L2_MPLS 0 -+#define HMCD_INSRT_N_UPDATE_L2_MPLS 1 -+#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 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_CASCADE_NEXT(h_Manip) (((t_FmPcdManip *)h_Manip)->cascadedNext) -+#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__) && ... */ -+ -+typedef _Packed 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]; -+} _PackedType t_CapwapReasmPram; -+ -+typedef _Packed struct t_IpReassTbl { -+ volatile uint16_t waysNumAndSetSize; -+ volatile uint16_t autoLearnHashKeyMask; -+ volatile uint32_t ipReassCommonPrmTblPtr; -+ volatile uint32_t liodnAlAndAutoLearnHashTblPtrHi; -+ volatile uint32_t autoLearnHashTblPtrLow; -+ volatile uint32_t liodnSlAndAutoLearnSetLockTblPtrHi; -+ volatile uint32_t autoLearnSetLockTblPtrLow; -+ volatile uint16_t minFragSize; -+ volatile uint16_t reserved1; -+ 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_IpReassTbl; -+ -+typedef _Packed struct t_IpReassCommonTbl { -+ 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 reserved3[2]; -+} _PackedType t_IpReassCommonTbl; -+ -+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 */ -+/***********************************************************************/ -+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_FragParams; -+ -+typedef struct -+{ -+ t_AdOfTypeContLookup *p_Frag; -+#if (DPAA_VERSION == 10) -+ uint8_t scratchBpid; -+#endif /* (DPAA_VERSION == 10) */ -+} t_IpFragParams; -+ -+typedef struct t_IpReassmParams -+{ -+ t_Handle h_Ipv4Ad; -+ t_Handle h_Ipv6Ad; -+ bool ipv6Assigned; -+ e_NetHeaderType hdr; /* Header selection */ -+ t_IpReassCommonTbl *p_IpReassCommonTbl; -+ t_IpReassTbl *p_Ipv4ReassTbl; -+ t_IpReassTbl *p_Ipv6ReassTbl; -+ uintptr_t ipv4AutoLearnHashTblAddr; -+ uintptr_t ipv6AutoLearnHashTblAddr; -+ uintptr_t ipv4AutoLearnSetLockTblAddr; -+ uintptr_t ipv6AutoLearnSetLockTblAddr; -+ 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; -+ uint16_t minFragSize[2]; -+ e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2]; -+ uint8_t relativeSchemeId[2]; -+ t_Handle h_Ipv4Scheme; -+ t_Handle h_Ipv6Scheme; -+ uint32_t nonConsistentSpFqid; -+} t_IpReassmParams; -+ -+ -+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; -+ /* HdrManip parameters*/ -+ uint8_t *p_Hmct; -+ uint8_t *p_Data; -+ bool dontParseAfterManip; -+ bool fieldUpdate; -+ bool custom; -+ uint16_t tableSize; -+ uint8_t dataSize; -+ bool cascadedNext; -+ e_ManipUnifiedPosition unifiedPosition; -+ /* end HdrManip */ -+ uint8_t *p_Template; -+ t_Handle h_Frag; -+ bool frag; -+ bool reassm; -+ uint16_t sizeForFragmentation; -+ uint8_t owner; -+ uint32_t updateParams; -+ uint32_t shadowUpdateParams; -+ t_FragParams fragParams; -+ union { -+ t_IpReassmParams ipReassmParams; -+ t_IpFragParams ipFragParams; -+ }; -+ 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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_pcd.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_pcd.c -new file mode 100644 -index 0000000..0f54050 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_pcd.c -@@ -0,0 +1,2112 @@ -+/* -+ * 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); -+ } -+ 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 interchangable, protocolOpt_t opt) -+{ -+ uint8_t i, k; -+ -+ ASSERT_COND(p_FmPcd); -+ -+ if (interchangable) -+ { -+ 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_IpReasmCommonPramTbl) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_FmPcdCcIpReassmTimeoutParams ccIpReassmTimeoutParams = {0}; -+ uint8_t result; -+ t_Error err = E_OK; -+ -+ ASSERT_COND(p_FmPcd); -+ ASSERT_COND(h_IpReasmCommonPramTbl); -+ -+ ccIpReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(h_IpReasmCommonPramTbl) - p_FmPcd->physicalMuramBase); -+ ccIpReassmTimeoutParams.activate = FALSE; /*Disable Timeout Task*/ -+ -+ if ((err = FmHcPcdCcIpTimeoutReassm(p_FmPcd->h_Hc, &ccIpReassmTimeoutParams, &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_Handle FmPcdGetHcHandle(t_Handle h_FmPcd) -+{ -+ ASSERT_COND(h_FmPcd); -+ SANITY_CHECK_RETURN_VALUE(((t_FmPcd*)h_FmPcd)->h_Hc, E_INVALID_HANDLE, NULL); -+ 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_Handle FM_PCD_GetHcDevH(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *) h_FmPcd; -+ -+ return (p_FmPcd) ? FmGcGetHcPortDevH(p_FmPcd->h_Hc) : NULL; -+} -+ -+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); -+ -+ 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->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) -+ { -+ if ((err = PlcrFree(p_FmPcd)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ 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; -+ } -+#ifdef FM_CAPWAP_SUPPORT -+ /* UDP_LITE */ -+ if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_LITE) -+ { -+ /* IPSec UDP encapsulation is currently set to use SHIM1 */ -+ 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 /* 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 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++) -+ { -+ GET_PRS_HDR_NUM(hdrNum, 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 (revInfo.packageRev != IP_OFFLOAD_PACKAGE_NUMBER) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Fman ctrl code package")); -+ -+ 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); -+ -+ default: -+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter")); -+ return 0; -+ } -+} -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_Error err = E_OK; -+ -+ DECLARE_DUMP; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); -+ -+ if (p_FmPcd->p_FmPcdKg) -+ err |= FM_PCD_KgDumpRegs(h_FmPcd); -+ if (p_FmPcd->p_FmPcdPlcr) -+ err |= FM_PCD_PlcrDumpRegs(h_FmPcd); -+ if (p_FmPcd->p_FmPcdPrs) -+ err |= FM_PCD_PrsDumpRegs(h_FmPcd); -+ -+ return err; -+} -+ -+t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ DECLARE_DUMP; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_STATE); -+ -+ return FmHcDumpRegs(p_FmPcd->h_Hc); -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+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; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported exception")); -+ -+ } -+ -+ 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; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported exception")); -+ } -+ /* 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); -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ -+ 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(MINOR, 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; -+ default: -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced")); -+ } -+ -+ 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; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter")); -+ } -+ -+ return E_OK; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_pcd.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_pcd.h -new file mode 100644 -index 0000000..b6b9b35 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_pcd.h -@@ -0,0 +1,540 @@ -+/* -+ * 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 _Packed 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) */ -+} _PackedType 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; -+ uint8_t pointedOwners; -+ uint32_t requiredAction; -+ bool extractedOrs; -+ uint8_t bitOffsetInPlcrProfile; -+ bool directPlcr; -+#if (DPAA_VERSION >= 11) -+ bool vspe; -+#endif -+} t_FmPcdKgScheme; -+ -+typedef _Packed union { -+ struct fman_kg_scheme_regs schemeRegs; -+ struct fman_kg_pe_regs portRegs; -+ struct fman_kg_cp_regs clsPlanRegs; -+} _PackedType 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; -+ uint8_t pointedOwners; -+ 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; -+ 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 interchangable, 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); -+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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_pcd_ipc.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_pcd_ipc.h -new file mode 100644 -index 0000000..5184ce6 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 existance of this header will envoke -+ 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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_plcr.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_plcr.c -new file mode 100644 -index 0000000..ded7960 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_plcr.c -@@ -0,0 +1,1927 @@ -+/* -+ * 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 "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 = (tmp<h_Fm); /* TimeStamp per nano seconds units */ -+ /* we want the tsu to count 10 nano for better precision normally tsu is 3.9 nano, now we will get 39 */ -+ tsuInTenthNanos = (uint32_t)(1000*10/(1<comittedInfoRate > p_NonPassthroughAlgParam->peakOrAccessiveInfoRate) -+ GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->comittedInfoRate, tsuInTenthNanos, 0, &integer, &fraction); -+ else -+ GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrAccessiveInfoRate, 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->comittedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction); -+ *cir = (uint32_t)(integer << 16 | (fraction & 0xFFFF)); -+ GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrAccessiveInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction); -+ *pir_eir = (uint32_t)(integer << 16 | (fraction & 0xFFFF)); -+ -+ *cbs = p_NonPassthroughAlgParam->comittedBurstSize; -+ *pbs_ebs = p_NonPassthroughAlgParam->peakOrAccessiveBurstSize; -+ -+ /* 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; -+ -+ ASSERT_COND(p_FmPcd); -+ -+/* 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.comittedInfoRate > p_ProfileParams->nonPassthroughAlgParams.peakOrAccessiveInfoRate) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than comittedInfoRate.")); -+ 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(p_FmPcd, &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; -+ } -+} -+ -+/*********************************************/ -+/*............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); -+ -+ FmPcdPlcrUpatePointedOwner(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].pointedOwners || -+ !(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); -+ -+ FmPcdPlcrUpatePointedOwner(p_FmPcd, profileIndx, TRUE); -+ FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction); -+ -+ /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/ -+ -+ return E_OK; -+} -+ -+void FmPcdPlcrUpatePointedOwner(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool add) -+{ -+ 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 (add) -+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].pointedOwners++; -+ else -+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].pointedOwners--; -+} -+ -+uint32_t FmPcdPlcrGetPointedOwners(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].pointedOwners; -+} -+ -+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; -+} -+ -+/* ... */ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ int i = 0; -+ -+ DECLARE_DUMP; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(((p_FmPcd->guestId == NCSW_MASTER_ID) || -+ p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs), E_INVALID_OPERATION); -+ -+ DUMP_SUBTITLE(("\n")); -+ DUMP_TITLE(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, ("FM-PCD policer regs")); -+ -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_gcr); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_gsr); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_evr); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_ier); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_ifr); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_eevr); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_eier); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_eifr); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_rpcnt); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_ypcnt); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_rrpcnt); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_rypcnt); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_tpcnt); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_flmcnt); -+ -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_serc); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_upcr); -+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_dpmr); -+ -+ DUMP_TITLE(&p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr, ("fmpl_pmr")); -+ DUMP_SUBSTRUCT_ARRAY(i, 63) -+ { -+ DUMP_MEMORY(&p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i], sizeof(uint32_t)); -+ } -+ -+ return E_OK; -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+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 (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; -+ -+ 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); -+ -+ 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; -+} -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_Profile) -+{ -+ t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile; -+ t_FmPcd *p_FmPcd; -+ t_FmPcdPlcrProfileRegs *p_ProfilesRegs; -+ uint16_t profileIndx; -+ uint32_t tmpReg, intFlags; -+ -+ DECLARE_DUMP; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE); -+ p_FmPcd = p_Profile->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); -+ -+ profileIndx = p_Profile->absoluteProfileId; -+ -+ DUMP_SUBTITLE(("\n")); -+ DUMP_TITLE(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, ("FM-PCD policer-profile regs")); -+ -+ p_ProfilesRegs = &p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs; -+ -+ tmpReg = FmPcdPlcrBuildReadPlcrActionReg((uint16_t)profileIndx); -+ intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr); -+ WritePar(p_FmPcd, tmpReg); -+ -+ DUMP_TITLE(p_ProfilesRegs, ("Profile %d regs", profileIndx)); -+ -+ DUMP_VAR(p_ProfilesRegs, fmpl_pemode); -+ DUMP_VAR(p_ProfilesRegs, fmpl_pegnia); -+ DUMP_VAR(p_ProfilesRegs, fmpl_peynia); -+ DUMP_VAR(p_ProfilesRegs, fmpl_pernia); -+ DUMP_VAR(p_ProfilesRegs, fmpl_pecir); -+ DUMP_VAR(p_ProfilesRegs, fmpl_pecbs); -+ DUMP_VAR(p_ProfilesRegs, fmpl_pepepir_eir); -+ DUMP_VAR(p_ProfilesRegs, fmpl_pepbs_ebs); -+ DUMP_VAR(p_ProfilesRegs, fmpl_pelts); -+ DUMP_VAR(p_ProfilesRegs, fmpl_pects); -+ DUMP_VAR(p_ProfilesRegs, fmpl_pepts_ets); -+ DUMP_VAR(p_ProfilesRegs, fmpl_pegpc); -+ DUMP_VAR(p_ProfilesRegs, fmpl_peypc); -+ DUMP_VAR(p_ProfilesRegs, fmpl_perpc); -+ DUMP_VAR(p_ProfilesRegs, fmpl_perypc); -+ DUMP_VAR(p_ProfilesRegs, fmpl_perrpc); -+ PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); -+ -+ return E_OK; -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_plcr.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_plcr.h -new file mode 100644 -index 0000000..2bb8b96 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_prs.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_prs.c -new file mode 100644 -index 0000000..e198afd ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_prs.c -@@ -0,0 +1,457 @@ -+/* -+ * 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 "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; -+} -+ -+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; -+#ifdef FM_CAPWAP_SUPPORT -+ uint8_t swPrsPatch[] = SW_PRS_UDP_LITE_PATCH; -+#else -+ uint8_t swPrsPatch[] = SW_PRS_IP_FRAG_PATCH; -+#endif /* FM_CAPWAP_SUPPORT */ -+ 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); -+} -+ -+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], 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; -+} -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ DECLARE_DUMP; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(((p_FmPcd->guestId == NCSW_MASTER_ID) || -+ p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs), E_INVALID_OPERATION); -+ -+ DUMP_SUBTITLE(("\n")); -+ DUMP_TITLE(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs, ("FM-PCD parser regs")); -+ -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_rpclim); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_rpimac); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pmeec); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_pevr); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_pever); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_perr); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_perer); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_ppsc); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_pds); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_l2rrs); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_l3rrs); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_l4rrs); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_srrs); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_l2rres); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_l3rres); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_l4rres); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_srres); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_spcs); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_spscs); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_hxscs); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_mrcs); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_mwcs); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_mrscs); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_mwscs); -+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fmpr_fcscs); -+ -+ return E_OK; -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_prs.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_prs.h -new file mode 100644 -index 0000000..3e5974c ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_prs.h -@@ -0,0 +1,193 @@ -+/* -+ * 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 */ -+/***********************************************************************/ -+ -+ -+#ifdef FM_CAPWAP_SUPPORT -+#define SW_PRS_UDP_LITE_PATCH \ -+{\ -+ 0x31,0x92,0x50,0x29,0x00,0x88,0x08,0x16,0x00,0x00, \ -+ 0x00,0x01,0x00,0x05,0x00,0x81,0x1C,0x0B,0x00,0x01, \ -+ 0x1B,0xFF, \ -+} -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+#if (DPAA_VERSION == 10) -+/* Version: 106.1.9 */ -+#define SW_PRS_IP_FRAG_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 -+/* version: 106.3.13 */ -+#define SW_PRS_IP_FRAG_PATCH \ -+{ \ -+ 0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x52,0xF6,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,0x43,0x00,0x00,0x00, \ -+ 0x00,0x01,0x1B,0xFE,0x00,0x00,0x99,0x00,0x53,0x09, \ -+ 0x00,0x00,0x00,0x00,0x9F,0x98,0x53,0x09,0x00,0x00, \ -+ 0x1B,0x24,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,0x0E,0x4F,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x53,0x3C,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,0x43,0x46,0x00,0x00, \ -+ 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x00,0x40, \ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0xAC,0x00,0x00, \ -+ 0x00,0x00,0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55, \ -+ 0x00,0x28,0x28,0x43,0x30,0x7E,0x43,0x5C,0x00,0x00, \ -+ 0x30,0x7E,0x43,0x5C,0x00,0x3C,0x1B,0x74,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,0x55,0x30,0x7E,0x53,0x90, \ -+ 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,0xA7,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,0xF1,0x00,0x00, \ -+ 0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55,0x00,0x28, \ -+ 0x28,0x43,0x30,0x7E,0x43,0xD6,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,0xB3,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, \ -+} -+#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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_replic.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_replic.c -new file mode 100644 -index 0000000..6f8b3a3 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_replic.c -@@ -0,0 +1,991 @@ -+/* -+ * 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) -+ 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); -+ -+ 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); -+ p_ReplicGroup = NULL; -+ } -+} -+ -+ -+/*****************************************************************************/ -+/* 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 (err) -+ { -+ if (GET_ERROR_TYPE(err) == E_BUSY) -+ return ERROR_CODE(E_BUSY); -+ else -+ RETURN_ERROR(MAJOR, err, ("try lock in Add member")); -+ } -+ -+ 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 (err) -+ { -+ if (GET_ERROR_TYPE(err) == E_BUSY) -+ return ERROR_CODE(E_BUSY); -+ else -+ RETURN_ERROR(MAJOR, err, ("try lock in Remove member")); -+ } -+ -+ 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 ************************/ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_replic.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_replic.h -new file mode 100644 -index 0000000..3cfd67e ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fm_replic.h -@@ -0,0 +1,104 @@ -+/* -+ * 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 _Packed struct -+{ -+ volatile uint32_t type; -+ volatile uint32_t frGroupPointer; -+ volatile uint32_t operationCode; -+ volatile uint32_t reserved; -+} _PackedType 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; -+#ifdef UNDER_CONSTRUCTION_STATISTICS_SUPPORT -+ e_FmPcdCcStatsMode statisticsMode; -+#endif /* UNDER_CONSTRUCTION_STATISTICS_SUPPORT */ -+ -+ 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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fman_kg.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fman_kg.c -new file mode 100644 -index 0000000..14a680e ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 = FMAN_KG_SCH_PP_NO_GEN; -+ } 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; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fman_prs.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fman_prs.c -new file mode 100644 -index 0000000..caa1d28 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Pcd/fman_prs.c -@@ -0,0 +1,124 @@ -+/* -+ * 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); -+} -+ -+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); -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Port/Makefile b/drivers/net/dpa/NetCommSw/Peripherals/FM/Port/Makefile -new file mode 100644 -index 0000000..9acf110 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Port/Makefile -@@ -0,0 +1,15 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+ -+NCSW_FM_INC = $(srctree)/drivers/net/dpa/NetCommSw/Peripherals/FM/inc -+ -+EXTRA_CFLAGS += -I$(NCSW_FM_INC) -+ -+obj-y += fsl-ncsw-Pcd.o -+ -+fsl-ncsw-Pcd-objs := fm_port.o fm_port_im.o -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Port/fm_port.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/Port/fm_port.c -new file mode 100644 -index 0000000..b7cd2da ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Port/fm_port.c -@@ -0,0 +1,5725 @@ -+/* -+ * 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 "fm_port.h" -+ -+/****************************************/ -+/* static functions */ -+/****************************************/ -+ -+static t_Error CheckInitParameters(t_FmPort *p_FmPort) -+{ -+ t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; -+ 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->fifoDeqPipelineDepth > 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 & ~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(MINOR, 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 suppported and should not be checked */ -+ || (p_FmPort->fifoDeqPipelineDepth != DEFAULT_notSupported)) -+ { -+ /* Check that not larger than 8 */ -+ if ((!p_FmPort->fifoDeqPipelineDepth) ||( p_FmPort->fifoDeqPipelineDepth > 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)) -+ { -+ /* Check that divisible by 256 and not larger than 256 */ -+ if (p_Params->rxFifoPriElevationLevel % BMI_FIFO_UNITS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS)); -+ if (!p_Params->rxFifoPriElevationLevel || (p_Params->rxFifoPriElevationLevel > BMI_MAX_FIFO_SIZE)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoPriElevationLevel has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE)); -+ if (p_Params->rxFifoThreshold % BMI_FIFO_UNITS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS)); -+ if (!p_Params->rxFifoThreshold ||(p_Params->rxFifoThreshold > BMI_MAX_FIFO_SIZE)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoThreshold has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE)); -+ -+ /* Check that not larger than 16 */ -+ if (p_Params->cutBytesFromEnd > 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_Params->cutBytesFromEnd + p_Params->cheksumLastBytesIgnore > 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)) -+ { -+ /* Check that divisible by 256 and not larger than 256 */ -+ if (p_Params->txFifoMinFillLevel % BMI_FIFO_UNITS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS)); -+ if (p_Params->txFifoMinFillLevel > (BMI_MAX_FIFO_SIZE - 256)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoMinFillLevel has to be in the range of 0 - %d", BMI_MAX_FIFO_SIZE)); -+ if (p_Params->txFifoLowComfLevel % BMI_FIFO_UNITS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS)); -+ if (!p_Params->txFifoLowComfLevel || (p_Params->txFifoLowComfLevel > BMI_MAX_FIFO_SIZE)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoLowComfLevel has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE)); -+ -+ if (p_FmPort->portType == e_FM_PORT_TYPE_TX) -+ if (p_FmPort->fifoDeqPipelineDepth > 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_Params->frmDiscardOverride && 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->fifoDeqPipelineDepth != 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 > BMI_MAX_FIFO_SIZE))) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoBufs.num has to be in the range of 256 - %d", BMI_MAX_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; -+ -+ /*************************/ -+ /* TX PORTS */ -+ /*************************/ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) || -+ (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) -+ { -+ minFifoSizeRequired = (uint32_t)DIV_CEIL(p_FmPort->maxFrameLength, BMI_FIFO_UNITS); -+ if (p_FmPort->imEn) -+ minFifoSizeRequired += 3*BMI_FIFO_UNITS; -+ else -+ minFifoSizeRequired += (p_FmPort->fifoDeqPipelineDepth+3)*BMI_FIFO_UNITS; -+ -+ /* 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) -+ minFifoSizeRequired += 3*BMI_FIFO_UNITS; -+ else -+ minFifoSizeRequired += 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) -+ minFifoSizeRequired = (uint32_t)(DIV_CEIL(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) -+ { -+#ifdef FM_FIFO_ALLOCATION_ALG -+ if (p_FmPort->fmRevInfo.majorRev == 4) -+ { -+ if (p_FmPort->rxPoolsParams.numOfPools == 1) -+ minFifoSizeRequired = 8*BMI_FIFO_UNITS; -+ else -+ minFifoSizeRequired = (uint32_t)(DIV_CEIL(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS) + -+ (7*BMI_FIFO_UNITS)); -+ } -+ else -+#endif /* FM_FIFO_ALLOCATION_ALG */ -+ minFifoSizeRequired = (uint32_t)(DIV_CEIL(p_FmPort->rxPoolsParams.largestBufSize, BMI_FIFO_UNITS) + -+ (7*BMI_FIFO_UNITS)); -+ -+ if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) -+ minFifoSizeRequired += 12*BMI_FIFO_UNITS; -+ else -+ minFifoSizeRequired += 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)) -+ minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 4)*BMI_FIFO_UNITS); -+ -+ /* for all ports - verify size */ -+ if (minFifoSizeRequired && (p_FmPort->fifoBufs.num < minFifoSizeRequired)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("User defined FIFO size should be enlarged to %d", -+ minFifoSizeRequired)); -+ -+ /* check if pool size is not too big */ -+ /* This is a definition problem in which if the fifo for the RX port -+ is lower than the largest pool size the hardware will allocate scatter gather -+ buffers even though the frame size can fit in a single buffer. */ -+ if (((p_FmPort->portType == e_FM_PORT_TYPE_RX) || -+ (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ && !p_FmPort->imEn) -+ { -+ if (p_FmPort->rxPoolsParams.largestBufSize > p_FmPort->fifoBufs.num) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("Frame larger than port Fifo size (%u) will be split to more "\ -+ "than a single buffer (S/G) even if shorter than largest buffer size (%u)", -+ p_FmPort->fifoBufs.num, p_FmPort->rxPoolsParams.largestBufSize)); -+ } -+ -+ 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; -+ volatile uint32_t *p_ExtBufRegs; -+ volatile uint32_t *p_BufPoolDepletionReg; -+ bool rxPort; -+ uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS]; -+ uint16_t sizesArray[BM_MAX_NUM_OF_POOLS]; -+ uint8_t numOfPools; -+ int i=0, j=0; -+ uint32_t tmpReg, vector; -+ -+ 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)); -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_ExtBufRegs = p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi; -+ p_BufPoolDepletionReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rmpd; -+ rxPort = TRUE; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_ExtBufRegs = p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oebmpi; -+ p_BufPoolDepletionReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ompd; -+ rxPort = FALSE; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Not available for port type")); -+ } -+ -+ FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray, sizesArray); -+ -+ /* build the register value */ -+ for (i=0;inumOfPoolsUsed;i++) -+ { -+ tmpReg = BMI_EXT_BUF_POOL_VALID | BMI_EXT_BUF_POOL_EN_COUNTER; -+ tmpReg |= ((uint32_t)orderedArray[i] << BMI_EXT_BUF_POOL_ID_SHIFT); -+ tmpReg |= sizesArray[orderedArray[i]]; -+ /* functionality available only for some deriviatives (limited by config) */ -+ if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) -+ for (j=0;jp_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;j++) -+ if (orderedArray[i] == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j]) -+ { -+ tmpReg |= BMI_EXT_BUF_POOL_BACKUP; -+ break; -+ } -+ WRITE_UINT32(*(p_ExtBufRegs+i), tmpReg); -+ } -+ -+ if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) -+ XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools); -+ -+ numOfPools = (uint8_t)(rxPort ? FM_PORT_MAX_NUM_OF_EXT_POOLS:FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS); -+ -+ /* clear unused pools */ -+ for (i=p_ExtBufPools->numOfPoolsUsed;irxPoolsParams.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 */ -+ tmpReg = 0; -+ if (p_BufPoolDepletion->poolsGrpModeEnable) -+ { -+ /* calculate vector for number of pools depletion */ -+ vector = 0; -+ for (i=0;ipoolsToConsider[i]) -+ { -+ for (j=0;jnumOfPoolsUsed;j++) -+ { -+ if (i == orderedArray[j]) -+ { -+ vector |= 0x80000000 >> j; -+ break; -+ } -+ } -+ } -+ } -+ /* configure num of pools and vector for number of pools mode */ -+ tmpReg |= (((uint32_t)p_BufPoolDepletion->numOfPools - 1) << BMI_POOL_DEP_NUM_OF_POOLS_SHIFT); -+ tmpReg |= vector; -+ } -+ -+ if (p_BufPoolDepletion->singlePoolModeEnable) -+ { -+ /* calculate vector for number of pools depletion */ -+ vector = 0; -+ for (i=0;ipoolsToConsiderForSingleMode[i]) -+ { -+ for (j=0;jnumOfPoolsUsed;j++) -+ { -+ if (i == orderedArray[j]) -+ { -+ vector |= 0x00000080 >> j; -+ break; -+ } -+ } -+ } -+ } -+ tmpReg |= vector; -+ } -+ -+#if (DPAA_VERSION >= 11) -+ /* fill QbbPEV */ -+ if (p_BufPoolDepletion->poolsGrpModeEnable || -+ p_BufPoolDepletion->singlePoolModeEnable) -+ { -+ vector = 0; -+ for (i=0; ipfcPrioritiesEn[i] == TRUE) -+ { -+ vector |= 0x00008000 >> i; -+ } -+ } -+ tmpReg |= vector; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ WRITE_UINT32(*p_BufPoolDepletionReg, tmpReg); -+ -+ 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 BmiRxPortInit(t_FmPort *p_FmPort) -+{ -+ t_FmPortRxBmiRegs *p_Regs = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs; -+ uint32_t tmpReg; -+ t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; -+ uint32_t errorsToEnq = 0; -+ t_FmPortPerformanceCnt performanceContersParams; -+ t_Error err; -+ -+ /* check that port is not busy */ -+ if (GET_UINT32(p_Regs->fmbm_rcfg) & BMI_PORT_CFG_EN) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Port(%d,%d) is already enabled",p_FmPort->portType, p_FmPort->portId)); -+ -+ /* Set Config register */ -+ tmpReg = 0; -+ if (p_FmPort->imEn) -+ tmpReg |= BMI_PORT_CFG_IM; -+ /* No discard - all error frames go to error queue */ -+ else if (p_Params->frmDiscardOverride) -+ tmpReg |= BMI_PORT_CFG_FDOVR; -+ -+ WRITE_UINT32(p_Regs->fmbm_rcfg, tmpReg); -+ -+ /* Configure dma attributes */ -+ tmpReg = 0; -+ tmpReg |= (uint32_t)p_Params->dmaSwapData << BMI_DMA_ATTR_SWP_SHIFT; -+ tmpReg |= (uint32_t)p_Params->dmaIntContextCacheAttr << BMI_DMA_ATTR_IC_CACHE_SHIFT; -+ tmpReg |= (uint32_t)p_Params->dmaHeaderCacheAttr << BMI_DMA_ATTR_HDR_CACHE_SHIFT; -+ tmpReg |= (uint32_t)p_Params->dmaScatterGatherCacheAttr << BMI_DMA_ATTR_SG_CACHE_SHIFT; -+ if (p_Params->dmaWriteOptimize) -+ tmpReg |= BMI_DMA_ATTR_WRITE_OPTIMIZE; -+ -+ WRITE_UINT32(p_Regs->fmbm_rda, tmpReg); -+ -+ /* Configure Rx Fifo params */ -+ tmpReg = 0; -+ tmpReg |= ((p_Params->rxFifoPriElevationLevel/BMI_FIFO_UNITS - 1) << BMI_RX_FIFO_PRI_ELEVATION_SHIFT); -+ tmpReg |= ((p_Params->rxFifoThreshold/BMI_FIFO_UNITS - 1) << BMI_RX_FIFO_THRESHOLD_SHIFT); -+ -+ WRITE_UINT32(p_Regs->fmbm_rfp, tmpReg); -+ -+#ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC -+ if (p_FmPort->fmRevInfo.majorRev < 6) -+ /* always allow access to the extra resources */ -+ WRITE_UINT32(p_Regs->fmbm_reth, BMI_RX_FIFO_THRESHOLD_BC); -+#endif /* FM_NO_RESTRICT_ON_ACCESS_RSRC */ -+ -+ /* frame end parameters */ -+ tmpReg = 0; -+ tmpReg |= ((uint32_t)p_Params->cheksumLastBytesIgnore << BMI_RX_FRAME_END_CS_IGNORE_SHIFT); -+ tmpReg |= ((uint32_t)p_Params->cutBytesFromEnd<< BMI_RX_FRAME_END_CUT_SHIFT); -+ -+ WRITE_UINT32(p_Regs->fmbm_rfed, tmpReg); -+ -+ /* IC parameters */ -+ tmpReg = 0; -+ tmpReg |= (((uint32_t)p_Params->intContext.extBufOffset/OFFSET_UNITS) << BMI_IC_TO_EXT_SHIFT); -+ tmpReg |= (((uint32_t)p_Params->intContext.intContextOffset/OFFSET_UNITS) << BMI_IC_FROM_INT_SHIFT); -+ tmpReg |= (((uint32_t)p_Params->intContext.size/OFFSET_UNITS) << BMI_IC_SIZE_SHIFT); -+ -+ WRITE_UINT32(p_Regs->fmbm_ricp, tmpReg); -+ -+ if (!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*/ -+ -+ /* check if the largest external buffer pool is large enough */ -+ if ((p_Params->bufMargins.startMargins + -+ MIN_EXT_BUF_SIZE + -+ p_Params->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_Params->bufMargins.startMargins, -+ p_Params->bufMargins.endMargins, -+ p_FmPort->rxPoolsParams.largestBufSize)); -+ -+ /* buffer margins */ -+ tmpReg = 0; -+ tmpReg |= (((uint32_t)p_Params->bufMargins.startMargins) << BMI_EXT_BUF_MARG_START_SHIFT); -+ tmpReg |= (((uint32_t)p_Params->bufMargins.endMargins) << BMI_EXT_BUF_MARG_END_SHIFT); -+#if (DPAA_VERSION >= 11) -+ if (p_Params->noScatherGather) -+ tmpReg |= BMI_SG_DISABLE; -+#endif -+ WRITE_UINT32(p_Regs->fmbm_rebm, tmpReg); -+ } -+ -+ if (p_FmPort->internalBufferOffset) -+ { -+ tmpReg = (uint32_t)((p_FmPort->internalBufferOffset%OFFSET_UNITS) ? -+ (p_FmPort->internalBufferOffset/OFFSET_UNITS + 1) : -+ (p_FmPort->internalBufferOffset/OFFSET_UNITS)); -+ p_FmPort->internalBufferOffset = (uint8_t)(tmpReg * OFFSET_UNITS); -+ WRITE_UINT32(p_Regs->fmbm_rim, tmpReg << BMI_IM_FOF_SHIFT); -+ } -+ -+ /* NIA */ -+ if (p_FmPort->imEn) -+ WRITE_UINT32(p_Regs->fmbm_rfne, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX); -+ else -+ { -+ tmpReg = 0; -+ if (p_Params->forwardReuseIntContext) -+ tmpReg |= BMI_PORT_RFNE_FRWD_RPD; -+ /* L3/L4 checksum verify is enabled by default. */ -+ /*tmpReg |= BMI_PORT_RFNE_FRWD_DCL4C;*/ -+ WRITE_UINT32(p_Regs->fmbm_rfne, tmpReg | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); -+ } -+ WRITE_UINT32(p_Regs->fmbm_rfene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); -+ -+ /* command attribute */ -+ tmpReg = BMI_CMD_RX_MR_DEF; -+ if (!p_FmPort->imEn) -+ { -+ tmpReg |= BMI_CMD_ATTR_ORDER; -+ if (p_Params->syncReq) -+ tmpReg |= BMI_CMD_ATTR_SYNC; -+ tmpReg |= ((uint32_t)p_Params->color << BMI_CMD_ATTR_COLOR_SHIFT); -+ } -+ -+ WRITE_UINT32(p_Regs->fmbm_rfca, tmpReg); -+ -+ /* default queues */ -+ if (!p_FmPort->imEn) -+ { -+ WRITE_UINT32(p_Regs->fmbm_rfqid, p_Params->dfltFqid); -+ WRITE_UINT32(p_Regs->fmbm_refqid, p_Params->errFqid); -+ } -+ -+ /* set counters */ -+ WRITE_UINT32(p_Regs->fmbm_rstc, BMI_COUNTERS_EN); -+ -+ performanceContersParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; -+ performanceContersParams.queueCompVal = 1; -+ performanceContersParams.dmaCompVal =(uint8_t) p_FmPort->openDmas.num; -+ performanceContersParams.fifoCompVal = p_FmPort->fifoBufs.num; -+ if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &performanceContersParams)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ WRITE_UINT32(p_Regs->fmbm_rpc, BMI_COUNTERS_EN); -+ -+ /* error/status mask - check that if discard OV is set, no -+ discard is required for specific errors.*/ -+ WRITE_UINT32(p_Regs->fmbm_rfsdm, p_Params->errorsToDiscard); -+ -+ errorsToEnq = (RX_ERRS_TO_ENQ & ~p_Params->errorsToDiscard); -+ WRITE_UINT32(p_Regs->fmbm_rfsem, errorsToEnq); -+ -+ return E_OK; -+} -+ -+static t_Error BmiTxPortInit(t_FmPort *p_FmPort) -+{ -+ t_FmPortTxBmiRegs *p_Regs = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs; -+ uint32_t tmpReg; -+ t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; -+ /*uint32_t rateCountUnit;*/ -+ t_FmPortPerformanceCnt performanceContersParams; -+ -+ /* check that port is not busy */ -+ if (GET_UINT32(p_Regs->fmbm_tcfg) & BMI_PORT_CFG_EN) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is already enabled")); -+ -+ tmpReg = 0; -+ if (p_FmPort->imEn) -+ tmpReg |= BMI_PORT_CFG_IM; -+ -+ WRITE_UINT32(p_Regs->fmbm_tcfg, tmpReg); -+ -+ /* Configure dma attributes */ -+ tmpReg = 0; -+ tmpReg |= (uint32_t)p_Params->dmaSwapData << BMI_DMA_ATTR_SWP_SHIFT; -+ tmpReg |= (uint32_t)p_Params->dmaIntContextCacheAttr << BMI_DMA_ATTR_IC_CACHE_SHIFT; -+ tmpReg |= (uint32_t)p_Params->dmaHeaderCacheAttr << BMI_DMA_ATTR_HDR_CACHE_SHIFT; -+ tmpReg |= (uint32_t)p_Params->dmaScatterGatherCacheAttr << BMI_DMA_ATTR_SG_CACHE_SHIFT; -+ -+ WRITE_UINT32(p_Regs->fmbm_tda, tmpReg); -+ -+ /* Configure Tx Fifo params */ -+ tmpReg = 0; -+ tmpReg |= ((p_Params->txFifoMinFillLevel/BMI_FIFO_UNITS) << BMI_TX_FIFO_MIN_FILL_SHIFT); -+ tmpReg |= (((uint32_t)p_FmPort->fifoDeqPipelineDepth - 1) << BMI_FIFO_PIPELINE_DEPTH_SHIFT); -+ tmpReg |= ((p_Params->txFifoLowComfLevel/BMI_FIFO_UNITS - 1) << BMI_TX_LOW_COMF_SHIFT); -+ -+ WRITE_UINT32(p_Regs->fmbm_tfp, tmpReg); -+ -+ /* frame end parameters */ -+ tmpReg = 0; -+ tmpReg |= ((uint32_t)p_Params->cheksumLastBytesIgnore << BMI_FRAME_END_CS_IGNORE_SHIFT); -+ -+ WRITE_UINT32(p_Regs->fmbm_tfed, tmpReg); -+ -+ if (!p_FmPort->imEn) -+ { -+ /* IC parameters */ -+ tmpReg = 0; -+ tmpReg |= (((uint32_t)p_Params->intContext.extBufOffset/OFFSET_UNITS) << BMI_IC_TO_EXT_SHIFT); -+ tmpReg |= (((uint32_t)p_Params->intContext.intContextOffset/OFFSET_UNITS) << BMI_IC_FROM_INT_SHIFT); -+ tmpReg |= (((uint32_t)p_Params->intContext.size/OFFSET_UNITS) << BMI_IC_SIZE_SHIFT); -+ -+ WRITE_UINT32(p_Regs->fmbm_ticp, tmpReg); -+ } -+ -+ /* NIA */ -+ if (p_FmPort->imEn) -+ { -+ WRITE_UINT32(p_Regs->fmbm_tfdne, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX); -+ WRITE_UINT32(p_Regs->fmbm_tfene, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX); -+#if (DPAA_VERSION >= 11) -+/* TODO - what should be the TFNE for FMan v3 IM? */ -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ else -+ { -+ WRITE_UINT32(p_Regs->fmbm_tfdne, NIA_ENG_QMI_DEQ); -+ WRITE_UINT32(p_Regs->fmbm_tfene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); -+#if (DPAA_VERSION >= 11) -+ WRITE_UINT32(p_Regs->fmbm_tfne, -+ (!p_Params->dfltFqid ? -+ BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME : -+ NIA_BMI_AC_FETCH_ALL_FRAME)); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ /* The line bellow is a trick so the FM will not release the buffer -+ to BM nor will try to enq the frame to QM */ -+ if (!p_Params->dfltFqid && p_Params->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_Regs->fmbm_tcfqid, 0xFFFFFF); -+ WRITE_UINT32(p_Regs->fmbm_tfene, NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE); -+#if (DPAA_VERSION >= 11) -+ WRITE_UINT32(p_Regs->fmbm_tfne, -+ (GET_UINT32(p_Regs->fmbm_tfne) & ~BMI_EBD_EN)); -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ } -+ -+ /* command attribute */ -+ tmpReg = BMI_CMD_TX_MR_DEF; -+ if (p_FmPort->imEn) -+ tmpReg |= BMI_CMD_MR_DEAS; -+ else -+ { -+ tmpReg |= BMI_CMD_ATTR_ORDER; -+ tmpReg |= ((uint32_t)p_Params->color << BMI_CMD_ATTR_COLOR_SHIFT); -+ } -+ WRITE_UINT32(p_Regs->fmbm_tfca, tmpReg); -+ -+ /* default queues */ -+ if (!p_FmPort->imEn) -+ { -+ if (p_Params->dfltFqid || !p_Params->dontReleaseBuf) -+ WRITE_UINT32(p_Regs->fmbm_tcfqid, p_Params->dfltFqid); -+ WRITE_UINT32(p_Regs->fmbm_tfeqid, p_Params->errFqid); -+ } -+ -+ /* statistics & performance counters */ -+ WRITE_UINT32(p_Regs->fmbm_tstc, BMI_COUNTERS_EN); -+ -+ performanceContersParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; -+ performanceContersParams.queueCompVal = 1; -+ performanceContersParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num; -+ performanceContersParams.fifoCompVal = p_FmPort->fifoBufs.num; -+ FM_PORT_SetPerformanceCountersParams(p_FmPort, &performanceContersParams); -+ -+ WRITE_UINT32(p_Regs->fmbm_tpc, BMI_COUNTERS_EN); -+ -+ -+ return E_OK; -+} -+ -+static t_Error BmiOhPortInit(t_FmPort *p_FmPort) -+{ -+ t_FmPortOhBmiRegs *p_Regs = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs; -+ uint32_t tmpReg, errorsToEnq = 0; -+ t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; -+ t_FmPortPerformanceCnt performanceContersParams; -+ -+ /* check that port is not busy */ -+ if (GET_UINT32(p_Regs->fmbm_ocfg) & BMI_PORT_CFG_EN) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is already enabled")); -+ -+ /* Configure dma attributes */ -+ tmpReg = 0; -+ tmpReg |= (uint32_t)p_Params->dmaSwapData << BMI_DMA_ATTR_SWP_SHIFT; -+ tmpReg |= (uint32_t)p_Params->dmaIntContextCacheAttr << BMI_DMA_ATTR_IC_CACHE_SHIFT; -+ tmpReg |= (uint32_t)p_Params->dmaHeaderCacheAttr << BMI_DMA_ATTR_HDR_CACHE_SHIFT; -+ tmpReg |= (uint32_t)p_Params->dmaScatterGatherCacheAttr << BMI_DMA_ATTR_SG_CACHE_SHIFT; -+ if (p_Params->dmaWriteOptimize) -+ tmpReg |= BMI_DMA_ATTR_WRITE_OPTIMIZE; -+ -+ WRITE_UINT32(p_Regs->fmbm_oda, tmpReg); -+ -+ /* IC parameters */ -+ tmpReg = 0; -+ tmpReg |= (((uint32_t)p_Params->intContext.extBufOffset/OFFSET_UNITS) << BMI_IC_TO_EXT_SHIFT); -+ tmpReg |= (((uint32_t)p_Params->intContext.intContextOffset/OFFSET_UNITS) << BMI_IC_FROM_INT_SHIFT); -+ tmpReg |= (((uint32_t)p_Params->intContext.size/OFFSET_UNITS) << BMI_IC_SIZE_SHIFT); -+ -+ WRITE_UINT32(p_Regs->fmbm_oicp, tmpReg); -+ -+ /* NIA */ -+ WRITE_UINT32(p_Regs->fmbm_ofdne, NIA_ENG_QMI_DEQ); -+ -+ if (p_FmPort->portType==e_FM_PORT_TYPE_OH_HOST_COMMAND) -+ WRITE_UINT32(p_Regs->fmbm_ofene, NIA_ENG_QMI_ENQ); -+ else -+ WRITE_UINT32(p_Regs->fmbm_ofene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); -+ -+ /* command attribute */ -+ if (p_FmPort->portType==e_FM_PORT_TYPE_OH_HOST_COMMAND) -+ tmpReg = BMI_CMD_MR_DEAS | BMI_CMD_MR_MA; -+ else -+ tmpReg = BMI_CMD_ATTR_ORDER | BMI_CMD_MR_DEAS | BMI_CMD_MR_MA; -+ -+ if (p_Params->syncReq) -+ tmpReg |= BMI_CMD_ATTR_SYNC; -+ tmpReg |= ((uint32_t)p_Params->color << BMI_CMD_ATTR_COLOR_SHIFT); -+ WRITE_UINT32(p_Regs->fmbm_ofca, tmpReg); -+ -+ /* No discard - all error frames go to error queue */ -+ if (p_Params->frmDiscardOverride) -+ tmpReg = BMI_PORT_CFG_FDOVR; -+ else -+ tmpReg = 0; -+ WRITE_UINT32(p_Regs->fmbm_ocfg, tmpReg); -+ -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ { -+ WRITE_UINT32(p_Regs->fmbm_ofsdm, p_Params->errorsToDiscard); -+ -+ errorsToEnq = (OP_ERRS_TO_ENQ & ~p_Params->errorsToDiscard); -+ WRITE_UINT32(p_Regs->fmbm_ofsem, errorsToEnq); -+ -+ /* NIA */ -+ WRITE_UINT32(p_Regs->fmbm_ofne, (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); -+ -+#ifndef FM_NO_OP_OBSERVED_POOLS -+ /* Call the external Buffer routine which also checks fifo -+ size and updates it if necessary */ -+ if ((p_FmPort->fmRevInfo.majorRev == 4) && -+ p_Params->enBufPoolDepletion) -+ { -+ /* define external buffer pools */ -+ t_Error err = SetExtBufferPools(p_FmPort); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+#endif /* FM_NO_OP_OBSERVED_POOLS */ -+ } -+ else -+ /* NIA */ -+ WRITE_UINT32(p_Regs->fmbm_ofne, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC); -+ -+ /* default queues */ -+ WRITE_UINT32(p_Regs->fmbm_ofqid, p_Params->dfltFqid); -+ WRITE_UINT32(p_Regs->fmbm_oefqid, p_Params->errFqid); -+ -+ if (p_FmPort->internalBufferOffset) -+ { -+ tmpReg = (uint32_t)((p_FmPort->internalBufferOffset % OFFSET_UNITS) ? -+ (p_FmPort->internalBufferOffset/OFFSET_UNITS + 1): -+ (p_FmPort->internalBufferOffset/OFFSET_UNITS)); -+ p_FmPort->internalBufferOffset = (uint8_t)(tmpReg * OFFSET_UNITS); -+ WRITE_UINT32(p_Regs->fmbm_oim, tmpReg << BMI_IM_FOF_SHIFT); -+ } -+ /* statistics & performance counters */ -+ WRITE_UINT32(p_Regs->fmbm_ostc, BMI_COUNTERS_EN); -+ -+ performanceContersParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; -+ performanceContersParams.queueCompVal = 0; -+ performanceContersParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num; -+ performanceContersParams.fifoCompVal = p_FmPort->fifoBufs.num; -+ FM_PORT_SetPerformanceCountersParams(p_FmPort, &performanceContersParams); -+ -+ WRITE_UINT32(p_Regs->fmbm_opc, BMI_COUNTERS_EN); -+#ifdef FM_DEQ_PIPELINE_PARAMS_FOR_OP -+ if ((p_FmPort->fmRevInfo.majorRev == 4) || -+ (p_FmPort->fmRevInfo.majorRev >= 6)) -+ { -+ tmpReg = (((uint32_t)p_FmPort->fifoDeqPipelineDepth - 1) << BMI_FIFO_PIPELINE_DEPTH_SHIFT); -+ WRITE_UINT32(p_Regs->fmbm_ofp, tmpReg); -+ } -+#endif /* FM_DEQ_PIPELINE_PARAMS_FOR_OP */ -+ -+#ifdef FM_FRAME_END_PARAMS_FOR_OP -+ if (p_FmPort->fmRevInfo.majorRev >= 6) -+ { -+ /* frame end parameters */ -+ tmpReg = 0; -+ tmpReg |= ((uint32_t)p_Params->cheksumLastBytesIgnore << BMI_FRAME_END_CS_IGNORE_SHIFT); -+ -+ WRITE_UINT32(p_Regs->fmbm_ofed, tmpReg); -+ } -+#endif /* FM_FRAME_END_PARAMS_FOR_OP */ -+ -+ return E_OK; -+} -+ -+static t_Error QmiInit(t_FmPort *p_FmPort) -+{ -+ t_FmPortDriverParam *p_Params = NULL; -+ uint32_t tmpReg; -+ -+ p_Params = p_FmPort->p_FmPortDriverParam; -+ -+ /* check that port is not busy */ -+ if (((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && -+ (p_FmPort->portType != e_FM_PORT_TYPE_RX)) && -+ (GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & QMI_PORT_CFG_EN)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is already enabled")); -+ -+ /* enable & clear counters */ -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, QMI_PORT_CFG_EN_COUNTERS); -+ -+ /* The following is done for non-Rx ports only */ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && -+ (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ { -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) || -+ (p_FmPort->portType == e_FM_PORT_TYPE_TX)) -+ { -+ /* define dequeue NIA */ -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_TX); -+ /* define enqueue NIA */ -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE); -+ } -+ else /* for HC & OP */ -+ { -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_FETCH); -+ /* define enqueue NIA */ -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_RELEASE); -+ } -+ -+ /* configure dequeue */ -+ tmpReg = 0; -+ if (p_Params->deqHighPriority) -+ tmpReg |= QMI_DEQ_CFG_PRI; -+ -+ switch (p_Params->deqType) -+ { -+ case (e_FM_PORT_DEQ_TYPE1): -+ tmpReg |= QMI_DEQ_CFG_TYPE1; -+ break; -+ case (e_FM_PORT_DEQ_TYPE2): -+ tmpReg |= QMI_DEQ_CFG_TYPE2; -+ break; -+ case (e_FM_PORT_DEQ_TYPE3): -+ tmpReg |= QMI_DEQ_CFG_TYPE3; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid dequeue type")); -+ } -+ -+#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT -+ if (p_FmPort->fmRevInfo.majorRev != 4) -+#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ -+ switch (p_Params->deqPrefetchOption) -+ { -+ case (e_FM_PORT_DEQ_NO_PREFETCH): -+ /* Do nothing - QMI_DEQ_CFG_PREFETCH_WAITING_TNUM | QMI_DEQ_CFG_PREFETCH_1_FRAME = 0 */ -+ break; -+ case (e_FM_PORT_DEQ_PARTIAL_PREFETCH): -+ tmpReg |= QMI_DEQ_CFG_PREFETCH_WAITING_TNUM | QMI_DEQ_CFG_PREFETCH_3_FRAMES; -+ break; -+ case (e_FM_PORT_DEQ_FULL_PREFETCH): -+ tmpReg |= QMI_DEQ_CFG_PREFETCH_NO_TNUM | QMI_DEQ_CFG_PREFETCH_3_FRAMES; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid dequeue prefetch option")); -+ } -+ -+ tmpReg |= p_Params->deqByteCnt; -+ tmpReg |= (uint32_t)p_Params->deqSubPortal << QMI_DEQ_CFG_SUBPORTAL_SHIFT; -+ -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndc, tmpReg); -+ } -+ else /* rx port */ -+ /* define enqueue NIA */ -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_RELEASE); -+ -+ return E_OK; -+} -+ -+static t_Error BmiRxPortCheckAndGetCounterPtr(t_FmPort *p_FmPort, e_FmPortCounters counter, volatile uint32_t **p_Ptr) -+{ -+ t_FmPortRxBmiRegs *p_BmiRegs = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs; -+ -+ /* 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 */ -+ break; -+ 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): -+ if (!(GET_UINT32(p_BmiRegs->fmbm_rstc) & BMI_COUNTERS_EN)) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports")); -+ } -+ -+ /* Set counter */ -+ switch (counter) -+ { -+ case (e_FM_PORT_COUNTERS_CYCLE): -+ *p_Ptr = &p_BmiRegs->fmbm_rccn; -+ break; -+ case (e_FM_PORT_COUNTERS_TASK_UTIL): -+ *p_Ptr = &p_BmiRegs->fmbm_rtuc; -+ break; -+ case (e_FM_PORT_COUNTERS_QUEUE_UTIL): -+ *p_Ptr = &p_BmiRegs->fmbm_rrquc; -+ break; -+ case (e_FM_PORT_COUNTERS_DMA_UTIL): -+ *p_Ptr = &p_BmiRegs->fmbm_rduc; -+ break; -+ case (e_FM_PORT_COUNTERS_FIFO_UTIL): -+ *p_Ptr = &p_BmiRegs->fmbm_rfuc; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): -+ *p_Ptr = &p_BmiRegs->fmbm_rpac; -+ break; -+ case (e_FM_PORT_COUNTERS_FRAME): -+ *p_Ptr = &p_BmiRegs->fmbm_rfrc; -+ break; -+ case (e_FM_PORT_COUNTERS_DISCARD_FRAME): -+ *p_Ptr = &p_BmiRegs->fmbm_rfcd; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_BAD_FRAME): -+ *p_Ptr = &p_BmiRegs->fmbm_rfbc; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME): -+ *p_Ptr = &p_BmiRegs->fmbm_rlfc; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): -+ *p_Ptr = &p_BmiRegs->fmbm_rffc; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): -+ *p_Ptr = &p_BmiRegs->fmbm_rfldec; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): -+ *p_Ptr = &p_BmiRegs->fmbm_rodc; -+ break; -+ case (e_FM_PORT_COUNTERS_DEALLOC_BUF): -+ *p_Ptr = &p_BmiRegs->fmbm_rbdc; -+ break; -+ case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER): -+ *p_Ptr = &p_BmiRegs->fmbm_rpec; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports")); -+ } -+ -+ return E_OK; -+} -+ -+static t_Error BmiTxPortCheckAndGetCounterPtr(t_FmPort *p_FmPort, e_FmPortCounters counter, volatile uint32_t **p_Ptr) -+{ -+ t_FmPortTxBmiRegs *p_BmiRegs = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs; -+ -+ /* 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): -+ /* performance counters - may be read when disabled */ -+ break; -+ 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): -+ if (!(GET_UINT32(p_BmiRegs->fmbm_tstc) & BMI_COUNTERS_EN)) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Tx ports")); -+ } -+ -+ /* Set counter */ -+ switch (counter) -+ { -+ case (e_FM_PORT_COUNTERS_CYCLE): -+ *p_Ptr = &p_BmiRegs->fmbm_tccn; -+ break; -+ case (e_FM_PORT_COUNTERS_TASK_UTIL): -+ *p_Ptr = &p_BmiRegs->fmbm_ttuc; -+ break; -+ case (e_FM_PORT_COUNTERS_QUEUE_UTIL): -+ *p_Ptr = &p_BmiRegs->fmbm_ttcquc; -+ break; -+ case (e_FM_PORT_COUNTERS_DMA_UTIL): -+ *p_Ptr = &p_BmiRegs->fmbm_tduc; -+ break; -+ case (e_FM_PORT_COUNTERS_FIFO_UTIL): -+ *p_Ptr = &p_BmiRegs->fmbm_tfuc; -+ break; -+ case (e_FM_PORT_COUNTERS_FRAME): -+ *p_Ptr = &p_BmiRegs->fmbm_tfrc; -+ break; -+ case (e_FM_PORT_COUNTERS_DISCARD_FRAME): -+ *p_Ptr = &p_BmiRegs->fmbm_tfdc; -+ break; -+ case (e_FM_PORT_COUNTERS_LENGTH_ERR): -+ *p_Ptr = &p_BmiRegs->fmbm_tfledc; -+ break; -+ case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): -+ *p_Ptr = &p_BmiRegs->fmbm_tfufdc; -+ break; -+ case (e_FM_PORT_COUNTERS_DEALLOC_BUF): -+ *p_Ptr = &p_BmiRegs->fmbm_tbdc; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Tx ports")); -+ } -+ -+ return E_OK; -+} -+ -+static t_Error BmiOhPortCheckAndGetCounterPtr(t_FmPort *p_FmPort, e_FmPortCounters counter, volatile uint32_t **p_Ptr) -+{ -+ t_FmPortOhBmiRegs *p_BmiRegs = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs; -+ -+ /* 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_DMA_UTIL): -+ case (e_FM_PORT_COUNTERS_FIFO_UTIL): -+ /* performance counters - may be read when disabled */ -+ break; -+ 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_RX_OUT_OF_BUFFERS_DISCARD): -+ 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): -+ if (!(GET_UINT32(p_BmiRegs->fmbm_ostc) & BMI_COUNTERS_EN)) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); -+ break; -+ case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): /* only valid for offline parsing */ -+ /* 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 (!(GET_UINT32(p_BmiRegs->fmbm_ostc) & BMI_COUNTERS_EN)) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter(%d) is not available for O/H ports", counter)); -+ } -+ -+ /* Set counter */ -+ switch (counter) -+ { -+ case (e_FM_PORT_COUNTERS_CYCLE): -+ *p_Ptr = &p_BmiRegs->fmbm_occn; -+ break; -+ case (e_FM_PORT_COUNTERS_TASK_UTIL): -+ *p_Ptr = &p_BmiRegs->fmbm_otuc; -+ break; -+ case (e_FM_PORT_COUNTERS_DMA_UTIL): -+ *p_Ptr = &p_BmiRegs->fmbm_oduc; -+ break; -+ case (e_FM_PORT_COUNTERS_FIFO_UTIL): -+ *p_Ptr = &p_BmiRegs->fmbm_ofuc; -+ break; -+ case (e_FM_PORT_COUNTERS_FRAME): -+ *p_Ptr = &p_BmiRegs->fmbm_ofrc; -+ break; -+ case (e_FM_PORT_COUNTERS_DISCARD_FRAME): -+ *p_Ptr = &p_BmiRegs->fmbm_ofdc; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): -+ *p_Ptr = &p_BmiRegs->fmbm_offc; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): -+ *p_Ptr = &p_BmiRegs->fmbm_ofldec; -+ break; -+ case (e_FM_PORT_COUNTERS_WRED_DISCARD): -+ *p_Ptr = &p_BmiRegs->fmbm_ofwdc; -+ break; -+ case (e_FM_PORT_COUNTERS_LENGTH_ERR): -+ *p_Ptr = &p_BmiRegs->fmbm_ofledc; -+ break; -+ case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): -+ *p_Ptr = &p_BmiRegs->fmbm_ofufdc; -+ break; -+ case (e_FM_PORT_COUNTERS_DEALLOC_BUF): -+ *p_Ptr = &p_BmiRegs->fmbm_obdc; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): -+ *p_Ptr = &p_BmiRegs->fmbm_oodc; -+ break; -+ case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER): -+ *p_Ptr = &p_BmiRegs->fmbm_opec; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for O/H ports")); -+ } -+ -+ 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; -+ GET_PRS_HDR_NUM(hdrNum, p_prsOpts->mplsPrsOptions.nextParse); -+ if (hdrNum == ILLEGAL_HDR_NUM) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); -+ GET_PRS_HDR_NUM(Ipv4HdrNum, 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 devided 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(MINOR, 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 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; -+ uint8_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; -+ -+ 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; -+#ifdef FM_CAPWAP_SUPPORT -+ case (e_FM_PORT_PCD_SUPPORT_CC_ONLY): -+ p_FmPort->pcdEngines |= FM_PCD_CC; -+ break; -+ 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->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; -+ p_BmiPrsNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne; -+ p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpso; -+ p_BmiInitPrsResult = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rprai[0]; -+ p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rccb; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; -+ p_BmiPrsNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofpne; -+ p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opso; -+ p_BmiInitPrsResult = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oprai[0]; -+ p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.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; ip_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(MINOR, 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(MINOR, 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); -+ } -+ -+#ifdef FM_CAPWAP_SUPPORT -+ /* if CC is used directly after BMI */ -+ if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY) || -+ (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG) || -+ (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)) -+ { -+ 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] */ -+ } -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+ if (p_FmPort->pcdEngines & FM_PCD_PRS) -+ { -+ ASSERT_COND(p_PcdParams->p_PrsParams); -+ /* if PRS is used it is always first */ -+ GET_PRS_HDR_NUM(hdrNum, p_PcdParams->p_PrsParams->firstPrsHdr); -+ if (hdrNum == ILLEGAL_HDR_NUM) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header.")); -+ 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 ; ip_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): -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_ETH) -+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_ETH_BC_SHIFT; -+ break; -+ case (ETH_MULTICAST): -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_ETH) -+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_ETH_MC_SHIFT; -+ break; -+ case (VLAN_STACKED): -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_VLAN) -+ tmpHxs[hdrNum] |= (i+1)<< PRS_HDR_VLAN_STACKED_SHIFT; -+ break; -+ case (MPLS_STACKED): -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_MPLS) -+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_MPLS_STACKED_SHIFT; -+ break; -+ case (IPV4_BROADCAST_1): -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4) -+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_1_BC_SHIFT; -+ break; -+ case (IPV4_MULTICAST_1): -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4) -+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_1_MC_SHIFT; -+ break; -+ case (IPV4_UNICAST_2): -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4) -+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_2_UC_SHIFT; -+ break; -+ case (IPV4_MULTICAST_BROADCAST_2): -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4) -+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_2_MC_BC_SHIFT; -+ break; -+ case (IPV6_MULTICAST_1): -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv6) -+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV6_1_MC_SHIFT; -+ break; -+ case (IPV6_UNICAST_2): -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv6) -+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV6_2_UC_SHIFT; -+ break; -+ case (IPV6_MULTICAST_2): -+ GET_PRS_HDR_NUM(hdrNum, 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)) -+ { -+ 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 */ -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_MPLS) -+ tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN; -+ GET_PRS_HDR_NUM(L3HdrNum, HEADER_TYPE_USER_DEFINED_L3); -+ tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT; -+ -+ /* for GRE, disable errors */ -+ GET_PRS_HDR_NUM(greHdrNum, HEADER_TYPE_GRE); -+ tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS; -+ -+ /* For UDP remove PAD from L4 checksum calculation */ -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_UDP); -+ tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL; -+ /* For TCP remove PAD from L4 checksum calculation */ -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_TCP); -+ tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL; -+ -+ /* config additional params for specific headers */ -+ for (i=0; ip_PrsParams->numOfHdrsWithAdditionalParams; i++) -+ { -+ GET_PRS_HDR_NUM(hdrNum, 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 update NIAs */ -+ if (p_FmPort->h_IpReassemblyManip) -+ { -+ /* link to sw parser code for IP Frag - only if no other code is applied. */ -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4) -+ if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) -+ tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | IP_FRAG_SW_PATCH_IPv4_LABEL); -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv6) -+ if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) -+ tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | IP_FRAG_SW_PATCH_IPv6_LABEL); -+ } -+ -+ if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd) && -+ (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ { -+ /* link to sw parser code for IP Frag - only if no other code is applied. */ -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv6) -+ if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) -+ tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | IP_FRAG_SW_PATCH_IPv6_LABEL); -+ } -+ -+#ifdef 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. */ -+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_USER_DEFINED_L4) -+ if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) -+ tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL); -+ } -+#endif /* FM_CAPWAP_SUPPORT */ -+ for (i=0 ; ip_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 -+ p_FmPort->privateInfo = 0; -+ -+ WRITE_UINT32(*p_BmiPrsStartOffset, GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset); -+ -+ /* set initial parser result - used for all engines */ -+ for (i=0;iprivateInfo << 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->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; -+ p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpso; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; -+ p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opso; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ } -+ -+ if ((GET_UINT32(*p_BmiNia) & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("port has to be detached previousely")); -+ -+ /* "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) -+ { -+ WRITE_UINT32(*p_BmiPrsStartOffset, 0); -+ -+ /* 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(MINOR, err, NO_MSG); -+ -+ err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId, p_FmPort->clsPlanGrpId); -+ if (err) -+ RETURN_ERROR(MINOR, 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(MINOR, 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 */ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); -+ } -+ -+ 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); -+ -+ /* check that current NIA is BMI to BMI */ -+ if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("may be called only for ports in BMI-to-BMI state.")); -+ -+ WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia); -+ -+ if (p_FmPort->requiredAction & UPDATE_NIA_PNEN) -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, p_FmPort->savedQmiPnen); -+ -+ if (p_FmPort->requiredAction & UPDATE_NIA_PNDN) -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, p_FmPort->savedNonRxQmiRegsPndn); -+ -+ if (p_FmPort->requiredAction & UPDATE_NIA_FENE) -+ { -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofene, p_FmPort->savedBmiFene); -+ else -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.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->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofpne, p_FmPort->savedBmiFpne); -+ else -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->savedBmiFpne); -+ } -+ if (p_FmPort->requiredAction & UPDATE_NIA_CMNE) -+ { -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocmne, p_FmPort->savedBmiCmne); -+ else -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcmne, p_FmPort->savedBmiCmne); -+ } -+ -+ 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 */ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); -+ } -+ -+ WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); -+ -+ if (p_FmPort->requiredAction & UPDATE_NIA_PNEN) -+ { -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE); -+ break; -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ case (e_FM_PORT_TYPE_RX): -+ case (e_FM_PORT_TYPE_RX_10G): -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_RELEASE); -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Can not reach this stage")); -+ } -+ } -+ -+ if (p_FmPort->requiredAction & UPDATE_NIA_PNDN) -+ { -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_TX); -+ break; -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_FETCH); -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Can not reach this stage")); -+ } -+ } -+ -+ if (p_FmPort->requiredAction & UPDATE_NIA_FENE) -+ { -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); -+ else -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); -+ } -+ -+ 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 FmPortSetMacsecLcv(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; -+ -+ 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_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Rx ports only")); -+ return; -+ } -+ -+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg; -+ /* get LCV for MACSEC */ -+ if ((p_FmPort->h_FmPcd) && ((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); -+} -+ -+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->p_FmPortBmiRegs->txPortBmiRegs.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_MuramPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, -+ 256, -+ 8); -+ if (!p_FmPort->p_MuramPage) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page")); -+ -+ IOMemSet32(p_FmPort->p_MuramPage, 0, 256); -+ muramPageOffset = (uint32_t)(XX_VirtToPhys(p_FmPort->p_MuramPage) - -+ 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_MuramPage; -+ 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 & GET_NIA_FPNE) -+ { -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ p_CcParams->getCcParams.nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofpne); -+ else -+ p_CcParams->getCcParams.nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.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->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpso; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.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")); -+ } -+ -+ 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 */ -+ SW_PORT_ID_TO_HW_PORT_ID(p_FmPort->hardwarePortId, p_FmPort->portType, p_FmPortParams->portId); -+ -+ 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.")); -+ } -+ -+ /* Initialize FM port parameters for initialization phase only */ -+ 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 = DEFAULT_PORT_dmaSwapData; -+ p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = DEFAULT_PORT_dmaIntContextCacheAttr; -+ p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = DEFAULT_PORT_dmaHeaderCacheAttr; -+ p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = 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->p_FmPortDriverParam->color = DEFAULT_PORT_color; -+ -+ p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength; -+ /* resource distribution. */ -+#ifdef FM_NO_GUARANTEED_RESET_VALUES -+ if (1) /* if (p_FmPort->fmRevInfo.majorRev < 6) */ -+ { -+ 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->fmRevInfo.majorRev); -+ 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); -+ } -+ else -+#endif /* FM_NO_GUARANTEED_RESET_VALUES */ -+ { -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) && -+ (p_FmPortParams->portId != FM_OH_PORT_ID)) -+ { -+ /* Overwrite HC defaults */ -+ 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->fmRevInfo.majorRev); -+ 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); -+ } -+ else -+ { -+ p_FmPort->fifoBufs.num = 0; -+ p_FmPort->fifoBufs.extra = 0; -+ p_FmPort->openDmas.num = 0; -+ p_FmPort->openDmas.extra = 0; -+ p_FmPort->tasks.num = 0; -+ p_FmPort->tasks.extra = 0; -+ } -+ } -+ -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) -+ p_FmPort->p_FmPortDriverParam->syncReq = DEFAULT_PORT_syncReqForHc; -+ else -+ p_FmPort->p_FmPortDriverParam->syncReq = DEFAULT_PORT_syncReq; -+ -+ /* Port type specific initialization: */ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_TX) && -+ (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)) -+ p_FmPort->p_FmPortDriverParam->frmDiscardOverride = DEFAULT_PORT_frmDiscardOverride; -+ -+ 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; -+#ifdef FM_NO_GUARANTEED_RESET_VALUES -+ if (1) /* if (p_FmPort->fmRevInfo.majorRev < 6) */ -+ { -+ p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel = DEFAULT_PORT_rxFifoPriElevationLevel; -+ p_FmPort->p_FmPortDriverParam->rxFifoThreshold = DEFAULT_PORT_rxFifoThreshold; -+ } -+ else -+#endif /* FM_NO_GUARANTEED_RESET_VALUES */ -+ { -+ 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): -+#ifdef FM_NO_GUARANTEED_RESET_VALUES -+ if (1) /* if (p_FmPort->fmRevInfo.majorRev < 6) */ -+ { -+ p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = DEFAULT_PORT_txFifoMinFillLevel; -+ p_FmPort->fifoDeqPipelineDepth = -+ (uint8_t)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? -+ DEFAULT_PORT_fifoDeqPipelineDepth_1G : -+ DEFAULT_PORT_fifoDeqPipelineDepth_10G); -+ p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = DEFAULT_PORT_txFifoLowComfLevel; -+ } -+ else -+#endif /* FM_NO_GUARANTEED_RESET_VALUES */ -+ { -+ 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->fifoDeqPipelineDepth = -+ (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; -+ -+#ifdef FM_NO_GUARANTEED_RESET_VALUES -+ if (1) /* if (p_FmPort->fmRevInfo.majorRev < 6) */ -+ p_FmPort->fifoDeqPipelineDepth = DEFAULT_PORT_fifoDeqPipelineDepth_OH; -+ else -+#endif /* FM_NO_GUARANTEED_RESET_VALUES */ -+ { -+ tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp); -+ p_FmPort->fifoDeqPipelineDepth = -+ (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->fifoDeqPipelineDepth = 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->fifoDeqPipelineDepth = 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->fifoDeqPipelineDepth = 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; -+} -+ -+/**************************************************************************//** -+ @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_Params; -+ t_Error err = E_OK; -+ t_FmInterModulePortInitParams fmParams; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ err = FmSpBuildBufferStructure(&p_FmPort->p_FmPortDriverParam->intContext, -+ &p_FmPort->p_FmPortDriverParam->bufferPrefixContent, -+ &p_FmPort->p_FmPortDriverParam->bufMargins, -+ &p_FmPort->bufferOffsets, -+ &p_FmPort->internalBufferOffset); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, 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 = 50 * BMI_FIFO_UNITS; -+ p_FmPort->fifoBufs.num += 4*KILOBYTE; -+ } -+#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */ -+ -+ CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters); -+ -+ p_Params = p_FmPort->p_FmPortDriverParam; -+ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || -+ (p_FmPort->portType == e_FM_PORT_TYPE_RX)) -+ if (!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*/ -+ err = SetExtBufferPools(p_FmPort); -+ if (err) -+ RETURN_ERROR(MAJOR, err, 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) -+ { -+ err = VerifySizeOfFifo(p_FmPort); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ fmParams.sizeOfFifo = p_FmPort->fifoBufs.num; -+ fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra; -+ fmParams.independentMode = p_FmPort->imEn; -+ fmParams.liodnOffset = p_Params->liodnOffset; -+ fmParams.liodnBase = p_Params->liodnBase; -+ fmParams.deqPipelineDepth = p_FmPort->fifoDeqPipelineDepth; -+ 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 */ -+ -+ -+ err = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams); -+ if (err) -+ RETURN_ERROR(MAJOR, err, 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); -+ -+#ifndef FM_NO_GUARANTEED_RESET_VALUES -+ if (p_FmPort->fmRevInfo.majorRev >= 6) -+ { -+ p_FmPort->tasks.num = fmParams.numOfTasks; -+ p_FmPort->tasks.extra = fmParams.numOfExtraTasks; -+ p_FmPort->openDmas.num = fmParams.numOfOpenDmas; -+ p_FmPort->openDmas.extra = fmParams.numOfExtraOpenDmas; -+ p_FmPort->fifoBufs.num = fmParams.sizeOfFifo; -+ p_FmPort->fifoBufs.extra = fmParams.extraSizeOfFifo; -+ } -+#endif /* FM_NO_GUARANTEED_RESET_VALUES */ -+ -+ /**********************/ -+ /* Init BMI Registers */ -+ /**********************/ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ err = BmiRxPortInit(p_FmPort); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ break; -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ err = BmiTxPortInit(p_FmPort); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ err = BmiOhPortInit(p_FmPort); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ } -+ -+ /**********************/ -+ /* Init QMI Registers */ -+ /**********************/ -+ if (!p_FmPort->imEn && ((err = QmiInit(p_FmPort)) != E_OK)) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK)) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ FmPortDriverParamFree(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); -+ -+ fmParams.hardwarePortId = p_FmPort->hardwarePortId; -+ fmParams.portType = (e_FmPortType)p_FmPort->portType; -+ fmParams.deqPipelineDepth = p_FmPort->fifoDeqPipelineDepth; -+ -+ 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(MINOR, E_INVALID_STATE, ("VSP free of port FAILED")); -+ -+ if (p_FmPort->p_MuramPage) -+ FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_MuramPage); -+#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->deqHighPriority = 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->deqType = 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->deqPrefetchOption = 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->deqByteCnt = 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 deafult */ -+ 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 cheksumLastBytesIgnore) -+{ -+ 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->cheksumLastBytesIgnore = cheksumLastBytesIgnore; -+ -+ 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->cutBytesFromEnd = 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->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->syncReq = 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->frmDiscardOverride = 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->dmaSwapData = 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->dmaIntContextCacheAttr = intContextCacheAttr; -+ -+ 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->dmaHeaderCacheAttr = headerCacheAttr; -+ -+ 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->dmaScatterGatherCacheAttr = scatterGatherCacheAttr; -+ -+ 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->dmaWriteOptimize = 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->txFifoMinFillLevel = 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->fifoDeqPipelineDepth = 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->txFifoLowComfLevel = 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->rxFifoThreshold = 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->rxFifoPriElevationLevel = 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(MINOR, 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(MINOR, 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 > BMI_MAX_FIFO_SIZE)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SizeOfFifo-num has to be in the range of 256 - %d", BMI_MAX_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(MINOR, 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; -+ volatile uint32_t *p_BmiCfgReg = NULL; -+ volatile uint32_t *p_BmiStatusReg = NULL; -+ bool rxPort = FALSE; -+ int tries; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg; -+ p_BmiStatusReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rst; -+ rxPort = TRUE; -+ break; -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg; -+ p_BmiStatusReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tst; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocfg; -+ p_BmiStatusReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ost; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ } -+ -+ /* check if port is already disabled */ -+ if (!(GET_UINT32(*p_BmiCfgReg) & BMI_PORT_CFG_EN)) -+ { -+ if (!rxPort && !p_FmPort->imEn) -+ { -+ if (!(GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc)& QMI_PORT_CFG_EN)) -+ /* port is disabled */ -+ return E_OK; -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistency: Port's QMI is enabled but BMI disabled")); -+ } -+ /* port is disabled */ -+ return E_OK; -+ } -+ -+ /* Disable QMI */ -+ if (!rxPort && !p_FmPort->imEn) -+ { -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, -+ GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & ~QMI_PORT_CFG_EN); -+ /* wait for QMI to finish Handling dequeue tnums */ -+ tries=1000; -+ while ((GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pns) & QMI_PORT_STATUS_DEQ_FD_BSY) && -+ --tries) -+ XX_UDelay(1); -+ if (!tries) -+ { -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, -+ GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) | QMI_PORT_CFG_EN); -+ RETURN_ERROR(MAJOR, E_BUSY, ("%s: can't disable! QMI busy", p_FmPort->name)); -+ } -+ } -+ -+ /* Disable BMI */ -+ WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) & ~BMI_PORT_CFG_EN); -+ -+ if (p_FmPort->imEn) -+ FmPortImDisable(p_FmPort); -+ -+ tries=5000; -+ while ((GET_UINT32(*p_BmiStatusReg) & BMI_PORT_STATUS_BSY) && -+ --tries) -+ XX_UDelay(1); -+ -+ if (!tries) -+ { -+ if (!rxPort && !p_FmPort->imEn) -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, -+ GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) | QMI_PORT_CFG_EN); -+ WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | BMI_PORT_CFG_EN); -+ -+ RETURN_ERROR(MAJOR, E_BUSY, ("%s: can't disable! BMI Busy", p_FmPort->name)); -+ } -+ -+ p_FmPort->enabled = 0; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_Enable(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ volatile uint32_t *p_BmiCfgReg = NULL; -+ bool rxPort = FALSE; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg; -+ rxPort = TRUE; -+ break; -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocfg; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ } -+ -+ /* check if port is already enabled */ -+ if (GET_UINT32(*p_BmiCfgReg) & BMI_PORT_CFG_EN) -+ { -+ if (!rxPort && !p_FmPort->imEn) -+ { -+ if (GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc)& QMI_PORT_CFG_EN) -+ /* port is enabled */ -+ return E_OK; -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistency: Port's BMI is enabled but QMI disabled")); -+ } -+ /* port is enabled */ -+ return E_OK; -+ } -+ -+ if (p_FmPort->imEn) -+ FmPortImEnable(p_FmPort); -+ -+ /* Enable QMI */ -+ if (!rxPort && !p_FmPort->imEn) -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, -+ GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) | QMI_PORT_CFG_EN); -+ -+ /* Enable BMI */ -+ WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | BMI_PORT_CFG_EN); -+ -+ p_FmPort->enabled = 1; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ uint32_t tmpRateLimit, tmpRateLimitScale; -+ volatile uint32_t *p_RateLimitReg, *p_RateLimitScaleReg; -+ uint8_t factor, countUnitBit; -+ uint16_t baseGran; -+ -+ 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")); -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmt; -+ p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmts; -+ baseGran = 16000; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmt; -+ p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmts; -+ baseGran = 10000; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ } -+ -+ 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")); -+ -+ tmpRateLimit = (uint32_t)(p_RateLimit->rateLimit*factor/baseGran - 1); -+ -+ if (!p_RateLimit->maxBurstSize || (p_RateLimit->maxBurstSize > MAX_BURST_SIZE)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxBurstSize must be between 1K and %dk", MAX_BURST_SIZE)); -+ -+ tmpRateLimitScale = ((31 - (uint32_t)countUnitBit) << BMI_COUNT_RATE_UNIT_SHIFT) | BMI_RATE_LIMIT_EN; -+ -+ if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ tmpRateLimit |= (uint32_t)(p_RateLimit->maxBurstSize - 1) << BMI_MAX_BURST_SHIFT; -+ else -+ { -+#ifndef FM_NO_ADVANCED_RATE_LIMITER -+ -+ if ((p_FmPort->fmRevInfo.majorRev == 4) || (p_FmPort->fmRevInfo.majorRev >= 6)) -+ { -+ switch (p_RateLimit->rateLimitDivider) -+ { -+ case (e_FM_PORT_DUAL_RATE_LIMITER_NONE): -+ break; -+ case (e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2): -+ tmpRateLimitScale |= BMI_RATE_LIMIT_SCALE_BY_2; -+ break; -+ case (e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4): -+ tmpRateLimitScale |= BMI_RATE_LIMIT_SCALE_BY_4; -+ break; -+ case (e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8): -+ tmpRateLimitScale |= BMI_RATE_LIMIT_SCALE_BY_8; -+ break; -+ default: -+ break; -+ } -+ tmpRateLimit |= BMI_RATE_LIMIT_BURST_SIZE_GRAN; -+ } -+ else -+#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */ -+ { -+ if (p_RateLimit->rateLimitDivider != e_FM_PORT_DUAL_RATE_LIMITER_NONE) -+ RETURN_ERROR(MINOR, 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); -+ } -+ tmpRateLimit |= (uint32_t)(p_RateLimit->maxBurstSize - 1) << BMI_MAX_BURST_SHIFT; -+ -+ } -+ WRITE_UINT32(*p_RateLimitScaleReg, tmpRateLimitScale); -+ WRITE_UINT32(*p_RateLimitReg, tmpRateLimit); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ volatile uint32_t *p_RateLimitReg, *p_RateLimitScaleReg; -+ -+ 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")); -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmt; -+ p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmts; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmt; -+ p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmts; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ } -+ -+ WRITE_UINT32(*p_RateLimitScaleReg, 0); -+ WRITE_UINT32(*p_RateLimitReg, 0); -+ -+ return E_OK; -+} -+ -+ -+t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ uint32_t tmpReg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ tmpReg = GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc); -+ if (enable) -+ tmpReg |= QMI_PORT_CFG_EN_COUNTERS ; -+ else -+ tmpReg &= ~QMI_PORT_CFG_EN_COUNTERS; -+ -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, tmpReg); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ volatile uint32_t *p_BmiPcReg = NULL; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiPcReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpc; -+ break; -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ p_BmiPcReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpc; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ p_BmiPcReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opc; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ } -+ -+ if (enable) -+ WRITE_UINT32(*p_BmiPcReg, BMI_COUNTERS_EN); -+ else -+ WRITE_UINT32(*p_BmiPcReg, 0); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ uint32_t tmpReg; -+ volatile uint32_t *p_BmiPcpReg = NULL; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiPcpReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpcp; -+ break; -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ p_BmiPcpReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpcp; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ p_BmiPcpReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opcp; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ } -+ -+ /* check parameters */ -+ if (!p_FmPortPerformanceCnt->taskCompVal || -+ (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("performanceCnt.taskCompVal has to be in the range of 1 - %d (current value)!", -+ p_FmPort->tasks.num)); -+ if (!p_FmPortPerformanceCnt->dmaCompVal || -+ (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("performanceCnt.dmaCompVal has to be in the range of 1 - %d (current value)!", -+ p_FmPort->openDmas.num)); -+ if (!p_FmPortPerformanceCnt->fifoCompVal || -+ (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("performanceCnt.fifoCompVal has to be in the range of 256 - %d (current value)!", -+ p_FmPort->fifoBufs.num)); -+ if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("performanceCnt.fifoCompVal has to be divisible by %d", -+ 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")); -+ } -+ -+ tmpReg = 0; -+ tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->queueCompVal - 1) << BMI_PERFORMANCE_PORT_COMP_SHIFT); -+ tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->dmaCompVal- 1) << BMI_PERFORMANCE_DMA_COMP_SHIFT); -+ tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->fifoCompVal/BMI_FIFO_UNITS - 1) << BMI_PERFORMANCE_FIFO_COMP_SHIFT); -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) && (p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND)) -+ tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->taskCompVal - 1) << BMI_PERFORMANCE_TASK_COMP_SHIFT); -+ -+ WRITE_UINT32(*p_BmiPcpReg, tmpReg); -+ -+ 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(MINOR, 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; -+ uint32_t tmpReg; -+ volatile uint32_t *p_BmiStcReg = NULL; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiStcReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rstc; -+ break; -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ p_BmiStcReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tstc; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ p_BmiStcReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ostc; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ } -+ -+ tmpReg = GET_UINT32(*p_BmiStcReg); -+ -+ if (enable) -+ tmpReg |= BMI_COUNTERS_EN; -+ else -+ tmpReg &= ~BMI_COUNTERS_EN; -+ -+ WRITE_UINT32(*p_BmiStcReg, tmpReg); -+ -+ 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_ErrQReg, *p_ErrDiscard; -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_ErrQReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem; -+ p_ErrDiscard = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_ErrQReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem; -+ 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")); -+ } -+ -+ if (GET_UINT32(*p_ErrDiscard) & errs) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Selectd Errors that were configured to cause frame discard.")); -+ -+ WRITE_UINT32(*p_ErrQReg, errs); -+ -+ 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; -+ uint32_t tmpReg; -+ int i; -+ -+ 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")); -+ -+ for (i=0 ; i< FM_PORT_MAX_NUM_OF_EXT_POOLS ; i++) -+ { -+ tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i]); -+ if ((uint8_t)((tmpReg & BMI_EXT_BUF_POOL_ID_MASK) >> BMI_EXT_BUF_POOL_ID_SHIFT) == poolId) -+ { -+ if (enable) -+ tmpReg |= BMI_EXT_BUF_POOL_EN_COUNTER; -+ else -+ tmpReg &= ~BMI_EXT_BUF_POOL_EN_COUNTER; -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i], tmpReg); -+ break; -+ } -+ } -+ if (i == FM_PORT_MAX_NUM_OF_EXT_POOLS) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE,("poolId %d is not included in this ports pools", poolId)); -+ -+ 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; -+ volatile uint32_t *p_Reg; -+ -+ 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; -+ 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) -+ { -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ if (BmiRxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) -+ { -+ REPORT_ERROR(MINOR, E_INVALID_STATE, NO_MSG); -+ return 0; -+ } -+ break; -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ if (BmiTxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) -+ { -+ REPORT_ERROR(MINOR, E_INVALID_STATE, NO_MSG); -+ return 0; -+ } -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ if (BmiOhPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) -+ { -+ REPORT_ERROR(MINOR, E_INVALID_STATE, NO_MSG); -+ return 0; -+ } -+ break; -+ default: -+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type")); -+ return 0; -+ } -+ return GET_UINT32(*p_Reg); -+ } -+ else /* QMI counter */ -+ { -+ /* check that counters are enabled */ -+ if (!(GET_UINT32(p_FmPort->p_FmPortQmiRegs->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): -+ return GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnetfc); -+ case (e_FM_PORT_COUNTERS_DEQ_TOTAL): -+ return GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndtfc); -+ case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): -+ return GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndfdc); -+ case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): -+ return GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndcc); -+ default: -+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available")); -+ 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; -+ volatile uint32_t *p_Reg; -+ -+ 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) -+ { -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ if (BmiRxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); -+ break; -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ if (BmiTxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ if (BmiOhPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type")); -+ } -+ WRITE_UINT32(*p_Reg, value); -+ } -+ else /* QMI counter */ -+ { -+ -+ /* check that counters are enabled */ -+ if (!(GET_UINT32(p_FmPort->p_FmPortQmiRegs->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): -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnetfc, value); -+ break; -+ case (e_FM_PORT_COUNTERS_DEQ_TOTAL): -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndtfc, value); -+ break; -+ case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndfdc, value); -+ break; -+ case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndcc, value); -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available")); -+ } -+ } -+ -+ return E_OK; -+} -+ -+uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ uint32_t extPoolReg; -+ uint8_t tmpPool; -+ uint8_t i; -+ -+ 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; -+ } -+ -+ for (i=0;ip_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i]); -+ if (extPoolReg & BMI_EXT_BUF_POOL_VALID) -+ { -+ tmpPool = (uint8_t)((extPoolReg & BMI_EXT_BUF_POOL_ID_MASK) >> BMI_EXT_BUF_POOL_ID_SHIFT); -+ if (tmpPool == poolId) -+ { -+ if (extPoolReg & BMI_EXT_BUF_POOL_EN_COUNTER) -+ return GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt[i]); -+ else -+ { -+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not enabled")); -+ return 0; -+ } -+ } -+ } -+ } -+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Pool %d is not used", poolId)); -+ return 0; -+} -+ -+t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value) -+{ -+ t_FmPort *p_FmPort = (t_FmPort *)h_FmPort; -+ uint32_t extPoolReg; -+ uint8_t tmpPool; -+ uint8_t i; -+ -+ 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")); -+ -+ -+ for (i=0;ip_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i]); -+ if (extPoolReg & BMI_EXT_BUF_POOL_VALID) -+ { -+ tmpPool = (uint8_t)((extPoolReg & BMI_EXT_BUF_POOL_ID_MASK) >> BMI_EXT_BUF_POOL_ID_SHIFT); -+ if (tmpPool == poolId) -+ { -+ if (extPoolReg & BMI_EXT_BUF_POOL_EN_COUNTER) -+ { -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt[i], value); -+ return E_OK; -+ } -+ else -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not enabled")); -+ } -+ } -+ } -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Pool %d is not used", poolId)); -+} -+ -+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(MINOR, 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; -+ uint32_t tmpReg; -+ -+ 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")); -+ -+ tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); -+ if (l4Checksum) -+ tmpReg &= ~BMI_PORT_RFNE_FRWD_DCL4C; -+ else -+ tmpReg |= BMI_PORT_RFNE_FRWD_DCL4C; -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, tmpReg); -+ -+ 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(IN_RANGE(0, p_VSPParams->dfltRelativeId, (p_VSPParams->numOfProfiles - 1)), 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<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; -+ -+ tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK; -+ tmpReg |= (uint32_t)hwStoragePrflId<= 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->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.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(MINOR, 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->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; -+ p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne; -+ tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; -+ p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.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(p_FmPort, E_INVALID_VALUE); -+ -+ 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->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.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); -+ } -+ } -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rccb; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.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(MINOR, err, NO_MSG); -+ } -+ WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset); -+ -+ p_FmPort->ccTreeId = h_CcTree; -+ RELEASE_LOCK(p_FmPort->lock); -+ } -+ else -+ RETURN_ERROR(MINOR, 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 (!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_IpReassemblyTree) -+ 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 (!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(MINOR, err, NO_MSG); -+ } -+ -+ if (p_FmPort->h_IpReassemblyTree) -+ 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_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ if (p_FmPort->imEn) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independent mode 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); -+ -+ memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams)); -+ p_PcdParams = &modifiedPcdParams; -+ if (p_PcdParams->h_IpReassemblyManip) -+ { -+ 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 IPR")); -+ } -+ p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip; -+ 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_IpReassemblyTree = FM_PCD_CcRootBuild(p_FmPort->h_FmPcd, p_FmPcdCcTreeParams); -+ -+ if (!p_FmPort->h_IpReassemblyTree) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ XX_Free(p_FmPcdCcTreeParams); -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM_PCD_CcBuildTree for IPR 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_IpReassemblyTree; -+ p_PcdParams->p_CcParams = &fmPortPcdCcParams; -+ XX_Free(p_FmPcdCcTreeParams); -+ } -+ -+ err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, -+ p_PcdParams->p_CcParams->h_CcTree, -+ p_PcdParams->h_NetEnv, -+ p_FmPort->h_IpReassemblyManip, -+ TRUE); -+ if (err != E_OK) -+ { -+ if (p_FmPort->h_IpReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_IpReassemblyTree); -+ p_FmPort->h_IpReassemblyTree = NULL; -+ } -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ } -+ -+ if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd)) -+ { -+ if (p_FmPort->h_IpReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_IpReassemblyTree); -+ p_FmPort->h_IpReassemblyTree = 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_IpReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_IpReassemblyTree); -+ p_FmPort->h_IpReassemblyTree = NULL; -+ } -+ FmPcdLockUnlockAll(p_FmPort->h_FmPcd); -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MINOR, 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_IpReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_IpReassemblyTree); -+ p_FmPort->h_IpReassemblyTree = NULL; -+ } -+ FmPcdLockUnlockAll(p_FmPort->h_FmPcd); -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MINOR, 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) -+ { -+#if (DPAA_VERSION >= 11) -+#endif /* (DPAA_VERSION >= 11) */ -+ -+#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 */ -+ -+ /* 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_IpReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_IpReassemblyTree); -+ p_FmPort->h_IpReassemblyTree = NULL; -+ } -+ FmPcdLockUnlockAll(p_FmPort->h_FmPcd); -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MINOR, 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_FRAG | NIA_ENG_FM_CTL; -+ } -+ else -+ { -+#endif /* (DPAA_VERSION == 10) */ -+ fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE; -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE; -+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL; -+#if (DPAA_VERSION == 10) -+ } -+#endif /* (DPAA_VERSION == 10) */ -+ if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK) -+ { -+ DeletePcd(p_FmPort); -+ if (p_FmPort->h_IpReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_IpReassemblyTree); -+ p_FmPort->h_IpReassemblyTree = NULL; -+ } -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MINOR, 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_IpReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_IpReassemblyTree); -+ p_FmPort->h_IpReassemblyTree = NULL; -+ } -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ if (p_FmPort->h_IpReassemblyManip) -+ { -+#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_IpReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_IpReassemblyTree); -+ p_FmPort->h_IpReassemblyTree = NULL; -+ } -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ } -+ } -+ else -+ FmPcdLockUnlockAll(p_FmPort->h_FmPcd); -+ -+ err = AttachPCD(h_FmPort); -+ if (err) -+ { -+ DeletePcd(p_FmPort); -+ if (p_FmPort->h_IpReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_IpReassemblyTree); -+ p_FmPort->h_IpReassemblyTree = NULL; -+ } -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MINOR, 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 (!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_IpReassemblyTree) -+ { -+ err = FM_PCD_CcRootDelete(p_FmPort->h_IpReassemblyTree); -+ if (err) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ p_FmPort->h_IpReassemblyTree = 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; ih_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; ih_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_PcdPrsModifyStartOffset (t_Handle h_FmPort, t_FmPcdPrsStart *p_FmPcdPrsStart) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ volatile uint32_t *p_BmiPrsStartOffset = NULL; -+ volatile uint32_t *p_BmiNia = NULL; -+ uint32_t tmpReg; -+ uint8_t hdrNum; -+ -+ 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_PRS , E_INVALID_STATE); -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpso; -+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; -+ tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opso; -+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; -+ tmpReg = 0; -+ 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 (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) -+ { -+ DBG(TRACE, ("FM Port Try Lock - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ /* set the first header */ -+ GET_PRS_HDR_NUM(hdrNum, p_FmPcdPrsStart->firstPrsHdr); -+ if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM)) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header.")); -+ } -+ WRITE_UINT32(*p_BmiNia, (uint32_t)(NIA_ENG_PRS | (uint32_t)hdrNum | tmpReg)); -+ -+ /* set start parsing offset */ -+ WRITE_UINT32(*p_BmiPrsStartOffset, -+ (uint32_t)(p_FmPcdPrsStart->parsingOffset + -+ p_FmPort->internalBufferOffset)); -+ RELEASE_LOCK(p_FmPort->lock); -+ -+ return E_OK; -+} -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+t_Error FM_PORT_DumpRegs(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err = E_OK; -+ char arr[20]; -+ uint8_t flag; -+ int i=0; -+ -+ DECLARE_DUMP; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortQmiRegs, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortBmiRegs, E_INVALID_HANDLE); -+ -+ 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 ERROR_CODE(E_INVALID_VALUE); -+ } -+ -+ DUMP_TITLE(NULL, -+ ("FMan-Port (%s #%d) registers:", -+ arr, p_FmPort->portId)); -+ -+ err = FmDumpPortRegs(p_FmPort->h_Fm, p_FmPort->hardwarePortId); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ DUMP_TITLE(p_FmPort->p_FmPortBmiRegs, ("Bmi Port Regs")); -+ -+ switch (flag) -+ { -+ case (0): -+ -+ DUMP_SUBTITLE(("\n")); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ocfg); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ost); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oda); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oicp); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofdne); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofne); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofca); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofpne); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opso); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opp); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_occb); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oim); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofp); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofed); -+ -+ DUMP_TITLE(&(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oprai), ("fmbm_oprai")); -+ DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_PRS_RESULT_NUM_OF_WORDS) -+ { -+ DUMP_MEMORY(&(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oprai[i]), sizeof(uint32_t)); -+ } -+ DUMP_SUBTITLE(("\n")); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofqid ); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oefqid); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofsdm ); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofsem ); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofene ); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_orlmts); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_orlmt); -+ -+ { -+#ifndef FM_NO_OP_OBSERVED_POOLS -+ if (p_FmPort->fmRevInfo.majorRev == 4) -+ { -+ DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oebmpi, ("fmbm_oebmpi")); -+ -+ DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS) -+ { -+ DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oebmpi[i], sizeof(uint32_t)); -+ } -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ocgm); -+ } -+#endif /* !FM_NO_OP_OBSERVED_POOLS */ -+ } -+ -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ostc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofrc ); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofdc ); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofledc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofufdc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_offc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofwdc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofldec); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opcp); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_occn); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_otuc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oduc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofuc); -+ DUMP_TITLE(&(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_odcfg), ("fmbm_odcfg")); -+ DUMP_SUBSTRUCT_ARRAY(i, 3) -+ { -+ DUMP_MEMORY(&(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_odcfg[i]), sizeof(uint32_t)); -+ } -+ DUMP_SUBTITLE(("\n")); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ogpr); -+ break; -+ case (1): -+ DUMP_SUBTITLE(("\n")); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rcfg); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rst); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rda); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfp); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_reth); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfed); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_ricp); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rebm); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfne); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfca); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfpne); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpso); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpp); -+ -+ DUMP_TITLE(&(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rprai), ("fmbm_rprai")); -+ DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_PRS_RESULT_NUM_OF_WORDS) -+ { -+ DUMP_MEMORY(&(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rprai[i]), sizeof(uint32_t)); -+ } -+ DUMP_SUBTITLE(("\n")); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfqid); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_refqid); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfsdm); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfsem); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfene); -+ DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi, ("fmbm_ebmpi")); -+ DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_MAX_NUM_OF_EXT_POOLS) -+ { -+ DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i], sizeof(uint32_t)); -+ } -+ DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt, ("fmbm_acnt")); -+ DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_MAX_NUM_OF_EXT_POOLS) -+ { -+ DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt[i], sizeof(uint32_t)); -+ } -+ DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcgm, ("fmbm_rcgm")); -+ DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_NUM_OF_CONGESTION_GRPS/32) -+ { -+ DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcgm[i], sizeof(uint32_t)); -+ } -+ DUMP_SUBTITLE(("\n")); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rmpd); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rstc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfrc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfbc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rlfc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rffc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfcd); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfldec); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rodc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpcp); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rccn); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rtuc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rrquc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rduc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfuc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpac); -+ DUMP_TITLE(&(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rdcfg), ("fmbm_rdcfg")); -+ DUMP_SUBSTRUCT_ARRAY(i, 3) -+ { -+ DUMP_MEMORY(&(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rdcfg[i]), sizeof(uint32_t)); -+ } -+ DUMP_SUBTITLE(("\n")); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rgpr); -+ break; -+ case (2): -+ -+ DUMP_SUBTITLE(("\n")); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tcfg); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tst); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tda); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfp); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfed); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_ticp); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfdne); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfca); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tcfqid); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfeqid); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfene); -+#if (DPAA_VERSION >= 11) -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfne); -+#endif /* (DPAA_VERSION >= 11) */ -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_trlmts); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_trlmt); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tstc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfrc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfdc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfledc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfufdc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tpc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tpcp); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tccn); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_ttuc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_ttcquc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tduc); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfuc); -+ DUMP_TITLE(&(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tdcfg), ("fmbm_tdcfg")); -+ DUMP_SUBSTRUCT_ARRAY(i, 3) -+ { -+ DUMP_MEMORY(&(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tdcfg[i]), sizeof(uint32_t)); -+ } -+ DUMP_SUBTITLE(("\n")); -+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tgpr); -+ break; -+ -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid flag")); -+ } -+ -+ DUMP_TITLE(p_FmPort->p_FmPortQmiRegs, ("Qmi Port Regs")); -+ -+ DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnc); -+ DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pns); -+ DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnts); -+ DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnen); -+ DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnetfc); -+ -+ if (flag !=1) -+ { -+ DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndn); -+ DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndc); -+ DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndtfc); -+ DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndfdc); -+ DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndcc); -+ } -+ -+ return E_OK; -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ bool tmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS], opPort; -+ uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS]; -+ int i; -+ uint8_t mod; -+ uint32_t tmpReg = 0; -+#if (DPAA_VERSION >= 11) -+ int j; -+ t_Error err; -+#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(MINOR, 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")); -+ -+ opPort = (bool)((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? TRUE:FALSE); -+ -+ /* to minimize memory access (groups may belong to the same regsiter, and may -+ be out of order), we first collect all information into a 256 booleans array, -+ representing each possible group. */ -+ -+ memset(&tmpArray, 0, FM_PORT_NUM_OF_CONGESTION_GRPS*sizeof(bool)); -+ memset(&priorityTmpArray, 0, FM_PORT_NUM_OF_CONGESTION_GRPS*sizeof(uint8_t)); -+ -+ for (i=0; inumOfCongestionGrpsToConsider; i++) -+ { -+ tmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] = TRUE; -+ -+#if (DPAA_VERSION >= 11) -+ for (j=0;jpfcPrioritiesEn[i][j]) -+ priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |= (0x01 <<(FM_MAX_NUM_OF_PFC_PRIORITIES-j-1)); -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ -+ for (i=0; ip_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm): -+ GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcgm[FM_PORT_CG_REG_NUM(i)]); -+ -+ /* set in the register, the bit representing the relevant congestion group. */ -+ -+ if (tmpArray[i]) -+ { -+ tmpReg |= (0x00000001 << (uint32_t)mod); -+ -+#if (DPAA_VERSION >= 11) -+ err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm,i,priorityTmpArray[i]); -+ if (err) -+ return err; -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ -+ if (mod == 31) /* last in a 32 bunch of congestion groups - write the corresponding register */ -+ { -+ if (opPort) -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm, tmpReg); -+ else -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcgm[FM_PORT_CG_REG_NUM(i)], tmpReg); -+ } -+ } -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ bool tmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS], opPort; -+ int i; -+ uint8_t mod; -+ uint32_t tmpReg = 0; -+ -+ 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(MINOR, 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")); -+ -+ opPort = (bool)((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? TRUE:FALSE); -+ -+ /* to minimize memory access (groups may belong to the same regsiter, and may -+ be out of order), we first collect all information into a 256 booleans array, -+ representing each possible group. */ -+ memset(&tmpArray, 0, FM_PORT_NUM_OF_CONGESTION_GRPS*sizeof(bool)); -+ for (i=0; inumOfCongestionGrpsToConsider; i++) -+ tmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] = TRUE; -+ -+ for (i=0; ip_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm): -+ GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcgm[FM_PORT_CG_REG_NUM(i)]); -+ -+ /* set in the register, the bit representing the relevant congestion group. */ -+ if (tmpArray[i]) -+ { -+ tmpReg &= ~(0x00000001 << (uint32_t)mod); -+ -+#if (DPAA_VERSION >= 11) -+ { -+ t_Error err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i, 0); -+ if (err) -+ return err; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ if (mod == 31) /* last in a 32 bunch of congestion groups - write the corresponding register */ -+ { -+ if (opPort) -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm, tmpReg); -+ else -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcgm[FM_PORT_CG_REG_NUM(i)], tmpReg); -+ } -+ } -+ -+ return E_OK; -+} -+ -+#if (DPAA_VERSION >= 11) -+#endif /* (DPAA_VERSION >= 11) */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Port/fm_port.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/Port/fm_port.h -new file mode 100644 -index 0000000..5c01851 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Port/fm_port.h -@@ -0,0 +1,942 @@ -+/* -+ * 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" -+ -+ -+#define __ERR_MODULE__ MODULE_FM_PORT -+ -+ -+#define MIN_EXT_BUF_SIZE 64 -+#define DATA_ALIGNMENT 64 -+#define MAX_LIODN_OFFSET 64 -+ -+/**************************************************************************//** -+ @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_txFifoMinFillLevel 0 -+#define DEFAULT_PORT_fifoDeqPipelineDepth_IM 2 -+#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 1 -+#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4 -+#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2 -+ -+#define DEFAULT_PORT_txFifoLowComfLevel (5*KILOBYTE) -+#define DEFAULT_PORT_rxFifoPriElevationLevel BMI_MAX_FIFO_SIZE -+#define DEFAULT_PORT_rxFifoThreshold (BMI_MAX_FIFO_SIZE*3/4) -+#define DEFAULT_PORT_frmDiscardOverride FALSE -+ -+#define DEFAULT_PORT_dmaSwapData DEFAULT_FM_SP_dmaSwapData -+#define DEFAULT_PORT_dmaIntContextCacheAttr DEFAULT_FM_SP_dmaIntContextCacheAttr -+#define DEFAULT_PORT_dmaHeaderCacheAttr DEFAULT_FM_SP_dmaHeaderCacheAttr -+#define DEFAULT_PORT_dmaScatterGatherCacheAttr DEFAULT_FM_SP_dmaScatterGatherCacheAttr -+#define DEFAULT_PORT_dmaWriteOptimize DEFAULT_FM_SP_dmaWriteOptimize -+ -+#define DEFAULT_PORT_noScatherGather DEFAULT_FM_SP_noScatherGather -+#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 -+ -+/* 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) || \ -+ ((type) == e_FM_PORT_TYPE_TX_10G)) ? 8 : \ -+ ((((type) == e_FM_PORT_TYPE_RX) || \ -+ ((type) == e_FM_PORT_TYPE_TX)) ? 2 : 0)) -+ -+#define DEFAULT_PORT_numOfOpenDmas(type, rev) \ -+ (uint32_t)((((type) == e_FM_PORT_TYPE_TX_10G) || \ -+ ((type) == e_FM_PORT_TYPE_RX_10G)) ? 8 : ((rev>=6) ? 2 : 1)) -+ -+#define DEFAULT_PORT_extraNumOfOpenDmas(type) \ -+ (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \ -+ ((type) == e_FM_PORT_TYPE_TX_10G)) ? 8 : \ -+ ((((type) == e_FM_PORT_TYPE_RX) || \ -+ ((type) == e_FM_PORT_TYPE_TX)) ? 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) || \ -+ ((type) == e_FM_PORT_TYPE_TX)) ? 44 : 8)) -+ -+#define DEFAULT_PORT_extraNumOfFifoBufs 0 -+ -+#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 IP-fragmentation labels (offsets) */ -+/***********************************************************************/ -+#if (DPAA_VERSION == 10) -+#define IP_FRAG_SW_PATCH_IPv4_SIZE 0x025 -+#define IP_FRAG_SW_PATCH_IPv4_LABEL 0x300 -+#else -+#define IP_FRAG_SW_PATCH_IPv4_SIZE 0x046 -+#define IP_FRAG_SW_PATCH_IPv4_LABEL 0x2E0 -+#endif /* (DPAA_VERSION == 10) */ -+#define IP_FRAG_SW_PATCH_IPv6_LABEL \ -+ (IP_FRAG_SW_PATCH_IPv4_LABEL + IP_FRAG_SW_PATCH_IPv4_SIZE) -+ -+#ifdef FM_CAPWAP_SUPPORT -+#define UDP_LITE_SW_PATCH_LABEL 0x2E0 -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+/**************************************************************************//** -+ @Description Memory Mapped Registers -+*//***************************************************************************/ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+typedef _Packed 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) */ -+} _PackedType t_FmPortRxBmiRegs; -+ -+typedef _Packed 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 reserved1[0x02];/**< (0x074-0x7C) */ -+ 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) */ -+} _PackedType t_FmPortTxBmiRegs; -+ -+typedef _Packed 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) */ -+} _PackedType t_FmPortOhBmiRegs; -+ -+typedef _Packed union -+{ -+ t_FmPortRxBmiRegs rxPortBmiRegs; -+ t_FmPortTxBmiRegs txPortBmiRegs; -+ t_FmPortOhBmiRegs ohPortBmiRegs; -+} _PackedType u_FmPortBmiRegs; -+ -+typedef _Packed 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 */ -+} _PackedType t_FmPortNonRxQmiRegs; -+ -+typedef _Packed 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 */ -+} _PackedType t_FmPortQmiRegs; -+ -+typedef _Packed struct -+{ -+ _Packed struct -+ { -+ volatile uint32_t softSeqAttach; /**< Soft Sequence Attachment */ -+ volatile uint32_t lcv; /**< Line-up Enable Confirmation Mask */ -+ } _PackedType hdrs[FM_PCD_PRS_NUM_OF_HDRS]; -+ volatile uint8_t reserved0[0x378]; -+ volatile uint32_t pcac; /**< Parse Internal Memory Configuration Access Control Register */ -+ volatile uint32_t pctpid; /**< Parse Internal Memory Configured TPID Register */ -+} _PackedType 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 -+#define BMI_EBD_EN 0x80000000 -+#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_STATUS_BSY 0x80000000 -+#define BMI_COUNTERS_EN 0x80000000 -+#define BMI_DMA_ATTR_WRITE_OPTIMIZE FM_SP_DMA_ATTR_WRITE_OPTIMIZE -+ -+#define BMI_PORT_RFNE_FRWD_DCL4C 0x10000000 -+#define BMI_PORT_RFNE_FRWD_RPD 0x40000000 -+#define BMI_RFNE_FDCS_MASK 0xFF000000 -+ -+#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_TX_MR_DEF (0) -+#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_EN_COUNTER FM_SP_EXT_BUF_POOL_EN_COUNTER -+#define BMI_EXT_BUF_POOL_VALID FM_SP_EXT_BUF_POOL_VALID -+ -+#define BMI_EXT_BUF_POOL_BACKUP FM_SP_EXT_BUF_POOL_BACKUP -+ -+#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_KEYSIZE_OVERFLOW)) -+ -+#define BMI_STATUS_OP_MASK_UNUSED (uint32_t)(BMI_STATUS_RX_MASK_UNUSED & \ -+ ~(FM_PORT_FRM_ERR_LENGTH | \ -+ 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_SWP_SHIFT FM_SP_DMA_ATTR_SWP_SHIFT -+#define BMI_DMA_ATTR_IC_CACHE_SHIFT FM_SP_DMA_ATTR_IC_CACHE_SHIFT -+#define BMI_DMA_ATTR_HDR_CACHE_SHIFT FM_SP_DMA_ATTR_HDR_CACHE_SHIFT -+#define BMI_DMA_ATTR_SG_CACHE_SHIFT FM_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_TO_EXT_SHIFT FM_SP_IC_TO_EXT_SHIFT -+#define BMI_IC_FROM_INT_SHIFT FM_SP_IC_FROM_INT_SHIFT -+#define BMI_IC_SIZE_SHIFT FM_SP_IC_SIZE_SHIFT -+ -+#define BMI_INT_BUF_MARG_SHIFT 28 -+ -+#define BMI_EXT_BUF_MARG_START_SHIFT FM_SP_EXT_BUF_MARG_START_SHIFT -+#define BMI_SG_DISABLE FM_SP_SG_DISABLE -+#define BMI_EXT_BUF_MARG_END_SHIFT FM_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_SHIFT FM_SP_POOL_DEP_NUM_OF_POOLS_SHIFT -+#define BMI_POOL_DEP_NUM_OF_POOLS_VECTOR_SHIFT 24 -+ -+#define BMI_EXT_BUF_POOL_ID_SHIFT FM_SP_EXT_BUF_POOL_ID_SHIFT -+#define BMI_TX_FIFO_MIN_FILL_SHIFT 16 -+#define BMI_FIFO_PIPELINE_DEPTH_SHIFT 12 -+#define BMI_TX_LOW_COMF_SHIFT 0 -+ -+#define BMI_FRAME_END_CS_IGNORE_SHIFT 24 -+ -+#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 BD_ERROR_PASS_FRAME BD_RX_ERRORS -+ -+#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 { -+ 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_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; -+ uint8_t fifoDeqPipelineDepth; -+ 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 savedNonRxQmiRegsPndn; -+ int savedPrsStartOffset; -+ bool includeInPrsStatistics; -+ uint16_t maxFrameLength; -+ t_FmFmanCtrl orFmanCtrl; -+ t_FmPortRsrc openDmas; -+ t_FmPortRsrc tasks; -+ t_FmPortRsrc fifoBufs; -+ t_FmPortRxPoolsParams rxPoolsParams; -+ t_Handle h_IpReassemblyManip; -+ t_Handle h_IpReassemblyTree; -+ uint64_t fmMuramPhysBaseAddr; -+#if (DPAA_VERSION >= 11) -+ bool vspe; -+ e_FmPortGprFuncType gprFunc; -+ void *p_MuramPage; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ 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; -+} -+ -+ -+#endif /* __FM_PORT_H */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Port/fm_port_im.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/Port/fm_port_im.c -new file mode 100644 -index 0000000..bf358a5 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Port/fm_port_im.c -@@ -0,0 +1,754 @@ -+/* -+ * 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 "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) && 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/*, reportErrors*/; -+ 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; -+ -+ errors = 0; -+ 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 ) -+ - There is an error, but it was defined to be passed anyway. */ -+ if ((buffPos != SINGLE_BUF) || !errors || (errors & (uint16_t)(BD_ERROR_PASS_FRAME>>16))) -+ { -+ 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); -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Rtc/Makefile b/drivers/net/dpa/NetCommSw/Peripherals/FM/Rtc/Makefile -new file mode 100644 -index 0000000..dbe51ff ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Rtc/Makefile -@@ -0,0 +1,15 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+ -+NCSW_FM_INC = $(srctree)/drivers/net/dpa/NetCommSw/Peripherals/FM/inc -+ -+EXTRA_CFLAGS += -I$(NCSW_FM_INC) -+ -+obj-y += fsl-ncsw-RTC.o -+ -+fsl-ncsw-RTC-objs := fm_rtc.o -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Rtc/fm_rtc.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/Rtc/fm_rtc.c -new file mode 100644 -index 0000000..d65b1d4 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Rtc/fm_rtc.c -@@ -0,0 +1,878 @@ -+/* -+ * 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 "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 void SetDefaultParam(t_FmRtc *p_Rtc) -+{ -+ t_FmRtcDriverParam *p_RtcDriverParam = p_Rtc->p_RtcDriverParam; -+ int i; -+ -+ p_Rtc->outputClockDivisor = DEFAULT_outputClockDivisor; -+ p_Rtc->p_RtcDriverParam->bypass = DEFAULT_bypass; -+ p_RtcDriverParam->srcClk = DEFAULT_srcClock; -+ p_RtcDriverParam->invertInputClkPhase = DEFAULT_invertInputClkPhase; -+ p_RtcDriverParam->invertOutputClkPhase = DEFAULT_invertOutputClkPhase; -+ p_RtcDriverParam->pulseRealign = DEFAULT_pulseRealign; -+ for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++) -+ { -+ p_RtcDriverParam->alarmPolarity[i] = DEFAULT_alarmPolarity; -+ } -+ for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++) -+ { -+ p_RtcDriverParam->triggerPolarity[i] = DEFAULT_triggerPolarity; -+ } -+ p_Rtc->clockPeriodNanoSec = DEFAULT_clockPeriod; /* 1 usec */ -+} -+ -+/*****************************************************************************/ -+static t_Error CheckInitParameters(t_FmRtc *p_Rtc) -+{ -+ t_FmRtcDriverParam *p_RtcDriverParam = p_Rtc->p_RtcDriverParam; -+ int i; -+ -+ if ((p_RtcDriverParam->srcClk != e_FM_RTC_SOURCE_CLOCK_EXTERNAL) && -+ (p_RtcDriverParam->srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM) && -+ (p_RtcDriverParam->srcClk != e_FM_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->alarmPolarity[i] != e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW) && -+ (p_RtcDriverParam->alarmPolarity[i] != e_FM_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->triggerPolarity[i] != e_FM_RTC_TRIGGER_ON_FALLING_EDGE) && -+ (p_RtcDriverParam->triggerPolarity[i] != e_FM_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; -+ t_FmRtcMemMap *p_MemMap; -+ register uint32_t events; -+ -+ ASSERT_COND(p_Rtc); -+ p_MemMap = p_Rtc->p_MemMap; -+ -+ /* Get valid events */ -+ events = GET_UINT32(p_MemMap->tmr_tevent); -+ events &= GET_UINT32(p_MemMap->tmr_temask); -+ -+ /* Clear event bits */ -+ WRITE_UINT32(p_MemMap->tmr_tevent, events); -+ -+ if (events & TMR_TEVENT_ALM1) -+ { -+ if (p_Rtc->alarmParams[0].clearOnExpiration) -+ { -+ WRITE_UINT32(p_MemMap->tmr_alarm[0].tmr_alarm_l, 0); -+ WRITE_UINT32(p_MemMap->tmr_temask, GET_UINT32(p_MemMap->tmr_temask) & ~TMR_TEVENT_ALM1); -+ } -+ ASSERT_COND(p_Rtc->alarmParams[0].f_AlarmCallback); -+ p_Rtc->alarmParams[0].f_AlarmCallback(p_Rtc->h_App, 0); -+ } -+ if (events & TMR_TEVENT_ALM2) -+ { -+ if (p_Rtc->alarmParams[1].clearOnExpiration) -+ { -+ WRITE_UINT32(p_MemMap->tmr_alarm[1].tmr_alarm_l, 0); -+ WRITE_UINT32(p_MemMap->tmr_temask, GET_UINT32(p_MemMap->tmr_temask) & ~TMR_TEVENT_ALM2); -+ } -+ ASSERT_COND(p_Rtc->alarmParams[1].f_AlarmCallback); -+ p_Rtc->alarmParams[1].f_AlarmCallback(p_Rtc->h_App, 1); -+ } -+ if (events & TMR_TEVENT_PP1) -+ { -+ ASSERT_COND(p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback); -+ p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback(p_Rtc->h_App, 0); -+ } -+ if (events & TMR_TEVENT_PP2) -+ { -+ ASSERT_COND(p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback); -+ p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback(p_Rtc->h_App, 1); -+ } -+ if (events & TMR_TEVENT_ETS1) -+ { -+ ASSERT_COND(p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback); -+ p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback(p_Rtc->h_App, 0); -+ } -+ if (events & 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 = (t_FmRtcDriverParam *)XX_Malloc(sizeof(t_FmRtcDriverParam)); -+ 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(t_FmRtcDriverParam)); -+ -+ /* Store RTC configuration parameters */ -+ p_Rtc->h_Fm = p_FmRtcParam->h_Fm; -+ -+ /* Set default RTC configuration parameters */ -+ SetDefaultParam(p_Rtc); -+ -+ /* Store RTC parameters in the RTC control structure */ -+ p_Rtc->p_MemMap = (t_FmRtcMemMap *)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; -+ t_FmRtcDriverParam *p_RtcDriverParam; -+ t_FmRtcMemMap *p_MemMap; -+ uint32_t freqCompensation; -+ uint32_t tmrCtrl; -+ int i; -+ uint64_t tmpDouble; -+ -+ 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. */ -+ WRITE_UINT32(p_MemMap->tmr_ctrl, TMR_CTRL_TMSR); -+ XX_UDelay(10); -+ WRITE_UINT32(p_MemMap->tmr_ctrl, 0); -+ -+ /* Set the source clock */ -+ switch (p_RtcDriverParam->srcClk) -+ { -+ case e_FM_RTC_SOURCE_CLOCK_SYSTEM: -+ tmrCtrl = TMR_CTRL_CKSEL_MAC_CLK; -+ break; -+ case e_FM_RTC_SOURCE_CLOCK_OSCILATOR: -+ tmrCtrl = TMR_CTRL_CKSEL_OSC_CLK; -+ break; -+ default: -+ /* Use a clock from the External TMR reference clock.*/ -+ tmrCtrl = TMR_CTRL_CKSEL_EXT_CLK; -+ break; -+ } -+ -+ /* whatever period the user picked, the timestamp will advance in '1' every time -+ * the period passed. */ -+ tmrCtrl |= ((1 << TMR_CTRL_TCLK_PERIOD_SHIFT) & TMR_CTRL_TCLK_PERIOD_MASK); -+ -+ if (p_RtcDriverParam->invertInputClkPhase) -+ tmrCtrl |= TMR_CTRL_CIPH; -+ if (p_RtcDriverParam->invertOutputClkPhase) -+ tmrCtrl |= TMR_CTRL_COPH; -+ -+ for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++) -+ { -+ if (p_RtcDriverParam->alarmPolarity[i] == e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW) -+ tmrCtrl |= (TMR_CTRL_ALMP1 >> i); -+ } -+ -+ for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++) -+ if (p_RtcDriverParam->triggerPolarity[i] == e_FM_RTC_TRIGGER_ON_FALLING_EDGE) -+ tmrCtrl |= (TMR_CTRL_ETEP1 << i); -+ -+ if (!p_RtcDriverParam->timerSlaveMode && p_Rtc->p_RtcDriverParam->bypass) -+ tmrCtrl |= TMR_CTRL_BYP; -+ -+ WRITE_UINT32(p_MemMap->tmr_ctrl, tmrCtrl); -+ -+ for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++) -+ { -+ /* Clear TMR_ALARM registers */ -+ WRITE_UINT32(p_MemMap->tmr_alarm[i].tmr_alarm_l, 0xFFFFFFFF); -+ WRITE_UINT32(p_MemMap->tmr_alarm[i].tmr_alarm_h, 0xFFFFFFFF); -+ } -+ -+ /* Clear TMR_TEVENT */ -+ WRITE_UINT32(p_MemMap->tmr_tevent, TMR_TEVENT_ALL); -+ -+ /* Initialize TMR_TEMASK */ -+ WRITE_UINT32(p_MemMap->tmr_temask, 0); -+ -+ -+ /* find source clock frequency in Mhz */ -+ if (p_Rtc->p_RtcDriverParam->srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM) -+ p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->extSrcClkFreq; -+ else -+ p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetClockFreq(p_Rtc->h_Fm)/2); -+ -+ /* if timer in Master mode Initialize TMR_CTRL */ -+ /* We want the counter (TMR_CNT) to count in nano-seconds */ -+ if (!p_RtcDriverParam->timerSlaveMode && 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) */ -+ freqCompensation = (uint32_t)DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000, -+ p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz); -+ WRITE_UINT32(p_MemMap->tmr_add, freqCompensation); -+ } -+ /* 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")); -+ -+ -+ for (i=0; i < 2; i++) -+ /* Clear TMR_FIPER registers */ -+ WRITE_UINT32(p_MemMap->tmr_fiper[i], 0xFFFFFFFF); -+ -+ /* Initialize TMR_PRSC */ -+ WRITE_UINT32(p_MemMap->tmr_prsc, p_Rtc->outputClockDivisor); -+ -+ /* Clear TMR_OFF */ -+ WRITE_UINT32(p_MemMap->tmr_off_l, 0); -+ WRITE_UINT32(p_MemMap->tmr_off_h, 0); -+ -+ /* 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->srcClk = srcClk; -+ if (srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM) -+ p_Rtc->p_RtcDriverParam->extSrcClkFreq = 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->invertInputClkPhase = 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->invertOutputClkPhase = 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->pulseRealign = 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->alarmPolarity[alarmId] = 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->triggerPolarity[triggerId] = triggerPolarity; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ uint32_t tmrCtrl; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ tmrCtrl = GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl); -+ -+ /* TODO check that no timestamping MACs are working in this stage. */ -+ if (resetClock) -+ { -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, (tmrCtrl | TMR_CTRL_TMSR)); -+ -+ XX_UDelay(10); -+ /* Clear TMR_OFF */ -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_off_l, 0); -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_off_h, 0); -+ } -+ -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, (tmrCtrl | TMR_CTRL_TE)); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_Disable(t_Handle h_FmRtc) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ uint32_t tmrCtrl; -+ -+ 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. */ -+ tmrCtrl = GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl); -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, (tmrCtrl & ~(TMR_CTRL_TE))); -+ -+ 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); -+ -+ /* TMR_OFF_L must be written first */ -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_off_l, (uint32_t)offset); -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_off_h, (uint32_t)(offset >> 32)); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ t_FmRtcMemMap *p_MemMap; -+ uint32_t tmpReg; -+ uint64_t tmpAlarm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ p_MemMap = p_Rtc->p_MemMap; -+ -+ 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)); -+ if (p_FmRtcAlarmParams->alarmTime % (uint64_t)p_Rtc->clockPeriodNanoSec) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm time must be a multiple of RTC period - %d nanoseconds", p_Rtc->clockPeriodNanoSec)); -+ tmpAlarm = p_FmRtcAlarmParams->alarmTime/(uint64_t)p_Rtc->clockPeriodNanoSec; -+ -+ /* TMR_ALARM_L must be written first */ -+ WRITE_UINT32(p_MemMap->tmr_alarm[p_FmRtcAlarmParams->alarmId].tmr_alarm_l, (uint32_t)tmpAlarm); -+ WRITE_UINT32(p_MemMap->tmr_alarm[p_FmRtcAlarmParams->alarmId].tmr_alarm_h, -+ (uint32_t)(tmpAlarm >> 32)); -+ -+ 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; -+ -+ if (p_FmRtcAlarmParams->alarmId == 0) -+ tmpReg = TMR_TEVENT_ALM1; -+ else -+ tmpReg = TMR_TEVENT_ALM2; -+ WRITE_UINT32(p_MemMap->tmr_temask, GET_UINT32(p_MemMap->tmr_temask) | tmpReg); -+ } -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ t_FmRtcMemMap *p_MemMap; -+ uint32_t tmpReg; -+ uint64_t tmpFiper; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ p_MemMap = p_Rtc->p_MemMap; -+ -+ if (p_FmRtcPeriodicPulseParams->periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES) -+ { -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID")); -+ } -+ if (GET_UINT32(p_MemMap->tmr_ctrl) & TMR_CTRL_TE) -+ 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)); -+ if (p_FmRtcPeriodicPulseParams->periodicPulsePeriod % (uint64_t)p_Rtc->clockPeriodNanoSec) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse must be a multiple of RTC period - %d nanoseconds", p_Rtc->clockPeriodNanoSec)); -+ tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod/(uint64_t)p_Rtc->clockPeriodNanoSec; -+ if (tmpFiper & 0xffffffff00000000LL) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse/RTC Period must be smaller than 4294967296", p_Rtc->clockPeriodNanoSec)); -+ -+ WRITE_UINT32(p_MemMap->tmr_fiper[p_FmRtcPeriodicPulseParams->periodicPulseId], (uint32_t)tmpFiper); -+ -+ if (p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback) -+ { -+ p_Rtc->periodicPulseParams[p_FmRtcPeriodicPulseParams->periodicPulseId].f_PeriodicPulseCallback = -+ p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback; -+ -+ if (p_FmRtcPeriodicPulseParams->periodicPulseId == 0) -+ tmpReg = TMR_TEVENT_PP1; -+ else -+ tmpReg = TMR_TEVENT_PP2; -+ WRITE_UINT32(p_MemMap->tmr_temask, GET_UINT32(p_MemMap->tmr_temask) | tmpReg); -+ } -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ uint32_t tmpReg; -+ -+ 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; -+ -+ if (periodicPulseId == 0) -+ tmpReg = TMR_TEVENT_PP1; -+ else -+ tmpReg = TMR_TEVENT_PP2; -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_temask, GET_UINT32(p_Rtc->p_MemMap->tmr_temask) & ~tmpReg); -+ -+ if (GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) & TMR_CTRL_FS) -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) & ~TMR_CTRL_FS); -+ -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_fiper[periodicPulseId], 0xFFFFFFFF); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ uint32_t tmpReg; -+ -+ 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; -+ if (p_FmRtcExternalTriggerParams->externalTriggerId == 0) -+ tmpReg = TMR_TEVENT_ETS1; -+ else -+ tmpReg = TMR_TEVENT_ETS2; -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_temask, GET_UINT32(p_Rtc->p_MemMap->tmr_temask) | tmpReg); -+ } -+ -+ if (p_FmRtcExternalTriggerParams->usePulseAsInput) -+ { -+ if (p_FmRtcExternalTriggerParams->externalTriggerId == 0) -+ tmpReg = TMR_CTRL_PP1L; -+ else -+ tmpReg = TMR_CTRL_PP2L; -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) | tmpReg); -+ } -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ uint32_t tmpReg; -+ -+ 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; -+ -+ if (externalTriggerId == 0) -+ tmpReg = TMR_TEVENT_ETS1; -+ else -+ tmpReg = TMR_TEVENT_ETS2; -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_temask, GET_UINT32(p_Rtc->p_MemMap->tmr_temask) & ~tmpReg); -+ -+ if (externalTriggerId == 0) -+ tmpReg = TMR_CTRL_PP1L; -+ else -+ tmpReg = TMR_CTRL_PP2L; -+ -+ if (GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) & tmpReg) -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) & ~tmpReg); -+ -+ 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; -+ uint64_t timeStamp; -+ -+ 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")); -+ } -+ -+ timeStamp = (uint64_t)GET_UINT32(p_Rtc->p_MemMap->tmr_etts[triggerId].tmr_etts_l); -+ timeStamp |= ((uint64_t)GET_UINT32(p_Rtc->p_MemMap->tmr_etts[triggerId].tmr_etts_h) << 32); -+ -+ timeStamp = timeStamp*p_Rtc->clockPeriodNanoSec; -+ *p_TimeStamp = timeStamp; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ uint64_t time; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ /* TMR_CNT_L must be read first to get an accurate value */ -+ time = (uint64_t)GET_UINT32(p_Rtc->p_MemMap->tmr_cnt_l); -+ time |= ((uint64_t)GET_UINT32(p_Rtc->p_MemMap->tmr_cnt_h) << 32); -+ -+ time = time*p_Rtc->clockPeriodNanoSec; -+ -+ *p_Ts = time; -+ -+ 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); -+ -+ ts = ts/p_Rtc->clockPeriodNanoSec; -+ /* TMR_CNT_L must be written first to get an accurate value */ -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_cnt_l, (uint32_t)ts); -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_cnt_h, (uint32_t)(ts >> 32)); -+ -+ 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 = GET_UINT32(p_Rtc->p_MemMap->tmr_add); -+ -+ 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 */ -+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_add, freqCompensation); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+t_Error FM_RTC_DumpRegs(t_Handle h_FmRtc) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ t_FmRtcMemMap *p_MemMap = p_Rtc->p_MemMap; -+ int i = 0; -+ -+ DECLARE_DUMP; -+ -+ if (p_MemMap) -+ { -+ -+ DUMP_TITLE(p_MemMap, ("RTC:")); -+ DUMP_VAR(p_MemMap, tmr_id); -+ DUMP_VAR(p_MemMap, tmr_id2); -+ DUMP_VAR(p_MemMap, tmr_ctrl); -+ DUMP_VAR(p_MemMap, tmr_tevent); -+ DUMP_VAR(p_MemMap, tmr_temask); -+ DUMP_VAR(p_MemMap, tmr_cnt_h); -+ DUMP_VAR(p_MemMap, tmr_cnt_l); -+ DUMP_VAR(p_MemMap, tmr_ctrl); -+ DUMP_VAR(p_MemMap, tmr_add); -+ DUMP_VAR(p_MemMap, tmr_acc); -+ DUMP_VAR(p_MemMap, tmr_prsc); -+ DUMP_VAR(p_MemMap, tmr_off_h); -+ DUMP_VAR(p_MemMap, tmr_off_l); -+ -+ DUMP_SUBSTRUCT_ARRAY(i, 2) -+ { -+ DUMP_VAR(p_MemMap, tmr_alarm[i].tmr_alarm_h); -+ DUMP_VAR(p_MemMap, tmr_alarm[i].tmr_alarm_l); -+ } -+ DUMP_SUBSTRUCT_ARRAY(i, 2) -+ { -+ DUMP_VAR(p_MemMap, tmr_fiper[i]); -+ DUMP_VAR(p_MemMap, tmr_fiper[i]); -+ } -+ DUMP_SUBSTRUCT_ARRAY(i, 2) -+ { -+ DUMP_VAR(p_MemMap, tmr_etts[i].tmr_etts_l); -+ DUMP_VAR(p_MemMap, tmr_etts[i].tmr_etts_l); -+ } -+ } -+ -+ return E_OK; -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/Rtc/fm_rtc.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/Rtc/fm_rtc.h -new file mode 100644 -index 0000000..4c1a422 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/Rtc/fm_rtc.h -@@ -0,0 +1,216 @@ -+/* -+ * 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 NANOSEC_PER_ONE_HZ_TICK 1000000000 -+#define MIN_RTC_CLK_FREQ_HZ 1000 -+#define MHz 1000000 -+ -+#define ACCUMULATOR_OVERFLOW ((uint64_t)(1LL << 32)) -+ -+/* RTC default values */ -+#define DEFAULT_srcClock e_FM_RTC_SOURCE_CLOCK_SYSTEM -+#define DEFAULT_bypass FALSE -+#define DEFAULT_invertInputClkPhase FALSE -+#define DEFAULT_invertOutputClkPhase FALSE -+#define DEFAULT_outputClockDivisor 0x00000002 -+#define DEFAULT_alarmPolarity e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH -+#define DEFAULT_triggerPolarity e_FM_RTC_TRIGGER_ON_FALLING_EDGE -+#define DEFAULT_pulseRealign FALSE -+#define DEFAULT_clockPeriod 1000 -+ -+/* FM RTC Registers definitions */ -+#define TMR_CTRL_ALMP1 0x80000000 -+#define TMR_CTRL_ALMP2 0x40000000 -+#define TMR_CTRL_FS 0x10000000 -+#define TMR_CTRL_PP1L 0x08000000 -+#define TMR_CTRL_PP2L 0x04000000 -+#define TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000 -+#define TMR_CTRL_FRD 0x00004000 -+#define TMR_CTRL_SLV 0x00002000 -+#define TMR_CTRL_ETEP1 0x00000100 -+#define TMR_CTRL_COPH 0x00000080 -+#define TMR_CTRL_CIPH 0x00000040 -+#define TMR_CTRL_TMSR 0x00000020 -+#define TMR_CTRL_DBG 0x00000010 -+#define TMR_CTRL_BYP 0x00000008 -+#define TMR_CTRL_TE 0x00000004 -+#define TMR_CTRL_CKSEL_OSC_CLK 0x00000003 -+#define TMR_CTRL_CKSEL_MAC_CLK 0x00000001 -+#define TMR_CTRL_CKSEL_EXT_CLK 0x00000000 -+#define TMR_CTRL_TCLK_PERIOD_SHIFT 16 -+ -+#define TMR_TEVENT_ETS2 0x02000000 -+#define TMR_TEVENT_ETS1 0x01000000 -+#define TMR_TEVENT_ALM2 0x00020000 -+#define TMR_TEVENT_ALM1 0x00010000 -+#define TMR_TEVENT_PP1 0x00000080 -+#define TMR_TEVENT_PP2 0x00000040 -+#define TMR_TEVENT_PP3 0x00000020 -+#define TMR_TEVENT_ALL (TMR_TEVENT_ETS2 | TMR_TEVENT_ETS1 | \ -+ TMR_TEVENT_ALM2 | TMR_TEVENT_ALM1 | \ -+ TMR_TEVENT_PP1 | TMR_TEVENT_PP2 | TMR_TEVENT_PP3) -+ -+#define TMR_PRSC_OCK_MASK 0x0000FFFF -+ -+ -+/**************************************************************************//** -+ @Description Memory Mapped Registers -+*//***************************************************************************/ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+/**************************************************************************//** -+ @Description FM RTC timer alarm -+*//***************************************************************************/ -+typedef _Packed struct t_TmrAlaram -+{ -+ volatile uint32_t tmr_alarm_h; /**< */ -+ volatile uint32_t tmr_alarm_l; /**< */ -+} _PackedType t_TmrAlaram; -+ -+/**************************************************************************//** -+ @Description FM RTC timer Ex trigger -+*//***************************************************************************/ -+typedef _Packed struct t_TmrExtTrigger -+{ -+ volatile uint32_t tmr_etts_h; /**< */ -+ volatile uint32_t tmr_etts_l; /**< */ -+} _PackedType t_TmrExtTrigger; -+ -+typedef _Packed struct -+{ -+ volatile uint32_t tmr_id; /* Module ID and version register */ -+ volatile uint32_t tmr_id2; /* Module ID and configuration register */ -+ volatile uint32_t PTP_RESERVED1[30]; -+ volatile uint32_t tmr_ctrl; /* timer control register */ -+ volatile uint32_t tmr_tevent; /* timer event register */ -+ volatile uint32_t tmr_temask; /* timer event mask register */ -+ volatile uint32_t PTP_RESERVED2[3]; -+ volatile uint32_t tmr_cnt_h; /* timer counter high register */ -+ volatile uint32_t tmr_cnt_l; /* timer counter low register */ -+ volatile uint32_t tmr_add; /* timer drift compensation addend register */ -+ volatile uint32_t tmr_acc; /* timer accumulator register */ -+ volatile uint32_t tmr_prsc; /* timer prescale */ -+ volatile uint32_t PTP_RESERVED3; -+ volatile uint32_t tmr_off_h; /* timer offset high */ -+ volatile uint32_t tmr_off_l; /* timer offset low */ -+ volatile t_TmrAlaram tmr_alarm[FM_RTC_NUM_OF_ALARMS]; /* timer alarm */ -+ volatile uint32_t PTP_RESERVED4[2]; -+ volatile uint32_t tmr_fiper[FM_RTC_NUM_OF_PERIODIC_PULSES]; /* timer fixed period interval */ -+ volatile uint32_t PTP_RESERVED5[2]; -+ volatile t_TmrExtTrigger tmr_etts[FM_RTC_NUM_OF_EXT_TRIGGERS]; /*time stamp general purpose external */ -+ volatile uint32_t PTP_RESERVED6[3]; -+} _PackedType t_FmRtcMemMap; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+/**************************************************************************//** -+ @Description RTC FM driver parameters structure. -+*//***************************************************************************/ -+typedef struct t_FmRtcDriverParam -+{ -+ t_Handle h_Fm; /**< */ -+ e_FmSrcClk srcClk; /**< */ -+ uint32_t extSrcClkFreq; /**< */ -+ uint32_t rtcFreqHz; /**< */ -+ bool timerSlaveMode; /*Slave/Master Mode*/ -+ bool invertInputClkPhase; -+ bool invertOutputClkPhase; -+ uint32_t eventsMask; -+ bool bypass; /**< Indicates if frequency compensation is bypassed */ -+ bool pulseRealign; -+ e_FmRtcAlarmPolarity alarmPolarity[FM_RTC_NUM_OF_ALARMS]; -+ e_FmRtcTriggerPolarity triggerPolarity[FM_RTC_NUM_OF_EXT_TRIGGERS]; -+} t_FmRtcDriverParam; -+ -+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 */ -+ t_FmRtcMemMap *p_MemMap; /**< Pointer to RTC memory map */ -+ 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]; -+ t_FmRtcDriverParam *p_RtcDriverParam; /**< RTC Driver parameters (for Init phase) */ -+} t_FmRtc; -+ -+ -+#endif /* __FM_RTC_H__ */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/SP/Makefile b/drivers/net/dpa/NetCommSw/Peripherals/FM/SP/Makefile -new file mode 100644 -index 0000000..ad469cd ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/SP/Makefile -@@ -0,0 +1,15 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+ -+NCSW_FM_INC = $(srctree)/drivers/net/dpa/NetCommSw/Peripherals/FM/inc -+ -+EXTRA_CFLAGS += -I$(NCSW_FM_INC) -+ -+obj-y += fsl-ncsw-sp.o -+ -+fsl-ncsw-sp-objs := fm_sp.o -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/SP/fm_sp.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/SP/fm_sp.c -new file mode 100644 -index 0000000..a457078 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/SP/fm_sp.c -@@ -0,0 +1,857 @@ -+/* -+ * 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" -+ -+ -+#if (DPAA_VERSION >= 11) -+ -+static void fm_vsp_fill_entry(fm_pcd_storage_profile_regs *regs, -+ uint16_t index, -+ fm_storage_profile_params *fm_vsp_params) -+{ -+ int i = 0, j = 0; -+ fm_pcd_storage_profile_regs *sp_regs; -+ uint32_t tmp_reg, vector; -+ t_FmExtPools *ext_buf_pools = fm_vsp_params->fm_ext_pools; -+ t_FmBufPoolDepletion *buf_pool_depletion= fm_vsp_params->buf_pool_depletion; -+ t_FmBackupBmPools *backup_pools = fm_vsp_params->backup_pools; -+ t_FmSpIntContextDataCopy *int_context_data_copy = fm_vsp_params->int_context; -+ t_FmSpBufMargins *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; -+ -+ ASSERT_COND(regs); -+ ASSERT_COND(ext_buf_pools); -+ ASSERT_COND(int_context_data_copy); -+ ASSERT_COND(external_buffer_margins); -+ ASSERT_COND(IN_RANGE(0, index, FM_VSP_MAX_NUM_OF_ENTRIES)); -+ -+ sp_regs = ®s[index]; -+ -+ /* fill external buffers manager pool information register*/ -+ for (i=0;inumOfPoolsUsed;i++) -+ { -+ tmp_reg = FM_SP_EXT_BUF_POOL_VALID | FM_SP_EXT_BUF_POOL_EN_COUNTER; -+ tmp_reg |= ((uint32_t)ext_buf_pools->extBufPool[i].id << FM_SP_EXT_BUF_POOL_ID_SHIFT); -+ tmp_reg |= ext_buf_pools->extBufPool[i].size; -+ /* functionality available only for some deriviatives (limited by config) */ -+ if (backup_pools) -+ for (j=0;jnumOfBackupPools;j++) -+ if (ext_buf_pools->extBufPool[i].id == backup_pools->poolIds[j]) -+ { -+ tmp_reg |= FM_SP_EXT_BUF_POOL_BACKUP; -+ break; -+ } -+ -+ WRITE_UINT32(sp_regs->fm_sp_ebmpi[i], tmp_reg); -+ } -+ -+ /* clear unused pools */ -+ for (i=ext_buf_pools->numOfPoolsUsed;ifm_sp_ebmpi[i], 0); -+ -+ /* fill pool depletion register*/ -+ tmp_reg = 0; -+ -+ if (buf_pool_depletion && buf_pool_depletion->poolsGrpModeEnable) -+ { -+ /* calculate vector for number of pools depletion */ -+ vector = 0; -+ for (i=0;ipoolsToConsider[i]) -+ for (j=0;jnumOfPoolsUsed;j++) -+ if (i == ext_buf_pools->extBufPool[j].id) -+ { -+ vector |= 0x80000000 >> j; -+ break; -+ } -+ -+ /* configure num of pools and vector for number of pools mode */ -+ tmp_reg |= (((uint32_t)buf_pool_depletion->numOfPools - 1) << FM_SP_POOL_DEP_NUM_OF_POOLS_SHIFT); -+ tmp_reg |= vector; -+ } -+ -+ if (buf_pool_depletion && buf_pool_depletion->singlePoolModeEnable) -+ { -+ /* calculate vector for number of pools depletion */ -+ vector = 0; -+ for (i=0;ipoolsToConsiderForSingleMode[i]) -+ for (j=0;jnumOfPoolsUsed;j++) -+ if (i == ext_buf_pools->extBufPool[j].id) -+ { -+ vector |= 0x00000080 >> j; -+ break; -+ } -+ -+ /* configure num of pools and vector for number of pools mode */ -+ tmp_reg |= vector; -+ } -+ -+ /* fill QbbPEV */ -+ if (buf_pool_depletion) -+ { -+ vector = 0; -+ for (i=0; ipfcPrioritiesEn[i] == TRUE) -+ vector|= 0x00008000 >> i; -+ tmp_reg |= vector; -+ } -+ WRITE_UINT32(sp_regs->fm_sp_mpd, tmp_reg); -+ -+ /* fill dma attributes register */ -+ tmp_reg = 0; -+ tmp_reg |= (uint32_t)fm_vsp_params->dma_swap_data << FM_SP_DMA_ATTR_SWP_SHIFT; -+ tmp_reg |= (uint32_t)fm_vsp_params->int_context_cache_attr << FM_SP_DMA_ATTR_IC_CACHE_SHIFT; -+ tmp_reg |= (uint32_t)fm_vsp_params->header_cache_attr << FM_SP_DMA_ATTR_HDR_CACHE_SHIFT; -+ tmp_reg |= (uint32_t)fm_vsp_params->scatter_gather_cache_attr << FM_SP_DMA_ATTR_SG_CACHE_SHIFT; -+ if (fm_vsp_params->dma_write_optimize) -+ tmp_reg |= FM_SP_DMA_ATTR_WRITE_OPTIMIZE; -+ WRITE_UINT32(sp_regs->fm_sp_da, tmp_reg); -+ -+ /* IC parameters - fill internal context parameters register */ -+ tmp_reg = 0; -+ tmp_reg |= (((uint32_t)int_context_data_copy->extBufOffset/OFFSET_UNITS) << FM_SP_IC_TO_EXT_SHIFT); -+ tmp_reg |= (((uint32_t)int_context_data_copy->intContextOffset/OFFSET_UNITS) << FM_SP_IC_FROM_INT_SHIFT); -+ tmp_reg |= (((uint32_t)int_context_data_copy->size/OFFSET_UNITS) << FM_SP_IC_SIZE_SHIFT); -+ WRITE_UINT32(sp_regs->fm_sp_icp, tmp_reg); -+ -+ /* buffer margins - fill external buffer margins register */ -+ tmp_reg = 0; -+ tmp_reg |= (((uint32_t)external_buffer_margins->startMargins) << FM_SP_EXT_BUF_MARG_START_SHIFT); -+ tmp_reg |= (((uint32_t)external_buffer_margins->endMargins) << FM_SP_EXT_BUF_MARG_END_SHIFT); -+ if (no_scather_gather) -+ tmp_reg |= FM_SP_SG_DISABLE; -+ WRITE_UINT32(sp_regs->fm_sp_ebm, tmp_reg); -+ -+ /* buffer margins - fill spliodn register */ -+ WRITE_UINT32(sp_regs->fm_sp_spliodn, liodn_offset); -+} -+ -+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; -+ -+ 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)); -+ -+ 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->dmaSwapData = DEFAULT_FM_SP_dmaSwapData; -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = DEFAULT_FM_SP_dmaIntContextCacheAttr; -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = DEFAULT_FM_SP_dmaHeaderCacheAttr; -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = DEFAULT_FM_SP_dmaScatterGatherCacheAttr; -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = DEFAULT_FM_SP_dmaWriteOptimize; -+ -+ p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = DEFAULT_FM_SP_noScatherGather; -+ -+ 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; -+ 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 = -+ (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(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; -+ -+ fm_vsp_params.buf_pool_depletion = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion; -+ fm_vsp_params.backup_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools; -+ fm_vsp_params.fm_ext_pools = &p_FmVspEntry->extBufPools; -+ -+ fm_vsp_params.buf_margins = &p_FmVspEntry->bufMargins; -+ fm_vsp_params.int_context = &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); -+ -+ /*set all registers related to VSP*/ -+ fm_vsp_fill_entry(p_FmVspEntry->p_FmSpRegsBase, absoluteProfileId, &fm_vsp_params); -+ -+ 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) */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/SP/fm_sp.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/SP/fm_sp.h -new file mode 100644 -index 0000000..30b41b6 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/SP/fm_sp.h -@@ -0,0 +1,131 @@ -+/* -+ * 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 -+ -+ -+ -+/***********************************************************************/ -+/* Memory map */ -+/***********************************************************************/ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+typedef _Packed struct { -+ volatile uint32_t fm_sp_ebmpi[FM_PORT_MAX_NUM_OF_EXT_POOLS]; -+ /*offset 0 - 0xc*/ -+ /**< Buffer Manager pool Information-*/ -+ -+ volatile uint32_t res[8-FM_PORT_MAX_NUM_OF_EXT_POOLS]; -+ /*offset 0x10 - 0xc*/ -+ volatile uint32_t fm_sp_acnt; /*offset 0x20*/ -+ volatile uint32_t fm_sp_ebm; /*offset 0x24*/ -+ volatile uint32_t fm_sp_da; /*offset 0x28*/ -+ volatile uint32_t fm_sp_icp; /*offset 0x2c*/ -+ volatile uint32_t fm_sp_mpd; /*offset 0x30*/ -+ volatile uint32_t res1[2]; /*offset 0x34 - 0x38*/ -+ volatile uint32_t fm_sp_spliodn; /*offset 0x3c*/ -+} _PackedType fm_pcd_storage_profile_regs; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+typedef struct fm_storage_profile_params { -+ t_FmExtPools *fm_ext_pools; -+ t_FmBackupBmPools *backup_pools; -+ t_FmSpIntContextDataCopy *int_context; -+ t_FmSpBufMargins *buf_margins; -+ -+ e_FmDmaSwapOption dma_swap_data; -+ e_FmDmaCacheOption int_context_cache_attr; -+ e_FmDmaCacheOption header_cache_attr; -+ e_FmDmaCacheOption scatter_gather_cache_attr; -+ bool dma_write_optimize; -+ uint16_t liodn_offset; -+ bool no_scather_gather; -+ t_FmBufPoolDepletion *buf_pool_depletion; -+} fm_storage_profile_params; -+ -+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; -+ fm_pcd_storage_profile_regs *p_FmSpRegsBase; -+ t_FmExtPools extBufPools; -+ t_FmVspEntryDriverParams *p_FmVspEntryDriverParams; -+} t_FmVspEntry; -+ -+ -+#endif /* __FM_SP_H */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/fm.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/fm.c -new file mode 100644 -index 0000000..10601ec ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/fm.c -@@ -0,0 +1,6162 @@ -+/* -+ * 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 "fm_common.h" -+#include "fm_ipc.h" -+#include "fm.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->p_FmDriverParam->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->dmaAxiDbgNumOfBeats || (p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats > 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->dmaCamNumOfEntries % DMA_CAM_UNITS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCamNumOfEntries has to be divisble by %d", DMA_CAM_UNITS)); -+ if (!p_Fm->p_FmDriverParam->dmaCamNumOfEntries || (p_Fm->p_FmDriverParam->dmaCamNumOfEntries > DMA_MODE_MAX_CAM_NUM_OF_ENTRIES)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCamNumOfEntries has to be in the range 1 - %d", DMA_MODE_MAX_CAM_NUM_OF_ENTRIES)); -+ if (p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency > DMA_THRESH_MAX_COMMQ) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_COMMQ)); -+ if (p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency > DMA_THRESH_MAX_COMMQ) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_COMMQ)); -+ if (p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.clearEmergency must be smaller than dmaCommQThresholds.assertEmergency")); -+#if (DPAA_VERSION < 11) -+ if (p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency > DMA_THRESH_MAX_BUF) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_BUF)); -+ if (p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency > DMA_THRESH_MAX_BUF) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_BUF)); -+ if (p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.clearEmergency must be smaller than dmaReadBufThresholds.assertEmergency")); -+ if (p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency > DMA_THRESH_MAX_BUF) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_BUF)); -+ if (p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency > DMA_THRESH_MAX_BUF) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_BUF)); -+ if (p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.clearEmergency must be smaller than dmaWriteBufThresholds.assertEmergency")); -+#endif /* (DPAA_VERSION < 11) */ -+#if (DPAA_VERSION >= 11) -+ if ((p_Fm->p_FmDriverParam->dmaDbgCntMode == e_FM_DMA_DBG_CNT_INT_READ_EM)|| -+ (p_Fm->p_FmDriverParam->dmaDbgCntMode == e_FM_DMA_DBG_CNT_INT_WRITE_EM) || -+ (p_Fm->p_FmDriverParam->dmaDbgCntMode == e_FM_DMA_DBG_CNT_RAW_WAR_PROT)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaDbgCntMode value not supported by this integration.")); -+ if ((p_Fm->p_FmDriverParam->dmaEmergency.emergencyBusSelect == FM_DMA_MURAM_READ_EMERGENCY)|| -+ (p_Fm->p_FmDriverParam->dmaEmergency.emergencyBusSelect == FM_DMA_MURAM_WRITE_EMERGENCY)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("emergencyBusSelect value not supported by this integration.")); -+ if (p_Fm->p_FmDriverParam->dmaStopOnBusError) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaStopOnBusError not supported by this integration.")); -+#ifdef FM_AID_MODE_NO_TNUM_SW005 -+ if (p_Fm->p_FmDriverParam->dmaAidMode != e_FM_DMA_AID_OUT_PORT_ID) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaAidMode not supported by this integration.")); -+#endif /* FM_AID_MODE_NO_TNUM_SW005 */ -+ if (p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaAxiDbgNumOfBeats 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->dmaWatchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("dmaWatchdog depends on FM clock. dmaWatchdog(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 number has to be in the range 256 - %d", 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->thresholds.dispLimit > FPM_MAX_DISP_LIMIT) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("thresholds.dispLimit 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->dmaWatchdog)) -+ 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->haltOnUnrecoverableEccError)) -+ 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->tnumAgingPeriod) -+ 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->p_FmDriverParam->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->p_FmDriverParam->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->p_FmDriverParam->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, mask, force; -+ -+ event = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr); -+ mask = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier); -+ event &= mask; -+ -+ /* clear the forced events */ -+ force = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr); -+ if (force & event) -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, force & ~event); -+ -+ /* clear the acknowledged events */ -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr, event); -+ -+ 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, mask, force; -+ -+ event = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie); -+ mask = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien); -+ -+ event &= mask; -+ -+ /* clear the forced events */ -+ force = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif); -+ if (force & event) -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, force & ~event); -+ -+ /* clear the acknowledged events */ -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie, event); -+ -+ 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) -+{ -+ uint64_t addr=0; -+ uint32_t status, mask, tmpReg=0; -+ uint8_t tnum; -+ uint8_t hardwarePortId; -+ uint8_t relativePortId; -+ uint16_t liodn; -+ -+ status = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr); -+ mask = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr); -+ -+ /* get bus error regs before clearing BER */ -+ if ((status & DMA_STATUS_BUS_ERR) && (mask & DMA_MODE_BER)) -+ { -+ addr = (uint64_t)GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtal); -+ addr |= ((uint64_t)(GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtah)) << 32); -+ -+ /* get information about the owner of that bus error */ -+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtcid); -+ } -+ -+ /* clear set events */ -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsr, status); -+ -+ if ((status & DMA_STATUS_BUS_ERR) && (mask & DMA_MODE_BER)) -+ { -+ hardwarePortId = (uint8_t)(((tmpReg & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT)); -+ HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId); -+ tnum = (uint8_t)((tmpReg & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT); -+ liodn = (uint16_t)(tmpReg & 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, -+ addr, -+ tnum, -+ liodn); -+ } -+ if (mask & DMA_MODE_ECC) -+ { -+ 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; -+ -+ event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee); -+ -+ /* clear the all occurred events */ -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee, event); -+ -+ 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, mask; -+ -+ event = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr); -+ mask = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rie); -+ -+ ASSERT_COND(event & FPM_RAM_CTL_MURAM_ECC); -+ -+ /* clear MURAM event bit */ -+ /* Prior to V3 this event bit clearing does not work ! ) */ -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, event & ~FPM_RAM_CTL_IRAM_ECC); -+ -+ ASSERT_COND(event & FPM_RAM_CTL_RAMS_ECC_EN); -+ -+ if ((mask & FPM_MURAM_ECC_ERR_EX_EN)) -+ p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC); -+} -+ -+static void IramErrIntr(t_Fm *p_Fm) -+{ -+ uint32_t event, mask; -+ -+ event = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr) ; -+ mask = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rie); -+ -+ ASSERT_COND(event & FPM_RAM_CTL_IRAM_ECC); -+ -+ /* clear the acknowledged events (do not clear IRAM event) */ -+ /* Prior to V3 this event bit clearing does not work ! ) */ -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, event & ~FPM_RAM_CTL_MURAM_ECC); -+ -+ ASSERT_COND(event & FPM_RAM_CTL_IRAM_ECC_EN); -+ -+ if ((mask & FPM_IRAM_ECC_ERR_EX_EN)) -+ p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC); -+} -+ -+static void QmiEvent(t_Fm *p_Fm) -+{ -+ uint32_t event, mask, force; -+ -+ event = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie); -+ mask = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien); -+ -+ event &= mask; -+ -+ /* clear the forced events */ -+ force = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_if); -+ if (force & event) -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_if, force & ~event); -+ -+ /* clear the acknowledged events */ -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie, event); -+ -+ 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) -+{ -+ uint64_t fraction; -+ uint32_t integer, tsFrequency, tmpReg; -+ -+ ASSERT_COND(p_Fm); -+ ASSERT_COND(p_Fm->p_FmStateStruct); -+ ASSERT_COND(p_Fm->p_FmStateStruct->count1MicroBit); -+ -+ tsFrequency = (uint32_t)(1<p_FmStateStruct->count1MicroBit); /* 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... */ -+ integer = tsFrequency/p_Fm->p_FmStateStruct->fmClkFreq; -+ /* we multiply by 2^16 to keep the fraction of the division */ -+ /* we do not divide back, since we write this value as fraction - see spec */ -+ fraction = ((tsFrequency << 16) - (integer << 16) * p_Fm->p_FmStateStruct->fmClkFreq) / p_Fm->p_FmStateStruct->fmClkFreq; -+ /* we check remainder of the division in order to round up if not integer */ -+ if (((tsFrequency << 16) - (integer << 16) * p_Fm->p_FmStateStruct->fmClkFreq) % p_Fm->p_FmStateStruct->fmClkFreq) -+ fraction++; -+ -+ tmpReg = (integer << FPM_TS_INT_SHIFT) | (uint16_t)fraction; -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_tsc2, tmpReg); -+ -+ /* enable timestamp with original clock */ -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_tsc1, FPM_TS_CTL_EN); -+ -+ p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE; -+} -+ -+static t_Error ClearIRam(t_Fm *p_Fm) -+{ -+ t_FMIramRegs *p_Iram; -+ int i; -+ -+ 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 < (FM_IRAM_SIZE/4); i++) -+ WRITE_UINT32(p_Iram->idata, 0xffffffff); -+ -+ WRITE_UINT32(p_Iram->iadd, FM_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->p_FmDriverParam->firmware.size / 4); i++) -+ WRITE_UINT32(p_Iram->idata, p_Fm->p_FmDriverParam->firmware.p_Code[i]); -+ -+ compTo16 = (uint8_t)(p_Fm->p_FmDriverParam->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->p_FmDriverParam->firmware.size-4); -+ while (GET_UINT32(p_Iram->iadd) != (p_Fm->p_FmDriverParam->firmware.size-4)) ; -+ -+ /* verify that writing has completed */ -+ while (GET_UINT32(p_Iram->idata) != p_Fm->p_FmDriverParam->firmware.p_Code[(p_Fm->p_FmDriverParam->firmware.size / 4)-1]) ; -+ -+ if (p_Fm->p_FmDriverParam->fwVerify) -+ { -+ WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE); -+ while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ; -+ for (i=0; i < (p_Fm->p_FmDriverParam->firmware.size / 4); i++) -+ { -+ tmp = GET_UINT32(p_Iram->idata); -+ if (tmp != p_Fm->p_FmDriverParam->firmware.p_Code[i]) -+ RETURN_ERROR(MAJOR, E_WRITE_FAILED, -+ ("UCode write error : write 0x%x, read 0x%x", -+ p_Fm->p_FmDriverParam->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->p_FmDriverParam->firmware.p_Code)[2], -+ ((uint8_t *)p_Fm->p_FmDriverParam->firmware.p_Code)[6], -+ ((uint8_t *)p_Fm->p_FmDriverParam->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; -+ -+ /* 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); -+ -+ /* 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 */ -+ /*************************************/ -+ if (ClearIRam(p_Fm) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ if (p_Fm->p_FmDriverParam->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); -+ -+ if (GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs) & QMI_GS_HALT_NOT_BUSY) -+ { -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee); -+ /* clear tmpReg event bits in order not to clear standing events */ -+ tmpReg &= ~(FPM_EV_MASK_DOUBLE_ECC | FPM_EV_MASK_STALL | FPM_EV_MASK_SINGLE_ECC); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee, tmpReg | FPM_EV_MASK_RELEASE_FM); -+ 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; -+ uint32_t tmpReg; -+ -+ ASSERT_COND(h_Fm); -+ ASSERT_COND(hardwarePortId); -+ -+ 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!")); -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1]); -+ tmpReg |= (uint32_t)((uint32_t)baseStorageProfile & 0x3f) << 16; -+ tmpReg |= (uint32_t)log2NumOfProfiles << 28; -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], tmpReg); -+ -+ 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 == 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, ipcAllocParams.base, 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, ipcAllocParams.base, 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; -+ uint32_t tmpReg; -+ -+ /* Get clock frequency */ -+ ipcParams.fmClkFreq = p_Fm->p_FmStateStruct->fmClkFreq; -+ -+ /* read FM revision register 1 */ -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fm_ip_rev_1); -+ ipcParams.majorRev = (uint8_t)((tmpReg & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT); -+ ipcParams.minorRev = (uint8_t)((tmpReg & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT); -+ -+ 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; -+ int timeout = 1000; -+ t_Error err = E_OK; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ uint8_t rxHardwarePortId, txHardwarePortId; -+ -+ 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); -+ -+ SW_PORT_ID_TO_HW_PORT_ID(rxHardwarePortId, e_FM_PORT_TYPE_RX_10G, macId); -+ SW_PORT_ID_TO_HW_PORT_ID(txHardwarePortId, e_FM_PORT_TYPE_TX_10G, macId); -+ 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!")); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc, 0x40000000); -+ CORE_MemoryBarrier(); -+ while ((GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc) & 0x40000000) && -+ --timeout) ; -+ if (!timeout) -+ return ERROR_CODE(E_TIMEOUT); -+ return E_OK; -+} -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+ -+t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm, -+ uint32_t congestionGroupId, -+ uint8_t priorityBitMap) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ -+ ASSERT_COND(h_Fm); -+ -+ if (congestionGroupId > FM_PORT_NUM_OF_CONGESTION_GRPS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("Congestion group ID bigger than %d \n!", -+ FM_PORT_NUM_OF_CONGESTION_GRPS)); -+ -+ if (p_Fm->guestId == NCSW_MASTER_ID) -+ { -+ uint32_t *p_Cpg = (uint32_t*)(p_Fm->baseAddr+FM_MM_CGP); -+ uint32_t tmpReg; -+ uint32_t reg_num; -+ uint32_t offset; -+ -+ ASSERT_COND(p_Fm->baseAddr); -+ reg_num = (FM_PORT_NUM_OF_CONGESTION_GRPS-1-(congestionGroupId))/4; -+ offset = (congestionGroupId%4); -+ -+ tmpReg = GET_UINT32(p_Cpg[reg_num]); -+ -+ if (priorityBitMap)//adding priority -+ { -+ if (tmpReg & (0xFF<<(offset*8))) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("PFC priority for the congestion group is already set!")); -+ } -+ tmpReg |= (uint32_t)priorityBitMap << (offset*8); -+ WRITE_UINT32(p_Cpg[reg_num], tmpReg); -+ } -+ -+ 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.")); -+ } -+ -+ SW_PORT_ID_TO_HW_PORT_ID(hardwarePortId, portType, portId) -+ 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); -+ -+ SW_PORT_ID_TO_HW_PORT_ID(hardwarePortId, portType, portId) -+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); -+ -+ numOfVSPs = p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles; -+ first = 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; -+ -+ 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); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_cee[eventRegId], enableEvents); -+} -+ -+uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ 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 GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_cee[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 FmSetNumOfRiscsPerPort(t_Handle h_Fm, -+ uint8_t hardwarePortId, -+ uint8_t numOfFmanCtrls, -+ t_FmFmanCtrl orFmanCtrl) -+{ -+ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint32_t tmpReg = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE); -+ -+ 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!")); -+ -+ tmpReg = (uint32_t)(hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT); -+ -+ /* TODO - maybe to put CTL# according to another criteria */ -+ if (numOfFmanCtrls == 2) -+ tmpReg = FPM_PORT_FM_CTL2 | FPM_PORT_FM_CTL1; -+ -+ /* order restoration */ -+ tmpReg |= (orFmanCtrl << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | orFmanCtrl; -+ -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_prc, tmpReg); -+ -+ 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 tmpReg, intFlags; -+ uint8_t hardwarePortId = p_PortParams->hardwarePortId, macId; -+ -+ 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 */ -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_mxd, 0); -+ } -+ -+ 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, p_PortParams->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; -+ bool update = FALSE; -+ -+ /* update qmi ENQ/DEQ threshold */ -+ p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth; -+ tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc); -+ enqTh = (uint8_t)(tmpReg>>8); -+ /* 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); -+ tmpReg &= ~QMI_CFG_ENQ_MASK; -+ tmpReg |= ((uint32_t)enqTh << 8); -+ update = TRUE; -+ } -+ -+ deqTh = (uint8_t)tmpReg; -+ /* 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); -+ tmpReg &= ~QMI_CFG_DEQ_MASK; -+ tmpReg |= (uint32_t)deqTh; -+ update = TRUE; -+ } -+ if (update) -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, tmpReg); -+ } -+ -+#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, -+ p_PortParams->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, -+ p_PortParams->hardwarePortId, -+ &p_PortParams->numOfOpenDmas, -+ &p_PortParams->numOfExtraOpenDmas, -+ TRUE); -+ if (err) -+ { -+ XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], (uint32_t)p_PortParams->liodnOffset); -+ -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6) -+ { -+ tmpReg = (uint32_t)(hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT); -+ if (p_PortParams->independentMode) -+ { -+ if ((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G)) -+ tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) |FPM_PORT_FM_CTL1; -+ else -+ tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) |FPM_PORT_FM_CTL2; -+ } -+ else -+ { -+ tmpReg |= (FPM_PORT_FM_CTL2|FPM_PORT_FM_CTL1); -+ -+ /* order restoration */ -+ if (hardwarePortId%2) -+ tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT); -+ else -+ tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT); -+ } -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_prc, tmpReg); -+ } -+ -+ /* set LIODN base for this port */ -+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2]); -+ if (hardwarePortId%2) -+ { -+ tmpReg &= ~FM_LIODN_BASE_MASK; -+ tmpReg |= (uint32_t)p_PortParams->liodnBase; -+ } -+ else -+ { -+ tmpReg &= ~(FM_LIODN_BASE_MASK<< DMA_LIODN_SHIFT); -+ tmpReg |= (uint32_t)p_PortParams->liodnBase << DMA_LIODN_SHIFT; -+ } -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], tmpReg); -+ -+ 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 tmpReg, intFlags; -+ uint8_t hardwarePortId = p_PortParams->hardwarePortId; -+ uint8_t numOfTasks, macId; -+ t_Error err; -+ t_FmIpcPortFreeParams portParams; -+ t_FmIpcMsg msg; -+ -+ 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; -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]); -+ /* free numOfTasks */ -+ numOfTasks = (uint8_t)(((tmpReg & BMI_NUM_OF_TASKS_MASK) >> BMI_NUM_OF_TASKS_SHIFT) + 1); -+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks); -+ p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks; -+ -+ /* free numOfOpenDmas */ -+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= -+ ((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1); -+ p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= -+ (((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1); -+ -+#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. */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK; -+ tmpReg |= (uint32_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize - 1) << BMI_CFG2_DMAS_SHIFT; -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg); -+ } -+#endif /* FM_HAS_TOTAL_DMAS */ -+ -+ /* free sizeOfFifo */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1]); -+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= -+ (((tmpReg & BMI_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS)); -+ p_Fm->p_FmStateStruct->accumulatedFifoSize -= -+ (((tmpReg & BMI_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS); -+ -+ /* clear registers */ -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], 0); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], 0); -+ /* WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], 0); */ -+ -+#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; -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc); -+ /* 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); -+ tmpReg &= ~QMI_CFG_ENQ_MASK; -+ tmpReg |= ((uint32_t)enqTh << QMI_CFG_ENQ_SHIFT); -+ -+ /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller, -+ so we can reduce deqTh */ -+ deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1); -+ tmpReg &= ~QMI_CFG_DEQ_MASK; -+ tmpReg |= (uint32_t)deqTh; -+ -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, tmpReg); -+ } -+ -+ 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; -+ uint32_t tmpReg; -+ t_Error err; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ -+ 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!")); -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]); -+ *p_IsStalled = (bool)!!(tmpReg & FPM_PS_STALLED); -+ -+ return E_OK; -+} -+ -+t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint32_t tmpReg; -+ t_Error err; -+ bool isStalled; -+ -+ 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; -+ -+ tmpReg = (uint32_t)((hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT) | FPM_PRC_REALSE_STALLED); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_prc, tmpReg); -+ -+ return E_OK; -+} -+ -+t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint32_t bitMask; -+ -+#ifndef FM_MAC_RESET -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) -+ return E_OK; -+#endif /*(FM_MAC_RESET >= 11)*/ -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->baseAddr && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcMacParams macParams; -+ t_Error err; -+ 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!")); -+ -+ /* Get the relevant bit mask */ -+ if (type == e_FM_MAC_10G) -+ { -+ switch (macId) -+ { -+ case (0): -+ bitMask = FPM_RSTC_10G0_RESET; -+ break; -+ case (1): -+ bitMask = FPM_RSTC_10G1_RESET; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Illegal MAC Id")); -+ } -+ } -+ else -+ { -+ switch (macId) -+ { -+ case (0): -+ bitMask = FPM_RSTC_1G0_RESET; -+ break; -+ case (1): -+ bitMask = FPM_RSTC_1G1_RESET; -+ break; -+ case (2): -+ bitMask = FPM_RSTC_1G2_RESET; -+ break; -+ case (3): -+ bitMask = FPM_RSTC_1G3_RESET; -+ break; -+ case (4): -+ bitMask = FPM_RSTC_1G4_RESET; -+ break; -+ case (5): -+ bitMask = FPM_RSTC_1G5_RESET; -+ break; -+ case (6): -+ bitMask = FPM_RSTC_1G6_RESET; -+ break; -+ case (7): -+ bitMask = FPM_RSTC_1G7_RESET; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Illegal MAC Id")); -+ } -+ } -+ -+ /* reset */ -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, bitMask); -+ -+ 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; -+} -+ -+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) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t))) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ -+ 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)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("timestamp is not enabled!")); -+ -+ return p_Fm->p_FmStateStruct->count1MicroBit; -+ } -+ 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); -+} -+ -+#ifdef FM_NO_GUARANTEED_RESET_VALUES -+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; -+ uint32_t tmpReg = 0, sizeOfFifo = *p_SizeOfFifo, extraSizeOfFifo = *p_ExtraSizeOfFifo; -+ uint16_t oldVal = 0; -+ -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ -+ 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.")); -+ -+ tmpReg = (uint32_t)((sizeOfFifo/BMI_FIFO_UNITS - 1) | -+ ((extraSizeOfFifo/BMI_FIFO_UNITS) << BMI_EXTRA_FIFO_SIZE_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], tmpReg); -+ } -+ 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) -+ { -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1]); -+ /* read into oldVal the current extra fifo size */ -+ oldVal = (uint16_t)((((tmpReg & BMI_EXTRA_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS) >> BMI_EXTRA_FIFO_SIZE_SHIFT); -+ } -+ -+ if (extraSizeOfFifo > oldVal) -+ { -+ 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); -+ } -+ -+ if (!initialConfig) -+ /* read into oldVal the current num of tasks */ -+ oldVal = (uint16_t)(((tmpReg & BMI_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS); -+ -+ /* check that there are enough uncommitted fifo size */ -+ if ((p_Fm->p_FmStateStruct->accumulatedFifoSize - oldVal + sizeOfFifo) > -+ (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Requested fifo size and extra size exceed total FIFO size.")); -+ else -+ { -+ /* update accumulated */ -+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= oldVal); -+ p_Fm->p_FmStateStruct->accumulatedFifoSize -= oldVal; -+ p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo; -+ /* calculate reg */ -+ tmpReg = (uint32_t)((sizeOfFifo/BMI_FIFO_UNITS - 1) | -+ ((extraSizeOfFifo/BMI_FIFO_UNITS) << BMI_EXTRA_FIFO_SIZE_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], tmpReg); -+ } -+ -+ return E_OK; -+} -+ -+#else /*FM_NO_GUARANTEED_RESET_VALUES*/ -+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; -+ uint32_t tmpReg = 0, sizeOfFifo = *p_SizeOfFifo, extraSizeOfFifo = *p_ExtraSizeOfFifo; -+ uint16_t currentVal, currentExtraVal; -+ -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ /* it's illegal to be in a state where this is not the first set and no value is specified */ -+ ASSERT_COND(initialConfig || sizeOfFifo); -+ -+ 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.")); -+ -+ if (sizeOfFifo) -+ { -+ /* whether it is the first time with explicit value, or runtime "set" - write register */ -+ tmpReg = (uint32_t)((sizeOfFifo/BMI_FIFO_UNITS - 1) | -+ ((extraSizeOfFifo/BMI_FIFO_UNITS) << BMI_EXTRA_FIFO_SIZE_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], tmpReg); -+ } -+ else /* first config without explicit value: Do Nothing - reset value shouldn't be -+ changed, read register for port save */ -+ { -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1]); -+ /* read into oldVal the current extra fifo size */ -+ *p_ExtraSizeOfFifo = (uint16_t)((((tmpReg & BMI_EXTRA_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS) >> BMI_EXTRA_FIFO_SIZE_SHIFT); -+ *p_SizeOfFifo = (uint16_t)(((tmpReg & BMI_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS); -+ } -+ } -+ 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 || !sizeOfFifo) -+ { -+ /* !initialConfig - runtime change of existing value. -+ * !numOfTasks - first configuration according to values in regs. -+ * In both cases: read the current FIFO size */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1]); -+ /* read into oldVal the current extra fifo size */ -+ currentExtraVal = (uint16_t)((((tmpReg & BMI_EXTRA_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS) >> BMI_EXTRA_FIFO_SIZE_SHIFT); -+ currentVal = (uint16_t)(((tmpReg & BMI_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS); -+ } -+ else /* first time and sizeOfFifo explicitly specified */ -+ currentVal = currentExtraVal = 0; -+ -+ if (!sizeOfFifo) -+ { -+ /* This is the first configuration and user did not specify value (!numOfTasks), -+ * reset values will be used and we just save these values for resource management */ -+ if (currentExtraVal) -+ { -+ if (!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); -+ } -+ if ((p_Fm->p_FmStateStruct->accumulatedFifoSize + currentVal) > -+ (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Total port's fifo size and extra size exceed total available FIFO size.")); -+ -+ p_Fm->p_FmStateStruct->accumulatedFifoSize += currentVal; -+ -+ *p_SizeOfFifo = currentVal; -+ *p_ExtraSizeOfFifo = currentExtraVal; -+ -+ } -+ else -+ { -+ /* user requires a specific value. -+ * If this is the first configuration call, (numOfTasks != 0) currentVal & currentExtraVal are set to "0", -+ * otherwise they hold the value written in the register. -+ */ -+ 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)) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Requested fifo size and extra size exceed total FIFO size.")); -+ else -+ { -+ /* update accumulated */ -+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= currentVal); -+ p_Fm->p_FmStateStruct->accumulatedFifoSize -= currentVal; -+ p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo; -+ /* calculate reg */ -+ tmpReg = (uint32_t)((sizeOfFifo/BMI_FIFO_UNITS - 1) | -+ ((extraSizeOfFifo/BMI_FIFO_UNITS) << BMI_EXTRA_FIFO_SIZE_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], tmpReg); -+ } -+ *p_SizeOfFifo = sizeOfFifo; -+ *p_ExtraSizeOfFifo = extraSizeOfFifo; -+ -+ } -+ -+ return E_OK; -+} -+#endif /* FM_NO_GUARANTEED_RESET_VALUES */ -+ -+#ifdef FM_NO_GUARANTEED_RESET_VALUES -+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; -+ uint32_t tmpReg = 0; -+ uint8_t oldVal = 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.")); -+ -+ /* calculate reg */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK); -+ tmpReg |= (uint32_t)(((numOfTasks-1) << BMI_NUM_OF_TASKS_SHIFT) | -+ (numOfExtraTasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1],tmpReg); -+ } -+ 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) -+ { -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]); -+ /* read into oldVal the current extra tasks */ -+ oldVal = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_TASKS_MASK) >> BMI_EXTRA_NUM_OF_TASKS_SHIFT); -+ } -+ -+ if (numOfExtraTasks > oldVal) -+ p_Fm->p_FmStateStruct->extraTasksPoolSize = -+ (uint8_t)MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks); -+ -+ if (!initialConfig) -+ /* read into oldVal the current num of tasks */ -+ oldVal = (uint8_t)(((tmpReg & BMI_NUM_OF_TASKS_MASK) >> BMI_NUM_OF_TASKS_SHIFT) + 1); -+ -+ /* check that there are enough uncommitted tasks */ -+ if ((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - oldVal + 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 >= oldVal); -+ /* update accumulated */ -+ p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= oldVal; -+ p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks; -+ /* calculate reg */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK); -+ tmpReg |= (uint32_t)(((numOfTasks-1) << BMI_NUM_OF_TASKS_SHIFT) | -+ (numOfExtraTasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1],tmpReg); -+ } -+ -+ return E_OK; -+} -+ -+#else /*FM_NO_GUARANTEED_RESET_VALUES*/ -+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; -+ uint32_t tmpReg = 0; -+ uint8_t currentVal, currentExtraVal,numOfTasks = *p_NumOfTasks, numOfExtraTasks = *p_NumOfExtraTasks; -+ -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ /* it's illegal to be in a state where this is not the first set and no value is specified */ -+ ASSERT_COND(initialConfig || numOfTasks); -+ -+ 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.")); -+ -+ if (numOfTasks) -+ { -+ /* whether it is the first time with explicit value, or runtime "set" - write register */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK); -+ tmpReg |= (uint32_t)(((numOfTasks-1) << BMI_NUM_OF_TASKS_SHIFT) | -+ (numOfExtraTasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1],tmpReg); -+ } -+ else /* first config without explicit value: Do Nothing - reset value shouldn't be -+ changed, read register for port save */ -+ { -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]); -+ *p_NumOfTasks = (uint8_t)(((tmpReg & BMI_NUM_OF_TASKS_MASK) >> BMI_NUM_OF_TASKS_SHIFT) + 1); -+ *p_NumOfExtraTasks = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_TASKS_MASK) >> BMI_EXTRA_NUM_OF_TASKS_SHIFT); -+ } -+ -+ } -+ 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 || !numOfTasks) -+ { -+ /* !initialConfig - runtime change of existing value. -+ * !numOfTasks - first configuration according to values in regs. -+ * In both cases: read the current number of tasks */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]); -+ currentVal = (uint8_t)(((tmpReg & BMI_NUM_OF_TASKS_MASK) >> BMI_NUM_OF_TASKS_SHIFT) + 1); -+ currentExtraVal = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_TASKS_MASK) >> BMI_EXTRA_NUM_OF_TASKS_SHIFT); -+ } -+ else /* first time and numOfTasks explicitly specified */ -+ currentVal = currentExtraVal = 0; -+ -+ if (!numOfTasks) -+ { -+ /* This is the first configuration and user did not specify value (!numOfTasks), -+ * reset values will be used and we just save these values for resource management */ -+ p_Fm->p_FmStateStruct->extraTasksPoolSize = -+ (uint8_t)MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, currentExtraVal); -+ if ((p_Fm->p_FmStateStruct->accumulatedNumOfTasks + currentVal) > -+ (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize)) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, -+ ("Total ports' numOfTasks and extra tasks pool for fm%d exceed total available numOfTasks.", -+ p_Fm->p_FmStateStruct->fmId)); -+ p_Fm->p_FmStateStruct->accumulatedNumOfTasks += currentVal; -+ *p_NumOfTasks = currentVal; -+ *p_NumOfExtraTasks = currentExtraVal; -+ } -+ else -+ { -+ /* user requires a specific value. -+ * If this is the first configuration call, (numOfTasks != 0) currentVal & currentExtraVal are set to "0", -+ * otherwise they hold the value written in the register. -+ */ -+ 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 acummulated */ -+ p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= currentVal; -+ p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks; -+ /* calculate reg */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK); -+ tmpReg |= (uint32_t)(((numOfTasks-1) << BMI_NUM_OF_TASKS_SHIFT) | -+ (numOfExtraTasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1],tmpReg); -+ } -+ *p_NumOfTasks = numOfTasks; -+ *p_NumOfExtraTasks = numOfExtraTasks; -+ } -+ -+ return E_OK; -+} -+#endif /* FM_NO_GUARANTEED_RESET_VALUES */ -+ -+#ifdef FM_NO_GUARANTEED_RESET_VALUES -+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; -+ uint8_t oldVal = 0, numOfOpenDmas = *p_NumOfOpenDmas, numOfExtraOpenDmas = *p_NumOfExtraOpenDmas; -+ uint32_t tmpReg = 0; -+ t_Error err; -+ -+ 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."));*/ -+ -+ /* calculate reg */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK); -+ tmpReg |= (uint32_t)(((numOfOpenDmas-1) << BMI_NUM_OF_DMAS_SHIFT) | -+ (numOfExtraOpenDmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], tmpReg); -+ } -+ 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) -+ { -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]); -+ /* read into oldVal the current extra tasks */ -+ oldVal = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_DMAS_MASK) >> BMI_EXTRA_NUM_OF_DMAS_SHIFT); -+ } -+ -+ if (numOfExtraOpenDmas > oldVal) -+ p_Fm->p_FmStateStruct->extraOpenDmasPoolSize = -+ (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas); -+ -+ if (!initialConfig) -+ /* read into oldVal the current num of tasks */ -+ oldVal = (uint8_t)(((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1); -+ -+ /* check that there are enough uncommitted open DMA's */ -+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= oldVal); -+#ifdef FM_HAS_TOTAL_DMAS -+ if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) && -+ (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - oldVal + 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) && -+ (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - oldVal + 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 -+ { -+ /* update acummulated */ -+ p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= oldVal; -+ p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas; -+ -+ /* calculate reg */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK); -+ tmpReg |= (uint32_t)(((numOfOpenDmas-1) << BMI_NUM_OF_DMAS_SHIFT) | -+ (numOfExtraOpenDmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], tmpReg); -+ -+#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. */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK; -+ tmpReg |= (uint32_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize - 1) << BMI_CFG2_DMAS_SHIFT; -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg); -+ } -+#endif /* FM_HAS_TOTAL_DMAS */ -+ } -+ -+ -+ return E_OK; -+} -+ -+#else /* FM_NO_GUARANTEED_RESET_VALUES */ -+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; -+ uint32_t tmpReg = 0; -+ t_Error err; -+ uint8_t currentVal, currentExtraVal, numOfOpenDmas = *p_NumOfOpenDmas, numOfExtraOpenDmas = *p_NumOfExtraOpenDmas; -+ -+ 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) -+ { -+ /* whether it is the first time with explicit value, or runtime "set" - write register */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK); -+ tmpReg |= (uint32_t)(((numOfOpenDmas-1) << BMI_NUM_OF_DMAS_SHIFT) | -+ (numOfExtraOpenDmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], tmpReg); -+ } -+ else /* first config without explicit value: Do Nothing - reset value shouldn't be -+ changed, read register for port save */ -+ { -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]); -+ /* read into oldVal the current extra tasks */ -+ *p_NumOfOpenDmas = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_DMAS_MASK) >> BMI_EXTRA_NUM_OF_DMAS_SHIFT); -+ *p_NumOfExtraOpenDmas = (uint8_t)(((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1); -+ } -+ } -+ 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 */ -+ -+ /* 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 (!initialConfig || !numOfOpenDmas) -+ { -+ /* !initialConfig - runtime change of existing value. -+ * !numOfTasks - first configuration according to values in regs. -+ * In both cases: read the current number of open Dma's */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]); -+ /* read into oldVal the current extra tasks */ -+ currentExtraVal = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_DMAS_MASK) >> BMI_EXTRA_NUM_OF_DMAS_SHIFT); -+ currentVal = (uint8_t)(((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1); -+ } -+ else /* first time and numOfTasks explicitly specified */ -+ currentVal = currentExtraVal = 0; -+ -+ if (!numOfOpenDmas) -+ { -+ /* 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; -+ } -+ else -+ { -+ /* user requires a specific value. -+ * If this is the first configuration call, (numOfTasks != 0) currentVal & currentExtraVal are set to "0", -+ * otherwise they hold the value written in the register. -+ */ -+ if (numOfExtraOpenDmas > currentExtraVal) -+ p_Fm->p_FmStateStruct->extraOpenDmasPoolSize = -+ (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas); -+ -+ -+ /* read into oldVal the current num of tasks */ -+#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) && -+ (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; -+ -+ /* calculate reg */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK); -+ tmpReg |= (uint32_t)(((numOfOpenDmas-1) << BMI_NUM_OF_DMAS_SHIFT) | -+ (numOfExtraOpenDmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], tmpReg); -+#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. */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK; -+ tmpReg |= (uint32_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize - 1) << BMI_CFG2_DMAS_SHIFT; -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg); -+ } -+#endif /* FM_HAS_TOTAL_DMAS */ -+ -+ } -+ *p_NumOfOpenDmas = numOfOpenDmas; -+ *p_NumOfExtraOpenDmas = numOfExtraOpenDmas; -+ } -+ -+ -+ return E_OK; -+} -+#endif /* FM_NO_GUARANTEED_RESET_VALUES */ -+ -+#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; -+ -+ SW_PORT_ID_TO_HW_PORT_ID(hardwarePortId, portType, portId) -+ 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; -+ -+ SW_PORT_ID_TO_HW_PORT_ID(hardwarePortId, portType, portId) -+ 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_FmDriverParam *p_FmDriverParam = NULL; -+ uint32_t tmpReg; -+ -+ ASSERT_COND(p_Fm); -+ ASSERT_COND(p_Fm->p_FmDriverParam); -+ -+ p_FmDriverParam = p_Fm->p_FmDriverParam; -+ -+ /* clear status reg events */ -+#if (DPAA_VERSION >= 11) -+ tmpReg = DMA_STATUS_FM_SPDAT_ECC; -+#else -+ tmpReg = DMA_STATUS_FM_ECC; -+#endif /* DPAA_VERSION >= 11 */ -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr) | tmpReg); -+ -+ /* configure mode register */ -+ tmpReg = 0; -+ tmpReg |= p_FmDriverParam->dmaCacheOverride << DMA_MODE_CACHE_OR_SHIFT; -+ if (p_FmDriverParam->dmaAidOverride) -+ tmpReg |= DMA_MODE_AID_OR; -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_BUS_ERROR) -+ tmpReg |= DMA_MODE_BER; -+ if (p_FmDriverParam->dmaEnEmergency) -+ { -+ tmpReg |= p_FmDriverParam->dmaEmergency.emergencyBusSelect; -+ tmpReg |= p_FmDriverParam->dmaEmergency.emergencyLevel << DMA_MODE_EMERGENCY_LEVEL_SHIFT; -+ if (p_FmDriverParam->dmaEnEmergencySmoother) -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmemsr, p_FmDriverParam->dmaEmergencySwitchCounter); -+ } -+ tmpReg |= ((p_FmDriverParam->dmaCamNumOfEntries/DMA_CAM_UNITS) - 1) << DMA_MODE_CEN_SHIFT; -+ tmpReg |= p_FmDriverParam->dmaDbgCntMode << DMA_MODE_DBG_SHIFT; -+ tmpReg |= DMA_MODE_SECURE_PROT; -+ tmpReg |= p_FmDriverParam->dmaAidMode << DMA_MODE_AID_MODE_SHIFT; -+ -+#if (DPAA_VERSION >= 11) -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_SINGLE_PORT_ECC) -+ tmpReg |= DMA_MODE_ECC; -+#else -+ if ((p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_SYSTEM_WRITE_ECC) | (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_READ_ECC) | (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_FM_WRITE_ECC)) -+ tmpReg |= DMA_MODE_ECC; -+ if (p_FmDriverParam->dmaStopOnBusError) -+ tmpReg |= DMA_MODE_SBER; -+ tmpReg |= (uint32_t)(p_FmDriverParam->dmaAxiDbgNumOfBeats - 1) << DMA_MODE_AXI_DBG_SHIFT; -+#ifdef FM_PEDANTIC_DMA -+ tmpReg |= DMA_MODE_EMERGENCY_READ; -+#endif /* FM_PEDANTIC_DMA */ -+#endif /* DPAA_VERSION >= 11 */ -+ -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg); -+ -+ /* configure thresholds register */ -+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtr); -+ tmpReg |= ((uint32_t)p_FmDriverParam->dmaCommQThresholds.assertEmergency << DMA_THRESH_COMMQ_SHIFT) | -+ ((uint32_t)p_FmDriverParam->dmaReadBufThresholds.assertEmergency << DMA_THRESH_READ_INT_BUF_SHIFT) | -+ ((uint32_t)p_FmDriverParam->dmaWriteBufThresholds.assertEmergency); -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmtr, tmpReg); -+ -+ /* configure hysteresis register */ -+ tmpReg = ((uint32_t)p_FmDriverParam->dmaCommQThresholds.clearEmergency << DMA_THRESH_COMMQ_SHIFT) | -+ ((uint32_t)p_FmDriverParam->dmaReadBufThresholds.clearEmergency << DMA_THRESH_READ_INT_BUF_SHIFT) | -+ ((uint32_t)p_FmDriverParam->dmaWriteBufThresholds.clearEmergency); -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmhy, tmpReg); -+ -+ /* configure emergency threshold */ -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsetr, p_FmDriverParam->dmaSosEmergency); -+ -+ /* configure Watchdog */ -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmwcr, USEC_TO_CLK(p_FmDriverParam->dmaWatchdog, p_Fm->p_FmStateStruct->fmClkFreq)); -+ -+ /* Allocate MURAM for CAM */ -+ p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, -+ (uint32_t)(p_FmDriverParam->dmaCamNumOfEntries*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_FmDriverParam->dmaCamNumOfEntries*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_FmDriverParam->dmaCamNumOfEntries*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_FmDriverParam->dmaCamNumOfEntries*72 + 128)); -+ -+ switch (p_FmDriverParam->dmaCamNumOfEntries) -+ { -+ 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 dmaCamNumOfEntries")); -+ } -+ } -+ -+ /* VirtToPhys */ -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmebcr, -+ (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr)); -+ -+ return E_OK; -+} -+ -+static t_Error InitFmFpm(t_Fm *p_Fm) -+{ -+ t_FmDriverParam *p_FmDriverParam = NULL; -+ uint32_t tmpReg; -+ int i; -+ -+ ASSERT_COND(p_Fm); -+ ASSERT_COND(p_Fm->p_FmDriverParam); -+ -+ p_FmDriverParam = p_Fm->p_FmDriverParam; -+ -+ tmpReg = (uint32_t)(p_FmDriverParam->thresholds.dispLimit << FPM_DISP_LIMIT_SHIFT); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_mxd, tmpReg); -+ -+ tmpReg = (((uint32_t)p_FmDriverParam->thresholds.prsDispTh << FPM_THR1_PRS_SHIFT) | -+ ((uint32_t)p_FmDriverParam->thresholds.kgDispTh << FPM_THR1_KG_SHIFT) | -+ ((uint32_t)p_FmDriverParam->thresholds.plcrDispTh << FPM_THR1_PLCR_SHIFT) | -+ ((uint32_t)p_FmDriverParam->thresholds.bmiDispTh << FPM_THR1_BMI_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_dis1, tmpReg); -+ -+ tmpReg = (((uint32_t)p_FmDriverParam->thresholds.qmiEnqDispTh << FPM_THR2_QMI_ENQ_SHIFT) | -+ ((uint32_t)p_FmDriverParam->thresholds.qmiDeqDispTh << FPM_THR2_QMI_DEQ_SHIFT) | -+ ((uint32_t)p_FmDriverParam->thresholds.fmCtl1DispTh << FPM_THR2_FM_CTL1_SHIFT) | -+ ((uint32_t)p_FmDriverParam->thresholds.fmCtl2DispTh << FPM_THR2_FM_CTL2_SHIFT)); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_dis2, tmpReg); -+ -+ /* define exceptions and error behavior */ -+ tmpReg = 0; -+ /* Clear events */ -+ tmpReg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC | FPM_EV_MASK_SINGLE_ECC); -+ /* enable interrupts */ -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_STALL_ON_TASKS) -+ tmpReg |= FPM_EV_MASK_STALL_EN; -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_SINGLE_ECC) -+ tmpReg |= FPM_EV_MASK_SINGLE_ECC_EN; -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_DOUBLE_ECC) -+ tmpReg |= FPM_EV_MASK_DOUBLE_ECC_EN; -+ tmpReg |= (p_Fm->p_FmDriverParam->catastrophicErr << FPM_EV_MASK_CAT_ERR_SHIFT); -+ tmpReg |= (p_Fm->p_FmDriverParam->dmaErr << FPM_EV_MASK_DMA_ERR_SHIFT); -+ if (!p_Fm->p_FmDriverParam->haltOnExternalActivation) -+ tmpReg |= FPM_EV_MASK_EXTERNAL_HALT; -+ if (!p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError) -+ tmpReg |= FPM_EV_MASK_ECC_ERR_HALT; -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee, tmpReg); -+ -+ /* clear all fmCtls event registers */ -+ for (i=0;ip_FmFpmRegs->fmfp_cev[i], 0xFFFFFFFF); -+ -+ /* RAM ECC - enable and clear events */ -+ /* first we need to clear all parser memory, as it is uninitialized and -+ may cause ECC errors -+ */ -+ tmpReg = 0; -+ /* event bits */ -+ tmpReg = (FPM_RAM_CTL_MURAM_ECC | FPM_RAM_CTL_IRAM_ECC); -+ /* Rams enable is not effected by the RCR bit, but by a COP configuration */ -+ if (p_Fm->p_FmDriverParam->externalEccRamsEnable) -+ tmpReg |= FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL; -+ -+ /* enable test mode */ -+ if (p_FmDriverParam->enMuramTestMode) -+ tmpReg |= FPM_RAM_CTL_MURAM_TEST_ECC; -+ if (p_FmDriverParam->enIramTestMode) -+ tmpReg |= FPM_RAM_CTL_IRAM_TEST_ECC; -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, tmpReg); -+ -+ tmpReg = 0; -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_IRAM_ECC) -+ { -+ tmpReg |= FPM_IRAM_ECC_ERR_EX_EN; -+ FmEnableRamsEcc(p_Fm); -+ } -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_MURAM_ECC) -+ { -+ tmpReg |= FPM_MURAM_ECC_ERR_EX_EN; -+ FmEnableRamsEcc(p_Fm); -+ } -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rie, tmpReg); -+ -+ return E_OK; -+} -+ -+static t_Error InitFmBmi(t_Fm *p_Fm) -+{ -+ uint32_t tmpReg; -+ -+ ASSERT_COND(p_Fm); -+ ASSERT_COND(p_Fm->p_FmDriverParam); -+ -+ tmpReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr); -+ tmpReg = tmpReg / BMI_FIFO_ALIGN; -+ -+ tmpReg |= ((p_Fm->p_FmStateStruct->totalFifoSize/BMI_FIFO_UNITS - 1) << BMI_CFG1_FIFO_SIZE_SHIFT); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg1, tmpReg); -+ -+ tmpReg = ((uint32_t)(p_Fm->p_FmStateStruct->totalNumOfTasks - 1) << BMI_CFG2_TASKS_SHIFT); -+#ifdef FM_HAS_TOTAL_DMAS -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6) -+ tmpReg |= (uint32_t)(p_Fm->p_FmStateStruct->maxNumOfOpenDmas - 1) << BMI_CFG2_DMAS_SHIFT; -+#endif /* FM_HAS_TOTAL_DMAS */ -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg); -+ -+ /* define unmaskable exceptions, enable and clear events */ -+ tmpReg = 0; -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr, (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)); -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC) -+ tmpReg |= BMI_ERR_INTR_EN_LIST_RAM_ECC; -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STORAGE_PROFILE_ECC) -+ tmpReg |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC; -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC) -+ tmpReg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC; -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC) -+ tmpReg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC; -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg); -+ -+ return E_OK; -+} -+ -+static t_Error InitFmQmi(t_Fm *p_Fm) -+{ -+ uint32_t tmpReg; -+ -+ ASSERT_COND(p_Fm); -+ ASSERT_COND(p_Fm->p_FmDriverParam); -+ -+ /* Clear error interrupt events */ -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie, (QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF)); -+ tmpReg = 0; -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID) -+ tmpReg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF; -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC) -+ tmpReg |= QMI_ERR_INTR_EN_DOUBLE_ECC; -+ /* enable events */ -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg); -+ -+ if (p_Fm->p_FmDriverParam->tnumAgingPeriod) -+ { -+ uint16_t periodInFmClocks; -+ uint8_t remainder; -+ -+ /* tnumAgingPeriod is in units of microseconds, p_FmClockFreq is in Mhz */ -+ periodInFmClocks = (uint16_t)(p_Fm->p_FmDriverParam->tnumAgingPeriod*p_Fm->p_FmStateStruct->fmClkFreq); -+ /* periodInFmClocks must be a 64 multiply */ -+ remainder = (uint8_t)(periodInFmClocks % 64); -+ if (remainder > 64) -+ tmpReg = (uint32_t)((periodInFmClocks/64) + 1); -+ else -+ { -+ tmpReg = (uint32_t)(periodInFmClocks/64); -+ if (!tmpReg) -+ tmpReg = 1; -+ } -+ tmpReg <<= QMI_TAPC_TAP; -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_tapc, tmpReg); -+ -+ } -+ -+ tmpReg = 0; -+ /* Clear interrupt events */ -+ if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) && (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)) -+ { -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie, QMI_INTR_EN_SINGLE_ECC); -+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC) -+ tmpReg |= QMI_INTR_EN_SINGLE_ECC; -+ /* enable events */ -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien, tmpReg); -+ } -+ -+ return E_OK; -+} -+ -+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->revInfo.majorRev = ipcParams.majorRev; -+ p_Fm->p_FmStateStruct->revInfo.minorRev = ipcParams.minorRev; -+ } -+ else -+ { -+ uint32_t tmpReg; -+ -+ 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) -+ { -+ /* read revision register 1 */ -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fm_ip_rev_1); -+ p_Fm->p_FmStateStruct->revInfo.majorRev = (uint8_t)((tmpReg & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT); -+ p_Fm->p_FmStateStruct->revInfo.minorRev = (uint8_t)((tmpReg & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT); -+ } -+ } -+ -+#if (DPAA_VERSION >= 11) -+ p_Fm->partVSPBase = AllocVSPsForPartition(p_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId); -+ if (p_Fm->partVSPBase == 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; -+} -+ -+#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; -+ -+ 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; -+ uint32_t tmpReg; -+ -+ 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 = (t_FmDriverParam *)XX_Malloc(sizeof(t_FmDriverParam)); -+ 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(t_FmDriverParam)); -+ -+#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->f_Exception = p_FmParam->f_Exception; -+ p_Fm->f_BusError = p_FmParam->f_BusError; -+ p_Fm->p_FmFpmRegs = (t_FmFpmRegs *)UINT_TO_PTR(baseAddr + FM_MM_FPM); -+ p_Fm->p_FmBmiRegs = (t_FmBmiRegs *)UINT_TO_PTR(baseAddr + FM_MM_BMI); -+ p_Fm->p_FmQmiRegs = (t_FmQmiRegs *)UINT_TO_PTR(baseAddr + FM_MM_QMI); -+ p_Fm->p_FmDmaRegs = (t_FmDmaRegs *)UINT_TO_PTR(baseAddr + FM_MM_DMA); -+ 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, ("cant 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) */ -+ -+ -+ -+ p_Fm->p_FmStateStruct->ramsEccEnable = FALSE; -+ p_Fm->p_FmStateStruct->extraFifoPoolSize = 0; -+ p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions; -+ /*p_Fm->p_FmDriverParam->numOfPartitions = p_FmParam->numOfPartitions; */ -+ p_Fm->p_FmDriverParam->tnumAgingPeriod = 0; -+ p_Fm->p_FmDriverParam->resetOnInit = DEFAULT_resetOnInit; -+ -+ p_Fm->p_FmDriverParam->catastrophicErr = DEFAULT_catastrophicErr; -+ p_Fm->p_FmDriverParam->dmaErr = DEFAULT_dmaErr; -+ p_Fm->p_FmDriverParam->haltOnExternalActivation = DEFAULT_haltOnExternalActivation; -+ p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError = DEFAULT_haltOnUnrecoverableEccError; -+ p_Fm->p_FmDriverParam->enIramTestMode = FALSE; -+ p_Fm->p_FmDriverParam->enMuramTestMode = FALSE; -+ p_Fm->p_FmDriverParam->externalEccRamsEnable = DEFAULT_externalEccRamsEnable; -+ -+ p_Fm->p_FmDriverParam->fwVerify = DEFAULT_VerifyUcode; -+ p_Fm->p_FmDriverParam->firmware.size = p_FmParam->firmware.size; -+ if (p_Fm->p_FmDriverParam->firmware.size) -+ { -+ p_Fm->p_FmDriverParam->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->p_FmDriverParam->firmware.size); -+ if (!p_Fm->p_FmDriverParam->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->p_FmDriverParam->firmware.p_Code, p_FmParam->firmware.p_Code ,p_Fm->p_FmDriverParam->firmware.size); -+ } -+ -+ if (p_Fm->guestId != NCSW_MASTER_ID) -+ return p_Fm; -+ -+ /* read revision register 1 */ -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fm_ip_rev_1); -+ p_Fm->p_FmStateStruct->revInfo.majorRev = (uint8_t)((tmpReg & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT); -+ p_Fm->p_FmStateStruct->revInfo.minorRev = (uint8_t)((tmpReg & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT); -+ /* Chip dependent, will be configured in Init */ -+ -+ p_Fm->p_FmDriverParam->dmaAidOverride = DEFAULT_aidOverride; -+ p_Fm->p_FmDriverParam->dmaAidMode = DEFAULT_aidMode; -+#ifdef FM_AID_MODE_NO_TNUM_SW005 -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) -+ p_Fm->p_FmDriverParam->dmaAidMode = e_FM_DMA_AID_OUT_PORT_ID; -+#endif /* FM_AID_MODE_NO_TNUM_SW005 */ -+#ifdef FM_NO_GUARANTEED_RESET_VALUES -+ -+ if (1)//p_Fm->p_FmStateStruct->revInfo.majorRev < 6) -+ { -+ p_Fm->p_FmStateStruct->totalFifoSize = 0; -+ p_Fm->p_FmStateStruct->totalNumOfTasks = BMI_MAX_NUM_OF_TASKS; -+ p_Fm->p_FmStateStruct->maxNumOfOpenDmas = BMI_MAX_NUM_OF_DMAS; -+ p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency = DEFAULT_dmaCommQLow; -+ p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency = DEFAULT_dmaCommQHigh; -+ p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency = DEFAULT_dmaReadIntBufLow; -+ p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency = DEFAULT_dmaReadIntBufHigh; -+ p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency = DEFAULT_dmaWriteIntBufLow; -+ p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency = DEFAULT_dmaWriteIntBufHigh; -+ p_Fm->p_FmDriverParam->dmaCacheOverride = DEFAULT_cacheOverride; -+ p_Fm->p_FmDriverParam->dmaCamNumOfEntries = DEFAULT_dmaCamNumOfEntries; -+ p_Fm->p_FmDriverParam->dmaDbgCntMode = DEFAULT_dmaDbgCntMode; -+ p_Fm->p_FmDriverParam->dmaEnEmergency = FALSE; -+ p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats = DEFAULT_axiDbgNumOfBeats; -+ p_Fm->p_FmDriverParam->dmaSosEmergency = DEFAULT_dmaSosEmergency; -+ p_Fm->p_FmDriverParam->dmaWatchdog = DEFAULT_dmaWatchdog; -+ p_Fm->p_FmDriverParam->thresholds.dispLimit = DEFAULT_dispLimit; -+ p_Fm->p_FmDriverParam->thresholds.prsDispTh = DEFAULT_prsDispTh; -+ p_Fm->p_FmDriverParam->thresholds.plcrDispTh = DEFAULT_plcrDispTh; -+ p_Fm->p_FmDriverParam->thresholds.kgDispTh = DEFAULT_kgDispTh; -+ p_Fm->p_FmDriverParam->thresholds.bmiDispTh = DEFAULT_bmiDispTh; -+ p_Fm->p_FmDriverParam->thresholds.qmiEnqDispTh = DEFAULT_qmiEnqDispTh; -+ p_Fm->p_FmDriverParam->thresholds.qmiDeqDispTh = DEFAULT_qmiDeqDispTh; -+ p_Fm->p_FmDriverParam->thresholds.fmCtl1DispTh = DEFAULT_fmCtl1DispTh; -+ p_Fm->p_FmDriverParam->thresholds.fmCtl2DispTh = DEFAULT_fmCtl2DispTh; -+ p_Fm->p_FmDriverParam->dmaEnEmergencySmoother = FALSE; -+ } -+ else -+#endif /* FM_NO_GUARANTEED_RESET_VALUES */ -+ { -+ /* read the values from the registers as they are initialized by the HW with -+ * the required values. -+ */ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg1); -+ p_Fm->p_FmStateStruct->totalFifoSize = -+ (((tmpReg & BMI_TOTAL_FIFO_SIZE_MASK) >> BMI_CFG1_FIFO_SIZE_SHIFT) + 1) * BMI_FIFO_UNITS; -+ -+#ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 -+ tmpReg = 0x007B0000; -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg); -+#endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */ -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2); -+ p_Fm->p_FmStateStruct->totalNumOfTasks = -+ (uint8_t)(((tmpReg & BMI_TOTAL_NUM_OF_TASKS_MASK) >> BMI_CFG2_TASKS_SHIFT) + 1); -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtr); -+ p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency = -+ (uint8_t)(tmpReg >> DMA_THRESH_COMMQ_SHIFT); -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmhy); -+ p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency = -+ (uint8_t)(tmpReg >> DMA_THRESH_COMMQ_SHIFT); -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr); -+ p_Fm->p_FmDriverParam->dmaCacheOverride = (e_FmDmaCacheOverride)((tmpReg & DMA_MODE_CACHE_OR_MASK) >> DMA_MODE_CACHE_OR_SHIFT); -+ p_Fm->p_FmDriverParam->dmaCamNumOfEntries = (uint8_t)((((tmpReg & DMA_MODE_CEN_MASK) >> DMA_MODE_CEN_SHIFT) +1)*DMA_CAM_UNITS); -+ p_Fm->p_FmDriverParam->dmaDbgCntMode = (e_FmDmaDbgCntMode)((tmpReg & DMA_MODE_DBG_MASK) >> DMA_MODE_DBG_SHIFT); -+ p_Fm->p_FmDriverParam->dmaEnEmergency = (bool)((tmpReg & DMA_MODE_EB)? TRUE : FALSE); -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_mxd); -+ p_Fm->p_FmDriverParam->thresholds.dispLimit = (uint8_t)((tmpReg & FPM_DISP_LIMIT_MASK) << FPM_DISP_LIMIT_SHIFT); -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_dis1); -+ p_Fm->p_FmDriverParam->thresholds.prsDispTh = (uint8_t)((tmpReg & FPM_THR1_PRS_MASK ) << FPM_THR1_PRS_SHIFT); -+ p_Fm->p_FmDriverParam->thresholds.plcrDispTh = (uint8_t)((tmpReg & FPM_THR1_KG_MASK ) << FPM_THR1_KG_SHIFT); -+ p_Fm->p_FmDriverParam->thresholds.kgDispTh = (uint8_t)((tmpReg & FPM_THR1_PLCR_MASK ) << FPM_THR1_PLCR_SHIFT); -+ p_Fm->p_FmDriverParam->thresholds.bmiDispTh = (uint8_t)((tmpReg & FPM_THR1_BMI_MASK ) << FPM_THR1_BMI_SHIFT); -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_dis2); -+ p_Fm->p_FmDriverParam->thresholds.qmiEnqDispTh = (uint8_t)((tmpReg & FPM_THR2_QMI_ENQ_MASK ) << FPM_THR2_QMI_ENQ_SHIFT); -+ p_Fm->p_FmDriverParam->thresholds.qmiDeqDispTh = (uint8_t)((tmpReg & FPM_THR2_QMI_DEQ_MASK ) << FPM_THR2_QMI_DEQ_SHIFT); -+ p_Fm->p_FmDriverParam->thresholds.fmCtl1DispTh = (uint8_t)((tmpReg & FPM_THR2_FM_CTL1_MASK ) << FPM_THR2_FM_CTL1_SHIFT); -+ p_Fm->p_FmDriverParam->thresholds.fmCtl2DispTh = (uint8_t)((tmpReg & FPM_THR2_FM_CTL2_MASK ) << FPM_THR2_FM_CTL2_SHIFT); -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsetr); -+ p_Fm->p_FmDriverParam->dmaSosEmergency = tmpReg; -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmwcr); -+ p_Fm->p_FmDriverParam->dmaWatchdog = tmpReg/p_Fm->p_FmStateStruct->fmClkFreq; -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmemsr); -+ p_Fm->p_FmDriverParam->dmaEnEmergencySmoother = (bool)((tmpReg & DMA_EMSR_EMSTR_MASK)? TRUE : FALSE); -+ p_Fm->p_FmDriverParam->dmaEmergencySwitchCounter = (tmpReg & DMA_EMSR_EMSTR_MASK); -+ } -+ -+ 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; -+ t_FmDriverParam *p_FmDriverParam = NULL; -+ t_Error err = E_OK; -+ uint32_t cfgReg = 0; -+ int i; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ -+ p_Fm->p_FmStateStruct->count1MicroBit = FM_TIMESTAMP_1_USEC_BIT; -+ -+ if (p_Fm->guestId != NCSW_MASTER_ID) -+ return InitGuestMode(p_Fm); -+ -+#ifdef FM_NO_GUARANTEED_RESET_VALUES -+ if (1)//p_Fm->p_FmStateStruct->revInfo.majorRev < 6) -+ /* 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); -+#endif /* FM_NO_GUARANTEED_RESET_VALUES */ -+ -+ CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters); -+ -+ p_FmDriverParam = p_Fm->p_FmDriverParam; -+ -+ /* clear revision-dependent non existing exception */ -+#ifdef FM_NO_DISPATCH_RAM_ECC -+ if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) && -+ (p_Fm->p_FmStateStruct->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 (p_Fm->p_FmStateStruct->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 (p_Fm->p_FmStateStruct->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_FmDriverParam->userSetExceptions; -+ -+#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 -+ if (p_FmDriverParam->resetOnInit) -+ { -+ if ((err = FwNotResetErratumBugzilla6173WA(p_Fm)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ else -+ { -+#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ -+ -+ /* Reset the FM if required. */ -+ if (p_FmDriverParam->resetOnInit) -+ { -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET); -+ CORE_MemoryBarrier(); -+ XX_UDelay(100); -+ -+ if (GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs) & QMI_GS_HALT_NOT_BUSY) -+ { -+ uint32_t tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee); -+ /* clear tmpReg event bits in order not to clear standing events */ -+ tmpReg &= ~(FPM_EV_MASK_DOUBLE_ECC | FPM_EV_MASK_STALL | FPM_EV_MASK_SINGLE_ECC); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee, tmpReg | FPM_EV_MASK_RELEASE_FM); -+ CORE_MemoryBarrier(); -+ XX_UDelay(100); -+ } -+ } -+ -+ /*************************************/ -+ /* Load FMan-Controller code to IRAM */ -+ /*************************************/ -+ if (ClearIRam(p_Fm) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ if (p_Fm->p_FmDriverParam->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 == 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; -+ -+ /**********************/ -+ /* 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")); -+ } -+ -+ /**********************/ -+ /* 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); -+ } -+ -+ /**********************/ -+ /* Enable all modules */ -+ /**********************/ -+ /* clear & enable global counters - calculate reg and save for later, -+ because it's the same reg for QMI enable */ -+ cfgReg = QMI_CFG_EN_COUNTERS; -+#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4) -+ cfgReg |= (uint32_t)(((QMI_DEF_TNUMS_THRESH) << 8) | (uint32_t)QMI_DEF_TNUMS_THRESH); -+#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ -+ -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_init, BMI_INIT_START); -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, cfgReg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN); -+ -+ EnableTimeStamp(p_Fm); -+ -+ if (p_Fm->p_FmDriverParam->firmware.p_Code) -+ { -+ XX_Free(p_Fm->p_FmDriverParam->firmware.p_Code); -+ p_Fm->p_FmDriverParam->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; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ -+ 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) -+ XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName); -+ -+ if (!p_Fm->recoveryMode) -+ XX_Free(p_Fm->p_FmStateStruct); -+ -+ XX_Free(p_Fm); -+ -+ return E_OK; -+ } -+ -+ /* disable BMI and QMI */ -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_init, 0); -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, 0); -+ -+ 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->p_FmDriverParam->firmware.p_Code) -+ XX_Free(p_Fm->p_FmDriverParam->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->p_FmDriverParam->resetOnInit = enable; -+ -+ 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; -+ -+ 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->dmaCacheOverride = cacheOverride; -+ -+ 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->dmaAidOverride = aidOverride; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode) -+{ -+ 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->dmaAidMode = aidMode; -+ -+ 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!")); -+#endif -+ p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats = axiDbgNumOfBeats; -+ -+ return E_OK; -+} -+ -+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->dmaCamNumOfEntries = numOfEntries; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode) -+{ -+ 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->dmaDbgCntMode = fmDmaDbgCntMode; -+ -+ 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->dmaStopOnBusError = stop; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency) -+{ -+ 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->dmaEnEmergency = TRUE; -+ memcpy(&p_Fm->p_FmDriverParam->dmaEmergency, p_Emergency, sizeof(t_FmDmaEmergency)); -+ -+ 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->dmaEnEmergencySmoother = TRUE; -+ p_Fm->p_FmDriverParam->dmaEmergencySwitchCounter = emergencyCnt; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr) -+{ -+ 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->dmaErr = dmaErr; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr) -+{ -+ 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->catastrophicErr = catastrophicErr; -+ -+ 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->enMuramTestMode = 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->enIramTestMode = 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->haltOnExternalActivation = 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->haltOnUnrecoverableEccError = 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->p_FmDriverParam->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->externalEccRamsEnable = 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->tnumAgingPeriod = tnumAgingPeriod; -+ -+ 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); -+ -+ memcpy(&p_Fm->p_FmDriverParam->thresholds, p_FmThresholds, sizeof(t_FmThresholds)); -+ -+ 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->dmaSosEmergency = 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!")); -+#endif -+ memcpy(&p_Fm->p_FmDriverParam->dmaWriteBufThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds)); -+ -+ return E_OK; -+} -+ -+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); -+ -+ memcpy(&p_Fm->p_FmDriverParam->dmaCommQThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds)); -+ -+ 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!")); -+#endif -+ memcpy(&p_Fm->p_FmDriverParam->dmaReadBufThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds)); -+ -+ return E_OK; -+} -+ -+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->dmaWatchdog = 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; -+} -+ -+/****************************************************/ -+/* 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; -+ -+ 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); -+ -+ /* normal interrupts */ -+ pending = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi); -+ if (!pending) -+ return; -+ -+ 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 = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_fcev[0]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_cee[0]); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_cev[0], event); -+ 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 = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_fcev[1]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_cee[1]); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_cev[1], event); -+ 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 = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_fcev[2]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_cee[2]); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_cev[2], event); -+ 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 = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_fcev[3]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_cee[3]); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_cev[3], event); -+ 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; -+ -+ 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); -+ -+ /* error interrupts */ -+ pending = GET_UINT32(p_Fm->p_FmFpmRegs->fm_epi); -+ 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; -+ uint32_t tmpRegs[8] = {0,0,0,0,0,0,0,0}; -+ uint8_t relativePortId, shift, weight, maxPercent = 0; -+ -+ 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); -+ -+ /* check that all ports add up to 100% */ -+ sum = 0; -+ for (i=0;inumOfPorts;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;inumOfPorts;i++) -+ { -+ if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent) -+ maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth; -+ } -+ -+ /* calculate weight for each port */ -+ for (i=0;inumOfPorts;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 exect 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 */ -+ SW_PORT_ID_TO_HW_PORT_ID(hardwarePortId, -+ p_PortsBandwidth->portsBandwidths[i].type, -+ p_PortsBandwidth->portsBandwidths[i].relativePortId); -+ relativePortId = (uint8_t)(hardwarePortId % 8); -+ shift = (uint8_t)(32-4*(relativePortId+1)); -+ -+ -+ if (weight > 1) -+ /* Add this port to tmpReg */ -+ /* (each 8 ports result in one register)*/ -+ tmpRegs[hardwarePortId/8] |= ((weight-1) << shift); -+ } -+ -+ for (i=0;i<8;i++) -+ if (tmpRegs[i]) -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_arb[i], tmpRegs[i]); -+ -+ return E_OK; -+} -+ -+t_Error FM_EnableRamsEcc(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint32_t tmpReg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ /*SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);*/ -+ -+ 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 -+ { -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr); -+ if (tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL) -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, tmpReg | FPM_RAM_CTL_IRAM_ECC_EN); -+ else -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, tmpReg | (FPM_RAM_CTL_RAMS_ECC_EN | FPM_RAM_CTL_IRAM_ECC_EN)); -+ 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; -+ uint32_t tmpReg; -+ bool explicitDisable = FALSE; -+ -+ 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->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; -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr); -+ if (tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL) -+ { -+ DBG(WARNING, ("Rams ECC is configured to be controlled through JTAG")); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, tmpReg & ~FPM_RAM_CTL_IRAM_ECC_EN); -+ } -+ else -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, tmpReg & ~(FPM_RAM_CTL_RAMS_ECC_EN | FPM_RAM_CTL_IRAM_ECC_EN)); -+ 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; -+ uint32_t tmpReg; -+ -+ 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); -+ -+ GET_EXCEPTION_FLAG(bitMask, exception); -+ if (bitMask) -+ { -+ if (enable) -+ p_Fm->p_FmStateStruct->exceptions |= bitMask; -+ else -+ p_Fm->p_FmStateStruct->exceptions &= ~bitMask; -+ -+ switch (exception) -+ { -+ case (e_FM_EX_DMA_BUS_ERROR): -+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr); -+ if (enable) -+ tmpReg |= DMA_MODE_BER; -+ else -+ tmpReg &= ~DMA_MODE_BER; -+ /* disable bus error */ -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg); -+ break; -+ case (e_FM_EX_DMA_READ_ECC): -+ case (e_FM_EX_DMA_SYSTEM_WRITE_ECC): -+ case (e_FM_EX_DMA_FM_WRITE_ECC): -+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr); -+ if (enable) -+ tmpReg |= DMA_MODE_ECC; -+ else -+ tmpReg &= ~DMA_MODE_ECC; -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg); -+ break; -+ case (e_FM_EX_FPM_STALL_ON_TASKS): -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee); -+ if (enable) -+ tmpReg |= FPM_EV_MASK_STALL_EN; -+ else -+ tmpReg &= ~FPM_EV_MASK_STALL_EN; -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee, tmpReg); -+ break; -+ case (e_FM_EX_FPM_SINGLE_ECC): -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee); -+ if (enable) -+ tmpReg |= FPM_EV_MASK_SINGLE_ECC_EN; -+ else -+ tmpReg &= ~FPM_EV_MASK_SINGLE_ECC_EN; -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee, tmpReg); -+ break; -+ case ( e_FM_EX_FPM_DOUBLE_ECC): -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee); -+ if (enable) -+ tmpReg |= FPM_EV_MASK_DOUBLE_ECC_EN; -+ else -+ tmpReg &= ~FPM_EV_MASK_DOUBLE_ECC_EN; -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee, tmpReg); -+ break; -+ case ( e_FM_EX_QMI_SINGLE_ECC): -+#if defined(FM_QMI_NO_ECC_EXCEPTIONS) || defined(FM_QMI_NO_SINGLE_ECC_EXCEPTION) -+ if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) || -+ (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)) -+ { -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC")); -+ return E_OK; -+ } -+#endif /* FM_QMI_NO_ECC_EXCEPTIONS */ -+ tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien); -+ if (enable) -+ tmpReg |= QMI_INTR_EN_SINGLE_ECC; -+ else -+ tmpReg &= ~QMI_INTR_EN_SINGLE_ECC; -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien, tmpReg); -+ break; -+ case (e_FM_EX_QMI_DOUBLE_ECC): -+#ifdef FM_QMI_NO_ECC_EXCEPTIONS -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev == 4) -+ { -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_DOUBLE_ECC")); -+ return E_OK; -+ } -+#endif /* FM_QMI_NO_ECC_EXCEPTIONS */ -+ tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien); -+ if (enable) -+ tmpReg |= QMI_ERR_INTR_EN_DOUBLE_ECC; -+ else -+ tmpReg &= ~QMI_ERR_INTR_EN_DOUBLE_ECC; -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg); -+ break; -+ case (e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID): -+ tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien); -+ if (enable) -+ tmpReg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF; -+ else -+ tmpReg &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF; -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg); -+ break; -+ case (e_FM_EX_BMI_LIST_RAM_ECC): -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier); -+ if (enable) -+ tmpReg |= BMI_ERR_INTR_EN_LIST_RAM_ECC; -+ else -+ tmpReg &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC; -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg); -+ break; -+ case (e_FM_EX_BMI_STORAGE_PROFILE_ECC): -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier); -+ if (enable) -+ tmpReg |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC; -+ else -+ tmpReg &= ~BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC; -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg); -+ break; -+ case (e_FM_EX_BMI_STATISTICS_RAM_ECC): -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier); -+ if (enable) -+ tmpReg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC; -+ else -+ tmpReg &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC; -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg); -+ break; -+ case (e_FM_EX_BMI_DISPATCH_RAM_ECC): -+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier); -+ if (enable) -+ { -+#ifdef FM_NO_DISPATCH_RAM_ECC -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4) -+ { -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_DISPATCH_RAM_ECC")); -+ return E_OK; -+ } -+#endif /* FM_NO_DISPATCH_RAM_ECC */ -+ tmpReg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC; -+ } -+ else -+ tmpReg &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC; -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg); -+ break; -+ case (e_FM_EX_IRAM_ECC): -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rie); -+ if (enable) -+ { -+ /* enable ECC if not enabled */ -+ FmEnableRamsEcc(p_Fm); -+ /* enable ECC interrupts */ -+ tmpReg |= FPM_IRAM_ECC_ERR_EX_EN; -+ } -+ else -+ { -+ /* ECC mechanism may be disabled, depending on driver status */ -+ FmDisableRamsEcc(p_Fm); -+ tmpReg &= ~FPM_IRAM_ECC_ERR_EX_EN; -+ } -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rie, tmpReg); -+ break; -+ -+ case (e_FM_EX_MURAM_ECC): -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rie); -+ if (enable) -+ { -+ /* enable ECC if not enabled */ -+ FmEnableRamsEcc(p_Fm); -+ /* enable ECC interrupts */ -+ tmpReg |= FPM_MURAM_ECC_ERR_EX_EN; -+ } -+ else -+ { -+ /* ECC mechanism may be disabled, depending on driver status */ -+ FmDisableRamsEcc(p_Fm); -+ tmpReg &= ~FPM_MURAM_ECC_ERR_EX_EN; -+ } -+ -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rie, tmpReg); -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ } -+ 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; -+ -+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 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, 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 >= 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; -+ } -+ -+ switch (counter) -+ { -+ case (e_FM_COUNTERS_ENQ_TOTAL_FRAME): -+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_etfc); -+ case (e_FM_COUNTERS_DEQ_TOTAL_FRAME): -+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dtfc); -+ case (e_FM_COUNTERS_DEQ_0): -+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc0); -+ case (e_FM_COUNTERS_DEQ_1): -+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc1); -+ case (e_FM_COUNTERS_DEQ_2): -+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc2); -+ case (e_FM_COUNTERS_DEQ_3): -+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc3); -+ case (e_FM_COUNTERS_DEQ_FROM_DEFAULT): -+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfdc); -+ case (e_FM_COUNTERS_DEQ_FROM_CONTEXT): -+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfcc); -+ case (e_FM_COUNTERS_DEQ_FROM_FD): -+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dffc); -+ case (e_FM_COUNTERS_DEQ_CONFIRM): -+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dcc); -+ break; -+ } -+ /* should never get here */ -+ ASSERT_COND(FALSE); -+ return 0; -+} -+ -+t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val) -+{ -+ 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); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ /* 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 >= 6) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Requested counter not supported")); -+ 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)) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); -+ break; -+ default: -+ break; -+ } -+ -+ /* Set counter */ -+ switch (counter) -+ { -+ case (e_FM_COUNTERS_ENQ_TOTAL_FRAME): -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_etfc, val); -+ break; -+ case (e_FM_COUNTERS_DEQ_TOTAL_FRAME): -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dtfc, val); -+ break; -+ case (e_FM_COUNTERS_DEQ_0): -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc0, val); -+ break; -+ case (e_FM_COUNTERS_DEQ_1): -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc1, val); -+ break; -+ case (e_FM_COUNTERS_DEQ_2): -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc2, val); -+ break; -+ case (e_FM_COUNTERS_DEQ_3): -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc3, val); -+ break; -+ case (e_FM_COUNTERS_DEQ_FROM_DEFAULT): -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfdc, val); -+ break; -+ case (e_FM_COUNTERS_DEQ_FROM_CONTEXT): -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfcc, val); -+ break; -+ case (e_FM_COUNTERS_DEQ_FROM_FD): -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dffc, val); -+ break; -+ case (e_FM_COUNTERS_DEQ_CONFIRM): -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dcc, val); -+ break; -+ default: -+ break; -+ } -+ -+ return E_OK; -+} -+ -+void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint32_t bitMask; -+ -+ 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); -+ -+ bitMask = (uint32_t)((muramPort==e_FM_DMA_MURAM_PORT_WRITE) ? DMA_MODE_EMERGENCY_WRITE : DMA_MODE_EMERGENCY_READ); -+ -+ if (enable) -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) | bitMask); -+ else /* disable */ -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) & ~bitMask); -+ -+ return; -+} -+ -+void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ 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); -+ -+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) | ((uint32_t)pri << DMA_MODE_BUS_PRI_SHIFT) ); -+ -+ return; -+} -+ -+void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint32_t tmpReg; -+ -+ SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ -+ 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; -+ } -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr); -+ -+ p_FmDmaStatus->cmqNotEmpty = (bool)(tmpReg & DMA_STATUS_CMD_QUEUE_NOT_EMPTY); -+ p_FmDmaStatus->busError = (bool)(tmpReg & DMA_STATUS_BUS_ERR); -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) -+ p_FmDmaStatus->singlePortEccError = (bool)(tmpReg & DMA_STATUS_FM_SPDAT_ECC); -+ else -+ { -+ p_FmDmaStatus->readBufEccError = (bool)(tmpReg & DMA_STATUS_READ_ECC); -+ p_FmDmaStatus->writeBufEccSysError = (bool)(tmpReg & DMA_STATUS_SYSTEM_WRITE_ECC); -+ p_FmDmaStatus->writeBufEccFmError = (bool)(tmpReg & DMA_STATUS_FM_WRITE_ECC); -+ } -+} -+ -+void FM_Resume(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint32_t tmpReg; -+ -+ 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); -+ -+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee); -+ /* clear tmpReg event bits in order not to clear standing events */ -+ tmpReg &= ~(FPM_EV_MASK_DOUBLE_ECC | FPM_EV_MASK_STALL | FPM_EV_MASK_SINGLE_ECC); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_ee, tmpReg | FPM_EV_MASK_RELEASE_FM); -+} -+ -+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 (revInfo.packageRev != IP_OFFLOAD_PACKAGE_NUMBER) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Fman ctrl code package")); -+ -+ if (revInfo.packageRev == IP_OFFLOAD_PACKAGE_NUMBER) -+ { -+ switch (spOper) -+ { -+ 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_RPD): -+ *p_SpOperCoding = 4; -+ break; -+ case (FM_SP_OP_IPSEC): -+ *p_SpOperCoding = 2; -+ break; -+ case (FM_SP_OP_DCL4C): -+ *p_SpOperCoding = 7; -+ 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); -+ -+ 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); -+ } -+ -+ 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)((clkCnt - utilValue) * 100 / clkCnt); -+ if (clkCnt != utilValue) -+ p_Mon->percentCnt[1] = (uint8_t)(((clkCnt - utilValue) - effValue) * 100 / (clkCnt - utilValue)); -+ else -+ p_Mon->percentCnt[1] = 0; -+ -+ return E_OK; -+} -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+t_Error FM_DumpRegs(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ uint8_t i,j = 0; -+ -+ DECLARE_DUMP; -+ -+ 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) || -+ p_Fm->baseAddr), E_INVALID_OPERATION); -+ -+ DUMP_SUBTITLE(("\n")); -+ -+ DUMP_TITLE(p_Fm->p_FmFpmRegs, ("FM-FPM Regs")); -+ -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_tnc); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_prc); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_brkc); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_mxd); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_dis1); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_dis2); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fm_epi); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fm_rie); -+ -+ DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_fcev, ("fmfp_fcev")); -+ DUMP_SUBSTRUCT_ARRAY(i, 4) -+ { -+ DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_fcev[i], sizeof(uint32_t)); -+ } -+ -+ DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_cee, ("fmfp_cee")); -+ DUMP_SUBSTRUCT_ARRAY(i, 4) -+ { -+ DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_cee[i], sizeof(uint32_t)); -+ } -+ -+ DUMP_SUBTITLE(("\n")); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_tsc1); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_tsc2); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_tsp); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_tsf); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fm_rcr); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_extc); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_ext1); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_ext2); -+ -+ DUMP_SUBTITLE(("\n")); -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_dra, 0); -+ CORE_MemoryBarrier(); -+ for (j=0; j<128; j++) -+ { -+ DUMP_TITLE(j, ("fmfp_dra")); -+ DUMP_SUBSTRUCT_ARRAY(i, 4) -+ { -+ DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_drd[i], sizeof(uint32_t)); -+ } -+ DUMP_TITLE(j, ("fmfp_ts")); -+ DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ts[j], sizeof(uint32_t)); -+ } -+ -+ DUMP_SUBTITLE(("\n")); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fm_ip_rev_1); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fm_ip_rev_2); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fm_rstc); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fm_cld); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fm_npi); -+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmfp_ee); -+ -+ DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_cev, ("fmfp_cev")); -+ DUMP_SUBSTRUCT_ARRAY(i, 4) -+ { -+ DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_cev[i], sizeof(uint32_t)); -+ } -+ -+ DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps, ("fmfp_ps")); -+ DUMP_SUBSTRUCT_ARRAY(i, 64) -+ { -+ DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[i], sizeof(uint32_t)); -+ } -+ -+ DUMP_TITLE(p_Fm->p_FmDmaRegs, ("FM-DMA Regs")); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsr); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmemsr); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmmr); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtr); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmhy); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsetr); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtah); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtal); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtcid); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmra); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmrd); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmwcr); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmebcr); -+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmdcr); -+ -+ DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr, ("fmdmplr")); -+ -+ DUMP_SUBSTRUCT_ARRAY(i, FM_MAX_NUM_OF_HW_PORT_IDS/2) -+ { -+ DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[i], sizeof(uint32_t)); -+ } -+ -+ DUMP_TITLE(p_Fm->p_FmBmiRegs, ("FM-BMI COMMON Regs")); -+ DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_init); -+ DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_cfg1); -+ DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_cfg2); -+ DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_ievr); -+ DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_ier); -+ -+ DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_arb, ("fmbm_arb")); -+ DUMP_SUBSTRUCT_ARRAY(i, 8) -+ { -+ DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_arb[i], sizeof(uint32_t)); -+ } -+ -+ DUMP_TITLE(p_Fm->p_FmQmiRegs, ("FM-QMI COMMON Regs")); -+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_gc); -+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eie); -+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eien); -+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eif); -+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ie); -+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ien); -+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_if); -+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_gs); -+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_etfc); -+ -+ return E_OK; -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ -+ -+/****************************************************/ -+/* Hidden-DEBUG Only API */ -+/****************************************************/ -+ -+t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception) -+{ -+ 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); -+ -+ 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")); -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, QMI_ERR_INTR_EN_DEQ_FROM_DEF); -+ 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")); -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_if, QMI_INTR_EN_SINGLE_ECC); -+ 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")); -+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, QMI_ERR_INTR_EN_DOUBLE_ECC); -+ 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")); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_LIST_RAM_ECC); -+ 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")); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC); -+ 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")); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_STATISTICS_RAM_ECC); -+ 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")); -+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_DISPATCH_RAM_ECC); -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced")); -+ } -+ -+ return E_OK; -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/fm.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/fm.h -new file mode 100644 -index 0000000..4f3ad00 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/fm.h -@@ -0,0 +1,897 @@ -+/* -+ * 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" -+ -+ -+#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 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; \ -+ } -+ -+/**************************************************************************//** -+ @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_totalFifoSize(major) \ -+ (((major == 2) || (major == 5)) ? \ -+ (100*KILOBYTE) : ((major == 6) ? \ -+ (288*KILOBYTE) : ((major == 4) ? \ -+ (46*KILOBYTE) : (122*KILOBYTE)))) -+ -+#define DEFAULT_eccEnable FALSE -+#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 -+#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR -+#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_dmaCamNumOfEntries 32 -+#define DEFAULT_dmaCommQLow ((DMA_THRESH_MAX_COMMQ+1)/2) -+#define DEFAULT_dmaCommQHigh ((DMA_THRESH_MAX_COMMQ+1)*3/4) -+#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_dmaSosEmergency 0 -+#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT -+#define DEFAULT_catastrophicErr e_FM_CATASTROPHIC_ERR_STALL_PORT -+#define DEFAULT_dmaErr e_FM_DMA_ERR_CATASTROPHIC -+#define DEFAULT_resetOnInit FALSE -+#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 -+#define DEFAULT_tnumAgingPeriod 0 -+#define DEFAULT_dmaWatchdog 0 /* disabled */ -+ -+#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_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 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 Memory Mapped Registers -+*//***************************************************************************/ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+typedef _Packed struct -+{ -+ volatile uint32_t fmfp_tnc; /**< FPM TNUM Control */ -+ volatile uint32_t fmfp_prc; /**< FPM Port_ID FmCtl Association */ -+ volatile uint32_t fmfp_brkc; /**< FPM Breakpoint Control */ -+ volatile uint32_t fmfp_mxd; /**< FPM Maximum dispatch */ -+ volatile uint32_t fmfp_dis1; /**< FPM Dispatch Thresholds1 */ -+ volatile uint32_t fmfp_dis2; /**< FPM Dispatch Thresholds2 */ -+ volatile uint32_t fm_epi; /**< FM Error Pending Interrupts */ -+ volatile uint32_t fm_rie; /**< FM Error Interrupt Enable */ -+ volatile uint32_t fmfp_fcev[4]; /**< FPM FMan-Controller Event 1-4 */ -+ volatile uint8_t res1[16]; /**< reserved */ -+ volatile uint32_t fmfp_cee[4]; /**< PM FMan-Controller Event 1-4 */ -+ volatile uint8_t res2[16]; /**< reserved */ -+ volatile uint32_t fmfp_tsc1; /**< FPM TimeStamp Control1 */ -+ volatile uint32_t fmfp_tsc2; /**< FPM TimeStamp Control2 */ -+ volatile uint32_t fmfp_tsp; /**< FPM Time Stamp */ -+ volatile uint32_t fmfp_tsf; /**< FPM Time Stamp Fraction */ -+ volatile uint32_t fm_rcr; /**< FM Rams Control */ -+ volatile uint32_t fmfp_extc; /**< FPM External Requests Control */ -+ volatile uint32_t fmfp_ext1; /**< FPM External Requests Config1 */ -+ volatile uint32_t fmfp_ext2; /**< FPM External Requests Config2 */ -+ volatile uint32_t fmfp_drd[4]; /**< FPM Data_Ram Data 0-3 */ -+ volatile uint8_t res3[48]; /**< reserved */ -+ volatile uint32_t fmfp_dra; /**< FPM Data Ram Access */ -+ volatile uint32_t fm_ip_rev_1; /**< FM IP Block Revision 1 */ -+ volatile uint32_t fm_ip_rev_2; /**< FM IP Block Revision 2 */ -+ volatile uint32_t fm_rstc; /**< FM Reset Command */ -+ volatile uint32_t fm_cld; /**< FM Classifier Debug */ -+ volatile uint32_t fm_npi; /**< FM Normal Pending Interrupts */ -+ volatile uint32_t fmfp_exte; /**< FPM External Requests Enable */ -+ volatile uint32_t fmfp_ee; /**< FPM Event & Enable */ -+ volatile uint32_t fmfp_cev[4]; /**< FPM CPU Event 1-4 */ -+ volatile uint8_t res4[16]; /**< reserved */ -+ volatile uint32_t fmfp_ps[0x40]; /**< FPM Port Status */ -+ volatile uint8_t reserved1[0x200]; -+ volatile uint32_t fmfp_ts[128]; /**< 0x400: FPM Task Status */ -+} _PackedType t_FmFpmRegs; -+ -+#define NUM_OF_DBG_TRAPS 3 -+ -+typedef _Packed struct -+{ -+ volatile uint32_t fmbm_init; /**< BMI Initialization */ -+ volatile uint32_t fmbm_cfg1; /**< BMI Configuration 1 */ -+ volatile uint32_t fmbm_cfg2; /**< BMI Configuration 2 */ -+ volatile uint32_t reserved[5]; -+ volatile uint32_t fmbm_ievr; /**< Interrupt Event Register */ -+ volatile uint32_t fmbm_ier; /**< Interrupt Enable Register */ -+ volatile uint32_t fmbm_ifr; /**< Interrupt Force Register */ -+ volatile uint32_t reserved1[5]; -+ volatile uint32_t fmbm_arb[8]; /**< BMI Arbitration */ -+ volatile uint32_t reserved2[12]; -+ volatile uint32_t fmbm_dtc[NUM_OF_DBG_TRAPS]; /**< BMI Debug Trap Counter */ -+ volatile uint32_t reserved3; -+ volatile uint32_t fmbm_dcv[NUM_OF_DBG_TRAPS][4]; /**< BMI Debug Compare Value */ -+ volatile uint32_t fmbm_dcm[NUM_OF_DBG_TRAPS][4]; /**< BMI Debug Compare Mask */ -+ volatile uint32_t fmbm_gde; /**< BMI Global Debug Enable */ -+ volatile uint32_t fmbm_pp[63]; /**< BMI Port Parameters */ -+ volatile uint32_t reserved4; -+ volatile uint32_t fmbm_pfs[63]; /**< BMI Port FIFO Size */ -+ volatile uint32_t reserved5; -+ volatile uint32_t fmbm_spliodn[63]; /**< Port Partition ID */ -+} _PackedType t_FmBmiRegs; -+ -+typedef _Packed struct -+{ -+ volatile uint32_t fmqm_gc; /**< General Configuration Register */ -+ volatile uint32_t reserved0; -+ volatile uint32_t fmqm_eie; /**< Error Interrupt Event Register */ -+ volatile uint32_t fmqm_eien; /**< Error Interrupt Enable Register */ -+ volatile uint32_t fmqm_eif; /**< Error Interrupt Force Register */ -+ volatile uint32_t fmqm_ie; /**< Interrupt Event Register */ -+ volatile uint32_t fmqm_ien; /**< Interrupt Enable Register */ -+ volatile uint32_t fmqm_if; /**< Interrupt Force Register */ -+ volatile uint32_t fmqm_gs; /**< Global Status Register */ -+ volatile uint32_t reserved1; -+ volatile uint32_t fmqm_etfc; /**< Enqueue Total Frame Counter */ -+ volatile uint32_t fmqm_dtfc; /**< Dequeue Total Frame Counter */ -+ volatile uint32_t fmqm_dc0; /**< Dequeue Counter 0 */ -+ volatile uint32_t fmqm_dc1; /**< Dequeue Counter 1 */ -+ volatile uint32_t fmqm_dc2; /**< Dequeue Counter 2 */ -+ volatile uint32_t fmqm_dc3; /**< Dequeue Counter 3 */ -+ volatile uint32_t fmqm_dfdc; /**< Dequeue FQID from Default Counter */ -+ volatile uint32_t fmqm_dfcc; /**< Dequeue FQID from Context Counter */ -+ volatile uint32_t fmqm_dffc; /**< Dequeue FQID from FD Counter */ -+ volatile uint32_t fmqm_dcc; /**< Dequeue Confirm Counter */ -+ volatile uint32_t reserved1a[7]; -+ volatile uint32_t fmqm_tapc; /**< Tnum Aging Period Control */ -+ volatile uint32_t fmqm_dmcvc; /**< Dequeue MAC Command Valid Counter */ -+ volatile uint32_t fmqm_difdcc; /**< Dequeue Invalid FD Command Counter */ -+ volatile uint32_t fmqm_da1v; /**< Dequeue A1 Valid Counter */ -+ volatile uint32_t reserved1b; -+ volatile uint32_t fmqm_dtc; /**< 0x0080 Debug Trap Counter */ -+ volatile uint32_t fmqm_efddd; /**< 0x0084 Enqueue Frame Descriptor Dynamic Debug */ -+ volatile uint32_t reserved3[2]; -+ _Packed struct { -+ volatile uint32_t fmqm_dtcfg1; /**< 0x0090 Debug Trap Configuration 1 Register */ -+ volatile uint32_t fmqm_dtval1; /**< Debug Trap Value 1 Register */ -+ volatile uint32_t fmqm_dtm1; /**< Debug Trap Mask 1 Register */ -+ volatile uint32_t fmqm_dtc1; /**< Debug Trap Counter 1 Register */ -+ volatile uint32_t fmqm_dtcfg2; /**< Debug Trap Configuration 2 Register */ -+ volatile uint32_t fmqm_dtval2; /**< Debug Trap Value 2 Register */ -+ volatile uint32_t fmqm_dtm2; /**< Debug Trap Mask 2 Register */ -+ volatile uint32_t reserved1; -+ } _PackedType dbgTraps[NUM_OF_DBG_TRAPS]; -+} _PackedType t_FmQmiRegs; -+ -+typedef _Packed struct -+{ -+ volatile uint32_t fmdmsr; /**< FM DMA status register 0x04 */ -+ volatile uint32_t fmdmmr; /**< FM DMA mode register 0x08 */ -+ volatile uint32_t fmdmtr; /**< FM DMA bus threshold register 0x0c */ -+ volatile uint32_t fmdmhy; /**< FM DMA bus hysteresis register 0x10 */ -+ volatile uint32_t fmdmsetr; /**< FM DMA SOS emergency Threshold Register 0x14 */ -+ volatile uint32_t fmdmtah; /**< FM DMA transfer bus address high register 0x18 */ -+ volatile uint32_t fmdmtal; /**< FM DMA transfer bus address low register 0x1C */ -+ volatile uint32_t fmdmtcid; /**< FM DMA transfer bus communication ID register 0x20 */ -+ volatile uint32_t fmdmra; /**< FM DMA bus internal ram address register 0x24 */ -+ volatile uint32_t fmdmrd; /**< FM DMA bus internal ram data register 0x28 */ -+ volatile uint32_t fmdmwcr; /**< FM DMA CAM watchdog counter value 0x2C */ -+ volatile uint32_t fmdmebcr; /**< FM DMA CAM base in MURAM register 0x30 */ -+ volatile uint32_t fmdmccqdr; /**< FM DMA CAM and CMD Queue Debug register 0x34 */ -+ volatile uint32_t fmdmccqvr1; /**< FM DMA CAM and CMD Queue Value register #1 0x38 */ -+ volatile uint32_t fmdmccqvr2; /**< FM DMA CAM and CMD Queue Value register #2 0x3C */ -+ volatile uint32_t fmdmcqvr3; /**< FM DMA CMD Queue Value register #3 0x40 */ -+ volatile uint32_t fmdmcqvr4; /**< FM DMA CMD Queue Value register #4 0x44 */ -+ volatile uint32_t fmdmcqvr5; /**< FM DMA CMD Queue Value register #5 0x48 */ -+ volatile uint32_t fmdmsefrc; /**< FM DMA Semaphore Entry Full Reject Counter 0x50 */ -+ volatile uint32_t fmdmsqfrc; /**< FM DMA Semaphore Queue Full Reject Counter 0x54 */ -+ volatile uint32_t fmdmssrc; /**< FM DMA Semaphore SYNC Reject Counter 0x54 */ -+ volatile uint32_t fmdmdcr; /**< FM DMA Debug Counter */ -+ volatile uint32_t fmdmemsr; /**< FM DMA Emrgency Smoother Register */ -+ volatile uint32_t reserved; -+ volatile uint32_t fmdmplr[FM_MAX_NUM_OF_HW_PORT_IDS/2]; -+ /**< FM DMA PID-LIODN # register */ -+} _PackedType t_FmDmaRegs; -+ -+typedef _Packed 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 uint8_t res[0x80000-0x10]; -+} _PackedType t_FMIramRegs; -+ -+/* Trace buffer registers - -+ each FM Controller has its own trace buffer residing at FM_MM_TRB(fmCtrlIndex) offset */ -+typedef _Packed 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; -+} _PackedType 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 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_EMERGENCY_READ 0x00080000 -+#define DMA_MODE_EMERGENCY_WRITE 0x00040000 -+#define DMA_MODE_CACHE_OR_MASK 0xC0000000 -+#define DMA_MODE_CEN_MASK 0x0000E000 -+#define DMA_MODE_DBG_MASK 0x00000380 -+ -+#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 DMA_STATUS_FM_ECC (DMA_STATUS_READ_ECC | \ -+ DMA_STATUS_SYSTEM_WRITE_ECC | \ -+ DMA_STATUS_FM_WRITE_ECC | \ -+ DMA_STATUS_SYSTEM_DPEXT_ECC | \ -+ DMA_STATUS_FM_DPEXT_ECC | \ -+ DMA_STATUS_SYSTEM_DPDAT_ECC | \ -+ DMA_STATUS_FM_DPDAT_ECC | \ -+ DMA_STATUS_FM_SPDAT_ECC) -+ -+#define FM_LIODN_BASE_MASK 0x00000FFF -+ -+#define DMA_EMSR_EMSTR_MASK 0x0000FFFF -+ -+/* 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_EMERGENCY_LEVEL_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 64 -+ -+#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 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_CTL_RAMS_ECC_EN 0x80000000 -+#define FPM_RAM_CTL_IRAM_ECC_EN 0x40000000 -+#define FPM_RAM_CTL_MURAM_ECC 0x00008000 -+#define FPM_RAM_CTL_IRAM_ECC 0x00004000 -+#define FPM_RAM_CTL_MURAM_TEST_ECC 0x20000000 -+#define FPM_RAM_CTL_IRAM_TEST_ECC 0x10000000 -+#define FPM_RAM_CTL_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_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 -+ -+ -+#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 -+ -+/* 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 -+ -+/**************************************************************************//** -+ @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 /* port */ -+#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 /* port */ -+#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 -+ -+/**************************************************************************//** -+ @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_GS_HALT_NOT_BUSY 0x00000002 -+ -+#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 -+ -+/**************************************************************************//** -+ @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 struct -+{ -+ /* uint8_t numOfPartitions; */ -+ bool resetOnInit; -+ t_FmThresholds thresholds; -+ e_FmDmaCacheOverride dmaCacheOverride; -+ e_FmDmaAidMode dmaAidMode; -+ bool dmaAidOverride; -+ uint8_t dmaAxiDbgNumOfBeats; -+ uint8_t dmaCamNumOfEntries; -+ uint32_t dmaWatchdog; -+ t_FmDmaThresholds dmaCommQThresholds; -+ t_FmDmaThresholds dmaWriteBufThresholds; -+ t_FmDmaThresholds dmaReadBufThresholds; -+ uint32_t dmaSosEmergency; -+ e_FmDmaDbgCntMode dmaDbgCntMode; -+ bool dmaStopOnBusError; -+ bool dmaEnEmergency; -+ t_FmDmaEmergency dmaEmergency; -+ bool dmaEnEmergencySmoother; -+ uint32_t dmaEmergencySwitchCounter; -+ bool haltOnExternalActivation; -+ bool haltOnUnrecoverableEccError; -+ e_FmCatastrophicErr catastrophicErr; -+ e_FmDmaErr dmaErr; -+ bool enMuramTestMode; -+ bool enIramTestMode; -+ bool externalEccRamsEnable; -+ uint16_t tnumAgingPeriod; -+ t_FmFirmwareParams firmware; -+ bool fwVerify; -+ uint32_t userSetExceptions; -+} t_FmDriverParam; -+ -+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; -+ 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 */ -+ t_FmFpmRegs *p_FmFpmRegs; -+ t_FmBmiRegs *p_FmBmiRegs; -+ t_FmQmiRegs *p_FmQmiRegs; -+ t_FmDmaRegs *p_FmDmaRegs; -+ t_FmExceptionsCallback *f_Exception; -+ t_FmBusErrorCallback *f_BusError; -+ t_Handle h_App; /* Application handle */ -+ t_Handle h_Spinlock; -+ bool recoveryMode; -+ t_FmStateStruct *p_FmStateStruct; -+#if (DPAA_VERSION >= 11) -+ t_FmSp *p_FmSp; -+ uint8_t partNumOfVSPs; -+ uint8_t partVSPBase; -+ uintptr_t vspBaseAddr; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/* un-needed for recovery */ -+ 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_FmDriverParam *p_FmDriverParam; -+} t_Fm; -+ -+ -+#endif /* __FM_H */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/fm_ipc.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/fm_ipc.h -new file mode 100644 -index 0000000..f39d5d9 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/fm_ipc.h -@@ -0,0 +1,464 @@ -+/* -+ * 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 */ -+ 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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/fm_muram.c b/drivers/net/dpa/NetCommSw/Peripherals/FM/fm_muram.c -new file mode 100644 -index 0000000..a1cbe3f ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/fm_muram.c -@@ -0,0 +1,175 @@ -+/* -+ * 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); -+} -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/inc/fm_common.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/inc/fm_common.h -new file mode 100644 -index 0000000..6476c7a ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/inc/fm_common.h -@@ -0,0 +1,1103 @@ -+/* -+ * 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 -+ -+ -+/**************************************************************************//** -+ @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; -+ -+ -+ -+#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_FmPcdCcIpReassmTimeoutParams { -+ bool activate; -+ uint8_t tsbs; -+ uint32_t iprcpt; -+} t_FmPcdCcIpReassmTimeoutParams; -+ -+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 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 poolIndex; -+ // uint8_t poolIdForManip; -+ uint8_t numOfTasks; -+ uint8_t numOfExtraTasks; -+ uint8_t hardwarePortId; -+ t_FmRevisionInfo revInfo; -+ uint32_t nia; -+} t_GetCcParams; -+ -+typedef struct { -+ uint32_t type; -+ int psoSize; -+ uint32_t nia; -+ t_FmFmanCtrl orFmanCtrl; -+ bool overwrite; -+} t_SetCcParams; -+ -+typedef struct { -+ t_GetCcParams getCcParams; -+ t_SetCcParams setCcParams; -+} t_FmPortGetSetCcParams; -+ -+ -+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 BUFFER_POOL_ID_FOR_MANIP 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 UPDATE_NIA_PNEN 0x80000000 -+#define UPDATE_PSO 0x40000000 -+#define UPDATE_NIA_PNDN 0x20000000 -+#define UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY 0x10000000 -+#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 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_FRAG 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 -+ -+#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_BMI_AC_FETCH_ALL_FRAME 0x0000020c -+ -+#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 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 NIA_IPR_DIRECT_SCHEME_IPV4_OFFSET 0x10 -+#define NIA_IPR_DIRECT_SCHEME_IPV6_OFFSET 0x14 -+ -+/**************************************************************************//** -+ @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 -+ -+ -+#define SW_PORT_ID_TO_HW_PORT_ID(_port, _type, _relativePortId) \ -+switch (_type) { \ -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): \ -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): \ -+ CHECK_PORT_ID_OH_PORTS(_relativePortId); \ -+ _port = (uint8_t)(BASE_OH_PORTID + (_relativePortId)); \ -+ break; \ -+ case (e_FM_PORT_TYPE_RX): \ -+ CHECK_PORT_ID_1G_RX_PORTS(_relativePortId); \ -+ _port = (uint8_t)(BASE_1G_RX_PORTID + (_relativePortId)); \ -+ break; \ -+ case (e_FM_PORT_TYPE_RX_10G): \ -+ CHECK_PORT_ID_10G_RX_PORTS(_relativePortId); \ -+ _port = (uint8_t)(BASE_10G_RX_PORTID + (_relativePortId)); \ -+ break; \ -+ case (e_FM_PORT_TYPE_TX): \ -+ CHECK_PORT_ID_1G_TX_PORTS(_relativePortId); \ -+ _port = (uint8_t)(BASE_1G_TX_PORTID + (_relativePortId)); \ -+ break; \ -+ case (e_FM_PORT_TYPE_TX_10G): \ -+ CHECK_PORT_ID_10G_TX_PORTS(_relativePortId); \ -+ _port = (uint8_t)(BASE_10G_TX_PORTID + (_relativePortId)); \ -+ break; \ -+ default: \ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type")); \ -+ _port = 0; \ -+ break; \ -+} -+ -+#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_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) -+ -+#define GET_PRS_HDR_NUM(num, hdr) \ -+switch (hdr) \ -+{ case (HEADER_TYPE_ETH): num = 0; break; \ -+ case (HEADER_TYPE_LLC_SNAP): num = 1; break; \ -+ case (HEADER_TYPE_VLAN): num = 2; break; \ -+ case (HEADER_TYPE_PPPoE): num = 3; break; \ -+ case (HEADER_TYPE_MPLS): num = 4; break; \ -+ case (HEADER_TYPE_IPv4): num = 5; break; \ -+ case (HEADER_TYPE_IPv6): num = 6; break; \ -+ case (HEADER_TYPE_GRE): num = 7; break; \ -+ case (HEADER_TYPE_MINENCAP): num = 8; break; \ -+ case (HEADER_TYPE_USER_DEFINED_L3): num = 9; break; \ -+ case (HEADER_TYPE_TCP): num = 10; break; \ -+ case (HEADER_TYPE_UDP): num = 11; break; \ -+ case (HEADER_TYPE_IPSEC_AH): \ -+ case (HEADER_TYPE_IPSEC_ESP): num = 12; break; \ -+ case (HEADER_TYPE_SCTP): num = 13; break; \ -+ case (HEADER_TYPE_DCCP): num = 14; break; \ -+ case (HEADER_TYPE_USER_DEFINED_L4): num = 15; break; \ -+ case (HEADER_TYPE_USER_DEFINED_SHIM1): \ -+ case (HEADER_TYPE_USER_DEFINED_SHIM2): \ -+ case (HEADER_TYPE_MACSEC): \ -+ num = NO_HDR_NUM; break; \ -+ default: \ -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header for parser"));\ -+ num = ILLEGAL_HDR_NUM; break; \ -+} -+ -+#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); -+ -+/***********************************************************************/ -+/* 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 FmPcdKgGetPointedOwners(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_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 FmPcdPlcrGetPointedOwners(t_Handle h_FmPcd, uint16_t absoluteProfileId); -+void FmPcdPlcrUpatePointedOwner(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool add); -+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); -+uint32_t FmPcdCcGetNodeAddrOffset(t_Handle h_FmPcd, t_Handle h_Pointer); -+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); -+t_Error FmPcdCcModiyNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, uint16_t keyIndex,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_IpReassemblyManip, 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); -+uint32_t FmPcdManipGetRequiredAction (t_Handle h_Manip); -+ -+/***********************************************************************/ -+/* 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 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. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return TimeStamp period in nanoseconds. -+ -+ @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 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 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); -+#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 */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/inc/fm_hc.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/inc/fm_hc.h -new file mode 100644 -index 0000000..db2d60b ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/inc/fm_hc.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. -+ */ -+ -+ -+#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); -+t_Handle FmGcGetHcPortDevH(t_Handle h_FmHc); -+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 FmHcPcdCcIpTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcIpReassmTimeoutParams *p_CcIpReassmTimeoutParams, 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); -+ -+ -+ -+#endif /* __FM_HC_H */ -diff --git a/drivers/net/dpa/NetCommSw/Peripherals/FM/inc/fm_sp_common.h b/drivers/net/dpa/NetCommSw/Peripherals/FM/inc/fm_sp_common.h -new file mode 100644 -index 0000000..0675444 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/Peripherals/FM/inc/fm_sp_common.h -@@ -0,0 +1,154 @@ -+/* -+ * 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" -+ -+ -+/* 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 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 -+#define DEFAULT_FM_SP_dmaSwapData e_FM_DMA_NO_SWP -+#define DEFAULT_FM_SP_dmaIntContextCacheAttr e_FM_DMA_NO_STASH -+#define DEFAULT_FM_SP_dmaHeaderCacheAttr e_FM_DMA_NO_STASH -+#define DEFAULT_FM_SP_dmaScatterGatherCacheAttr e_FM_DMA_NO_STASH -+#define DEFAULT_FM_SP_dmaWriteOptimize TRUE -+#define DEFAULT_FM_SP_noScatherGather FALSE -+ -+/**************************************************************************//** -+ @Description Registers bit fields -+*//***************************************************************************/ -+#define FM_SP_EXT_BUF_POOL_EN_COUNTER 0x40000000 -+#define FM_SP_EXT_BUF_POOL_VALID 0x80000000 -+#define FM_SP_EXT_BUF_POOL_BACKUP 0x20000000 -+#define FM_SP_DMA_ATTR_WRITE_OPTIMIZE 0x00100000 -+#define FM_SP_SG_DISABLE 0x80000000 -+ -+/* shifts */ -+#define FM_SP_EXT_BUF_POOL_ID_SHIFT 16 -+#define FM_SP_POOL_DEP_NUM_OF_POOLS_SHIFT 16 -+#define FM_SP_EXT_BUF_MARG_START_SHIFT 16 -+#define FM_SP_EXT_BUF_MARG_END_SHIFT 0 -+#define FM_SP_DMA_ATTR_SWP_SHIFT 30 -+#define FM_SP_DMA_ATTR_IC_CACHE_SHIFT 28 -+#define FM_SP_DMA_ATTR_HDR_CACHE_SHIFT 26 -+#define FM_SP_DMA_ATTR_SG_CACHE_SHIFT 24 -+#define FM_SP_IC_TO_EXT_SHIFT 16 -+#define FM_SP_IC_FROM_INT_SHIFT 8 -+#define FM_SP_IC_SIZE_SHIFT 0 -+ -+ -+/**************************************************************************//** -+ @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 */ -diff --git a/drivers/net/dpa/NetCommSw/etc/Makefile b/drivers/net/dpa/NetCommSw/etc/Makefile -new file mode 100644 -index 0000000..ed10553 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/etc/Makefile -@@ -0,0 +1,11 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+ -+obj-y += fsl-ncsw-etc.o -+ -+fsl-ncsw-etc-objs := mm.o memcpy.o sprint.o list.o error.o -diff --git a/drivers/net/dpa/NetCommSw/etc/error.c b/drivers/net/dpa/NetCommSw/etc/error.c -new file mode 100644 -index 0000000..fead7f5 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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)) */ -diff --git a/drivers/net/dpa/NetCommSw/etc/list.c b/drivers/net/dpa/NetCommSw/etc/list.c -new file mode 100644 -index 0000000..2d044be ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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; -+} -diff --git a/drivers/net/dpa/NetCommSw/etc/memcpy.c b/drivers/net/dpa/NetCommSw/etc/memcpy.c -new file mode 100644 -index 0000000..02973e5 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/etc/memcpy.c -@@ -0,0 +1,601 @@ -+/* -+ * 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 * 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"); -+ } -+} -diff --git a/drivers/net/dpa/NetCommSw/etc/mm.c b/drivers/net/dpa/NetCommSw/etc/mm.c -new file mode 100644 -index 0000000..7b9d201 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/etc/mm.c -@@ -0,0 +1,1142 @@ -+/* -+ * 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); -+ } -+ 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 ) -+ 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; -+ -+ /* Initializes a new memory block */ -+ if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ -+ /* A busy list is empty */ -+ p_MM->busyBlocks = 0; -+ -+ /* 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) -+ 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); -+ 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); -+ 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); -+ 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"); -+ } -+} -diff --git a/drivers/net/dpa/NetCommSw/etc/mm.h b/drivers/net/dpa/NetCommSw/etc/mm.h -new file mode 100644 -index 0000000..43b2298 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/etc/sprint.c b/drivers/net/dpa/NetCommSw/etc/sprint.c -new file mode 100644 -index 0000000..46d2956 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/Peripherals/crc_mac_addr_ext.h b/drivers/net/dpa/NetCommSw/inc/Peripherals/crc_mac_addr_ext.h -new file mode 100644 -index 0000000..a84d563 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/Peripherals/dpaa_ext.h b/drivers/net/dpa/NetCommSw/inc/Peripherals/dpaa_ext.h -new file mode 100644 -index 0000000..c20a6eb ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/Peripherals/dpaa_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 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 { -+ volatile uint32_t id; /**< FD id */ -+ volatile uint32_t addrl; /**< Data Address */ -+ 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_DD(fd) ((((t_DpaaFD *)fd)->id & DPAA_FD_DD_MASK) >> (31-1)) /**< Macro to get FD DD field */ -+#define DPAA_FD_GET_PID(fd) (((((t_DpaaFD *)fd)->id & DPAA_FD_PID_MASK) >> (31-7)) | \ -+ ((((t_DpaaFD *)fd)->id & DPAA_FD_ELIODN_MASK) >> (31-19-6))) /**< Macro to get FD PID field */ -+#define DPAA_FD_GET_BPID(fd) ((((t_DpaaFD *)fd)->id & DPAA_FD_BPID_MASK) >> (31-15)) /**< Macro to get FD BPID field */ -+#define DPAA_FD_GET_ADDRH(fd) (((t_DpaaFD *)fd)->id & DPAA_FD_ADDRH_MASK) /**< 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_DD(fd,val) (((t_DpaaFD *)fd)->id = ((((t_DpaaFD *)fd)->id & ~DPAA_FD_DD_MASK) | (((val) << (31-1)) & DPAA_FD_DD_MASK ))) /**< Macro to set FD DD field */ -+ /**< Macro to set FD PID field or LIODN offset*/ -+#define DPAA_FD_SET_PID(fd,val) (((t_DpaaFD *)fd)->id = ((((t_DpaaFD *)fd)->id & ~(DPAA_FD_PID_MASK|DPAA_FD_ELIODN_MASK)) | ((((val) << (31-7)) & DPAA_FD_PID_MASK) | ((((val)>>6) << (31-19)) & DPAA_FD_ELIODN_MASK)))) -+#define DPAA_FD_SET_BPID(fd,val) (((t_DpaaFD *)fd)->id = ((((t_DpaaFD *)fd)->id & ~DPAA_FD_BPID_MASK) | (((val) << (31-15)) & DPAA_FD_BPID_MASK))) /**< Macro to set FD BPID field */ -+#define DPAA_FD_SET_ADDRH(fd,val) (((t_DpaaFD *)fd)->id = ((((t_DpaaFD *)fd)->id & ~DPAA_FD_ADDRH_MASK) | ((val) & DPAA_FD_ADDRH_MASK))) /**< 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__) && ... */ -+ -+/** @} */ /* end of DPAA_grp group */ -+ -+ -+#endif /* __DPAA_EXT_H */ -diff --git a/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_ext.h b/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_ext.h -new file mode 100644 -index 0000000..6acf50b ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_ext.h -@@ -0,0 +1,1681 @@ -+/* 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" -+ -+ -+/**************************************************************************//** -+ @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 */ -+/* @} */ -+ -+/**************************************************************************//** -+ @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, /**< No swap, transfer data as is.*/ -+ e_FM_DMA_SWP_PPC_LE, /**< The transferred data should be swapped -+ in PowerPc Little Endian mode. */ -+ e_FM_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 = 0, /**< Cacheable, no Allocate (No Stashing) */ -+ e_FM_DMA_STASH = 1 /**< 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 [64], -+ 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". */ -+ 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 FM_ConfigResetOnInit -+ -+ @Description Define whether to reset the FM before initialization. -+ Change the default configuration [FALSE]. -+ -+ @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_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 [major] -+ -+ @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 [e_FM_DMA_NO_CACHE_OR] -+ -+ @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 [TRUE] -+ -+ @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 [e_FM_DMA_AID_OUT_TNUM] -+ -+ @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 [1] -+ -+ @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 [32]. -+ -+ @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 [e_FM_DMA_DBG_NO_CNT]. -+ -+ @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 [FALSE]. -+ -+ @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 [e_FM_DMA_ERR_CATASTROPHIC]. -+ -+ @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 -+ [e_FM_CATASTROPHIC_ERR_STALL_PORT]. -+ -+ @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 -+ [FALSE]. -+ -+ @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 -+ [FALSE]. -+ 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 [FALSE]. -+ 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 TNUM's -+ in the QMI in the internal driver data base from its default -+ [0]. -+ -+ @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) -+*//***************************************************************************/ -+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: [0] -+ prsDispTh: [16] -+ plcrDispTh: [16] -+ kgDispTh: [16] -+ bmiDispTh: [16] -+ qmiEnqDispTh: [16] -+ qmiDeqDispTh: [16] -+ fmCtl1DispTh: [16] -+ fmCtl2DispTh: [16] -+ -+ -+ @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 [0] -+ -+ @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: [DMA_THRESH_MAX_BUF] -+ clearEmergency: [DMA_THRESH_MAX_BUF] -+ 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: [DMA_THRESH_MAX_COMMQ] -+ clearEmergency: [DMA_THRESH_MAX_COMMQ] -+ -+ @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: [DMA_THRESH_MAX_BUF] -+ clearEmergency: [DMA_THRESH_MAX_BUF] -+ 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 -+ [0]. -+ -+ @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); -+ -+/** @} */ /* 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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_mac_ext.h b/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_mac_ext.h -new file mode 100644 -index 0000000..614622e ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_mac_ext.h -@@ -0,0 +1,819 @@ -+/* -+ * 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_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 recieve). */ -+ 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 <10G-MAC 0> */ -+ 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 actuall speed; -+ i.e. user should use the FM_MAC_AdjustLink() routine to -+ provide accurate speed; -+ 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 [FALSE]. -+ -+ @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_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 [0xf000]. -+ -+ @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 - [0xf000] -+ 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(). -+ 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_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 only for dTSEC. -+ -+ @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 autonegotiation process. -+ When autonegegotiation process is invoked under traffic the -+ autonegotiation process between the internal TBI PHY and the -+ external PHY does not always complete succesfuly. Calling this -+ function will restart the autonegotiation process that will end -+ succesfuly. It is recomended to call this function after issuing -+ autoneg 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 */ -+ -+/**************************************************************************//** -+ @Function DtsecRestartTbiAN -+ -+ @Description Restart TBI autonegotiation for a given Dtsec TBI interface. -+ -+ @Param[in] h_Dtsec - A handle to the Dtsec. -+*//***************************************************************************/ -+void DtsecRestartTbiAN(t_Handle h_Dtsec); -+ -+#endif /* __FM_MAC_EXT_H */ -diff --git a/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_muram_ext.h b/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_muram_ext.h -new file mode 100644 -index 0000000..ef62c8e ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_pcd_ext.h b/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_pcd_ext.h -new file mode 100644 -index 0000000..f4dfd63 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_pcd_ext.h -@@ -0,0 +1,3650 @@ -+/* 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 a 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_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */ -+#define FM_PCD_PRS_SW_OFFSET 0x00000040 /**< Size of illegal addresses at the beginning -+ of the SW parser area */ -+#if (DPAA_VERSION >= 11) -+#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000240 /**< Number of bytes saved for patches */ -+#else -+#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 /**< Number of bytes saved for patches */ -+#endif /* (DPAA_VERSION >= 11) */ -+ -+#define FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at -+ the end of the SW parser area */ -+#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); -+ -+t_Handle FM_PCD_GetHcDevH(t_Handle h_FmPcd); -+ -+/**************************************************************************//** -+ @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. -+ [4]. -+ -+ @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. -+ [4]. -+ -+ @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 [disabled]. -+ -+ @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 -+ [0]. -+ -+ @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. */ -+ 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_MANIP_DSCP_VALUES 64 -+ -+#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). */ -+/* @} */ -+ -+#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 /**< Drop 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 */ -+#ifdef FM_CAPWAP_SUPPORT -+ e_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */ -+#endif /* 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_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 fields removal -+*//***************************************************************************/ -+typedef enum e_FmPcdManipHdrInsrtSpecificL2 { -+ e_FM_PCD_MANIP_HDR_INSRT_MPLS /**< Insert MPLS header (Unlimited MPLS labels) */ -+} e_FmPcdManipHdrInsrtSpecificL2; -+ -+/**************************************************************************//** -+ @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 */ -+} 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_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 */ -+#ifdef FM_CAPWAP_SUPPORT -+ e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */ -+#endif /* 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; -+ -+#ifdef 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 /* 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 */ -+} 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 */ -+} 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: - relevant only if FM_CAPWAP_SUPPORT define -+ 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. */ -+ 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 comittedInfoRate; /**< KBits/Second or Packets/Second */ -+ uint32_t comittedBurstSize; /**< Bytes/Packets */ -+ uint32_t peakOrAccessiveInfoRate; /**< KBits/Second or Packets/Second */ -+ uint32_t peakOrAccessiveBurstSize; /**< 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; -+ -+#ifdef 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 /* 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 { -+#ifdef 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 /* FM_CAPWAP_SUPPORT */ -+ 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's 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 */ -+ 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' 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. */ -+} t_FmPcdManipSpecialOffloadIPSecParams; -+ -+/**************************************************************************//** -+ @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 */ -+ } u; -+} t_FmPcdManipSpecialOffloadParams; -+ -+/**************************************************************************//** -+ @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 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 */ -+ } 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; -+ -+/**************************************************************************//** -+ @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 remove */ -+ } 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 */ -+#ifdef 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 /* 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;/**< FALSE to activate the parser a second time after -+ completing the manipulation on the frame */ -+} t_FmPcdManipHdrParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining fragmentation manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipFragParams { -+ e_NetHeaderType hdr; /**< Header selection */ -+ union { -+ 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 { -+ 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. */ -+#ifdef FM_CAPWAP_SUPPORT -+ bool fragOrReasm; /**< TRUE, if defined fragmentation/reassembly manipulation */ -+ t_FmPcdManipFragOrReasmParams fragOrReasmParams; /**< Parameters for fragmentation/reassembly manipulation, -+ relevant if fragOrReasm = TRUE */ -+#endif /* 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 */ -+ 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; -+ -+/**************************************************************************//** -+ @Description Structure for retrieving reassembly statistics -+*//***************************************************************************/ -+typedef struct t_FmPcdManipReassemStats { -+ union { -+ t_FmPcdManipReassemIpStats ipReassem; /**< Structure for IP reassembly statistics */ -+ } u; -+} t_FmPcdManipReassemStats; -+ -+/**************************************************************************//** -+ @Description Structure for retrieving fragmentation statistics -+*//***************************************************************************/ -+typedef struct t_FmPcdManipFragStats { -+ union { -+ t_FmPcdManipFragIpStats ipFrag; /**< Structure for IP fragmentation statistics */ -+ } 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) */ -+ -+#ifdef FM_CAPWAP_SUPPORT -+/**************************************************************************//** -+ @Description structure for defining statistics node -+*//***************************************************************************/ -+typedef struct t_FmPcdStatsParams { -+ e_FmPcdStatsType type; /**< type of statistics node */ -+} t_FmPcdStatsParams; -+#endif /* 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(). -+*//***************************************************************************/ -+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(). -+*//***************************************************************************/ -+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. -+*//***************************************************************************/ -+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(). -+*//***************************************************************************/ -+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. -+*//***************************************************************************/ -+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_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(). -+*//***************************************************************************/ -+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(). -+*//***************************************************************************/ -+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_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) */ -+ -+#ifdef 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 /* 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 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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_port_ext.h b/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_port_ext.h -new file mode 100644 -index 0000000..afa2cd9 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_port_ext.h -@@ -0,0 +1,2247 @@ -+/* 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 */ -+#ifdef FM_CAPWAP_SUPPORT -+ , e_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */ -+ , 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 /**< classification discard */ -+#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; -+ -+ -+ -+/**************************************************************************//** -+ @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: [FALSE] -+ 10G: [TRUE] -+ -+ 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 -+ [e_FM_PORT_DEQ_TYPE1]. -+ -+ 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 -+ [e_FM_PORT_DEQ_FULL_PREFETCH] -+ 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:[0x400]. -+ 10G:[0x1400]. -+ -+ 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_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] 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 -+ [0] -+ -+ 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 [4] -+ 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 = [FALSE] -+ -+ 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: -+ [FM_PORT_FRM_ERR_CLS_DISCARD]. -+ 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_FM_SP_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_FM_SP_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_FM_SP_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_FM_SP_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_FM_SP_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 [e_FM_PORT_COLOR_GREEN] -+ -+ 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 = [TRUE] -+ -+ 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 = [FALSE] -+ -+ 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:[128] -+ -+ @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:[16] -+ -+ @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 -+ [0, MEMORY_ATTR_CACHEABLE]. -+ -+ @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 [9600]. -+ 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 [0] -+ -+ 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: [1], -+ 10G port: [4] -+ -+ May be used for Tx 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 [5] -+ -+ 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 [BMI_MAX_FIFO_SIZE] -+ -+ 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 [BMI_MAX_FIFO_SIZE] -+ -+ 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; -+ -+ -+/**************************************************************************//** -+ @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; -+ -+ -+#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(). -+*//***************************************************************************/ -+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_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 improvments; 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_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 */ -+ 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; 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_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 */ -+ t_Handle h_IpReassemblyManip;/**< IP Reassembly manipulation */ -+} 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 */ -+ 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_PcdPrsModifyStartOffset -+ -+ @Description Runtime change of the parser start offset within the header. -+ The routine may not be called while port -+ receives packets using the PCD functionalities, therefore 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] p_FmPcdPrsStart A structure of parameters for defining the -+ start point for the parser. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(), FM_PORT_SetPCD() and FM_PORT_DetatchPCD(). -+*//***************************************************************************/ -+t_Error FM_PORT_PcdPrsModifyStartOffset (t_Handle h_FmPort, t_FmPcdPrsStart *p_FmPcdPrsStart); -+ -+ -+/** @} */ /* 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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_rtc_ext.h b/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_rtc_ext.h -new file mode 100644 -index 0000000..c8fa262 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_rtc_ext.h -@@ -0,0 +1,593 @@ -+/* -+ * 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" -+ -+ -+/**************************************************************************//** -+ -+ @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, /**< Active-high output polarity */ -+ e_FM_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, /**< Trigger on rising edge */ -+ e_FM_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, /**< external high precision timer reference clock */ -+ e_FM_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */ -+ e_FM_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 [1000]. -+ -+ @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 [FALSE] -+ -+ 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. [FALSE] -+ -+ 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. -+ [FALSE] -+ -+ @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. -+ [FALSE] -+ -+ @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. [0x00000002] -+ -+ @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. [e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH] -+ -+ @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. [e_FM_RTC_TRIGGER_ON_FALLING_EDGE] -+ -+ @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); -+ -+#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__ */ -diff --git a/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_vsp_ext.h b/drivers/net/dpa/NetCommSw/inc/Peripherals/fm_vsp_ext.h -new file mode 100644 -index 0000000..f9aed03 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/Peripherals/mii_acc_ext.h b/drivers/net/dpa/NetCommSw/inc/Peripherals/mii_acc_ext.h -new file mode 100644 -index 0000000..f635d3c ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/core_ext.h b/drivers/net/dpa/NetCommSw/inc/core_ext.h -new file mode 100644 -index 0000000..9cd5669 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/core_ext.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 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 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 */ -+ -+ -+/**************************************************************************//** -+ @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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/cores/e500v2_ext.h b/drivers/net/dpa/NetCommSw/inc/cores/e500v2_ext.h -new file mode 100644 -index 0000000..099c7b9 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/cores/e500v2_ext.h -@@ -0,0 +1,474 @@ -+/* -+ * 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 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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/cores/ppc_ext.h b/drivers/net/dpa/NetCommSw/inc/cores/ppc_ext.h -new file mode 100644 -index 0000000..9344b3a ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/ctype_ext.h b/drivers/net/dpa/NetCommSw/inc/ctype_ext.h -new file mode 100644 -index 0000000..e3d5d8d ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/ctype_ext.h -@@ -0,0 +1,94 @@ -+/* -+ * 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 __CTYPE_EXT_H -+#define __CTYPE_EXT_H -+ -+ -+#if defined(NCSW_LINUX) && defined(__KERNEL__) -+/* -+ * NOTE! This ctype does not handle EOF like the standard C -+ * library is required to. -+ */ -+ -+#define _U 0x01 /* upper */ -+#define _L 0x02 /* lower */ -+#define _D 0x04 /* digit */ -+#define _C 0x08 /* cntrl */ -+#define _P 0x10 /* punct */ -+#define _S 0x20 /* white space (space/lf/tab) */ -+#define _X 0x40 /* hex digit */ -+#define _SP 0x80 /* hard space (0x20) */ -+ -+extern unsigned char _ctype[]; -+ -+#define __ismask(x) (_ctype[(int)(unsigned char)(x)]) -+ -+#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0) -+#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0) -+#define iscntrl(c) ((__ismask(c)&(_C)) != 0) -+#define isdigit(c) ((__ismask(c)&(_D)) != 0) -+#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0) -+#define islower(c) ((__ismask(c)&(_L)) != 0) -+#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0) -+#define ispunct(c) ((__ismask(c)&(_P)) != 0) -+#define isspace(c) ((__ismask(c)&(_S)) != 0) -+#define isupper(c) ((__ismask(c)&(_U)) != 0) -+#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0) -+ -+#define isascii(c) (((unsigned char)(c))<=0x7f) -+#define toascii(c) (((unsigned char)(c))&0x7f) -+ -+static __inline__ unsigned char __tolower(unsigned char c) -+{ -+ if (isupper(c)) -+ c -= 'A'-'a'; -+ return c; -+} -+ -+static __inline__ unsigned char __toupper(unsigned char c) -+{ -+ if (islower(c)) -+ c -= 'a'-'A'; -+ return c; -+} -+ -+#define tolower(c) __tolower(c) -+#define toupper(c) __toupper(c) -+ -+#else -+#include -+#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */ -+ -+ -+#endif /* __CTYPE_EXT_H */ -diff --git a/drivers/net/dpa/NetCommSw/inc/ddr_std_ext.h b/drivers/net/dpa/NetCommSw/inc/ddr_std_ext.h -new file mode 100644 -index 0000000..4e94922 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/ddr_std_ext.h -@@ -0,0 +1,75 @@ -+/* -+ * 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_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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/debug_ext.h b/drivers/net/dpa/NetCommSw/inc/debug_ext.h -new file mode 100644 -index 0000000..00ae748 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/debug_ext.h -@@ -0,0 +1,265 @@ -+/* -+ * 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_MAX_STR 64 -+ -+ -+#define _CREATE_DUMP_SUBSTR(phrase) \ -+ dumpTmpLevel = 0; dumpSubStr[0] = '\0'; \ -+ sprintf(dumpTmpStr, "%s", #phrase); \ -+ p_DumpToken = strtok(dumpTmpStr, (dumpIsArr[0] ? "[" : ".")); \ -+ while (p_DumpToken != NULL) \ -+ { \ -+ strcat(dumpSubStr, p_DumpToken); \ -+ if (dumpIsArr[dumpTmpLevel]) \ -+ { \ -+ strcat(dumpSubStr, dumpIdxStr[dumpTmpLevel]); \ -+ p_DumpToken = strtok(NULL, "."); \ -+ } \ -+ if ((p_DumpToken = strtok(NULL, (dumpIsArr[++dumpTmpLevel] ? "[" : "."))) != 0) \ -+ strcat(dumpSubStr, "."); \ -+ }\ -+ -+ -+/**************************************************************************//** -+ @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][6] = { "", }; \ -+ char dumpSubStr[DUMP_MAX_STR] = ""; \ -+ char dumpTmpStr[DUMP_MAX_STR] = ""; \ -+ char *p_DumpToken = NULL; \ -+ int dumpArrIdx = 0, dumpArrSize = 0, dumpVarSize = 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(dumpVarSize); \ -+ 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) && sprintf(dumpIdxStr[dumpLevel-1], "[%d]", idx); \ -+ idx++, ((idx < cnt) || ((dumpIsArr[--dumpLevel] = 0) == 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); \ -+ dumpVarSize = sizeof((st)->phrase); \ -+ switch (dumpVarSize) \ -+ { \ -+ case 1: DUMP_Print("0x%010llX: 0x%02x%14s\t%s\r\n", \ -+ physAddr, GET_UINT8(*(uint8_t*)addr), "", dumpSubStr); break; \ -+ case 2: DUMP_Print("0x%010llX: 0x%04x%12s\t%s\r\n", \ -+ physAddr, GET_UINT16(*(uint16_t*)addr), "", dumpSubStr); break; \ -+ case 4: DUMP_Print("0x%010llX: 0x%08x%8s\t%s\r\n", \ -+ physAddr, GET_UINT32(*(uint32_t*)addr), "", dumpSubStr); break; \ -+ case 8: DUMP_Print("0x%010llX: 0x%016llx\t%s\r\n", \ -+ physAddr, GET_UINT64(*(uint64_t*)addr), dumpSubStr); break; \ -+ default: DUMP_Print("Bad size %d (" #st "->" #phrase ")\r\n", dumpVarSize); \ -+ } \ -+ } 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); \ -+ dumpVarSize = sizeof((st)->phrase[0]); \ -+ switch (dumpVarSize) \ -+ { \ -+ case 1: \ -+ for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \ -+ physAddr = XX_VirtToPhys((void *)&((st)->phrase[dumpArrIdx])); \ -+ DUMP_Print("0x%010llX: 0x%02x%14s\t%s[%d]\r\n", \ -+ physAddr, GET_UINT8((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \ -+ } break; \ -+ case 2: \ -+ for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \ -+ physAddr = XX_VirtToPhys((void *)&((st)->phrase[dumpArrIdx])); \ -+ DUMP_Print("0x%010llX: 0x%04x%12s\t%s[%d]\r\n", \ -+ physAddr, GET_UINT16((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \ -+ } break; \ -+ case 4: \ -+ 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); \ -+ } break; \ -+ case 8: \ -+ for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \ -+ physAddr = XX_VirtToPhys((void *)&((st)->phrase[dumpArrIdx])); \ -+ DUMP_Print("0x%010llX: 0x%016llx\t%s[%d]\r\n", \ -+ physAddr, GET_UINT64((st)->phrase[dumpArrIdx]), dumpSubStr, dumpArrIdx); \ -+ } break; \ -+ default: DUMP_Print("Bad size %d (" #st "->" #phrase "[0])\r\n", dumpVarSize); \ -+ } \ -+ } while (0) -+ -+ -+#endif /* DEBUG_ERRORS > 0 */ -+ -+ -+/** @} */ /* end of dump_id group */ -+/** @} */ /* end of gen_id group */ -+ -+ -+#endif /* __DEBUG_EXT_H */ -diff --git a/drivers/net/dpa/NetCommSw/inc/endian_ext.h b/drivers/net/dpa/NetCommSw/inc/endian_ext.h -new file mode 100644 -index 0000000..252f89b ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/endian_ext.h -@@ -0,0 +1,446 @@ -+/* -+ * 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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/enet_ext.h b/drivers/net/dpa/NetCommSw/inc/enet_ext.h -new file mode 100644 -index 0000000..c6b9071 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/enet_ext.h -@@ -0,0 +1,203 @@ -+/* 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_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_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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/error_ext.h b/drivers/net/dpa/NetCommSw/inc/error_ext.h -new file mode 100644 -index 0000000..bbd6743 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/error_ext.h -@@ -0,0 +1,527 @@ -+/* 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 CORE_GetId(), __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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/etc/list_ext.h b/drivers/net/dpa/NetCommSw/inc/etc/list_ext.h -new file mode 100644 -index 0000000..ee6b9f2 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/etc/mem_ext.h b/drivers/net/dpa/NetCommSw/inc/etc/mem_ext.h -new file mode 100644 -index 0000000..d0565d4 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/etc/memcpy_ext.h b/drivers/net/dpa/NetCommSw/inc/etc/memcpy_ext.h -new file mode 100644 -index 0000000..cc5bb72 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/etc/memcpy_ext.h -@@ -0,0 +1,174 @@ -+/* 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); -+ -+/** @} */ /* end of mem_cpy group */ -+/** @} */ /* end of etc_id group */ -+ -+ -+#endif /* __MEMCPY_EXT_H */ -diff --git a/drivers/net/dpa/NetCommSw/inc/etc/mm_ext.h b/drivers/net/dpa/NetCommSw/inc/etc/mm_ext.h -new file mode 100644 -index 0000000..fa7c85e ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/etc/sprint_ext.h b/drivers/net/dpa/NetCommSw/inc/etc/sprint_ext.h -new file mode 100644 -index 0000000..52f7a9d ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/flib/common/arch/ppc_access.h b/drivers/net/dpa/NetCommSw/inc/flib/common/arch/ppc_access.h -new file mode 100644 -index 0000000..c3953bb ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/flib/common/arch/ppc_access.h -@@ -0,0 +1,36 @@ -+/* -+ * 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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/flib/common/general.h b/drivers/net/dpa/NetCommSw/inc/flib/common/general.h -new file mode 100644 -index 0000000..8150e01 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/flib/common/general.h -@@ -0,0 +1,51 @@ -+/* -+ * 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); -+ -+ -+#define iowrite32be(val, addr) WRITE_UINT32(*addr, val) -+#define ioread32be(addr) GET_UINT32(*addr) -+ -+#define ether_crc(len, addr) get_mac_addr_crc(*(uint64_t *)(addr)>>16) -+ -+ -+#endif /* __GENERAL_H */ -diff --git a/drivers/net/dpa/NetCommSw/inc/flib/fsl_enet.h b/drivers/net/dpa/NetCommSw/inc/flib/fsl_enet.h -new file mode 100644 -index 0000000..bb0dea9 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/flib/fsl_enet.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 __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_10000 = 10000 /**< 10000 Mbps = 10 Gbps */ -+}; -+ -+enum mac_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 -+}; -+ -+ -+#endif /* __FSL_ENET_H */ -diff --git a/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_dtsec.h b/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_dtsec.h -new file mode 100644 -index 0000000..55527c1 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_dtsec.h -@@ -0,0 +1,1060 @@ -+/* -+ * 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: -+ * -+ * - 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. -+ * -+ * - dtsec_init() - Applies the configuration on dTSEC hardware. Note that -+ * dTSEC is initialized while both Tx and Rx are disabled. -+ * -+ * - dtsec_set_mac_address() - Set the station address (mac address). -+ * This is used by dTSEC to match against received packets. -+ * -+ * - 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 dtsec_stop_tx() and 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 -+ * 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 dtsec_start_tx() and -+ * 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 dtsec_get_event() function. -+ * To configure the interrupt mask use dtsec_enable_interrupt() and -+ * dtsec_disable_interrupt() functions. -+ * After servicing a dTSEC interrupt use 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 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 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 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 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 -+ -+/* 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 -+}; -+ -+ -+/** -+ * 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 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 -+ * dtsec_init() function. A default set of configuration values can be obtained -+ * by calling 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; -+}; -+ -+ -+/** -+ * 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 -+ * dtsec_init(), if specific configuration needs to be applied. -+ */ -+void dtsec_defconfig(struct dtsec_cfg *cfg); -+ -+/** -+ * 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, -+ * 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 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); -+ -+/** -+ * 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 dtsec_get_revision(struct dtsec_regs *regs); -+ -+/** -+ * 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 dtsec_set_uc_promisc() and -+ * dtsec_set_mc_promisc() to disable filtering for both unicast and multicast -+ * addresses. -+ */ -+void dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable); -+ -+/** -+ * 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 dtsec_init() and whenever the link speed changes -+ * (for instance following PHY auto-negociation). -+ * -+ * Returns: 0 if successful, an error code otherwise. -+ */ -+int dtsec_adjust_link(struct dtsec_regs *regs, -+ enum enet_interface iface_mode, -+ enum enet_speed speed, bool full_dx); -+ -+/** -+ * 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 dtsec_set_tbi_phy_addr(struct dtsec_regs *regs, -+ uint8_t addr); -+ -+/** -+ * 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 dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx); -+ -+/** -+ * 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 dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx); -+ -+/** -+ * 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 dtsec_init(). While promiscuous mode is disabled dTSEC will match -+ * the destination address of received unicast frames against this address. -+ */ -+void dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *macaddr); -+ -+/** -+ * dtsec_get_mac_address() - Query MAC station address -+ * @regs: Pointer to dTSEC register block -+ * @macaddr: MAC address array -+ */ -+void dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr); -+ -+/** -+ * 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 dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length); -+ -+ -+/** -+ * 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 dtsec_get_max_frame_len(struct dtsec_regs *regs); -+ -+ -+/** -+ * 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 dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en); -+ -+/** -+ * dtsec_set_tx_pause_time() - 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 dtsec_set_tx_pause_time(struct dtsec_regs *regs, uint16_t time); -+ -+/** -+ * 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 dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask); -+ -+/** -+ * 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 dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask); -+/** -+ * 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 dtsec_get_interrupt_mask(struct dtsec_regs *regs); -+ -+void dtsec_clear_addr_in_paddr (struct dtsec_regs *regs, -+ uint8_t paddr_num); -+ -+void dtsec_add_addr_in_paddr (struct dtsec_regs *regs, -+ uint64_t addr, -+ uint8_t paddr_num); -+ -+void dtsec_enable_tmr_interrupt (struct dtsec_regs *regs); -+ -+void dtsec_disable_tmr_interrupt(struct dtsec_regs *regs); -+ -+/** -+ * 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 dtsec_enable_interrupt(). -+ */ -+void dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask); -+ -+/** -+ * 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 dtsec_disable_interrupt(). -+ */ -+void dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask); -+ -+/** -+ * 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 dtsec_set_ts(struct dtsec_regs *regs, bool en); -+ -+/** -+ * 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 dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable); -+ -+/** -+ * 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 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 dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, bool ucast); -+ -+/** -+ * dtsec_set_mc_promisc() - Set multicast promiscous mode -+ * @regs: Pointer to dTSEC register block -+ * @enable: Enable multicast promiscous mode -+ * -+ * Call this to enable/disable L2 address filtering for multicast packets. -+ */ -+void dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable); -+ -+/* statistics APIs */ -+ -+/** -+ * 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 dtsec_set_stat_level(struct dtsec_regs *regs, enum mac_stat_level level); -+ -+/** -+ * dtsec_reset_stat() - Completely resets all dTSEC HW counters -+ * @regs: Pointer to dTSEC register block -+ */ -+void dtsec_reset_stat(struct dtsec_regs *regs); -+ -+/** -+ * 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 dtsec_get_clear_carry_regs(struct dtsec_regs *regs, -+ uint32_t *car1, uint32_t *car2); -+ -+uint32_t dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs); -+ -+uint32_t dtsec_get_stat_counter(struct dtsec_regs *regs, -+ enum dtsec_stat_counters reg_name); -+ -+void dtsec_start_tx(struct dtsec_regs *regs); -+void dtsec_start_rx(struct dtsec_regs *regs); -+void dtsec_stop_rx(struct dtsec_regs *regs); -+void dtsec_stop_tx(struct dtsec_regs *regs); -+uint32_t dtsec_get_rctrl(struct dtsec_regs *regs); -+ -+#endif /* __FSL_FMAN_DTSEC_H */ -diff --git a/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_kg.h b/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_kg.h -new file mode 100644 -index 0000000..dd981bb ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_memac.h b/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_memac.h -new file mode 100644 -index 0000000..5cf48c7 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_memac.h -@@ -0,0 +1,381 @@ -+/* -+ * 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 */ -+ -+/* 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 -+ -+/* 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 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 detec indication */ -+#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_IMASKS \ -+ ((uint32_t)(MEMAC_IMASK_MGI | \ -+ MEMAC_IMASK_TECC_ER | \ -+ MEMAC_IMASK_RECC_ER)) -+ -+#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_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) */ -+ -+#define MEMAC_EVENTS_MASK \ -+ ((uint32_t)(MEMAC_IEVNT_PCS | \ -+ MEMAC_IEVNT_AN | \ -+ MEMAC_IEVNT_LT | \ -+ MEMAC_IEVNT_MGI | \ -+ MEMAC_IEVNT_RX_FIFO_OVFL | \ -+ MEMAC_IEVNT_TX_FIFO_UNFL | \ -+ MEMAC_IEVNT_TX_FIFO_OVFL | \ -+ MEMAC_IEVNT_TX_ECC_ER | \ -+ MEMAC_IEVNT_RX_ECC_ER | \ -+ MEMAC_IEVNT_LI_FAULT | \ -+ MEMAC_IEVNT_RX_EMPTY | \ -+ MEMAC_IEVNT_TX_EMPTY | \ -+ MEMAC_IEVNT_RX_LOWP | \ -+ MEMAC_IEVNT_PHY_LOS | \ -+ MEMAC_IEVNT_REM_FAULT | \ -+ MEMAC_IEVNT_LOC_FAULT)) -+ -+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[5]; -+ 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; -+ uint16_t max_frame_length; -+ uint16_t pause_quanta; -+ uint32_t tx_ipg_length; -+}; -+ -+/** -+ * 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 -+ * memac_init(), if specific configuration needs to be applied. -+ */ -+void memac_defconfig(struct memac_cfg *cfg); -+void memac_set_promiscuous(struct memac_regs *regs, bool val); -+void memac_hardware_add_addr_in_paddr(struct memac_regs *regs, -+ uint8_t *adr, -+ uint8_t paddr_num); -+void memac_hardware_clear_addr_in_paddr(struct memac_regs *regs, -+ uint8_t paddr_num); -+void memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx); -+void memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx); -+uint64_t memac_get_counter(struct memac_regs *regs, -+ enum memac_counters reg_name); -+void memac_set_tx_pause_frames(struct memac_regs *regs, -+ uint8_t priority, -+ uint16_t pauseTime, -+ uint16_t threshTime); -+uint16_t memac_get_max_frame_length(struct memac_regs *regs); -+void memac_init(struct memac_regs *regs, -+ struct memac_cfg *cfg, -+ enum enet_interface enet_interface, -+ enum enet_speed enet_speed, -+ uint32_t exceptions); -+void memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable); -+void memac_reset_counter(struct memac_regs *regs); -+void memac_reset(struct memac_regs *regs); -+void memac_set_hash_table(struct memac_regs *regs, uint32_t val); -+void memac_set_rx_ignore_pause_frames(struct memac_regs *regs,bool enable); -+void memac_set_loopback(struct memac_regs *regs, bool enable); -+void memac_reset_counter(struct memac_regs *regs); -+uint32_t memac_get_event(struct memac_regs *regs, uint32_t ev_mask); -+void memac_ack_event(struct memac_regs *regs, uint32_t ev_mask); -+uint32_t memac_get_interrupt_mask(struct memac_regs *regs); -+ -+ -+#endif /*__FSL_FMAN_MEMAC_H*/ -diff --git a/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_prs.h b/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_prs.h -new file mode 100644 -index 0000000..30d2ecf ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_prs.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. -+ */ -+ -+#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); -+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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_tgec.h b/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_tgec.h -new file mode 100644 -index 0000000..2505888 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/flib/fsl_fman_tgec.h -@@ -0,0 +1,472 @@ -+/* -+ * 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 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 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 -+ * tgec_init() function. A default set of configuration values can be obtained -+ * by calling 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 tgec_set_mac_address(struct tgec_regs *regs, uint8_t *macaddr); -+ -+/** -+ * tgec_reset_stat() - Completely resets all TGEC HW counters -+ * @regs: Pointer to TGEC register block -+ */ -+void tgec_reset_stat(struct tgec_regs *regs); -+ -+/** -+ * 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 tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name); -+ -+void tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx); -+void tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx); -+void tgec_set_promiscuous(struct tgec_regs *regs, bool val); -+ -+/** -+ * 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 tgec_set_hash_table(struct tgec_regs *regs, uint32_t value); -+ -+/** -+ * tgec_tx_mac_pause() - 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 tgec_tx_mac_pause(struct tgec_regs *regs, uint16_t pause_time); -+ -+/** -+ * tgec_rx_ignore_mac_pause() - 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 tgec_rx_ignore_mac_pause(struct tgec_regs *regs, bool en); -+ -+/** -+ * 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 tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en); -+ -+uint32_t tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask); -+void tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask); -+uint32_t tgec_get_interrupt_mask(struct tgec_regs *regs); -+ -+ -+/** -+ * 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 tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *addr_ptr); -+void tgec_clear_addr_in_paddr(struct tgec_regs *regs); -+uint32_t tgec_get_revision(struct tgec_regs *regs); -+void tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask); -+void tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask); -+ -+/** -+ * tgec_get_max_frame_len() - Returns the maximum frame length value -+ * @regs: Pointer to TGEC register block -+ */ -+ -+uint16_t tgec_get_max_frame_len(struct tgec_regs *regs); -+ -+/** -+ * tgec_defconfig() - Initialize the main tgec configuration parameters -+ * @cfg: Pointer to tgec_cfg structure -+ * -+ * This routine determines the values of the tgec_cfg structure members. -+ * This structure represents the initial parameters which the tgec controller -+ * will be initialized with later when calling the tgec_init function. -+ */ -+ -+void tgec_defconfig(struct tgec_cfg *cfg); -+ -+/** -+ * 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 tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg, -+ uint32_t exception_mask); -+ -+ -+void tgec_fm_tx_fifo_corruption_errata_10gmac_a007(struct tgec_regs *regs); -+ -+ -+#endif /* __FSL_FMAN_TGEC_H */ -diff --git a/drivers/net/dpa/NetCommSw/inc/integrations/P1023/dpaa_integration_ext.h b/drivers/net/dpa/NetCommSw/inc/integrations/P1023/dpaa_integration_ext.h -new file mode 100644 -index 0000000..9864217 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/integrations/P1023/dpaa_integration_ext.h -@@ -0,0 +1,234 @@ -+/* -+ * 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_RX_PORTS 2 -+#define FM_MAX_NUM_OF_10G_RX_PORTS 0 -+#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 2 -+#define FM_MAX_NUM_OF_10G_TX_PORTS 0 -+#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_OH_PORTS 5 -+#define FM_MAX_NUM_OF_1G_MACS (FM_MAX_NUM_OF_1G_RX_PORTS) -+#define FM_MAX_NUM_OF_10G_MACS (FM_MAX_NUM_OF_10G_RX_PORTS) -+#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS+FM_MAX_NUM_OF_10G_MACS) -+#define FM_MAX_NUM_OF_MACSECS 1 -+ -+#define FM_MACSEC_SUPPORT -+#define FM_DISABLE_SEC_ERRORS -+ -+#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 (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. */ -+ -+/* 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 -+*//***************************************************************************/ -+ -+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;} -+ -+ -+/* 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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/integrations/P1023/part_ext.h b/drivers/net/dpa/NetCommSw/inc/integrations/P1023/part_ext.h -new file mode 100644 -index 0000000..6814d5f ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/integrations/P1023/part_integration_ext.h b/drivers/net/dpa/NetCommSw/inc/integrations/P1023/part_integration_ext.h -new file mode 100644 -index 0000000..e838283 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h b/drivers/net/dpa/NetCommSw/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h -new file mode 100644 -index 0000000..a655882 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h -@@ -0,0 +1,274 @@ -+/* 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 -+ -+/**************************************************************************//** -+ @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_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_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 ( 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 -+ -+#endif /* __DPAA_INTEGRATION_EXT_H */ -diff --git a/drivers/net/dpa/NetCommSw/inc/integrations/P3040_P4080_P5020/part_ext.h b/drivers/net/dpa/NetCommSw/inc/integrations/P3040_P4080_P5020/part_ext.h -new file mode 100644 -index 0000000..512f0ba ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/integrations/P3040_P4080_P5020/part_integration_ext.h b/drivers/net/dpa/NetCommSw/inc/integrations/P3040_P4080_P5020/part_integration_ext.h -new file mode 100644 -index 0000000..03c59b8 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/integrations/T4240/dpaa_integration_ext.h b/drivers/net/dpa/NetCommSw/inc/integrations/T4240/dpaa_integration_ext.h -new file mode 100644 -index 0000000..641d6c8 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/integrations/T4240/dpaa_integration_ext.h -@@ -0,0 +1,274 @@ -+/* -+ * 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 ( 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 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 /**< 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 48 -+ -+/* 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 -+ -+/* FM errata */ -+#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 -+#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 -+ -+#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 */ -+ -+/***************************************************************************** -+ 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 */ -+ -+ -+#endif /* __DPAA_INTEGRATION_EXT_H */ -diff --git a/drivers/net/dpa/NetCommSw/inc/integrations/T4240/part_ext.h b/drivers/net/dpa/NetCommSw/inc/integrations/T4240/part_ext.h -new file mode 100644 -index 0000000..0d62dd1 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/integrations/T4240/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/integrations/T4240/part_integration_ext.h b/drivers/net/dpa/NetCommSw/inc/integrations/T4240/part_integration_ext.h -new file mode 100644 -index 0000000..3254c76 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/integrations/T4240/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/math_ext.h b/drivers/net/dpa/NetCommSw/inc/math_ext.h -new file mode 100644 -index 0000000..bff428d ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/math_ext.h -@@ -0,0 +1,99 @@ -+/* -+ * 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 -+ -+#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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/ncsw_ext.h b/drivers/net/dpa/NetCommSw/inc/ncsw_ext.h -new file mode 100644 -index 0000000..c3341cd ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/ncsw_ext.h -@@ -0,0 +1,432 @@ -+/* 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 -+#define COPY_BLOCK Mem2IOCpy32 -+ -+#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) (X=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 */ -+ -+#undef NO_IRQ -+#define NO_IRQ (-1) -+#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) (((x)/(y)) + ((((((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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/net_ext.h b/drivers/net/dpa/NetCommSw/inc/net_ext.h -new file mode 100644 -index 0000000..8f3bc36 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/std_ext.h b/drivers/net/dpa/NetCommSw/inc/std_ext.h -new file mode 100644 -index 0000000..d91e6fd ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/stdarg_ext.h b/drivers/net/dpa/NetCommSw/inc/stdarg_ext.h -new file mode 100644 -index 0000000..3c8bb0a ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/stdlib_ext.h b/drivers/net/dpa/NetCommSw/inc/stdlib_ext.h -new file mode 100644 -index 0000000..a47860c ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/string_ext.h b/drivers/net/dpa/NetCommSw/inc/string_ext.h -new file mode 100644 -index 0000000..a5c6c7e ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/inc/types_ext.h b/drivers/net/dpa/NetCommSw/inc/types_ext.h -new file mode 100644 -index 0000000..fd900e2 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/inc/types_ext.h -@@ -0,0 +1,104 @@ -+/* 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__) */ -+ -+static __inline__ void TypesChecker(void) -+{ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ _Packed struct strct { -+ __volatile__ int vi; -+ } _PackedType; -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ size_t size = 0; -+ bool tr = TRUE, fls = FALSE; -+ struct strct *p_Struct = NULL; -+ physAddress_t addr = 0x100; -+ -+ tr = fls; -+ p_Struct = p_Struct; -+ size++; -+ if (tr) size++; -+ -+ WRITE_UINT8(*((uint8_t*)((size_t)(addr))), -+ GET_UINT8(*((uint8_t*)((size_t)(addr))))); -+ -+ WRITE_UINT8(*((uint8_t*)((size_t)(UINT8_MAX))), -+ GET_UINT8(*((uint8_t*)((size_t)(UINT8_MAX))))); -+ WRITE_UINT16(*((uint16_t*)((size_t)(UINT16_MAX))), -+ GET_UINT16(*((uint16_t*)((size_t)(UINT16_MAX))))); -+ WRITE_UINT32(*((uint32_t*)((size_t)(UINT32_MAX))), -+ GET_UINT32(*((uint32_t*)((size_t)(UINT32_MAX))))); -+ WRITE_UINT64(*((uint64_t*)((size_t)(UINT64_MAX))), -+ GET_UINT64(*((uint64_t*)((size_t)(UINT64_MAX))))); -+ WRITE_UINT8(*((uint8_t*)((size_t)(INT8_MAX))), -+ GET_UINT8(*((uint8_t*)((size_t)(INT8_MIN))))); -+ WRITE_UINT16(*((uint16_t*)((size_t)(INT16_MAX))), -+ GET_UINT16(*((uint16_t*)((size_t)(INT16_MIN))))); -+ WRITE_UINT32(*((uint32_t*)((size_t)(INT32_MAX))), -+ GET_UINT32(*((uint32_t*)((size_t)(INT32_MIN))))); -+ WRITE_UINT64(*((uint64_t*)((size_t)(INT64_MAX))), -+ GET_UINT64(*((uint64_t*)((size_t)(INT64_MIN))))); -+} -+ -+#endif /* __TYPES_EXT_H */ -diff --git a/drivers/net/dpa/NetCommSw/inc/xx_common.h b/drivers/net/dpa/NetCommSw/inc/xx_common.h -new file mode 100644 -index 0000000..1c45177 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 -+ -+#endif /* __XX_COMMON_H */ -diff --git a/drivers/net/dpa/NetCommSw/inc/xx_ext.h b/drivers/net/dpa/NetCommSw/inc/xx_ext.h -new file mode 100644 -index 0000000..21b62d0 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/ncsw_config.mk b/drivers/net/dpa/NetCommSw/ncsw_config.mk -new file mode 100644 -index 0000000..0f025f5 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/ncsw_config.mk -@@ -0,0 +1,41 @@ -+# -+# Makefile config for the Freescale NetcommSW -+# -+NET_DPA = $(srctree)/drivers/net -+DRV_DPA = $(srctree)/drivers/net/dpa -+NCSW = $(srctree)/drivers/net/dpa/NetCommSw -+ -+ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y") -+EXTRA_CFLAGS +=-include $(NCSW)/p3040_4080_5020_dflags.h -+endif -+ifeq ("$(CONFIG_FMAN_P1023)", "y") -+EXTRA_CFLAGS +=-include $(NCSW)/p1023_dflags.h -+endif -+ifdef CONFIG_FMAN_T4240 -+EXTRA_CFLAGS +=-include $(NCSW)/t4240_dflags.h -+endif -+ -+EXTRA_CFLAGS += -I$(DRV_DPA)/ -+EXTRA_CFLAGS += -I$(NCSW)/inc -+EXTRA_CFLAGS += -I$(NCSW)/inc/cores -+EXTRA_CFLAGS += -I$(NCSW)/inc/etc -+EXTRA_CFLAGS += -I$(NCSW)/inc/Peripherals -+EXTRA_CFLAGS += -I$(NCSW)/inc/flib -+ -+ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y") -+EXTRA_CFLAGS += -I$(NCSW)/inc/integrations/P3040_P4080_P5020 -+endif -+ifeq ("$(CONFIG_FMAN_P1023)", "y") -+EXTRA_CFLAGS += -I$(NCSW)/inc/integrations/P1023 -+endif -+ifdef CONFIG_FMAN_T4240 -+EXTRA_CFLAGS += -I$(NCSW)/inc/integrations/T4240 -+endif -+ -+EXTRA_CFLAGS += -I$(NCSW)/src/inc -+EXTRA_CFLAGS += -I$(NCSW)/src/inc/system -+EXTRA_CFLAGS += -I$(NCSW)/src/inc/wrapper -+EXTRA_CFLAGS += -I$(NCSW)/src/inc/xx -+EXTRA_CFLAGS += -I$(srctree)/include/linux/fmd -+EXTRA_CFLAGS += -I$(srctree)/include/linux/fmd/Peripherals -+EXTRA_CFLAGS += -I$(srctree)/include/linux/fmd/integrations -diff --git a/drivers/net/dpa/NetCommSw/p1023_dflags.h b/drivers/net/dpa/NetCommSw/p1023_dflags.h -new file mode 100644 -index 0000000..b48819d ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/p3040_4080_5020_dflags.h b/drivers/net/dpa/NetCommSw/p3040_4080_5020_dflags.h -new file mode 100644 -index 0000000..7438974 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/src/Makefile b/drivers/net/dpa/NetCommSw/src/Makefile -new file mode 100644 -index 0000000..e02b6fa ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/Makefile -@@ -0,0 +1,11 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+# -+obj-y += system/ -+obj-y += wrapper/ -+obj-y += xx/ -diff --git a/drivers/net/dpa/NetCommSw/src/inc/system/sys_ext.h b/drivers/net/dpa/NetCommSw/src/inc/system/sys_ext.h -new file mode 100644 -index 0000000..20f27d2 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/src/inc/system/sys_io_ext.h b/drivers/net/dpa/NetCommSw/src/inc/system/sys_io_ext.h -new file mode 100644 -index 0000000..d6aa9d4 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/src/inc/types_linux.h b/drivers/net/dpa/NetCommSw/src/inc/types_linux.h -new file mode 100644 -index 0000000..ac15d66 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/inc/types_linux.h -@@ -0,0 +1,200 @@ -+/* -+ * 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 -+ -+#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 */ -+/************************/ -+#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__ */ -diff --git a/drivers/net/dpa/NetCommSw/src/inc/wrapper/fsl_fman.h b/drivers/net/dpa/NetCommSw/src/inc/wrapper/fsl_fman.h -new file mode 100644 -index 0000000..6afde38 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/inc/wrapper/fsl_fman.h -@@ -0,0 +1,301 @@ -+/* -+ * 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 fsl_fman.h -+ -+ @Description Linux internal kernel API -+*//***************************************************************************/ -+ -+#ifndef __FSL_FMAN_H -+#define __FSL_FMAN_H -+ -+#include -+#include /* struct device */ -+#include /* struct qman_fq */ -+#include "dpaa_integration_ext.h" -+#include "fm_port_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 A structure .., -+*//***************************************************************************/ -+struct fm; -+ -+/**************************************************************************//** -+ @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 */ -+}; -+ -+/**************************************************************************//** -+ @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_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. -+*//***************************************************************************/ -+int 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. -+*//***************************************************************************/ -+void fm_port_disable(struct fm_port *port); -+ -+void *fm_port_get_handle(struct fm_port *port); -+ -+/**************************************************************************//** -+ @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); -+ -+/** @} */ /* end of FM_LnxKern_ctrl_grp group */ -+/** @} */ /* end of FM_LnxKern_grp group */ -+ -+ -+#endif /* __FSL_FMAN_H */ -diff --git a/drivers/net/dpa/NetCommSw/src/inc/wrapper/fsl_fman_test.h b/drivers/net/dpa/NetCommSw/src/inc/wrapper/fsl_fman_test.h -new file mode 100644 -index 0000000..0466a47 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/src/inc/wrapper/lnxwrp_fm_ext.h b/drivers/net/dpa/NetCommSw/src/inc/wrapper/lnxwrp_fm_ext.h -new file mode 100644 -index 0000000..8dda657 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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_FMAN_TEST -+t_Handle LNXWRP_FM_TEST_Init(void); -+t_Error LNXWRP_FM_TEST_Free(t_Handle h_FmTestLnxWrp); -+#endif /* CONFIG_FSL_FMAN_TEST */ -+ -+/** @} */ /* end of FM_LnxKern_init_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group FM_LnxKern_ctrl_grp Control Unit -+ -+ @Description Control Unit -+ -+ TODO -+ @{ -+*//***************************************************************************/ -+ -+#include "fsl_fman.h" -+ -+/** @} */ /* end of FM_LnxKern_ctrl_grp group */ -+/** @} */ /* end of FM_LnxKern_grp group */ -+ -+ -+#endif /* __LNXWRP_FM_EXT_H */ -diff --git a/drivers/net/dpa/NetCommSw/src/inc/xx/xx.h b/drivers/net/dpa/NetCommSw/src/inc/xx/xx.h -new file mode 100644 -index 0000000..b183c86 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 */ -diff --git a/drivers/net/dpa/NetCommSw/src/system/Makefile b/drivers/net/dpa/NetCommSw/src/system/Makefile -new file mode 100644 -index 0000000..c464c0f ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/system/Makefile -@@ -0,0 +1,10 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+# -+ -+obj-y += sys_io.o -diff --git a/drivers/net/dpa/NetCommSw/src/system/sys_io.c b/drivers/net/dpa/NetCommSw/src/system/sys_io.c -new file mode 100644 -index 0000000..c106a8b ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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)); -+} -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/Makefile b/drivers/net/dpa/NetCommSw/src/wrapper/Makefile -new file mode 100644 -index 0000000..c850bf2 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/Makefile -@@ -0,0 +1,19 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+NCSW_FM_INC = $(srctree)/drivers/net/dpa/NetCommSw/Peripherals/FM/inc -+ -+EXTRA_CFLAGS += -I$(NCSW_FM_INC) -+EXTRA_CFLAGS += -I$(NET_DPA) -+ -+obj-y += fsl-ncsw-PFM.o -+obj-$(CONFIG_FSL_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 \ -+ lnxwrp_resources.o -+obj-$(CONFIG_COMPAT) += lnxwrp_ioctls_fm_compat.o -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/fman_test.c b/drivers/net/dpa/NetCommSw/src/wrapper/fman_test.c -new file mode 100644 -index 0000000..7990b9a ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/fman_test.c -@@ -0,0 +1,1663 @@ -+/* 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 "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 trafic */ -+ 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); -+ -+ 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 __devinitconst = { -+ .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[] __devinitdata = { -+ { .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 (cannnot 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); -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_fm.c b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_fm.c -new file mode 100644 -index 0000000..8924679 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_fm.c -@@ -0,0 +1,1221 @@ -+/* -+ * 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 /* For struct qe_firmware */ -+#include -+#include /* For file access mask */ -+#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" -+ -+#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" -+ -+/* Maximum value for the fsl_fm_rx_extra_headroom bootarg */ -+#define FSL_FM_RX_EXTRA_HEADROOM_MAX 384 -+ -+/* -+ * 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 accomodate 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; -+ -+static t_LnxWrpFm lnxWrpFm; -+ -+int fm_get_max_frm() -+{ -+ return fsl_fm_max_frm; -+} -+ -+int fm_get_rx_extra_headroom() -+{ -+ return fsl_fm_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 < 0 || -+ fsl_fm_rx_extra_headroom > FSL_FM_RX_EXTRA_HEADROOM_MAX) { -+ printk(KERN_WARNING "Invalid value for %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; -+ } -+ -+ 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; -+ -+ if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev) -+ return IRQ_NONE; -+ -+ 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}; -+ static const uint8_t physOhPortId[] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7}; -+ 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]; -+ -+#ifdef FM_OP_PARTITION_ERRATA_FMANx8 -+ for (i=0; iopPorts[i-1].settings.param.specificParams.nonRxParams.opLiodnOffset = -+ p_Ppids->fmbm_ppid[physOhPortId[i]-1]; -+ } -+#endif /* FM_OP_PARTITION_ERRATA_FMANx8 */ -+ -+ return E_OK; -+} -+ -+/** -+ * 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; -+} -+ -+static t_LnxWrpFmDev * ReadFmDevTreeNode (struct platform_device *of_dev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev; -+ struct device_node *fm_node, *dev_node; -+ struct of_device_id name; -+ struct resource res; -+ const uint32_t *uint32_prop; -+ int _errno=0, lenp; -+ -+ 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; -+ } -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ return NULL; -+ if (*uint32_prop > INTG_MAX_NUM_OF_FM) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!")); -+ return NULL; -+ } -+ p_LnxWrpFmDev = CreateFmDev(*uint32_prop); -+ if (!p_LnxWrpFmDev) { -+ REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG); -+ return NULL; -+ } -+ p_LnxWrpFmDev->dev = &of_dev->dev; -+ p_LnxWrpFmDev->id = *uint32_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)); -+ return NULL; -+ } -+ -+ /* Get the FM error interrupt */ -+ p_LnxWrpFmDev->err_irq = of_irq_to_resource(fm_node, 1, NULL); -+ /* TODO - un-comment it once there will be err_irq in the DTS */ -+#if 0 -+ if (unlikely(p_LnxWrpFmDev->err_irq == /*NO_IRQ*/0)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ)); -+ return NULL; -+ } -+#endif /* 0 */ -+ -+ /* 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)); -+ return NULL; -+ } -+ -+ p_LnxWrpFmDev->fmBaseAddr = 0; -+ p_LnxWrpFmDev->fmPhysBaseAddr = res.start; -+ p_LnxWrpFmDev->fmMemSize = res.end + 1 - res.start; -+ -+ uint32_prop = (uint32_t *)of_get_property(fm_node, "clock-frequency", &lenp); -+ if (unlikely(uint32_prop == NULL)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_get_property(%s, clock-frequency) failed", fm_node->full_name)); -+ return NULL; -+ } -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ return NULL; -+ p_LnxWrpFmDev->fmDevSettings.param.fmClkFreq = (*uint32_prop + 500000)/1000000; /* In MHz, rounded */ -+ -+ /* Get the MURAM base address and size */ -+ memset(&name, 0, sizeof(struct of_device_id)); -+ if (WARN_ON(strlen("muram") >= sizeof(name.name))) -+ return NULL; -+ strcpy(name.name, "muram"); -+ if (WARN_ON(strlen("fsl,fman-muram") >= sizeof(name.compatible))) -+ return NULL; -+ strcpy(name.compatible, "fsl,fman-muram"); -+ for_each_child_of_node(fm_node, dev_node) { -+ if (likely(of_match_node(&name, 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)); -+ return NULL; -+ } -+ -+ p_LnxWrpFmDev->fmMuramBaseAddr = 0; -+ p_LnxWrpFmDev->fmMuramPhysBaseAddr = res.start; -+ p_LnxWrpFmDev->fmMuramMemSize = res.end + 1 - res.start; -+ } -+ } -+ -+ /* Get the RTC base address and size */ -+ memset(&name, 0, sizeof(struct of_device_id)); -+ if (WARN_ON(strlen("rtc") >= sizeof(name.name))) -+ return NULL; -+ strcpy(name.name, "rtc"); -+ if (WARN_ON(strlen("fsl,fman-rtc") >= sizeof(name.compatible))) -+ return NULL; -+ strcpy(name.compatible, "fsl,fman-rtc"); -+ for_each_child_of_node(fm_node, dev_node) { -+ if (likely(of_match_node(&name, 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)); -+ 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)); -+ return NULL; -+ } -+ p_LnxWrpFmDev->fmVspBaseAddr = 0; -+ p_LnxWrpFmDev->fmVspPhysBaseAddr = res.start; -+ p_LnxWrpFmDev->fmVspMemSize = res.end + 1 - res.start; -+ } -+ } -+#endif -+ -+ /* Get all PCD nodes */ -+ memset(&name, 0, sizeof(struct of_device_id)); -+ if (WARN_ON(strlen("parser") >= sizeof(name.name))) -+ return NULL; -+ strcpy(name.name, "parser"); -+ if (WARN_ON(strlen("fsl,fman-parser") >= sizeof(name.compatible))) -+ return NULL; -+ strcpy(name.compatible, "fsl,fman-parser"); -+ for_each_child_of_node(fm_node, dev_node) -+ if (likely(of_match_node(&name, dev_node) != NULL)) -+ p_LnxWrpFmDev->prsActive = TRUE; -+ -+ memset(&name, 0, sizeof(struct of_device_id)); -+ if (WARN_ON(strlen("keygen") >= sizeof(name.name))) -+ return NULL; -+ strcpy(name.name, "keygen"); -+ if (WARN_ON(strlen("fsl,fman-keygen") >= sizeof(name.compatible))) -+ return NULL; -+ strcpy(name.compatible, "fsl,fman-keygen"); -+ for_each_child_of_node(fm_node, dev_node) -+ if (likely(of_match_node(&name, dev_node) != NULL)) -+ p_LnxWrpFmDev->kgActive = TRUE; -+ -+ memset(&name, 0, sizeof(struct of_device_id)); -+ if (WARN_ON(strlen("cc") >= sizeof(name.name))) -+ return NULL; -+ strcpy(name.name, "cc"); -+ if (WARN_ON(strlen("fsl,fman-cc") >= sizeof(name.compatible))) -+ return NULL; -+ strcpy(name.compatible, "fsl,fman-cc"); -+ for_each_child_of_node(fm_node, dev_node) -+ if (likely(of_match_node(&name, dev_node) != NULL)) -+ p_LnxWrpFmDev->ccActive = TRUE; -+ -+ memset(&name, 0, sizeof(struct of_device_id)); -+ if (WARN_ON(strlen("policer") >= sizeof(name.name))) -+ return NULL; -+ strcpy(name.name, "policer"); -+ if (WARN_ON(strlen("fsl,fman-policer") >= sizeof(name.compatible))) -+ return NULL; -+ strcpy(name.compatible, "fsl,fman-policer"); -+ for_each_child_of_node(fm_node, dev_node) -+ if (likely(of_match_node(&name, dev_node) != NULL)) -+ p_LnxWrpFmDev->plcrActive = TRUE; -+ -+ 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; -+} -+ -+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)); -+ -+ 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)); -+ } -+ -+ 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); -+} -+ -+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 + fw->microcode[0].code_offset; -+ p_LnxWrpFmDev->fmDevSettings.param.firmware.size = -+ sizeof(u32) * 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)); -+ } -+ -+ 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 -+ -+ 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")); -+ -+#ifdef CONFIG_FMAN_P1023 -+ if (FM_ConfigDmaAidOverride(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM")); -+#endif -+ -+ -+#if defined(CONFIG_FMAN_RESOURCE_ALLOCATION_ALGORITHM) && defined(CONFIG_FMAN_P3040_P4080_P5020) -+ /* Enable 14g w/ jumbo frames following HW suggestion. */ -+ FM_ConfigTotalFifoSize(p_LnxWrpFmDev->h_Dev, 128*KILOBYTE); -+#elif defined(CONFIG_FMAN_RESOURCE_ALLOCATION_ALGORITHM) && defined(CONFIG_FMAN_P1023) -+ FM_ConfigTotalFifoSize(p_LnxWrpFmDev->h_Dev, 48*KILOBYTE); -+#endif -+#if (DPAA_VERSION >= 11) -+#define DEFAULT_TOTAL_FIFO_SIZE_FOR_FMAN_V3H 295*KILOBYTE -+ FM_ConfigTotalFifoSize(p_LnxWrpFmDev->h_Dev, -+ DEFAULT_TOTAL_FIFO_SIZE_FOR_FMAN_V3H); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ 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, 5) != 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; -+ } -+ -+ DBG(TRACE, ("FM%d probed", p_LnxWrpFmDev->id)); -+ -+#if defined(CONFIG_FMAN_RESOURCE_ALLOCATION_ALGORITHM) -+ /* Precalculate resources for FMAN based on number of -+ * FMan ports available -+ */ -+ if(fm_set_active_fman_ports(of_dev, p_LnxWrpFmDev)!= 0) -+ return -EIO; -+ -+#if defined(CONFIG_FMAN_P3040_P4080_P5020) -+ /* 128K MURAM for p3,p4 and p5 */ -+ if(fm_precalculate_fifosizes( -+ p_LnxWrpFmDev, -+ 128*KILOBYTE) -+ != 0) -+ return -EIO; -+#else -+ /* for all other platforms: MURAM Space for fifosize=3/4 * MURAM_SIZE*/ -+ if(fm_precalculate_fifosizes( -+ p_LnxWrpFmDev, -+ 48*KILOBYTE) -+ != 0) -+ return -EIO; -+#endif -+ if(fm_precalculate_open_dma( -+ p_LnxWrpFmDev, -+ BMI_MAX_NUM_OF_DMAS, /* 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 -EIO; -+ if(fm_precalculate_tnums( -+ p_LnxWrpFmDev, -+ BMI_MAX_NUM_OF_TASKS) /* max TNUMS: dpa integration file. */ -+ != 0) -+ return -EIO; -+#endif -+ -+ return 0; -+} -+ -+static int __devexit 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[] __devinitconst = { -+ { -+ .compatible = "fsl,fman" -+ }, -+ {} -+}; -+#ifndef MODULE -+MODULE_DEVICE_TABLE(of, fm_match); -+#endif /* !MODULE */ -+ -+static struct platform_driver fm_driver = { -+ .driver = { -+ .name = "fsl-fman", -+ .of_match_table = fm_match, -+ .owner = THIS_MODULE, -+ }, -+ .probe = fm_probe, -+ .remove = __devexit_p(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(struct fm_port *port) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port; -+ -+ return (void *)p_LnxWrpFmPortDev->h_Dev; -+} -+EXPORT_SYMBOL(fm_port_get_handle); -+ -+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); -+ -+int 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; -+ -+ FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev); -+ -+ return 0; -+} -+EXPORT_SYMBOL(fm_port_enable); -+ -+void fm_port_disable(struct fm_port *port) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port; -+ -+ FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev); -+} -+EXPORT_SYMBOL(fm_port_disable); -+ -+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); -+ -+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 ("__DATE__ ":"__TIME__")," \ -+ " 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); -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_fm.h b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_fm.h -new file mode 100644 -index 0000000..40f0934 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_fm.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. -+ */ -+ -+/* -+ @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 __ERR_MODULE__ MODULE_FM -+ -+#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 0 -+#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; -+ 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_LnxWrpFmDev; -+ uint16_t txCh; -+ struct device *dev; -+ struct device_attribute *dev_attr_stats; -+ struct device_attribute *dev_attr_regs; -+} 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_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_pcd_attr_stats; -+ struct device_attribute *dev_pcd_attr_regs; -+ -+ 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); -+ -+ -+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; -+} -+ -+void LnxWrpPCDIOCTLTypeChecking(void); -+void LnxWrpPCDIOCTLEnumChecking(void); -+ -+#endif /* __LNXWRP_FM_H__ */ -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_fm_port.c b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_fm_port.c -new file mode 100644 -index 0000000..8ddc46a ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_fm_port.c -@@ -0,0 +1,1098 @@ -+/* -+ * 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 "sprint_ext.h" -+#include "fm_common.h" -+#include "fm_port_ext.h" -+#include "fm_ioctls.h" -+#include "lnxwrp_resources.h" -+#include "lnxwrp_sysfs_fm_port.h" -+ -+/* 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) -+ -+ -+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; -+ -+ 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); -+ -+ _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; -+#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; -+ } -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ return NULL; -+ if (of_device_is_compatible(port_node, "fsl,fman-port-oh")) { -+ if (unlikely(*uint32_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 (*uint32_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[*uint32_prop - 1]; -+ p_LnxWrpFmPortDev->id = *uint32_prop - 1; -+ p_LnxWrpFmPortDev->settings.param.portType = -+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING; -+ } -+ p_LnxWrpFmPortDev->settings.param.portId = *uint32_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; -+ } -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ return NULL; -+ p_LnxWrpFmPortDev->txCh = *uint32_prop; -+ -+ p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams. -+ qmChannel = p_LnxWrpFmPortDev->txCh; -+ } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-tx")) { -+ if (unlikely(*uint32_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[*uint32_prop]; -+ -+ p_LnxWrpFmPortDev->id = *uint32_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; -+ } -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ return NULL; -+ p_LnxWrpFmPortDev->txCh = *uint32_prop; -+ p_LnxWrpFmPortDev-> -+ settings.param.specificParams.nonRxParams.qmChannel = -+ p_LnxWrpFmPortDev->txCh; -+ } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-tx")) { -+ if (unlikely(*uint32_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[*uint32_prop + -+ FM_MAX_NUM_OF_1G_TX_PORTS]; -+ -+ p_LnxWrpFmPortDev->id = *uint32_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; -+ } -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ return NULL; -+ p_LnxWrpFmPortDev->txCh = *uint32_prop; -+ p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams. -+ qmChannel = p_LnxWrpFmPortDev->txCh; -+ } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-rx")) { -+ if (unlikely(*uint32_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[*uint32_prop]; -+ -+ p_LnxWrpFmPortDev->id = *uint32_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")) { -+ if (unlikely(*uint32_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[*uint32_prop + -+ FM_MAX_NUM_OF_1G_RX_PORTS]; -+ -+ p_LnxWrpFmPortDev->id = *uint32_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; -+} -+ -+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 */ -+ -+#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 */ -+ -+/* 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 defined(CONFIG_FMAN_RESOURCE_ALLOCATION_ALGORITHM) -+#if (DPAA_VERSION >= 11) -+#warning The resource allocation algorithm is not available for FMan v3 platforms -+#else -+ /* even if these functions return w/ error, do not crash kernel. -+ Do not return anything because the container function is not -+ linux complient (it should return -EIO). */ -+ fm_config_precalculate_fifosize(p_LnxWrpFmPortDev); -+ fm_config_precalculate_open_dma(p_LnxWrpFmPortDev); -+ fm_config_precalculate_tnums(p_LnxWrpFmPortDev); -+#endif -+#endif -+ -+ if (FM_PORT_Init(p_LnxWrpFmPortDev->h_Dev) != 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; -+ -+ 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 = FALSE; -+ -+ if ((params->frag_enable == TRUE) && -+ (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) { -+ -+ p_LnxWrpFmPortDev->settings.frag_enabled = TRUE; -+ p_LnxWrpFmPortDev->buffPrefixContent.dataAlign = -+ FRAG_DATA_ALIGN; -+ p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace = -+ FRAG_MANIP_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 ((params->frag_enable == TRUE) && -+ (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) { -+ t_FmExtPools opExtPools; -+ int i; -+ -+ memset(&opExtPools, 0, sizeof(opExtPools)); -+ opExtPools.numOfPoolsUsed = params->num_pools; -+ for (i = 0; i < params->num_pools; i++) { -+ opExtPools.extBufPool[i].id = params->pool_param[i].id; -+ opExtPools.extBufPool[i].size = params->pool_param[i].size; -+ } -+ ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigExtBufPools, -+ ARGS(1, (&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, 7); -+ 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, 7); -+ 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; -+ } 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; -+ } 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; -+ p_LnxWrpFmPortDev->h_Dev = FM_PCD_GetHcDevH(p_LnxWrpFmDev->h_PcdDev); -+ } 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 __devexit 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[] __devinitconst = { -+ { -+ .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 = __devexit_p(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 (" __DATE__ ":" __TIME__ -+ ")\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); -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_ioctls_fm.c b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_ioctls_fm.c -new file mode 100644 -index 0000000..8690359 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_ioctls_fm.c -@@ -0,0 +1,4423 @@ -+/* -+ * 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 -+#include -+ -+#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" -+ -+#if defined(CONFIG_COMPAT) -+#include "lnxwrp_ioctls_fm_compat.h" -+#endif -+ -+#include "lnxwrp_fm.h" -+ -+#include "dpaa_eth.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_PRS_SW_OFFSET) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_PRS_SW_PATCHES_SIZE) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_PRS_SW_TAIL_SIZE) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_SW_PRS_MAX_IMAGE_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 */ -+ 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_COMPAT) -+ /* different alignment */ -+ ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *)); -+#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)); -+ ASSERT_COND(sizeof(TODO) == sizeof(t_FmPcdManipFragOrReasmParams)); -+ ASSERT_COND(sizeof(TODO) == sizeof(t_FmPcdManipHdrRmvByHdrParams)); -+*/ -+#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_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_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) { -+ 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_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_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); -+ 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 (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_plcr_profile_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(*compat_param)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, -+ ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(*compat_param)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_frm_replic_group_params_t *) -+ compat_ptr(arg), -+ sizeof(*compat_param))) { -+ 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(*compat_param)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, -+ ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(*compat_param)); -+ 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(*compat_param))) -+ 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); -+ 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))) -+ 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))) -+ 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_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) - 50); -+ -+ 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); -+ -+ /* 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_PRS_MODIFY_START_OFFSET: -+ { -+ ioc_fm_pcd_prs_start_t *param; -+ -+ param = (ioc_fm_pcd_prs_start_t *) XX_Malloc(sizeof(ioc_fm_pcd_prs_start_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_prs_start_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_prs_start_t *)compat_ptr(arg), -+ sizeof(ioc_fm_pcd_prs_start_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_prs_start_t *)arg, -+ sizeof(ioc_fm_pcd_prs_start_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_PORT_PcdPrsModifyStartOffset(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPrsStart *)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) -+ { -+ struct net_device *net_dev = dev_get_drvdata(p_LnxWrpFmPortDev->pcd_owner_params.dev); -+ -+ if (net_dev) -+ { -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ -+ if (priv) -+ { -+ struct mac_device *mac_dev = priv->mac_dev; -+ -+ if (mac_dev) -+ { -+ void *mac_handle = mac_dev->get_mac_handle(mac_dev); -+ -+ err = (cmd == FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR) -+ ? FM_MAC_AddHashMacAddr((t_Handle) mac_handle, (t_EnetAddr*) param) -+ : FM_MAC_RemoveHashMacAddr((t_Handle) mac_handle, (t_EnetAddr*) param) -+ ; -+ } -+ else -+ { -+ err = E_NOT_AVAILABLE; -+ REPORT_ERROR(MINOR, err, ("Attempt to add/remove hash MAC addr. to/from MAC-less port!")); -+ } -+ } -+ else -+ /* Not possible, set err nevertheless: */ -+ err = E_NOT_AVAILABLE; -+ } -+ else -+ { -+ err = E_NOT_AVAILABLE; -+ REPORT_ERROR(MINOR, err, ("No net device (and no MAC!) associated to this port!")); -+ } -+ } -+ 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; -+ } -+ -+ 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[] __devinitdata = { -+ { .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, -+}; -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_ioctls_fm_compat.c b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_ioctls_fm_compat.c -new file mode 100644 -index 0000000..c4c6a35 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_ioctls_fm_compat.c -@@ -0,0 +1,1213 @@ -+/* -+ * 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 -+#include -+ -+#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; -+ 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; -+ 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: -+ 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_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->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->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; -+ 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; -+ 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_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); -+ -+ 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); -+ } -+} -+ -+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_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: -+ param->u.special_offload = compat_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); -+ } -+} -+ -+#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) -+ { -+ param->p_fm = compat_pcd_id2ptr(compat_param->p_fm); -+ memcpy(¶m->ext_buf_pools, &compat_param->ext_buf_pools, sizeof(ioc_fm_ext_pools)); -+ param->liodn_offset = compat_param->liodn_offset; -+ param->portParams.port_id = compat_param->portParams.port_id; -+ param->portParams.port_type = compat_param->portParams.port_type; -+ param->relative_profile_id = compat_param->relative_profile_id; -+ param->id = compat_pcd_id2ptr(compat_param->id); -+ } -+ else -+ { -+ compat_param->p_fm = compat_pcd_ptr2id(param->p_fm); -+ memcpy(&compat_param->ext_buf_pools, ¶m->ext_buf_pools, sizeof(ioc_fm_ext_pools)); -+ compat_param->liodn_offset = param->liodn_offset; -+ compat_param->portParams.port_id = param->portParams.port_id; -+ compat_param->portParams.port_type = param->portParams.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) */ -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_ioctls_fm_compat.h b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_ioctls_fm_compat.h -new file mode 100644 -index 0000000..e8e6677 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_ioctls_fm_compat.h -@@ -0,0 +1,679 @@ -+/* -+ * 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 (256+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; -+ 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; -+} 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_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; -+ } 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; -+#ifdef FM_CAPWAP_SUPPORT -+#error CAPWAP 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_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_fm_pcd_manip_special_offload_params_t special_offload; -+ } u; -+ compat_uptr_t p_next_manip; -+#ifdef FM_CAPWAP_SUPPORT -+#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; -+ -+#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 */ -+ } portParams; -+ 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_ctrl_mon_counters_params_t { -+ uint8_t fm_ctrl_index; -+ compat_uptr_t p_mon; -+} ioc_compat_fm_ctrl_mon_counters_params_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_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_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) */ -+/* } pcd compat functions */ -+#endif -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_resources.c b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_resources.c -new file mode 100644 -index 0000000..2686aa2 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_resources.c -@@ -0,0 +1,1196 @@ -+/* -+ * 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.c -+ -+ @Description FMD wrapper resource allocation functions. -+ -+*/ -+#if !defined(FMAN_RESOURCES_UNIT_TEST) -+ -+#include -+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) -+#define MODVERSIONS -+#endif -+#ifdef MODVERSIONS -+#include -+#endif /* MODVERSIONS */ -+#include -+#include -+#include -+#include -+ -+#endif /*#if !defined(FMAN_RESOURCES_UNIT_TEST)*/ -+ -+#include "lnxwrp_resources.h" -+ -+#if !defined(FMAN_RESOURCES_UNIT_TEST) -+static struct device_node *match_mac_to_dpaa_port(struct device_node -+ *enet_mac_node) -+{ -+ struct device_node *dpaa_node = NULL; -+ struct device_node *dpaa_itf = NULL; -+ -+ /* find DPAA node starting from root */ -+ dpaa_node = of_find_compatible_node(NULL, NULL, "fsl,dpaa"); -+ if (dpaa_node) { -+ /* for all dpaa ports check which one refers this mac node. */ -+ for_each_child_of_node(dpaa_node, dpaa_itf) { -+ struct device_node *by_handle_enet_mac_node = NULL; -+ const phandle *phandle_prop = NULL; -+ int lenp = 0; -+ -+ phandle_prop = -+ (typeof(phandle_prop)) -+ of_get_property(dpaa_itf, "fsl,fman-mac", -+ &lenp); -+ if (phandle_prop == NULL) -+ continue; -+ -+ if (WARN_ON(lenp != sizeof(phandle))) -+ return NULL; -+ -+ by_handle_enet_mac_node = -+ of_find_node_by_phandle(*phandle_prop); -+ if (unlikely(by_handle_enet_mac_node == NULL)) -+ return NULL; -+ -+ /* check */ -+ if (by_handle_enet_mac_node == enet_mac_node) { -+ of_node_put(by_handle_enet_mac_node); -+ return dpaa_itf; -+ } -+ -+ of_node_put(by_handle_enet_mac_node); -+ } -+ of_node_put(dpaa_node); -+ } -+ -+ return NULL; -+} -+ -+static struct device_node *match_fman_port_to_mac(struct device_node *fm_node, -+ struct device_node -+ *fm_port_node) -+{ -+ struct device_node *fm_node_idx = NULL; -+ -+ /* for all enet nodes (macs) check which one refers this FMan port. */ -+ for_each_child_of_node(fm_node, fm_node_idx) { -+ if (of_device_is_compatible(fm_node_idx, "fsl,fman-1g-mac") || -+ of_device_is_compatible(fm_node_idx, "fsl,fman-10g-mac") || -+ of_device_is_compatible(fm_node_idx, "fsl,fman-memac")) { -+ struct device_node *fman_port_node_rx = NULL; -+ struct device_node *fman_port_node_tx = NULL; -+ /* RX is first */ -+ fman_port_node_rx = of_parse_phandle(fm_node_idx, -+ "fsl,port-handles", 0); -+ if (unlikely(fman_port_node_rx == NULL)) -+ continue; -+ /* TX is second */ -+ fman_port_node_tx = of_parse_phandle(fm_node_idx, -+ "fsl,port-handles", 1); -+ if (unlikely(fman_port_node_tx == NULL)) { -+ of_node_put(fman_port_node_rx); -+ continue; -+ } -+ -+ /* check */ -+ if (fman_port_node_rx == fm_port_node -+ || fman_port_node_tx == fm_port_node) { -+ of_node_put(fman_port_node_rx); -+ of_node_put(fman_port_node_tx); -+ return fm_node_idx; -+ } -+ -+ of_node_put(fman_port_node_rx); -+ of_node_put(fman_port_node_tx); -+ } -+ } -+ -+ return NULL; -+} -+ -+static bool is_fman_port_active(struct device_node *fm_node, -+ struct device_node *fm_port_node) -+{ -+ struct device_node *enet_mac_node = NULL; -+ struct device_node *itf_node = NULL; -+ -+ /* Which MAC node refers to this FMan port. */ -+ enet_mac_node = match_fman_port_to_mac(fm_node, fm_port_node); -+ -+ if (unlikely(enet_mac_node == NULL)) -+ return false; -+ -+ /* Which dpaa port node refers this MAC node. */ -+ itf_node = match_mac_to_dpaa_port(enet_mac_node); -+ of_node_put(enet_mac_node); -+ -+ if (unlikely(!itf_node)) -+ return false; -+ -+ /* check if itf (DPAA ports) is available. -+ * if available, means that the FMan port is -+ * also available - return true -+ */ -+ if (!of_device_is_available(itf_node)) { -+ of_node_put(itf_node); -+ return false; -+ } -+ of_node_put(itf_node); -+ -+ return true; -+} -+ -+int fm_set_active_fman_ports(struct platform_device *of_dev, -+ t_LnxWrpFmDev *p_LnxWrpFmDev) -+{ -+ struct device_node *fm_node = NULL; -+ struct device_node *fm_port_node = NULL; -+ -+ memset(&p_LnxWrpFmDev->fm_active_ports_info, 0, -+ sizeof(struct fm_active_ports)); -+ -+ /* get FMan node */ -+ fm_node = of_dev->dev.of_node; -+ -+ /* for all ports which belong to this FMan, check if they are active. -+ * If active, set their parameters. */ -+ for_each_child_of_node(fm_node, fm_port_node) { -+ -+ if (!of_device_is_available(fm_port_node)) -+ continue; -+ -+ /* OH FMan ports */ -+ if (of_device_is_compatible(fm_port_node, -+ "fsl,fman-port-oh")) { -+ p_LnxWrpFmDev->fm_active_ports_info.num_oh_ports++; -+ continue; -+ } -+ -+ if (!is_fman_port_active(fm_node, fm_port_node)) -+ continue; -+ -+ /* 10g TX FMan ports */ -+ if (of_device_is_compatible(fm_port_node, -+ "fsl,fman-port-10g-tx")) -+ p_LnxWrpFmDev->fm_active_ports_info.num_tx10_ports++; -+ -+ /* 10g RX FMan ports */ -+ else if (of_device_is_compatible(fm_port_node, -+ "fsl,fman-port-10g-rx")) -+ p_LnxWrpFmDev->fm_active_ports_info.num_rx10_ports++; -+ -+ /* 1G TX FMan ports */ -+ else if (of_device_is_compatible(fm_port_node, -+ "fsl,fman-port-1g-tx")) -+ p_LnxWrpFmDev->fm_active_ports_info.num_tx_ports++; -+ -+ /* 1G RX FMan ports */ -+ else if (of_device_is_compatible(fm_port_node, -+ "fsl,fman-port-1g-rx")) -+ p_LnxWrpFmDev->fm_active_ports_info.num_rx_ports++; -+ } -+ -+ /* If performance is needed no oh port is probed -+ * except the one used for host command. */ -+#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES) -+ if (p_LnxWrpFmDev->fm_active_ports_info.num_oh_ports) -+ p_LnxWrpFmDev->fm_active_ports_info.num_oh_ports = 1; -+ -+ printk(KERN_WARNING "FMAN(%u)-Performance mode - no OH support...\n", -+ p_LnxWrpFmDev->id); -+#endif -+ -+ return 0; -+} -+#endif /*!defined(FMAN_RESOURCES_UNIT_TEST)*/ -+ -+/* BPOOL size is constant and equal w/ DPA_BP_SIZE */ -+static uint32_t get_largest_buf_size(uint32_t max_rx_frame_size, uint32_t buf_size) -+{ -+ uint32_t priv_data_size = 16; /* DPA_PRIV_DATA_SIZE */ -+ uint32_t hash_results_size = 16; /* DPA_HASH_RESULTS_SIZE */ -+ uint32_t parse_results_size = -+ sizeof(t_FmPrsResult); /* DPA_PARSE_RESULTS_SIZE */ -+ uint32_t bp_head = priv_data_size + hash_results_size + -+ parse_results_size + -+ fm_get_rx_extra_headroom(); /* DPA_BP_HEAD */ -+ uint32_t bp_size = bp_head + max_rx_frame_size -+ + NET_IP_ALIGN; /* DPA_BP_SIZE */ -+ -+#ifndef CONFIG_DPAA_ETH_SG_SUPPORT -+ return CEIL_DIV(bp_size, buf_size); -+#else -+ bp_size = CEIL_DIV(bp_size, 16); /* frame split in 16 frags */ -+ -+ return max((uint32_t)16, CEIL_DIV(bp_size, buf_size)); -+#endif /* CONFIG_DPAA_ETH_SG_SUPPORT */ -+} -+ -+/* 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) -+{ -+ -+ /* input parameters */ -+ struct fm_active_ports *fm_active_ports_info = NULL; -+ int num_1g_ports = 0; -+ int num_2g5_ports = 0; -+ int num_10g_ports = 0; -+ int num_oh_ports = 0; -+ -+ /* output parameters */ -+ struct fm_resource_settings *fm_resource_settings_info = NULL; -+ int oh_buff = 0; -+ int tx_1g_bufs = 0, rx_1g_bufs = 0; -+ int tx_2g5_bufs = 0, rx_2g5_bufs = 0; -+ int tx_10g_bufs = 0, rx_10g_bufs = 0; -+ int err = 0; -+ -+ /* throughput parameters: divide it by 10 when used */ -+ int gb1g = 10, gb2g5 = 25, gb10g = 100, gb_sum = 0; -+ -+ /* buffers parameters */ -+ int buf_size = 0x100; /* Buffer unit size */ -+ int total_no_buffers = 0; /* Calculus based on MURAM size for -+ fifos and buf. unit size */ -+ -+ int shared_ext_buff = 0; /* External buffers allocated - LLD -+ boundaries:DEFAULT_PORT_extraSizeOfFifo */ -+ -+ int min_tx_1g_2g5_bufs = 0; /* minimum TX1g buffers required -+ (see refman.) */ -+ int min_tx_10g_bufs = 0; /* minimum TX10g buffers required -+ (see refman.) */ -+ int min_rx_bufs = 0; /* minimum RX buffers required (see refman.) */ -+ -+ /* Buffer sizes calculus */ -+ int max_frame_size = fm_get_max_frm(); -+ int remaining_bufs = 0; -+ int rx_1g_bufs_ceil = 0, rx_2g5_bufs_ceil = 0, rx_10g_bufs_ceil = 0; -+ int rx_2g5_max_bufs = 0, rx_10g_max_bufs = 0; -+ int rx_1g_used = 0, rx_1g_2g5_used = 0, rx_1g_10g_used =0, -+ rx_2g5_used = 0, rx_2g5_10g_used = 0, rx_1g_2g5_10g_used = 0; -+ -+ /* overflow checking */ -+ int tot_rx_buffs, tot_tx_buffs, tot_oh_buffs, tot_used_buffs, -+ leftovers = 0; -+ int overflow = 0; -+ bool loop = false; -+ -+ /* check input parameters correctness */ -+ ASSERT_COND(p_LnxWrpFmDev != NULL); -+ fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info; -+ fm_resource_settings_info = &p_LnxWrpFmDev->fm_resource_settings_info; -+ ASSERT_COND(fm_active_ports_info != NULL); -+ ASSERT_COND(fm_resource_settings_info != NULL); -+ ASSERT_COND(fm_active_ports_info->num_tx_ports == -+ fm_active_ports_info->num_rx_ports); -+ ASSERT_COND(fm_active_ports_info->num_tx25_ports == -+ fm_active_ports_info->num_tx25_ports); -+ ASSERT_COND(fm_active_ports_info->num_tx10_ports == -+ fm_active_ports_info->num_tx10_ports); -+ ASSERT_COND(max_frame_size != 0); -+ ASSERT_COND(muram_fifo_size != 0); -+ -+ /* set input parameters */ -+ num_1g_ports = fm_active_ports_info->num_tx_ports; -+ num_2g5_ports = fm_active_ports_info->num_tx25_ports; -+ num_10g_ports = fm_active_ports_info->num_tx10_ports; -+ num_oh_ports = fm_active_ports_info->num_oh_ports; -+ -+ /* throughput calculus */ -+ gb_sum = gb1g * num_1g_ports + gb2g5 * num_2g5_ports -+ + gb10g * num_10g_ports; /* divide it by 10 */ -+ -+ /* Base buffer calculus */ -+ oh_buff = 8; -+ total_no_buffers = muram_fifo_size / buf_size; -+ -+ min_tx_1g_2g5_bufs = CEIL_DIV(max_frame_size, buf_size) -+ + DPDE_1G + 3 + 1; /* +1 to handle Jumbo Frames */ -+ min_tx_10g_bufs = CEIL_DIV(max_frame_size, buf_size) -+ + DPDE_10G + 3 + 1; /* +1 to handle Jumbo Frames */ -+ -+ { -+/* -+ * On P1023RDS FM_FIFO_ALLOCATION_ALG is enabled allowing a smaller Rx FIFO -+ * on hardware major rev 4. If the Rx FIFO is smaller than the size of the -+ * buffer in the buffer pool SG frames will be received -+ */ -+#if defined(FM_FIFO_ALLOCATION_ALG) && \ -+ !defined(FMAN_RESOURCES_UNIT_TEST) && \ -+ defined(CONFIG_DPAA_ETH_SG_SUPPORT) -+ uint8_t fm_rev_major = 0; -+ fm_rev_major = (uint8_t) ((* -+ ((volatile uint32_t *) -+ UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr + -+ 0x000c30c4)) & 0xff00) >> 8); -+ -+ if (fm_rev_major == 4) -+ min_rx_bufs = 8; -+ else -+#endif -+ min_rx_bufs = get_largest_buf_size(max_frame_size, -+ buf_size) + 7; -+ } -+ -+#ifdef CONFIG_FMAN_P1023 -+ shared_ext_buff = 0; -+#else -+ /* changing these might reduce performance */ -+ shared_ext_buff = num_10g_ports ? 32 : 16; /* LLD boundaries: -+ DEFAULT_PORT_extraNumOfFifoBufs */ -+#endif -+ -+ /* TX ports will have minimum required buffers -+ Calculus of the remaining buffers for all RX ports */ -+ tx_1g_bufs = num_1g_ports ? min_tx_1g_2g5_bufs : 0; -+ tx_2g5_bufs = num_2g5_ports ? min_tx_1g_2g5_bufs : 0; -+ tx_10g_bufs = num_10g_ports ? min_tx_10g_bufs : 0; -+ -+ remaining_bufs = total_no_buffers - -+ oh_buff * num_oh_ports - -+ num_1g_ports * min_tx_1g_2g5_bufs - -+ num_2g5_ports * min_tx_1g_2g5_bufs - -+ num_10g_ports * min_tx_10g_bufs - shared_ext_buff; -+ -+ if (remaining_bufs < 0) { -+ printk(KERN_ALERT -+ "\nThis configuration will not work due to low number of" -+ " buffers (%u buffers)...\n", -+ total_no_buffers); -+ err = -1; -+ goto precalculated_fifosize_out; -+ } -+ -+ /* Per port buffer size calculus -+ . for TX ports give always minimum required -+ . for RX ports give whatever left scaled per port type */ -+ /* ------------------------------------------------------- */ -+ if (num_1g_ports) { -+ rx_1g_bufs_ceil = -+ (gb_sum / -+ 10) ? CEIL_DIV(((remaining_bufs * gb1g) / 10), -+ (gb_sum / 10)) : 0; -+ rx_1g_bufs = MAX(min_rx_bufs, rx_1g_bufs_ceil); -+ rx_1g_used = rx_1g_bufs - rx_1g_bufs_ceil; /* always >= 0 */ -+ /* distribute to 2.5g and 10g ports */ -+ rx_1g_2g5_used = -+ (num_2g5_ports + -+ num_10g_ports) ? CEIL_DIV(rx_1g_used * num_1g_ports * -+ num_2g5_ports, -+ num_2g5_ports + -+ num_10g_ports) : 0; -+ rx_1g_10g_used = -+ (num_2g5_ports + -+ num_10g_ports) ? CEIL_DIV(rx_1g_used * num_1g_ports * -+ num_10g_ports, -+ num_2g5_ports + -+ num_10g_ports) : 0; -+ } -+ -+ if (num_2g5_ports) { -+ rx_2g5_bufs_ceil = -+ (gb_sum / -+ 10) ? CEIL_DIV(((remaining_bufs * gb2g5) / 10), -+ (gb_sum / 10)) : 0; -+ rx_2g5_max_bufs = MAX(min_rx_bufs, rx_2g5_bufs_ceil); -+ rx_2g5_bufs = -+ MAX(min_rx_bufs, rx_2g5_max_bufs - rx_1g_2g5_used); -+ rx_2g5_used = rx_2g5_bufs - rx_2g5_bufs_ceil; /* always >= 0 */ -+ /* distribute to 10g ports */ -+ rx_2g5_10g_used = -+ num_10g_ports ? CEIL_DIV(rx_2g5_used * num_2g5_ports, -+ num_10g_ports) : 0; -+ } -+ -+ if (num_10g_ports) { -+ rx_10g_bufs_ceil = -+ (gb_sum / -+ 10) ? CEIL_DIV(((remaining_bufs * gb10g) / 10), -+ (gb_sum / 10)) : 0; -+ rx_10g_max_bufs = MAX(min_rx_bufs, rx_10g_bufs_ceil); -+ /* keep count of all distribution */ -+ rx_1g_2g5_10g_used = rx_1g_10g_used + rx_2g5_10g_used; -+ rx_10g_bufs = -+ MAX(min_rx_bufs, -+ rx_10g_max_bufs - rx_1g_2g5_10g_used); -+ } -+ -+ /* overflow-leftover calculus */ -+ tot_rx_buffs = rx_1g_bufs * num_1g_ports + -+ rx_2g5_bufs * num_2g5_ports + rx_10g_bufs * num_10g_ports; -+ tot_tx_buffs = tx_1g_bufs * num_1g_ports + -+ tx_2g5_bufs * num_2g5_ports + tx_10g_bufs * num_10g_ports; -+ tot_oh_buffs = oh_buff * num_oh_ports; -+ tot_used_buffs = -+ tot_oh_buffs + tot_tx_buffs + tot_rx_buffs + shared_ext_buff; -+ -+ overflow = tot_used_buffs - total_no_buffers; -+ /* used more than available */ -+ if (overflow > 0) { -+ loop = true; -+ while (overflow > 0 && loop) { -+ loop = false; -+ if (overflow && num_10g_ports -+ && rx_10g_bufs > min_rx_bufs) { -+ rx_10g_bufs--; -+ overflow -= num_10g_ports; -+ loop = true; -+ } -+ if (overflow && num_2g5_ports -+ && rx_2g5_bufs > min_rx_bufs) { -+ rx_2g5_bufs--; -+ overflow -= num_2g5_ports; -+ loop = true; -+ } -+ if (overflow && num_1g_ports -+ && rx_1g_bufs > min_rx_bufs) { -+ rx_1g_bufs--; -+ overflow -= num_1g_ports; -+ loop = true; -+ } -+ } -+ -+ if (overflow > 0) { -+ printk(KERN_ALERT -+ "This configuration will not work due to over" -+ " buffer allocation (%d buffers)...\n", -+ overflow); -+ err = -1; -+ goto precalculated_fifosize_out; -+ } -+ } -+ /* left a few buffers */ -+ else if (overflow < 0) { -+ leftovers = total_no_buffers - tot_used_buffs; -+ loop = true; -+ while (leftovers > 0 && loop) { -+ loop = false; -+ if (leftovers && num_1g_ports) { -+ rx_1g_bufs++; -+ leftovers -= num_1g_ports; -+ loop = true; -+ } -+ -+ if (leftovers && num_2g5_ports) { -+ rx_2g5_bufs++; -+ leftovers -= num_2g5_ports; -+ loop = true; -+ } -+ -+ if (leftovers && num_10g_ports) { -+ rx_10g_bufs++; -+ leftovers -= num_10g_ports; -+ loop = true; -+ } -+ } -+ } -+ -+ /* set fifosizes for this FMan ports */ -+ fm_resource_settings_info->tx1g_num_buffers = tx_1g_bufs; -+ fm_resource_settings_info->rx1g_num_buffers = rx_1g_bufs; -+ fm_resource_settings_info->tx2g5_num_buffers = tx_2g5_bufs; -+ fm_resource_settings_info->rx2g5_num_buffers = rx_2g5_bufs; -+ fm_resource_settings_info->tx10g_num_buffers = tx_10g_bufs; -+ fm_resource_settings_info->rx10g_num_buffers = rx_10g_bufs; -+ fm_resource_settings_info->oh_num_buffers = oh_buff; -+ fm_resource_settings_info->shared_ext_buffers = shared_ext_buff; -+ -+precalculated_fifosize_out: -+ printk(KERN_INFO " FMAN(%u) Fifo size settings:\n", -+ p_LnxWrpFmDev->id); -+ printk(KERN_INFO " - Total buffers available(%u - 256B/buffer)\n", -+ total_no_buffers); -+ printk(KERN_INFO " - Total throughput(%uGbps)\n", (gb_sum / 10)); -+ printk(KERN_INFO " - Max frame size(%uB)\n", max_frame_size); -+ if (num_1g_ports) { -+ printk(KERN_INFO -+ " - 1G ports TX %u(%u bufs set (min: %u))\n", -+ num_1g_ports, tx_1g_bufs, min_tx_1g_2g5_bufs); -+ printk(KERN_INFO -+ " - 1G ports RX %u(%u bufs set (min: %u))\n", -+ num_1g_ports, rx_1g_bufs, min_rx_bufs); -+ } -+ if (num_2g5_ports) { -+ printk(KERN_INFO -+ " - 2.5G ports TX %u(%u bufs set (min: %u))\n", -+ num_2g5_ports, tx_2g5_bufs, min_tx_1g_2g5_bufs); -+ printk(KERN_INFO -+ " - 2.5G ports RX %u(%u bufs set (min: %u))\n", -+ num_2g5_ports, rx_2g5_bufs, min_rx_bufs); -+ } -+ if (num_10g_ports) { -+ printk(KERN_INFO -+ " - 10G ports TX %u(%u bufs set (min: %u))\n", -+ num_10g_ports, tx_10g_bufs, min_tx_10g_bufs); -+ printk(KERN_INFO -+ " - 10G ports RX %u(%u bufs set (min: %u))\n", -+ num_10g_ports, rx_10g_bufs, min_rx_bufs); -+ } -+ if (num_oh_ports) -+ printk(KERN_INFO " - OH-HC ports %u(%u)\n", num_oh_ports, -+ oh_buff); -+ printk(KERN_INFO " - Shared extra buffers(%u)\n", shared_ext_buff); -+ -+ return err; -+} -+ -+#if !defined(FMAN_RESOURCES_UNIT_TEST) -+int fm_config_precalculate_fifosize(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = -+ (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ struct fm_resource_settings *fm_resource_settings_info = NULL; -+ struct fm_active_ports *fm_active_ports_info = NULL; -+ t_FmPortRsrc portRsrc; -+ t_Error errCode; -+ uint32_t buf_size = 0x100; -+ -+ ASSERT_COND(p_LnxWrpFmDev != NULL); -+ fm_resource_settings_info = &p_LnxWrpFmDev->fm_resource_settings_info; -+ fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info; -+ -+ memset(&portRsrc, 0, sizeof(t_FmPortRsrc)); -+ -+/* IF 1G PORT */ -+ if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX) { -+ portRsrc.num = -+ fm_resource_settings_info->tx1g_num_buffers * buf_size; -+ portRsrc.extra = 0; -+ } else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_RX) { -+ portRsrc.num = -+ fm_resource_settings_info->rx1g_num_buffers * buf_size; -+ portRsrc.extra = -+ fm_resource_settings_info->shared_ext_buffers * -+ buf_size; -+ } -+/* IF 2.5G PORT */ -+ /* TODO: Not supported by LLD yet. */ -+ -+/* IF 10G PORT */ -+ else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_TX_10G) { -+ portRsrc.num = -+ fm_resource_settings_info->tx10g_num_buffers * -+ buf_size; -+ portRsrc.extra = 0; -+ } else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_RX_10G) { -+ portRsrc.num = -+ fm_resource_settings_info->rx10g_num_buffers * -+ buf_size; -+ portRsrc.extra = -+ fm_resource_settings_info->shared_ext_buffers * -+ buf_size; -+ } else { /* IF OH PORT */ -+ portRsrc.num = -+ fm_resource_settings_info->oh_num_buffers * buf_size; -+ portRsrc.extra = 0; -+ } -+ -+ errCode = FM_PORT_ConfigSizeOfFifo(p_LnxWrpFmPortDev->h_Dev, &portRsrc); -+ if (errCode != E_OK) { -+ printk(KERN_WARNING -+ "FM_PORT_SetSizeOfFifo failed (errCode:0x%2x)", -+ errCode); -+ return -EIO; -+ } -+ -+ return 0; -+} -+#endif /*if !defined(FMAN_RESOURCES_UNIT_TEST)*/ -+ -+/* 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 thresholds. -+ * -+ * 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 thresholds. If the thresholds 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) -+{ -+ /* input parameters */ -+ struct fm_active_ports *fm_active_ports_info = NULL; -+ int num_1g_ports = 0; -+ int num_2g5_ports = 0; -+ int num_10g_ports = 0; -+ int num_oh_ports = 0; -+ -+ /* output parameters */ -+ struct fm_resource_settings *fm_resource_settings_info = NULL; -+ int tx_1g_dmas = 0, rx_1g_dmas = 0; -+ int tx_2g5_dmas = 0, rx_2g5_dmas = 0; -+ int tx_10g_dmas = 0, rx_10g_dmas = 0; -+ int oh_dmas = 0; -+ int shared_ext_open_dma = 0; -+ int err = 0; -+ -+ /* open dma calculus */ -+ int remaing_dmas = 0; -+ int rx_tx_raport = -+ FM_OPENDMA_RX_TX_RAPORT; /* RX = FM_OPENDMA_RX_TX_RAPORT *TX */ -+ int min_tx_1_2g5_treshold = 1; -+ int min_rx_1_2g5_treshold = 1; -+ int max_open_dma_treshold = 16; /* LLD: MAX_NUM_OF_DMAS */ -+ int max_ext_open_dma_treshold = 8; /* LLD: MAX_NUM_OF_EXTRA_DMAS */ -+ -+ int open_dmas_computed = 0; -+ int weighted_remaining_ports = 0; -+ int overflow = 0; -+ bool re_loop = false; -+ -+ /* check input parameters correctness */ -+ ASSERT_COND(p_LnxWrpFmDev != NULL); -+ fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info; -+ fm_resource_settings_info = &p_LnxWrpFmDev->fm_resource_settings_info; -+ ASSERT_COND(fm_active_ports_info != NULL); -+ ASSERT_COND(fm_resource_settings_info != NULL); -+ ASSERT_COND(fm_active_ports_info->num_tx_ports == -+ fm_active_ports_info->num_rx_ports); -+ ASSERT_COND(fm_active_ports_info->num_tx25_ports == -+ fm_active_ports_info->num_tx25_ports); -+ ASSERT_COND(fm_active_ports_info->num_tx10_ports == -+ fm_active_ports_info->num_tx10_ports); -+ ASSERT_COND(min_tx_10g_treshold <= max_open_dma_treshold); -+ ASSERT_COND(min_tx_10g_treshold <= max_open_dma_treshold); -+ -+ /* set input parameters */ -+ num_1g_ports = fm_active_ports_info->num_tx_ports; -+ num_2g5_ports = fm_active_ports_info->num_tx25_ports; -+ num_10g_ports = fm_active_ports_info->num_tx10_ports; -+ num_oh_ports = fm_active_ports_info->num_oh_ports; -+ -+ /* compute open DMAs per port */ -+ /* ------------------------------------------------------- */ -+ if (num_10g_ports) { -+ tx_10g_dmas = default_tx_10g_dmas; /* per 10G TX port */ -+ rx_10g_dmas = default_rx_10g_dmas; /* per 10G RX port */ -+ } -+ if (num_oh_ports) -+ oh_dmas = 1; /* per OH port */ -+ -+ /* should this be null? or LLD: -+ DEFAULT_PORT_extraNumOfOpenDmas:10g-8,else 1 */ -+ shared_ext_open_dma = 0; -+ -+ /* based on total number of ports set open DMAs for all other ports */ -+ remaing_dmas = max_fm_open_dma - -+ (oh_dmas * num_oh_ports) - -+ (tx_10g_dmas * num_10g_ports + rx_10g_dmas * num_10g_ports) - -+ shared_ext_open_dma; -+ -+ if (remaing_dmas < 0) { -+ printk(KERN_ALERT -+ "This configuration will not work due to low number" -+ " of open dmas (%u open dmas)...\n", -+ max_fm_open_dma); -+ err = -1; -+ goto precalculated_open_dma_out; -+ } -+ -+ weighted_remaining_ports = -+ /*tx */ num_1g_ports * rx_tx_raport + /*rx */ num_1g_ports + -+ /*tx */ num_2g5_ports * rx_tx_raport + /*rx */ num_2g5_ports; -+ -+ /* compute the other ports */ -+ if (num_1g_ports) { -+ tx_1g_dmas = -+ MAX(MIN -+ (ROUND_DIV -+ (remaing_dmas, weighted_remaining_ports), -+ max_open_dma_treshold), min_tx_1_2g5_treshold); -+ rx_1g_dmas = -+ MAX(MIN -+ (ROUND_DIV -+ ((remaing_dmas * rx_tx_raport), -+ weighted_remaining_ports), -+ max_open_dma_treshold), min_rx_1_2g5_treshold); -+ } -+ if (num_2g5_ports) { -+ tx_2g5_dmas = -+ MAX(MIN -+ (CEIL_DIV(remaing_dmas, weighted_remaining_ports), -+ max_open_dma_treshold), min_tx_1_2g5_treshold); -+ rx_2g5_dmas = -+ MAX(MIN -+ (CEIL_DIV -+ ((remaing_dmas * rx_tx_raport), -+ weighted_remaining_ports), -+ max_open_dma_treshold), min_rx_1_2g5_treshold); -+ -+ } -+ -+ /* Check if these settings is not exceding treshold */ -+ open_dmas_computed = num_1g_ports * tx_1g_dmas + -+ num_1g_ports * rx_1g_dmas + -+ num_2g5_ports * tx_2g5_dmas + -+ num_2g5_ports * rx_2g5_dmas + -+ num_10g_ports * tx_10g_dmas + -+ num_10g_ports * rx_10g_dmas + -+ num_oh_ports * oh_dmas + shared_ext_open_dma; -+ -+ /* overflow-leftover calculus */ -+ overflow = open_dmas_computed - max_fm_open_dma; -+ re_loop = true; -+ while (overflow > 0 && re_loop == true) { -+ re_loop = false; -+ if (num_1g_ports && overflow -+ && rx_1g_dmas > min_rx_1_2g5_treshold) { -+ rx_1g_dmas--; -+ overflow -= num_1g_ports; -+ re_loop = true; -+ } -+ if (num_2g5_ports && overflow -+ && rx_2g5_dmas > min_rx_1_2g5_treshold) { -+ rx_2g5_dmas--; -+ overflow -= num_2g5_ports; -+ re_loop = true; -+ } -+ if (num_10g_ports && overflow -+ && rx_10g_dmas > min_rx_10g_treshold) { -+ rx_10g_dmas--; -+ overflow -= num_10g_ports; -+ re_loop = true; -+ } -+ -+ if (num_1g_ports && overflow -+ && tx_1g_dmas > min_tx_1_2g5_treshold) { -+ tx_1g_dmas--; -+ overflow -= num_1g_ports; -+ re_loop = true; -+ } -+ if (num_2g5_ports && overflow -+ && tx_2g5_dmas > min_tx_1_2g5_treshold) { -+ tx_2g5_dmas--; -+ overflow -= num_2g5_ports; -+ re_loop = true; -+ } -+ if (num_10g_ports && overflow -+ && tx_10g_dmas > min_tx_10g_treshold) { -+ tx_10g_dmas--; -+ overflow -= num_10g_ports; -+ re_loop = true; -+ } -+ } -+ -+ if (overflow > 0) { -+ printk(KERN_ALERT -+ "This configuration will not work due to over open dma" -+ " allocation (%d open dmas)...\n", -+ overflow); -+ err = -1; -+ goto precalculated_open_dma_out; -+ } -+ -+ /* could remain leftovers... e.g. overflow=1, -+ 2ports => leftover=1 => shared=1 */ -+ open_dmas_computed = num_1g_ports * tx_1g_dmas + -+ num_1g_ports * rx_1g_dmas + -+ num_2g5_ports * tx_2g5_dmas + -+ num_2g5_ports * rx_2g5_dmas + -+ num_10g_ports * tx_10g_dmas + -+ num_10g_ports * rx_10g_dmas + -+ num_oh_ports * oh_dmas + shared_ext_open_dma; -+ -+ if (max_fm_open_dma - open_dmas_computed > 0) -+ shared_ext_open_dma = -+ MIN(shared_ext_open_dma + max_fm_open_dma - -+ open_dmas_computed, max_ext_open_dma_treshold); -+ -+ /* set open dmas */ -+ fm_resource_settings_info->tx_1g_dmas = tx_1g_dmas; -+ fm_resource_settings_info->rx_1g_dmas = rx_1g_dmas; -+ fm_resource_settings_info->tx_2g5_dmas = tx_2g5_dmas; -+ fm_resource_settings_info->rx_2g5_dmas = rx_2g5_dmas; -+ fm_resource_settings_info->tx_10g_dmas = tx_10g_dmas; -+ fm_resource_settings_info->rx_10g_dmas = rx_10g_dmas; -+ fm_resource_settings_info->oh_dmas = oh_dmas; -+ fm_resource_settings_info->shared_ext_open_dma = shared_ext_open_dma; -+ -+precalculated_open_dma_out: -+ printk(KERN_INFO " FMAN(%u) open dma settings:\n", -+ p_LnxWrpFmDev->id); -+ printk(KERN_INFO " - Total open dma available(%u)\n", -+ max_fm_open_dma); -+ if (num_1g_ports) { -+ printk(KERN_INFO " - 1G ports TX %u(%u)\n", num_1g_ports, -+ tx_1g_dmas); -+ printk(KERN_INFO " - 1G ports RX %u(%u)\n", num_1g_ports, -+ rx_1g_dmas); -+ } -+ if (num_2g5_ports) { -+ printk(KERN_INFO " - 2.5G ports TX %u(%u)\n", num_2g5_ports, -+ tx_2g5_dmas); -+ printk(KERN_INFO " - 2.5G ports RX %u(%u)\n", num_2g5_ports, -+ tx_2g5_dmas); -+ } -+ if (num_10g_ports) { -+ printk(KERN_INFO " - 10G ports TX %u(%u)\n", num_10g_ports, -+ tx_10g_dmas); -+ printk(KERN_INFO " - 10G ports RX %u(%u)\n", num_10g_ports, -+ rx_10g_dmas); -+ } -+ if (num_oh_ports) -+ printk(KERN_INFO " - OH-HC ports %u(%u)\n", num_oh_ports, -+ oh_dmas); -+ printk(KERN_INFO " - Shared extra open dma(%u)\n", -+ shared_ext_open_dma ? shared_ext_open_dma : 0); -+ -+ return err; -+} -+ -+#if !defined(FMAN_RESOURCES_UNIT_TEST) -+int fm_config_precalculate_open_dma(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = -+ (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ struct fm_resource_settings *fm_resource_settings_info = NULL; -+ t_FmPortRsrc numOfOpenDmas; -+ t_Error errCode; -+ -+ ASSERT_COND(p_LnxWrpFmDev != NULL); -+ fm_resource_settings_info = &p_LnxWrpFmDev->fm_resource_settings_info; -+ -+ memset(&numOfOpenDmas, 0, sizeof(t_FmPortRsrc)); -+ -+/* IF 1G PORT */ -+ if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX) -+ numOfOpenDmas.num = fm_resource_settings_info->tx_1g_dmas; -+ else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_RX) -+ numOfOpenDmas.num = fm_resource_settings_info->rx_1g_dmas; -+/* IF 2.5G PORT*/ -+ /* TODO: Not supported by LLD yet. */ -+ -+/* IF 10G PORT */ -+ else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_TX_10G) -+ numOfOpenDmas.num = fm_resource_settings_info->tx_10g_dmas; -+ else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_RX_10G) -+ numOfOpenDmas.num = fm_resource_settings_info->rx_10g_dmas; -+/* IF OH PORT */ -+ else -+ numOfOpenDmas.num = fm_resource_settings_info->oh_dmas; -+ -+ numOfOpenDmas.extra = fm_resource_settings_info->shared_ext_open_dma; -+ -+ errCode = FM_PORT_ConfigNumOfOpenDmas(p_LnxWrpFmPortDev->h_Dev, -+ &numOfOpenDmas); -+ if (errCode != E_OK) { -+ printk(KERN_WARNING -+ "FM_PORT_SetNumOfOpenDmas failed (errCode:0x%2x)", -+ errCode); -+ return -EIO; -+ } -+ -+ return 0; -+} -+#endif /*if !defined(FMAN_RESOURCES_UNIT_TEST)*/ -+ -+/* 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) -+{ -+ /* input parameters */ -+ struct fm_active_ports *fm_active_ports_info = NULL; -+ int num_1g_ports = 0; -+ int num_2g5_ports = 0; -+ int num_10g_ports = 0; -+ int num_oh_ports = 0; -+ -+ /* output parameters */ -+ struct fm_resource_settings *fm_resource_settings_info = NULL; -+ int tx_1g_tnums = 0, rx_1g_tnums = 0; -+ int tx_2g5_tnums = 0, rx_2g5_tnums = 0; -+ int tx_10g_tnums = 0, rx_10g_tnums = 0; -+ int oh_tnums = 0; -+ int shared_ext_tnums = 0; -+ int err = 0; -+ -+ /* open dma calculus */ -+ int default_and_treshold_rx_tx_10g_tnums = 16; /* DPDE_10g */ -+ int default_and_treshold_rx_tx_1g_2g5_tnums = 4; /* DPDE_1g */ -+ int default_and_treshold_oh_tnums = 2; /* Hell knows why */ -+ int max_tnums_treshold = 64; /* LLD: MAX_NUM_OF_TASKS */ -+ int max_ext_tnums_treshold = 8; /* LLD: MAX_NUM_OF_EXTRA_TASKS */ -+ int remaing_tnums = 0; -+ int tnums_computed = 0; -+ int leftovers = 0; -+ bool re_loop = true; -+ -+ /* check input parameters correctness */ -+ ASSERT_COND(p_LnxWrpFmDev != NULL); -+ fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info; -+ fm_resource_settings_info = &p_LnxWrpFmDev->fm_resource_settings_info; -+ ASSERT_COND(fm_active_ports_info != NULL); -+ ASSERT_COND(fm_resource_settings_info != NULL); -+ ASSERT_COND(fm_active_ports_info->num_tx_ports == -+ fm_active_ports_info->num_rx_ports); -+ ASSERT_COND(fm_active_ports_info->num_tx25_ports == -+ fm_active_ports_info->num_tx25_ports); -+ ASSERT_COND(fm_active_ports_info->num_tx10_ports == -+ fm_active_ports_info->num_tx10_ports); -+ -+ /* set input parameters */ -+ num_1g_ports = fm_active_ports_info->num_tx_ports; -+ num_2g5_ports = fm_active_ports_info->num_tx25_ports; -+ num_10g_ports = fm_active_ports_info->num_tx10_ports; -+ num_oh_ports = fm_active_ports_info->num_oh_ports; -+ -+ /* compute FMan TNUMs per port */ -+ /* ------------------------------------------------------- */ -+ if (num_1g_ports) { -+ tx_1g_tnums = default_and_treshold_rx_tx_1g_2g5_tnums; -+ rx_1g_tnums = default_and_treshold_rx_tx_1g_2g5_tnums; -+ } -+ if (num_2g5_ports) { -+ tx_2g5_tnums = default_and_treshold_rx_tx_1g_2g5_tnums; -+ rx_2g5_tnums = default_and_treshold_rx_tx_1g_2g5_tnums; -+ } -+ if (num_10g_ports) { -+ tx_10g_tnums = default_and_treshold_rx_tx_10g_tnums; -+ rx_10g_tnums = default_and_treshold_rx_tx_10g_tnums; -+ } -+ if (num_oh_ports) -+ oh_tnums = default_and_treshold_oh_tnums; -+ -+ shared_ext_tnums = num_10g_ports ? -+ max_ext_tnums_treshold : 2; /* DEFAULT_PORT_extraNumOfTasks */ -+ -+ /* based on total number of ports set open DMAs for all other ports */ -+ remaing_tnums = max_fm_tnums - -+ (oh_tnums * num_oh_ports) - -+ (tx_1g_tnums * num_1g_ports + rx_1g_tnums * num_1g_ports) - -+ (tx_2g5_tnums * num_2g5_ports + rx_2g5_tnums * num_2g5_ports) - -+ (tx_10g_tnums * num_10g_ports + rx_10g_tnums * num_10g_ports) - -+ shared_ext_tnums; -+ -+ if (remaing_tnums < 0) { -+ printk(KERN_ALERT -+ "This configuration will not work due to low number" -+ " of tnums (%u tnums) and number of total ports" -+ " available...\n", -+ max_fm_tnums); -+ err = -1; -+ goto precalculated_tnums_out; -+ } -+ -+ leftovers = remaing_tnums; -+ re_loop = true; -+ while (leftovers > 0 && re_loop == true) { -+ re_loop = false; -+ if (num_10g_ports && (leftovers - (int) num_10g_ports) >= 0 -+ && (rx_10g_tnums < max_tnums_treshold)) { -+ rx_10g_tnums++; -+ leftovers -= num_10g_ports; -+ re_loop = true; -+ } -+ -+ if (num_10g_ports && (leftovers - (int) num_10g_ports) >= 0 -+ && (tx_10g_tnums < max_tnums_treshold)) { -+ tx_10g_tnums++; -+ leftovers -= num_10g_ports; -+ re_loop = true; -+ } -+ -+ if (num_2g5_ports && (leftovers - (int) num_2g5_ports) >= 0 -+ && (rx_2g5_tnums < max_tnums_treshold)) { -+ rx_2g5_tnums++; -+ leftovers -= num_2g5_ports; -+ re_loop = true; -+ } -+ -+ if (num_2g5_ports && (leftovers - (int) num_2g5_ports) >= 0 -+ && (tx_2g5_tnums < max_tnums_treshold)) { -+ tx_2g5_tnums++; -+ leftovers -= num_2g5_ports; -+ re_loop = true; -+ } -+ -+ if (num_1g_ports && (leftovers - (int) num_1g_ports) >= 0 -+ && (rx_1g_tnums < max_tnums_treshold)) { -+ rx_1g_tnums++; -+ leftovers -= num_1g_ports; -+ re_loop = true; -+ } -+ -+ if (num_1g_ports && (leftovers - (int) num_1g_ports) >= 0 -+ && (tx_1g_tnums < max_tnums_treshold)) { -+ tx_1g_tnums++; -+ leftovers -= num_1g_ports; -+ re_loop = true; -+ } -+ } -+ -+ tnums_computed = -+ num_1g_ports * tx_1g_tnums + -+ num_1g_ports * rx_1g_tnums + -+ num_2g5_ports * tx_2g5_tnums + -+ num_2g5_ports * rx_2g5_tnums + -+ num_10g_ports * tx_10g_tnums + -+ num_10g_ports * rx_10g_tnums + -+ num_oh_ports * oh_tnums + -+ shared_ext_tnums; -+ -+ if (leftovers > 0) -+ shared_ext_tnums = -+ MIN(shared_ext_tnums + max_fm_tnums - tnums_computed, -+ max_ext_tnums_treshold); -+ -+ ASSERT_COND((oh_tnums * num_oh_ports) + -+ (tx_1g_tnums * num_1g_ports + rx_1g_tnums * num_1g_ports) + -+ (tx_2g5_tnums * num_2g5_ports + -+ rx_2g5_tnums * num_2g5_ports) + -+ (tx_10g_tnums * num_10g_ports + -+ rx_10g_tnums * num_10g_ports) + shared_ext_tnums <= -+ max_fm_tnums); -+ -+ /* set computed tnums */ -+ fm_resource_settings_info->tx_1g_tnums = tx_1g_tnums; -+ fm_resource_settings_info->rx_1g_tnums = rx_1g_tnums; -+ fm_resource_settings_info->tx_2g5_tnums = tx_2g5_tnums; -+ fm_resource_settings_info->rx_2g5_tnums = rx_2g5_tnums; -+ fm_resource_settings_info->tx_10g_tnums = tx_10g_tnums; -+ fm_resource_settings_info->rx_10g_tnums = rx_10g_tnums; -+ fm_resource_settings_info->oh_tnums = oh_tnums; -+ fm_resource_settings_info->shared_ext_tnums = shared_ext_tnums; -+ -+precalculated_tnums_out: -+ printk(KERN_INFO " FMAN(%u) Tnums settings:\n", p_LnxWrpFmDev->id); -+ printk(KERN_INFO " - Total Tnums available(%u)\n", max_fm_tnums); -+ if (num_1g_ports) { -+ printk(KERN_INFO " - 1G ports TX %u(%u)\n", num_1g_ports, -+ tx_1g_tnums); -+ printk(KERN_INFO " - 1G ports RX %u(%u)\n", num_1g_ports, -+ rx_1g_tnums); -+ } -+ if (num_2g5_ports) { -+ printk(KERN_INFO " - 2.5G ports TX %u(%u)\n", num_2g5_ports, -+ tx_2g5_tnums); -+ printk(KERN_INFO " - 2.5G ports RX %u(%u)\n", num_2g5_ports, -+ rx_2g5_tnums); -+ } -+ if (num_10g_ports) { -+ printk(KERN_INFO " - 10G ports TX %u(%u)\n", num_10g_ports, -+ tx_10g_tnums); -+ printk(KERN_INFO " - 10G ports RX %u(%u)\n", num_10g_ports, -+ rx_10g_tnums); -+ } -+ if (num_oh_ports) -+ printk(KERN_INFO " - OH-HC ports %u(%u)\n", num_oh_ports, -+ oh_tnums); -+ printk(KERN_INFO " - Shared extra tnums(%u)\n", shared_ext_tnums); -+ -+ return err; -+} -+ -+#if !defined(FMAN_RESOURCES_UNIT_TEST) -+int fm_config_precalculate_tnums(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = -+ (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ struct fm_resource_settings *fm_resource_settings_info = NULL; -+ t_FmPortRsrc numOfTask; -+ t_Error errCode; -+ -+ ASSERT_COND(p_LnxWrpFmDev != NULL); -+ fm_resource_settings_info = &p_LnxWrpFmDev->fm_resource_settings_info; -+ -+ memset(&numOfTask, 0, sizeof(t_FmPortRsrc)); -+ -+/* IF 1G PORT */ -+ if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX) -+ numOfTask.num = fm_resource_settings_info->tx_1g_tnums; -+ else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_RX) -+ numOfTask.num = fm_resource_settings_info->rx_1g_tnums; -+/* IF 2.5G PORT*/ -+ /* TODO: Not supported by LLD yet. */ -+ -+/* IF 10G PORT */ -+ else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_TX_10G) -+ numOfTask.num = fm_resource_settings_info->tx_10g_tnums; -+ else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_RX_10G) -+ numOfTask.num = fm_resource_settings_info->rx_10g_tnums; -+/* IF OH PORT */ -+ else -+ numOfTask.num = fm_resource_settings_info->oh_dmas; -+ -+ numOfTask.extra = fm_resource_settings_info->shared_ext_tnums; -+ -+ errCode = FM_PORT_ConfigNumOfTasks(p_LnxWrpFmPortDev->h_Dev, &numOfTask); -+ if (errCode != E_OK) { -+ printk(KERN_WARNING -+ "FM_PORT_SetNumOfTasks failed (errCode:0x%2x)", -+ errCode); -+ return -EIO; -+ } -+ -+ return 0; -+} -+#endif /*if !defined(FMAN_RESOURCES_UNIT_TEST)*/ -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_resources.h b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_resources.h -new file mode 100644 -index 0000000..1b72e1d ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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_ */ -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_resources_ut.c b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_resources_ut.c -new file mode 100644 -index 0000000..6c06a5a ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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; -+} -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_resources_ut.h b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_resources_ut.h -new file mode 100644 -index 0000000..063946e ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_resources_ut.make b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_resources_ut.make -new file mode 100644 -index 0000000..58009cd ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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) -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs.c b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs.c -new file mode 100644 -index 0000000..3f122b5 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/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 SysfsStats_t *sysfs_stats, -+ uint8_t *offset) -+{ -+ int i = 0; -+ -+ while (sysfs_stats[i].statisticName != NULL) { -+ if (strcmp(sysfs_stats[i].statisticName, attr_name) == 0) { -+ if (offset != NULL) -+ *offset = i; -+ return sysfs_stats[i].statisticCounter; -+ } -+ -+ i++; -+ } -+ WARN(1, "FMD: Should never get here!"); -+ return 0; -+} -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs.h b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs.h -new file mode 100644 -index 0000000..67cb2b0 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs.h -@@ -0,0 +1,67 @@ -+/* -+ * 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.h -+ -+ @Description FM sysfs functions. -+ -+*/ -+ -+#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 SysfsStats_t { -+ const char *statisticName; -+ uint8_t statisticCounter; -+}; -+ -+uint8_t fm_find_statistic_counter_by_name(const char *attr_name, -+ const struct SysfsStats_t *sysfs_stats, -+ uint8_t *offset); -+ -+#endif /* LNXWRP_SYSFS_H_ */ -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs_fm.c b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs_fm.c -new file mode 100644 -index 0000000..2cfc0b9 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs_fm.c -@@ -0,0 +1,573 @@ -+/* -+ * 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.c -+ -+ @Description FM sysfs related functions. -+ -+*/ -+ -+#include "lnxwrp_sysfs.h" -+#include "lnxwrp_fm.h" -+ -+enum e_FmDmaMatchStatistics { -+ e_FM_DMA_COUNTERS_CMQ_NOT_EMPTY, -+ e_FM_DMA_COUNTERS_BUS_ERROR, -+ e_FM_DMA_COUNTERS_READ_BUF_ECC_ERROR, -+ e_FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR, -+ e_FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR -+}; -+ -+static const struct SysfsStats_t fmSysfsStats[] = { -+ /* FM statistics */ -+ { -+ .statisticName = "enq_total_frame", -+ .statisticCounter = e_FM_COUNTERS_ENQ_TOTAL_FRAME, -+ }, -+ { -+ .statisticName = "deq_total_frame", -+ .statisticCounter = e_FM_COUNTERS_DEQ_TOTAL_FRAME, -+ }, -+ { -+ .statisticName = "deq_0", -+ .statisticCounter = e_FM_COUNTERS_DEQ_0, -+ }, -+ { -+ .statisticName = "deq_1", -+ .statisticCounter = e_FM_COUNTERS_DEQ_1, -+ }, -+ { -+ .statisticName = "deq_2", -+ .statisticCounter = e_FM_COUNTERS_DEQ_2, -+ }, -+ { -+ .statisticName = "deq_3", -+ .statisticCounter = e_FM_COUNTERS_DEQ_3, -+ }, -+ { -+ .statisticName = "deq_from_default", -+ .statisticCounter = e_FM_COUNTERS_DEQ_FROM_DEFAULT, -+ }, -+ { -+ .statisticName = "deq_from_context", -+ .statisticCounter = e_FM_COUNTERS_DEQ_FROM_CONTEXT, -+ }, -+ { -+ .statisticName = "deq_from_fd", -+ .statisticCounter = e_FM_COUNTERS_DEQ_FROM_FD, -+ }, -+ { -+ .statisticName = "deq_confirm", -+ .statisticCounter = e_FM_COUNTERS_DEQ_CONFIRM, -+ }, -+ /* FM:DMA statistics */ -+ { -+ .statisticName = "cmq_not_empty", -+ .statisticCounter = e_FM_DMA_COUNTERS_CMQ_NOT_EMPTY, -+ }, -+ { -+ .statisticName = "bus_error", -+ .statisticCounter = e_FM_DMA_COUNTERS_BUS_ERROR, -+ }, -+ { -+ .statisticName = "read_buf_ecc_error", -+ .statisticCounter = e_FM_DMA_COUNTERS_READ_BUF_ECC_ERROR, -+ }, -+ { -+ .statisticName = "write_buf_ecc_sys_error", -+ .statisticCounter = e_FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR, -+ }, -+ { -+ .statisticName = "write_buf_ecc_fm_error", -+ .statisticCounter = e_FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR, -+ }, -+ /* FM:PCD statistics */ -+ { -+ .statisticName = "pcd_kg_total", -+ .statisticCounter = e_FM_PCD_KG_COUNTERS_TOTAL, -+ }, -+ { -+ .statisticName = "pcd_plcr_yellow", -+ .statisticCounter = e_FM_PCD_PLCR_COUNTERS_YELLOW, -+ }, -+ { -+ .statisticName = "pcd_plcr_red", -+ .statisticCounter = e_FM_PCD_PLCR_COUNTERS_RED, -+ }, -+ { -+ .statisticName = "pcd_plcr_recolored_to_red", -+ .statisticCounter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, -+ }, -+ { -+ .statisticName = "pcd_plcr_recolored_to_yellow", -+ .statisticCounter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, -+ }, -+ { -+ .statisticName = "pcd_plcr_total", -+ .statisticCounter = e_FM_PCD_PLCR_COUNTERS_TOTAL, -+ }, -+ { -+ .statisticName = "pcd_plcr_length_mismatch", -+ .statisticCounter = e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, -+ }, -+ { -+ .statisticName = "pcd_prs_parse_dispatch", -+ .statisticCounter = e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, -+ }, -+ { -+ .statisticName = "pcd_prs_l2_parse_result_returned", -+ .statisticCounter = e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, -+ }, -+ { -+ .statisticName = "pcd_prs_l3_parse_result_returned", -+ .statisticCounter = e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, -+ }, -+ { -+ .statisticName = "pcd_prs_l4_parse_result_returned", -+ .statisticCounter = e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, -+ }, -+ { -+ .statisticName = "pcd_prs_shim_parse_result_returned", -+ .statisticCounter = e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, -+ }, -+ { -+ .statisticName = "pcd_prs_l2_parse_result_returned_with_err", -+ .statisticCounter = -+ e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR, -+ }, -+ { -+ .statisticName = "pcd_prs_l3_parse_result_returned_with_err", -+ .statisticCounter = -+ e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR, -+ }, -+ { -+ .statisticName = "pcd_prs_l4_parse_result_returned_with_err", -+ .statisticCounter = -+ e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR, -+ }, -+ { -+ .statisticName = "pcd_prs_shim_parse_result_returned_with_err", -+ .statisticCounter = -+ e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR, -+ }, -+ { -+ .statisticName = "pcd_prs_soft_prs_cycles", -+ .statisticCounter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, -+ }, -+ { -+ .statisticName = "pcd_prs_soft_prs_stall_cycles", -+ .statisticCounter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES, -+ }, -+ { -+ .statisticName = "pcd_prs_hard_prs_cycle_incl_stall_cycles", -+ .statisticCounter = -+ e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES, -+ }, -+ { -+ .statisticName = "pcd_prs_muram_read_cycles", -+ .statisticCounter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, -+ }, -+ { -+ .statisticName = "pcd_prs_muram_read_stall_cycles", -+ .statisticCounter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, -+ }, -+ { -+ .statisticName = "pcd_prs_muram_write_cycles", -+ .statisticCounter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, -+ }, -+ { -+ .statisticName = "pcd_prs_muram_write_stall_cycles", -+ .statisticCounter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, -+ }, -+ { -+ .statisticName = "pcd_prs_fpm_command_stall_cycles", -+ .statisticCounter = e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES, -+ }, -+ {} -+}; -+ -+/* 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_LnxWrpFmDev = NULL; -+ t_FmDmaStatus fmDmaStatus; -+ unsigned long flags = 0; -+ unsigned n = 0; -+ uint8_t counter_value = 0, counter = 0; -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+ p_LnxWrpFmDev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_LnxWrpFmDev == NULL)) -+ return -EINVAL; -+ -+ if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev) -+ return -EIO; -+ -+ counter = fm_find_statistic_counter_by_name( -+ attr->attr.name, -+ fmSysfsStats, NULL); -+ -+ local_irq_save(flags); -+ -+ memset(&fmDmaStatus, 0, sizeof(fmDmaStatus)); -+ FM_GetDmaStatus(p_LnxWrpFmDev->h_Dev, &fmDmaStatus); -+ -+ switch (counter) { -+ case e_FM_DMA_COUNTERS_CMQ_NOT_EMPTY: -+ counter_value = fmDmaStatus.cmqNotEmpty; -+ break; -+ case e_FM_DMA_COUNTERS_BUS_ERROR: -+ counter_value = fmDmaStatus.busError; -+ break; -+ case e_FM_DMA_COUNTERS_READ_BUF_ECC_ERROR: -+ counter_value = fmDmaStatus.readBufEccError; -+ break; -+ case e_FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR: -+ counter_value = fmDmaStatus.writeBufEccSysError; -+ break; -+ case e_FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR: -+ counter_value = fmDmaStatus.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_LnxWrpFmDev->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_LnxWrpFmDev = NULL; -+ unsigned long flags = 0; -+ unsigned n = 0, counter = 0; -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+ p_LnxWrpFmDev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_LnxWrpFmDev == NULL)) -+ return -EINVAL; -+ -+ if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev) -+ return -EIO; -+ -+ counter = fm_find_statistic_counter_by_name( -+ attr->attr.name, -+ fmSysfsStats, NULL); -+ -+ local_irq_save(flags); -+ -+ n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n", -+ p_LnxWrpFmDev->id, -+ FM_GetCounter(p_LnxWrpFmDev->h_Dev, -+ (e_FmCounters) counter)); -+ -+ 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_LnxWrpFmDev = NULL; -+ unsigned long flags = 0; -+ unsigned n = 0, counter = 0; -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+ p_LnxWrpFmDev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_LnxWrpFmDev == NULL)) -+ return -EINVAL; -+ -+ if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev || -+ !p_LnxWrpFmDev->h_PcdDev) -+ return -EIO; -+ -+ counter = fm_find_statistic_counter_by_name( -+ attr->attr.name, -+ fmSysfsStats, NULL); -+ -+ local_irq_save(flags); -+ -+ n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n", -+ p_LnxWrpFmDev->id, -+ FM_PCD_GetCounter(p_LnxWrpFmDev->h_PcdDev, -+ (e_FmPcdCounters) counter)); -+ -+ local_irq_restore(flags); -+ -+ 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(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 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 const struct attribute_group fm_dev_stats_attr_grp = { -+ .name = "statistics", -+ .attrs = fm_dev_stats_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_LnxWrpFmDev = NULL; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ -+ p_LnxWrpFmDev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_LnxWrpFmDev == NULL)) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ -+ n = snprintf(buf, PAGE_SIZE, "FM driver registers dump.\n"); -+ -+ if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev) -+ return -EIO; -+ else -+ FM_DumpRegs(p_LnxWrpFmDev->h_Dev); -+ -+ 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_pcd_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_LnxWrpFmDev = NULL; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ p_LnxWrpFmDev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_LnxWrpFmDev == NULL)) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, "FM driver registers dump.\n"); -+ -+ if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_PcdDev) -+ return -EIO; -+ else -+ FM_PCD_DumpRegs(p_LnxWrpFmDev->h_PcdDev); -+ -+ 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_pcd_regs, S_IRUGO, show_pcd_regs, NULL); -+ -+int fm_sysfs_create(struct device *dev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = NULL; -+ -+ if (dev == NULL) -+ return -EIO; -+ -+ p_LnxWrpFmDev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ -+ /* store to remove them when module is disabled */ -+ p_LnxWrpFmDev->dev_attr_regs = &dev_attr_fm_regs; -+ p_LnxWrpFmDev->dev_pcd_attr_regs = &dev_attr_fm_pcd_regs; -+ -+ /* Create sysfs statistics group for FM module */ -+ if (sysfs_create_group(&dev->kobj, &fm_dev_stats_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 || -+ device_create_file(dev, &dev_attr_fm_pcd_regs) != 0) -+ return -EIO; -+ -+ return 0; -+} -+ -+void fm_sysfs_destroy(struct device *dev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = NULL; -+ -+ if (WARN_ON(dev == NULL)) -+ return; -+ -+ p_LnxWrpFmDev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_LnxWrpFmDev == NULL)) -+ return; -+ -+ sysfs_remove_group(&dev->kobj, &fm_dev_stats_attr_grp); -+ device_remove_file(dev, p_LnxWrpFmDev->dev_attr_regs); -+ device_remove_file(dev, p_LnxWrpFmDev->dev_pcd_attr_regs); -+} -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs_fm.h b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs_fm.h -new file mode 100644 -index 0000000..8aff850 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs_fm.h -@@ -0,0 +1,48 @@ -+/* -+ * 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.h -+ -+ @Description FM sysfs functions. -+ -+*/ -+ -+#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); -+ -+#endif /* LNXWRP_SYSFS_FM_H_ */ -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs_fm_port.c b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs_fm_port.c -new file mode 100644 -index 0000000..97dacb7 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs_fm_port.c -@@ -0,0 +1,365 @@ -+/* -+ * 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.c -+ -+ @Description FM port sysfs related functions. -+ -+*/ -+ -+#include "lnxwrp_sysfs.h" -+#include "lnxwrp_fm.h" -+ -+static const struct SysfsStats_t portSysfsStats[] = { -+ /* RX/TX/OH common statistics */ -+ { -+ .statisticName = "port_frame", -+ .statisticCounter = e_FM_PORT_COUNTERS_FRAME, -+ }, -+ { -+ .statisticName = "port_discard_frame", -+ .statisticCounter = e_FM_PORT_COUNTERS_DISCARD_FRAME, -+ }, -+ { -+ .statisticName = "port_dealloc_buf", -+ .statisticCounter = e_FM_PORT_COUNTERS_DEALLOC_BUF, -+ }, -+ { -+ .statisticName = "port_enq_total", -+ .statisticCounter = e_FM_PORT_COUNTERS_ENQ_TOTAL, -+ }, -+ /* TX/OH */ -+ { -+ .statisticName = "port_length_err", -+ .statisticCounter = e_FM_PORT_COUNTERS_LENGTH_ERR, -+ }, -+ { -+ .statisticName = "port_unsupprted_format", -+ .statisticCounter = e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, -+ }, -+ { -+ .statisticName = "port_deq_total", -+ .statisticCounter = e_FM_PORT_COUNTERS_DEQ_TOTAL, -+ }, -+ { -+ .statisticName = "port_deq_from_default", -+ .statisticCounter = e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, -+ }, -+ { -+ .statisticName = "port_deq_confirm", -+ .statisticCounter = e_FM_PORT_COUNTERS_DEQ_CONFIRM, -+ }, -+ /* RX/OH */ -+ { -+ .statisticName = "port_rx_bad_frame", -+ .statisticCounter = e_FM_PORT_COUNTERS_RX_BAD_FRAME, -+ }, -+ { -+ .statisticName = "port_rx_large_frame", -+ .statisticCounter = e_FM_PORT_COUNTERS_RX_LARGE_FRAME, -+ }, -+ { -+ .statisticName = "port_rx_out_of_buffers_discard", -+ .statisticCounter = e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, -+ }, -+ { -+ .statisticName = "port_rx_filter_frame", -+ .statisticCounter = 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, "\tFM %d Port %d counter: %d\n", -+ p_LnxWrpFmDev->id, -+ p_LnxWrpFmPortDev->id, -+ 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, -+ /*RX*/ &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 = -+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev); -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ 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"); -+ FM_PORT_DumpRegs(p_LnxWrpFmPortDev->h_Dev); -+ } -+ -+ 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, 0x644, show_fm_port_regs, 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; -+ -+ /* Registers dump entry - in future will be moved to debugfs */ -+ if (device_create_file(dev, &dev_attr_fm_port_regs) != 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; -+ /* TODO:FMD16 e_FM_PORT_TYPE_DUMMY is accutally a HC port. -+ * NetCommSw defined this way... no idea why!!! */ -+ 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; -+ /* TODO:FMD16 e_FM_PORT_TYPE_DUMMY is accutally a HC port. -+ * NetCommSw defined this way... no idea why!!! */ -+ 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); -+} -diff --git a/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs_fm_port.h b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs_fm_port.h -new file mode 100644 -index 0000000..03b3a03 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/wrapper/lnxwrp_sysfs_fm_port.h -@@ -0,0 +1,48 @@ -+/* -+ * 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); -+ -+#endif /* LNXWRP_SYSFS_FM_PORT_H_ */ -diff --git a/drivers/net/dpa/NetCommSw/src/xx/Makefile b/drivers/net/dpa/NetCommSw/src/xx/Makefile -new file mode 100644 -index 0000000..870c1b0 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/xx/Makefile -@@ -0,0 +1,12 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+EXTRA_CFLAGS += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/dpa/NetCommSw/ncsw_config.mk -+ -+obj-y += fsl-ncsw-xx.o -+ -+fsl-ncsw-xx-objs := xx_linux.o udivdi3.o stdlib.o \ -+ module_strings.o -diff --git a/drivers/net/dpa/NetCommSw/src/xx/module_strings.c b/drivers/net/dpa/NetCommSw/src/xx/module_strings.c -new file mode 100644 -index 0000000..98c64fb ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/xx/module_strings.c -@@ -0,0 +1,45 @@ -+/* -+ * 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 */ -+}; -diff --git a/drivers/net/dpa/NetCommSw/src/xx/stdlib.c b/drivers/net/dpa/NetCommSw/src/xx/stdlib.c -new file mode 100644 -index 0000000..851bcf1 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/xx/stdlib.c -@@ -0,0 +1,264 @@ -+/* -+ * 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: stdlib.c */ -+/* */ -+/* Description: */ -+/* Standard library routines (externals) */ -+/* */ -+/* Modifications: */ -+/* ============== */ -+/* */ -+/*------------------------------------------------------*/ -+#include "stdlib_ext.h" -+#include "stdarg_ext.h" -+#include "ctype_ext.h" -+#include "string_ext.h" -+#include "std_ext.h" -+#include "xx_ext.h" -+ -+ -+#ifdef MODULE -+/** -+ * 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) -+{ -+ uint32_t result = 0,value; -+ -+ if (!base) { -+ base = 10; -+ if (*cp == '0') { -+ base = 8; -+ cp++; -+ if ((*cp == 'x') && isxdigit(cp[1])) { -+ cp++; -+ base = 16; -+ } -+ } -+ } -+ while (isxdigit(*cp) && -+ (value = (uint32_t)(isdigit(*cp) ? *cp-'0' : toupper((uint8_t)(*cp))-'A'+10)) < base) { -+ result = result*base + value; -+ cp++; -+ } -+ if (endp) -+ *endp = (char *)cp; -+ return result; -+} -+ -+/** -+ * 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) -+{ -+ if(*cp=='-') -+ return (long)(-strtoul(cp+1,endp,base)); -+ return (long)strtoul(cp,endp,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) -+{ -+ uint64_t result = 0,value; -+ -+ if (!base) { -+ base = 10; -+ if (*cp == '0') { -+ base = 8; -+ cp++; -+ if ((*cp == 'x') && isxdigit(cp[1])) { -+ cp++; -+ base = 16; -+ } -+ } -+ } -+ while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) -+ ? toupper((uint8_t)(*cp)) : *cp)-'A'+10) < base) { -+ result = result*base + value; -+ cp++; -+ } -+ if (endp) -+ *endp = (char *)cp; -+ return result; -+} -+ -+/** -+ * strtoll - convert a string to a int64 -+ * @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) -+{ -+ if(*cp=='-') -+ return (long long)(-strtoull(cp+1,endp,base)); -+ return (long long)(strtoull(cp,endp,base)); -+} -+ -+/** -+ * atoi - convert a string to a int -+ * @s: The start of the string -+ */ -+int atoi(const char *s) -+{ -+ int i=0; -+ const char **tmp_s = &s; -+ -+ while (isdigit(**tmp_s)) -+ i = i*10 + *((*tmp_s)++) - '0'; -+ return i; -+} -+ -+/** -+ * strlen - Find the length of a string -+ * @s: The string to be sized -+ */ -+size_t strlen(const char * s) -+{ -+ const char *sc; -+ -+ for (sc = s; *sc != '\0'; ++sc) -+ /* nothing */; -+ -+ return sc - 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) -+{ -+ const char *sc; -+ -+ for (sc = s; count-- && *sc != '\0'; ++sc) -+ /* nothing */; -+ -+ return sc - s; -+} -+ -+/** -+ * 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) -+{ -+ char *tmp = dest; -+ -+ while ((*dest++ = *src++) != '\0') -+ /* nothing */; -+ -+ return tmp; -+} -+#endif /* MODULE */ -+ -+/** -+ * 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 * strtok(char * s,const char * ct) -+{ -+ char *sbegin, *send; -+ -+ sbegin = s ? s : ___strtok; -+ if (!sbegin) { -+ return NULL; -+ } -+ sbegin += strspn(sbegin,ct); -+ if (*sbegin == '\0') { -+ ___strtok = NULL; -+ return( NULL ); -+ } -+ send = strpbrk( sbegin, ct); -+ if (send && *send != '\0') -+ *send++ = '\0'; -+ ___strtok = send; -+ return (sbegin); -+} -+ -+ -+#ifdef MODULE -+/** -+ * 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) -+{ -+ char *tmp = dest; -+ -+ while (count-- && (*dest++ = *src++) != '\0') -+ /* nothing */; -+ -+ return tmp; -+} -+ -+/** -+ * 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) -+{ -+ return vsnprintf(buf, INT32_MAX, fmt, args); -+} -+#endif /* MODULE */ -diff --git a/drivers/net/dpa/NetCommSw/src/xx/udivdi3.c b/drivers/net/dpa/NetCommSw/src/xx/udivdi3.c -new file mode 100644 -index 0000000..419e27e ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/xx/udivdi3.c -@@ -0,0 +1,132 @@ -+/* -+ * 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 -+#include -+#endif /* MODVERSIONS */ -+ -+#include -+#include -+#include -+ -+ -+#define BITS_PER_UNIT 8 -+#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT) -+ -+ -+typedef unsigned int UQItype __attribute__ ((mode (QI))); -+typedef int SItype __attribute__ ((mode (SI))); -+typedef unsigned int USItype __attribute__ ((mode (SI))); -+typedef int DItype __attribute__ ((mode (DI))); -+typedef int word_type __attribute__ ((mode (__word__))); -+typedef unsigned int UDItype __attribute__ ((mode (DI))); -+ -+struct DIstruct {SItype low, high;}; -+ -+typedef union -+{ -+ struct DIstruct s; -+ DItype ll; -+} DIunion; -+ -+ -+/* bit divisor, dividend and result. dynamic precision */ -+static __inline__ uint64_t _div64_64(uint64_t dividend, uint64_t divisor) -+{ -+ uint32_t d = divisor; -+ -+ if (divisor > 0xffffffffULL) -+ { -+ unsigned int shift = fls(divisor >> 32); -+ -+ d = divisor >> shift; -+ dividend >>= shift; -+ } -+ -+ /* avoid 64 bit division if possible */ -+ if (dividend >> 32) -+ do_div(dividend, d); -+ else -+ dividend = (uint32_t) dividend / d; -+ -+ return dividend; -+} -+ -+UDItype __udivdi3 (UDItype n, UDItype d) -+{ -+ return _div64_64(n, d); -+} -+ -+DItype __divdi3 (DItype n, DItype d) -+{ -+ DItype sign = 1; -+ if (n<0) -+ { -+ sign *= -1; -+ n *= -1; -+ } -+ if (d<0) -+ { -+ sign *= -1; -+ d *= -1; -+ } -+ return sign*_div64_64((UDItype)n, (UDItype)d); -+} -+ -+UDItype __umoddi3 (UDItype n, UDItype d) -+{ -+ return n-(_div64_64(n, d)*d); -+} -+ -+#ifdef MODULE -+word_type __ucmpdi2 (DItype a, DItype b) -+{ -+ DIunion au, bu; -+ -+ au.ll = a, bu.ll = b; -+ -+ if ((USItype) au.s.high < (USItype) bu.s.high) -+ return 0; -+ else if ((USItype) au.s.high > (USItype) bu.s.high) -+ return 2; -+ if ((USItype) au.s.low < (USItype) bu.s.low) -+ return 0; -+ else if ((USItype) au.s.low > (USItype) bu.s.low) -+ return 2; -+ return 1; -+} -+#endif /* MODULE */ -diff --git a/drivers/net/dpa/NetCommSw/src/xx/xx_linux.c b/drivers/net/dpa/NetCommSw/src/xx/xx_linux.c -new file mode 100644 -index 0000000..209d2e5 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/src/xx/xx_linux.c -@@ -0,0 +1,902 @@ -+/* -+ * 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 -+ -+#include -+ -+#ifdef BIGPHYSAREA_ENABLE -+#include -+#endif /* BIGPHYSAREA_ENABLE */ -+ -+#include -+#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", raw_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; -+ -+ local_irq_save(flags); -+ -+ return (uint32_t)flags; -+} -+ -+void XX_RestoreAllIntr(uint32_t flags) -+{ -+ local_irq_restore((unsigned long)flags); -+} -+ -+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; -+} -+ -+/*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_host *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))); -+} -diff --git a/drivers/net/dpa/NetCommSw/t4240_dflags.h b/drivers/net/dpa/NetCommSw/t4240_dflags.h -new file mode 100644 -index 0000000..435b0d2 ---- /dev/null -+++ b/drivers/net/dpa/NetCommSw/t4240_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 */ -diff --git a/drivers/net/dpa/dpa-ethtool.c b/drivers/net/dpa/dpa-ethtool.c -new file mode 100644 -index 0000000..11bcf3e ---- /dev/null -+++ b/drivers/net/dpa/dpa-ethtool.c -@@ -0,0 +1,241 @@ -+/* 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. -+ */ -+ -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+ -+#include -+ -+#include "dpaa_eth.h" -+ -+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_err(net_dev, "phy device not initialized\n"); -+ return -ENODEV; -+ } -+ -+ _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; -+ strncpy(drvinfo->version, VERSION, -+ sizeof(drvinfo->driver) - 1)[sizeof(drvinfo->version)-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; -+} -+ -+uint32_t __cold dpa_get_msglevel(struct net_device *net_dev) -+{ -+ return ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable; -+} -+ -+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; -+} -+ -+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; -+} -+ -+void __cold dpa_get_ringparam(struct net_device *net_dev, struct ethtool_ringparam *et_ringparam) -+{ -+ et_ringparam->rx_max_pending = 0; -+ et_ringparam->rx_mini_max_pending = 0; -+ et_ringparam->rx_jumbo_max_pending = 0; -+ et_ringparam->tx_max_pending = 0; -+ -+ et_ringparam->rx_pending = 0; -+ et_ringparam->rx_mini_pending = 0; -+ et_ringparam->rx_jumbo_pending = 0; -+ et_ringparam->tx_pending = 0; -+} -+ -+void __cold dpa_get_pauseparam(struct net_device *net_dev, struct ethtool_pauseparam *et_pauseparam) -+{ -+ 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; -+ } -+ if (unlikely(priv->mac_dev->phy_dev == NULL)) { -+ netdev_err(net_dev, "phy device not initialized\n"); -+ return; -+ } -+ -+ et_pauseparam->autoneg = priv->mac_dev->phy_dev->autoneg; -+} -+ -+int __cold dpa_set_pauseparam(struct net_device *net_dev, struct ethtool_pauseparam *et_pauseparam) -+{ -+ 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; -+ } -+ -+ priv->mac_dev->phy_dev->autoneg = et_pauseparam->autoneg; -+ -+ return 0; -+} -+ -+u32 dpa_get_rx_csum(struct net_device *dev) -+{ -+ netdev_info(dev, "Can't automatically tell the status of " -+ "Rx checksum validation. Feature not available yet.\n" -+ "Rx csum validation is most commonly performed (for supported " -+ "protocols) if a PCD scheme is applied on this interface.\n"); -+ return 0; -+} -+ -+int dpa_set_rx_csum(struct net_device *dev, uint32_t data) -+{ -+ netdev_info(dev, "Can't automatically %s Rx checksum validation." -+ "Feature not available yet.\n" -+ "Rx csum validation is most commonly performed (for supported " -+ "protocols) if a PCD scheme is applied on this interface.\n", -+ data ? "enable" : "disable"); -+ return -EINVAL; -+} -+ -+static int dpa_eth_op_set_flags(struct net_device *dev, u32 data) -+{ -+ return -EINVAL; -+} -+ -+const struct ethtool_ops dpa_ethtool_ops __devinitconst = { -+ .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_link = ethtool_op_get_link, -+ .get_ringparam = dpa_get_ringparam, -+ .get_pauseparam = dpa_get_pauseparam, -+ .set_pauseparam = dpa_set_pauseparam, -+ .get_tx_csum = ethtool_op_get_tx_csum, -+ .set_tx_csum = ethtool_op_set_tx_ipv6_csum, -+ .get_rx_csum = dpa_get_rx_csum, -+ .set_rx_csum = dpa_set_rx_csum, -+ .get_sg = ethtool_op_get_sg, -+ .set_sg = ethtool_op_set_sg, -+ .get_tso = ethtool_op_get_tso, -+ .set_tso = ethtool_op_set_tso, -+ .get_ufo = ethtool_op_get_ufo, -+ .set_ufo = ethtool_op_set_ufo, -+ .get_flags = ethtool_op_get_flags, -+ .set_flags = dpa_eth_op_set_flags, -+}; -diff --git a/drivers/net/dpa/dpaa_1588.c b/drivers/net/dpa/dpaa_1588.c -new file mode 100644 -index 0000000..8413b1e ---- /dev/null -+++ b/drivers/net/dpa/dpaa_1588.c -@@ -0,0 +1,621 @@ -+/* -+ * drivers/net/dpa/dpaa_1588.c -+ * -+ * 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_1588.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) { -+ 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; -+} -+ -+static int dpa_ptp_get_time(dma_addr_t fd_addr, u32 *high, u32 *low) -+{ -+ u8 *ts_addr = (u8 *)phys_to_virt(fd_addr); -+ u32 sec, nsec, mod; -+ u64 tmp; -+ -+ ts_addr += DPA_PTP_TIMESTAMP_OFFSET; -+ sec = *((u32 *)ts_addr); -+ nsec = *(((u32 *)ts_addr) + 1); -+ tmp = ((u64)sec << 32 | nsec) * DPA_PTP_NOMINAL_FREQ_PERIOD; -+ -+ mod = do_div(tmp, NANOSEC_PER_SECOND); -+ *high = (u32)tmp; -+ *low = mod; -+ -+ 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; -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ u32 access_len = ETH_ALEN + ETH_ALEN + DPA_ETYPE_LEN; -+#endif -+ struct iphdr *iph; -+ struct udphdr *udph; -+ struct ipv6hdr *ipv6h; -+ -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ /* 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; -+#endif -+ -+ *eth_type = *((u16 *)pos); -+ -+ /* Check if inner tag is here */ -+ if (*eth_type == ETH_P_8021Q) { -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ access_len += DPA_VLAN_TAG_LEN; -+ -+ if (!pskb_may_pull(skb, access_len)) -+ return NULL; -+#endif -+ -+ 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; -+ -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ if (!pskb_may_pull(skb, access_len + PTP_OFFS_MSG_TYPE + 1)) -+ return NULL; -+#endif -+ -+ 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; -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ access_len += sizeof(struct iphdr); -+ -+ if (!pskb_may_pull(skb, access_len)) -+ return NULL; -+#endif -+ -+ if (ntohs(iph->protocol) != IPPROTO_UDP) -+ return NULL; -+ -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ access_len += iph->ihl * 4 - sizeof(struct iphdr) + -+ sizeof(struct udphdr); -+ -+ if (!pskb_may_pull(skb, access_len)) -+ return NULL; -+#endif -+ -+ 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; -+ -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ access_len += sizeof(struct ipv6hdr) + sizeof(struct udphdr); -+#endif -+ -+ 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(struct net_device *dev, struct sk_buff *skb, -+ dma_addr_t fd_addr, struct dpa_ptp_data *ptp_data) -+{ -+ u32 sec, nsec; -+ 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; -+ } -+ -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ if (!pskb_may_pull(skb, ptp_loc - skb->data + PTP_OFFS_SEQ_ID + 2)) -+ return -EINVAL; -+#endif -+ -+ 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); -+ -+ dpa_ptp_get_time(fd_addr, &sec, &nsec); -+ ptp_data->ts.sec = (u64)sec; -+ ptp_data->ts.nsec = nsec; -+ -+ return 0; -+} -+ -+void dpa_ptp_store_txstamp(struct net_device *dev, struct sk_buff *skb, -+ const struct qm_fd *fd) -+{ -+ struct dpa_priv_s *priv = netdev_priv(dev); -+ struct dpa_ptp_tsu *tsu = priv->tsu; -+ struct dpa_ptp_data ptp_tx_data; -+ dma_addr_t fd_addr = qm_fd_addr(fd); -+ int ret; -+ -+ ret = dpa_ptp_store_stamp(dev, skb, fd_addr, &ptp_tx_data); -+ if (ret) -+ return; -+ dpa_ptp_insert(&tsu->tx_timestamps, &ptp_tx_data); -+} -+ -+void dpa_ptp_store_rxstamp(struct net_device *dev, struct sk_buff *skb, -+ const struct qm_fd *fd) -+{ -+ struct dpa_priv_s *priv = netdev_priv(dev); -+ struct dpa_ptp_tsu *tsu = priv->tsu; -+ struct dpa_ptp_data ptp_rx_data; -+ dma_addr_t fd_addr = qm_fd_addr(fd); -+ int ret; -+ -+ ret = dpa_ptp_store_stamp(dev, skb, -+ fd_addr + fm_get_rx_extra_headroom(), -+ &ptp_rx_data); -+ if (ret) -+ 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(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; -+ if (mac_dev->fm_rtc_set_alarm) -+ mac_dev->fm_rtc_set_alarm(tsu->dpa_priv->net_dev, 0, tmp); -+ if (mac_dev->fm_rtc_set_fiper) -+ mac_dev->fm_rtc_set_fiper(tsu->dpa_priv->net_dev, 0, fiper); -+ -+ if (mac_dev->fm_rtc_enable) -+ mac_dev->fm_rtc_enable(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(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(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(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(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(dev); -+ if (mac_dev->ptp_enable) -+ mac_dev->ptp_enable(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(dev); -+ if (mac_dev->ptp_disable) -+ mac_dev->ptp_disable(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; -+ -+ memset(tsu, 0, sizeof(*tsu)); -+ 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); -+ -+static int __init __cold dpa_ptp_load(void) -+{ -+ return 0; -+} -+module_init(dpa_ptp_load); -+ -+static void __exit __cold dpa_ptp_unload(void) -+{ -+} -+module_exit(dpa_ptp_unload); -diff --git a/drivers/net/dpa/dpaa_1588.h b/drivers/net/dpa/dpaa_1588.h -new file mode 100644 -index 0000000..eda0e3a ---- /dev/null -+++ b/drivers/net/dpa/dpaa_1588.h -@@ -0,0 +1,141 @@ -+/* -+ * drivers/net/dpa/dpaa_1588.h -+ * -+ * 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 2048 -+#define DEFAULT_PTP_TX_BUF_SZ 1024 -+ -+/* 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 DPA_PTP_TIMESTAMP_OFFSET 0x30 -+#define DPA_PTP_NOMINAL_FREQ_PERIOD 5 /* 5ns -> 200M */ -+#define NANOSEC_PER_SECOND 1000000000 -+ -+/* 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(struct net_device *dev, struct sk_buff *skb, -+ const struct qm_fd *fd); -+extern void dpa_ptp_store_rxstamp(struct net_device *dev, struct sk_buff *skb, -+ const struct qm_fd *fd); -+extern int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd); -+#endif -diff --git a/drivers/net/dpa/dpaa_eth-common.h b/drivers/net/dpa/dpaa_eth-common.h -new file mode 100644 -index 0000000..17c2382 ---- /dev/null -+++ b/drivers/net/dpa/dpaa_eth-common.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 __DPA_COMMON_H -+#define __DPA_COMMON_H -+ -+#include /* pr_*() */ -+#include /* dev_*() */ -+#include /* smp_processor_id() */ -+ -+#define __hot -+ -+#define cpu_printk(level, format, arg...) \ -+ pr_##level("cpu%d: " format, raw_smp_processor_id(), ##arg) -+ -+/* Simple enum of FQ types - used for array indexing */ -+enum {RX, TX}; -+ -+/* 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 Confirmation FQs (actually Rx FQs) */ -+ FQ_TYPE_TX_ERROR, /* Tx Error FQs (these are actually Rx FQs) */ -+#ifdef CONFIG_DPA_TX_RECYCLE -+ FQ_TYPE_TX_RECYCLE, /* Tx FQs for recycleable frames only */ -+#endif -+}; -+ -+ -+#define DPA_PARSE_RESULTS_SIZE sizeof(t_FmPrsResult) -+#define DPA_HASH_RESULTS_SIZE 16 -+ -+#define DPA_TX_PRIV_DATA_SIZE 16 -+ -+#define dpaa_eth_init_port(type, port, param, errq_id, defq_id, priv_size, \ -+ has_timer) \ -+{ \ -+ param.errq = errq_id; \ -+ param.defq = defq_id; \ -+ param.priv_data_size = priv_size; \ -+ param.parse_results = true; \ -+ param.hash_results = true; \ -+ param.frag_enable = false; \ -+ param.time_stamp = has_timer; \ -+ fm_set_##type##_port_params(port, ¶m); \ -+} -+ -+#endif /* __DPA_COMMON_H */ -diff --git a/drivers/net/dpa/dpaa_eth.c b/drivers/net/dpa/dpaa_eth.c -new file mode 100644 -index 0000000..23d450b ---- /dev/null -+++ b/drivers/net/dpa/dpaa_eth.c -@@ -0,0 +1,4251 @@ -+/* -+ * 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. -+ */ -+ -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+ -+#include -+#include -+#include -+#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 /* get_hard_smp_processor_id() */ -+#ifdef CONFIG_DEBUG_FS -+#include -+#endif -+#include -+ -+#include "fsl_fman.h" -+#include "fm_ext.h" -+#include "fm_port_ext.h" -+ -+#include "mac.h" -+#include "dpaa_eth.h" -+#include "dpaa_1588.h" -+ -+#define ARRAY2_SIZE(arr) (ARRAY_SIZE(arr) * ARRAY_SIZE((arr)[0])) -+ -+/* DPAA platforms benefit from hardware-assisted queue management */ -+#define DPA_NETIF_FEATURES (NETIF_F_HW_QDISC | NETIF_F_HW_ACCEL_MQ) -+ -+#define DEFAULT_COUNT 128 -+#define REFILL_THRESHOLD 80 -+ -+#define DPA_NAPI_WEIGHT 64 -+ -+/* Size in bytes of the Congestion State notification threshold on 10G ports */ -+#define DPA_CS_THRESHOLD_10G 0x10000000 -+/* -+ * Size in bytes of the 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. -+ */ -+#define DPA_CS_THRESHOLD_1G 0x06000000 -+ -+/* Size in bytes of the FQ taildrop threshold */ -+#define DPA_FQ_TD 0x200000 -+ -+/* S/G table requires at least 256 bytes */ -+#define SGT_BUFFER_SIZE DPA_BP_SIZE(256) -+ -+/* Maximum frame size on Tx for which skb copying is preferrable to -+ * creating a S/G frame */ -+#define DPA_SKB_COPY_MAX_SIZE 256 -+ -+/* Valid checksum indication */ -+#define DPA_CSUM_VALID 0xFFFF -+ -+/* Maximum offset value for a contig or sg FD (represented on 9bits) */ -+#define DPA_MAX_FD_OFFSET ((1 << 9) - 1) -+ -+/* -+ * Maximum size of a buffer that is to be recycled back to the buffer pool. -+ * The value is arbitrary, but tries to reach a balance such that originating -+ * frames may get recycled, while forwarded skbs that get reallocated on Tx -+ * aren't allowed to grow unboundedly. -+ */ -+#define DPA_BP_MAX_BUF_SIZE (DEFAULT_BUF_SIZE + 256) -+ -+#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 __devinitdata tx_timeout = 1000; -+module_param(tx_timeout, ushort, S_IRUGO); -+MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms"); -+ -+#ifdef CONFIG_DEBUG_FS -+static struct dentry *dpa_debugfs_root; -+#endif -+ -+/* dpaa_eth mirror for the FMan values */ -+static int dpa_rx_extra_headroom; -+static int dpa_max_frm; -+ -+static const char rtx[][3] = { -+ [RX] = "RX", -+ [TX] = "TX" -+}; -+ -+#if defined(CONFIG_FSL_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)); -+#endif /* CONFIG_DPAA_FMAN_UNIT_TESTS */ -+ -+/* BM */ -+ -+#define DPAA_ETH_MAX_PAD (L1_CACHE_BYTES * 8) -+ -+static struct dpa_bp *dpa_bp_array[64]; -+ -+static struct dpa_bp *default_pool; -+ -+/* A set of callbacks for hooking into the fastpath at different points. */ -+static struct dpaa_eth_hooks_s 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); -+ -+ -+struct dpa_bp *dpa_bpid2pool(int bpid) -+{ -+ return dpa_bp_array[bpid]; -+} -+ -+static void dpa_bp_depletion(struct bman_portal *portal, -+ struct bman_pool *pool, void *cb_ctx, int depleted) -+{ -+ if (net_ratelimit()) -+ pr_err("Invalid Pool depleted notification!\n"); -+} -+ -+/* -+ * Copy from a memory region that requires kmapping to a linear buffer, -+ * taking into account page boundaries in the source -+ */ -+static void -+copy_from_unmapped_area(void *dest, dma_addr_t phys_start, size_t buf_size) -+{ -+ struct page *page; -+ size_t size, offset; -+ void *page_vaddr; -+ -+ while (buf_size > 0) { -+ offset = offset_in_page(phys_start); -+ size = (offset + buf_size > PAGE_SIZE) ? -+ PAGE_SIZE - offset : buf_size; -+ -+ page = pfn_to_page(phys_start >> PAGE_SHIFT); -+ page_vaddr = kmap_atomic(page); -+ -+ memcpy(dest, page_vaddr + offset, size); -+ -+ kunmap_atomic(page_vaddr); -+ -+ phys_start += size; -+ dest += size; -+ buf_size -= size; -+ } -+} -+ -+/* -+ * Copy to a memory region that requires kmapping from a linear buffer, -+ * taking into account page boundaries in the destination -+ */ -+static void -+copy_to_unmapped_area(dma_addr_t phys_start, void *src, size_t buf_size) -+{ -+ struct page *page; -+ size_t size, offset; -+ void *page_vaddr; -+ -+ while (buf_size > 0) { -+ offset = offset_in_page(phys_start); -+ size = (offset + buf_size > PAGE_SIZE) ? -+ PAGE_SIZE - offset : buf_size; -+ -+ page = pfn_to_page(phys_start >> PAGE_SHIFT); -+ page_vaddr = kmap_atomic(page); -+ -+ memcpy(page_vaddr + offset, src, size); -+ -+ kunmap_atomic(page_vaddr); -+ -+ phys_start += size; -+ src += size; -+ buf_size -= size; -+ } -+} -+ -+#ifndef CONFIG_DPAA_ETH_SG_SUPPORT -+static void dpa_bp_add_8(const struct dpa_bp *dpa_bp) -+{ -+ struct bm_buffer bmb[8]; -+ struct sk_buff **skbh; -+ dma_addr_t addr; -+ int i; -+ struct sk_buff *skb; -+ int *count_ptr; -+ -+ count_ptr = per_cpu_ptr(dpa_bp->percpu_count, smp_processor_id()); -+ -+ for (i = 0; i < 8; i++) { -+ /* -+ * The buffers tend to be aligned all to the same cache -+ * index. A standard dequeue operation pulls in 15 packets. -+ * This means that when it stashes, it evicts half of the -+ * packets it's stashing. In order to prevent that, we pad -+ * by a variable number of cache lines, to reduce collisions. -+ * We always pad by at least 1 cache line, because we want -+ * a little extra room at the beginning for IPSec and to -+ * accommodate NET_IP_ALIGN. -+ */ -+ int pad = (i + 1) * L1_CACHE_BYTES; -+ -+ skb = dev_alloc_skb(dpa_bp->size + pad); -+ if (unlikely(!skb)) { -+ printk(KERN_ERR "dev_alloc_skb() failed\n"); -+ bm_buffer_set64(&bmb[i], 0); -+ break; -+ } -+ -+ skbh = (struct sk_buff **)(skb->head + pad); -+ *skbh = skb; -+ -+ /* -+ * Here we need to map only for device write (DMA_FROM_DEVICE), -+ * but on Tx recycling we may also get buffers in the pool that -+ * are mapped bidirectionally. -+ * Use DMA_BIDIRECTIONAL here as well to avoid any -+ * inconsistencies when unmapping. -+ */ -+ addr = dma_map_single(dpa_bp->dev, skb->head + pad, -+ dpa_bp->size, DMA_BIDIRECTIONAL); -+ if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) { -+ dev_err(dpa_bp->dev, "DMA mapping failed"); -+ break; -+ } -+ -+ bm_buffer_set64(&bmb[i], addr); -+ } -+ -+ /* Avoid releasing a completely null buffer; bman_release() requires -+ * at least one buf. */ -+ if (likely(i)) { -+ /* -+ * 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 (bman_release(dpa_bp->pool, bmb, i, 0)) -+ cpu_relax(); -+ -+ *count_ptr += i; -+ } -+} -+ -+void dpa_make_private_pool(struct dpa_bp *dpa_bp) -+{ -+ int i; -+ -+ dpa_bp->percpu_count = __alloc_percpu(sizeof(*dpa_bp->percpu_count), -+ __alignof__(*dpa_bp->percpu_count)); -+ -+ /* Give each cpu an allotment of "count" buffers */ -+ for_each_online_cpu(i) { -+ int *thiscount; -+ int *countptr; -+ int j; -+ thiscount = per_cpu_ptr(dpa_bp->percpu_count, -+ smp_processor_id()); -+ countptr = per_cpu_ptr(dpa_bp->percpu_count, i); -+ -+ for (j = 0; j < dpa_bp->target_count; j += 8) -+ dpa_bp_add_8(dpa_bp); -+ -+ /* Adjust the counts */ -+ *countptr = j; -+ -+ if (countptr != thiscount) -+ *thiscount = *thiscount - j; -+ } -+} -+#endif /* CONFIG_DPAA_ETH_SG_SUPPORT */ -+ -+static void dpaa_eth_seed_pool(struct dpa_bp *bp) -+{ -+ int count = bp->target_count; -+ size_t addr = bp->paddr; -+ -+ while (count) { -+ struct bm_buffer bufs[8]; -+ int 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(); -+ } -+} -+ -+/* -+ * Add buffers/pages/skbuffs for Rx processing whenever bpool count falls below -+ * REFILL_THRESHOLD. -+ */ -+static void dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv) -+{ -+ int *countptr = percpu_priv->dpa_bp_count; -+ int count = *countptr; -+ const struct dpa_bp *dpa_bp = percpu_priv->dpa_bp; -+ -+#ifndef CONFIG_DPAA_ETH_SG_SUPPORT -+ if (unlikely(count < REFILL_THRESHOLD)) { -+ int i; -+ -+ for (i = count; i < DEFAULT_COUNT; i += 8) -+ dpa_bp_add_8(dpa_bp); -+ } -+#else -+ /* Add pages to the buffer pool */ -+ while (count < DEFAULT_COUNT) -+ count += _dpa_bp_add_8_pages(dpa_bp); -+ *countptr = count; -+ -+ /* Add skbs to the percpu skb list, reuse var count */ -+ count = percpu_priv->skb_count; -+ if (unlikely(count < DEFAULT_SKB_COUNT / 4)) -+ dpa_list_add_skbs(percpu_priv, -+ DEFAULT_SKB_COUNT - count); -+#endif -+} -+ -+static int dpa_make_shared_port_pool(struct dpa_bp *bp) -+{ -+ /* -+ * 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; -+ -+ devm_request_mem_region(bp->dev, bp->paddr, -+ bp->size * bp->config_count, KBUILD_MODNAME); -+ bp->vaddr = devm_ioremap_prot(bp->dev, bp->paddr, -+ bp->size * bp->config_count, 0); -+ if (bp->vaddr == NULL) { -+ pr_err("Could not map memory for pool %d\n", bp->bpid); -+ return -EIO; -+ } -+ -+ if (bp->seed_pool) -+ dpaa_eth_seed_pool(bp); -+ -+ return 0; -+} -+ -+static int __devinit __must_check __attribute__((nonnull)) -+dpa_bp_alloc(struct dpa_bp *dpa_bp) -+{ -+ int err; -+ struct bman_pool_params bp_params; -+ struct platform_device *pdev; -+ -+ BUG_ON(dpa_bp->size == 0); -+ BUG_ON(dpa_bp->config_count == 0); -+ -+ bp_params.flags = BMAN_POOL_FLAG_DEPLETION; -+ bp_params.cb = dpa_bp_depletion; -+ bp_params.cb_ctx = dpa_bp; -+ -+ /* We support two options. Either a global shared pool, or -+ * a specified pool. If the pool is specified, we only -+ * create one per bpid */ -+ if (dpa_bp->kernel_pool && default_pool) { -+ atomic_inc(&default_pool->refs); -+ return 0; -+ } -+ -+ if (dpa_bp_array[dpa_bp->bpid]) { -+ atomic_inc(&dpa_bp_array[dpa_bp->bpid]->refs); -+ 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 = bman_get_params(dpa_bp->pool)->bpid; -+ -+ pdev = platform_device_register_simple("dpaa_eth_bpool", -+ dpa_bp->bpid, NULL, 0); -+ if (IS_ERR(pdev)) { -+ err = PTR_ERR(pdev); -+ goto pdev_register_failed; -+ } -+ -+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(40)); -+ if (err) -+ goto pdev_mask_failed; -+ -+ dpa_bp->dev = &pdev->dev; -+ -+ if (dpa_bp->kernel_pool) { -+ dpa_make_private_pool(dpa_bp); -+ if (!default_pool) -+ default_pool = dpa_bp; -+ } else { -+ err = dpa_make_shared_port_pool(dpa_bp); -+ if (err) -+ goto make_shared_pool_failed; -+ } -+ -+ dpa_bp_array[dpa_bp->bpid] = dpa_bp; -+ -+ atomic_set(&dpa_bp->refs, 1); -+ -+ return 0; -+ -+make_shared_pool_failed: -+pdev_mask_failed: -+ platform_device_unregister(pdev); -+pdev_register_failed: -+ bman_free_pool(dpa_bp->pool); -+ -+ return err; -+} -+ -+#ifndef CONFIG_DPAA_ETH_SG_SUPPORT -+static inline void _dpa_bp_free_buf(void *addr) -+{ -+ struct sk_buff **skbh = addr; -+ struct sk_buff *skb; -+ -+ skb = *skbh; -+ dev_kfree_skb_any(skb); -+} -+#else -+static inline void _dpa_bp_free_buf(void *addr) -+{ -+ free_page((unsigned long)addr); -+} -+#endif -+ -+static void __cold __attribute__((nonnull)) -+_dpa_bp_free(struct dpa_bp *dpa_bp) -+{ -+ struct dpa_bp *bp = dpa_bpid2pool(dpa_bp->bpid); -+ -+ if (!atomic_dec_and_test(&bp->refs)) -+ return; -+ -+ if (bp->kernel_pool) { -+ int num; -+ -+ do { -+ struct bm_buffer bmb[8]; -+ int i; -+ -+ num = bman_acquire(bp->pool, bmb, 8, 0); -+ -+ 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); -+ -+ _dpa_bp_free_buf(phys_to_virt(addr)); -+ } -+ } while (num == 8); -+ } -+ -+ dpa_bp_array[bp->bpid] = 0; -+ bman_free_pool(bp->pool); -+} -+ -+static void __cold __attribute__((nonnull)) -+dpa_bp_free(struct dpa_priv_s *priv, struct dpa_bp *dpa_bp) -+{ -+ int i; -+ -+ for (i = 0; i < priv->bp_count; i++) -+ _dpa_bp_free(&priv->dpa_bp[i]); -+} -+ -+/* QM */ -+ -+static struct qman_fq *_dpa_get_tx_conf_queue(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 priv->conf_fqs[i]; -+ -+ return NULL; -+} -+ -+static int __devinit __must_check __attribute__((nonnull)) -+_dpa_fq_alloc(struct list_head *list, struct dpa_fq *dpa_fq) -+{ -+ int _errno; -+ const struct dpa_priv_s *priv; -+ struct device *dev; -+ struct qman_fq *fq; -+ struct qm_mcc_initfq initfq; -+ struct qman_fq *confq; -+ -+ 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) { -+ 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; -+ -+ /* 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) { -+ initfq.we_mask |= QM_INITFQ_WE_CGID; -+ initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE; -+ initfq.fqd.cgid = 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 = min(sizeof(struct sk_buff) + -+ DPA_BP_HEAD, (size_t)FSL_QMAN_MAX_OAL); -+ } -+ -+ /* -+ * For MAC-less devices we only get here for RX frame queues -+ * initialization, which are the TX queues of the other -+ * partition. -+ * It is safe to rely on one partition to set the FQ taildrop -+ * threshold for the TX queues of the other partition -+ * because the ERN notifications will be received by the -+ * partition doing qman_enqueue. -+ */ -+ if (!priv->mac_dev) { -+ 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) { -+ confq = _dpa_get_tx_conf_queue(priv, &dpa_fq->fq_base); -+ if (confq) { -+ initfq.we_mask |= QM_INITFQ_WE_CONTEXTA | -+ QM_INITFQ_WE_CONTEXTB; -+ /* CTXA[OVFQ] = 1 */ -+ initfq.fqd.context_a.hi = 0x80000000; -+ initfq.fqd.context_a.lo = 0x0; -+ initfq.fqd.context_b = qman_fq_fqid(confq); -+ } -+ } -+ -+#ifdef CONFIG_DPA_TX_RECYCLE -+ /* -+ * Configure the Tx queues for recycled frames, such that the -+ * buffers are released by FMan and no confirmation is sent -+ */ -+ if (dpa_fq->fq_type == FQ_TYPE_TX_RECYCLE) { -+ initfq.we_mask |= QM_INITFQ_WE_CONTEXTA | -+ QM_INITFQ_WE_CONTEXTB; -+ /* -+ * ContextA: OVFQ=1 (use ContextB FQID for confirmation) -+ * OVOM=1 (use contextA2 bits instead of ICAD) -+ * A2V=1 (contextA A2 field is valid) -+ * B0V=1 (contextB field is valid) -+ * ContextA A2: EBD=1 (deallocate buffers inside FMan) -+ * ContextB: Confirmation FQID = 0 -+ */ -+ initfq.fqd.context_a.hi = 0x96000000; -+ initfq.fqd.context_a.lo = 0x80000000; -+ initfq.fqd.context_b = 0; -+ } -+#endif -+ -+ /* 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) { -+ 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); -+ list_add_tail(&dpa_fq->list, list); -+ -+ return 0; -+} -+ -+static 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; -+} -+ -+static 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; -+} -+ -+static inline void * __must_check __attribute__((nonnull)) -+dpa_phys2virt(const struct dpa_bp *dpa_bp, dma_addr_t addr) -+{ -+ return dpa_bp->vaddr + (addr - dpa_bp->paddr); -+} -+ -+static void -+dpa_release_sgt(struct qm_sg_entry *sgt, struct dpa_bp *dpa_bp, -+ struct bm_buffer *bmb) -+{ -+ int i = 0, j; -+ -+ do { -+ dpa_bp = dpa_bpid2pool(sgt[i].bpid); -+ BUG_ON(IS_ERR(dpa_bp)); -+ -+ j = 0; -+ do { -+ BUG_ON(sgt[i].extension); -+ -+ bmb[j].hi = sgt[i].addr_hi; -+ bmb[j].lo = sgt[i].addr_lo; -+ -+ j++; i++; -+ } while (j < ARRAY_SIZE(bmb) && -+ !sgt[i-1].final && -+ sgt[i-1].bpid == sgt[i].bpid); -+ -+ while (bman_release(dpa_bp->pool, bmb, j, 0)) -+ cpu_relax(); -+ } while (!sgt[i-1].final); -+} -+ -+static void -+dpa_fd_release_sg(const struct net_device *net_dev, -+ const struct qm_fd *fd) -+{ -+ const struct dpa_priv_s *priv; -+ struct qm_sg_entry *sgt; -+ struct dpa_bp *_dpa_bp, *dpa_bp; -+ struct bm_buffer _bmb, bmb[8]; -+ -+ priv = netdev_priv(net_dev); -+ -+ _bmb.hi = fd->addr_hi; -+ _bmb.lo = fd->addr_lo; -+ -+ _dpa_bp = dpa_bpid2pool(fd->bpid); -+ -+ if (_dpa_bp->vaddr) { -+ sgt = dpa_phys2virt(_dpa_bp, bm_buf_addr(&_bmb)) + -+ dpa_fd_offset(fd); -+ dpa_release_sgt(sgt, dpa_bp, bmb); -+ } else { -+ sgt = kmalloc(DPA_SGT_MAX_ENTRIES * sizeof(*sgt), GFP_ATOMIC); -+ if (sgt == NULL) { -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ netdev_err(net_dev, -+ "Memory allocation failed\n"); -+ return; -+ } -+ -+ copy_from_unmapped_area(sgt, bm_buf_addr(&_bmb) + -+ dpa_fd_offset(fd), -+ min(DPA_SGT_MAX_ENTRIES * sizeof(*sgt), -+ _dpa_bp->size)); -+ dpa_release_sgt(sgt, dpa_bp, bmb); -+ kfree(sgt); -+ } -+ -+ while (bman_release(_dpa_bp->pool, &_bmb, 1, 0)) -+ cpu_relax(); -+} -+ -+void __attribute__((nonnull)) -+dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd) -+{ -+ const struct dpa_priv_s *priv; -+ struct qm_sg_entry *sgt; -+ struct dpa_bp *_dpa_bp, *dpa_bp; -+ struct bm_buffer _bmb, bmb[8]; -+ -+ priv = netdev_priv(net_dev); -+ -+ _bmb.hi = fd->addr_hi; -+ _bmb.lo = fd->addr_lo; -+ -+ _dpa_bp = dpa_bpid2pool(fd->bpid); -+ BUG_ON(IS_ERR(_dpa_bp)); -+ -+ if (fd->format == qm_fd_sg) { -+ sgt = (phys_to_virt(bm_buf_addr(&_bmb)) + dpa_fd_offset(fd)); -+ dpa_release_sgt(sgt, dpa_bp, bmb); -+ } -+ -+ while (bman_release(_dpa_bp->pool, &_bmb, 1, 0)) -+ cpu_relax(); -+} -+ -+#ifndef CONFIG_DPAA_ETH_SG_SUPPORT -+/* -+ * Cleanup function for outgoing frame descriptors that were built on Tx path, -+ * either contiguous frames or scatter/gather ones with a single data buffer. -+ * 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) -+{ -+ dma_addr_t addr = qm_fd_addr(fd); -+ dma_addr_t sg_addr; -+ struct dpa_bp *bp = priv->dpa_bp; -+ struct sk_buff **skbh; -+ struct sk_buff *skb = NULL; -+ -+ BUG_ON(!fd); -+ -+ if (unlikely(!addr)) -+ return skb; -+ -+ skbh = (struct sk_buff **)phys_to_virt(addr); -+ -+ if (fd->format == qm_fd_contig) { -+ /* For contiguous frames, just unmap data buffer; -+ * mapping direction depends on whether the frame was -+ * meant to be recycled or not */ -+ if (fd->cmd & FM_FD_CMD_FCO) -+ dma_unmap_single(bp->dev, addr, bp->size, -+ DMA_BIDIRECTIONAL); -+ else -+ dma_unmap_single(bp->dev, addr, bp->size, -+ DMA_TO_DEVICE); -+ /* Retrieve the skb backpointer */ -+ skb = *skbh; -+ } else { -+ /* For s/g, we need to unmap both the SGT buffer and the -+ * data buffer, and also free the SGT buffer */ -+ struct qm_sg_entry *sg_entry; -+ void *vaddr = phys_to_virt(addr); -+ -+ /* Unmap first buffer (contains S/G table) */ -+ dma_unmap_single(bp->dev, addr, SGT_BUFFER_SIZE, -+ DMA_TO_DEVICE); -+ -+ /* Unmap data buffer */ -+ sg_entry = (struct qm_sg_entry *)(vaddr + fd->offset); -+ sg_addr = qm_sg_addr(sg_entry); -+ if (likely(sg_addr)) -+ dma_unmap_single(bp->dev, sg_addr, bp->size, -+ DMA_TO_DEVICE); -+ /* Retrieve the skb backpointer */ -+ skb = *skbh; -+ -+ /* Free first buffer (which was allocated on Tx) */ -+ kfree(vaddr); -+ } -+ -+ return skb; -+} -+#endif /* CONFIG_DPAA_ETH_SG_SUPPORT */ -+ -+/* net_device */ -+ -+static struct net_device_stats * __cold -+dpa_get_stats(struct net_device *net_dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ unsigned long *netstats; -+ unsigned long *cpustats; -+ int i, j; -+ struct dpa_percpu_priv_s *percpu_priv; -+ int numstats = sizeof(net_dev->stats) / sizeof(unsigned long); -+ -+ netstats = (unsigned long *)&net_dev->stats; -+ -+ memset(netstats, 0, sizeof(net_dev->stats)); -+ -+ for_each_online_cpu(i) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i); -+ -+ cpustats = (unsigned long *)&percpu_priv->stats; -+ -+ for (j = 0; j < numstats; j++) -+ netstats[j] += cpustats[j]; -+ } -+ -+ return &net_dev->stats; -+} -+ -+static int dpa_change_mtu(struct net_device *net_dev, int new_mtu) -+{ -+ const int max_mtu = dpa_get_max_mtu(); -+ const int min_mtu = dpa_get_min_mtu(); -+ -+ /* Make sure we don't exceed the Ethernet controller's MAXFRM */ -+ if (new_mtu < min_mtu || new_mtu > max_mtu) { -+ netdev_err(net_dev, "Invalid L3 mtu %d " -+ "(must be between %d and %d).\n", -+ new_mtu, min_mtu, max_mtu); -+ return -EINVAL; -+ } -+ net_dev->mtu = new_mtu; -+ -+ return 0; -+} -+ -+/* .ndo_init callback */ -+static 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; -+} -+ -+static int dpa_set_mac_address(struct net_device *net_dev, void *addr) -+{ -+ const struct dpa_priv_s *priv; -+ int _errno; -+ -+ 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; -+ } -+ -+ if (!priv->mac_dev) -+ /* MAC-less interface, so nothing more to do here */ -+ return 0; -+ -+ _errno = priv->mac_dev->change_addr(priv->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; -+} -+ -+static void dpa_set_rx_mode(struct net_device *net_dev) -+{ -+ int _errno; -+ const struct dpa_priv_s *priv; -+ -+ priv = netdev_priv(net_dev); -+ -+ if (!priv->mac_dev) -+ return; -+ -+ if (!!(net_dev->flags & IFF_PROMISC) != priv->mac_dev->promisc) { -+ _errno = priv->mac_dev->change_promisc(priv->mac_dev); -+ if (unlikely(_errno < 0) && netif_msg_drv(priv)) -+ netdev_err(net_dev, -+ "mac_dev->change_promisc() = %d\n", -+ _errno); -+ } -+ -+ _errno = priv->mac_dev->set_multi(net_dev); -+ if (unlikely(_errno < 0) && netif_msg_drv(priv)) -+ netdev_err(net_dev, "mac_dev->set_multi() = %d\n", _errno); -+} -+ -+#ifdef CONFIG_FSL_DPA_1588 -+static int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -+{ -+ struct dpa_priv_s *priv = netdev_priv(dev); -+ int ret = 0; -+ -+ if (!netif_running(dev)) -+ return -EINVAL; -+ -+ 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; -+ } -+ -+ return ret; -+} -+#endif -+ -+#ifndef CONFIG_DPAA_ETH_SG_SUPPORT -+/* -+ * When we put the buffer into the pool, we purposefully added -+ * some padding to the address so that the buffers wouldn't all -+ * be page-aligned. But the skb has been reset to a default state, -+ * so it is pointing up to DPAA_ETH_MAX_PAD - L1_CACHE_BYTES bytes -+ * before the actual data. We subtract skb->head from the fd addr, -+ * and then mask off the translated part to get the actual distance. -+ */ -+static int dpa_process_one(struct dpa_percpu_priv_s *percpu_priv, -+ struct sk_buff *skb, struct dpa_bp *bp, const struct qm_fd *fd) -+{ -+ dma_addr_t addr = qm_fd_addr(fd); -+ u32 addrlo = lower_32_bits(addr); -+ u32 skblo = lower_32_bits((unsigned long)skb->head); -+ u32 pad = (addrlo - skblo) & (PAGE_SIZE - 1); -+ unsigned int data_start; -+ -+ (*percpu_priv->dpa_bp_count)--; -+ -+ /* -+ * The skb is currently pointed at head + headroom. The packet -+ * starts at skb->head + pad + fd offset. -+ */ -+ data_start = pad + dpa_fd_offset(fd) - skb_headroom(skb); -+ skb_put(skb, dpa_fd_length(fd) + data_start); -+ skb_pull(skb, data_start); -+ -+ return 0; -+} -+#endif -+ -+/* -+ * 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); -+ t_FmPrsResult *parse_result; -+ -+ if (unlikely(!frm)) -+ return; -+ -+ dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL); -+ -+ parse_result = (t_FmPrsResult *)(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_err(net_dev, "FD status = 0x%08x\n", -+ fd->status & FM_FD_STAT_ERRORS); -+ -+ 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; -+ -+ 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_ERRORS); -+ -+ 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; -+ -+ percpu_priv->stats.tx_errors++; -+ -+ 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. -+ * -+ * @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. -+ * -+ * Returns 0 if the frame contained no detectable error (including if the FMan -+ * Parser has not in fact been running), and a non-zero value if the Parser -+ * has run but encountered an error. -+ */ -+int __hot _dpa_process_parse_results(const t_FmPrsResult *parse_results, -+ const struct qm_fd *fd, -+ struct sk_buff *skb, -+ int *use_gro, -+ unsigned int *hdr_size __maybe_unused) -+{ -+ if (likely(fm_l4_hxs_has_run(parse_results))) { -+ /* -+ * Was there any parsing error? Note: this includes the check -+ * for a valid L4 checksum. -+ */ -+ if (unlikely(fm_l4_hxs_error(parse_results))) -+ /* Leave it to the caller to handle the frame. */ -+ return parse_results->l4r; -+ -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ /* -+ * If the HXS Parser has successfully run, we can reduce the -+ * number of bytes we'll memcopy into skb->data. -+ */ -+ *hdr_size = parse_results->nxthdr_off; -+#endif -+ /* -+ * We know the frame is valid. But has the L4 checksum actually -+ * been validated? (The L4CV bit is only set if the frame is -+ * TCP or UDP-with-non-zero-csum.) -+ */ -+ if (fd->status & FM_FD_STAT_L4CV) -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ else -+ /* -+ * If it turns out to be a 0-csum UDP, the stack will -+ * figure it out itself later, sparing us an extra -+ * check here on the fastpath of every incoming frame. -+ */ -+ skb->ip_summed = CHECKSUM_NONE; -+ -+ /* -+ * 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; -+ } else { -+ /* Inform the stack that we haven't done any csum validation. */ -+ skb->ip_summed = CHECKSUM_NONE; -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ /* -+ * Also, since the Parser hasn't run, we don't know the size of -+ * the headers, so we fall back to a safe default. -+ */ -+ *hdr_size = min((ssize_t)DPA_COPIED_HEADERS_SIZE, -+ dpa_fd_length(fd)); -+#endif -+ /* -+ * Bypass GRO for unknown traffic or if no PCDs are applied. -+ * It's unlikely that a GRO handler is installed for this proto -+ * or, if it is, user does not seem to care about performance -+ * (otherwise, PCDs would have been in place). -+ */ -+ *use_gro = 0; -+ } -+ -+ return 0; -+} -+ -+#ifndef CONFIG_DPAA_ETH_SG_SUPPORT -+void __hot _dpa_rx(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 dpa_bp *dpa_bp; -+ struct sk_buff *skb; -+ struct sk_buff **skbh; -+ dma_addr_t addr = qm_fd_addr(fd); -+ u32 fd_status = fd->status; -+ unsigned int skb_len; -+ t_FmPrsResult *parse_result; -+ int ret; -+ unsigned int hdr_size_unused; -+ int use_gro = net_dev->features & NETIF_F_GRO; -+ -+ skbh = (struct sk_buff **)phys_to_virt(addr); -+ -+ if (unlikely(fd_status & FM_FD_STAT_ERRORS) != 0) { -+ if (netif_msg_hw(priv) && net_ratelimit()) -+ netdev_warn(net_dev, "FD status = 0x%08x\n", -+ fd->status & FM_FD_STAT_ERRORS); -+ -+ percpu_priv->stats.rx_errors++; -+ -+ goto _return_dpa_fd_release; -+ } -+ -+ if (unlikely(fd->format != qm_fd_contig)) { -+ percpu_priv->stats.rx_dropped++; -+ if (netif_msg_rx_status(priv) && net_ratelimit()) -+ netdev_warn(net_dev, "Dropping a SG frame\n"); -+ goto _return_dpa_fd_release; -+ } -+ -+ dpa_bp = dpa_bpid2pool(fd->bpid); -+ -+ dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL); -+ -+ skb = *skbh; -+ prefetch(skb); -+ -+ /* Fill the SKB */ -+ dpa_process_one(percpu_priv, skb, dpa_bp, fd); -+ -+ prefetch(skb_shinfo(skb)); -+ -+#ifdef CONFIG_FSL_DPA_1588 -+ if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_rx_en_ioctl) -+ dpa_ptp_store_rxstamp(net_dev, skb, fd); -+#endif -+ -+ skb->protocol = eth_type_trans(skb, net_dev); -+ -+ if (unlikely(dpa_check_rx_mtu(skb, net_dev->mtu))) { -+ percpu_priv->stats.rx_dropped++; -+ goto drop_large_frame; -+ } -+ -+ /* Execute the Rx processing hook, if it exists. */ -+ if (dpaa_eth_hooks.rx_default && dpaa_eth_hooks.rx_default(skb, -+ net_dev, fqid) == DPAA_ETH_STOLEN) -+ /* won't count the rx bytes in */ -+ goto skb_stolen; -+ -+ skb_len = skb->len; -+ -+ /* Validate the skb csum and figure out whether GRO is appropriate */ -+ parse_result = (t_FmPrsResult *)((u8 *)skbh + DPA_RX_PRIV_DATA_SIZE); -+ ret = _dpa_process_parse_results(parse_result, fd, skb, &use_gro, -+ &hdr_size_unused); -+ if (unlikely(ret)) { -+ percpu_priv->l4_hxs_errors++; -+ percpu_priv->stats.rx_dropped++; -+ goto drop_invalid_frame; -+ } -+ if (use_gro) { -+ gro_result_t gro_result; -+ -+ gro_result = napi_gro_receive(&percpu_priv->napi, skb); -+ if (unlikely(gro_result == GRO_DROP)) { -+ percpu_priv->stats.rx_dropped++; -+ goto packet_dropped; -+ } -+ } else if (unlikely(netif_receive_skb(skb) == NET_RX_DROP)) { -+ percpu_priv->stats.rx_dropped++; -+ goto packet_dropped; -+ } -+ -+ percpu_priv->stats.rx_packets++; -+ percpu_priv->stats.rx_bytes += skb_len; -+ -+packet_dropped: -+skb_stolen: -+ return; -+ -+drop_invalid_frame: -+drop_large_frame: -+ dev_kfree_skb(skb); -+ return; -+ -+_return_dpa_fd_release: -+ dpa_fd_release(net_dev, fd); -+} -+#endif /* CONFIG_DPAA_ETH_SG_SUPPORT */ -+ -+static void dpaa_eth_napi_disable(struct dpa_priv_s *priv) -+{ -+ struct dpa_percpu_priv_s *percpu_priv; -+ int i; -+ -+ if (priv->shared) -+ return; -+ -+ for_each_online_cpu(i) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i); -+ napi_disable(&percpu_priv->napi); -+ } -+} -+ -+static void dpaa_eth_napi_enable(struct dpa_priv_s *priv) -+{ -+ struct dpa_percpu_priv_s *percpu_priv; -+ int i; -+ -+ if (priv->shared) -+ return; -+ -+ for_each_online_cpu(i) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i); -+ napi_enable(&percpu_priv->napi); -+ } -+} -+ -+static int dpaa_eth_poll(struct napi_struct *napi, int budget) -+{ -+ int cleaned = qman_poll_dqrr(budget); -+ -+ if (cleaned < budget) { -+ int tmp; -+ napi_complete(napi); -+ tmp = qman_irqsource_add(QM_PIRQ_DQRI); -+ BUG_ON(tmp); -+ } -+ -+ return cleaned; -+} -+ -+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; -+ -+ if (unlikely(fd->status & FM_FD_STAT_ERRORS) != 0) { -+ if (netif_msg_hw(priv) && net_ratelimit()) -+ netdev_warn(net_dev, "FD status = 0x%08x\n", -+ fd->status & FM_FD_STAT_ERRORS); -+ -+ percpu_priv->stats.tx_errors++; -+ } -+ -+ 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; -+ -+ /* This might not perfectly reflect the reality, if the core dequeueing -+ * 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); -+ -+#ifdef CONFIG_FSL_DPA_1588 -+ if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl) -+ dpa_ptp_store_txstamp(net_dev, skb, fd); -+#endif -+ dev_kfree_skb(skb); -+} -+ -+static struct dpa_bp *dpa_size2pool(struct dpa_priv_s *priv, size_t size) -+{ -+ int i; -+ -+ for (i = 0; i < priv->bp_count; i++) -+ if (DPA_BP_SIZE(size) <= priv->dpa_bp[i].size) -+ return dpa_bpid2pool(priv->dpa_bp[i].bpid); -+ return ERR_PTR(-ENODEV); -+} -+ -+/** -+ * 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) -+{ -+ t_FmPrsResult *parse_result; -+ struct iphdr *iph; -+ struct ipv6hdr *ipv6h = NULL; -+ int l4_proto; -+ int ethertype = ntohs(skb->protocol); -+ int retval = 0; -+ -+ if (!priv->mac_dev || 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 = (t_FmPrsResult *)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 = FM_L3_PARSE_RESULT_IPV4; -+ iph = ip_hdr(skb); -+ BUG_ON(iph == NULL); -+ l4_proto = ntohs(iph->protocol); -+ break; -+ case ETH_P_IPV6: -+ parse_result->l3r = FM_L3_PARSE_RESULT_IPV6; -+ ipv6h = ipv6_hdr(skb); -+ BUG_ON(ipv6h == NULL); -+ l4_proto = ntohs(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] = skb_network_offset(skb); -+ parse_result->l4_off = 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; -+} -+ -+static int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev) -+{ -+ struct dpa_bp *dpa_bp; -+ struct bm_buffer bmb; -+ struct dpa_percpu_priv_s *percpu_priv; -+ struct dpa_priv_s *priv; -+ struct qm_fd fd; -+ int queue_mapping; -+ int err; -+ void *dpa_bp_vaddr; -+ t_FmPrsResult parse_results; -+ -+ priv = netdev_priv(net_dev); -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, smp_processor_id()); -+ -+ memset(&fd, 0, sizeof(fd)); -+ fd.format = qm_fd_contig; -+ -+ queue_mapping = smp_processor_id(); -+ -+ dpa_bp = dpa_size2pool(priv, skb_headlen(skb)); -+ if (unlikely(IS_ERR(dpa_bp))) { -+ percpu_priv->stats.tx_errors++; -+ err = PTR_ERR(dpa_bp); -+ goto bpools_too_small_error; -+ } -+ -+ err = bman_acquire(dpa_bp->pool, &bmb, 1, 0); -+ if (unlikely(err <= 0)) { -+ percpu_priv->stats.tx_errors++; -+ if (err == 0) -+ err = -ENOMEM; -+ goto buf_acquire_failed; -+ } -+ fd.bpid = dpa_bp->bpid; -+ -+ fd.length20 = skb_headlen(skb); -+ fd.addr_hi = bmb.hi; -+ fd.addr_lo = bmb.lo; -+ fd.offset = DPA_BP_HEAD; -+ -+ /* -+ * The virtual address of the buffer pool is expected to be NULL -+ * in scenarios like MAC-less or Shared-MAC between Linux and -+ * USDPAA. In this case the buffers are dynamically mapped/unmapped. -+ */ -+ if (dpa_bp->vaddr) { -+ dpa_bp_vaddr = dpa_phys2virt(dpa_bp, bm_buf_addr(&bmb)); -+ -+ /* Copy the packet payload */ -+ skb_copy_from_linear_data(skb, -+ dpa_bp_vaddr + dpa_fd_offset(&fd), -+ dpa_fd_length(&fd)); -+ -+ /* Enable L3/L4 hardware checksum computation, if applicable */ -+ err = dpa_enable_tx_csum(priv, skb, &fd, -+ dpa_bp_vaddr + DPA_TX_PRIV_DATA_SIZE); -+ } else { -+ err = dpa_enable_tx_csum(priv, skb, &fd, -+ (char *)&parse_results); -+ -+ copy_to_unmapped_area(bm_buf_addr(&bmb) + DPA_TX_PRIV_DATA_SIZE, -+ &parse_results, -+ DPA_PARSE_RESULTS_SIZE); -+ -+ copy_to_unmapped_area(bm_buf_addr(&bmb) + dpa_fd_offset(&fd), -+ skb->data, -+ dpa_fd_length(&fd)); -+ } -+ -+ if (unlikely(err < 0)) { -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ netdev_err(net_dev, "Tx HW csum error: %d\n", err); -+ percpu_priv->stats.tx_errors++; -+ goto l3_l4_csum_failed; -+ } -+ -+ err = dpa_xmit(priv, &percpu_priv->stats, queue_mapping, &fd); -+ -+l3_l4_csum_failed: -+bpools_too_small_error: -+buf_acquire_failed: -+ /* We're done with the skb */ -+ dev_kfree_skb(skb); -+ -+ return NETDEV_TX_OK; -+} -+ -+#ifndef CONFIG_DPAA_ETH_SG_SUPPORT -+static int 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; -+ void *vaddr; -+ dma_addr_t paddr; -+ struct sk_buff **skbh; -+ struct qm_sg_entry *sg_entry; -+ struct net_device *net_dev = priv->net_dev; -+ int err; -+ -+ /* Allocate the first buffer in the FD (used for storing S/G table) */ -+ vaddr = kmalloc(SGT_BUFFER_SIZE, GFP_ATOMIC); -+ if (unlikely(vaddr == NULL)) { -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ netdev_err(net_dev, "Memory allocation failed\n"); -+ return -ENOMEM; -+ } -+ /* Store skb backpointer at the beginning of the buffer */ -+ skbh = (struct sk_buff **)vaddr; -+ *skbh = skb; -+ -+ /* Fill in FD */ -+ fd->format = qm_fd_sg; -+ fd->offset = DPA_BP_HEAD; -+ fd->length20 = skb->len; -+ -+ /* Enable hardware checksum computation */ -+ err = dpa_enable_tx_csum(priv, skb, fd, -+ (char *)vaddr + 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); -+ kfree(vaddr); -+ return err; -+ } -+ -+ /* Map the buffer and store its address in the FD */ -+ paddr = dma_map_single(dpa_bp->dev, vaddr, SGT_BUFFER_SIZE, -+ DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(dpa_bp->dev, paddr))) { -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ netdev_err(net_dev, "DMA mapping failed\n"); -+ kfree(vaddr); -+ return -EINVAL; -+ } -+ -+ fd->addr_hi = upper_32_bits(paddr); -+ fd->addr_lo = lower_32_bits(paddr); -+ -+ /* Fill in S/G entry */ -+ sg_entry = (struct qm_sg_entry *)(vaddr + fd->offset); -+ -+ sg_entry->extension = 0; -+ sg_entry->final = 1; -+ sg_entry->length = skb->len; -+ /* -+ * Put the same offset in the data buffer as in the SGT (first) buffer. -+ * This is the format for S/G frames generated by FMan; the manual is -+ * not clear if same is required of Tx S/G frames, but since we know -+ * for sure we have at least DPA_BP_HEAD bytes of skb headroom, lets not -+ * take any chances. -+ */ -+ sg_entry->offset = DPA_BP_HEAD; -+ -+ paddr = dma_map_single(dpa_bp->dev, skb->data - sg_entry->offset, -+ dpa_bp->size, DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(dpa_bp->dev, paddr))) { -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ netdev_err(net_dev, "DMA mapping failed\n"); -+ return -EINVAL; -+ } -+ sg_entry->addr_hi = upper_32_bits(paddr); -+ sg_entry->addr_lo = lower_32_bits(paddr); -+ -+ return 0; -+} -+ -+static int skb_to_contig_fd(struct dpa_priv_s *priv, -+ struct dpa_percpu_priv_s *percpu_priv, -+ struct sk_buff *skb, struct qm_fd *fd) -+{ -+ struct sk_buff **skbh; -+ dma_addr_t addr; -+ struct dpa_bp *dpa_bp = priv->dpa_bp; -+ struct net_device *net_dev = priv->net_dev; -+ enum dma_data_direction dma_dir = DMA_TO_DEVICE; -+ bool can_recycle = false; -+ int offset, extra_offset; -+ int err; -+ -+ /* -+ * We are guaranteed that we have at least DPA_BP_HEAD of headroom. -+ * Buffers we allocated are padded to improve cache usage. In order -+ * to increase buffer re-use, we aim to keep any such buffers the -+ * same. This means the address passed to the FM should be DPA_BP_HEAD -+ * before the data for forwarded frames. -+ * -+ * However, offer some flexibility in fd layout, to allow originating -+ * (termination) buffers to be also recycled when possible. -+ * -+ * First, see if the conditions needed to recycle the skb are met: -+ * - skb not cloned, not shared -+ * - buffer size is large enough to accomodate a maximum size Rx frame -+ * - buffer size does not exceed the maximum size allowed in the pool -+ * (to avoid unbounded increase of buffer size in certain forwarding -+ * conditions) -+ * - buffer address is 16 byte aligned, as per DPAARM -+ * - there's enough room in the buffer pool -+ */ -+ if (likely(skb_is_recycleable(skb, dpa_bp->size) && -+ (skb_end_pointer(skb) - skb->head <= DPA_BP_MAX_BUF_SIZE) && -+ (*percpu_priv->dpa_bp_count < dpa_bp->target_count))) { -+ /* Compute the minimum necessary fd offset */ -+ offset = dpa_bp->size - skb->len - skb_tailroom(skb); -+ -+ /* -+ * And make sure the offset is no lower than DPA_BP_HEAD, -+ * as required by FMan -+ */ -+ offset = max(offset, (int)DPA_BP_HEAD); -+ -+ /* -+ * We also need to align the buffer address to 16, such that -+ * Fman will be able to reuse it on Rx. -+ * Since the buffer going to FMan starts at (skb->data - offset) -+ * this is what we'll try to align. We already know that -+ * headroom is at least DPA_BP_HEAD bytes long, but with -+ * the extra offset needed for alignment we may go beyond -+ * the beginning of the buffer. -+ * -+ * Also need to check that we don't go beyond the maximum -+ * offset that can be set for a contiguous FD. -+ */ -+ extra_offset = (unsigned long)(skb->data - offset) & 0xF; -+ if (likely((offset + extra_offset) <= skb_headroom(skb) && -+ (offset + extra_offset) <= DPA_MAX_FD_OFFSET)) { -+ /* We're good to go for recycling*/ -+ offset += extra_offset; -+ can_recycle = true; -+ } -+ } -+ -+ if (likely(can_recycle)) { -+ /* Buffer will get recycled, setup fd accordingly */ -+ fd->cmd |= FM_FD_CMD_FCO; -+ fd->bpid = dpa_bp->bpid; -+ /* -+ * Since the buffer will get back to the Bman pool -+ * and be re-used on Rx, map it for both read and write -+ */ -+ dma_dir = DMA_BIDIRECTIONAL; -+ } else { -+ /* -+ * No recycling here, so we don't care about address alignment. -+ * Just use the smallest offset required by FMan -+ */ -+ offset = DPA_BP_HEAD; -+ } -+ -+ skbh = (struct sk_buff **)(skb->data - offset); -+ *skbh = skb; -+ -+ -+ /* Enable L3/L4 hardware checksum computation. -+ * -+ * We must do this before dma_map_single(), 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; -+ } -+ -+ fd->format = qm_fd_contig; -+ fd->length20 = skb->len; -+ fd->offset = offset; -+ -+ addr = dma_map_single(dpa_bp->dev, skbh, dpa_bp->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; -+ } -+ -+ fd->addr_hi = upper_32_bits(addr); -+ fd->addr_lo = lower_32_bits(addr); -+ -+ return 0; -+} -+ -+int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev) -+{ -+ struct dpa_priv_s *priv; -+ struct qm_fd fd; -+ struct dpa_percpu_priv_s *percpu_priv; -+ struct net_device_stats *percpu_stats; -+ int queue_mapping; -+ int err; -+ -+ /* 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 */ -+ goto done; -+ -+ priv = netdev_priv(net_dev); -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, smp_processor_id()); -+ percpu_stats = &percpu_priv->stats; -+ -+ clear_fd(&fd); -+ queue_mapping = dpa_get_queue_mapping(skb); -+ -+ if (unlikely(skb_headroom(skb) < DPA_BP_HEAD)) { -+ struct sk_buff *skb_new; -+ -+ skb_new = skb_realloc_headroom(skb, DPA_BP_HEAD); -+ if (unlikely(!skb_new)) { -+ percpu_stats->tx_errors++; -+ kfree_skb(skb); -+ goto done; -+ } -+ kfree_skb(skb); -+ skb = skb_new; -+ } -+ -+#ifdef CONFIG_FSL_DPA_1588 -+ if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl) -+ fd.cmd |= FM_FD_CMD_UPD; -+#endif -+ -+ /* -+ * We have two paths here: -+ * -+ * 1.If the skb is cloned, create a S/G frame to avoid unsharing it. -+ * The S/G table will contain only one entry, pointing to our skb -+ * data buffer. -+ * The private data area containing the skb backpointer will reside -+ * inside the first buffer, such that it won't risk being overwritten -+ * in case a second skb pointing to the same data buffer is being -+ * processed concurently. -+ * No recycling is possible in this case, as the data buffer is shared. -+ * -+ * 2.If skb is not cloned, then the private area inside it can be -+ * safely used to store the skb backpointer. Simply create a contiguous -+ * fd in this case. -+ * Recycling can happen if the right conditions are met. -+ */ -+ if (skb_cloned(skb) && (skb->len > DPA_SKB_COPY_MAX_SIZE)) -+ err = skb_to_sg_fd(priv, skb, &fd); -+ else { -+ /* If cloned skb, but length is below DPA_SKB_COPY_MAX_SIZE, -+ * it's more efficient to unshare it and then use the new skb */ -+ skb = skb_unshare(skb, GFP_ATOMIC); -+ if (unlikely(!skb)) { -+ percpu_stats->tx_errors++; -+ goto done; -+ } -+ err = skb_to_contig_fd(priv, percpu_priv, skb, &fd); -+ } -+ if (unlikely(err < 0)) { -+ percpu_stats->tx_errors++; -+ goto fd_create_failed; -+ } -+ -+ if (fd.cmd & FM_FD_CMD_FCO) { -+ /* This skb is recycleable, and the fd generated from it -+ * has been filled in accordingly */ -+ skb_recycle(skb); -+ skb = NULL; -+ (*percpu_priv->dpa_bp_count)++; -+ percpu_priv->tx_returned++; -+ } -+ -+ if (unlikely(dpa_xmit(priv, percpu_stats, queue_mapping, -+ &fd) < 0)) -+ goto xmit_failed; -+ -+ net_dev->trans_start = jiffies; -+ goto done; -+ -+xmit_failed: -+ if (fd.cmd & FM_FD_CMD_FCO) { -+ (*percpu_priv->dpa_bp_count)--; -+ percpu_priv->tx_returned--; -+ } -+fd_create_failed: -+ _dpa_cleanup_tx_fd(priv, &fd); -+ dev_kfree_skb(skb); -+ -+done: -+ return NETDEV_TX_OK; -+} -+#endif /* CONFIG_DPAA_ETH_SG_SUPPORT */ -+ -+/** -+ * 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); -+ } -+} -+ -+static enum qman_cb_dqrr_result -+ingress_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; -+ -+ net_dev = ((struct dpa_fq *)fq)->net_dev; -+ priv = netdev_priv(net_dev); -+ -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, smp_processor_id()); -+ -+ if (dpaa_eth_napi_schedule(percpu_priv)) { -+ percpu_priv->in_interrupt++; -+ return qman_cb_dqrr_stop; -+ } -+ -+ dpaa_eth_refill_bpools(percpu_priv); -+ _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid); -+ -+ return qman_cb_dqrr_consume; -+} -+ -+static enum qman_cb_dqrr_result __hot -+shared_rx_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; -+ const struct qm_fd *fd = &dq->fd; -+ struct dpa_bp *dpa_bp; -+ struct sk_buff *skb; -+ struct qm_sg_entry *sgt; -+ int i; -+ -+ net_dev = ((struct dpa_fq *)fq)->net_dev; -+ priv = netdev_priv(net_dev); -+ -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, smp_processor_id()); -+ -+ dpa_bp = dpa_bpid2pool(fd->bpid); -+ BUG_ON(IS_ERR(dpa_bp)); -+ -+ if (unlikely(fd->status & FM_FD_STAT_ERRORS) != 0) { -+ if (netif_msg_hw(priv) && net_ratelimit()) -+ netdev_warn(net_dev, "FD status = 0x%08x\n", -+ fd->status & FM_FD_STAT_ERRORS); -+ -+ percpu_priv->stats.rx_errors++; -+ -+ goto out; -+ } -+ -+ skb = __netdev_alloc_skb(net_dev, -+ DPA_BP_HEAD + dpa_fd_length(fd), -+ GFP_ATOMIC); -+ if (unlikely(skb == NULL)) { -+ if (netif_msg_rx_err(priv) && net_ratelimit()) -+ netdev_err(net_dev, "Could not alloc skb\n"); -+ -+ percpu_priv->stats.rx_dropped++; -+ -+ goto out; -+ } -+ -+ skb_reserve(skb, DPA_BP_HEAD); -+ -+ if (fd->format == qm_fd_sg) { -+ if (dpa_bp->vaddr) { -+ sgt = dpa_phys2virt(dpa_bp, -+ qm_fd_addr(fd)) + dpa_fd_offset(fd); -+ -+ for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) { -+ BUG_ON(sgt[i].extension); -+ -+ /* copy from sgt[i] */ -+ memcpy(skb_put(skb, sgt[i].length), -+ dpa_phys2virt(dpa_bp, -+ qm_sg_addr(&sgt[i]) + -+ sgt[i].offset), -+ sgt[i].length); -+ if (sgt[i].final) -+ break; -+ } -+ } else { -+ sgt = kmalloc(DPA_SGT_MAX_ENTRIES * sizeof(*sgt), -+ GFP_ATOMIC); -+ if (unlikely(sgt == NULL)) { -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ netdev_err(net_dev, -+ "Memory allocation failed\n"); -+ return -ENOMEM; -+ } -+ -+ copy_from_unmapped_area(sgt, -+ qm_fd_addr(fd) + dpa_fd_offset(fd), -+ min(DPA_SGT_MAX_ENTRIES * sizeof(*sgt), -+ dpa_bp->size)); -+ -+ for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) { -+ BUG_ON(sgt[i].extension); -+ -+ copy_from_unmapped_area( -+ skb_put(skb, sgt[i].length), -+ qm_sg_addr(&sgt[i]) + sgt[i].offset, -+ sgt[i].length); -+ -+ if (sgt[i].final) -+ break; -+ } -+ -+ kfree(sgt); -+ } -+ goto skb_copied; -+ } -+ -+ /* otherwise fd->format == qm_fd_contig */ -+ if (dpa_bp->vaddr) { -+ /* Fill the SKB */ -+ memcpy(skb_put(skb, dpa_fd_length(fd)), -+ dpa_phys2virt(dpa_bp, qm_fd_addr(fd)) + -+ dpa_fd_offset(fd), dpa_fd_length(fd)); -+ } else { -+ copy_from_unmapped_area(skb_put(skb, dpa_fd_length(fd)), -+ qm_fd_addr(fd) + dpa_fd_offset(fd), -+ dpa_fd_length(fd)); -+ } -+ -+skb_copied: -+ skb->protocol = eth_type_trans(skb, net_dev); -+ -+ if (unlikely(dpa_check_rx_mtu(skb, net_dev->mtu))) { -+ percpu_priv->stats.rx_dropped++; -+ dev_kfree_skb_any(skb); -+ goto out; -+ } -+ -+ if (unlikely(netif_rx(skb) != NET_RX_SUCCESS)) -+ percpu_priv->stats.rx_dropped++; -+ else { -+ percpu_priv->stats.rx_packets++; -+ percpu_priv->stats.rx_bytes += dpa_fd_length(fd); -+ } -+ -+out: -+ if (fd->format == qm_fd_sg) -+ dpa_fd_release_sg(net_dev, fd); -+ else -+ dpa_fd_release(net_dev, fd); -+ -+ return qman_cb_dqrr_consume; -+} -+ -+ -+static enum qman_cb_dqrr_result __hot -+ingress_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; -+ -+ net_dev = ((struct dpa_fq *)fq)->net_dev; -+ priv = netdev_priv(net_dev); -+ -+ /* IRQ handler, non-migratable; safe to use __this_cpu_ptr here */ -+ percpu_priv = __this_cpu_ptr(priv->percpu_priv); -+ -+ if (unlikely(dpaa_eth_napi_schedule(percpu_priv))) { -+ percpu_priv->in_interrupt++; -+ return qman_cb_dqrr_stop; -+ } -+ -+ /* Vale of plenty: make sure we didn't run out of buffers */ -+ dpaa_eth_refill_bpools(percpu_priv); -+ _dpa_rx(net_dev, priv, percpu_priv, &dq->fd, fq->fqid); -+ -+ return qman_cb_dqrr_consume; -+} -+ -+static enum qman_cb_dqrr_result -+ingress_tx_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 = per_cpu_ptr(priv->percpu_priv, smp_processor_id()); -+ -+ if (dpaa_eth_napi_schedule(percpu_priv)) { -+ percpu_priv->in_interrupt++; -+ return qman_cb_dqrr_stop; -+ } -+ -+ _dpa_tx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid); -+ -+ return qman_cb_dqrr_consume; -+} -+ -+static enum qman_cb_dqrr_result __hot -+ingress_tx_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); -+ -+ /* Non-migratable context, safe to use __this_cpu_ptr */ -+ percpu_priv = __this_cpu_ptr(priv->percpu_priv); -+ -+ if (dpaa_eth_napi_schedule(percpu_priv)) { -+ percpu_priv->in_interrupt++; -+ return qman_cb_dqrr_stop; -+ } -+ -+ _dpa_tx_conf(net_dev, priv, percpu_priv, &dq->fd, fq->fqid); -+ -+ return qman_cb_dqrr_consume; -+} -+ -+static enum qman_cb_dqrr_result -+shared_tx_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; -+ struct dpa_bp *dpa_bp; -+ const struct qm_fd *fd = &dq->fd; -+ -+ net_dev = ((struct dpa_fq *)fq)->net_dev; -+ priv = netdev_priv(net_dev); -+ -+ dpa_bp = dpa_bpid2pool(fd->bpid); -+ BUG_ON(IS_ERR(dpa_bp)); -+ -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, smp_processor_id()); -+ -+ if (netif_msg_hw(priv) && net_ratelimit()) -+ netdev_warn(net_dev, "FD status = 0x%08x\n", -+ fd->status & FM_FD_STAT_ERRORS); -+ -+ if ((fd->format == qm_fd_sg) && (!dpa_bp->vaddr)) -+ dpa_fd_release_sg(net_dev, fd); -+ else -+ dpa_fd_release(net_dev, fd); -+ -+ percpu_priv->stats.tx_errors++; -+ -+ return qman_cb_dqrr_consume; -+} -+ -+static enum qman_cb_dqrr_result __hot -+shared_tx_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; -+ struct dpa_bp *dpa_bp; -+ const struct qm_fd *fd = &dq->fd; -+ -+ net_dev = ((struct dpa_fq *)fq)->net_dev; -+ priv = netdev_priv(net_dev); -+ -+ dpa_bp = dpa_bpid2pool(fd->bpid); -+ BUG_ON(IS_ERR(dpa_bp)); -+ -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, smp_processor_id()); -+ -+ if (unlikely(fd->status & FM_FD_STAT_ERRORS) != 0) { -+ if (netif_msg_hw(priv) && net_ratelimit()) -+ netdev_warn(net_dev, "FD status = 0x%08x\n", -+ fd->status & FM_FD_STAT_ERRORS); -+ -+ percpu_priv->stats.tx_errors++; -+ } -+ -+ if ((fd->format == qm_fd_sg) && (!dpa_bp->vaddr)) -+ dpa_fd_release_sg(net_dev, fd); -+ else -+ dpa_fd_release(net_dev, fd); -+ -+ percpu_priv->tx_confirm++; -+ -+ return qman_cb_dqrr_consume; -+} -+ -+static 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; -+ } -+} -+ -+static void shared_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 dpa_percpu_priv_s *percpu_priv; -+ struct dpa_fq *dpa_fq = (struct dpa_fq *)fq; -+ -+ net_dev = dpa_fq->net_dev; -+ priv = netdev_priv(net_dev); -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, smp_processor_id()); -+ -+ dpa_fd_release(net_dev, &msg->ern.fd); -+ -+ percpu_priv->stats.tx_dropped++; -+ percpu_priv->stats.tx_fifo_errors++; -+ count_ern(percpu_priv, msg); -+} -+ -+static void egress_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 __this_cpu_ptr */ -+ percpu_priv = __this_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.cmd & FM_FD_CMD_FCO) { -+ dpa_fd_release(net_dev, &fd); -+ return; -+ } -+ -+ skb = _dpa_cleanup_tx_fd(priv, &fd); -+ dev_kfree_skb_any(skb); -+} -+ -+static const struct qman_fq rx_shared_fq __devinitconst = { -+ .cb = { .dqrr = shared_rx_dqrr } -+}; -+static const struct qman_fq rx_private_defq __devinitconst = { -+ .cb = { .dqrr = ingress_rx_default_dqrr } -+}; -+static const struct qman_fq rx_private_errq __devinitconst = { -+ .cb = { .dqrr = ingress_rx_error_dqrr } -+}; -+static const struct qman_fq tx_private_defq __devinitconst = { -+ .cb = { .dqrr = ingress_tx_default_dqrr } -+}; -+static const struct qman_fq tx_private_errq __devinitconst = { -+ .cb = { .dqrr = ingress_tx_error_dqrr } -+}; -+static const struct qman_fq tx_shared_defq __devinitconst = { -+ .cb = { .dqrr = shared_tx_default_dqrr } -+}; -+static const struct qman_fq tx_shared_errq __devinitconst = { -+ .cb = { .dqrr = shared_tx_error_dqrr } -+}; -+static const struct qman_fq private_egress_fq __devinitconst = { -+ .cb = { .ern = egress_ern } -+}; -+static const struct qman_fq shared_egress_fq __devinitconst = { -+ .cb = { .ern = shared_ern } -+}; -+ -+#ifdef CONFIG_DPAA_ETH_UNIT_TESTS -+static bool __devinitdata tx_unit_test_passed = true; -+ -+static void __devinit tx_unit_test_ern(struct qman_portal *portal, -+ struct qman_fq *fq, -+ const struct qm_mr_entry *msg) -+{ -+ struct net_device *net_dev; -+ struct dpa_priv_s *priv; -+ struct sk_buff **skbh; -+ struct sk_buff *skb; -+ const struct qm_fd *fd; -+ dma_addr_t addr; -+ -+ net_dev = ((struct dpa_fq *)fq)->net_dev; -+ priv = netdev_priv(net_dev); -+ -+ tx_unit_test_passed = false; -+ -+ fd = &msg->ern.fd; -+ -+ addr = qm_fd_addr(fd); -+ -+ skbh = (struct sk_buff **)phys_to_virt(addr); -+ skb = *skbh; -+ -+ if (!skb || !is_kernel_addr((unsigned long)skb)) -+ panic("Corrupt skb in ERN!\n"); -+ -+ kfree_skb(skb); -+} -+ -+static unsigned char __devinitdata *tx_unit_skb_head; -+static unsigned char __devinitdata *tx_unit_skb_end; -+static int __devinitdata tx_unit_tested; -+ -+static enum qman_cb_dqrr_result __devinit tx_unit_test_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 sk_buff **skbh; -+ struct sk_buff *skb; -+ const struct qm_fd *fd; -+ dma_addr_t addr; -+ unsigned char *startaddr; -+ struct dpa_percpu_priv_s *percpu_priv; -+ -+ tx_unit_test_passed = false; -+ -+ tx_unit_tested++; -+ -+ net_dev = ((struct dpa_fq *)fq)->net_dev; -+ priv = netdev_priv(net_dev); -+ -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, smp_processor_id()); -+ -+ fd = &dq->fd; -+ -+ addr = qm_fd_addr(fd); -+ -+ skbh = (struct sk_buff **)phys_to_virt(addr); -+ startaddr = (unsigned char *)skbh; -+ skb = *skbh; -+ -+ if (!skb || !is_kernel_addr((unsigned long)skb)) -+ panic("Invalid skb address in TX Unit Test FD\n"); -+ -+ /* Make sure we're dealing with the same skb */ -+ if (skb->head != tx_unit_skb_head -+ || skb_end_pointer(skb) != tx_unit_skb_end) -+ goto out; -+ -+ /* -+ * If we recycled, then there must be enough room between fd.addr -+ * and skb->end for a new RX buffer -+ */ -+ if (fd->cmd & FM_FD_CMD_FCO) { -+ size_t bufsize = skb_end_pointer(skb) - startaddr; -+ -+ if (bufsize < dpa_get_max_frm()) -+ goto out; -+ } else { -+ /* -+ * If we didn't recycle, but the buffer was big enough, -+ * increment the counter to put it back -+ */ -+ if (skb_end_pointer(skb) - skb->head >= -+ dpa_get_max_frm()) -+ (*percpu_priv->dpa_bp_count)++; -+ -+ /* If we didn't recycle, the data pointer should be good */ -+ if (skb->data != startaddr + dpa_fd_offset(fd)) -+ goto out; -+ } -+ -+ tx_unit_test_passed = true; -+out: -+ /* The skb is no longer needed, and belongs to us */ -+ kfree_skb(skb); -+ -+ return qman_cb_dqrr_consume; -+} -+ -+static const struct qman_fq tx_unit_test_fq __devinitconst = { -+ .cb = { .dqrr = tx_unit_test_dqrr, .ern = tx_unit_test_ern } -+}; -+ -+static struct __devinitdata dpa_fq unit_fq; -+#ifdef CONFIG_DPA_TX_RECYCLE -+static struct dpa_fq unit_recycle_fq; -+#endif -+static bool __devinitdata tx_unit_test_ran; /* Starts as false */ -+ -+static int __devinit dpa_tx_unit_test(struct net_device *net_dev) -+{ -+ /* Create a new FQ */ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct qman_fq *oldq; -+ int size, headroom; -+ struct dpa_percpu_priv_s *percpu_priv; -+ cpumask_var_t old_cpumask; -+ int test_count = 0; -+ int err = 0; -+ int tests_failed = 0; -+ const cpumask_t *cpus = qman_affine_cpus(); -+#ifdef CONFIG_DPA_TX_RECYCLE -+ struct qman_fq *oldrecycleq; -+#endif -+ -+ if (!alloc_cpumask_var(&old_cpumask, GFP_KERNEL)) { -+ pr_err("UNIT test cpumask allocation failed\n"); -+ return -ENOMEM; -+ } -+ -+ cpumask_copy(old_cpumask, tsk_cpus_allowed(current)); -+ set_cpus_allowed_ptr(current, cpus); -+ /* disable bottom halves */ -+ local_bh_disable(); -+ -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, smp_processor_id()); -+ -+ qman_irqsource_remove(QM_PIRQ_DQRI); -+ unit_fq.net_dev = net_dev; -+ unit_fq.fq_base = tx_unit_test_fq; -+ -+ /* Save old queue */ -+ oldq = priv->egress_fqs[smp_processor_id()]; -+ -+ err = qman_create_fq(0, QMAN_FQ_FLAG_DYNAMIC_FQID, &unit_fq.fq_base); -+ -+ if (err < 0) { -+ pr_err("UNIT test FQ create failed: %d\n", err); -+ goto fq_create_fail; -+ } -+ -+ err = qman_init_fq(&unit_fq.fq_base, -+ QMAN_INITFQ_FLAG_SCHED | QMAN_INITFQ_FLAG_LOCAL, NULL); -+ if (err < 0) { -+ pr_err("UNIT test FQ init failed: %d\n", err); -+ goto fq_init_fail; -+ } -+ -+ /* Replace queue 0 with this queue */ -+ priv->egress_fqs[smp_processor_id()] = &unit_fq.fq_base; -+ -+#ifdef CONFIG_DPA_TX_RECYCLE -+ oldrecycleq = priv->recycle_fqs[smp_processor_id()]; -+ unit_recycle_fq.net_dev = net_dev; -+ unit_recycle_fq.fq_base = tx_unit_test_fq; -+ -+ err = qman_create_fq(0, QMAN_FQ_FLAG_DYNAMIC_FQID, -+ &unit_recycle_fq.fq_base); -+ -+ if (err < 0) { -+ pr_err("UNIT test Recycle FQ create failed: %d\n", err); -+ goto recycle_fq_create_fail; -+ } -+ -+ err = qman_init_fq(&unit_recycle_fq.fq_base, -+ QMAN_INITFQ_FLAG_SCHED | QMAN_INITFQ_FLAG_LOCAL, NULL); -+ if (err < 0) { -+ pr_err("UNIT test Recycle FQ init failed: %d\n", err); -+ goto recycle_fq_init_fail; -+ } -+ -+ priv->recycle_fqs[smp_processor_id()] = &unit_recycle_fq.fq_base; -+ -+ pr_err("TX Unit Test using FQ: %d - Recycle FQ: %d\n", -+ qman_fq_fqid(&unit_fq.fq_base), -+ qman_fq_fqid(&unit_recycle_fq.fq_base)); -+#else -+ pr_err("TX Unit Test using FQ %d\n", qman_fq_fqid(&unit_fq.fq_base)); -+#endif -+ -+ /* Try packet sizes from 64-bytes to just above the maximum */ -+ for (size = 64; size <= 9600 + 128; size += 64) { -+ for (headroom = DPA_BP_HEAD; headroom < 0x800; headroom += 16) { -+ int ret; -+ struct sk_buff *skb; -+ -+ test_count++; -+ -+ skb = dev_alloc_skb(size + headroom); -+ -+ if (!skb) { -+ pr_err("Failed to allocate skb\n"); -+ err = -ENOMEM; -+ goto end_test; -+ } -+ -+ if (skb_end_pointer(skb) - skb->head >= -+ dpa_get_max_frm()) -+ (*percpu_priv->dpa_bp_count)--; -+ -+ skb_put(skb, size + headroom); -+ skb_pull(skb, headroom); -+ -+ tx_unit_skb_head = skb->head; -+ tx_unit_skb_end = skb_end_pointer(skb); -+ -+ skb_set_queue_mapping(skb, smp_processor_id()); -+ -+ /* tx */ -+ ret = net_dev->netdev_ops->ndo_start_xmit(skb, net_dev); -+ -+ if (ret != NETDEV_TX_OK) { -+ pr_err("Failed to TX with err %d\n", ret); -+ err = -EIO; -+ goto end_test; -+ } -+ -+ /* Wait for it to arrive */ -+ ret = spin_event_timeout(qman_poll_dqrr(1) != 0, -+ 100000, 1); -+ -+ if (!ret) { -+ pr_err("TX Packet never arrived\n"); -+ /* -+ * Count the test as failed. -+ */ -+ tests_failed++; -+ } -+ -+ /* Was it good? */ -+ if (tx_unit_test_passed == false) { -+ pr_err("Test failed:\n"); -+ pr_err("size: %d pad: %d head: %p end: %p\n", -+ size, headroom, tx_unit_skb_head, -+ tx_unit_skb_end); -+ tests_failed++; -+ } -+ } -+ } -+ -+end_test: -+ err = qman_retire_fq(&unit_fq.fq_base, NULL); -+ if (unlikely(err < 0)) -+ pr_err("Could not retire TX Unit Test FQ (%d)\n", err); -+ -+ err = qman_oos_fq(&unit_fq.fq_base); -+ if (unlikely(err < 0)) -+ pr_err("Could not OOS TX Unit Test FQ (%d)\n", err); -+ -+#ifdef CONFIG_DPA_TX_RECYCLE -+ err = qman_retire_fq(&unit_recycle_fq.fq_base, NULL); -+ if (unlikely(err < 0)) -+ pr_err("Could not retire Recycle TX Unit Test FQ (%d)\n", err); -+ -+ err = qman_oos_fq(&unit_recycle_fq.fq_base); -+ if (unlikely(err < 0)) -+ pr_err("Could not OOS Recycle TX Unit Test FQ (%d)\n", err); -+ -+recycle_fq_init_fail: -+ qman_destroy_fq(&unit_recycle_fq.fq_base, 0); -+ -+recycle_fq_create_fail: -+ priv->recycle_fqs[smp_processor_id()] = oldrecycleq; -+#endif -+ -+fq_init_fail: -+ qman_destroy_fq(&unit_fq.fq_base, 0); -+ -+fq_create_fail: -+ priv->egress_fqs[smp_processor_id()] = oldq; -+ local_bh_enable(); -+ qman_irqsource_add(QM_PIRQ_DQRI); -+ tx_unit_test_ran = true; -+ set_cpus_allowed_ptr(current, old_cpumask); -+ free_cpumask_var(old_cpumask); -+ -+ pr_err("Tested %d/%d packets. %d failed\n", test_count, tx_unit_tested, -+ tests_failed); -+ -+ if (tests_failed) -+ err = -EINVAL; -+ -+ /* Reset counters */ -+ memset(&percpu_priv->stats, 0, sizeof(percpu_priv->stats)); -+ -+ return err; -+} -+#endif -+ -+static 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; -+ -+ if (!mac_dev) -+ goto no_mac; -+ -+ dpaa_eth_napi_enable(priv); -+ -+ err = mac_dev->init_phy(net_dev); -+ if (err < 0) { -+ if (netif_msg_ifup(priv)) -+ netdev_err(net_dev, "init_phy() = %d\n", err); -+ goto init_phy_failed; -+ } -+ -+ for_each_port_device(i, mac_dev->port_dev) -+ fm_port_enable(mac_dev->port_dev[i]); -+ -+ 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; -+ } -+ -+no_mac: -+ 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]); -+ -+init_phy_failed: -+ dpaa_eth_napi_disable(priv); -+ -+ return err; -+} -+ -+static int __cold dpa_stop(struct net_device *net_dev) -+{ -+ int _errno, i; -+ 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); -+ -+ if (!mac_dev) -+ return 0; -+ -+ _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) -+ fm_port_disable(mac_dev->port_dev[i]); -+ -+ if (mac_dev->phy_dev) -+ phy_disconnect(mac_dev->phy_dev); -+ mac_dev->phy_dev = NULL; -+ -+ dpaa_eth_napi_disable(priv); -+ -+ return _errno; -+} -+ -+static 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 = per_cpu_ptr(priv->percpu_priv, smp_processor_id()); -+ -+ if (netif_msg_timer(priv)) -+ netdev_crit(net_dev, "Transmit timeout latency: %u ms\n", -+ jiffies_to_msecs(jiffies - net_dev->trans_start)); -+ -+ percpu_priv->stats.tx_errors++; -+} -+ -+static int __devinit dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1) -+{ -+ return ((struct dpa_bp *)dpa_bp0)->size - -+ ((struct dpa_bp *)dpa_bp1)->size; -+} -+ -+static struct dpa_bp * __devinit __cold __must_check __attribute__((nonnull)) -+dpa_bp_probe(struct platform_device *_of_dev, size_t *count) -+{ -+ int i, lenp, na, ns; -+ struct device *dev; -+ struct device_node *dev_node; -+ const phandle *phandle_prop; -+ const uint32_t *bpid; -+ const uint32_t *bpool_cfg; -+ struct dpa_bp *dpa_bp; -+ int has_kernel_pool = 0; -+ int has_shared_pool = 0; -+ -+ dev = &_of_dev->dev; -+ -+ /* The default is one, if there's no property */ -+ *count = 1; -+ -+ /* There are three types of buffer pool configuration: -+ * 1) No bp assignment -+ * 2) A static assignment to an empty configuration -+ * 3) A static assignment to one or more configured pools -+ * -+ * We don't support using multiple unconfigured pools. -+ */ -+ -+ /* Get the buffer pools to be used */ -+ phandle_prop = of_get_property(dev->of_node, -+ "fsl,bman-buffer-pools", &lenp); -+ -+ if (phandle_prop) -+ *count = lenp / sizeof(phandle); -+ else { -+ if (default_pool) -+ return default_pool; -+ -+ has_kernel_pool = 1; -+ } -+ -+ dpa_bp = devm_kzalloc(dev, *count * sizeof(*dpa_bp), GFP_KERNEL); -+ if (unlikely(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 && phandle_prop; i++) { -+ of_node_put(dev_node); -+ dev_node = of_find_node_by_phandle(phandle_prop[i]); -+ if (unlikely(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; -+ } -+ -+ bpid = of_get_property(dev_node, "fsl,bpid", &lenp); -+ if ((bpid == NULL) || (lenp != sizeof(*bpid))) { -+ dev_err(dev, "fsl,bpid property not found.\n"); -+ dpa_bp = ERR_PTR(-EINVAL); -+ goto _return_of_node_put; -+ } -+ dpa_bp[i].bpid = *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 = 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; -+ -+ has_shared_pool = 1; -+ } else { -+ has_kernel_pool = 1; -+ } -+ -+ if (i > 0) -+ has_shared_pool = 1; -+ } -+ -+ if (has_kernel_pool && has_shared_pool) { -+ dev_err(dev, "Invalid buffer pool configuration " -+ "for node %s\n", dev_node->full_name); -+ dpa_bp = ERR_PTR(-EINVAL); -+ goto _return_of_node_put; -+ } else if (has_kernel_pool) { -+ dpa_bp->target_count = DEFAULT_COUNT; -+ dpa_bp->size = DEFAULT_BUF_SIZE; -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ if (dpa_bp->size > PAGE_SIZE) { -+ dev_warn(dev, "Default buffer size too large. " -+ "Round down to PAGE_SIZE\n"); -+ dpa_bp->size = PAGE_SIZE; -+ } -+#endif -+ dpa_bp->kernel_pool = 1; -+ } -+ -+ 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; -+} -+ -+static 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; -+ -+ if (dpa_bp->kernel_pool) { -+ priv->shared = 0; -+ -+ if (netif_msg_probe(priv)) -+ dev_info(net_dev->dev.parent, -+ "Using private BM buffer pools\n"); -+ } else { -+ priv->shared = 1; -+ } -+ -+ 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, dpa_bp); -+ priv->dpa_bp = NULL; -+ return err; -+ } -+ -+ /* For now, just point to the default pool. -+ * We can add support for more pools, later -+ */ -+ if (dpa_bp->kernel_pool) -+ priv->dpa_bp = default_pool; -+ } -+ -+ return 0; -+} -+ -+static struct mac_device * __devinit __cold __must_check -+__attribute__((nonnull)) -+dpa_mac_probe(struct platform_device *_of_dev) -+{ -+ struct device *dpa_dev, *dev; -+ struct device_node *mac_node; -+ int lenp; -+ const phandle *phandle_prop; -+ struct platform_device *of_dev; -+ struct mac_device *mac_dev; -+#ifdef CONFIG_FSL_DPA_1588 -+ struct net_device *net_dev = NULL; -+ struct dpa_priv_s *priv = NULL; -+ struct device_node *timer_node; -+#endif -+ -+ phandle_prop = of_get_property(_of_dev->dev.of_node, -+ "fsl,fman-mac", &lenp); -+ if (phandle_prop == NULL) -+ return NULL; -+ -+ BUG_ON(lenp != sizeof(phandle)); -+ -+ dpa_dev = &_of_dev->dev; -+ -+ mac_node = of_find_node_by_phandle(*phandle_prop); -+ if (unlikely(mac_node == NULL)) { -+ dev_err(dpa_dev, "of_find_node_by_phandle() failed\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_DPA_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))) { -+ priv = netdev_priv(net_dev); -+ if (!dpa_ptp_init(priv)) -+ dev_info(dev, "%s: ptp-timer enabled\n", -+ mac_node->full_name); -+ } -+ } -+#endif -+ -+ return mac_dev; -+} -+ -+static const char fsl_qman_frame_queues[][25] __devinitconst = { -+ [RX] = "fsl,qman-frame-queues-rx", -+ [TX] = "fsl,qman-frame-queues-tx" -+}; -+ -+#ifdef CONFIG_DEBUG_FS -+static int __cold dpa_debugfs_show(struct seq_file *file, void *offset) -+{ -+ int i; -+ struct dpa_priv_s *priv; -+ struct dpa_percpu_priv_s *percpu_priv, total; -+ struct dpa_bp *dpa_bp; -+ unsigned int dpa_bp_count = 0; -+ unsigned int count_total = 0; -+ struct qm_mcr_querycgr query_cgr; -+ -+ BUG_ON(offset == NULL); -+ -+ priv = netdev_priv((struct net_device *)file->private); -+ -+ dpa_bp = priv->dpa_bp; -+ -+ memset(&total, 0, sizeof(total)); -+ -+ /* "Standard" counters */ -+ seq_printf(file, "\nDPA counters for %s:\n" -+ "CPU irqs rx tx recycle" \ -+ " confirm tx sg tx err rx err l4 hxs drp bp count\n", -+ priv->net_dev->name); -+ for_each_online_cpu(i) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i); -+ -+ /* Only private interfaces have an associated counter for bp -+ * buffers */ -+ if (!priv->shared) -+ dpa_bp_count = *percpu_priv->dpa_bp_count; -+ -+ total.in_interrupt += percpu_priv->in_interrupt; -+ total.stats.rx_packets += percpu_priv->stats.rx_packets; -+ total.stats.tx_packets += percpu_priv->stats.tx_packets; -+ total.tx_returned += percpu_priv->tx_returned; -+ total.tx_confirm += percpu_priv->tx_confirm; -+ total.tx_frag_skbuffs += percpu_priv->tx_frag_skbuffs; -+ total.stats.tx_errors += percpu_priv->stats.tx_errors; -+ total.stats.rx_errors += percpu_priv->stats.rx_errors; -+ total.l4_hxs_errors += percpu_priv->l4_hxs_errors; -+ count_total += dpa_bp_count; -+ -+ seq_printf(file, " %hu/%hu %8u %8lu %8lu %8u %8u" \ -+ " %8u %8lu %8lu %8u %8d\n", -+ get_hard_smp_processor_id(i), i, -+ percpu_priv->in_interrupt, -+ percpu_priv->stats.rx_packets, -+ percpu_priv->stats.tx_packets, -+ percpu_priv->tx_returned, -+ percpu_priv->tx_confirm, -+ percpu_priv->tx_frag_skbuffs, -+ percpu_priv->stats.tx_errors, -+ percpu_priv->stats.rx_errors, -+ percpu_priv->l4_hxs_errors, -+ dpa_bp_count); -+ } -+ seq_printf(file, "Total %8u %8lu %8lu %8u %8u %8u %8lu %8lu"\ -+ " %8u %8d\n", -+ total.in_interrupt, -+ total.stats.rx_packets, -+ total.stats.tx_packets, -+ total.tx_returned, -+ total.tx_confirm, -+ total.tx_frag_skbuffs, -+ total.stats.tx_errors, -+ total.stats.rx_errors, -+ total.l4_hxs_errors, -+ count_total); -+ -+ /* Congestion stats */ -+ seq_printf(file, "\nDevice congestion stats:\n"); -+ seq_printf(file, "Device has been congested for %d ms.\n", -+ jiffies_to_msecs(priv->cgr_data.congested_jiffies)); -+ -+ qman_query_cgr(&priv->cgr_data.cgr, &query_cgr); -+ seq_printf(file, "CGR id %d avg count: %llu\n", -+ priv->cgr_data.cgr.cgrid, qm_mcr_querycgr_a_get64(&query_cgr)); -+ seq_printf(file, "Device entered congestion %u times. " -+ "Current congestion state is: %s.\n", -+ priv->cgr_data.cgr_congested_count, -+ query_cgr.cgr.cs ? "congested" : "not congested"); -+ /* Reset congestion stats (like QMan CGR API does) */ -+ priv->cgr_data.congested_jiffies = 0; -+ priv->cgr_data.cgr_congested_count = 0; -+ -+ /* Rx Errors demultiplexing */ -+ seq_printf(file, "\nDPA RX Errors:\nCPU dma err phys err" \ -+ " size err hdr err csum err\n"); -+ for_each_online_cpu(i) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i); -+ -+ total.rx_errors.dme += percpu_priv->rx_errors.dme; -+ total.rx_errors.fpe += percpu_priv->rx_errors.fpe; -+ total.rx_errors.fse += percpu_priv->rx_errors.fse; -+ total.rx_errors.phe += percpu_priv->rx_errors.phe; -+ total.rx_errors.cse += percpu_priv->rx_errors.cse; -+ -+ seq_printf(file, " %hu/%hu %8u %8u %8u" \ -+ " %8u %8u\n", -+ get_hard_smp_processor_id(i), i, -+ percpu_priv->rx_errors.dme, -+ percpu_priv->rx_errors.fpe, -+ percpu_priv->rx_errors.fse, -+ percpu_priv->rx_errors.phe, -+ percpu_priv->rx_errors.cse); -+ } -+ seq_printf(file, "Total %8u %8u %8u %8u %8u\n", -+ total.rx_errors.dme, -+ total.rx_errors.fpe, -+ total.rx_errors.fse, -+ total.rx_errors.phe, -+ total.rx_errors.cse); -+ -+ /* ERN demultiplexing */ -+ seq_printf(file, "\nDPA ERN counters:\n CPU cg_td wred " \ -+ "err_cond early_w late_w fq_td fq_ret" \ -+ " orp_z\n"); -+ for_each_online_cpu(i) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i); -+ -+ total.ern_cnt.cg_tdrop += percpu_priv->ern_cnt.cg_tdrop; -+ total.ern_cnt.wred += percpu_priv->ern_cnt.wred; -+ total.ern_cnt.err_cond += percpu_priv->ern_cnt.err_cond; -+ total.ern_cnt.early_window += percpu_priv->ern_cnt.early_window; -+ total.ern_cnt.late_window += percpu_priv->ern_cnt.late_window; -+ total.ern_cnt.fq_tdrop += percpu_priv->ern_cnt.fq_tdrop; -+ total.ern_cnt.fq_retired += percpu_priv->ern_cnt.fq_retired; -+ total.ern_cnt.orp_zero += percpu_priv->ern_cnt.orp_zero; -+ -+ seq_printf(file, " %hu/%hu %8u %8u %8u %8u %8u %8u" \ -+ " %8u %8u\n", -+ get_hard_smp_processor_id(i), i, -+ percpu_priv->ern_cnt.cg_tdrop, -+ percpu_priv->ern_cnt.wred, -+ percpu_priv->ern_cnt.err_cond, -+ percpu_priv->ern_cnt.early_window, -+ percpu_priv->ern_cnt.late_window, -+ percpu_priv->ern_cnt.fq_tdrop, -+ percpu_priv->ern_cnt.fq_retired, -+ percpu_priv->ern_cnt.orp_zero); -+ } -+ seq_printf(file, "Total %8u %8u %8u %8u %8u %8u %8u %8u\n", -+ total.ern_cnt.cg_tdrop, -+ total.ern_cnt.wred, -+ total.ern_cnt.err_cond, -+ total.ern_cnt.early_window, -+ total.ern_cnt.late_window, -+ total.ern_cnt.fq_tdrop, -+ total.ern_cnt.fq_retired, -+ total.ern_cnt.orp_zero); -+ -+ return 0; -+} -+ -+static int __cold dpa_debugfs_open(struct inode *inode, struct file *file) -+{ -+ int _errno; -+ const struct net_device *net_dev; -+ -+ _errno = single_open(file, dpa_debugfs_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; -+} -+ -+static const struct file_operations dpa_debugfs_fops = { -+ .open = dpa_debugfs_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+#endif -+ -+#ifdef CONFIG_DPAA_ETH_USE_NDO_SELECT_QUEUE -+static u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb) -+{ -+ return smp_processor_id(); -+} -+#endif -+ -+static const struct net_device_ops dpa_private_ops = { -+ .ndo_open = dpa_start, -+ .ndo_start_xmit = dpa_tx, -+ .ndo_stop = dpa_stop, -+ .ndo_tx_timeout = dpa_timeout, -+ .ndo_get_stats = dpa_get_stats, -+ .ndo_set_mac_address = dpa_set_mac_address, -+ .ndo_validate_addr = eth_validate_addr, -+#ifdef CONFIG_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, -+#ifdef CONFIG_FSL_DPA_1588 -+ .ndo_do_ioctl = dpa_ioctl, -+#endif -+}; -+ -+static const struct net_device_ops dpa_shared_ops = { -+ .ndo_open = dpa_start, -+ .ndo_start_xmit = dpa_shared_tx, -+ .ndo_stop = dpa_stop, -+ .ndo_tx_timeout = dpa_timeout, -+ .ndo_get_stats = dpa_get_stats, -+ .ndo_set_mac_address = dpa_set_mac_address, -+ .ndo_validate_addr = eth_validate_addr, -+#ifdef CONFIG_DPAA_ETH_USE_NDO_SELECT_QUEUE -+ .ndo_select_queue = dpa_select_queue, -+#endif -+ .ndo_set_rx_mode = dpa_set_rx_mode, -+#ifdef CONFIG_FSL_DPA_1588 -+ .ndo_do_ioctl = dpa_ioctl, -+#endif -+}; -+ -+static u32 rx_pool_channel; -+static DEFINE_SPINLOCK(rx_pool_channel_init); -+ -+static int __devinit dpa_get_channel(struct device *dev, -+ struct device_node *dpa_node) -+{ -+ 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; -+} -+ -+struct fqid_cell { -+ uint32_t start; -+ uint32_t count; -+}; -+ -+static const struct fqid_cell default_fqids[][3] __devinitconst = { -+ [RX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_RX_QUEUES} }, -+ [TX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_TX_QUEUES} } -+}; -+ -+static const struct fqid_cell tx_confirm_fqids[] __devinitconst = { -+ {0, DPAA_ETH_TX_QUEUES} -+}; -+ -+#ifdef CONFIG_DPA_TX_RECYCLE -+static const struct fqid_cell tx_recycle_fqids[] = { -+ {0, DPAA_ETH_TX_QUEUES} -+}; -+#endif -+ -+static int __devinit -+dpa_fq_probe(struct platform_device *_of_dev, struct list_head *list, -+ struct dpa_fq **defq, struct dpa_fq **errq, -+ struct dpa_fq **fqs, struct dpa_fq **txconfq, -+ struct dpa_fq **txrecycle, int ptype) -+{ -+ struct device *dev = &_of_dev->dev; -+ struct device_node *np = dev->of_node; -+ const struct fqid_cell *fqids; -+ int i, j, lenp; -+ int num_fqids; -+ struct dpa_fq *dpa_fq; -+ int err = 0; -+ -+ /* per-core tx confirmation queues */ -+ if (txconfq) { -+ fqids = tx_confirm_fqids; -+ dpa_fq = devm_kzalloc(dev, sizeof(*dpa_fq) * fqids[0].count, -+ GFP_KERNEL); -+ if (dpa_fq == NULL) { -+ dev_err(dev, "devm_kzalloc() failed\n"); -+ return -ENOMEM; -+ } -+ *txconfq = dpa_fq; -+ for (j = 0; j < fqids[0].count; j++) -+ dpa_fq[j].fq_type = FQ_TYPE_TX_CONFIRM; -+ -+ for (j = 0; j < fqids[0].count; j++) { -+ dpa_fq[j].fqid = fqids[0].start ? -+ fqids[0].start + j : 0; -+ _dpa_assign_wq(dpa_fq + j); -+ list_add_tail(&dpa_fq[j].list, list); -+ } -+ } -+ -+#ifdef CONFIG_DPA_TX_RECYCLE -+ /* per-core tx queues for recycleable frames (FManv3 only) */ -+ if (txrecycle) { -+ fqids = tx_recycle_fqids; -+ dpa_fq = devm_kzalloc(dev, sizeof(*dpa_fq) * fqids[0].count, -+ GFP_KERNEL); -+ if (dpa_fq == NULL) { -+ dev_err(dev, "devm_kzalloc() failed\n"); -+ return -ENOMEM; -+ } -+ -+ *txrecycle = dpa_fq; -+ for (j = 0; j < fqids[0].count; j++) -+ dpa_fq[j].fq_type = FQ_TYPE_TX_RECYCLE; -+ -+ for (j = 0; j < fqids[0].count; j++) { -+ dpa_fq[j].fqid = fqids[0].start ? -+ fqids[0].start + j : 0; -+ _dpa_assign_wq(dpa_fq + j); -+ list_add_tail(&dpa_fq[j].list, list); -+ } -+ } -+#endif -+ -+ fqids = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp); -+ if (fqids == NULL) { -+ fqids = default_fqids[ptype]; -+ num_fqids = 3; -+ } else -+ num_fqids = lenp / sizeof(*fqids); -+ -+ for (i = 0; i < num_fqids; i++) { -+ dpa_fq = devm_kzalloc(dev, sizeof(*dpa_fq) * fqids[i].count, -+ GFP_KERNEL); -+ if (dpa_fq == NULL) { -+ dev_err(dev, "devm_kzalloc() failed\n"); -+ return -ENOMEM; -+ } -+ -+ /* The first queue is the Error queue */ -+ if (i == 0 && errq) { -+ *errq = dpa_fq; -+ -+ if (fqids[i].count != 1) { -+ dev_err(dev, "Too many error queues!\n"); -+ err = -EINVAL; -+ goto invalid_error_queues; -+ } -+ -+ dpa_fq[0].fq_type = (ptype == RX ? -+ FQ_TYPE_RX_ERROR : FQ_TYPE_TX_ERROR); -+ } -+ -+ /* The second queue is the the Default queue */ -+ if (i == 1 && defq) { -+ *defq = dpa_fq; -+ -+ if (fqids[i].count != 1) { -+ dev_err(dev, "Too many default queues!\n"); -+ err = -EINVAL; -+ goto invalid_default_queues; -+ } -+ -+ dpa_fq[0].fq_type = (ptype == RX ? -+ FQ_TYPE_RX_DEFAULT : FQ_TYPE_TX_CONFIRM); -+ } -+ -+ /* -+ * All subsequent queues are gathered together. -+ * The first 8 will be used by the private linux interface -+ * if these are TX queues -+ */ -+ if (i == 2 || (!errq && i == 0 && fqs)) { -+ *fqs = dpa_fq; -+ -+ for (j = 0; j < fqids[i].count; j++) -+ dpa_fq[j].fq_type = (ptype == RX ? -+ FQ_TYPE_RX_PCD : FQ_TYPE_TX); -+ } -+ -+#warning We lost the 8-queue enforcement -+ -+ for (j = 0; j < fqids[i].count; j++) { -+ dpa_fq[j].fqid = fqids[i].start ? -+ fqids[i].start + j : 0; -+ _dpa_assign_wq(dpa_fq + j); -+ list_add_tail(&dpa_fq[j].list, list); -+ } -+ } -+ -+invalid_default_queues: -+invalid_error_queues: -+ return err; -+} -+ -+static void dpa_setup_ingress(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 void dpa_setup_egress(struct dpa_priv_s *priv, -+ struct list_head *head, struct dpa_fq *fq, -+ struct fm_port *port) -+{ -+ struct list_head *ptr = &fq->list; -+ int i = 0; -+ -+ while (true) { -+ struct dpa_fq *iter = list_entry(ptr, struct dpa_fq, list); -+ if (priv->shared) -+ iter->fq_base = shared_egress_fq; -+ else -+ iter->fq_base = private_egress_fq; -+ -+ iter->net_dev = priv->net_dev; -+ priv->egress_fqs[i++] = &iter->fq_base; -+ -+ if (port) { -+ iter->flags = QMAN_FQ_FLAG_TO_DCPORTAL; -+ iter->channel = fm_get_tx_port_channel(port); -+ } else -+ iter->flags = QMAN_FQ_FLAG_NO_MODIFY; -+ -+ if (list_is_last(ptr, head)) -+ break; -+ -+ ptr = ptr->next; -+ } -+} -+ -+#ifdef CONFIG_DPA_TX_RECYCLE -+static void dpa_setup_recycle_queues(struct dpa_priv_s *priv, struct dpa_fq *fq, -+ struct fm_port *port) -+{ -+ int i = 0; -+ struct list_head *ptr = &fq->list; -+ -+ for (i = 0; i < DPAA_ETH_TX_QUEUES; i++) { -+ struct dpa_fq *iter = list_entry(ptr, struct dpa_fq, list); -+ -+ iter->fq_base = private_egress_fq; -+ iter->net_dev = priv->net_dev; -+ -+ priv->recycle_fqs[i] = &iter->fq_base; -+ -+ iter->flags = QMAN_FQ_FLAG_TO_DCPORTAL; -+ iter->channel = fm_get_tx_port_channel(port); -+ -+ ptr = ptr->next; -+ } -+} -+#endif -+ -+static void dpa_setup_conf_queues(struct dpa_priv_s *priv, struct dpa_fq *fq) -+{ -+ struct list_head *ptr = &fq->list; -+ int i; -+ -+ /* -+ * Configure the queues to be core affine. -+ * The implicit assumption here is that each cpu has its own Tx queue -+ */ -+ for (i = 0; i < DPAA_ETH_TX_QUEUES; i++) { -+ struct dpa_fq *iter = list_entry(ptr, struct dpa_fq, list); -+ -+ dpa_setup_ingress(priv, iter, &tx_private_defq); -+ /* Leave the confirmation queue in the default pool channel */ -+ priv->conf_fqs[i] = &iter->fq_base; -+ -+ ptr = ptr->next; -+ } -+} -+ -+static void dpa_setup_ingress_queues(struct dpa_priv_s *priv, -+ struct list_head *head, struct dpa_fq *fq) -+{ -+ struct list_head *ptr = &fq->list; -+ u32 fqid; -+ int portals[NR_CPUS]; -+ int i, cpu, num_portals = 0; -+ const cpumask_t *affine_cpus = qman_affine_cpus(); -+ -+ for_each_cpu(cpu, affine_cpus) -+ portals[num_portals++] = qman_affine_channel(cpu); -+ if (num_portals == 0) { -+ dev_err(fq->net_dev->dev.parent, -+ "No Qman software (affine) channels found"); -+ return; -+ } -+ -+ i = 0; -+ fqid = 0; -+ if (priv->mac_dev) -+ fqid = (priv->mac_dev->res->start & 0x1fffff) >> 6; -+ -+ while (true) { -+ struct dpa_fq *iter = list_entry(ptr, struct dpa_fq, list); -+ -+ if (priv->shared) -+ dpa_setup_ingress(priv, iter, &rx_shared_fq); -+ else -+ dpa_setup_ingress(priv, iter, &rx_private_defq); -+ -+ if (!iter->fqid) -+ iter->fqid = fqid++; -+ -+ /* Assign the queues to a channel in a round-robin fashion */ -+ iter->channel = portals[i]; -+ i = (i + 1) % num_portals; -+ -+ if (list_is_last(ptr, head)) -+ break; -+ -+ ptr = ptr->next; -+ } -+} -+ -+static void __devinit -+dpaa_eth_init_tx_port(struct fm_port *port, struct dpa_fq *errq, -+ struct dpa_fq *defq, bool has_timer) -+{ -+ struct fm_port_params tx_port_param; -+ -+ dpaa_eth_init_port(tx, port, tx_port_param, errq->fqid, defq->fqid, -+ DPA_TX_PRIV_DATA_SIZE, has_timer); -+} -+ -+static void __devinit -+dpaa_eth_init_rx_port(struct fm_port *port, struct dpa_bp *bp, size_t count, -+ struct dpa_fq *errq, struct dpa_fq *defq, bool has_timer) -+{ -+ struct fm_port_params rx_port_param; -+ int i; -+ -+ count = min(ARRAY_SIZE(rx_port_param.pool_param), count); -+ rx_port_param.num_pools = 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 = bp[i].size; -+ } -+ -+ dpaa_eth_init_port(rx, port, rx_port_param, errq->fqid, defq->fqid, -+ DPA_RX_PRIV_DATA_SIZE, has_timer); -+} -+ -+static void dpa_rx_fq_init(struct dpa_priv_s *priv, struct list_head *head, -+ struct dpa_fq *defq, struct dpa_fq *errq, -+ struct dpa_fq *fqs) -+{ -+ if (fqs) -+ dpa_setup_ingress_queues(priv, head, fqs); -+ -+ /* Only real devices need default/error queues set up */ -+ if (!priv->mac_dev) -+ return; -+ -+ if (defq->fqid == 0 && netif_msg_probe(priv)) -+ pr_info("Using dynamic RX QM frame queues\n"); -+ -+ if (priv->shared) { -+ dpa_setup_ingress(priv, defq, &rx_shared_fq); -+ dpa_setup_ingress(priv, errq, &rx_shared_fq); -+ } else { -+ dpa_setup_ingress(priv, defq, &rx_private_defq); -+ dpa_setup_ingress(priv, errq, &rx_private_errq); -+ } -+} -+ -+static void dpa_tx_fq_init(struct dpa_priv_s *priv, struct list_head *head, -+ struct dpa_fq *defq, struct dpa_fq *errq, -+ struct dpa_fq *fqs, struct dpa_fq *confqs, -+ struct dpa_fq *recyclefqs, struct fm_port *port) -+{ -+ if (fqs) -+ dpa_setup_egress(priv, head, fqs, port); -+ -+ /* Only real devices need default/error queues set up */ -+ if (!priv->mac_dev) -+ return; -+ -+ if (defq->fqid == 0 && netif_msg_probe(priv)) -+ pr_info("Using dynamic TX QM frame queues\n"); -+ -+ /* The shared driver doesn't use tx confirmation */ -+ if (priv->shared) { -+ dpa_setup_ingress(priv, defq, &tx_shared_defq); -+ dpa_setup_ingress(priv, errq, &tx_shared_errq); -+ } else { -+ dpa_setup_ingress(priv, defq, &tx_private_defq); -+ dpa_setup_ingress(priv, errq, &tx_private_errq); -+ if (confqs) -+ dpa_setup_conf_queues(priv, confqs); -+#ifdef CONFIG_DPA_TX_RECYCLE -+ if (recyclefqs) -+ dpa_setup_recycle_queues(priv, recyclefqs, port); -+#endif -+ -+ } -+} -+ -+static int dpa_netdev_init(struct device_node *dpa_node, -+ struct net_device *net_dev) -+{ -+ int err; -+ const uint8_t *mac_addr; -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct device *dev = net_dev->dev.parent; -+ -+ net_dev->features |= DPA_NETIF_FEATURES; -+ net_dev->vlan_features |= DPA_NETIF_FEATURES; -+ -+ if (!priv->mac_dev) { -+ /* Get the MAC address */ -+ mac_addr = of_get_mac_address(dpa_node); -+ if (mac_addr == NULL) { -+ if (netif_msg_probe(priv)) -+ dev_err(dev, "No MAC address found!\n"); -+ return -EINVAL; -+ } -+ } else { -+ net_dev->mem_start = priv->mac_dev->res->start; -+ net_dev->mem_end = priv->mac_dev->res->end; -+ -+ mac_addr = priv->mac_dev->addr; -+ net_dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); -+ net_dev->vlan_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); -+ -+ /* -+ * Advertise S/G and HIGHDMA support for MAC-ful, -+ * private interfaces -+ */ -+ if (!priv->shared) { -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ net_dev->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. -+ */ -+ | NETIF_F_GSO; -+ net_dev->vlan_features |= NETIF_F_SG | NETIF_F_HIGHDMA -+ | NETIF_F_GSO; -+#endif -+ /* Advertise GRO support */ -+ net_dev->features |= NETIF_F_GRO; -+ net_dev->vlan_features |= NETIF_F_GRO; -+ } -+ } -+ -+ memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len); -+ memcpy(net_dev->dev_addr, mac_addr, net_dev->addr_len); -+ -+ SET_ETHTOOL_OPS(net_dev, &dpa_ethtool_ops); -+ net_dev->needed_headroom = DPA_BP_HEAD; -+ 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_DEBUG_FS -+ priv->debugfs_file = debugfs_create_file(net_dev->name, S_IRUGO, -+ dpa_debugfs_root, net_dev, -+ &dpa_debugfs_fops); -+ if (unlikely(priv->debugfs_file == NULL)) { -+ netdev_err(net_dev, "debugfs_create_file(%s/%s/%s) = %d\n", -+ powerpc_debugfs_root->d_iname, -+ dpa_debugfs_root->d_iname, -+ net_dev->name, err); -+ -+ unregister_netdev(net_dev); -+ return -ENOMEM; -+ } -+#endif -+ -+ return 0; -+} -+ -+static int dpa_shared_netdev_init(struct device_node *dpa_node, -+ struct net_device *net_dev) -+{ -+ net_dev->netdev_ops = &dpa_shared_ops; -+ -+ return dpa_netdev_init(dpa_node, net_dev); -+} -+ -+static int dpa_private_netdev_init(struct device_node *dpa_node, -+ struct net_device *net_dev) -+{ -+ int i; -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct dpa_percpu_priv_s *percpu_priv; -+ -+ /* -+ * Although we access another CPU's private data here -+ * we do it at initialization so it is safe -+ */ -+ for_each_online_cpu(i) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i); -+ percpu_priv->net_dev = net_dev; -+ -+ percpu_priv->dpa_bp = priv->dpa_bp; -+ percpu_priv->dpa_bp_count = -+ per_cpu_ptr(priv->dpa_bp->percpu_count, i); -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ /* init the percpu list and add some skbs */ -+ skb_queue_head_init(&percpu_priv->skb_list); -+ -+ dpa_list_add_skbs(percpu_priv, DEFAULT_SKB_COUNT); -+#endif -+ netif_napi_add(net_dev, &percpu_priv->napi, dpaa_eth_poll, -+ DPA_NAPI_WEIGHT); -+ } -+ -+ net_dev->netdev_ops = &dpa_private_ops; -+ -+ return dpa_netdev_init(dpa_node, net_dev); -+} -+ -+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"); -+ BUG(); -+ -+ return 0; -+} -+ -+int dpa_free_pcd_fqids(struct device *dev, uint32_t base_fqid) -+{ -+ -+ dev_crit(dev, "callback not implemented!\n"); -+ BUG(); -+ -+ return 0; -+} -+ -+static int dpaa_eth_add_channel(void *__arg) -+{ -+ const cpumask_t *cpus = qman_affine_cpus(); -+ u32 pool = QM_SDQCR_CHANNELS_POOL_CONV((u32)(unsigned long)__arg); -+ int cpu; -+ -+ for_each_cpu(cpu, cpus) { -+ set_cpus_allowed_ptr(current, get_cpu_mask(cpu)); -+ qman_static_dequeue_add(pool); -+ } -+ return 0; -+} -+ -+static 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 = DPA_CS_THRESHOLD_10G; -+ else -+ cs_th = DPA_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; -+} -+ -+static const struct of_device_id dpa_match[] __devinitconst ; -+static int __devinit -+dpaa_eth_probe(struct platform_device *_of_dev) -+{ -+ int err, i; -+ struct device *dev; -+ struct device_node *dpa_node; -+ struct dpa_bp *dpa_bp; -+ struct dpa_fq *dpa_fq, *tmp; -+ struct list_head rxfqlist; -+ struct list_head txfqlist; -+ size_t count; -+ struct net_device *net_dev = NULL; -+ struct dpa_priv_s *priv = NULL; -+ struct dpa_fq *rxdefault = NULL; -+ struct dpa_fq *txdefault = NULL; -+ struct dpa_fq *rxerror = NULL; -+ struct dpa_fq *txerror = NULL; -+ struct dpa_fq *rxextra = NULL; -+ struct dpa_fq *txfqs = NULL; -+ struct dpa_fq *txconf = NULL; -+ struct dpa_fq *txrecycle = NULL; -+ struct fm_port *rxport = NULL; -+ struct fm_port *txport = NULL; -+ bool has_timer = FALSE; -+ bool is_shared = false; -+ struct mac_device *mac_dev; -+ int proxy_enet; -+ const struct of_device_id *match; -+ -+ dev = &_of_dev->dev; -+ -+ dpa_node = dev->of_node; -+ -+ match = of_match_device(dpa_match, dev); -+ if (!match) -+ return -EINVAL; -+ -+ if (!of_device_is_available(dpa_node)) -+ return -ENODEV; -+ -+ /* -+ * If it's not an fsl,dpa-ethernet node, we just serve as a proxy -+ * initializer driver, and don't do any linux device setup -+ */ -+ proxy_enet = strcmp(match->compatible, "fsl,dpa-ethernet"); -+ -+ /* -+ * Allocate this early, so we can store relevant information in -+ * the private area -+ */ -+ if (!proxy_enet) { -+ net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TX_QUEUES); -+ if (!net_dev) { -+ dev_err(dev, "alloc_etherdev_mq() failed\n"); -+ return -ENOMEM; -+ } -+ -+ /* 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; -+ -+ priv->msg_enable = netif_msg_init(debug, -1); -+ } -+ -+ /* Get the buffer pools assigned to this interface */ -+ dpa_bp = dpa_bp_probe(_of_dev, &count); -+ if (IS_ERR(dpa_bp)) { -+ err = PTR_ERR(dpa_bp); -+ goto bp_probe_failed; -+ } -+ if (!dpa_bp->kernel_pool) -+ is_shared = true; -+ -+ mac_dev = dpa_mac_probe(_of_dev); -+ if (IS_ERR(mac_dev)) { -+ err = PTR_ERR(mac_dev); -+ goto mac_probe_failed; -+ } else if (mac_dev) { -+ rxport = mac_dev->port_dev[RX]; -+ txport = mac_dev->port_dev[TX]; -+ } -+ -+ INIT_LIST_HEAD(&rxfqlist); -+ INIT_LIST_HEAD(&txfqlist); -+ -+ if (rxport) -+ err = dpa_fq_probe(_of_dev, &rxfqlist, &rxdefault, &rxerror, -+ &rxextra, NULL, NULL, RX); -+ else -+ err = dpa_fq_probe(_of_dev, &rxfqlist, NULL, NULL, -+ &rxextra, NULL, NULL, RX); -+ -+ if (err < 0) -+ goto rx_fq_probe_failed; -+ -+ if (txport) -+#ifdef CONFIG_DPA_TX_RECYCLE -+ err = dpa_fq_probe(_of_dev, &txfqlist, &txdefault, &txerror, -+ &txfqs, (is_shared ? NULL : &txconf), -+ (is_shared ? NULL : &txrecycle), TX); -+#else -+ err = dpa_fq_probe(_of_dev, &txfqlist, &txdefault, &txerror, -+ &txfqs, (is_shared ? NULL : &txconf), NULL, TX); -+#endif -+ else -+ err = dpa_fq_probe(_of_dev, &txfqlist, NULL, NULL, &txfqs, -+ NULL, NULL, TX); -+ -+ if (err < 0) -+ goto tx_fq_probe_failed; -+ -+ /* -+ * Now we have all of the configuration information. -+ * We support a number of configurations: -+ * 1) Private interface - An optimized linux ethernet driver with -+ * a real network connection. -+ * 2) Shared interface - A device intended for virtual connections -+ * or for a real interface that is shared between partitions -+ * 3) Proxy initializer - Just configures the MAC on behalf of -+ * another partition -+ */ -+ -+ /* bp init */ -+ if (net_dev) { -+ struct task_struct *kth; -+ -+ err = dpa_bp_create(net_dev, dpa_bp, count); -+ -+ if (err < 0) -+ goto bp_create_failed; -+ -+ priv->mac_dev = mac_dev; -+ -+ priv->channel = dpa_get_channel(dev, dpa_node); -+ -+ if (priv->channel < 0) { -+ err = priv->channel; -+ goto get_channel_failed; -+ } -+ -+ /* Start a thread that will walk the cpus with affine portals -+ * and add this pool channel to each's dequeue mask. */ -+ kth = kthread_run(dpaa_eth_add_channel, -+ (void *)(unsigned long)priv->channel, -+ "dpaa_%p:%d", net_dev, priv->channel); -+ if (!kth) { -+ err = -ENOMEM; -+ goto add_channel_failed; -+ } -+ -+ dpa_rx_fq_init(priv, &rxfqlist, rxdefault, rxerror, rxextra); -+ dpa_tx_fq_init(priv, &txfqlist, txdefault, txerror, txfqs, -+ txconf, txrecycle, txport); -+ -+ /* -+ * 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. -+ * Don't create a congestion group for MAC-less interfaces. -+ */ -+ if (priv->mac_dev) { -+ err = dpaa_eth_cgr_init(priv); -+ if (err < 0) { -+ dev_err(dev, "Error initializing CGR\n"); -+ goto cgr_init_failed; -+ } -+ } -+ -+ /* Add the FQs to the interface, and make them active */ -+ INIT_LIST_HEAD(&priv->dpa_fq_list); -+ -+ list_for_each_entry_safe(dpa_fq, tmp, &rxfqlist, list) { -+ err = _dpa_fq_alloc(&priv->dpa_fq_list, dpa_fq); -+ if (err < 0) -+ goto fq_alloc_failed; -+ } -+ -+ list_for_each_entry_safe(dpa_fq, tmp, &txfqlist, list) { -+ err = _dpa_fq_alloc(&priv->dpa_fq_list, dpa_fq); -+ if (err < 0) -+ goto fq_alloc_failed; -+ } -+ -+ if (priv->tsu && priv->tsu->valid) -+ has_timer = TRUE; -+ } -+ -+ /* All real interfaces need their ports initialized */ -+ if (mac_dev) { -+ struct fm_port_pcd_param rx_port_pcd_param; -+ -+ dpaa_eth_init_rx_port(rxport, dpa_bp, count, rxerror, -+ rxdefault, has_timer); -+ dpaa_eth_init_tx_port(txport, txerror, txdefault, has_timer); -+ -+ 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); -+ } -+ -+ /* -+ * Proxy interfaces need to be started, and the allocated -+ * memory freed -+ */ -+ if (!net_dev) { -+ devm_kfree(&_of_dev->dev, dpa_bp); -+ devm_kfree(&_of_dev->dev, rxdefault); -+ devm_kfree(&_of_dev->dev, rxerror); -+ devm_kfree(&_of_dev->dev, txdefault); -+ devm_kfree(&_of_dev->dev, txerror); -+ -+ if (mac_dev) -+ for_each_port_device(i, mac_dev->port_dev) -+ fm_port_enable(mac_dev->port_dev[i]); -+ -+ return 0; -+ } -+ -+ /* Now we need to initialize either a private or shared interface */ -+ priv->percpu_priv = __alloc_percpu(sizeof(*priv->percpu_priv), -+ __alignof__(*priv->percpu_priv)); -+ if (priv->percpu_priv == NULL) { -+ dev_err(dev, "__alloc_percpu() failed\n"); -+ err = -ENOMEM; -+ goto alloc_percpu_failed; -+ } -+ -+ if (priv->shared) -+ err = dpa_shared_netdev_init(dpa_node, net_dev); -+ else -+ err = dpa_private_netdev_init(dpa_node, net_dev); -+ -+ if (err < 0) -+ goto netdev_init_failed; -+ -+ dpaa_eth_sysfs_init(&net_dev->dev); -+ -+#ifdef CONFIG_DPAA_ETH_UNIT_TESTS -+ /* The unit test is designed to test private interfaces */ -+ if (!priv->shared && !tx_unit_test_ran) { -+ err = dpa_tx_unit_test(net_dev); -+ -+ WARN_ON(err); -+ } -+#endif -+ -+ return 0; -+ -+netdev_init_failed: -+ if (net_dev) -+ free_percpu(priv->percpu_priv); -+alloc_percpu_failed: -+fq_alloc_failed: -+ if (net_dev) { -+ dpa_fq_free(dev, &priv->dpa_fq_list); -+ qman_release_cgrid(priv->cgr_data.cgr.cgrid); -+ qman_delete_cgr(&priv->cgr_data.cgr); -+ } -+cgr_init_failed: -+add_channel_failed: -+get_channel_failed: -+ if (net_dev) -+ dpa_bp_free(priv, priv->dpa_bp); -+bp_create_failed: -+tx_fq_probe_failed: -+rx_fq_probe_failed: -+mac_probe_failed: -+bp_probe_failed: -+ dev_set_drvdata(dev, NULL); -+ if (net_dev) -+ free_netdev(net_dev); -+ -+ return err; -+} -+ -+static const struct of_device_id dpa_match[] __devinitconst = { -+ { -+ .compatible = "fsl,dpa-ethernet" -+ }, -+ { -+ .compatible = "fsl,dpa-ethernet-init" -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, dpa_match); -+ -+static int __devexit __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); -+ -+ free_percpu(priv->percpu_priv); -+ -+ dpa_bp_free(priv, priv->dpa_bp); -+ -+#ifdef CONFIG_DEBUG_FS -+ debugfs_remove(priv->debugfs_file); -+#endif -+ -+#ifdef CONFIG_FSL_DPA_1588 -+ if (priv->tsu && priv->tsu->valid) -+ dpa_ptp_cleanup(priv); -+#endif -+ -+ free_netdev(net_dev); -+ -+ return err; -+} -+ -+static struct platform_driver dpa_driver = { -+ .driver = { -+ .name = KBUILD_MODNAME, -+ .of_match_table = dpa_match, -+ .owner = THIS_MODULE, -+ }, -+ .probe = dpaa_eth_probe, -+ .remove = __devexit_p(dpa_remove) -+}; -+ -+static int __init __cold dpa_load(void) -+{ -+ int _errno; -+ -+ pr_info(KBUILD_MODNAME ": " DPA_DESCRIPTION " (" VERSION ")\n"); -+ -+ /* initialise dpaa_eth mirror values */ -+ dpa_rx_extra_headroom = fm_get_rx_extra_headroom(); -+ dpa_max_frm = fm_get_max_frm(); -+ -+#ifdef CONFIG_DEBUG_FS -+ dpa_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, -+ powerpc_debugfs_root); -+ if (unlikely(dpa_debugfs_root == NULL)) { -+ _errno = -ENOMEM; -+ pr_err(KBUILD_MODNAME ": %s:%hu:%s(): " -+ "debugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n", -+ KBUILD_BASENAME".c", __LINE__, __func__, -+ powerpc_debugfs_root->d_iname, _errno); -+ goto _return; -+ } -+#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); -+ goto _return_debugfs_remove; -+ } -+ -+ goto _return; -+ -+_return_debugfs_remove: -+#ifdef CONFIG_DEBUG_FS -+ debugfs_remove(dpa_debugfs_root); -+#endif -+_return: -+ 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_DEBUG_FS -+ debugfs_remove(dpa_debugfs_root); -+#endif -+ -+ pr_debug(KBUILD_MODNAME ": %s:%s() ->\n", -+ KBUILD_BASENAME".c", __func__); -+} -+module_exit(dpa_unload); -diff --git a/drivers/net/dpa/dpaa_eth.h b/drivers/net/dpa/dpaa_eth.h -new file mode 100644 -index 0000000..d33696f ---- /dev/null -+++ b/drivers/net/dpa/dpaa_eth.h -@@ -0,0 +1,604 @@ -+/* -+ * 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 /* struct ethtool_ops */ -+#include -+#include /* struct list_head */ -+#include /* struct work_struct */ -+#include -+#include -+#include /* vlan_eth_hdr */ -+#include /* ip_hdr */ -+#include /* ipv6_hdr */ -+#ifdef CONFIG_DEBUG_FS -+#include /* struct dentry */ -+#endif -+ -+#include /* struct qman_fq */ -+ -+#include "dpaa_eth-common.h" -+ -+#include "fsl_fman.h" -+#include "fm_ext.h" -+#include "fm_port_ext.h" /* FM_PORT_FRM_ERR_* */ -+ -+#include "mac.h" /* struct mac_device */ -+ -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+#define dpa_get_rx_extra_headroom() fm_get_rx_extra_headroom() -+#else -+#define dpa_get_rx_extra_headroom() dpa_rx_extra_headroom -+#endif -+#define dpa_get_max_frm() dpa_max_frm -+ -+/* -+ * Currently we have the same max_frm on all interfaces, so these macros -+ * don't get a net_device argument. This will change in the future. -+ */ -+#define dpa_get_min_mtu() 64 -+#define dpa_get_max_mtu() \ -+ (dpa_get_max_frm() - (VLAN_ETH_HLEN + ETH_FCS_LEN)) -+ -+#define DPA_RX_PRIV_DATA_SIZE (DPA_TX_PRIV_DATA_SIZE + \ -+ dpa_get_rx_extra_headroom()) -+/* number of Tx queues to FMan */ -+#define DPAA_ETH_TX_QUEUES NR_CPUS -+#define DPAA_ETH_RX_QUEUES 128 -+ -+#if defined(CONFIG_DPAA_FMAN_UNIT_TESTS) -+/*TODO: temporary for fman pcd testing */ -+#define FMAN_PCD_TESTS_MAX_NUM_RANGES 20 -+#endif -+ -+/* 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); -+ -+/* -+ * 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); -+ -+/* The netdevice's needed_headroom */ -+#define DPA_BP_HEAD (DPA_TX_PRIV_DATA_SIZE + DPA_PARSE_RESULTS_SIZE + \ -+ DPA_HASH_RESULTS_SIZE) -+#define DPA_BP_SIZE(s) (DPA_BP_HEAD + dpa_get_rx_extra_headroom() + (s)) -+ -+#define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */ -+ -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+#define DEFAULT_SKB_COUNT 64 /* maximum number of SKBs in each percpu list */ -+/* -+ * We may want this value configurable. Must be <= PAGE_SIZE -+ * A lower value may help with recycling rates, at least on forwarding -+ */ -+#define DEFAULT_BUF_SIZE PAGE_SIZE -+/* -+ * Default amount data to be copied from the beginning of a frame into the -+ * linear part of the skb, in case we aren't using the hardware parser. -+ */ -+#define DPA_COPIED_HEADERS_SIZE 128 -+ -+#else -+/* -+ * Default buffer size is based on L2 MAX_FRM value, minus the FCS which is -+ * stripped down by hardware. -+ */ -+#define DEFAULT_BUF_SIZE DPA_BP_SIZE(dpa_get_max_frm() - ETH_FCS_LEN) -+#endif /* CONFIG_DPAA_ETH_SG_SUPPORT */ -+ -+/* -+ * 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 -+ -+/* -+ * 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 -+/* -+ * This includes L4 checksum errors, but also other errors that the Hard Parser -+ * can detect, such as invalid combinations of TCP control flags, or bad UDP -+ * lengths. -+ */ -+#define FM_L4_PARSE_ERROR 0x10 -+/* Check if the hardware parser has run */ -+#define FM_L4_HXS_RUN 0xE0 -+ -+/* -+ * 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_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_ERR_PHYSICAL FM_PORT_FRM_ERR_PHYSICAL -+ -+/* -+ * Check if the FMan Hardware Parser has run for L4 protocols. -+ * -+ * @parse_result_ptr must be of type (t_FmPrsResult *). -+ */ -+#define fm_l4_hxs_has_run(parse_result_ptr) \ -+ ((parse_result_ptr)->l4r & FM_L4_HXS_RUN) -+/* -+ * Iff the FMan Hardware Parser has run for L4 protocols, check error status. -+ * -+ * @parse_result_ptr must be of type (t_FmPrsResult *). -+ */ -+#define fm_l4_hxs_error(parse_result_ptr) \ -+ ((parse_result_ptr)->l4r & FM_L4_PARSE_ERROR) -+/* -+ * Check if the parsed frame was found to be a TCP segment. -+ * -+ * @parse_result_ptr must be of type (t_FmPrsResult *). -+ */ -+#define fm_l4_frame_is_tcp(parse_result_ptr) \ -+ ((parse_result_ptr)->l4r & FM_L4_PARSE_RESULT_TCP) -+ -+struct pcd_range { -+ uint32_t base; -+ uint32_t count; -+}; -+ -+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_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 *vaddr; -+ int kernel_pool; -+ /* current number of buffers in the bpool alloted to this CPU */ -+ int *percpu_count; -+ atomic_t refs; -+}; -+ -+struct dpa_rx_errors { -+ u32 dme; /* DMA Error */ -+ u32 fpe; /* Frame Physical Error */ -+ u32 fse; /* Frame Size Error */ -+ u32 phe; /* Header Error */ -+ u32 cse; /* Checksum Validation Error */ -+}; -+ -+/* Counters for QMan ERN frames - one counter per rejection code */ -+struct dpa_ern_cnt { -+ u32 cg_tdrop; /* Congestion group taildrop */ -+ u32 wred; /* WRED congestion */ -+ u32 err_cond; /* Error condition */ -+ u32 early_window; /* Order restoration, frame too early */ -+ u32 late_window; /* Order restoration, frame too late */ -+ u32 fq_tdrop; /* FQ taildrop */ -+ u32 fq_retired; /* FQ is retired */ -+ u32 orp_zero; /* ORP disabled */ -+}; -+ -+struct dpa_percpu_priv_s { -+ struct net_device *net_dev; -+ /* -+ * Pointer to the percpu_count of the shared buffer pool -+ * used for the private ports; this assumes there is only -+ * one bpool used -+ */ -+ int *dpa_bp_count; -+ struct dpa_bp *dpa_bp; -+ struct napi_struct napi; -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+ /* a list of preallocated SKBs for this CPU */ -+ struct sk_buff_head skb_list; -+ /* current number of skbs in the CPU's list */ -+ int skb_count; -+#endif -+ u32 in_interrupt; -+ u32 tx_returned; -+ u32 tx_confirm; -+ /* fragmented (non-linear) skbuffs received from the stack */ -+ u32 tx_frag_skbuffs; -+ /* -+ * Frames identified as L4 packets (by FMan's Hardware Parser, but for -+ * which the parsing failed due to some error condition. If we come -+ * across such frames, we drop them instead of passing them up the -+ * stack, which means the L4 stats in the stack won't increment. -+ */ -+ u32 l4_hxs_errors; -+ struct net_device_stats stats; -+ struct dpa_rx_errors rx_errors; -+ struct dpa_ern_cnt ern_cnt; -+}; -+ -+struct dpa_priv_s { -+ struct dpa_bp *dpa_bp; -+ size_t bp_count; -+ int shared; -+ struct net_device *net_dev; -+ -+ uint16_t channel; /* "fsl,qman-channel-id" */ -+ struct list_head dpa_fq_list; -+ struct qman_fq *egress_fqs[DPAA_ETH_TX_QUEUES]; -+ struct qman_fq *conf_fqs[DPAA_ETH_TX_QUEUES]; -+#ifdef CONFIG_DPA_TX_RECYCLE -+ struct qman_fq *recycle_fqs[DPAA_ETH_TX_QUEUES]; -+#endif -+ -+ struct mac_device *mac_dev; -+ -+ struct dpa_percpu_priv_s *percpu_priv; -+#ifdef CONFIG_DEBUG_FS -+ struct dentry *debugfs_file; -+#endif -+ -+ uint32_t msg_enable; /* net_device message level */ -+ struct dpa_ptp_tsu *tsu; -+ -+#if defined(CONFIG_DPAA_FMAN_UNIT_TESTS) -+/* 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; -+}; -+ -+extern const struct ethtool_ops dpa_ethtool_ops; -+ -+void __attribute__((nonnull)) -+dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd); -+ -+void dpa_make_private_pool(struct dpa_bp *dpa_bp); -+ -+struct dpa_bp *dpa_bpid2pool(int bpid); -+ -+void __hot _dpa_rx(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); -+ -+int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev); -+ -+struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv, -+ const struct qm_fd *fd); -+ -+int __hot _dpa_process_parse_results(const t_FmPrsResult *parse_results, -+ const struct qm_fd *fd, -+ struct sk_buff *skb, -+ int *use_gro, -+ unsigned int *hdr_size __maybe_unused); -+ -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+void dpa_bp_add_8_pages(const struct dpa_bp *dpa_bp, int cpu_id); -+int _dpa_bp_add_8_pages(const struct dpa_bp *dpa_bp); -+ -+void dpa_list_add_skbs(struct dpa_percpu_priv_s *cpu_priv, int count); -+#endif -+ -+/* -+ * 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) -+{ -+ /* -+ * 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_irqsource_remove(QM_PIRQ_DQRI); -+ if (likely(!ret)) { -+ napi_schedule(&percpu_priv->napi); -+ 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 != ETH_P_8021Q) || (skb->len > mtu + 4)) -+ return -1; -+ -+ return 0; -+} -+ -+void fm_mac_dump_regs(struct mac_device *mac_dev); -+ -+void dpaa_eth_sysfs_remove(struct device *dev); -+void dpaa_eth_sysfs_init(struct device *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 __hot dpa_xmit(struct dpa_priv_s *priv, -+ struct net_device_stats *percpu_stats, int queue, -+ struct qm_fd *fd) -+{ -+ int err, i; -+ struct qman_fq *egress_fq; -+ -+#ifdef CONFIG_DPA_TX_RECYCLE -+ /* Choose egress fq based on whether we want -+ * to recycle the frame or not */ -+ if (fd->cmd & FM_FD_CMD_FCO) -+ egress_fq = priv->recycle_fqs[queue]; -+ else -+ egress_fq = priv->egress_fqs[queue]; -+#else -+ egress_fq = priv->egress_fqs[queue]; -+#endif -+ -+ 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; -+} -+ -+#if defined CONFIG_DPA_ETH_WQ_LEGACY -+#define DPA_NUM_WQS 8 -+/* -+ * Older WQ assignment: statically-defined FQIDs (such as PCDs) are assigned -+ * round-robin to all WQs available. Dynamically-allocated FQIDs go to WQ7. -+ * -+ * Not necessarily the best scheme, but worked fine so far, so we might want -+ * to keep it around for a while. -+ */ -+static inline void _dpa_assign_wq(struct dpa_fq *fq) -+{ -+ fq->wq = fq->fqid ? fq->fqid % DPA_NUM_WQS : DPA_NUM_WQS - 1; -+} -+#elif defined CONFIG_DPA_ETH_WQ_MULTI -+/* -+ * 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: -+ fq->wq = 1; -+ break; -+ case FQ_TYPE_RX_DEFAULT: -+ case FQ_TYPE_TX: -+#ifdef CONFIG_DPA_TX_RECYCLE -+ case FQ_TYPE_TX_RECYCLE: -+#endif -+ case FQ_TYPE_RX_PCD: -+ fq->wq = 3; -+ break; -+ case FQ_TYPE_RX_ERROR: -+ case FQ_TYPE_TX_ERROR: -+ fq->wq = 2; -+ break; -+ default: -+ WARN(1, "Invalid FQ type %d for FQID %d!\n", -+ fq->fq_type, fq->fqid); -+ } -+} -+#else -+/* This shouldn't happen, since we've made a "default" choice in the Kconfig. */ -+#error "No WQ assignment scheme chosen; Kconfig out-of-sync?" -+#endif /* CONFIG_DPA_ETH_WQ_ASSIGN_* */ -+ -+ -+#ifdef CONFIG_DPAA_ETH_USE_NDO_SELECT_QUEUE -+/* Use in lieu of skb_get_queue_mapping() */ -+#define dpa_get_queue_mapping(skb) \ -+ smp_processor_id() -+#else -+/* Use the queue selected by XPS */ -+#define dpa_get_queue_mapping(skb) \ -+ skb_get_queue_mapping(skb) -+#endif -+ -+#endif /* __DPA_H */ -diff --git a/drivers/net/dpa/dpaa_eth_sg.c b/drivers/net/dpa/dpaa_eth_sg.c -new file mode 100644 -index 0000000..fb9cab6 ---- /dev/null -+++ b/drivers/net/dpa/dpaa_eth_sg.c -@@ -0,0 +1,793 @@ -+/* -+ * 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. -+ */ -+ -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+ -+#include -+#include -+#include -+#include -+ -+#include "dpaa_eth.h" -+#include "dpaa_1588.h" -+ -+#ifdef CONFIG_DPAA_ETH_SG_SUPPORT -+#define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */ -+ -+/* -+ * It does not return a page as you get the page from the fd, -+ * this is only for refcounting and DMA unmapping -+ */ -+static inline void dpa_bp_removed_one_page(struct dpa_bp *dpa_bp, -+ dma_addr_t dma_addr) -+{ -+ int *count_ptr; -+ -+ count_ptr = __this_cpu_ptr(dpa_bp->percpu_count); -+ (*count_ptr)--; -+ -+ dma_unmap_single(dpa_bp->dev, dma_addr, dpa_bp->size, -+ DMA_BIDIRECTIONAL); -+} -+ -+/* DMA map and add a page into the bpool */ -+static void dpa_bp_add_page(struct dpa_bp *dpa_bp, unsigned long vaddr) -+{ -+ struct bm_buffer bmb; -+ int *count_ptr; -+ dma_addr_t addr; -+ int offset; -+ -+ count_ptr = __this_cpu_ptr(dpa_bp->percpu_count); -+ -+ /* Make sure we don't map beyond end of page */ -+ offset = vaddr & (PAGE_SIZE - 1); -+ if (unlikely(dpa_bp->size + offset > PAGE_SIZE)) { -+ free_page(vaddr); -+ return; -+ } -+ 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)++; -+} -+ -+int _dpa_bp_add_8_pages(const struct dpa_bp *dpa_bp) -+{ -+ struct bm_buffer bmb[8]; -+ unsigned long new_page; -+ dma_addr_t addr; -+ int i; -+ struct device *dev = dpa_bp->dev; -+ -+ for (i = 0; i < 8; i++) { -+ new_page = __get_free_page(GFP_ATOMIC); -+ if (likely(new_page)) { -+ addr = dma_map_single(dev, (void *)new_page, -+ dpa_bp->size, DMA_BIDIRECTIONAL); -+ if (likely(!dma_mapping_error(dev, addr))) { -+ bm_buffer_set64(&bmb[i], addr); -+ continue; -+ } else -+ free_page(new_page); -+ } -+ -+ /* Something went wrong */ -+ goto bail_out; -+ } -+ -+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; -+ -+bail_out: -+ dev_err(dpa_bp->dev, "dpa_bp_add_8_pages() failed\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_pages(). -+ */ -+void dpa_bp_add_8_pages(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_pages(dpa_bp); -+} -+ -+void dpa_list_add_skb(struct dpa_percpu_priv_s *cpu_priv, -+ struct sk_buff *new_skb) -+{ -+ struct sk_buff_head *list_ptr; -+ -+ if (cpu_priv->skb_count > DEFAULT_SKB_COUNT) { -+ dev_kfree_skb(new_skb); -+ return; -+ } -+ -+ list_ptr = &cpu_priv->skb_list; -+ skb_queue_head(list_ptr, new_skb); -+ -+ cpu_priv->skb_count += 1; -+} -+ -+static struct sk_buff *dpa_list_get_skb(struct dpa_percpu_priv_s *cpu_priv) -+{ -+ struct sk_buff_head *list_ptr; -+ struct sk_buff *new_skb; -+ -+ list_ptr = &cpu_priv->skb_list; -+ -+ new_skb = skb_dequeue(list_ptr); -+ if (new_skb) -+ cpu_priv->skb_count -= 1; -+ -+ return new_skb; -+} -+ -+void dpa_list_add_skbs(struct dpa_percpu_priv_s *cpu_priv, int count) -+{ -+ struct sk_buff *new_skb; -+ int i; -+ -+ for (i = 0; i < count; i++) { -+ new_skb = dev_alloc_skb(DPA_BP_HEAD + -+ dpa_get_rx_extra_headroom() + -+ DPA_COPIED_HEADERS_SIZE); -+ if (unlikely(!new_skb)) { -+ pr_err("dev_alloc_skb() failed\n"); -+ break; -+ } -+ -+ dpa_list_add_skb(cpu_priv, new_skb); -+ } -+} -+ -+void dpa_make_private_pool(struct dpa_bp *dpa_bp) -+{ -+ int i; -+ -+ dpa_bp->percpu_count = __alloc_percpu(sizeof(*dpa_bp->percpu_count), -+ __alignof__(*dpa_bp->percpu_count)); -+ -+ /* Give each CPU an allotment of "page_count" buffers */ -+ for_each_online_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_pages(dpa_bp, i); -+ } -+} -+ -+/* -+ * 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); -+ struct sk_buff **skbh; -+ struct sk_buff *skb = NULL; -+ const enum dma_data_direction dma_dir = DMA_TO_DEVICE; -+ -+ dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, dma_dir); -+ -+ /* retrieve skb back pointer */ -+ skbh = (struct sk_buff **)phys_to_virt(addr); -+ skb = *skbh; -+ -+ if (fd->format == qm_fd_sg) { -+ /* -+ * The sgt page is guaranteed to reside in lowmem. -+ */ -+ sgt = phys_to_virt(addr + dpa_fd_offset(fd)); -+ -+ /* sgt[0] is from lowmem, was dma_map_single()-ed */ -+ dma_unmap_single(dpa_bp->dev, sgt[0].addr, -+ sgt[0].length, dma_dir); -+ -+ /* remaining pages were mapped with dma_map_page() */ -+ for (i = 1; i < skb_shinfo(skb)->nr_frags; i++) { -+ BUG_ON(sgt[i].extension); -+ -+ dma_unmap_page(dpa_bp->dev, sgt[i].addr, -+ dpa_bp->size, dma_dir); -+ } -+ -+ /* -+ * TODO: dpa_bp_add_page() ? -+ * We could put these in the pool, since we allocated them -+ * and we know they're not used by anyone else -+ */ -+ -+ /* Free separately the pages that we allocated on Tx */ -+ free_page((unsigned long)phys_to_virt(addr)); -+} -+ -+ return skb; -+} -+ -+/* -+ * Move the first DPA_COPIED_HEADERS_SIZE bytes to the skb linear buffer to -+ * provide the networking stack the headers it requires in the linear buffer. -+ * -+ * If the entire frame fits in the skb linear buffer, the page holding the -+ * received data is recycled as it is no longer required. -+ * -+ * Return 0 if the ingress skb was properly constructed, non-zero if an error -+ * was encountered and the frame should be dropped. -+ */ -+static int __hot contig_fd_to_skb(const struct dpa_priv_s *priv, -+ const struct qm_fd *fd, struct sk_buff *skb, int *use_gro) -+{ -+ unsigned int copy_size = DPA_COPIED_HEADERS_SIZE; -+ dma_addr_t addr = qm_fd_addr(fd); -+ void *vaddr; -+ struct page *page; -+ int frag_offset, page_offset; -+ struct dpa_bp *dpa_bp = priv->dpa_bp; -+ unsigned char *tailptr; -+ const t_FmPrsResult *parse_results; -+ int ret; -+ -+ vaddr = phys_to_virt(addr); -+ -+#ifdef CONFIG_FSL_DPA_1588 -+ if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_rx_en_ioctl) -+ dpa_ptp_store_rxstamp(priv->net_dev, skb, fd); -+#endif -+ -+ /* Peek at the parse results for frame validation. */ -+ parse_results = (const t_FmPrsResult *)(vaddr + DPA_RX_PRIV_DATA_SIZE); -+ ret = _dpa_process_parse_results(parse_results, fd, skb, use_gro, -+ ©_size); -+ if (unlikely(ret)) -+ /* This is definitely a bad frame, don't go further. */ -+ return ret; -+ -+ tailptr = skb_put(skb, copy_size); -+ -+ /* Copy (at least) the headers in the linear portion */ -+ memcpy(tailptr, vaddr + dpa_fd_offset(fd), copy_size); -+ -+ /* -+ * If frame is longer than the amount we copy in the linear -+ * buffer, add the page as fragment, -+ * otherwise recycle the page -+ */ -+ page = pfn_to_page(addr >> PAGE_SHIFT); -+ -+ if (copy_size < dpa_fd_length(fd)) { -+ /* add the page as a fragment in the skb */ -+ page_offset = (unsigned long)vaddr & (PAGE_SIZE - 1); -+ frag_offset = page_offset + dpa_fd_offset(fd) + copy_size; -+ skb_add_rx_frag(skb, 0, page, frag_offset, -+ dpa_fd_length(fd) - copy_size); -+ } else { -+ /* recycle the page */ -+ dpa_bp_add_page(dpa_bp, (unsigned long)vaddr); -+ } -+ -+ return 0; -+} -+ -+ -+/* -+ * Move the first bytes of the frame to the skb linear buffer to -+ * provide the networking stack the headers it requires in the linear buffer, -+ * and add the rest of the frame as skb fragments. -+ * -+ * The page holding the S/G Table is recycled here. -+ */ -+static int __hot sg_fd_to_skb(const struct dpa_priv_s *priv, -+ const struct qm_fd *fd, struct sk_buff *skb, -+ int *use_gro) -+{ -+ const struct qm_sg_entry *sgt; -+ dma_addr_t addr = qm_fd_addr(fd); -+ dma_addr_t sg_addr; -+ void *vaddr, *sg_vaddr; -+ struct dpa_bp *dpa_bp; -+ struct page *page; -+ int frag_offset, frag_len; -+ int page_offset; -+ int i, ret; -+ unsigned int copy_size = DPA_COPIED_HEADERS_SIZE; -+ const t_FmPrsResult *parse_results; -+ -+ vaddr = phys_to_virt(addr); -+ /* -+ * In the case of a SG frame, FMan stores the Internal Context -+ * in the buffer containing the sgt. -+ */ -+ parse_results = (const t_FmPrsResult *)(vaddr + DPA_RX_PRIV_DATA_SIZE); -+ /* Validate the frame before anything else. */ -+ ret = _dpa_process_parse_results(parse_results, fd, skb, use_gro, -+ ©_size); -+ if (unlikely(ret)) -+ /* Bad frame, stop processing now. */ -+ return ret; -+ -+ /* -+ * Iterate through the SGT entries and add the data buffers as -+ * skb fragments -+ */ -+ sgt = vaddr + dpa_fd_offset(fd); -+ for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) { -+ /* Extension bit is not supported */ -+ BUG_ON(sgt[i].extension); -+ -+ dpa_bp = dpa_bpid2pool(sgt[i].bpid); -+ BUG_ON(IS_ERR(dpa_bp)); -+ -+ sg_addr = qm_sg_addr(&sgt[i]); -+ sg_vaddr = phys_to_virt(sg_addr); -+ -+ dpa_bp_removed_one_page(dpa_bp, sg_addr); -+ page = pfn_to_page(sg_addr >> PAGE_SHIFT); -+ -+ /* -+ * Padding at the beginning of the page -+ * (offset in page from where BMan buffer begins) -+ */ -+ page_offset = (unsigned long)sg_vaddr & (PAGE_SIZE - 1); -+ -+ if (i == 0) { -+ /* This is the first fragment */ -+ /* Move the network headers in the skb linear portion */ -+ memcpy(skb_put(skb, copy_size), -+ sg_vaddr + sgt[i].offset, -+ copy_size); -+ -+ /* Adjust offset/length for the remaining data */ -+ frag_offset = sgt[i].offset + page_offset + copy_size; -+ frag_len = sgt[i].length - copy_size; -+ } else { -+ /* -+ * Not the first fragment; all data from buferr will -+ * be added in an skb fragment -+ */ -+ frag_offset = sgt[i].offset + page_offset; -+ frag_len = sgt[i].length; -+ } -+ /* Add data buffer to the skb */ -+ skb_add_rx_frag(skb, i, page, frag_offset, frag_len); -+ -+ if (sgt[i].final) -+ break; -+ } -+ -+#ifdef CONFIG_FSL_DPA_1588 -+ if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_rx_en_ioctl) -+ dpa_ptp_store_rxstamp(priv->net_dev, skb, fd); -+#endif -+ -+ /* recycle the SGT page */ -+ dpa_bp = dpa_bpid2pool(fd->bpid); -+ BUG_ON(IS_ERR(dpa_bp)); -+ dpa_bp_add_page(dpa_bp, (unsigned long)vaddr); -+ -+ return 0; -+} -+ -+void __hot _dpa_rx(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 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 net_device_stats *percpu_stats = &percpu_priv->stats; -+ int use_gro = net_dev->features & NETIF_F_GRO; -+ -+ if (unlikely(fd_status & FM_FD_STAT_ERRORS) != 0) { -+ if (netif_msg_hw(priv) && net_ratelimit()) -+ netdev_warn(net_dev, "FD status = 0x%08x\n", -+ fd_status & FM_FD_STAT_ERRORS); -+ -+ percpu_stats->rx_errors++; -+ goto _release_frame; -+ } -+ -+ dpa_bp = dpa_bpid2pool(fd->bpid); -+ skb = dpa_list_get_skb(percpu_priv); -+ -+ if (unlikely(skb == NULL)) { -+ /* List is empty, so allocate a new skb */ -+ skb = dev_alloc_skb(DPA_BP_HEAD + dpa_get_rx_extra_headroom() + -+ DPA_COPIED_HEADERS_SIZE); -+ if (unlikely(skb == NULL)) { -+ if (netif_msg_rx_err(priv) && net_ratelimit()) -+ netdev_err(net_dev, -+ "Could not alloc skb\n"); -+ percpu_stats->rx_dropped++; -+ goto _release_frame; -+ } -+ } -+ -+ /* TODO We might want to do some prefetches here (skb, shinfo, data) */ -+ -+ /* -+ * Make sure forwarded skbs will have enough space on Tx, -+ * if extra headers are added. -+ */ -+ skb_reserve(skb, DPA_BP_HEAD + dpa_get_rx_extra_headroom()); -+ -+ dpa_bp_removed_one_page(dpa_bp, addr); -+ -+ /* prefetch the first 64 bytes of the frame or the SGT start */ -+ prefetch(phys_to_virt(addr) + dpa_fd_offset(fd)); -+ -+ if (likely(fd->format == qm_fd_contig)) { -+ if (unlikely(contig_fd_to_skb(priv, fd, skb, &use_gro))) { -+ /* -+ * There was a L4 HXS error - e.g. the L4 csum was -+ * invalid - so drop the frame early instead of passing -+ * it on to the stack. We'll increment our private -+ * counters to track this event. -+ */ -+ percpu_priv->l4_hxs_errors++; -+ percpu_stats->rx_dropped++; -+ goto drop_bad_frame; -+ } -+ } else if (fd->format == qm_fd_sg) { -+ if (unlikely(sg_fd_to_skb(priv, fd, skb, &use_gro))) { -+ percpu_priv->l4_hxs_errors++; -+ percpu_stats->rx_dropped++; -+ goto drop_bad_frame; -+ } -+ } else -+ /* The only FD types that we may receive are contig and S/G */ -+ BUG(); -+ -+ 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; -+ -+ if (use_gro) { -+ gro_result_t gro_result; -+ -+ gro_result = napi_gro_receive(&percpu_priv->napi, skb); -+ if (unlikely(gro_result == GRO_DROP)) { -+ percpu_stats->rx_dropped++; -+ goto packet_dropped; -+ } -+ } else if (unlikely(netif_receive_skb(skb) == NET_RX_DROP)) { -+ percpu_stats->rx_dropped++; -+ 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); -+} -+ -+static int __hot skb_to_contig_fd(struct dpa_priv_s *priv, -+ struct sk_buff *skb, struct qm_fd *fd) -+{ -+ struct sk_buff **skbh; -+ dma_addr_t addr; -+ struct dpa_bp *dpa_bp; -+ struct net_device *net_dev = priv->net_dev; -+ int err; -+ -+ /* We are guaranteed that we have at least DPA_BP_HEAD of headroom. */ -+ skbh = (struct sk_buff **)(skb->data - DPA_BP_HEAD); -+ -+ *skbh = skb; -+ -+ dpa_bp = priv->dpa_bp; -+ -+ /* -+ * 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 FD */ -+ fd->format = qm_fd_contig; -+ fd->length20 = skb->len; -+ fd->offset = DPA_BP_HEAD; /* This is now guaranteed */ -+ -+ addr = dma_map_single(dpa_bp->dev, skbh, dpa_bp->size, DMA_TO_DEVICE); -+ 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; -+ } -+ fd->addr_hi = upper_32_bits(addr); -+ fd->addr_lo = lower_32_bits(addr); -+ -+ return 0; -+} -+ -+static 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; -+ struct sk_buff **skbh; -+ struct net_device *net_dev = priv->net_dev; -+ int err; -+ -+ struct qm_sg_entry *sgt; -+ unsigned long sgt_page; -+ void *buffer_start; -+ skb_frag_t *frag; -+ int i, j; -+ const enum dma_data_direction dma_dir = DMA_TO_DEVICE; -+ -+ fd->format = qm_fd_sg; -+ -+ /* get a new page to store the SGTable */ -+ sgt_page = __get_free_page(GFP_ATOMIC); -+ if (unlikely(!sgt_page)) { -+ dev_err(dpa_bp->dev, "__get_free_page() failed\n"); -+ return -ENOMEM; -+ } -+ -+ /* -+ * 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, -+ (void *)sgt_page + 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; -+ } -+ -+ sgt = (struct qm_sg_entry *)(sgt_page + DPA_BP_HEAD); -+ sgt[0].bpid = dpa_bp->bpid; -+ sgt[0].offset = 0; -+ sgt[0].length = skb_headlen(skb); -+ sgt[0].extension = 0; -+ sgt[0].final = 0; -+ addr = dma_map_single(dpa_bp->dev, skb->data, sgt[0].length, 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; -+ -+ } -+ sgt[0].addr_hi = upper_32_bits(addr); -+ sgt[0].addr_lo = lower_32_bits(addr); -+ -+ /* populate the rest of SGT entries */ -+ for (i = 1; i <= skb_shinfo(skb)->nr_frags; i++) { -+ frag = &skb_shinfo(skb)->frags[i - 1]; -+ sgt[i].bpid = dpa_bp->bpid; -+ sgt[i].offset = 0; -+ sgt[i].length = frag->size; -+ sgt[i].extension = 0; -+ sgt[i].final = 0; -+ -+ /* This shouldn't happen */ -+ BUG_ON(!frag->page.p); -+ -+ addr = dma_map_page(dpa_bp->dev, frag->page.p, frag->page_offset, -+ dpa_bp->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 */ -+ sgt[i].addr_hi = upper_32_bits(addr); -+ sgt[i].addr_lo = lower_32_bits(addr); -+ } -+ sgt[i - 1].final = 1; -+ -+ fd->length20 = skb->len; -+ fd->offset = DPA_BP_HEAD; -+ -+ /* DMA map the SGT page */ -+ buffer_start = (void *)sgt - dpa_fd_offset(fd); -+ skbh = (struct sk_buff **)buffer_start; -+ *skbh = skb; -+ -+ addr = dma_map_single(dpa_bp->dev, buffer_start, dpa_bp->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; -+ } -+ fd->addr_hi = upper_32_bits(addr); -+ fd->addr_lo = lower_32_bits(addr); -+ -+ return 0; -+ -+sgt_map_failed: -+sg_map_failed: -+ for (j = 0; j < i; j++) -+ dma_unmap_page(dpa_bp->dev, qm_sg_addr(&sgt[j]), -+ dpa_bp->size, dma_dir); -+sg0_map_failed: -+csum_failed: -+ free_page(sgt_page); -+ -+ return err; -+} -+ -+int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev) -+{ -+ struct dpa_priv_s *priv; -+ struct qm_fd fd; -+ struct dpa_percpu_priv_s *percpu_priv; -+ struct net_device_stats *percpu_stats; -+ int queue_mapping; -+ int err; -+ -+ priv = netdev_priv(net_dev); -+ /* Non-migratable context, safe to use __this_cpu_ptr */ -+ percpu_priv = __this_cpu_ptr(priv->percpu_priv); -+ percpu_stats = &percpu_priv->stats; -+ -+ clear_fd(&fd); -+ -+ queue_mapping = dpa_get_queue_mapping(skb); -+ -+ -+#ifdef CONFIG_FSL_DPA_1588 -+ if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl) -+ fd.cmd |= FM_FD_CMD_UPD; -+#endif -+ -+ if (skb_is_nonlinear(skb)) { -+ /* 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 accomodate private -+ * data, parse results, etc. Normally this shouldn't happen if -+ * we're here via the standard kernel stack. -+ */ -+ if (unlikely(skb_headroom(skb) < DPA_BP_HEAD)) { -+ struct sk_buff *skb_new; -+ -+ skb_new = skb_realloc_headroom(skb, DPA_BP_HEAD); -+ 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 -+ */ -+ skb = skb_unshare(skb, GFP_ATOMIC); -+ if (unlikely(!skb)) { -+ percpu_stats->tx_errors++; -+ return NETDEV_TX_OK; -+ } -+ -+ /* Finally, create a contig FD from this skb */ -+ err = skb_to_contig_fd(priv, skb, &fd); -+ } -+ if (unlikely(err < 0)) { -+ percpu_stats->tx_errors++; -+ dev_kfree_skb(skb); -+ return NETDEV_TX_OK; -+ } -+ -+ if (unlikely(dpa_xmit(priv, percpu_stats, queue_mapping, &fd) < 0)) -+ goto xmit_failed; -+ -+ net_dev->trans_start = jiffies; -+ -+ return NETDEV_TX_OK; -+ -+xmit_failed: -+ _dpa_cleanup_tx_fd(priv, &fd); -+ dev_kfree_skb(skb); -+ -+ return NETDEV_TX_OK; -+} -+ -+#endif /* CONFIG_DPAA_ETH_SG_SUPPORT */ -diff --git a/drivers/net/dpa/dpaa_eth_sysfs.c b/drivers/net/dpa/dpaa_eth_sysfs.c -new file mode 100644 -index 0000000..53c0c8f ---- /dev/null -+++ b/drivers/net/dpa/dpaa_eth_sysfs.c -@@ -0,0 +1,189 @@ -+ -+/* -+ * 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" -+ -+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_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 confirmation"; -+ break; -+ case FQ_TYPE_TX_ERROR: -+ str = "Tx error"; -+ break; -+ case FQ_TYPE_TX: -+ str = "Tx"; -+ break; -+#ifdef CONFIG_DPA_TX_RECYCLE -+ case FQ_TYPE_TX_RECYCLE: -+ str = "Tx(recycling)"; -+ break; -+#endif -+ 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_dflt_bpid(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; -+ -+ if (priv->bp_count != 1) -+ bytes += snprintf(buf, PAGE_SIZE, "-1\n"); -+ else -+ bytes += snprintf(buf, PAGE_SIZE, "%u\n", dpa_bp->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; -+ -+ if (mac_dev) -+ fm_mac_dump_regs(mac_dev); -+ else -+ return sprintf(buf, "no mac registers\n"); -+ -+ return 0; -+} -+ -+static struct device_attribute dpaa_eth_attrs[] = { -+ __ATTR(device_addr, S_IRUGO, dpaa_eth_show_addr, NULL), -+ __ATTR(fqids, S_IRUGO, dpaa_eth_show_fqids, NULL), -+ __ATTR(dflt_bpid, S_IRUGO, dpaa_eth_show_dflt_bpid, NULL), -+ __ATTR(mac_regs, S_IRUGO, dpaa_eth_show_mac_regs, NULL) -+}; -+ -+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"); -+ goto device_create_file_failed; -+ } -+ -+ return; -+ -+device_create_file_failed: -+ while (i > 0) -+ device_remove_file(dev, &dpaa_eth_attrs[--i]); -+} -+ -+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]); -+} -diff --git a/drivers/net/dpa/mac-api.c b/drivers/net/dpa/mac-api.c -new file mode 100644 -index 0000000..7b2b3a9 ---- /dev/null -+++ b/drivers/net/dpa/mac-api.c -@@ -0,0 +1,837 @@ -+/* 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. -+ */ -+ -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dpaa_eth-common.h" -+#include "dpaa_eth.h" -+#include "mac.h" -+ -+#include "error_ext.h" /* GET_ERROR_TYPE, E_OK */ -+#include "fm_mac_ext.h" -+#include "fm_rtc_ext.h" -+ -+#include "../ethernet/freescale/fsl_pq_mdio.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 { -+ t_Handle mac; -+}; -+ -+const char *mac_driver_description __initconst = MAC_DESCRIPTION; -+const size_t mac_sizeof_priv[] __devinitconst = { -+ [DTSEC] = sizeof(struct mac_priv_s), -+ [XGMAC] = sizeof(struct mac_priv_s), -+ [MEMAC] = sizeof(struct mac_priv_s) -+}; -+ -+static const e_EnetMode _100[] __devinitconst = -+{ -+ [PHY_INTERFACE_MODE_MII] = e_ENET_MODE_MII_100, -+ [PHY_INTERFACE_MODE_RMII] = e_ENET_MODE_RMII_100 -+}; -+ -+static const e_EnetMode _1000[] __devinitconst = -+{ -+ [PHY_INTERFACE_MODE_GMII] = e_ENET_MODE_GMII_1000, -+ [PHY_INTERFACE_MODE_SGMII] = e_ENET_MODE_SGMII_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 e_EnetMode __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_10000: -+ return e_ENET_MODE_XGMII_10000; -+ default: -+ return e_ENET_MODE_MII_100; -+ } -+} -+ -+static void mac_exception(t_Handle _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_SetException( -+ ((struct mac_priv_s *)macdev_priv(_mac_dev))->mac, -+ e_FM_MAC_EX_10G_RX_FIFO_OVFL, false); -+ printk(KERN_ERR "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 __devinit __cold init(struct mac_device *mac_dev) -+{ -+ int _errno; -+ t_Error err; -+ 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 = (t_Handle)mac_dev->fm; -+ param.mdioIrq = NO_IRQ; -+ param.f_Exception = mac_exception; -+ param.f_Event = mac_exception; -+ param.h_App = mac_dev; -+ -+ priv->mac = FM_MAC_Config(¶m); -+ if (unlikely(priv->mac == NULL)) { -+ dev_err(mac_dev->dev, "FM_MAC_Config() failed\n"); -+ _errno = -EINVAL; -+ goto _return; -+ } -+ -+ fm_mac_set_handle(mac_dev->fm_dev, priv->mac, -+ (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ? -+ param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS); -+ -+ err = FM_MAC_ConfigMaxFrameLength(priv->mac, -+ fm_get_max_frm()); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) { -+ dev_err(mac_dev->dev, -+ "FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err); -+ goto _return_fm_mac_free; -+ } -+ -+ if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) { -+ /* 10G always works with pad and CRC */ -+ err = FM_MAC_ConfigPadAndCrc(priv->mac, true); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) { -+ dev_err(mac_dev->dev, -+ "FM_MAC_ConfigPadAndCrc() = 0x%08x\n", err); -+ goto _return_fm_mac_free; -+ } -+ -+ err = FM_MAC_ConfigHalfDuplex(priv->mac, mac_dev->half_duplex); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) { -+ dev_err(mac_dev->dev, -+ "FM_MAC_ConfigHalfDuplex() = 0x%08x\n", err); -+ goto _return_fm_mac_free; -+ } -+ } -+ else { -+ err = FM_MAC_ConfigResetOnInit(priv->mac, true); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) { -+ dev_err(mac_dev->dev, -+ "FM_MAC_ConfigResetOnInit() = 0x%08x\n", err); -+ goto _return_fm_mac_free; -+ } -+ } -+ -+ err = FM_MAC_Init(priv->mac); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) { -+ dev_err(mac_dev->dev, "FM_MAC_Init() = 0x%08x\n", err); -+ 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) { -+ err = FM_MAC_SetException(priv->mac, -+ e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL, FALSE); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) { -+ dev_err(mac_dev->dev, -+ "FM_MAC_SetException() = 0x%08x\n", err); -+ 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) { -+ err = FM_MAC_SetException(priv->mac, -+ e_FM_MAC_EX_10G_1TX_ECC_ER, FALSE); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) { -+ dev_err(mac_dev->dev, -+ "FM_MAC_SetException() = 0x%08x\n", err); -+ goto _return_fm_mac_free; -+ } -+ } -+ -+ err = FM_MAC_GetVesrion(priv->mac, &version); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) { -+ dev_err(mac_dev->dev, "FM_MAC_GetVesrion() = 0x%08x\n", -+ err); -+ 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: -+ err = FM_MAC_Free(priv->mac); -+ if (unlikely(-GET_ERROR_TYPE(err) < 0)) -+ dev_err(mac_dev->dev, "FM_MAC_Free() = 0x%08x\n", err); -+_return: -+ return _errno; -+} -+ -+static int __devinit __cold memac_init(struct mac_device *mac_dev) -+{ -+ int _errno; -+ t_Error err; -+ 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 = (t_Handle)mac_dev->fm; -+ param.mdioIrq = NO_IRQ; -+ param.f_Exception = mac_exception; -+ param.f_Event = mac_exception; -+ param.h_App = mac_dev; -+ -+ priv->mac = FM_MAC_Config(¶m); -+ if (unlikely(priv->mac == NULL)) { -+ dev_err(mac_dev->dev, "FM_MAC_Config() failed\n"); -+ _errno = -EINVAL; -+ goto _return; -+ } -+ -+ err = FM_MAC_ConfigMaxFrameLength(priv->mac, fm_get_max_frm()); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) { -+ dev_err(mac_dev->dev, -+ "FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err); -+ goto _return_fm_mac_free; -+ } -+ -+ err = FM_MAC_ConfigResetOnInit(priv->mac, true); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) { -+ dev_err(mac_dev->dev, -+ "FM_MAC_ConfigResetOnInit() = 0x%08x\n", err); -+ goto _return_fm_mac_free; -+ } -+ -+ err = FM_MAC_Init(priv->mac); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) { -+ dev_err(mac_dev->dev, "FM_MAC_Init() = 0x%08x\n", err); -+ goto _return_fm_mac_free; -+ } -+ -+ dev_info(mac_dev->dev, "FMan MEMAC\n"); -+ -+ goto _return; -+ -+_return_fm_mac_free: -+ err = FM_MAC_Free(priv->mac); -+ if (unlikely(-GET_ERROR_TYPE(err) < 0)) -+ dev_err(mac_dev->dev, "FM_MAC_Free() = 0x%08x\n", err); -+_return: -+ return _errno; -+} -+ -+static int __cold start(struct mac_device *mac_dev) -+{ -+ int _errno; -+ t_Error err; -+ struct phy_device *phy_dev = mac_dev->phy_dev; -+ -+ err = FM_MAC_Enable(((struct mac_priv_s *)macdev_priv(mac_dev))->mac, -+ e_COMM_MODE_RX_AND_TX); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_MAC_Enable() = 0x%08x\n", err); -+ -+ if (phy_dev) { -+ if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) -+ phy_start(phy_dev); -+ else if (phy_dev->drv->read_status) -+ phy_dev->drv->read_status(phy_dev); -+ } -+ -+ return _errno; -+} -+ -+static int __cold stop(struct mac_device *mac_dev) -+{ -+ int _errno; -+ t_Error err; -+ -+ if (mac_dev->phy_dev && -+ (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000)) -+ phy_stop(mac_dev->phy_dev); -+ -+ err = FM_MAC_Disable(((struct mac_priv_s *)macdev_priv(mac_dev))->mac, -+ e_COMM_MODE_RX_AND_TX); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_MAC_Disable() = 0x%08x\n", err); -+ -+ return _errno; -+} -+ -+static int __cold change_promisc(struct mac_device *mac_dev) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_MAC_SetPromiscuous( -+ ((struct mac_priv_s *)macdev_priv(mac_dev))->mac, -+ mac_dev->promisc = !mac_dev->promisc); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, -+ "FM_MAC_SetPromiscuous() = 0x%08x\n", err); -+ -+ return _errno; -+} -+ -+static int __cold set_multi(struct net_device *net_dev) -+{ -+ struct dpa_priv_s *priv; -+ struct mac_device *mac_dev; -+ struct mac_priv_s *mac_priv; -+ struct mac_address *old_addr, *tmp; -+ struct netdev_hw_addr *ha; -+ int _errno; -+ t_Error err; -+ -+ priv = netdev_priv(net_dev); -+ mac_dev = priv->mac_dev; -+ mac_priv = macdev_priv(mac_dev); -+ -+ /* Clear previous address list */ -+ list_for_each_entry_safe(old_addr, tmp, &mac_dev->mc_addr_list, list) { -+ err = FM_MAC_RemoveHashMacAddr(mac_priv->mac, -+ (t_EnetAddr *)old_addr->addr); -+ _errno = -GET_ERROR_TYPE(err); -+ if (_errno < 0) { -+ dev_err(mac_dev->dev, -+ "FM_MAC_RemoveHashMacAddr() = 0x%08x\n", err); -+ 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) { -+ err = FM_MAC_AddHashMacAddr(mac_priv->mac, -+ (t_EnetAddr *)ha->addr); -+ _errno = -GET_ERROR_TYPE(err); -+ if (_errno < 0) { -+ dev_err(mac_dev->dev, -+ "FM_MAC_AddHashMacAddr() = 0x%08x\n", err); -+ 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; -+} -+ -+static int __cold change_addr(struct mac_device *mac_dev, uint8_t *addr) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_MAC_ModifyMacAddr( -+ ((struct mac_priv_s *)macdev_priv(mac_dev))->mac, -+ (t_EnetAddr *)addr); -+ _errno = -GET_ERROR_TYPE(err); -+ if (_errno < 0) -+ dev_err(mac_dev->dev, -+ "FM_MAC_ModifyMacAddr() = 0x%08x\n", err); -+ -+ return _errno; -+} -+ -+static void adjust_link(struct net_device *net_dev) -+{ -+#if (DPAA_VERSION < 11) -+ 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 mac_priv_s *mac_priv; -+ int _errno; -+ t_Error err; -+ -+ if (!phy_dev->link) { -+ fsl_pq_mdio_lock(NULL); -+ -+ mac_priv = (struct mac_priv_s *)macdev_priv(mac_dev); -+ DtsecRestartTbiAN(mac_priv->mac); -+ -+ fsl_pq_mdio_unlock(NULL); -+ return; -+ } -+ -+ err = FM_MAC_AdjustLink( -+ ((struct mac_priv_s *)macdev_priv(mac_dev))->mac, -+ phy_dev->speed, phy_dev->duplex); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_MAC_AdjustLink() = 0x%08x\n", -+ err); -+#endif -+ -+ return; -+} -+ -+/* 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 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->phy_node) -+ phy_dev = phy_connect(net_dev, mac_dev->fixed_bus_id, -+ &adjust_link, 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 &= priv->mac_dev->if_support; -+ phy_dev->advertising = phy_dev->supported; -+ -+ priv->mac_dev->phy_dev = phy_dev; -+ -+ return 0; -+} -+ -+static int xgmac_init_phy(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; -+ -+ if (!mac_dev->phy_node) -+ phy_dev = phy_attach(net_dev, mac_dev->fixed_bus_id, 0, -+ mac_dev->phy_if); -+ else -+ phy_dev = of_phy_attach(net_dev, mac_dev->phy_node, 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 &= priv->mac_dev->if_support; -+ 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 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 (macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) { -+ if (!mac_dev->phy_node) -+ phy_dev = phy_attach(net_dev, mac_dev->fixed_bus_id, 0, -+ mac_dev->phy_if); -+ else -+ phy_dev = of_phy_attach(net_dev, mac_dev->phy_node, 0, -+ mac_dev->phy_if); -+ } else { -+ if (!mac_dev->phy_node) -+ phy_dev = phy_connect(net_dev, mac_dev->fixed_bus_id, -+ &adjust_link, 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 &= priv->mac_dev->if_support; -+ phy_dev->advertising = phy_dev->supported; -+ -+ mac_dev->phy_dev = phy_dev; -+ -+ return 0; -+} -+ -+static int __cold uninit(struct mac_device *mac_dev) -+{ -+ int _errno, __errno; -+ t_Error err; -+ const struct mac_priv_s *priv; -+ -+ priv = macdev_priv(mac_dev); -+ -+ err = FM_MAC_Disable(priv->mac, e_COMM_MODE_RX_AND_TX); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_MAC_Disable() = 0x%08x\n", err); -+ -+ err = FM_MAC_Free(priv->mac); -+ __errno = -GET_ERROR_TYPE(err); -+ if (unlikely(__errno < 0)) { -+ dev_err(mac_dev->dev, "FM_MAC_Free() = 0x%08x\n", err); -+ if (_errno < 0) -+ _errno = __errno; -+ } -+ -+ return _errno; -+} -+ -+static int __cold ptp_enable(struct mac_device *mac_dev) -+{ -+ int _errno; -+ t_Error err; -+ const struct mac_priv_s *priv; -+ -+ priv = macdev_priv(mac_dev); -+ -+ err = FM_MAC_Enable1588TimeStamp(priv->mac); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_MAC_Enable1588TimeStamp()" -+ "= 0x%08x\n", err); -+ return _errno; -+} -+ -+static int __cold ptp_disable(struct mac_device *mac_dev) -+{ -+ int _errno; -+ t_Error err; -+ const struct mac_priv_s *priv; -+ -+ priv = macdev_priv(mac_dev); -+ -+ err = FM_MAC_Disable1588TimeStamp(priv->mac); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_MAC_Disable1588TimeStamp()" -+ "= 0x%08x\n", err); -+ return _errno; -+} -+ -+static void *get_mac_handle(struct mac_device *mac_dev) -+{ -+ const struct mac_priv_s *priv; -+ priv = macdev_priv(mac_dev); -+ return (void*)priv->mac; -+} -+ -+static int __cold fm_rtc_enable(struct net_device *net_dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_Enable(fm_get_rtc_handle(mac_dev->fm_dev), 0); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_RTC_Enable = 0x%08x\n", err); -+ -+ return _errno; -+} -+ -+static int __cold fm_rtc_disable(struct net_device *net_dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_Disable(fm_get_rtc_handle(mac_dev->fm_dev)); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_RTC_Disable = 0x%08x\n", err); -+ -+ return _errno; -+} -+ -+static int __cold fm_rtc_get_cnt(struct net_device *net_dev, uint64_t *ts) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_GetCurrentTime(fm_get_rtc_handle(mac_dev->fm_dev), ts); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_RTC_GetCurrentTime = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+ -+static int __cold fm_rtc_set_cnt(struct net_device *net_dev, uint64_t ts) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_SetCurrentTime(fm_get_rtc_handle(mac_dev->fm_dev), ts); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_RTC_SetCurrentTime = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+ -+static int __cold fm_rtc_get_drift(struct net_device *net_dev, uint32_t *drift) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_GetFreqCompensation(fm_get_rtc_handle(mac_dev->fm_dev), -+ drift); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_RTC_GetFreqCompensation =" -+ "0x%08x\n", err); -+ -+ return _errno; -+} -+ -+static int __cold fm_rtc_set_drift(struct net_device *net_dev, uint32_t drift) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_SetFreqCompensation(fm_get_rtc_handle(mac_dev->fm_dev), -+ drift); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_RTC_SetFreqCompensation =" -+ "0x%08x\n", err); -+ -+ return _errno; -+} -+ -+static int __cold fm_rtc_set_alarm(struct net_device *net_dev, uint32_t id, -+ uint64_t time) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; -+ 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(mac_dev->fm_dev), -+ &alarm); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_RTC_SetAlarm =" -+ "0x%08x\n", err); -+ -+ return _errno; -+} -+ -+static int __cold fm_rtc_set_fiper(struct net_device *net_dev, uint32_t id, -+ uint64_t fiper) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; -+ 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(mac_dev->fm_dev), &pp); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ dev_err(mac_dev->dev, "FM_RTC_SetPeriodicPulse =" -+ "0x%08x\n", err); -+ -+ return _errno; -+} -+ -+ -+void fm_mac_dump_regs(struct mac_device *mac_dev) -+{ -+ struct mac_priv_s *mac_priv = macdev_priv(mac_dev); -+ -+ FM_MAC_DumpRegs(mac_priv->mac); -+} -+ -+static void __devinit __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->change_promisc = change_promisc; -+ mac_dev->change_addr = change_addr; -+ mac_dev->set_multi = set_multi; -+ mac_dev->uninit = uninit; -+ mac_dev->ptp_enable = ptp_enable; -+ mac_dev->ptp_disable = ptp_disable; -+ mac_dev->get_mac_handle = get_mac_handle; -+ 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; -+} -+ -+static void __devinit __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->change_promisc = change_promisc; -+ mac_dev->change_addr = change_addr; -+ mac_dev->set_multi = set_multi; -+ mac_dev->uninit = uninit; -+} -+ -+static void __devinit __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->change_promisc = change_promisc; -+ mac_dev->change_addr = change_addr; -+ mac_dev->set_multi = set_multi; -+ mac_dev->uninit = uninit; -+ 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; -+} -+ -+void (*const mac_setup[])(struct mac_device *mac_dev) __devinitconst = { -+ [DTSEC] = setup_dtsec, -+ [XGMAC] = setup_xgmac, -+ [MEMAC] = setup_memac -+}; -diff --git a/drivers/net/dpa/mac.c b/drivers/net/dpa/mac.c -new file mode 100644 -index 0000000..7f72b2a ---- /dev/null -+++ b/drivers/net/dpa/mac.c -@@ -0,0 +1,441 @@ -+/* 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. -+ */ -+ -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dpaa_eth-common.h" -+ -+#include "lnxwrp_fm_ext.h" -+ -+#include "../ethernet/freescale/fsl_pq_mdio.h" -+#include "mac.h" -+ -+#define DTSEC_SUPPORTED \ -+ (SUPPORTED_10baseT_Half \ -+ | SUPPORTED_10baseT_Full \ -+ | SUPPORTED_100baseT_Half \ -+ | SUPPORTED_100baseT_Full \ -+ | SUPPORTED_Autoneg \ -+ | SUPPORTED_MII) -+ -+static const char phy_str[][11] __devinitconst = -+{ -+ [PHY_INTERFACE_MODE_MII] = "mii", -+ [PHY_INTERFACE_MODE_GMII] = "gmii", -+ [PHY_INTERFACE_MODE_SGMII] = "sgmii", -+ [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" -+}; -+ -+static phy_interface_t __devinit __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[] __devinitconst = -+{ -+ [PHY_INTERFACE_MODE_MII] = SPEED_100, -+ [PHY_INTERFACE_MODE_GMII] = SPEED_1000, -+ [PHY_INTERFACE_MODE_SGMII] = 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 -+}; -+ -+static struct mac_device * __devinit __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 __devexit __cold free_macdev(struct mac_device *mac_dev) -+{ -+ dev_set_drvdata(mac_dev->dev, NULL); -+ -+ return mac_dev->uninit(mac_dev); -+} -+ -+static const struct of_device_id mac_match[] __devinitconst = { -+ [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 __devinit __cold mac_probe(struct platform_device *_of_dev) -+{ -+ int _errno, i, lenp; -+ struct device *dev; -+ struct device_node *mac_node, *dev_node; -+ struct mac_device *mac_dev; -+ struct platform_device *of_dev; -+ struct resource res; -+ const uint8_t *mac_addr; -+ const char *char_prop; -+ const phandle *phandle_prop; -+ const uint32_t *uint32_prop; -+ 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; -+ } -+ -+ /* -+ * XXX: Warning, future versions of Linux will most likely not even -+ * call the driver code to allow us to override the TBIPA value, -+ * we'll need to address this when we move to newer kernel rev -+ */ -+#define TBIPA_OFFSET 0x1c -+#define TBIPA_DEFAULT_ADDR 5 -+ mac_dev->tbi_node = of_parse_phandle(mac_node, "tbi-handle", 0); -+ if (mac_dev->tbi_node) { -+ u32 tbiaddr = TBIPA_DEFAULT_ADDR; -+ -+ uint32_prop = of_get_property(mac_dev->tbi_node, "reg", NULL); -+ if (uint32_prop) -+ tbiaddr = *uint32_prop; -+ out_be32(mac_dev->vaddr + TBIPA_OFFSET, 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 */ -+ uint32_prop = of_get_property(mac_node, "cell-index", &lenp); -+ if (unlikely(uint32_prop == NULL)) { -+ dev_err(dev, "of_get_property(%s, cell-index) failed\n", -+ mac_node->full_name); -+ _errno = -EINVAL; -+ goto _return_dev_set_drvdata; -+ } -+ BUG_ON(lenp != sizeof(uint32_t)); -+ mac_dev->cell_index = *uint32_prop; -+ -+ /* Get the MAC address */ -+ mac_addr = of_get_mac_address(mac_node); -+ if (unlikely(mac_addr == NULL)) { -+ dev_err(dev, "of_get_mac_address(%s) failed\n", -+ mac_node->full_name); -+ _errno = -EINVAL; -+ goto _return_dev_set_drvdata; -+ } -+ memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr)); -+ -+ /* Get the port handles */ -+ phandle_prop = of_get_property(mac_node, "fsl,port-handles", &lenp); -+ if (unlikely(phandle_prop == NULL)) { -+ dev_err(dev, "of_get_property(%s, port-handles) failed\n", -+ mac_node->full_name); -+ _errno = -EINVAL; -+ goto _return_dev_set_drvdata; -+ } -+ BUG_ON(lenp != sizeof(phandle) * ARRAY_SIZE(mac_dev->port_dev)); -+ -+ for_each_port_device(i, mac_dev->port_dev) { -+ /* Find the port node */ -+ dev_node = of_find_node_by_phandle(phandle_prop[i]); -+ if (unlikely(dev_node == NULL)) { -+ dev_err(dev, "of_find_node_by_phandle() failed\n"); -+ _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 */ -+ char_prop = (const char *)of_get_property(mac_node, -+ "phy-connection-type", NULL); -+ if (unlikely(char_prop == NULL)) { -+ dev_warn(dev, -+ "of_get_property(%s, phy-connection-type) " -+ "failed. 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")) -+ mac_dev->if_support &= ~(SUPPORTED_10baseT_Half | -+ SUPPORTED_100baseT_Half); -+ -+ /* Gigabit support (no half-duplex) */ -+ if (mac_dev->max_speed == 1000) -+ 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 == NULL) { -+ int sz; -+ const u32 *phy_id = of_get_property(mac_node, "fixed-link", -+ &sz); -+ if (!phy_id || sz < sizeof(*phy_id)) { -+ dev_err(dev, "No PHY (or fixed link) found\n"); -+ _errno = -EINVAL; -+ goto _return_dev_set_drvdata; -+ } -+ -+ sprintf(mac_dev->fixed_bus_id, PHY_ID_FMT, "0", phy_id[0]); -+ } -+ -+ _errno = mac_dev->init(mac_dev); -+ if (unlikely(_errno < 0)) { -+ dev_err(dev, "mac_dev->init() = %d\n", _errno); -+ goto _return_dev_set_drvdata; -+ } -+ -+ 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 __devexit __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 = __devexit_p(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 (" VERSION ")\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); -diff --git a/drivers/net/dpa/mac.h b/drivers/net/dpa/mac.h -new file mode 100644 -index 0000000..5cdb57c ---- /dev/null -+++ b/drivers/net/dpa/mac.h -@@ -0,0 +1,110 @@ -+/* 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 "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 *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; -+ -+ int (*init_phy)(struct net_device *net_dev); -+ int (*init)(struct mac_device *mac_dev); -+ int (*start)(struct mac_device *mac_dev); -+ int (*stop)(struct mac_device *mac_dev); -+ int (*change_promisc)(struct mac_device *mac_dev); -+ int (*change_addr)(struct mac_device *mac_dev, uint8_t *addr); -+ int (*set_multi)(struct net_device *net_dev); -+ int (*uninit)(struct mac_device *mac_dev); -+ int (*ptp_enable)(struct mac_device *mac_dev); -+ int (*ptp_disable)(struct mac_device *mac_dev); -+ void *(*get_mac_handle)(struct mac_device *mac_dev); -+ int (*fm_rtc_enable)(struct net_device *net_dev); -+ int (*fm_rtc_disable)(struct net_device *net_dev); -+ int (*fm_rtc_get_cnt)(struct net_device *net_dev, uint64_t *ts); -+ int (*fm_rtc_set_cnt)(struct net_device *net_dev, uint64_t ts); -+ int (*fm_rtc_get_drift)(struct net_device *net_dev, uint32_t *drift); -+ int (*fm_rtc_set_drift)(struct net_device *net_dev, uint32_t drift); -+ int (*fm_rtc_set_alarm)(struct net_device *net_dev, uint32_t id, -+ uint64_t time); -+ int (*fm_rtc_set_fiper)(struct net_device *net_dev, uint32_t id, -+ uint64_t fiper); -+}; -+ -+struct mac_address { -+ uint8_t addr[ETH_ALEN]; -+ struct list_head list; -+}; -+ -+#define for_each_port_device(i, port_dev) \ -+ for (i = 0; i < ARRAY_SIZE(port_dev); i++) -+ -+static inline void * __attribute((nonnull)) 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); -+ -+#endif /* __MAC_H */ -diff --git a/drivers/net/dpa/memac_mdio.c b/drivers/net/dpa/memac_mdio.c -new file mode 100644 -index 0000000..5d27ea3 ---- /dev/null -+++ b/drivers/net/dpa/memac_mdio.c -@@ -0,0 +1,322 @@ -+ /* -+ * 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. -+ * -+ * QorIQ MEMAC MDIO Controller -+ * -+ * Authors: Sandeep Singh -+ * Andy Fleming -+ * Roy Zang -+ * -+ * Based on memac mdio code from uboot: drivers/net/fm/memac_phy.c -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct memac_mdio_controller { -+ u32 res0[0xc]; -+ u32 mdio_stat; /* MDIO configuration and status */ -+ u32 mdio_ctl; /* MDIO control */ -+ u32 mdio_data; /* MDIO data */ -+ u32 mdio_addr; /* MDIO address */ -+} __packed; -+ -+#define MDIO_STAT_CLKDIV(x) (((x>>1) & 0xff) << 8) -+#define MDIO_STAT_BSY (1 << 0) -+#define MDIO_STAT_RD_ER (1 << 1) -+#define MDIO_CTL_DEV_ADDR(x) (x & 0x1f) -+#define MDIO_CTL_PORT_ADDR(x) ((x & 0x1f) << 5) -+#define MDIO_CTL_PRE_DIS (1 << 10) -+#define MDIO_CTL_SCAN_EN (1 << 11) -+#define MDIO_CTL_POST_INC (1 << 14) -+#define MDIO_CTL_READ (1 << 15) -+#define MDIO_STAT_ENC (1 << 6) -+#define MDIO_STAT_HOLD_15_CLK (7 << 2) -+ -+#define MDIO_DATA(x) (x & 0xffff) -+#define MDIO_DATA_BSY (1 << 31) -+ -+/* Number of microseconds to wait for an MII register to respond */ -+#define MII_TIMEOUT 1000 -+ -+int memac_mdio_write(struct mii_bus *bus, int port_addr, -+ int dev_addr, int regnum, u16 value) -+{ -+ struct memac_mdio_controller __iomem *regs = bus->priv; -+ u32 mdio_ctl, mdio_stat; -+ int status; -+ -+ mdio_stat = in_be32(®s->mdio_stat); -+ if (bus->is_c45) { -+ if (dev_addr == MDIO_DEVAD_NONE) -+ return 0xffff; -+ mdio_stat = mdio_stat | MDIO_STAT_ENC | MDIO_STAT_HOLD_15_CLK; -+ } else { -+ /* Clause 22 */ -+ dev_addr = regnum & 0x1f; -+ mdio_stat = mdio_stat & ~MDIO_STAT_ENC; -+ } -+ -+ out_be32(®s->mdio_stat, mdio_stat); -+ -+ /* Wait till the bus is free */ -+ status = spin_event_timeout(!(in_be32(®s->mdio_stat) -+ & MDIO_STAT_BSY), MII_TIMEOUT, 0); -+ if (!status) { -+ dev_err(&bus->dev, "Timeout waiting for MII bus\n"); -+ return -ETIMEDOUT; -+ } -+ -+ /* Set the port and dev addr */ -+ mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr); -+ out_be32(®s->mdio_ctl, mdio_ctl); -+ -+ /* Set the register address */ -+ if (bus->is_c45) { -+ status = spin_event_timeout(!(in_be32(®s->mdio_stat) -+ & MDIO_STAT_BSY), MII_TIMEOUT, 0); -+ if (!status) { -+ dev_err(&bus->dev, "Timeout waiting for MII bus\n"); -+ return -ETIMEDOUT; -+ } -+ out_be32(®s->mdio_addr, regnum & 0xffff); -+ } -+ -+ /* Wait till the bus is free */ -+ status = spin_event_timeout(!(in_be32(®s->mdio_stat) -+ & MDIO_STAT_BSY), MII_TIMEOUT, 0); -+ if (!status) { -+ dev_err(&bus->dev, "Timeout waiting for MII bus\n"); -+ return -ETIMEDOUT; -+ } -+ -+ /* Write the value to the register */ -+ out_be32(®s->mdio_data, MDIO_DATA(value)); -+ -+ /* Wait till the MDIO write is complete */ -+ status = spin_event_timeout(!(in_be32(®s->mdio_stat) -+ & MDIO_DATA_BSY), MII_TIMEOUT, 0); -+ if (!status) -+ return -ETIMEDOUT; -+ -+ return 0; -+} -+ -+ -+int memac_mdio_read(struct mii_bus *bus, int port_addr, int dev_addr, -+ int regnum) -+{ -+ struct memac_mdio_controller __iomem *regs = bus->priv; -+ u32 mdio_ctl, mdio_stat; -+ int status; -+ -+ mdio_stat = in_be32(®s->mdio_stat); -+ if (bus->is_c45) { -+ if (dev_addr == MDIO_DEVAD_NONE) -+ return 0xffff; -+ mdio_stat = mdio_stat | MDIO_STAT_ENC | MDIO_STAT_HOLD_15_CLK; -+ } else { -+ /* Clause 22 */ -+ dev_addr = regnum & 0x1f; -+ mdio_stat = mdio_stat & ~MDIO_STAT_ENC; -+ } -+ -+ out_be32(®s->mdio_stat, mdio_stat); -+ -+ /* Wait till the bus is free */ -+ status = spin_event_timeout(!(in_be32(®s->mdio_stat) -+ & MDIO_STAT_BSY), MII_TIMEOUT, 0); -+ if (!status) -+ return -ETIMEDOUT; -+ -+ /* Set the Port and Device Addrs */ -+ mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr); -+ out_be32(®s->mdio_ctl, mdio_ctl); -+ -+ /* Set the register address */ -+ if (bus->is_c45) { -+ status = spin_event_timeout(!(in_be32(®s->mdio_stat) -+ & MDIO_STAT_BSY), MII_TIMEOUT, 0); -+ if (!status) { -+ dev_err(&bus->dev, "Timeout waiting for MII bus\n"); -+ return -ETIMEDOUT; -+ } -+ out_be32(®s->mdio_addr, regnum & 0xffff); -+ } -+ -+ /* Wait till the bus is free */ -+ status = spin_event_timeout(!(in_be32(®s->mdio_stat) -+ & MDIO_STAT_BSY), MII_TIMEOUT, 0); -+ if (!status) { -+ dev_err(&bus->dev, "Timeout waiting for MII bus\n"); -+ return -ETIMEDOUT; -+ } -+ -+ /* Initiate the read */ -+ mdio_ctl |= MDIO_CTL_READ; -+ out_be32(®s->mdio_ctl, mdio_ctl); -+ -+ /* Wait till the MDIO write is complete */ -+ status = spin_event_timeout(!(in_be32(®s->mdio_stat) -+ & MDIO_STAT_BSY), MII_TIMEOUT, 0); -+ if (!status) { -+ dev_err(&bus->dev, "Timeout waiting for MII bus\n"); -+ return -ETIMEDOUT; -+ } -+ -+ /* Return all Fs if nothing was there */ -+ if (in_be32(®s->mdio_stat) & MDIO_STAT_RD_ER) -+ return 0xffff; -+ -+ return in_be32(®s->mdio_data) & 0xffff; -+} -+ -+ -+/* Reset the MIIM registers, and wait for the bus to free */ -+static int memac_mdio_reset(struct mii_bus *bus) -+{ -+ struct memac_mdio_controller __iomem *regs = bus->priv; -+ int status; -+ -+ clrbits32(®s->mdio_stat, MDIO_STAT_ENC); -+ -+ /* Wait till the bus is free */ -+ status = spin_event_timeout(!(in_be32(®s->mdio_stat) -+ & MDIO_STAT_BSY), MII_TIMEOUT, 0); -+ -+ if (!status) { -+ dev_err(&bus->dev, "Timeout waiting for MII bus\n"); -+ return -EBUSY; -+ } -+ -+ return 0; -+} -+ -+ -+static int memac_mdio_probe(struct platform_device *ofdev) -+{ -+ struct memac_mdio_controller __iomem *regs; -+ struct device_node *np = ofdev->dev.of_node; -+ struct mii_bus *new_bus; -+ u64 addr, size; -+ int err = 0; -+ -+ new_bus = mdiobus_alloc(); -+ if (NULL == new_bus) -+ return -ENOMEM; -+ -+ new_bus->name = "Freescale MEMAC MDIO Bus"; -+ new_bus->read = &memac_mdio_read; -+ new_bus->write = &memac_mdio_write; -+ new_bus->reset = &memac_mdio_reset; -+ -+ /* Set the PHY base address */ -+ addr = of_translate_address(np, of_get_address(np, 0, &size, NULL)); -+ regs = ioremap(addr, size); -+ -+ if (NULL == regs) { -+ err = -ENOMEM; -+ goto err_ioremap; -+ } -+ -+ new_bus->priv = (void *)regs; -+ -+ new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL); -+ -+ if (NULL == new_bus->irq) { -+ err = -ENOMEM; -+ goto err_irq_alloc; -+ } -+ -+ new_bus->parent = &ofdev->dev; -+ dev_set_drvdata(&ofdev->dev, new_bus); -+ -+ sprintf(new_bus->id, "%s@%llx", np->name, (unsigned long long)addr); -+ -+ err = of_mdiobus_register(new_bus, np); -+ -+ if (err) { -+ dev_err(&ofdev->dev, "%s: Cannot register as MDIO bus\n", -+ new_bus->name); -+ goto err_registration; -+ } -+ -+ return 0; -+ -+err_registration: -+ kfree(new_bus->irq); -+err_irq_alloc: -+ iounmap(regs); -+err_ioremap: -+ return err; -+} -+ -+ -+static int memac_mdio_remove(struct platform_device *ofdev) -+{ -+ struct device *device = &ofdev->dev; -+ struct mii_bus *bus = dev_get_drvdata(device); -+ -+ mdiobus_unregister(bus); -+ -+ dev_set_drvdata(device, NULL); -+ -+ iounmap((void __iomem *)bus->priv); -+ bus->priv = NULL; -+ mdiobus_free(bus); -+ -+ return 0; -+} -+ -+static struct of_device_id memac_mdio_match[] = { -+ { -+ .compatible = "fsl,fman-memac-mdio", -+ }, -+ {}, -+}; -+ -+static struct platform_driver memac_mdio_driver = { -+ .driver = { -+ .name = "fsl-fman-memac-mdio", -+ .of_match_table = memac_mdio_match, -+ }, -+ .probe = memac_mdio_probe, -+ .remove = memac_mdio_remove, -+}; -+ -+int __init memac_mdio_init(void) -+{ -+ return platform_driver_register(&memac_mdio_driver); -+} -+ -+void memac_mdio_exit(void) -+{ -+ platform_driver_unregister(&memac_mdio_driver); -+} -+subsys_initcall_sync(memac_mdio_init); -+module_exit(memac_mdio_exit); -diff --git a/drivers/net/dpa/offline_port.c b/drivers/net/dpa/offline_port.c -new file mode 100644 -index 0000000..691cd48 ---- /dev/null -+++ b/drivers/net/dpa/offline_port.c -@@ -0,0 +1,349 @@ -+/* -+ * 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. -+ */ -+ -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+ -+#include -+#include -+#include -+ -+#include "offline_port.h" -+#include "dpaa_eth-common.h" -+ -+#define OH_MOD_DESCRIPTION "FSL FMan Offline Parsing port driver" -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_AUTHOR("Bogdan Hamciuc "); -+MODULE_DESCRIPTION(OH_MOD_DESCRIPTION); -+ -+ -+static const struct of_device_id oh_port_match_table[] __devinitconst = { -+ { -+ .compatible = "fsl,dpa-oh" -+ }, -+ { -+ .compatible = "fsl,dpa-oh-shared" -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, oh_port_match_table); -+ -+static int oh_port_remove(struct platform_device *_of_dev); -+static int oh_port_probe(struct platform_device *_of_dev); -+ -+static struct platform_driver oh_port_driver = { -+ .driver = { -+ .name = KBUILD_MODNAME, -+ .of_match_table = oh_port_match_table, -+ .owner = THIS_MODULE, -+ }, -+ .probe = oh_port_probe, -+ .remove = __devexit_p(oh_port_remove) -+}; -+ -+/* Allocation code for the OH port's PCD frame queues */ -+static int __devinit __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 __devinit __cold oh_free_pcd_fqids(struct device *dev, uint32_t base_fqid) -+{ -+ dev_crit(dev, "callback not implemented!\n"); -+ BUG(); -+ -+ return 0; -+} -+ -+static int __devinit -+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; -+ const phandle *oh_port_handle; -+ struct platform_device *oh_of_dev; -+ struct device_node *oh_node; -+ struct device *oh_dev; -+ struct dpa_oh_config_s *oh_config; -+ uint32_t *oh_all_queues; -+ uint32_t queues_count; -+ uint32_t crt_fqid_base; -+ uint32_t crt_fq_count; -+ struct fm_port_params oh_port_tx_params; -+ struct fm_port_pcd_param oh_port_pcd_params; -+ /* True if the current partition owns the OH port. */ -+ bool init_oh_port; -+ const struct of_device_id *match; -+ -+ 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_port_handle = of_get_property(dpa_oh_node, -+ "fsl,fman-oh-port", &lenp); -+ if (oh_port_handle == NULL) { -+ dev_err(dpa_oh_dev, "No OH port handle found in node %s\n", -+ dpa_oh_node->full_name); -+ return -EINVAL; -+ } -+ -+ BUG_ON(lenp % sizeof(*oh_port_handle)); -+ if (lenp != sizeof(*oh_port_handle)) { -+ dev_err(dpa_oh_dev, "Found %lu OH port bindings in node %s," -+ " only 1 phandle is allowed.\n", -+ (unsigned long int)(lenp / sizeof(*oh_port_handle)), -+ dpa_oh_node->full_name); -+ return -EINVAL; -+ } -+ -+ /* Read configuration for the OH port */ -+ oh_node = of_find_node_by_phandle(*oh_port_handle); -+ 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); -+ -+ oh_of_dev = of_find_device_by_node(oh_node); -+ BUG_ON(oh_of_dev == NULL); -+ oh_dev = &oh_of_dev->dev; -+ of_node_put(oh_node); -+ -+ /* -+ * 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); -+ 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); -+ return -ENOMEM; -+ } -+ -+ /* -+ * Read FQ ids/nums for the DPA OH node -+ */ -+ oh_all_queues = (uint32_t *)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 = oh_all_queues[fq_idx++]; -+ crt_fq_count = 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 = oh_all_queues[fq_idx++]; -+ crt_fq_count = 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); -+ -+ /* 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; -+ } -+ -+ /* Set Tx params */ -+ dpaa_eth_init_port(tx, oh_config->oh_port, oh_port_tx_params, -+ oh_config->error_fqid, oh_config->default_fqid, -+ DPA_TX_PRIV_DATA_SIZE, FALSE); -+ /* 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 */ -+ fm_port_enable(oh_config->oh_port); -+ dev_info(dpa_oh_dev, "OH port %s enabled.\n", oh_node->full_name); -+ -+ return 0; -+ -+return_kfree: -+ devm_kfree(dpa_oh_dev, oh_config); -+ return _errno; -+} -+ -+static int __devexit __cold oh_port_remove(struct platform_device *_of_dev) -+{ -+ int _errno = 0; -+ 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->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 return_error; -+ } -+ -+ fm_port_disable(oh_config->oh_port); -+ devm_kfree(&_of_dev->dev, oh_config); -+ dev_set_drvdata(&_of_dev->dev, NULL); -+ -+return_error: -+ return _errno; -+} -+ -+static int __init __cold oh_port_load(void) -+{ -+ int _errno; -+ -+ pr_info(KBUILD_MODNAME ": " OH_MOD_DESCRIPTION " (" VERSION ")\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); -diff --git a/drivers/net/dpa/offline_port.h b/drivers/net/dpa/offline_port.h -new file mode 100644 -index 0000000..1b1a63f ---- /dev/null -+++ b/drivers/net/dpa/offline_port.h -@@ -0,0 +1,45 @@ -+/* -+ * 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 -+ -+#include "fsl_fman.h" -+ -+/* OH port configuration */ -+struct dpa_oh_config_s { -+ uint32_t error_fqid; -+ uint32_t default_fqid; -+ struct fm_port *oh_port; -+}; -+ -+#endif /* __OFFLINE_PORT_H */ -diff --git a/drivers/net/dpa/xgmac_mdio.c b/drivers/net/dpa/xgmac_mdio.c -new file mode 100644 -index 0000000..a66c6be ---- /dev/null -+++ b/drivers/net/dpa/xgmac_mdio.c -@@ -0,0 +1,286 @@ -+/* Copyright 2009-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. -+ * -+ * QorIQ 10-G MDIO Controller -+ * -+ * Author: Andy Fleming -+ * -+ * Based on fsl_pq_mdio.c -+ */ -+ -+#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 "xgmac_mdio.h" -+ -+/* Write value to the PHY for this device to the register at regnum, */ -+/* waiting until the write is done before it returns. All PHY */ -+/* configuration has to be done through the TSEC1 MIIM regs */ -+int xgmac_mdio_write(struct mii_bus *bus, int port_addr, -+ int dev_addr, int regnum, u16 value) -+{ -+ struct tgec_mdio_controller __iomem *regs = bus->priv; -+ u32 mdio_ctl, mdio_stat; -+ -+ if (dev_addr == MDIO_DEVAD_NONE) -+ return 0xffff; -+ -+ /* Setup the MII Mgmt clock speed */ -+ mdio_stat = MDIO_STAT_CLKDIV(100); -+ out_be32(®s->mdio_stat, mdio_stat); -+ -+ /* Wait till the bus is free */ -+ while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) -+ cpu_relax(); -+ -+ /* Set the port and dev addr */ -+ mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr); -+ out_be32(®s->mdio_ctl, mdio_ctl); -+ -+ /* Set the register address */ -+ out_be32(®s->mdio_addr, regnum & 0xffff); -+ -+ /* Wait till the bus is free */ -+ while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) -+ cpu_relax(); -+ -+ /* Write the value to the register */ -+ out_be32(®s->mdio_data, MDIO_DATA(value)); -+ -+ /* Wait till the MDIO write is complete */ -+ while ((in_be32(®s->mdio_data)) & MDIO_DATA_BSY) -+ cpu_relax(); -+ -+ return 0; -+} -+ -+ -+/* Reads from register regnum in the PHY for device dev, */ -+/* returning the value. Clears miimcom first. All PHY */ -+/* configuration has to be done through the TSEC1 MIIM regs */ -+int xgmac_mdio_read(struct mii_bus *bus, int port_addr, int dev_addr, -+ int regnum) -+{ -+ struct tgec_mdio_controller __iomem *regs = bus->priv; -+ u32 mdio_ctl, mdio_stat; -+ -+ /* Setup the MII Mgmt clock speed */ -+ mdio_stat = MDIO_STAT_CLKDIV(100); -+ out_be32(®s->mdio_stat, mdio_stat); -+ -+ /* Wait till the bus is free */ -+ while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) -+ cpu_relax(); -+ -+ /* Set the Port and Device Addrs */ -+ mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr); -+ out_be32(®s->mdio_ctl, mdio_ctl); -+ -+ /* Set the register address */ -+ out_be32(®s->mdio_addr, regnum & 0xffff); -+ -+ /* Wait till the bus is free */ -+ while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) -+ cpu_relax(); -+ -+ /* Initiate the read */ -+ mdio_ctl |= MDIO_CTL_READ; -+ out_be32(®s->mdio_ctl, mdio_ctl); -+ -+ /* Wait till the MDIO write is complete */ -+ while ((in_be32(®s->mdio_data)) & MDIO_DATA_BSY) -+ cpu_relax(); -+ -+ /* Return all Fs if nothing was there */ -+ if (in_be32(®s->mdio_stat) & MDIO_STAT_RD_ER) -+ return 0xffff; -+ -+ return in_be32(®s->mdio_data) & 0xffff; -+} -+ -+ -+/* Reset the MIIM registers, and wait for the bus to free */ -+static int xgmac_mdio_reset(struct mii_bus *bus) -+{ -+ struct tgec_mdio_controller __iomem *regs = bus->priv; -+ int timeout = PHY_INIT_TIMEOUT; -+ u32 mdio_stat; -+ -+ mutex_lock(&bus->mdio_lock); -+ -+ /* Setup the MII Mgmt clock speed */ -+ mdio_stat = MDIO_STAT_CLKDIV(100); -+ out_be32(®s->mdio_stat, mdio_stat); -+ -+ /* Wait till the bus is free */ -+ while (((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) && timeout--) -+ cpu_relax(); -+ -+ mutex_unlock(&bus->mdio_lock); -+ -+ if (timeout < 0) { -+ printk(KERN_ERR "%s: The MII Bus is stuck!\n", -+ bus->name); -+ return -EBUSY; -+ } -+ -+ return 0; -+} -+ -+ -+static int xgmac_mdio_probe(struct platform_device *ofdev) -+{ -+ struct tgec_mdio_controller __iomem *regs; -+ struct device_node *np = ofdev->dev.of_node; -+ struct mii_bus *new_bus; -+ u64 addr, size; -+ int err = 0; -+ -+ if (!of_device_is_available(np)) -+ return -ENODEV; -+ -+ new_bus = mdiobus_alloc(); -+ if (NULL == new_bus) -+ return -ENOMEM; -+ -+ new_bus->name = "Freescale XGMAC MDIO Bus", -+ new_bus->read = &xgmac_mdio_read, -+ new_bus->write = &xgmac_mdio_write, -+ new_bus->reset = &xgmac_mdio_reset, -+ -+ /* Set the PHY base address */ -+ addr = of_translate_address(np, of_get_address(np, 0, &size, NULL)); -+ regs = ioremap(addr, size); -+ -+ if (NULL == regs) { -+ err = -ENOMEM; -+ goto err_ioremap; -+ } -+ -+ new_bus->priv = (void __force *)regs; -+ -+ new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL); -+ -+ if (NULL == new_bus->irq) { -+ err = -ENOMEM; -+ goto err_irq_alloc; -+ } -+ -+ new_bus->parent = &ofdev->dev; -+ dev_set_drvdata(&ofdev->dev, new_bus); -+ -+ sprintf(new_bus->id, "%s@%llx", np->name, (unsigned long long)addr); -+ -+ err = of_mdiobus_register(new_bus, np); -+ -+ if (err) { -+ printk(KERN_ERR "%s: Cannot register as MDIO bus\n", -+ new_bus->name); -+ goto err_registration; -+ } -+ -+ return 0; -+ -+err_registration: -+ kfree(new_bus->irq); -+err_irq_alloc: -+ iounmap(regs); -+err_ioremap: -+ return err; -+} -+ -+ -+static int xgmac_mdio_remove(struct platform_device *ofdev) -+{ -+ struct device *device = &ofdev->dev; -+ struct mii_bus *bus = dev_get_drvdata(device); -+ -+ mdiobus_unregister(bus); -+ -+ dev_set_drvdata(device, NULL); -+ -+ iounmap((void __iomem *)bus->priv); -+ bus->priv = NULL; -+ mdiobus_free(bus); -+ -+ return 0; -+} -+ -+static struct of_device_id xgmac_mdio_match[] = { -+ { -+ .compatible = "fsl,fman-xmdio", -+ }, -+ {}, -+}; -+ -+static struct platform_driver xgmac_mdio_driver = { -+ .driver = { -+ .name = "fsl-fman_xmdio", -+ .of_match_table = xgmac_mdio_match, -+ }, -+ .probe = xgmac_mdio_probe, -+ .remove = xgmac_mdio_remove, -+}; -+ -+int __init xgmac_mdio_init(void) -+{ -+ return platform_driver_register(&xgmac_mdio_driver); -+} -+ -+void xgmac_mdio_exit(void) -+{ -+ platform_driver_unregister(&xgmac_mdio_driver); -+} -+subsys_initcall_sync(xgmac_mdio_init); -+module_exit(xgmac_mdio_exit); -diff --git a/drivers/net/dpa/xgmac_mdio.h b/drivers/net/dpa/xgmac_mdio.h -new file mode 100644 -index 0000000..6eb49cd ---- /dev/null -+++ b/drivers/net/dpa/xgmac_mdio.h -@@ -0,0 +1,61 @@ -+/* Copyright 2009-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. -+ * -+ * Freescale FMAN XGMAC MDIO Driver -- MDIO Management Bus Implementation -+ * Driver for the MDIO bus controller on QorIQ 10G ports -+ * -+ * Author: Andy Fleming -+ */ -+ -+#ifndef __XGMAC_MDIO_H -+#define __XGMAC_MDIO_H -+ -+struct tgec_mdio_controller { -+ u32 res0[0xc]; -+ u32 mdio_stat; /* MDIO configuration and status */ -+ u32 mdio_ctl; /* MDIO control */ -+ u32 mdio_data; /* MDIO data */ -+ u32 mdio_addr; /* MDIO address */ -+} __attribute__ ((packed)); -+ -+#define MDIO_STAT_CLKDIV(x) (((x>>1) & 0xff) << 8) -+#define MDIO_STAT_BSY (1 << 0) -+#define MDIO_STAT_RD_ER (1 << 1) -+#define MDIO_CTL_DEV_ADDR(x) (x & 0x1f) -+#define MDIO_CTL_PORT_ADDR(x) ((x & 0x1f) << 5) -+#define MDIO_CTL_PRE_DIS (1 << 10) -+#define MDIO_CTL_SCAN_EN (1 << 11) -+#define MDIO_CTL_POST_INC (1 << 14) -+#define MDIO_CTL_READ (1 << 15) -+ -+#define MDIO_DATA(x) (x & 0xffff) -+#define MDIO_DATA_BSY (1 << 31) -+ -+#endif /* __XGMAC_MDIO_H */ -diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c -index ada234a..9e3df77 100644 ---- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c -+++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c -@@ -5,7 +5,7 @@ - * Author: Andy Fleming - * Modifier: Sandeep Gopalpet - * -- * Copyright 2002-2004, 2008-2009 Freescale Semiconductor, Inc. -+ * Copyright 2002-2004, 2008-2009, 2012 Freescale Semiconductor, Inc. - * - * Based on gianfar_mii.c and ucc_geth_mii.c (Li Yang, Kim Phillips) - * -@@ -50,8 +50,13 @@ - struct fsl_pq_mdio_priv { - void __iomem *map; - struct fsl_pq_mdio __iomem *regs; -+ struct mutex mdio_lock; - }; - -+/* pointer to bus, to be used by the fsl_pq_mdio locking functions when called -+ * with a null parameter */ -+struct mii_bus *fsl_pq_mdio_bus; -+ - /* - * Write value to the PHY at mii_id at register regnum, - * on the bus attached to the local interface, which may be different from the -@@ -62,7 +67,7 @@ struct fsl_pq_mdio_priv { - * controlling the external PHYs, for example. - */ - int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id, -- int regnum, u16 value) -+ int regnum, u16 value) - { - /* Set the PHY address and the register address we want to write */ - out_be32(®s->miimadd, (mii_id << 8) | regnum); -@@ -87,8 +92,8 @@ int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id, - * and are always tied to the local mdio pins, which may not be the - * same as system mdio bus, used for controlling the external PHYs, for eg. - */ --int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, -- int mii_id, int regnum) -+int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, int mii_id, -+ int regnum) - { - u16 value; - -@@ -116,28 +121,63 @@ static struct fsl_pq_mdio __iomem *fsl_pq_mdio_get_regs(struct mii_bus *bus) - return priv->regs; - } - -+void fsl_pq_mdio_lock(struct mii_bus *bus) -+{ -+ struct fsl_pq_mdio_priv *priv; -+ -+ priv = (bus) ? bus->priv : fsl_pq_mdio_bus->priv; -+ -+ mutex_lock(&priv->mdio_lock); -+} -+EXPORT_SYMBOL(fsl_pq_mdio_lock); -+ -+void fsl_pq_mdio_unlock(struct mii_bus *bus) -+{ -+ struct fsl_pq_mdio_priv *priv; -+ -+ priv = (bus) ? bus->priv : fsl_pq_mdio_bus->priv; -+ -+ mutex_unlock(&priv->mdio_lock); -+} -+EXPORT_SYMBOL(fsl_pq_mdio_unlock); -+ - /* - * Write value to the PHY at mii_id at register regnum, - * on the bus, waiting until the write is done before returning. - */ --int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) -+int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int devad, int regnum, -+ u16 value) - { - struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); -+ int result; -+ -+ fsl_pq_mdio_lock(bus); - - /* Write to the local MII regs */ -- return fsl_pq_local_mdio_write(regs, mii_id, regnum, value); -+ result = fsl_pq_local_mdio_write(regs, mii_id, regnum, value); -+ -+ fsl_pq_mdio_unlock(bus); -+ -+ return result; - } - - /* - * Read the bus for PHY at addr mii_id, register regnum, and - * return the value. Clears miimcom first. - */ --int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) -+int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int devad, int regnum) - { - struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); -+ int result; -+ -+ fsl_pq_mdio_lock(bus); - - /* Read the local MII regs */ -- return fsl_pq_local_mdio_read(regs, mii_id, regnum); -+ result = fsl_pq_local_mdio_read(regs, mii_id, regnum); -+ -+ fsl_pq_mdio_unlock(bus); -+ -+ return result; - } - - /* Reset the MIIM registers, and wait for the bus to free */ -@@ -183,10 +223,28 @@ void fsl_pq_mdio_bus_name(char *name, struct device_node *np) - } - EXPORT_SYMBOL_GPL(fsl_pq_mdio_bus_name); - -+/* Scan the bus in reverse, looking for an empty spot */ -+static int fsl_pq_mdio_find_free(struct mii_bus *new_bus) -+{ -+ int i; -+ -+ for (i = PHY_MAX_ADDR; i > 0; i--) { -+ u32 phy_id; -+ -+ if (get_phy_id(new_bus, i, &phy_id)) -+ return -1; -+ -+ if (phy_id == 0xffffffff) -+ break; -+ } -+ -+ return i; -+} - -+ -+#if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) - static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np) - { --#if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) - struct gfar __iomem *enet_regs; - - /* -@@ -202,15 +260,15 @@ static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct devi - } else if (of_device_is_compatible(np, "fsl,etsec2-mdio") || - of_device_is_compatible(np, "fsl,etsec2-tbi")) { - return of_iomap(np, 1); -- } --#endif -- return NULL; -+ } else -+ return NULL; - } -+#endif - - -+#if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) - static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) - { --#if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) - struct device_node *np = NULL; - int err = 0; - -@@ -243,10 +301,9 @@ static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) - return err; - else - return -EINVAL; --#else -- return -ENODEV; --#endif - } -+#endif -+ - - static int fsl_pq_mdio_probe(struct platform_device *ofdev) - { -@@ -266,6 +323,8 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev) - if (!priv) - return -ENOMEM; - -+ mutex_init(&priv->mdio_lock); -+ - new_bus = mdiobus_alloc(); - if (!new_bus) { - err = -ENOMEM; -@@ -301,6 +360,7 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev) - - if (of_device_is_compatible(np, "fsl,gianfar-mdio") || - of_device_is_compatible(np, "fsl,gianfar-tbi") || -+ of_device_is_compatible(np, "fsl,fman-mdio") || - of_device_is_compatible(np, "fsl,ucc-mdio") || - of_device_is_compatible(np, "ucc_geth_phy")) - map -= offsetof(struct fsl_pq_mdio, miimcfg); -@@ -322,13 +382,19 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev) - of_device_is_compatible(np, "fsl,etsec2-mdio") || - of_device_is_compatible(np, "fsl,etsec2-tbi") || - of_device_is_compatible(np, "gianfar")) { -+#if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) - tbipa = get_gfar_tbipa(regs, np); - if (!tbipa) { - err = -EINVAL; - goto err_free_irqs; - } -+#else -+ err = -ENODEV; -+ goto err_free_irqs; -+#endif - } else if (of_device_is_compatible(np, "fsl,ucc-mdio") || - of_device_is_compatible(np, "ucc_geth_phy")) { -+#if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) - u32 id; - static u32 mii_mng_master; - -@@ -341,6 +407,18 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev) - mii_mng_master = id; - ucc_set_qe_mux_mii_mng(id - 1); - } -+#else -+ err = -ENODEV; -+ goto err_free_irqs; -+#endif -+ } else if (of_device_is_compatible(np, "fsl,fman-mdio")) { -+#ifdef CONFIG_FSL_FMAN -+ pr_debug("fsl_pq_mdio: found fsl,fman-mdio\n"); -+ tbiaddr = 5; -+#else -+ err = -ENODEV; -+ goto err_free_irqs; -+#endif - } else { - err = -ENODEV; - goto err_free_irqs; -@@ -356,15 +434,32 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev) - - if (prop) - tbiaddr = *prop; -+ } - -- if (tbiaddr == -1) { -- err = -EBUSY; -- goto err_free_irqs; -- } else { -- out_be32(tbipa, tbiaddr); -- } -+ if (tbiaddr == -1) { -+#ifndef CONFIG_FSL_FMAN -+ out_be32(tbipa, 0); -+#endif -+ -+ tbiaddr = fsl_pq_mdio_find_free(new_bus); - } - -+ /* -+ * We define TBIPA at 0 to be illegal, opting to fail for boards that -+ * have PHYs at 1-31, rather than change tbipa and rescan. -+ */ -+ if (tbiaddr == 0) { -+ err = -EBUSY; -+ -+ goto err_free_irqs; -+ } -+ -+#ifndef CONFIG_FSL_FMAN -+ out_be32(tbipa, tbiaddr); -+#endif -+ -+ fsl_pq_mdio_bus = new_bus; -+ - err = of_mdiobus_register(new_bus, np); - if (err) { - printk (KERN_ERR "%s: Cannot register as MDIO bus\n", -@@ -428,6 +523,9 @@ static struct of_device_id fsl_pq_mdio_match[] = { - { - .compatible = "fsl,etsec2-mdio", - }, -+ { -+ .compatible = "fsl,fman-mdio", -+ }, - {}, - }; - MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match); -diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.h b/drivers/net/ethernet/freescale/fsl_pq_mdio.h -index bd17a2a..898a042 100644 ---- a/drivers/net/ethernet/freescale/fsl_pq_mdio.h -+++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.h -@@ -41,12 +41,17 @@ struct fsl_pq_mdio { - u8 res4[2728]; - } __packed; - --int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum); --int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value); -+ -+int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int devad, int regnum); -+int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int devad, int regnum, -+ u16 value); - int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id, -- int regnum, u16 value); --int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, int mii_id, int regnum); -+ int regnum, u16 value); -+int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, int mii_id, -+ int regnum); - int __init fsl_pq_mdio_init(void); - void fsl_pq_mdio_exit(void); - void fsl_pq_mdio_bus_name(char *name, struct device_node *np); -+void fsl_pq_mdio_lock(struct mii_bus *bus); -+void fsl_pq_mdio_unlock(struct mii_bus *bus); - #endif /* FSL_PQ_MDIO_H */ -diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c -index 6c58da2..2be6a54 100644 ---- a/drivers/net/phy/mdio_bus.c -+++ b/drivers/net/phy/mdio_bus.c -@@ -75,6 +75,38 @@ static struct class mdio_bus_class = { - .dev_release = mdiobus_release, - }; - -+#ifdef CONFIG_OF_MDIO -+/* Helper function for of_mdio_find_bus */ -+static int of_mdio_bus_match(struct device *dev, void *mdio_bus_np) -+{ -+ return dev->of_node == mdio_bus_np; -+} -+/** -+ * of_mdio_find_bus - Given an mii_bus node, find the mii_bus. -+ * @mdio_np: Pointer to the mii_bus. -+ * -+ * Returns a pointer to the mii_bus, or NULL if none found. -+ * -+ * Because the association of a device_node and mii_bus is made via -+ * of_mdiobus_register(), the mii_bus cannot be found before it is -+ * registered with of_mdiobus_register(). -+ * -+ */ -+struct mii_bus *of_mdio_find_bus(struct device_node *mdio_bus_np) -+{ -+ struct device *d; -+ -+ if (!mdio_bus_np) -+ return NULL; -+ -+ d = class_find_device(&mdio_bus_class, NULL, mdio_bus_np, -+ of_mdio_bus_match); -+ -+ return d ? to_mii_bus(d) : NULL; -+} -+EXPORT_SYMBOL(of_mdio_find_bus); -+#endif -+ - /** - * mdiobus_register - bring up all the PHYs on a given bus and attach them to bus - * @bus: target mii_bus -@@ -208,14 +240,14 @@ EXPORT_SYMBOL(mdiobus_scan); - * because the bus read/write functions may wait for an interrupt - * to conclude the operation. - */ --int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum) -+int mdiobus_read(struct mii_bus *bus, int addr, int devad, u16 regnum) - { - int retval; - - BUG_ON(in_interrupt()); - - mutex_lock(&bus->mdio_lock); -- retval = bus->read(bus, addr, regnum); -+ retval = bus->read(bus, addr, devad, regnum); - mutex_unlock(&bus->mdio_lock); - - return retval; -@@ -233,14 +265,14 @@ EXPORT_SYMBOL(mdiobus_read); - * because the bus read/write functions may wait for an interrupt - * to conclude the operation. - */ --int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val) -+int mdiobus_write(struct mii_bus *bus, int addr, int devad, u16 regnum, u16 val) - { - int err; - - BUG_ON(in_interrupt()); - - mutex_lock(&bus->mdio_lock); -- err = bus->write(bus, addr, regnum, val); -+ err = bus->write(bus, addr, devad, regnum, val); - mutex_unlock(&bus->mdio_lock); - - return err; -diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c -index 3cbda08..0825a78 100644 ---- a/drivers/net/phy/phy.c -+++ b/drivers/net/phy/phy.c -@@ -6,7 +6,7 @@ - * - * Author: Andy Fleming - * -- * Copyright (c) 2004 Freescale Semiconductor, Inc. -+ * Copyright (c) 2004,2011 Freescale Semiconductor, Inc. - * Copyright (c) 2006, 2007 Maciej W. Rozycki - * - * This program is free software; you can redistribute it and/or modify it -@@ -322,7 +322,7 @@ int phy_mii_ioctl(struct phy_device *phydev, - - case SIOCGMIIREG: - mii_data->val_out = mdiobus_read(phydev->bus, mii_data->phy_id, -- mii_data->reg_num); -+ 0, mii_data->reg_num); - break; - - case SIOCSMIIREG: -@@ -353,7 +353,7 @@ int phy_mii_ioctl(struct phy_device *phydev, - } - } - -- mdiobus_write(phydev->bus, mii_data->phy_id, -+ mdiobus_write(phydev->bus, mii_data->phy_id, 0, - mii_data->reg_num, val); - - if (mii_data->reg_num == MII_BMCR && -@@ -479,6 +479,10 @@ static void phy_force_reduction(struct phy_device *phydev) - - idx = phy_find_valid(idx, phydev->supported); - -+ /* Avoid reaching an invalid speed and duplex combination */ -+ if (!(settings[idx].setting & phydev->supported)) -+ return; -+ - phydev->speed = settings[idx].speed; - phydev->duplex = settings[idx].duplex; - -@@ -869,6 +873,8 @@ void phy_state_machine(struct work_struct *work) - if (0 == phydev->link_timeout--) { - phy_force_reduction(phydev); - needs_aneg = 1; -+ phydev->link_timeout = -+ PHY_FORCE_TIMEOUT; - } - } - -diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c -index 83a5a5a..e88f49a 100644 ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -6,7 +6,7 @@ - * - * Author: Andy Fleming - * -- * Copyright (c) 2004 Freescale Semiconductor, Inc. -+ * Copyright (c) 2004-2006, 2008-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 -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -51,15 +52,13 @@ static void phy_device_release(struct device *dev) - } - - static struct phy_driver genphy_driver; -+static struct phy_driver gen10g_driver; - extern int mdio_bus_init(void); - extern void mdio_bus_exit(void); - - static LIST_HEAD(phy_fixup_list); - static DEFINE_MUTEX(phy_fixup_lock); - --static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, -- u32 flags, phy_interface_t interface); -- - /* - * Creates a new phy_fixup and adds it to the list - * @bus_id: A string which matches phydev->dev.bus_id (or PHY_ANY_ID) -@@ -210,23 +209,29 @@ static struct phy_device* phy_device_create(struct mii_bus *bus, - int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id) - { - int phy_reg; -+ int i; -+ -+ for (i = 1; i < 5; i++) { -+ /* Grab the bits from PHYIR1, and put them -+ * in the upper half */ -+ phy_reg = bus->read(bus, addr, i, MII_PHYSID1); - -- /* Grab the bits from PHYIR1, and put them -- * in the upper half */ -- phy_reg = mdiobus_read(bus, addr, MII_PHYSID1); -+ if (phy_reg < 0) -+ return -EIO; - -- if (phy_reg < 0) -- return -EIO; -+ *phy_id = (phy_reg & 0xffff) << 16; - -- *phy_id = (phy_reg & 0xffff) << 16; -+ /* Grab the bits from PHYIR2, and put them in the lower half */ -+ phy_reg = bus->read(bus, addr, i, MII_PHYSID2); - -- /* Grab the bits from PHYIR2, and put them in the lower half */ -- phy_reg = mdiobus_read(bus, addr, MII_PHYSID2); -+ if (phy_reg < 0) -+ return -EIO; - -- if (phy_reg < 0) -- return -EIO; -+ *phy_id |= (phy_reg & 0xffff); - -- *phy_id |= (phy_reg & 0xffff); -+ if (*phy_id != 0xffffffff) -+ break; -+ } - - return 0; - } -@@ -433,12 +438,12 @@ int phy_init_hw(struct phy_device *phydev) - * - * Description: Called by drivers to attach to a particular PHY - * device. The phy_device is found, and properly hooked up -- * to the phy_driver. If no driver is attached, then the -- * genphy_driver is used. The phy_device is given a ptr to -+ * to the phy_driver. If no driver is attached, then a -+ * generic driver is used. The phy_device is given a ptr to - * the attaching device, and given a callback for link status - * change. The phy_device is returned to the attaching driver. - */ --static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, -+int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, - u32 flags, phy_interface_t interface) - { - struct device *d = &phydev->dev; -@@ -447,7 +452,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, - /* Assume that if there is no driver, that it doesn't - * exist, and we should use the genphy driver. */ - if (NULL == d->driver) { -- d->driver = &genphy_driver.driver; -+ int err; -+ if (interface == PHY_INTERFACE_MODE_XGMII) -+ d->driver = &gen10g_driver.driver; -+ else -+ d->driver = &genphy_driver.driver; - - err = d->driver->probe(d); - if (err >= 0) -@@ -531,6 +540,8 @@ void phy_detach(struct phy_device *phydev) - * real driver could be loaded */ - if (phydev->dev.driver == &genphy_driver.driver) - device_release_driver(&phydev->dev); -+ else if (phydev->dev.driver == &gen10g_driver.driver) -+ device_release_driver(&phydev->dev); - } - EXPORT_SYMBOL(phy_detach); - -@@ -612,6 +623,12 @@ static int genphy_config_advert(struct phy_device *phydev) - return changed; - } - -+int gen10g_config_advert(struct phy_device *dev) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(gen10g_config_advert); -+ - /** - * genphy_setup_forced - configures/forces speed/duplex from @phydev - * @phydev: target phy_device struct -@@ -620,7 +637,7 @@ static int genphy_config_advert(struct phy_device *phydev) - * to the values in phydev. Assumes that the values are valid. - * Please see phy_sanitize_settings(). - */ --static int genphy_setup_forced(struct phy_device *phydev) -+int genphy_setup_forced(struct phy_device *phydev) - { - int err; - int ctl = 0; -@@ -639,7 +656,12 @@ static int genphy_setup_forced(struct phy_device *phydev) - - return err; - } -+EXPORT_SYMBOL(genphy_setup_forced); - -+int gen10g_setup_forced(struct phy_device *phydev) -+{ -+ return 0; -+} - - /** - * genphy_restart_aneg - Enable and Restart Autonegotiation -@@ -665,6 +687,12 @@ int genphy_restart_aneg(struct phy_device *phydev) - } - EXPORT_SYMBOL(genphy_restart_aneg); - -+int gen10g_restart_aneg(struct phy_device *phydev) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(gen10g_restart_aneg); -+ - - /** - * genphy_config_aneg - restart auto-negotiation or write BMCR -@@ -707,6 +735,12 @@ int genphy_config_aneg(struct phy_device *phydev) - } - EXPORT_SYMBOL(genphy_config_aneg); - -+int gen10g_config_aneg(struct phy_device *phydev) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(gen10g_config_aneg); -+ - /** - * genphy_update_link - update link status in @phydev - * @phydev: target phy_device struct -@@ -790,6 +824,16 @@ int genphy_read_status(struct phy_device *phydev) - - lpa &= adv; - -+ err = phy_read(phydev, MII_BMSR); -+ -+ if (err < 0) -+ return err; -+ -+ /* if the link changed while reading speed and duplex -+ * abort the speed and duplex update */ -+ if (((err & BMSR_LSTATUS) == 0) != (phydev->link == 0)) -+ return 0; -+ - phydev->speed = SPEED_10; - phydev->duplex = DUPLEX_HALF; - phydev->pause = phydev->asym_pause = 0; -@@ -836,6 +880,33 @@ int genphy_read_status(struct phy_device *phydev) - } - EXPORT_SYMBOL(genphy_read_status); - -+int gen10g_read_status(struct phy_device *phydev) -+{ -+ int devad, reg; -+ u32 mmd_mask = phydev->mmds; -+ -+ phydev->link = 1; -+ -+ /* For now just lie and say it's 10G all the time */ -+ phydev->speed = 10000; -+ phydev->duplex = DUPLEX_FULL; -+ -+ for (devad = 0; mmd_mask; devad++, mmd_mask = mmd_mask >> 1) { -+ if (!mmd_mask & 1) -+ continue; -+ -+ /* Read twice because link state is latched and a -+ * read moves the current state into the register */ -+ phy45_read(phydev, devad, MDIO_STAT1); -+ reg = phy45_read(phydev, devad, MDIO_STAT1); -+ if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS)) -+ phydev->link = 0; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(gen10g_read_status); -+ - static int genphy_config_init(struct phy_device *phydev) - { - int val; -@@ -882,6 +953,36 @@ static int genphy_config_init(struct phy_device *phydev) - - return 0; - } -+ -+/* Replicate mdio45_probe */ -+int gen10g_config_init(struct phy_device *phydev) -+{ -+ int mmd, stat2, devs1, devs2; -+ -+ phydev->supported = phydev->advertising = SUPPORTED_10000baseT_Full; -+ -+ /* Assume PHY must have at least one of PMA/PMD, WIS, PCS, PHY -+ * XS or DTE XS; give up if none is present. */ -+ for (mmd = 1; mmd <= 5; mmd++) { -+ /* Is this MMD present? */ -+ stat2 = phy45_read(phydev, mmd, MDIO_STAT2); -+ if (stat2 < 0 || -+ (stat2 & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL) -+ continue; -+ -+ /* It should tell us about all the other MMDs */ -+ devs1 = phy45_read(phydev, mmd, MDIO_DEVS1); -+ devs2 = phy45_read(phydev, mmd, MDIO_DEVS2); -+ if (devs1 < 0 || devs2 < 0) -+ continue; -+ -+ phydev->mmds = devs1 | (devs2 << 16); -+ return 0; -+ } -+ -+ return -ENODEV; -+} -+ - int genphy_suspend(struct phy_device *phydev) - { - int value; -@@ -897,6 +998,12 @@ int genphy_suspend(struct phy_device *phydev) - } - EXPORT_SYMBOL(genphy_suspend); - -+int gen10g_suspend(struct phy_device *phydev) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(gen10g_suspend); -+ - int genphy_resume(struct phy_device *phydev) - { - int value; -@@ -912,6 +1019,13 @@ int genphy_resume(struct phy_device *phydev) - } - EXPORT_SYMBOL(genphy_resume); - -+int gen10g_resume(struct phy_device *phydev) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(gen10g_resume); -+ -+ - /** - * phy_probe - probe and init a PHY device - * @dev: device to probe and init -@@ -1022,7 +1136,20 @@ static struct phy_driver genphy_driver = { - .read_status = genphy_read_status, - .suspend = genphy_suspend, - .resume = genphy_resume, -- .driver = {.owner= THIS_MODULE, }, -+ .driver = {.owner = THIS_MODULE, }, -+}; -+ -+static struct phy_driver gen10g_driver = { -+ .phy_id = 0xffffffff, -+ .phy_id_mask = 0xffffffff, -+ .name = "Generic 10G PHY", -+ .config_init = gen10g_config_init, -+ .features = 0, -+ .config_aneg = gen10g_config_aneg, -+ .read_status = gen10g_read_status, -+ .suspend = gen10g_suspend, -+ .resume = gen10g_resume, -+ .driver = {.owner = THIS_MODULE, }, - }; - - static int __init phy_init(void) -@@ -1035,13 +1162,25 @@ static int __init phy_init(void) - - rc = phy_driver_register(&genphy_driver); - if (rc) -- mdio_bus_exit(); -+ goto genphy_register_failed; -+ -+ rc = phy_driver_register(&gen10g_driver); -+ if (rc) -+ goto gen10g_register_failed; -+ -+ return rc; -+ -+gen10g_register_failed: -+ phy_driver_unregister(&genphy_driver); -+genphy_register_failed: -+ mdio_bus_exit(); - - return rc; - } - - static void __exit phy_exit(void) - { -+ phy_driver_unregister(&gen10g_driver); - phy_driver_unregister(&genphy_driver); - mdio_bus_exit(); - } -diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c -index 980c079..5f3f65a 100644 ---- a/drivers/of/of_mdio.c -+++ b/drivers/of/of_mdio.c -@@ -45,6 +45,8 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) - for (i=0; iirq[i] = PHY_POLL; - -+ mdio->dev.of_node = np; -+ - /* Register the MDIO bus */ - rc = mdiobus_register(mdio); - if (rc) -@@ -77,12 +79,16 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) - mdio->irq[addr] = PHY_POLL; - } - -+ mdio->is_c45 = of_device_is_compatible(child, -+ "ethernet-phy-ieee802.3-c45"); -+ - phy = get_phy_device(mdio, addr); - if (!phy || IS_ERR(phy)) { - dev_err(&mdio->dev, "error probing PHY at address %i\n", - addr); - continue; - } -+ phy_scan_fixups(phy); - - /* Associate the OF node with the device structure so it - * can be looked up later */ -@@ -188,3 +194,17 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, - return IS_ERR(phy) ? NULL : phy; - } - EXPORT_SYMBOL(of_phy_connect_fixed_link); -+ -+/* XXX add comment */ -+struct phy_device *of_phy_attach(struct net_device *dev, -+ struct device_node *phy_np, u32 flags, -+ phy_interface_t iface) -+{ -+ struct phy_device *phy = of_phy_find_device(phy_np); -+ -+ if (!phy) -+ return NULL; -+ -+ return phy_attach_direct(dev, phy, flags, iface) ? NULL : phy; -+} -+EXPORT_SYMBOL(of_phy_attach); -diff --git a/drivers/of/platform.c b/drivers/of/platform.c -index 63b3ec4..fb3762c 100644 ---- a/drivers/of/platform.c -+++ b/drivers/of/platform.c -@@ -139,6 +139,18 @@ struct platform_device *of_device_alloc(struct device_node *np, - if (!dev) - return NULL; - -+ dev->dev.of_node = of_node_get(np); -+ if (bus_id) -+ dev_set_name(&dev->dev, "%s", bus_id); -+ else -+ of_device_make_bus_id(&dev->dev); -+ -+ if (kset_find_obj(dev->dev.kobj.kset, kobject_name(&dev->dev.kobj))) { -+ kfree(dev); -+ of_node_put(np); -+ return NULL; -+ } -+ - /* count the io and irq resources */ - while (of_address_to_resource(np, num_reg, &temp_res) == 0) - num_reg++; -@@ -161,17 +173,11 @@ struct platform_device *of_device_alloc(struct device_node *np, - WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq); - } - -- dev->dev.of_node = of_node_get(np); - #if defined(CONFIG_MICROBLAZE) - dev->dev.dma_mask = &dev->archdata.dma_mask; - #endif - dev->dev.parent = parent; - -- if (bus_id) -- dev_set_name(&dev->dev, "%s", bus_id); -- else -- of_device_make_bus_id(&dev->dev); -- - return dev; - } - EXPORT_SYMBOL(of_device_alloc); -diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig -index f96beaa..632fa9d 100644 ---- a/drivers/staging/Kconfig -+++ b/drivers/staging/Kconfig -@@ -128,4 +128,10 @@ source "drivers/staging/nvec/Kconfig" - - source "drivers/staging/media/Kconfig" - -+source "drivers/staging/fsl_qbman/Kconfig" -+ -+source "drivers/staging/fsl_pme2/Kconfig" -+ -+source "drivers/staging/fsl_rman/Kconfig" -+ - endif # STAGING -diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile -index 8f57e12..c19d40c 100644 ---- a/drivers/staging/Makefile -+++ b/drivers/staging/Makefile -@@ -55,3 +55,6 @@ obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ - obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ - obj-$(CONFIG_INTEL_MEI) += mei/ - obj-$(CONFIG_MFD_NVEC) += nvec/ -+obj-$(CONFIG_FSL_DPA) += fsl_qbman/ -+obj-$(CONFIG_FSL_PME2) += fsl_pme2/ -+obj-$(CONFIG_FSL_RMAN_UIO) += fsl_rman/ -diff --git a/drivers/staging/fsl_pme2/Kconfig b/drivers/staging/fsl_pme2/Kconfig -new file mode 100644 -index 0000000..58c5f2d ---- /dev/null -+++ b/drivers/staging/fsl_pme2/Kconfig -@@ -0,0 +1,226 @@ -+config FSL_PME2 -+ bool "Freescale Datapath Pattern Matcher support" -+ depends on FSL_QMAN -+ -+menu "Freescale Datapath PME options" -+ depends on FSL_PME2 -+ -+config FSL_PME2_CTRL -+ bool "Freescale PME2 (p4080, etc) device control" -+ default y -+ ---help--- -+ This compiles device support for the Freescale PME2 pattern matching -+ part contained in datapath-enabled SoCs (ie. accessed via Qman and -+ Bman portal functionality). At least one guest operating system must -+ have this driver support, together with the appropriate device-tree -+ entry, for PME2 functionality to be available. It is responsible for -+ allocating system memory to the device and configuring it for -+ operation. For this reason, it must be built into the kernel and will -+ initialise during early kernel boot. -+ -+config FSL_PME2_PDSRSIZE -+ int "Pattern Description and Stateful Rule default table size" -+ depends on FSL_PME2_CTRL -+ range 74240 1048573 -+ default 131072 -+ help -+ Select the default size of the Pattern Description and Stateful Rule -+ table as the number of 128 byte entries. This only takes effect if -+ the device tree node doesn't have the 'fsl,pme-pdsr' property. -+ range 74240-1048573 (9.5MB-134MB) -+ default 131072 (16MB) -+ -+if FSL_PME2_CTRL -+comment "Statefule Rule Engine" -+endif -+ -+config FSL_PME2_SRESIZE -+ int "SRE Session Context Entries table default table size" -+ depends on FSL_PME2_CTRL -+ range 0 134217727 -+ default 327680 -+ help -+ Select the default size of the SRE Context Table as the number of 32 -+ byte entries. This only takes effect if the device tree node doesn't -+ have the 'fsl,pme-sre' property. -+ range 0-134217727 (0-4GB) -+ default 327680 (10MB) -+ -+config FSL_PME2_SRE_AIM -+ bool "Alternate Inconclusive Mode" -+ depends on FSL_PME2_CTRL -+ default n -+ help -+ Select the inconclusive match mode treatment. When true the -+ “alternate” inconclusive mode is used. When false the “default” -+ inconclusive mode is used. -+ -+config FSL_PME2_SRE_ESR -+ bool "End of SUI Simple Report" -+ depends on FSL_PME2_CTRL -+ default n -+ help -+ Select if an End of SUI will produce a Simple End of SUI report. -+ -+config FSL_PME2_SRE_CTX_SIZE_PER_SESSION -+ int "Default SRE Context Size per Session (16 => 64KB, 17 => 128KB)" -+ depends on FSL_PME2_CTRL -+ range 5 17 -+ default 17 -+ help -+ Select SRE context size per session as a power of 2. -+ range 5-17 -+ Examples: -+ 5 => 32 B -+ 6 => 64 B -+ 7 => 128 B -+ 8 => 256 B -+ 9 => 512 B -+ 10 => 1 KB -+ 11 => 2 KB -+ 12 => 4 KB -+ 13 => 8 KB -+ 14 => 16 KB -+ 15 => 32 KB -+ 16 => 64 KB -+ 17 => 128 KB -+ -+config FSL_PME2_SRE_CNR -+ int "Configured Number of Stateful Rules as a multiple of 256 (128 => 32768 )" -+ depends on FSL_PME2_CTRL -+ range 0 128 -+ default 128 -+ help -+ Select number of stateful rules as a multiple of 256. -+ range 0-128 -+ Examples: -+ 0 => 0 -+ 1 => 256 -+ 2 => 512 -+ ... -+ 127 => 32512 -+ 128 => 32768 -+ -+config FSL_PME2_SRE_MAX_INSTRUCTION_LIMIT -+ int "Maximum number of SRE instructions to be executed per reaction." -+ depends on FSL_PME2_CTRL -+ range 0 65535 -+ default 65535 -+ help -+ Select the maximum number of SRE instructions to be executed per -+ reaction. -+ range 0 65535 -+ -+config FSL_PME2_SRE_MAX_BLOCK_NUMBER -+ int "Maximum number of Reaction Head blocks to be traversed per pattern match event" -+ depends on FSL_PME2_CTRL -+ range 0 32767 -+ default 32767 -+ help -+ Select the maximum number of reaction head blocks to be traversed per -+ pattern match event (e.g. a matched pattern or an End of SUI event). -+ range 0-32767 -+ -+config FSL_PME2_PORTAL -+ tristate "Freescale PME2 (p4080, etc) device usage" -+ default y -+ ---help--- -+ This compiles I/O support for the Freescale PME2 pattern matching -+ part contained in datapath-enabled SoCs (ie. accessed via Qman and -+ Bman portal functionality). -+ -+if FSL_PME2_PORTAL -+ -+config FSL_PME2_TEST_HIGH -+ tristate "PME2 high-level self-test" -+ default n -+ ---help--- -+ This uses the high-level Qman driver (and the cpu-affine portals it -+ manages) to perform high-level PME2 API testing with it. -+ -+config FSL_PME2_TEST_SCAN -+ tristate "PME2 scan self-test" -+ depends on FSL_PME2_CTRL -+ default n -+ ---help--- -+ This uses the high-level Qman driver (and the cpu-affine portals it -+ manages) to perform scan PME2 API testing with it. -+ -+config FSL_PME2_TEST_SCAN_WITH_BPID -+ bool "PME2 scan self-test with buffer pool" -+ depends on FSL_PME2_TEST_SCAN && FSL_BMAN -+ default y -+ ---help--- -+ This uses a buffer pool id for scan test -+ -+config FSL_PME2_TEST_SCAN_WITH_BPID_SIZE -+ int "Buffer Pool size." -+ depends on FSL_PME2_TEST_SCAN_WITH_BPID -+ range 0 11 -+ default 3 -+ ---help--- -+ This uses the specified buffer pool size. -+ -+config FSL_PME2_DB -+ tristate "PME2 Database support" -+ depends on FSL_PME2_CTRL -+ default y -+ ---help--- -+ This compiles the database driver for PME2. -+ -+config FSL_PME2_DB_QOSOUT_PRIORITY -+ int "PME DB output frame queue priority." -+ depends on FSL_PME2_DB -+ range 0 7 -+ default 2 -+ ---help--- -+ The PME DB has a scheduled output frame queue. The qos priority level is configurable. -+ range 0-7 -+ 0 => High Priority 0 -+ 1 => High Priority 1 -+ 2 => Medium Priority -+ 3 => Medium Priority -+ 4 => Medium Priority -+ 5 => Low Priority -+ 6 => Low Priority -+ 7 => Low Priority -+ -+config FSL_PME2_SCAN -+ tristate "PME2 Scan support" -+ default y -+ ---help--- -+ This compiles the scan driver for PME2. -+ -+config FSL_PME2_SCAN_DEBUG -+ bool "Debug Statements" -+ default n -+ depends on FSL_PME2_SCAN -+ ---help--- -+ The PME2_SCAN driver can optionally trace with more verbosity -+ of verbosity. -+ -+config FSL_PME_BUG_4K_SCAN_REV_2_1_4 -+ bool "workaround for errata in PME version 2.1.4" -+ default y -+ ---help--- -+ If this option is selected, the driver will be compiled with a -+ workaround for this errata. This prevents scans of SUIs greater -+ than 4095 - 127 bytes when this revision of HW is detected. -+ -+ If in doubt, say Y. -+ -+ -+endif -+ -+config FSL_PME2_STAT_ACCUMULATOR_UPDATE_INTERVAL -+ int "Configure the pme2 statistics update interval in milliseconds" -+ depends on FSL_PME2_CTRL -+ range 0 10000 -+ default 3400 -+ help -+ The pme accumulator reads the current device statistics and add it -+ to a running counter. The frequency of these updates may be -+ controlled. If 0 is specified, no automatic updates is done. -+ range 0-10000 -+ -+endmenu -diff --git a/drivers/staging/fsl_pme2/Makefile b/drivers/staging/fsl_pme2/Makefile -new file mode 100644 -index 0000000..694513b ---- /dev/null -+++ b/drivers/staging/fsl_pme2/Makefile -@@ -0,0 +1,9 @@ -+# PME -+obj-$(CONFIG_FSL_PME2_CTRL) += pme2_ctrl.o pme2_sysfs.o -+obj-$(CONFIG_FSL_PME2_PORTAL) += pme2.o -+pme2-y := pme2_low.o pme2_high.o -+obj-$(CONFIG_FSL_PME2_TEST_HIGH) += pme2_test_high.o -+obj-$(CONFIG_FSL_PME2_TEST_SCAN) += pme2_test_scanning.o -+pme2_test_scanning-y = pme2_test_scan.o pme2_sample_db.o -+obj-$(CONFIG_FSL_PME2_DB) += pme2_db.o -+obj-$(CONFIG_FSL_PME2_SCAN) += pme2_scan.o -diff --git a/drivers/staging/fsl_pme2/pme2_ctrl.c b/drivers/staging/fsl_pme2/pme2_ctrl.c -new file mode 100644 -index 0000000..4022c72 ---- /dev/null -+++ b/drivers/staging/fsl_pme2/pme2_ctrl.c -@@ -0,0 +1,1331 @@ -+/* 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 "pme2_private.h" -+#include "pme2_regs.h" -+ -+/* PME HW Revision */ -+#define PME_REV(rev1_reg) (rev1_reg & 0x0000FFFF) -+#define PME_REV_2_0 0x00000200 -+#define PME_REV_2_1 0x00000201 -+#define DEC1_MAX_REV_2_0 0x000FFFFC -+#define DEC1_MAX_REV_2_1 0x0007FFFC -+ -+ -+/* Driver Name is used in naming the sysfs directory -+ * /sys/bus/of_platform/drivers/DRV_NAME -+ */ -+#define DRV_NAME "fsl-pme" -+ -+#define DEFAULT_PDSR_SZ (CONFIG_FSL_PME2_PDSRSIZE << 7) -+#define DEFAULT_SRE_SZ (CONFIG_FSL_PME2_SRESIZE << 5) -+#define PDSR_TBL_ALIGN (1 << 7) -+#define SRE_TBL_ALIGN (1 << 5) -+#define DEFAULT_SRFCC 400 -+ -+/* Defaults */ -+#define DEFAULT_DEC0_MTE 0x3FFF -+#define DEFAULT_DLC_MPM 0xFFFF -+#define DEFAULT_DLC_MPE 0xFFFF -+/* Boot parameters */ -+DECLARE_GLOBAL(max_test_line_per_pat, unsigned int, uint, -+ DEFAULT_DEC0_MTE, -+ "Maximum allowed Test Line Executions per pattern, " -+ "scaled by a factor of 8"); -+DECLARE_GLOBAL(max_pat_eval_per_sui, unsigned int, uint, -+ DEFAULT_DLC_MPE, -+ "Maximum Pattern Evaluations per SUI, scaled by a factor of 8") -+DECLARE_GLOBAL(max_pat_matches_per_sui, unsigned int, uint, -+ DEFAULT_DLC_MPM, -+ "Maximum Pattern Matches per SUI"); -+/* SRE */ -+DECLARE_GLOBAL(sre_rule_num, unsigned int, uint, -+ CONFIG_FSL_PME2_SRE_CNR, -+ "Configured Number of Stateful Rules"); -+DECLARE_GLOBAL(sre_session_ctx_size, unsigned int, uint, -+ 1 << CONFIG_FSL_PME2_SRE_CTX_SIZE_PER_SESSION, -+ "SRE Context Size per Session"); -+ -+/************ -+ * Section 1 -+ ************ -+ * This code is called during kernel early-boot and could never be made -+ * loadable. -+ */ -+static dma_addr_t dxe_a, sre_a; -+static size_t dxe_sz = DEFAULT_PDSR_SZ, sre_sz = DEFAULT_SRE_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. */ -+static __init int parse_mem_property(struct device_node *node, const char *name, -+ dma_addr_t *addr, size_t *sz, u64 align, int zero) -+{ -+ const u32 *pint; -+ int ret; -+ -+ pint = of_get_property(node, name, &ret); -+ if (!pint || (ret != 16)) { -+ pr_info("pme: No %s property '%s', using memblock_alloc(0x%016zx)\n", -+ node->full_name, name, *sz); -+ *addr = memblock_alloc(*sz, align); -+ if (zero) -+ memset(phys_to_virt(*addr), 0, *sz); -+ return 0; -+ } -+ pr_info("pme: Using %s property '%s'\n", node->full_name, name); -+ /* 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; -+ } -+ *addr = ((u64)pint[0] << 32) | (u64)pint[1]; -+ *sz = ((u64)pint[2] << 32) | (u64)pint[3]; -+ if((u64)*addr & (align - 1)) { -+ pr_err("pme: Invalid alignment, address %016llx\n",(u64)*addr); -+ return -EINVAL; -+ } -+ /* Keep things simple, it's either all in the DRAM range or it's all -+ * outside. */ -+ if (*addr < memblock_end_of_DRAM()) { -+ if ((u64)*addr + (u64)*sz > memblock_end_of_DRAM()){ -+ pr_err("pme: outside DRAM range\n"); -+ return -EINVAL; -+ } -+ if (memblock_reserve(*addr, *sz) < 0) { -+ pr_err("pme: Failed to reserve %s\n", name); -+ return -ENOMEM; -+ } -+ if (zero) -+ memset(phys_to_virt(*addr), 0, *sz); -+ } else if (zero) { -+ /* map as cacheable, non-guarded */ -+ void *tmpp = ioremap_prot(*addr, *sz, 0); -+ memset(tmpp, 0, *sz); -+ iounmap(tmpp); -+ } -+ return 0; -+} -+ -+/* No errors/interrupts. Physical addresses are assumed <= 32bits. */ -+static int __init fsl_pme2_init(struct device_node *node) -+{ -+ const char *s; -+ int ret = 0; -+ -+ s = of_get_property(node, "fsl,hv-claimable", &ret); -+ if (s && !strcmp(s, "standby")) { -+ pr_info(" -> in standby mode\n"); -+ return 0; -+ } -+ /* Check if pdsr memory already allocated */ -+ if (dxe_a) { -+ pr_err("pme: Error fsl_pme2_init already done\n"); -+ return -EINVAL; -+ } -+ ret = parse_mem_property(node, "fsl,pme-pdsr", &dxe_a, &dxe_sz, -+ PDSR_TBL_ALIGN, 0); -+ if (ret) -+ return ret; -+ ret = parse_mem_property(node, "fsl,pme-sre", &sre_a, &sre_sz, -+ SRE_TBL_ALIGN, 0); -+ return ret; -+} -+ -+__init void pme2_init_early(void) -+{ -+ struct device_node *dn; -+ int ret; -+ for_each_compatible_node(dn, NULL, "fsl,pme") { -+ ret = fsl_pme2_init(dn); -+ if (ret) -+ pr_err("pme: Error fsl_pme2_init\n"); -+ } -+} -+ -+/************ -+ * Section 2 -+ *********** -+ * This code is called during driver initialisation. It doesn't do anything with -+ * the device-tree entries nor the PME device, it simply creates the sysfs stuff -+ * and gives the user something to hold. This could be made loadable, if there -+ * was any benefit to doing so - but as the device is already "bound" by static -+ * code, there's little point to hiding the fact. -+ */ -+ -+MODULE_AUTHOR("Geoff Thorpe"); -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("FSL PME2 (p4080) device control"); -+ -+/* Opaque pointer target used to represent the PME CCSR map, ... */ -+struct pme; -+ -+/* ... and the instance of it. */ -+static struct pme *global_pme; -+static int pme_err_irq; -+ -+static inline void __pme_out(struct pme *p, u32 offset, u32 val) -+{ -+ u32 __iomem *regs = (void *)p; -+ out_be32(regs + (offset >> 2), val); -+} -+#define pme_out(p, r, v) __pme_out(p, PME_REG_##r, v) -+static inline u32 __pme_in(struct pme *p, u32 offset) -+{ -+ u32 __iomem *regs = (void *)p; -+ return in_be32(regs + (offset >> 2)); -+} -+#define pme_in(p, r) __pme_in(p, PME_REG_##r) -+ -+#define PME_EFQC(en, fq) \ -+ ({ \ -+ /* Assume a default delay of 64 cycles */ \ -+ u8 __i419 = 0x1; \ -+ u32 __fq419 = (fq) & 0x00ffffff; \ -+ ((en) ? 0x80000000 : 0) | (__i419 << 28) | __fq419; \ -+ }) -+ -+#define PME_FACONF_ENABLE 0x00000002 -+#define PME_FACONF_RESET 0x00000001 -+ -+/* pme stats accumulator work */ -+static void accumulator_update(struct work_struct *work); -+void accumulator_update_interval(u32 interval); -+static DECLARE_DELAYED_WORK(accumulator_work, accumulator_update); -+u32 pme_stat_interval = CONFIG_FSL_PME2_STAT_ACCUMULATOR_UPDATE_INTERVAL; -+#define PME_SBE_ERR 0x01000000 -+#define PME_DBE_ERR 0x00080000 -+#define PME_PME_ERR 0x00000100 -+#define PME_ALL_ERR (PME_SBE_ERR | PME_DBE_ERR | PME_PME_ERR) -+ -+static struct of_device_id of_fsl_pme_ids[] = { -+ { -+ .compatible = "fsl,pme", -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, of_fsl_pme_ids); -+ -+/* Pme interrupt handler */ -+static irqreturn_t pme_isr(int irq, void *ptr) -+{ -+ static u32 last_isrstate; -+ u32 isrstate = pme_in(global_pme, ISR) ^ last_isrstate; -+ -+ /* What new ISR state has been raise */ -+ if (!isrstate) -+ return IRQ_NONE; -+ if (isrstate & PME_SBE_ERR) -+ pr_crit("PME: SBE detected\n"); -+ if (isrstate & PME_DBE_ERR) -+ pr_crit("PME: DBE detected\n"); -+ if (isrstate & PME_PME_ERR) -+ pr_crit("PME: PME serious detected\n"); -+ /* Clear the ier interrupt bit */ -+ last_isrstate |= isrstate; -+ pme_out(global_pme, IER, ~last_isrstate); -+ return IRQ_HANDLED; -+} -+ -+static int of_fsl_pme_remove(struct platform_device *ofdev) -+{ -+ /* Cancel pme accumulator */ -+ accumulator_update_interval(0); -+ cancel_delayed_work_sync(&accumulator_work); -+ /* Disable PME..TODO need to wait till it's quiet */ -+ pme_out(global_pme, FACONF, PME_FACONF_RESET); -+ /* Release interrupt */ -+ if (likely(pme_err_irq != NO_IRQ)) -+ free_irq(pme_err_irq, &ofdev->dev); -+ /* Remove sysfs attribute */ -+ pme2_remove_sysfs_dev_files(ofdev); -+ /* Unmap controller region */ -+ iounmap(global_pme); -+ global_pme = NULL; -+ return 0; -+} -+ -+static int __devinit of_fsl_pme_probe(struct platform_device *ofdev) -+{ -+ int ret, err = 0; -+ void __iomem *regs; -+ struct device *dev = &ofdev->dev; -+ struct device_node *nprop = dev->of_node; -+ u32 clkfreq = DEFAULT_SRFCC * 1000000; -+ const u32 *value; -+ const char *s; -+ int srec_aim = 0, srec_esr = 0; -+ u32 srecontextsize_code; -+ u32 dec1; -+ -+ /* TODO: This standby handling won't work properly after failover, it's -+ * just to allow bring up for now. */ -+ s = of_get_property(nprop, "fsl,hv-claimable", &ret); -+ if (s && !strcmp(s, "standby")) -+ return 0; -+ pme_err_irq = of_irq_to_resource(nprop, 0, NULL); -+ if (unlikely(pme_err_irq == NO_IRQ)) -+ dev_warn(dev, "Can't get %s property '%s'\n", nprop->full_name, -+ "interrupts"); -+ -+ /* Get configuration properties from device tree */ -+ /* First, get register page */ -+ regs = of_iomap(nprop, 0); -+ if (regs == NULL) { -+ dev_err(dev, "of_iomap() failed\n"); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ /* Global configuration, leave pme disabled */ -+ global_pme = (struct pme *)regs; -+ pme_out(global_pme, FACONF, 0); -+ pme_out(global_pme, EFQC, PME_EFQC(0, 0)); -+ -+ /* TODO: these coherency settings for PMFA, DXE, and SRE force all -+ * transactions to snoop, as the kernel does not yet support flushing in -+ * dma_map_***() APIs (ie. h/w can not treat otherwise coherent memory -+ * in a non-coherent manner, temporarily or otherwise). When the kernel -+ * supports this, we should tune these settings back to; -+ * FAMCR = 0x00010001 -+ * DMCR = 0x00000000 -+ * SMCR = 0x00000000 -+ */ -+ /* PME HW rev 2.1: Added TWC field in FAMCR */ -+ pme_out(global_pme, FAMCR, 0x11010101); -+ pme_out(global_pme, DMCR, 0x00000001); -+ pme_out(global_pme, SMCR, 0x00000211); -+ -+ if (likely(pme_err_irq != NO_IRQ)) { -+ /* Register the pme ISR handler */ -+ err = request_irq(pme_err_irq, pme_isr, IRQF_SHARED, "pme-err", -+ dev); -+ if (err) { -+ dev_err(dev, "request_irq() failed\n"); -+ goto out_unmap_ctrl_region; -+ } -+ } -+ -+#ifdef CONFIG_FSL_PME2_SRE_AIM -+ srec_aim = 1; -+#endif -+#ifdef CONFIG_FSL_PME2_SRE_ESR -+ srec_esr = 1; -+#endif -+ /* Validate some parameters */ -+ if (!sre_session_ctx_size || !is_power_of_2(sre_session_ctx_size) || -+ (sre_session_ctx_size < 32) || -+ (sre_session_ctx_size > (131072))) { -+ dev_err(dev, "invalid sre_session_ctx_size\n"); -+ err = -EINVAL; -+ goto out_free_irq; -+ } -+ srecontextsize_code = ilog2(sre_session_ctx_size); -+ srecontextsize_code -= 4; -+ -+ /* Configure Clock Frequency */ -+ value = of_get_property(nprop, "clock-frequency", NULL); -+ if (value) -+ clkfreq = *value; -+ pme_out(global_pme, SFRCC, DIV_ROUND_UP(clkfreq, 1000000)); -+ -+ pme_out(global_pme, PDSRBAH, upper_32_bits(dxe_a)); -+ pme_out(global_pme, PDSRBAL, lower_32_bits(dxe_a)); -+ pme_out(global_pme, SCBARH, upper_32_bits(sre_a)); -+ pme_out(global_pme, SCBARL, lower_32_bits(sre_a)); -+ /* Maximum allocated index into the PDSR table available to the DXE -+ * Rev 2.0: Max 0xF_FFFC -+ * Rev 2.1: Max 0x7_FFFC -+ */ -+ if (PME_REV(pme_in(global_pme, PM_IP_REV1)) == PME_REV_2_0) { -+ if (((dxe_sz/PDSR_TBL_ALIGN)-1) > DEC1_MAX_REV_2_0) -+ dec1 = DEC1_MAX_REV_2_0; -+ else -+ dec1 = (dxe_sz/PDSR_TBL_ALIGN)-1; -+ } else { -+ if (((dxe_sz/PDSR_TBL_ALIGN)-1) > DEC1_MAX_REV_2_1) -+ dec1 = DEC1_MAX_REV_2_1; -+ else -+ dec1 = (dxe_sz/PDSR_TBL_ALIGN)-1; -+ } -+ pme_out(global_pme, DEC1, dec1); -+ /* Maximum allocated index into the PDSR table available to the SRE */ -+ pme_out(global_pme, SEC2, dec1); -+ /* Maximum allocated 32-byte offset into SRE Context Table.*/ -+ if (sre_sz) -+ pme_out(global_pme, SEC3, (sre_sz/SRE_TBL_ALIGN)-1); -+ /* Max test line execution */ -+ pme_out(global_pme, DEC0, max_test_line_per_pat); -+ pme_out(global_pme, DLC, -+ (max_pat_eval_per_sui << 16) | max_pat_matches_per_sui); -+ -+ /* SREC - SRE Config */ -+ pme_out(global_pme, SREC, -+ /* Number of rules in database */ -+ (sre_rule_num << 0) | -+ /* Simple Report Enabled */ -+ ((srec_esr ? 1 : 0) << 18) | -+ /* Context Size per Session */ -+ (srecontextsize_code << 19) | -+ /* Alternate Inclusive Mode */ -+ ((srec_aim ? 1 : 0) << 29)); -+ pme_out(global_pme, SEC1, -+ (CONFIG_FSL_PME2_SRE_MAX_INSTRUCTION_LIMIT << 16) | -+ CONFIG_FSL_PME2_SRE_MAX_BLOCK_NUMBER); -+ -+ /* Setup Accumulator */ -+ if (pme_stat_interval) -+ schedule_delayed_work(&accumulator_work, -+ msecs_to_jiffies(pme_stat_interval)); -+ /* Create sysfs entries */ -+ err = pme2_create_sysfs_dev_files(ofdev); -+ if (err) -+ goto out_stop_accumulator; -+ -+ /* Enable interrupts */ -+ pme_out(global_pme, IER, PME_ALL_ERR); -+ dev_info(dev, "ver: 0x%08x\n", pme_in(global_pme, PM_IP_REV1)); -+ -+ /* Enable pme */ -+ pme_out(global_pme, FACONF, PME_FACONF_ENABLE); -+ return 0; -+ -+out_stop_accumulator: -+ if (pme_stat_interval) { -+ accumulator_update_interval(0); -+ cancel_delayed_work_sync(&accumulator_work); -+ } -+out_free_irq: -+ if (likely(pme_err_irq != NO_IRQ)) -+ free_irq(pme_err_irq, &ofdev->dev); -+out_unmap_ctrl_region: -+ pme_out(global_pme, FACONF, PME_FACONF_RESET); -+ iounmap(global_pme); -+ global_pme = NULL; -+out: -+ return err; -+} -+ -+static struct platform_driver of_fsl_pme_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = DRV_NAME, -+ .of_match_table = of_fsl_pme_ids, -+ }, -+ .probe = of_fsl_pme_probe, -+ .remove = __devexit_p(of_fsl_pme_remove), -+}; -+ -+static int pme2_ctrl_init(void) -+{ -+ return platform_driver_register(&of_fsl_pme_driver); -+} -+ -+static void pme2_ctrl_exit(void) -+{ -+ platform_driver_unregister(&of_fsl_pme_driver); -+} -+ -+module_init(pme2_ctrl_init); -+module_exit(pme2_ctrl_exit); -+ -+/************ -+ * Section 3 -+ ************ -+ * These APIs are the only functional hooks into the control driver, besides the -+ * sysfs attributes. -+ */ -+ -+int pme2_have_control(void) -+{ -+ return global_pme ? 1 : 0; -+} -+EXPORT_SYMBOL(pme2_have_control); -+ -+int pme2_exclusive_set(struct qman_fq *fq) -+{ -+ if (!pme2_have_control()) -+ return -ENODEV; -+ pme_out(global_pme, EFQC, PME_EFQC(1, qman_fq_fqid(fq))); -+ return 0; -+} -+EXPORT_SYMBOL(pme2_exclusive_set); -+ -+int pme2_exclusive_unset(void) -+{ -+ if (!pme2_have_control()) -+ return -ENODEV; -+ pme_out(global_pme, EFQC, PME_EFQC(0, 0)); -+ return 0; -+} -+EXPORT_SYMBOL(pme2_exclusive_unset); -+ -+int pme_attr_set(enum pme_attr attr, u32 val) -+{ -+ u32 mask; -+ u32 attr_val; -+ -+ if (!pme2_have_control()) -+ return -ENODEV; -+ -+ /* Check if Buffer size configuration */ -+ if (attr >= pme_attr_bsc_first && attr <= pme_attr_bsc_last) { -+ u32 bsc_pool_id = attr - pme_attr_bsc_first; -+ u32 bsc_pool_offset = bsc_pool_id % 8; -+ u32 bsc_pool_mask = ~(0xF << ((7-bsc_pool_offset)*4)); -+ /* range for val 0..0xB */ -+ if (val > 0xb) -+ return -EINVAL; -+ /* calculate which sky-blue reg */ -+ /* 0..7 -> bsc_(0..7), PME_REG_BSC0 */ -+ /* 8..15 -> bsc_(8..15) PME_REG_BSC1*/ -+ /* ... */ -+ /* 56..63 -> bsc_(56..63) PME_REG_BSC7*/ -+ attr_val = pme_in(global_pme, BSC0 + ((bsc_pool_id/8)*4)); -+ /* Now mask in the new value */ -+ attr_val = attr_val & bsc_pool_mask; -+ attr_val = attr_val | (val << ((7-bsc_pool_offset)*4)); -+ pme_out(global_pme, BSC0 + ((bsc_pool_id/8)*4), attr_val); -+ return 0; -+ } -+ -+ switch (attr) { -+ case pme_attr_efqc_int: -+ if (val > 4) -+ return -EINVAL; -+ mask = 0x8FFFFFFF; -+ attr_val = pme_in(global_pme, EFQC); -+ /* clear efqc_int */ -+ attr_val &= mask; -+ val <<= 28; -+ val |= attr_val; -+ pme_out(global_pme, EFQC, val); -+ break; -+ -+ case pme_attr_sw_db: -+ pme_out(global_pme, SWDB, val); -+ break; -+ -+ case pme_attr_dmcr: -+ pme_out(global_pme, DMCR, val); -+ break; -+ -+ case pme_attr_smcr: -+ pme_out(global_pme, SMCR, val); -+ break; -+ -+ case pme_attr_famcr: -+ pme_out(global_pme, FAMCR, val); -+ break; -+ -+ case pme_attr_kvlts: -+ if (val < 2 || val > 16) -+ return -EINVAL; -+ /* HW range: 1..15, SW range: 2..16 */ -+ pme_out(global_pme, KVLTS, --val); -+ break; -+ -+ case pme_attr_max_chain_length: -+ if (val > 0x7FFF) -+ val = 0x7FFF; -+ pme_out(global_pme, KEC, val); -+ break; -+ -+ case pme_attr_pattern_range_counter_idx: -+ if (val > 0x1FFFF) -+ val = 0x1FFFF; -+ pme_out(global_pme, DRCIC, val); -+ break; -+ -+ case pme_attr_pattern_range_counter_mask: -+ if (val > 0x1FFFF) -+ val = 0x1FFFF; -+ pme_out(global_pme, DRCMC, val); -+ break; -+ -+ case pme_attr_max_allowed_test_line_per_pattern: -+ if (val > 0x3FFF) -+ val = 0x3FFF; -+ pme_out(global_pme, DEC0, val); -+ break; -+ -+ case pme_attr_max_pattern_matches_per_sui: -+ /* mpe, mpm */ -+ if (val > 0xFFFF) -+ val = 0xFFFF; -+ mask = 0xFFFF0000; -+ attr_val = pme_in(global_pme, DLC); -+ /* clear mpm */ -+ attr_val &= mask; -+ val &= ~mask; -+ val |= attr_val; -+ pme_out(global_pme, DLC, val); -+ break; -+ -+ case pme_attr_max_pattern_evaluations_per_sui: -+ /* mpe, mpm */ -+ if (val > 0xFFFF) -+ val = 0xFFFF; -+ mask = 0x0000FFFF; -+ attr_val = pme_in(global_pme, DLC); -+ /* clear mpe */ -+ attr_val &= mask; -+ /* clear unwanted bits in val*/ -+ val &= mask; -+ val <<= 16; -+ val |= attr_val; -+ pme_out(global_pme, DLC, val); -+ break; -+ -+ case pme_attr_report_length_limit: -+ if (val > 0xFFFF) -+ val = 0xFFFF; -+ pme_out(global_pme, RLL, val); -+ break; -+ -+ case pme_attr_end_of_simple_sui_report: -+ /* bit 13 */ -+ mask = 0x00040000; -+ attr_val = pme_in(global_pme, SREC); -+ if (val) -+ attr_val |= mask; -+ else -+ attr_val &= ~mask; -+ pme_out(global_pme, SREC, attr_val); -+ break; -+ -+ case pme_attr_aim: -+ /* bit 2 */ -+ mask = 0x20000000; -+ attr_val = pme_in(global_pme, SREC); -+ if (val) -+ attr_val |= mask; -+ else -+ attr_val &= ~mask; -+ pme_out(global_pme, SREC, attr_val); -+ break; -+ -+ case pme_attr_end_of_sui_reaction_ptr: -+ if (val > 0xFFFFF) -+ val = 0xFFFFF; -+ pme_out(global_pme, ESRP, val); -+ break; -+ -+ case pme_attr_sre_pscl: -+ pme_out(global_pme, SFRCC, val); -+ break; -+ -+ case pme_attr_sre_max_block_num: -+ /* bits 17..31 */ -+ if (val > 0x7FFF) -+ val = 0x7FFF; -+ mask = 0xFFFF8000; -+ attr_val = pme_in(global_pme, SEC1); -+ /* clear mbn */ -+ attr_val &= mask; -+ /* clear unwanted bits in val*/ -+ val &= ~mask; -+ val |= attr_val; -+ pme_out(global_pme, SEC1, val); -+ break; -+ -+ case pme_attr_sre_max_instruction_limit: -+ /* bits 0..15 */ -+ if (val > 0xFFFF) -+ val = 0xFFFF; -+ mask = 0x0000FFFF; -+ attr_val = pme_in(global_pme, SEC1); -+ /* clear mil */ -+ attr_val &= mask; -+ /* clear unwanted bits in val*/ -+ val &= mask; -+ val <<= 16; -+ val |= attr_val; -+ pme_out(global_pme, SEC1, val); -+ break; -+ -+ case pme_attr_srrv0: -+ pme_out(global_pme, SRRV0, val); -+ break; -+ case pme_attr_srrv1: -+ pme_out(global_pme, SRRV1, val); -+ break; -+ case pme_attr_srrv2: -+ pme_out(global_pme, SRRV2, val); -+ break; -+ case pme_attr_srrv3: -+ pme_out(global_pme, SRRV3, val); -+ break; -+ case pme_attr_srrv4: -+ pme_out(global_pme, SRRV4, val); -+ break; -+ case pme_attr_srrv5: -+ pme_out(global_pme, SRRV5, val); -+ break; -+ case pme_attr_srrv6: -+ pme_out(global_pme, SRRV6, val); -+ break; -+ case pme_attr_srrv7: -+ pme_out(global_pme, SRRV7, val); -+ break; -+ case pme_attr_srrfi: -+ pme_out(global_pme, SRRFI, val); -+ break; -+ case pme_attr_srri: -+ pme_out(global_pme, SRRI, val); -+ break; -+ case pme_attr_srrwc: -+ pme_out(global_pme, SRRWC, val); -+ break; -+ case pme_attr_srrr: -+ pme_out(global_pme, SRRR, val); -+ break; -+ case pme_attr_tbt0ecc1th: -+ pme_out(global_pme, TBT0ECC1TH, val); -+ break; -+ case pme_attr_tbt1ecc1th: -+ pme_out(global_pme, TBT1ECC1TH, val); -+ break; -+ case pme_attr_vlt0ecc1th: -+ pme_out(global_pme, VLT0ECC1TH, val); -+ break; -+ case pme_attr_vlt1ecc1th: -+ pme_out(global_pme, VLT1ECC1TH, val); -+ break; -+ case pme_attr_cmecc1th: -+ pme_out(global_pme, CMECC1TH, val); -+ break; -+ case pme_attr_dxcmecc1th: -+ pme_out(global_pme, DXCMECC1TH, val); -+ break; -+ case pme_attr_dxemecc1th: -+ pme_out(global_pme, DXEMECC1TH, val); -+ break; -+ case pme_attr_esr: -+ pme_out(global_pme, ESR, val); -+ break; -+ case pme_attr_pehd: -+ pme_out(global_pme, PEHD, val); -+ break; -+ case pme_attr_ecc1bes: -+ pme_out(global_pme, ECC1BES, val); -+ break; -+ case pme_attr_ecc2bes: -+ pme_out(global_pme, ECC2BES, val); -+ break; -+ case pme_attr_miace: -+ pme_out(global_pme, MIA_CE, val); -+ break; -+ case pme_attr_miacr: -+ pme_out(global_pme, MIA_CR, val); -+ break; -+ case pme_attr_cdcr: -+ pme_out(global_pme, CDCR, val); -+ break; -+ case pme_attr_pmtr: -+ pme_out(global_pme, PMTR, val); -+ break; -+ -+ default: -+ pr_err("pme: Unknown attr %u\n", attr); -+ return -EINVAL; -+ }; -+ return 0; -+} -+EXPORT_SYMBOL(pme_attr_set); -+ -+int pme_attr_get(enum pme_attr attr, u32 *val) -+{ -+ u32 mask; -+ u32 attr_val; -+ -+ if (!pme2_have_control()) -+ return -ENODEV; -+ -+ /* Check if Buffer size configuration */ -+ if (attr >= pme_attr_bsc_first && attr <= pme_attr_bsc_last) { -+ u32 bsc_pool_id = attr - pme_attr_bsc_first; -+ u32 bsc_pool_offset = bsc_pool_id % 8; -+ /* calculate which sky-blue reg */ -+ /* 0..7 -> bsc_(0..7), PME_REG_BSC0 */ -+ /* 8..15 -> bsc_(8..15) PME_REG_BSC1*/ -+ /* ... */ -+ /* 56..63 -> bsc_(56..63) PME_REG_BSC7*/ -+ attr_val = pme_in(global_pme, BSC0 + ((bsc_pool_id/8)*4)); -+ attr_val = attr_val >> ((7-bsc_pool_offset)*4); -+ attr_val = attr_val & 0x0000000F; -+ *val = attr_val; -+ return 0; -+ } -+ -+ switch (attr) { -+ case pme_attr_efqc_int: -+ mask = 0x8FFFFFFF; -+ attr_val = pme_in(global_pme, EFQC); -+ attr_val &= ~mask; -+ attr_val >>= 28; -+ break; -+ -+ case pme_attr_sw_db: -+ attr_val = pme_in(global_pme, SWDB); -+ break; -+ -+ case pme_attr_dmcr: -+ attr_val = pme_in(global_pme, DMCR); -+ break; -+ -+ case pme_attr_smcr: -+ attr_val = pme_in(global_pme, SMCR); -+ break; -+ -+ case pme_attr_famcr: -+ attr_val = pme_in(global_pme, FAMCR); -+ break; -+ -+ case pme_attr_kvlts: -+ /* bit 28-31 */ -+ attr_val = pme_in(global_pme, KVLTS); -+ attr_val &= 0x0000000F; -+ /* HW range: 1..15, SW range: 2..16 */ -+ attr_val += 1; -+ break; -+ -+ case pme_attr_max_chain_length: -+ /* bit 17-31 */ -+ attr_val = pme_in(global_pme, KEC); -+ attr_val &= 0x00007FFF; -+ break; -+ -+ case pme_attr_pattern_range_counter_idx: -+ /* bit 15-31 */ -+ attr_val = pme_in(global_pme, DRCIC); -+ attr_val &= 0x0001FFFF; -+ break; -+ -+ case pme_attr_pattern_range_counter_mask: -+ /* bit 15-31 */ -+ attr_val = pme_in(global_pme, DRCMC); -+ attr_val &= 0x0001FFFF; -+ break; -+ -+ case pme_attr_max_allowed_test_line_per_pattern: -+ /* bit 18-31 */ -+ attr_val = pme_in(global_pme, DEC0); -+ attr_val &= 0x00003FFF; -+ break; -+ -+ case pme_attr_max_pdsr_index: -+ /* bit 12-31 */ -+ attr_val = pme_in(global_pme, DEC1); -+ attr_val &= 0x000FFFFF; -+ break; -+ -+ case pme_attr_max_pattern_matches_per_sui: -+ attr_val = pme_in(global_pme, DLC); -+ attr_val &= 0x0000FFFF; -+ break; -+ -+ case pme_attr_max_pattern_evaluations_per_sui: -+ attr_val = pme_in(global_pme, DLC); -+ attr_val >>= 16; -+ break; -+ -+ case pme_attr_report_length_limit: -+ attr_val = pme_in(global_pme, RLL); -+ /* clear unwanted bits in val*/ -+ attr_val &= 0x0000FFFF; -+ break; -+ -+ case pme_attr_end_of_simple_sui_report: -+ /* bit 13 */ -+ attr_val = pme_in(global_pme, SREC); -+ attr_val >>= 18; -+ /* clear unwanted bits in val*/ -+ attr_val &= 0x00000001; -+ break; -+ -+ case pme_attr_aim: -+ /* bit 2 */ -+ attr_val = pme_in(global_pme, SREC); -+ attr_val >>= 29; -+ /* clear unwanted bits in val*/ -+ attr_val &= 0x00000001; -+ break; -+ -+ case pme_attr_sre_context_size: -+ /* bits 9..12 */ -+ attr_val = pme_in(global_pme, SREC); -+ attr_val >>= 19; -+ /* clear unwanted bits in val*/ -+ attr_val &= 0x0000000F; -+ attr_val += 4; -+ attr_val = 1 << attr_val; -+ break; -+ -+ case pme_attr_sre_rule_num: -+ /* bits 24..31 */ -+ attr_val = pme_in(global_pme, SREC); -+ /* clear unwanted bits in val*/ -+ attr_val &= 0x000000FF; -+ /* Multiply by 256 */ -+ attr_val <<= 8; -+ break; -+ -+ case pme_attr_sre_session_ctx_num: { -+ u32 ctx_sz = 0; -+ /* = sre_table_size / sre_session_ctx_size */ -+ attr_val = pme_in(global_pme, SEC3); -+ /* clear unwanted bits in val*/ -+ attr_val &= 0x07FFFFFF; -+ attr_val += 1; -+ attr_val *= 32; -+ ctx_sz = pme_in(global_pme, SREC); -+ ctx_sz >>= 19; -+ /* clear unwanted bits in val*/ -+ ctx_sz &= 0x0000000F; -+ ctx_sz += 4; -+ attr_val /= (1 << ctx_sz); -+ } -+ break; -+ -+ case pme_attr_end_of_sui_reaction_ptr: -+ /* bits 12..31 */ -+ attr_val = pme_in(global_pme, ESRP); -+ /* clear unwanted bits in val*/ -+ attr_val &= 0x000FFFFF; -+ break; -+ -+ case pme_attr_sre_pscl: -+ /* bits 22..31 */ -+ attr_val = pme_in(global_pme, SFRCC); -+ break; -+ -+ case pme_attr_sre_max_block_num: -+ /* bits 17..31 */ -+ attr_val = pme_in(global_pme, SEC1); -+ /* clear unwanted bits in val*/ -+ attr_val &= 0x00007FFF; -+ break; -+ -+ case pme_attr_sre_max_instruction_limit: -+ /* bits 0..15 */ -+ attr_val = pme_in(global_pme, SEC1); -+ attr_val >>= 16; -+ break; -+ -+ case pme_attr_sre_max_index_size: -+ /* bits 12..31 */ -+ attr_val = pme_in(global_pme, SEC2); -+ /* clear unwanted bits in val*/ -+ attr_val &= 0x000FFFFF; -+ break; -+ -+ case pme_attr_sre_max_offset_ctrl: -+ /* bits 5..31 */ -+ attr_val = pme_in(global_pme, SEC3); -+ /* clear unwanted bits in val*/ -+ attr_val &= 0x07FFFFFF; -+ break; -+ -+ case pme_attr_src_id: -+ /* bits 24..31 */ -+ attr_val = pme_in(global_pme, SRCIDR); -+ /* clear unwanted bits in val*/ -+ attr_val &= 0x000000FF; -+ break; -+ -+ case pme_attr_liodnr: -+ /* bits 20..31 */ -+ attr_val = pme_in(global_pme, LIODNR); -+ /* clear unwanted bits in val*/ -+ attr_val &= 0x00000FFF; -+ break; -+ -+ case pme_attr_rev1: -+ /* bits 0..31 */ -+ attr_val = pme_in(global_pme, PM_IP_REV1); -+ break; -+ -+ case pme_attr_rev2: -+ /* bits 0..31 */ -+ attr_val = pme_in(global_pme, PM_IP_REV2); -+ break; -+ -+ case pme_attr_srrr: -+ attr_val = pme_in(global_pme, SRRR); -+ break; -+ -+ case pme_attr_trunci: -+ attr_val = pme_in(global_pme, TRUNCI); -+ break; -+ -+ case pme_attr_rbc: -+ attr_val = pme_in(global_pme, RBC); -+ break; -+ -+ case pme_attr_tbt0ecc1ec: -+ attr_val = pme_in(global_pme, TBT0ECC1EC); -+ break; -+ -+ case pme_attr_tbt1ecc1ec: -+ attr_val = pme_in(global_pme, TBT1ECC1EC); -+ break; -+ -+ case pme_attr_vlt0ecc1ec: -+ attr_val = pme_in(global_pme, VLT0ECC1EC); -+ break; -+ -+ case pme_attr_vlt1ecc1ec: -+ attr_val = pme_in(global_pme, VLT1ECC1EC); -+ break; -+ -+ case pme_attr_cmecc1ec: -+ attr_val = pme_in(global_pme, CMECC1EC); -+ break; -+ -+ case pme_attr_dxcmecc1ec: -+ attr_val = pme_in(global_pme, DXCMECC1EC); -+ break; -+ -+ case pme_attr_dxemecc1ec: -+ attr_val = pme_in(global_pme, DXEMECC1EC); -+ break; -+ -+ case pme_attr_tbt0ecc1th: -+ attr_val = pme_in(global_pme, TBT0ECC1TH); -+ break; -+ -+ case pme_attr_tbt1ecc1th: -+ attr_val = pme_in(global_pme, TBT1ECC1TH); -+ break; -+ -+ case pme_attr_vlt0ecc1th: -+ attr_val = pme_in(global_pme, VLT0ECC1TH); -+ break; -+ -+ case pme_attr_vlt1ecc1th: -+ attr_val = pme_in(global_pme, VLT1ECC1TH); -+ break; -+ -+ case pme_attr_cmecc1th: -+ attr_val = pme_in(global_pme, CMECC1TH); -+ break; -+ -+ case pme_attr_dxcmecc1th: -+ attr_val = pme_in(global_pme, DXCMECC1TH); -+ break; -+ -+ case pme_attr_dxemecc1th: -+ attr_val = pme_in(global_pme, DXEMECC1TH); -+ break; -+ -+ case pme_attr_stnib: -+ attr_val = pme_in(global_pme, STNIB); -+ break; -+ -+ case pme_attr_stnis: -+ attr_val = pme_in(global_pme, STNIS); -+ break; -+ -+ case pme_attr_stnth1: -+ attr_val = pme_in(global_pme, STNTH1); -+ break; -+ -+ case pme_attr_stnth2: -+ attr_val = pme_in(global_pme, STNTH2); -+ break; -+ -+ case pme_attr_stnthv: -+ attr_val = pme_in(global_pme, STNTHV); -+ break; -+ -+ case pme_attr_stnths: -+ attr_val = pme_in(global_pme, STNTHS); -+ break; -+ -+ case pme_attr_stnch: -+ attr_val = pme_in(global_pme, STNCH); -+ break; -+ -+ case pme_attr_stnpm: -+ attr_val = pme_in(global_pme, STNPM); -+ break; -+ -+ case pme_attr_stns1m: -+ attr_val = pme_in(global_pme, STNS1M); -+ break; -+ -+ case pme_attr_stnpmr: -+ attr_val = pme_in(global_pme, STNPMR); -+ break; -+ -+ case pme_attr_stndsr: -+ attr_val = pme_in(global_pme, STNDSR); -+ break; -+ -+ case pme_attr_stnesr: -+ attr_val = pme_in(global_pme, STNESR); -+ break; -+ -+ case pme_attr_stns1r: -+ attr_val = pme_in(global_pme, STNS1R); -+ break; -+ -+ case pme_attr_stnob: -+ attr_val = pme_in(global_pme, STNOB); -+ break; -+ -+ case pme_attr_mia_byc: -+ attr_val = pme_in(global_pme, MIA_BYC); -+ break; -+ -+ case pme_attr_mia_blc: -+ attr_val = pme_in(global_pme, MIA_BLC); -+ break; -+ -+ case pme_attr_isr: -+ attr_val = pme_in(global_pme, ISR); -+ break; -+ -+ case pme_attr_ecr0: -+ attr_val = pme_in(global_pme, ECR0); -+ break; -+ -+ case pme_attr_ecr1: -+ attr_val = pme_in(global_pme, ECR1); -+ break; -+ -+ case pme_attr_esr: -+ attr_val = pme_in(global_pme, ESR); -+ break; -+ -+ case pme_attr_pmstat: -+ attr_val = pme_in(global_pme, PMSTAT); -+ break; -+ -+ case pme_attr_pehd: -+ attr_val = pme_in(global_pme, PEHD); -+ break; -+ -+ case pme_attr_ecc1bes: -+ attr_val = pme_in(global_pme, ECC1BES); -+ break; -+ -+ case pme_attr_ecc2bes: -+ attr_val = pme_in(global_pme, ECC2BES); -+ break; -+ -+ case pme_attr_eccaddr: -+ attr_val = pme_in(global_pme, ECCADDR); -+ break; -+ -+ case pme_attr_ecccode: -+ attr_val = pme_in(global_pme, ECCCODE); -+ break; -+ -+ case pme_attr_miace: -+ attr_val = pme_in(global_pme, MIA_CE); -+ break; -+ -+ case pme_attr_miacr: -+ attr_val = pme_in(global_pme, MIA_CR); -+ break; -+ -+ case pme_attr_cdcr: -+ attr_val = pme_in(global_pme, CDCR); -+ break; -+ -+ case pme_attr_pmtr: -+ attr_val = pme_in(global_pme, PMTR); -+ break; -+ -+ case pme_attr_faconf: -+ attr_val = pme_in(global_pme, FACONF); -+ break; -+ -+ case pme_attr_pdsrbah: -+ attr_val = pme_in(global_pme, PDSRBAH); -+ break; -+ -+ case pme_attr_pdsrbal: -+ attr_val = pme_in(global_pme, PDSRBAL); -+ break; -+ -+ case pme_attr_scbarh: -+ attr_val = pme_in(global_pme, SCBARH); -+ break; -+ -+ case pme_attr_scbarl: -+ attr_val = pme_in(global_pme, SCBARL); -+ break; -+ -+ case pme_attr_srrv0: -+ attr_val = pme_in(global_pme, SRRV0); -+ break; -+ -+ case pme_attr_srrv1: -+ attr_val = pme_in(global_pme, SRRV1); -+ break; -+ -+ case pme_attr_srrv2: -+ attr_val = pme_in(global_pme, SRRV2); -+ break; -+ -+ case pme_attr_srrv3: -+ attr_val = pme_in(global_pme, SRRV3); -+ break; -+ -+ case pme_attr_srrv4: -+ attr_val = pme_in(global_pme, SRRV4); -+ break; -+ -+ case pme_attr_srrv5: -+ attr_val = pme_in(global_pme, SRRV5); -+ break; -+ -+ case pme_attr_srrv6: -+ attr_val = pme_in(global_pme, SRRV6); -+ break; -+ -+ case pme_attr_srrv7: -+ attr_val = pme_in(global_pme, SRRV7); -+ break; -+ -+ case pme_attr_srrfi: -+ attr_val = pme_in(global_pme, SRRFI); -+ break; -+ -+ case pme_attr_srri: -+ attr_val = pme_in(global_pme, SRRI); -+ break; -+ -+ case pme_attr_srrwc: -+ attr_val = pme_in(global_pme, SRRWC); -+ break; -+ -+ default: -+ pr_err("pme: Unknown attr %u\n", attr); -+ return -EINVAL; -+ }; -+ *val = attr_val; -+ return 0; -+} -+EXPORT_SYMBOL(pme_attr_get); -+ -+static enum pme_attr stat_list[] = { -+ pme_attr_trunci, -+ pme_attr_rbc, -+ pme_attr_tbt0ecc1ec, -+ pme_attr_tbt1ecc1ec, -+ pme_attr_vlt0ecc1ec, -+ pme_attr_vlt1ecc1ec, -+ pme_attr_cmecc1ec, -+ pme_attr_dxcmecc1ec, -+ pme_attr_dxemecc1ec, -+ pme_attr_stnib, -+ pme_attr_stnis, -+ pme_attr_stnth1, -+ pme_attr_stnth2, -+ pme_attr_stnthv, -+ pme_attr_stnths, -+ pme_attr_stnch, -+ pme_attr_stnpm, -+ pme_attr_stns1m, -+ pme_attr_stnpmr, -+ pme_attr_stndsr, -+ pme_attr_stnesr, -+ pme_attr_stns1r, -+ pme_attr_stnob, -+ pme_attr_mia_byc, -+ pme_attr_mia_blc -+}; -+ -+static u64 pme_stats[sizeof(stat_list)/sizeof(enum pme_attr)]; -+static DEFINE_SPINLOCK(stat_lock); -+ -+int pme_stat_get(enum pme_attr stat, u64 *value, int reset) -+{ -+ int i, ret = 0; -+ int value_set = 0; -+ u32 val; -+ -+ spin_lock_irq(&stat_lock); -+ for (i = 0; i < sizeof(stat_list)/sizeof(enum pme_attr); i++) { -+ if (stat_list[i] == stat) { -+ ret = pme_attr_get(stat_list[i], &val); -+ /* Do I need to check ret */ -+ pme_stats[i] += val; -+ *value = pme_stats[i]; -+ value_set = 1; -+ if (reset) -+ pme_stats[i] = 0; -+ break; -+ } -+ } -+ if (!value_set) { -+ pr_err("pme: Invalid stat request %d\n", stat); -+ ret = -EINVAL; -+ } -+ spin_unlock_irq(&stat_lock); -+ return ret; -+} -+EXPORT_SYMBOL(pme_stat_get); -+ -+void accumulator_update_interval(u32 interval) -+{ -+ int schedule = 0; -+ -+ spin_lock_irq(&stat_lock); -+ if (!pme_stat_interval && interval) -+ schedule = 1; -+ pme_stat_interval = interval; -+ spin_unlock_irq(&stat_lock); -+ if (schedule) -+ schedule_delayed_work(&accumulator_work, -+ msecs_to_jiffies(interval)); -+} -+ -+static void accumulator_update(struct work_struct *work) -+{ -+ int i, ret; -+ u32 local_interval; -+ u32 val; -+ -+ spin_lock_irq(&stat_lock); -+ local_interval = pme_stat_interval; -+ for (i = 0; i < sizeof(stat_list)/sizeof(enum pme_attr); i++) { -+ ret = pme_attr_get(stat_list[i], &val); -+ pme_stats[i] += val; -+ } -+ spin_unlock_irq(&stat_lock); -+ if (local_interval) -+ schedule_delayed_work(&accumulator_work, -+ msecs_to_jiffies(local_interval)); -+} -diff --git a/drivers/staging/fsl_pme2/pme2_db.c b/drivers/staging/fsl_pme2/pme2_db.c -new file mode 100644 -index 0000000..4c9cd21 ---- /dev/null -+++ b/drivers/staging/fsl_pme2/pme2_db.c -@@ -0,0 +1,572 @@ -+/* Copyright 2009-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 "pme2_private.h" -+#include -+ -+/* Forward declaration */ -+static struct miscdevice fsl_pme2_db_dev; -+ -+/* Global spinlock for handling exclusive inc/dec */ -+static DEFINE_SPINLOCK(exclusive_lock); -+ -+/* Private structure that is allocated for each open that is done on the -+ * pme_db device. This is used to maintain the state of a database session */ -+struct db_session { -+ /* The ctx that is needed to communicate with the pme high level */ -+ struct pme_ctx ctx; -+ /* Used to track the EXCLUSIVE_INC and EXCLUSIVE_DEC ioctls */ -+ unsigned int exclusive_counter; -+}; -+ -+struct cmd_token { -+ /* pme high level token */ -+ struct pme_ctx_token hl_token; -+ /* data */ -+ struct qm_fd rx_fd; -+ /* Completion interface */ -+ struct completion cb_done; -+ u8 ern; -+}; -+ -+#ifdef CONFIG_COMPAT -+static void compat_to_db(struct pme_db *dst, struct compat_pme_db *src) -+{ -+ dst->flags = src->flags; -+ dst->status = src->status; -+ dst->input.data = compat_ptr(src->input.data); -+ dst->input.size = src->input.size; -+ dst->output.data = compat_ptr(src->output.data); -+ dst->output.size = src->output.size; -+} -+ -+static void db_to_compat(struct compat_pme_db *dst, struct pme_db *src) -+{ -+ dst->flags = src->flags; -+ dst->status = src->status; -+ dst->output.data = ptr_to_compat(src->output.data); -+ dst->output.size = src->output.size; -+ dst->input.data = ptr_to_compat(src->input.data); -+ dst->input.size = src->input.size; -+} -+#endif -+ -+/* PME Compound Frame Index */ -+#define INPUT_FRM 1 -+#define OUTPUT_FRM 0 -+ -+/* Callback for database operations */ -+static void db_cb(struct pme_ctx *ctx, const struct qm_fd *fd, -+ struct pme_ctx_token *ctx_token) -+{ -+ struct cmd_token *token = (struct cmd_token *)ctx_token; -+ token->rx_fd = *fd; -+ complete(&token->cb_done); -+} -+ -+static void db_ern_cb(struct pme_ctx *ctx, const struct qm_mr_entry *mr, -+ struct pme_ctx_token *ctx_token) -+{ -+ struct cmd_token *token = (struct cmd_token *)ctx_token; -+ token->ern = 1; -+ token->rx_fd = mr->ern.fd; -+ complete(&token->cb_done); -+} -+ -+struct ctrl_op { -+ struct pme_ctx_ctrl_token ctx_ctr; -+ struct completion cb_done; -+ enum pme_status cmd_status; -+ u8 res_flag; -+ u8 ern; -+}; -+ -+static void ctrl_cb(struct pme_ctx *ctx, const struct qm_fd *fd, -+ struct pme_ctx_ctrl_token *token) -+{ -+ struct ctrl_op *ctrl = (struct ctrl_op *)token; -+ ctrl->cmd_status = pme_fd_res_status(fd); -+ ctrl->res_flag = pme_fd_res_flags(fd) & PME_STATUS_UNRELIABLE; -+ complete(&ctrl->cb_done); -+} -+ -+static void ctrl_ern_cb(struct pme_ctx *ctx, const struct qm_mr_entry *mr, -+ struct pme_ctx_ctrl_token *token) -+{ -+ struct ctrl_op *ctrl = (struct ctrl_op *)token; -+ ctrl->ern = 1; -+ complete(&ctrl->cb_done); -+} -+ -+static int exclusive_inc(struct file *fp, struct db_session *db) -+{ -+ int ret; -+ -+ BUG_ON(!db); -+ BUG_ON(!(db->ctx.flags & PME_CTX_FLAG_EXCLUSIVE)); -+ spin_lock(&exclusive_lock); -+ ret = pme_ctx_exclusive_inc(&db->ctx, -+ (PME_CTX_OP_WAIT | PME_CTX_OP_WAIT_INT)); -+ if (!ret) -+ db->exclusive_counter++; -+ spin_unlock(&exclusive_lock); -+ return ret; -+} -+ -+static int exclusive_dec(struct file *fp, struct db_session *db) -+{ -+ int ret = 0; -+ -+ BUG_ON(!db); -+ BUG_ON(!(db->ctx.flags & PME_CTX_FLAG_EXCLUSIVE)); -+ spin_lock(&exclusive_lock); -+ if (!db->exclusive_counter) { -+ PMEPRERR("exclusivity counter already zero\n"); -+ ret = -EINVAL; -+ } else { -+ pme_ctx_exclusive_dec(&db->ctx); -+ db->exclusive_counter--; -+ } -+ spin_unlock(&exclusive_lock); -+ return ret; -+} -+ -+static int execute_cmd(struct file *fp, struct db_session *db, -+ struct pme_db *db_cmd) -+{ -+ int ret = 0; -+ struct cmd_token token; -+ struct qm_sg_entry tx_comp[2]; -+ struct qm_fd tx_fd; -+ void *tx_data = NULL; -+ void *rx_data = NULL; -+ u32 src_sz, dst_sz; -+ dma_addr_t dma_addr; -+ -+ memset(&token, 0, sizeof(struct cmd_token)); -+ memset(tx_comp, 0, sizeof(tx_comp)); -+ memset(&tx_fd, 0, sizeof(struct qm_fd)); -+ init_completion(&token.cb_done); -+ -+ PMEPRINFO("Received User Space Contiguous mem\n"); -+ PMEPRINFO("length = %d\n", db_cmd->input.size); -+ tx_data = kmalloc(db_cmd->input.size, GFP_KERNEL); -+ if (!tx_data) { -+ PMEPRERR("Err alloc %zd byte\n", db_cmd->input.size); -+ return -ENOMEM; -+ } -+ -+ if (copy_from_user(tx_data, -+ (void __user *)db_cmd->input.data, -+ db_cmd->input.size)) { -+ PMEPRERR("Error copying contigous user data\n"); -+ ret = -EFAULT; -+ goto free_tx_data; -+ } -+ -+ /* Setup input frame */ -+ tx_comp[INPUT_FRM].final = 1; -+ tx_comp[INPUT_FRM].length = db_cmd->input.size; -+ dma_addr = pme_map(tx_data); -+ if (pme_map_error(dma_addr)) { -+ PMEPRERR("Error pme_map_error\n"); -+ ret = -EIO; -+ goto free_tx_data; -+ } -+ set_sg_addr(&tx_comp[INPUT_FRM], dma_addr); -+ /* setup output frame, if output is expected */ -+ if (db_cmd->output.size) { -+ PMEPRINFO("expect output %d\n", db_cmd->output.size); -+ rx_data = kmalloc(db_cmd->output.size, GFP_KERNEL); -+ if (!rx_data) { -+ PMEPRERR("Err alloc %zd byte", db_cmd->output.size); -+ ret = -ENOMEM; -+ goto unmap_input_frame; -+ } -+ /* Setup output frame */ -+ tx_comp[OUTPUT_FRM].length = db_cmd->output.size; -+ dma_addr = pme_map(rx_data); -+ if (pme_map_error(dma_addr)) { -+ PMEPRERR("Error pme_map_error\n"); -+ ret = -EIO; -+ goto comp_frame_free_rx; -+ } -+ set_sg_addr(&tx_comp[OUTPUT_FRM], dma_addr); -+ tx_fd.format = qm_fd_compound; -+ /* Build compound frame */ -+ dma_addr = pme_map(tx_comp); -+ if (pme_map_error(dma_addr)) { -+ PMEPRERR("Error pme_map_error\n"); -+ ret = -EIO; -+ goto comp_frame_unmap_output; -+ } -+ set_fd_addr(&tx_fd, dma_addr); -+ } else { -+ tx_fd.format = qm_fd_sg_big; -+ tx_fd.length29 = db_cmd->input.size; -+ /* Build sg frame */ -+ dma_addr = pme_map(&tx_comp[INPUT_FRM]); -+ if (pme_map_error(dma_addr)) { -+ PMEPRERR("Error pme_map_error\n"); -+ ret = -EIO; -+ goto unmap_input_frame; -+ } -+ set_fd_addr(&tx_fd, dma_addr); -+ } -+ ret = pme_ctx_pmtcc(&db->ctx, PME_CTX_OP_WAIT, &tx_fd, -+ (struct pme_ctx_token *)&token); -+ if (unlikely(ret)) { -+ PMEPRINFO("pme_ctx_pmtcc error %d\n", ret); -+ goto unmap_frame; -+ } -+ PMEPRINFO("Wait for completion\n"); -+ /* Wait for the command to complete */ -+ wait_for_completion(&token.cb_done); -+ -+ if (token.ern) { -+ ret = -EIO; -+ goto unmap_frame; -+ } -+ -+ PMEPRINFO("pme2_db: process_completed_token\n"); -+ PMEPRINFO("pme2_db: received %d frame type\n", token.rx_fd.format); -+ if (token.rx_fd.format == qm_fd_compound) { -+ /* Need to copy output */ -+ src_sz = tx_comp[OUTPUT_FRM].length; -+ dst_sz = db_cmd->output.size; -+ PMEPRINFO("pme gen %u data, have space for %u\n", -+ src_sz, dst_sz); -+ db_cmd->output.size = min(dst_sz, src_sz); -+ /* Doesn't make sense we generated more than available space -+ * should have got truncation. -+ */ -+ BUG_ON(dst_sz < src_sz); -+ if (copy_to_user((void __user *)db_cmd->output.data, rx_data, -+ db_cmd->output.size)) { -+ PMEPRERR("Error copying to user data\n"); -+ ret = -EFAULT; -+ goto comp_frame_unmap_cf; -+ } -+ } else if (token.rx_fd.format == qm_fd_sg_big) -+ db_cmd->output.size = 0; -+ else -+ panic("unexpected frame type received %d\n", -+ token.rx_fd.format); -+ -+ db_cmd->flags = pme_fd_res_flags(&token.rx_fd); -+ db_cmd->status = pme_fd_res_status(&token.rx_fd); -+ -+unmap_frame: -+ if (token.rx_fd.format == qm_fd_sg_big) -+ goto single_frame_unmap_frame; -+ -+comp_frame_unmap_cf: -+comp_frame_unmap_output: -+comp_frame_free_rx: -+ kfree(rx_data); -+ goto unmap_input_frame; -+single_frame_unmap_frame: -+unmap_input_frame: -+free_tx_data: -+ kfree(tx_data); -+ -+ return ret; -+} -+ -+static int execute_nop(struct file *fp, struct db_session *db) -+{ -+ int ret = 0; -+ struct ctrl_op ctx_ctrl = { -+ .ctx_ctr.cb = ctrl_cb, -+ .ctx_ctr.ern_cb = ctrl_ern_cb -+ }; -+ init_completion(&ctx_ctrl.cb_done); -+ -+ ret = pme_ctx_ctrl_nop(&db->ctx, PME_CTX_OP_WAIT|PME_CTX_OP_WAIT_INT, -+ &ctx_ctrl.ctx_ctr); -+ if (!ret) -+ wait_for_completion(&ctx_ctrl.cb_done); -+ -+ if (ctx_ctrl.ern) -+ ret = -EIO; -+ return ret; -+} -+ -+static atomic_t sre_reset_lock = ATOMIC_INIT(1); -+static int ioctl_sre_reset(unsigned long arg) -+{ -+ struct pme_db_sre_reset reset_vals; -+ int i; -+ u32 srrr_val; -+ int ret = 0; -+ -+ if (copy_from_user(&reset_vals, (struct pme_db_sre_reset __user *)arg, -+ sizeof(struct pme_db_sre_reset))) -+ return -EFAULT; -+ PMEPRINFO("sre_reset:\n"); -+ PMEPRINFO(" rule_index = 0x%x:\n", reset_vals.rule_index); -+ PMEPRINFO(" rule_increment = 0x%x:\n", reset_vals.rule_increment); -+ PMEPRINFO(" rule_repetitions = 0x%x:\n", reset_vals.rule_repetitions); -+ PMEPRINFO(" rule_reset_interval = 0x%x:\n", -+ reset_vals.rule_reset_interval); -+ PMEPRINFO(" rule_reset_priority = 0x%x:\n", -+ reset_vals.rule_reset_priority); -+ -+ /* Validate ranges */ -+ if ((reset_vals.rule_index >= PME_PMFA_SRE_INDEX_MAX) || -+ (reset_vals.rule_increment > PME_PMFA_SRE_INC_MAX) || -+ (reset_vals.rule_repetitions >= PME_PMFA_SRE_REP_MAX) || -+ (reset_vals.rule_reset_interval >= -+ PME_PMFA_SRE_INTERVAL_MAX)) -+ return -ERANGE; -+ /* Check and make sure only one caller is present */ -+ if (!atomic_dec_and_test(&sre_reset_lock)) { -+ /* Someone else is already in this call */ -+ atomic_inc(&sre_reset_lock); -+ return -EBUSY; -+ }; -+ /* All validated. Run the command */ -+ for (i = 0; i < PME_SRE_RULE_VECTOR_SIZE; i++) -+ pme_attr_set(pme_attr_srrv0 + i, reset_vals.rule_vector[i]); -+ pme_attr_set(pme_attr_srrfi, reset_vals.rule_index); -+ pme_attr_set(pme_attr_srri, reset_vals.rule_increment); -+ pme_attr_set(pme_attr_srrwc, -+ (0xFFF & reset_vals.rule_reset_interval) << 1 | -+ (reset_vals.rule_reset_priority ? 1 : 0)); -+ /* Need to set SRRR last */ -+ pme_attr_set(pme_attr_srrr, reset_vals.rule_repetitions); -+ do { -+ mdelay(PME_PMFA_SRE_POLL_MS); -+ ret = pme_attr_get(pme_attr_srrr, &srrr_val); -+ if (ret) { -+ PMEPRCRIT("pme2: Error reading srrr\n"); -+ /* bail */ -+ break; -+ } -+ /* Check for error */ -+ else if (srrr_val & 0x10000000) { -+ PMEPRERR("pme2: Error in SRRR\n"); -+ ret = -EIO; -+ } -+ PMEPRINFO("pme2: srrr count %d\n", srrr_val); -+ } while (srrr_val); -+ atomic_inc(&sre_reset_lock); -+ return ret; -+} -+ -+/** -+ * fsl_pme2_db_open - open the driver -+ * -+ * Open the driver and prepare for requests. -+ * -+ * Every time an application opens the driver, we create a db_session object -+ * for that file handle. -+ */ -+static int fsl_pme2_db_open(struct inode *node, struct file *fp) -+{ -+ int ret; -+ struct db_session *db = NULL; -+ -+ db = kzalloc(sizeof(struct db_session), GFP_KERNEL); -+ if (!db) -+ return -ENOMEM; -+ fp->private_data = db; -+ db->ctx.cb = db_cb; -+ db->ctx.ern_cb = db_ern_cb; -+ -+ ret = pme_ctx_init(&db->ctx, -+ PME_CTX_FLAG_EXCLUSIVE | -+ PME_CTX_FLAG_PMTCC | -+ PME_CTX_FLAG_DIRECT| -+ PME_CTX_FLAG_LOCAL, -+ 0, 4, CONFIG_FSL_PME2_DB_QOSOUT_PRIORITY, 0, NULL); -+ if (ret) { -+ PMEPRERR("pme_ctx_init %d\n", ret); -+ goto free_data; -+ } -+ -+ /* enable the context */ -+ ret = pme_ctx_enable(&db->ctx); -+ if (ret) { -+ PMEPRERR("error enabling ctx %d\n", ret); -+ pme_ctx_finish(&db->ctx); -+ goto free_data; -+ } -+ PMEPRINFO("pme2_db: Finish pme_db open %d\n", smp_processor_id()); -+ return 0; -+free_data: -+ kfree(fp->private_data); -+ fp->private_data = NULL; -+ return ret; -+} -+ -+static int fsl_pme2_db_close(struct inode *node, struct file *fp) -+{ -+ int ret = 0; -+ struct db_session *db = fp->private_data; -+ -+ PMEPRINFO("Start pme_db close\n"); -+ while (db->exclusive_counter) { -+ pme_ctx_exclusive_dec(&db->ctx); -+ db->exclusive_counter--; -+ } -+ -+ /* Disable context. */ -+ ret = pme_ctx_disable(&db->ctx, PME_CTX_OP_WAIT, NULL); -+ if (ret) -+ PMEPRCRIT("Error disabling ctx %d\n", ret); -+ pme_ctx_finish(&db->ctx); -+ kfree(db); -+ PMEPRINFO("Finish pme_db close\n"); -+ return 0; -+} -+ -+/* Main switch loop for ioctl operations */ -+static long fsl_pme2_db_ioctl(struct file *fp, unsigned int cmd, -+ unsigned long arg) -+{ -+ struct db_session *db = fp->private_data; -+ int ret = 0; -+ -+ switch (cmd) { -+ -+ case PMEIO_PMTCC: { -+ int ret; -+ struct pme_db db_cmd; -+ -+ /* Copy the command to kernel space */ -+ if (copy_from_user(&db_cmd, (void __user *)arg, -+ sizeof(db_cmd))) -+ return -EFAULT; -+ ret = execute_cmd(fp, db, &db_cmd); -+ if (!ret) -+ ret = copy_to_user((struct pme_db __user *)arg, -+ &db_cmd, sizeof(db_cmd)); -+ return ret; -+ } -+ break; -+ -+ case PMEIO_EXL_INC: -+ return exclusive_inc(fp, db); -+ case PMEIO_EXL_DEC: -+ return exclusive_dec(fp, db); -+ case PMEIO_EXL_GET: -+ BUG_ON(!db); -+ BUG_ON(!(db->ctx.flags & PME_CTX_FLAG_EXCLUSIVE)); -+ if (copy_to_user((void __user *)arg, -+ &db->exclusive_counter, -+ sizeof(db->exclusive_counter))) -+ ret = -EFAULT; -+ return ret; -+ case PMEIO_NOP: -+ return execute_nop(fp, db); -+ case PMEIO_SRE_RESET: -+ return ioctl_sre_reset(arg); -+ -+#ifdef CONFIG_COMPAT -+ case PMEIO_PMTCC32: { -+ int ret; -+ struct pme_db db_cmd; -+ struct compat_pme_db db_cmd32; -+ struct compat_pme_db __user *user_db_cmd = compat_ptr(arg); -+ -+ /* Copy the command to kernel space */ -+ if (copy_from_user(&db_cmd32, user_db_cmd, sizeof(db_cmd32))) -+ return -EFAULT; -+ /* Convert to 64-bit struct */ -+ compat_to_db(&db_cmd, &db_cmd32); -+ ret = execute_cmd(fp, db, &db_cmd); -+ if (!ret) { -+ /* Convert to compat struct */ -+ db_to_compat(&db_cmd32, &db_cmd); -+ ret = copy_to_user(user_db_cmd, &db_cmd32, -+ sizeof(*user_db_cmd)); -+ } -+ return ret; -+ } -+ break; -+#endif -+ } -+ pr_info("Unknown pme_db ioctl cmd %u\n", cmd); -+ return -EINVAL; -+} -+ -+static const struct file_operations fsl_pme2_db_fops = { -+ .owner = THIS_MODULE, -+ .open = fsl_pme2_db_open, -+ .release = fsl_pme2_db_close, -+ .unlocked_ioctl = fsl_pme2_db_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = fsl_pme2_db_ioctl, -+#endif -+}; -+ -+static struct miscdevice fsl_pme2_db_dev = { -+ .minor = MISC_DYNAMIC_MINOR, -+ .name = PME_DEV_DB_NODE, -+ .fops = &fsl_pme2_db_fops -+}; -+ -+static int __init fsl_pme2_db_init(void) -+{ -+ int err = 0; -+ -+ pr_info("Freescale pme2 db driver\n"); -+ if (!pme2_have_control()) { -+ PMEPRERR("not on ctrl-plane\n"); -+ return -ENODEV; -+ } -+ err = misc_register(&fsl_pme2_db_dev); -+ if (err) { -+ PMEPRERR("cannot register device\n"); -+ return err; -+ } -+ PMEPRINFO("device %s registered\n", fsl_pme2_db_dev.name); -+ return 0; -+} -+ -+static void __exit fsl_pme2_db_exit(void) -+{ -+ int err = misc_deregister(&fsl_pme2_db_dev); -+ if (err) { -+ PMEPRERR("Failed to deregister device %s, " -+ "code %d\n", fsl_pme2_db_dev.name, err); -+ return; -+ } -+ PMEPRINFO("device %s deregistered\n", fsl_pme2_db_dev.name); -+} -+ -+module_init(fsl_pme2_db_init); -+module_exit(fsl_pme2_db_exit); -+ -+MODULE_AUTHOR("Freescale Semiconductor - OTC"); -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("FSL PME2 db driver"); -diff --git a/drivers/staging/fsl_pme2/pme2_high.c b/drivers/staging/fsl_pme2/pme2_high.c -new file mode 100644 -index 0000000..14dacd3 ---- /dev/null -+++ b/drivers/staging/fsl_pme2/pme2_high.c -@@ -0,0 +1,997 @@ -+/* 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 "pme2_private.h" -+ -+/* The pme_ctx state machine is described via the following list of -+ * internal PME_CTX_FLAG_*** bits and cross-referenced to the APIs (and -+ * functionality) they track. -+ * -+ * DEAD: set at any point, an error has been hit, doesn't "cause" disabling or -+ * any autonomous ref-decrement (been there, hit the gotchas, won't do it -+ * again). -+ * -+ * DISABLING: set by pme_ctx_disable() at any point that is not already -+ * disabling, disabled, or in ctrl, and the ref is decremented. DISABLING is -+ * unset by pme_ctx_enable(). -+ * -+ * DISABLED: once pme_ctx_disable() has set DISABLING and refs==0, DISABLED is -+ * set before returning. (Any failure will clear DISABLING and increment the ref -+ * count.) DISABLING is unset by pme_ctx_enable(). -+ * -+ * ENABLING: set by pme_ctx_enable() provided the context is disabled, not dead, -+ * not in RECONFIG, and not already enabling. Once set, the ref is incremented -+ * and the tx FQ is scheduled (for non-exclusive flows). If this fails, the ref -+ * is decremented and the context is re-disabled. ENABLING is unset once -+ * pme_ctx_enable() completes. -+ * -+ * RECONFIG: set by pme_ctx_reconfigure_[rt]x() provided the context is -+ * disabled, not dead, and not already in reconfig. RECONFIG is cleared prior to -+ * the function returning. -+ * -+ * Simplifications: the do_flag() wrapper provides synchronised modifications of -+ * the ctx 'flags', and callers can rely on the following implications to reduce -+ * the number of flags in the masks being passed in; -+ * DISABLED implies DISABLING (and enable will clear both) -+ */ -+ -+/* Internal-only ctx flags, mustn't conflict with exported ones */ -+#define PME_CTX_FLAG_DEAD 0x80000000 -+#define PME_CTX_FLAG_DISABLING 0x40000000 -+#define PME_CTX_FLAG_DISABLED 0x20000000 -+#define PME_CTX_FLAG_ENABLING 0x10000000 -+#define PME_CTX_FLAG_RECONFIG 0x08000000 -+#define PME_CTX_FLAG_PRIVATE 0xf8000000 /* mask of them all */ -+ -+/* Internal-only cmd flags, musn't conflict with exported ones */ -+#define PME_CTX_OP_INSIDE_DISABLE 0x80000000 -+#define PME_CTX_OP_PRIVATE 0x80000000 /* mask of them all */ -+ -+struct pme_nostash { -+ struct qman_fq fqin; -+ struct pme_ctx *parent; -+}; -+ -+/* This wrapper simplifies conditional (and locked) read-modify-writes to -+ * 'flags'. Inlining should allow the compiler to optimise it based on the -+ * parameters, eg. if 'must_be_set'/'must_not_be_set' are zero it will -+ * degenerate to an unconditional read-modify-write, if 'to_set'/'to_unset' are -+ * zero it will degenerate to a read-only flag-check, etc. */ -+static inline int do_flags(struct pme_ctx *ctx, -+ u32 must_be_set, u32 must_not_be_set, -+ u32 to_set, u32 to_unset) -+{ -+ int err = -EBUSY; -+ unsigned long irqflags; -+ -+ spin_lock_irqsave(&ctx->lock, irqflags); -+ if (((ctx->flags & must_be_set) == must_be_set) && -+ !(ctx->flags & must_not_be_set)) { -+ ctx->flags |= to_set; -+ ctx->flags &= ~to_unset; -+ err = 0; -+ } -+ spin_unlock_irqrestore(&ctx->lock, irqflags); -+ return err; -+} -+ -+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 *); -+static const struct qman_fq_cb pme_fq_base_in = { -+ .fqs = cb_fqs, -+ .ern = cb_ern -+}; -+static const struct qman_fq_cb pme_fq_base_out = { -+ .dqrr = cb_dqrr, -+ .fqs = cb_fqs -+}; -+ -+/* Globals related to competition for PME_EFQC, ie. exclusivity */ -+static DECLARE_WAIT_QUEUE_HEAD(exclusive_queue); -+static spinlock_t exclusive_lock = __SPIN_LOCK_UNLOCKED(exclusive_lock); -+static unsigned int exclusive_refs; -+static struct pme_ctx *exclusive_ctx; -+ -+/* Index 0..255, bools do indicated which errors are serious -+ * 0x40, 0x41, 0x48, 0x49, 0x4c, 0x4e, 0x4f, 0x50, 0x51, 0x59, 0x5a, 0x5b, -+ * 0x5c, 0x5d, 0x5f, 0x60, 0x80, 0xc0, 0xc1, 0xc2, 0xc4, 0xd2, -+ * 0xd4, 0xd5, 0xd7, 0xd9, 0xda, 0xe0, 0xe7 -+ */ -+static u8 serious_error_vec[] = { -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, -+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -+ 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+}; -+ -+/* TODO: this is hitting the rx FQ with a large blunt instrument, ie. park() -+ * does a retire, query, oos, and (re)init. It's possible to force-eligible the -+ * rx FQ instead, then use a DCA_PK within the cb_dqrr() callback to park it. -+ * Implement this optimisation later if it's an issue (and incur the additional -+ * complexity in the state-machine). */ -+static int park(struct qman_fq *fq, struct qm_mcc_initfq *initfq) -+{ -+ int ret; -+ u32 flags; -+ -+ ret = qman_retire_fq(fq, &flags); -+ if (ret) -+ return ret; -+ BUG_ON(flags & QMAN_FQ_STATE_BLOCKOOS); -+ /* We can't revert from now on */ -+ ret = qman_query_fq(fq, &initfq->fqd); -+ BUG_ON(ret); -+ ret = qman_oos_fq(fq); -+ BUG_ON(ret); -+ /* can't set QM_INITFQ_WE_OAC and QM_INITFQ_WE_TDTHRESH -+ * at the same time */ -+ initfq->we_mask = QM_INITFQ_WE_MASK & ~QM_INITFQ_WE_TDTHRESH; -+ ret = qman_init_fq(fq, 0, initfq); -+ BUG_ON(ret); -+ initfq->we_mask = QM_INITFQ_WE_TDTHRESH; -+ ret = qman_init_fq(fq, 0, initfq); -+ BUG_ON(ret); -+ return 0; -+} -+ -+static inline int reconfigure_rx(struct pme_ctx *ctx, int to_park, u8 qosout, -+ u16 dest, -+ const struct qm_fqd_stashing *stashing) -+{ -+ struct qm_mcc_initfq initfq; -+ u32 flags = QMAN_INITFQ_FLAG_SCHED; -+ int ret; -+ -+ ret = do_flags(ctx, PME_CTX_FLAG_DISABLED, -+ PME_CTX_FLAG_DEAD | PME_CTX_FLAG_RECONFIG, -+ PME_CTX_FLAG_RECONFIG, 0); -+ if (ret) -+ return ret; -+ if (to_park) { -+ ret = park(&ctx->fq, &initfq); -+ if (ret) -+ goto done; -+ } -+ initfq.we_mask = QM_INITFQ_WE_DESTWQ | QM_INITFQ_WE_FQCTRL; -+ initfq.fqd.dest.wq = qosout; -+ if (stashing) { -+ initfq.we_mask |= QM_INITFQ_WE_CONTEXTA; -+ initfq.fqd.context_a.stashing = *stashing; -+ initfq.fqd.fq_ctrl = QM_FQCTRL_CTXASTASHING; -+ } else -+ initfq.fqd.fq_ctrl = 0; /* disable stashing */ -+ if (ctx->flags & PME_CTX_FLAG_LOCAL) -+ flags |= QMAN_INITFQ_FLAG_LOCAL; -+ else { -+ initfq.fqd.dest.channel = dest; -+ /* Set hold-active *IFF* it's a pool channel */ -+ if (dest >= qm_channel_pool1) -+ initfq.fqd.fq_ctrl |= QM_FQCTRL_HOLDACTIVE; -+ } -+ ret = qman_init_fq(&ctx->fq, flags, &initfq); -+done: -+ do_flags(ctx, 0, 0, 0, PME_CTX_FLAG_RECONFIG); -+ return ret; -+} -+ -+/* this code is factored out of pme_ctx_disable() and get_ctrl() */ -+static int empty_pipeline(struct pme_ctx *ctx, __maybe_unused u32 flags) -+{ -+ int ret; -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & PME_CTX_OP_WAIT) { -+ if (flags & PME_CTX_OP_WAIT_INT) { -+ ret = -EINTR; -+ wait_event_interruptible(ctx->queue, -+ !(ret = atomic_read(&ctx->refs))); -+ } else -+ wait_event(ctx->queue, -+ !(ret = atomic_read(&ctx->refs))); -+ } else -+#endif -+ ret = atomic_read(&ctx->refs); -+ if (ret) -+ /* convert a +ve ref-count to a -ve error code */ -+ ret = -EBUSY; -+ return ret; -+} -+ -+/** -+ * set_pme_revision - set the pme revision in the ctx -+ * -+ * In order to make decisions based on PME HW version, read this -+ * information and store it on the ctx object. -+ */ -+static int set_pme_revision(struct pme_ctx *ctx) -+{ -+ int ret = 0; -+ u32 rev1, rev2; -+ struct device_node *dn; -+ const u32 *dt_rev; -+ int len; -+ -+#ifdef CONFIG_FSL_PME2_CTRL -+ /* Can try and read it from CCSR */ -+ if (pme2_have_control()) { -+ ret = pme_attr_get(pme_attr_rev1, &rev1); -+ if (ret) -+ return ret; -+ ret = pme_attr_get(pme_attr_rev2, &rev2); -+ if (ret) -+ return ret; -+ ctx->pme_rev1 = rev1; -+ ctx->pme_rev2 = rev2; -+ return 0; -+ } -+#endif -+ -+ /* Not on control-plane, try and get it from pme portal node */ -+ dn = of_find_node_with_property(NULL, "fsl,pme-rev1"); -+ if (!dn) -+ return -ENODEV; -+ dt_rev = of_get_property(dn, "fsl,pme-rev1", &len); -+ if (!dt_rev || len != 4) { -+ of_node_put(dn); -+ return -ENODEV; -+ } -+ rev1 = *dt_rev; -+ -+ dt_rev = of_get_property(dn, "fsl,pme-rev2", &len); -+ if (!dt_rev || len != 4) { -+ of_node_put(dn); -+ return -ENODEV; -+ } -+ rev2 = *dt_rev; -+ of_node_put(dn); -+ ctx->pme_rev1 = rev1; -+ ctx->pme_rev2 = rev2; -+ return ret; -+} -+ -+int pme_ctx_init(struct pme_ctx *ctx, u32 flags, u32 bpid, u8 qosin, -+ u8 qosout, u16 dest, -+ const struct qm_fqd_stashing *stashing) -+{ -+ int rxinit = 0, ret = -ENOMEM, fqin_inited = 0; -+ -+ ctx->fq.cb = pme_fq_base_out; -+ atomic_set(&ctx->refs, 0); -+ ctx->flags = (flags & ~PME_CTX_FLAG_PRIVATE) | PME_CTX_FLAG_DISABLED | -+ PME_CTX_FLAG_DISABLING; -+ if (ctx->flags & PME_CTX_FLAG_PMTCC) -+ ctx->flags |= PME_CTX_FLAG_DIRECT | PME_CTX_FLAG_EXCLUSIVE; -+ spin_lock_init(&ctx->lock); -+ init_waitqueue_head(&ctx->queue); -+ INIT_LIST_HEAD(&ctx->tokens); -+ ctx->hw_flow = NULL; -+ ctx->hw_residue = NULL; -+ ret = set_pme_revision(ctx); -+ if (ret) -+ goto err; -+#ifdef CONFIG_FSL_PME_BUG_4K_SCAN_REV_2_1_4 -+ if (is_version_2_1_4(ctx->pme_rev1, ctx->pme_rev2)) -+ ctx->max_scan_size = PME_MAX_SCAN_SIZE_BUG_2_1_4; -+#endif -+ ctx->us_data = kzalloc(sizeof(struct pme_nostash), GFP_KERNEL); -+ if (!ctx->us_data) -+ goto err; -+ ctx->us_data->parent = ctx; -+ if (!ctx->us_data) -+ goto err; -+ ctx->us_data->fqin.cb = pme_fq_base_in; -+ if (qman_create_fq(0, QMAN_FQ_FLAG_TO_DCPORTAL | -+ QMAN_FQ_FLAG_DYNAMIC_FQID | -+ ((flags & PME_CTX_FLAG_LOCKED) ? -+ QMAN_FQ_FLAG_LOCKED : 0), -+ &ctx->us_data->fqin)) -+ goto err; -+ fqin_inited = 1; -+ if (qman_create_fq(0, QMAN_FQ_FLAG_NO_ENQUEUE | -+ QMAN_FQ_FLAG_DYNAMIC_FQID | -+ ((flags & PME_CTX_FLAG_LOCKED) ? -+ QMAN_FQ_FLAG_LOCKED : 0), &ctx->fq)) -+ goto err; -+ rxinit = 1; -+ /* Input FQ */ -+ if (!(flags & PME_CTX_FLAG_DIRECT)) { -+ ctx->hw_flow = pme_hw_flow_new(); -+ if (!ctx->hw_flow) -+ goto err; -+ } -+ ret = pme_ctx_reconfigure_tx(ctx, bpid, qosin); -+ if (ret) -+ goto err; -+ /* Output FQ */ -+ ret = reconfigure_rx(ctx, 0, qosout, dest, stashing); -+ if (ret) { -+ /* Need to OOS the FQ before it gets free'd */ -+ ret = qman_oos_fq(&ctx->us_data->fqin); -+ BUG_ON(ret); -+ goto err; -+ } -+ return 0; -+err: -+ if (ctx->hw_flow) -+ pme_hw_flow_free(ctx->hw_flow); -+ if (ctx->us_data) { -+ if (fqin_inited) -+ qman_destroy_fq(&ctx->us_data->fqin, 0); -+ kfree(ctx->us_data); -+ } -+ if (rxinit) -+ qman_destroy_fq(&ctx->fq, 0); -+ return ret; -+} -+EXPORT_SYMBOL(pme_ctx_init); -+ -+/* NB, we don't lock here because there must be no other callers (even if we -+ * locked, what does the loser do after we win?) */ -+void pme_ctx_finish(struct pme_ctx *ctx) -+{ -+ u32 flags; -+ int ret; -+ -+ ret = do_flags(ctx, PME_CTX_FLAG_DISABLED, PME_CTX_FLAG_RECONFIG, 0, 0); -+ BUG_ON(ret); -+ /* Rx/Tx are empty (coz ctx is disabled) so retirement should be -+ * immediate */ -+ ret = qman_retire_fq(&ctx->us_data->fqin, &flags); -+ BUG_ON(ret); -+ BUG_ON(flags & QMAN_FQ_STATE_BLOCKOOS); -+ ret = qman_retire_fq(&ctx->fq, &flags); -+ BUG_ON(ret); -+ BUG_ON(flags & QMAN_FQ_STATE_BLOCKOOS); -+ /* OOS and free (don't kfree fq, it's a static ctx member) */ -+ ret = qman_oos_fq(&ctx->us_data->fqin); -+ BUG_ON(ret); -+ ret = qman_oos_fq(&ctx->fq); -+ BUG_ON(ret); -+ qman_destroy_fq(&ctx->us_data->fqin, 0); -+ qman_destroy_fq(&ctx->fq, 0); -+ kfree(ctx->us_data); -+ if (ctx->hw_flow) -+ pme_hw_flow_free(ctx->hw_flow); -+ if (ctx->hw_residue) -+ pme_hw_residue_free(ctx->hw_residue); -+} -+EXPORT_SYMBOL(pme_ctx_finish); -+ -+int pme_ctx_is_disabled(struct pme_ctx *ctx) -+{ -+ return (ctx->flags & PME_CTX_FLAG_DISABLED); -+} -+EXPORT_SYMBOL(pme_ctx_is_disabled); -+ -+int pme_ctx_is_dead(struct pme_ctx *ctx) -+{ -+ return (ctx->flags & PME_CTX_FLAG_DEAD); -+} -+EXPORT_SYMBOL(pme_ctx_is_dead); -+ -+/* predeclare this here because pme_ctx_disable() may invoke it in "privileged -+ * mode". The code is down with the other ctrl commands, where it belongs. */ -+static inline int __update_flow(struct pme_ctx *ctx, u32 flags, -+ struct pme_flow *params, struct pme_ctx_ctrl_token *token, -+ int is_disabling); -+ -+/* This gets invoked by pme_ctx_disable() if it runs to completion, otherwise -+ * it's called from cb_helper. */ -+static inline void __disable_done(struct pme_ctx *ctx) -+{ -+ struct qm_mcc_initfq initfq; -+ int ret = 0; -+ if (!(ctx->flags & PME_CTX_FLAG_EXCLUSIVE)) { -+ /* Park fqin (exclusive is always parked) */ -+ ret = park(&ctx->us_data->fqin, &initfq); -+ /* All the conditions for park() to succeed should be met. If -+ * this fails, there's a bug (s/w or h/w). */ -+ if (ret) -+ pr_crit("pme2: park() should never fail! (%d)\n", ret); -+ } -+ do_flags(ctx, 0, 0, PME_CTX_FLAG_DISABLED, 0); -+} -+ -+int pme_ctx_disable(struct pme_ctx *ctx, u32 flags, -+ struct pme_ctx_ctrl_token *token) -+{ -+ int ret; -+ -+ /* We must not (already) be DISABLING */ -+ ret = do_flags(ctx, 0, PME_CTX_FLAG_DISABLING, -+ PME_CTX_FLAG_DISABLING, 0); -+ if (ret) -+ return ret; -+ /* Make sure the pipeline is empty */ -+ atomic_dec(&ctx->refs); -+ ret = empty_pipeline(ctx, flags); -+ if (ret) -+ goto err; -+ /* We're idle, but is the flow context flushed from PME onboard cache? -+ * If it's not flushed when the system deallocates it, that 32 bytes -+ * could be in use later when PME decides to flush a write to it. Need -+ * to make it coherent again... */ -+ if (!(ctx->flags & PME_CTX_FLAG_DIRECT)) { -+ /* Pass on wait flags (if any) but cancel any flow-context field -+ * writes (this is not the pme_ctx_ctrl_update_flow() API). */ -+ ret = __update_flow(ctx, flags & ~PME_CMD_FCW_ALL, NULL, -+ token, 1); -+ if (ret) -+ goto err; -+ return 1; -+ } -+ __disable_done(ctx); -+ return 0; -+err: -+ atomic_inc(&ctx->refs); -+ do_flags(ctx, 0, 0, 0, PME_CTX_FLAG_DISABLING); -+ wake_up(&ctx->queue); -+ return ret; -+} -+EXPORT_SYMBOL(pme_ctx_disable); -+ -+int pme_ctx_enable(struct pme_ctx *ctx) -+{ -+ int ret; -+ ret = do_flags(ctx, PME_CTX_FLAG_DISABLED, -+ PME_CTX_FLAG_DEAD | PME_CTX_FLAG_RECONFIG | -+ PME_CTX_FLAG_ENABLING, -+ PME_CTX_FLAG_ENABLING, 0); -+ if (ret) -+ return ret; -+ if (!(ctx->flags & PME_CTX_FLAG_EXCLUSIVE)) { -+ ret = qman_init_fq(&ctx->us_data->fqin, -+ QMAN_INITFQ_FLAG_SCHED, NULL); -+ if (ret) { -+ do_flags(ctx, 0, 0, 0, PME_CTX_FLAG_ENABLING); -+ return ret; -+ } -+ } -+ atomic_inc(&ctx->refs); -+ do_flags(ctx, 0, 0, 0, PME_CTX_FLAG_DISABLED | PME_CTX_FLAG_DISABLING | -+ PME_CTX_FLAG_ENABLING); -+ return 0; -+} -+EXPORT_SYMBOL(pme_ctx_enable); -+ -+int pme_ctx_reconfigure_tx(struct pme_ctx *ctx, u32 bpid, u8 qosin) -+{ -+ struct qm_mcc_initfq initfq; -+ int ret; -+ -+ ret = do_flags(ctx, PME_CTX_FLAG_DISABLED, -+ PME_CTX_FLAG_DEAD | PME_CTX_FLAG_RECONFIG, -+ PME_CTX_FLAG_RECONFIG, 0); -+ if (ret) -+ return ret; -+ memset(&initfq,0,sizeof(initfq)); -+ pme_initfq(&initfq, ctx->hw_flow, qosin, bpid, qman_fq_fqid(&ctx->fq)); -+ ret = qman_init_fq(&ctx->us_data->fqin, 0, &initfq); -+ do_flags(ctx, 0, 0, 0, PME_CTX_FLAG_RECONFIG); -+ return ret; -+} -+EXPORT_SYMBOL(pme_ctx_reconfigure_tx); -+ -+int pme_ctx_reconfigure_rx(struct pme_ctx *ctx, u8 qosout, -+ u16 dest, const struct qm_fqd_stashing *stashing) -+{ -+ return reconfigure_rx(ctx, 1, qosout, dest, stashing); -+} -+EXPORT_SYMBOL(pme_ctx_reconfigure_rx); -+ -+/* Helpers for 'ctrl' and 'work' APIs. These are used when the 'ctx' in question -+ * is EXCLUSIVE. */ -+static inline void release_exclusive(__maybe_unused struct pme_ctx *ctx) -+{ -+ unsigned long irqflags; -+ -+ BUG_ON(exclusive_ctx != ctx); -+ BUG_ON(!exclusive_refs); -+ spin_lock_irqsave(&exclusive_lock, irqflags); -+ if (!(--exclusive_refs)) { -+ exclusive_ctx = NULL; -+ pme2_exclusive_unset(); -+ wake_up(&exclusive_queue); -+ } -+ spin_unlock_irqrestore(&exclusive_lock, irqflags); -+} -+static int __try_exclusive(struct pme_ctx *ctx) -+{ -+ int ret = 0; -+ unsigned long irqflags; -+ -+ spin_lock_irqsave(&exclusive_lock, irqflags); -+ if (exclusive_refs) { -+ /* exclusivity already held, continue if we're the owner */ -+ if (exclusive_ctx != ctx) -+ ret = -EBUSY; -+ } else { -+ /* it's not currently held */ -+ ret = pme2_exclusive_set(&ctx->us_data->fqin); -+ if (!ret) -+ exclusive_ctx = ctx; -+ } -+ if (!ret) -+ exclusive_refs++; -+ spin_unlock_irqrestore(&exclusive_lock, irqflags); -+ return ret; -+} -+/* Use this macro as the wait expression because we don't want to continue -+ * looping if the reason we're failing is that we don't have CCSR access -+ * (-ENODEV). */ -+#define try_exclusive(ret, ctx) \ -+ (!(ret = __try_exclusive(ctx)) || (ret == -ENODEV)) -+static inline int get_exclusive(struct pme_ctx *ctx, __maybe_unused u32 flags) -+{ -+ int ret; -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & PME_CTX_OP_WAIT) { -+ if (flags & PME_CTX_OP_WAIT_INT) { -+ ret = -EINTR; -+ wait_event_interruptible(exclusive_queue, -+ try_exclusive(ret, ctx)); -+ } else -+ wait_event(exclusive_queue, -+ try_exclusive(ret, ctx)); -+ } else -+#endif -+ ret = __try_exclusive(ctx); -+ return ret; -+} -+ -+/* Used for 'work' APIs, convert PME->QMAN wait flags. The PME and -+ * QMAN "wait" flags have been aligned so that the below conversion should -+ * compile with good straight-line speed. */ -+static inline u32 ctrl2eq(u32 flags) -+{ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ return flags & (QMAN_ENQUEUE_FLAG_WAIT | QMAN_ENQUEUE_FLAG_WAIT_INT); -+#else -+ return flags; -+#endif -+} -+ -+static inline void release_work(struct pme_ctx *ctx) -+{ -+ if (atomic_dec_and_test(&ctx->refs)) -+ wake_up(&ctx->queue); -+} -+ -+#define BLOCK_NORMAL_WORK (PME_CTX_FLAG_DEAD | PME_CTX_FLAG_DISABLING) -+static int try_work(struct pme_ctx *ctx, u32 flags) -+{ -+ atomic_inc(&ctx->refs); -+ if (unlikely(!(flags & PME_CTX_OP_INSIDE_DISABLE) && -+ (ctx->flags & BLOCK_NORMAL_WORK))) { -+ release_work(ctx); -+ return -EIO; -+ } -+ return 0; -+} -+ -+static int get_work(struct pme_ctx *ctx, u32 flags) -+{ -+ int ret = 0; -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & PME_CTX_OP_WAIT) { -+ if (flags & PME_CTX_OP_WAIT_INT) { -+ ret = -EINTR; -+ wait_event_interruptible(ctx->queue, -+ !(ret = try_work(ctx, flags))); -+ } else -+ wait_event(ctx->queue, !try_work(ctx, flags)); -+ } else -+#endif -+ ret = try_work(ctx, flags); -+ return ret; -+} -+ -+static inline int do_work(struct pme_ctx *ctx, u32 flags, struct qm_fd *fd, -+ struct pme_ctx_token *token, struct qman_fq *orp_fq, u16 seqnum) -+{ -+ unsigned long irqflags; -+ int ret = get_work(ctx, flags); -+ if (ret) -+ return ret; -+ if (ctx->flags & PME_CTX_FLAG_EXCLUSIVE) { -+ ret = get_exclusive(ctx, flags); -+ if (ret) { -+ release_work(ctx); -+ return ret; -+ } -+ } -+ BUG_ON(sizeof(*fd) != sizeof(token->blob)); -+ memcpy(&token->blob, fd, sizeof(*fd)); -+ -+ spin_lock_irqsave(&ctx->lock, irqflags); -+ list_add_tail(&token->node, &ctx->tokens); -+ spin_unlock_irqrestore(&ctx->lock, irqflags); -+ -+ if (!orp_fq) -+ ret = qman_enqueue(&ctx->us_data->fqin, fd, ctrl2eq(flags)); -+ else -+ ret = qman_enqueue_orp(&ctx->us_data->fqin, fd, ctrl2eq(flags), -+ orp_fq, seqnum); -+ if (ret) { -+ spin_lock_irqsave(&ctx->lock, irqflags); -+ list_del(&token->node); -+ spin_unlock_irqrestore(&ctx->lock, irqflags); -+ if (ctx->flags & PME_CTX_FLAG_EXCLUSIVE) -+ release_exclusive(ctx); -+ release_work(ctx); -+ } -+ return ret; -+} -+ -+static inline int __update_flow(struct pme_ctx *ctx, u32 flags, -+ struct pme_flow *params, struct pme_ctx_ctrl_token *token, -+ int is_disabling) -+{ -+ struct qm_fd fd; -+ int ret; -+ int hw_res_used = 0; -+ struct pme_hw_residue *hw_res = pme_hw_residue_new(); -+ unsigned long irqflags; -+ -+ BUG_ON(ctx->flags & PME_CTX_FLAG_DIRECT); -+ if (!hw_res) -+ return -ENOMEM; -+ token->internal_flow_ptr = pme_hw_flow_new(); -+ if (!token->internal_flow_ptr) { -+ pme_hw_residue_free(hw_res); -+ return -ENOMEM; -+ } -+ token->base_token.cmd_type = pme_cmd_flow_write; -+ -+ flags &= ~PME_CTX_OP_PRIVATE; -+ /* The callback will want to know this */ -+ token->base_token.is_disable_flush = is_disabling ? 1 : 0; -+ flags |= (is_disabling ? PME_CTX_OP_INSIDE_DISABLE : 0); -+ spin_lock_irqsave(&ctx->lock, irqflags); -+ if (flags & PME_CTX_OP_RESETRESLEN) { -+ if (ctx->hw_residue) { -+ params->ren = 1; -+ flags |= PME_CMD_FCW_RES; -+ } else -+ flags &= ~PME_CMD_FCW_RES; -+ } -+ /* allocate residue memory if it is being added */ -+ if ((flags & PME_CMD_FCW_RES) && params->ren && !ctx->hw_residue) { -+ ctx->hw_residue = hw_res; -+ hw_res_used = 1; -+ } -+ spin_unlock_irqrestore(&ctx->lock, irqflags); -+ if (!hw_res_used) -+ pme_hw_residue_free(hw_res); -+ /* enqueue the FCW command to PME */ -+ memset(&fd, 0, sizeof(fd)); -+ if (params) -+ memcpy(token->internal_flow_ptr, params, -+ sizeof(struct pme_flow)); -+ pme_fd_cmd_fcw(&fd, flags & PME_CMD_FCW_ALL, -+ (struct pme_flow *)token->internal_flow_ptr, -+ ctx->hw_residue); -+ ret = do_work(ctx, flags, &fd, &token->base_token, NULL, 0); -+ return ret; -+} -+ -+int pme_ctx_ctrl_update_flow(struct pme_ctx *ctx, u32 flags, -+ struct pme_flow *params, struct pme_ctx_ctrl_token *token) -+{ -+ return __update_flow(ctx, flags, params, token, 0); -+} -+EXPORT_SYMBOL(pme_ctx_ctrl_update_flow); -+ -+int pme_ctx_ctrl_read_flow(struct pme_ctx *ctx, u32 flags, -+ struct pme_flow *params, struct pme_ctx_ctrl_token *token) -+{ -+ struct qm_fd fd; -+ -+ BUG_ON(ctx->flags & (PME_CTX_FLAG_DIRECT | PME_CTX_FLAG_PMTCC)); -+ token->base_token.cmd_type = pme_cmd_flow_read; -+ /* enqueue the FCR command to PME */ -+ token->usr_flow_ptr = params; -+ token->internal_flow_ptr = pme_hw_flow_new(); -+ if (!token->internal_flow_ptr) -+ return -ENOMEM; -+ memset(&fd, 0, sizeof(fd)); -+ pme_fd_cmd_fcr(&fd, (struct pme_flow *)token->internal_flow_ptr); -+ return do_work(ctx, flags, &fd, &token->base_token, NULL, 0); -+} -+EXPORT_SYMBOL(pme_ctx_ctrl_read_flow); -+ -+int pme_ctx_ctrl_nop(struct pme_ctx *ctx, u32 flags, -+ struct pme_ctx_ctrl_token *token) -+{ -+ struct qm_fd fd; -+ -+ token->base_token.cmd_type = pme_cmd_nop; -+ /* enqueue the NOP command to PME */ -+ memset(&fd, 0, sizeof(fd)); -+ qm_fd_addr_set64(&fd, (unsigned long)token); -+ pme_fd_cmd_nop(&fd); -+ return do_work(ctx, flags, &fd, &token->base_token, NULL, 0); -+} -+EXPORT_SYMBOL(pme_ctx_ctrl_nop); -+ -+static inline int __prep_scan(__maybe_unused struct pme_ctx *ctx, -+ struct qm_fd *fd, u32 args, struct pme_ctx_token *token) -+{ -+ BUG_ON(ctx->flags & PME_CTX_FLAG_PMTCC); -+ token->cmd_type = pme_cmd_scan; -+ pme_fd_cmd_scan(fd, args); -+#ifdef CONFIG_FSL_PME_BUG_4K_SCAN_REV_2_1_4 -+ if (ctx->max_scan_size) { -+ if (fd->format == qm_fd_contig || fd->format == qm_fd_sg) { -+ if (fd->length20 > ctx->max_scan_size) { -+ return -EINVAL; -+ } -+ } else if (fd->format == qm_fd_contig_big || -+ fd->format == qm_fd_sg_big) { -+ if (fd->length29 > ctx->max_scan_size) { -+ return -EINVAL; -+ } -+ } -+ } -+#endif -+ return 0; -+} -+ -+int pme_ctx_scan(struct pme_ctx *ctx, u32 flags, struct qm_fd *fd, u32 args, -+ struct pme_ctx_token *token) -+{ -+ int ret; -+ -+ ret = __prep_scan(ctx, fd, args, token); -+ if (ret) -+ return ret; -+ return do_work(ctx, flags, fd, token, NULL, 0); -+} -+EXPORT_SYMBOL(pme_ctx_scan); -+ -+int pme_ctx_scan_orp(struct pme_ctx *ctx, u32 flags, struct qm_fd *fd, u32 args, -+ struct pme_ctx_token *token, struct qman_fq *orp_fq, u16 seqnum) -+{ -+ __prep_scan(ctx, fd, args, token); -+ return do_work(ctx, flags, fd, token, orp_fq, seqnum); -+} -+EXPORT_SYMBOL(pme_ctx_scan_orp); -+ -+int pme_ctx_pmtcc(struct pme_ctx *ctx, u32 flags, struct qm_fd *fd, -+ struct pme_ctx_token *token) -+{ -+ BUG_ON(!(ctx->flags & PME_CTX_FLAG_PMTCC)); -+ token->cmd_type = pme_cmd_pmtcc; -+ pme_fd_cmd_pmtcc(fd); -+ return do_work(ctx, flags, fd, token, NULL, 0); -+} -+EXPORT_SYMBOL(pme_ctx_pmtcc); -+ -+int pme_ctx_exclusive_inc(struct pme_ctx *ctx, u32 flags) -+{ -+ return get_exclusive(ctx, flags); -+} -+EXPORT_SYMBOL(pme_ctx_exclusive_inc); -+ -+void pme_ctx_exclusive_dec(struct pme_ctx *ctx) -+{ -+ release_exclusive(ctx); -+} -+EXPORT_SYMBOL(pme_ctx_exclusive_dec); -+ -+/* The 99.99% case is that enqueues happen in order or they get order-restored -+ * by the ORP, and so dequeues of responses happen in order too, so our FIFO -+ * linked-list of tokens is append-on-enqueue and pop-on-dequeue, and all's -+ * well. -+ * -+ * *EXCEPT*, if ever an enqueue gets rejected ... what then happens is that we -+ * have dequeues and ERNs to deal with, and the order we see them in is not -+ * necessarily the linked-list order. So we need to handle this in DQRR and MR -+ * callbacks, without sacrificing fast-path performance. Ouch. -+ * -+ * We use pop_matching_token() to take care of the mess (inlined, of course). */ -+#define MATCH(fd1,fd2) \ -+ ((qm_fd_addr_get64(fd1) == qm_fd_addr_get64(fd2)) && \ -+ ((fd1)->opaque == (fd2)->opaque)) -+static inline struct pme_ctx_token *pop_matching_token(struct pme_ctx *ctx, -+ const struct qm_fd *fd) -+{ -+ struct pme_ctx_token *token; -+ const struct qm_fd *t_fd; -+ unsigned long irqflags; -+ -+ /* The fast-path case is that the for() loop actually degenerates into; -+ * token = list_first_entry(); -+ * if (likely(MATCH())) -+ * [done] -+ * The penalty of the slow-path case is the for() loop plus the fact -+ * we're optimising for a "likely" match first time, which might hurt -+ * when that assumption is wrong a few times in succession. */ -+ spin_lock_irqsave(&ctx->lock, irqflags); -+ list_for_each_entry(token, &ctx->tokens, node) { -+ t_fd = (const struct qm_fd *)&token->blob[0]; -+ if (likely(MATCH(t_fd, fd))) { -+ list_del(&token->node); -+ goto found; -+ } -+ } -+ token = NULL; -+ pr_err("PME2 Could not find matching token!\n"); -+ BUG(); -+found: -+ spin_unlock_irqrestore(&ctx->lock, irqflags); -+ return token; -+} -+ -+static inline void cb_helper(__always_unused struct qman_portal *portal, -+ struct pme_ctx *ctx, const struct qm_fd *fd, int error) -+{ -+ struct pme_ctx_token *token; -+ struct pme_ctx_ctrl_token *ctrl_token; -+ -+ /* Resist the urge to use "unlikely" - 'error' is a constant param to an -+ * inline fn, so the compiler can collapse this completely. */ -+ if (error) -+ do_flags(ctx, 0, 0, PME_CTX_FLAG_DEAD, 0); -+ token = pop_matching_token(ctx, fd); -+ if (likely(token->cmd_type == pme_cmd_scan)) -+ ctx->cb(ctx, fd, token); -+ else if (token->cmd_type == pme_cmd_pmtcc) -+ ctx->cb(ctx, fd, token); -+ else { -+ /* outcast ctx and call supplied callback */ -+ ctrl_token = container_of(token, struct pme_ctx_ctrl_token, -+ base_token); -+ if (token->cmd_type == pme_cmd_flow_write) { -+ /* Release the allocated flow context */ -+ pme_hw_flow_free(ctrl_token->internal_flow_ptr); -+ /* Is this pme_ctx_disable() completion? */ -+ if (token->is_disable_flush) -+ __disable_done(ctx); -+ } else if (token->cmd_type == pme_cmd_flow_read) { -+ /* Copy read result */ -+ memcpy(ctrl_token->usr_flow_ptr, -+ ctrl_token->internal_flow_ptr, -+ sizeof(struct pme_flow)); -+ /* Release the allocated flow context */ -+ pme_hw_flow_free(ctrl_token->internal_flow_ptr); -+ } -+ ctrl_token->cb(ctx, fd, ctrl_token); -+ } -+ /* Consume the frame */ -+ if (ctx->flags & PME_CTX_FLAG_EXCLUSIVE) -+ release_exclusive(ctx); -+ if (atomic_dec_and_test(&ctx->refs)) -+ wake_up(&ctx->queue); -+} -+ -+/* TODO: this scheme does not allow PME receivers to use held-active at all. Eg. -+ * there's no configuration of held-active for 'fq', and if there was, there's -+ * (a) nothing in the cb_dqrr() to support "park" or "defer" logic, and (b) -+ * nothing in cb_fqs() to support a delayed FQPN (DCAP_PK) notification. */ -+static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *portal, -+ struct qman_fq *fq, const struct qm_dqrr_entry *dq) -+{ -+ u8 status = (u8)pme_fd_res_status(&dq->fd); -+ u8 flags = pme_fd_res_flags(&dq->fd); -+ struct pme_ctx *ctx = (struct pme_ctx *)fq; -+ -+ /* Put context into dead state is an unreliable or serious error is -+ * received -+ */ -+ if (unlikely(flags & PME_STATUS_UNRELIABLE)) -+ cb_helper(portal, ctx, &dq->fd, 1); -+ else if (unlikely((serious_error_vec[status]))) -+ cb_helper(portal, ctx, &dq->fd, 1); -+ else -+ cb_helper(portal, ctx, &dq->fd, 0); -+ -+ return qman_cb_dqrr_consume; -+} -+ -+static void cb_ern(__always_unused struct qman_portal *portal, -+ struct qman_fq *fq, const struct qm_mr_entry *mr) -+{ -+ struct pme_ctx *ctx; -+ struct pme_nostash *data; -+ struct pme_ctx_token *token; -+ -+ data = container_of(fq, struct pme_nostash, fqin); -+ ctx = data->parent; -+ -+ token = pop_matching_token(ctx, &mr->ern.fd); -+ if (likely(token->cmd_type == pme_cmd_scan)) { -+ BUG_ON(!ctx->ern_cb); -+ ctx->ern_cb(ctx, mr, token); -+ } else if (token->cmd_type == pme_cmd_pmtcc) { -+ BUG_ON(!ctx->ern_cb); -+ ctx->ern_cb(ctx, mr, token); -+ } else { -+ struct pme_ctx_ctrl_token *ctrl_token; -+ /* outcast ctx and call supplied callback */ -+ ctrl_token = container_of(token, struct pme_ctx_ctrl_token, -+ base_token); -+ if (token->cmd_type == pme_cmd_flow_write) { -+ /* Release the allocated flow context */ -+ pme_hw_flow_free(ctrl_token->internal_flow_ptr); -+ } else if (token->cmd_type == pme_cmd_flow_read) { -+ /* Copy read result */ -+ memcpy(ctrl_token->usr_flow_ptr, -+ ctrl_token->internal_flow_ptr, -+ sizeof(struct pme_flow)); -+ /* Release the allocated flow context */ -+ pme_hw_flow_free(ctrl_token->internal_flow_ptr); -+ } -+ BUG_ON(!ctrl_token->ern_cb); -+ ctrl_token->ern_cb(ctx, mr, ctrl_token); -+ } -+ /* Consume the frame */ -+ if (ctx->flags & PME_CTX_FLAG_EXCLUSIVE) -+ release_exclusive(ctx); -+ if (atomic_dec_and_test(&ctx->refs)) -+ wake_up(&ctx->queue); -+} -+ -+static void cb_fqs(__always_unused struct qman_portal *portal, -+ __always_unused struct qman_fq *fq, -+ const struct qm_mr_entry *mr) -+{ -+ u8 verb = mr->verb & QM_MR_VERB_TYPE_MASK; -+ if (verb == QM_MR_VERB_FQRNI) -+ return; -+ /* nothing else is supposed to occur */ -+ BUG(); -+} -diff --git a/drivers/staging/fsl_pme2/pme2_low.c b/drivers/staging/fsl_pme2/pme2_low.c -new file mode 100644 -index 0000000..cb54cf4 ---- /dev/null -+++ b/drivers/staging/fsl_pme2/pme2_low.c -@@ -0,0 +1,275 @@ -+/* 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 "pme2_private.h" -+ -+MODULE_AUTHOR("Geoff Thorpe"); -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("FSL PME2 (p4080) device usage"); -+ -+#define PME_RESIDUE_SIZE 128 -+#define PME_RESIDUE_ALIGN 64 -+#define PME_FLOW_SIZE sizeof(struct pme_flow) -+#define PME_FLOW_ALIGN 32 -+static struct kmem_cache *slab_residue; -+static struct kmem_cache *slab_flow; -+static struct kmem_cache *slab_fq; -+ -+/* Hack to support "pme_map()". The point of this is that dma_map_single() now -+ * requires a non-NULL device, so the idea is that address mapping must be -+ * device-sensitive. Now the PAMU IO-MMU already takes care of this, as can be -+ * seen by the device-tree structure generated by the hypervisor (each portal -+ * node has sub-nodes for each h/w end-point it provides access to, and each -+ * sub-node has its own LIODN configuration). So we just need to map cpu -+ * pointers to (guest-)physical address and the PAMU takes care of the rest, so -+ * this doesn't need to be portal-sensitive nor device-sensitive. */ -+static struct platform_device *pdev; -+ -+static int pme2_low_init(void) -+{ -+ int ret = -ENOMEM; -+ -+ slab_residue = kmem_cache_create("pme2_residue", PME_RESIDUE_SIZE, -+ PME_RESIDUE_ALIGN, SLAB_HWCACHE_ALIGN, NULL); -+ if (!slab_residue) -+ goto end; -+ slab_flow = kmem_cache_create("pme2_flow", PME_FLOW_SIZE, -+ PME_FLOW_ALIGN, 0, NULL); -+ if (!slab_flow) -+ goto end; -+ slab_fq = kmem_cache_create("pme2_fqslab", sizeof(struct qman_fq), -+ __alignof__(struct qman_fq), SLAB_HWCACHE_ALIGN, NULL); -+ if (!slab_fq) -+ goto end; -+ ret = -ENODEV; -+ pdev = platform_device_alloc("pme", -1); -+ if (!pdev) -+ goto end; -+ if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(40))) -+ goto end; -+ if (platform_device_add(pdev)) -+ goto end; -+ return 0; -+end: -+ if (pdev) { -+ platform_device_put(pdev); -+ pdev = NULL; -+ } -+ if (slab_flow) { -+ kmem_cache_destroy(slab_flow); -+ slab_flow = NULL; -+ } -+ if (slab_residue) { -+ kmem_cache_destroy(slab_residue); -+ slab_residue = NULL; -+ } -+ if (slab_fq) { -+ kmem_cache_destroy(slab_fq); -+ slab_fq = NULL; -+ } -+ return ret; -+} -+ -+static void pme2_low_exit(void) -+{ -+ platform_device_del(pdev); -+ platform_device_put(pdev); -+ pdev = NULL; -+ kmem_cache_destroy(slab_fq); -+ kmem_cache_destroy(slab_flow); -+ kmem_cache_destroy(slab_residue); -+ slab_fq = slab_flow = slab_residue = NULL; -+} -+ -+module_init(pme2_low_init); -+module_exit(pme2_low_exit); -+ -+struct qman_fq *slabfq_alloc(void) -+{ -+ return kmem_cache_alloc(slab_fq, GFP_KERNEL); -+} -+ -+void slabfq_free(struct qman_fq *fq) -+{ -+ kmem_cache_free(slab_fq, fq); -+} -+ -+/***********************/ -+/* low-level functions */ -+/***********************/ -+ -+struct pme_hw_residue *pme_hw_residue_new(void) -+{ -+ return kmem_cache_alloc(slab_residue, GFP_KERNEL); -+} -+EXPORT_SYMBOL(pme_hw_residue_new); -+ -+void pme_hw_residue_free(struct pme_hw_residue *p) -+{ -+ kmem_cache_free(slab_residue, p); -+} -+EXPORT_SYMBOL(pme_hw_residue_free); -+ -+struct pme_hw_flow *pme_hw_flow_new(void) -+{ -+ struct pme_flow *flow = kmem_cache_zalloc(slab_flow, GFP_KERNEL); -+ return (struct pme_hw_flow *)flow; -+} -+EXPORT_SYMBOL(pme_hw_flow_new); -+ -+void pme_hw_flow_free(struct pme_hw_flow *p) -+{ -+ kmem_cache_free(slab_flow, p); -+} -+EXPORT_SYMBOL(pme_hw_flow_free); -+ -+static const struct pme_flow default_sw_flow = { -+ .sos = 1, -+ .srvm = 0, -+ .esee = 1, -+ .ren = 0, -+ .rlen = 0, -+ .seqnum_hi = 0, -+ .seqnum_lo = 0, -+ .sessionid = 0x7ffffff, -+ .rptr_hi = 0, -+ .rptr_lo = 0, -+ .clim = 0xffff, -+ .mlim = 0xffff -+}; -+ -+void pme_sw_flow_init(struct pme_flow *flow) -+{ -+ memcpy(flow, &default_sw_flow, sizeof(*flow)); -+} -+EXPORT_SYMBOL(pme_sw_flow_init); -+ -+void pme_initfq(struct qm_mcc_initfq *initfq, struct pme_hw_flow *flow, u8 qos, -+ u8 rbpid, u32 rfqid) -+{ -+ struct pme_context_a *pme_a = -+ (struct pme_context_a *)&initfq->fqd.context_a; -+ struct pme_context_b *pme_b = -+ (struct pme_context_b *)&initfq->fqd.context_b; -+ -+ initfq->we_mask = QM_INITFQ_WE_DESTWQ | QM_INITFQ_WE_CONTEXTA | -+ QM_INITFQ_WE_CONTEXTB; -+ initfq->fqd.dest.channel = qm_channel_pme; -+ initfq->fqd.dest.wq = qos; -+ if (flow) { -+ dma_addr_t fcp = flow_map((struct pme_flow *)flow); -+ pme_a->mode = pme_mode_flow; -+ pme_context_a_set64(pme_a, fcp); -+ } else { -+ pme_a->mode = pme_mode_direct; -+ pme_context_a_set64(pme_a, 0); -+ } -+ pme_b->rbpid = rbpid; -+ pme_b->rfqid = rfqid; -+} -+EXPORT_SYMBOL(pme_initfq); -+ -+void pme_fd_cmd_nop(struct qm_fd *fd) -+{ -+ struct pme_cmd_nop *nop = (struct pme_cmd_nop *)&fd->cmd; -+ nop->cmd = pme_cmd_nop; -+} -+EXPORT_SYMBOL(pme_fd_cmd_nop); -+ -+void pme_fd_cmd_fcw(struct qm_fd *fd, u8 flags, struct pme_flow *flow, -+ struct pme_hw_residue *residue) -+{ -+ dma_addr_t f; -+ struct pme_cmd_flow_write *fcw = (struct pme_cmd_flow_write *)&fd->cmd; -+ -+ BUG_ON(!flow); -+ BUG_ON((unsigned long)flow & 31); -+ fcw->cmd = pme_cmd_flow_write; -+ fcw->flags = flags; -+ if (flags & PME_CMD_FCW_RES) { -+ if (residue) { -+ dma_addr_t rptr = residue_map(residue); -+ BUG_ON(!residue); -+ BUG_ON((unsigned long)residue & 63); -+ pme_flow_rptr_set64(flow, rptr); -+ } else -+ pme_flow_rptr_set64(flow, 0); -+ } -+ f = flow_map(flow); -+ qm_fd_addr_set64(fd, f); -+ fd->format = qm_fd_contig; -+ fd->offset = 0; -+ fd->length20 = sizeof(*flow); -+} -+EXPORT_SYMBOL(pme_fd_cmd_fcw); -+ -+void pme_fd_cmd_fcr(struct qm_fd *fd, struct pme_flow *flow) -+{ -+ dma_addr_t f; -+ struct pme_cmd_flow_read *fcr = (struct pme_cmd_flow_read *)&fd->cmd; -+ -+ BUG_ON(!flow); -+ BUG_ON((unsigned long)flow & 31); -+ fcr->cmd = pme_cmd_flow_read; -+ f = flow_map(flow); -+ qm_fd_addr_set64(fd, f); -+ fd->format = qm_fd_contig; -+ fd->offset = 0; -+ fd->length20 = sizeof(*flow); -+} -+EXPORT_SYMBOL(pme_fd_cmd_fcr); -+ -+void pme_fd_cmd_pmtcc(struct qm_fd *fd) -+{ -+ struct pme_cmd_pmtcc *pmtcc = (struct pme_cmd_pmtcc *)&fd->cmd; -+ pmtcc->cmd = pme_cmd_pmtcc; -+} -+EXPORT_SYMBOL(pme_fd_cmd_pmtcc); -+ -+void pme_fd_cmd_scan(struct qm_fd *fd, u32 args) -+{ -+ struct pme_cmd_scan *scan = (struct pme_cmd_scan *)&fd->cmd; -+ fd->cmd = args; -+ scan->cmd = pme_cmd_scan; -+} -+EXPORT_SYMBOL(pme_fd_cmd_scan); -+ -+dma_addr_t pme_map(void *ptr) -+{ -+ return dma_map_single(&pdev->dev, ptr, 1, DMA_BIDIRECTIONAL); -+} -+EXPORT_SYMBOL(pme_map); -+ -+int pme_map_error(dma_addr_t dma_addr) -+{ -+ return dma_mapping_error(&pdev->dev, dma_addr); -+} -+EXPORT_SYMBOL(pme_map_error); -diff --git a/drivers/staging/fsl_pme2/pme2_private.h b/drivers/staging/fsl_pme2/pme2_private.h -new file mode 100644 -index 0000000..1a9cb03 ---- /dev/null -+++ b/drivers/staging/fsl_pme2/pme2_private.h -@@ -0,0 +1,214 @@ -+/* 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 "pme2_sys.h" -+#include -+ -+#undef PME2_DEBUG -+ -+#ifdef PME2_DEBUG -+#define PMEPRINFO(fmt, args...) pr_info("PME2: %s: " fmt, __func__, ## args) -+#else -+#define PMEPRINFO(fmt, args...) -+#endif -+ -+#define PMEPRERR(fmt, args...) pr_err("PME2: %s: " fmt, __func__, ## args) -+#define PMEPRCRIT(fmt, args...) pr_crit("PME2: %s: " fmt, __func__, ## args) -+ -+#ifdef CONFIG_FSL_PME2_CTRL -+/* Hooks */ -+int pme2_create_sysfs_dev_files(struct platform_device *ofdev); -+void pme2_remove_sysfs_dev_files(struct platform_device *ofdev); -+void accumulator_update_interval(u32 interval); -+#endif -+ -+static inline void set_fd_addr(struct qm_fd *fd, dma_addr_t addr) -+{ -+ qm_fd_addr_set64(fd, addr); -+} -+static inline dma_addr_t get_fd_addr(const struct qm_fd *fd) -+{ -+ return (dma_addr_t)qm_fd_addr_get64(fd); -+} -+static inline void set_sg_addr(struct qm_sg_entry *sg, dma_addr_t addr) -+{ -+ qm_sg_entry_set64(sg, addr); -+} -+static inline dma_addr_t get_sg_addr(const struct qm_sg_entry *sg) -+{ -+ return (dma_addr_t)qm_sg_entry_get64(sg); -+} -+ -+/******************/ -+/* Datapath types */ -+/******************/ -+ -+enum pme_mode { -+ pme_mode_direct = 0x00, -+ pme_mode_flow = 0x80 -+}; -+ -+struct pme_context_a { -+ enum pme_mode mode:8; -+ u8 __reserved; -+ /* Flow Context pointer (48-bit), ignored if mode==direct */ -+ u16 flow_hi; -+ u32 flow_lo; -+} __packed; -+static inline u64 pme_context_a_get64(const struct pme_context_a *p) -+{ -+ return ((u64)p->flow_hi << 32) | (u64)p->flow_lo; -+} -+/* Macro, so we compile better if 'v' isn't always 64-bit */ -+#define pme_context_a_set64(p, v) \ -+ do { \ -+ struct pme_context_a *__p931 = (p); \ -+ __p931->flow_hi = upper_32_bits(v); \ -+ __p931->flow_lo = lower_32_bits(v); \ -+ } while (0) -+ -+struct pme_context_b { -+ u32 rbpid:8; -+ u32 rfqid:24; -+} __packed; -+ -+ -+/* This is the 32-bit frame "cmd/status" field, sent to PME */ -+union pme_cmd { -+ struct pme_cmd_nop { -+ enum pme_cmd_type cmd:3; -+ } nop; -+ struct pme_cmd_flow_read { -+ enum pme_cmd_type cmd:3; -+ } fcr; -+ struct pme_cmd_flow_write { -+ enum pme_cmd_type cmd:3; -+ u8 __reserved:5; -+ u8 flags; /* See PME_CMD_FCW_*** */ -+ } __packed fcw; -+ struct pme_cmd_pmtcc { -+ enum pme_cmd_type cmd:3; -+ } pmtcc; -+ struct pme_cmd_scan { -+ union { -+ struct { -+ enum pme_cmd_type cmd:3; -+ u8 flags:5; /* See PME_CMD_SCAN_*** */ -+ } __packed; -+ }; -+ u8 set; -+ u16 subset; -+ } __packed scan; -+}; -+ -+/* The exported macro forms a "scan_args" u32 from 3 inputs, these private -+ * inlines do the inverse, if you need to crack one apart. */ -+static inline u8 scan_args_get_flags(u32 args) -+{ -+ return args >> 24; -+} -+static inline u8 scan_args_get_set(u32 args) -+{ -+ return (args >> 16) & 0xff; -+} -+static inline u16 scan_args_get_subset(u32 args) -+{ -+ return args & 0xffff; -+} -+ -+/* Hook from pme2_high to pme2_low */ -+struct qman_fq *slabfq_alloc(void); -+void slabfq_free(struct qman_fq *fq); -+ -+/* Hook from pme2_high to pme2_ctrl */ -+int pme2_have_control(void); -+int pme2_exclusive_set(struct qman_fq *fq); -+int pme2_exclusive_unset(void); -+ -+#define DECLARE_GLOBAL(name, t, mt, def, desc) \ -+ static t name = def; \ -+ module_param(name, mt, 0644); \ -+ MODULE_PARM_DESC(name, desc ", default: " __stringify(def)); -+ -+/* Constants used by the SRE ioctl. */ -+#define PME_PMFA_SRE_POLL_MS 100 -+#define PME_PMFA_SRE_INDEX_MAX (1 << 27) -+#define PME_PMFA_SRE_INC_MAX (1 << 12) -+#define PME_PMFA_SRE_REP_MAX (1 << 28) -+#define PME_PMFA_SRE_INTERVAL_MAX (1 << 12) -+ -+/* Encapsulations for mapping */ -+#define flow_map(flow) \ -+({ \ -+ struct pme_flow *__f913 = (flow); \ -+ pme_map(__f913); \ -+}) -+ -+#define residue_map(residue) \ -+({ \ -+ struct pme_hw_residue *__f913 = (residue); \ -+ pme_map(__f913); \ -+}) -+ -+/* 4k minus residue */ -+#define PME_MAX_SCAN_SIZE_BUG_2_1_4 (4095 - 127) -+ -+#define PME_PM_IP_REV_1_IP_MJ_MASK 0x0000ff00UL -+#define PME_PM_IP_REV_1_IP_MJ_SHIFT 8UL -+#define PME_PM_IP_REV_1_IP_MN_MASK 0x000000ffUL -+#define PME_PM_IP_REV_1_IP_MN_SHIFT 0UL -+#define PME_PM_IP_REV_2_IP_ERR_MASK 0x0000ff00UL -+#define PME_PM_IP_REV_2_IP_ERR_SHIFT 8UL -+ -+static inline int get_major_rev(u32 pme_rev1) -+{ -+ return (pme_rev1 & PME_PM_IP_REV_1_IP_MJ_MASK) >> -+ PME_PM_IP_REV_1_IP_MJ_SHIFT; -+} -+ -+static inline int get_minor_rev(u32 pme_rev1) -+{ -+ return (pme_rev1 & PME_PM_IP_REV_1_IP_MN_MASK) >> -+ PME_PM_IP_REV_1_IP_MN_SHIFT; -+} -+ -+static inline int get_errata_rev(u32 pme_rev2) -+{ -+ return (pme_rev2 & PME_PM_IP_REV_2_IP_ERR_MASK) >> -+ PME_PM_IP_REV_2_IP_ERR_SHIFT; -+} -+ -+static inline int is_version_2_1_4(u32 pme_rev1, u32 pme_rev2) -+{ -+ return (get_major_rev(pme_rev1) == 2) && -+ (get_minor_rev(pme_rev1) == 1) && -+ (get_errata_rev(pme_rev2) == 4); -+} -diff --git a/drivers/staging/fsl_pme2/pme2_regs.h b/drivers/staging/fsl_pme2/pme2_regs.h -new file mode 100644 -index 0000000..1894b02 ---- /dev/null -+++ b/drivers/staging/fsl_pme2/pme2_regs.h -@@ -0,0 +1,173 @@ -+/* Copyright 2009-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 PME2_REGS_H -+#define PME2_REGS_H -+ -+#define PME_REG_ISR 0x000 -+#define PME_REG_IER 0x004 -+#define PME_REG_ISDR 0x008 -+#define PME_REG_IIR 0x00C -+#define PME_REG_RLL 0x014 -+#define PME_REG_CDCR 0x018 -+#define PME_REG_TRUNCI 0x024 -+#define PME_REG_RBC 0x028 -+#define PME_REG_ESR 0x02C -+#define PME_REG_ECR0 0x030 -+#define PME_REG_ECR1 0x034 -+#define PME_REG_EFQC 0x050 -+#define PME_REG_FACONF 0x060 -+#define PME_REG_PMSTAT 0x064 -+#define PME_REG_FAMCR 0x068 -+#define PME_REG_PMTR 0x06C -+#define PME_REG_PEHD 0x074 -+#define PME_REG_BSC0 0x080 -+#define PME_REG_BSC1 0x084 -+#define PME_REG_BSC2 0x088 -+#define PME_REG_BSC3 0x08C -+#define PME_REG_BSC4 0x090 -+#define PME_REG_BSC5 0x094 -+#define PME_REG_BSC6 0x098 -+#define PME_REG_BSC7 0x09C -+#define PME_REG_QMBFD0 0x0E0 -+#define PME_REG_QMBFD1 0x0E4 -+#define PME_REG_QMBFD2 0x0E8 -+#define PME_REG_QMBFD3 0x0EC -+#define PME_REG_QMBCTXTAH 0x0F0 -+#define PME_REG_QMBCTXTAL 0x0F4 -+#define PME_REG_QMBCTXTB 0x0F8 -+#define PME_REG_QMBCTL 0x0FC -+#define PME_REG_ECC1BES 0x100 -+#define PME_REG_ECC2BES 0x104 -+#define PME_REG_ECCADDR 0x110 -+#define PME_REG_ECCCODE 0x118 -+#define PME_REG_TBT0ECC1TH 0x180 -+#define PME_REG_TBT0ECC1EC 0x184 -+#define PME_REG_TBT1ECC1TH 0x188 -+#define PME_REG_TBT1ECC1EC 0x18C -+#define PME_REG_VLT0ECC1TH 0x190 -+#define PME_REG_VLT0ECC1EC 0x194 -+#define PME_REG_VLT1ECC1TH 0x198 -+#define PME_REG_VLT1ECC1EC 0x19C -+#define PME_REG_CMECC1TH 0x1A0 -+#define PME_REG_CMECC1EC 0x1A4 -+#define PME_REG_DXCMECC1TH 0x1B0 -+#define PME_REG_DXCMECC1EC 0x1B4 -+#define PME_REG_DXEMECC1TH 0x1C0 -+#define PME_REG_DXEMECC1EC 0x1C4 -+#define PME_REG_STNIB 0x200 -+#define PME_REG_STNIS 0x204 -+#define PME_REG_STNTH1 0x208 -+#define PME_REG_STNTH2 0x20C -+#define PME_REG_STNTHV 0x210 -+#define PME_REG_STNTHS 0x214 -+#define PME_REG_STNCH 0x218 -+#define PME_REG_SWDB 0x21C -+#define PME_REG_KVLTS 0x220 -+#define PME_REG_KEC 0x224 -+#define PME_REG_STNPM 0x280 -+#define PME_REG_STNS1M 0x284 -+#define PME_REG_DRCIC 0x288 -+#define PME_REG_DRCMC 0x28C -+#define PME_REG_STNPMR 0x290 -+#define PME_REG_PDSRBAH 0x2A0 -+#define PME_REG_PDSRBAL 0x2A4 -+#define PME_REG_DMCR 0x2A8 -+#define PME_REG_DEC0 0x2AC -+#define PME_REG_DEC1 0x2B0 -+#define PME_REG_DLC 0x2C0 -+#define PME_REG_STNDSR 0x300 -+#define PME_REG_STNESR 0x304 -+#define PME_REG_STNS1R 0x308 -+#define PME_REG_STNOB 0x30C -+#define PME_REG_SCBARH 0x310 -+#define PME_REG_SCBARL 0x314 -+#define PME_REG_SMCR 0x318 -+#define PME_REG_SREC 0x320 -+#define PME_REG_ESRP 0x328 -+#define PME_REG_SRRV0 0x338 -+#define PME_REG_SRRV1 0x33C -+#define PME_REG_SRRV2 0x340 -+#define PME_REG_SRRV3 0x344 -+#define PME_REG_SRRV4 0x348 -+#define PME_REG_SRRV5 0x34C -+#define PME_REG_SRRV6 0x350 -+#define PME_REG_SRRV7 0x354 -+#define PME_REG_SRRFI 0x358 -+#define PME_REG_SRRI 0x360 -+#define PME_REG_SRRR 0x364 -+#define PME_REG_SRRWC 0x368 -+#define PME_REG_SFRCC 0x36C -+#define PME_REG_SEC1 0x370 -+#define PME_REG_SEC2 0x374 -+#define PME_REG_SEC3 0x378 -+#define PME_REG_MIA_BYC 0x380 -+#define PME_REG_MIA_BLC 0x384 -+#define PME_REG_MIA_CE 0x388 -+#define PME_REG_MIA_CR 0x390 -+#define PME_REG_PPIDMR0 0x800 -+#define PME_REG_PPIDMR1 0x804 -+#define PME_REG_PPIDMR2 0x808 -+#define PME_REG_PPIDMR3 0x80C -+#define PME_REG_PPIDMR4 0x810 -+#define PME_REG_PPIDMR5 0x814 -+#define PME_REG_PPIDMR6 0x818 -+#define PME_REG_PPIDMR7 0x81C -+#define PME_REG_PPIDMR8 0x820 -+#define PME_REG_PPIDMR9 0x824 -+#define PME_REG_PPIDMR10 0x828 -+#define PME_REG_PPIDMR11 0x82C -+#define PME_REG_PPIDMR12 0x830 -+#define PME_REG_PPIDMR13 0x834 -+#define PME_REG_PPIDMR14 0x838 -+#define PME_REG_PPIDMR15 0x83C -+#define PME_REG_PPIDMR16 0x840 -+#define PME_REG_PPIDMR17 0x844 -+#define PME_REG_PPIDMR18 0x848 -+#define PME_REG_PPIDMR19 0x84C -+#define PME_REG_PPIDMR20 0x850 -+#define PME_REG_PPIDMR21 0x854 -+#define PME_REG_PPIDMR22 0x858 -+#define PME_REG_PPIDMR23 0x85C -+#define PME_REG_PPIDMR24 0x860 -+#define PME_REG_PPIDMR25 0x864 -+#define PME_REG_PPIDMR26 0x868 -+#define PME_REG_PPIDMR27 0x86C -+#define PME_REG_PPIDMR28 0x870 -+#define PME_REG_PPIDMR29 0x874 -+#define PME_REG_PPIDMR30 0x878 -+#define PME_REG_PPIDMR31 0x87C -+#define PME_REG_SRCIDR 0xA00 -+#define PME_REG_LIODNR 0xA0C -+#define PME_REG_PM_IP_REV1 0xBF8 -+#define PME_REG_PM_IP_REV2 0xBFC -+ -+#endif /* REGS_H */ -diff --git a/drivers/staging/fsl_pme2/pme2_sample_db.c b/drivers/staging/fsl_pme2/pme2_sample_db.c -new file mode 100644 -index 0000000..75fef4e ---- /dev/null -+++ b/drivers/staging/fsl_pme2/pme2_sample_db.c -@@ -0,0 +1,453 @@ -+/* Copyright 2009-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 "pme2_test.h" -+ -+static u8 pme_db[] = { -+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+/* Rev 2.2 */ -+/* 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, -+ 0x48, 0x41, 0x40, 0x20, 0x00, 0x11, */ -+/* Rev 2.1 */ -+ 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, -+ 0x90, 0x41, 0x40, 0x20, 0x00, 0x11, -+/* Rev 2.0 */ -+/* 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, -+ 0x20, 0x41, 0x40, 0x20, 0x00, 0x11, */ -+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+/* Rev 2.0 */ -+/* 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, -+ 0x48, 0x41, 0xff, 0x81, 0x00, 0x00, */ -+/* Rev 2.1 */ -+ 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, -+ 0x90, 0x41, 0xff, 0x81, 0x00, 0x00, -+/* Rev 2.0 */ -+/* 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, -+ 0x20, 0x41, 0xff, 0x81, 0x00, 0x00, */ -+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, -+ 0x01, 0xff, 0x80, 0x00, 0x41, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x06, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, -+ 0x04, 0x05, 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, 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, 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 u8 db_read[] = { -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, -+/* Rev 2.2 */ -+/* 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, -+ 0x48, 0x41 */ -+/* Rev 2.1 */ -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, -+ 0x90, 0x41 -+/* Rev 2.0 */ -+/* 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, -+ 0x20, 0x41 */ -+}; -+ -+static u8 db_read_expected_result[] = { -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, -+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, -+/* Rev 2.2 */ -+/* 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, -+ 0x48, 0x41, 0x40, 0x20, 0x00, 0x11*/ -+/* Rev 2.1 */ -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, -+ 0x90, 0x41, 0x40, 0x20, 0x00, 0x11 -+/* Rev 2.0 */ -+/* 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, -+ 0x20, 0x41, 0x40, 0x20, 0x00, 0x11*/ -+}; -+ -+struct pmtcc_ctx { -+ struct pme_ctx base_ctx; -+ struct qm_fd result_fd; -+ struct completion done; -+ u8 ern; -+}; -+ -+static void pmtcc_cb(struct pme_ctx *ctx, const struct qm_fd *fd, -+ struct pme_ctx_token *ctx_token) -+{ -+ struct pmtcc_ctx *my_ctx = (struct pmtcc_ctx *)ctx; -+ memcpy(&my_ctx->result_fd, fd, sizeof(*fd)); -+ complete(&my_ctx->done); -+} -+ -+static void pmtcc_ern_cb(struct pme_ctx *ctx, const struct qm_mr_entry *mr, -+ struct pme_ctx_token *ctx_token) -+{ -+ struct pmtcc_ctx *my_ctx = (struct pmtcc_ctx *)ctx; -+ my_ctx->result_fd = mr->ern.fd; -+ my_ctx->ern = 1; -+ complete(&my_ctx->done); -+} -+ -+#define FIRST_PMTCC 56 -+int pme2_clear_sample_db(void) -+{ -+ struct pmtcc_ctx ctx = { -+ .base_ctx.cb = pmtcc_cb, -+ .base_ctx.ern_cb = pmtcc_ern_cb, -+ .ern = 0 -+ }; -+ struct qm_fd fd; -+ int ret = 0; -+ enum pme_status status; -+ struct pme_ctx_token token; -+ void *mem; -+ struct cpumask backup_mask = current->cpus_allowed; -+ struct cpumask new_mask = *qman_affine_cpus(); -+ -+ cpumask_and(&new_mask, &new_mask, bman_affine_cpus()); -+ ret = set_cpus_allowed_ptr(current, &new_mask); -+ if (ret) { -+ pr_info("cleanr_sample_db: can't set cpumask\n"); -+ goto _clear_0; -+ } -+ init_completion(&ctx.done); -+ ret = pme_ctx_init(&ctx.base_ctx, -+ PME_CTX_FLAG_EXCLUSIVE | -+ PME_CTX_FLAG_PMTCC | -+ PME_CTX_FLAG_LOCAL, 0, 4, 4, 0, NULL); -+ if (ret) { -+ pr_err("clear_sample_db: can't init ctx\n"); -+ goto _clear_1; -+ } -+ -+ /* enable the context */ -+ ret = pme_ctx_enable(&ctx.base_ctx); -+ if (ret) { -+ pr_err("clear_sample_db: can't enable ctx\n"); -+ goto _clear_2; -+ } -+ -+ /* Write the database */ -+ memset(&fd, 0, sizeof(struct qm_fd)); -+ mem = kmalloc(FIRST_PMTCC, GFP_KERNEL); -+ if (!mem) -+ goto _clear_3; -+ memcpy(mem, pme_db, FIRST_PMTCC); -+ -+ fd.length20 = FIRST_PMTCC; -+ qm_fd_addr_set64(&fd, pme_map(mem)); -+ -+ ret = pme_ctx_pmtcc(&ctx.base_ctx, PME_CTX_OP_WAIT, &fd, &token); -+ if (ret == -ENODEV) { -+ pr_err("clear_sample_db: not the control plane, bailing\n"); -+ goto _clear_4; -+ } -+ if (ret) { -+ pr_err("clear_sample_db: error with pmtcc\n"); -+ goto _clear_4; -+ } -+ wait_for_completion(&ctx.done); -+ if (ctx.ern) { -+ pr_err("clear_sample_db: Rx ERN from pmtcc\n"); -+ goto _clear_4; -+ } -+ status = pme_fd_res_status(&ctx.result_fd); -+ if (status) { -+ pr_info("clear_sample_db: PMTCC write status failed %d\n", -+ status); -+ goto _clear_4; -+ } -+_clear_4: -+ kfree(mem); -+_clear_3: -+ /* Disable */ -+ ret = pme_ctx_disable(&ctx.base_ctx, -+ PME_CTX_OP_WAIT | PME_CTX_OP_WAIT_INT, NULL); -+_clear_2: -+ pme_ctx_finish(&ctx.base_ctx); -+_clear_1: -+ ret = set_cpus_allowed_ptr(current, &backup_mask); -+ if (ret) -+ pr_info("clear_sample_db: can't restore cpumask"); -+_clear_0: -+ if (!ret) -+ pr_info("clear_sample_db: Done\n"); -+ else -+ pr_info("clear_sample_db: Error 0x%x\n", ret); -+ return ret; -+ -+} -+ -+int pme2_sample_db(void) -+{ -+ struct pmtcc_ctx ctx = { -+ .base_ctx.cb = pmtcc_cb, -+ .base_ctx.ern_cb = pmtcc_ern_cb, -+ .ern = 0 -+ }; -+ struct qm_fd fd; -+ struct qm_sg_entry *sg_table = NULL; -+ int ret = 0; -+ enum pme_status status; -+ struct pme_ctx_token token; -+ void *mem = NULL, *mem_result = NULL; -+ u32 pme_rev; -+ struct cpumask backup_mask = current->cpus_allowed; -+ struct cpumask new_mask = *qman_affine_cpus(); -+ -+ cpumask_and(&new_mask, &new_mask, bman_affine_cpus()); -+ ret = set_cpus_allowed_ptr(current, &new_mask); -+ if (ret) { -+ pr_info("sample_db: can't set cpumask\n"); -+ goto _finish_0; -+ } -+ ret = pme_attr_get(pme_attr_rev1, &pme_rev); -+ if (ret) { -+ pr_err("sample_db: can't read pme revision %d\n", ret); -+ goto _finish_1; -+ } -+ /* If Rev 2.0, Rev 2.2...update database */ -+ switch (pme_rev & 0x0000FFFF) { -+ case 0x00000200: -+ pr_info("sample_db: db for pme ver 2.0\n"); -+ pme_db[133] = 0x01; -+ pme_db[134] = 0x20; -+ pme_db[161] = 0x01; -+ pme_db[162] = 0x20; -+ db_read[21] = 0x01; -+ db_read[22] = 0x20; -+ db_read_expected_result[21] = 0x01; -+ db_read_expected_result[22] = 0x20; -+ break; -+ case 0x00000201: -+ pr_info("sample_db: db for pme ver 2.1\n"); -+ break; -+ case 0x00000202: -+ pr_info("sample_db: db for pme ver 2.2\n"); -+ pme_db[134] = 0x48; -+ pme_db[162] = 0x48; -+ db_read[22] = 0x48; -+ db_read_expected_result[22] = 0x48; -+ break; -+ default: -+ pr_err("sample_db: Unknown pme hw ver 0x%x\n", -+ pme_rev & 0x0000FFFF); -+ ret = -ENODEV; -+ goto _finish_1; -+ } -+ init_completion(&ctx.done); -+ ret = pme_ctx_init(&ctx.base_ctx, -+ PME_CTX_FLAG_EXCLUSIVE | -+ PME_CTX_FLAG_PMTCC | -+ PME_CTX_FLAG_LOCAL, 0, 4, 4, 0, NULL); -+ if (ret) { -+ pr_err("sample_db: can't init ctx\n"); -+ goto _finish_1; -+ } -+ -+ /* enable the context */ -+ ret = pme_ctx_enable(&ctx.base_ctx); -+ if (ret) { -+ pr_err("sample_db: can't enable ctx\n"); -+ goto _finish_2; -+ } -+ -+ /* Write the database */ -+ memset(&fd, 0, sizeof(struct qm_fd)); -+ mem = kmalloc(sizeof(pme_db), GFP_KERNEL); -+ if (!mem) -+ goto _finish_3; -+ memcpy(mem, pme_db, sizeof(pme_db)); -+ -+ fd.length20 = sizeof(pme_db); -+ qm_fd_addr_set64(&fd, pme_map(mem)); -+ -+ ret = pme_ctx_pmtcc(&ctx.base_ctx, PME_CTX_OP_WAIT, &fd, &token); -+ if (ret == -ENODEV) { -+ pr_err("sample_db: not the control plane, bailing\n"); -+ goto _finish_4; -+ } -+ if (ret) { -+ pr_err("sample_db: error with pmtcc\n"); -+ goto _finish_4; -+ } -+ wait_for_completion(&ctx.done); -+ if (ctx.ern) { -+ pr_err("sample_db: Rx ERN from pmtcc\n"); -+ goto _finish_4; -+ } -+ status = pme_fd_res_status(&ctx.result_fd); -+ if (status) { -+ pr_info("sample_db: PMTCC write status failed %d\n", status); -+ goto _finish_4; -+ } -+ kfree(mem); -+ mem = NULL; -+ /* Read back the database */ -+ init_completion(&ctx.done); -+ memset(&fd, 0, sizeof(struct qm_fd)); -+ sg_table = kzalloc(2 * sizeof(*sg_table), GFP_KERNEL | GFP_DMA); -+ mem_result = kmalloc(28, GFP_KERNEL); -+ mem = kmalloc(sizeof(db_read), GFP_KERNEL); -+ if (!sg_table || !mem || !mem_result) { -+ pr_err("sample_db: out of memory\n"); -+ ret = -ENOMEM; -+ goto _finish_4; -+ } -+ memcpy(mem, db_read, sizeof(db_read)); -+ qm_sg_entry_set64(&sg_table[0], pme_map(mem_result)); -+ sg_table[0].length = 28; -+ qm_sg_entry_set64(&sg_table[1], pme_map(mem)); -+ sg_table[1].length = sizeof(db_read); -+ sg_table[1].final = 1; -+ fd.format = qm_fd_compound; -+ qm_fd_addr_set64(&fd, pme_map(sg_table)); -+ ret = pme_ctx_pmtcc(&ctx.base_ctx, PME_CTX_OP_WAIT, &fd, &token); -+ if (ret) { -+ pr_err("sample_db: error with pmtcc\n"); -+ goto _finish_4; -+ } -+ wait_for_completion(&ctx.done); -+ if (ctx.ern) { -+ ret = -EINVAL; -+ pr_err("sample_db: Rx ERN from pmtcc\n"); -+ goto _finish_4; -+ } -+ status = pme_fd_res_status(&ctx.result_fd); -+ if (status) { -+ ret = -EINVAL; -+ pr_err("sample_db: PMTCC read status failed %d\n", status); -+ goto _finish_4; -+ } -+ if (pme_fd_res_flags(&ctx.result_fd) & PME_STATUS_UNRELIABLE) { -+ pr_err("sample_db: flags result set %x\n", -+ pme_fd_res_flags(&ctx.result_fd)); -+ ret = -EINVAL; -+ goto _finish_4; -+ } -+ if (memcmp(db_read_expected_result, mem_result, 28) != 0) { -+ pr_err("sample_db: DB read result not expected\n"); -+ pr_err("Expected\n"); -+ hexdump(db_read_expected_result, -+ sizeof(db_read_expected_result)); -+ pr_info("Received\n"); -+ hexdump(mem_result, 28); -+ ret = -EINVAL; -+ } -+_finish_4: -+ kfree(mem_result); -+ kfree(sg_table); -+ kfree(mem); -+_finish_3: -+ /* Disable */ -+ ret = pme_ctx_disable(&ctx.base_ctx, -+ PME_CTX_OP_WAIT | PME_CTX_OP_WAIT_INT, NULL); -+_finish_2: -+ pme_ctx_finish(&ctx.base_ctx); -+_finish_1: -+ if (ret) -+ set_cpus_allowed_ptr(current, &backup_mask); -+ else { -+ ret = set_cpus_allowed_ptr(current, &backup_mask); -+ if (ret) -+ pr_info("sample_db: can't restore cpumask"); -+ } -+ -+_finish_0: -+ if (!ret) -+ pr_info("pme: sample DB initialised\n"); -+ else -+ pr_info("pme: Error during sample DB 0x%x\n", ret); -+ return ret; -+} -diff --git a/drivers/staging/fsl_pme2/pme2_scan.c b/drivers/staging/fsl_pme2/pme2_scan.c -new file mode 100644 -index 0000000..f00081e ---- /dev/null -+++ b/drivers/staging/fsl_pme2/pme2_scan.c -@@ -0,0 +1,1123 @@ -+/* Copyright 2009-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 "pme2_private.h" -+#include -+#include -+#include -+#include -+ -+#define WAIT_AND_INTERRUPTABLE (PME_CTX_OP_WAIT|PME_CTX_OP_WAIT_INT) -+#define INPUT_FRM 1 -+#define OUTPUT_FRM 0 -+/* Private structure that is allocated for each open that is done on the -+ * pme_scan device. */ -+struct scan_session { -+ /* The ctx that is needed to communicate with the pme high level */ -+ struct pme_ctx ctx; -+ /* Locks completed_commands */ -+ spinlock_t set_subset_lock; -+ __u8 set; -+ __u16 subset; -+ /* For asynchronous processing */ -+ wait_queue_head_t waiting_for_completion; -+ struct list_head completed_commands; -+ /* Locks completed_commands */ -+ spinlock_t completed_commands_lock; -+ u32 completed_count; -+}; -+ -+/* Command Token for scan operations. One of these is created for every -+ * operation on a context. When the context operation is complete cleanup -+ * is done */ -+struct cmd_token { -+ /* pme high level token */ -+ struct pme_ctx_token hl_token; -+ /* The kernels copy of the user op structure */ -+ struct pme_scan_cmd kernel_op; -+ /* Set to non zero if this is a synchronous request */ -+ u8 synchronous; -+ /* data */ -+ struct qm_fd tx_fd; -+ struct qm_sg_entry tx_comp[2]; -+ struct qm_fd rx_fd; -+ void *tx_data; -+ size_t tx_size; -+ void *rx_data; -+ size_t rx_size; -+ /* For blocking requests, we need a wait point and condition */ -+ wait_queue_head_t *queue; -+ /* List management for completed async requests */ -+ struct list_head completed_list; -+ u8 done; -+ u8 ern; -+}; -+ -+struct ctrl_op { -+ struct pme_ctx_ctrl_token ctx_ctr; -+ struct completion cb_done; -+ enum pme_status cmd_status; -+ u8 res_flag; -+ u8 ern; -+}; -+ -+#ifdef CONFIG_COMPAT -+static void compat_to_scan_cmd(struct pme_scan_cmd *dst, -+ struct compat_pme_scan_cmd *src) -+{ -+ dst->flags = src->flags; -+ dst->opaque = compat_ptr(src->opaque); -+ dst->input.data = compat_ptr(src->input.data); -+ dst->input.size = src->input.size; -+ dst->output.data = compat_ptr(src->output.data); -+ dst->output.size = src->output.size; -+} -+ -+static void scan_result_to_compat(struct compat_pme_scan_result *dst, -+ struct pme_scan_result *src) -+{ -+ dst->flags = src->flags; -+ dst->opaque = ptr_to_compat(src->opaque); -+ dst->status = src->status; -+ dst->output.data = ptr_to_compat(src->output.data); -+ dst->output.size = src->output.size; -+} -+ -+static void compat_to_scan_result(struct pme_scan_result *dst, -+ struct compat_pme_scan_result *src) -+{ -+ dst->flags = src->flags; -+ dst->opaque = compat_ptr(src->opaque); -+ dst->status = src->status; -+ dst->output.data = compat_ptr(src->output.data); -+ dst->output.size = src->output.size; -+} -+#endif -+ -+static void ctrl_cb(struct pme_ctx *ctx, const struct qm_fd *fd, -+ struct pme_ctx_ctrl_token *token) -+{ -+ struct ctrl_op *ctrl = (struct ctrl_op *)token; -+ ctrl->cmd_status = pme_fd_res_status(fd); -+ ctrl->res_flag = pme_fd_res_flags(fd) & PME_STATUS_UNRELIABLE; -+ complete(&ctrl->cb_done); -+} -+ -+static void ctrl_ern_cb(struct pme_ctx *ctx, const struct qm_mr_entry *mr, -+ struct pme_ctx_ctrl_token *token) -+{ -+ struct ctrl_op *ctrl = (struct ctrl_op *)token; -+ ctrl->ern = 1; -+ complete(&ctrl->cb_done); -+} -+ -+static inline int scan_data_empty(struct scan_session *session) -+{ -+ return list_empty(&session->completed_commands); -+} -+ -+/* Cleanup for the execute_cmd method */ -+static inline void cleanup_token(struct cmd_token *token_p) -+{ -+ kfree(token_p->tx_data); -+ kfree(token_p->rx_data); -+ return; -+} -+ -+/* Callback for scan operations */ -+static void scan_cb(struct pme_ctx *ctx, const struct qm_fd *fd, -+ struct pme_ctx_token *ctx_token) -+{ -+ struct cmd_token *token = (struct cmd_token *)ctx_token; -+ struct scan_session *session = (struct scan_session *)ctx; -+ -+ token->rx_fd = *fd; -+ /* If this is a asynchronous command, queue the token */ -+ if (!token->synchronous) { -+ spin_lock(&session->completed_commands_lock); -+ list_add_tail(&token->completed_list, -+ &session->completed_commands); -+ session->completed_count++; -+ spin_unlock(&session->completed_commands_lock); -+ } -+ /* Wake up the thread that's waiting for us */ -+ token->done = 1; -+ wake_up(token->queue); -+ return; -+} -+ -+static void scan_ern_cb(struct pme_ctx *ctx, const struct qm_mr_entry *mr, -+ struct pme_ctx_token *ctx_token) -+{ -+ struct cmd_token *token = (struct cmd_token *)ctx_token; -+ struct scan_session *session = (struct scan_session *)ctx; -+ -+ token->ern = 1; -+ token->rx_fd = mr->ern.fd; -+ /* If this is a asynchronous command, queue the token */ -+ if (!token->synchronous) { -+ spin_lock(&session->completed_commands_lock); -+ list_add_tail(&token->completed_list, -+ &session->completed_commands); -+ session->completed_count++; -+ spin_unlock(&session->completed_commands_lock); -+ } -+ /* Wake up the thread that's waiting for us */ -+ token->done = 1; -+ wake_up(token->queue); -+ return; -+} -+ -+static int process_completed_token(struct file *fp, struct cmd_token *token_p, -+ struct pme_scan_result *scan_result) -+{ -+ int ret = 0; -+ u32 src_sz, dst_sz; -+ -+ memset(scan_result, 0, sizeof(struct pme_scan_result)); -+ if (token_p->ern) { -+ ret = -EIO; -+ goto done; -+ } -+ scan_result->output.data = token_p->kernel_op.output.data; -+ -+ if (token_p->rx_fd.format == qm_fd_compound) { -+ /* Need to copy output */ -+ src_sz = token_p->tx_comp[OUTPUT_FRM].length; -+ dst_sz = token_p->kernel_op.output.size; -+ scan_result->output.size = min(dst_sz, src_sz); -+ /* Doesn't make sense we generated more than available space -+ * should have got truncation. -+ */ -+ BUG_ON(dst_sz < src_sz); -+ if (copy_to_user(scan_result->output.data, token_p->rx_data, -+ scan_result->output.size)) { -+ pr_err("Error copying to user data\n"); -+ cleanup_token(token_p); -+ return -EFAULT; -+ } -+ } else if (token_p->rx_fd.format == qm_fd_sg_big) -+ scan_result->output.size = 0; -+ else -+ pr_err("pme2_scan: unexpected frame type received\n"); -+ -+ scan_result->flags |= pme_fd_res_flags(&token_p->rx_fd); -+ scan_result->status |= pme_fd_res_status(&token_p->rx_fd); -+done: -+ scan_result->opaque = token_p->kernel_op.opaque; -+ cleanup_token(token_p); -+ return ret; -+} -+ -+static int getscan_cmd(struct file *fp, struct scan_session *session, -+ struct pme_scan_params __user *user_scan_params) -+{ -+ int ret = 0; -+ struct pme_flow params; -+ struct pme_scan_params local_scan_params; -+ struct ctrl_op ctx_ctrl = { -+ .ctx_ctr.cb = ctrl_cb, -+ .ctx_ctr.ern_cb = ctrl_ern_cb, -+ .cmd_status = 0, -+ .res_flag = 0, -+ .ern = 0 -+ }; -+ init_completion(&ctx_ctrl.cb_done); -+ -+ memset(&local_scan_params, 0, sizeof(local_scan_params)); -+ -+ /* must be enabled */ -+ if (pme_ctx_is_disabled(&session->ctx)) { -+ pr_err("pme2_scan: ctx is disabled\n"); -+ ret = -EINVAL; -+ goto done; -+ } -+ ret = pme_ctx_ctrl_read_flow(&session->ctx, WAIT_AND_INTERRUPTABLE, -+ ¶ms, &ctx_ctrl.ctx_ctr); -+ if (ret) { -+ PMEPRINFO("read flow error %d\n", ret); -+ goto done; -+ } -+ wait_for_completion(&ctx_ctrl.cb_done); -+ -+ if (ctx_ctrl.ern || ctx_ctrl.cmd_status || ctx_ctrl.res_flag) { -+ PMEPRINFO("read flow error %d\n", ctx_ctrl.cmd_status); -+ ret = -EFAULT; -+ goto done; -+ } -+ local_scan_params.residue.enable = params.ren; -+ local_scan_params.residue.length = params.rlen; -+ local_scan_params.sre.sessionid = params.sessionid; -+ local_scan_params.sre.verbose = params.srvm; -+ local_scan_params.sre.esee = params.esee; -+ local_scan_params.dxe.clim = params.clim; -+ local_scan_params.dxe.mlim = params.mlim; -+ spin_lock(&session->set_subset_lock); -+ local_scan_params.pattern.set = session->set; -+ local_scan_params.pattern.subset = session->subset; -+ spin_unlock(&session->set_subset_lock); -+ -+ if (copy_to_user(user_scan_params, &local_scan_params, -+ sizeof(local_scan_params))) { -+ pr_err("Error copying to user data\n"); -+ ret = -EFAULT; -+ } -+done: -+ return ret; -+} -+ -+static int setscan_cmd(struct file *fp, struct scan_session *session, -+ struct pme_scan_params __user *user_params) -+{ -+ int ret = 0; -+ u32 flag = WAIT_AND_INTERRUPTABLE; -+ struct ctrl_op ctx_ctrl = { -+ .ctx_ctr.cb = ctrl_cb, -+ .ctx_ctr.ern_cb = ctrl_ern_cb, -+ .cmd_status = 0, -+ .res_flag = 0, -+ .ern = 0 -+ }; -+ struct pme_flow params; -+ struct pme_scan_params local_params; -+ -+ pme_sw_flow_init(¶ms); -+ init_completion(&ctx_ctrl.cb_done); -+ if (copy_from_user(&local_params, user_params, sizeof(local_params))) -+ return -EFAULT; -+ -+ /* must be enabled */ -+ if (pme_ctx_is_disabled(&session->ctx)) { -+ ret = -EINVAL; -+ goto done; -+ } -+ /* Only send a flw_ctx_w if PME_SCAN_PARAMS_{RESIDUE, SRE or DXE} -+ * is being done */ -+ if (local_params.flags == PME_SCAN_PARAMS_PATTERN) -+ goto set_subset; -+ if (local_params.flags & PME_SCAN_PARAMS_RESIDUE) -+ flag |= PME_CMD_FCW_RES; -+ if (local_params.flags & PME_SCAN_PARAMS_SRE) -+ flag |= PME_CMD_FCW_SRE; -+ if (local_params.flags & PME_SCAN_PARAMS_DXE) -+ flag |= PME_CMD_FCW_DXE; -+ params.ren = local_params.residue.enable; -+ params.sessionid = local_params.sre.sessionid; -+ params.srvm = local_params.sre.verbose; -+ params.esee = local_params.sre.esee; -+ params.clim = local_params.dxe.clim; -+ params.mlim = local_params.dxe.mlim; -+ -+ ret = pme_ctx_ctrl_update_flow(&session->ctx, flag, ¶ms, -+ &ctx_ctrl.ctx_ctr); -+ if (ret) { -+ PMEPRINFO("update flow error %d\n", ret); -+ goto done; -+ } -+ wait_for_completion(&ctx_ctrl.cb_done); -+ if (ctx_ctrl.ern || ctx_ctrl.cmd_status || ctx_ctrl.res_flag) { -+ PMEPRINFO("update flow err %d\n", ctx_ctrl.cmd_status); -+ ret = -EFAULT; -+ goto done; -+ } -+ -+set_subset: -+ if (local_params.flags & PME_SCAN_PARAMS_PATTERN) { -+ spin_lock(&session->set_subset_lock); -+ session->set = local_params.pattern.set; -+ session->subset = local_params.pattern.subset; -+ spin_unlock(&session->set_subset_lock); -+ goto done; -+ } -+done: -+ return ret; -+} -+ -+static int resetseq_cmd(struct file *fp, struct scan_session *session) -+{ -+ int ret = 0; -+ struct pme_flow params; -+ struct ctrl_op ctx_ctrl = { -+ .ctx_ctr.cb = ctrl_cb, -+ .ctx_ctr.ern_cb = ctrl_ern_cb, -+ .cmd_status = 0, -+ .res_flag = 0, -+ .ern = 0 -+ }; -+ init_completion(&ctx_ctrl.cb_done); -+ pme_sw_flow_init(¶ms); -+ -+ /* must be enabled */ -+ if (pme_ctx_is_disabled(&session->ctx)) { -+ pr_err("pme2_scan: ctx is disabled\n"); -+ ret = -EINVAL; -+ goto done; -+ } -+ pme_flow_seqnum_set64(¶ms, 0); -+ params.sos = 1; -+ -+ ret = pme_ctx_ctrl_update_flow(&session->ctx, PME_CMD_FCW_SEQ, ¶ms, -+ &ctx_ctrl.ctx_ctr); -+ if (ret) { -+ pr_err("pme2_scan: update flow error %d\n", ret); -+ return ret; -+ } -+ wait_for_completion(&ctx_ctrl.cb_done); -+ if (ctx_ctrl.ern || ctx_ctrl.cmd_status || ctx_ctrl.res_flag) { -+ PMEPRINFO("update flow err %d\n", ctx_ctrl.cmd_status); -+ ret = -EFAULT; -+ } -+done: -+ return ret; -+} -+ -+static int resetresidue_cmd(struct file *fp, struct scan_session *session) -+{ -+ int ret = 0; -+ struct pme_flow params; -+ struct ctrl_op ctx_ctrl = { -+ .ctx_ctr.cb = ctrl_cb, -+ .ctx_ctr.ern_cb = ctrl_ern_cb, -+ .cmd_status = 0, -+ .res_flag = 0, -+ .ern = 0 -+ }; -+ -+ init_completion(&ctx_ctrl.cb_done); -+ pme_sw_flow_init(¶ms); -+ /* must be enabled */ -+ if (pme_ctx_is_disabled(&session->ctx)) { -+ pr_err("pme2_scan: ctx is disabled\n"); -+ ret = -EINVAL; -+ goto done; -+ } -+ params.rlen = 0; -+ ret = pme_ctx_ctrl_update_flow(&session->ctx, -+ WAIT_AND_INTERRUPTABLE | PME_CTX_OP_RESETRESLEN, -+ ¶ms, &ctx_ctrl.ctx_ctr); -+ if (ret) -+ pr_info("pme2_scan: update flow error %d\n", ret); -+ wait_for_completion(&ctx_ctrl.cb_done); -+ if (ctx_ctrl.ern || ctx_ctrl.cmd_status || ctx_ctrl.res_flag) { -+ PMEPRINFO("update flow err %d\n", ctx_ctrl.cmd_status); -+ ret = -EFAULT; -+ } -+done: -+ return ret; -+} -+ -+static int process_scan_cmd( -+ struct file *fp, -+ struct scan_session *session, -+ struct pme_scan_cmd *user_cmd, -+ struct pme_scan_result *user_ret, -+ u8 synchronous) -+{ -+ int ret = 0; -+ struct cmd_token local_token; -+ struct cmd_token *token_p = NULL; -+ DECLARE_WAIT_QUEUE_HEAD(local_waitqueue); -+ u8 scan_flags = 0; -+ -+ BUG_ON(synchronous && !user_ret); -+ -+ /* If synchronous, use a local token (from the stack) -+ * If asynchronous, allocate a token to use */ -+ if (synchronous) -+ token_p = &local_token; -+ else { -+ token_p = kmalloc(sizeof(*token_p), GFP_KERNEL); -+ if (!token_p) -+ return -ENOMEM; -+ } -+ memset(token_p, 0, sizeof(*token_p)); -+ /* Copy the command to kernel space */ -+ memcpy(&token_p->kernel_op, user_cmd, sizeof(struct pme_scan_cmd)); -+ -+#ifdef CONFIG_FSL_PME_BUG_4K_SCAN_REV_2_1_4 -+ if (session->ctx.max_scan_size) { -+ if (token_p->kernel_op.input.size > -+ session->ctx.max_scan_size) { -+ if (!synchronous) -+ kfree(token_p); -+ return -EINVAL; -+ } -+ } -+#endif -+ -+ /* Copy the input */ -+ token_p->synchronous = synchronous; -+ token_p->tx_size = token_p->kernel_op.input.size; -+ token_p->tx_data = kmalloc(token_p->kernel_op.input.size, GFP_KERNEL); -+ if (!token_p->tx_data) { -+ pr_err("pme2_scan: Err alloc %zd byte", token_p->tx_size); -+ cleanup_token(token_p); -+ return -ENOMEM; -+ } -+ if (copy_from_user(token_p->tx_data, -+ token_p->kernel_op.input.data, -+ token_p->kernel_op.input.size)) { -+ pr_err("Error copying contigous user data\n"); -+ cleanup_token(token_p); -+ return -EFAULT; -+ } -+ /* Setup input frame */ -+ token_p->tx_comp[INPUT_FRM].final = 1; -+ token_p->tx_comp[INPUT_FRM].length = token_p->tx_size; -+ qm_sg_entry_set64(&token_p->tx_comp[INPUT_FRM], -+ pme_map(token_p->tx_data)); -+ /* setup output frame, if output is expected */ -+ if (token_p->kernel_op.output.size) { -+ token_p->rx_size = token_p->kernel_op.output.size; -+ PMEPRINFO("pme2_scan: expect output %d\n", token_p->rx_size); -+ token_p->rx_data = kmalloc(token_p->rx_size, GFP_KERNEL); -+ if (!token_p->rx_data) { -+ pr_err("pme2_scan: Err alloc %zd byte", -+ token_p->rx_size); -+ cleanup_token(token_p); -+ return -ENOMEM; -+ } -+ /* Setup output frame */ -+ token_p->tx_comp[OUTPUT_FRM].length = token_p->rx_size; -+ qm_sg_entry_set64(&token_p->tx_comp[OUTPUT_FRM], -+ pme_map(token_p->rx_data)); -+ token_p->tx_fd.format = qm_fd_compound; -+ /* Build compound frame */ -+ qm_fd_addr_set64(&token_p->tx_fd, -+ pme_map(token_p->tx_comp)); -+ } else { -+ token_p->tx_fd.format = qm_fd_sg_big; -+ /* Build sg frame */ -+ qm_fd_addr_set64(&token_p->tx_fd, -+ pme_map(&token_p->tx_comp[INPUT_FRM])); -+ token_p->tx_fd.length29 = token_p->tx_size; -+ } -+ -+ /* use the local wait queue if synchronous, the shared -+ * queue if asynchronous */ -+ if (synchronous) -+ token_p->queue = &local_waitqueue; -+ else -+ token_p->queue = &session->waiting_for_completion; -+ token_p->done = 0; -+ -+ if (token_p->kernel_op.flags & PME_SCAN_CMD_STARTRESET) -+ scan_flags |= PME_CMD_SCAN_SR; -+ if (token_p->kernel_op.flags & PME_SCAN_CMD_END) -+ scan_flags |= PME_CMD_SCAN_E; -+ ret = pme_ctx_scan(&session->ctx, WAIT_AND_INTERRUPTABLE, -+ &token_p->tx_fd, -+ PME_SCAN_ARGS(scan_flags, session->set, session->subset), -+ &token_p->hl_token); -+ if (unlikely(ret)) { -+ cleanup_token(token_p); -+ return ret; -+ } -+ -+ if (!synchronous) -+ /* Don't wait. The command is away */ -+ return 0; -+ -+ PMEPRINFO("Wait for completion\n"); -+ /* Wait for the command to complete */ -+ /* TODO: Should this be wait_event_interruptible ? -+ * If so, will need logic to indicate */ -+ wait_event(*token_p->queue, token_p->done == 1); -+ return process_completed_token(fp, token_p, user_ret); -+} -+ -+/** -+ * fsl_pme2_scan_open - open the driver -+ * -+ * Open the driver and prepare for requests. -+ * -+ * Every time an application opens the driver, we create a scan_session object -+ * for that file handle. -+ */ -+static int fsl_pme2_scan_open(struct inode *node, struct file *fp) -+{ -+ int ret; -+ struct scan_session *session; -+ struct pme_flow flow; -+ struct ctrl_op ctx_ctrl = { -+ .ctx_ctr.cb = ctrl_cb, -+ .ctx_ctr.ern_cb = ctrl_ern_cb, -+ .cmd_status = 0, -+ .res_flag = 0, -+ .ern = 0 -+ }; -+ -+ pme_sw_flow_init(&flow); -+ init_completion(&ctx_ctrl.cb_done); -+ PMEPRINFO("pme2_scan: open %d\n", smp_processor_id()); -+ fp->private_data = kzalloc(sizeof(*session), GFP_KERNEL); -+ if (!fp->private_data) -+ return -ENOMEM; -+ session = (struct scan_session *)fp->private_data; -+ /* Set up the structures used for asynchronous requests */ -+ init_waitqueue_head(&session->waiting_for_completion); -+ INIT_LIST_HEAD(&session->completed_commands); -+ spin_lock_init(&session->completed_commands_lock); -+ spin_lock_init(&session->set_subset_lock); -+ PMEPRINFO("kmalloc session %p\n", fp->private_data); -+ session = fp->private_data; -+ session->ctx.cb = scan_cb; -+ session->ctx.ern_cb = scan_ern_cb; -+ -+ /* qosin, qosout should be driver attributes */ -+ ret = pme_ctx_init(&session->ctx, PME_CTX_FLAG_LOCAL, 0, 4, 4, 0, NULL); -+ if (ret) { -+ pr_err("pme2_scan: pme_ctx_init %d\n", ret); -+ goto exit; -+ } -+ /* enable the context */ -+ ret = pme_ctx_enable(&session->ctx); -+ if (ret) { -+ PMEPRINFO("error enabling ctx %d\n", ret); -+ pme_ctx_finish(&session->ctx); -+ goto exit; -+ } -+ /* Update flow to set sane defaults in the flow context */ -+ ret = pme_ctx_ctrl_update_flow(&session->ctx, -+ PME_CTX_OP_WAIT | PME_CMD_FCW_ALL, &flow, &ctx_ctrl.ctx_ctr); -+ if (!ret) { -+ wait_for_completion(&ctx_ctrl.cb_done); -+ if (ctx_ctrl.ern || ctx_ctrl.cmd_status || ctx_ctrl.res_flag) -+ ret = -EFAULT; -+ } -+ if (ret) { -+ int my_ret; -+ PMEPRINFO("error updating flow ctx %d\n", ret); -+ my_ret = pme_ctx_disable(&session->ctx, PME_CTX_OP_WAIT, -+ &ctx_ctrl.ctx_ctr); -+ if (my_ret > 0) -+ wait_for_completion(&ctx_ctrl.cb_done); -+ else if (my_ret < 0) -+ PMEPRINFO("error disabling ctx %d\n", ret); -+ pme_ctx_finish(&session->ctx); -+ goto exit; -+ } -+ /* Set up the structures used for asynchronous requests */ -+ PMEPRINFO("pme2_scan: Finish pme_scan open %d\n", smp_processor_id()); -+ return 0; -+exit: -+ kfree(fp->private_data); -+ fp->private_data = NULL; -+ return ret; -+} -+ -+static int fsl_pme2_scan_close(struct inode *node, struct file *fp) -+{ -+ struct ctrl_op ctx_ctrl = { -+ .ctx_ctr.cb = ctrl_cb, -+ .ctx_ctr.ern_cb = ctrl_ern_cb, -+ .cmd_status = 0, -+ .res_flag = 0, -+ .ern = 0 -+ }; -+ int ret = 0; -+ struct scan_session *session = fp->private_data; -+ -+ init_completion(&ctx_ctrl.cb_done); -+ /* Before disabling check to see if it's already disabled. This can -+ * happen if a pme serious error has occurred for instance.*/ -+ if (!pme_ctx_is_disabled(&session->ctx)) { -+ ret = pme_ctx_disable(&session->ctx, PME_CTX_OP_WAIT, -+ &ctx_ctrl.ctx_ctr); -+ if (ret > 0) { -+ wait_for_completion(&ctx_ctrl.cb_done); -+ if (ctx_ctrl.ern) -+ PMEPRCRIT("Unexpected ERN\n"); -+ } else if (ret < 0) { -+ pr_err("pme2_scan: Error disabling ctx %d\n", ret); -+ return ret; -+ } -+ } -+ pme_ctx_finish(&session->ctx); -+ kfree(session); -+ PMEPRINFO("pme2_scan: Finish pme_session close\n"); -+ return 0; -+} -+ -+static unsigned int fsl_pme2_scan_poll(struct file *fp, -+ struct poll_table_struct *wait) -+{ -+ struct scan_session *session; -+ unsigned int mask = POLLOUT | POLLWRNORM; -+ -+ if (!fp->private_data) -+ return -EINVAL; -+ -+ session = (struct scan_session *)fp->private_data; -+ -+ poll_wait(fp, &session->waiting_for_completion, wait); -+ -+ if (!scan_data_empty(session)) -+ mask |= (POLLIN | POLLRDNORM); -+ return mask; -+} -+ -+ -+/* Main switch loop for ioctl operations */ -+static long fsl_pme2_scan_ioctl(struct file *fp, unsigned int cmd, -+ unsigned long arg) -+{ -+ struct scan_session *session = fp->private_data; -+ int ret = 0; -+ -+ switch (cmd) { -+ -+ case PMEIO_GETSCAN: -+ return getscan_cmd(fp, session, (struct pme_scan_params *)arg); -+ break; -+ -+ case PMEIO_SETSCAN: -+ return setscan_cmd(fp, session, (struct pme_scan_params *)arg); -+ break; -+ -+ case PMEIO_RESETSEQ: -+ return resetseq_cmd(fp, session); -+ break; -+ -+ case PMEIO_RESETRES: -+ return resetresidue_cmd(fp, session); -+ break; -+ -+ case PMEIO_SCAN: -+ { -+ int ret; -+ struct pme_scan scan; -+ -+ if (copy_from_user(&scan, (void __user *)arg, sizeof(scan))) -+ return -EFAULT; -+ ret = process_scan_cmd(fp, session, &scan.cmd, &scan.result, 1); -+ if (!ret) { -+ struct pme_scan_result __user *user_result = -+ &((struct pme_scan __user *)arg)->result; -+ ret = copy_to_user(user_result, &scan.result, -+ sizeof(*user_result)); -+ } -+ return ret; -+ } -+ break; -+ -+ case PMEIO_SCAN_W1: -+ { -+ struct pme_scan_cmd scan_cmd; -+ -+ if (copy_from_user(&scan_cmd, (void __user *)arg, -+ sizeof(scan_cmd))) -+ return -EFAULT; -+ return process_scan_cmd(fp, session, &scan_cmd, NULL, 0); -+ } -+ break; -+ -+ case PMEIO_SCAN_R1: -+ { -+ struct pme_scan_result result; -+ struct cmd_token *completed_cmd = NULL; -+ struct pme_scan_result __user *ur = -+ (struct pme_scan_result __user *)arg; -+ int ret; -+ -+ if (copy_from_user(&result, (void __user *)arg, -+ sizeof(result))) -+ return -EFAULT; -+ -+ /* Check to see if any results */ -+ spin_lock(&session->completed_commands_lock); -+ if (!list_empty(&session->completed_commands)) { -+ completed_cmd = list_first_entry( -+ &session->completed_commands, -+ struct cmd_token, -+ completed_list); -+ list_del(&completed_cmd->completed_list); -+ session->completed_count--; -+ } -+ spin_unlock(&session->completed_commands_lock); -+ if (completed_cmd) { -+ ret = process_completed_token(fp, completed_cmd, -+ &result); -+ if (!ret) -+ ret = copy_to_user(ur, &result, sizeof(result)); -+ return ret; -+ } else -+ return -EIO; -+ } -+ break; -+ -+ case PMEIO_SCAN_Wn: -+ { -+ struct pme_scan_cmds scan_cmds; -+ int i, ret = 0; -+ -+ /* Copy the command to kernel space */ -+ if (copy_from_user(&scan_cmds, (void __user *)arg, -+ sizeof(scan_cmds))) -+ return -EFAULT; -+ PMEPRINFO("Received Wn for %d cmds\n", scan_cmds.num); -+ for (i = 0; i < scan_cmds.num; i++) { -+ struct pme_scan_cmd scan_cmd; -+ -+ if (copy_from_user(&scan_cmd, &scan_cmds.cmds[i], -+ sizeof(scan_cmd))) { -+ pr_err("pme2_scan: Err with %d\n", i); -+ scan_cmds.num = i; -+ if (copy_to_user((void __user *)arg, &scan_cmds, -+ sizeof(scan_cmds))) { -+ return -EFAULT; -+ } -+ return -EFAULT; -+ } -+ ret = process_scan_cmd(fp, session, &scan_cmd, NULL, 0); -+ if (ret) { -+ pr_err("pme2_scan: Err with %d cmd %d\n", -+ i, ret); -+ scan_cmds.num = i; -+ if (copy_to_user((void *)arg, &scan_cmds, -+ sizeof(scan_cmds))) { -+ pr_err("Error copying to user data\n"); -+ return -EFAULT; -+ } -+ return -EINTR; -+ } -+ } -+ return ret; -+ } -+ break; -+ -+ case PMEIO_SCAN_Rn: -+ { -+ struct pme_scan_results results; -+ struct pme_scan_result result; -+ struct pme_scan_result __user *ur; -+ int i = 0, ret = 0; -+ struct cmd_token *completed_cmd = NULL; -+ -+ /* Copy the command to kernel space */ -+ if (copy_from_user(&results, (void __user *)arg, -+ sizeof(results))) -+ return -EFAULT; -+ ur = ((struct pme_scan_results __user *)arg)->results -+ PMEPRINFO("pme2_scan: Received Rn for %d res\n", results.num); -+ if (!results.num) -+ return 0; -+ do { -+ completed_cmd = NULL; -+ ret = 0; -+ /* Check to see if any results */ -+ spin_lock(&session->completed_commands_lock); -+ if (!list_empty(&session->completed_commands)) { -+ /* Move to a different list */ -+ PMEPRINFO("pme2_scan: Pop response\n"); -+ completed_cmd = list_first_entry( -+ &session->completed_commands, -+ struct cmd_token, -+ completed_list); -+ list_del(&completed_cmd->completed_list); -+ session->completed_count--; -+ } -+ spin_unlock(&session->completed_commands_lock); -+ if (completed_cmd) { -+ if (copy_from_user(&result, (void __user *)ur+i, -+ sizeof(result))) -+ return -EFAULT; -+ ret = process_completed_token(fp, completed_cmd, -+ &result); -+ if (!ret) -+ ret = copy_to_user(ur, &result, -+ sizeof(struct pme_scan_result)); -+ if (!ret) { -+ i++; -+ ur++; -+ } -+ } -+ } while (!ret && completed_cmd && (i != results.num)); -+ -+ if (i != results.num) { -+ PMEPRINFO("pme2_scan: Only filled %d responses\n", i); -+ results.num = i; -+ PMEPRINFO("pme2_scan: results.num = %d\n", results.num); -+ if (copy_to_user((void __user *)arg, &results, -+ sizeof(struct pme_scan_results))) { -+ pr_err("Error copying to user data\n"); -+ return -EFAULT; -+ } -+ } -+ return ret; -+ } -+ break; -+ -+ case PMEIO_RELEASE_BUFS: -+ return -EINVAL; -+ break; -+ -+#ifdef CONFIG_COMPAT -+ case PMEIO_SCAN32: -+ { -+ int ret; -+ struct compat_pme_scan scan32; -+ struct compat_pme_scan __user *user_scan = compat_ptr(arg); -+ struct pme_scan scan; -+ -+ if (copy_from_user(&scan32, user_scan, sizeof(scan32))) -+ return -EFAULT; -+ /* Convert to 64-bit structs */ -+ compat_to_scan_cmd(&scan.cmd, &scan32.cmd); -+ compat_to_scan_result(&scan.result, &scan32.result); -+ -+ ret = process_scan_cmd(fp, session, &scan.cmd, &scan.result, 1); -+ if (!ret) { -+ struct compat_pme_scan_result __user *user_result = -+ &user_scan->result; -+ /* Convert to 32-bit struct */ -+ scan_result_to_compat(&scan32.result, &scan.result); -+ ret = copy_to_user(user_result, &scan32.result, -+ sizeof(*user_result)); -+ } -+ return ret; -+ } -+ break; -+ -+ case PMEIO_SCAN_W132: -+ { -+ struct compat_pme_scan_cmd scan_cmd32; -+ struct pme_scan_cmd scan_cmd; -+ -+ if (copy_from_user(&scan_cmd32, compat_ptr(arg), -+ sizeof(scan_cmd32))) -+ return -EFAULT; -+ /* Convert to 64-bit struct */ -+ compat_to_scan_cmd(&scan_cmd, &scan_cmd32); -+ return process_scan_cmd(fp, session, &scan_cmd, NULL, 0); -+ } -+ break; -+ -+ case PMEIO_SCAN_R132: -+ { -+ struct compat_pme_scan_result result32; -+ struct pme_scan_result result; -+ struct cmd_token *completed_cmd = NULL; -+ struct compat_pme_scan_result __user *ur = compat_ptr(arg); -+ int ret; -+ -+ if (copy_from_user(&result32, (void __user *)arg, -+ sizeof(result32))) -+ return -EFAULT; -+ /* copy to 64-bit structure */ -+ compat_to_scan_result(&result, &result32); -+ -+ /* Check to see if any results */ -+ spin_lock(&session->completed_commands_lock); -+ if (!list_empty(&session->completed_commands)) { -+ completed_cmd = list_first_entry( -+ &session->completed_commands, -+ struct cmd_token, -+ completed_list); -+ list_del(&completed_cmd->completed_list); -+ session->completed_count--; -+ } -+ spin_unlock(&session->completed_commands_lock); -+ if (completed_cmd) { -+ ret = process_completed_token(fp, completed_cmd, -+ &result); -+ scan_result_to_compat(&result32, &result); -+ ret = copy_to_user(ur, &result32, sizeof(result32)); -+ } else -+ return -EIO; -+ } -+ break; -+ -+ case PMEIO_SCAN_Wn32: -+ { -+ struct compat_pme_scan_cmds scan_cmds32; -+ int i, ret = 0; -+ -+ /* Copy the command to kernel space */ -+ if (copy_from_user(&scan_cmds32, compat_ptr(arg), -+ sizeof(scan_cmds32))) -+ return -EFAULT; -+ PMEPRINFO("Received Wn for %d cmds\n", scan_cmds32.num); -+ for (i = 0; i < scan_cmds32.num; i++) { -+ struct pme_scan_cmd scan_cmd; -+ struct compat_pme_scan_cmd __user *u_scan_cmd32; -+ struct compat_pme_scan_cmd scan_cmd32; -+ -+ u_scan_cmd32 = compat_ptr(scan_cmds32.cmds); -+ u_scan_cmd32 += i; -+ -+ if (copy_from_user(&scan_cmd32, u_scan_cmd32, -+ sizeof(scan_cmd32))) { -+ pr_err("pme2_scan: Err with %d\n", i); -+ scan_cmds32.num = i; -+ if (copy_to_user(compat_ptr(arg), &scan_cmds32, -+ sizeof(scan_cmds32))) -+ return -EFAULT; -+ return -EFAULT; -+ } -+ compat_to_scan_cmd(&scan_cmd, &scan_cmd32); -+ ret = process_scan_cmd(fp, session, &scan_cmd, NULL, 0); -+ if (ret) { -+ pr_err("pme2_scan: Err with %d cmd %d\n", -+ i, ret); -+ scan_cmds32.num = i; -+ if (copy_to_user(compat_ptr(arg), &scan_cmds32, -+ sizeof(scan_cmds32))) -+ return -EFAULT; -+ return -EINTR; -+ } -+ } -+ return ret; -+ } -+ break; -+ -+ case PMEIO_SCAN_Rn32: -+ { -+ struct compat_pme_scan_results results32; -+ int i = 0, ret = 0; -+ struct cmd_token *completed_cmd = NULL; -+ struct compat_pme_scan_result __user *ur; -+ -+ /* Copy the command to kernel space */ -+ if (copy_from_user(&results32, compat_ptr(arg), -+ sizeof(results32))) -+ return -EFAULT; -+ ur = compat_ptr(results32.results); -+ PMEPRINFO("pme2_scan: Rx Rn for %d res\n", results32.num); -+ if (!results32.num) -+ return 0; -+ do { -+ completed_cmd = NULL; -+ ret = 0; -+ /* Check to see if any results */ -+ spin_lock(&session->completed_commands_lock); -+ if (!list_empty(&session->completed_commands)) { -+ /* Move to a different list */ -+ PMEPRINFO("pme2_scan: Pop response\n"); -+ completed_cmd = list_first_entry( -+ &session->completed_commands, -+ struct cmd_token, -+ completed_list); -+ list_del(&completed_cmd->completed_list); -+ session->completed_count--; -+ } -+ spin_unlock(&session->completed_commands_lock); -+ if (completed_cmd) { -+ struct compat_pme_scan_result l_result32; -+ struct pme_scan_result result; -+ -+ if (copy_from_user(&l_result32, ur+i, -+ sizeof(l_result32))) -+ return -EFAULT; -+ compat_to_scan_result(&result, &l_result32); -+ ret = process_completed_token(fp, completed_cmd, -+ &result); -+ scan_result_to_compat(&l_result32, &result); -+ ret = copy_to_user(ur+i, &l_result32, -+ sizeof(l_result32)); -+ if (!ret) -+ i++; -+ } -+ } while (!ret && completed_cmd && (i != results32.num)); -+ -+ if (i != results32.num) { -+ PMEPRINFO("pme2_scan: Only filled %d responses\n", i); -+ results32.num = i; -+ PMEPRINFO("pme2_scan: results32.num = %d\n", -+ results32.num); -+ if (copy_to_user(compat_ptr(arg), &results32, -+ sizeof(struct pme_scan_results))) { -+ pr_err("Error copying to user data\n"); -+ return -EFAULT; -+ } -+ } -+ return ret; -+ } -+ break; -+#endif /* CONFIG_COMPAT */ -+ -+ default: -+ pr_err("UNKNOWN IOCTL cmd 0x%x\n", cmd); -+ return -EINVAL; -+ break; -+ } -+ -+ return ret; -+} -+ -+static const struct file_operations fsl_pme2_scan_fops = { -+ .owner = THIS_MODULE, -+ .open = fsl_pme2_scan_open, -+ .release = fsl_pme2_scan_close, -+ .poll = fsl_pme2_scan_poll, -+ .unlocked_ioctl = fsl_pme2_scan_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = fsl_pme2_scan_ioctl, -+#endif -+}; -+ -+static struct miscdevice fsl_pme2_scan_dev = { -+ .minor = MISC_DYNAMIC_MINOR, -+ .name = PME_DEV_SCAN_NODE, -+ .fops = &fsl_pme2_scan_fops -+}; -+ -+static int __init fsl_pme2_scan_init(void) -+{ -+ int err = 0; -+ -+ pr_info("Freescale pme2 scan driver\n"); -+ err = misc_register(&fsl_pme2_scan_dev); -+ if (err) { -+ pr_err("fsl-pme2-scan: cannot register device\n"); -+ return err; -+ } -+ pr_info("fsl-pme2-scan: device %s registered\n", -+ fsl_pme2_scan_dev.name); -+ return 0; -+} -+ -+static void __exit fsl_pme2_scan_exit(void) -+{ -+ int err = misc_deregister(&fsl_pme2_scan_dev); -+ if (err) -+ pr_err("fsl-pme2-scan: Failed to deregister device %s, " -+ "code %d\n", fsl_pme2_scan_dev.name, err); -+ pr_info("fsl-pme2-scan: device %s deregistered\n", -+ fsl_pme2_scan_dev.name); -+} -+ -+module_init(fsl_pme2_scan_init); -+module_exit(fsl_pme2_scan_exit); -+ -+MODULE_AUTHOR("Jeffrey Ladouceur "); -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("Freescale PME2 scan driver"); -diff --git a/drivers/staging/fsl_pme2/pme2_sys.h b/drivers/staging/fsl_pme2/pme2_sys.h -new file mode 100644 -index 0000000..fefe1f5 ---- /dev/null -+++ b/drivers/staging/fsl_pme2/pme2_sys.h -@@ -0,0 +1,63 @@ -+/* 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+int pme2_create_sysfs_dev_files(struct platform_device *ofdev); -+void pme2_remove_sysfs_dev_files(struct platform_device *ofdev); -+void accumulator_update_interval(u32 interval); -diff --git a/drivers/staging/fsl_pme2/pme2_sysfs.c b/drivers/staging/fsl_pme2/pme2_sysfs.c -new file mode 100644 -index 0000000..07e6e64 ---- /dev/null -+++ b/drivers/staging/fsl_pme2/pme2_sysfs.c -@@ -0,0 +1,563 @@ -+/* 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 "pme2_regs.h" -+#include "pme2_private.h" -+ -+#define MAX_ACCUMULATOR_INTERVAL 10000 -+extern u32 pme_stat_interval; -+ -+/* The pme sysfs contains the following types of attributes -+ * 1) root level: general pme confuration -+ * 2) bsc: bufferpool size configuration -+ * 3) stats: pme statistics -+ */ -+static ssize_t pme_store(struct device *dev, struct device_attribute *dev_attr, -+ const char *buf, size_t count, enum pme_attr attr) -+{ -+ unsigned long val; -+ size_t ret; -+ if (strict_strtoul(buf, 0, &val)) { -+ dev_dbg(dev, "invalid input %s\n",buf); -+ return -EINVAL; -+ } -+ ret = pme_attr_set(attr, val); -+ if (ret) { -+ dev_err(dev, "attr_set err attr=%u, val=%lu\n", attr, val); -+ return ret; -+ } -+ return count; -+} -+ -+static ssize_t pme_show(struct device *dev, struct device_attribute *dev_attr, -+ char *buf, enum pme_attr attr, const char *fmt) -+{ -+ u32 data; -+ int ret; -+ -+ ret = pme_attr_get(attr, &data); -+ if (!ret) -+ return snprintf(buf, PAGE_SIZE, fmt, data); -+ return ret; -+} -+ -+ -+static ssize_t pme_stat_show(struct device *dev, -+ struct device_attribute *dev_attr, char *buf, enum pme_attr attr) -+{ -+ u64 data = 0; -+ int ret = 0; -+ -+ ret = pme_stat_get(attr, &data, 0); -+ if (!ret) -+ return snprintf(buf, PAGE_SIZE, "%llu\n", data); -+ else -+ return ret; -+} -+ -+static ssize_t pme_stat_store(struct device *dev, -+ struct device_attribute *dev_attr, const char *buf, -+ size_t count, enum pme_attr attr) -+{ -+ unsigned long val; -+ u64 data = 0; -+ size_t ret = 0; -+ if (strict_strtoul(buf, 0, &val)) { -+ pr_err("pme: invalid input %s\n", buf); -+ return -EINVAL; -+ } -+ if (val) { -+ pr_err("pme: invalid input %s\n", buf); -+ return -EINVAL; -+ } -+ ret = pme_stat_get(attr, &data, 1); -+ return count; -+} -+ -+ -+#define PME_SYSFS_ATTR(pme_attr, perm, showhex) \ -+static ssize_t pme_store_##pme_attr(struct device *dev, \ -+ struct device_attribute *attr, const char *buf, size_t count) \ -+{ \ -+ return pme_store(dev, attr, buf, count, pme_attr_##pme_attr);\ -+} \ -+static ssize_t pme_show_##pme_attr(struct device *dev, \ -+ struct device_attribute *attr, char *buf) \ -+{ \ -+ return pme_show(dev, attr, buf, pme_attr_##pme_attr, showhex);\ -+} \ -+static DEVICE_ATTR( pme_attr, perm, pme_show_##pme_attr, pme_store_##pme_attr); -+ -+ -+#define PME_SYSFS_STAT_ATTR(pme_attr, perm) \ -+static ssize_t pme_store_##pme_attr(struct device *dev, \ -+ struct device_attribute *attr, const char *buf, size_t count) \ -+{ \ -+ return pme_stat_store(dev, attr, buf, count, pme_attr_##pme_attr);\ -+} \ -+static ssize_t pme_show_##pme_attr(struct device *dev, \ -+ struct device_attribute *attr, char *buf) \ -+{ \ -+ return pme_stat_show(dev, attr, buf, pme_attr_##pme_attr);\ -+} \ -+static DEVICE_ATTR(pme_attr, perm, pme_show_##pme_attr, pme_store_##pme_attr); -+ -+ -+#define PME_SYSFS_BSC_ATTR(bsc_id, perm, showhex) \ -+static ssize_t pme_store_bsc_##bsc_id(struct device *dev,\ -+ struct device_attribute *attr, const char *buf, size_t count) \ -+{ \ -+ return pme_store(dev, attr, buf, count, pme_attr_bsc(bsc_id));\ -+} \ -+static ssize_t pme_show_bsc_##bsc_id(struct device *dev,\ -+ struct device_attribute *attr, char *buf) \ -+{ \ -+ return pme_show(dev, attr, buf, pme_attr_bsc(bsc_id), showhex);\ -+} \ -+static DEVICE_ATTR(bsc_id, perm, pme_show_bsc_##bsc_id, \ -+ pme_store_bsc_##bsc_id); -+ -+/* Statistics Ctrl: update interval */ -+static ssize_t pme_store_update_interval(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ unsigned long val; -+ -+ if (!pme2_have_control()) { -+ PMEPRERR("not on ctrl-plane\n"); -+ return -ENODEV; -+ } -+ if (strict_strtoul(buf, 0, &val)) { -+ dev_info(dev, "invalid input %s\n", buf); -+ return -EINVAL; -+ } -+ if (val > MAX_ACCUMULATOR_INTERVAL) { -+ dev_info(dev, "invalid input %s\n", buf); -+ return -ERANGE; -+ } -+ accumulator_update_interval(val); -+ return count; -+} -+static ssize_t pme_show_update_interval(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ if (!pme2_have_control()) -+ return -ENODEV; -+ return snprintf(buf, PAGE_SIZE, "%u\n", pme_stat_interval); -+} -+ -+#define FMT_0HEX "0x%08x\n" -+#define FMT_HEX "0x%x\n" -+#define FMT_DEC "%u\n" -+#define PRIV_RO S_IRUSR -+#define PRIV_RW (S_IRUSR | S_IWUSR) -+ -+/* Register Interfaces */ -+/* read-write; */ -+PME_SYSFS_ATTR(efqc_int, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(sw_db, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(dmcr, PRIV_RW, FMT_0HEX); -+PME_SYSFS_ATTR(smcr, PRIV_RW, FMT_0HEX); -+PME_SYSFS_ATTR(famcr, PRIV_RW, FMT_0HEX); -+PME_SYSFS_ATTR(kvlts, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(max_chain_length, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(pattern_range_counter_idx, PRIV_RW, FMT_0HEX); -+PME_SYSFS_ATTR(pattern_range_counter_mask, PRIV_RW, FMT_0HEX); -+PME_SYSFS_ATTR(max_allowed_test_line_per_pattern, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(max_pattern_matches_per_sui, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(max_pattern_evaluations_per_sui, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(report_length_limit, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(end_of_simple_sui_report, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(aim, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(end_of_sui_reaction_ptr, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(sre_pscl, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(sre_max_block_num, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(sre_max_instruction_limit, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(esr, PRIV_RW, FMT_0HEX); -+PME_SYSFS_ATTR(pehd, PRIV_RW, FMT_0HEX); -+PME_SYSFS_ATTR(ecc1bes, PRIV_RW, FMT_0HEX); -+PME_SYSFS_ATTR(ecc2bes, PRIV_RW, FMT_0HEX); -+PME_SYSFS_ATTR(miace, PRIV_RW, FMT_0HEX); -+PME_SYSFS_ATTR(miacr, PRIV_RW, FMT_0HEX); -+PME_SYSFS_ATTR(cdcr, PRIV_RW, FMT_0HEX); -+PME_SYSFS_ATTR(pmtr, PRIV_RW, FMT_DEC); -+ -+/* read-only; */ -+PME_SYSFS_ATTR(max_pdsr_index, PRIV_RO, FMT_DEC); -+PME_SYSFS_ATTR(sre_context_size, PRIV_RO, FMT_DEC); -+PME_SYSFS_ATTR(sre_rule_num, PRIV_RO, FMT_DEC); -+PME_SYSFS_ATTR(sre_session_ctx_num, PRIV_RO, FMT_DEC); -+PME_SYSFS_ATTR(sre_max_index_size, PRIV_RO, FMT_DEC); -+PME_SYSFS_ATTR(sre_max_offset_ctrl, PRIV_RO, FMT_DEC); -+PME_SYSFS_ATTR(src_id, PRIV_RO, FMT_DEC); -+PME_SYSFS_ATTR(liodnr, PRIV_RO, FMT_DEC); -+PME_SYSFS_ATTR(rev1, PRIV_RO, FMT_0HEX); -+PME_SYSFS_ATTR(rev2, PRIV_RO, FMT_0HEX); -+PME_SYSFS_ATTR(isr, PRIV_RO, FMT_0HEX); -+PME_SYSFS_ATTR(ecr0, PRIV_RO, FMT_0HEX); -+PME_SYSFS_ATTR(ecr1, PRIV_RO, FMT_0HEX); -+PME_SYSFS_ATTR(pmstat, PRIV_RO, FMT_0HEX); -+PME_SYSFS_ATTR(eccaddr, PRIV_RO, FMT_0HEX); -+PME_SYSFS_ATTR(ecccode, PRIV_RO, FMT_0HEX); -+PME_SYSFS_ATTR(faconf, PRIV_RO, FMT_0HEX); -+PME_SYSFS_ATTR(pdsrbah, PRIV_RO, FMT_0HEX); -+PME_SYSFS_ATTR(pdsrbal, PRIV_RO, FMT_0HEX); -+PME_SYSFS_ATTR(scbarh, PRIV_RO, FMT_0HEX); -+PME_SYSFS_ATTR(scbarl, PRIV_RO, FMT_0HEX); -+ -+ -+/* Buffer Pool Size Configuration */ -+PME_SYSFS_BSC_ATTR(0, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(1, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(2, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(3, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(4, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(5, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(6, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(7, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(8, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(9, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(10, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(11, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(12, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(13, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(14, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(15, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(16, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(17, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(18, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(19, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(20, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(21, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(22, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(23, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(24, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(25, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(26, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(27, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(28, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(29, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(30, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(31, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(32, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(33, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(34, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(35, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(36, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(37, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(38, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(39, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(40, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(41, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(42, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(43, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(44, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(45, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(46, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(47, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(48, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(49, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(50, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(51, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(52, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(53, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(54, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(55, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(56, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(57, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(58, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(59, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(60, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(61, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(62, PRIV_RW, FMT_DEC); -+PME_SYSFS_BSC_ATTR(63, PRIV_RW, FMT_DEC); -+ -+/* Stats Counters*/ -+PME_SYSFS_STAT_ATTR(trunci, PRIV_RW); -+PME_SYSFS_STAT_ATTR(rbc, PRIV_RW); -+PME_SYSFS_STAT_ATTR(tbt0ecc1ec, PRIV_RW); -+PME_SYSFS_STAT_ATTR(tbt1ecc1ec, PRIV_RW); -+PME_SYSFS_STAT_ATTR(vlt0ecc1ec, PRIV_RW); -+PME_SYSFS_STAT_ATTR(vlt1ecc1ec, PRIV_RW); -+PME_SYSFS_STAT_ATTR(cmecc1ec, PRIV_RW); -+PME_SYSFS_STAT_ATTR(dxcmecc1ec, PRIV_RW); -+PME_SYSFS_STAT_ATTR(dxemecc1ec, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stnib, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stnis, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stnth1, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stnth2, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stnthv, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stnths, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stnch, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stnpm, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stns1m, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stnpmr, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stndsr, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stnesr, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stns1r, PRIV_RW); -+PME_SYSFS_STAT_ATTR(stnob, PRIV_RW); -+PME_SYSFS_STAT_ATTR(mia_byc, PRIV_RW); -+PME_SYSFS_STAT_ATTR(mia_blc, PRIV_RW); -+ -+/* Stats Control */ -+PME_SYSFS_ATTR(tbt0ecc1th, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(tbt1ecc1th, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(vlt0ecc1th, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(vlt1ecc1th, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(cmecc1th, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(dxcmecc1th, PRIV_RW, FMT_DEC); -+PME_SYSFS_ATTR(dxemecc1th, PRIV_RW, FMT_DEC); -+ -+static DEVICE_ATTR(update_interval, (S_IRUSR | S_IWUSR), -+ pme_show_update_interval, pme_store_update_interval); -+ -+static struct attribute *pme_dev_bsc_attributes[] = { -+ &dev_attr_0.attr, -+ &dev_attr_1.attr, -+ &dev_attr_2.attr, -+ &dev_attr_3.attr, -+ &dev_attr_4.attr, -+ &dev_attr_5.attr, -+ &dev_attr_6.attr, -+ &dev_attr_7.attr, -+ &dev_attr_8.attr, -+ &dev_attr_9.attr, -+ &dev_attr_10.attr, -+ &dev_attr_11.attr, -+ &dev_attr_12.attr, -+ &dev_attr_13.attr, -+ &dev_attr_14.attr, -+ &dev_attr_15.attr, -+ &dev_attr_16.attr, -+ &dev_attr_17.attr, -+ &dev_attr_18.attr, -+ &dev_attr_19.attr, -+ &dev_attr_20.attr, -+ &dev_attr_21.attr, -+ &dev_attr_22.attr, -+ &dev_attr_23.attr, -+ &dev_attr_24.attr, -+ &dev_attr_25.attr, -+ &dev_attr_26.attr, -+ &dev_attr_27.attr, -+ &dev_attr_28.attr, -+ &dev_attr_29.attr, -+ &dev_attr_30.attr, -+ &dev_attr_31.attr, -+ &dev_attr_32.attr, -+ &dev_attr_33.attr, -+ &dev_attr_34.attr, -+ &dev_attr_35.attr, -+ &dev_attr_36.attr, -+ &dev_attr_37.attr, -+ &dev_attr_38.attr, -+ &dev_attr_39.attr, -+ &dev_attr_40.attr, -+ &dev_attr_41.attr, -+ &dev_attr_42.attr, -+ &dev_attr_43.attr, -+ &dev_attr_44.attr, -+ &dev_attr_45.attr, -+ &dev_attr_46.attr, -+ &dev_attr_47.attr, -+ &dev_attr_48.attr, -+ &dev_attr_49.attr, -+ &dev_attr_50.attr, -+ &dev_attr_51.attr, -+ &dev_attr_52.attr, -+ &dev_attr_53.attr, -+ &dev_attr_54.attr, -+ &dev_attr_55.attr, -+ &dev_attr_56.attr, -+ &dev_attr_57.attr, -+ &dev_attr_58.attr, -+ &dev_attr_59.attr, -+ &dev_attr_60.attr, -+ &dev_attr_61.attr, -+ &dev_attr_62.attr, -+ &dev_attr_63.attr, -+ NULL -+}; -+ -+static struct attribute *pme_dev_attributes[] = { -+ &dev_attr_efqc_int.attr, -+ &dev_attr_sw_db.attr, -+ &dev_attr_dmcr.attr, -+ &dev_attr_smcr.attr, -+ &dev_attr_famcr.attr, -+ &dev_attr_kvlts.attr, -+ &dev_attr_max_chain_length.attr, -+ &dev_attr_pattern_range_counter_idx.attr, -+ &dev_attr_pattern_range_counter_mask.attr, -+ &dev_attr_max_allowed_test_line_per_pattern.attr, -+ &dev_attr_max_pdsr_index.attr, -+ &dev_attr_max_pattern_matches_per_sui.attr, -+ &dev_attr_max_pattern_evaluations_per_sui.attr, -+ &dev_attr_report_length_limit.attr, -+ &dev_attr_end_of_simple_sui_report.attr, -+ &dev_attr_aim.attr, -+ &dev_attr_sre_context_size.attr, -+ &dev_attr_sre_rule_num.attr, -+ &dev_attr_sre_session_ctx_num.attr, -+ &dev_attr_end_of_sui_reaction_ptr.attr, -+ &dev_attr_sre_pscl.attr, -+ &dev_attr_sre_max_block_num.attr, -+ &dev_attr_sre_max_instruction_limit.attr, -+ &dev_attr_sre_max_index_size.attr, -+ &dev_attr_sre_max_offset_ctrl.attr, -+ &dev_attr_src_id.attr, -+ &dev_attr_liodnr.attr, -+ &dev_attr_rev1.attr, -+ &dev_attr_rev2.attr, -+ &dev_attr_isr.attr, -+ &dev_attr_ecr0.attr, -+ &dev_attr_ecr1.attr, -+ &dev_attr_esr.attr, -+ &dev_attr_pmstat.attr, -+ &dev_attr_pehd.attr, -+ &dev_attr_ecc1bes.attr, -+ &dev_attr_ecc2bes.attr, -+ &dev_attr_eccaddr.attr, -+ &dev_attr_ecccode.attr, -+ &dev_attr_miace.attr, -+ &dev_attr_miacr.attr, -+ &dev_attr_cdcr.attr, -+ &dev_attr_pmtr.attr, -+ &dev_attr_faconf.attr, -+ &dev_attr_pdsrbah.attr, -+ &dev_attr_pdsrbal.attr, -+ &dev_attr_scbarh.attr, -+ &dev_attr_scbarl.attr, -+ NULL -+}; -+ -+static struct attribute *pme_dev_stats_counter_attributes[] = { -+ &dev_attr_trunci.attr, -+ &dev_attr_rbc.attr, -+ &dev_attr_tbt0ecc1ec.attr, -+ &dev_attr_tbt1ecc1ec.attr, -+ &dev_attr_vlt0ecc1ec.attr, -+ &dev_attr_vlt1ecc1ec.attr, -+ &dev_attr_cmecc1ec.attr, -+ &dev_attr_dxcmecc1ec.attr, -+ &dev_attr_dxemecc1ec.attr, -+ &dev_attr_stnib.attr, -+ &dev_attr_stnis.attr, -+ &dev_attr_stnth1.attr, -+ &dev_attr_stnth2.attr, -+ &dev_attr_stnthv.attr, -+ &dev_attr_stnths.attr, -+ &dev_attr_stnch.attr, -+ &dev_attr_stnpm.attr, -+ &dev_attr_stns1m.attr, -+ &dev_attr_stnpmr.attr, -+ &dev_attr_stndsr.attr, -+ &dev_attr_stnesr.attr, -+ &dev_attr_stns1r.attr, -+ &dev_attr_stnob.attr, -+ &dev_attr_mia_byc.attr, -+ &dev_attr_mia_blc.attr, -+ NULL -+}; -+ -+static struct attribute *pme_dev_stats_ctrl_attributes[] = { -+ &dev_attr_update_interval.attr, -+ &dev_attr_tbt0ecc1th.attr, -+ &dev_attr_tbt1ecc1th.attr, -+ &dev_attr_vlt0ecc1th.attr, -+ &dev_attr_vlt1ecc1th.attr, -+ &dev_attr_cmecc1th.attr, -+ &dev_attr_dxcmecc1th.attr, -+ &dev_attr_dxemecc1th.attr, -+ NULL -+}; -+ -+/* root level */ -+static const struct attribute_group pme_dev_attr_grp = { -+ .name = NULL, /* put in device directory */ -+ .attrs = pme_dev_attributes -+}; -+ -+/* root/bsc */ -+static struct attribute_group pme_dev_bsc_attr_grp = { -+ .name = "bsc", -+ .attrs = pme_dev_bsc_attributes -+}; -+ -+/* root/stats */ -+static struct attribute_group pme_dev_stats_counters_attr_grp = { -+ .name = "stats", -+ .attrs = pme_dev_stats_counter_attributes -+}; -+ -+/* root/stats_ctrl */ -+static struct attribute_group pme_dev_stats_ctrl_attr_grp = { -+ .name = "stats_ctrl", -+ .attrs = pme_dev_stats_ctrl_attributes -+}; -+ -+ -+int pme2_create_sysfs_dev_files(struct platform_device *ofdev) -+{ -+ int ret; -+ -+ ret = sysfs_create_group(&ofdev->dev.kobj, &pme_dev_attr_grp); -+ if (ret) -+ goto done; -+ ret = sysfs_create_group(&ofdev->dev.kobj, &pme_dev_bsc_attr_grp); -+ if (ret) -+ goto del_group_1; -+ ret = sysfs_create_group(&ofdev->dev.kobj, &pme_dev_stats_counters_attr_grp); -+ if (ret) -+ goto del_group_2; -+ ret = sysfs_create_group(&ofdev->dev.kobj, &pme_dev_stats_ctrl_attr_grp); -+ if (ret) -+ goto del_group_3; -+ goto done; -+del_group_3: -+ sysfs_remove_group(&ofdev->dev.kobj, &pme_dev_stats_counters_attr_grp); -+del_group_2: -+ sysfs_remove_group(&ofdev->dev.kobj, &pme_dev_bsc_attr_grp); -+del_group_1: -+ sysfs_remove_group(&ofdev->dev.kobj, &pme_dev_attr_grp); -+done: -+ if (ret) -+ dev_err(&ofdev->dev, -+ "Cannot create dev attributes ret=%d\n", ret); -+ return ret; -+} -+ -+void pme2_remove_sysfs_dev_files(struct platform_device *ofdev) -+{ -+ sysfs_remove_group(&ofdev->dev.kobj, &pme_dev_stats_ctrl_attr_grp); -+ sysfs_remove_group(&ofdev->dev.kobj, &pme_dev_stats_counters_attr_grp); -+ sysfs_remove_group(&ofdev->dev.kobj, &pme_dev_bsc_attr_grp); -+ sysfs_remove_group(&ofdev->dev.kobj, &pme_dev_attr_grp); -+} -diff --git a/drivers/staging/fsl_pme2/pme2_test.h b/drivers/staging/fsl_pme2/pme2_test.h -new file mode 100644 -index 0000000..994ca26 ---- /dev/null -+++ b/drivers/staging/fsl_pme2/pme2_test.h -@@ -0,0 +1,74 @@ -+/* 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 "pme2_sys.h" -+ -+static inline void __hexdump(unsigned long start, unsigned long end, -+ unsigned long p, size_t sz, const unsigned char *c) -+{ -+ while (start < end) { -+ unsigned int pos = 0; -+ char buf[64]; -+ int nl = 0; -+ pos += sprintf(buf + pos, "%08lx: ", start); -+ do { -+ if ((start < p) || (start >= (p + sz))) -+ pos += sprintf(buf + pos, ".."); -+ else -+ pos += sprintf(buf + pos, "%02x", *(c++)); -+ if (!(++start & 15)) { -+ buf[pos++] = '\n'; -+ nl = 1; -+ } else { -+ nl = 0; -+ if(!(start & 1)) -+ buf[pos++] = ' '; -+ if(!(start & 3)) -+ buf[pos++] = ' '; -+ } -+ } while (start & 15); -+ if (!nl) -+ buf[pos++] = '\n'; -+ buf[pos] = '\0'; -+ pr_info("%s", buf); -+ } -+} -+static inline void hexdump(const void *ptr, size_t sz) -+{ -+ unsigned long p = (unsigned long)ptr; -+ unsigned long start = p & ~(unsigned long)15; -+ unsigned long end = (p + sz + 15) & ~(unsigned long)15; -+ const unsigned char *c = ptr; -+ __hexdump(start, end, p, sz, c); -+} -+ -+int pme2_sample_db(void); -+int pme2_clear_sample_db(void); -diff --git a/drivers/staging/fsl_pme2/pme2_test_high.c b/drivers/staging/fsl_pme2/pme2_test_high.c -new file mode 100644 -index 0000000..a54cf0f ---- /dev/null -+++ b/drivers/staging/fsl_pme2/pme2_test_high.c -@@ -0,0 +1,237 @@ -+/* 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 "pme2_test.h" -+ -+MODULE_AUTHOR("Geoff Thorpe"); -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("FSL PME2 (p4080) high-level self-test"); -+ -+/* Default Flow Context State */ -+static u8 fl_ctx_exp[]={ -+ 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe0, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 -+}; -+ -+void scan_cb(struct pme_ctx *ctx, const struct qm_fd *fd, -+ struct pme_ctx_token *token) -+{ -+ hexdump(fd, sizeof(*fd)); -+} -+ -+struct ctrl_op { -+ struct pme_ctx_ctrl_token ctx_ctr; -+ struct completion cb_done; -+ enum pme_status cmd_status; -+ u8 res_flag; -+}; -+ -+static void ctrl_cb(struct pme_ctx *ctx, const struct qm_fd *fd, -+ struct pme_ctx_ctrl_token *token) -+{ -+ struct ctrl_op *ctrl = (struct ctrl_op *)token; -+ pr_info("pme2_test_high: ctrl_cb() invoked, fd;!\n"); -+ ctrl->cmd_status = pme_fd_res_status(fd); -+ ctrl->res_flag = pme_fd_res_flags(fd); -+ hexdump(fd, sizeof(*fd)); -+ complete(&ctrl->cb_done); -+} -+ -+ -+#define POST_CTRL(val) \ -+do { \ -+ if (ret) \ -+ val = -1;\ -+ else if (pme_ctx_is_dead(&ctx))\ -+ val = -1;\ -+ else if (ctx_ctrl.cmd_status)\ -+ val = -1;\ -+ else if (ctx_ctrl.res_flag)\ -+ val = -1;\ -+} while (0) -+ -+void pme2_test_high(void) -+{ -+ int post_ctrl = 0; -+ struct pme_flow flow; -+ struct qm_fqd_stashing stashing; -+ struct pme_ctx ctx = { -+ .cb = scan_cb -+ }; -+ int ret; -+ struct ctrl_op ctx_ctrl = { -+ .ctx_ctr.cb = ctrl_cb, -+ .cmd_status = 0, -+ .res_flag = 0 -+ }; -+ struct cpumask backup_mask = current->cpus_allowed; -+ struct cpumask new_mask = *qman_affine_cpus(); -+ -+ pr_info("PME2: high-level test starting\n"); -+ -+ cpumask_and(&new_mask, &new_mask, bman_affine_cpus()); -+ ret = set_cpus_allowed_ptr(current, &new_mask); -+ if (ret) { -+ post_ctrl = -1; -+ pr_info("PME2: test high: can't set cpumask\n"); -+ goto done; -+ } -+ -+ pme_sw_flow_init(&flow); -+ init_completion(&ctx_ctrl.cb_done); -+ ret = pme_ctx_init(&ctx, PME_CTX_FLAG_LOCAL, 0, 4, 4, 0, NULL); -+ POST_CTRL(post_ctrl); -+ if (post_ctrl) -+ goto restore_mask; -+ -+ /* enable the context */ -+ pme_ctx_enable(&ctx); -+ pr_info("PME2: pme_ctx_enable done\n"); -+ ret = pme_ctx_ctrl_update_flow(&ctx, PME_CTX_OP_WAIT | PME_CMD_FCW_ALL, -+ &flow, &ctx_ctrl.ctx_ctr); -+ pr_info("PME2: pme_ctx_ctrl_update_flow done\n"); -+ wait_for_completion(&ctx_ctrl.cb_done); -+ POST_CTRL(post_ctrl); -+ if (post_ctrl) -+ goto disable_ctx; -+ /* read back flow settings */ -+ ret = pme_ctx_ctrl_read_flow(&ctx, PME_CTX_OP_WAIT, &flow, -+ &ctx_ctrl.ctx_ctr); -+ pr_info("PME2: pme_ctx_ctrl_read_flow done\n"); -+ wait_for_completion(&ctx_ctrl.cb_done); -+ POST_CTRL(post_ctrl); -+ if (post_ctrl) -+ goto disable_ctx; -+ if (memcmp(&flow, fl_ctx_exp, sizeof(flow))) { -+ pr_info("Default Flow Context Read FAIL\n"); -+ pr_info("Expected:\n"); -+ hexdump(fl_ctx_exp, sizeof(fl_ctx_exp)); -+ pr_info("Received:\n"); -+ hexdump(&flow, sizeof(flow)); -+ post_ctrl = -1; -+ goto disable_ctx; -+ } else -+ pr_info("Default Flow Context Read OK\n"); -+ /* start a NOP */ -+ ret = pme_ctx_ctrl_nop(&ctx, 0, &ctx_ctrl.ctx_ctr); -+ pr_info("PME2: pme_ctx_ctrl_nop done\n"); -+ wait_for_completion(&ctx_ctrl.cb_done); -+ POST_CTRL(post_ctrl); -+ if (post_ctrl) -+ goto disable_ctx; -+ /* start an update to add residue to the context */ -+ flow.ren = 1; -+ ret = pme_ctx_ctrl_update_flow(&ctx, PME_CTX_OP_WAIT | PME_CMD_FCW_RES, -+ &flow, &ctx_ctrl.ctx_ctr); -+ pr_info("PME2: pme_ctx_ctrl_update_flow done\n"); -+ wait_for_completion(&ctx_ctrl.cb_done); -+ POST_CTRL(post_ctrl); -+ if (post_ctrl) -+ goto disable_ctx; -+ /* start a blocking disable */ -+ ret = pme_ctx_disable(&ctx, PME_CTX_OP_WAIT, &ctx_ctrl.ctx_ctr); -+ if (ret < 1) { -+ post_ctrl = -1; -+ goto finish_ctx; -+ } -+ wait_for_completion(&ctx_ctrl.cb_done); -+ /* do some reconfiguration */ -+ ret = pme_ctx_reconfigure_tx(&ctx, 63, 7); -+ if (ret) { -+ post_ctrl = -1; -+ goto finish_ctx; -+ } -+ stashing.exclusive = 0; -+ stashing.annotation_cl = 0; -+ stashing.data_cl = 2; -+ stashing.context_cl = 2; -+ ret = pme_ctx_reconfigure_rx(&ctx, 7, 0, &stashing); -+ if (ret) { -+ post_ctrl = -1; -+ goto finish_ctx; -+ } -+ /* reenable */ -+ ret = pme_ctx_enable(&ctx); -+ if (ret) { -+ post_ctrl = -1; -+ goto finish_ctx; -+ } -+ /* read back flow settings */ -+ ret = pme_ctx_ctrl_read_flow(&ctx, -+ PME_CTX_OP_WAIT | PME_CTX_OP_WAIT_INT | PME_CMD_FCW_RES, &flow, -+ &ctx_ctrl.ctx_ctr); -+ pr_info("PME2: pme_ctx_ctrl_read_flow done\n"); -+ wait_for_completion(&ctx_ctrl.cb_done); -+ POST_CTRL(post_ctrl); -+ if (post_ctrl) -+ goto disable_ctx; -+ /* blocking NOP */ -+ ret = pme_ctx_ctrl_nop(&ctx, PME_CTX_OP_WAIT | PME_CTX_OP_WAIT_INT, -+ &ctx_ctrl.ctx_ctr); -+ pr_info("PME2: pme_ctx_ctrl_nop done\n"); -+ wait_for_completion(&ctx_ctrl.cb_done); -+ POST_CTRL(post_ctrl); -+ /* Disable, and done */ -+disable_ctx: -+ ret = pme_ctx_disable(&ctx, PME_CTX_OP_WAIT, &ctx_ctrl.ctx_ctr); -+ BUG_ON(ret < 1); -+ wait_for_completion(&ctx_ctrl.cb_done); -+finish_ctx: -+ pme_ctx_finish(&ctx); -+restore_mask: -+ ret = set_cpus_allowed_ptr(current, &backup_mask); -+ if (ret) { -+ pr_err("PME2 test high: can't restore cpumask"); -+ post_ctrl = -1; -+ } -+done: -+ if (post_ctrl) -+ pr_info("PME2: high-level test failed\n"); -+ else -+ pr_info("PME2: high-level test passed\n"); -+} -+ -+static int pme2_test_high_init(void) -+{ -+ int big_loop = 2; -+ while (big_loop--) -+ pme2_test_high(); -+ return 0; -+} -+ -+static void pme2_test_high_exit(void) -+{ -+} -+ -+module_init(pme2_test_high_init); -+module_exit(pme2_test_high_exit); -diff --git a/drivers/staging/fsl_pme2/pme2_test_scan.c b/drivers/staging/fsl_pme2/pme2_test_scan.c -new file mode 100644 -index 0000000..65608db ---- /dev/null -+++ b/drivers/staging/fsl_pme2/pme2_test_scan.c -@@ -0,0 +1,653 @@ -+/* Copyright 2009-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 "pme2_test.h" -+ -+enum scan_ctrl_mode { -+ no_scan = 0, -+ do_scan = 1, -+}; -+ -+enum db_ctrl_mode { -+ create_destroy = 0, -+ create = 1, -+ destroy = 2, -+ nothing = 3 -+}; -+ -+MODULE_AUTHOR("Jeffrey Ladouceur"); -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("PME scan testing"); -+ -+static enum db_ctrl_mode db_ctrl; -+module_param(db_ctrl, uint, 0644); -+MODULE_PARM_DESC(db_ctrl, "PME Database control"); -+ -+static enum scan_ctrl_mode scan_ctrl = 1; -+module_param(scan_ctrl, uint, 0644); -+MODULE_PARM_DESC(scan_ctrl, "Scan control"); -+ -+static u8 scan_result_direct_mode_inc_mode[] = { -+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 -+}; -+ -+static u8 fl_ctx_exp[] = { -+ 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe0, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 -+}; -+ -+/* same again with 'sos' bit cleared */ -+static u8 fl_ctx_exp_post_scan[] = { -+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe0, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 -+}; -+ -+struct scan_ctx { -+ struct pme_ctx base_ctx; -+ struct qm_fd result_fd; -+}; -+ -+struct ctrl_op { -+ struct pme_ctx_ctrl_token ctx_ctr; -+ struct completion cb_done; -+ enum pme_status cmd_status; -+ u8 res_flag; -+}; -+ -+static void ctrl_cb(struct pme_ctx *ctx, const struct qm_fd *fd, -+ struct pme_ctx_ctrl_token *token) -+{ -+ struct ctrl_op *ctrl = (struct ctrl_op *)token; -+ ctrl->cmd_status = pme_fd_res_status(fd); -+ ctrl->res_flag = pme_fd_res_flags(fd) & PME_STATUS_UNRELIABLE; -+ /* hexdump(fd, sizeof(*fd)); */ -+ complete(&ctrl->cb_done); -+} -+ -+static DECLARE_COMPLETION(scan_comp); -+ -+static void scan_cb(struct pme_ctx *ctx, const struct qm_fd *fd, -+ struct pme_ctx_token *ctx_token) -+{ -+ struct scan_ctx *my_ctx = (struct scan_ctx *)ctx; -+ memcpy(&my_ctx->result_fd, fd, sizeof(*fd)); -+ complete(&scan_comp); -+} -+ -+#ifdef CONFIG_FSL_PME2_TEST_SCAN_WITH_BPID -+ -+static struct bman_pool *pool; -+static u32 pme_bpid; -+static void *bman_buffers_virt_base; -+static dma_addr_t bman_buffers_phys_base; -+ -+static void release_buffer(dma_addr_t addr) -+{ -+ struct bm_buffer bufs_in; -+ bm_buffer_set64(&bufs_in, addr); -+ if (bman_release(pool, &bufs_in, 1, BMAN_RELEASE_FLAG_WAIT)) -+ panic("bman_release() failed\n"); -+} -+ -+static void empty_buffer(void) -+{ -+ struct bm_buffer bufs_in; -+ int ret; -+ -+ do { -+ ret = bman_acquire(pool, &bufs_in, 1, 0); -+ } while (!ret); -+} -+#endif /*CONFIG_FSL_PME2_TEST_SCAN_WITH_BPID*/ -+ -+static int scan_test_direct(int trunc, int use_bp) -+{ -+ struct scan_ctx a_scan_ctx = { -+ .base_ctx = { -+ .cb = scan_cb -+ } -+ }; -+ struct ctrl_op ctx_ctrl = { -+ .ctx_ctr.cb = ctrl_cb, -+ .cmd_status = 0, -+ .res_flag = 0 -+ }; -+ struct qm_fd fd; -+ struct qm_sg_entry sg_table[2]; -+ int ret; -+ enum pme_status status; -+ struct pme_ctx_token token; -+ u8 *scan_result; -+ u32 scan_result_size; -+ u8 scan_data[] = { -+ 0x41, 0x42, 0x43, 0x44, 0x45 -+ }; -+ u8 result_data[] = { -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00 -+ }; -+ -+ init_completion(&ctx_ctrl.cb_done); -+ scan_result = scan_result_direct_mode_inc_mode; -+ scan_result_size = sizeof(scan_result_direct_mode_inc_mode); -+ -+ ret = pme_ctx_init(&a_scan_ctx.base_ctx, -+ PME_CTX_FLAG_DIRECT | PME_CTX_FLAG_LOCAL, -+ 0, 4, 4, 0, NULL); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ return ret; -+ } -+ /* enable the context */ -+ ret = pme_ctx_enable(&a_scan_ctx.base_ctx); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto ctx_finish; -+ } -+ -+ /* Do a pre-built output, scan with match test */ -+ /* Build a frame descriptor */ -+ memset(&fd, 0, sizeof(struct qm_fd)); -+ memset(&sg_table, 0, sizeof(sg_table)); -+ -+ if (trunc) { -+ fd.length20 = sizeof(scan_data); -+ qm_fd_addr_set64(&fd, pme_map(scan_data)); -+ } else { -+ /* build the result */ -+ qm_sg_entry_set64(&sg_table[0], pme_map(result_data)); -+ sg_table[0].length = sizeof(result_data); -+ qm_sg_entry_set64(&sg_table[1], pme_map(scan_data)); -+ sg_table[1].length = sizeof(scan_data); -+ sg_table[1].final = 1; -+ fd._format2 = qm_fd_compound; -+ qm_fd_addr_set64(&fd, pme_map(sg_table)); -+ } -+ -+ ret = pme_ctx_scan(&a_scan_ctx.base_ctx, 0, &fd, -+ PME_SCAN_ARGS(PME_CMD_SCAN_SR | PME_CMD_SCAN_E, 0, 0xff00), -+ &token); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto ctx_disable; -+ } -+ wait_for_completion(&scan_comp); -+ -+ status = pme_fd_res_status(&a_scan_ctx.result_fd); -+ if (status) { -+ pr_err("pme scan test failed 0x%x\n", status); -+ goto ctx_disable; -+ } -+ if (trunc) { -+ int res_flag = pme_fd_res_flags(&a_scan_ctx.result_fd); -+ /* Check the response...expect truncation bit to be set */ -+ if (!(res_flag & PME_STATUS_TRUNCATED)) { -+ pr_err("pme scan test failed, expected truncation\n"); -+ goto ctx_disable; -+ } -+ } else { -+ if (memcmp(scan_result, result_data, scan_result_size) != 0) { -+ pr_err("pme scan test result not expected\n"); -+ hexdump(scan_result, scan_result_size); -+ pr_err("Received...\n"); -+ hexdump(result_data, sizeof(result_data)); -+ goto ctx_disable; -+ } -+ } -+ -+ ret = pme_ctx_disable(&a_scan_ctx.base_ctx, PME_CTX_OP_WAIT, NULL); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto ctx_finish; -+ } -+ if (!use_bp) { -+ pme_ctx_finish(&a_scan_ctx.base_ctx); -+ return 0; -+ } -+ /* use buffer pool */ -+ /* Check with bman */ -+ /* reconfigure */ -+ -+#ifdef CONFIG_FSL_PME2_TEST_SCAN_WITH_BPID -+ ret = pme_ctx_reconfigure_tx(&a_scan_ctx.base_ctx, pme_bpid, 5); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto ctx_finish; -+ } -+ ret = pme_ctx_enable(&a_scan_ctx.base_ctx); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto ctx_finish; -+ } -+ /* Do a pre-built output, scan with match test */ -+ /* Build a frame descriptor */ -+ memset(&fd, 0, sizeof(struct qm_fd)); -+ memset(&sg_table, 0, sizeof(sg_table)); -+ -+ /* build the result */ -+ /* result is all zero...use bman */ -+ qm_sg_entry_set64(&sg_table[1], pme_map(scan_data)); -+ sg_table[1].length = sizeof(scan_data); -+ sg_table[1].final = 1; -+ -+ fd._format2 = qm_fd_compound; -+ qm_fd_addr_set64(&fd, pme_map(sg_table)); -+ -+ ret = pme_ctx_scan(&a_scan_ctx.base_ctx, 0, &fd, -+ PME_SCAN_ARGS(PME_CMD_SCAN_SR | PME_CMD_SCAN_E, 0, 0xff00), -+ &token); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto ctx_disable; -+ } -+ wait_for_completion(&scan_comp); -+ -+ status = pme_fd_res_status(&a_scan_ctx.result_fd); -+ if (status) { -+ pr_err("pme scan test failed 0x%x\n", status); -+ goto ctx_disable; -+ } -+ /* sg result should point to bman buffer */ -+ if (!qm_sg_entry_get64(&sg_table[0])) { -+ pr_err("pme scan test failed, sg result not bman buffer\n"); -+ goto ctx_disable; -+ } -+ if (memcmp(scan_result, bman_buffers_virt_base, scan_result_size) -+ != 0) { -+ pr_err("pme scan test not expected, Expected\n"); -+ hexdump(scan_result, scan_result_size); -+ pr_err("Received...\n"); -+ hexdump(bman_buffers_virt_base, scan_result_size); -+ release_buffer(qm_sg_entry_get64(&sg_table[0])); -+ goto ctx_disable; -+ } -+ release_buffer(qm_sg_entry_get64(&sg_table[0])); -+ ret = pme_ctx_disable(&a_scan_ctx.base_ctx, PME_CTX_OP_WAIT, NULL); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto ctx_finish; -+ } -+ pme_ctx_finish(&a_scan_ctx.base_ctx); -+ return 0; -+#endif -+ -+/* failure path */ -+ctx_disable: -+ ret = pme_ctx_disable(&a_scan_ctx.base_ctx, PME_CTX_OP_WAIT, NULL); -+ctx_finish: -+ pme_ctx_finish(&a_scan_ctx.base_ctx); -+ return (!ret) ? -EINVAL : ret; -+} -+ -+static int scan_test_flow(void) -+{ -+ struct pme_flow flow; -+ struct pme_flow rb_flow; -+ struct scan_ctx a_scan_ctx = { -+ .base_ctx = { -+ .cb = scan_cb -+ } -+ }; -+ struct ctrl_op ctx_ctrl = { -+ .ctx_ctr.cb = ctrl_cb, -+ .cmd_status = 0, -+ .res_flag = 0 -+ }; -+ struct qm_fd fd; -+ struct qm_sg_entry sg_table[2]; -+ int ret; -+ enum pme_status status; -+ struct pme_ctx_token token; -+ u8 *scan_result; -+ u32 scan_result_size; -+ u8 scan_data[] = { -+ 0x41, 0x42, 0x43, 0x44, 0x45 -+ }; -+ u8 result_data[] = { -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00 -+ }; -+ -+ pme_sw_flow_init(&flow); -+ init_completion(&ctx_ctrl.cb_done); -+ scan_result = scan_result_direct_mode_inc_mode; -+ scan_result_size = sizeof(scan_result_direct_mode_inc_mode); -+ -+ ret = pme_ctx_init(&a_scan_ctx.base_ctx, -+ PME_CTX_FLAG_LOCAL, 0, 4, 4, 0, NULL); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ return ret; -+ } -+ /* enable the context */ -+ ret = pme_ctx_enable(&a_scan_ctx.base_ctx); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto flow_ctx_finish; -+ } -+ ret = pme_ctx_ctrl_update_flow(&a_scan_ctx.base_ctx, -+ PME_CTX_OP_WAIT | PME_CMD_FCW_ALL, &flow, &ctx_ctrl.ctx_ctr); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto flow_ctx_disable; -+ } -+ wait_for_completion(&ctx_ctrl.cb_done); -+ if (ctx_ctrl.cmd_status || ctx_ctrl.res_flag) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto flow_ctx_disable; -+ } -+ /* read back flow settings */ -+ ret = pme_ctx_ctrl_read_flow(&a_scan_ctx.base_ctx, -+ PME_CTX_OP_WAIT, &rb_flow, &ctx_ctrl.ctx_ctr); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto flow_ctx_disable; -+ } -+ wait_for_completion(&ctx_ctrl.cb_done); -+ if (ctx_ctrl.cmd_status || ctx_ctrl.res_flag) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto flow_ctx_disable; -+ } -+ if (memcmp(&rb_flow, fl_ctx_exp, sizeof(rb_flow)) != 0) { -+ pr_err("pme scan test Flow Context Read FAIL\n"); -+ pr_err("Expected\n"); -+ hexdump(fl_ctx_exp, sizeof(fl_ctx_exp)); -+ pr_err("Received...\n"); -+ hexdump(&rb_flow, sizeof(rb_flow)); -+ goto flow_ctx_disable; -+ } -+ -+ /* Do a pre-built output, scan with match test */ -+ /* Build a frame descriptor */ -+ memset(&fd, 0, sizeof(struct qm_fd)); -+ memset(&sg_table, 0, sizeof(sg_table)); -+ -+ /* build the result */ -+ qm_sg_entry_set64(&sg_table[0], pme_map(result_data)); -+ sg_table[0].length = sizeof(result_data); -+ qm_sg_entry_set64(&sg_table[1], pme_map(scan_data)); -+ sg_table[1].length = sizeof(scan_data); -+ sg_table[1].final = 1; -+ -+ fd._format2 = qm_fd_compound; -+ qm_fd_addr_set64(&fd, pme_map(sg_table)); -+ -+ ret = pme_ctx_scan(&a_scan_ctx.base_ctx, 0, &fd, -+ PME_SCAN_ARGS(PME_CMD_SCAN_SR | PME_CMD_SCAN_E, 0, 0xff00), -+ &token); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto flow_ctx_disable; -+ } -+ wait_for_completion(&scan_comp); -+ -+ status = pme_fd_res_status(&a_scan_ctx.result_fd); -+ if (status) { -+ pr_err("pme scan test failed 0x%x\n", status); -+ goto flow_ctx_disable; -+ } -+ -+ if (memcmp(scan_result, result_data, scan_result_size) != 0) { -+ pr_err("pme scan test result not expected\n"); -+ hexdump(scan_result, scan_result_size); -+ pr_err("Received...\n"); -+ hexdump(result_data, sizeof(result_data)); -+ goto flow_ctx_disable; -+ } -+ -+ /* read back flow settings */ -+ ret = pme_ctx_ctrl_read_flow(&a_scan_ctx.base_ctx, -+ PME_CTX_OP_WAIT, &rb_flow, &ctx_ctrl.ctx_ctr); -+ if (ret) { -+ pr_err("pme scan test failed 0x%x\n", status); -+ goto flow_ctx_disable; -+ } -+ wait_for_completion(&ctx_ctrl.cb_done); -+ if (ctx_ctrl.cmd_status || ctx_ctrl.res_flag) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto flow_ctx_disable; -+ } -+ if (memcmp(&rb_flow, fl_ctx_exp_post_scan, sizeof(rb_flow)) != 0) { -+ pr_err("pme scan test Flow Context Read FAIL\n"); -+ pr_err("Expected\n"); -+ hexdump(fl_ctx_exp_post_scan, sizeof(fl_ctx_exp_post_scan)); -+ pr_err("Received\n"); -+ hexdump(&rb_flow, sizeof(rb_flow)); -+ goto flow_ctx_disable; -+ } -+ -+ /* Test truncation test */ -+ /* Build a frame descriptor */ -+ memset(&fd, 0, sizeof(struct qm_fd)); -+ -+ fd.length20 = sizeof(scan_data); -+ qm_fd_addr_set64(&fd, pme_map(scan_data)); -+ -+ ret = pme_ctx_scan(&a_scan_ctx.base_ctx, 0, &fd, -+ PME_SCAN_ARGS(PME_CMD_SCAN_SR | PME_CMD_SCAN_E, 0, 0xff00), -+ &token); -+ if (ret) { -+ pr_err("pme scan test failed 0x%x\n", status); -+ goto flow_ctx_disable; -+ } -+ wait_for_completion(&scan_comp); -+ -+ status = pme_fd_res_status(&a_scan_ctx.result_fd); -+ if (status) { -+ pr_err("pme scan test failed 0x%x\n", status); -+ goto flow_ctx_disable; -+ } -+ /* Check the response...expect truncation bit to be set */ -+ if (!(pme_fd_res_flags(&a_scan_ctx.result_fd) & PME_STATUS_TRUNCATED)) { -+ pr_err("st: Scan result failed...expected trunc\n"); -+ goto flow_ctx_disable; -+ } -+ -+ /* read back flow settings */ -+ ret = pme_ctx_ctrl_read_flow(&a_scan_ctx.base_ctx, -+ PME_CTX_OP_WAIT, &rb_flow, &ctx_ctrl.ctx_ctr); -+ if (ret) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto flow_ctx_disable; -+ } -+ wait_for_completion(&ctx_ctrl.cb_done); -+ if (ctx_ctrl.cmd_status || ctx_ctrl.res_flag) { -+ pr_err("pme scan test failed: 0x%x\n", ret); -+ goto flow_ctx_disable; -+ } -+ if (memcmp(&rb_flow, fl_ctx_exp_post_scan, sizeof(rb_flow)) != 0) { -+ pr_err("pme scan test Flow Context Read FAIL\n"); -+ pr_err("Expected\n"); -+ hexdump(fl_ctx_exp_post_scan, sizeof(fl_ctx_exp_post_scan)); -+ pr_err("Received\n"); -+ hexdump(&rb_flow, sizeof(rb_flow)); -+ goto flow_ctx_disable; -+ } -+ -+ /* Disable */ -+ ret = pme_ctx_disable(&a_scan_ctx.base_ctx, PME_CTX_OP_WAIT, -+ &ctx_ctrl.ctx_ctr); -+ if (ret < 1) { -+ pr_err("pme scan test failed 0x%x\n", ret); -+ goto flow_ctx_finish; -+ } -+ wait_for_completion(&ctx_ctrl.cb_done); -+ pme_ctx_finish(&a_scan_ctx.base_ctx); -+ return 0; -+ /* error path */ -+/* failure path */ -+flow_ctx_disable: -+ ret = pme_ctx_disable(&a_scan_ctx.base_ctx, PME_CTX_OP_WAIT, NULL); -+flow_ctx_finish: -+ pme_ctx_finish(&a_scan_ctx.base_ctx); -+ return (!ret) ? -EINVAL : ret; -+} -+ -+void pme2_test_scan(void) -+{ -+ int ret; -+ -+ ret = scan_test_direct(0, 0); -+ if (ret) -+ goto done; -+ ret = scan_test_direct(1, 0); -+ if (ret) -+ goto done; -+#ifdef CONFIG_FSL_PME2_TEST_SCAN_WITH_BPID -+ ret = scan_test_direct(0, 1); -+ if (ret) -+ goto done; -+#endif -+ ret = scan_test_flow(); -+done: -+ if (ret) -+ pr_info("pme scan test FAILED 0x%x\n", ret); -+ else -+ pr_info("pme Scan Test Passed\n"); -+} -+ -+static int setup_buffer_pool(void) -+{ -+#ifdef CONFIG_FSL_PME2_TEST_SCAN_WITH_BPID -+ u32 bpid_size = CONFIG_FSL_PME2_TEST_SCAN_WITH_BPID_SIZE; -+ struct bman_pool_params pparams = { -+ .flags = BMAN_POOL_FLAG_DYNAMIC_BPID, -+ .thresholds = { -+ 0, -+ 0, -+ 0, -+ 0 -+ } -+ }; -+ -+ if (!pme2_have_control()) { -+ pr_err("pme scan test: Not the ctrl-plane\n"); -+ return -EINVAL; -+ } -+ pool = bman_new_pool(&pparams); -+ if (!pool) { -+ pr_err("pme scan test: can't get buffer pool\n"); -+ return -EINVAL; -+ } -+ pme_bpid = bman_get_params(pool)->bpid; -+ bman_buffers_virt_base = kmalloc(1<<(bpid_size+5), GFP_KERNEL); -+ bman_buffers_phys_base = pme_map(bman_buffers_virt_base); -+ if (pme_map_error(bman_buffers_phys_base)) { -+ pr_info("pme scan test: pme_map_error\n"); -+ bman_free_pool(pool); -+ kfree(bman_buffers_virt_base); -+ return -ENODEV; -+ } -+ release_buffer(bman_buffers_phys_base); -+ /* Configure the buffer pool */ -+ pme_attr_set(pme_attr_bsc(pme_bpid), bpid_size); -+ /* realease to the specified buffer pool */ -+ return 0; -+#endif -+ return 0; -+} -+ -+static int teardown_buffer_pool(void) -+{ -+#ifdef CONFIG_FSL_PME2_TEST_SCAN_WITH_BPID -+ pme_attr_set(pme_attr_bsc(pme_bpid), 0); -+ empty_buffer(); -+ bman_free_pool(pool); -+ kfree(bman_buffers_virt_base); -+#endif -+ return 0; -+} -+ -+static int pme2_test_scan_init(void) -+{ -+ int big_loop = 2; -+ int ret = 0; -+ struct cpumask backup_mask = current->cpus_allowed; -+ struct cpumask new_mask = *qman_affine_cpus(); -+ -+ cpumask_and(&new_mask, &new_mask, bman_affine_cpus()); -+ ret = set_cpus_allowed_ptr(current, &new_mask); -+ if (ret) { -+ pr_info("pme scan test: can't set cpumask\n"); -+ goto done_all; -+ } -+ -+ ret = setup_buffer_pool(); -+ if (ret) -+ goto done_cpu_mask; -+ -+ /* create sample database */ -+ if (db_ctrl == create_destroy || db_ctrl == create) { -+ if (!pme2_have_control()) { -+ pr_err("pme scan test: Not the ctrl-plane\n"); -+ ret = -EINVAL; -+ goto done_scan; -+ } -+ if (pme2_sample_db()) { -+ pr_err("pme scan test: error creating db\n"); -+ goto done_scan; -+ } -+ } -+ -+ if (scan_ctrl == do_scan) { -+ while (big_loop--) -+ pme2_test_scan(); -+ } -+ -+ if (db_ctrl == create_destroy || db_ctrl == destroy) { -+ /* Clear database */ -+ if (pme2_clear_sample_db()) -+ pr_err("pme scan test: error clearing db\n"); -+ } -+ -+done_scan: -+ teardown_buffer_pool(); -+done_cpu_mask: -+ ret = set_cpus_allowed_ptr(current, &backup_mask); -+ if (ret) -+ pr_err("PME2 test high: can't restore cpumask"); -+done_all: -+ return ret; -+} -+ -+static void pme2_test_scan_exit(void) -+{ -+} -+ -+module_init(pme2_test_scan_init); -+module_exit(pme2_test_scan_exit); -diff --git a/drivers/staging/fsl_qbman/Kconfig b/drivers/staging/fsl_qbman/Kconfig -new file mode 100644 -index 0000000..1c3906b ---- /dev/null -+++ b/drivers/staging/fsl_qbman/Kconfig -@@ -0,0 +1,232 @@ -+config FSL_DPA -+ bool "Freescale Datapath Queue and Buffer management" -+ depends on HAS_FSL_QBMAN -+ default y -+ select FSL_QMAN_FQ_LOOKUP if PPC64 -+ -+menu "Freescale Datapath QMan/BMan options" -+ depends on FSL_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_DPA_UIO -+ tristate "export USDPAA portals via UIO" -+ depends on UIO -+ default y -+ ---help--- -+ Any portals unused by the kernel are exported as UIO devices for -+ use by USDPAA (User Space DataPath Acceleration Architecture) -+ applications. -+ -+config FSL_BMAN -+ bool "Freescale Buffer Manager (BMan) support" -+ default y -+ -+if FSL_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_BMAN -+ -+config FSL_QMAN -+ bool "Freescale Queue Manager (QMan) support" -+ default y -+ -+if FSL_QMAN -+ -+config FSL_QMAN_BUG_AND_FEATURE_REV1 -+ bool "workarounds for errata and missing features in p4080 rev1" -+ default y -+ ---help--- -+ If this option is selected, the driver will be compiled with -+ workarounds for errata as well as feature limitations (relative to -+ more recent parts) of p4080 rev1. On unaffected revisions, this -+ support incurs only a negligable overhead, typically only a couple of -+ instructions per non-fast-path operation (the fast-path operations are -+ unaffected). -+ -+ If in doubt, say Y. -+ -+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_TEST_ERRATA -+ bool "QMan errata-handling self-test" -+ depends on FSL_QMAN_TEST -+ default y -+ ---help--- -+ This requires the presence of cpu-affine portals, and performs -+ testing that handling for known hardware-errata is correct. -+ -+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. -+ -+endif # FSL_QMAN -+ -+endmenu -diff --git a/drivers/staging/fsl_qbman/Makefile b/drivers/staging/fsl_qbman/Makefile -new file mode 100644 -index 0000000..330cdfb ---- /dev/null -+++ b/drivers/staging/fsl_qbman/Makefile -@@ -0,0 +1,25 @@ -+# Common -+obj-$(CONFIG_FSL_DPA) += dpa_alloc.o -+ -+# Bman -+obj-$(CONFIG_FSL_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_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_test_hotpotato.o \ -+ qman_test_high.o -+qman_tester-$(CONFIG_FSL_QMAN_TEST_ERRATA) += qman_test_errata.o -+obj-$(CONFIG_FSL_QMAN_DEBUGFS) += qman_debugfs_interface.o -+qman_debugfs_interface-y = qman_debugfs.o -+ -+# USDPAA -+obj-$(CONFIG_FSL_DPA_UIO) += dpa_uio.o -diff --git a/drivers/staging/fsl_qbman/bman_config.c b/drivers/staging/fsl_qbman/bman_config.c -new file mode 100644 -index 0000000..4ea7418 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_config.c -@@ -0,0 +1,718 @@ -+/* 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. -+ */ -+ -+#ifndef CONFIG_SMP -+#include /* get_hard_smp_processor_id() */ -+#endif -+ -+#include -+#include "bman_private.h" -+ -+/* 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_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 { -+ u32 __reserved1:4; -+ u32 portal_num:4; -+ u32 __reserved2:12; -+ u32 numb:4; -+ u32 __reserved3:2; -+ u32 pid:6; -+ } __packed info; -+}; -+ -+union bman_eadr { -+ u32 eadr_raw; -+ struct { -+ u32 __reserved1:5; -+ u32 memid:3; -+ u32 __reserved2:14; -+ u32 eadr:10; -+ } __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); -+} -+ -+#if 0 -+static void bm_get_details(struct bman *bm, u8 *int_options, u8 *errata, -+ u8 *conf_options) -+{ -+ u32 v = bm_in(IP_REV_1); -+ *int_options = (v >> 16) & 0xff; -+ *errata = (v >> 8) & 0xff; -+ *conf_options = v & 0xff; -+} -+ -+static u8 bm_get_corenet_sourceid(struct bman *bm) -+{ -+ return bm_in(SRCIDR); -+} -+ -+static void bm_set_liodn(struct bman *bm, u16 liodn) -+{ -+ bm_out(LIODNR, liodn & 0xfff); -+} -+ -+#endif -+ -+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; -+ -+/* 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 BMAN 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) -+{ -+ const u32 *pint; -+ int ret; -+ unsigned long vaddr; -+ -+ pint = of_get_property(node, name, &ret); -+ if (!pint || (ret != 16)) { -+ pr_info("No %s property '%s', using memblock_alloc(%016zx)\n", -+ node->full_name, name, *sz); -+ *addr = memblock_alloc(*sz, *sz); -+ vaddr = (unsigned long)phys_to_virt(*addr); -+ if (zero) -+ memset((void *)vaddr, 0, *sz); -+ flush_dcache_range(vaddr, vaddr + *sz); -+ return 0; -+ } -+ pr_info("Using %s property '%s'\n", node->full_name, name); -+ /* 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; -+ } -+ *addr = ((u64)pint[0] << 32) | (u64)pint[1]; -+ *sz = ((u64)pint[2] << 32) | (u64)pint[3]; -+ /* Keep things simple, it's either all in the DRAM range or it's all -+ * outside. */ -+ if (*addr < memblock_end_of_DRAM()) { -+ BUG_ON((u64)*addr + (u64)*sz > memblock_end_of_DRAM()); -+ if (memblock_reserve(*addr, *sz) < 0) { -+ pr_err("Failed to reserve %s\n", name); -+ return -ENOMEM; -+ } -+ vaddr = (unsigned long)phys_to_virt(*addr); -+ if (zero) -+ memset((void *)vaddr, 0, *sz); -+ flush_dcache_range(vaddr, vaddr + *sz); -+ } else if (zero) { -+ /* map as cacheable, non-guarded */ -+ void *tmpp = ioremap_prot(*addr, *sz, 0); -+ memset(tmpp, 0, *sz); -+ vaddr = (unsigned long)tmpp; -+ flush_dcache_range(vaddr, vaddr + *sz); -+ iounmap(tmpp); -+ } -+ return 0; -+} -+ -+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; -+ if (!standby) { -+ ret = parse_mem_property(node, "fsl,bman-fbpr", -+ &fbpr_a, &fbpr_sz, 0); -+ BUG_ON(ret); -+ } -+ /* 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_warning("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 void 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); -+ } -+ } -+} -+ -+static void log_edata_bits(u32 bit_count) -+{ -+ u32 i, j, mask = 0xffffffff; -+ -+ pr_warning("Bman ErrInt, EDATA:\n"); -+ i = bit_count/32; -+ if (bit_count%32) { -+ i++; -+ mask = ~(mask << bit_count%32); -+ } -+ j = 16-i; -+ pr_warning(" 0x%08x\n", bm_in(EDATA(j)) & mask); -+ j++; -+ for (; j < 16; j++) -+ pr_warning(" 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_warning("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_warning("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_warning("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 == NO_IRQ) { -+ 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); -+ 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" -+ -+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)) -+ 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; -+ 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 __devinit 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 + 1); i++) { -+ bman_dev_pool_count_attributes[i] = -+ kmalloc(sizeof(struct attribute), GFP_KERNEL); -+ if (!bman_dev_pool_count_attributes[i]) { -+ pr_err("cannot alloc for each" -+ " 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; -+ } -+ 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: -+ for (i = 0; i < (bman_pool_max + 1); i++) -+ kfree(bman_dev_pool_count_attributes[i]); -+ 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); -+ -+static struct platform_driver of_fsl_bman_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = DRV_NAME, -+ .of_match_table = of_fsl_bman_ids, -+ }, -+ .probe = of_fsl_bman_probe, -+ .remove = __devexit_p(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 */ -diff --git a/drivers/staging/fsl_qbman/bman_debugfs.c b/drivers/staging/fsl_qbman/bman_debugfs.c -new file mode 100644 -index 0000000..2c3d771 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_debugfs.c -@@ -0,0 +1,120 @@ -+/* 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_printf(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: -+ if (dfs_root) -+ 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"); -diff --git a/drivers/staging/fsl_qbman/bman_driver.c b/drivers/staging/fsl_qbman/bman_driver.c -new file mode 100644 -index 0000000..805dbd0 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_driver.c -@@ -0,0 +1,471 @@ -+/* 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_private.h" -+ -+/* -+ * 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); -+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 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(*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_release_bpid_range(range[0], range[1]); -+ pr_info("Bman: BPID allocator includes range %d:%d\n", -+ range[0], 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; -+ -+ 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 = 10; -+ } 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 = 18; -+ } -+ -+ 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 (*index >= bman_portal_max) -+ goto err; -+ -+ pcfg->public_cfg.cpu = -1; -+ -+ irq = irq_of_parse_and_map(node, 0); -+ if (irq == NO_IRQ) { -+ pr_err("Can't get %s property 'interrupts'\n", node->full_name); -+ goto err; -+ } -+ pcfg->public_cfg.irq = irq; -+ pcfg->public_cfg.index = *index; -+ bman_depletion_fill(&pcfg->public_cfg.mask); -+ -+ pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot( -+ pcfg->addr_phys[DPA_PORTAL_CE].start, -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]), -+ 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); -+ return pcfg; -+err: -+ kfree(pcfg); -+ return NULL; -+} -+ -+static void destroy_pcfg(struct bm_portal_config *pcfg) -+{ -+ iounmap(pcfg->addr_virt[DPA_PORTAL_CI]); -+ iounmap(pcfg->addr_virt[DPA_PORTAL_CE]); -+ kfree(pcfg); -+} -+ -+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; -+} -+ -+/* UIO handling callbacks */ -+#define BMAN_UIO_PREAMBLE() \ -+ const struct bm_portal_config *pcfg = \ -+ container_of(__p, struct bm_portal_config, list) -+static int bman_uio_cb_init(const struct list_head *__p, struct uio_info *info) -+{ -+ BMAN_UIO_PREAMBLE(); -+ /* big enough for "bman-uio-xx" */ -+ char *name = kzalloc(16, GFP_KERNEL); -+ if (!name) -+ return -ENOMEM; -+ sprintf(name, "bman-uio-%x", pcfg->public_cfg.index); -+ info->name = name; -+ info->mem[DPA_PORTAL_CE].name = "cena"; -+ info->mem[DPA_PORTAL_CE].addr = pcfg->addr_phys[DPA_PORTAL_CE].start; -+ info->mem[DPA_PORTAL_CE].size = -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]); -+ info->mem[DPA_PORTAL_CE].memtype = UIO_MEM_PHYS; -+ info->mem[DPA_PORTAL_CI].name = "cinh"; -+ info->mem[DPA_PORTAL_CI].addr = pcfg->addr_phys[DPA_PORTAL_CI].start; -+ info->mem[DPA_PORTAL_CI].size = -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]); -+ info->mem[DPA_PORTAL_CI].memtype = UIO_MEM_PHYS; -+ info->irq = pcfg->public_cfg.irq; -+ return 0; -+} -+static void bman_uio_cb_destroy(const struct list_head *__p, -+ struct uio_info *info) -+{ -+ BMAN_UIO_PREAMBLE(); -+ kfree(info->name); -+ /* We own this struct but had passed it to the dpa_uio layer as a const -+ * so that we don't accidentally meddle with it in the dpa_uio code. -+ * Here it's passed back to us for final clean it up, so de-constify. */ -+ destroy_pcfg((struct bm_portal_config *)pcfg); -+} -+static void bman_uio_cb_interrupt(const struct list_head *__p) -+{ -+ BMAN_UIO_PREAMBLE(); -+ /* This is the only manipulation of a portal register that isn't in the -+ * regular kernel portal driver (_high.c/_low.h). It is also the only -+ * time the kernel touches a register on a portal that is otherwise -+ * being driven by a user-space driver. So rather than messing up -+ * encapsulation for one trivial call, I am hard-coding the offset to -+ * the inhibit register and writing it directly from here. */ -+ out_be32(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe0c, ~(u32)0); -+} -+static const struct dpa_uio_vtable bman_uio = { -+ .init_uio = bman_uio_cb_init, -+ .destroy = bman_uio_cb_destroy, -+ .on_interrupt = bman_uio_cb_interrupt -+}; -+ -+static struct bman_portal *init_pcfg(struct bm_portal_config *pcfg) -+{ -+ struct bman_portal *p; -+ struct cpumask oldmask = *tsk_cpus_allowed(current); -+ set_cpus_allowed_ptr(current, get_cpu_mask(pcfg->public_cfg.cpu)); -+ p = bman_create_affine_portal(pcfg); -+ if (p) { -+#ifdef CONFIG_FSL_DPA_PIRQ_SLOW -+ bman_irqsource_add(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); -+ } else -+ pr_crit("Bman portal failure on cpu %d\n", -+ pcfg->public_cfg.cpu); -+ set_cpus_allowed_ptr(current, &oldmask); -+ return p; -+} -+ -+static void init_slave(int cpu) -+{ -+ struct bman_portal *p; -+ struct cpumask oldmask = *tsk_cpus_allowed(current); -+ set_cpus_allowed_ptr(current, get_cpu_mask(cpu)); -+ p = bman_create_affine_slave(shared_portals[shared_portals_idx++]); -+ if (!p) -+ pr_err("Bman slave portal failure on cpu %d\n", cpu); -+ else -+ pr_info("Bman portal %sinitialised, cpu %d\n", "(slave) ", cpu); -+ set_cpus_allowed_ptr(current, &oldmask); -+ if (shared_portals_idx >= num_shared_portals) -+ shared_portals_idx = 0; -+} -+ -+/* 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); -+ -+/* 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 exported as UIO devices. -+ */ -+static __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(unused_pcfgs); -+ LIST_HEAD(unshared_pcfgs); -+ LIST_HEAD(shared_pcfgs); -+ struct device_node *dn; -+ struct bm_portal_config *pcfg; -+ struct bman_portal *p; -+ int cpu, ret; -+ -+ /* 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_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); -+ } -+ for_each_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_online_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); -+ } -+ /* 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"); -+#ifdef CONFIG_FSL_DPA_UIO -+ /* Export any left over portals as UIO devices */ -+ do { -+ pcfg = get_pcfg(&unused_pcfgs); -+ if (!pcfg) -+ break; -+ ret = dpa_uio_register(&pcfg->list, &bman_uio); -+ if (ret) { -+ pr_err("Failure registering BMan UIO portal\n"); -+ destroy_pcfg(pcfg); -+ } -+ } while (1); -+#endif -+ /* 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; -+} -+subsys_initcall(bman_init); -diff --git a/drivers/staging/fsl_qbman/bman_high.c b/drivers/staging/fsl_qbman/bman_high.c -new file mode 100644 -index 0000000..ecdfae7 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_high.c -@@ -0,0 +1,1009 @@ -+/* 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; -+ /* 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]; -+}; -+ -+/* 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() do { ; } while (0) -+ -+/* 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; -+} -+ -+struct bman_portal *bman_create_affine_portal( -+ const struct bm_portal_config *config) -+{ -+ struct bman_portal *portal = get_raw_affine_portal(); -+ struct bm_portal *__p = &portal->p; -+ const struct bman_depletion *pools = &config->public_cfg.mask; -+ int ret; -+ u8 bpid = 0; -+ -+ /* A criteria for calling this function (from bman_driver.c) is that -+ * we're already affine to the cpu and won't schedule onto another cpu. -+ * This means we can put_affine_portal() and yet continue to use -+ * "portal", which in turn means aspects of this routine can sleep. */ -+ put_affine_portal(); -+ -+ /* 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 -+ 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\n"); -+ 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; -+ spin_lock(&affine_mask_lock); -+ cpumask_set_cpu(config->public_cfg.cpu, &affine_mask); -+ spin_unlock(&affine_mask_lock); -+ 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: -+ if (portal->pools) -+ kfree(portal->pools); -+fail_pools: -+ bm_isr_finish(__p); -+fail_isr: -+ bm_mc_finish(__p); -+fail_mc: -+ bm_rcr_finish(__p); -+fail_rcr: -+ return NULL; -+} -+ -+struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect) -+{ -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ struct bman_portal *p = get_raw_affine_portal(); -+ 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; -+ put_affine_portal(); -+ return p; -+#else -+ BUG(); -+ return NULL; -+#endif -+} -+ -+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; -+ 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; -+ 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; -+ 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_irqsource_add(__maybe_unused u32 bits) -+{ -+ struct bman_portal *p = get_raw_affine_portal(); -+ int ret = 0; -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (p->sharing_redirect) -+ ret = -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); -+ } -+ 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) { -+ if (pool->sp) -+ 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) { -+ /* When releasing a BPID to the dynamic allocator, that pool -+ * must be *empty*. This code makes it so by dropping everything -+ * into the bit-bucket. This ignores whether or not it was a -+ * mistake (or a leak) on the caller's part not to drain the -+ * pool beforehand. */ -+ struct bm_buffer bufs[8]; -+ int ret = 0; -+ do { -+ /* Acquire is all-or-nothing, so we drain in 8s, then in -+ * 1s for the remainder. */ -+ if (ret != 1) -+ ret = bman_acquire(pool, bufs, 8, 0); -+ if (ret < 8) -+ ret = bman_acquire(pool, bufs, 1, 0); -+ } while (ret > 0); -+ 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) -+ 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 -+ -+/* to facilitate better copying of bufs into the ring without either (a) copying -+ * noise into the first byte (prematurely triggering the command), nor (b) being -+ * very inefficient by copying small fields using read-modify-write */ -+struct overlay_bm_buffer { -+ u32 first; -+ u32 second; -+}; -+ -+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; -+ struct overlay_bm_buffer *o_dest; -+ struct overlay_bm_buffer *o_src = (struct overlay_bm_buffer *)&bufs[0]; -+ __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. */ -+ o_dest = (struct overlay_bm_buffer *)&r->bufs[0]; -+ o_dest->first = (o_src->first & 0x0000ffff) | -+ (((u32)pool->params.bpid << 16) & 0x00ff0000); -+ o_dest->second = o_src->second; -+ if (i) -+ copy_words(&r->bufs[1], &bufs[1], i * sizeof(bufs[0])); -+ 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) -+ 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 = 0; -+#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 -+ /* This needs some explanation. Adding the given buffers may take the -+ * stockpile over the threshold, but in fact the stockpile may already -+ * *be* over the threshold if a previous release-to-hw attempt had -+ * failed. So we have 3 cases to cover; -+ * 1. we add to the stockpile and don't hit the threshold, -+ * 2. we add to the stockpile, hit the threshold and release-to-hw, -+ * 3. we have to release-to-hw before adding to the stockpile -+ * (not enough room in the stockpile for case 2). -+ * Our constraints on thresholds guarantee that in case 3, there must be -+ * at least 8 bufs already in the stockpile, so all release-to-hw ops -+ * are for 8 bufs. Despite all this, the API must indicate whether the -+ * given buffers were taken off the caller's hands, irrespective of -+ * whether a release-to-hw was attempted. */ -+ while (num) { -+ /* Add buffers to stockpile if they fit */ -+ if ((pool->sp_fill + num) < BMAN_STOCKPILE_SZ) { -+ copy_words(pool->sp + pool->sp_fill, bufs, -+ sizeof(struct bm_buffer) * num); -+ pool->sp_fill += num; -+ num = 0; /* --> will return success no matter what */ -+ } -+ /* Do hw op if hitting the high-water threshold */ -+ if ((pool->sp_fill + num) >= BMAN_STOCKPILE_HIGH) { -+ ret = __bman_release(pool, -+ pool->sp + (pool->sp_fill - 8), 8, flags); -+ if (ret) { -+ ret = (num ? ret : 0); -+ goto release_done; -+ } -+ pool->sp_fill -= 8; -+ } -+ } -+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; -+ -+ 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) -+ copy_words(&bufs[0], &mcr->acquire.bufs[0], -+ num * sizeof(bufs[0])); -+ 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 = 0; -+#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 -+ /* Only need a h/w op if we'll hit the low-water thresh */ -+ if (!(flags & BMAN_ACQUIRE_FLAG_STOCKPILE) && -+ (pool->sp_fill <= (BMAN_STOCKPILE_LOW + num))) { -+ /* refill stockpile with max amount, but if max amount -+ * isn't available, try amount the user wants */ -+ int bufcount = 8; -+ ret = __bman_acquire(pool, pool->sp + pool->sp_fill, bufcount); -+ if (ret < 0 && bufcount != num) { -+ bufcount = num; -+ /* Maybe buffer pool has less than 8 */ -+ ret = __bman_acquire(pool, pool->sp + pool->sp_fill, -+ bufcount); -+ } -+ if (ret < 0) -+ goto hw_starved; -+ DPA_ASSERT(ret == bufcount); -+ pool->sp_fill += bufcount; -+ } else { -+hw_starved: -+ if (pool->sp_fill < num) { -+ ret = -ENOMEM; -+ goto acquire_done; -+ } -+ } -+ copy_words(bufs, pool->sp + (pool->sp_fill - num), -+ sizeof(struct bm_buffer) * num); -+ pool->sp_fill -= num; -+ 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; -+ 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 -diff --git a/drivers/staging/fsl_qbman/bman_low.h b/drivers/staging/fsl_qbman/bman_low.h -new file mode 100644 -index 0000000..262bae7 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_low.h -@@ -0,0 +1,494 @@ -+/* 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 */ -+/***************************/ -+ -+/* Cache-inhibited register offsets */ -+#define REG_RCR_PI_CINH 0x0000 -+#define REG_RCR_CI_CINH 0x0004 -+#define REG_RCR_ITR 0x0008 -+#define REG_CFG 0x0100 -+#define REG_SCN(n) (0x0200 + ((n) << 2)) -+#define REG_ISR 0x0e00 -+ -+/* Cache-enabled register offsets */ -+#define CL_CR 0x0000 -+#define CL_RR0 0x0100 -+#define CL_RR1 0x0140 -+#define CL_RCR 0x1000 -+#define CL_RCR_PI_CENA 0x3000 -+#define CL_RCR_CI_CENA 0x3100 -+ -+/* 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) __raw_readl((bm)->addr_ci + (o)) -+#define __bm_out(bm, o, val) __raw_writel((val), (bm)->addr_ci + (o)) -+#define bm_in(reg) __bm_in(&portal->addr, REG_##reg) -+#define bm_out(reg, val) __bm_out(&portal->addr, 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) __raw_readl((bm)->addr_ce + (o)) -+#define __bm_cl_out(bm, o, val) \ -+ do { \ -+ u32 *__tmpclout = (bm)->addr_ce + (o); \ -+ __raw_writel((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, CL_##reg##_CENA) -+#define bm_cl_touch_rw(reg) __bm_cl_touch_rw(&portal->addr, CL_##reg##_CENA) -+#define bm_cl_in(reg) __bm_cl_in(&portal->addr, CL_##reg##_CENA) -+#define bm_cl_out(reg, val) __bm_cl_out(&portal->addr, CL_##reg##_CENA, val) -+#define bm_cl_invalidate(reg) __bm_cl_invalidate(&portal->addr, 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 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 occurances, 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 + 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 - 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 -+ dcbz_64(rcr->cursor); -+ 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--; -+ dcbz_64(rcr->cursor); -+ 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 = 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 = 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 + CL_CR; -+ mc->rr = portal->addr.addr_ce + 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 -+ dcbz_64(mc->cr); -+ 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) 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) -+{ -+ return __bm_in(&portal->addr, REG_ISR + (n << 2)); -+} -+ -+static inline void __bm_isr_write(struct bm_portal *portal, enum bm_isr_reg n, -+ u32 val) -+{ -+ __bm_out(&portal->addr, REG_ISR + (n << 2), val); -+} -diff --git a/drivers/staging/fsl_qbman/bman_private.h b/drivers/staging/fsl_qbman/bman_private.h -new file mode 100644 -index 0000000..c567314 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_private.h -@@ -0,0 +1,144 @@ -+/* 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 -+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; -+}; -+ -+#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_affine_portal( -+ const struct bm_portal_config *config); -+struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect); -+const struct bm_portal_config *bman_destroy_affine_portal(void); -+ -+/* 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'. NB, some of these -+ * definitions are exported for use by the bman_irqsource_***() APIs, so are -+ * commented-out here. */ -+#if 0 -+#define BM_PIRQ_RCRI 0x00000002 /* RCR Ring (below threshold) */ -+#define BM_PIRQ_BSCN 0x00000001 /* Buffer depletion State Change */ -+#endif -+/* 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); -+ -+#endif /* CONFIG_FSL_BMAN_CONFIG */ -diff --git a/drivers/staging/fsl_qbman/bman_test.c b/drivers/staging/fsl_qbman/bman_test.c -new file mode 100644 -index 0000000..db5b7fd ---- /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); -diff --git a/drivers/staging/fsl_qbman/bman_test.h b/drivers/staging/fsl_qbman/bman_test.h -new file mode 100644 -index 0000000..27c7c05 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_test.h -@@ -0,0 +1,91 @@ -+/* 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); -+ -+static inline void __hexdump(unsigned long start, unsigned long end, -+ unsigned long p, size_t sz, unsigned char *c) -+{ -+ while (start < end) { -+ unsigned int pos = 0; -+ char buf[64]; -+ int nl = 0; -+ pos += sprintf(buf + pos, "%08lx: ", start); -+ do { -+ if ((start < p) || (start >= (p + sz))) -+ pos += sprintf(buf + pos, ".."); -+ else -+ pos += sprintf(buf + pos, "%02x", *(c++)); -+ if (!(++start & 15)) { -+ buf[pos++] = '\n'; -+ nl = 1; -+ } else { -+ nl = 0; -+ if(!(start & 1)) -+ buf[pos++] = ' '; -+ if(!(start & 3)) -+ buf[pos++] = ' '; -+ } -+ } while (start & 15); -+ if (!nl) -+ buf[pos++] = '\n'; -+ buf[pos] = '\0'; -+ pr_info("%s", buf); -+ } -+} -+static inline void hexdump(void *ptr, size_t sz) -+{ -+ unsigned long p = (unsigned long)ptr; -+ unsigned long start = p & ~(unsigned long)15; -+ unsigned long end = (p + sz + 15) & ~(unsigned long)15; -+ unsigned char *c = ptr; -+ __hexdump(start, end, p, sz, c); -+} -+static inline void hexdump_by_cl(void *ptr, size_t sz) -+{ -+ unsigned long p = (unsigned long)ptr; -+ unsigned long start = p & ~(unsigned long)63; -+ unsigned long end = (p + sz + 63) & ~(unsigned long)63; -+ unsigned char *c = ptr; -+ __hexdump(start, end, p, sz, c); -+} -diff --git a/drivers/staging/fsl_qbman/bman_test_high.c b/drivers/staging/fsl_qbman/bman_test_high.c -new file mode 100644 -index 0000000..f2a5284 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_test_high.c -@@ -0,0 +1,181 @@ -+/* 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; -+ -+ 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, NULL, 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"); -+} -diff --git a/drivers/staging/fsl_qbman/bman_test_thresh.c b/drivers/staging/fsl_qbman/bman_test_thresh.c -new file mode 100644 -index 0000000..b11862f ---- /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 */ -+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 */ -+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"); -+} -diff --git a/drivers/staging/fsl_qbman/dpa_alloc.c b/drivers/staging/fsl_qbman/dpa_alloc.c -new file mode 100644 -index 0000000..03a9d28 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/dpa_alloc.c -@@ -0,0 +1,503 @@ -+/* 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_valid(u32 bpid) -+{ -+ struct bm_pool_state state; -+ int ret = bman_query_pools(&state); -+ BUG_ON(ret); -+ if (bman_depletion_get(&state.as.state, bpid)) -+ /* "Available==1" means unavailable, go figure. Ie. it has no -+ * buffers, which is means it is valid for deallocation. (So -+ * true means false, which means true...) */ -+ return 1; -+ return 0; -+} -+void bman_release_bpid_range(u32 bpid, u32 count) -+{ -+ u32 total_invalid = release_id_range(&bpalloc, bpid, count, bp_valid); -+ 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); -+ -+/* 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_valid(u32 fqid) -+{ -+ struct qman_fq fq = { -+ .fqid = fqid -+ }; -+ struct qm_mcr_queryfq_np np; -+ int err = qman_query_fq_np(&fq, &np); -+ BUG_ON(err); -+ return ((np.state & QM_MCR_NP_STATE_MASK) == QM_MCR_NP_STATE_OOS); -+} -+void qman_release_fqid_range(u32 fqid, u32 count) -+{ -+ u32 total_invalid = release_id_range(&fqalloc, fqid, count, fq_valid); -+ 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); -+ -+/* 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 qp_valid(u32 qp) -+{ -+ /* TBD: when resource-management improves, we may be able to find -+ * something better than this. Currently 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. */ -+ 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, can't free */ -+ 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, qp_valid); -+ 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); -+ -+/* 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); -+ -+void qman_release_cgrid_range(u32 cgrid, u32 count) -+{ -+ u32 total_invalid = release_id_range(&cgralloc, cgrid, count, NULL); -+ 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); -+ -+/* 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_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); -+ -+/* 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_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); -+ -+/* 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; -+}; -+ -+/* #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; -+ list_for_each_entry(p, &alloc->list, 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...) do { ; } while (0) -+#define DUMP(a) do { ; } while (0) -+#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; -+ 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->list, 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; -+ } -+ spin_unlock_irq(&alloc->lock); -+err: -+ DPRINT("returning %d\n", i ? num : -ENOMEM); -+ DUMP(alloc); -+ return i ? (int)num : -ENOMEM; -+} -+ -+/* Allocate the list node using GFP_ATOMIC, because we *really* want to avoid -+ * forcing error-handling on to users in the deallocation path. */ -+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->list, 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->list); -+done: -+ /* Merge to the left */ -+ i = list_entry(node->list.prev, struct alloc_node, list); -+ if (node->list.prev != &alloc->list) { -+ 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->list) { -+ 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); -+} -+ -+int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base, u32 num) -+{ -+ struct alloc_node *i = NULL; -+ struct alloc_node *margin_left, *margin_right; -+ -+ DPRINT("alloc_reserve(%d,%d)\n", base_id, count); -+ DUMP(alloc); -+ 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->list, list) -+ if ((i->base <= base) && ((i->base + i->num) >= (base + num))) -+ /* yep, the reservation is within this node */ -+ goto done; -+ 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); -+ } -+ spin_unlock_irq(&alloc->lock); -+err: -+ DPRINT("returning %d\n", i ? 0 : -ENOMEM); -+ DUMP(alloc); -+ return i ? 0 : -ENOMEM; -+} -+ -+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->list)) { -+ i = list_entry(alloc->list.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; -+} -diff --git a/drivers/staging/fsl_qbman/dpa_sys.h b/drivers/staging/fsl_qbman/dpa_sys.h -new file mode 100644 -index 0000000..8adc656 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/dpa_sys.h -@@ -0,0 +1,353 @@ -+/* 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 -+ -+/* When copying aligned words or shorts, try to avoid memcpy() */ -+#define CONFIG_TRY_BETTER_MEMCPY -+ -+/* Handle portals destined for USDPAA (user-space). -+ * -+ * The UIO handling is mostly in dpa_uio.c which is common to qman and bman, but -+ * there are some specifics to each case, and they have independent data -+ * structures. The "pcfg"s for qman and bman portals are maintained in lists in -+ * their respective drivers, and they're detached from those lists when they are -+ * to be registered as UIO devices, so we have dpa_uio.c store them in a -+ * mixed-type list, and use this vtable of callbacks to let the qman+bman -+ * drivers container_of() the list item to their respective object wrappers and -+ * implement whatever logic distinguishes them. -+ */ -+struct dpa_uio_vtable { -+ /* This callback should fill in 'name', 'mem', and 'irq'. The rest will -+ * be filled in by dpa_uio.c */ -+ int (*init_uio)(const struct list_head *pcfg, struct uio_info *info); -+ /* Free up whatever object contains 'pcfg' */ -+ void (*destroy)(const struct list_head *pcfg, struct uio_info *info); -+ /* Called when the portal is opened (Qman uses this for rerouting -+ * stashing to the current cpu) */ -+ int (*on_open)(const struct list_head *pcfg); -+ void (*on_close)(const struct list_head *pcfg); -+ /* Called when an interrupt fires - must disable interrupts */ -+ void (*on_interrupt)(const struct list_head *pcfg); -+}; -+int __init dpa_uio_register(struct list_head *new_pcfg, -+ const struct dpa_uio_vtable *vtable); -+ -+/* For 2-element tables related to cache-inhibited and cache-enabled mappings */ -+#define DPA_PORTAL_CE 0 -+#define DPA_PORTAL_CI 1 -+ -+/* These stubs are re-mapped to hypervisor+failover features in kernel trees -+ * that contain that support. */ -+static inline int pamu_enable_liodn(struct device_node *n, int i) -+{ -+ return 0; -+} -+/***********************/ -+/* Misc inline assists */ -+/***********************/ -+ -+/* 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() \ -+ do { \ -+ __asm__ __volatile__ ("sync" : : : "memory"); \ -+ } while(0) -+#define lwsync() \ -+ do { \ -+ __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory"); \ -+ } while(0) -+#define dcbf(p) \ -+ do { \ -+ __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory"); \ -+ } while(0) -+#define dcbt_ro(p) \ -+ do { \ -+ __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p)); \ -+ } while(0) -+#define dcbt_rw(p) \ -+ do { \ -+ __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p)); \ -+ } while(0) -+#define dcbi(p) dcbf(p) -+#ifdef CONFIG_PPC_E500MC -+#define dcbzl(p) \ -+ do { \ -+ __asm__ __volatile__ ("dcbzl 0,%0" : : "r" (p)); \ -+ } while (0) -+#define dcbz_64(p) \ -+ do { \ -+ dcbzl(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) -+#else -+#define dcbz(p) \ -+ do { \ -+ __asm__ __volatile__ ("dcbz 0,%0" : : "r" (p)); \ -+ } while (0) -+#define dcbz_64(p) \ -+ do { \ -+ dcbz((u32)p + 32); \ -+ dcbz(p); \ -+ } while (0) -+#define dcbf_64(p) \ -+ do { \ -+ dcbf((u32)p + 32); \ -+ dcbf(p); \ -+ } while (0) -+/* Commonly used combo */ -+#define dcbit_ro(p) \ -+ do { \ -+ dcbi(p); \ -+ dcbi((u32)p + 32); \ -+ dcbt_ro(p); \ -+ dcbt_ro((u32)p + 32); \ -+ } while (0) -+#endif /* CONFIG_PPC_E500MC */ -+ -+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; -+} -+ -+#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, 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; -+} -+ -+#endif /* DPA_SYS_H */ -diff --git a/drivers/staging/fsl_qbman/dpa_uio.c b/drivers/staging/fsl_qbman/dpa_uio.c -new file mode 100644 -index 0000000..cdb78db ---- /dev/null -+++ b/drivers/staging/fsl_qbman/dpa_uio.c -@@ -0,0 +1,190 @@ -+/* 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. -+ */ -+ -+#include "bman_private.h" -+#include "qman_private.h" -+ -+static const char dpa_uio_version[] = "USDPAA UIO portal driver v0.2"; -+ -+static LIST_HEAD(dpa_uio_list); -+ -+struct dpa_uio_info { -+ const struct dpa_uio_vtable *vtable; -+ const struct list_head *pcfg; -+ atomic_t ref; /* exclusive, only one open() at a time */ -+ struct uio_info uio; -+ struct platform_device *pdev; -+ struct list_head node; -+}; -+ -+static int dpa_uio_open(struct uio_info *info, struct inode *inode) -+{ -+ struct dpa_uio_info *i = container_of(info, struct dpa_uio_info, uio); -+ int ret = 0; -+ -+ if (!atomic_dec_and_test(&i->ref)) { -+ atomic_inc(&i->ref); -+ return -EBUSY; -+ } -+ if (i->vtable->on_open) { -+ ret = i->vtable->on_open(i->pcfg); -+ if (ret) -+ atomic_inc(&i->ref); -+ } -+ return ret; -+} -+ -+static int dpa_uio_release(struct uio_info *info, struct inode *inode) -+{ -+ struct dpa_uio_info *i = container_of(info, struct dpa_uio_info, uio); -+ if (i->vtable->on_close) -+ i->vtable->on_close(i->pcfg); -+ atomic_inc(&i->ref); -+ return 0; -+} -+ -+static pgprot_t dpa_uio_pgprot(struct uio_info *info, unsigned int mem_idx, -+ pgprot_t prot) -+{ -+ if (mem_idx == DPA_PORTAL_CE) -+ /* It's the cache-enabled portal region. NB, we shouldn't use -+ * pgprot_cached() here because it includes _PAGE_COHERENT. The -+ * region is cachable but *not* coherent - stashing (if enabled) -+ * leads to "coherent-like" behaviour, otherwise the driver -+ * explicitly invalidates/prefetches. */ -+ return pgprot_cached_noncoherent(prot); -+ /* Otherwise it's the cache-inhibited portal region */ -+ return pgprot_noncached(prot); -+} -+ -+static irqreturn_t dpa_uio_irq_handler(int irq, struct uio_info *info) -+{ -+ struct dpa_uio_info *i = container_of(info, struct dpa_uio_info, uio); -+ i->vtable->on_interrupt(i->pcfg); -+ return IRQ_HANDLED; -+} -+ -+static int __init dpa_uio_portal_init(struct dpa_uio_info *info) -+{ -+ int ret; -+ -+ /* Fill in qbman-specific fields of uio_info */ -+ ret = info->vtable->init_uio(info->pcfg, &info->uio); -+ if (ret) { -+ pr_err("dpa_uio_portal: qbman parameter setup failed\n"); -+ return -ENODEV; -+ } -+ -+ /* Fill in common fields of uio_info */ -+ info->uio.version = dpa_uio_version; -+ info->uio.handler = dpa_uio_irq_handler; -+ info->uio.set_pgprot = dpa_uio_pgprot; -+ info->uio.open = dpa_uio_open; -+ info->uio.release = dpa_uio_release; -+ -+ /* Fill in state private to this file */ -+ atomic_set(&info->ref, 1); -+ info->pdev = platform_device_alloc(info->uio.name, -1); -+ if (!info->pdev) { -+ info->vtable->destroy(info->pcfg, &info->uio); -+ pr_err("dpa_uio_portal: platform_device_alloc() failed\n"); -+ return -ENOMEM; -+ } -+ ret = platform_device_add(info->pdev); -+ if (ret) { -+ platform_device_put(info->pdev); -+ info->vtable->destroy(info->pcfg, &info->uio); -+ pr_err("dpa_uio_portal: platform_device_add() failed\n"); -+ return -ENOMEM; -+ } -+ -+ /* Register the device */ -+ ret = uio_register_device(&info->pdev->dev, &info->uio); -+ if (ret) { -+ platform_device_del(info->pdev); -+ platform_device_put(info->pdev); -+ info->vtable->destroy(info->pcfg, &info->uio); -+ pr_err("dpa_uio_portal: UIO registration failed\n"); -+ return -EBUSY; -+ } -+ pr_info("USDPAA portal initialised, %s\n", info->uio.name); -+ return 0; -+} -+ -+static void __init dpa_uio_portal_finish(struct dpa_uio_info *info) -+{ -+ info->vtable->destroy(info->pcfg, &info->uio); -+ uio_unregister_device(&info->uio); -+ platform_device_del(info->pdev); -+ platform_device_put(info->pdev); -+ pr_info("USDPAA portal removed, %s\n", info->uio.name); -+} -+ -+static int __init dpa_uio_init(void) -+{ -+ struct dpa_uio_info *info, *tmp; -+ list_for_each_entry_safe(info, tmp, &dpa_uio_list, node) { -+ int ret = dpa_uio_portal_init(info); -+ if (ret) { -+ list_del(&info->node); -+ kfree(info); -+ } -+ } -+ pr_info("USDPAA portal layer loaded\n"); -+ return 0; -+} -+ -+static void __exit dpa_uio_exit(void) -+{ -+ struct dpa_uio_info *info, *tmp; -+ list_for_each_entry_safe(info, tmp, &dpa_uio_list, node) { -+ dpa_uio_portal_finish(info); -+ list_del(&info->node); -+ kfree(info); -+ } -+ pr_info("USDPAA portal layer unloaded\n"); -+} -+ -+int __init dpa_uio_register(struct list_head *new_pcfg, -+ const struct dpa_uio_vtable *vtable) -+{ -+ struct dpa_uio_info *info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (!info) -+ return -ENOMEM; -+ info->vtable = vtable; -+ info->pcfg = new_pcfg; -+ list_add_tail(&info->node, &dpa_uio_list); -+ return 0; -+} -+ -+module_init(dpa_uio_init) -+module_exit(dpa_uio_exit) -+MODULE_LICENSE("GPL"); -diff --git a/drivers/staging/fsl_qbman/qman_config.c b/drivers/staging/fsl_qbman/qman_config.c -new file mode 100644 -index 0000000..c924ab9 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_config.c -@@ -0,0 +1,1221 @@ -+/* 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 CONFIG_SMP -+#include /* get_hard_smp_processor_id() */ -+#endif -+ -+#include -+#include "qman_private.h" -+ -+/* 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 -+ -+/* 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 { -+ u32 __reserved:2; -+ u32 portal_type:1; -+ u32 portal_num:5; -+ u32 fqid:24; -+ } __packed info; -+}; -+ -+union qman_ecir2 { -+ u32 ecir2_raw; -+ struct { -+ u32 portal_type:1; -+ u32 __reserved:21; -+ u32 portal_num:10; -+ } __packed info; -+}; -+ -+union qman_eadr { -+ u32 eadr_raw; -+ struct { -+ u32 __reserved1:4; -+ u32 memid:4; -+ u32 __reserved2:12; -+ u32 eadr:12; -+ } __packed info; -+ struct { -+ u32 __reserved1:3; -+ u32 memid:5; -+ u32 __reserved:8; -+ u32 eadr:16; -+ } __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); -+} -+ -+#if 0 -+ -+static void qm_set_portal(struct qman *qm, u8 swportalID, -+ u16 ec_tp_cfg, u16 ecd_tp_cfg) -+{ -+ qm_out(QCSP_DD_CFG(swportalID), -+ ((ec_tp_cfg & 0x1ff) << 16) | (ecd_tp_cfg & 0x1ff)); -+} -+ -+static void qm_set_ddebug(struct qman *qm, u8 mdd, u8 m_cfg) -+{ -+ qm_out(DD_CFG, ((mdd & 0x3) << 4) | (m_cfg & 0xf)); -+} -+ -+static void qm_set_dc_ddebug(struct qman *qm, enum qm_dc_portal portal, u16 ecd_tp_cfg) -+{ -+ qm_out(DCP_DD_CFG(portal), ecd_tp_cfg & 0x1ff); -+} -+ -+static u32 qm_get_pfdr_free_pool_count(struct qman *qm) -+{ -+ return qm_in(PFDR_FPC); -+} -+ -+static void qm_get_pfdr_free_pool(struct qman *qm, u32 *head, u32 *tail) -+{ -+ *head = qm_in(PFDR_FP_HEAD); -+ *tail = qm_in(PFDR_FP_TAIL); -+} -+ -+static void qm_set_default_wq(struct qman *qm, u16 wqid) -+{ -+ qm_out(WQ_DEF_ENC_WQID, wqid); -+} -+ -+static void qm_set_channel_ddebug(struct qman *qm, u16 channel, u16 tp_cfg) -+{ -+ u32 offset; -+ int upperhalf = 0; -+ if ((channel >= QM_CHANNEL_SWPORTAL0) && -+ (channel <= qm_channel_swportal9)) { -+ offset = (channel - QM_CHANNEL_SWPORTAL0); -+ upperhalf = offset & 0x1; -+ offset = REG_WQ_SC_DD_CFG(offset / 2); -+ } else if ((channel >= qm_channel_pool1) && -+ (channel <= qm_channel_pool15)) { -+ offset = (channel + 1 - qm_channel_pool1); -+ upperhalf = offset & 0x1; -+ offset = REG_WQ_PC_DD_CFG(offset / 2); -+ } else if ((channel >= qm_channel_fman0_sp0) && -+ (channel <= qm_channel_fman0_sp11)) { -+ offset = (channel - qm_channel_fman0_sp0); -+ upperhalf = offset & 0x1; -+ offset = REG_WQ_DC0_DD_CFG(offset / 2); -+ } -+ else if ((channel >= qm_channel_fman1_sp0) && -+ (channel <= qm_channel_fman1_sp11)) { -+ offset = (channel - qm_channel_fman1_sp0); -+ upperhalf = offset & 0x1; -+ offset = REG_WQ_DC1_DD_CFG(offset / 2); -+ } -+ else if (channel == qm_channel_caam) -+ offset = REG_WQ_DCn_DD_CFG(2); -+ else if (channel == qm_channel_pme) -+ offset = REG_WQ_DCn_DD_CFG(3); -+ else { -+ pr_crit("Illegal qm_channel type %d\n", channel); -+ return; -+ } -+ __qm_out(qm, offset, upperhalf ? ((u32)tp_cfg << 16) : tp_cfg); -+} -+ -+static void qm_get_details(struct qman *qm, u8 *int_options, u8 *errata, -+ u8 *conf_options) -+{ -+ u32 v = qm_in(IP_REV_1); -+ *int_options = (v >> 16) & 0xff; -+ *errata = (v >> 8) & 0xff; -+ *conf_options = v & 0xff; -+} -+ -+static void qm_set_corenet_bar(struct qman *qm, u16 eba, u32 ba) -+{ -+ /* choke if 'ba' isn't properly aligned */ -+ DPA_ASSERT(!(ba & 0x001fffff)); -+ qm_out(QCSP_BARE, eba); -+ qm_out(QCSP_BAR, ba); -+} -+ -+static u8 qm_get_corenet_sourceid(struct qman *qm) -+{ -+ return qm_in(SRCIDR); -+} -+ -+static u16 qm_get_liodn(struct qman *qm) -+{ -+ return qm_in(LIODNR); -+} -+ -+static void qm_set_congestion_config(struct qman *qm, u16 pres) -+{ -+ qm_out(CM_CFG, pres); -+} -+ -+#endif -+ -+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) -+{ -+#ifdef CONFIG_FSL_QMAN_BUG_AND_FEATURE_REV1 -+#define csw(x) \ -+do { \ -+ if (++x == 8) \ -+ x = 7; \ -+} while (0) -+ if (qman_ip_rev == QMAN_REV10) { -+ csw(csw2); -+ csw(csw3); -+ csw(csw4); -+ csw(csw5); -+ csw(csw6); -+ csw(csw7); -+ } -+#endif -+ 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) -+{ -+#ifdef CONFIG_FSL_QMAN_BUG_AND_FEATURE_REV1 -+ if (qman_ip_rev == QMAN_REV10) -+ qm_out(HID_CFG, 3); -+ else -+#endif -+ 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) -+{ -+ u32 v = qm_in(IP_REV_1); -+ *id = (v >> 16); -+ *major = (v >> 8) & 0xff; -+ *minor = v & 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; -+ -+/* 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) -+{ -+ const u32 *pint; -+ int ret; -+ unsigned long vaddr; -+ -+ pint = of_get_property(node, name, &ret); -+ if (!pint || (ret != 16)) { -+ pr_info("No %s property '%s', using memblock_alloc(%016zx)\n", -+ node->full_name, name, *sz); -+ *addr = memblock_alloc(*sz, *sz); -+ vaddr = (unsigned long)phys_to_virt(*addr); -+ if (zero) -+ memset((void *)vaddr, 0, *sz); -+ flush_dcache_range(vaddr, vaddr + *sz); -+ return 0; -+ } -+ pr_info("Using %s property '%s'\n", node->full_name, name); -+ /* 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; -+ } -+ *addr = ((u64)pint[0] << 32) | (u64)pint[1]; -+ *sz = ((u64)pint[2] << 32) | (u64)pint[3]; -+ /* Keep things simple, it's either all in the DRAM range or it's all -+ * outside. */ -+ if (*addr < memblock_end_of_DRAM()) { -+ BUG_ON((u64)*addr + (u64)*sz > memblock_end_of_DRAM()); -+ if (memblock_reserve(*addr, *sz) < 0) { -+ pr_err("Failed to reserve %s\n", name); -+ return -ENOMEM; -+ } -+ vaddr = (unsigned long)phys_to_virt(*addr); -+ if (zero) -+ memset(phys_to_virt(*addr), 0, *sz); -+ flush_dcache_range(vaddr, vaddr + *sz); -+ } else if (zero) { -+ /* map as cacheable, non-guarded */ -+ void *tmpp = ioremap_prot(*addr, *sz, 0); -+ memset(tmpp, 0, *sz); -+ vaddr = (unsigned long)tmpp; -+ flush_dcache_range(vaddr, vaddr + *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; -+ 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 '%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); -+ BUG_ON(ret); -+ ret = parse_mem_property(node, "fsl,qman-pfdr", -+ &pfdr_a, &pfdr_sz, 0); -+ BUG_ON(ret); -+ } -+ /* Global configuration */ -+ regs = ioremap(res.start, res.end - res.start + 1); -+ qm = qm_create(regs); -+ qm_node = node; -+ qm_get_version(qm, &id, &major, &minor); -+ pr_info("Qman ver:%04x,%02x,%02x\n", id, major, minor); -+ if (!qman_ip_rev) { -+ if ((major == 1) && (minor == 0)) -+ qman_ip_rev = QMAN_REV10; -+ 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 { -+ pr_warning("unknown Qman version, default to rev1.1\n"); -+ qman_ip_rev = QMAN_REV11; -+ } -+ } -+ -+ if (standby) { -+ pr_info(" -> in standby mode\n"); -+ return 0; -+ } -+ return 0; -+} -+ -+int qman_have_ccsr(void) -+{ -+ return qm ? 1 : 0; -+} -+ -+__init void 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); -+ } -+ } -+} -+ -+static void log_edata_bits(u32 bit_count) -+{ -+ u32 i, j, mask = 0xffffffff; -+ -+ pr_warning("Qman ErrInt, EDATA:\n"); -+ i = bit_count/32; -+ if (bit_count%32) { -+ i++; -+ mask = ~(mask << bit_count%32); -+ } -+ j = 16-i; -+ pr_warning(" 0x%08x\n", qm_in(EDATA(j)) & mask); -+ j++; -+ for (; j < 16; j++) -+ pr_warning(" 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_warning("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_warning("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_warning("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_warning("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_warning("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_warning("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_warning("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 == NO_IRQ) { -+ 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; -+ /* 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_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; -+ temp /= CONFIG_QMAN_CEETM_UPDATE_PERIOD; -+ temp *= 10000000; -+ pres = (u16)(temp / qman_clk); -+ -+ 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; -+} -+ -+#ifdef CONFIG_SYSFS -+ -+#define DRV_NAME "fsl-qman" -+ -+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; -+ 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 (strict_strtoul(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 (strict_strtoul(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 (strict_strtoul(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)); -+}; -+ -+ -+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; -+ 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_IWUGO), -+ 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_IWUGO), show_dlm_avg, set_dlm_avg); -+static DEVICE_ATTR(dcp1_dlm_avg, (S_IRUSR|S_IWUGO), show_dlm_avg, set_dlm_avg); -+static DEVICE_ATTR(dcp2_dlm_avg, (S_IRUSR|S_IWUGO), show_dlm_avg, set_dlm_avg); -+static DEVICE_ATTR(dcp3_dlm_avg, (S_IRUSR|S_IWUGO), 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 __devinit 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; -+ if (qman_ip_rev != QMAN_REV10) { -+ 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); -+ -+static struct platform_driver of_fsl_qman_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = DRV_NAME, -+ .of_match_table = of_fsl_qman_ids, -+ }, -+ .probe = of_fsl_qman_probe, -+ .remove = __devexit_p(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 */ -diff --git a/drivers/staging/fsl_qbman/qman_debugfs.c b/drivers/staging/fsl_qbman/qman_debugfs.c -new file mode 100644 -index 0000000..8a17550 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_debugfs.c -@@ -0,0 +1,1404 @@ -+/* 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 *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}; -+static const u32 fqd_states_count = sizeof(fqd_states)/sizeof(u8); -+ -+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 u32 mask_filter_count = -+ sizeof(mask_filter)/sizeof(struct mask_filter_s); -+ -+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 (strict_strtoul(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_printf(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_printf(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_printf(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_printf(file, " fq_ctrl: None\n"); -+ else { -+ i = 0; -+ seq_printf(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_printf(file, " ctx_a_stash_exclusive: None\n"); -+ else { -+ seq_printf(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(struct qm_mcr_querycgr)); -+ 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_printf(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_printf(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); -+ -+ if (qman_ip_rev != QMAN_REV10) { -+ 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 */ -+ if (qman_ip_rev != QMAN_REV10) { -+ 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_printf(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_printf(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, -+}; -+ -+/******************************************************************************* -+ * 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[fqd_states_count]; -+ -+ 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) < fqd_states_count) -+ qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++; -+ } -+ flush_line_buffer(&line_buf, file); -+ -+ for (i = 0; i < fqd_states_count; 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[fqd_states_count]; -+ -+ 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) < fqd_states_count) -+ qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++; -+ } -+ -+ for (i = 0; i < fqd_states_count; 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[mask_filter_count/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 < mask_filter_count; j += 2) -+ if ((fqd.fq_ctrl & QM_FQCTRL_MASK) & -+ mask_filter[j].mask) -+ qm_prog_cnt[j/2]++; -+ } -+ for (i = 0; i < mask_filter_count/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_printf(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 = vmalloc(sizeof(u16) * (0xFFFF+1)); -+ if (!wq) -+ return -ENOMEM; -+ memset(wq, 0, sizeof(u16) * (0xFFFF+1)); -+ -+ 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_printf(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_printf(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; -+ -+ cqid = query_cq_fields_data.cqid; -+ ret = qman_ceetm_query_cq(cqid, 0, &query_result); -+ if (ret) -+ return ret; -+ seq_printf(file, "Query CQ Fields Result cqid 0x%x\n", cqid); -+ 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; -+ if (val > MAX_FQID) -+ return -EINVAL; -+ 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, -+}; -+/* 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); -+ -+ /* 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_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: -+ if (dfs_root) -+ 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"); -diff --git a/drivers/staging/fsl_qbman/qman_driver.c b/drivers/staging/fsl_qbman/qman_driver.c -new file mode 100644 -index 0000000..7157fac ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_driver.c -@@ -0,0 +1,743 @@ -+/* 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 -+ -+/* 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); -+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 qman_portal_max; -+ -+u32 qman_clk; -+struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX]; -+ -+/* size of the fqd region in bytes */ -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+static u32 fqd_size = (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ); -+#endif -+ -+/* 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; -+ -+/* 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_release_fqid_range(range[0], range[1]); -+ pr_info("Qman: FQID allocator includes range %d:%d\n", -+ range[0], 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 < chanid[1]; ret++) -+ pools_sdqcr |= QM_SDQCR_CHANNELS_POOL_CONV(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_release_pool_range(chanid[0], chanid[1]); -+ pr_info("Qman: pool channel allocator includes range %d:%d\n", -+ chanid[0], 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_release_cgrid_range(range[0], range[1]); -+ pr_info("Qman: CGRID allocator includes range %d:%d\n", -+ range[0], 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 = (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_release_ceetm0_lfqid_range(range[0], range[1]); -+ if (dcp_portal == qm_dc_portal_fman1) -+ qman_release_ceetm1_lfqid_range(range[0], range[1]); -+ pr_debug("Qman: The lfqid allocator of CEETM %d includes range" -+ " 0x%x:0x%x\n", dcp_portal, range[0], 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 < 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 = 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", -+ range[0], range[1], dcp_portal); -+ qman_ceetms[dcp_portal].sp_range[0] = range[0]; -+ qman_ceetms[dcp_portal].sp_range[1] = 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 < 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 = 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", -+ range[0], range[1], dcp_portal); -+ qman_ceetms[dcp_portal].lni_range[0] = range[0]; -+ qman_ceetms[dcp_portal].lni_range[1] = 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_release_ceetm0_channel_range(range[0], range[1]); -+ if (dcp_portal == qm_dc_portal_fman1) -+ qman_release_ceetm1_channel_range(range[0], range[1]); -+ pr_debug("Qman: The channel allocator of CEETM %d includes" -+ " range %d:%d\n", dcp_portal, range[0], range[1]); -+ -+ /* Set CEETM PRES register */ -+ ret = qman_ceetm_set_prescaler(dcp_portal); -+ if (ret) -+ return ret; -+ return 0; -+} -+ -+void qman_get_ip_revision(struct device_node *dn) -+{ -+ u16 ip_rev = 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")) { -+ ip_rev = QMAN_REV10; -+ qman_portal_max = 10; -+ } 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; -+ } else if (of_device_is_compatible(dn, -+ "fsl,qman-portal-3.0.2")) { -+ ip_rev = QMAN_REV30; -+ qman_portal_max = 10; -+ } else if (of_device_is_compatible(dn, -+ "fsl,qman-portal-3.0.3")) { -+ ip_rev = QMAN_REV30; -+ qman_portal_max = 18; -+ } -+ -+ if (!qman_ip_rev) { -+ if (ip_rev) { -+ qman_ip_rev = ip_rev; -+ } else { -+ pr_warning("unknown Qman version," -+ " default to rev1.1\n"); -+ qman_ip_rev = QMAN_REV11; -+ } -+ } else if (ip_rev && (qman_ip_rev != ip_rev)) -+ pr_warning("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, *channel; -+ int irq, ret; -+ -+ pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL); -+ if (!pcfg) { -+ pr_err("can't allocate portal config"); -+ return NULL; -+ } -+ -+ 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 = 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 (*index >= qman_portal_max) -+ goto err; -+ -+ channel = of_get_property(node, "fsl,qman-channel-id", &ret); -+ if (!channel || (ret != 4)) { -+ pr_err("Can't get %s property '%s'\n", node->full_name, -+ "fsl,qman-channel-id"); -+ goto err; -+ } -+ if (*channel != (*index + QM_CHANNEL_SWPORTAL0)) -+ pr_err("Warning: node %s has mismatched %s and %s\n", -+ node->full_name, "cell-index", "fsl,qman-channel-id"); -+ pcfg->public_cfg.channel = *channel; -+ pcfg->public_cfg.cpu = -1; -+ irq = irq_of_parse_and_map(node, 0); -+ if (irq == NO_IRQ) { -+ 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; -+ pcfg->node = node; -+#ifdef CONFIG_FSL_QMAN_CONFIG -+ /* We need the same LIODN offset for all portals */ -+ qman_liodn_fixup(pcfg->public_cfg.channel); -+#endif -+ -+ pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot( -+ pcfg->addr_phys[DPA_PORTAL_CE].start, -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]), -+ 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); -+ -+ return pcfg; -+err: -+ kfree(pcfg); -+ return NULL; -+} -+ -+/* Destroy a previously-parsed portal config. */ -+static void destroy_pcfg(struct qm_portal_config *pcfg) -+{ -+ iounmap(pcfg->addr_virt[DPA_PORTAL_CI]); -+ iounmap(pcfg->addr_virt[DPA_PORTAL_CE]); -+ kfree(pcfg); -+} -+ -+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; -+} -+ -+#ifdef CONFIG_FSL_PAMU -+static void portal_set_liodns(const struct qm_portal_config *pcfg, int cpu) -+{ -+ unsigned int index = 0; -+ unsigned int liodn_cnt = pamu_get_liodn_count(pcfg->node); -+ while (index < liodn_cnt) { -+ int ret = pamu_set_stash_dest(pcfg->node, index++, cpu, 1); -+ if (ret < 0) -+ pr_warning("Failed to set QMan stashing LIODN\n"); -+ } -+} -+#else -+#define portal_set_liodns(pcfg, cpu) do { } while (0) -+#endif -+ -+static void portal_set_cpu(const struct qm_portal_config *pcfg, int cpu) -+{ -+ portal_set_liodns(pcfg, cpu); -+#ifdef CONFIG_FSL_QMAN_CONFIG -+ if (qman_set_sdest(pcfg->public_cfg.channel, cpu)) -+#endif -+ pr_warning("Failed to set QMan portal's stash request queue\n"); -+} -+ -+/* UIO handling callbacks */ -+#define QMAN_UIO_PREAMBLE() \ -+ const struct qm_portal_config *pcfg = \ -+ container_of(__p, struct qm_portal_config, list) -+static int qman_uio_cb_init(const struct list_head *__p, struct uio_info *info) -+{ -+ QMAN_UIO_PREAMBLE(); -+ /* big enough for "qman-uio-xx" */ -+ char *name = kzalloc(16, GFP_KERNEL); -+ if (!name) -+ return -ENOMEM; -+ sprintf(name, "qman-uio-%x", pcfg->public_cfg.index); -+ info->name = name; -+ info->mem[DPA_PORTAL_CE].name = "cena"; -+ info->mem[DPA_PORTAL_CE].addr = pcfg->addr_phys[DPA_PORTAL_CE].start; -+ info->mem[DPA_PORTAL_CE].size = -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]); -+ info->mem[DPA_PORTAL_CE].memtype = UIO_MEM_PHYS; -+ info->mem[DPA_PORTAL_CI].name = "cinh"; -+ info->mem[DPA_PORTAL_CI].addr = pcfg->addr_phys[DPA_PORTAL_CI].start; -+ info->mem[DPA_PORTAL_CI].size = -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]); -+ info->mem[DPA_PORTAL_CI].memtype = UIO_MEM_PHYS; -+ info->irq = pcfg->public_cfg.irq; -+ return 0; -+} -+static void qman_uio_cb_destroy(const struct list_head *__p, -+ struct uio_info *info) -+{ -+ QMAN_UIO_PREAMBLE(); -+ kfree(info->name); -+ /* We own this struct but had passed it to the dpa_uio layer as a const -+ * so that we don't accidentally meddle with it in the dpa_uio code. -+ * Here it's passed back to us for final clean it up, so de-constify. */ -+ destroy_pcfg((struct qm_portal_config *)pcfg); -+} -+static int qman_uio_cb_open(const struct list_head *__p) -+{ -+ QMAN_UIO_PREAMBLE(); -+ /* 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. */ -+ portal_set_cpu(pcfg, hard_smp_processor_id()); -+ return 0; -+} -+static void qman_uio_cb_interrupt(const struct list_head *__p) -+{ -+ QMAN_UIO_PREAMBLE(); -+ /* This is the only manipulation of a portal register that isn't in the -+ * regular kernel portal driver (_high.c/_low.h). It is also the only -+ * time the kernel touches a register on a portal that is otherwise -+ * being driven by a user-space driver. So rather than messing up -+ * encapsulation for one trivial call, I am hard-coding the offset to -+ * the inhibit register and writing it directly from here. */ -+ out_be32(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe0c, ~(u32)0); -+} -+static const struct dpa_uio_vtable qman_uio = { -+ .init_uio = qman_uio_cb_init, -+ .destroy = qman_uio_cb_destroy, -+ .on_open = qman_uio_cb_open, -+ .on_interrupt = qman_uio_cb_interrupt -+}; -+ -+static struct qman_portal *init_pcfg(struct qm_portal_config *pcfg) -+{ -+ struct qman_portal *p; -+ struct cpumask oldmask = *tsk_cpus_allowed(current); -+ -+ portal_set_cpu(pcfg, pcfg->public_cfg.cpu); -+ set_cpus_allowed_ptr(current, get_cpu_mask(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; -+#endif -+#ifdef CONFIG_FSL_DPA_PIRQ_FAST -+ irq_sources |= QM_PIRQ_DQRI; -+#endif -+ qman_irqsource_add(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); -+ set_cpus_allowed_ptr(current, &oldmask); -+ return p; -+} -+ -+static void init_slave(int cpu) -+{ -+ struct qman_portal *p; -+ struct cpumask oldmask = *tsk_cpus_allowed(current); -+ set_cpus_allowed_ptr(current, get_cpu_mask(cpu)); -+ p = qman_create_affine_slave(shared_portals[shared_portals_idx++]); -+ 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 __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(unused_pcfgs); -+ 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; -+ -+ /* 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_warning("Can't find Qman clock frequency\n"); -+ else -+ qman_clk = *clk; -+ } -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ /* Setup lookup table for FQ demux */ -+ ret = qman_setup_fq_lookup_table(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; -+ } -+ -+ /* 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; -+ } -+ /* 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_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); -+ } -+ for_each_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_online_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); -+ } -+ 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"); -+#ifdef CONFIG_FSL_DPA_UIO -+ /* Export any left over portals as UIO devices */ -+ do { -+ pcfg = get_pcfg(&unused_pcfgs); -+ if (!pcfg) -+ break; -+ ret = dpa_uio_register(&pcfg->list, &qman_uio); -+ if (ret) { -+ pr_err("Failure registering QMan UIO portal\n"); -+ destroy_pcfg(pcfg); -+ } -+ } while (1); -+#endif -+ /* 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; -+} -+subsys_initcall(qman_init); -diff --git a/drivers/staging/fsl_qbman/qman_high.c b/drivers/staging/fsl_qbman/qman_high.c -new file mode 100644 -index 0000000..a00185e ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_high.c -@@ -0,0 +1,4351 @@ -+/* 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" */ -+ -+/* 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 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; -+ /* 256-element array, each is a linked-list of CSCN handlers. */ -+ struct list_head cgr_cbs[256]; -+ /* list lock */ -+ spinlock_t cgr_lock; -+}; -+ -+#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); -+/* "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() do { ; } while (0) -+ -+/* 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 = vmalloc((num_entries * sizeof(void *))); -+ if (!qman_fq_lookup_table) { -+ pr_err("QMan: Could not allocate fq lookup table\n"); -+ return -ENOMEM; -+ } -+ memset(qman_fq_lookup_table, 0, num_entries * sizeof(void *)); -+ 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 -+ -+/* 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 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); -+ 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 */ -+ return -1; -+ qm_mr_next(p); -+ qm_mr_cci_consume(p, 1); -+ goto loop; -+} -+ -+struct qman_portal *qman_create_affine_portal( -+ const struct qm_portal_config *config, -+ const struct qman_cgrs *cgrs) -+{ -+ struct qman_portal *portal = get_raw_affine_portal(); -+ struct qm_portal *__p = &portal->p; -+ char buf[16]; -+ int ret; -+ u32 isdr; -+ -+ /* A criteria for calling this function (from qman_driver.c) is that -+ * we're already affine to the cpu and won't schedule onto another cpu. -+ * This means we can put_affine_portal() and yet continue to use -+ * "portal", which in turn means aspects of this routine can sleep. */ -+ put_affine_portal(); -+ /* 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 (qm_eqcr_init(__p, qm_eqcr_pvb, qm_eqcr_cce)) { -+ 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]); -+ for (ret = 0; ret < __CGR_NUM; ret++) -+ INIT_LIST_HEAD(&portal->cgr_cbs[ret]); -+ spin_lock_init(&portal->cgr_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) -+ goto fail_devalloc; -+ if (dma_set_mask(&portal->pdev->dev, DMA_BIT_MASK(40))) -+ goto fail_devadd; -+ ret = platform_device_add(portal->pdev); -+ if (ret) -+ 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"); -+ goto fail_dqrr_mr_empty; -+ } -+ if (qm_mr_current(__p) != NULL) { -+ /* special handling, drain just in case it's a few FQRNIs */ -+ if (drain_mr_fqrni(__p)) { -+ pr_err("Qman MR unclean\n"); -+ goto fail_dqrr_mr_empty; -+ } -+ } -+ /* Success */ -+ portal->config = config; -+ spin_lock(&affine_mask_lock); -+ cpumask_set_cpu(config->public_cfg.cpu, &affine_mask); -+ affine_channels[config->public_cfg.cpu] = config->public_cfg.channel; -+ spin_unlock(&affine_mask_lock); -+ 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 (portal->cgrs) -+ 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: -+ return NULL; -+} -+ -+/* 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) -+{ -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ struct qman_portal *p = get_raw_affine_portal(); -+ /* 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; -+ put_affine_portal(); -+ return p; -+#else -+ BUG(); -+ return NULL; -+#endif -+} -+ -+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; -+ /* 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); -+ free_irq(pcfg->public_cfg.irq, qm); -+ kfree(qm->cgrs); -+ 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); -+ qm->config = NULL; -+ 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_get_portal_config(void) -+{ -+ struct qman_portal *p = get_affine_portal(); -+ const struct qman_portal_config *ret = &p->config->public_cfg; -+ 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; -+ -+ if (is & QM_PIRQ_CSCI) { -+ struct qman_cgrs rr, c; -+ struct qm_mc_result *mcr; -+ struct qman_cgr *cgr; -+ int i; -+ 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(); -+ /* 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 */ -+ qman_cgrs_for_each_1(i, &c) -+ list_for_each_entry(cgr, &p->cgr_cbs[i], node) { -+ if (cgr->cb) -+ cgr->cb(p, cgr, qman_cgrs_get(&rr, i)); -+ } -+ spin_unlock_irqrestore(&p->cgr_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; -+ 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, msg->fq.fqid); -+ BUG_ON(!fq); -+ fq_state_change(p, fq, msg, verb); -+ if (fq->cb.fqs) -+ fq->cb.fqs(p, fq, msg); -+ break; -+ case QM_MR_VERB_FQPN: -+ /* Parked */ -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ fq = get_fq_table_entry(msg->fq.contextB); -+#else -+ fq = (void *)(uintptr_t)msg->fq.contextB; -+#endif -+ fq_state_change(p, fq, msg, verb); -+ if (fq->cb.fqs) -+ fq->cb.fqs(p, fq, 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(msg->ern.tag); -+#else -+ fq = (void *)(uintptr_t)msg->ern.tag; -+#endif -+ fq->cb.ern(p, fq, msg); -+ } -+ num++; -+ qm_mr_next(&p->p); -+ goto mr_loop; -+mr_done: -+ qm_mr_cci_consume(&p->p, num); -+ } -+ -+ /* QM_PIRQ_CSCI 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); -+} -+ -+/* 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; -+ -+loop: -+ qm_dqrr_pvb_update(&p->p); -+ dq = qm_dqrr_current(&p->p); -+ if (!dq) -+ goto done; -+ 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)); -+ /* 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)); -+ /* 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_irqsource_add(u32 bits __maybe_unused) -+{ -+ struct qman_portal *p = get_raw_affine_portal(); -+ int ret = 0; -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (p->sharing_redirect) -+ ret = -EINVAL; -+ else -+#endif -+ { -+ __maybe_unused unsigned long irqflags; -+ PORTAL_IRQ_LOCK(p, irqflags); -+ set_bits(bits & QM_PIRQ_VISIBLE, &p->irq_sources); -+ qm_isr_enable_write(&p->p, p->irq_sources); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ } -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_irqsource_add); -+ -+int qman_irqsource_remove(u32 bits) -+{ -+ struct qman_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 &= 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); -+ put_affine_portal(); -+ return 0; -+} -+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); -+ -+int qman_poll_dqrr(unsigned int limit) -+{ -+ struct qman_portal *p = get_poll_portal(); -+ 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); -+ } -+ put_poll_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_poll_dqrr); -+ -+u32 qman_poll_slow(void) -+{ -+ struct qman_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 = qm_isr_status_read(&p->p) & ~p->irq_sources; -+ ret = __poll_portal_slow(p, is); -+ qm_isr_status_clear(&p->p, ret); -+ } -+ put_poll_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_poll_slow); -+ -+/* Legacy wrapper */ -+void qman_poll(void) -+{ -+ struct qman_portal *p = get_poll_portal(); -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (unlikely(p->sharing_redirect)) -+ goto done; -+#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); -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+done: -+#endif -+ put_poll_portal(); -+} -+EXPORT_SYMBOL(qman_poll); -+ -+void qman_stop_dequeues(void) -+{ -+ struct qman_portal *p = get_affine_portal(); -+ qman_stop_dequeues_ex(p); -+ put_affine_portal(); -+} -+EXPORT_SYMBOL(qman_stop_dequeues); -+ -+void qman_start_dequeues(void) -+{ -+ struct qman_portal *p = get_affine_portal(); -+ 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); -+ put_affine_portal(); -+} -+EXPORT_SYMBOL(qman_start_dequeues); -+ -+void qman_static_dequeue_add(u32 pools) -+{ -+ unsigned long irqflags __maybe_unused; -+ struct qman_portal *p = get_affine_portal(); -+ 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); -+ put_affine_portal(); -+} -+EXPORT_SYMBOL(qman_static_dequeue_add); -+ -+void qman_static_dequeue_del(u32 pools) -+{ -+ struct qman_portal *p = get_affine_portal(); -+ 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); -+ put_affine_portal(); -+} -+EXPORT_SYMBOL(qman_static_dequeue_del); -+ -+u32 qman_static_dequeue_get(void) -+{ -+ struct qman_portal *p = get_affine_portal(); -+ u32 ret = p->sdqcr; -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_static_dequeue_get); -+ -+void qman_dca(struct qm_dqrr_entry *dq, int park_request) -+{ -+ struct qman_portal *p = get_affine_portal(); -+ qm_dqrr_cdc_consume_1ptr(&p->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 = 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; -+ mcc = qm_mc_start(&p->p); -+ mcc->queryfq_np.fqid = 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)) { -+ /* OAC not supported on rev1.0 */ -+ if (unlikely(qman_ip_rev == QMAN_REV10)) -+ return -EINVAL; -+ /* 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 = 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; -+ } -+ } -+ 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 = 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 = 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 = 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 = 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; -+ 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 = 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; -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ 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 = 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) -+ *wq = mcr->querywq; -+ 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; -+ -+ 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; -+ } -+ 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; -+ -+ 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) -+ *congestion = mcr->querycongestion; -+ 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; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(qman_query_congestion); -+ -+/* internal function used as a wait_event() expression */ -+static int set_vdqcr(struct qman_portal **p, struct qman_fq *fq, u32 vdqcr) -+{ -+ unsigned long irqflags __maybe_unused; -+ int ret = -EBUSY; -+ *p = get_affine_portal(); -+ 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); -+ put_affine_portal(); -+ return ret; -+} -+ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+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_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_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; -+ -+ *p = get_affine_portal(); -+ 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)); -+ put_affine_portal(); -+ return NULL; -+ } -+ (*p)->eqci_owned = fq; -+ } -+#endif -+ avail = qm_eqcr_get_avail(&(*p)->p); -+ if (avail < 2) -+ update_eqcr_ci(*p, avail); -+ eq = qm_eqcr_start(&(*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)); -+ put_affine_portal(); -+ 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 = fq->fqid; -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ eq->tag = fq->key; -+#else -+ eq->tag = (u32)(uintptr_t)fq; -+#endif -+ /* From p4080 rev1 -> rev2, the FD struct's address went from 48-bit to -+ * 40-bit but rev1 chips will still interpret it as 48-bit, meaning we -+ * have to scrub the upper 8-bits, just in case the user left noise in -+ * there. Doing this selectively via a run-time check of the h/w -+ * revision (as we do for most errata, for example) is too slow in this -+ * critical path code. The most inexpensive way to handle this is just -+ * to reinterpret the FD as 4 32-bit words and to mask the first word -+ * appropriately, irrespecitive of the h/w revision. The struct fields -+ * corresponding to this word are; -+ * u8 dd:2; -+ * u8 liodn_offset:6; -+ * u8 bpid; -+ * u8 eliodn_offset:4; -+ * u8 __reserved:4; -+ * u8 addr_hi; -+ * So we mask this word with 0xc0ff00ff, which implicitly scrubs out -+ * liodn_offset, eliodn_offset, and __reserved - the latter two fields -+ * are interpreted as the 8 msbits of the 48-bit address in the case of -+ * rev1. -+ */ -+ { -+ const u32 *src = (const u32 *)fd; -+ u32 *dest = (u32 *)&eq->fd; -+ dest[0] = src[0] & 0xc0ff00ff; -+ dest[1] = src[1]; -+ dest[2] = src[2]; -+ dest[3] = src[3]; -+ } -+ 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) -+ 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; -+} -+#endif -+ -+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) -+ 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_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 = orp_seqnum; -+ eq->orp = 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) -+ 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_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; -+ -+ /* frame mode not supported on rev1.0 */ -+ if (unlikely(qman_ip_rev == QMAN_REV10)) { -+ if (opts && (opts->we_mask & QM_CGR_WE_MODE) && -+ opts->cgr.mode == QMAN_CGR_MODE_FRAME) { -+ put_affine_portal(); -+ return -EIO; -+ } -+ } -+ PORTAL_IRQ_LOCK(p, irqflags); -+ mcc = qm_mc_start(&p->p); -+ if (opts) -+ mcc->initcgr = *opts; -+ 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 PORTAL_IDX(n) (n->config->public_cfg.channel - QM_CHANNEL_SWPORTAL0) -+ -+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; -+ -+ p = get_affine_portal(); -+ -+ 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 and I'm not the first for this portal, just add -+ * to the list */ -+ if ((opts == NULL) && !list_empty(&p->cgr_cbs[cgr->cgrid])) -+ 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[cgr->cgrid]); -+ -+ /* 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; -+ int ret; -+ -+ if ((qman_ip_rev & 0xFF00) < QMAN_REV30) { -+ pr_warning("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; -+ -+ memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr)); -+ if (opts) -+ local_opts = *opts; -+ -+ local_opts.cgr.cscn_targ_upd_ctrl = QM_CGR_TARG_UDP_CTRL_WRITE_BIT | -+ QM_CGR_TARG_UDP_CTRL_DCP | 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_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 last in list, CSCN_TARG must be set accordingly */ -+ if (!list_empty(&p->cgr_cbs[cgr->cgrid])) -+ goto release_lock; -+ ret = qman_query_cgr(cgr, &cgr_state); -+ if (ret) { -+ /* add back to the list */ -+ list_add(&cgr->node, &p->cgr_cbs[cgr->cgrid]); -+ 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 = -+ ~QM_CGR_TARG_UDP_CTRL_WRITE_BIT | 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[cgr->cgrid]); -+release_lock: -+ spin_unlock_irqrestore(&p->cgr_lock, irqflags); -+put_portal: -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_delete_cgr); -+ -+int qm_get_clock(u64 *clock_hz) -+{ -+ if (!qman_clk) { -+ pr_warning("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 */ -+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; -+} -+ -+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 = 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(); -+ res = mcr->result; -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_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; -+ } -+ -+ *cq_query = mcr->cq_query; -+ return 0; -+} -+ -+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; -+} -+ -+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; -+} -+ -+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; -+} -+ -+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 = 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; -+} -+ -+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; -+} -+ -+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; -+} -+ -+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 = *ccgr_query; -+ 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); -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ res = mcr->result; -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: QUERY CCGR failed\n"); -+ return -EIO; -+ } -+ *response = mcr->ccgr_query; -+ return 0; -+} -+ -+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; -+} -+ -+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_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; -+} -+ -+/* bit divisor, dividend and result. dynamic precision */ -+static __inline__ uint64_t _div64_64(uint64_t dividend, uint64_t divisor) -+{ -+ uint32_t d = divisor; -+ -+ if (divisor > 0xffffffffULL) -+ { -+ unsigned int shift = fls(divisor >> 32); -+ -+ d = divisor >> shift; -+ dividend >>= shift; -+ } -+ -+ /* avoid 64 bit division if possible */ -+ if (dividend >> 32) -+ do_div(dividend, d); -+ else -+ dividend = (uint32_t) dividend / d; -+ -+ return dividend; -+} -+ -+int qman_ceetm_bps2tokenrate(u32 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 interger 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) -+ * -+ */ -+ temp = ROUNDING(((u64)bps << 32), pres, rounding); -+ temp = ROUNDING(temp, 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, u32 *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->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->idx, sp->dcp_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 = 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 = 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 = 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; -+ -+ config_opts.cid = CEETM_COMMAND_LNI_SHAPER | lni->idx; -+ config_opts.dcpid = lni->dcp_idx; -+ config_opts.shaper_config.cpl = (coupled << 7) | oal; -+ config_opts.shaper_config.crtcr = (lni->cr_token_rate.whole << 13) | -+ lni->cr_token_rate.fraction; -+ config_opts.shaper_config.ertcr = (lni->er_token_rate.whole << 13) | -+ lni->er_token_rate.fraction; -+ config_opts.shaper_config.crtbl = lni->cr_token_bucket_limit; -+ config_opts.shaper_config.ertbl = lni->er_token_bucket_limit; -+ 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) -+{ -+ if (!lni->shaper_enable) { -+ pr_err("The shaper has been disabled\n"); -+ return -EINVAL; -+ } -+ -+ lni->shaper_enable = 0; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_lni_disable_shaper); -+ -+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; -+ -+ if (!lni->shaper_enable) { -+ pr_err("The LNI#%d is unshaped, cannot set CR rate\n", -+ lni->idx); -+ return -EINVAL; -+ } -+ -+ query_opts.cid = 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; -+ } -+ -+ lni->cr_token_rate.whole = token_rate->whole; -+ lni->cr_token_rate.fraction = token_rate->fraction; -+ lni->cr_token_bucket_limit = token_limit; -+ config_opts.cid = CEETM_COMMAND_LNI_SHAPER | lni->idx; -+ config_opts.dcpid = lni->dcp_idx; -+ config_opts.shaper_config.crtcr = (token_rate->whole << 13) | -+ (token_rate->fraction); -+ config_opts.shaper_config.crtbl = 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_lni_set_commit_rate); -+ -+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 = 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 | !query_result.shaper_query.crtcr | -+ !query_result.shaper_query.crtbl) { -+ pr_err("The LNI CR rate or limit is not set\n"); -+ return -EINVAL; -+ } -+ token_rate->whole = query_result.shaper_query.crtcr >> 13; -+ token_rate->fraction = query_result.shaper_query.crtcr & 0x1FFF; -+ *token_limit = query_result.shaper_query.crtbl; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate); -+ -+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; -+ -+ if (!lni->shaper_enable) { -+ pr_err("The LIN#%d is unshaped, cannot set ER rate\n", -+ lni->idx); -+ return -EINVAL; -+ } -+ -+ query_opts.cid = 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; -+ } -+ -+ lni->er_token_rate.whole = token_rate->whole; -+ lni->er_token_rate.fraction = token_rate->fraction; -+ lni->er_token_bucket_limit = token_limit; -+ config_opts.cid = CEETM_COMMAND_LNI_SHAPER | lni->idx; -+ config_opts.dcpid = lni->dcp_idx; -+ config_opts.shaper_config.ertcr = -+ (token_rate->whole << 13) | (token_rate->fraction); -+ config_opts.shaper_config.ertbl = 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_lni_set_excess_rate); -+ -+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 = 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 | !query_result.shaper_query.ertcr | -+ !query_result.shaper_query.ertbl) { -+ pr_err("The LNI ER rate or limit is not set\n"); -+ return -EINVAL; -+ } -+ token_rate->whole = query_result.shaper_query.ertcr >> 13; -+ token_rate->fraction = query_result.shaper_query.ertcr & 0x1FFF; -+ *token_limit = query_result.shaper_query.ertbl; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate); -+ -+#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 = 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 = 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 = lnitcfcc; -+ config_opts.cid = 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 = 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)(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); -+ -+#define QMAN_CEETM_ENABLE_CHANNEL_SHAPER 0x80 -+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; -+ static u8 map; -+ -+ if (lni->dcp_idx == qm_dc_portal_fman0) -+ ret = qman_alloc_ceetm0_channel(&channel_idx); -+ if (lni->dcp_idx == qm_dc_portal_fman1) -+ ret = qman_alloc_ceetm1_channel(&channel_idx); -+ if (ret) { -+ pr_err("The is no channel available for LNI#%d\n", lni->idx); -+ return -ENODEV; -+ } -+ -+ p = kzalloc(sizeof(*p), GFP_KERNEL); -+ p->idx = channel_idx; -+ p->dcp_idx = lni->dcp_idx; -+ list_add_tail(&p->node, &lni->channels); -+ INIT_LIST_HEAD(&p->class_queues); -+ INIT_LIST_HEAD(&p->ccgs); -+ config_opts.cid = CEETM_COMMAND_CHANNEL_MAPPING | channel_idx; -+ config_opts.dcpid = lni->dcp_idx; -+ map = (u8)~QMAN_CEETM_ENABLE_CHANNEL_SHAPER; -+ map &= lni->idx; -+ config_opts.channel_mapping.map = map; -+ 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; -+ } -+ -+ config_opts.cid = 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); -+ if (channel->dcp_idx == qm_dc_portal_fman1) -+ qman_release_ceetm1_channelid(channel->idx); -+ 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; -+ u8 map; -+ -+ 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 = (u16)(CEETM_COMMAND_CHANNEL_MAPPING | channel->idx); -+ query_opts.dcpid = (u8)channel->dcp_idx; -+ -+ if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) { -+ pr_err("Can't query channel mapping\n"); -+ return -EINVAL; -+ } -+ -+ map = query_result.channel_mapping_query.map; -+ map |= QMAN_CEETM_ENABLE_CHANNEL_SHAPER; -+ -+ config_opts.cid = CEETM_COMMAND_CHANNEL_MAPPING | channel->idx; -+ config_opts.dcpid = channel->dcp_idx; -+ config_opts.channel_mapping.map = map; -+ 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 = CEETM_COMMAND_CHANNEL_SHAPER | channel->idx; -+ config_opts.shaper_config.cpl = coupled << 7; -+ config_opts.shaper_config.crtcr = (channel->cr_token_rate.whole << 13) | -+ channel->cr_token_rate.fraction; -+ config_opts.shaper_config.ertcr = (channel->er_token_rate.whole << 13) | -+ channel->er_token_rate.fraction; -+ config_opts.shaper_config.crtbl = channel->cr_token_bucket_limit; -+ config_opts.shaper_config.ertbl = 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; -+ u8 map; -+ -+ if (channel->shaper_enable == 0) { -+ pr_err("This channel shaper has been disabled\n"); -+ return -EINVAL; -+ } -+ -+ query_opts.cid = 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; -+ } -+ -+ map = query_result.channel_mapping_query.map; -+ map &= ~QMAN_CEETM_ENABLE_CHANNEL_SHAPER; -+ -+ config_opts.cid = CEETM_COMMAND_CHANNEL_MAPPING | channel->idx; -+ config_opts.dcpid = channel->dcp_idx; -+ config_opts.channel_mapping.map = map; -+ return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_channel_disable_shaper); -+ -+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; -+ -+ if (!channel->shaper_enable) { -+ pr_err("This channel is unshaped\n"); -+ return -EINVAL; -+ } -+ -+ query_opts.cid = 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 = CEETM_COMMAND_CHANNEL_SHAPER | channel->idx; -+ config_opts.dcpid = channel->dcp_idx; -+ config_opts.shaper_config.crtcr = (token_rate->whole << 13) | -+ (token_rate->fraction); -+ config_opts.shaper_config.crtbl = 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_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 = 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 = query_result.shaper_query.crtcr >> 13; -+ token_rate->fraction = query_result.shaper_query.crtcr & 0x1FFF; -+ *token_limit = query_result.shaper_query.crtbl; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate); -+ -+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; -+ -+ if (!channel->shaper_enable) { -+ pr_err("This channel is unshaped\n"); -+ return -EINVAL; -+ } -+ -+ query_opts.cid = 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 = CEETM_COMMAND_CHANNEL_SHAPER | channel->idx; -+ config_opts.dcpid = channel->dcp_idx; -+ config_opts.shaper_config.ertcr = -+ (token_rate->whole << 13) | (token_rate->fraction); -+ config_opts.shaper_config.ertbl = 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_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 = 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 = query_result.shaper_query.ertcr >> 13; -+ token_rate->fraction = query_result.shaper_query.ertcr & 0x1FFF; -+ *token_limit = query_result.shaper_query.ertbl; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate); -+ -+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 = CEETM_COMMAND_CHANNEL_SHAPER | channel->idx; -+ config_opts.dcpid = channel->dcp_idx; -+ config_opts.shaper_config.crtbl = 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 = 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 = 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 | (prio_a > 7)) { -+ pr_err("The priority of group A is out of range\n"); -+ return -EINVAL; -+ } -+ if (!prio_a || (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 = channel->idx; -+ config_opts.dcpid = channel->dcp_idx; -+ if (!group_b) -+ config_opts.gpc = (u8)((1 << 6) | prio_a); -+ else -+ config_opts.gpc = (u8)((prio_b << 3) | prio_a); -+ -+ 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 >> 6) & 0x1; -+ *prio_a = query_result.gpc & 0x3; -+ *prio_b = (query_result.gpc >> 3) & 0x3; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_get_group); -+ -+#define CQ_ELIGIBILITY_MASK(n) (1 << (7 - n)) -+#define CQ_A_ELIGIBILITY_MASK (1 << 8) -+#define CQ_B_ELIGIBILITY_MASK (1 << 9) -+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; -+ struct qm_mcc_ceetm_class_scheduler_config csch_config; -+ struct qm_mcr_ceetm_class_scheduler_query csch_query_result; -+ int i; -+ -+ 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 = (channel->idx << 4) | idx; -+ cq_config.dcpid = channel->dcp_idx; -+ cq_config.ccgid = ccg->idx; -+ if (qman_ceetm_configure_cq(&cq_config)) { -+ pr_err("Can't configure the CQ#%d with CCGRID#%d\n", -+ idx, ccg->idx); -+ return -EINVAL; -+ } -+ } -+ -+ if (channel->shaper_enable) { -+ if (qman_ceetm_query_class_scheduler(channel, -+ &csch_query_result)) { -+ pr_err("Can't query channel#%d!\n", channel->idx); -+ return -EINVAL; -+ } -+ csch_config.cqcid = channel->idx; -+ csch_config.dcpid = channel->dcp_idx; -+ csch_config.crem = csch_query_result.crem | -+ CQ_ELIGIBILITY_MASK(idx); -+ csch_config.erem = csch_query_result.erem | -+ CQ_ELIGIBILITY_MASK(idx); -+ csch_config.gpc = csch_query_result.gpc; -+ for (i = 0; i < 8; i++) -+ csch_config.w[i] = csch_query_result.w[i]; -+ -+ if (qman_ceetm_configure_class_scheduler(&csch_config)) { -+ pr_err("Can't config channel scheduler to set" -+ " eligibility mask for CQ#%d\n", idx); -+ 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; -+ struct qm_mcc_ceetm_class_scheduler_config csch_config; -+ struct qm_mcr_ceetm_class_scheduler_query csch_query_result; -+ int i; -+ -+ if ((idx < 7) || (idx > 15)) { -+ pr_err("This grouped class queue id is out of range\n"); -+ return -EINVAL; -+ } -+ p = kmalloc(sizeof(*p), GFP_KERNEL); -+ if (!p) { -+ pr_err("Can't allocate memory for CQ#%d!\n", idx); -+ return -ENOMEM; -+ } -+ -+ 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; -+ } -+ } -+ 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 = (channel->idx << 4) | idx; -+ cq_config.dcpid = channel->dcp_idx; -+ cq_config.ccgid = ccg->idx; -+ if (qman_ceetm_configure_cq(&cq_config)) { -+ pr_err("Can't configure the CQ#%d with CCGRID#%d\n", -+ idx, ccg->idx); -+ return -EINVAL; -+ } -+ } -+ -+ if (channel->shaper_enable) { -+ if (qman_ceetm_query_class_scheduler(channel, -+ &csch_query_result)) { -+ pr_err("Can't query channel#%d!\n", channel->idx); -+ return -EINVAL; -+ } -+ csch_config.cqcid = channel->idx; -+ csch_config.dcpid = channel->dcp_idx; -+ csch_config.crem = csch_query_result.crem | -+ CQ_A_ELIGIBILITY_MASK; -+ csch_config.erem = csch_query_result.erem | -+ CQ_A_ELIGIBILITY_MASK; -+ csch_config.gpc = csch_query_result.gpc; -+ for (i = 0; i < 8; i++) -+ csch_config.w[i] = csch_query_result.w[i]; -+ if (qman_ceetm_configure_class_scheduler(&csch_config)) { -+ pr_err("Can't config channel scheduler to set" -+ " eligibility mask for CQ#%d\n", idx); -+ 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; -+ struct qm_mcc_ceetm_class_scheduler_config csch_config; -+ struct qm_mcr_ceetm_class_scheduler_query csch_query_result; -+ int i; -+ -+ if ((idx < 11) || (idx > 15)) { -+ pr_err("This grouped class queue id is out of range\n"); -+ return -EINVAL; -+ } -+ -+ p = kmalloc(sizeof(*p), GFP_KERNEL); -+ if (!p) { -+ pr_err("Can't allocate memory for CQ#%d!\n", idx); -+ return -ENOMEM; -+ } -+ -+ 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; -+ } -+ } -+ 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 = (channel->idx << 4) | idx; -+ cq_config.dcpid = channel->dcp_idx; -+ cq_config.ccgid = ccg->idx; -+ if (qman_ceetm_configure_cq(&cq_config)) { -+ pr_err("Can't configure the CQ#%d with CCGRID#%d\n", -+ idx, ccg->idx); -+ return -EINVAL; -+ } -+ } -+ -+ if (channel->shaper_enable) { -+ if (qman_ceetm_query_class_scheduler(channel, -+ &csch_query_result)) { -+ pr_err("Can't query channel#%d!\n", channel->idx); -+ return -EINVAL; -+ } -+ csch_config.cqcid = channel->idx; -+ csch_config.dcpid = channel->dcp_idx; -+ csch_config.crem = csch_query_result.crem | -+ CQ_B_ELIGIBILITY_MASK; -+ csch_config.erem = csch_query_result.erem | -+ CQ_B_ELIGIBILITY_MASK; -+ csch_config.gpc = csch_query_result.gpc; -+ for (i = 0; i < 8; i++) -+ csch_config.w[i] = csch_query_result.w[i]; -+ if (qman_ceetm_configure_class_scheduler(&csch_config)) { -+ pr_err("Can't config channel scheduler to set" -+ " eligibility mask for CQ#%d\n", idx); -+ 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); -+ 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 (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 = 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 = query_result.gpc; -+ for (i = 0; i < 8; i++) -+ config_opts.w[i] = query_result.w[i]; -+ config_opts.w[cq->idx] = (weight_code->y << 3) | weight_code->x; -+ 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 (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] >> 3) & 0x1F; -+ weight_code->x = query_result.w[cq->idx] & 0x3; -+ 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) -+ */ -+#define QM_WBFS_MAKECODE(x, y) (((y) << 3) | ((x & 0x7))) -+#define QM_WBFS_CODE_X(c) ((c) & 0x7) -+#define QM_WBFS_CODE_Y(c) ((c) >> 3) -+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(unsigned int weight_code, -+ u32 *numerator, -+ u32 *denominator) -+{ -+ *numerator = (u32) 1 << (QM_WBFS_CODE_X(weight_code) + 6); -+ *denominator = 64 - QM_WBFS_CODE_Y(weight_code); -+ 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, -+ unsigned int *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 = QM_WBFS_MAKECODE(x, y); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_ratio2wbfs); -+ -+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 = (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 = result.frm_cnt; -+ *byte_count = result.byte_cnt; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_cq_get_dequeue_statistics); -+ -+#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); -+ if (cq->parent->dcp_idx == qm_dc_portal_fman1) -+ ret = qman_alloc_ceetm1_lfqid(&lfqid); -+ 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 = CEETM_LFQMT_LFQID_MSB | -+ (cq->parent->dcp_idx << 16) | -+ (lfqid & CEETM_LFQMT_LFQID_LSB); -+ lfqmt_config.cqid = (cq->parent->idx << 4) | (cq->idx); -+ lfqmt_config.dctidx = p->dctidx; -+ if (qman_ceetm_configure_lfqmt(&lfqmt_config)) { -+ pr_err("Can't configure LFQMT for LFQID#%d @ CQ#%d\n", -+ lfqid, cq->idx); -+ 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); -+ if (lfq->parent->dcp_idx == qm_dc_portal_fman1) -+ qman_release_ceetm1_lfqid(lfq->idx); -+ 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 = (u16)lfq->dctidx; -+ dct_config.dcpid = lfq->parent->dcp_idx; -+ dct_config.context_b = context_b; -+ dct_config.context_a = 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 = (u16)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 = query_result.context_a; -+ *context_b = 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); -+ -+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 < 0) || (idx > 15)) { -+ 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; -+ -+ *ccg = p; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_ccg_claim); -+ -+int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg) -+{ -+ list_del(&ccg->node); -+ kfree(ccg); -+ return 0; -+} -+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; -+ -+ config_opts.ccgrid = CEETM_CCGR_CM_CONFIGURE | -+ (ccg->parent->idx << 4) | ccg->idx; -+ config_opts.dcpid = ccg->parent->dcp_idx; -+ config_opts.we_mask = we_mask; -+ config_opts.cm_config.ctl = (params->wr_en_g << 6) | -+ (params->wr_en_y << 5) | -+ (params->wr_en_r << 4) | -+ (params->td_en << 3) | -+ (params->td_mode << 2) | -+ (params->cscn_en << 1) | -+ (params->mode); -+ config_opts.cm_config.oal = params->oal; -+ config_opts.cm_config.cs_thres = params->cs_thres_in; -+ config_opts.cm_config.cs_thres_x = params->cs_thres_out; -+ config_opts.cm_config.td_thres = params->td_thres; -+ config_opts.cm_config.wr_parm_g = params->wr_parm_g; -+ config_opts.cm_config.wr_parm_y = params->wr_parm_y; -+ config_opts.cm_config.wr_parm_r = params->wr_parm_r; -+ -+ return qman_ceetm_configure_ccgr(&config_opts); -+} -+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 = 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 = query_result.cm_query.wr_parm_r; -+ params->wr_parm_y = query_result.cm_query.wr_parm_y; -+ params->wr_parm_g = query_result.cm_query.wr_parm_g; -+ params->td_thres = query_result.cm_query.td_thres; -+ params->cs_thres_out = query_result.cm_query.cs_thres_x; -+ params->cs_thres_in = query_result.cm_query.cs_thres; -+ params->oal = query_result.cm_query.oal; -+ params->wr_en_g = (query_result.cm_query.ctl >> 6) & -+ CEETM_CCGR_CTL_MASK; -+ params->wr_en_y = (query_result.cm_query.ctl >> 5) & -+ CEETM_CCGR_CTL_MASK; -+ params->wr_en_r = (query_result.cm_query.ctl >> 4) & -+ CEETM_CCGR_CTL_MASK; -+ params->td_en = (query_result.cm_query.ctl >> 3) & -+ CEETM_CCGR_CTL_MASK; -+ params->td_mode = (query_result.cm_query.ctl >> 2) & -+ CEETM_CCGR_CTL_MASK; -+ params->cscn_en = (query_result.cm_query.ctl >> 1) & -+ CEETM_CCGR_CTL_MASK; -+ params->mode = (query_result.cm_query.ctl & CEETM_CCGR_CTL_MASK); -+ -+ 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 = (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 = result.frm_cnt; -+ *byte_count = result.byte_cnt; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_ccg_get_reject_statistics); -+ -+#define CEETM_CSCN_TARG_SWP 0 -+#define CEETM_CSCN_TARG_DCP 1 -+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) -+{ -+ struct qm_mcc_ceetm_ccgr_config config_opts; -+ int ret; -+ -+ config_opts.ccgrid = CEETM_CCGR_CM_CONFIGURE | -+ (ccg->parent->idx << 4) | ccg->idx; -+ config_opts.dcpid = ccg->parent->dcp_idx; -+ config_opts.we_mask = we_mask | QM_CCGR_WE_CSCN_TUPD; -+ config_opts.cm_config.cscn_tupd = (cscn_enabled << 15) | -+ (CEETM_CSCN_TARG_SWP << 14) | -+ swp_idx; -+ config_opts.cm_config.ctl = (params->wr_en_g << 6) | -+ (params->wr_en_y << 5) | -+ (params->wr_en_r << 4) | -+ (params->td_en << 3) | -+ (params->td_mode << 2) | -+ (params->cscn_en << 1) | -+ (params->mode); -+ config_opts.cm_config.cs_thres = params->cs_thres_in; -+ config_opts.cm_config.cs_thres_x = params->cs_thres_out; -+ config_opts.cm_config.td_thres = params->td_thres; -+ config_opts.cm_config.wr_parm_g = params->wr_parm_g; -+ config_opts.cm_config.wr_parm_y = params->wr_parm_y; -+ config_opts.cm_config.wr_parm_r = params->wr_parm_r; -+ -+ ret = qman_ceetm_configure_ccgr(&config_opts); -+ if (ret) { -+ pr_err("Configure CSCN_TARG_SWP failed!\n"); -+ return -EINVAL; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_cscn_swp_set); -+ -+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; -+ -+ query_opts.ccgrid = 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; -+ } -+ -+ if (swp_idx < 63) -+ *cscn_enabled = (query_result.cm_query.cscn_targ_swp[0] >> -+ (63 - swp_idx)) & 0x1; -+ else -+ *cscn_enabled = (query_result.cm_query.cscn_targ_swp[1] >> -+ (127 - swp_idx)) & 0x1; -+ 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 = CEETM_CCGR_CM_CONFIGURE | -+ (ccg->parent->idx << 4) | ccg->idx; -+ config_opts.dcpid = ccg->parent->dcp_idx; -+ config_opts.we_mask = we_mask | QM_CCGR_WE_CSCN_TUPD | QM_CCGR_WE_CDV; -+ config_opts.cm_config.cdv = vcgid; -+ config_opts.cm_config.cscn_tupd = (cscn_enabled << 15) | -+ (CEETM_CSCN_TARG_DCP << 14) | -+ dcp_idx; -+ config_opts.cm_config.ctl = (params->wr_en_g << 6) | -+ (params->wr_en_y << 5) | -+ (params->wr_en_r << 4) | -+ (params->td_en << 3) | -+ (params->td_mode << 2) | -+ (params->cscn_en << 1) | -+ (params->mode); -+ config_opts.cm_config.cs_thres = params->cs_thres_in; -+ config_opts.cm_config.cs_thres_x = params->cs_thres_out; -+ config_opts.cm_config.td_thres = params->td_thres; -+ config_opts.cm_config.wr_parm_g = params->wr_parm_g; -+ config_opts.cm_config.wr_parm_y = params->wr_parm_y; -+ config_opts.cm_config.wr_parm_r = params->wr_parm_r; -+ -+ 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 = 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 >> -+ (7 - dcp_idx)) & 0x1; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_cscn_dcp_get); -+ -+int qman_ceetm_querycongestion(u16 *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 < 1 ; i++) { -+ mcc->ccgr_query.ccgrid = 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 < 16; j++) -+ *(ccg_state + j) = -+ mcr->ccgr_query.congestion_state.ccg_state[j]; -+ } else { -+ pr_err("QUERY CEETM CONGESTION STATE failed\n"); -+ 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); -diff --git a/drivers/staging/fsl_qbman/qman_low.h b/drivers/staging/fsl_qbman/qman_low.h -new file mode 100644 -index 0000000..d517af5 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_low.h -@@ -0,0 +1,1171 @@ -+/* 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 */ -+#define REG_EQCR_PI_CINH 0x0000 -+#define REG_EQCR_CI_CINH 0x0004 -+#define REG_EQCR_ITR 0x0008 -+#define REG_DQRR_PI_CINH 0x0040 -+#define REG_DQRR_CI_CINH 0x0044 -+#define REG_DQRR_ITR 0x0048 -+#define REG_DQRR_DCAP 0x0050 -+#define REG_DQRR_SDQCR 0x0054 -+#define REG_DQRR_VDQCR 0x0058 -+#define REG_DQRR_PDQCR 0x005c -+#define REG_MR_PI_CINH 0x0080 -+#define REG_MR_CI_CINH 0x0084 -+#define REG_MR_ITR 0x0088 -+#define REG_CFG 0x0100 -+#define REG_ISR 0x0e00 -+#define REG_ITPR 0x0e14 -+ -+/* Cache-enabled register offsets */ -+#define CL_EQCR 0x0000 -+#define CL_DQRR 0x1000 -+#define CL_MR 0x2000 -+#define CL_EQCR_PI_CENA 0x3000 -+#define CL_EQCR_CI_CENA 0x3100 -+#define CL_DQRR_PI_CENA 0x3200 -+#define CL_DQRR_CI_CENA 0x3300 -+#define CL_MR_PI_CENA 0x3400 -+#define CL_MR_CI_CENA 0x3500 -+#define CL_CR 0x3800 -+#define CL_RR0 0x3900 -+#define CL_RR1 0x3940 -+ -+/* 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) __raw_readl((qm)->addr_ci + (o)) -+#define __qm_out(qm, o, val) __raw_writel((val), (qm)->addr_ci + (o)) -+#define qm_in(reg) __qm_in(&portal->addr, REG_##reg) -+#define qm_out(reg, val) __qm_out(&portal->addr, 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) __raw_readl((qm)->addr_ce + (o)) -+#define __qm_cl_out(qm, o, val) \ -+ do { \ -+ u32 *__tmpclout = (qm)->addr_ce + (o); \ -+ __raw_writel((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, CL_##reg##_CENA) -+#define qm_cl_touch_rw(reg) __qm_cl_touch_rw(&portal->addr, CL_##reg##_CENA) -+#define qm_cl_in(reg) __qm_cl_in(&portal->addr, CL_##reg##_CENA) -+#define qm_cl_out(reg, val) __qm_cl_out(&portal->addr, CL_##reg##_CENA, val) -+#define qm_cl_invalidate(reg) __qm_cl_invalidate(&portal->addr, 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 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_eqcr_cmode { /* s/w-only */ -+ qm_eqcr_cci, /* CI index, cache-inhibited */ -+ qm_eqcr_cce /* CI index, cache-enabled */ -+}; -+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; -+ enum qm_eqcr_cmode cmode; -+#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 */ -+ mc_idle, -+ /* Can be _mc_commit()ed or _mc_abort()ed */ -+ mc_user, -+ /* Can only be _mc_retry()ed */ -+ mc_hw -+ } state; -+#endif -+}; -+ -+#ifdef CONFIG_FSL_QMAN_BUG_AND_FEATURE_REV1 -+/* For workarounds that require storage. The struct alignment is required for -+ * cases where operations on "shadow" structs need the same alignment as is -+ * present on the corresponding h/w data structs (specifically, there is a -+ * zero-bit present above the range required to address the ring, so that -+ * iteration can be achieved by incrementing a ring pointer and clearing the -+ * carry-bit). The "portal" struct needs the same alignment because this type -+ * goes at its head, so it has a more radical alignment requirement if this -+ * structure is used. (NB: "64" instead of "L1_CACHE_BYTES", because this -+ * alignment relates to the h/w interface, not the CPU cache granularity!)*/ -+#define QM_PORTAL_ALIGNMENT __attribute__((aligned(32 * 64))) -+struct qm_portal_bugs { -+ /* shadow MR ring, for QMAN9 workaround, 8-CL-aligned */ -+ struct qm_mr_entry mr[QM_MR_SIZE]; -+ /* shadow MC result, for QMAN6 and QMAN7 workarounds, CL-aligned */ -+ struct qm_mc_result result; -+ /* boolean switch for QMAN7 workaround */ -+ int initfq_and_sched; -+} QM_PORTAL_ALIGNMENT; -+#else -+#define QM_PORTAL_ALIGNMENT ____cacheline_aligned -+#endif -+ -+struct qm_addr { -+ void __iomem *addr_ce; /* cache-enabled */ -+ void __iomem *addr_ci; /* cache-inhibited */ -+}; -+ -+struct qm_portal { -+#ifdef CONFIG_FSL_QMAN_BUG_AND_FEATURE_REV1 -+ struct qm_portal_bugs bugs; -+#endif -+ /* 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, -+ __maybe_unused enum qm_eqcr_cmode cmode) -+{ -+ /* This use of 'register', as well as all other occurances, 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 + 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 - -+ 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; -+ eqcr->cmode = cmode; -+#endif -+ cfg = (qm_in(CFG) & 0x00ffffff) | -+ ((pmode & 0x3) << 24); /* QCSP_CFG::EPM */ -+ qm_out(CFG, cfg); -+ return 0; -+} -+ -+static inline void qm_eqcr_finish(struct qm_portal *portal) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ u8 pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1); -+ u8 ci = qm_in(EQCR_CI_CINH) & (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(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 -+ dcbz_64(eqcr->cursor); -+ 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--; -+ dcbz_64(eqcr->cursor); -+ return eqcr->cursor; -+} -+ -+#define EQCR_COMMIT_CHECKS(eqcr) \ -+do { \ -+ DPA_ASSERT(eqcr->busy); \ -+ DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & 0x00ffffff)); \ -+ DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & 0x00ffffff)); \ -+} while(0) -+ -+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; -+ DPA_ASSERT(eqcr->cmode == qm_eqcr_cci); -+ eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1); -+ diff = 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; -+ DPA_ASSERT(eqcr->cmode == qm_eqcr_cce); -+ 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; -+ DPA_ASSERT(eqcr->cmode == qm_eqcr_cce); -+ eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1); -+ qm_cl_invalidate(EQCR_CI); -+ diff = 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 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 + 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 = 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); -+#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 = 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 = 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); -+ /* 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(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_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(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_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 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 */ -+} -+ -+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); -+} -+ -+#ifdef CONFIG_FSL_QMAN_BUG_AND_FEATURE_REV1 -+static inline void __mr_copy_and_fixup(struct qm_portal *p, u8 idx) -+{ -+ if (qman_ip_rev == QMAN_REV10) { -+ struct qm_mr_entry *shadow = qm_cl(p->bugs.mr, idx); -+ struct qm_mr_entry *res = qm_cl(p->mr.ring, idx); -+ copy_words(shadow, res, sizeof(*res)); -+ /* Bypass the QM_MR_RC_*** definitions, and check the byte value -+ * directly to handle the erratum. */ -+ if (shadow->ern.rc == 0x06) -+ shadow->ern.rc = 0x60; -+ } -+} -+#else -+#define __mr_copy_and_fixup(p, idx) do { ; } while (0) -+#endif -+ -+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; -+ int loop; -+ -+#ifdef CONFIG_FSL_QMAN_BUG_AND_FEATURE_REV1 -+ if ((qman_ip_rev == QMAN_REV10) && (pmode != qm_mr_pvb)) { -+ pr_err("Qman is rev1, so QMAN9 workaround requires 'pvb'\n"); -+ return -EINVAL; -+ } -+#endif -+ mr->ring = portal->addr.addr_ce + CL_MR; -+ mr->pi = qm_in(MR_PI_CINH) & (QM_MR_SIZE - 1); -+ mr->ci = qm_in(MR_CI_CINH) & (QM_MR_SIZE - 1); -+#ifdef CONFIG_FSL_QMAN_BUG_AND_FEATURE_REV1 -+ if (qman_ip_rev == QMAN_REV10) -+ /* Situate the cursor in the shadow ring */ -+ mr->cursor = portal->bugs.mr + mr->ci; -+ else -+#endif -+ mr->cursor = mr->ring + mr->ci; -+ mr->fill = 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 -+ /* Only new entries get the copy-and-fixup treatment from -+ * qm_mr_pvb_update(), so perform it here for any stale entries. */ -+ for (loop = 0; loop < mr->fill; loop++) -+ __mr_copy_and_fixup(portal, (mr->ci + loop) & (QM_MR_SIZE - 1)); -+ 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 = 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 = 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_copy_and_fixup(portal, mr->pi); -+ 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 + CL_CR; -+ mc->rr = portal->addr.addr_ce + 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 = 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 == mc_idle); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ if (mc->state != 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 == mc_idle); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = mc_user; -+#endif -+ dcbz_64(mc->cr); -+ 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 == mc_user); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = 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 == mc_user); -+ lwsync(); -+#ifdef CONFIG_FSL_QMAN_BUG_AND_FEATURE_REV1 -+ if ((qman_ip_rev == QMAN_REV10) && ((myverb & QM_MCC_VERB_MASK) == -+ QM_MCC_VERB_INITFQ_SCHED)) { -+ u32 fqid = mc->cr->initfq.fqid; -+ /* Do two commands to avoid the hw bug. Note, we poll locally -+ * rather than using qm_mc_result() because from a DPA_CHECKING -+ * perspective, we don't want to appear to have "finished" until -+ * both commands are done. */ -+ mc->cr->__dont_write_directly__verb = mc->vbit | -+ QM_MCC_VERB_INITFQ_PARKED; -+ dcbf(mc->cr); -+ portal->bugs.initfq_and_sched = 1; -+ do { -+ dcbit_ro(rr); -+ } while (!__raw_readb(&rr->verb)); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = mc_idle; -+#endif -+ if (rr->result != QM_MCR_RESULT_OK) { -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = mc_hw; -+#endif -+ return; -+ } -+ mc->rridx ^= 1; -+ mc->vbit ^= QM_MCC_VERB_VBIT; -+ rr = mc->rr + mc->rridx; -+ dcbz_64(mc->cr); -+ mc->cr->alterfq.fqid = fqid; -+ lwsync(); -+ myverb = QM_MCC_VERB_ALTER_SCHED; -+ } else -+ portal->bugs.initfq_and_sched = 0; -+#endif -+ 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 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 == 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; -+ } -+#ifdef CONFIG_FSL_QMAN_BUG_AND_FEATURE_REV1 -+ if (qman_ip_rev == QMAN_REV10) { -+ if ((__raw_readb(&rr->verb) & QM_MCR_VERB_MASK) == -+ QM_MCR_VERB_QUERYFQ) { -+ void *misplaced = (void *)rr + 50; -+ copy_words(&portal->bugs.result, rr, sizeof(*rr)); -+ rr = &portal->bugs.result; -+ copy_shorts(&rr->queryfq.fqd.td, misplaced, -+ sizeof(rr->queryfq.fqd.td)); -+ } else if (portal->bugs.initfq_and_sched) { -+ /* We split the user-requested command, make the final -+ * result match the requested type. */ -+ copy_words(&portal->bugs.result, rr, sizeof(*rr)); -+ rr = &portal->bugs.result; -+ rr->verb = (rr->verb & QM_MCR_VERB_RRID) | -+ QM_MCR_VERB_INITFQ_SCHED; -+ } -+ } -+#endif -+ mc->rridx ^= 1; -+ mc->vbit ^= QM_MCC_VERB_VBIT; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = 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) -+{ -+ return __qm_in(&portal->addr, REG_ISR + (n << 2)); -+} -+ -+static inline void __qm_isr_write(struct qm_portal *portal, enum qm_isr_reg n, -+ u32 val) -+{ -+ __qm_out(&portal->addr, REG_ISR + (n << 2), val); -+} -diff --git a/drivers/staging/fsl_qbman/qman_private.h b/drivers/staging/fsl_qbman/qman_private.h -new file mode 100644 -index 0000000..e43a41a ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_private.h -@@ -0,0 +1,300 @@ -+/* 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 -+ -+#if !defined(CONFIG_FSL_QMAN_FQ_LOOKUP) && defined(CONFIG_PPC64) -+#error "_PPC64 requires _FSL_QMAN_FQ_LOOKUP" -+#endif -+ -+ /* ----------------- */ -+ /* 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) -+{ -+ memcpy(dest, src, sizeof(*dest)); -+} -+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++); -+} -+ -+#define qman_cgrs_for_each_1(cgr, cgrs) \ -+ for ((cgr) = -1; (cgr) = qman_cgrs_next((cgrs), (cgr)),\ -+ (cgr) < __CGR_NUM;) -+ -+/* 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_node *node; -+ /* Allow these to be joined in lists */ -+ struct list_head list; -+ /* User-visible portal configuration settings */ -+ struct qman_portal_config public_cfg; -+}; -+ -+/* Revision info (for errata and feature handling) */ -+#define QMAN_REV10 0x0100 -+#define QMAN_REV11 0x0101 -+#define QMAN_REV12 0x0102 -+#define QMAN_REV20 0x0200 -+#define QMAN_REV30 0x0300 -+extern u16 qman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */ -+extern u32 qman_clk; -+ -+#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); -+#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_affine_portal( -+ const struct qm_portal_config *config, -+ const struct qman_cgrs *cgrs); -+struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect); -+const struct qm_portal_config *qman_destroy_affine_portal(void); -+ -+/* 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 -+#if 0 /* These are defined in the external fsl_qman.h API */ -+#define QM_SDQCR_CHANNELS_POOL_MASK 0x00007fff -+#define QM_SDQCR_CHANNELS_POOL(n) (0x00008000 >> (n)) -+#endif -+#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(); 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. */ -+#if 0 /* These are defined in the external fsl_qman.h API */ -+#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) -+#endif -+#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'. NB, some of these -+ * definitions are exported for use by the qman_irqsource_***() APIs, so are -+ * commented-out here. */ -+#define QM_PIRQ_DQAVAIL 0x0000ffff /* Channels with frame availability */ -+#if 0 -+#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) -+#endif -+/* 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) -+ -+/* CEETM related */ -+#define QMAN_CEETM_MAX 2 -+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); -diff --git a/drivers/staging/fsl_qbman/qman_test.c b/drivers/staging/fsl_qbman/qman_test.c -new file mode 100644 -index 0000000..ea39449 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_test.c -@@ -0,0 +1,60 @@ -+/* 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 -+#ifdef CONFIG_FSL_QMAN_TEST_ERRATA -+ qman_test_errata(); -+#endif -+ } -+ return 0; -+} -+ -+static void test_exit(void) -+{ -+} -+ -+module_init(test_init); -+module_exit(test_exit); -diff --git a/drivers/staging/fsl_qbman/qman_test.h b/drivers/staging/fsl_qbman/qman_test.h -new file mode 100644 -index 0000000..082d9f2 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_test.h -@@ -0,0 +1,84 @@ -+/* 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 -+ -+void qman_test_hotpotato(void); -+void qman_test_high(void); -+void qman_test_errata(void); -+void qman_test_fqrange(void); -+ -+static inline void __hexdump(unsigned long start, unsigned long end, -+ unsigned long p, size_t sz, const unsigned char *c) -+{ -+ while (start < end) { -+ unsigned int pos = 0; -+ char buf[64]; -+ int nl = 0; -+ pos += sprintf(buf + pos, "%08lx: ", start); -+ do { -+ if ((start < p) || (start >= (p + sz))) -+ pos += sprintf(buf + pos, ".."); -+ else -+ pos += sprintf(buf + pos, "%02x", *(c++)); -+ if (!(++start & 15)) { -+ buf[pos++] = '\n'; -+ nl = 1; -+ } else { -+ nl = 0; -+ if(!(start & 1)) -+ buf[pos++] = ' '; -+ if(!(start & 3)) -+ buf[pos++] = ' '; -+ } -+ } while (start & 15); -+ if (!nl) -+ buf[pos++] = '\n'; -+ buf[pos] = '\0'; -+ pr_info("%s", buf); -+ } -+} -+static inline void hexdump(const void *ptr, size_t sz) -+{ -+ unsigned long p = (unsigned long)ptr; -+ unsigned long start = p & ~(unsigned long)15; -+ unsigned long end = (p + sz + 15) & ~(unsigned long)15; -+ const unsigned char *c = ptr; -+ __hexdump(start, end, p, sz, c); -+} -diff --git a/drivers/staging/fsl_qbman/qman_test_errata.c b/drivers/staging/fsl_qbman/qman_test_errata.c -new file mode 100644 -index 0000000..0f44cad ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_test_errata.c -@@ -0,0 +1,247 @@ -+/* Copyright 2009-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" -+ -+/* Waiting on a model fix from virtutech */ -+#if 0 -+/*********************/ -+/* generic utilities */ -+/*********************/ -+ -+static int do_enqueues(struct qman_fq *fq, const struct qm_fd *fds, int num) -+{ -+ int ret = 0; -+ u32 flags = QMAN_ENQUEUE_FLAG_WAIT; -+ while (num-- && !ret) { -+ if (!num) -+ flags |= QMAN_ENQUEUE_FLAG_WAIT_SYNC; -+ pr_info("about to enqueue\n"); -+ ret = qman_enqueue(fq, fds++, flags); -+ } -+ return ret; -+} -+ -+/***************************/ -+/* "tdthresh" test (QMAN6) */ -+/***************************/ -+ -+/* First thresh == 201 * (2^21) == 421527552 (0x19200000) */ -+#define THRESH_MANT 201 -+#define THRESH_EXP 21 -+ -+/* first three equal thresh, fourth takes us over */ -+static const struct qm_fd td_eq[] = { -+ QM_FD_FMT_20(0, 0x34, 0x87654321, QM_FD_SG, 0, 79321), -+ QM_FD_FMT_29(0, 0x34, 0x87654321, QM_FD_COMPOUND, 29923679), -+ QM_FD_FMT_29(0, 0x0d, 0xacadabba, QM_FD_CONTIG_BIG, 391524552), -+ QM_FD_FMT_20(0, 0x0b, 0x0fa10ada, QM_FD_CONTIG, 0, 1), -+ QM_FD_FMT_20(0, 0x0b, 0x0fa10ada, QM_FD_CONTIG, 0, 1), -+}; -+ -+struct tdthresh_fq { -+ struct qman_fq fq; -+ int got_ern; -+ int num_dqrr; -+}; -+ -+static enum qman_cb_dqrr_result cb_dqrr_tdthresh(struct qman_portal *p, -+ struct qman_fq *__fq, -+ const struct qm_dqrr_entry *dqrr) -+{ -+ struct tdthresh_fq *t = (void *)__fq; -+ t->num_dqrr++; -+ return qman_cb_dqrr_consume; -+} -+ -+static void cb_ern_tdthresh(struct qman_portal *p, struct qman_fq *__fq, -+ const struct qm_mr_entry *mr) -+{ -+ struct tdthresh_fq *t = (void *)__fq; -+ t->got_ern = 1; -+} -+ -+static void test_tdthresh(void) -+{ -+ struct tdthresh_fq tdfq = { -+ .fq = { -+ .cb = { -+ .dqrr = cb_dqrr_tdthresh, -+ .ern = cb_ern_tdthresh -+ } -+ }, -+ .got_ern = 0, -+ .num_dqrr = 0 -+ }; -+ struct qman_fq *fq = &tdfq.fq; -+ struct qm_mcc_initfq opts = { -+ .we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_TDTHRESH, -+ .fqd = { -+ .fq_ctrl = QM_FQCTRL_TDE, -+ .td = { -+ .exp = THRESH_EXP, -+ .mant = THRESH_MANT, -+ } -+ } -+ }; -+ struct qm_fqd fqd; -+ u32 flags; -+ int ret = qman_create_fq(0, QMAN_FQ_FLAG_DYNAMIC_FQID, fq); -+ BUG_ON(ret); -+ /* leave it parked, and set it for local dequeue (loopback) */ -+ ret = qman_init_fq(fq, QMAN_INITFQ_FLAG_LOCAL, &opts); -+ BUG_ON(ret); -+ /* query it back and confirm everything is ok */ -+ ret = qman_query_fq(fq, &fqd); -+ BUG_ON(ret); -+ if (fqd.fq_ctrl != opts.fqd.fq_ctrl) { -+ pr_err("queried fq_ctrl=%x, should be=%x\n", fqd.fq_ctrl, -+ opts.fqd.fq_ctrl); -+ panic("fail"); -+ } -+ if (memcmp(&fqd.td, &opts.fqd.td, sizeof(fqd.td))) { -+ pr_err("queried td_thresh=%x:%x, should be=%x:%x\n", -+ fqd.td.exp, fqd.td.mant, -+ opts.fqd.td.exp, opts.fqd.td.mant); -+ panic("fail"); -+ } -+ ret = do_enqueues(fq, td_eq, 3); -+ BUG_ON(ret); -+ pr_info(" tdthresh: eq[0..2] complete\n"); -+ /* enqueues are flushed, so if Qman is going to throw an ERN, the irq -+ * assertion will already be on its way. */ -+ msleep(500); -+ BUG_ON(tdfq.got_ern); -+ pr_info(" tdthresh: eq <= thresh OK\n"); -+ ret = do_enqueues(fq, td_eq + 3, 1); -+ BUG_ON(ret); -+ pr_info(" tdthresh: eq[3] complete\n"); -+ /* enqueues are flushed, so if Qman is going to throw an ERN, the irq -+ * assertion will already be on its way. */ -+ msleep(500); -+ BUG_ON(tdfq.got_ern); -+ pr_info(" tdthresh: eq <= thresh OK\n"); -+ ret = do_enqueues(fq, td_eq + 4, 1); -+ BUG_ON(ret); -+ pr_info(" tdthresh: eq[4] complete\n"); -+ /* enqueues are flushed, so if Qman is going to throw an ERN, the irq -+ * assertion will already be on its way. */ -+ msleep(500); -+ BUG_ON(!tdfq.got_ern); -+ pr_info(" tdthresh: eq > thresh OK\n"); -+ ret = qman_volatile_dequeue(fq, -+ QMAN_VOLATILE_FLAG_WAIT | QMAN_VOLATILE_FLAG_FINISH, -+ QM_VDQCR_NUMFRAMES_TILLEMPTY); -+ BUG_ON(ret); -+ BUG_ON(tdfq.num_dqrr != 4); -+ ret = qman_retire_fq(fq, &flags); -+ BUG_ON(ret); -+ BUG_ON(flags); -+ ret = qman_oos_fq(fq); -+ BUG_ON(ret); -+} -+ -+/****************************/ -+/* "ern code6" test (QMAN9) */ -+/****************************/ -+ -+/* Dummy FD to enqueue out-of-sequence and generate an ERN */ -+static const struct qm_fd c6_eq = -+ QM_FD_FMT_29(0, 0xba, 0xdeadbeef, QM_FD_CONTIG_BIG, 1234); -+ -+struct code6_fq { -+ struct qman_fq fq; -+ struct qm_mr_entry mr; -+ struct completion got_ern; -+}; -+ -+static void cb_ern_code6(struct qman_portal *p, struct qman_fq *__fq, -+ const struct qm_mr_entry *mr) -+{ -+ struct code6_fq *c = (void *)__fq; -+ memcpy(&c->mr, mr, sizeof(*mr)); -+ complete(&c->got_ern); -+} -+ -+static void test_ern_code6(void) -+{ -+ struct code6_fq c6fq = { -+ .fq = { -+ .cb = { -+ .ern = cb_ern_code6 -+ } -+ }, -+ .got_ern = COMPLETION_INITIALIZER(c6fq.got_ern) -+ }; -+ struct qman_fq *fq = &c6fq.fq; -+ struct qm_mcc_initfq opts = { -+ .we_mask = QM_INITFQ_WE_FQCTRL, -+ .fqd = { -+ .fq_ctrl = QM_FQCTRL_ORP -+ } -+ }; -+ u32 flags; -+ int ret = qman_create_fq(0, QMAN_FQ_FLAG_DYNAMIC_FQID, fq); -+ BUG_ON(ret); -+ /* leave it parked, and set it for local dequeue (loopback) */ -+ ret = qman_init_fq(fq, QMAN_INITFQ_FLAG_LOCAL, &opts); -+ BUG_ON(ret); -+ /* enqueue with ORP using a "too early" sequence number */ -+ ret = qman_enqueue_orp(fq, &c6_eq, -+ QMAN_ENQUEUE_FLAG_WAIT | QMAN_ENQUEUE_FLAG_WAIT_SYNC, fq, 5); -+ BUG_ON(ret); -+ pr_info(" code6: eq complete\n"); -+ ret = qman_retire_fq(fq, &flags); -+ BUG_ON(ret); -+ pr_info(" code6: retire complete, flags=%08x\n", flags); -+ BUG_ON(flags != QMAN_FQ_STATE_ORL); -+ wait_for_completion(&c6fq.got_ern); -+ pr_info(" code6: ERN, VERB=0x%02x, RC==0x%02x\n", -+ c6fq.mr.verb, c6fq.mr.ern.rc); -+ BUG_ON(c6fq.mr.verb & 0x20); -+ BUG_ON((c6fq.mr.ern.rc & QM_MR_RC_MASK) != QM_MR_RC_ORPWINDOW_RETIRED); -+ ret = qman_oos_fq(fq); -+ BUG_ON(ret); -+} -+ -+void qman_test_errata(void) -+{ -+ pr_info("Testing Qman errata handling ...\n"); -+ test_tdthresh(); -+ test_ern_code6(); -+ pr_info(" ... SUCCESS!\n"); -+} -+#else -+void qman_test_errata(void) -+{ -+ pr_info("Qman errata-handling test disabled, waiting on model fix\n"); -+} -+#endif -diff --git a/drivers/staging/fsl_qbman/qman_test_high.c b/drivers/staging/fsl_qbman/qman_test_high.c -new file mode 100644 -index 0000000..cba6c25 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_test_high.c -@@ -0,0 +1,212 @@ -+/* 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) -+{ -+ int flags, 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"); -+ 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); -+} -diff --git a/drivers/staging/fsl_qbman/qman_test_hotpotato.c b/drivers/staging/fsl_qbman/qman_test_hotpotato.c -new file mode 100644 -index 0000000..91e01d7 ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_test_hotpotato.c -@@ -0,0 +1,497 @@ -+/* 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 occuring.) -+ * -+ * 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) -+ 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); -+ } -+} -+ -+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); -+ } -+} -+ -+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"); -+} -diff --git a/drivers/staging/fsl_qbman/qman_utility.c b/drivers/staging/fsl_qbman/qman_utility.c -new file mode 100644 -index 0000000..fa2f40b ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_utility.c -@@ -0,0 +1,130 @@ -+/* 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 = kmalloc(QNUM_BYTES(num), GFP_KERNEL); -+ if (!pool->bits) { -+ kfree(pool); -+ return NULL; -+ } -+ memset(pool->bits, 0, QNUM_BYTES(num)); -+ /* 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); -diff --git a/drivers/staging/fsl_rman/Kconfig b/drivers/staging/fsl_rman/Kconfig -new file mode 100644 -index 0000000..ee34e03 ---- /dev/null -+++ b/drivers/staging/fsl_rman/Kconfig -@@ -0,0 +1,4 @@ -+config FSL_RMAN_UIO -+ bool "Freescale RapidIO Message Manager support" -+ depends on FSL_DPA && UIO -+ default y -diff --git a/drivers/staging/fsl_rman/Makefile b/drivers/staging/fsl_rman/Makefile -new file mode 100644 -index 0000000..f712470 ---- /dev/null -+++ b/drivers/staging/fsl_rman/Makefile -@@ -0,0 +1,2 @@ -+# Rman -+obj-$(CONFIG_FSL_RMAN_UIO) += rman_uio_driver.o -diff --git a/drivers/staging/fsl_rman/rman_uio_driver.c b/drivers/staging/fsl_rman/rman_uio_driver.c -new file mode 100644 -index 0000000..e5bfae7 ---- /dev/null -+++ b/drivers/staging/fsl_rman/rman_uio_driver.c -@@ -0,0 +1,345 @@ -+/* -+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. -+ * -+ * Author: Minghuan Lian -+ * -+ * 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., -+ * 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static const char rman_uio_version[] = "Rman UIO driver v1.0"; -+ -+#define IB_INDEX_OFFSET 12 -+#define MMIER 0x0420 /* Message manage Interrupt Enable Register*/ -+#define MMEDR 0x0424 /* Message manager error detect register */ -+#define MMEDR_CLEAR 0x800000FF -+ -+struct rman_uio_info { -+ atomic_t ref; /* exclusive, only one open() at a time */ -+ struct uio_info uio; -+ char name[30]; -+}; -+ -+struct rman_dev { -+ u32 revision; -+ int irq; -+ void __iomem *global_regs; -+ struct device *dev; -+ struct rman_uio_info info; -+ struct resource *res; -+ struct list_head ib_list; -+}; -+ -+struct rman_inbound_block { -+ struct list_head node; -+ u32 index; -+ struct device *dev; -+ struct rman_uio_info info; -+ struct resource *res; -+}; -+ -+static int rman_uio_open(struct uio_info *info, struct inode *inode) -+{ -+ struct rman_uio_info *i = container_of(info, struct rman_uio_info, uio); -+ if (!atomic_dec_and_test(&i->ref)) { -+ pr_err("%s: failing non-exclusive open()\n", i->name); -+ atomic_inc(&i->ref); -+ return -EBUSY; -+ } -+ return 0; -+} -+ -+static int rman_uio_release(struct uio_info *info, struct inode *inode) -+{ -+ struct rman_uio_info *i = container_of(info, struct rman_uio_info, uio); -+ atomic_inc(&i->ref); -+ return 0; -+} -+ -+static irqreturn_t rman_uio_irq_handler(int irq, struct uio_info *dev_info) -+{ -+ struct rman_dev *rmdev = dev_info->priv; -+ u32 status; -+ -+ status = in_be32(rmdev->global_regs + MMEDR); -+ -+ if (status) { -+ /* disable interrupt */ -+ out_be32(rmdev->global_regs + MMIER, 0); -+ return IRQ_HANDLED; -+ } else -+ return IRQ_NONE; -+} -+ -+static int __init rman_uio_init(struct rman_dev *rmdev) -+{ -+ int ret; -+ struct rman_uio_info *info; -+ -+ info = &rmdev->info; -+ atomic_set(&info->ref, 1); -+ info->uio.name = info->name; -+ info->uio.version = rman_uio_version; -+ info->uio.mem[0].name = "rman regs"; -+ info->uio.mem[0].addr = rmdev->res->start; -+ info->uio.mem[0].size = rmdev->res->end - rmdev->res->start + 1; -+ info->uio.mem[0].internal_addr = rmdev->global_regs; -+ info->uio.mem[0].memtype = UIO_MEM_PHYS; -+ info->uio.irq = rmdev->irq; -+ info->uio.irq_flags = IRQF_SHARED; -+ info->uio.handler = rman_uio_irq_handler; -+ info->uio.open = rman_uio_open; -+ info->uio.release = rman_uio_release; -+ info->uio.priv = rmdev; -+ ret = uio_register_device(rmdev->dev, &info->uio); -+ if (ret) { -+ pr_err("rman_uio: UIO registration failed\n"); -+ return ret; -+ } -+ return 0; -+} -+ -+static int __init rman_ib_uio_init(struct rman_inbound_block *ib) -+{ -+ int ret; -+ struct rman_uio_info *info; -+ -+ info = &ib->info; -+ atomic_set(&info->ref, 1); -+ info->uio.name = info->name; -+ info->uio.version = rman_uio_version; -+ info->uio.mem[0].name = "rman inbound block regs"; -+ info->uio.mem[0].addr = ib->res->start; -+ info->uio.mem[0].size = ib->res->end - ib->res->start + 1; -+ info->uio.mem[0].memtype = UIO_MEM_PHYS; -+ info->uio.open = rman_uio_open; -+ info->uio.release = rman_uio_release; -+ info->uio.priv = ib; -+ ret = uio_register_device(ib->dev, &info->uio); -+ if (ret) { -+ pr_err("rman_ib_uio: UIO registration failed\n"); -+ return ret; -+ } -+ return 0; -+} -+ -+static int fsl_rman_ib_probe(struct device_node *ib_node, -+ struct rman_dev *rmdev) -+{ -+ struct rman_inbound_block *ib; -+ struct resource regs; -+ int err; -+ -+ if (!ib_node || !rmdev) -+ return -EINVAL; -+ -+ ib = kzalloc(sizeof(*ib), GFP_KERNEL); -+ if (!ib) { -+ dev_err(rmdev->dev, "Can't alloc memory for inbound_block\n"); -+ return -ENOMEM; -+ } -+ -+ ib->dev = rmdev->dev; -+ -+ err = of_address_to_resource(ib_node, 0, ®s); -+ if (unlikely(err < 0)) { -+ dev_err(ib->dev, "Can't get property 'reg'\n"); -+ err = -EFAULT; -+ goto _err; -+ } -+ -+ ib->index = (regs.start >> IB_INDEX_OFFSET) & 0xf; -+ snprintf(ib->info.name, sizeof(ib->info.name)-1, -+ "rman-inbound-block%d", ib->index); -+ -+ ib->res = devm_request_mem_region(rmdev->dev, regs.start, -+ regs.end + 1 - regs.start, -+ ib->info.name); -+ if (unlikely(!ib->res)) { -+ dev_err(ib->dev, "devm_request_mem_region failed\n"); -+ err = -ENOMEM; -+ goto _err; -+ } -+ dev_dbg(ib->dev, -+ "inbound block%d reg start 0x%016llx, size 0x%016llx.\n", -+ ib->index, ib->res->start, -+ ib->res->end + 1 - ib->res->start); -+ -+ err = rman_ib_uio_init(ib); -+ if (err) -+ goto _err; -+ -+ list_add(&ib->node, &rmdev->ib_list); -+ dev_info(ib->dev, "RMan inbound block%d initialized.\n", ib->index); -+ return 0; -+_err: -+ kfree(ib); -+ return err; -+} -+ -+static int fsl_rman_ib_remove(struct rman_inbound_block *ib) -+{ -+ if (!ib) -+ return 0; -+ uio_unregister_device(&ib->info.uio); -+ kfree(ib); -+ return 0; -+} -+ -+static int __devinit fsl_rman_probe(struct platform_device *dev) -+{ -+ struct resource regs; -+ struct rman_dev *rman_dev; -+ struct device_node *rman_node, *child; -+ struct rman_inbound_block *ib, *tmp; -+ int err; -+ -+ rman_node = dev->dev.of_node; -+ if (!rman_node) { -+ dev_err(&dev->dev, "Device OF-Node is NULL"); -+ return -EFAULT; -+ } -+ dev_info(&dev->dev, "Of-device full name %s initialized\n", -+ rman_node->full_name); -+ -+ rman_dev = kzalloc(sizeof(struct rman_dev), GFP_KERNEL); -+ if (!rman_dev) { -+ dev_err(&dev->dev, "Can't allocate memory for 'rman_dev'\n"); -+ return -ENOMEM; -+ } -+ -+ rman_dev->dev = &dev->dev; -+ INIT_LIST_HEAD(&rman_dev->ib_list); -+ platform_set_drvdata(dev, rman_dev); -+ -+ for_each_child_of_node(rman_node, child) { -+ if (of_device_is_compatible(child, "fsl,rman-inbound-block")) -+ fsl_rman_ib_probe(child, rman_dev); -+ -+ if (of_device_is_compatible(child, "fsl,rman-global-cfg")) { -+ err = of_address_to_resource(child, 0, ®s); -+ if (unlikely(err < 0)) { -+ dev_err(&dev->dev, -+ "Can't get property 'reg'\n"); -+ err = -EFAULT; -+ goto _err; -+ } -+ } -+ } -+ -+ snprintf(rman_dev->info.name, sizeof(rman_dev->info.name)-1, -+ "rman-uio"); -+ rman_dev->res = devm_request_mem_region(&dev->dev, regs.start, -+ regs.end + 1 - regs.start, -+ rman_dev->info.name); -+ dev_dbg(&dev->dev, "global regs start 0x%016llx, size 0x%016llx.\n", -+ rman_dev->res->start, -+ rman_dev->res->end + 1 - rman_dev->res->start); -+ if (unlikely(rman_dev->res == NULL)) { -+ dev_err(&dev->dev, "devm_request_mem_region failed\n"); -+ err = -ENOMEM; -+ goto _err; -+ } -+ -+ rman_dev->global_regs = devm_ioremap(&dev->dev, rman_dev->res->start, -+ rman_dev->res->end - rman_dev->res->start + 1); -+ if (unlikely(rman_dev->global_regs == 0)) { -+ dev_err(&dev->dev, "devm_ioremap failed\n"); -+ err = -EIO; -+ goto _err; -+ } -+ -+ rman_dev->irq = irq_of_parse_and_map(rman_node, 0); -+ dev_dbg(rman_dev->dev, "errirq: %d\n", rman_dev->irq); -+ -+ err = rman_uio_init(rman_dev); -+ if (err) -+ goto _err; -+ return 0; -+ -+_err: -+ platform_set_drvdata(dev, NULL); -+ list_for_each_entry_safe(ib, tmp, &rman_dev->ib_list, node) { -+ list_del(&ib->node); -+ fsl_rman_ib_remove(ib); -+ } -+ kfree(rman_dev); -+ return err; -+} -+ -+static int __devexit fsl_rman_remove(struct platform_device *dev) -+{ -+ struct rman_dev *rman_dev = platform_get_drvdata(dev); -+ struct rman_inbound_block *ib, *tmp; -+ -+ if (!rman_dev) -+ return 0; -+ -+ list_for_each_entry_safe(ib, tmp, &rman_dev->ib_list, node) { -+ list_del(&ib->node); -+ fsl_rman_ib_remove(ib); -+ } -+ -+ uio_unregister_device(&rman_dev->info.uio); -+ platform_set_drvdata(dev, NULL); -+ kfree(rman_dev); -+ return 0; -+} -+ -+static const struct of_device_id fsl_of_rman_match[] = { -+ { -+ .compatible = "fsl,rman", -+ }, -+ {} -+}; -+ -+static struct platform_driver fsl_rman_driver = { -+ .driver = { -+ .name = "fsl-of-rman", -+ .owner = THIS_MODULE, -+ .of_match_table = fsl_of_rman_match, -+ }, -+ .probe = fsl_rman_probe, -+ .remove = __devexit_p(fsl_rman_remove), -+}; -+ -+static __init int fsl_rman_init(void) -+{ -+ int err; -+ -+ err = platform_driver_register(&fsl_rman_driver); -+ if (unlikely(err < 0)) -+ pr_warning( -+ ": %s:%hu:%s(): platform_driver_register() = %d\n", -+ __FILE__, __LINE__, __func__, err); -+ -+ return err; -+} -+ -+static void __exit fsl_rman_exit(void) -+{ -+ platform_driver_unregister(&fsl_rman_driver); -+} -+ -+module_init(fsl_rman_init); -+module_exit(fsl_rman_exit); -+MODULE_LICENSE("GPL"); -diff --git a/include/linux/Kbuild b/include/linux/Kbuild -index 2f89d0e..69c95b0 100644 ---- a/include/linux/Kbuild -+++ b/include/linux/Kbuild -@@ -2,6 +2,7 @@ header-y += byteorder/ - header-y += can/ - header-y += caif/ - header-y += dvb/ -+header-y += fmd/ - header-y += hdlc/ - header-y += isdn/ - header-y += mmc/ -diff --git a/include/linux/fmd/Kbuild b/include/linux/fmd/Kbuild -new file mode 100644 -index 0000000..56a2040 ---- /dev/null -+++ b/include/linux/fmd/Kbuild -@@ -0,0 +1,5 @@ -+header-y += integrations/ -+header-y += Peripherals/ -+ -+header-y += ioctls.h -+header-y += net_ioctls.h -diff --git a/include/linux/fmd/Peripherals/Kbuild b/include/linux/fmd/Peripherals/Kbuild -new file mode 100644 -index 0000000..43883ef ---- /dev/null -+++ b/include/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 -diff --git a/include/linux/fmd/Peripherals/fm_ioctls.h b/include/linux/fmd/Peripherals/fm_ioctls.h -new file mode 100644 -index 0000000..6008303 ---- /dev/null -+++ b/include/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 */ -+ } portParams; -+ 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[1]; -+} 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 19 -+#define FMD_API_VERSION_MINOR 0 -+#define FMD_API_VERSION_RESPIN 0 -+ -+#endif /* __FM_IOCTLS_H */ -diff --git a/include/linux/fmd/Peripherals/fm_pcd_ioctls.h b/include/linux/fmd/Peripherals/fm_pcd_ioctls.h -new file mode 100644 -index 0000000..0123b17 ---- /dev/null -+++ b/include/linux/fmd/Peripherals/fm_pcd_ioctls.h -@@ -0,0 +1,2708 @@ -+/* 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_PRS_SW_OFFSET 0x00000040 /**< Size of illegal addresses at the beginning -+ of the SW parser area */ -+#if DPAA_VERSION >= 11 -+#define IOC_FM_PCD_PRS_SW_PATCHES_SIZE 0x00000240 /**< Number of bytes saved for patches */ -+#else -+#define IOC_FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 /**< Number of bytes saved for patches */ -+#endif -+ -+#define IOC_FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at -+ the end of the SW parser area */ -+#define IOC_FM_SW_PRS_MAX_IMAGE_SIZE (IOC_FM_PCD_SW_PRS_SIZE-IOC_FM_PCD_PRS_SW_OFFSET-IOC_FM_PCD_PRS_SW_TAIL_SIZE-IOC_FM_PCD_PRS_SW_PATCHES_SIZE) -+ /**< Maximum size of SW parser code */ -+ -+#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) -+ -+#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 */ -+ -+/* @} */ -+ -+#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 */ -+#ifdef FM_CAPWAP_SUPPORT -+ 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; -+ -+/**************************************************************************//** -+ @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 */ -+} 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 */ -+#ifdef FM_CAPWAP_SUPPORT -+ e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */ -+#endif /* 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; -+ -+#ifdef FM_CAPWAP_SUPPORT -+/**************************************************************************//** -+ @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 */ -+ e_IOC_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics */ -+} 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 */ -+} 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 */ -+} 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_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 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 -+*//***************************************************************************/ -+#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 */ -+#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. */ -+ 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 comitted_info_rate; /**< KBits/Sec or Packets/Sec */ -+ uint32_t comitted_burst_size; /**< KBits or Packets */ -+ uint32_t peak_or_accessive_info_rate; /**< KBits/Sec or Packets/Sec */ -+ uint32_t peak_or_accessive_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; -+ -+#ifdef FM_CAPWAP_SUPPORT -+/**************************************************************************//** -+ @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; -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+/**************************************************************************//** -+ @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 { -+#ifdef 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 */ -+ 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. */ -+} ioc_fm_pcd_manip_special_offload_ipsec_params_t; -+ -+/**************************************************************************//** -+ @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 */ -+ } 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 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; -+ -+/**************************************************************************//** -+ @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 */ -+ } 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 */ -+#ifdef FM_CAPWAP_SUPPORT -+ 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 { -+ 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 { -+ 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. */ -+#ifdef FM_CAPWAP_SUPPORT -+#error "FM_CAPWAP_SUPPORT feature not supported!" -+ 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 */ -+ 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; -+ -+/**************************************************************************//** -+ @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 */ -+ } 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 */ -+ } 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; -+ -+#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 */ -+ -+/**************************************************************************//** -+ @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_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 -+ -+#ifdef FM_CAPWAP_SUPPORT -+#warning "CAPWAP IOCTL not implemented" -+/**************************************************************************//** -+ @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 */ -diff --git a/include/linux/fmd/Peripherals/fm_port_ioctls.h b/include/linux/fmd/Peripherals/fm_port_ioctls.h -new file mode 100644 -index 0000000..8488845 ---- /dev/null -+++ b/include/linux/fmd/Peripherals/fm_port_ioctls.h -@@ -0,0 +1,921 @@ -+/* 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 */ -+#ifdef FM_CAPWAP_SUPPORT -+ , e_IOC_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */ -+ , 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; -+ -+/**************************************************************************//** -+ @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 */ -+} 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) -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdPrsModifyStartOffset -+ -+ @Description Runtime change of the parser start offset within the header. -+ -+ @Param[in] ioc_fm_pcd_prs_start_t A structure of parameters for defining the -+ start point for the parser. -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#define FM_PORT_IOC_PCD_PRS_MODIFY_START_OFFSET _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(32), ioc_fm_pcd_prs_start_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) */ -+ -+/** @} */ /* 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 */ -diff --git a/include/linux/fmd/Peripherals/fm_test_ioctls.h b/include/linux/fmd/Peripherals/fm_test_ioctls.h -new file mode 100644 -index 0000000..207ed1e ---- /dev/null -+++ b/include/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 */ -diff --git a/include/linux/fmd/integrations/Kbuild b/include/linux/fmd/integrations/Kbuild -new file mode 100644 -index 0000000..e548d67 ---- /dev/null -+++ b/include/linux/fmd/integrations/Kbuild -@@ -0,0 +1 @@ -+header-y += integration_ioctls.h -diff --git a/include/linux/fmd/integrations/integration_ioctls.h b/include/linux/fmd/integrations/integration_ioctls.h -new file mode 100644 -index 0000000..61d696e ---- /dev/null -+++ b/include/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 */ -diff --git a/include/linux/fmd/ioctls.h b/include/linux/fmd/ioctls.h -new file mode 100644 -index 0000000..4f36cb0 ---- /dev/null -+++ b/include/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__ */ -diff --git a/include/linux/fmd/net_ioctls.h b/include/linux/fmd/net_ioctls.h -new file mode 100644 -index 0000000..c99d64c ---- /dev/null -+++ b/include/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/include/linux/fsl_bman.h b/include/linux/fsl_bman.h -new file mode 100644 -index 0000000..072f326 ---- /dev/null -+++ b/include/linux/fsl_bman.h -@@ -0,0 +1,510 @@ -+/* 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 { -+ u8 __reserved1; -+ u8 bpid; -+ u16 hi; /* High 16-bits of 48-bit address */ -+ u32 lo; /* Low 32-bits of 48-bit address */ -+ }; -+ struct { -+ u64 __notaddress:16; -+ u64 addr:48; -+ }; -+ }; -+} __attribute__((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 */ -+/* Note: this first version is causing a noticable performance degradation, -+ * which needs analysis, so leaving it commented out for now. The second version -+ * achieves optimal performance. */ -+#if 0 -+#define bm_buffer_set64(buf, v) \ -+ do { \ -+ struct bm_buffer *__buf931 = (buf); \ -+ __buf931->addr = v; \ -+ } while (0) -+#else -+#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) -+#endif -+ -+/* 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 Reponse" */ -+/* See 1.5.3.4: "Query Reponse" */ -+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); -+} -+ -+ -+ /* 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. -+ */ -+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 occured. -+ * 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 -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* FSL_BMAN_H */ -diff --git a/include/linux/fsl_pme.h b/include/linux/fsl_pme.h -new file mode 100644 -index 0000000..1c8482f ---- /dev/null -+++ b/include/linux/fsl_pme.h -@@ -0,0 +1,798 @@ -+/* Copyright 2009-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 FSL_PME_H -+#define FSL_PME_H -+ -+/* pme_fd_res_status() returns this enum */ -+enum pme_status { -+ pme_status_ok = 0x00, -+ pme_status_kes_ccl = 0x40, /* KES Confidence Collision Limit */ -+ pme_status_kes_cme = 0x41, /* KES Confidence Mask Error */ -+ pme_status_dxe_ire = 0x48, /* DXE Invalid Repeat Error */ -+ pme_status_dxe_tlse = 0x49, /* DXE Test Line Syntax Error */ -+ pme_status_dxe_ile = 0x4b, /* DXE Instruction Limit Error */ -+ pme_status_dxe_pdsrsore = 0x4c, /* DXE PDSR Space Out Range Error */ -+ pme_status_dxe_soe = 0x4d, /* DXE Stack Overflow Error */ -+ pme_status_dxe_alse = 0x4e, /* DXE Alternate Link Same Error */ -+ pme_status_dxe_slse = 0x4f, /* DXE Subsequent Link Same Error */ -+ pme_status_dxe_slre = 0x50, /* DXE Subsequent Link Reverse Error */ -+ pme_status_dxe_itlb = 0x51, /* DXE Invalid Test Line Branch */ -+ pme_status_dxe_cle = 0x52, /* DXE Compare Limit Exceeded */ -+ pme_status_dxe_mle = 0x53, /* DXE Match Limit Exceeded */ -+ pme_status_sre_irhbni = 0x59, /* SRE Invalid Reaction Head Block */ -+ /* Number Instructions */ -+ pme_status_sre_rl = 0x5a, /* SRE Reaction Limit */ -+ pme_status_sre_pdsrsore = 0x5b, /* SRE PDSR Space Out Range Error */ -+ pme_status_sre_score = 0x5c, /* SRE Session Context Out Range Error */ -+ pme_status_sre_ctore = 0x5d, /* SRE Context Table Out Range Error */ -+ pme_status_sre_il = 0x5e, /* SRE Instruction Limit */ -+ pme_status_sre_iij = 0x5f, /* SRE Invalid Instruction Jump */ -+ pme_status_sre_ise = 0x60, /* SRE Instruction Syntax Error */ -+ pme_status_pmfa_pmtcce = 0x80, /* PMFA PCTCC Error */ -+ pme_status_pmfa_fcwe = 0x90, /* PMFA Flow Context Write Command Error */ -+ pme_status_pmfa_fcre = 0x91, /* PMFA Flow Context Read Command Error */ -+ pme_status_pmfa_ume = 0x93, /* PMFA Unrecognized Mode Error */ -+ pme_status_pmfa_uce = 0x94, /* PMFA Unrecognized Command Error */ -+ pme_status_pmfa_ufe = 0x95, /* PMFA Unrecognized Frame Error */ -+ pme_status_sre_csmre = 0xc0, /* SRE Context System Memory Read Error */ -+ pme_status_sre_ismre = 0xc1, /* SRE Instruction System Memory Read */ -+ /* Error */ -+ pme_status_dxe_smre = 0xc2, /* DXE System Memory Read Error */ -+ pme_status_pmfa_pmtccsmre = 0xc4, /* PMFA PMTCC System Memory Read */ -+ /* Error */ -+ pme_status_pmfa_csmre = 0xc5, /* PMFA Context System Memory Read */ -+ /* Error */ -+ pme_status_pmfa_dsmre = 0xc6, /* PMFA Data System Memory Read Error */ -+ pme_status_kes_cmecce = 0xd2, /* KES Confidence Memory ECC Error */ -+ pme_status_kes_2btmecce = 0xd4, /*KES 2-Byte Trigger Memory ECC Error */ -+ pme_status_kes_vltmecce = 0xd5, /*KES Variable Length Trigger Memory */ -+ /* ECC Error */ -+ pme_status_pmfa_cmecce = 0xd7, /* PMFA Confidence Memory ECC Error */ -+ pme_status_pmfa_2btmecce = 0xd9, /* PMFA 2-Byte Trigger Memory ECC */ -+ /* Error */ -+ pme_status_pmfa_vltmecce = 0xda, /* PMFA Variable Length Trigger */ -+ /* Memory ECC Error */ -+ pme_status_dxe_iemce = 0xdb, /* DXE Internal Examination Memory */ -+ /* Collision Error */ -+ pme_status_dxe_iemecce = 0xdc, /* DXE Internal Examination Memory */ -+ /* ECC Error */ -+ pme_status_dxe_icmecce = 0xdd, /* DXE Internal Context Memory ECC */ -+ /* Error */ -+ pme_status_sre_ctsmwe = 0xe0, /* SRE Context Table System Memory */ -+ /* Write Error */ -+ pme_status_pmfa_pmtccsmwe = 0xe7, /* PMFA PMTCC System Memory Write */ -+ /* Error */ -+ pme_status_pmfa_csmwe = 0xe8, /* PMFA Context System Memory Write */ -+ /* Error */ -+ pme_status_pmfa_dsmwe = 0xe9, /* PMFA Data System Memory Write Error */ -+}; -+ -+/* pme_fd_res_flags() returns these flags */ -+#define PME_STATUS_UNRELIABLE 0x80 -+#define PME_STATUS_TRUNCATED 0x10 -+#define PME_STATUS_MASK 0x90 -+ -+/**************/ -+/* USER SPACE */ -+/**************/ -+ -+#define PME_IOCTL_MAGIC 'p' -+ -+/* Wrapper for a pointer and size. */ -+struct pme_buffer { -+ void __user *data; -+ size_t size; -+}; -+ -+/***************/ -+/* SCAN DEVICE */ -+/***************/ -+/* The /dev/pme_scan device creates a file-descriptor that uses scheduled FQs -+ * serviced by PME's datapath portal. This can only be used for scanning. */ -+#define PME_DEV_SCAN_NODE "pme_scan" -+#define PME_DEV_SCAN_PATH "/dev/" PME_DEV_SCAN_NODE -+ -+/* ioctls for 'scan' device */ -+#define PMEIO_SETSCAN _IOW(PME_IOCTL_MAGIC, 0x06, struct pme_scan_params) -+#define PMEIO_GETSCAN _IOR(PME_IOCTL_MAGIC, 0x07, struct pme_scan_params) -+#define PMEIO_RESETSEQ _IO(PME_IOCTL_MAGIC, 0x08) -+#define PMEIO_RESETRES _IO(PME_IOCTL_MAGIC, 0x09) -+#define PMEIO_SCAN_W1 _IOW(PME_IOCTL_MAGIC, 0x0a, struct pme_scan_cmd) -+#define PMEIO_SCAN_Wn _IOWR(PME_IOCTL_MAGIC, 0x0b, struct pme_scan_cmds) -+#define PMEIO_SCAN_R1 _IOR(PME_IOCTL_MAGIC, 0x0c, struct pme_scan_result) -+#define PMEIO_SCAN_Rn _IOWR(PME_IOCTL_MAGIC, 0x0d, struct pme_scan_results) -+#define PMEIO_SCAN _IOWR(PME_IOCTL_MAGIC, 0x0e, struct pme_scan) -+/* The release_bufs ioctl takes as parameter a (void *) */ -+#define PMEIO_RELEASE_BUFS _IOW(PME_IOCTL_MAGIC, 0x0f, void *) -+ -+/* Parameters for PMEIO_SETSCAN and PMEIO_GETSCAN ioctl()s. This doesn't cover -+ * "sequence" fields ('soc' and 'seqnum'), they can only be influenced by flags -+ * passed to scan operations, or by PMEIO_RESETSEQ ioctl()s. */ -+struct pme_scan_params { -+ __u32 flags; /* PME_SCAN_PARAMS_*** bitmask */ -+ struct pme_scan_params_residue { -+ __u8 enable; /* boolean, residue enable */ -+ __u8 length; /* read-only for GETSCAN, ignored for SETSCAN */ -+ } residue; -+ struct pme_scan_params_sre { -+ __u32 sessionid; /* 27-bit */ -+ __u8 verbose; /* 0-3 */ -+ __u8 esee; /* boolean, End Of Sui Event Enable */ -+ } sre; -+ struct pme_scan_params_dxe { -+ __u16 clim; /* compare limit */ -+ __u16 mlim; /* match limit */ -+ } dxe; -+ struct pme_scan_params_pattern { -+ __u8 set; -+ __u16 subset; -+ } pattern; -+}; -+#define PME_SCAN_PARAMS_RESIDUE 0x00000001 -+#define PME_SCAN_PARAMS_SRE 0x00000002 -+#define PME_SCAN_PARAMS_DXE 0x00000004 -+#define PME_SCAN_PARAMS_PATTERN 0x00000008 -+ -+/* argument to PMEIO_SCAN_W1 ioctl */ -+struct pme_scan_cmd { -+ __u32 flags; /* PME_SCAN_CMD_*** bitmask */ -+ void *opaque; /* value carried through in the pme_scan_result */ -+ struct pme_buffer input; -+ struct pme_buffer output; /* ignored for 'RES_BMAN' output */ -+}; -+ -+#define PME_SCAN_CMD_RES_BMAN 0x00000001 /* use Bman for output */ -+#define PME_SCAN_CMD_STARTRESET 0x00000002 -+#define PME_SCAN_CMD_END 0x00000004 -+ -+/* argument to PMEIO_SCAN_Wn ioctl -+ * 'num' indicates how many 'cmds' are present on input and is updated on the -+ * response to indicate how many were sent. */ -+struct pme_scan_cmds { -+ unsigned num; -+ struct pme_scan_cmd __user *cmds; -+}; -+ -+/* argument to PMEIO_SCAN_R1 ioctl. The ioctl doesn't read any of these -+ * fields, they are only written to. If the output comes from BMAN buffer -+ * then 'flags' will have PME_SCAN_RESULT_BMAN set. */ -+struct pme_scan_result { -+ __u8 flags; /* PME_SCAN_RESULT_*** bitmask */ -+ enum pme_status status; -+ struct pme_buffer output; -+ void *opaque; /* value carried from the pme_scan_cmd */ -+}; -+#define PME_SCAN_RESULT_UNRELIABLE PME_STATUS_UNRELIABLE -+#define PME_SCAN_RESULT_TRUNCATED PME_STATUS_TRUNCATED -+#define PME_SCAN_RESULT_BMAN 0x01 -+ -+/* argument to PMEIO_SCAN_Rn ioctl. -+ * 'num' indicates how many 'cmds' are present on input and is updated on the -+ * response to indicate how many were retrieved. */ -+struct pme_scan_results { -+ unsigned num; -+ struct pme_scan_result *results; -+}; -+ -+/* argument to PMEIO_SCANWR ioctl. */ -+struct pme_scan { -+ struct pme_scan_cmd cmd; -+ struct pme_scan_result result; -+}; -+ -+/*************/ -+/* DB DEVICE */ -+/*************/ -+/* The /dev/pme_db device creates a file-descriptor that uses parked FQs -+ * serviced by the PME's EFQC (Exclusive Frame Queue Control) mechanism. This is -+ * usually for PMTCC commands for programming the database, though can also be -+ * used for high-priority scanning. This device would typically require root -+ * perms. The EFQC exclusivity is reference-counted, so by default is asserted -+ * on-demand and released when processing quiesces for the context, but -+ * exclusivity can be maintained across inter-frame gaps using the INC and DEC -+ * ioctls, which provide supplementary increments and decrements of the -+ * reference count. */ -+#define PME_DEV_DB_NODE "pme_db" -+#define PME_DEV_DB_PATH "/dev/" PME_DEV_DB_NODE -+ -+/* ioctls for 'db' device */ -+#define PMEIO_EXL_INC _IO(PME_IOCTL_MAGIC, 0x00) -+#define PMEIO_EXL_DEC _IO(PME_IOCTL_MAGIC, 0x01) -+#define PMEIO_EXL_GET _IOR(PME_IOCTL_MAGIC, 0x02, int) -+#define PMEIO_PMTCC _IOWR(PME_IOCTL_MAGIC, 0x03, struct pme_db) -+#define PMEIO_SRE_RESET _IOR(PME_IOCTL_MAGIC, 0x04, struct pme_db_sre_reset) -+#define PMEIO_NOP _IO(PME_IOCTL_MAGIC, 0x05) -+ -+/* Database structures */ -+#define PME_DB_RESULT_UNRELIABLE PME_STATUS_UNRELIABLE -+#define PME_DB_RESULT_TRUNCATED PME_STATUS_TRUNCATED -+ -+struct pme_db { -+ struct pme_buffer input; -+ struct pme_buffer output; -+ __u8 flags; /* PME_DB_RESULT_*** bitmask */ -+ enum pme_status status; -+}; -+ -+/* This is related to the sre_reset ioctl */ -+#define PME_SRE_RULE_VECTOR_SIZE 8 -+struct pme_db_sre_reset { -+ __u32 rule_vector[PME_SRE_RULE_VECTOR_SIZE]; -+ __u32 rule_index; -+ __u16 rule_increment; -+ __u32 rule_repetitions; -+ __u16 rule_reset_interval; -+ __u8 rule_reset_priority; -+}; -+ -+/****************/ -+/* KERNEL SPACE */ -+/****************/ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+ -+/* "struct pme_hw_flow" represents a flow-context resource for h/w, whereas -+ * "struct pme_flow" (below) is the s/w type used to provide (and receive) -+ * parameters to(/from) the h/w resource. */ -+struct pme_hw_flow; -+ -+/* "struct pme_hw_residue" represents a residue resource for h/w. */ -+struct pme_hw_residue; -+ -+/* This is the pme_flow structure type, used for querying or updating a PME flow -+ * context */ -+struct pme_flow { -+ u8 sos:1; -+ u8 __reserved1:1; -+ u8 srvm:2; -+ u8 esee:1; -+ u8 __reserved2:3; -+ u8 ren:1; -+ u8 rlen:7; -+ /* Sequence Number (48-bit) */ -+ u16 seqnum_hi; -+ u32 seqnum_lo; -+ u32 __reserved3; -+ u32 sessionid:27; -+ u32 __reserved4:5; -+ u16 __reserved5; -+ /* Residue pointer (48-bit), ignored if ren==0 */ -+ u16 rptr_hi; -+ u32 rptr_lo; -+ u16 clim; -+ u16 mlim; -+ u32 __reserved6; -+} __packed; -+static inline u64 pme_flow_seqnum_get64(const struct pme_flow *p) -+{ -+ return ((u64)p->seqnum_hi << 32) | (u64)p->seqnum_lo; -+} -+static inline u64 pme_flow_rptr_get64(const struct pme_flow *p) -+{ -+ return ((u64)p->rptr_hi << 32) | (u64)p->rptr_lo; -+} -+/* Macro, so we compile better if 'v' isn't always 64-bit */ -+#define pme_flow_seqnum_set64(p, v) \ -+ do { \ -+ struct pme_flow *__p931 = (p); \ -+ __p931->seqnum_hi = upper_32_bits(v); \ -+ __p931->seqnum_lo = lower_32_bits(v); \ -+ } while (0) -+#define pme_flow_rptr_set64(p, v) \ -+ do { \ -+ struct pme_flow *__p931 = (p); \ -+ __p931->rptr_hi = upper_32_bits(v); \ -+ __p931->rptr_lo = lower_32_bits(v); \ -+ } while (0) -+ -+/* pme_ctx_ctrl_update_flow(), pme_fd_cmd_fcw() and pme_scan_params::flags -+ * use these; */ -+#define PME_CMD_FCW_RES 0x80 /* "Residue": ren, rlen */ -+#define PME_CMD_FCW_SEQ 0x40 /* "Sequence": sos, sequnum */ -+#define PME_CMD_FCW_SRE 0x20 /* "Stateful Rule": srvm, esee, sessionid */ -+#define PME_CMD_FCW_DXE 0x10 /* "Data Examination": clim, mlim */ -+#define PME_CMD_FCW_ALL 0xf0 -+ -+/* pme_ctx_scan() and pme_fd_cmd_scan() use these; */ -+#define PME_CMD_SCAN_SRVM(n) ((n) << 3) /* n in [0..3] */ -+#define PME_CMD_SCAN_FLUSH 0x04 -+#define PME_CMD_SCAN_SR 0x02 /* aka "Start of Flow or Reset */ -+#define PME_CMD_SCAN_E 0x01 /* aka "End of Flow */ -+ -+/***********************/ -+/* low-level functions */ -+/***********************/ -+ -+/* (De)Allocate PME hardware resources */ -+struct pme_hw_residue *pme_hw_residue_new(void); -+void pme_hw_residue_free(struct pme_hw_residue *); -+struct pme_hw_flow *pme_hw_flow_new(void); -+void pme_hw_flow_free(struct pme_hw_flow *); -+ -+/* Initialise a flow context to known default values */ -+void pme_sw_flow_init(struct pme_flow *); -+ -+/* Fill in an "Initialise FQ" management command for a PME input FQ. NB, the -+ * caller is responsible for setting the following fields, they will not be set -+ * by the API; -+ * - initfq->fqid, the frame queue to be initialised -+ * - initfq->count, should most likely be zero. A count of 0 initialises 1 FQ, -+ * a count of 1 initialises 2 FQs, etc/ -+ * The 'qos' parameter indicates which workqueue in the PME channel the -+ * FQ should schedule to for regular scanning (0..7). If 'flow' is non-NULL the -+ * FQ is configured for Flow Mode, otherwise it is configured for Direct Action -+ * Mode. 'bpid' is the buffer pool ID to use when Bman-based output is -+ * produced, and 'rfqid' is the frame queue ID to enqueue output frames to. -+ * Following this api, when calling qm_mc_commit(), use QM_MCC_VERB_INITFQ_SCHED -+ * for regular PMEscanning or QM_MCC_VERB_INITFQ_PARK for exclusive PME -+ * processing (usually PMTCC).*/ -+void pme_initfq(struct qm_mcc_initfq *initfq, struct pme_hw_flow *flow, u8 qos, -+ u8 rbpid, u32 rfqid); -+ -+/* Given a dequeued frame from PME, return status/flags */ -+static inline enum pme_status pme_fd_res_status(const struct qm_fd *fd) -+{ -+ return (enum pme_status)(fd->status >> 24); -+} -+static inline u8 pme_fd_res_flags(const struct qm_fd *fd) -+{ -+ return (fd->status >> 16) & PME_STATUS_MASK; -+} -+ -+/* Fill in a frame descriptor for a NOP command. */ -+void pme_fd_cmd_nop(struct qm_fd *fd); -+ -+/* Fill in a frame descriptor for a Flow Context Write command. NB, the caller -+ * is responsible for setting all the relevant fields in 'flow', only the -+ * following fields are set by the API; -+ * - flow->rptr_hi -+ * - flow->rptr_lo -+ * The fields in 'flow' are divided into 4 groups, 'flags' indicates which of -+ * them should be written to the h/w flow context using PME_CMD_FCW_*** defines. -+ * 'residue' should be non-NULL iff flow->ren is non-zero and PME_CMD_FCW_RES is -+ * set. */ -+void pme_fd_cmd_fcw(struct qm_fd *fd, u8 flags, struct pme_flow *flow, -+ struct pme_hw_residue *residue); -+ -+/* Fill in a frame descriptor for a Flow Context Read command. */ -+void pme_fd_cmd_fcr(struct qm_fd *fd, struct pme_flow *flow); -+ -+/* Modify a frame descriptor for a PMTCC command (only modifies 'cmd' field) */ -+void pme_fd_cmd_pmtcc(struct qm_fd *fd); -+ -+/* Modify a frame descriptor for a Scan command (only modifies 'cmd' field). -+ * 'flags' are chosen from PME_CMD_SCAN_*** symbols. NB, the use of the -+ * intermediary representation (and PME_SCAN_ARGS) improves performance - ie. -+ * if the scan params are essentially constant, this compacts them for storage -+ * into the same format used in the interface to h/w. So it reduces parameter -+ * passing, stack-use, and encoding time. */ -+#define PME_SCAN_ARGS(flags, set, subset) \ -+({ \ -+ u8 __flags461 = (flags); \ -+ u8 __set461 = (set); \ -+ u16 __subset461 = (subset); \ -+ u32 __res461 = ((u32)__flags461 << 24) | \ -+ ((u32)__set461 << 16) | \ -+ (u32)__subset461; \ -+ __res461; \ -+}) -+void pme_fd_cmd_scan(struct qm_fd *fd, u32 args); -+ -+/* convert pointer to physical address for use by PME */ -+dma_addr_t pme_map(void *ptr); -+int pme_map_error(dma_addr_t dma_addr); -+ -+enum pme_cmd_type { -+ pme_cmd_nop = 0x7, -+ pme_cmd_flow_read = 0x5, /* aka FCR */ -+ pme_cmd_flow_write = 0x4, /* aka FCW */ -+ pme_cmd_pmtcc = 0x1, -+ pme_cmd_scan = 0 -+}; -+ -+/************************/ -+/* high-level functions */ -+/************************/ -+ -+/* predeclaration of a private structure" */ -+struct pme_ctx; -+struct pme_nostash; -+ -+/* Calls to pme_ctx_scan() and pme_ctx_pmtcc() provide these, and they are -+ * provided back in the completion callback. You can embed this within a larger -+ * structure in order to maintain per-command data of your own. The fields are -+ * owned by the driver until the callback is invoked, so for example do not link -+ * this token into a list while the command is in-flight! */ -+struct pme_ctx_token { -+ u32 blob[4]; -+ struct list_head node; -+ enum pme_cmd_type cmd_type:8; -+ u8 is_disable_flush; -+}; -+ -+struct pme_ctx_ctrl_token { -+ void (*cb)(struct pme_ctx *, const struct qm_fd *, -+ struct pme_ctx_ctrl_token *); -+ void (*ern_cb)(struct pme_ctx *, const struct qm_mr_entry *, -+ struct pme_ctx_ctrl_token *); -+ /* don't touch the rest */ -+ struct pme_hw_flow *internal_flow_ptr; -+ struct pme_flow *usr_flow_ptr; -+ struct pme_ctx_token base_token; -+}; -+ -+/* Scan results invoke a user-provided callback of this type */ -+typedef void (*pme_scan_cb)(struct pme_ctx *, const struct qm_fd *, -+ struct pme_ctx_token *); -+/* Enqueue rejections may happen before order-restoration or after (eg. if due -+ * to congestion or tail-drop). Use * 'rc' code of the 'mr_entry' to -+ * determine. */ -+typedef void (*pme_scan_ern_cb)(struct pme_ctx *, const struct qm_mr_entry *, -+ struct pme_ctx_token *); -+ -+/* PME "association" - ie. connects two frame-queues, with or without a PME flow -+ * (if not, direct action mode), and manages mux/demux of scans and flow-context -+ * updates. To allow state used by your callback to be stashed, as well as -+ * optimising the PME driver and the Qman driver beneath it, embed this -+ * structure as the first field in your own context structure. */ -+struct pme_ctx { -+ struct qman_fq fq; -+ /* IMPORTANT: Set (only) these two fields prior to calling * -+ * pme_ctx_init(). 'ern_cb' can be NULL if you know you will not -+ * receive enqueue rejections. */ -+ pme_scan_cb cb; -+ pme_scan_ern_cb ern_cb; -+ /* These fields should not be manipulated directly. Also the structure -+ * may change and/or grow, so avoid making any alignment or size -+ * assumptions. */ -+ atomic_t refs; -+ volatile u32 flags; -+ spinlock_t lock; -+ wait_queue_head_t queue; -+ struct list_head tokens; -+ /* TODO: the following "slow-path" values should be bundled into a -+ * secondary structure so that sizeof(struct pme_ctx) is minimised (for -+ * stashing of caller-side fast-path state). */ -+ struct pme_hw_flow *hw_flow; -+ struct pme_hw_residue *hw_residue; -+ struct qm_fqd_stashing stashing; -+ struct qm_fd update_fd; -+ struct pme_nostash *us_data; -+ u32 pme_rev1; -+ u32 pme_rev2; -+ int max_scan_size; -+}; -+ -+/* Flags for pme_ctx_init() */ -+#define PME_CTX_FLAG_LOCKED 0x00000001 /* use QMAN_FQ_FLAG_LOCKED */ -+#define PME_CTX_FLAG_EXCLUSIVE 0x00000002 /* unscheduled, exclusive mode */ -+#define PME_CTX_FLAG_PMTCC 0x00000004 /* PMTCC rather than scanning */ -+#define PME_CTX_FLAG_DIRECT 0x00000008 /* Direct Action mode (not Flow) */ -+#define PME_CTX_FLAG_LOCAL 0x00000020 /* Ignore dest, use cpu portal */ -+ -+/* Flags for operations */ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+#define PME_CTX_OP_WAIT QMAN_ENQUEUE_FLAG_WAIT -+#define PME_CTX_OP_WAIT_INT QMAN_ENQUEUE_FLAG_WAIT_INT -+#endif -+#define PME_CTX_OP_RESETRESLEN 0x00000001 /* no en/disable, just set len */ -+/* Note that pme_ctx_ctrl_update_flow() also uses PME_CMD_FCW flags, so they -+ * mustn't conflict with PME_CTX_OP_***. -+ * Also, the above are defined to match QMAN_ENQUEUE values for optimisation -+ * purposes (ie. fast-path operations that don't _WAIT will not incur PME->QMAN -+ * flag conversion overheads). */ -+ -+/** -+ * pme_ctx_init - Initialise a PME context -+ * @ctx: the context structure to initialise -+ * @flags: bit-mask of PME_CTX_FLAG_*** options -+ * @bpid: buffer pool ID used for any Bman-generated output -+ * @qosin: workqueue priority on the PME channel (0-7) -+ * @qosout: workqueue priority on the result channel (0-7) -+ * @dest: channel to receive results from PME -+ * @stashing: desired dequeue stashing behaviour -+ * -+ * This creates and initialises a PME context, composed of two FQs, an optional -+ * flow-context, and scheduling parameters for the datapath. The ctx->cb and -+ * ctx->pool fields must have been initialised prior to calling this api. The -+ * initialised context is left 'disabled', meaning that the FQ towards PME is -+ * Parked and no operations are possible. If PME_CTX_INIT_EXCLUSIVE is specified -+ * in @flags, then the input FQ is not scheduled, otherwise enabling the context -+ * will schedule the FQ to PME. Exclusive access is only available if the driver -+ * is built with control functionality and if the operating system has access to -+ * PME's CCSR map. @qosin applies if EXCLUSIVE is not set, and indicates which -+ * of the PME's 8 prioritised workqueues the FQ should schedule to. @dest -+ * indicates the channel that should receive results from PME, unless -+ * PME_CTX_FLAG_LOCAL is set in which case this parameter is ignored and the -+ * dedicated portal channel for the current cpu will be used instead. @qosout -+ * indicates which of the 8 prioritised workqueus the FQ should schedule to on -+ * the s/w portal. @stashing configures whether FQ context, frame data, and/or -+ * frame annotation should be stashed into cpu cache when dequeuing output, and -+ * if so, how many cachelines. For the FQ context part, set the number of -+ * cachelines to cover; 1. sizeof(struct qman_fq_base), to accelerate only Qman -+ * driver processing, 2. sizeof(struct pme_ctx), to accelerate Qman and PME -+ * driver processing, or 3. sizeof(), where is the -+ * caller's structure of which the pme_ctx is the first member - this will allow -+ * callbacks to operate on state which has a high probability of already being -+ * in-cache. -+ * Returns 0 on success. -+ */ -+int pme_ctx_init(struct pme_ctx *ctx, u32 flags, u32 bpid, u8 qosin, -+ u8 qosout, u16 dest, -+ const struct qm_fqd_stashing *stashing); -+ -+/* Cleanup allocated resources */ -+void pme_ctx_finish(struct pme_ctx *ctx); -+ -+/* enable a context */ -+int pme_ctx_enable(struct pme_ctx *ctx); -+ -+/* disable a context -+ * If it returns zero, the context is disabled. -+ * If it returns +1, the context is disabling and the token's completion -+ * callback will be invoked when disabling is complete. -+ * Returns -EBUSY on error, in which case the context remains enabled. -+ * If the PME_CTX_OP_WAIT flag is specified, it should only fail if -+ * PME_CTX_OP_WAIT_INT is also specified and a signal is pending. */ -+int pme_ctx_disable(struct pme_ctx *ctx, u32 flags, -+ struct pme_ctx_ctrl_token *token); -+ -+/* query whether a context is disabled. Returns > 0 if the ctx is disabled. */ -+int pme_ctx_is_disabled(struct pme_ctx *ctx); -+ -+/* query whether a context is in an error state. */ -+int pme_ctx_is_dead(struct pme_ctx *ctx); -+ -+/* A pre-condition for the following APIs is the ctx must be disabled -+ * dest maybe ignored if the flags parameter indicated LOCAL during the -+ * corresponding pme_ctx_init. -+ */ -+int pme_ctx_reconfigure_tx(struct pme_ctx *ctx, u32 bpid, u8 qosin); -+int pme_ctx_reconfigure_rx(struct pme_ctx *ctx, u8 qosout, -+ u16 dest, const struct qm_fqd_stashing *stashing); -+ -+/* Precondition: pme_ctx must be enabled -+ * if PME_CTX_OP_WAIT is specified, it'll wait (if it has to) to start the ctrl -+ * command but never waits for it to complete. The callback serves that purpose. -+ * NB: 'params' may be modified by this call. For instance if -+ * PME_CTX_OP_RESETRESLEN was specified and residue is enabled, then the -+ * params->ren will be set to 1 (in order not to disabled residue). -+ * NB: _update() will overwrite the 'params->rptr_[hi/low]' fields since the -+ * residue resource is managed by this layer. -+ */ -+int pme_ctx_ctrl_update_flow(struct pme_ctx *ctx, u32 flags, -+ struct pme_flow *params, struct pme_ctx_ctrl_token *token); -+int pme_ctx_ctrl_read_flow(struct pme_ctx *ctx, u32 flags, -+ struct pme_flow *params, struct pme_ctx_ctrl_token *token); -+int pme_ctx_ctrl_nop(struct pme_ctx *ctx, u32 flags, -+ struct pme_ctx_ctrl_token *token); -+ -+/* if PME_CTX_OP_WAIT is specified, it'll wait (if it has to) to start the scan -+ * but never waits for it to complete. The scan callback serves that purpose. -+ * 'fd' is modified by both these calls, but only the 'cmd' field. The 'args' -+ * parameters is produced by the PME_SCAN_ARGS() inline function. */ -+int pme_ctx_scan(struct pme_ctx *ctx, u32 flags, struct qm_fd *fd, u32 args, -+ struct pme_ctx_token *token); -+int pme_ctx_pmtcc(struct pme_ctx *ctx, u32 flags, struct qm_fd *fd, -+ struct pme_ctx_token *token); -+ -+/* This is extends pme_ctx_scan() to provide ORP support. 'orp_fq' represents -+ * the FQD that is used as the ORP and 'seqnum' is the sequence number to use -+ * for order restoration, these are usually the FQ the frame was dequeued from -+ * and the sequence number of that dequeued frame (respectively). */ -+int pme_ctx_scan_orp(struct pme_ctx *ctx, u32 flags, struct qm_fd *fd, u32 args, -+ struct pme_ctx_token *token, struct qman_fq *orp_fq, u16 seqnum); -+ -+/* Precondition: must be PME_CTX_FLAG_EXCLUSIVE */ -+int pme_ctx_exclusive_inc(struct pme_ctx *ctx, u32 flags); -+void pme_ctx_exclusive_dec(struct pme_ctx *ctx); -+ -+/* Does pme have access to ccsr */ -+int pme2_have_control(void); -+ -+/**************************/ -+/* control-plane only API */ -+/**************************/ -+#ifdef CONFIG_FSL_PME2_CTRL -+ -+/* Attributes for pme_reg_[set|get]() */ -+enum pme_attr { -+ pme_attr_efqc_int, -+ pme_attr_sw_db, -+ pme_attr_dmcr, -+ pme_attr_smcr, -+ pme_attr_famcr, -+ pme_attr_kvlts, -+ pme_attr_max_chain_length, -+ pme_attr_pattern_range_counter_idx, -+ pme_attr_pattern_range_counter_mask, -+ pme_attr_max_allowed_test_line_per_pattern, -+ pme_attr_max_pdsr_index, -+ pme_attr_max_pattern_matches_per_sui, -+ pme_attr_max_pattern_evaluations_per_sui, -+ pme_attr_report_length_limit, -+ pme_attr_end_of_simple_sui_report, -+ pme_attr_aim, -+ pme_attr_sre_context_size, -+ pme_attr_sre_rule_num, -+ pme_attr_sre_session_ctx_num, -+ pme_attr_end_of_sui_reaction_ptr, -+ pme_attr_sre_pscl, -+ pme_attr_sre_max_block_num, -+ pme_attr_sre_max_instruction_limit, -+ pme_attr_sre_max_index_size, -+ pme_attr_sre_max_offset_ctrl, -+ pme_attr_src_id, -+ pme_attr_liodnr, -+ pme_attr_rev1, -+ pme_attr_rev2, -+ pme_attr_srrv0, -+ pme_attr_srrv1, -+ pme_attr_srrv2, -+ pme_attr_srrv3, -+ pme_attr_srrv4, -+ pme_attr_srrv5, -+ pme_attr_srrv6, -+ pme_attr_srrv7, -+ pme_attr_srrfi, -+ pme_attr_srri, -+ pme_attr_srrwc, -+ pme_attr_srrr, -+ pme_attr_trunci, -+ pme_attr_rbc, -+ pme_attr_tbt0ecc1ec, -+ pme_attr_tbt1ecc1ec, -+ pme_attr_vlt0ecc1ec, -+ pme_attr_vlt1ecc1ec, -+ pme_attr_cmecc1ec, -+ pme_attr_dxcmecc1ec, -+ pme_attr_dxemecc1ec, -+ pme_attr_stnib, -+ pme_attr_stnis, -+ pme_attr_stnth1, -+ pme_attr_stnth2, -+ pme_attr_stnthv, -+ pme_attr_stnths, -+ pme_attr_stnch, -+ pme_attr_stnpm, -+ pme_attr_stns1m, -+ pme_attr_stnpmr, -+ pme_attr_stndsr, -+ pme_attr_stnesr, -+ pme_attr_stns1r, -+ pme_attr_stnob, -+ pme_attr_mia_byc, -+ pme_attr_mia_blc, -+ pme_attr_isr, -+ pme_attr_tbt0ecc1th, -+ pme_attr_tbt1ecc1th, -+ pme_attr_vlt0ecc1th, -+ pme_attr_vlt1ecc1th, -+ pme_attr_cmecc1th, -+ pme_attr_dxcmecc1th, -+ pme_attr_dxemecc1th, -+ pme_attr_esr, -+ pme_attr_ecr0, -+ pme_attr_ecr1, -+ pme_attr_pmstat, -+ pme_attr_pmtr, -+ pme_attr_pehd, -+ pme_attr_ecc1bes, -+ pme_attr_ecc2bes, -+ pme_attr_eccaddr, -+ pme_attr_ecccode, -+ pme_attr_miace, -+ pme_attr_miacr, -+ pme_attr_cdcr, -+ pme_attr_faconf, -+ pme_attr_ier, -+ pme_attr_isdr, -+ pme_attr_iir, -+ pme_attr_pdsrbah, -+ pme_attr_pdsrbal, -+ pme_attr_scbarh, -+ pme_attr_scbarl, -+ pme_attr_bsc_first, /* create 64-wide space for bsc */ -+ pme_attr_bsc_last = pme_attr_bsc_first + 63, -+}; -+ -+#define pme_attr_bsc(n) (pme_attr_bsc_first + (n)) -+/* Get/set driver attributes */ -+int pme_attr_set(enum pme_attr attr, u32 val); -+int pme_attr_get(enum pme_attr attr, u32 *val); -+int pme_stat_get(enum pme_attr stat, u64 *value, int reset); -+#endif /* defined(CONFIG_FSL_PME2_CTRL) */ -+ -+#ifdef CONFIG_COMPAT -+#include -+ -+struct compat_pme_buffer { -+ compat_uptr_t data; -+ compat_size_t size; -+}; -+ -+struct compat_pme_scan_cmd { -+ __u32 flags; /* PME_SCAN_CMD_*** bitmask */ -+ compat_uptr_t opaque; -+ struct compat_pme_buffer input; -+ struct compat_pme_buffer output; -+}; -+#define PMEIO_SCAN_W132 _IOW(PME_IOCTL_MAGIC, 0x0a, struct compat_pme_scan_cmd) -+ -+struct compat_pme_scan_cmds { -+ compat_uint_t num; -+ compat_uptr_t cmds; -+}; -+#define PMEIO_SCAN_Wn32 _IOWR(PME_IOCTL_MAGIC, 0x0b, \ -+ struct compat_pme_scan_cmds) -+ -+ -+struct compat_pme_scan_result { -+ __u8 flags; /* PME_SCAN_RESULT_*** bitmask */ -+ enum pme_status status; -+ struct compat_pme_buffer output; -+ compat_uptr_t opaque; /* value carried from the pme_scan_cmd */ -+}; -+#define PMEIO_SCAN_R132 _IOR(PME_IOCTL_MAGIC, 0x0c, \ -+ struct compat_pme_scan_result) -+ -+ -+struct compat_pme_scan_results { -+ compat_uint_t num; -+ compat_uptr_t results; -+}; -+#define PMEIO_SCAN_Rn32 _IOWR(PME_IOCTL_MAGIC, 0x0d, \ -+ struct compat_pme_scan_results) -+ -+ -+struct compat_pme_scan { -+ struct compat_pme_scan_cmd cmd; -+ struct compat_pme_scan_result result; -+}; -+#define PMEIO_SCAN32 _IOWR(PME_IOCTL_MAGIC, 0x0e, struct compat_pme_scan) -+ -+struct compat_pme_db { -+ struct compat_pme_buffer input; -+ struct compat_pme_buffer output; -+ __u8 flags; /* PME_DB_RESULT_*** bitmask */ -+ enum pme_status status; -+}; -+#define PMEIO_PMTCC32 _IOWR(PME_IOCTL_MAGIC, 0x03, struct compat_pme_db) -+ -+#endif /* CONFIG_COMPAT */ -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* FSL_PME_H */ -diff --git a/include/linux/fsl_qman.h b/include/linux/fsl_qman.h -new file mode 100644 -index 0000000..68a8768 ---- /dev/null -+++ b/include/linux/fsl_qman.h -@@ -0,0 +1,3213 @@ -+/* 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 -+extern u16 qm_channel_pool1; -+extern u16 qm_channel_caam; -+extern u16 qm_channel_pme; -+enum qm_dc_portal { -+ qm_dc_portal_fman0 = 0, -+ qm_dc_portal_fman1 = 1, -+ qm_dc_portal_caam = 2, -+ qm_dc_portal_pme = 3 -+}; -+ -+/* Portal processing (interrupt) sources */ -+#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) -+ -+/* --- 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 { -+ 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 */ -+ }; -+ struct { -+ u64 __notaddress:24; -+ /* More efficient address accessor */ -+ u64 addr:40; -+ }; -+ 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 { -+ enum qm_fd_format format:3; -+ u16 offset:9; -+ u32 length20:20; -+ }; -+ /* If 'format' is _contig_big or _sg_big, 29b length */ -+ struct { -+ enum qm_fd_format _format1:3; -+ u32 length29:29; -+ }; -+ /* If 'format' is _compound, 29b "congestion weight" */ -+ struct { -+ enum qm_fd_format _format2:3; -+ u32 cong_weight:29; -+ }; -+ }; -+ union { -+ u32 cmd; -+ u32 status; -+ }; -+} __attribute__((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 */ -+struct qm_sg_entry { -+ union { -+ struct { -+ u8 __reserved1[3]; -+ u8 addr_hi; /* high 8-bits of 40-bit address */ -+ u32 addr_lo; /* low 32-bits of 40-bit address */ -+ }; -+ struct { -+ u64 __notaddress:24; -+ u64 addr:40; -+ }; -+ }; -+ u32 extension:1; /* Extension bit */ -+ u32 final:1; /* Final bit */ -+ u32 length:30; -+ u8 __reserved2; -+ u8 bpid; -+ u16 __reserved3:3; -+ u16 offset:13; -+} __packed; -+static inline u64 qm_sg_entry_get64(const struct qm_sg_entry *sg) -+{ -+ return sg->addr; -+} -+static inline dma_addr_t qm_sg_addr(const struct qm_sg_entry *sg) -+{ -+ return (dma_addr_t)sg->addr; -+} -+/* 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->addr = 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 { -+ u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */ -+ u8 __reserved1:4; -+ enum qm_dc_portal portal:2; -+ 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_<...> */ -+ u8 exclusive; -+ u8 __reserved1:2; -+ /* Numbers of cachelines */ -+ u8 annotation_cl:2; -+ u8 data_cl:2; -+ u8 context_cl:2; -+} __packed; -+struct qm_fqd_taildrop { -+ u16 __reserved1:3; -+ u16 mant:8; -+ u16 exp:5; -+} __packed; -+struct qm_fqd_oac { -+ /* See QM_OAC_<...> */ -+ u8 oac:2; /* "Overhead Accounting Control" */ -+ u8 __reserved1:6; -+ /* Two's-complement value (-128 to +127) */ -+ signed char oal; /* "Overhead Accounting Length" */ -+} __packed; -+struct qm_fqd { -+ union { -+ u8 orpc; -+ struct { -+ u8 __reserved1:2; -+ u8 orprws:3; -+ u8 oa:1; -+ u8 olws:2; -+ } __packed; -+ }; -+ u8 cgid; -+ u16 fq_ctrl; /* See QM_FQCTRL_<...> */ -+ union { -+ u16 dest_wq; -+ struct { -+ u16 channel:13; /* qm_channel */ -+ u16 wq:3; -+ } __packed dest; -+ }; -+ u16 __reserved2:1; -+ u16 ics_cred:15; -+ /* 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 { -+ u32 hi; -+ u32 lo; -+ }; -+ /* Treat it as s/w portal stashing config */ -+ /* See 1.5.6.7.1: "FQD Context_A field used for [...] */ -+ struct { -+ struct qm_fqd_stashing stashing; -+ /* 48-bit address of FQ context to -+ * stash, must be cacheline-aligned */ -+ u16 context_hi; -+ u32 context_lo; -+ } __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 { -+ u32 MA:8; -+ u32 Mn:5; -+ u32 SA:7; /* must be between 64-127 */ -+ u32 Sn:6; -+ u32 Pn:6; -+ } __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 { -+ u16 __reserved:3; -+ u16 TA:8; -+ u16 Tn:5; -+} __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 { -+ u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */ -+ u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */ -+ }; -+ u32 cscn_targ; /* use QM_CGR_TARG_* */ -+ }; -+ u8 cstd_en; /* boolean, use QM_CGR_EN */ -+ u8 cs; /* boolean, only used in query response */ -+ struct qm_cgr_cs_thres cs_thres; /* use qm_cgr_cs_thres_set64() */ -+ 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 { -+ u16 id:13; /* qm_channel */ -+ u16 __reserved1:3; -+ } __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]; -+ u8 gpc; -+ 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 { -+ u8 map; -+ u8 __reserved2[58]; -+ } __packed channel_mapping; -+ struct { -+ u8 map_reserved:5; -+ u8 map_lni_id:3; -+ u8 __reserved2[58]; -+ } __packed sp_mapping; -+ struct { -+ u8 cpl; -+ u32 crtcr:24; -+ u32 ertcr:24; -+ u16 crtbl; -+ u16 ertbl; -+ u8 __reserved2[48]; -+ } __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 { -+ u8 ctl; -+ 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; -+ u16 __reserved3[2]; -+ u64 byte_cnt:40; -+ 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_*** */ -+ 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_*** */ -+} __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]; -+ 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 */ -+ 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 ((u64)q->i_bcnt_hi << 32) | (u64)q->i_bcnt_lo; -+} -+static inline u64 qm_mcr_querycgr_a_get64(const struct qm_mcr_querycgr *q) -+{ -+ return ((u64)q->a_bcnt_hi << 32) | (u64)q->a_bcnt_lo; -+} -+static inline u64 qm_mcr_cgrtestwrite_i_get64( -+ const struct qm_mcr_cgrtestwrite *q) -+{ -+ return ((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 ((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 { -+ u16 id:13; /* qm_channel */ -+ u16 __reserved:3; -+ } __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]; -+ u8 gpc; -+ 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 { -+ u8 map; -+ u8 __reserved2[58]; -+ } __packed channel_mapping_query; -+ struct { -+ u8 map_reserved:5; -+ u8 map_lni_id:3; -+ u8 __reserved2[58]; -+ } __packed sp_mapping_query; -+ struct { -+ u8 cpl; -+ u32 crtcr:24; -+ u32 ertcr:24; -+ u16 crtbl; -+ u16 ertbl; -+ u8 __reserved2[16]; -+ 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 { -+ u8 ctl; -+ 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; -+ u8 cscn_targ_dcp; -+ u16 dcp_lsn; -+ u64 i_cnt:40; -+ u8 __reserved4[3]; -+ u64 a_cnt:40; -+ u64 cscn_targ_swp[2]; -+ } __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]; -+ u16 ccg_state[16]; -+ } __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[15]; -+ u64 frm_cnt:40; -+ u8 __reserved2[2]; -+ u64 byte_cnt:40; -+ 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_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 - legacey 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); -+ -+/** -+ * 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); -+} -+ -+ /* 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); -+} -+ -+ -+ /* 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_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); -+} -+ -+ /* 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; -+ 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; -+}; -+ -+/* 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; -+ 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; -+}; -+ -+/* 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 assumes no particular type, so feed it with types that are -+ * appropriate for its use. 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) ? ((n) / (d)) : \ -+ (((r) > 0) ? (((n) + (d) - 1) / (d)) : \ -+ (((n) + ((d) / 2)) / (d)))) -+ -+/** -+ * 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(u32 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, -+ u32 *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_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_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_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); -+} -+ /* ----------------------------- */ -+ /* CEETM :: sub-portals */ -+ /* ----------------------------- */ -+ -+/** -+ * qman_ceetm_claim_sp - 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_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_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 Refernce -+ * 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_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_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 1 - 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); -+ -+ /* --------------------- */ -+ /* 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); -+ -+/* 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(unsigned int 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, -+ unsigned int *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); -+ -+ /* ---------------------- */ -+ /* 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 */ -+ int mode:1; -+ /* En/disable tail-drop. 1==enable */ -+ int td_en:1; -+ /* Tail-drop on congestion-state or threshold. 1=threshold */ -+ int td_mode:1; -+ /* Generate congestion state change notifications. 1==enable */ -+ int cscn_en:1; -+ /* Enable WRED rejections (per colour). 1==enable */ -+ int wr_en_g:1; -+ int wr_en_y:1; -+ int 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_CDV 0x0000 /* cdv */ -+#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) */ -+ -+/** -+ * 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_swp_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_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_swp - 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); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* FSL_QMAN_H */ -diff --git a/include/linux/fsl_usdpaa.h b/include/linux/fsl_usdpaa.h -new file mode 100644 -index 0000000..1f9e1dc ---- /dev/null -+++ b/include/linux/fsl_usdpaa.h -@@ -0,0 +1,154 @@ -+/* 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 -+ -+#ifdef CONFIG_FSL_USDPAA -+ -+/* Allocation of resource IDs uses a generic interface. 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; -+}; -+/* 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 -+struct usdpaa_ioctl_dma_map { -+ /* If the map succeeds, pa_offset is returned and can be used in a -+ * subsequent call to mmap(). */ -+ uint64_t pa_offset; -+ /* 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_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_DMA_MAP \ -+ _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map) -+/* 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, 0x04, unsigned char) -+#define USDPAA_IOCTL_DMA_UNLOCK \ -+ _IOW(USDPAA_IOCTL_MAGIC, 0x05, unsigned char) -+ -+#ifdef __KERNEL__ -+ -+/* Early-boot hook */ -+void __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 list; -+ spinlock_t lock; -+}; -+#define DECLARE_DPA_ALLOC(name) \ -+ struct dpa_alloc name = { \ -+ .list = { \ -+ .prev = &name.list, \ -+ .next = &name.list \ -+ }, \ -+ .lock = __SPIN_LOCK_UNLOCKED(name.lock) \ -+ } -+static inline void dpa_alloc_init(struct dpa_alloc *alloc) -+{ -+ INIT_LIST_HEAD(&alloc->list); -+ 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); -+/* 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); -+#endif /* __KERNEL__ */ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* FSL_USDPAA_H */ -diff --git a/include/linux/init.h b/include/linux/init.h -index 9146f39..e20c0b8 100644 ---- a/include/linux/init.h -+++ b/include/linux/init.h -@@ -82,12 +82,22 @@ - #define __exit __section(.exit.text) __exitused __cold notrace - - /* Used for HOTPLUG */ -+/* XXX - hack to disable __devinit for DPA drivers */ -+#ifdef CONFIG_DPA -+#define __devinit -+#define __devinitdata -+#define __devinitconst -+#define __devexit -+#define __devexitdata -+#define __devexitconst -+#else - #define __devinit __section(.devinit.text) __cold notrace - #define __devinitdata __section(.devinit.data) - #define __devinitconst __section(.devinit.rodata) - #define __devexit __section(.devexit.text) __exitused __cold notrace - #define __devexitdata __section(.devexit.data) - #define __devexitconst __section(.devexit.rodata) -+#endif - - /* Used for HOTPLUG_CPU */ - #define __cpuinit __section(.cpuinit.text) __cold notrace -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index 487dc1a..af46f21 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -1061,6 +1061,13 @@ struct net_device { - #define NETIF_F_RXCSUM (1 << 29) /* Receive checksumming offload */ - #define NETIF_F_NOCACHE_COPY (1 << 30) /* Use no-cache copyfromuser */ - #define NETIF_F_LOOPBACK (1 << 31) /* Enable loopback */ -+/* -+ * FSL temporary hack: until we pull 64-bit feature support -+ * from upstream, we need to override two existing bits from the mask. -+ * Obviously, this means we won't be supporting FCOE traffic. -+ */ -+#define NETIF_F_HW_QDISC (1 << 24) /* Supports hardware Qdisc */ -+#define NETIF_F_HW_ACCEL_MQ (1 << 26) /* Hardware-accelerated multiqueue */ - - /* Segmentation offload features */ - #define NETIF_F_GSO_SHIFT 16 -diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h -index 53b94e0..514fef4 100644 ---- a/include/linux/of_mdio.h -+++ b/include/linux/of_mdio.h -@@ -21,5 +21,8 @@ extern struct phy_device *of_phy_connect(struct net_device *dev, - extern struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, - void (*hndlr)(struct net_device *), - phy_interface_t iface); -+extern struct phy_device *of_phy_attach(struct net_device *dev, -+ struct device_node *phy_np, u32 flags, -+ phy_interface_t iface); - - #endif /* __LINUX_OF_MDIO_H */ -diff --git a/include/linux/phy.h b/include/linux/phy.h -index 79f337c..1efebc0 100644 ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -65,6 +65,7 @@ typedef enum { - PHY_INTERFACE_MODE_RGMII_TXID, - PHY_INTERFACE_MODE_RTBI, - PHY_INTERFACE_MODE_SMII, -+ PHY_INTERFACE_MODE_XGMII, - } phy_interface_t; - - -@@ -96,8 +97,10 @@ struct mii_bus { - const char *name; - char id[MII_BUS_ID_SIZE]; - void *priv; -- int (*read)(struct mii_bus *bus, int phy_id, int regnum); -- int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val); -+ int (*read)(struct mii_bus *bus, int port_addr, int dev_addr, -+ int regnum); -+ int (*write)(struct mii_bus *bus, int port_addr, int dev_addr, -+ int regnum, u16 val); - int (*reset)(struct mii_bus *bus); - - /* -@@ -126,6 +129,9 @@ struct mii_bus { - * interrupt at the index matching its address - */ - int *irq; -+ -+ /* indicate whether it's for Clause 45 PHY */ -+ bool is_c45; - }; - #define to_mii_bus(d) container_of(d, struct mii_bus, dev) - -@@ -134,8 +140,9 @@ int mdiobus_register(struct mii_bus *bus); - void mdiobus_unregister(struct mii_bus *bus); - void mdiobus_free(struct mii_bus *bus); - struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr); --int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum); --int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val); -+int mdiobus_read(struct mii_bus *bus, int addr, int devad, u16 regnum); -+int mdiobus_write(struct mii_bus *bus, int addr, int devad, -+ u16 regnum, u16 val); - - - #define PHY_INTERRUPT_DISABLED 0x0 -@@ -307,6 +314,7 @@ struct phy_device { - /* See mii.h for more info */ - u32 supported; - u32 advertising; -+ u32 mmds; - - int autoneg; - -@@ -453,7 +461,22 @@ struct phy_fixup { - */ - static inline int phy_read(struct phy_device *phydev, u32 regnum) - { -- return mdiobus_read(phydev->bus, phydev->addr, regnum); -+ return mdiobus_read(phydev->bus, phydev->addr, 0, regnum); -+} -+ -+/** -+ * phy45_read - Convenience function for reading a given port/dev/reg address -+ * @phydev: The phy_device struct -+ * @devad: The device address to read -+ * @regnum: The register number to read -+ * -+ * NOTE: MUST NOT be called from interrupt context, -+ * because the bus read/write functions may wait for an interrupt -+ * to conclude the operation. -+ */ -+static inline int phy45_read(struct phy_device *phydev, int devad, u16 regnum) -+{ -+ return mdiobus_read(phydev->bus, phydev->addr, devad, regnum); - } - - /** -@@ -468,12 +491,31 @@ static inline int phy_read(struct phy_device *phydev, u32 regnum) - */ - static inline int phy_write(struct phy_device *phydev, u32 regnum, u16 val) - { -- return mdiobus_write(phydev->bus, phydev->addr, regnum, val); -+ return mdiobus_write(phydev->bus, phydev->addr, 0, regnum, val); -+} -+ -+/** -+ * phy45_write - Convenience function for writing a given port/dev/reg -+ * @phydev: the phy_device struct -+ * @devad: the device addr -+ * @regnum: register number to write -+ * @val: value to write to @regnum -+ * -+ * NOTE: MUST NOT be called from interrupt context, -+ * because the bus read/write functions may wait for an interrupt -+ * to conclude the operation. -+ */ -+static inline int phy45_write(struct phy_device *phydev, u16 regnum, -+ int devad, u16 val) -+{ -+ return mdiobus_write(phydev->bus, phydev->addr, devad, regnum, val); - } - - int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id); - struct phy_device* get_phy_device(struct mii_bus *bus, int addr); - int phy_device_register(struct phy_device *phy); -+int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, -+ u32 flags, phy_interface_t interface); - int phy_init_hw(struct phy_device *phydev); - struct phy_device * phy_attach(struct net_device *dev, - const char *bus_id, u32 flags, phy_interface_t interface); -diff --git a/net/core/dev.c b/net/core/dev.c -index bb9f2d6..79bdb33 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -2492,6 +2492,12 @@ int dev_queue_xmit(struct sk_buff *skb) - rcu_read_lock_bh(); - - txq = dev_pick_tx(dev, skb); -+ if ((dev->features & NETIF_F_HW_QDISC) && -+ likely(!netif_tx_queue_stopped(txq))) { -+ rc = dev_hard_start_xmit(skb, dev, txq); -+ goto out; -+ } -+ - q = rcu_dereference_bh(txq->qdisc); - - #ifdef CONFIG_NET_CLS_ACT diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-gpio-intel-sch.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-gpio-intel-sch.patch deleted file mode 100644 index c14c30cd..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-gpio-intel-sch.patch +++ /dev/null @@ -1,233 +0,0 @@ -Back port gpio-sch.c driver for the Intel Centerton (Atom) - -Back port the current gpio-sch.c driver from linux-stable, adding -support for the Intel Centerton (Atom) GPIO controller. - -Also pull in the related PCI device ID. - -diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig -index 2870b99..410e264 100644 ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -154,13 +154,13 @@ config GPIO_VR41XX - Say yes here to support the NEC VR4100 series General-purpose I/O Uint - - config GPIO_SCH -- tristate "Intel SCH/TunnelCreek GPIO" -+ tristate "Intel SCH/TunnelCreek/Centerton GPIO" - depends on PCI && X86 - select MFD_CORE - select LPC_SCH - help -- Say yes here to support GPIO interface on Intel Poulsbo SCH -- or Intel Tunnel Creek processor. -+ Say yes here to support GPIO interface on Intel Poulsbo SCH, -+ Intel Tunnel Creek processor or Intel Centerton processor. - The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are - powered by the core power rail and are turned off during sleep - modes (S3 and higher). The remaining four GPIOs are powered by -@@ -169,6 +169,9 @@ config GPIO_SCH - system from the Suspend-to-RAM state. - The Intel Tunnel Creek processor has 5 GPIOs powered by the - core power rail and 9 from suspend power supply. -+ The Intel Centerton processor has a total of 30 GPIO pins. -+ Twenty-one are powered by the core power rail and 9 from the -+ suspend power supply. - - config GPIO_U300 - bool "ST-Ericsson U300 COH 901 335/571 GPIO" -diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c -index 1635158..9610ae5 100644 ---- a/drivers/gpio/gpio-sch.c -+++ b/drivers/gpio/gpio-sch.c -@@ -125,13 +125,17 @@ static int sch_gpio_resume_direction_in(struct gpio_chip *gc, - unsigned gpio_num) - { - u8 curr_dirs; -+ unsigned short offset, bit; - - spin_lock(&gpio_lock); - -- curr_dirs = inb(gpio_ba + RGIO); -+ offset = RGIO + gpio_num / 8; -+ bit = gpio_num % 8; -+ -+ curr_dirs = inb(gpio_ba + offset); - -- if (!(curr_dirs & (1 << gpio_num))) -- outb(curr_dirs | (1 << gpio_num) , gpio_ba + RGIO); -+ if (!(curr_dirs & (1 << bit))) -+ outb(curr_dirs | (1 << bit), gpio_ba + offset); - - spin_unlock(&gpio_lock); - return 0; -@@ -139,22 +143,31 @@ static int sch_gpio_resume_direction_in(struct gpio_chip *gc, - - static int sch_gpio_resume_get(struct gpio_chip *gc, unsigned gpio_num) - { -- return !!(inb(gpio_ba + RGLV) & (1 << gpio_num)); -+ unsigned short offset, bit; -+ -+ offset = RGLV + gpio_num / 8; -+ bit = gpio_num % 8; -+ -+ return !!(inb(gpio_ba + offset) & (1 << bit)); - } - - static void sch_gpio_resume_set(struct gpio_chip *gc, - unsigned gpio_num, int val) - { - u8 curr_vals; -+ unsigned short offset, bit; - - spin_lock(&gpio_lock); - -- curr_vals = inb(gpio_ba + RGLV); -+ offset = RGLV + gpio_num / 8; -+ bit = gpio_num % 8; -+ -+ curr_vals = inb(gpio_ba + offset); - - if (val) -- outb(curr_vals | (1 << gpio_num), gpio_ba + RGLV); -+ outb(curr_vals | (1 << bit), gpio_ba + offset); - else -- outb((curr_vals & ~(1 << gpio_num)), gpio_ba + RGLV); -+ outb((curr_vals & ~(1 << bit)), gpio_ba + offset); - - spin_unlock(&gpio_lock); - } -@@ -163,14 +176,18 @@ static int sch_gpio_resume_direction_out(struct gpio_chip *gc, - unsigned gpio_num, int val) - { - u8 curr_dirs; -+ unsigned short offset, bit; - - sch_gpio_resume_set(gc, gpio_num, val); - -+ offset = RGIO + gpio_num / 8; -+ bit = gpio_num % 8; -+ - spin_lock(&gpio_lock); - -- curr_dirs = inb(gpio_ba + RGIO); -- if (curr_dirs & (1 << gpio_num)) -- outb(curr_dirs & ~(1 << gpio_num), gpio_ba + RGIO); -+ curr_dirs = inb(gpio_ba + offset); -+ if (curr_dirs & (1 << bit)) -+ outb(curr_dirs & ~(1 << bit), gpio_ba + offset); - - spin_unlock(&gpio_lock); - return 0; -@@ -185,7 +202,7 @@ static struct gpio_chip sch_gpio_resume = { - .set = sch_gpio_resume_set, - }; - --static int __devinit sch_gpio_probe(struct platform_device *pdev) -+static int sch_gpio_probe(struct platform_device *pdev) - { - struct resource *res; - int err, id; -@@ -204,36 +221,41 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev) - gpio_ba = res->start; - - switch (id) { -- case PCI_DEVICE_ID_INTEL_SCH_LPC: -- sch_gpio_core.base = 0; -- sch_gpio_core.ngpio = 10; -- -- sch_gpio_resume.base = 10; -- sch_gpio_resume.ngpio = 4; -- -- /* -- * GPIO[6:0] enabled by default -- * GPIO7 is configured by the CMC as SLPIOVR -- * Enable GPIO[9:8] core powered gpios explicitly -- */ -- outb(0x3, gpio_ba + CGEN + 1); -- /* -- * SUS_GPIO[2:0] enabled by default -- * Enable SUS_GPIO3 resume powered gpio explicitly -- */ -- outb(0x8, gpio_ba + RGEN); -- break; -- -- case PCI_DEVICE_ID_INTEL_ITC_LPC: -- sch_gpio_core.base = 0; -- sch_gpio_core.ngpio = 5; -- -- sch_gpio_resume.base = 5; -- sch_gpio_resume.ngpio = 9; -- break; -- -- default: -- return -ENODEV; -+ case PCI_DEVICE_ID_INTEL_SCH_LPC: -+ sch_gpio_core.base = 0; -+ sch_gpio_core.ngpio = 10; -+ sch_gpio_resume.base = 10; -+ sch_gpio_resume.ngpio = 4; -+ /* -+ * GPIO[6:0] enabled by default -+ * GPIO7 is configured by the CMC as SLPIOVR -+ * Enable GPIO[9:8] core powered gpios explicitly -+ */ -+ outb(0x3, gpio_ba + CGEN + 1); -+ /* -+ * SUS_GPIO[2:0] enabled by default -+ * Enable SUS_GPIO3 resume powered gpio explicitly -+ */ -+ outb(0x8, gpio_ba + RGEN); -+ break; -+ -+ case PCI_DEVICE_ID_INTEL_ITC_LPC: -+ sch_gpio_core.base = 0; -+ sch_gpio_core.ngpio = 5; -+ sch_gpio_resume.base = 5; -+ sch_gpio_resume.ngpio = 9; -+ break; -+ -+ case PCI_DEVICE_ID_INTEL_CENTERTON_ILB: -+ sch_gpio_core.base = 0; -+ sch_gpio_core.ngpio = 21; -+ sch_gpio_resume.base = 21; -+ sch_gpio_resume.ngpio = 9; -+ break; -+ -+ default: -+ err = -ENODEV; -+ goto err_sch_gpio_core; - } - - sch_gpio_core.dev = &pdev->dev; -@@ -250,10 +272,8 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev) - return 0; - - err_sch_gpio_resume: -- err = gpiochip_remove(&sch_gpio_core); -- if (err) -- dev_err(&pdev->dev, "%s failed, %d\n", -- "gpiochip_remove()", err); -+ if (gpiochip_remove(&sch_gpio_core)) -+ dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); - - err_sch_gpio_core: - release_region(res->start, resource_size(res)); -@@ -262,7 +282,7 @@ err_sch_gpio_core: - return err; - } - --static int __devexit sch_gpio_remove(struct platform_device *pdev) -+static int sch_gpio_remove(struct platform_device *pdev) - { - struct resource *res; - if (gpio_ba) { -@@ -294,7 +314,7 @@ static struct platform_driver sch_gpio_driver = { - .owner = THIS_MODULE, - }, - .probe = sch_gpio_probe, -- .remove = __devexit_p(sch_gpio_remove), -+ .remove = sch_gpio_remove, - }; - - static int __init sch_gpio_init(void) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-gpio-mpc8xxx-do-not-set.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-gpio-mpc8xxx-do-not-set.patch deleted file mode 100644 index b95d261a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-gpio-mpc8xxx-do-not-set.patch +++ /dev/null @@ -1,22 +0,0 @@ -driver-gpio-mpc8xxx-do-not-set-IRQ_TYPE_NONE - -Apply upstream patch to avoid harmless, but annoying error messages -when setting GPIO via sysfs. - -See commit de0ccf788147440eee2383c74408080f3ff0a43b in the stable -kernel tree. Or this thread: - -https://lkml.org/lkml/2013/2/4/77 - -diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c -index 34be13b..60e259f 100644 ---- a/drivers/gpio/gpio-mpc8xxx.c -+++ b/drivers/gpio/gpio-mpc8xxx.c -@@ -296,7 +296,6 @@ static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, - - irq_set_chip_data(virq, h->host_data); - irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq); -- irq_set_irq_type(virq, IRQ_TYPE_NONE); - - return 0; - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-adt7475-clear-pwm-invert-bit.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-adt7475-clear-pwm-invert-bit.patch deleted file mode 100644 index 68da8d3c..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-adt7475-clear-pwm-invert-bit.patch +++ /dev/null @@ -1,47 +0,0 @@ -driver hwmon adt7475 clear pwm invert bit - -The Accton 4654, the only system using this driver, has a problem -where sometimes the power on value of the PWM control registers -(registers 0x5C,0x5D,0x5E) differs from the default. Sometimes the -"PWM invert" bit is set incorrectly, it should be clear for normal -operations. - -With the improper setting the fans will not spin. - -This patch clears the "PWM invert" bit every time the PWM value is -updated via sysfs. - -Clear PWM invert bit, i.e. force normal sense of duty cycle. See -ADT7473 data sheet for description of register 0x5C, bit 4: - - This bit inverts the PWM output. The default is 0, which corresponds - to a logic high output for 100% duty cycle. Setting this bit to 1 - inverts the PWM output, so 100% duty cycle corresponds to a logic - low output. - -diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c -index b5fcd87..d460f4e 100644 ---- a/drivers/hwmon/adt7475.c -+++ b/drivers/hwmon/adt7475.c -@@ -671,6 +671,21 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, - return count; - } - -+ /* Clear PWM invert bit, i.e. force normal sense of -+ * duty cycle. See ADT7473 data sheet for description -+ * of register 0x5C, bit 4: -+ * -+ * This bit inverts the PWM output. The default is -+ * 0, which corresponds to a logic high output for -+ * 100% duty cycle. Setting this bit to 1 inverts -+ * the PWM output, so 100% duty cycle corresponds to -+ * a logic low output. -+ * -+ */ -+ data->pwm[CONTROL][sattr->index] &= ~(1 << 4); -+ i2c_smbus_write_byte_data(client, PWM_CONFIG_REG(sattr->index), -+ data->pwm[CONTROL][sattr->index]); -+ - reg = PWM_REG(sattr->index); - break; - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-max6620-fix-rpm-calc.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-max6620-fix-rpm-calc.patch deleted file mode 100644 index eea85466..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-max6620-fix-rpm-calc.patch +++ /dev/null @@ -1,190 +0,0 @@ -The driver only fills the most significant 8 bits of the fan tach - -count (11 bit value). Fixing the driver to use all of 11 bits for -more accuracy. - -diff --git a/drivers/hwmon/max6620.c b/drivers/hwmon/max6620.c -index 3c337c7..76c1f7f 100644 ---- a/drivers/hwmon/max6620.c -+++ b/drivers/hwmon/max6620.c -@@ -46,6 +46,8 @@ - - /* clock: The clock frequency of the chip the driver should assume */ - static int clock = 8192; -+static u32 sr = 2; -+static u32 np = 2; - - module_param(clock, int, S_IRUGO); - -@@ -213,22 +215,22 @@ static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, cha - - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct max6620_data *data = max6620_update_device(dev); -- int rpm; -- -- /* -- * Calculation details: -- * -- * Each tachometer counts over an interval given by the "count" -- * register (0.25, 0.5, 1 or 2 seconds). This module assumes -- * that the fans produce two pulses per revolution (this seems -- * to be the most common). -- */ -- if(data->tach[attr->index] == 0 || data->tach[attr->index] == 255) { -+ struct i2c_client *client = to_i2c_client(dev); -+ u32 rpm = 0; -+ u32 tach = 0; -+ u32 tach1 = 0; -+ u32 tach2 = 0; -+ -+ tach1 = i2c_smbus_read_byte_data(client, tach_reg[attr->index]); -+ tach1 = (tach1 << 3) & 0x7f8; -+ tach2 = i2c_smbus_read_byte_data(client, tach_reg[attr->index] + 1); -+ tach2 = (tach2 >> 5) & 0x7; -+ tach = tach1 | tach2; -+ if (tach == 0) { - rpm = 0; - } else { -- rpm = ((clock / (data->tach[attr->index] << 3)) * 30 * DIV_FROM_REG(data->fandyn[attr->index])); -+ rpm = (60 * sr * clock)/(tach * np); - } -- - return sprintf(buf, "%d\n", rpm); - } - -@@ -236,22 +238,21 @@ static ssize_t get_target(struct device *dev, struct device_attribute *devattr, - - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct max6620_data *data = max6620_update_device(dev); -- int kscale, ktach, rpm; -- -- /* -- * Use the datasheet equation: -- * -- * FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)] -- * -- * then multiply by 60 to give rpm. -- */ -- -- kscale = DIV_FROM_REG(data->fandyn[attr->index]); -- ktach = data->target[attr->index]; -- if(ktach == 0) { -+ struct i2c_client *client = to_i2c_client(dev); -+ u32 rpm; -+ u32 target; -+ u32 target1; -+ u32 target2; -+ -+ target1 = i2c_smbus_read_byte_data(client, target_reg[attr->index]); -+ target1 = (target1 << 3) & 0x7f8; -+ target2 = i2c_smbus_read_byte_data(client, target_reg[attr->index] + 1); -+ target2 = (target2 >> 5) & 0x7; -+ target = target1 | target2; -+ if (target == 0) { - rpm = 0; - } else { -- rpm = ((60 * kscale * clock) / (ktach << 3)); -+ rpm = (60 * sr * clock)/(target * np); - } - return sprintf(buf, "%d\n", rpm); - } -@@ -261,9 +262,11 @@ static ssize_t set_target(struct device *dev, struct device_attribute *devattr, - struct i2c_client *client = to_i2c_client(dev); - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct max6620_data *data = i2c_get_clientdata(client); -- int kscale, ktach; -- unsigned long rpm; -+ u32 rpm; - int err; -+ u32 target; -+ u32 target1; -+ u32 target2; - - err = kstrtoul(buf, 10, &rpm); - if (err) -@@ -271,25 +274,13 @@ static ssize_t set_target(struct device *dev, struct device_attribute *devattr, - - rpm = SENSORS_LIMIT(rpm, FAN_RPM_MIN, FAN_RPM_MAX); - -- /* -- * Divide the required speed by 60 to get from rpm to rps, then -- * use the datasheet equation: -- * -- * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1 -- */ -- - mutex_lock(&data->update_lock); - -- kscale = DIV_FROM_REG(data->fandyn[attr->index]); -- ktach = ((60 * kscale * clock) / rpm); -- if (ktach < 0) -- ktach = 0; -- if (ktach > 255) -- ktach = 255; -- data->target[attr->index] = ktach; -- -- i2c_smbus_write_byte_data(client, target_reg[attr->index], data->target[attr->index]); -- i2c_smbus_write_byte_data(client, target_reg[attr->index]+0x01, 0x00); -+ target = (60 * sr * 8192)/(rpm * np); -+ target1 = (target >> 3) & 0xff; -+ target2 = (target << 5) & 0xe0; -+ i2c_smbus_write_byte_data(client, target_reg[attr->index], target1); -+ i2c_smbus_write_byte_data(client, target_reg[attr->index] + 1, target2); - - mutex_unlock(&data->update_lock); - -@@ -609,8 +600,11 @@ static int max6620_init_client(struct i2c_client *client) { - } - - -- -- if (i2c_smbus_write_byte_data(client, MAX6620_REG_CONFIG, config)) { -+ /* -+ * Set bit 4, disable other fans from going full speed on a fail -+ * failure. -+ */ -+ if (i2c_smbus_write_byte_data(client, MAX6620_REG_CONFIG, config | 0x10)) { - dev_err(&client->dev, "Config write error, aborting.\n"); - return err; - } -@@ -618,28 +612,21 @@ static int max6620_init_client(struct i2c_client *client) { - data->config = config; - for (i = 0; i < 4; i++) { - data->fancfg[i] = i2c_smbus_read_byte_data(client, config_reg[i]); -- data->fancfg[i] |= 0x80; // enable TACH monitoring -+ data->fancfg[i] |= 0xa8; // enable TACH monitoring - i2c_smbus_write_byte_data(client, config_reg[i], data->fancfg[i]); - data->fandyn[i] = i2c_smbus_read_byte_data(client, dyn_reg[i]); -- data-> fandyn[i] |= 0x1C; -+ /* 2 counts (001) and Rate change 100 (0.125 secs) */ -+ data-> fandyn[i] = 0x30; - i2c_smbus_write_byte_data(client, dyn_reg[i], data->fandyn[i]); - data->tach[i] = i2c_smbus_read_byte_data(client, tach_reg[i]); - data->volt[i] = i2c_smbus_read_byte_data(client, volt_reg[i]); - data->target[i] = i2c_smbus_read_byte_data(client, target_reg[i]); - data->dac[i] = i2c_smbus_read_byte_data(client, dac_reg[i]); - -- -- - } -- -- -- - return 0; - } - -- -- -- - static struct max6620_data *max6620_update_device(struct device *dev) - { - int i; -@@ -678,7 +665,7 @@ static struct max6620_data *max6620_update_device(struct device *dev) - return data; - } - --module_i2c_driver(max6620_driver); -+// module_i2c_driver(max6620_driver); - - static int __init max6620_init(void) - { diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-max6620.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-max6620.patch deleted file mode 100644 index 1fc7bf64..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-max6620.patch +++ /dev/null @@ -1,743 +0,0 @@ -Driver for MAX6620 Fan sensor - -diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig -index 33b8c3a..5c984a6 100644 ---- a/drivers/hwmon/Kconfig -+++ b/drivers/hwmon/Kconfig -@@ -832,6 +832,16 @@ config SENSORS_MAX6650 - This driver can also be built as a module. If so, the module - will be called max6650. - -+config SENSORS_MAX6620 -+ tristate "Maxim MAX6620 sensor chip" -+ depends on I2C && EXPERIMENTAL -+ help -+ If you say yes here you get support for the MAX6620 -+ sensor chips. -+ -+ This driver can also be built as a module. If so, the module -+ will be called max6620. -+ - config SENSORS_MAX6697 - tristate "Maxim MAX6697 and compatibles" - depends on I2C -diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile -index 64c587d..ff3a18e 100644 ---- a/drivers/hwmon/Makefile -+++ b/drivers/hwmon/Makefile -@@ -97,6 +97,7 @@ obj-$(CONFIG_SENSORS_MAX1668) += max1668.o - obj-$(CONFIG_SENSORS_MAX6639) += max6639.o - obj-$(CONFIG_SENSORS_MAX6642) += max6642.o - obj-$(CONFIG_SENSORS_MAX6650) += max6650.o -+obj-$(CONFIG_SENSORS_MAX6620) += max6620.o - obj-$(CONFIG_SENSORS_MAX6697) += max6697.o - obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o - obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o -diff --git a/drivers/hwmon/max6620.c b/drivers/hwmon/max6620.c -new file mode 100644 -index 0000000..3c337c7 ---- /dev/null -+++ b/drivers/hwmon/max6620.c -@@ -0,0 +1,702 @@ -+/* -+ * max6620.c - Linux Kernel module for hardware monitoring. -+ * -+ * (C) 2012 by L. Grunenberg -+ * -+ * based on code written by : -+ * 2007 by Hans J. Koch -+ * John Morris -+ * Copyright (c) 2003 Spirent Communications -+ * and Claus Gindhart -+ * -+ * This module has only been tested with the MAX6620 chip. -+ * -+ * The datasheet was last seen at: -+ * -+ * http://pdfserv.maxim-ic.com/en/ds/MAX6620.pdf -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * Insmod parameters -+ */ -+ -+ -+/* clock: The clock frequency of the chip the driver should assume */ -+static int clock = 8192; -+ -+module_param(clock, int, S_IRUGO); -+ -+static const unsigned short normal_i2c[] = {0x0a, 0x1a, 0x2a, I2C_CLIENT_END}; -+ -+/* -+ * MAX 6620 registers -+ */ -+ -+#define MAX6620_REG_CONFIG 0x00 -+#define MAX6620_REG_FAULT 0x01 -+#define MAX6620_REG_CONF_FAN0 0x02 -+#define MAX6620_REG_CONF_FAN1 0x03 -+#define MAX6620_REG_CONF_FAN2 0x04 -+#define MAX6620_REG_CONF_FAN3 0x05 -+#define MAX6620_REG_DYN_FAN0 0x06 -+#define MAX6620_REG_DYN_FAN1 0x07 -+#define MAX6620_REG_DYN_FAN2 0x08 -+#define MAX6620_REG_DYN_FAN3 0x09 -+#define MAX6620_REG_TACH0 0x10 -+#define MAX6620_REG_TACH1 0x12 -+#define MAX6620_REG_TACH2 0x14 -+#define MAX6620_REG_TACH3 0x16 -+#define MAX6620_REG_VOLT0 0x18 -+#define MAX6620_REG_VOLT1 0x1A -+#define MAX6620_REG_VOLT2 0x1C -+#define MAX6620_REG_VOLT3 0x1E -+#define MAX6620_REG_TAR0 0x20 -+#define MAX6620_REG_TAR1 0x22 -+#define MAX6620_REG_TAR2 0x24 -+#define MAX6620_REG_TAR3 0x26 -+#define MAX6620_REG_DAC0 0x28 -+#define MAX6620_REG_DAC1 0x2A -+#define MAX6620_REG_DAC2 0x2C -+#define MAX6620_REG_DAC3 0x2E -+ -+/* -+ * Config register bits -+ */ -+ -+#define MAX6620_CFG_RUN 0x80 -+#define MAX6620_CFG_POR 0x40 -+#define MAX6620_CFG_TIMEOUT 0x20 -+#define MAX6620_CFG_FULLFAN 0x10 -+#define MAX6620_CFG_OSC 0x08 -+#define MAX6620_CFG_WD_MASK 0x06 -+#define MAX6620_CFG_WD_2 0x02 -+#define MAX6620_CFG_WD_6 0x04 -+#define MAX6620_CFG_WD10 0x06 -+#define MAX6620_CFG_WD 0x01 -+ -+ -+/* -+ * Failure status register bits -+ */ -+ -+#define MAX6620_FAIL_TACH0 0x10 -+#define MAX6620_FAIL_TACH1 0x20 -+#define MAX6620_FAIL_TACH2 0x40 -+#define MAX6620_FAIL_TACH3 0x80 -+#define MAX6620_FAIL_MASK0 0x01 -+#define MAX6620_FAIL_MASK1 0x02 -+#define MAX6620_FAIL_MASK2 0x04 -+#define MAX6620_FAIL_MASK3 0x08 -+ -+ -+/* Minimum and maximum values of the FAN-RPM */ -+#define FAN_RPM_MIN 240 -+#define FAN_RPM_MAX 30000 -+ -+#define DIV_FROM_REG(reg) (1 << ((reg & 0xE0) >> 5)) -+ -+static int max6620_probe(struct i2c_client *client, const struct i2c_device_id *id); -+static int max6620_init_client(struct i2c_client *client); -+static int max6620_remove(struct i2c_client *client); -+static struct max6620_data *max6620_update_device(struct device *dev); -+ -+static const u8 config_reg[] = { -+ MAX6620_REG_CONF_FAN0, -+ MAX6620_REG_CONF_FAN1, -+ MAX6620_REG_CONF_FAN2, -+ MAX6620_REG_CONF_FAN3, -+}; -+ -+static const u8 dyn_reg[] = { -+ MAX6620_REG_DYN_FAN0, -+ MAX6620_REG_DYN_FAN1, -+ MAX6620_REG_DYN_FAN2, -+ MAX6620_REG_DYN_FAN3, -+}; -+ -+static const u8 tach_reg[] = { -+ MAX6620_REG_TACH0, -+ MAX6620_REG_TACH1, -+ MAX6620_REG_TACH2, -+ MAX6620_REG_TACH3, -+}; -+ -+static const u8 volt_reg[] = { -+ MAX6620_REG_VOLT0, -+ MAX6620_REG_VOLT1, -+ MAX6620_REG_VOLT2, -+ MAX6620_REG_VOLT3, -+}; -+ -+static const u8 target_reg[] = { -+ MAX6620_REG_TAR0, -+ MAX6620_REG_TAR1, -+ MAX6620_REG_TAR2, -+ MAX6620_REG_TAR3, -+}; -+ -+static const u8 dac_reg[] = { -+ MAX6620_REG_DAC0, -+ MAX6620_REG_DAC1, -+ MAX6620_REG_DAC2, -+ MAX6620_REG_DAC3, -+}; -+ -+/* -+ * Driver data (common to all clients) -+ */ -+ -+static const struct i2c_device_id max6620_id[] = { -+ { "max6620", 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, max6620_id); -+ -+static struct i2c_driver max6620_driver = { -+ .class = I2C_CLASS_HWMON, -+ .driver = { -+ .name = "max6620", -+ }, -+ .probe = max6620_probe, -+ .remove = __devexit_p(max6620_remove), -+ .id_table = max6620_id, -+ .address_list = normal_i2c, -+}; -+ -+/* -+ * Client data (each client gets its own) -+ */ -+ -+struct max6620_data { -+ struct device *hwmon_dev; -+ struct mutex update_lock; -+ int nr_fans; -+ char valid; /* zero until following fields are valid */ -+ unsigned long last_updated; /* in jiffies */ -+ -+ /* register values */ -+ u8 speed[4]; -+ u8 config; -+ u8 fancfg[4]; -+ u8 fandyn[4]; -+ u8 tach[4]; -+ u8 volt[4]; -+ u8 target[4]; -+ u8 dac[4]; -+ u8 fault; -+}; -+ -+static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, char *buf) { -+ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct max6620_data *data = max6620_update_device(dev); -+ int rpm; -+ -+ /* -+ * Calculation details: -+ * -+ * Each tachometer counts over an interval given by the "count" -+ * register (0.25, 0.5, 1 or 2 seconds). This module assumes -+ * that the fans produce two pulses per revolution (this seems -+ * to be the most common). -+ */ -+ if(data->tach[attr->index] == 0 || data->tach[attr->index] == 255) { -+ rpm = 0; -+ } else { -+ rpm = ((clock / (data->tach[attr->index] << 3)) * 30 * DIV_FROM_REG(data->fandyn[attr->index])); -+ } -+ -+ return sprintf(buf, "%d\n", rpm); -+} -+ -+static ssize_t get_target(struct device *dev, struct device_attribute *devattr, char *buf) { -+ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct max6620_data *data = max6620_update_device(dev); -+ int kscale, ktach, rpm; -+ -+ /* -+ * Use the datasheet equation: -+ * -+ * FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)] -+ * -+ * then multiply by 60 to give rpm. -+ */ -+ -+ kscale = DIV_FROM_REG(data->fandyn[attr->index]); -+ ktach = data->target[attr->index]; -+ if(ktach == 0) { -+ rpm = 0; -+ } else { -+ rpm = ((60 * kscale * clock) / (ktach << 3)); -+ } -+ return sprintf(buf, "%d\n", rpm); -+} -+ -+static ssize_t set_target(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { -+ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct max6620_data *data = i2c_get_clientdata(client); -+ int kscale, ktach; -+ unsigned long rpm; -+ int err; -+ -+ err = kstrtoul(buf, 10, &rpm); -+ if (err) -+ return err; -+ -+ rpm = SENSORS_LIMIT(rpm, FAN_RPM_MIN, FAN_RPM_MAX); -+ -+ /* -+ * Divide the required speed by 60 to get from rpm to rps, then -+ * use the datasheet equation: -+ * -+ * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1 -+ */ -+ -+ mutex_lock(&data->update_lock); -+ -+ kscale = DIV_FROM_REG(data->fandyn[attr->index]); -+ ktach = ((60 * kscale * clock) / rpm); -+ if (ktach < 0) -+ ktach = 0; -+ if (ktach > 255) -+ ktach = 255; -+ data->target[attr->index] = ktach; -+ -+ i2c_smbus_write_byte_data(client, target_reg[attr->index], data->target[attr->index]); -+ i2c_smbus_write_byte_data(client, target_reg[attr->index]+0x01, 0x00); -+ -+ mutex_unlock(&data->update_lock); -+ -+ return count; -+} -+ -+/* -+ * Get/set the fan speed in open loop mode using pwm1 sysfs file. -+ * Speed is given as a relative value from 0 to 255, where 255 is maximum -+ * speed. Note that this is done by writing directly to the chip's DAC, -+ * it won't change the closed loop speed set by fan1_target. -+ * Also note that due to rounding errors it is possible that you don't read -+ * back exactly the value you have set. -+ */ -+ -+static ssize_t get_pwm(struct device *dev, struct device_attribute *devattr, char *buf) { -+ -+ int pwm; -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct max6620_data *data = max6620_update_device(dev); -+ -+ /* -+ * Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans. -+ * Lower DAC values mean higher speeds. -+ */ -+ pwm = ((int)data->volt[attr->index]); -+ -+ if (pwm < 0) -+ pwm = 0; -+ -+ return sprintf(buf, "%d\n", pwm); -+} -+ -+static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { -+ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct max6620_data *data = i2c_get_clientdata(client); -+ unsigned long pwm; -+ int err; -+ -+ err = kstrtoul(buf, 10, &pwm); -+ if (err) -+ return err; -+ -+ pwm = SENSORS_LIMIT(pwm, 0, 255); -+ -+ mutex_lock(&data->update_lock); -+ -+ data->dac[attr->index] = pwm; -+ -+ -+ i2c_smbus_write_byte_data(client, dac_reg[attr->index], data->dac[attr->index]); -+ i2c_smbus_write_byte_data(client, dac_reg[attr->index]+1, 0x00); -+ -+ mutex_unlock(&data->update_lock); -+ -+ return count; -+} -+ -+/* -+ * Get/Set controller mode: -+ * Possible values: -+ * 0 = Fan always on -+ * 1 = Open loop, Voltage is set according to speed, not regulated. -+ * 2 = Closed loop, RPM for all fans regulated by fan1 tachometer -+ */ -+ -+static ssize_t get_enable(struct device *dev, struct device_attribute *devattr, char *buf) { -+ -+ struct max6620_data *data = max6620_update_device(dev); -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ int mode = (data->fancfg[attr->index] & 0x80 ) >> 7; -+ int sysfs_modes[2] = {1, 2}; -+ -+ return sprintf(buf, "%d\n", sysfs_modes[mode]); -+} -+ -+static ssize_t set_enable(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { -+ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct max6620_data *data = i2c_get_clientdata(client); -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ int max6620_modes[3] = {0, 1, 0}; -+ unsigned long mode; -+ int err; -+ -+ err = kstrtoul(buf, 10, &mode); -+ if (err) -+ return err; -+ -+ if (mode > 2) -+ return -EINVAL; -+ -+ mutex_lock(&data->update_lock); -+ -+ data->fancfg[attr->index] = i2c_smbus_read_byte_data(client, config_reg[attr->index]); -+ data->fancfg[attr->index] = (data->fancfg[attr->index] & ~0x80) -+ | (max6620_modes[mode] << 7); -+ -+ i2c_smbus_write_byte_data(client, config_reg[attr->index], data->fancfg[attr->index]); -+ -+ mutex_unlock(&data->update_lock); -+ -+ return count; -+} -+ -+/* -+ * Read/write functions for fan1_div sysfs file. The MAX6620 has no such -+ * divider. We handle this by converting between divider and counttime: -+ * -+ * (counttime == k) <==> (divider == 2^k), k = 0, 1, 2, 3, 4 or 5 -+ * -+ * Lower values of k allow to connect a faster fan without the risk of -+ * counter overflow. The price is lower resolution. You can also set counttime -+ * using the module parameter. Note that the module parameter "prescaler" also -+ * influences the behaviour. Unfortunately, there's no sysfs attribute -+ * defined for that. See the data sheet for details. -+ */ -+ -+static ssize_t get_div(struct device *dev, struct device_attribute *devattr, char *buf) { -+ -+ struct max6620_data *data = max6620_update_device(dev); -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ -+ return sprintf(buf, "%d\n", DIV_FROM_REG(data->fandyn[attr->index])); -+} -+ -+static ssize_t set_div(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { -+ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct max6620_data *data = i2c_get_clientdata(client); -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ unsigned long div; -+ int err; -+ u8 div_bin; -+ -+ err = kstrtoul(buf, 10, &div); -+ if (err) -+ return err; -+ -+ mutex_lock(&data->update_lock); -+ switch (div) { -+ case 1: -+ div_bin = 0; -+ break; -+ case 2: -+ div_bin = 1; -+ break; -+ case 4: -+ div_bin = 2; -+ break; -+ case 8: -+ div_bin = 3; -+ break; -+ case 16: -+ div_bin = 4; -+ break; -+ case 32: -+ div_bin = 5; -+ break; -+ default: -+ mutex_unlock(&data->update_lock); -+ return -EINVAL; -+ } -+ data->fandyn[attr->index] &= 0x1F; -+ data->fandyn[attr->index] |= div_bin << 5; -+ i2c_smbus_write_byte_data(client, dyn_reg[attr->index], data->fandyn[attr->index]); -+ mutex_unlock(&data->update_lock); -+ -+ return count; -+} -+ -+/* -+ * Get alarm stati: -+ * Possible values: -+ * 0 = no alarm -+ * 1 = alarm -+ */ -+ -+static ssize_t get_alarm(struct device *dev, struct device_attribute *devattr, char *buf) { -+ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct max6620_data *data = max6620_update_device(dev); -+ struct i2c_client *client = to_i2c_client(dev); -+ int alarm = 0; -+ -+ if (data->fault & (1 << attr->index)) { -+ mutex_lock(&data->update_lock); -+ alarm = 1; -+ data->fault &= ~(1 << attr->index); -+ data->fault |= i2c_smbus_read_byte_data(client, -+ MAX6620_REG_FAULT); -+ mutex_unlock(&data->update_lock); -+ } -+ -+ return sprintf(buf, "%d\n", alarm); -+} -+ -+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0); -+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1); -+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2); -+static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, get_fan, NULL, 3); -+static SENSOR_DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, get_target, set_target, 0); -+static SENSOR_DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_div, set_div, 0); -+// static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, 0); -+static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 0); -+static SENSOR_DEVICE_ATTR(fan2_target, S_IWUSR | S_IRUGO, get_target, set_target, 1); -+static SENSOR_DEVICE_ATTR(fan2_div, S_IWUSR | S_IRUGO, get_div, set_div, 1); -+// static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, 1); -+static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 1); -+static SENSOR_DEVICE_ATTR(fan3_target, S_IWUSR | S_IRUGO, get_target, set_target, 2); -+static SENSOR_DEVICE_ATTR(fan3_div, S_IWUSR | S_IRUGO, get_div, set_div, 2); -+// static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, 2); -+static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 2); -+static SENSOR_DEVICE_ATTR(fan4_target, S_IWUSR | S_IRUGO, get_target, set_target, 3); -+static SENSOR_DEVICE_ATTR(fan4_div, S_IWUSR | S_IRUGO, get_div, set_div, 3); -+// static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, 3); -+static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 3); -+ -+static struct attribute *max6620_attrs[] = { -+ &sensor_dev_attr_fan1_input.dev_attr.attr, -+ &sensor_dev_attr_fan2_input.dev_attr.attr, -+ &sensor_dev_attr_fan3_input.dev_attr.attr, -+ &sensor_dev_attr_fan4_input.dev_attr.attr, -+ &sensor_dev_attr_fan1_target.dev_attr.attr, -+ &sensor_dev_attr_fan1_div.dev_attr.attr, -+// &sensor_dev_attr_pwm1_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm1.dev_attr.attr, -+ &sensor_dev_attr_fan2_target.dev_attr.attr, -+ &sensor_dev_attr_fan2_div.dev_attr.attr, -+// &sensor_dev_attr_pwm2_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm2.dev_attr.attr, -+ &sensor_dev_attr_fan3_target.dev_attr.attr, -+ &sensor_dev_attr_fan3_div.dev_attr.attr, -+// &sensor_dev_attr_pwm3_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm3.dev_attr.attr, -+ &sensor_dev_attr_fan4_target.dev_attr.attr, -+ &sensor_dev_attr_fan4_div.dev_attr.attr, -+// &sensor_dev_attr_pwm4_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm4.dev_attr.attr, -+ NULL -+}; -+ -+static struct attribute_group max6620_attr_grp = { -+ .attrs = max6620_attrs, -+}; -+ -+ -+/* -+ * Real code -+ */ -+ -+static int __devinit max6620_probe(struct i2c_client *client, const struct i2c_device_id *id) { -+ -+ struct max6620_data *data; -+ int err; -+ -+ data = devm_kzalloc(&client->dev, sizeof(struct max6620_data), GFP_KERNEL); -+ if (!data) { -+ dev_err(&client->dev, "out of memory.\n"); -+ return -ENOMEM; -+ } -+ -+ i2c_set_clientdata(client, data); -+ mutex_init(&data->update_lock); -+ data->nr_fans = id->driver_data; -+ -+ /* -+ * Initialize the max6620 chip -+ */ -+ dev_info(&client->dev, "About to initialize module\n"); -+ -+ err = max6620_init_client(client); -+ if (err) -+ return err; -+ dev_info(&client->dev, "Module initialized\n"); -+ -+ err = sysfs_create_group(&client->dev.kobj, &max6620_attr_grp); -+ if (err) -+ return err; -+dev_info(&client->dev, "Sysfs entries created\n"); -+ -+ data->hwmon_dev = hwmon_device_register(&client->dev); -+ if (!IS_ERR(data->hwmon_dev)) -+ return 0; -+ -+ err = PTR_ERR(data->hwmon_dev); -+ dev_err(&client->dev, "error registering hwmon device.\n"); -+ -+ sysfs_remove_group(&client->dev.kobj, &max6620_attr_grp); -+ return err; -+} -+ -+static int __devexit max6620_remove(struct i2c_client *client) { -+ -+ struct max6620_data *data = i2c_get_clientdata(client); -+ -+ hwmon_device_unregister(data->hwmon_dev); -+ -+ sysfs_remove_group(&client->dev.kobj, &max6620_attr_grp); -+ return 0; -+} -+ -+static int max6620_init_client(struct i2c_client *client) { -+ -+ struct max6620_data *data = i2c_get_clientdata(client); -+ int config; -+ int err = -EIO; -+ int i; -+ -+ config = i2c_smbus_read_byte_data(client, MAX6620_REG_CONFIG); -+ -+ if (config < 0) { -+ dev_err(&client->dev, "Error reading config, aborting.\n"); -+ return err; -+ } -+ -+ -+ -+ if (i2c_smbus_write_byte_data(client, MAX6620_REG_CONFIG, config)) { -+ dev_err(&client->dev, "Config write error, aborting.\n"); -+ return err; -+ } -+ -+ data->config = config; -+ for (i = 0; i < 4; i++) { -+ data->fancfg[i] = i2c_smbus_read_byte_data(client, config_reg[i]); -+ data->fancfg[i] |= 0x80; // enable TACH monitoring -+ i2c_smbus_write_byte_data(client, config_reg[i], data->fancfg[i]); -+ data->fandyn[i] = i2c_smbus_read_byte_data(client, dyn_reg[i]); -+ data-> fandyn[i] |= 0x1C; -+ i2c_smbus_write_byte_data(client, dyn_reg[i], data->fandyn[i]); -+ data->tach[i] = i2c_smbus_read_byte_data(client, tach_reg[i]); -+ data->volt[i] = i2c_smbus_read_byte_data(client, volt_reg[i]); -+ data->target[i] = i2c_smbus_read_byte_data(client, target_reg[i]); -+ data->dac[i] = i2c_smbus_read_byte_data(client, dac_reg[i]); -+ -+ -+ -+ } -+ -+ -+ -+ return 0; -+} -+ -+ -+ -+ -+static struct max6620_data *max6620_update_device(struct device *dev) -+{ -+ int i; -+ struct i2c_client *client = to_i2c_client(dev); -+ struct max6620_data *data = i2c_get_clientdata(client); -+ -+ mutex_lock(&data->update_lock); -+ -+ if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { -+ -+ for (i = 0; i < 4; i++) { -+ data->fancfg[i] = i2c_smbus_read_byte_data(client, config_reg[i]); -+ data->fandyn[i] = i2c_smbus_read_byte_data(client, dyn_reg[i]); -+ data->tach[i] = i2c_smbus_read_byte_data(client, tach_reg[i]); -+ data->volt[i] = i2c_smbus_read_byte_data(client, volt_reg[i]); -+ data->target[i] = i2c_smbus_read_byte_data(client, target_reg[i]); -+ data->dac[i] = i2c_smbus_read_byte_data(client, dac_reg[i]); -+ } -+ -+ -+ /* -+ * Alarms are cleared on read in case the condition that -+ * caused the alarm is removed. Keep the value latched here -+ * for providing the register through different alarm files. -+ */ -+ u8 fault_reg; -+ fault_reg = i2c_smbus_read_byte_data(client, MAX6620_REG_FAULT); -+ data->fault |= (fault_reg >> 4) & (fault_reg & 0x0F); -+ -+ data->last_updated = jiffies; -+ data->valid = 1; -+ } -+ -+ mutex_unlock(&data->update_lock); -+ -+ return data; -+} -+ -+module_i2c_driver(max6620_driver); -+ -+static int __init max6620_init(void) -+{ -+ return i2c_add_driver(&max6620_driver); -+} -+module_init(max6620_init); -+ -+/** -+ * sht21_init() - clean up driver -+ * -+ * Called when module is removed. -+ */ -+static void __exit max6620_exit(void) -+{ -+ i2c_del_driver(&max6620_driver); -+} -+module_exit(max6620_exit); -+ -+MODULE_AUTHOR("Lucas Grunenberg"); -+MODULE_DESCRIPTION("MAX6620 sensor driver"); -+MODULE_LICENSE("GPL"); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-max6697.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-max6697.patch deleted file mode 100644 index a6181b1c..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-max6697.patch +++ /dev/null @@ -1,856 +0,0 @@ -Backport max6697.c from mainline Linux kernel - -diff --git a/Documentation/devicetree/bindings/i2c/max6697.txt b/Documentation/devicetree/bindings/i2c/max6697.txt -new file mode 100644 -index 0000000..5f79399 ---- /dev/null -+++ b/Documentation/devicetree/bindings/i2c/max6697.txt -@@ -0,0 +1,64 @@ -+max6697 properties -+ -+Required properties: -+- compatible: -+ Should be one of -+ maxim,max6581 -+ maxim,max6602 -+ maxim,max6622 -+ maxim,max6636 -+ maxim,max6689 -+ maxim,max6693 -+ maxim,max6694 -+ maxim,max6697 -+ maxim,max6698 -+ maxim,max6699 -+- reg: I2C address -+ -+Optional properties: -+ -+- smbus-timeout-disable -+ Set to disable SMBus timeout. If not specified, SMBus timeout will be -+ enabled. -+- extended-range-enable -+ Only valid for MAX6581. Set to enable extended temperature range. -+ Extended temperature will be disabled if not specified. -+- beta-compensation-enable -+ Only valid for MAX6693 and MX6694. Set to enable beta compensation on -+ remote temperature channel 1. -+ Beta compensation will be disabled if not specified. -+- alert-mask -+ Alert bit mask. Alert disabled for bits set. -+ Select bit 0 for local temperature, bit 1..7 for remote temperatures. -+ If not specified, alert will be enabled for all channels. -+- over-temperature-mask -+ Over-temperature bit mask. Over-temperature reporting disabled for -+ bits set. -+ Select bit 0 for local temperature, bit 1..7 for remote temperatures. -+ If not specified, over-temperature reporting will be enabled for all -+ channels. -+- resistance-cancellation -+ Boolean for all chips other than MAX6581. Set to enable resistance -+ cancellation on remote temperature channel 1. -+ For MAX6581, resistance cancellation enabled for all channels if -+ specified as boolean, otherwise as per bit mask specified. -+ Only supported for remote temperatures (bit 1..7). -+ If not specified, resistance cancellation will be disabled for all -+ channels. -+- transistor-ideality -+ For MAX6581 only. Two values; first is bit mask, second is ideality -+ select value as per MAX6581 data sheet. Select bit 1..7 for remote -+ channels. -+ Transistor ideality will be initialized to default (1.008) if not -+ specified. -+ -+Example: -+ -+temp-sensor@1a { -+ compatible = "maxim,max6697"; -+ reg = <0x1a>; -+ smbus-timeout-disable; -+ resistance-cancellation; -+ alert-mask = <0x72>; -+ over-temperature-mask = <0x7f>; -+}; -diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig -index 6b366b4..33b8c3a 100644 ---- a/drivers/hwmon/Kconfig -+++ b/drivers/hwmon/Kconfig -@@ -832,6 +832,17 @@ config SENSORS_MAX6650 - This driver can also be built as a module. If so, the module - will be called max6650. - -+config SENSORS_MAX6697 -+ tristate "Maxim MAX6697 and compatibles" -+ depends on I2C -+ help -+ If you say yes here you get support for MAX6581, MAX6602, MAX6622, -+ MAX6636, MAX6689, MAX6693, MAX6694, MAX6697, MAX6698, and MAX6699 -+ temperature sensor chips. -+ -+ This driver can also be built as a module. If so, the module -+ will be called max6697. -+ - config SENSORS_NTC_THERMISTOR - tristate "NTC thermistor support" - depends on EXPERIMENTAL -diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile -index dba7a20..64c587d 100644 ---- a/drivers/hwmon/Makefile -+++ b/drivers/hwmon/Makefile -@@ -97,6 +97,7 @@ obj-$(CONFIG_SENSORS_MAX1668) += max1668.o - obj-$(CONFIG_SENSORS_MAX6639) += max6639.o - obj-$(CONFIG_SENSORS_MAX6642) += max6642.o - obj-$(CONFIG_SENSORS_MAX6650) += max6650.o -+obj-$(CONFIG_SENSORS_MAX6697) += max6697.o - obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o - obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o - obj-$(CONFIG_SENSORS_PC87360) += pc87360.o -diff --git a/drivers/hwmon/max6697.c b/drivers/hwmon/max6697.c -new file mode 100644 -index 0000000..b567828 ---- /dev/null -+++ b/drivers/hwmon/max6697.c -@@ -0,0 +1,702 @@ -+/* -+ * Copyright (c) 2012 Guenter Roeck -+ * -+ * based on max1668.c -+ * Copyright (c) 2011 David George -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+enum chips { max6581, max6602, max6622, max6636, max6689, max6693, max6694, -+ max6697, max6698, max6699 }; -+ -+/* Report local sensor as temp1 */ -+ -+static const u8 MAX6697_REG_TEMP[] = { -+ 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08 }; -+static const u8 MAX6697_REG_TEMP_EXT[] = { -+ 0x57, 0x09, 0x52, 0x53, 0x54, 0x55, 0x56, 0 }; -+static const u8 MAX6697_REG_MAX[] = { -+ 0x17, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x18 }; -+static const u8 MAX6697_REG_CRIT[] = { -+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27 }; -+ -+/* -+ * Map device tree / platform data register bit map to chip bit map. -+ * Applies to alert register and over-temperature register. -+ */ -+#define MAX6697_MAP_BITS(reg) ((((reg) & 0x7e) >> 1) | \ -+ (((reg) & 0x01) << 6) | ((reg) & 0x80)) -+ -+#define MAX6697_REG_STAT(n) (0x44 + (n)) -+ -+#define MAX6697_REG_CONFIG 0x41 -+#define MAX6581_CONF_EXTENDED (1 << 1) -+#define MAX6693_CONF_BETA (1 << 2) -+#define MAX6697_CONF_RESISTANCE (1 << 3) -+#define MAX6697_CONF_TIMEOUT (1 << 5) -+#define MAX6697_REG_ALERT_MASK 0x42 -+#define MAX6697_REG_OVERT_MASK 0x43 -+ -+#define MAX6581_REG_RESISTANCE 0x4a -+#define MAX6581_REG_IDEALITY 0x4b -+#define MAX6581_REG_IDEALITY_SELECT 0x4c -+#define MAX6581_REG_OFFSET 0x4d -+#define MAX6581_REG_OFFSET_SELECT 0x4e -+ -+#define MAX6697_CONV_TIME 156 /* ms per channel, worst case */ -+ -+struct max6697_chip_data { -+ int channels; -+ u32 have_ext; -+ u32 have_crit; -+ u32 have_fault; -+ u8 valid_conf; -+ const u8 *alarm_map; -+}; -+ -+struct max6697_data { -+ struct device *hwmon_dev; -+ -+ enum chips type; -+ const struct max6697_chip_data *chip; -+ -+ int update_interval; /* in milli-seconds */ -+ int temp_offset; /* in degrees C */ -+ -+ struct mutex update_lock; -+ unsigned long last_updated; /* In jiffies */ -+ bool valid; /* true if following fields are valid */ -+ -+ /* 1x local and up to 7x remote */ -+ u8 temp[8][4]; /* [nr][0]=temp [1]=ext [2]=max [3]=crit */ -+#define MAX6697_TEMP_INPUT 0 -+#define MAX6697_TEMP_EXT 1 -+#define MAX6697_TEMP_MAX 2 -+#define MAX6697_TEMP_CRIT 3 -+ u32 alarms; -+}; -+ -+/* Diode fault status bits on MAX6581 are right shifted by one bit */ -+static const u8 max6581_alarm_map[] = { -+ 0, 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, -+ 16, 17, 18, 19, 20, 21, 22, 23 }; -+ -+static const struct max6697_chip_data max6697_chip_data[] = { -+ [max6581] = { -+ .channels = 8, -+ .have_crit = 0xff, -+ .have_ext = 0x7f, -+ .have_fault = 0xfe, -+ .valid_conf = MAX6581_CONF_EXTENDED | MAX6697_CONF_TIMEOUT, -+ .alarm_map = max6581_alarm_map, -+ }, -+ [max6602] = { -+ .channels = 5, -+ .have_crit = 0x12, -+ .have_ext = 0x02, -+ .have_fault = 0x1e, -+ .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT, -+ }, -+ [max6622] = { -+ .channels = 5, -+ .have_crit = 0x12, -+ .have_ext = 0x02, -+ .have_fault = 0x1e, -+ .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT, -+ }, -+ [max6636] = { -+ .channels = 7, -+ .have_crit = 0x72, -+ .have_ext = 0x02, -+ .have_fault = 0x7e, -+ .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT, -+ }, -+ [max6689] = { -+ .channels = 7, -+ .have_crit = 0x72, -+ .have_ext = 0x02, -+ .have_fault = 0x7e, -+ .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT, -+ }, -+ [max6693] = { -+ .channels = 7, -+ .have_crit = 0x72, -+ .have_ext = 0x02, -+ .have_fault = 0x7e, -+ .valid_conf = MAX6697_CONF_RESISTANCE | MAX6693_CONF_BETA | -+ MAX6697_CONF_TIMEOUT, -+ }, -+ [max6694] = { -+ .channels = 5, -+ .have_crit = 0x12, -+ .have_ext = 0x02, -+ .have_fault = 0x1e, -+ .valid_conf = MAX6697_CONF_RESISTANCE | MAX6693_CONF_BETA | -+ MAX6697_CONF_TIMEOUT, -+ }, -+ [max6697] = { -+ .channels = 7, -+ .have_crit = 0x72, -+ .have_ext = 0x02, -+ .have_fault = 0x7e, -+ .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT, -+ }, -+ [max6698] = { -+ .channels = 7, -+ .have_crit = 0x72, -+ .have_ext = 0x02, -+ .have_fault = 0x0e, -+ .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT, -+ }, -+ [max6699] = { -+ .channels = 5, -+ .have_crit = 0x12, -+ .have_ext = 0x02, -+ .have_fault = 0x1e, -+ .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT, -+ }, -+}; -+ -+static struct max6697_data *max6697_update_device(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct max6697_data *data = i2c_get_clientdata(client); -+ struct max6697_data *ret = data; -+ int val; -+ int i; -+ u32 alarms; -+ -+ mutex_lock(&data->update_lock); -+ -+ if (data->valid && -+ !time_after(jiffies, data->last_updated -+ + msecs_to_jiffies(data->update_interval))) -+ goto abort; -+ -+ for (i = 0; i < data->chip->channels; i++) { -+ if (data->chip->have_ext & (1 << i)) { -+ val = i2c_smbus_read_byte_data(client, -+ MAX6697_REG_TEMP_EXT[i]); -+ if (unlikely(val < 0)) { -+ ret = ERR_PTR(val); -+ goto abort; -+ } -+ data->temp[i][MAX6697_TEMP_EXT] = val; -+ } -+ -+ val = i2c_smbus_read_byte_data(client, MAX6697_REG_TEMP[i]); -+ if (unlikely(val < 0)) { -+ ret = ERR_PTR(val); -+ goto abort; -+ } -+ data->temp[i][MAX6697_TEMP_INPUT] = val; -+ -+ val = i2c_smbus_read_byte_data(client, MAX6697_REG_MAX[i]); -+ if (unlikely(val < 0)) { -+ ret = ERR_PTR(val); -+ goto abort; -+ } -+ data->temp[i][MAX6697_TEMP_MAX] = val; -+ -+ if (data->chip->have_crit & (1 << i)) { -+ val = i2c_smbus_read_byte_data(client, -+ MAX6697_REG_CRIT[i]); -+ if (unlikely(val < 0)) { -+ ret = ERR_PTR(val); -+ goto abort; -+ } -+ data->temp[i][MAX6697_TEMP_CRIT] = val; -+ } -+ } -+ -+ alarms = 0; -+ for (i = 0; i < 3; i++) { -+ val = i2c_smbus_read_byte_data(client, MAX6697_REG_STAT(i)); -+ if (unlikely(val < 0)) { -+ ret = ERR_PTR(val); -+ goto abort; -+ } -+ alarms = (alarms << 8) | val; -+ } -+ data->alarms = alarms; -+ data->last_updated = jiffies; -+ data->valid = true; -+abort: -+ mutex_unlock(&data->update_lock); -+ -+ return ret; -+} -+ -+static ssize_t show_temp_input(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ int index = to_sensor_dev_attr(devattr)->index; -+ struct max6697_data *data = max6697_update_device(dev); -+ int temp; -+ -+ if (IS_ERR(data)) -+ return PTR_ERR(data); -+ -+ temp = (data->temp[index][MAX6697_TEMP_INPUT] - data->temp_offset) << 3; -+ temp |= data->temp[index][MAX6697_TEMP_EXT] >> 5; -+ -+ return sprintf(buf, "%d\n", temp * 125); -+} -+ -+static ssize_t show_temp(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ int nr = to_sensor_dev_attr_2(devattr)->nr; -+ int index = to_sensor_dev_attr_2(devattr)->index; -+ struct max6697_data *data = max6697_update_device(dev); -+ int temp; -+ -+ if (IS_ERR(data)) -+ return PTR_ERR(data); -+ -+ temp = data->temp[nr][index]; -+ temp -= data->temp_offset; -+ -+ return sprintf(buf, "%d\n", temp * 1000); -+} -+ -+static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ int index = to_sensor_dev_attr(attr)->index; -+ struct max6697_data *data = max6697_update_device(dev); -+ -+ if (IS_ERR(data)) -+ return PTR_ERR(data); -+ -+ if (data->chip->alarm_map) -+ index = data->chip->alarm_map[index]; -+ -+ return sprintf(buf, "%u\n", (data->alarms >> index) & 0x1); -+} -+ -+static ssize_t set_temp(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, size_t count) -+{ -+ int nr = to_sensor_dev_attr_2(devattr)->nr; -+ int index = to_sensor_dev_attr_2(devattr)->index; -+ struct i2c_client *client = to_i2c_client(dev); -+ struct max6697_data *data = i2c_get_clientdata(client); -+ long temp; -+ int ret; -+ -+ ret = kstrtol(buf, 10, &temp); -+ if (ret < 0) -+ return ret; -+ -+ mutex_lock(&data->update_lock); -+ temp = DIV_ROUND_CLOSEST(temp, 1000) + data->temp_offset; -+ temp = clamp_val(temp, 0, data->type == max6581 ? 255 : 127); -+ data->temp[nr][index] = temp; -+ ret = i2c_smbus_write_byte_data(client, -+ index == 2 ? MAX6697_REG_MAX[nr] -+ : MAX6697_REG_CRIT[nr], -+ temp); -+ mutex_unlock(&data->update_lock); -+ -+ return ret < 0 ? ret : count; -+} -+ -+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0); -+static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 0, MAX6697_TEMP_MAX); -+static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 0, MAX6697_TEMP_CRIT); -+ -+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input, NULL, 1); -+static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 1, MAX6697_TEMP_MAX); -+static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 1, MAX6697_TEMP_CRIT); -+ -+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_input, NULL, 2); -+static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 2, MAX6697_TEMP_MAX); -+static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 2, MAX6697_TEMP_CRIT); -+ -+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_input, NULL, 3); -+static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 3, MAX6697_TEMP_MAX); -+static SENSOR_DEVICE_ATTR_2(temp4_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 3, MAX6697_TEMP_CRIT); -+ -+static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp_input, NULL, 4); -+static SENSOR_DEVICE_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 4, MAX6697_TEMP_MAX); -+static SENSOR_DEVICE_ATTR_2(temp5_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 4, MAX6697_TEMP_CRIT); -+ -+static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_temp_input, NULL, 5); -+static SENSOR_DEVICE_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 5, MAX6697_TEMP_MAX); -+static SENSOR_DEVICE_ATTR_2(temp6_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 5, MAX6697_TEMP_CRIT); -+ -+static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_temp_input, NULL, 6); -+static SENSOR_DEVICE_ATTR_2(temp7_max, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 6, MAX6697_TEMP_MAX); -+static SENSOR_DEVICE_ATTR_2(temp7_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 6, MAX6697_TEMP_CRIT); -+ -+static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_temp_input, NULL, 7); -+static SENSOR_DEVICE_ATTR_2(temp8_max, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 7, MAX6697_TEMP_MAX); -+static SENSOR_DEVICE_ATTR_2(temp8_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, -+ 7, MAX6697_TEMP_CRIT); -+ -+static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 22); -+static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 16); -+static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 17); -+static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_alarm, NULL, 18); -+static SENSOR_DEVICE_ATTR(temp5_max_alarm, S_IRUGO, show_alarm, NULL, 19); -+static SENSOR_DEVICE_ATTR(temp6_max_alarm, S_IRUGO, show_alarm, NULL, 20); -+static SENSOR_DEVICE_ATTR(temp7_max_alarm, S_IRUGO, show_alarm, NULL, 21); -+static SENSOR_DEVICE_ATTR(temp8_max_alarm, S_IRUGO, show_alarm, NULL, 23); -+ -+static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 14); -+static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 8); -+static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 9); -+static SENSOR_DEVICE_ATTR(temp4_crit_alarm, S_IRUGO, show_alarm, NULL, 10); -+static SENSOR_DEVICE_ATTR(temp5_crit_alarm, S_IRUGO, show_alarm, NULL, 11); -+static SENSOR_DEVICE_ATTR(temp6_crit_alarm, S_IRUGO, show_alarm, NULL, 12); -+static SENSOR_DEVICE_ATTR(temp7_crit_alarm, S_IRUGO, show_alarm, NULL, 13); -+static SENSOR_DEVICE_ATTR(temp8_crit_alarm, S_IRUGO, show_alarm, NULL, 15); -+ -+static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 1); -+static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 2); -+static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_alarm, NULL, 3); -+static SENSOR_DEVICE_ATTR(temp5_fault, S_IRUGO, show_alarm, NULL, 4); -+static SENSOR_DEVICE_ATTR(temp6_fault, S_IRUGO, show_alarm, NULL, 5); -+static SENSOR_DEVICE_ATTR(temp7_fault, S_IRUGO, show_alarm, NULL, 6); -+static SENSOR_DEVICE_ATTR(temp8_fault, S_IRUGO, show_alarm, NULL, 7); -+ -+static DEVICE_ATTR(dummy, 0, NULL, NULL); -+ -+static mode_t max6697_is_visible(struct kobject *kobj, struct attribute *attr, -+ int index) -+{ -+ struct device *dev = container_of(kobj, struct device, kobj); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct max6697_data *data = i2c_get_clientdata(client); -+ const struct max6697_chip_data *chip = data->chip; -+ int channel = index / 6; /* channel number */ -+ int nr = index % 6; /* attribute index within channel */ -+ -+ if (channel >= chip->channels) -+ return 0; -+ -+ if ((nr == 3 || nr == 4) && !(chip->have_crit & (1 << channel))) -+ return 0; -+ if (nr == 5 && !(chip->have_fault & (1 << channel))) -+ return 0; -+ -+ return attr->mode; -+} -+ -+/* -+ * max6697_is_visible uses the index into the following array to determine -+ * if attributes should be created or not. Any change in order or content -+ * must be matched in max6697_is_visible. -+ */ -+static struct attribute *max6697_attributes[] = { -+ &sensor_dev_attr_temp1_input.dev_attr.attr, -+ &sensor_dev_attr_temp1_max.dev_attr.attr, -+ &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp1_crit.dev_attr.attr, -+ &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, -+ &dev_attr_dummy.attr, -+ -+ &sensor_dev_attr_temp2_input.dev_attr.attr, -+ &sensor_dev_attr_temp2_max.dev_attr.attr, -+ &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp2_crit.dev_attr.attr, -+ &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp2_fault.dev_attr.attr, -+ -+ &sensor_dev_attr_temp3_input.dev_attr.attr, -+ &sensor_dev_attr_temp3_max.dev_attr.attr, -+ &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp3_crit.dev_attr.attr, -+ &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp3_fault.dev_attr.attr, -+ -+ &sensor_dev_attr_temp4_input.dev_attr.attr, -+ &sensor_dev_attr_temp4_max.dev_attr.attr, -+ &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp4_crit.dev_attr.attr, -+ &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp4_fault.dev_attr.attr, -+ -+ &sensor_dev_attr_temp5_input.dev_attr.attr, -+ &sensor_dev_attr_temp5_max.dev_attr.attr, -+ &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp5_crit.dev_attr.attr, -+ &sensor_dev_attr_temp5_crit_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp5_fault.dev_attr.attr, -+ -+ &sensor_dev_attr_temp6_input.dev_attr.attr, -+ &sensor_dev_attr_temp6_max.dev_attr.attr, -+ &sensor_dev_attr_temp6_max_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp6_crit.dev_attr.attr, -+ &sensor_dev_attr_temp6_crit_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp6_fault.dev_attr.attr, -+ -+ &sensor_dev_attr_temp7_input.dev_attr.attr, -+ &sensor_dev_attr_temp7_max.dev_attr.attr, -+ &sensor_dev_attr_temp7_max_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp7_crit.dev_attr.attr, -+ &sensor_dev_attr_temp7_crit_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp7_fault.dev_attr.attr, -+ -+ &sensor_dev_attr_temp8_input.dev_attr.attr, -+ &sensor_dev_attr_temp8_max.dev_attr.attr, -+ &sensor_dev_attr_temp8_max_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp8_crit.dev_attr.attr, -+ &sensor_dev_attr_temp8_crit_alarm.dev_attr.attr, -+ &sensor_dev_attr_temp8_fault.dev_attr.attr, -+ NULL -+}; -+ -+static const struct attribute_group max6697_group = { -+ .attrs = max6697_attributes, .is_visible = max6697_is_visible, -+}; -+ -+static void max6697_get_config_of(struct device_node *node, -+ struct max6697_platform_data *pdata) -+{ -+ int len; -+ const __be32 *prop; -+ -+ prop = of_get_property(node, "smbus-timeout-disable", &len); -+ if (prop) -+ pdata->smbus_timeout_disable = true; -+ prop = of_get_property(node, "extended-range-enable", &len); -+ if (prop) -+ pdata->extended_range_enable = true; -+ prop = of_get_property(node, "beta-compensation-enable", &len); -+ if (prop) -+ pdata->beta_compensation = true; -+ prop = of_get_property(node, "alert-mask", &len); -+ if (prop && len == sizeof(u32)) -+ pdata->alert_mask = be32_to_cpu(prop[0]); -+ prop = of_get_property(node, "over-temperature-mask", &len); -+ if (prop && len == sizeof(u32)) -+ pdata->over_temperature_mask = be32_to_cpu(prop[0]); -+ prop = of_get_property(node, "resistance-cancellation", &len); -+ if (prop) { -+ if (len == sizeof(u32)) -+ pdata->resistance_cancellation = be32_to_cpu(prop[0]); -+ else -+ pdata->resistance_cancellation = 0xfe; -+ } -+ prop = of_get_property(node, "transistor-ideality", &len); -+ if (prop && len == 2 * sizeof(u32)) { -+ pdata->ideality_mask = be32_to_cpu(prop[0]); -+ pdata->ideality_value = be32_to_cpu(prop[1]); -+ } -+} -+ -+static int max6697_init_chip(struct i2c_client *client) -+{ -+ struct max6697_data *data = i2c_get_clientdata(client); -+ struct max6697_platform_data *pdata = dev_get_platdata(&client->dev); -+ struct max6697_platform_data p; -+ const struct max6697_chip_data *chip = data->chip; -+ int factor = chip->channels; -+ int ret, reg; -+ -+ /* -+ * Don't touch configuration if neither platform data nor OF -+ * configuration was specified. If that is the case, use the -+ * current chip configuration. -+ */ -+ if (!pdata && !client->dev.of_node) { -+ reg = i2c_smbus_read_byte_data(client, MAX6697_REG_CONFIG); -+ if (reg < 0) -+ return reg; -+ if (data->type == max6581) { -+ if (reg & MAX6581_CONF_EXTENDED) -+ data->temp_offset = 64; -+ reg = i2c_smbus_read_byte_data(client, -+ MAX6581_REG_RESISTANCE); -+ if (reg < 0) -+ return reg; -+ factor += hweight8(reg); -+ } else { -+ if (reg & MAX6697_CONF_RESISTANCE) -+ factor++; -+ } -+ goto done; -+ } -+ -+ if (client->dev.of_node) { -+ memset(&p, 0, sizeof(p)); -+ max6697_get_config_of(client->dev.of_node, &p); -+ pdata = &p; -+ } -+ -+ reg = 0; -+ if (pdata->smbus_timeout_disable && -+ (chip->valid_conf & MAX6697_CONF_TIMEOUT)) { -+ reg |= MAX6697_CONF_TIMEOUT; -+ } -+ if (pdata->extended_range_enable && -+ (chip->valid_conf & MAX6581_CONF_EXTENDED)) { -+ reg |= MAX6581_CONF_EXTENDED; -+ data->temp_offset = 64; -+ } -+ if (pdata->resistance_cancellation && -+ (chip->valid_conf & MAX6697_CONF_RESISTANCE)) { -+ reg |= MAX6697_CONF_RESISTANCE; -+ factor++; -+ } -+ if (pdata->beta_compensation && -+ (chip->valid_conf & MAX6693_CONF_BETA)) { -+ reg |= MAX6693_CONF_BETA; -+ } -+ -+ ret = i2c_smbus_write_byte_data(client, MAX6697_REG_CONFIG, reg); -+ if (ret < 0) -+ return ret; -+ -+ ret = i2c_smbus_write_byte_data(client, MAX6697_REG_ALERT_MASK, -+ MAX6697_MAP_BITS(pdata->alert_mask)); -+ if (ret < 0) -+ return ret; -+ -+ ret = i2c_smbus_write_byte_data(client, MAX6697_REG_OVERT_MASK, -+ MAX6697_MAP_BITS(pdata->over_temperature_mask)); -+ if (ret < 0) -+ return ret; -+ -+ if (data->type == max6581) { -+ factor += hweight8(pdata->resistance_cancellation >> 1); -+ ret = i2c_smbus_write_byte_data(client, MAX6581_REG_RESISTANCE, -+ pdata->resistance_cancellation >> 1); -+ if (ret < 0) -+ return ret; -+ ret = i2c_smbus_write_byte_data(client, MAX6581_REG_IDEALITY, -+ pdata->ideality_value); -+ if (ret < 0) -+ return ret; -+ ret = i2c_smbus_write_byte_data(client, -+ MAX6581_REG_IDEALITY_SELECT, -+ pdata->ideality_mask >> 1); -+ if (ret < 0) -+ return ret; -+ } -+done: -+ data->update_interval = factor * MAX6697_CONV_TIME; -+ return 0; -+} -+ -+static int max6697_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct i2c_adapter *adapter = client->adapter; -+ struct device *dev = &client->dev; -+ struct max6697_data *data; -+ int err; -+ -+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) -+ return -ENODEV; -+ -+ data = devm_kzalloc(dev, sizeof(struct max6697_data), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ data->type = id->driver_data; -+ data->chip = &max6697_chip_data[data->type]; -+ i2c_set_clientdata(client, data); -+ mutex_init(&data->update_lock); -+ -+ err = max6697_init_chip(client); -+ if (err) -+ return err; -+ -+ err = sysfs_create_group(&client->dev.kobj, &max6697_group); -+ if (err) -+ return err; -+ -+ data->hwmon_dev = hwmon_device_register(dev); -+ if (IS_ERR(data->hwmon_dev)) { -+ err = PTR_ERR(data->hwmon_dev); -+ goto error; -+ } -+ -+ return 0; -+ -+error: -+ sysfs_remove_group(&client->dev.kobj, &max6697_group); -+ return err; -+} -+ -+static int max6697_remove(struct i2c_client *client) -+{ -+ struct max6697_data *data = i2c_get_clientdata(client); -+ -+ hwmon_device_unregister(data->hwmon_dev); -+ sysfs_remove_group(&client->dev.kobj, &max6697_group); -+ -+ return 0; -+} -+ -+static const struct i2c_device_id max6697_id[] = { -+ { "max6581", max6581 }, -+ { "max6602", max6602 }, -+ { "max6622", max6622 }, -+ { "max6636", max6636 }, -+ { "max6689", max6689 }, -+ { "max6693", max6693 }, -+ { "max6694", max6694 }, -+ { "max6697", max6697 }, -+ { "max6698", max6698 }, -+ { "max6699", max6699 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, max6697_id); -+ -+static struct i2c_driver max6697_driver = { -+ .class = I2C_CLASS_HWMON, -+ .driver = { -+ .name = "max6697", -+ }, -+ .probe = max6697_probe, -+ .remove = max6697_remove, -+ .id_table = max6697_id, -+}; -+ -+module_i2c_driver(max6697_driver); -+ -+MODULE_AUTHOR("Guenter Roeck "); -+MODULE_DESCRIPTION("MAX6697 temperature sensor driver"); -+MODULE_LICENSE("GPL"); -diff --git a/include/linux/platform_data/max6697.h b/include/linux/platform_data/max6697.h -new file mode 100644 -index 0000000..ed9d3b3 ---- /dev/null -+++ b/include/linux/platform_data/max6697.h -@@ -0,0 +1,36 @@ -+/* -+ * max6697.h -+ * Copyright (c) 2012 Guenter Roeck -+ * -+ * 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 MAX6697_H -+#define MAX6697_H -+ -+#include -+ -+/* -+ * For all bit masks: -+ * bit 0: local temperature -+ * bit 1..7: remote temperatures -+ */ -+struct max6697_platform_data { -+ bool smbus_timeout_disable; /* set to disable SMBus timeouts */ -+ bool extended_range_enable; /* set to enable extended temp range */ -+ bool beta_compensation; /* set to enable beta compensation */ -+ u8 alert_mask; /* set bit to 1 to disable alert */ -+ u8 over_temperature_mask; /* set bit to 1 to disable */ -+ u8 resistance_cancellation; /* set bit to 0 to disable -+ * bit mask for MAX6581, -+ * boolean for other chips -+ */ -+ u8 ideality_mask; /* set bit to 0 to disable */ -+ u8 ideality_value; /* transistor ideality as per -+ * MAX6581 datasheet -+ */ -+}; -+ -+#endif /* MAX6697_H */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-pmbus-dni_dps460.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-pmbus-dni_dps460.patch deleted file mode 100644 index 566f4019..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-hwmon-pmbus-dni_dps460.patch +++ /dev/null @@ -1,294 +0,0 @@ -Add PMBUS driver for DNI DPS460 Power Supply - -diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig -index 4b26f51..de91280 100644 ---- a/drivers/hwmon/pmbus/Kconfig -+++ b/drivers/hwmon/pmbus/Kconfig -@@ -76,6 +76,16 @@ config SENSORS_MAX34440 - This driver can also be built as a module. If so, the module will - be called max34440. - -+config SENSORS_DNI_DPS460 -+ tristate "Delta DPS460" -+ default n -+ help -+ If you say yes here you get hardware monitoring support for Delta -+ DPS460. -+ -+ This driver can also be built as a module. If so, the module will -+ be called dni_dps460. -+ - config SENSORS_MAX8688 - tristate "Maxim MAX8688" - default n -diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile -index 789376c..be70828 100644 ---- a/drivers/hwmon/pmbus/Makefile -+++ b/drivers/hwmon/pmbus/Makefile -@@ -9,6 +9,7 @@ obj-$(CONFIG_SENSORS_LM25066) += lm25066.o - obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o - obj-$(CONFIG_SENSORS_MAX16064) += max16064.o - obj-$(CONFIG_SENSORS_MAX34440) += max34440.o -+obj-$(CONFIG_SENSORS_DNI_DPS460) += dni_dps460.o - obj-$(CONFIG_SENSORS_MAX8688) += max8688.o - obj-$(CONFIG_SENSORS_UCD9000) += ucd9000.o - obj-$(CONFIG_SENSORS_UCD9200) += ucd9200.o -diff --git a/drivers/hwmon/pmbus/dni_dps460.c b/drivers/hwmon/pmbus/dni_dps460.c -new file mode 100644 -index 0000000..c687217 ---- /dev/null -+++ b/drivers/hwmon/pmbus/dni_dps460.c -@@ -0,0 +1,253 @@ -+/* -+ * Hardware monitoring driver for Delta DPS460 -+ * -+ * Copyright (C) 2014 Cumulus Networks, LLC -+ * Author: Puneet Shenoy -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "pmbus.h" -+ -+enum chips { dni_dps460 }; -+ -+/* Data provided by DELL Inc */ -+#define FAN_RPM_MIN 7200 -+#define FAN_RPM_MAX 18000 -+#define FAN_VALUE_MIN 0x28 -+#define FAN_VALUE_MAX 0x64 -+ -+/* Needed to access the mutex. Copied from pmbus_core.c */ -+#define PB_NUM_STATUS_REG (PMBUS_PAGES * 6 + 1) -+struct pmbus_data { -+ struct device *hwmon_dev; -+ -+ u32 flags; /* from platform data */ -+ -+ int exponent; /* linear mode: exponent for output voltages */ -+ -+ const struct pmbus_driver_info *info; -+ -+ int max_attributes; -+ int num_attributes; -+ struct attribute **attributes; -+ struct attribute_group group; -+ -+ /* -+ * Sensors cover both sensor and limit registers. -+ */ -+ int max_sensors; -+ int num_sensors; -+ struct pmbus_sensor *sensors; -+ /* -+ * Booleans are used for alarms. -+ * Values are determined from status registers. -+ */ -+ int max_booleans; -+ int num_booleans; -+ struct pmbus_boolean *booleans; -+ /* -+ * Labels are used to map generic names (e.g., "in1") -+ * to PMBus specific names (e.g., "vin" or "vout1"). -+ */ -+ int max_labels; -+ int num_labels; -+ struct pmbus_label *labels; -+ -+ struct mutex update_lock; -+ bool valid; -+ unsigned long last_updated; /* in jiffies */ -+ -+ /* -+ * A single status register covers multiple attributes, -+ * so we keep them all together. -+ */ -+ u8 status[PB_NUM_STATUS_REG]; -+ -+ u8 currpage; -+}; -+ -+/* -+ * We are only concerned with the first fan. The get_target and set_target are -+ * are written accordingly. -+ */ -+static ssize_t get_target(struct device *dev, struct device_attribute *devattr, -+ char *buf) { -+ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct pmbus_data *data = i2c_get_clientdata(client); -+ int val; -+ u32 rpm; -+ -+ /* -+ * The FAN_COMMAND_n takes a value which is not the RPM. -+ * The value and RPM have a liner relation. -+ * rpm = (FAN_RPM_MIN/FAN_VALUE_MIN) * val -+ * The slope is (FAN_RPM_MIN/FAN_VALUE_MIN) = 180 -+ */ -+ mutex_lock(&data->update_lock); -+ val = pmbus_read_word_data(client, 0, PMBUS_FAN_COMMAND_1); -+ pmbus_clear_faults(client); -+ mutex_unlock(&data->update_lock); -+ if (val < 0) { -+ return val; -+ } -+ rpm = val * (FAN_RPM_MIN/FAN_VALUE_MIN); -+ return sprintf(buf, "%d\n", rpm); -+} -+ -+static ssize_t set_target(struct device *dev, struct device_attribute *devattr, -+ const char *buf, size_t count) { -+ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct pmbus_data *data = i2c_get_clientdata(client); -+ int err; -+ unsigned int val; -+ unsigned int rpm; -+ -+ err = kstrtol(buf, 10, &rpm); -+ if (err) -+ return err; -+ -+ rpm = SENSORS_LIMIT(rpm, FAN_RPM_MIN, FAN_RPM_MAX); -+ -+ mutex_lock(&data->update_lock); -+ -+ val = FAN_VALUE_MIN * rpm; -+ val /= FAN_RPM_MIN; -+ pmbus_write_word_data(client, 0, PMBUS_FAN_COMMAND_1, (u16)val); -+ pmbus_clear_faults(client); -+ -+ mutex_unlock(&data->update_lock); -+ -+ return count; -+} -+ -+static ssize_t show_pec(struct device *dev, struct device_attribute *dummy, -+ char *buf) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ return sprintf(buf, "%d\n", !!(client->flags & I2C_CLIENT_PEC)); -+} -+ -+static ssize_t set_pec(struct device *dev, struct device_attribute *dummy, -+ const char *buf, size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ long val; -+ int err; -+ -+ err = strict_strtol(buf, 10, &val); -+ if (err < 0) -+ return err; -+ -+ if (val != 0) -+ client->flags |= I2C_CLIENT_PEC; -+ else -+ client->flags &= ~I2C_CLIENT_PEC; -+ -+ return count; -+} -+ -+static SENSOR_DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec, 0); -+static SENSOR_DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, get_target, -+ set_target, 0); -+ -+static struct attribute *dni_dps460_attrs[] = { -+ &sensor_dev_attr_fan1_target.dev_attr.attr, -+ &sensor_dev_attr_pec.dev_attr.attr, -+ NULL -+}; -+static struct attribute_group dni_dps460_attr_grp = { -+ .attrs = dni_dps460_attrs, -+}; -+ -+static int dni_dps460_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct pmbus_driver_info *info; -+ int ret; -+ -+ if (!i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_BYTE_DATA | -+ I2C_FUNC_SMBUS_WORD_DATA | -+ I2C_FUNC_SMBUS_PEC)) -+ return -ENODEV; -+ -+ /* Needs PEC(PACKET ERROR CODE). Writes wont work without this. */ -+ client->flags = I2C_CLIENT_PEC; -+ -+ info = kzalloc(sizeof(struct pmbus_driver_info), GFP_KERNEL); -+ if (!info) -+ return -ENOMEM; -+ -+ /* Use only 1 page with 1 Fan, 2 Temps. */ -+ info->pages = 1; -+ info->func[0] = PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 | -+ PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; -+ -+ ret = pmbus_do_probe(client, id, info); -+ if (ret < 0) -+ goto out; -+ -+ ret = sysfs_create_group(&client->dev.kobj, &dni_dps460_attr_grp); -+ if (ret) -+ goto out; -+ return 0; -+out: -+ kfree(info); -+ return ret; -+} -+ -+static int dni_dps460_remove(struct i2c_client *client) -+{ -+ struct pmbus_data *data = i2c_get_clientdata(client); -+ -+ sysfs_remove_group(&client->dev.kobj, &dni_dps460_attr_grp); -+ if (data->info) -+ kfree(data->info); -+ pmbus_do_remove(client); -+ return 0; -+} -+ -+static const struct i2c_device_id dni_dps460_id[] = { -+ {"dni_dps460", dni_dps460}, -+ {} -+}; -+MODULE_DEVICE_TABLE(i2c, dni_dps460_id); -+ -+static struct i2c_driver dni_dps460_driver = { -+ .driver = { -+ .name = "dni_dps460", -+ }, -+ .probe = dni_dps460_probe, -+ .remove = dni_dps460_remove, -+ .id_table = dni_dps460_id, -+}; -+ -+module_i2c_driver(dni_dps460_driver); -+ -+MODULE_AUTHOR("Puneet Shenoy"); -+MODULE_DESCRIPTION("PMBus driver for Delta DPS460"); -+MODULE_LICENSE("GPL"); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-avoton.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-avoton.patch deleted file mode 100644 index ec269021..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-avoton.patch +++ /dev/null @@ -1,22 +0,0 @@ -Patch to support Intel Avoton I2C smbus - -diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c -index 817d025..dfe074f 100644 ---- a/drivers/i2c/busses/i2c-i801.c -+++ b/drivers/i2c/busses/i2c-i801.c -@@ -149,6 +149,7 @@ - #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 - #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 - #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22 -+#define PCI_DEVICE_ID_INTEL_AVOTON_SMBUS 0x1f3c - - struct i801_priv { - struct i2c_adapter adapter; -@@ -639,6 +640,7 @@ static const struct pci_device_id i801_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMBUS) }, - { 0, } - }; - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-i801-update.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-i801-update.patch deleted file mode 100644 index 0867b046..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-i801-update.patch +++ /dev/null @@ -1,974 +0,0 @@ -Update the i801 driver to the latest kernel source (3.15.7). Needed for -accton as5712. CM-3232. - -diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c -index dfe074f..6777cd6 100644 ---- a/drivers/i2c/busses/i2c-i801.c -+++ b/drivers/i2c/busses/i2c-i801.c -@@ -2,7 +2,7 @@ - Copyright (c) 1998 - 2002 Frodo Looijaard , - Philip Edelbrock , and Mark D. Studebaker - -- Copyright (C) 2007, 2008 Jean Delvare -+ Copyright (C) 2007 - 2012 Jean Delvare - Copyright (C) 2010 Intel Corporation, - David Woodhouse - -@@ -53,6 +53,14 @@ - Panther Point (PCH) 0x1e22 32 hard yes yes yes - Lynx Point (PCH) 0x8c22 32 hard yes yes yes - Lynx Point-LP (PCH) 0x9c22 32 hard yes yes yes -+ Avoton (SOC) 0x1f3c 32 hard yes yes yes -+ Wellsburg (PCH) 0x8d22 32 hard yes yes yes -+ Wellsburg (PCH) MS 0x8d7d 32 hard yes yes yes -+ Wellsburg (PCH) MS 0x8d7e 32 hard yes yes yes -+ Wellsburg (PCH) MS 0x8d7f 32 hard yes yes yes -+ Coleto Creek (PCH) 0x23b0 32 hard yes yes yes -+ Wildcat Point-LP (PCH) 0x9ca2 32 hard yes yes yes -+ BayTrail (SOC) 0x0f12 32 hard yes yes yes - - Features supported by this driver: - Software PEC no -@@ -61,10 +69,12 @@ - Block process call transaction no - I2C block read transaction yes (doesn't use the block buffer) - Slave mode no -+ Interrupt processing yes - - See the file Documentation/i2c/busses/i2c-i801 for details. - */ - -+#include - #include - #include - #include -@@ -77,6 +87,15 @@ - #include - #include - #include -+#include -+#include -+ -+#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ -+ defined CONFIG_DMI -+#include -+#include -+#include -+#endif - - /* I801 SMBus address offsets */ - #define SMBHSTSTS(p) (0 + (p)->smba) -@@ -92,8 +111,12 @@ - - /* PCI Address Constants */ - #define SMBBAR 4 -+#define SMBPCISTS 0x006 - #define SMBHSTCFG 0x040 - -+/* Host status bits for SMBPCISTS */ -+#define SMBPCISTS_INTS 0x08 -+ - /* Host configuration bits for SMBHSTCFG */ - #define SMBHSTCFG_HST_EN 1 - #define SMBHSTCFG_SMB_SMI_EN 2 -@@ -103,12 +126,8 @@ - #define SMBAUXCTL_CRC 1 - #define SMBAUXCTL_E32B 2 - --/* kill bit for SMBHSTCNT */ --#define SMBHSTCNT_KILL 2 -- - /* Other settings */ --#define MAX_TIMEOUT 100 --#define ENABLE_INT9 0 /* set to 0x01 to enable - untested */ -+#define MAX_RETRIES 400 - - /* I801 command constants */ - #define I801_QUICK 0x00 -@@ -118,10 +137,13 @@ - #define I801_PROC_CALL 0x10 /* unimplemented */ - #define I801_BLOCK_DATA 0x14 - #define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */ --#define I801_BLOCK_LAST 0x34 --#define I801_I2C_BLOCK_LAST 0x38 /* ICH5 and later */ --#define I801_START 0x40 --#define I801_PEC_EN 0x80 /* ICH3 and later */ -+ -+/* I801 Host Control register bits */ -+#define SMBHSTCNT_INTREN 0x01 -+#define SMBHSTCNT_KILL 0x02 -+#define SMBHSTCNT_LAST_BYTE 0x20 -+#define SMBHSTCNT_START 0x40 -+#define SMBHSTCNT_PEC_EN 0x80 /* ICH3 and later */ - - /* I801 Hosts Status register bits */ - #define SMBHSTSTS_BYTE_DONE 0x80 -@@ -133,11 +155,14 @@ - #define SMBHSTSTS_INTR 0x02 - #define SMBHSTSTS_HOST_BUSY 0x01 - --#define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_FAILED | \ -- SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \ -- SMBHSTSTS_INTR) -+#define STATUS_ERROR_FLAGS (SMBHSTSTS_FAILED | SMBHSTSTS_BUS_ERR | \ -+ SMBHSTSTS_DEV_ERR) -+ -+#define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR | \ -+ STATUS_ERROR_FLAGS) - - /* Older devices have their ID defined in */ -+#define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12 - #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 - #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 - /* Patsburg also has three 'Integrated Device Function' SMBus controllers */ -@@ -145,11 +170,26 @@ - #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71 - #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72 - #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS 0x1e22 -+#define PCI_DEVICE_ID_INTEL_AVOTON_SMBUS 0x1f3c - #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 -+#define PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS 0x23b0 - #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 - #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 -+#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS 0x8d22 -+#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0 0x8d7d -+#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1 0x8d7e -+#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2 0x8d7f - #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22 --#define PCI_DEVICE_ID_INTEL_AVOTON_SMBUS 0x1f3c -+#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS 0x9ca2 -+ -+struct i801_mux_config { -+ char *gpio_chip; -+ unsigned values[3]; -+ int n_values; -+ unsigned classes[3]; -+ unsigned gpios[2]; /* Relative to gpio_chip->base */ -+ int n_gpios; -+}; - - struct i801_priv { - struct i2c_adapter adapter; -@@ -157,6 +197,23 @@ struct i801_priv { - unsigned char original_hstcfg; - struct pci_dev *pci_dev; - unsigned int features; -+ -+ /* isr processing */ -+ wait_queue_head_t waitq; -+ u8 status; -+ -+ /* Command state used by isr for byte-by-byte block transactions */ -+ u8 cmd; -+ bool is_read; -+ int count; -+ int len; -+ u8 *data; -+ -+#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ -+ defined CONFIG_DMI -+ const struct i801_mux_config *mux_drvdata; -+ struct platform_device *mux_pdev; -+#endif - }; - - static struct pci_driver i801_driver; -@@ -165,6 +222,7 @@ static struct pci_driver i801_driver; - #define FEATURE_BLOCK_BUFFER (1 << 1) - #define FEATURE_BLOCK_PROC (1 << 2) - #define FEATURE_I2C_BLOCK_READ (1 << 3) -+#define FEATURE_IRQ (1 << 4) - /* Not really a feature, but it's convenient to handle it as such */ - #define FEATURE_IDF (1 << 15) - -@@ -173,11 +231,16 @@ static const char *i801_feature_names[] = { - "Block buffer", - "Block process call", - "I2C block read", -+ "Interrupt", - }; - - static unsigned int disable_features; - module_param(disable_features, uint, S_IRUGO | S_IWUSR); --MODULE_PARM_DESC(disable_features, "Disable selected driver features"); -+MODULE_PARM_DESC(disable_features, "Disable selected driver features:\n" -+ "\t\t 0x01 disable SMBus PEC\n" -+ "\t\t 0x02 disable the block buffer\n" -+ "\t\t 0x08 disable the I2C block read functionality\n" -+ "\t\t 0x10 don't use interrupts "); - - /* Make sure the SMBus host is ready to start transmitting. - Return 0 if it is, -EBUSY if it is not. */ -@@ -208,19 +271,28 @@ static int i801_check_pre(struct i801_priv *priv) - return 0; - } - --/* Convert the status register to an error code, and clear it. */ --static int i801_check_post(struct i801_priv *priv, int status, int timeout) -+/* -+ * Convert the status register to an error code, and clear it. -+ * Note that status only contains the bits we want to clear, not the -+ * actual register value. -+ */ -+static int i801_check_post(struct i801_priv *priv, int status) - { - int result = 0; - -- /* If the SMBus is still busy, we give up */ -- if (timeout) { -+ /* -+ * If the SMBus is still busy, we give up -+ * Note: This timeout condition only happens when using polling -+ * transactions. For interrupt operation, NAK/timeout is indicated by -+ * DEV_ERR. -+ */ -+ if (unlikely(status < 0)) { - dev_err(&priv->pci_dev->dev, "Transaction timeout\n"); - /* try to stop the current command */ - dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n"); - outb_p(inb_p(SMBHSTCNT(priv)) | SMBHSTCNT_KILL, - SMBHSTCNT(priv)); -- msleep(1); -+ usleep_range(1000, 2000); - outb_p(inb_p(SMBHSTCNT(priv)) & (~SMBHSTCNT_KILL), - SMBHSTCNT(priv)); - -@@ -247,64 +319,76 @@ static int i801_check_post(struct i801_priv *priv, int status, int timeout) - dev_dbg(&priv->pci_dev->dev, "Lost arbitration\n"); - } - -- if (result) { -- /* Clear error flags */ -- outb_p(status & STATUS_FLAGS, SMBHSTSTS(priv)); -- status = inb_p(SMBHSTSTS(priv)) & STATUS_FLAGS; -- if (status) { -- dev_warn(&priv->pci_dev->dev, "Failed clearing status " -- "flags at end of transaction (%02x)\n", -- status); -- } -- } -+ /* Clear status flags except BYTE_DONE, to be cleared by caller */ -+ outb_p(status, SMBHSTSTS(priv)); - - return result; - } - --static int i801_transaction(struct i801_priv *priv, int xact) -+/* Wait for BUSY being cleared and either INTR or an error flag being set */ -+static int i801_wait_intr(struct i801_priv *priv) - { -- int status; -- int result; - int timeout = 0; -- -- result = i801_check_pre(priv); -- if (result < 0) -- return result; -- -- /* the current contents of SMBHSTCNT can be overwritten, since PEC, -- * INTREN, SMBSCMD are passed in xact */ -- outb_p(xact | I801_START, SMBHSTCNT(priv)); -+ int status; - - /* We will always wait for a fraction of a second! */ - do { -- msleep(1); -+ usleep_range(250, 500); - status = inb_p(SMBHSTSTS(priv)); -- } while ((status & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT)); -- -- result = i801_check_post(priv, status, timeout > MAX_TIMEOUT); -- if (result < 0) -- return result; -+ } while (((status & SMBHSTSTS_HOST_BUSY) || -+ !(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR))) && -+ (timeout++ < MAX_RETRIES)); - -- outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv)); -- return 0; -+ if (timeout > MAX_RETRIES) { -+ dev_dbg(&priv->pci_dev->dev, "INTR Timeout!\n"); -+ return -ETIMEDOUT; -+ } -+ return status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR); - } - --/* wait for INTR bit as advised by Intel */ --static void i801_wait_hwpec(struct i801_priv *priv) -+/* Wait for either BYTE_DONE or an error flag being set */ -+static int i801_wait_byte_done(struct i801_priv *priv) - { - int timeout = 0; - int status; - -+ /* We will always wait for a fraction of a second! */ - do { -- msleep(1); -+ usleep_range(250, 500); - status = inb_p(SMBHSTSTS(priv)); -- } while ((!(status & SMBHSTSTS_INTR)) -- && (timeout++ < MAX_TIMEOUT)); -+ } while (!(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE)) && -+ (timeout++ < MAX_RETRIES)); - -- if (timeout > MAX_TIMEOUT) -- dev_dbg(&priv->pci_dev->dev, "PEC Timeout!\n"); -+ if (timeout > MAX_RETRIES) { -+ dev_dbg(&priv->pci_dev->dev, "BYTE_DONE Timeout!\n"); -+ return -ETIMEDOUT; -+ } -+ return status & STATUS_ERROR_FLAGS; -+} - -- outb_p(status, SMBHSTSTS(priv)); -+static int i801_transaction(struct i801_priv *priv, int xact) -+{ -+ int status; -+ int result; -+ -+ result = i801_check_pre(priv); -+ if (result < 0) -+ return result; -+ -+ if (priv->features & FEATURE_IRQ) { -+ outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START, -+ SMBHSTCNT(priv)); -+ wait_event(priv->waitq, (status = priv->status)); -+ priv->status = 0; -+ return i801_check_post(priv, status); -+ } -+ -+ /* the current contents of SMBHSTCNT can be overwritten, since PEC, -+ * SMBSCMD are passed in xact */ -+ outb_p(xact | SMBHSTCNT_START, SMBHSTCNT(priv)); -+ -+ status = i801_wait_intr(priv); -+ return i801_check_post(priv, status); - } - - static int i801_block_transaction_by_block(struct i801_priv *priv, -@@ -324,8 +408,8 @@ static int i801_block_transaction_by_block(struct i801_priv *priv, - outb_p(data->block[i+1], SMBBLKDAT(priv)); - } - -- status = i801_transaction(priv, I801_BLOCK_DATA | ENABLE_INT9 | -- I801_PEC_EN * hwpec); -+ status = i801_transaction(priv, I801_BLOCK_DATA | -+ (hwpec ? SMBHSTCNT_PEC_EN : 0)); - if (status) - return status; - -@@ -341,6 +425,98 @@ static int i801_block_transaction_by_block(struct i801_priv *priv, - return 0; - } - -+static void i801_isr_byte_done(struct i801_priv *priv) -+{ -+ if (priv->is_read) { -+ /* For SMBus block reads, length is received with first byte */ -+ if (((priv->cmd & 0x1c) == I801_BLOCK_DATA) && -+ (priv->count == 0)) { -+ priv->len = inb_p(SMBHSTDAT0(priv)); -+ if (priv->len < 1 || priv->len > I2C_SMBUS_BLOCK_MAX) { -+ dev_err(&priv->pci_dev->dev, -+ "Illegal SMBus block read size %d\n", -+ priv->len); -+ /* FIXME: Recover */ -+ priv->len = I2C_SMBUS_BLOCK_MAX; -+ } else { -+ dev_dbg(&priv->pci_dev->dev, -+ "SMBus block read size is %d\n", -+ priv->len); -+ } -+ priv->data[-1] = priv->len; -+ } -+ -+ /* Read next byte */ -+ if (priv->count < priv->len) -+ priv->data[priv->count++] = inb(SMBBLKDAT(priv)); -+ else -+ dev_dbg(&priv->pci_dev->dev, -+ "Discarding extra byte on block read\n"); -+ -+ /* Set LAST_BYTE for last byte of read transaction */ -+ if (priv->count == priv->len - 1) -+ outb_p(priv->cmd | SMBHSTCNT_LAST_BYTE, -+ SMBHSTCNT(priv)); -+ } else if (priv->count < priv->len - 1) { -+ /* Write next byte, except for IRQ after last byte */ -+ outb_p(priv->data[++priv->count], SMBBLKDAT(priv)); -+ } -+ -+ /* Clear BYTE_DONE to continue with next byte */ -+ outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv)); -+} -+ -+/* -+ * There are two kinds of interrupts: -+ * -+ * 1) i801 signals transaction completion with one of these interrupts: -+ * INTR - Success -+ * DEV_ERR - Invalid command, NAK or communication timeout -+ * BUS_ERR - SMI# transaction collision -+ * FAILED - transaction was canceled due to a KILL request -+ * When any of these occur, update ->status and wake up the waitq. -+ * ->status must be cleared before kicking off the next transaction. -+ * -+ * 2) For byte-by-byte (I2C read/write) transactions, one BYTE_DONE interrupt -+ * occurs for each byte of a byte-by-byte to prepare the next byte. -+ */ -+static irqreturn_t i801_isr(int irq, void *dev_id) -+{ -+ struct i801_priv *priv = dev_id; -+ u16 pcists; -+ u8 status; -+ -+ /* Confirm this is our interrupt */ -+ pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists); -+ if (!(pcists & SMBPCISTS_INTS)) -+ return IRQ_NONE; -+ -+ status = inb_p(SMBHSTSTS(priv)); -+ if (status != 0x42) -+ dev_dbg(&priv->pci_dev->dev, "irq: status = %02x\n", status); -+ -+ if (status & SMBHSTSTS_BYTE_DONE) -+ i801_isr_byte_done(priv); -+ -+ /* -+ * Clear irq sources and report transaction result. -+ * ->status must be cleared before the next transaction is started. -+ */ -+ status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS; -+ if (status) { -+ outb_p(status, SMBHSTSTS(priv)); -+ priv->status |= status; -+ wake_up(&priv->waitq); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+/* -+ * For "byte-by-byte" block transactions: -+ * I2C write uses cmd=I801_BLOCK_DATA, I2C_EN=1 -+ * I2C read uses cmd=I801_I2C_BLOCK_DATA -+ */ - static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, - union i2c_smbus_data *data, - char read_write, int command, -@@ -350,7 +526,6 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, - int smbcmd; - int status; - int result; -- int timeout; - - result = i801_check_pre(priv); - if (result < 0) -@@ -363,36 +538,39 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, - outb_p(data->block[1], SMBBLKDAT(priv)); - } - -+ if (command == I2C_SMBUS_I2C_BLOCK_DATA && -+ read_write == I2C_SMBUS_READ) -+ smbcmd = I801_I2C_BLOCK_DATA; -+ else -+ smbcmd = I801_BLOCK_DATA; -+ -+ if (priv->features & FEATURE_IRQ) { -+ priv->is_read = (read_write == I2C_SMBUS_READ); -+ if (len == 1 && priv->is_read) -+ smbcmd |= SMBHSTCNT_LAST_BYTE; -+ priv->cmd = smbcmd | SMBHSTCNT_INTREN; -+ priv->len = len; -+ priv->count = 0; -+ priv->data = &data->block[1]; -+ -+ outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv)); -+ wait_event(priv->waitq, (status = priv->status)); -+ priv->status = 0; -+ return i801_check_post(priv, status); -+ } -+ - for (i = 1; i <= len; i++) { -- if (i == len && read_write == I2C_SMBUS_READ) { -- if (command == I2C_SMBUS_I2C_BLOCK_DATA) -- smbcmd = I801_I2C_BLOCK_LAST; -- else -- smbcmd = I801_BLOCK_LAST; -- } else { -- if (command == I2C_SMBUS_I2C_BLOCK_DATA -- && read_write == I2C_SMBUS_READ) -- smbcmd = I801_I2C_BLOCK_DATA; -- else -- smbcmd = I801_BLOCK_DATA; -- } -- outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT(priv)); -+ if (i == len && read_write == I2C_SMBUS_READ) -+ smbcmd |= SMBHSTCNT_LAST_BYTE; -+ outb_p(smbcmd, SMBHSTCNT(priv)); - - if (i == 1) -- outb_p(inb(SMBHSTCNT(priv)) | I801_START, -+ outb_p(inb(SMBHSTCNT(priv)) | SMBHSTCNT_START, - SMBHSTCNT(priv)); - -- /* We will always wait for a fraction of a second! */ -- timeout = 0; -- do { -- msleep(1); -- status = inb_p(SMBHSTSTS(priv)); -- } while ((!(status & SMBHSTSTS_BYTE_DONE)) -- && (timeout++ < MAX_TIMEOUT)); -- -- result = i801_check_post(priv, status, timeout > MAX_TIMEOUT); -- if (result < 0) -- return result; -+ status = i801_wait_byte_done(priv); -+ if (status) -+ goto exit; - - if (i == 1 && read_write == I2C_SMBUS_READ - && command != I2C_SMBUS_I2C_BLOCK_DATA) { -@@ -419,10 +597,12 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, - outb_p(data->block[i+1], SMBBLKDAT(priv)); - - /* signals SMBBLKDAT ready */ -- outb_p(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR, SMBHSTSTS(priv)); -+ outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv)); - } - -- return 0; -+ status = i801_wait_intr(priv); -+exit: -+ return i801_check_post(priv, status); - } - - static int i801_set_block_buffer_mode(struct i801_priv *priv) -@@ -477,9 +657,6 @@ static int i801_block_transaction(struct i801_priv *priv, - read_write, - command, hwpec); - -- if (result == 0 && hwpec) -- i801_wait_hwpec(priv); -- - if (command == I2C_SMBUS_I2C_BLOCK_DATA - && read_write == I2C_SMBUS_WRITE) { - /* restore saved configuration register value */ -@@ -567,7 +744,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, - ret = i801_block_transaction(priv, data, read_write, size, - hwpec); - else -- ret = i801_transaction(priv, xact | ENABLE_INT9); -+ ret = i801_transaction(priv, xact); - - /* Some BIOSes don't like it when PEC is enabled at reboot or resume - time, so we forcibly disable it after every transaction. Turn off -@@ -641,6 +818,13 @@ static const struct pci_device_id i801_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMBUS) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) }, - { 0, } - }; - -@@ -684,14 +868,14 @@ struct dmi_onboard_device_info { - const char *i2c_type; - }; - --static struct dmi_onboard_device_info __devinitdata dmi_devices[] = { -+static const struct dmi_onboard_device_info dmi_devices[] = { - { "Syleus", DMI_DEV_TYPE_OTHER, 0x73, "fscsyl" }, - { "Hermes", DMI_DEV_TYPE_OTHER, 0x73, "fscher" }, - { "Hades", DMI_DEV_TYPE_OTHER, 0x73, "fschds" }, - }; - --static void __devinit dmi_check_onboard_device(u8 type, const char *name, -- struct i2c_adapter *adap) -+static void dmi_check_onboard_device(u8 type, const char *name, -+ struct i2c_adapter *adap) - { - int i; - struct i2c_board_info info; -@@ -714,8 +898,7 @@ static void __devinit dmi_check_onboard_device(u8 type, const char *name, - /* We use our own function to check for onboard devices instead of - dmi_find_device() as some buggy BIOS's have the devices we are interested - in marked as disabled */ --static void __devinit dmi_check_onboard_devices(const struct dmi_header *dm, -- void *adap) -+static void dmi_check_onboard_devices(const struct dmi_header *dm, void *adap) - { - int i, count; - -@@ -744,7 +927,7 @@ static void __devinit dmi_check_onboard_devices(const struct dmi_header *dm, - } - - /* Register optional slaves */ --static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) -+static void i801_probe_optional_slaves(struct i801_priv *priv) - { - /* Only register slaves on main SMBus channel */ - if (priv->features & FEATURE_IDF) -@@ -764,11 +947,170 @@ static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) - } - #else - static void __init input_apanel_init(void) {} --static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {} -+static void i801_probe_optional_slaves(struct i801_priv *priv) {} - #endif /* CONFIG_X86 && CONFIG_DMI */ - --static int __devinit i801_probe(struct pci_dev *dev, -- const struct pci_device_id *id) -+#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ -+ defined CONFIG_DMI -+static struct i801_mux_config i801_mux_config_asus_z8_d12 = { -+ .gpio_chip = "gpio_ich", -+ .values = { 0x02, 0x03 }, -+ .n_values = 2, -+ .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD }, -+ .gpios = { 52, 53 }, -+ .n_gpios = 2, -+}; -+ -+static struct i801_mux_config i801_mux_config_asus_z8_d18 = { -+ .gpio_chip = "gpio_ich", -+ .values = { 0x02, 0x03, 0x01 }, -+ .n_values = 3, -+ .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD, I2C_CLASS_SPD }, -+ .gpios = { 52, 53 }, -+ .n_gpios = 2, -+}; -+ -+static const struct dmi_system_id mux_dmi_table[] = { -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "Z8NA-D6(C)"), -+ }, -+ .driver_data = &i801_mux_config_asus_z8_d12, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)E-D12(X)"), -+ }, -+ .driver_data = &i801_mux_config_asus_z8_d12, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "Z8NH-D12"), -+ }, -+ .driver_data = &i801_mux_config_asus_z8_d12, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "Z8PH-D12/IFB"), -+ }, -+ .driver_data = &i801_mux_config_asus_z8_d12, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "Z8NR-D12"), -+ }, -+ .driver_data = &i801_mux_config_asus_z8_d12, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)H-D12"), -+ }, -+ .driver_data = &i801_mux_config_asus_z8_d12, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "Z8PG-D18"), -+ }, -+ .driver_data = &i801_mux_config_asus_z8_d18, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "Z8PE-D18"), -+ }, -+ .driver_data = &i801_mux_config_asus_z8_d18, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "Z8PS-D12"), -+ }, -+ .driver_data = &i801_mux_config_asus_z8_d12, -+ }, -+ { } -+}; -+ -+/* Setup multiplexing if needed */ -+static int i801_add_mux(struct i801_priv *priv) -+{ -+ struct device *dev = &priv->adapter.dev; -+ const struct i801_mux_config *mux_config; -+ struct i2c_mux_gpio_platform_data gpio_data; -+ int err; -+ -+ if (!priv->mux_drvdata) -+ return 0; -+ mux_config = priv->mux_drvdata; -+ -+ /* Prepare the platform data */ -+ memset(&gpio_data, 0, sizeof(struct i2c_mux_gpio_platform_data)); -+ gpio_data.parent = priv->adapter.nr; -+ gpio_data.values = mux_config->values; -+ gpio_data.n_values = mux_config->n_values; -+ gpio_data.classes = mux_config->classes; -+ gpio_data.gpio_chip = mux_config->gpio_chip; -+ gpio_data.gpios = mux_config->gpios; -+ gpio_data.n_gpios = mux_config->n_gpios; -+ gpio_data.idle = I2C_MUX_GPIO_NO_IDLE; -+ -+ /* Register the mux device */ -+ priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio", -+ PLATFORM_DEVID_AUTO, &gpio_data, -+ sizeof(struct i2c_mux_gpio_platform_data)); -+ if (IS_ERR(priv->mux_pdev)) { -+ err = PTR_ERR(priv->mux_pdev); -+ priv->mux_pdev = NULL; -+ dev_err(dev, "Failed to register i2c-mux-gpio device\n"); -+ return err; -+ } -+ -+ return 0; -+} -+ -+static void i801_del_mux(struct i801_priv *priv) -+{ -+ if (priv->mux_pdev) -+ platform_device_unregister(priv->mux_pdev); -+} -+ -+static unsigned int i801_get_adapter_class(struct i801_priv *priv) -+{ -+ const struct dmi_system_id *id; -+ const struct i801_mux_config *mux_config; -+ unsigned int class = I2C_CLASS_HWMON | I2C_CLASS_SPD; -+ int i; -+ -+ id = dmi_first_match(mux_dmi_table); -+ if (id) { -+ /* Remove branch classes from trunk */ -+ mux_config = id->driver_data; -+ for (i = 0; i < mux_config->n_values; i++) -+ class &= ~mux_config->classes[i]; -+ -+ /* Remember for later */ -+ priv->mux_drvdata = mux_config; -+ } -+ -+ return class; -+} -+#else -+static inline int i801_add_mux(struct i801_priv *priv) { return 0; } -+static inline void i801_del_mux(struct i801_priv *priv) { } -+ -+static inline unsigned int i801_get_adapter_class(struct i801_priv *priv) -+{ -+ return I2C_CLASS_HWMON | I2C_CLASS_SPD; -+} -+#endif -+ -+static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) - { - unsigned char temp; - int err, i; -@@ -780,7 +1122,7 @@ static int __devinit i801_probe(struct pci_dev *dev, - - i2c_set_adapdata(&priv->adapter, priv); - priv->adapter.owner = THIS_MODULE; -- priv->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; -+ priv->adapter.class = i801_get_adapter_class(priv); - priv->adapter.algo = &smbus_algorithm; - - priv->pci_dev = dev; -@@ -788,10 +1130,14 @@ static int __devinit i801_probe(struct pci_dev *dev, - case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0: - case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1: - case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2: -+ case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0: -+ case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1: -+ case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2: - priv->features |= FEATURE_IDF; - /* fall through */ - default: - priv->features |= FEATURE_I2C_BLOCK_READ; -+ priv->features |= FEATURE_IRQ; - /* fall through */ - case PCI_DEVICE_ID_INTEL_82801DB_3: - priv->features |= FEATURE_SMBUS_PEC; -@@ -851,16 +1197,30 @@ static int __devinit i801_probe(struct pci_dev *dev, - } - pci_write_config_byte(priv->pci_dev, SMBHSTCFG, temp); - -- if (temp & SMBHSTCFG_SMB_SMI_EN) -+ if (temp & SMBHSTCFG_SMB_SMI_EN) { - dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n"); -- else -- dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n"); -+ /* Disable SMBus interrupt feature if SMBus using SMI# */ -+ priv->features &= ~FEATURE_IRQ; -+ } - - /* Clear special mode bits */ - if (priv->features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER)) - outb_p(inb_p(SMBAUXCTL(priv)) & - ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv)); - -+ if (priv->features & FEATURE_IRQ) { -+ init_waitqueue_head(&priv->waitq); -+ -+ err = request_irq(dev->irq, i801_isr, IRQF_SHARED, -+ i801_driver.name, priv); -+ if (err) { -+ dev_err(&dev->dev, "Failed to allocate irq %d: %d\n", -+ dev->irq, err); -+ goto exit_release; -+ } -+ dev_info(&dev->dev, "SMBus using PCI Interrupt\n"); -+ } -+ - /* set up the sysfs linkage to our parent device */ - priv->adapter.dev.parent = &dev->dev; - -@@ -872,14 +1232,20 @@ static int __devinit i801_probe(struct pci_dev *dev, - err = i2c_add_adapter(&priv->adapter); - if (err) { - dev_err(&dev->dev, "Failed to add SMBus adapter\n"); -- goto exit_release; -+ goto exit_free_irq; - } - - i801_probe_optional_slaves(priv); -+ /* We ignore errors - multiplexing is optional */ -+ i801_add_mux(priv); - - pci_set_drvdata(dev, priv); -+ - return 0; - -+exit_free_irq: -+ if (priv->features & FEATURE_IRQ) -+ free_irq(dev->irq, priv); - exit_release: - pci_release_region(dev, SMBBAR); - exit: -@@ -887,14 +1253,18 @@ exit: - return err; - } - --static void __devexit i801_remove(struct pci_dev *dev) -+static void i801_remove(struct pci_dev *dev) - { - struct i801_priv *priv = pci_get_drvdata(dev); - -+ i801_del_mux(priv); - i2c_del_adapter(&priv->adapter); - pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); -+ -+ if (priv->features & FEATURE_IRQ) -+ free_irq(dev->irq, priv); - pci_release_region(dev, SMBBAR); -- pci_set_drvdata(dev, NULL); -+ - kfree(priv); - /* - * do not call pci_disable_device(dev) since it can cause hard hangs on -@@ -928,7 +1298,7 @@ static struct pci_driver i801_driver = { - .name = "i801_smbus", - .id_table = i801_ids, - .probe = i801_probe, -- .remove = __devexit_p(i801_remove), -+ .remove = i801_remove, - .suspend = i801_suspend, - .resume = i801_resume, - }; -@@ -945,8 +1315,7 @@ static void __exit i2c_i801_exit(void) - pci_unregister_driver(&i801_driver); - } - --MODULE_AUTHOR("Mark D. Studebaker , " -- "Jean Delvare "); -+MODULE_AUTHOR("Mark D. Studebaker , Jean Delvare "); - MODULE_DESCRIPTION("I801 SMBus driver"); - MODULE_LICENSE("GPL"); - -diff --git a/include/linux/i2c-mux-gpio.h b/include/linux/i2c-mux-gpio.h -new file mode 100644 -index 0000000..4406108 ---- /dev/null -+++ b/include/linux/i2c-mux-gpio.h -@@ -0,0 +1,43 @@ -+/* -+ * i2c-mux-gpio interface to platform code -+ * -+ * Peter Korsgaard -+ * -+ * 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 _LINUX_I2C_MUX_GPIO_H -+#define _LINUX_I2C_MUX_GPIO_H -+ -+/* MUX has no specific idle mode */ -+#define I2C_MUX_GPIO_NO_IDLE ((unsigned)-1) -+ -+/** -+ * struct i2c_mux_gpio_platform_data - Platform-dependent data for i2c-mux-gpio -+ * @parent: Parent I2C bus adapter number -+ * @base_nr: Base I2C bus number to number adapters from or zero for dynamic -+ * @values: Array of bitmasks of GPIO settings (low/high) for each -+ * position -+ * @n_values: Number of multiplexer positions (busses to instantiate) -+ * @classes: Optional I2C auto-detection classes -+ * @gpio_chip: Optional GPIO chip name; if set, GPIO pin numbers are given -+ * relative to the base GPIO number of that chip -+ * @gpios: Array of GPIO numbers used to control MUX -+ * @n_gpios: Number of GPIOs used to control MUX -+ * @idle: Bitmask to write to MUX when idle or GPIO_I2CMUX_NO_IDLE if not used -+ */ -+struct i2c_mux_gpio_platform_data { -+ int parent; -+ int base_nr; -+ const unsigned *values; -+ int n_values; -+ const unsigned *classes; -+ char *gpio_chip; -+ const unsigned *gpios; -+ int n_gpios; -+ unsigned idle; -+}; -+ -+#endif /* _LINUX_I2C_MUX_GPIO_H */ -diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h -index 165a8d1..4cf54aa 100644 ---- a/include/linux/platform_device.h -+++ b/include/linux/platform_device.h -@@ -14,6 +14,9 @@ - #include - #include - -+#define PLATFORM_DEVID_NONE (-1) -+#define PLATFORM_DEVID_AUTO (-2) -+ - struct mfd_cell; - - struct platform_device { diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-ismt-add-delay-param.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-ismt-add-delay-param.patch deleted file mode 100644 index 8113f5e8..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-ismt-add-delay-param.patch +++ /dev/null @@ -1,50 +0,0 @@ -Add 'delay' module param to the driver. This is needed on S6000 for safe PMBUS -access. Without setting the 'delay', the ismt driver throws 'completion wait -timed out' error message. - -diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c -index 09a3e03..44f54ff 100644 ---- a/drivers/i2c/busses/i2c-ismt.c -+++ b/drivers/i2c/busses/i2c-ismt.c -@@ -70,6 +70,7 @@ - #include - #include - #include -+#include - - #include - -@@ -192,9 +193,12 @@ static DEFINE_PCI_DEVICE_TABLE(ismt_ids) = { - MODULE_DEVICE_TABLE(pci, ismt_ids); - - /* Bus speed control bits for slow debuggers - refer to the docs for usage */ --static unsigned int bus_speed; -+static unsigned int bus_speed = 100; -+static unsigned int delay = 1000; - module_param(bus_speed, uint, S_IRUGO); --MODULE_PARM_DESC(bus_speed, "Bus Speed in kHz (0 = BIOS default)"); -+MODULE_PARM_DESC(bus_speed, "Bus Speed in kHz (1000 by default)"); -+module_param(delay, uint, S_IRUGO); -+MODULE_PARM_DESC(delay, "Delay in microsecs before access (1000 by default)"); - - /** - * __ismt_desc_dump() - dump the contents of a specific descriptor -@@ -391,6 +395,9 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr, - struct ismt_priv *priv = i2c_get_adapdata(adap); - struct device *dev = &priv->pci_dev->dev; - -+ if (delay > 0) -+ udelay(delay); -+ - desc = &priv->hw[priv->head]; - - /* Initialize the DMA buffer */ -@@ -756,7 +763,7 @@ static void ismt_hw_init(struct ismt_priv *priv) - bus_speed = 1000; - break; - } -- dev_dbg(dev, "SMBus clock is running at %d kHz\n", bus_speed); -+ dev_info(dev, "SMBus clock is running at %d kHz with delay %d us\n", bus_speed, delay); - } - - /** diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-ismt-header.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-ismt-header.patch deleted file mode 100644 index 06d27574..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-ismt-header.patch +++ /dev/null @@ -1,159 +0,0 @@ -Seperating the ismt_priv structure into a i2c-ismt.h that can they be used in -platform modules like dell_s6000_platform - -diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c -index 44f54ff..9058fc6 100644 ---- a/drivers/i2c/busses/i2c-ismt.c -+++ b/drivers/i2c/busses/i2c-ismt.c -@@ -62,15 +62,12 @@ - */ - - #include --#include - #include - #include --#include --#include --#include - #include - #include - #include -+#include - - #include - -@@ -150,36 +147,9 @@ - #define ISMT_SPGT_SPD_400K (0x2 << 30) /* 400 kHz */ - #define ISMT_SPGT_SPD_1M (0x3 << 30) /* 1 MHz */ - -- - /* MSI Control Register (MSICTL) bit definitions */ - #define ISMT_MSICTL_MSIE 0x01 /* MSI Enable */ - --/* iSMT Hardware Descriptor */ --struct ismt_desc { -- u8 tgtaddr_rw; /* target address & r/w bit */ -- u8 wr_len_cmd; /* write length in bytes or a command */ -- u8 rd_len; /* read length */ -- u8 control; /* control bits */ -- u8 status; /* status bits */ -- u8 retry; /* collision retry and retry count */ -- u8 rxbytes; /* received bytes */ -- u8 txbytes; /* transmitted bytes */ -- u32 dptr_low; /* lower 32 bit of the data pointer */ -- u32 dptr_high; /* upper 32 bit of the data pointer */ --} __packed; -- --struct ismt_priv { -- struct i2c_adapter adapter; -- void *smba; /* PCI BAR */ -- struct pci_dev *pci_dev; -- struct ismt_desc *hw; /* descriptor virt base addr */ -- dma_addr_t io_rng_dma; /* descriptor HW base addr */ -- u8 head; /* ring buffer head pointer */ -- struct completion cmp; /* interrupt completion */ -- u8 dma_buffer[I2C_SMBUS_BLOCK_MAX + 1]; /* temp R/W data buffer */ -- bool using_msi; /* type of interrupt flag */ --}; -- - /** - * ismt_ids - PCI device IDs supported by this driver - */ -diff --git a/include/linux/i2c-ismt.h b/include/linux/i2c-ismt.h -new file mode 100644 -index 0000000..98be6d7 ---- /dev/null -+++ b/include/linux/i2c-ismt.h -@@ -0,0 +1,92 @@ -+/* -+ * This file is provided under a dual BSD/GPLv2 license. When using or -+ * redistributing this file, you may do so under either license. -+ * -+ * Copyright(c) 2012 Intel Corporation. All rights reserved. -+ * -+ * GPL LICENSE SUMMARY -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of version 2 of the GNU General Public License as -+ * published by the Free Software Foundation. -+ * -+ * 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 St - Fifth Floor, Boston, MA 02110-1301 USA. -+ * The full GNU General Public License is included in this distribution -+ * in the file called LICENSE.GPL. -+ * -+ * BSD LICENSE -+ * -+ * 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 Intel Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * 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 -+ * OWNER 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. -+ */ -+ -+/* -+ * Supports the SMBus Message Transport (SMT) in the Intel Atom Processor -+ * S12xx Product Family. -+ * -+ * Features supported by this driver: -+ * Hardware PEC yes -+ * Block buffer yes -+ * Block process call transaction no -+ * Slave mode no -+ */ -+#include -+#include -+#include -+#include -+ -+/* iSMT Hardware Descriptor */ -+struct ismt_desc { -+ u8 tgtaddr_rw; /* target address & r/w bit */ -+ u8 wr_len_cmd; /* write length in bytes or a command */ -+ u8 rd_len; /* read length */ -+ u8 control; /* control bits */ -+ u8 status; /* status bits */ -+ u8 retry; /* collision retry and retry count */ -+ u8 rxbytes; /* received bytes */ -+ u8 txbytes; /* transmitted bytes */ -+ u32 dptr_low; /* lower 32 bit of the data pointer */ -+ u32 dptr_high; /* upper 32 bit of the data pointer */ -+} __packed; -+ -+struct ismt_priv { -+ struct i2c_adapter adapter; -+ void *smba; /* PCI BAR */ -+ struct pci_dev *pci_dev; -+ struct ismt_desc *hw; /* descriptor virt base addr */ -+ dma_addr_t io_rng_dma; /* descriptor HW base addr */ -+ u8 head; /* ring buffer head pointer */ -+ struct completion cmp; /* interrupt completion */ -+ u8 dma_buffer[I2C_SMBUS_BLOCK_MAX + 1]; /* temp R/W data buffer */ -+ bool using_msi; /* type of interrupt flag */ -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-ismt.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-ismt.patch deleted file mode 100644 index 58c88b17..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-bus-intel-ismt.patch +++ /dev/null @@ -1,1137 +0,0 @@ -Back port i2c-ismt.c bus driver for Atom CPUs. - -See linux-stable commit 13f35ac14cd0a9a1c4f0034c4c40d0ae98844ce9: - -i2c: Adding support for Intel iSMT SMBus 2.0 host controller - -The iSMT (Intel SMBus Message Transport) supports multi-master I2C/SMBus, -as well as IPMI. It's operation is DMA-based and utilizes descriptors to -initiate transactions on the bus. - -The iSMT hardware can act as both a master and a target, although this -driver only supports being a master. -Summary: - -diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig -index 949ea64..8f29057 100644 ---- a/drivers/i2c/busses/Kconfig -+++ b/drivers/i2c/busses/Kconfig -@@ -120,6 +120,16 @@ config I2C_ISCH - This driver can also be built as a module. If so, the module - will be called i2c-isch. - -+config I2C_ISMT -+ tristate "Intel iSMT SMBus Controller" -+ depends on PCI && X86 -+ help -+ If you say yes to this option, support will be included for the Intel -+ iSMT SMBus host controller interface. -+ -+ This driver can also be built as a module. If so, the module will be -+ called i2c-ismt. -+ - config I2C_PIIX4 - tristate "Intel PIIX4 and compatible (ATI/AMD/Serverworks/Broadcom/SMSC)" - depends on PCI -diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile -index d6b8779..070adee 100644 ---- a/drivers/i2c/busses/Makefile -+++ b/drivers/i2c/busses/Makefile -@@ -14,6 +14,7 @@ obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o - obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o - obj-$(CONFIG_I2C_I801) += i2c-i801.o - obj-$(CONFIG_I2C_ISCH) += i2c-isch.o -+obj-$(CONFIG_I2C_ISMT) += i2c-ismt.o - obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o - obj-$(CONFIG_I2C_NFORCE2_S4985) += i2c-nforce2-s4985.o - obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o -diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c -new file mode 100644 -index 0000000..09a3e03 ---- /dev/null -+++ b/drivers/i2c/busses/i2c-ismt.c -@@ -0,0 +1,1016 @@ -+/* -+ * This file is provided under a dual BSD/GPLv2 license. When using or -+ * redistributing this file, you may do so under either license. -+ * -+ * Copyright(c) 2012 Intel Corporation. All rights reserved. -+ * -+ * GPL LICENSE SUMMARY -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of version 2 of the GNU General Public License as -+ * published by the Free Software Foundation. -+ * -+ * 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 St - Fifth Floor, Boston, MA 02110-1301 USA. -+ * The full GNU General Public License is included in this distribution -+ * in the file called LICENSE.GPL. -+ * -+ * BSD LICENSE -+ * -+ * 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 Intel Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * 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 -+ * OWNER 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. -+ */ -+ -+/* -+ * Supports the SMBus Message Transport (SMT) in the Intel Atom Processor -+ * S12xx Product Family. -+ * -+ * Features supported by this driver: -+ * Hardware PEC yes -+ * Block buffer yes -+ * Block process call transaction no -+ * Slave mode no -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+/* PCI Address Constants */ -+#define SMBBAR 0 -+ -+/* PCI DIDs for the Intel SMBus Message Transport (SMT) Devices */ -+#define PCI_DEVICE_ID_INTEL_S1200_SMT0 0x0c59 -+#define PCI_DEVICE_ID_INTEL_S1200_SMT1 0x0c5a -+#define PCI_DEVICE_ID_INTEL_AVOTON_SMT 0x1f15 -+ -+#define ISMT_DESC_ENTRIES 32 /* number of descriptor entries */ -+#define ISMT_MAX_RETRIES 3 /* number of SMBus retries to attempt */ -+ -+/* Hardware Descriptor Constants - Control Field */ -+#define ISMT_DESC_CWRL 0x01 /* Command/Write Length */ -+#define ISMT_DESC_BLK 0X04 /* Perform Block Transaction */ -+#define ISMT_DESC_FAIR 0x08 /* Set fairness flag upon successful arbit. */ -+#define ISMT_DESC_PEC 0x10 /* Packet Error Code */ -+#define ISMT_DESC_I2C 0x20 /* I2C Enable */ -+#define ISMT_DESC_INT 0x40 /* Interrupt */ -+#define ISMT_DESC_SOE 0x80 /* Stop On Error */ -+ -+/* Hardware Descriptor Constants - Status Field */ -+#define ISMT_DESC_SCS 0x01 /* Success */ -+#define ISMT_DESC_DLTO 0x04 /* Data Low Time Out */ -+#define ISMT_DESC_NAK 0x08 /* NAK Received */ -+#define ISMT_DESC_CRC 0x10 /* CRC Error */ -+#define ISMT_DESC_CLTO 0x20 /* Clock Low Time Out */ -+#define ISMT_DESC_COL 0x40 /* Collisions */ -+#define ISMT_DESC_LPR 0x80 /* Large Packet Received */ -+ -+/* Macros */ -+#define ISMT_DESC_ADDR_RW(addr, rw) (((addr) << 1) | (rw)) -+ -+/* iSMT General Register address offsets (SMBBAR + ) */ -+#define ISMT_GR_GCTRL 0x000 /* General Control */ -+#define ISMT_GR_SMTICL 0x008 /* SMT Interrupt Cause Location */ -+#define ISMT_GR_ERRINTMSK 0x010 /* Error Interrupt Mask */ -+#define ISMT_GR_ERRAERMSK 0x014 /* Error AER Mask */ -+#define ISMT_GR_ERRSTS 0x018 /* Error Status */ -+#define ISMT_GR_ERRINFO 0x01c /* Error Information */ -+ -+/* iSMT Master Registers */ -+#define ISMT_MSTR_MDBA 0x100 /* Master Descriptor Base Address */ -+#define ISMT_MSTR_MCTRL 0x108 /* Master Control */ -+#define ISMT_MSTR_MSTS 0x10c /* Master Status */ -+#define ISMT_MSTR_MDS 0x110 /* Master Descriptor Size */ -+#define ISMT_MSTR_RPOLICY 0x114 /* Retry Policy */ -+ -+/* iSMT Miscellaneous Registers */ -+#define ISMT_SPGT 0x300 /* SMBus PHY Global Timing */ -+ -+/* General Control Register (GCTRL) bit definitions */ -+#define ISMT_GCTRL_TRST 0x04 /* Target Reset */ -+#define ISMT_GCTRL_KILL 0x08 /* Kill */ -+#define ISMT_GCTRL_SRST 0x40 /* Soft Reset */ -+ -+/* Master Control Register (MCTRL) bit definitions */ -+#define ISMT_MCTRL_SS 0x01 /* Start/Stop */ -+#define ISMT_MCTRL_MEIE 0x10 /* Master Error Interrupt Enable */ -+#define ISMT_MCTRL_FMHP 0x00ff0000 /* Firmware Master Head Ptr (FMHP) */ -+ -+/* Master Status Register (MSTS) bit definitions */ -+#define ISMT_MSTS_HMTP 0xff0000 /* HW Master Tail Pointer (HMTP) */ -+#define ISMT_MSTS_MIS 0x20 /* Master Interrupt Status (MIS) */ -+#define ISMT_MSTS_MEIS 0x10 /* Master Error Int Status (MEIS) */ -+#define ISMT_MSTS_IP 0x01 /* In Progress */ -+ -+/* Master Descriptor Size (MDS) bit definitions */ -+#define ISMT_MDS_MASK 0xff /* Master Descriptor Size mask (MDS) */ -+ -+/* SMBus PHY Global Timing Register (SPGT) bit definitions */ -+#define ISMT_SPGT_SPD_MASK 0xc0000000 /* SMBus Speed mask */ -+#define ISMT_SPGT_SPD_80K 0x00 /* 80 kHz */ -+#define ISMT_SPGT_SPD_100K (0x1 << 30) /* 100 kHz */ -+#define ISMT_SPGT_SPD_400K (0x2 << 30) /* 400 kHz */ -+#define ISMT_SPGT_SPD_1M (0x3 << 30) /* 1 MHz */ -+ -+ -+/* MSI Control Register (MSICTL) bit definitions */ -+#define ISMT_MSICTL_MSIE 0x01 /* MSI Enable */ -+ -+/* iSMT Hardware Descriptor */ -+struct ismt_desc { -+ u8 tgtaddr_rw; /* target address & r/w bit */ -+ u8 wr_len_cmd; /* write length in bytes or a command */ -+ u8 rd_len; /* read length */ -+ u8 control; /* control bits */ -+ u8 status; /* status bits */ -+ u8 retry; /* collision retry and retry count */ -+ u8 rxbytes; /* received bytes */ -+ u8 txbytes; /* transmitted bytes */ -+ u32 dptr_low; /* lower 32 bit of the data pointer */ -+ u32 dptr_high; /* upper 32 bit of the data pointer */ -+} __packed; -+ -+struct ismt_priv { -+ struct i2c_adapter adapter; -+ void *smba; /* PCI BAR */ -+ struct pci_dev *pci_dev; -+ struct ismt_desc *hw; /* descriptor virt base addr */ -+ dma_addr_t io_rng_dma; /* descriptor HW base addr */ -+ u8 head; /* ring buffer head pointer */ -+ struct completion cmp; /* interrupt completion */ -+ u8 dma_buffer[I2C_SMBUS_BLOCK_MAX + 1]; /* temp R/W data buffer */ -+ bool using_msi; /* type of interrupt flag */ -+}; -+ -+/** -+ * ismt_ids - PCI device IDs supported by this driver -+ */ -+static DEFINE_PCI_DEVICE_TABLE(ismt_ids) = { -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT0) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT1) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMT) }, -+ { 0, } -+}; -+ -+MODULE_DEVICE_TABLE(pci, ismt_ids); -+ -+/* Bus speed control bits for slow debuggers - refer to the docs for usage */ -+static unsigned int bus_speed; -+module_param(bus_speed, uint, S_IRUGO); -+MODULE_PARM_DESC(bus_speed, "Bus Speed in kHz (0 = BIOS default)"); -+ -+/** -+ * __ismt_desc_dump() - dump the contents of a specific descriptor -+ */ -+static void __ismt_desc_dump(struct device *dev, const struct ismt_desc *desc) -+{ -+ -+ dev_dbg(dev, "Descriptor struct: %p\n", desc); -+ dev_dbg(dev, "\ttgtaddr_rw=0x%02X\n", desc->tgtaddr_rw); -+ dev_dbg(dev, "\twr_len_cmd=0x%02X\n", desc->wr_len_cmd); -+ dev_dbg(dev, "\trd_len= 0x%02X\n", desc->rd_len); -+ dev_dbg(dev, "\tcontrol= 0x%02X\n", desc->control); -+ dev_dbg(dev, "\tstatus= 0x%02X\n", desc->status); -+ dev_dbg(dev, "\tretry= 0x%02X\n", desc->retry); -+ dev_dbg(dev, "\trxbytes= 0x%02X\n", desc->rxbytes); -+ dev_dbg(dev, "\ttxbytes= 0x%02X\n", desc->txbytes); -+ dev_dbg(dev, "\tdptr_low= 0x%08X\n", desc->dptr_low); -+ dev_dbg(dev, "\tdptr_high= 0x%08X\n", desc->dptr_high); -+} -+/** -+ * ismt_desc_dump() - dump the contents of a descriptor for debug purposes -+ * @priv: iSMT private data -+ */ -+static void ismt_desc_dump(struct ismt_priv *priv) -+{ -+ struct device *dev = &priv->pci_dev->dev; -+ struct ismt_desc *desc = &priv->hw[priv->head]; -+ -+ dev_dbg(dev, "Dump of the descriptor struct: 0x%X\n", priv->head); -+ __ismt_desc_dump(dev, desc); -+} -+ -+/** -+ * ismt_gen_reg_dump() - dump the iSMT General Registers -+ * @priv: iSMT private data -+ */ -+static void ismt_gen_reg_dump(struct ismt_priv *priv) -+{ -+ struct device *dev = &priv->pci_dev->dev; -+ -+ dev_dbg(dev, "Dump of the iSMT General Registers\n"); -+ dev_dbg(dev, " GCTRL.... : (0x%p)=0x%X\n", -+ priv->smba + ISMT_GR_GCTRL, -+ readl(priv->smba + ISMT_GR_GCTRL)); -+ dev_dbg(dev, " SMTICL... : (0x%p)=0x%016llX\n", -+ priv->smba + ISMT_GR_SMTICL, -+ (long long unsigned int)readq(priv->smba + ISMT_GR_SMTICL)); -+ dev_dbg(dev, " ERRINTMSK : (0x%p)=0x%X\n", -+ priv->smba + ISMT_GR_ERRINTMSK, -+ readl(priv->smba + ISMT_GR_ERRINTMSK)); -+ dev_dbg(dev, " ERRAERMSK : (0x%p)=0x%X\n", -+ priv->smba + ISMT_GR_ERRAERMSK, -+ readl(priv->smba + ISMT_GR_ERRAERMSK)); -+ dev_dbg(dev, " ERRSTS... : (0x%p)=0x%X\n", -+ priv->smba + ISMT_GR_ERRSTS, -+ readl(priv->smba + ISMT_GR_ERRSTS)); -+ dev_dbg(dev, " ERRINFO.. : (0x%p)=0x%X\n", -+ priv->smba + ISMT_GR_ERRINFO, -+ readl(priv->smba + ISMT_GR_ERRINFO)); -+} -+ -+/** -+ * ismt_mstr_reg_dump() - dump the iSMT Master Registers -+ * @priv: iSMT private data -+ */ -+static void ismt_mstr_reg_dump(struct ismt_priv *priv) -+{ -+ struct device *dev = &priv->pci_dev->dev; -+ -+ dev_dbg(dev, "Dump of the iSMT Master Registers\n"); -+ dev_dbg(dev, " MDBA..... : (0x%p)=0x%016llX\n", -+ priv->smba + ISMT_MSTR_MDBA, -+ (long long unsigned int)readq(priv->smba + ISMT_MSTR_MDBA)); -+ dev_dbg(dev, " MCTRL.... : (0x%p)=0x%X\n", -+ priv->smba + ISMT_MSTR_MCTRL, -+ readl(priv->smba + ISMT_MSTR_MCTRL)); -+ dev_dbg(dev, " MSTS..... : (0x%p)=0x%X\n", -+ priv->smba + ISMT_MSTR_MSTS, -+ readl(priv->smba + ISMT_MSTR_MSTS)); -+ dev_dbg(dev, " MDS...... : (0x%p)=0x%X\n", -+ priv->smba + ISMT_MSTR_MDS, -+ readl(priv->smba + ISMT_MSTR_MDS)); -+ dev_dbg(dev, " RPOLICY.. : (0x%p)=0x%X\n", -+ priv->smba + ISMT_MSTR_RPOLICY, -+ readl(priv->smba + ISMT_MSTR_RPOLICY)); -+ dev_dbg(dev, " SPGT..... : (0x%p)=0x%X\n", -+ priv->smba + ISMT_SPGT, -+ readl(priv->smba + ISMT_SPGT)); -+} -+ -+/** -+ * ismt_submit_desc() - add a descriptor to the ring -+ * @priv: iSMT private data -+ */ -+static void ismt_submit_desc(struct ismt_priv *priv) -+{ -+ uint fmhp; -+ uint val; -+ -+ ismt_desc_dump(priv); -+ ismt_gen_reg_dump(priv); -+ ismt_mstr_reg_dump(priv); -+ -+ /* Set the FMHP (Firmware Master Head Pointer)*/ -+ fmhp = ((priv->head + 1) % ISMT_DESC_ENTRIES) << 16; -+ val = readl(priv->smba + ISMT_MSTR_MCTRL); -+ writel((val & ~ISMT_MCTRL_FMHP) | fmhp, -+ priv->smba + ISMT_MSTR_MCTRL); -+ -+ /* Set the start bit */ -+ val = readl(priv->smba + ISMT_MSTR_MCTRL); -+ writel(val | ISMT_MCTRL_SS, -+ priv->smba + ISMT_MSTR_MCTRL); -+} -+ -+/** -+ * ismt_process_desc() - handle the completion of the descriptor -+ * @desc: the iSMT hardware descriptor -+ * @data: data buffer from the upper layer -+ * @priv: ismt_priv struct holding our dma buffer -+ * @size: SMBus transaction type -+ * @read_write: flag to indicate if this is a read or write -+ */ -+static int ismt_process_desc(const struct ismt_desc *desc, -+ union i2c_smbus_data *data, -+ struct ismt_priv *priv, int size, -+ char read_write) -+{ -+ u8 *dma_buffer = priv->dma_buffer; -+ -+ dev_dbg(&priv->pci_dev->dev, "Processing completed descriptor\n"); -+ __ismt_desc_dump(&priv->pci_dev->dev, desc); -+ -+ if (desc->status & ISMT_DESC_SCS) { -+ if (read_write == I2C_SMBUS_WRITE && -+ size != I2C_SMBUS_PROC_CALL) -+ return 0; -+ -+ switch (size) { -+ case I2C_SMBUS_BYTE: -+ case I2C_SMBUS_BYTE_DATA: -+ data->byte = dma_buffer[0]; -+ break; -+ case I2C_SMBUS_WORD_DATA: -+ case I2C_SMBUS_PROC_CALL: -+ data->word = dma_buffer[0] | (dma_buffer[1] << 8); -+ break; -+ case I2C_SMBUS_BLOCK_DATA: -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ memcpy(&data->block[1], dma_buffer, desc->rxbytes); -+ data->block[0] = desc->rxbytes; -+ break; -+ } -+ return 0; -+ } -+ -+ if (likely(desc->status & ISMT_DESC_NAK)) -+ return -ENXIO; -+ -+ if (desc->status & ISMT_DESC_CRC) -+ return -EBADMSG; -+ -+ if (desc->status & ISMT_DESC_COL) -+ return -EAGAIN; -+ -+ if (desc->status & ISMT_DESC_LPR) -+ return -EPROTO; -+ -+ if (desc->status & (ISMT_DESC_DLTO | ISMT_DESC_CLTO)) -+ return -ETIMEDOUT; -+ -+ return -EIO; -+} -+ -+/** -+ * ismt_access() - process an SMBus command -+ * @adap: the i2c host adapter -+ * @addr: address of the i2c/SMBus target -+ * @flags: command options -+ * @read_write: read from or write to device -+ * @command: the i2c/SMBus command to issue -+ * @size: SMBus transaction type -+ * @data: read/write data buffer -+ */ -+static int ismt_access(struct i2c_adapter *adap, u16 addr, -+ unsigned short flags, char read_write, u8 command, -+ int size, union i2c_smbus_data *data) -+{ -+ int ret; -+ dma_addr_t dma_addr = 0; /* address of the data buffer */ -+ u8 dma_size = 0; -+ enum dma_data_direction dma_direction = 0; -+ struct ismt_desc *desc; -+ struct ismt_priv *priv = i2c_get_adapdata(adap); -+ struct device *dev = &priv->pci_dev->dev; -+ -+ desc = &priv->hw[priv->head]; -+ -+ /* Initialize the DMA buffer */ -+ memset(priv->dma_buffer, 0, sizeof(priv->dma_buffer)); -+ -+ /* Initialize the descriptor */ -+ memset(desc, 0, sizeof(struct ismt_desc)); -+ desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(addr, read_write); -+ -+ /* Initialize common control bits */ -+ if (likely(priv->using_msi)) -+ desc->control = ISMT_DESC_INT | ISMT_DESC_FAIR; -+ else -+ desc->control = ISMT_DESC_FAIR; -+ -+ if ((flags & I2C_CLIENT_PEC) && (size != I2C_SMBUS_QUICK) -+ && (size != I2C_SMBUS_I2C_BLOCK_DATA)) -+ desc->control |= ISMT_DESC_PEC; -+ -+ switch (size) { -+ case I2C_SMBUS_QUICK: -+ dev_dbg(dev, "I2C_SMBUS_QUICK\n"); -+ break; -+ -+ case I2C_SMBUS_BYTE: -+ if (read_write == I2C_SMBUS_WRITE) { -+ /* -+ * Send Byte -+ * The command field contains the write data -+ */ -+ dev_dbg(dev, "I2C_SMBUS_BYTE: WRITE\n"); -+ desc->control |= ISMT_DESC_CWRL; -+ desc->wr_len_cmd = command; -+ } else { -+ /* Receive Byte */ -+ dev_dbg(dev, "I2C_SMBUS_BYTE: READ\n"); -+ dma_size = 1; -+ dma_direction = DMA_FROM_DEVICE; -+ desc->rd_len = 1; -+ } -+ break; -+ -+ case I2C_SMBUS_BYTE_DATA: -+ if (read_write == I2C_SMBUS_WRITE) { -+ /* -+ * Write Byte -+ * Command plus 1 data byte -+ */ -+ dev_dbg(dev, "I2C_SMBUS_BYTE_DATA: WRITE\n"); -+ desc->wr_len_cmd = 2; -+ dma_size = 2; -+ dma_direction = DMA_TO_DEVICE; -+ priv->dma_buffer[0] = command; -+ priv->dma_buffer[1] = data->byte; -+ } else { -+ /* Read Byte */ -+ dev_dbg(dev, "I2C_SMBUS_BYTE_DATA: READ\n"); -+ desc->control |= ISMT_DESC_CWRL; -+ desc->wr_len_cmd = command; -+ desc->rd_len = 1; -+ dma_size = 1; -+ dma_direction = DMA_FROM_DEVICE; -+ } -+ break; -+ -+ case I2C_SMBUS_WORD_DATA: -+ if (read_write == I2C_SMBUS_WRITE) { -+ /* Write Word */ -+ dev_dbg(dev, "I2C_SMBUS_WORD_DATA: WRITE\n"); -+ desc->wr_len_cmd = 3; -+ dma_size = 3; -+ dma_direction = DMA_TO_DEVICE; -+ priv->dma_buffer[0] = command; -+ priv->dma_buffer[1] = data->word & 0xff; -+ priv->dma_buffer[2] = data->word >> 8; -+ } else { -+ /* Read Word */ -+ dev_dbg(dev, "I2C_SMBUS_WORD_DATA: READ\n"); -+ desc->wr_len_cmd = command; -+ desc->control |= ISMT_DESC_CWRL; -+ desc->rd_len = 2; -+ dma_size = 2; -+ dma_direction = DMA_FROM_DEVICE; -+ } -+ break; -+ -+ case I2C_SMBUS_PROC_CALL: -+ dev_dbg(dev, "I2C_SMBUS_PROC_CALL\n"); -+ desc->wr_len_cmd = 3; -+ desc->rd_len = 2; -+ dma_size = 3; -+ dma_direction = DMA_BIDIRECTIONAL; -+ priv->dma_buffer[0] = command; -+ priv->dma_buffer[1] = data->word & 0xff; -+ priv->dma_buffer[2] = data->word >> 8; -+ break; -+ -+ case I2C_SMBUS_BLOCK_DATA: -+ if (read_write == I2C_SMBUS_WRITE) { -+ /* Block Write */ -+ dev_dbg(dev, "I2C_SMBUS_BLOCK_DATA: WRITE\n"); -+ dma_size = data->block[0] + 1; -+ dma_direction = DMA_TO_DEVICE; -+ desc->wr_len_cmd = dma_size; -+ desc->control |= ISMT_DESC_BLK; -+ priv->dma_buffer[0] = command; -+ memcpy(&priv->dma_buffer[1], &data->block[1], dma_size); -+ } else { -+ /* Block Read */ -+ dev_dbg(dev, "I2C_SMBUS_BLOCK_DATA: READ\n"); -+ dma_size = I2C_SMBUS_BLOCK_MAX; -+ dma_direction = DMA_FROM_DEVICE; -+ desc->rd_len = dma_size; -+ desc->wr_len_cmd = command; -+ desc->control |= (ISMT_DESC_BLK | ISMT_DESC_CWRL); -+ } -+ break; -+ -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ /* Make sure the length is valid */ -+ if (data->block[0] < 1) -+ data->block[0] = 1; -+ -+ if (data->block[0] > I2C_SMBUS_BLOCK_MAX) -+ data->block[0] = I2C_SMBUS_BLOCK_MAX; -+ -+ if (read_write == I2C_SMBUS_WRITE) { -+ /* i2c Block Write */ -+ dev_dbg(dev, "I2C_SMBUS_I2C_BLOCK_DATA: WRITE\n"); -+ dma_size = data->block[0] + 1; -+ dma_direction = DMA_TO_DEVICE; -+ desc->wr_len_cmd = dma_size; -+ desc->control |= ISMT_DESC_I2C; -+ priv->dma_buffer[0] = command; -+ memcpy(&priv->dma_buffer[1], &data->block[1], dma_size); -+ } else { -+ /* i2c Block Read */ -+ dev_dbg(dev, "I2C_SMBUS_I2C_BLOCK_DATA: READ\n"); -+ dma_size = data->block[0]; -+ dma_direction = DMA_FROM_DEVICE; -+ desc->rd_len = dma_size; -+ desc->wr_len_cmd = command; -+ desc->control |= (ISMT_DESC_I2C | ISMT_DESC_CWRL); -+ /* -+ * Per the "Table 15-15. I2C Commands", -+ * in the External Design Specification (EDS), -+ * (Document Number: 508084, Revision: 2.0), -+ * the _rw bit must be 0 -+ */ -+ desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(addr, 0); -+ } -+ break; -+ -+ default: -+ dev_err(dev, "Unsupported transaction %d\n", -+ size); -+ return -EOPNOTSUPP; -+ } -+ -+ /* map the data buffer */ -+ if (dma_size != 0) { -+ dev_dbg(dev, " dev=%p\n", dev); -+ dev_dbg(dev, " data=%p\n", data); -+ dev_dbg(dev, " dma_buffer=%p\n", priv->dma_buffer); -+ dev_dbg(dev, " dma_size=%d\n", dma_size); -+ dev_dbg(dev, " dma_direction=%d\n", dma_direction); -+ -+ dma_addr = dma_map_single(dev, -+ priv->dma_buffer, -+ dma_size, -+ dma_direction); -+ -+ if (dma_mapping_error(dev, dma_addr)) { -+ dev_err(dev, "Error in mapping dma buffer %p\n", -+ priv->dma_buffer); -+ return -EIO; -+ } -+ -+ dev_dbg(dev, " dma_addr = 0x%016llX\n", -+ (unsigned long long)dma_addr); -+ -+ desc->dptr_low = lower_32_bits(dma_addr); -+ desc->dptr_high = upper_32_bits(dma_addr); -+ } -+ -+ INIT_COMPLETION(priv->cmp); -+ -+ /* Add the descriptor */ -+ ismt_submit_desc(priv); -+ -+ /* Now we wait for interrupt completion, 1s */ -+ ret = wait_for_completion_timeout(&priv->cmp, HZ*1); -+ -+ /* unmap the data buffer */ -+ if (dma_size != 0) -+ dma_unmap_single(&adap->dev, dma_addr, dma_size, dma_direction); -+ -+ if (unlikely(!ret)) { -+ dev_err(dev, "completion wait timed out\n"); -+ ret = -ETIMEDOUT; -+ goto out; -+ } -+ -+ /* do any post processing of the descriptor here */ -+ ret = ismt_process_desc(desc, data, priv, size, read_write); -+ -+out: -+ /* Update the ring pointer */ -+ priv->head++; -+ priv->head %= ISMT_DESC_ENTRIES; -+ -+ return ret; -+} -+ -+/** -+ * ismt_func() - report which i2c commands are supported by this adapter -+ * @adap: the i2c host adapter -+ */ -+static u32 ismt_func(struct i2c_adapter *adap) -+{ -+ return I2C_FUNC_SMBUS_QUICK | -+ I2C_FUNC_SMBUS_BYTE | -+ I2C_FUNC_SMBUS_BYTE_DATA | -+ I2C_FUNC_SMBUS_WORD_DATA | -+ I2C_FUNC_SMBUS_PROC_CALL | -+ I2C_FUNC_SMBUS_BLOCK_DATA | -+ I2C_FUNC_SMBUS_I2C_BLOCK | -+ I2C_FUNC_SMBUS_PEC; -+} -+ -+/** -+ * smbus_algorithm - the adapter algorithm and supported functionality -+ * @smbus_xfer: the adapter algorithm -+ * @functionality: functionality supported by the adapter -+ */ -+static const struct i2c_algorithm smbus_algorithm = { -+ .smbus_xfer = ismt_access, -+ .functionality = ismt_func, -+}; -+ -+/** -+ * ismt_handle_isr() - interrupt handler bottom half -+ * @priv: iSMT private data -+ */ -+static irqreturn_t ismt_handle_isr(struct ismt_priv *priv) -+{ -+ complete(&priv->cmp); -+ -+ return IRQ_HANDLED; -+} -+ -+ -+/** -+ * ismt_do_interrupt() - IRQ interrupt handler -+ * @vec: interrupt vector -+ * @data: iSMT private data -+ */ -+static irqreturn_t ismt_do_interrupt(int vec, void *data) -+{ -+ u32 val; -+ struct ismt_priv *priv = data; -+ -+ /* -+ * check to see it's our interrupt, return IRQ_NONE if not ours -+ * since we are sharing interrupt -+ */ -+ val = readl(priv->smba + ISMT_MSTR_MSTS); -+ -+ if (!(val & (ISMT_MSTS_MIS | ISMT_MSTS_MEIS))) -+ return IRQ_NONE; -+ else -+ writel(val | ISMT_MSTS_MIS | ISMT_MSTS_MEIS, -+ priv->smba + ISMT_MSTR_MSTS); -+ -+ return ismt_handle_isr(priv); -+} -+ -+/** -+ * ismt_do_msi_interrupt() - MSI interrupt handler -+ * @vec: interrupt vector -+ * @data: iSMT private data -+ */ -+static irqreturn_t ismt_do_msi_interrupt(int vec, void *data) -+{ -+ return ismt_handle_isr(data); -+} -+ -+/** -+ * ismt_hw_init() - initialize the iSMT hardware -+ * @priv: iSMT private data -+ */ -+static void ismt_hw_init(struct ismt_priv *priv) -+{ -+ u32 val; -+ struct device *dev = &priv->pci_dev->dev; -+ -+ /* initialize the Master Descriptor Base Address (MDBA) */ -+ writeq(priv->io_rng_dma, priv->smba + ISMT_MSTR_MDBA); -+ -+ /* initialize the Master Control Register (MCTRL) */ -+ writel(ISMT_MCTRL_MEIE, priv->smba + ISMT_MSTR_MCTRL); -+ -+ /* initialize the Master Status Register (MSTS) */ -+ writel(0, priv->smba + ISMT_MSTR_MSTS); -+ -+ /* initialize the Master Descriptor Size (MDS) */ -+ val = readl(priv->smba + ISMT_MSTR_MDS); -+ writel((val & ~ISMT_MDS_MASK) | (ISMT_DESC_ENTRIES - 1), -+ priv->smba + ISMT_MSTR_MDS); -+ -+ /* -+ * Set the SMBus speed (could use this for slow HW debuggers) -+ */ -+ -+ val = readl(priv->smba + ISMT_SPGT); -+ -+ switch (bus_speed) { -+ case 0: -+ break; -+ -+ case 80: -+ dev_dbg(dev, "Setting SMBus clock to 80 kHz\n"); -+ writel(((val & ~ISMT_SPGT_SPD_MASK) | ISMT_SPGT_SPD_80K), -+ priv->smba + ISMT_SPGT); -+ break; -+ -+ case 100: -+ dev_dbg(dev, "Setting SMBus clock to 100 kHz\n"); -+ writel(((val & ~ISMT_SPGT_SPD_MASK) | ISMT_SPGT_SPD_100K), -+ priv->smba + ISMT_SPGT); -+ break; -+ -+ case 400: -+ dev_dbg(dev, "Setting SMBus clock to 400 kHz\n"); -+ writel(((val & ~ISMT_SPGT_SPD_MASK) | ISMT_SPGT_SPD_400K), -+ priv->smba + ISMT_SPGT); -+ break; -+ -+ case 1000: -+ dev_dbg(dev, "Setting SMBus clock to 1000 kHz\n"); -+ writel(((val & ~ISMT_SPGT_SPD_MASK) | ISMT_SPGT_SPD_1M), -+ priv->smba + ISMT_SPGT); -+ break; -+ -+ default: -+ dev_warn(dev, "Invalid SMBus clock speed, only 0, 80, 100, 400, and 1000 are valid\n"); -+ break; -+ } -+ -+ val = readl(priv->smba + ISMT_SPGT); -+ -+ switch (val & ISMT_SPGT_SPD_MASK) { -+ case ISMT_SPGT_SPD_80K: -+ bus_speed = 80; -+ break; -+ case ISMT_SPGT_SPD_100K: -+ bus_speed = 100; -+ break; -+ case ISMT_SPGT_SPD_400K: -+ bus_speed = 400; -+ break; -+ case ISMT_SPGT_SPD_1M: -+ bus_speed = 1000; -+ break; -+ } -+ dev_dbg(dev, "SMBus clock is running at %d kHz\n", bus_speed); -+} -+ -+/** -+ * ismt_dev_init() - initialize the iSMT data structures -+ * @priv: iSMT private data -+ */ -+static int ismt_dev_init(struct ismt_priv *priv) -+{ -+ /* allocate memory for the descriptor */ -+ priv->hw = dmam_alloc_coherent(&priv->pci_dev->dev, -+ (ISMT_DESC_ENTRIES -+ * sizeof(struct ismt_desc)), -+ &priv->io_rng_dma, -+ GFP_KERNEL); -+ if (!priv->hw) -+ return -ENOMEM; -+ -+ memset(priv->hw, 0, (ISMT_DESC_ENTRIES * sizeof(struct ismt_desc))); -+ -+ priv->head = 0; -+ init_completion(&priv->cmp); -+ -+ return 0; -+} -+ -+/** -+ * ismt_int_init() - initialize interrupts -+ * @priv: iSMT private data -+ */ -+static int ismt_int_init(struct ismt_priv *priv) -+{ -+ int err; -+ -+ /* Try using MSI interrupts */ -+ err = pci_enable_msi(priv->pci_dev); -+ if (err) { -+ dev_warn(&priv->pci_dev->dev, -+ "Unable to use MSI interrupts, falling back to legacy\n"); -+ goto intx; -+ } -+ -+ err = devm_request_irq(&priv->pci_dev->dev, -+ priv->pci_dev->irq, -+ ismt_do_msi_interrupt, -+ 0, -+ "ismt-msi", -+ priv); -+ if (err) { -+ pci_disable_msi(priv->pci_dev); -+ goto intx; -+ } -+ -+ priv->using_msi = true; -+ goto done; -+ -+ /* Try using legacy interrupts */ -+intx: -+ err = devm_request_irq(&priv->pci_dev->dev, -+ priv->pci_dev->irq, -+ ismt_do_interrupt, -+ IRQF_SHARED, -+ "ismt-intx", -+ priv); -+ if (err) { -+ dev_err(&priv->pci_dev->dev, "no usable interrupts\n"); -+ return -ENODEV; -+ } -+ -+ priv->using_msi = false; -+ -+done: -+ return 0; -+} -+ -+static struct pci_driver ismt_driver; -+ -+/** -+ * ismt_probe() - probe for iSMT devices -+ * @pdev: PCI-Express device -+ * @id: PCI-Express device ID -+ */ -+static int -+ismt_probe(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ int err; -+ struct ismt_priv *priv; -+ unsigned long start, len; -+ -+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ pci_set_drvdata(pdev, priv); -+ i2c_set_adapdata(&priv->adapter, priv); -+ priv->adapter.owner = THIS_MODULE; -+ -+ priv->adapter.class = I2C_CLASS_HWMON; -+ -+ priv->adapter.algo = &smbus_algorithm; -+ -+ /* set up the sysfs linkage to our parent device */ -+ priv->adapter.dev.parent = &pdev->dev; -+ -+ /* number of retries on lost arbitration */ -+ priv->adapter.retries = ISMT_MAX_RETRIES; -+ -+ priv->pci_dev = pdev; -+ -+ err = pcim_enable_device(pdev); -+ if (err) { -+ dev_err(&pdev->dev, "Failed to enable SMBus PCI device (%d)\n", -+ err); -+ return err; -+ } -+ -+ /* enable bus mastering */ -+ pci_set_master(pdev); -+ -+ /* Determine the address of the SMBus area */ -+ start = pci_resource_start(pdev, SMBBAR); -+ len = pci_resource_len(pdev, SMBBAR); -+ if (!start || !len) { -+ dev_err(&pdev->dev, -+ "SMBus base address uninitialized, upgrade BIOS\n"); -+ return -ENODEV; -+ } -+ -+ snprintf(priv->adapter.name, sizeof(priv->adapter.name), -+ "SMBus iSMT adapter at %lx", start); -+ -+ dev_dbg(&priv->pci_dev->dev, " start=0x%lX\n", start); -+ dev_dbg(&priv->pci_dev->dev, " len=0x%lX\n", len); -+ -+ err = acpi_check_resource_conflict(&pdev->resource[SMBBAR]); -+ if (err) { -+ dev_err(&pdev->dev, "ACPI resource conflict!\n"); -+ return err; -+ } -+ -+ err = pci_request_region(pdev, SMBBAR, ismt_driver.name); -+ if (err) { -+ dev_err(&pdev->dev, -+ "Failed to request SMBus region 0x%lx-0x%lx\n", -+ start, start + len); -+ return err; -+ } -+ -+ priv->smba = pcim_iomap(pdev, SMBBAR, len); -+ if (!priv->smba) { -+ dev_err(&pdev->dev, "Unable to ioremap SMBus BAR\n"); -+ err = -ENODEV; -+ goto fail; -+ } -+ -+ if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) || -+ (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)) { -+ if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) || -+ (pci_set_consistent_dma_mask(pdev, -+ DMA_BIT_MASK(32)) != 0)) { -+ dev_err(&pdev->dev, "pci_set_dma_mask fail %p\n", -+ pdev); -+ err = -ENODEV; -+ goto fail; -+ } -+ } -+ -+ err = ismt_dev_init(priv); -+ if (err) -+ goto fail; -+ -+ ismt_hw_init(priv); -+ -+ err = ismt_int_init(priv); -+ if (err) -+ goto fail; -+ -+ err = i2c_add_adapter(&priv->adapter); -+ if (err) { -+ dev_err(&pdev->dev, "Failed to add SMBus iSMT adapter\n"); -+ err = -ENODEV; -+ goto fail; -+ } -+ return 0; -+ -+fail: -+ pci_release_region(pdev, SMBBAR); -+ return err; -+} -+ -+/** -+ * ismt_remove() - release driver resources -+ * @pdev: PCI-Express device -+ */ -+static void ismt_remove(struct pci_dev *pdev) -+{ -+ struct ismt_priv *priv = pci_get_drvdata(pdev); -+ -+ i2c_del_adapter(&priv->adapter); -+ pci_release_region(pdev, SMBBAR); -+} -+ -+/** -+ * ismt_suspend() - place the device in suspend -+ * @pdev: PCI-Express device -+ * @mesg: PM message -+ */ -+#ifdef CONFIG_PM -+static int ismt_suspend(struct pci_dev *pdev, pm_message_t mesg) -+{ -+ pci_save_state(pdev); -+ pci_set_power_state(pdev, pci_choose_state(pdev, mesg)); -+ return 0; -+} -+ -+/** -+ * ismt_resume() - PCI resume code -+ * @pdev: PCI-Express device -+ */ -+static int ismt_resume(struct pci_dev *pdev) -+{ -+ pci_set_power_state(pdev, PCI_D0); -+ pci_restore_state(pdev); -+ return pci_enable_device(pdev); -+} -+ -+#else -+ -+#define ismt_suspend NULL -+#define ismt_resume NULL -+ -+#endif -+ -+static struct pci_driver ismt_driver = { -+ .name = "ismt_smbus", -+ .id_table = ismt_ids, -+ .probe = ismt_probe, -+ .remove = ismt_remove, -+ .suspend = ismt_suspend, -+ .resume = ismt_resume, -+}; -+ -+static int __init i2c_ismt_init(void) -+{ -+ return pci_register_driver(&ismt_driver); -+} -+ -+static void __exit i2c_ismt_exit(void) -+{ -+ pci_unregister_driver(&ismt_driver); -+} -+ -+module_init(i2c_ismt_init); -+module_exit(i2c_ismt_exit); -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_AUTHOR("Bill E. Brown "); -+MODULE_DESCRIPTION("Intel SMBus Message Transport (iSMT) driver"); -diff --git a/include/asm-generic/io-64-nonatomic-hi-lo.h b/include/asm-generic/io-64-nonatomic-hi-lo.h -new file mode 100644 -index 0000000..a6806a9 ---- /dev/null -+++ b/include/asm-generic/io-64-nonatomic-hi-lo.h -@@ -0,0 +1,28 @@ -+#ifndef _ASM_IO_64_NONATOMIC_HI_LO_H_ -+#define _ASM_IO_64_NONATOMIC_HI_LO_H_ -+ -+#include -+#include -+ -+#ifndef readq -+static inline __u64 readq(const volatile void __iomem *addr) -+{ -+ const volatile u32 __iomem *p = addr; -+ u32 low, high; -+ -+ high = readl(p + 1); -+ low = readl(p); -+ -+ return low + ((u64)high << 32); -+} -+#endif -+ -+#ifndef writeq -+static inline void writeq(__u64 val, volatile void __iomem *addr) -+{ -+ writel(val >> 32, addr + 4); -+ writel(val, addr); -+} -+#endif -+ -+#endif /* _ASM_IO_64_NONATOMIC_HI_LO_H_ */ -diff --git a/include/asm-generic/io-64-nonatomic-lo-hi.h b/include/asm-generic/io-64-nonatomic-lo-hi.h -new file mode 100644 -index 0000000..ca546b1 ---- /dev/null -+++ b/include/asm-generic/io-64-nonatomic-lo-hi.h -@@ -0,0 +1,28 @@ -+#ifndef _ASM_IO_64_NONATOMIC_LO_HI_H_ -+#define _ASM_IO_64_NONATOMIC_LO_HI_H_ -+ -+#include -+#include -+ -+#ifndef readq -+static inline __u64 readq(const volatile void __iomem *addr) -+{ -+ const volatile u32 __iomem *p = addr; -+ u32 low, high; -+ -+ low = readl(p); -+ high = readl(p + 1); -+ -+ return low + ((u64)high << 32); -+} -+#endif -+ -+#ifndef writeq -+static inline void writeq(__u64 val, volatile void __iomem *addr) -+{ -+ writel(val, addr); -+ writel(val >> 32, addr + 4); -+} -+#endif -+ -+#endif /* _ASM_IO_64_NONATOMIC_LO_HI_H_ */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-mux-device-tree.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-mux-device-tree.patch deleted file mode 100644 index b22c1b8f..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-i2c-mux-device-tree.patch +++ /dev/null @@ -1,247 +0,0 @@ -This is back porting the i2c mux device tree bindings patch from -David Deney: https://lkml.org/lkml/2012/4/12/422 - -Quoting that email: - - We need to populate our I2C devices from the device tree, but some - of our systems have multiplexers which currently break this process. - - The basic idea is to have the generic i2c-mux framework propagate - the device_node for the child bus into the corresponding - i2c_adapter, and then call of_i2c_register_devices(). This means - that the device tree bindings for *all* i2c muxes must have some - common properties. I try to document these in mux.txt. - -diff --git a/Documentation/devicetree/bindings/i2c/mux.txt b/Documentation/devicetree/bindings/i2c/mux.txt -new file mode 100644 -index 0000000..af84cce ---- /dev/null -+++ b/Documentation/devicetree/bindings/i2c/mux.txt -@@ -0,0 +1,60 @@ -+Common i2c bus multiplexer/switch properties. -+ -+An i2c bus multiplexer/switch will have several child busses that are -+numbered uniquely in a device dependent manner. The nodes for an i2c bus -+multiplexer/switch will have one child node for each child -+bus. -+ -+Required properties: -+- #address-cells = <1>; -+- #size-cells = <0>; -+ -+Required properties for child nodes: -+- #address-cells = <1>; -+- #size-cells = <0>; -+- reg : The sub-bus number. -+ -+Optional properties for child nodes: -+- Other properties specific to the multiplexer/switch hardware. -+- Child nodes conforming to i2c bus binding -+ -+ -+Example : -+ -+ /* -+ An NXP pca9548 8 channel I2C multiplexer at address 0x70 -+ with two NXP pca8574 GPIO expanders attached, one each to -+ ports 3 and 4. -+ */ -+ -+ mux@70 { -+ compatible = "nxp,pca9548"; -+ reg = <0x70>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ -+ gpio1: gpio@38 { -+ compatible = "nxp,pca8574"; -+ reg = <0x38>; -+ #gpio-cells = <2>; -+ gpio-controller; -+ }; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ -+ gpio2: gpio@38 { -+ compatible = "nxp,pca8574"; -+ reg = <0x38>; -+ #gpio-cells = <2>; -+ gpio-controller; -+ }; -+ }; -+ }; -diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c -index d7a4833..609794b 100644 ---- a/drivers/i2c/i2c-mux.c -+++ b/drivers/i2c/i2c-mux.c -@@ -24,6 +24,8 @@ - #include - #include - #include -+#include -+#include - - /* multiplexer per channel data */ - struct i2c_mux_priv { -@@ -31,11 +33,11 @@ struct i2c_mux_priv { - struct i2c_algorithm algo; - - struct i2c_adapter *parent; -- void *mux_dev; /* the mux chip/device */ -+ void *mux_priv; /* the mux chip/device */ - u32 chan_id; /* the channel id */ - -- int (*select)(struct i2c_adapter *, void *mux_dev, u32 chan_id); -- int (*deselect)(struct i2c_adapter *, void *mux_dev, u32 chan_id); -+ int (*select)(struct i2c_adapter *, void *mux_priv, u32 chan_id); -+ int (*deselect)(struct i2c_adapter *, void *mux_priv, u32 chan_id); - }; - - static int i2c_mux_master_xfer(struct i2c_adapter *adap, -@@ -47,11 +49,11 @@ static int i2c_mux_master_xfer(struct i2c_adapter *adap, - - /* Switch to the right mux port and perform the transfer. */ - -- ret = priv->select(parent, priv->mux_dev, priv->chan_id); -+ ret = priv->select(parent, priv->mux_priv, priv->chan_id); - if (ret >= 0) - ret = parent->algo->master_xfer(parent, msgs, num); - if (priv->deselect) -- priv->deselect(parent, priv->mux_dev, priv->chan_id); -+ priv->deselect(parent, priv->mux_priv, priv->chan_id); - - return ret; - } -@@ -67,12 +69,12 @@ static int i2c_mux_smbus_xfer(struct i2c_adapter *adap, - - /* Select the right mux port and perform the transfer. */ - -- ret = priv->select(parent, priv->mux_dev, priv->chan_id); -+ ret = priv->select(parent, priv->mux_priv, priv->chan_id); - if (ret >= 0) - ret = parent->algo->smbus_xfer(parent, addr, flags, - read_write, command, size, data); - if (priv->deselect) -- priv->deselect(parent, priv->mux_dev, priv->chan_id); -+ priv->deselect(parent, priv->mux_priv, priv->chan_id); - - return ret; - } -@@ -87,7 +89,8 @@ static u32 i2c_mux_functionality(struct i2c_adapter *adap) - } - - struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, -- void *mux_dev, u32 force_nr, u32 chan_id, -+ struct device *mux_dev, -+ void *mux_priv, u32 force_nr, u32 chan_id, - int (*select) (struct i2c_adapter *, - void *, u32), - int (*deselect) (struct i2c_adapter *, -@@ -102,7 +105,7 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, - - /* Set up private adapter data */ - priv->parent = parent; -- priv->mux_dev = mux_dev; -+ priv->mux_priv = mux_priv; - priv->chan_id = chan_id; - priv->select = select; - priv->deselect = deselect; -@@ -124,6 +127,26 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, - priv->adap.algo_data = priv; - priv->adap.dev.parent = &parent->dev; - -+ /* -+ * Try to get populate the mux adapter's of_node, expands to -+ * nothing if !CONFIG_OF. -+ */ -+ if (mux_dev->of_node) { -+ struct device_node *child; -+ u32 reg; -+ int ret; -+ -+ for_each_child_of_node(mux_dev->of_node, child) { -+ ret = of_property_read_u32(child, "reg", ®); -+ if (ret) -+ continue; -+ if (chan_id == reg) { -+ priv->adap.dev.of_node = child; -+ break; -+ } -+ } -+ } -+ - if (force_nr) { - priv->adap.nr = force_nr; - ret = i2c_add_numbered_adapter(&priv->adap); -@@ -141,6 +164,8 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, - dev_info(&parent->dev, "Added multiplexed i2c bus %d\n", - i2c_adapter_id(&priv->adap)); - -+ of_i2c_register_devices(&priv->adap); -+ - return &priv->adap; - } - EXPORT_SYMBOL_GPL(i2c_add_mux_adapter); -diff --git a/drivers/i2c/muxes/gpio-i2cmux.c b/drivers/i2c/muxes/gpio-i2cmux.c -index 7b6ce62..cd238c7 100644 ---- a/drivers/i2c/muxes/gpio-i2cmux.c -+++ b/drivers/i2c/muxes/gpio-i2cmux.c -@@ -105,7 +105,8 @@ static int __devinit gpiomux_probe(struct platform_device *pdev) - for (i = 0; i < pdata->n_values; i++) { - u32 nr = pdata->base_nr ? (pdata->base_nr + i) : 0; - -- mux->adap[i] = i2c_add_mux_adapter(parent, mux, nr, i, -+ mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, -+ nr, i, - gpiomux_select, deselect); - if (!mux->adap[i]) { - ret = -ENODEV; -diff --git a/drivers/i2c/muxes/pca9541.c b/drivers/i2c/muxes/pca9541.c -index ed699c5..e9e07ba 100644 ---- a/drivers/i2c/muxes/pca9541.c -+++ b/drivers/i2c/muxes/pca9541.c -@@ -353,7 +353,8 @@ static int pca9541_probe(struct i2c_client *client, - force = 0; - if (pdata) - force = pdata->modes[0].adap_id; -- data->mux_adap = i2c_add_mux_adapter(adap, client, force, 0, -+ data->mux_adap = i2c_add_mux_adapter(adap, &client->dev, client, -+ force, 0, - pca9541_select_chan, - pca9541_release_chan); - -diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c -index 6f89536..5c6ecc7 100644 ---- a/drivers/i2c/muxes/pca954x.c -+++ b/drivers/i2c/muxes/pca954x.c -@@ -226,7 +226,7 @@ static int pca954x_probe(struct i2c_client *client, - } - - data->virt_adaps[num] = -- i2c_add_mux_adapter(adap, client, -+ i2c_add_mux_adapter(adap, &client->dev, client, - force, num, pca954x_select_chan, - (pdata && pdata->modes[num].deselect_on_exit) - ? pca954x_deselect_mux : NULL); -diff --git a/include/linux/i2c-mux.h b/include/linux/i2c-mux.h -index 34536ef..260ca6a 100644 ---- a/include/linux/i2c-mux.h -+++ b/include/linux/i2c-mux.h -@@ -33,7 +33,8 @@ - * mux control. - */ - struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, -- void *mux_dev, u32 force_nr, u32 chan_id, -+ struct device *mux_dev, -+ void *mux_priv, u32 force_nr, u32 chan_id, - int (*select) (struct i2c_adapter *, - void *mux_dev, u32 chan_id), - int (*deselect) (struct i2c_adapter *, diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-mfd-intel-centerton-lpc-sch.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-mfd-intel-centerton-lpc-sch.patch deleted file mode 100644 index eca45f2b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-mfd-intel-centerton-lpc-sch.patch +++ /dev/null @@ -1,210 +0,0 @@ -Back port Intel's Multifunction Device (MFD) driver. - -Adds Intel Centerton Multifunction Device support. - -This patch adds the Intel Centerton processor DeviceID for the -Integrated Legacy Block (ILB). The ILB provides GPIO, SMBus, and -Watchdog functionality. -Summary: - -diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c -index ea1169b..753d6ef 100644 ---- a/drivers/mfd/lpc_sch.c -+++ b/drivers/mfd/lpc_sch.c -@@ -36,6 +36,7 @@ - - #define GPIOBASE 0x44 - #define GPIO_IO_SIZE 64 -+#define GPIO_IO_SIZE_CENTERTON 128 - - #define WDTBASE 0x84 - #define WDT_IO_SIZE 64 -@@ -44,39 +45,41 @@ static struct resource smbus_sch_resource = { - .flags = IORESOURCE_IO, - }; - -- - static struct resource gpio_sch_resource = { - .flags = IORESOURCE_IO, - }; - --static struct mfd_cell lpc_sch_cells[] = { -- { -- .name = "isch_smbus", -- .num_resources = 1, -- .resources = &smbus_sch_resource, -- }, -- { -- .name = "sch_gpio", -- .num_resources = 1, -- .resources = &gpio_sch_resource, -- }, --}; -- - static struct resource wdt_sch_resource = { - .flags = IORESOURCE_IO, - }; - --static struct mfd_cell tunnelcreek_cells[] = { -- { -- .name = "tunnelcreek_wdt", -- .num_resources = 1, -- .resources = &wdt_sch_resource, -- }, -+static struct mfd_cell lpc_sch_cells[3]; -+ -+static struct mfd_cell isch_smbus_cell = { -+ .name = "isch_smbus", -+ .num_resources = 1, -+ .resources = &smbus_sch_resource, -+ .ignore_resource_conflicts = true, - }; - --static struct pci_device_id lpc_sch_ids[] = { -+static struct mfd_cell sch_gpio_cell = { -+ .name = "sch_gpio", -+ .num_resources = 1, -+ .resources = &gpio_sch_resource, -+ .ignore_resource_conflicts = true, -+}; -+ -+static struct mfd_cell wdt_sch_cell = { -+ .name = "ie6xx_wdt", -+ .num_resources = 1, -+ .resources = &wdt_sch_resource, -+ .ignore_resource_conflicts = true, -+}; -+ -+static const struct pci_device_id lpc_sch_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CENTERTON_ILB) }, - { 0, } - }; - MODULE_DEVICE_TABLE(pci, lpc_sch_ids); -@@ -86,72 +89,76 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev, - { - unsigned int base_addr_cfg; - unsigned short base_addr; -- int i; -+ int i, cells = 0; - int ret; - - pci_read_config_dword(dev, SMBASE, &base_addr_cfg); -- if (!(base_addr_cfg & (1 << 31))) { -- dev_err(&dev->dev, "Decode of the SMBus I/O range disabled\n"); -- return -ENODEV; -+ base_addr = 0; -+ if (!(base_addr_cfg & (1 << 31))) -+ dev_warn(&dev->dev, "Decode of the SMBus I/O range disabled\n"); -+ else -+ base_addr = (unsigned short)base_addr_cfg; -+ -+ if (base_addr == 0) { -+ dev_warn(&dev->dev, "I/O space for SMBus uninitialized\n"); -+ } else { -+ lpc_sch_cells[cells++] = isch_smbus_cell; -+ smbus_sch_resource.start = base_addr; -+ smbus_sch_resource.end = base_addr + SMBUS_IO_SIZE - 1; - } -- base_addr = (unsigned short)base_addr_cfg; -+ -+ pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg); -+ base_addr = 0; -+ if (!(base_addr_cfg & (1 << 31))) -+ dev_warn(&dev->dev, "Decode of the GPIO I/O range disabled\n"); -+ else -+ base_addr = (unsigned short)base_addr_cfg; -+ - if (base_addr == 0) { -- dev_err(&dev->dev, "I/O space for SMBus uninitialized\n"); -- return -ENODEV; -+ dev_warn(&dev->dev, "I/O space for GPIO uninitialized\n"); -+ } else { -+ lpc_sch_cells[cells++] = sch_gpio_cell; -+ gpio_sch_resource.start = base_addr; -+ if (id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB) -+ gpio_sch_resource.end = base_addr + GPIO_IO_SIZE_CENTERTON - 1; -+ else -+ gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1; - } - -- smbus_sch_resource.start = base_addr; -- smbus_sch_resource.end = base_addr + SMBUS_IO_SIZE - 1; -+ if (id->device == PCI_DEVICE_ID_INTEL_ITC_LPC -+ || id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB) { -+ pci_read_config_dword(dev, WDTBASE, &base_addr_cfg); -+ base_addr = 0; -+ if (!(base_addr_cfg & (1 << 31))) -+ dev_warn(&dev->dev, "Decode of the WDT I/O range disabled\n"); -+ else -+ base_addr = (unsigned short)base_addr_cfg; -+ if (base_addr == 0) -+ dev_warn(&dev->dev, "I/O space for WDT uninitialized\n"); -+ else { -+ lpc_sch_cells[cells++] = wdt_sch_cell; -+ wdt_sch_resource.start = base_addr; -+ wdt_sch_resource.end = base_addr + WDT_IO_SIZE - 1; -+ } -+ } - -- pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg); -- if (!(base_addr_cfg & (1 << 31))) { -- dev_err(&dev->dev, "Decode of the GPIO I/O range disabled\n"); -+ if (WARN_ON(cells > ARRAY_SIZE(lpc_sch_cells))) { -+ dev_err(&dev->dev, "Cell count exceeds array size"); - return -ENODEV; - } -- base_addr = (unsigned short)base_addr_cfg; -- if (base_addr == 0) { -- dev_err(&dev->dev, "I/O space for GPIO uninitialized\n"); -+ -+ if (cells == 0) { -+ dev_err(&dev->dev, "All decode registers disabled.\n"); - return -ENODEV; - } - -- gpio_sch_resource.start = base_addr; -- gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1; -- -- for (i=0; i < ARRAY_SIZE(lpc_sch_cells); i++) -+ for (i = 0; i < cells; i++) - lpc_sch_cells[i].id = id->device; - -- ret = mfd_add_devices(&dev->dev, 0, -- lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0); -+ ret = mfd_add_devices(&dev->dev, 0, lpc_sch_cells, cells, NULL, 0); - if (ret) -- goto out_dev; -+ mfd_remove_devices(&dev->dev); - -- if (id->device == PCI_DEVICE_ID_INTEL_ITC_LPC) { -- pci_read_config_dword(dev, WDTBASE, &base_addr_cfg); -- if (!(base_addr_cfg & (1 << 31))) { -- dev_err(&dev->dev, "Decode of the WDT I/O range disabled\n"); -- ret = -ENODEV; -- goto out_dev; -- } -- base_addr = (unsigned short)base_addr_cfg; -- if (base_addr == 0) { -- dev_err(&dev->dev, "I/O space for WDT uninitialized\n"); -- ret = -ENODEV; -- goto out_dev; -- } -- -- wdt_sch_resource.start = base_addr; -- wdt_sch_resource.end = base_addr + WDT_IO_SIZE - 1; -- -- for (i = 0; i < ARRAY_SIZE(tunnelcreek_cells); i++) -- tunnelcreek_cells[i].id = id->device; -- -- ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells, -- ARRAY_SIZE(tunnelcreek_cells), NULL, 0); -- } -- -- return ret; --out_dev: -- mfd_remove_devices(&dev->dev); - return ret; - } - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-mfd-lpc-ich.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-mfd-lpc-ich.patch deleted file mode 100644 index 504929a4..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-mfd-lpc-ich.patch +++ /dev/null @@ -1,1191 +0,0 @@ -Add LPC interface for Intel ICH - -diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c -new file mode 100644 -index 0000000..c58fc62 ---- /dev/null -+++ b/drivers/mfd/lpc_ich.c -@@ -0,0 +1,1091 @@ -+/* -+ * lpc_ich.c - LPC interface for Intel ICH -+ * -+ * LPC bridge function of the Intel ICH contains many other -+ * functional units, such as Interrupt controllers, Timers, -+ * Power Management, System Management, GPIO, RTC, and LPC -+ * Configuration Registers. -+ * -+ * This driver is derived from lpc_sch. -+ -+ * Copyright (c) 2011 Extreme Engineering Solution, Inc. -+ * Author: Aaron Sierra -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License 2 as published -+ * by the Free Software Foundation. -+ * -+ * 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; see the file COPYING. If not, write to -+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ * This driver supports the following I/O Controller hubs: -+ * (See the intel documentation on http://developer.intel.com.) -+ * document number 290655-003, 290677-014: 82801AA (ICH), 82801AB (ICHO) -+ * document number 290687-002, 298242-027: 82801BA (ICH2) -+ * document number 290733-003, 290739-013: 82801CA (ICH3-S) -+ * document number 290716-001, 290718-007: 82801CAM (ICH3-M) -+ * document number 290744-001, 290745-025: 82801DB (ICH4) -+ * document number 252337-001, 252663-008: 82801DBM (ICH4-M) -+ * document number 273599-001, 273645-002: 82801E (C-ICH) -+ * document number 252516-001, 252517-028: 82801EB (ICH5), 82801ER (ICH5R) -+ * document number 300641-004, 300884-013: 6300ESB -+ * document number 301473-002, 301474-026: 82801F (ICH6) -+ * document number 313082-001, 313075-006: 631xESB, 632xESB -+ * document number 307013-003, 307014-024: 82801G (ICH7) -+ * document number 322896-001, 322897-001: NM10 -+ * document number 313056-003, 313057-017: 82801H (ICH8) -+ * document number 316972-004, 316973-012: 82801I (ICH9) -+ * document number 319973-002, 319974-002: 82801J (ICH10) -+ * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH) -+ * document number 320066-003, 320257-008: EP80597 (IICH) -+ * document number 324645-001, 324646-001: Cougar Point (CPT) -+ * document number TBD : Patsburg (PBG) -+ * document number TBD : DH89xxCC -+ * document number TBD : Panther Point -+ * document number TBD : Lynx Point -+ * document number TBD : Lynx Point-LP -+ * document number TBD : Wellsburg -+ * document number TBD : Avoton SoC -+ * document number TBD : Coleto Creek -+ * document number TBD : Wildcat Point-LP -+ * document number TBD : 9 Series -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define ACPIBASE 0x40 -+#define ACPIBASE_GPE_OFF 0x28 -+#define ACPIBASE_GPE_END 0x2f -+#define ACPIBASE_SMI_OFF 0x30 -+#define ACPIBASE_SMI_END 0x33 -+#define ACPIBASE_PMC_OFF 0x08 -+#define ACPIBASE_PMC_END 0x0c -+#define ACPIBASE_TCO_OFF 0x60 -+#define ACPIBASE_TCO_END 0x7f -+#define ACPICTRL_PMCBASE 0x44 -+ -+#define ACPIBASE_GCS_OFF 0x3410 -+#define ACPIBASE_GCS_END 0x3414 -+ -+#define GPIOBASE_ICH0 0x58 -+#define GPIOCTRL_ICH0 0x5C -+#define GPIOBASE_ICH6 0x48 -+#define GPIOCTRL_ICH6 0x4C -+ -+#define RCBABASE 0xf0 -+ -+#define wdt_io_res(i) wdt_res(0, i) -+#define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) -+#define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) -+ -+struct lpc_ich_priv { -+ int chipset; -+ -+ int abase; /* ACPI base */ -+ int actrl_pbase; /* ACPI control or PMC base */ -+ int gbase; /* GPIO base */ -+ int gctrl; /* GPIO control */ -+ -+ int abase_save; /* Cached ACPI base value */ -+ int actrl_pbase_save; /* Cached ACPI control or PMC base value */ -+ int gctrl_save; /* Cached GPIO control value */ -+}; -+ -+static struct resource wdt_ich_res[] = { -+ /* ACPI - TCO */ -+ { -+ .flags = IORESOURCE_IO, -+ }, -+ /* ACPI - SMI */ -+ { -+ .flags = IORESOURCE_IO, -+ }, -+ /* GCS or PMC */ -+ { -+ .flags = IORESOURCE_MEM, -+ }, -+}; -+ -+static struct resource gpio_ich_res[] = { -+ /* GPIO */ -+ { -+ .flags = IORESOURCE_IO, -+ }, -+ /* ACPI - GPE0 */ -+ { -+ .flags = IORESOURCE_IO, -+ }, -+}; -+ -+enum lpc_cells { -+ LPC_WDT = 0, -+ LPC_GPIO, -+}; -+ -+static struct mfd_cell lpc_ich_cells[] = { -+ [LPC_WDT] = { -+ .name = "iTCO_wdt", -+ .num_resources = ARRAY_SIZE(wdt_ich_res), -+ .resources = wdt_ich_res, -+ .ignore_resource_conflicts = true, -+ }, -+ [LPC_GPIO] = { -+ .name = "gpio_ich", -+ .num_resources = ARRAY_SIZE(gpio_ich_res), -+ .resources = gpio_ich_res, -+ .ignore_resource_conflicts = true, -+ }, -+}; -+ -+/* chipset related info */ -+enum lpc_chipsets { -+ LPC_ICH = 0, /* ICH */ -+ LPC_ICH0, /* ICH0 */ -+ LPC_ICH2, /* ICH2 */ -+ LPC_ICH2M, /* ICH2-M */ -+ LPC_ICH3, /* ICH3-S */ -+ LPC_ICH3M, /* ICH3-M */ -+ LPC_ICH4, /* ICH4 */ -+ LPC_ICH4M, /* ICH4-M */ -+ LPC_CICH, /* C-ICH */ -+ LPC_ICH5, /* ICH5 & ICH5R */ -+ LPC_6300ESB, /* 6300ESB */ -+ LPC_ICH6, /* ICH6 & ICH6R */ -+ LPC_ICH6M, /* ICH6-M */ -+ LPC_ICH6W, /* ICH6W & ICH6RW */ -+ LPC_631XESB, /* 631xESB/632xESB */ -+ LPC_ICH7, /* ICH7 & ICH7R */ -+ LPC_ICH7DH, /* ICH7DH */ -+ LPC_ICH7M, /* ICH7-M & ICH7-U */ -+ LPC_ICH7MDH, /* ICH7-M DH */ -+ LPC_NM10, /* NM10 */ -+ LPC_ICH8, /* ICH8 & ICH8R */ -+ LPC_ICH8DH, /* ICH8DH */ -+ LPC_ICH8DO, /* ICH8DO */ -+ LPC_ICH8M, /* ICH8M */ -+ LPC_ICH8ME, /* ICH8M-E */ -+ LPC_ICH9, /* ICH9 */ -+ LPC_ICH9R, /* ICH9R */ -+ LPC_ICH9DH, /* ICH9DH */ -+ LPC_ICH9DO, /* ICH9DO */ -+ LPC_ICH9M, /* ICH9M */ -+ LPC_ICH9ME, /* ICH9M-E */ -+ LPC_ICH10, /* ICH10 */ -+ LPC_ICH10R, /* ICH10R */ -+ LPC_ICH10D, /* ICH10D */ -+ LPC_ICH10DO, /* ICH10DO */ -+ LPC_PCH, /* PCH Desktop Full Featured */ -+ LPC_PCHM, /* PCH Mobile Full Featured */ -+ LPC_P55, /* P55 */ -+ LPC_PM55, /* PM55 */ -+ LPC_H55, /* H55 */ -+ LPC_QM57, /* QM57 */ -+ LPC_H57, /* H57 */ -+ LPC_HM55, /* HM55 */ -+ LPC_Q57, /* Q57 */ -+ LPC_HM57, /* HM57 */ -+ LPC_PCHMSFF, /* PCH Mobile SFF Full Featured */ -+ LPC_QS57, /* QS57 */ -+ LPC_3400, /* 3400 */ -+ LPC_3420, /* 3420 */ -+ LPC_3450, /* 3450 */ -+ LPC_EP80579, /* EP80579 */ -+ LPC_CPT, /* Cougar Point */ -+ LPC_CPTD, /* Cougar Point Desktop */ -+ LPC_CPTM, /* Cougar Point Mobile */ -+ LPC_PBG, /* Patsburg */ -+ LPC_DH89XXCC, /* DH89xxCC */ -+ LPC_PPT, /* Panther Point */ -+ LPC_LPT, /* Lynx Point */ -+ LPC_LPT_LP, /* Lynx Point-LP */ -+ LPC_WBG, /* Wellsburg */ -+ LPC_AVN, /* Avoton SoC */ -+ LPC_BAYTRAIL, /* Bay Trail SoC */ -+ LPC_COLETO, /* Coleto Creek */ -+ LPC_WPT_LP, /* Wildcat Point-LP */ -+ LPC_BRASWELL, /* Braswell SoC */ -+ LPC_9S, /* 9 Series */ -+}; -+ -+static struct lpc_ich_info lpc_chipset_info[] = { -+ [LPC_ICH] = { -+ .name = "ICH", -+ .iTCO_version = 1, -+ }, -+ [LPC_ICH0] = { -+ .name = "ICH0", -+ .iTCO_version = 1, -+ }, -+ [LPC_ICH2] = { -+ .name = "ICH2", -+ .iTCO_version = 1, -+ }, -+ [LPC_ICH2M] = { -+ .name = "ICH2-M", -+ .iTCO_version = 1, -+ }, -+ [LPC_ICH3] = { -+ .name = "ICH3-S", -+ .iTCO_version = 1, -+ }, -+ [LPC_ICH3M] = { -+ .name = "ICH3-M", -+ .iTCO_version = 1, -+ }, -+ [LPC_ICH4] = { -+ .name = "ICH4", -+ .iTCO_version = 1, -+ }, -+ [LPC_ICH4M] = { -+ .name = "ICH4-M", -+ .iTCO_version = 1, -+ }, -+ [LPC_CICH] = { -+ .name = "C-ICH", -+ .iTCO_version = 1, -+ }, -+ [LPC_ICH5] = { -+ .name = "ICH5 or ICH5R", -+ .iTCO_version = 1, -+ }, -+ [LPC_6300ESB] = { -+ .name = "6300ESB", -+ .iTCO_version = 1, -+ }, -+ [LPC_ICH6] = { -+ .name = "ICH6 or ICH6R", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V6_GPIO, -+ }, -+ [LPC_ICH6M] = { -+ .name = "ICH6-M", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V6_GPIO, -+ }, -+ [LPC_ICH6W] = { -+ .name = "ICH6W or ICH6RW", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V6_GPIO, -+ }, -+ [LPC_631XESB] = { -+ .name = "631xESB/632xESB", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V6_GPIO, -+ }, -+ [LPC_ICH7] = { -+ .name = "ICH7 or ICH7R", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V7_GPIO, -+ }, -+ [LPC_ICH7DH] = { -+ .name = "ICH7DH", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V7_GPIO, -+ }, -+ [LPC_ICH7M] = { -+ .name = "ICH7-M or ICH7-U", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V7_GPIO, -+ }, -+ [LPC_ICH7MDH] = { -+ .name = "ICH7-M DH", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V7_GPIO, -+ }, -+ [LPC_NM10] = { -+ .name = "NM10", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V7_GPIO, -+ }, -+ [LPC_ICH8] = { -+ .name = "ICH8 or ICH8R", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V7_GPIO, -+ }, -+ [LPC_ICH8DH] = { -+ .name = "ICH8DH", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V7_GPIO, -+ }, -+ [LPC_ICH8DO] = { -+ .name = "ICH8DO", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V7_GPIO, -+ }, -+ [LPC_ICH8M] = { -+ .name = "ICH8M", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V7_GPIO, -+ }, -+ [LPC_ICH8ME] = { -+ .name = "ICH8M-E", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V7_GPIO, -+ }, -+ [LPC_ICH9] = { -+ .name = "ICH9", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V9_GPIO, -+ }, -+ [LPC_ICH9R] = { -+ .name = "ICH9R", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V9_GPIO, -+ }, -+ [LPC_ICH9DH] = { -+ .name = "ICH9DH", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V9_GPIO, -+ }, -+ [LPC_ICH9DO] = { -+ .name = "ICH9DO", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V9_GPIO, -+ }, -+ [LPC_ICH9M] = { -+ .name = "ICH9M", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V9_GPIO, -+ }, -+ [LPC_ICH9ME] = { -+ .name = "ICH9M-E", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V9_GPIO, -+ }, -+ [LPC_ICH10] = { -+ .name = "ICH10", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V10CONS_GPIO, -+ }, -+ [LPC_ICH10R] = { -+ .name = "ICH10R", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V10CONS_GPIO, -+ }, -+ [LPC_ICH10D] = { -+ .name = "ICH10D", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V10CORP_GPIO, -+ }, -+ [LPC_ICH10DO] = { -+ .name = "ICH10DO", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V10CORP_GPIO, -+ }, -+ [LPC_PCH] = { -+ .name = "PCH Desktop Full Featured", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_PCHM] = { -+ .name = "PCH Mobile Full Featured", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_P55] = { -+ .name = "P55", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_PM55] = { -+ .name = "PM55", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_H55] = { -+ .name = "H55", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_QM57] = { -+ .name = "QM57", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_H57] = { -+ .name = "H57", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_HM55] = { -+ .name = "HM55", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_Q57] = { -+ .name = "Q57", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_HM57] = { -+ .name = "HM57", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_PCHMSFF] = { -+ .name = "PCH Mobile SFF Full Featured", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_QS57] = { -+ .name = "QS57", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_3400] = { -+ .name = "3400", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_3420] = { -+ .name = "3420", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_3450] = { -+ .name = "3450", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_EP80579] = { -+ .name = "EP80579", -+ .iTCO_version = 2, -+ }, -+ [LPC_CPT] = { -+ .name = "Cougar Point", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_CPTD] = { -+ .name = "Cougar Point Desktop", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_CPTM] = { -+ .name = "Cougar Point Mobile", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_PBG] = { -+ .name = "Patsburg", -+ .iTCO_version = 2, -+ }, -+ [LPC_DH89XXCC] = { -+ .name = "DH89xxCC", -+ .iTCO_version = 2, -+ }, -+ [LPC_PPT] = { -+ .name = "Panther Point", -+ .iTCO_version = 2, -+ .gpio_version = ICH_V5_GPIO, -+ }, -+ [LPC_LPT] = { -+ .name = "Lynx Point", -+ .iTCO_version = 2, -+ }, -+ [LPC_LPT_LP] = { -+ .name = "Lynx Point_LP", -+ .iTCO_version = 2, -+ }, -+ [LPC_WBG] = { -+ .name = "Wellsburg", -+ .iTCO_version = 2, -+ }, -+ [LPC_AVN] = { -+ .name = "Avoton SoC", -+ .iTCO_version = 3, -+ .gpio_version = AVOTON_GPIO, -+ }, -+ [LPC_BAYTRAIL] = { -+ .name = "Bay Trail SoC", -+ .iTCO_version = 3, -+ }, -+ [LPC_COLETO] = { -+ .name = "Coleto Creek", -+ .iTCO_version = 2, -+ }, -+ [LPC_WPT_LP] = { -+ .name = "Wildcat Point_LP", -+ .iTCO_version = 2, -+ }, -+ [LPC_BRASWELL] = { -+ .name = "Braswell SoC", -+ .iTCO_version = 3, -+ }, -+ [LPC_9S] = { -+ .name = "9 Series", -+ .iTCO_version = 2, -+ }, -+}; -+ -+/* -+ * This data only exists for exporting the supported PCI ids -+ * via MODULE_DEVICE_TABLE. We do not actually register a -+ * pci_driver, because the I/O Controller Hub has also other -+ * functions that probably will be registered by other drivers. -+ */ -+static const struct pci_device_id lpc_ich_ids[] = { -+ { PCI_VDEVICE(INTEL, 0x2410), LPC_ICH}, -+ { PCI_VDEVICE(INTEL, 0x2420), LPC_ICH0}, -+ { PCI_VDEVICE(INTEL, 0x2440), LPC_ICH2}, -+ { PCI_VDEVICE(INTEL, 0x244c), LPC_ICH2M}, -+ { PCI_VDEVICE(INTEL, 0x2480), LPC_ICH3}, -+ { PCI_VDEVICE(INTEL, 0x248c), LPC_ICH3M}, -+ { PCI_VDEVICE(INTEL, 0x24c0), LPC_ICH4}, -+ { PCI_VDEVICE(INTEL, 0x24cc), LPC_ICH4M}, -+ { PCI_VDEVICE(INTEL, 0x2450), LPC_CICH}, -+ { PCI_VDEVICE(INTEL, 0x24d0), LPC_ICH5}, -+ { PCI_VDEVICE(INTEL, 0x25a1), LPC_6300ESB}, -+ { PCI_VDEVICE(INTEL, 0x2640), LPC_ICH6}, -+ { PCI_VDEVICE(INTEL, 0x2641), LPC_ICH6M}, -+ { PCI_VDEVICE(INTEL, 0x2642), LPC_ICH6W}, -+ { PCI_VDEVICE(INTEL, 0x2670), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x2671), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x2672), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x2673), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x2674), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x2675), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x2676), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x2677), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x2678), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x2679), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x267a), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x267b), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x267c), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x267d), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x267e), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x267f), LPC_631XESB}, -+ { PCI_VDEVICE(INTEL, 0x27b8), LPC_ICH7}, -+ { PCI_VDEVICE(INTEL, 0x27b0), LPC_ICH7DH}, -+ { PCI_VDEVICE(INTEL, 0x27b9), LPC_ICH7M}, -+ { PCI_VDEVICE(INTEL, 0x27bd), LPC_ICH7MDH}, -+ { PCI_VDEVICE(INTEL, 0x27bc), LPC_NM10}, -+ { PCI_VDEVICE(INTEL, 0x2810), LPC_ICH8}, -+ { PCI_VDEVICE(INTEL, 0x2812), LPC_ICH8DH}, -+ { PCI_VDEVICE(INTEL, 0x2814), LPC_ICH8DO}, -+ { PCI_VDEVICE(INTEL, 0x2815), LPC_ICH8M}, -+ { PCI_VDEVICE(INTEL, 0x2811), LPC_ICH8ME}, -+ { PCI_VDEVICE(INTEL, 0x2918), LPC_ICH9}, -+ { PCI_VDEVICE(INTEL, 0x2916), LPC_ICH9R}, -+ { PCI_VDEVICE(INTEL, 0x2912), LPC_ICH9DH}, -+ { PCI_VDEVICE(INTEL, 0x2914), LPC_ICH9DO}, -+ { PCI_VDEVICE(INTEL, 0x2919), LPC_ICH9M}, -+ { PCI_VDEVICE(INTEL, 0x2917), LPC_ICH9ME}, -+ { PCI_VDEVICE(INTEL, 0x3a18), LPC_ICH10}, -+ { PCI_VDEVICE(INTEL, 0x3a16), LPC_ICH10R}, -+ { PCI_VDEVICE(INTEL, 0x3a1a), LPC_ICH10D}, -+ { PCI_VDEVICE(INTEL, 0x3a14), LPC_ICH10DO}, -+ { PCI_VDEVICE(INTEL, 0x3b00), LPC_PCH}, -+ { PCI_VDEVICE(INTEL, 0x3b01), LPC_PCHM}, -+ { PCI_VDEVICE(INTEL, 0x3b02), LPC_P55}, -+ { PCI_VDEVICE(INTEL, 0x3b03), LPC_PM55}, -+ { PCI_VDEVICE(INTEL, 0x3b06), LPC_H55}, -+ { PCI_VDEVICE(INTEL, 0x3b07), LPC_QM57}, -+ { PCI_VDEVICE(INTEL, 0x3b08), LPC_H57}, -+ { PCI_VDEVICE(INTEL, 0x3b09), LPC_HM55}, -+ { PCI_VDEVICE(INTEL, 0x3b0a), LPC_Q57}, -+ { PCI_VDEVICE(INTEL, 0x3b0b), LPC_HM57}, -+ { PCI_VDEVICE(INTEL, 0x3b0d), LPC_PCHMSFF}, -+ { PCI_VDEVICE(INTEL, 0x3b0f), LPC_QS57}, -+ { PCI_VDEVICE(INTEL, 0x3b12), LPC_3400}, -+ { PCI_VDEVICE(INTEL, 0x3b14), LPC_3420}, -+ { PCI_VDEVICE(INTEL, 0x3b16), LPC_3450}, -+ { PCI_VDEVICE(INTEL, 0x5031), LPC_EP80579}, -+ { PCI_VDEVICE(INTEL, 0x1c41), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c42), LPC_CPTD}, -+ { PCI_VDEVICE(INTEL, 0x1c43), LPC_CPTM}, -+ { PCI_VDEVICE(INTEL, 0x1c44), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c45), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c46), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c47), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c48), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c49), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c4a), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c4b), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c4c), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c4d), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c4e), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c4f), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c50), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c51), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c52), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c53), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c54), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c55), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c56), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c57), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c58), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c59), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c5a), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c5b), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c5c), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c5d), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c5e), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1c5f), LPC_CPT}, -+ { PCI_VDEVICE(INTEL, 0x1d40), LPC_PBG}, -+ { PCI_VDEVICE(INTEL, 0x1d41), LPC_PBG}, -+ { PCI_VDEVICE(INTEL, 0x2310), LPC_DH89XXCC}, -+ { PCI_VDEVICE(INTEL, 0x1e40), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e41), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e42), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e43), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e44), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e45), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e46), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e47), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e48), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e49), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e4a), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e4b), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e4c), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e4d), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e4e), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e4f), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e50), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e51), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e52), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e53), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e54), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e55), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e56), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e57), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e58), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e59), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e5a), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e5b), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e5c), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e5d), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e5e), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x1e5f), LPC_PPT}, -+ { PCI_VDEVICE(INTEL, 0x8c40), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c41), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c42), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c43), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c44), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c45), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c46), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c47), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c48), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c49), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c4a), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c4b), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c4c), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c4d), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c4e), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c4f), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c50), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c51), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c52), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c53), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c54), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c55), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c56), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c57), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c58), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c59), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c5a), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c5b), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c5c), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c5d), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c5e), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x8c5f), LPC_LPT}, -+ { PCI_VDEVICE(INTEL, 0x9c40), LPC_LPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x9c41), LPC_LPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x9c42), LPC_LPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x9c43), LPC_LPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x9c44), LPC_LPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x9c45), LPC_LPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x9c46), LPC_LPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x9c47), LPC_LPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x8d40), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d41), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d42), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d43), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d44), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d45), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d46), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d47), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d48), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d49), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d4a), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d4b), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d4c), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d4d), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d4e), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d4f), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d50), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d51), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d52), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d53), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d54), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d55), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d56), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d57), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d58), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d59), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d5a), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d5b), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d5c), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d5d), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d5e), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x8d5f), LPC_WBG}, -+ { PCI_VDEVICE(INTEL, 0x1f38), LPC_AVN}, -+ { PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN}, -+ { PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN}, -+ { PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN}, -+ { PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL}, -+ { PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO}, -+ { PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x9cc3), LPC_WPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x9cc5), LPC_WPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x9cc6), LPC_WPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x9cc7), LPC_WPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x9cc9), LPC_WPT_LP}, -+ { PCI_VDEVICE(INTEL, 0x229c), LPC_BRASWELL}, -+ { PCI_VDEVICE(INTEL, 0x8cc1), LPC_9S}, -+ { PCI_VDEVICE(INTEL, 0x8cc2), LPC_9S}, -+ { PCI_VDEVICE(INTEL, 0x8cc3), LPC_9S}, -+ { PCI_VDEVICE(INTEL, 0x8cc4), LPC_9S}, -+ { PCI_VDEVICE(INTEL, 0x8cc6), LPC_9S}, -+ { 0, }, /* End of list */ -+}; -+MODULE_DEVICE_TABLE(pci, lpc_ich_ids); -+ -+static void lpc_ich_restore_config_space(struct pci_dev *dev) -+{ -+ struct lpc_ich_priv *priv = pci_get_drvdata(dev); -+ -+ if (priv->abase_save >= 0) { -+ pci_write_config_byte(dev, priv->abase, priv->abase_save); -+ priv->abase_save = -1; -+ } -+ -+ if (priv->actrl_pbase_save >= 0) { -+ pci_write_config_byte(dev, priv->actrl_pbase, -+ priv->actrl_pbase_save); -+ priv->actrl_pbase_save = -1; -+ } -+ -+ if (priv->gctrl_save >= 0) { -+ pci_write_config_byte(dev, priv->gctrl, priv->gctrl_save); -+ priv->gctrl_save = -1; -+ } -+} -+ -+static void lpc_ich_enable_acpi_space(struct pci_dev *dev) -+{ -+ struct lpc_ich_priv *priv = pci_get_drvdata(dev); -+ u8 reg_save; -+ -+ switch (lpc_chipset_info[priv->chipset].iTCO_version) { -+ case 3: -+ /* -+ * Some chipsets (eg Avoton) enable the ACPI space in the -+ * ACPI BASE register. -+ */ -+ pci_read_config_byte(dev, priv->abase, ®_save); -+ pci_write_config_byte(dev, priv->abase, reg_save | 0x2); -+ priv->abase_save = reg_save; -+ break; -+ default: -+ /* -+ * Most chipsets enable the ACPI space in the ACPI control -+ * register. -+ */ -+ pci_read_config_byte(dev, priv->actrl_pbase, ®_save); -+ pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x80); -+ priv->actrl_pbase_save = reg_save; -+ break; -+ } -+} -+ -+static void lpc_ich_enable_gpio_space(struct pci_dev *dev) -+{ -+ struct lpc_ich_priv *priv = pci_get_drvdata(dev); -+ u8 reg_save; -+ -+ pci_read_config_byte(dev, priv->gctrl, ®_save); -+ pci_write_config_byte(dev, priv->gctrl, reg_save | 0x10); -+ priv->gctrl_save = reg_save; -+} -+ -+static void lpc_ich_enable_pmc_space(struct pci_dev *dev) -+{ -+ struct lpc_ich_priv *priv = pci_get_drvdata(dev); -+ u8 reg_save; -+ -+ pci_read_config_byte(dev, priv->actrl_pbase, ®_save); -+ pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x2); -+ -+ priv->actrl_pbase_save = reg_save; -+} -+ -+static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell) -+{ -+ struct lpc_ich_priv *priv = pci_get_drvdata(dev); -+ -+ cell->platform_data = &lpc_chipset_info[priv->chipset]; -+ cell->pdata_size = sizeof(struct lpc_ich_info); -+} -+ -+/* -+ * We don't check for resource conflict globally. There are 2 or 3 independent -+ * GPIO groups and it's enough to have access to one of these to instantiate -+ * the device. -+ */ -+static int lpc_ich_check_conflict_gpio(struct resource *res) -+{ -+ int ret; -+ u8 use_gpio = 0; -+ -+ if (resource_size(res) >= 0x50 && -+ !acpi_check_region(res->start + 0x40, 0x10, "LPC ICH GPIO3")) -+ use_gpio |= 1 << 2; -+ -+ if (!acpi_check_region(res->start + 0x30, 0x10, "LPC ICH GPIO2")) -+ use_gpio |= 1 << 1; -+ -+ ret = acpi_check_region(res->start + 0x00, 0x30, "LPC ICH GPIO1"); -+ if (!ret) -+ use_gpio |= 1 << 0; -+ -+ return use_gpio ? use_gpio : ret; -+} -+ -+static int lpc_ich_init_gpio(struct pci_dev *dev) -+{ -+ struct lpc_ich_priv *priv = pci_get_drvdata(dev); -+ u32 base_addr_cfg; -+ u32 base_addr; -+ int ret; -+ bool acpi_conflict = false; -+ struct resource *res; -+ -+ /* Setup power management base register */ -+ pci_read_config_dword(dev, priv->abase, &base_addr_cfg); -+ base_addr = base_addr_cfg & 0x0000ff80; -+ if (!base_addr) { -+ dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); -+ lpc_ich_cells[LPC_GPIO].num_resources--; -+ goto gpe0_done; -+ } -+ -+ res = &gpio_ich_res[ICH_RES_GPE0]; -+ res->start = base_addr + ACPIBASE_GPE_OFF; -+ res->end = base_addr + ACPIBASE_GPE_END; -+ ret = acpi_check_resource_conflict(res); -+ if (ret) { -+ /* -+ * This isn't fatal for the GPIO, but we have to make sure that -+ * the platform_device subsystem doesn't see this resource -+ * or it will register an invalid region. -+ */ -+ lpc_ich_cells[LPC_GPIO].num_resources--; -+ acpi_conflict = true; -+ } else { -+ lpc_ich_enable_acpi_space(dev); -+ } -+ -+gpe0_done: -+ /* Setup GPIO base register */ -+ pci_read_config_dword(dev, priv->gbase, &base_addr_cfg); -+ base_addr = base_addr_cfg & 0x0000ff80; -+ if (!base_addr) { -+ dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n"); -+ ret = -ENODEV; -+ goto gpio_done; -+ } -+ -+ /* Older devices provide fewer GPIO and have a smaller resource size. */ -+ res = &gpio_ich_res[ICH_RES_GPIO]; -+ res->start = base_addr; -+ switch (lpc_chipset_info[priv->chipset].gpio_version) { -+ case ICH_V5_GPIO: -+ case ICH_V10CORP_GPIO: -+ res->end = res->start + 128 - 1; -+ break; -+ default: -+ res->end = res->start + 64 - 1; -+ break; -+ } -+ -+ ret = lpc_ich_check_conflict_gpio(res); -+ if (ret < 0) { -+ /* this isn't necessarily fatal for the GPIO */ -+ acpi_conflict = true; -+ goto gpio_done; -+ } -+ lpc_chipset_info[priv->chipset].use_gpio = ret; -+ lpc_ich_enable_gpio_space(dev); -+ -+ lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_GPIO]); -+ ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, -+ &lpc_ich_cells[LPC_GPIO], 1, NULL, 0); -+ -+gpio_done: -+ if (acpi_conflict) -+ pr_warn("Resource conflict(s) found affecting %s\n", -+ lpc_ich_cells[LPC_GPIO].name); -+ return ret; -+} -+ -+static int lpc_ich_init_wdt(struct pci_dev *dev) -+{ -+ struct lpc_ich_priv *priv = pci_get_drvdata(dev); -+ u32 base_addr_cfg; -+ u32 base_addr; -+ int ret; -+ struct resource *res; -+ -+ /* Setup power management base register */ -+ pci_read_config_dword(dev, priv->abase, &base_addr_cfg); -+ base_addr = base_addr_cfg & 0x0000ff80; -+ if (!base_addr) { -+ dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); -+ ret = -ENODEV; -+ goto wdt_done; -+ } -+ -+ res = wdt_io_res(ICH_RES_IO_TCO); -+ res->start = base_addr + ACPIBASE_TCO_OFF; -+ res->end = base_addr + ACPIBASE_TCO_END; -+ -+ res = wdt_io_res(ICH_RES_IO_SMI); -+ res->start = base_addr + ACPIBASE_SMI_OFF; -+ res->end = base_addr + ACPIBASE_SMI_END; -+ -+ lpc_ich_enable_acpi_space(dev); -+ -+ /* -+ * iTCO v2: -+ * Get the Memory-Mapped GCS register. To get access to it -+ * we have to read RCBA from PCI Config space 0xf0 and use -+ * it as base. GCS = RCBA + ICH6_GCS(0x3410). -+ * -+ * iTCO v3: -+ * Get the Power Management Configuration register. To get access -+ * to it we have to read the PMC BASE from config space and address -+ * the register at offset 0x8. -+ */ -+ if (lpc_chipset_info[priv->chipset].iTCO_version == 1) { -+ /* Don't register iomem for TCO ver 1 */ -+ lpc_ich_cells[LPC_WDT].num_resources--; -+ } else if (lpc_chipset_info[priv->chipset].iTCO_version == 2) { -+ pci_read_config_dword(dev, RCBABASE, &base_addr_cfg); -+ base_addr = base_addr_cfg & 0xffffc000; -+ if (!(base_addr_cfg & 1)) { -+ dev_notice(&dev->dev, "RCBA is disabled by " -+ "hardware/BIOS, device disabled\n"); -+ ret = -ENODEV; -+ goto wdt_done; -+ } -+ res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); -+ res->start = base_addr + ACPIBASE_GCS_OFF; -+ res->end = base_addr + ACPIBASE_GCS_END; -+ } else if (lpc_chipset_info[priv->chipset].iTCO_version == 3) { -+ lpc_ich_enable_pmc_space(dev); -+ pci_read_config_dword(dev, ACPICTRL_PMCBASE, &base_addr_cfg); -+ base_addr = base_addr_cfg & 0xfffffe00; -+ -+ res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); -+ res->start = base_addr + ACPIBASE_PMC_OFF; -+ res->end = base_addr + ACPIBASE_PMC_END; -+ } -+ -+ lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]); -+ ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, -+ &lpc_ich_cells[LPC_WDT], 1, NULL, 0); -+ -+wdt_done: -+ return ret; -+} -+ -+static int lpc_ich_probe(struct pci_dev *dev, -+ const struct pci_device_id *id) -+{ -+ struct lpc_ich_priv *priv; -+ int ret; -+ bool cell_added = false; -+ -+ priv = devm_kzalloc(&dev->dev, -+ sizeof(struct lpc_ich_priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->chipset = id->driver_data; -+ -+ priv->actrl_pbase_save = -1; -+ priv->abase_save = -1; -+ -+ priv->abase = ACPIBASE; -+ priv->actrl_pbase = ACPICTRL_PMCBASE; -+ -+ priv->gctrl_save = -1; -+ if (priv->chipset <= LPC_ICH5) { -+ priv->gbase = GPIOBASE_ICH0; -+ priv->gctrl = GPIOCTRL_ICH0; -+ } else { -+ priv->gbase = GPIOBASE_ICH6; -+ priv->gctrl = GPIOCTRL_ICH6; -+ } -+ -+ pci_set_drvdata(dev, priv); -+ -+ if (lpc_chipset_info[priv->chipset].iTCO_version) { -+ ret = lpc_ich_init_wdt(dev); -+ if (!ret) -+ cell_added = true; -+ } -+ -+ if (lpc_chipset_info[priv->chipset].gpio_version) { -+ ret = lpc_ich_init_gpio(dev); -+ if (!ret) -+ cell_added = true; -+ } -+ -+ /* -+ * We only care if at least one or none of the cells registered -+ * successfully. -+ */ -+ if (!cell_added) { -+ dev_warn(&dev->dev, "No MFD cells added\n"); -+ lpc_ich_restore_config_space(dev); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static void lpc_ich_remove(struct pci_dev *dev) -+{ -+ mfd_remove_devices(&dev->dev); -+ lpc_ich_restore_config_space(dev); -+} -+ -+static struct pci_driver lpc_ich_driver = { -+ .name = "lpc_ich", -+ .id_table = lpc_ich_ids, -+ .probe = lpc_ich_probe, -+ .remove = lpc_ich_remove, -+}; -+ -+module_pci_driver(lpc_ich_driver); -+ -+MODULE_AUTHOR("Aaron Sierra "); -+MODULE_DESCRIPTION("LPC interface for Intel ICH"); -+MODULE_LICENSE("GPL"); -diff --git a/include/linux/mfd/lpc_ich.h b/include/linux/mfd/lpc_ich.h -new file mode 100644 -index 0000000..8feac78 ---- /dev/null -+++ b/include/linux/mfd/lpc_ich.h -@@ -0,0 +1,52 @@ -+/* -+ * linux/drivers/mfd/lpc_ich.h -+ * -+ * Copyright (c) 2012 Extreme Engineering Solution, Inc. -+ * Author: Aaron Sierra -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License 2 as published -+ * by the Free Software Foundation. -+ * -+ * 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; see the file COPYING. If not, write to -+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+#ifndef LPC_ICH_H -+#define LPC_ICH_H -+ -+/* Watchdog resources */ -+#define ICH_RES_IO_TCO 0 -+#define ICH_RES_IO_SMI 1 -+#define ICH_RES_MEM_OFF 2 -+#define ICH_RES_MEM_GCS_PMC 0 -+ -+/* GPIO resources */ -+#define ICH_RES_GPIO 0 -+#define ICH_RES_GPE0 1 -+ -+/* GPIO compatibility */ -+enum { -+ ICH_I3100_GPIO, -+ ICH_V5_GPIO, -+ ICH_V6_GPIO, -+ ICH_V7_GPIO, -+ ICH_V9_GPIO, -+ ICH_V10CORP_GPIO, -+ ICH_V10CONS_GPIO, -+ AVOTON_GPIO, -+}; -+ -+struct lpc_ich_info { -+ char name[32]; -+ unsigned int iTCO_version; -+ unsigned int gpio_version; -+ u8 use_gpio; -+}; -+ -+#endif -diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index b2b6916..08f92c8 100644 ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -658,6 +658,17 @@ config MFD_TIMBERDALE - The timberdale FPGA can be found on the Intel Atom development board - for in-vehicle infontainment, called Russellville. - -+config LPC_ICH -+ tristate "Intel ICH LPC" -+ depends on PCI && X86_64 -+ select MFD_CORE -+ default y -+ help -+ The LPC bridge function of the Intel ICH provides support for -+ many functional units. This driver provides needed support for -+ other drivers to control these functions, currently GPIO and -+ watchdog. -+ - config LPC_SCH - tristate "Intel SCH LPC" - depends on PCI -diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index b2292eb..4aaf80c 100644 ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -91,6 +91,7 @@ obj-$(CONFIG_MFD_DB5500_PRCMU) += db5500-prcmu.o - obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o - obj-$(CONFIG_PMIC_ADP5520) += adp5520.o - obj-$(CONFIG_LPC_SCH) += lpc_sch.o -+obj-$(CONFIG_LPC_ICH) += lpc_ich.o - obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o - obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o - obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-mtd-micron-spiroms.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-mtd-micron-spiroms.patch deleted file mode 100644 index 184b35d8..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-mtd-micron-spiroms.patch +++ /dev/null @@ -1,134 +0,0 @@ -Add Micron N25Q64 ID to SPI rom driver - -diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c -index bc02754..9145658 100644 ---- a/drivers/mtd/devices/m25p80.c -+++ b/drivers/mtd/devices/m25p80.c -@@ -47,6 +47,7 @@ - #define OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */ - #define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */ - #define OPCODE_RDID 0x9f /* Read JEDEC ID */ -+#define OPCODE_RDFSR 0x70 /* Read Flag Status Register */ - - /* Used for SST flashes only. */ - #define OPCODE_BP 0x02 /* Byte program */ -@@ -69,6 +70,9 @@ - #define SR_BP2 0x10 /* Block protect 2 */ - #define SR_SRWD 0x80 /* SR write protect */ - -+/* Flag Status Register bits. */ -+#define FSR_RDY 0x80 /* Ready/Busy program erase controller */ -+ - /* Define max times to check status register before we give up. */ - #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ - #define MAX_CMD_SIZE 6 -@@ -91,6 +95,7 @@ struct m25p { - struct mtd_info mtd; - u16 page_size; - u16 addr_width; -+ bool check_fsr; - u8 erase_opcode; - u8 *command; - }; -@@ -107,6 +112,28 @@ static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) - */ - - /* -+ * Read the Flag Status Register (required for some Micron chips). -+ * Return the Flag Status Register value. -+ * Returns negative if error occurred. -+ */ -+static int read_fsr(struct m25p *flash) -+{ -+ ssize_t retval; -+ u8 code = OPCODE_RDFSR; -+ u8 val; -+ -+ retval = spi_write_then_read(flash->spi, &code, 1, &val, 1); -+ -+ if (retval < 0) { -+ dev_err(&flash->spi->dev, "error %d reading FSR\n", -+ (int) retval); -+ return retval; -+ } -+ -+ return val; -+} -+ -+/* - * Read the status register, returning its value in the location - * Return the status register value. - * Returns negative if error occurred. -@@ -166,10 +193,18 @@ static inline int write_disable(struct m25p *flash) - */ - static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable) - { -+ int status; -+ - switch (JEDEC_MFR(jedec_id)) { - case CFI_MFR_MACRONIX: - flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B; - return spi_write(flash->spi, flash->command, 1); -+ case CFI_MFR_ST: -+ flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B; -+ write_enable(flash); -+ status = spi_write(flash->spi, flash->command, 1); -+ write_disable(flash); -+ return status; - default: - /* Spansion style */ - flash->command[0] = OPCODE_BRWR; -@@ -185,15 +220,21 @@ static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable) - static int wait_till_ready(struct m25p *flash) - { - unsigned long deadline; -- int sr; -+ int sr, fsr; - - deadline = jiffies + MAX_READY_WAIT_JIFFIES; - - do { - if ((sr = read_sr(flash)) < 0) - break; -- else if (!(sr & SR_WIP)) -+ else if (!(sr & SR_WIP)) { -+ if (flash->check_fsr) { -+ fsr = read_fsr(flash); -+ if (!(fsr & FSR_RDY)) -+ return 1; -+ } - return 0; -+ } - - cond_resched(); - -@@ -625,6 +666,7 @@ struct flash_info { - u16 flags; - #define SECT_4K 0x01 /* OPCODE_BE_4K works uniformly */ - #define M25P_NO_ERASE 0x02 /* No erase command needed */ -+#define E_FSR 0x08 /* Flag SR exists for flash */ - }; - - #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ -@@ -731,6 +773,11 @@ static const struct spi_device_id m25p_ids[] = { - { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, - { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, - -+ { "n25q64", INFO(0x20ba17, 0, 64 * 1024, 128, 0) }, -+ { "n25q128", INFO(0x20ba18, 0, 64 * 1024, 256, E_FSR) }, -+ { "n25q256", INFO(0x20ba19, 0, 64 * 1024, 512, E_FSR | SECT_4K) }, -+ { "n25q512", INFO(0x20ba20, 0, 64 * 1024, 1024, E_FSR | SECT_4K) }, -+ - { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) }, - { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) }, - { "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4, 0) }, -@@ -932,6 +979,9 @@ static int __devinit m25p_probe(struct spi_device *spi) - if (info->flags & M25P_NO_ERASE) - flash->mtd.flags |= MTD_NO_ERASE; - -+ if (info->flags & E_FSR) -+ flash->check_fsr = 1; -+ - ppdata.of_node = spi->dev.of_node; - flash->mtd.dev.parent = &spi->dev; - flash->page_size = info->page_size; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pata-port-width.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pata-port-width.patch deleted file mode 100644 index 64d809aa..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pata-port-width.patch +++ /dev/null @@ -1,270 +0,0 @@ -Support port width and no data swap for OF ata devices - -diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c -index 4cadfa2..50a570c 100644 ---- a/drivers/ata/libata-sff.c -+++ b/drivers/ata/libata-sff.c -@@ -561,12 +561,27 @@ unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf, - struct ata_port *ap = dev->link->ap; - void __iomem *data_addr = ap->ioaddr.data_addr; - unsigned int words = buflen >> 1; -+ unsigned int word; - - /* Transfer multiple of 2 bytes */ -- if (rw == READ) -+ if (rw == READ) { - ioread16_rep(data_addr, buf, words); -- else -+ } else { -+ for (word = 0; word < words; word++) { -+ unsigned char tmp; -+ tmp = buf[word * 2]; -+ buf[word * 2] = buf[word * 2 + 1]; -+ buf[word * 2 + 1] = tmp; -+ } - iowrite16_rep(data_addr, buf, words); -+ } -+ -+ for (word = 0; word < words; word++) { -+ unsigned char tmp; -+ tmp = buf[word * 2]; -+ buf[word * 2] = buf[word * 2 + 1]; -+ buf[word * 2 + 1] = tmp; -+ } - - /* Transfer trailing byte, if any. */ - if (unlikely(buflen & 0x01)) { -@@ -581,9 +596,9 @@ unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf, - */ - if (rw == READ) { - ioread16_rep(data_addr, pad, 1); -- *buf = pad[0]; -+ *buf = pad[1]; - } else { -- pad[0] = *buf; -+ pad[1] = *buf; - iowrite16_rep(data_addr, pad, 1); - } - words++; -diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c -index 2a472c5..7128350 100644 ---- a/drivers/ata/pata_of_platform.c -+++ b/drivers/ata/pata_of_platform.c -@@ -23,9 +23,11 @@ static int __devinit pata_of_platform_probe(struct platform_device *ofdev) - struct resource io_res; - struct resource ctl_res; - struct resource irq_res; -- unsigned int reg_shift = 0; -+ unsigned int port_width = 1; -+ bool port_bswap = 0; - int pio_mode = 0; - int pio_mask; -+ const u32 *reg_shift_prop, *port_width_prop; - const u32 *prop; - - ret = of_address_to_resource(dn, 0, &io_res); -@@ -57,26 +59,31 @@ static int __devinit pata_of_platform_probe(struct platform_device *ofdev) - else - irq_res.flags = 0; - -- prop = of_get_property(dn, "reg-shift", NULL); -- if (prop) -- reg_shift = be32_to_cpup(prop); -+ reg_shift_prop = of_get_property(dn, "reg-shift", NULL); -+ port_width_prop = of_get_property(dn, "port-width", NULL); -+ if (reg_shift_prop && port_width_prop) { -+ dev_err(&ofdev->dev, "invalid configuration, reg-shift and port-width " -+ "are mutually exclusive\n"); -+ return -EINVAL; -+ } -+ -+ if (reg_shift_prop) { -+ unsigned int reg_shift = be32_to_cpup(reg_shift_prop); -+ port_width = (reg_shift ? (reg_shift << 1) : 1); -+ } else if (port_width_prop) { -+ port_width = be32_to_cpup(port_width_prop); -+ } - -- prop = of_get_property(dn, "pio-mode", NULL); -+ prop = of_get_property(dn, "port-bswap", NULL); - if (prop) { -- pio_mode = be32_to_cpup(prop); -- if (pio_mode > 6) { -- dev_err(&ofdev->dev, "invalid pio-mode\n"); -- return -EINVAL; -- } -- } else { -- dev_info(&ofdev->dev, "pio-mode unspecified, assuming PIO0\n"); -+ port_bswap = (be32_to_cpup(prop) != 0); - } - - pio_mask = 1 << pio_mode; - pio_mask |= (1 << pio_mode) - 1; - - return __pata_platform_probe(&ofdev->dev, &io_res, &ctl_res, &irq_res, -- reg_shift, pio_mask); -+ port_width, port_bswap, pio_mask); - } - - static int __devexit pata_of_platform_remove(struct platform_device *ofdev) -diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c -index 2067308..e493501 100644 ---- a/drivers/ata/pata_platform.c -+++ b/drivers/ata/pata_platform.c -@@ -55,20 +55,83 @@ static struct ata_port_operations pata_platform_port_ops = { - .set_mode = pata_platform_set_mode, - }; - -+static void bswap_buf16(unsigned char *buf, unsigned int words) -+{ -+ u16 *wbuf = (u16 *)buf; -+ unsigned int word; -+ -+ for (word = 0; word < words; word++) { -+ *wbuf = (*wbuf << 8) | ((*wbuf >> 8) & 0xff); -+ wbuf++; -+ } -+} -+ -+static unsigned int pata_platform_data_xfer_bswap(struct ata_device *dev, unsigned char *buf, -+ unsigned int buflen, int rw) -+{ -+ struct ata_port *ap = dev->link->ap; -+ void __iomem *data_addr = ap->ioaddr.data_addr; -+ unsigned int words = buflen >> 1; -+ -+ if (ap->pflags & ATA_PFLAG_PIO32) { -+ dev_err(&dev->tdev, "32-bit PIO with port-bswap not impelemented\n"); -+ return 0; -+ } -+ -+ /* Transfer multiple of 2 bytes */ -+ if (rw == READ) { -+ ioread16_rep(data_addr, buf, words); -+ } else { -+ bswap_buf16(buf, words); -+ iowrite16_rep(data_addr, buf, words); -+ } -+ -+ bswap_buf16(buf, words); -+ -+ /* Transfer trailing byte, if any. */ -+ if (unlikely(buflen & 0x01)) { -+ unsigned char pad[2] = { }; -+ -+ /* Point buf to the tail of buffer */ -+ buf += buflen - 1; -+ -+ if (rw == READ) { -+ ioread16_rep(data_addr, pad, 1); -+ *buf = pad[1]; -+ } else { -+ pad[1] = *buf; -+ iowrite16_rep(data_addr, pad, 1); -+ } -+ words++; -+ } -+ -+ return words << 1; -+} -+ - static void pata_platform_setup_port(struct ata_ioports *ioaddr, -- unsigned int shift) -+ unsigned int port_width, -+ bool port_bswap) - { -+ unsigned int port_shift = port_width >> 1; -+ unsigned int data_offset = 0; -+ unsigned int ctl_offset = 0; -+ -+ if (port_bswap) { -+ data_offset = (port_width - 2); -+ ctl_offset = (port_width - 1); -+ } -+ - /* Fixup the port shift for platforms that need it */ -- ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift); -- ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift); -- ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift); -- ioaddr->nsect_addr = ioaddr->cmd_addr + (ATA_REG_NSECT << shift); -- ioaddr->lbal_addr = ioaddr->cmd_addr + (ATA_REG_LBAL << shift); -- ioaddr->lbam_addr = ioaddr->cmd_addr + (ATA_REG_LBAM << shift); -- ioaddr->lbah_addr = ioaddr->cmd_addr + (ATA_REG_LBAH << shift); -- ioaddr->device_addr = ioaddr->cmd_addr + (ATA_REG_DEVICE << shift); -- ioaddr->status_addr = ioaddr->cmd_addr + (ATA_REG_STATUS << shift); -- ioaddr->command_addr = ioaddr->cmd_addr + (ATA_REG_CMD << shift); -+ ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << port_shift) + data_offset; -+ ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << port_shift) + ctl_offset; -+ ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << port_shift) + ctl_offset; -+ ioaddr->nsect_addr = ioaddr->cmd_addr + (ATA_REG_NSECT << port_shift) + ctl_offset; -+ ioaddr->lbal_addr = ioaddr->cmd_addr + (ATA_REG_LBAL << port_shift) + ctl_offset; -+ ioaddr->lbam_addr = ioaddr->cmd_addr + (ATA_REG_LBAM << port_shift) + ctl_offset; -+ ioaddr->lbah_addr = ioaddr->cmd_addr + (ATA_REG_LBAH << port_shift) + ctl_offset; -+ ioaddr->device_addr = ioaddr->cmd_addr + (ATA_REG_DEVICE << port_shift) + ctl_offset; -+ ioaddr->status_addr = ioaddr->cmd_addr + (ATA_REG_STATUS << port_shift) + ctl_offset; -+ ioaddr->command_addr = ioaddr->cmd_addr + (ATA_REG_CMD << port_shift) + ctl_offset; - } - - /** -@@ -102,7 +165,8 @@ int __devinit __pata_platform_probe(struct device *dev, - struct resource *io_res, - struct resource *ctl_res, - struct resource *irq_res, -- unsigned int ioport_shift, -+ unsigned int port_width, -+ bool port_bswap, - int __pio_mask) - { - struct ata_host *host; -@@ -166,7 +230,12 @@ int __devinit __pata_platform_probe(struct device *dev, - - ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; - -- pata_platform_setup_port(&ap->ioaddr, ioport_shift); -+ pata_platform_setup_port(&ap->ioaddr, port_width, port_bswap); -+ if (port_bswap) { -+ pata_platform_port_ops.sff_data_xfer = pata_platform_data_xfer_bswap; -+ } -+ dev_info(dev, "port width: %u byte swap %s\n", -+ port_width, port_bswap ? "enabled" : "disabled"); - - ata_port_desc(ap, "%s cmd 0x%llx ctl 0x%llx", mmio ? "mmio" : "ioport", - (unsigned long long)io_res->start, -@@ -238,7 +307,8 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) - irq_res->flags = pp_info ? pp_info->irq_flags : 0; - - return __pata_platform_probe(&pdev->dev, io_res, ctl_res, irq_res, -- pp_info ? pp_info->ioport_shift : 0, -+ pp_info ? pp_info->port_width : 1, -+ pp_info ? pp_info->port_bswap : false, - pio_mask); - } - -diff --git a/include/linux/ata_platform.h b/include/linux/ata_platform.h -index 9a26c83..b38ab9c 100644 ---- a/include/linux/ata_platform.h -+++ b/include/linux/ata_platform.h -@@ -7,7 +7,12 @@ struct pata_platform_info { - * constantly spaced and need larger than the 1-byte - * spacing used by ata_std_ports(). - */ -- unsigned int ioport_shift; -+ unsigned int port_width; -+ /* -+ * Handle data byte swapping for platforms with byte-swapped -+ * ports. -+ */ -+ bool port_bswap; - /* - * Indicate platform specific irq types and initial - * IRQ flags when call request_irq() -@@ -19,7 +24,8 @@ extern int __devinit __pata_platform_probe(struct device *dev, - struct resource *io_res, - struct resource *ctl_res, - struct resource *irq_res, -- unsigned int ioport_shift, -+ unsigned int port_width, -+ bool port_bswap, - int __pio_mask); - - extern int __devexit __pata_platform_remove(struct device *dev); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pca9505-i2c-gpio.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pca9505-i2c-gpio.patch deleted file mode 100644 index d2650011..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pca9505-i2c-gpio.patch +++ /dev/null @@ -1,874 +0,0 @@ -Adds pca9505 and pca9506 40-bit gpio support to the pca953x driver - -diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig -index 4e04157..2870b99 100644 ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -227,7 +227,7 @@ config GPIO_MAX732X_IRQ - controller. It requires the driver to be built in the kernel. - - config GPIO_PCA953X -- tristate "PCA953x, PCA955x, TCA64xx, and MAX7310 I/O ports" -+ tristate "PCA953x, PCA955x, PCA9698, TCA64xx, and MAX7310 I/O ports" - depends on I2C - help - Say yes here to provide access to several register-oriented -@@ -241,6 +241,8 @@ config GPIO_PCA953X - - 16 bits: pca9535, pca9539, pca9555, tca6416 - -+ 40 bits: pca9698 -+ - config GPIO_PCA953X_IRQ - bool "Interrupt controller support for PCA953x" - depends on GPIO_PCA953X=y -diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c -index d3f3e8f..5a215fb 100644 ---- a/drivers/gpio/gpio-pca953x.c -+++ b/drivers/gpio/gpio-pca953x.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -28,6 +29,8 @@ - #define PCA953X_INVERT 2 - #define PCA953X_DIRECTION 3 - -+#define REG_ADDR_AI 0x80 -+ - #define PCA957X_IN 0 - #define PCA957X_INVRT 1 - #define PCA957X_BKEN 2 -@@ -43,6 +46,8 @@ - #define PCA957X_TYPE 0x2000 - - static const struct i2c_device_id pca953x_id[] = { -+ { "pca9505", 40 | PCA953X_TYPE | PCA_INT, }, -+ { "pca9506", 40 | PCA953X_TYPE | PCA_INT, }, - { "pca9534", 8 | PCA953X_TYPE | PCA_INT, }, - { "pca9535", 16 | PCA953X_TYPE | PCA_INT, }, - { "pca9536", 4 | PCA953X_TYPE, }, -@@ -55,6 +60,7 @@ static const struct i2c_device_id pca953x_id[] = { - { "pca9557", 8 | PCA953X_TYPE, }, - { "pca9574", 8 | PCA957X_TYPE | PCA_INT, }, - { "pca9575", 16 | PCA957X_TYPE | PCA_INT, }, -+ { "pca9698", 40 | PCA953X_TYPE, }, - - { "max7310", 8 | PCA953X_TYPE, }, - { "max7312", 16 | PCA953X_TYPE | PCA_INT, }, -@@ -63,24 +69,29 @@ static const struct i2c_device_id pca953x_id[] = { - { "pca6107", 8 | PCA953X_TYPE | PCA_INT, }, - { "tca6408", 8 | PCA953X_TYPE | PCA_INT, }, - { "tca6416", 16 | PCA953X_TYPE | PCA_INT, }, -- /* NYET: { "tca6424", 24, }, */ -+ { "tca6424", 24 | PCA953X_TYPE | PCA_INT, }, - { } - }; - MODULE_DEVICE_TABLE(i2c, pca953x_id); - -+#define MAX_BANK 5 -+#define BANK_SZ 8 -+ -+#define NBANK(chip) (chip->gpio_chip.ngpio / BANK_SZ) -+ - struct pca953x_chip { - unsigned gpio_start; -- uint16_t reg_output; -- uint16_t reg_direction; -+ u8 reg_output[MAX_BANK]; -+ u8 reg_direction[MAX_BANK]; - struct mutex i2c_lock; - - #ifdef CONFIG_GPIO_PCA953X_IRQ - struct mutex irq_lock; -- uint16_t irq_mask; -- uint16_t irq_stat; -- uint16_t irq_trig_raise; -- uint16_t irq_trig_fall; -- int irq_base; -+ u8 irq_mask[MAX_BANK]; -+ u8 irq_stat[MAX_BANK]; -+ u8 irq_trig_raise[MAX_BANK]; -+ u8 irq_trig_fall[MAX_BANK]; -+ struct irq_domain *domain; - #endif - - struct i2c_client *client; -@@ -89,26 +100,68 @@ struct pca953x_chip { - int chip_type; - }; - --static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) -+static int pca953x_read_single(struct pca953x_chip *chip, int reg, u32 *val, -+ int off) -+{ -+ int ret; -+ int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ); -+ int offset = off / BANK_SZ; -+ -+ ret = i2c_smbus_read_byte_data(chip->client, -+ (reg << bank_shift) + offset); -+ *val = ret; -+ -+ if (ret < 0) { -+ dev_err(&chip->client->dev, "failed reading register\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int pca953x_write_single(struct pca953x_chip *chip, int reg, u32 val, -+ int off) -+{ -+ int ret = 0; -+ int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ); -+ int offset = off / BANK_SZ; -+ -+ ret = i2c_smbus_write_byte_data(chip->client, -+ (reg << bank_shift) + offset, val); -+ -+ if (ret < 0) { -+ dev_err(&chip->client->dev, "failed writing register\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int pca953x_write_regs(struct pca953x_chip *chip, int reg, u8 *val) - { - int ret = 0; - - if (chip->gpio_chip.ngpio <= 8) -- ret = i2c_smbus_write_byte_data(chip->client, reg, val); -- else { -+ ret = i2c_smbus_write_byte_data(chip->client, reg, *val); -+ else if (chip->gpio_chip.ngpio >= 24) { -+ int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ); -+ ret = i2c_smbus_write_i2c_block_data(chip->client, -+ (reg << bank_shift) | REG_ADDR_AI, -+ NBANK(chip), val); -+ } else { - switch (chip->chip_type) { - case PCA953X_TYPE: - ret = i2c_smbus_write_word_data(chip->client, -- reg << 1, val); -+ reg << 1, (u16) *val); - break; - case PCA957X_TYPE: - ret = i2c_smbus_write_byte_data(chip->client, reg << 1, -- val & 0xff); -+ val[0]); - if (ret < 0) - break; - ret = i2c_smbus_write_byte_data(chip->client, - (reg << 1) + 1, -- (val & 0xff00) >> 8); -+ val[1]); - break; - } - } -@@ -121,34 +174,42 @@ static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) - return 0; - } - --static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val) -+static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val) - { - int ret; - -- if (chip->gpio_chip.ngpio <= 8) -+ if (chip->gpio_chip.ngpio <= 8) { - ret = i2c_smbus_read_byte_data(chip->client, reg); -- else -- ret = i2c_smbus_read_word_data(chip->client, reg << 1); -+ *val = ret; -+ } else if (chip->gpio_chip.ngpio >= 24) { -+ int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ); - -+ ret = i2c_smbus_read_i2c_block_data(chip->client, -+ (reg << bank_shift) | REG_ADDR_AI, -+ NBANK(chip), val); -+ } else { -+ ret = i2c_smbus_read_word_data(chip->client, reg << 1); -+ val[0] = (u16)ret & 0xFF; -+ val[1] = (u16)ret >> 8; -+ } - if (ret < 0) { - dev_err(&chip->client->dev, "failed reading register\n"); - return ret; - } - -- *val = (uint16_t)ret; - return 0; - } - - static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) - { - struct pca953x_chip *chip; -- uint16_t reg_val; -+ u8 reg_val; - int ret, offset = 0; - - chip = container_of(gc, struct pca953x_chip, gpio_chip); - - mutex_lock(&chip->i2c_lock); -- reg_val = chip->reg_direction | (1u << off); -+ reg_val = chip->reg_direction[off / BANK_SZ] | (1u << (off % BANK_SZ)); - - switch (chip->chip_type) { - case PCA953X_TYPE: -@@ -158,11 +219,11 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) - offset = PCA957X_CFG; - break; - } -- ret = pca953x_write_reg(chip, offset, reg_val); -+ ret = pca953x_write_single(chip, offset, reg_val, off); - if (ret) - goto exit; - -- chip->reg_direction = reg_val; -+ chip->reg_direction[off / BANK_SZ] = reg_val; - ret = 0; - exit: - mutex_unlock(&chip->i2c_lock); -@@ -173,7 +234,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, - unsigned off, int val) - { - struct pca953x_chip *chip; -- uint16_t reg_val; -+ u8 reg_val; - int ret, offset = 0; - - chip = container_of(gc, struct pca953x_chip, gpio_chip); -@@ -181,9 +242,11 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, - mutex_lock(&chip->i2c_lock); - /* set output level */ - if (val) -- reg_val = chip->reg_output | (1u << off); -+ reg_val = chip->reg_output[off / BANK_SZ] -+ | (1u << (off % BANK_SZ)); - else -- reg_val = chip->reg_output & ~(1u << off); -+ reg_val = chip->reg_output[off / BANK_SZ] -+ & ~(1u << (off % BANK_SZ)); - - switch (chip->chip_type) { - case PCA953X_TYPE: -@@ -193,14 +256,14 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, - offset = PCA957X_OUT; - break; - } -- ret = pca953x_write_reg(chip, offset, reg_val); -+ ret = pca953x_write_single(chip, offset, reg_val, off); - if (ret) - goto exit; - -- chip->reg_output = reg_val; -+ chip->reg_output[off / BANK_SZ] = reg_val; - - /* then direction */ -- reg_val = chip->reg_direction & ~(1u << off); -+ reg_val = chip->reg_direction[off / BANK_SZ] & ~(1u << (off % BANK_SZ)); - switch (chip->chip_type) { - case PCA953X_TYPE: - offset = PCA953X_DIRECTION; -@@ -209,11 +272,11 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, - offset = PCA957X_CFG; - break; - } -- ret = pca953x_write_reg(chip, offset, reg_val); -+ ret = pca953x_write_single(chip, offset, reg_val, off); - if (ret) - goto exit; - -- chip->reg_direction = reg_val; -+ chip->reg_direction[off / BANK_SZ] = reg_val; - ret = 0; - exit: - mutex_unlock(&chip->i2c_lock); -@@ -223,7 +286,7 @@ exit: - static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) - { - struct pca953x_chip *chip; -- uint16_t reg_val; -+ u32 reg_val; - int ret, offset = 0; - - chip = container_of(gc, struct pca953x_chip, gpio_chip); -@@ -237,7 +300,7 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) - offset = PCA957X_IN; - break; - } -- ret = pca953x_read_reg(chip, offset, ®_val); -+ ret = pca953x_read_single(chip, offset, ®_val, off); - mutex_unlock(&chip->i2c_lock); - if (ret < 0) { - /* NOTE: diagnostic already emitted; that's all we should -@@ -247,22 +310,24 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) - return 0; - } - -- return (reg_val & (1u << off)) ? 1 : 0; -+ return (reg_val & (1u << (off % BANK_SZ))) ? 1 : 0; - } - - static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) - { - struct pca953x_chip *chip; -- uint16_t reg_val; -+ u8 reg_val; - int ret, offset = 0; - - chip = container_of(gc, struct pca953x_chip, gpio_chip); - - mutex_lock(&chip->i2c_lock); - if (val) -- reg_val = chip->reg_output | (1u << off); -+ reg_val = chip->reg_output[off / BANK_SZ] -+ | (1u << (off % BANK_SZ)); - else -- reg_val = chip->reg_output & ~(1u << off); -+ reg_val = chip->reg_output[off / BANK_SZ] -+ & ~(1u << (off % BANK_SZ)); - - switch (chip->chip_type) { - case PCA953X_TYPE: -@@ -272,11 +337,11 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) - offset = PCA957X_OUT; - break; - } -- ret = pca953x_write_reg(chip, offset, reg_val); -+ ret = pca953x_write_single(chip, offset, reg_val, off); - if (ret) - goto exit; - -- chip->reg_output = reg_val; -+ chip->reg_output[off / BANK_SZ] = reg_val; - exit: - mutex_unlock(&chip->i2c_lock); - } -@@ -307,21 +372,21 @@ static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off) - struct pca953x_chip *chip; - - chip = container_of(gc, struct pca953x_chip, gpio_chip); -- return chip->irq_base + off; -+ return irq_create_mapping(chip->domain, off); - } - - static void pca953x_irq_mask(struct irq_data *d) - { - struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); - -- chip->irq_mask &= ~(1 << (d->irq - chip->irq_base)); -+ chip->irq_mask[d->hwirq / BANK_SZ] &= ~(1 << (d->hwirq % BANK_SZ)); - } - - static void pca953x_irq_unmask(struct irq_data *d) - { - struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); - -- chip->irq_mask |= 1 << (d->irq - chip->irq_base); -+ chip->irq_mask[d->hwirq / BANK_SZ] |= 1 << (d->hwirq % BANK_SZ); - } - - static void pca953x_irq_bus_lock(struct irq_data *d) -@@ -334,17 +399,20 @@ static void pca953x_irq_bus_lock(struct irq_data *d) - static void pca953x_irq_bus_sync_unlock(struct irq_data *d) - { - struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); -- uint16_t new_irqs; -- uint16_t level; -+ u8 new_irqs; -+ int level, i; - - /* Look for any newly setup interrupt */ -- new_irqs = chip->irq_trig_fall | chip->irq_trig_raise; -- new_irqs &= ~chip->reg_direction; -- -- while (new_irqs) { -- level = __ffs(new_irqs); -- pca953x_gpio_direction_input(&chip->gpio_chip, level); -- new_irqs &= ~(1 << level); -+ for (i = 0; i < NBANK(chip); i++) { -+ new_irqs = chip->irq_trig_fall[i] | chip->irq_trig_raise[i]; -+ new_irqs &= ~chip->reg_direction[i]; -+ -+ while (new_irqs) { -+ level = __ffs(new_irqs); -+ pca953x_gpio_direction_input(&chip->gpio_chip, -+ level + (BANK_SZ * i)); -+ new_irqs &= ~(1 << level); -+ } - } - - mutex_unlock(&chip->irq_lock); -@@ -353,8 +421,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) - static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) - { - struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); -- uint16_t level = d->irq - chip->irq_base; -- uint16_t mask = 1 << level; -+ int bank_nb = d->hwirq / BANK_SZ; -+ u8 mask = 1 << (d->hwirq % BANK_SZ); - - if (!(type & IRQ_TYPE_EDGE_BOTH)) { - dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", -@@ -363,14 +431,14 @@ static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) - } - - if (type & IRQ_TYPE_EDGE_FALLING) -- chip->irq_trig_fall |= mask; -+ chip->irq_trig_fall[bank_nb] |= mask; - else -- chip->irq_trig_fall &= ~mask; -+ chip->irq_trig_fall[bank_nb] &= ~mask; - - if (type & IRQ_TYPE_EDGE_RISING) -- chip->irq_trig_raise |= mask; -+ chip->irq_trig_raise[bank_nb] |= mask; - else -- chip->irq_trig_raise &= ~mask; -+ chip->irq_trig_raise[bank_nb] &= ~mask; - - return 0; - } -@@ -384,13 +452,13 @@ static struct irq_chip pca953x_irq_chip = { - .irq_set_type = pca953x_irq_set_type, - }; - --static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) -+static u8 pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending) - { -- uint16_t cur_stat; -- uint16_t old_stat; -- uint16_t pending; -- uint16_t trigger; -- int ret, offset = 0; -+ u8 cur_stat[MAX_BANK]; -+ u8 old_stat[MAX_BANK]; -+ u8 pendings = 0; -+ u8 trigger[MAX_BANK], triggers = 0; -+ int ret, i, offset = 0; - - switch (chip->chip_type) { - case PCA953X_TYPE: -@@ -400,59 +468,88 @@ static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) - offset = PCA957X_IN; - break; - } -- ret = pca953x_read_reg(chip, offset, &cur_stat); -+ ret = pca953x_read_regs(chip, offset, cur_stat); - if (ret) - return 0; - - /* Remove output pins from the equation */ -- cur_stat &= chip->reg_direction; -+ for (i = 0; i < NBANK(chip); i++) -+ cur_stat[i] &= chip->reg_direction[i]; -+ -+ memcpy(old_stat, chip->irq_stat, NBANK(chip)); - -- old_stat = chip->irq_stat; -- trigger = (cur_stat ^ old_stat) & chip->irq_mask; -+ for (i = 0; i < NBANK(chip); i++) { -+ trigger[i] = (cur_stat[i] ^ old_stat[i]) & chip->irq_mask[i]; -+ triggers += trigger[i]; -+ } - -- if (!trigger) -+ if (!triggers) - return 0; - -- chip->irq_stat = cur_stat; -+ memcpy(chip->irq_stat, cur_stat, NBANK(chip)); - -- pending = (old_stat & chip->irq_trig_fall) | -- (cur_stat & chip->irq_trig_raise); -- pending &= trigger; -+ for (i = 0; i < NBANK(chip); i++) { -+ pending[i] = (old_stat[i] & chip->irq_trig_fall[i]) | -+ (cur_stat[i] & chip->irq_trig_raise[i]); -+ pending[i] &= trigger[i]; -+ pendings += pending[i]; -+ } - -- return pending; -+ return pendings; - } - - static irqreturn_t pca953x_irq_handler(int irq, void *devid) - { - struct pca953x_chip *chip = devid; -- uint16_t pending; -- uint16_t level; -- -- pending = pca953x_irq_pending(chip); -+ u8 pending[MAX_BANK]; -+ u8 level; -+ int i; - -- if (!pending) -+ if (!pca953x_irq_pending(chip, pending)) - return IRQ_HANDLED; - -- do { -- level = __ffs(pending); -- handle_nested_irq(level + chip->irq_base); -- -- pending &= ~(1 << level); -- } while (pending); -+ for (i = 0; i < NBANK(chip); i++) { -+ while (pending[i]) { -+ level = __ffs(pending[i]); -+ handle_nested_irq(irq_find_mapping(chip->domain, -+ level + (BANK_SZ * i))); -+ pending[i] &= ~(1 << level); -+ } -+ } - - return IRQ_HANDLED; - } - -+static int pca953x_gpio_irq_map(struct irq_domain *d, unsigned int irq, -+ irq_hw_number_t hwirq) -+{ -+ irq_clear_status_flags(irq, IRQ_NOREQUEST); -+ irq_set_chip_data(irq, d->host_data); -+ irq_set_chip(irq, &pca953x_irq_chip); -+ irq_set_nested_thread(irq, true); -+#ifdef CONFIG_ARM -+ set_irq_flags(irq, IRQF_VALID); -+#else -+ irq_set_noprobe(irq); -+#endif -+ -+ return 0; -+} -+ -+static const struct irq_domain_ops pca953x_irq_simple_ops = { -+ .map = pca953x_gpio_irq_map, -+ .xlate = irq_domain_xlate_twocell, -+}; -+ - static int pca953x_irq_setup(struct pca953x_chip *chip, - const struct i2c_device_id *id, - int irq_base) - { - struct i2c_client *client = chip->client; -- int ret, offset = 0; -+ int ret, i, offset = 0; - - if (irq_base != -1 - && (id->driver_data & PCA_INT)) { -- int lvl; - - switch (chip->chip_type) { - case PCA953X_TYPE: -@@ -462,37 +559,29 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, - offset = PCA957X_IN; - break; - } -- ret = pca953x_read_reg(chip, offset, &chip->irq_stat); -+ ret = pca953x_read_regs(chip, offset, chip->irq_stat); - if (ret) -- goto out_failed; -+ return ret; - - /* - * There is no way to know which GPIO line generated the - * interrupt. We have to rely on the previous read for - * this purpose. - */ -- chip->irq_stat &= chip->reg_direction; -+ for (i = 0; i < NBANK(chip); i++) -+ chip->irq_stat[i] &= chip->reg_direction[i]; - mutex_init(&chip->irq_lock); - -- chip->irq_base = irq_alloc_descs(-1, irq_base, chip->gpio_chip.ngpio, -1); -- if (chip->irq_base < 0) -- goto out_failed; -- -- for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { -- int irq = lvl + chip->irq_base; -+ chip->domain = irq_domain_add_simple(client->dev.of_node, -+ chip->gpio_chip.ngpio, -+ irq_base, -+ &pca953x_irq_simple_ops, -+ chip); -+ if (!chip->domain) -+ return -ENODEV; - -- irq_clear_status_flags(irq, IRQ_NOREQUEST); -- irq_set_chip_data(irq, chip); -- irq_set_chip(irq, &pca953x_irq_chip); -- irq_set_nested_thread(irq, true); --#ifdef CONFIG_ARM -- set_irq_flags(irq, IRQF_VALID); --#else -- irq_set_noprobe(irq); --#endif -- } -- -- ret = request_threaded_irq(client->irq, -+ ret = devm_request_threaded_irq(&client->dev, -+ client->irq, - NULL, - pca953x_irq_handler, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, -@@ -500,26 +589,15 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, - if (ret) { - dev_err(&client->dev, "failed to request irq %d\n", - client->irq); -- goto out_failed; -+ return ret; - } - - chip->gpio_chip.to_irq = pca953x_gpio_to_irq; - } - - return 0; -- --out_failed: -- chip->irq_base = -1; -- return ret; - } - --static void pca953x_irq_teardown(struct pca953x_chip *chip) --{ -- if (chip->irq_base != -1) { -- irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio); -- free_irq(chip->client->irq, chip); -- } --} - #else /* CONFIG_GPIO_PCA953X_IRQ */ - static int pca953x_irq_setup(struct pca953x_chip *chip, - const struct i2c_device_id *id, -@@ -532,10 +610,6 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, - - return 0; - } -- --static void pca953x_irq_teardown(struct pca953x_chip *chip) --{ --} - #endif - - /* -@@ -547,7 +621,7 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip) - * WARNING: This is DEPRECATED and will be removed eventually! - */ - static void --pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) -+pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert) - { - struct device_node *node; - const __be32 *val; -@@ -575,75 +649,80 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) - } - #else - static void --pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) -+pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert) - { - *gpio_base = -1; - } - #endif - --static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert) -+static int device_pca953x_init(struct pca953x_chip *chip, u32 invert) - { - int ret; -+ u8 val[MAX_BANK]; - -- ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); -+ ret = pca953x_read_regs(chip, PCA953X_OUTPUT, chip->reg_output); - if (ret) - goto out; - -- ret = pca953x_read_reg(chip, PCA953X_DIRECTION, -- &chip->reg_direction); -+ ret = pca953x_read_regs(chip, PCA953X_DIRECTION, -+ chip->reg_direction); - if (ret) - goto out; - - /* set platform specific polarity inversion */ -- ret = pca953x_write_reg(chip, PCA953X_INVERT, invert); -+ if (invert) -+ memset(val, 0xFF, NBANK(chip)); -+ else -+ memset(val, 0, NBANK(chip)); -+ -+ ret = pca953x_write_regs(chip, PCA953X_INVERT, val); - out: - return ret; - } - --static int __devinit device_pca957x_init(struct pca953x_chip *chip, int invert) -+static int device_pca957x_init(struct pca953x_chip *chip, u32 invert) - { - int ret; -- uint16_t val = 0; -- -- /* Let every port in proper state, that could save power */ -- pca953x_write_reg(chip, PCA957X_PUPD, 0x0); -- pca953x_write_reg(chip, PCA957X_CFG, 0xffff); -- pca953x_write_reg(chip, PCA957X_OUT, 0x0); -+ u8 val[MAX_BANK]; - -- ret = pca953x_read_reg(chip, PCA957X_IN, &val); -- if (ret) -- goto out; -- ret = pca953x_read_reg(chip, PCA957X_OUT, &chip->reg_output); -+ ret = pca953x_read_regs(chip, PCA957X_OUT, chip->reg_output); - if (ret) - goto out; -- ret = pca953x_read_reg(chip, PCA957X_CFG, &chip->reg_direction); -+ ret = pca953x_read_regs(chip, PCA957X_CFG, chip->reg_direction); - if (ret) - goto out; - - /* set platform specific polarity inversion */ -- pca953x_write_reg(chip, PCA957X_INVRT, invert); -+ if (invert) -+ memset(val, 0xFF, NBANK(chip)); -+ else -+ memset(val, 0, NBANK(chip)); -+ pca953x_write_regs(chip, PCA957X_INVRT, val); - - /* To enable register 6, 7 to controll pull up and pull down */ -- pca953x_write_reg(chip, PCA957X_BKEN, 0x202); -+ memset(val, 0x02, NBANK(chip)); -+ pca953x_write_regs(chip, PCA957X_BKEN, val); - - return 0; - out: - return ret; - } - --static int __devinit pca953x_probe(struct i2c_client *client, -+static int pca953x_probe(struct i2c_client *client, - const struct i2c_device_id *id) - { - struct pca953x_platform_data *pdata; - struct pca953x_chip *chip; -- int irq_base=0, invert=0; -+ int irq_base = 0; - int ret; -+ u32 invert = 0; - -- chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); -+ chip = devm_kzalloc(&client->dev, -+ sizeof(struct pca953x_chip), GFP_KERNEL); - if (chip == NULL) - return -ENOMEM; - -- pdata = client->dev.platform_data; -+ pdata = dev_get_platdata(&client->dev); - if (pdata) { - irq_base = pdata->irq_base; - chip->gpio_start = pdata->gpio_base; -@@ -674,15 +753,15 @@ static int __devinit pca953x_probe(struct i2c_client *client, - else - ret = device_pca957x_init(chip, invert); - if (ret) -- goto out_failed; -+ return ret; - - ret = pca953x_irq_setup(chip, id, irq_base); - if (ret) -- goto out_failed; -+ return ret; - - ret = gpiochip_add(&chip->gpio_chip); - if (ret) -- goto out_failed_irq; -+ return ret; - - if (pdata && pdata->setup) { - ret = pdata->setup(client, chip->gpio_chip.base, -@@ -693,17 +772,11 @@ static int __devinit pca953x_probe(struct i2c_client *client, - - i2c_set_clientdata(client, chip); - return 0; -- --out_failed_irq: -- pca953x_irq_teardown(chip); --out_failed: -- kfree(chip); -- return ret; - } - - static int pca953x_remove(struct i2c_client *client) - { -- struct pca953x_platform_data *pdata = client->dev.platform_data; -+ struct pca953x_platform_data *pdata = dev_get_platdata(&client->dev); - struct pca953x_chip *chip = i2c_get_clientdata(client); - int ret = 0; - -@@ -724,14 +797,44 @@ static int pca953x_remove(struct i2c_client *client) - return ret; - } - -- pca953x_irq_teardown(chip); -- kfree(chip); - return 0; - } - -+static const struct of_device_id pca953x_dt_ids[] = { -+ { .compatible = "nxp,pca9505", }, -+ { .compatible = "nxp,pca9506", }, -+ { .compatible = "nxp,pca9534", }, -+ { .compatible = "nxp,pca9535", }, -+ { .compatible = "nxp,pca9536", }, -+ { .compatible = "nxp,pca9537", }, -+ { .compatible = "nxp,pca9538", }, -+ { .compatible = "nxp,pca9539", }, -+ { .compatible = "nxp,pca9554", }, -+ { .compatible = "nxp,pca9555", }, -+ { .compatible = "nxp,pca9556", }, -+ { .compatible = "nxp,pca9557", }, -+ { .compatible = "nxp,pca9574", }, -+ { .compatible = "nxp,pca9575", }, -+ { .compatible = "nxp,pca9698", }, -+ -+ { .compatible = "maxim,max7310", }, -+ { .compatible = "maxim,max7312", }, -+ { .compatible = "maxim,max7313", }, -+ { .compatible = "maxim,max7315", }, -+ -+ { .compatible = "ti,pca6107", }, -+ { .compatible = "ti,tca6408", }, -+ { .compatible = "ti,tca6416", }, -+ { .compatible = "ti,tca6424", }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(of, pca953x_dt_ids); -+ - static struct i2c_driver pca953x_driver = { - .driver = { - .name = "pca953x", -+ .of_match_table = pca953x_dt_ids, - }, - .probe = pca953x_probe, - .remove = pca953x_remove, -diff --git a/include/linux/i2c/pca953x.h b/include/linux/i2c/pca953x.h -index 139ba52..2a69244 100644 ---- a/include/linux/i2c/pca953x.h -+++ b/include/linux/i2c/pca953x.h -@@ -11,7 +11,7 @@ struct pca953x_platform_data { - unsigned gpio_base; - - /* initial polarity inversion setting */ -- uint16_t invert; -+ uint32_t invert; - - /* interrupt base */ - int irq_base; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pca954x-i2c-mux-deselect-on-exit-config-option.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pca954x-i2c-mux-deselect-on-exit-config-option.patch deleted file mode 100644 index 14ca76f6..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pca954x-i2c-mux-deselect-on-exit-config-option.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/drivers/i2c/muxes/Kconfig 2015-10-27 16:54:02.741944172 +0000 -+++ b/drivers/i2c/muxes/Kconfig 2015-10-27 16:55:02.645945471 +0000 -@@ -56,6 +56,14 @@ config I2C_MUX_PCA954x - This driver can also be built as a module. If so, the module - will be called pca954x. - -+config I2C_MUX_PCA954X_DESELECT_ON_EXIT -+ bool "Enable deselect-on-exit feature for PCA954X devices." -+ depends on I2C_MUX_PCA954x -+ help -+ If you say yes here you enable the deselect-on-exit feature in -+ the pca954x i2c driver. -+ -+ - config I2C_MUX_DNI_6448 - tristate "Delta Networks 6448 I2C Mux" - depends on EXPERIMENTAL ---- linux-3.2.65-1+deb7u2/drivers/i2c/muxes/pca954x.c 2015-10-27 17:13:03.937968935 +0000 -+++ b/drivers/i2c/muxes/pca954x.c 2015-10-27 17:12:41.265968443 +0000 -@@ -222,6 +222,10 @@ static int pca954x_probe(struct i2c_clie - deselect_on_exit = 1; - } - -+#ifdef CONFIG_I2C_MUX_PCA954X_DESELECT_ON_EXIT -+ deselect_on_exit = 1; -+#endif -+ - data->type = id->driver_data; - data->last_chan = 0; /* force the first selection */ - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pca954x-i2c-mux-deselect-on-exit-dtb-property.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pca954x-i2c-mux-deselect-on-exit-dtb-property.patch deleted file mode 100644 index bab38ed5..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-pca954x-i2c-mux-deselect-on-exit-dtb-property.patch +++ /dev/null @@ -1,66 +0,0 @@ -Modify the pca954x driver to check for the "deselect_on_exit" property in the dtb. -After the current transaction is complete the MUX deselects all sub-interfaces. - -diff --git a/Documentation/devicetree/bindings/i2c/mux.txt b/Documentation/devicetree/bindings/i2c/mux.txt -index af84cce..fc9b542 100644 ---- a/Documentation/devicetree/bindings/i2c/mux.txt -+++ b/Documentation/devicetree/bindings/i2c/mux.txt -@@ -17,7 +17,8 @@ Required properties for child nodes: - Optional properties for child nodes: - - Other properties specific to the multiplexer/switch hardware. - - Child nodes conforming to i2c bus binding -- -+- deselect-on-exit -- if set deselect the mux after each transaction, -+ supported by the pca954x.c driver. - - Example : - -@@ -32,6 +33,7 @@ Example : - reg = <0x70>; - #address-cells = <1>; - #size-cells = <0>; -+ deselect-on-exit; - - i2c@3 { - #address-cells = <1>; -diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c -index 5c6ecc7..c9db544 100644 ---- a/drivers/i2c/muxes/pca954x.c -+++ b/drivers/i2c/muxes/pca954x.c -@@ -188,6 +188,7 @@ static int pca954x_probe(struct i2c_client *client, - struct pca954x_platform_data *pdata = client->dev.platform_data; - int num, force; - struct pca954x *data; -+ int deselect_on_exit = 0; - int ret = -ENODEV; - - if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) -@@ -210,6 +211,17 @@ static int pca954x_probe(struct i2c_client *client, - goto exit_free; - } - -+ /* -+ * Check whether we want to deselect the mux after the -+ * transaction. This can be specified in one of two ways: -+ * -+ * 1. using platform data: pdata->modes[num].deselect_on_exit -+ * 2. using the device tree property deselect_on_exit -+ */ -+ if (of_find_property(client->dev.of_node, "deselect-on-exit", NULL)) { -+ deselect_on_exit = 1; -+ } -+ - data->type = id->driver_data; - data->last_chan = 0; /* force the first selection */ - -@@ -228,8 +240,8 @@ static int pca954x_probe(struct i2c_client *client, - data->virt_adaps[num] = - i2c_add_mux_adapter(adap, &client->dev, client, - force, num, pca954x_select_chan, -- (pdata && pdata->modes[num].deselect_on_exit) -- ? pca954x_deselect_mux : NULL); -+ (pdata && pdata->modes[num].deselect_on_exit) || deselect_on_exit -+ ? pca954x_deselect_mux : NULL); - - if (data->virt_adaps[num] == NULL) { - ret = -ENODEV; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-rtc-hw-clock-fix-up.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-rtc-hw-clock-fix-up.patch deleted file mode 100644 index 4aa1736a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-rtc-hw-clock-fix-up.patch +++ /dev/null @@ -1,92 +0,0 @@ -platform rtc hw clock fix up - -In some cases the RTC contains invalid date/time values. At boot time -when the invalid values are detected, attempt to write valid time/date -to the hardware. - -diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c -index bc90b09..b7bb5ca 100644 ---- a/drivers/rtc/hctosys.c -+++ b/drivers/rtc/hctosys.c -@@ -24,6 +24,57 @@ - - int rtc_hctosys_ret = -ENODEV; - -+// Approximately the number of seconds in a 42 year span -+#define SECONDS_IN_42_YEARS (42 * 365 * 24 * 3600) -+ -+static int __init rtc_hc_fixup(struct rtc_device *rtc, struct rtc_time *p_tm) -+{ -+ int err = 0; -+ -+ /* -+ * rtc_time_to_tm() converts seconds since 1970-01-01 to a -+ * struct rtc_time. -+ * -+ * Some RTC drivers only store (year % 100) and assume 2000 on -+ * read back. For example when storing 1970, only 70 is -+ * stored in the hardware, but on read back it would be 2070. -+ * -+ * To work around this, pick a default date/time with the -+ * year > 2000. -+ * -+ * Adding 42 years worth of seconds puts the default date/time -+ * near 2012. -+ * -+ * As this code is being written in 2013, a default time -+ * around 2012 is safe to assume. -+ * -+ */ -+ rtc_time_to_tm(SECONDS_IN_42_YEARS, p_tm); -+ err = rtc_set_time(rtc, p_tm); -+ -+ if (err) { -+ dev_err(rtc->dev.parent, -+ "hc_fixup: unable to set hardware clock date/time\n"); -+ return err; -+ } -+ -+ err = rtc_read_time(rtc, p_tm); -+ if (err) { -+ dev_err(rtc->dev.parent, -+ "hc_fixup: unable to read the hardware clock\n"); -+ return err; -+ } -+ -+ err = rtc_valid_tm(p_tm); -+ if (err) { -+ dev_err(rtc->dev.parent, -+ "hc_fixup: unable to fix-up invalid date/time\n"); -+ return err; -+ } -+ -+ return err; -+} -+ - static int __init rtc_hctosys(void) - { - int err = -ENODEV; -@@ -43,15 +94,20 @@ static int __init rtc_hctosys(void) - if (err) { - dev_err(rtc->dev.parent, - "hctosys: unable to read the hardware clock\n"); -- goto err_read; -- -+ err = rtc_hc_fixup(rtc, &tm); -+ if (err) { -+ goto err_read; -+ } - } - - err = rtc_valid_tm(&tm); - if (err) { - dev_err(rtc->dev.parent, - "hctosys: invalid date/time\n"); -- goto err_invalid; -+ err = rtc_hc_fixup(rtc, &tm); -+ if (err) { -+ goto err_invalid; -+ } - } - - rtc_tm_to_time(&tm, &tv.tv_sec); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-run-time-cfi-byte-swapping.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-run-time-cfi-byte-swapping.patch deleted file mode 100644 index 0b2ddc32..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-run-time-cfi-byte-swapping.patch +++ /dev/null @@ -1,236 +0,0 @@ -#Copyright 2012 Cumulus Networks, Inc. All rights reserved. - -Adjust multi-byte word CFI endianness based on device tree specification. - -Currently, CFI byte swapping is controlled by set of configuration parameters -CONFIG_MTD_CFI_NOSWAP, CONFIG_MTD_CFI_LE_BYTE_SWAP, and -CONFIG_MTD_CFI_BE_BYTE_SWAP. This clearly prohibits using the same kernel on -systems whose local address busses are not connected the same way. - -This patch adds a new configuration variable CONFIG_MTD_CFI_OF_SWAP which -evaluates the device tree specification for a "byteswap" property that is used -to control byte swapping where desired. - -diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig -index b1e3c26..c7ae3f5 100644 ---- a/drivers/mtd/chips/Kconfig -+++ b/drivers/mtd/chips/Kconfig -@@ -52,8 +52,8 @@ config MTD_CFI_NOSWAP - 'NO', which is the default when CONFIG_MTD_CFI_ADV_OPTIONS isn't - enabled, means that the CPU will not do any swapping; the chips - are expected to be wired to the CPU in 'host-endian' form. -- Specific arrangements are possible with the BIG_ENDIAN_BYTE and -- LITTLE_ENDIAN_BYTE, if the bytes are reversed. -+ Specific arrangements are possible with the BIG_ENDIAN_BYTE, -+ LITTLE_ENDIAN_BYTE, and OF_BYTE_SWAP if the bytes are reversed. - - If you have a LART, on which the data (and address) lines were - connected in a fashion which ensured that the nets were as short -@@ -68,6 +68,9 @@ config MTD_CFI_BE_BYTE_SWAP - config MTD_CFI_LE_BYTE_SWAP - bool "LITTLE_ENDIAN_BYTE" - -+config MTD_CFI_OF_BYTE_SWAP -+ bool "OF_BYTESWAP_PROPERTY" -+ - endchoice - - config MTD_CFI_GEOMETRY -diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c -index 179814a..aa272a3 100644 ---- a/drivers/mtd/chips/cfi_cmdset_0020.c -+++ b/drivers/mtd/chips/cfi_cmdset_0020.c -@@ -139,8 +139,8 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary) - } - - /* Do some byteswapping if necessary */ -- extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); -- extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask); -+ extp->FeatureSupport = cfi32_to_cpu(map, extp->FeatureSupport); -+ extp->BlkStatusRegMask = cfi32_to_cpu(map, extp->BlkStatusRegMask); - - #ifdef DEBUG_CFI_FEATURES - /* Tell the user about it in lots of lovely detail */ -diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c -index 7d65f9d..7f32f30 100644 ---- a/drivers/mtd/maps/physmap_of.c -+++ b/drivers/mtd/maps/physmap_of.c -@@ -161,6 +161,9 @@ static int __devinit of_flash_probe(struct platform_device *dev) - struct of_flash *info; - const char *probe_type; - const __be32 *width; -+#ifdef CONFIG_MTD_CFI_OF_BYTE_SWAP -+ struct property * byteswap_prop; -+#endif - int err; - int i; - int count; -@@ -236,6 +239,16 @@ static int __devinit of_flash_probe(struct platform_device *dev) - info->list[i].map.size = res_size; - info->list[i].map.bankwidth = be32_to_cpup(width); - -+#ifdef CONFIG_MTD_CFI_OF_BYTE_SWAP -+ byteswap_prop = of_find_property(dp, "byteswap", NULL); -+ if (byteswap_prop == NULL) { -+ info->list[i].map.byteswap = 0; -+ } else { -+ info->list[i].map.byteswap = 1; -+ dev_info(&dev->dev, "byteswapping configured in OF\n"); -+ } -+#endif -+ - err = -ENOMEM; - info->list[i].map.virt = ioremap(info->list[i].map.phys, - info->list[i].map.size); -diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h -index d249254..d5d2ec6 100644 ---- a/include/linux/mtd/cfi.h -+++ b/include/linux/mtd/cfi.h -@@ -354,10 +354,10 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf - onecmd = cmd; - break; - case 2: -- onecmd = cpu_to_cfi16(cmd); -+ onecmd = cpu_to_cfi16(map, cmd); - break; - case 4: -- onecmd = cpu_to_cfi32(cmd); -+ onecmd = cpu_to_cfi32(map, cmd); - break; - } - -@@ -437,10 +437,10 @@ static inline unsigned long cfi_merge_status(map_word val, struct map_info *map, - case 1: - break; - case 2: -- res = cfi16_to_cpu(res); -+ res = cfi16_to_cpu(map, res); - break; - case 4: -- res = cfi32_to_cpu(res); -+ res = cfi32_to_cpu(map, res); - break; - default: BUG(); - } -@@ -480,12 +480,12 @@ static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr) - if (map_bankwidth_is_1(map)) { - return val.x[0]; - } else if (map_bankwidth_is_2(map)) { -- return cfi16_to_cpu(val.x[0]); -+ return cfi16_to_cpu(map, val.x[0]); - } else { - /* No point in a 64-bit byteswap since that would just be - swapping the responses from different chips, and we are - only interested in one chip (a representative sample) */ -- return cfi32_to_cpu(val.x[0]); -+ return cfi32_to_cpu(map, val.x[0]); - } - } - -@@ -496,12 +496,12 @@ static inline uint16_t cfi_read_query16(struct map_info *map, uint32_t addr) - if (map_bankwidth_is_1(map)) { - return val.x[0] & 0xff; - } else if (map_bankwidth_is_2(map)) { -- return cfi16_to_cpu(val.x[0]); -+ return cfi16_to_cpu(map, val.x[0]); - } else { - /* No point in a 64-bit byteswap since that would just be - swapping the responses from different chips, and we are - only interested in one chip (a representative sample) */ -- return cfi32_to_cpu(val.x[0]); -+ return cfi32_to_cpu(map, val.x[0]); - } - } - -diff --git a/include/linux/mtd/cfi_endian.h b/include/linux/mtd/cfi_endian.h -index 51cc3f5..c785284 100644 ---- a/include/linux/mtd/cfi_endian.h -+++ b/include/linux/mtd/cfi_endian.h -@@ -37,35 +37,48 @@ - #define CFI_BIG_ENDIAN - #endif - -+#ifdef CONFIG_MTD_CFI_OF_BYTE_SWAP -+#define CFI_OF_BYTE_SWAP -+#endif -+ - #endif - - #if defined(CFI_LITTLE_ENDIAN) --#define cpu_to_cfi8(x) (x) --#define cfi8_to_cpu(x) (x) --#define cpu_to_cfi16(x) cpu_to_le16(x) --#define cpu_to_cfi32(x) cpu_to_le32(x) --#define cpu_to_cfi64(x) cpu_to_le64(x) --#define cfi16_to_cpu(x) le16_to_cpu(x) --#define cfi32_to_cpu(x) le32_to_cpu(x) --#define cfi64_to_cpu(x) le64_to_cpu(x) -+#define cpu_to_cfi8(m,x) (x) -+#define cfi8_to_cpu(m,x) (x) -+#define cpu_to_cfi16(m,x) cpu_to_le16(x) -+#define cpu_to_cfi32(m,x) cpu_to_le32(x) -+#define cpu_to_cfi64(m,x) cpu_to_le64(x) -+#define cfi16_to_cpu(m,x) le16_to_cpu(x) -+#define cfi32_to_cpu(m,x) le32_to_cpu(x) -+#define cfi64_to_cpu(m,x) le64_to_cpu(x) - #elif defined (CFI_BIG_ENDIAN) --#define cpu_to_cfi8(x) (x) --#define cfi8_to_cpu(x) (x) --#define cpu_to_cfi16(x) cpu_to_be16(x) --#define cpu_to_cfi32(x) cpu_to_be32(x) --#define cpu_to_cfi64(x) cpu_to_be64(x) --#define cfi16_to_cpu(x) be16_to_cpu(x) --#define cfi32_to_cpu(x) be32_to_cpu(x) --#define cfi64_to_cpu(x) be64_to_cpu(x) -+#define cpu_to_cfi8(m,x) (x) -+#define cfi8_to_cpu(m,x) (x) -+#define cpu_to_cfi16(m,x) cpu_to_be16(x) -+#define cpu_to_cfi32(m,x) cpu_to_be32(x) -+#define cpu_to_cfi64(m,x) cpu_to_be64(x) -+#define cfi16_to_cpu(m,x) be16_to_cpu(x) -+#define cfi32_to_cpu(m,x) be32_to_cpu(x) -+#define cfi64_to_cpu(m,x) be64_to_cpu(x) - #elif defined (CFI_HOST_ENDIAN) --#define cpu_to_cfi8(x) (x) --#define cfi8_to_cpu(x) (x) --#define cpu_to_cfi16(x) (x) --#define cpu_to_cfi32(x) (x) --#define cpu_to_cfi64(x) (x) --#define cfi16_to_cpu(x) (x) --#define cfi32_to_cpu(x) (x) --#define cfi64_to_cpu(x) (x) -+#define cpu_to_cfi8(m,x) (x) -+#define cfi8_to_cpu(m,x) (x) -+#define cpu_to_cfi16(m,x) (x) -+#define cpu_to_cfi32(m,x) (x) -+#define cpu_to_cfi64(m,x) (x) -+#define cfi16_to_cpu(m,x) (x) -+#define cfi32_to_cpu(m,x) (x) -+#define cfi64_to_cpu(m,x) (x) -+#elif defined (CFI_OF_BYTE_SWAP) -+#define cpu_to_cfi8(m,x) (x) -+#define cfi8_to_cpu(m,x) (x) -+#define cpu_to_cfi16(m,x) ((m)->byteswap ? swab16(x) : (x)) -+#define cpu_to_cfi32(m,x) ((m)->byteswap ? swab32(x) : (x)) -+#define cpu_to_cfi64(m,x) ((m)->byteswap ? swab64(x) : (x)) -+#define cfi16_to_cpu(m,x) ((m)->byteswap ? swab16(x) : (x)) -+#define cfi32_to_cpu(m,x) ((m)->byteswap ? swab32(x) : (x)) -+#define cfi64_to_cpu(m,x) ((m)->byteswap ? swab64(x) : (x)) - #else - #error No CFI endianness defined - #endif -diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h -index 3887901..b8ca7de 100644 ---- a/include/linux/mtd/map.h -+++ b/include/linux/mtd/map.h -@@ -219,6 +219,10 @@ struct map_info { - in bytes, before you are talking to the first chip again. - */ - -+#ifdef CONFIG_MTD_CFI_OF_BYTE_SWAP -+ int byteswap; /* get byte swap configuration from device tree */ -+#endif -+ - #ifdef CONFIG_MTD_COMPLEX_MAPPINGS - map_word (*read)(struct map_info *, unsigned long); - void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-s6000-i2c-gpio-mux.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-s6000-i2c-gpio-mux.patch deleted file mode 100644 index 6d5a12a3..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-s6000-i2c-gpio-mux.patch +++ /dev/null @@ -1,157 +0,0 @@ -diff -rupN a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig ---- a/drivers/platform/x86/Kconfig 2015-02-19 18:57:03.000000000 -0800 -+++ b/drivers/platform/x86/Kconfig 2015-06-13 22:57:05.465077296 -0700 -@@ -786,4 +786,9 @@ config SAMSUNG_Q10 - This driver provides support for backlight control on Samsung Q10 - and related laptops, including Dell Latitude X200. - -+config X86_64_DELL_S6000_S1220_R0 -+ tristate "Platform Driver for the DELL S6000" -+ ---help--- -+ Support the Dell S6000. -+ - endif # X86_PLATFORM_DEVICES -diff -rupN a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile ---- a/drivers/platform/x86/Makefile 2015-02-19 18:57:03.000000000 -0800 -+++ b/drivers/platform/x86/Makefile 2015-06-13 22:56:47.129074056 -0700 -@@ -46,3 +46,4 @@ obj-$(CONFIG_MXM_WMI) += mxm-wmi.o - obj-$(CONFIG_INTEL_MID_POWER_BUTTON) += intel_mid_powerbtn.o - obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o - obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o -+obj-$(CONFIG_X86_64_DELL_S6000_S1220_R0) += x86_64_dell_s6000_s1220_r0.o -diff -rupN a/drivers/platform/x86/x86_64_dell_s6000_s1220_r0.c b/drivers/platform/x86/x86_64_dell_s6000_s1220_r0.c ---- a/drivers/platform/x86/x86_64_dell_s6000_s1220_r0.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/drivers/platform/x86/x86_64_dell_s6000_s1220_r0.c 2015-06-13 22:56:25.865078612 -0700 -@@ -0,0 +1,132 @@ -+/** -+ * Dell S6000 Platform Support. -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+ -+/************************************************************* -+ * -+ * I2C Bus 0 on the S6000 is muxed via gpio1 and gpio2. -+ * -+ ************************************************************/ -+static const unsigned s6000_gpiomux_gpios[] = { -+ 1, 2 -+}; -+ -+static const unsigned s6000_gpiomux_values[] = { -+ 0, 1, 2, 3 -+}; -+ -+static struct gpio_i2cmux_platform_data s6000_i2cmux_data = { -+ /* -+ * i2c Bus 0 -+ */ -+ .parent = 0, -+ -+ /* -+ * Start the bus numbers at 10. The first digit -+ * will represent the different bus numbers based -+ * the gpio selector (00, 01, 10, 11): -+ * -+ * i2c-10 --> i2c-0, gpios = 00 -+ * i2c-11 --> i2c-0, gpios = 01 -+ * i2c-12 --> i2c-0, gpios = 10 -+ * i2c-13 --> i2c-0, gpios = 11 -+ */ -+ .base_nr = 10, -+ -+ .values = s6000_gpiomux_values, -+ .n_values = ARRAY_SIZE(s6000_gpiomux_values), -+ .gpios = s6000_gpiomux_gpios, -+ .n_gpios = ARRAY_SIZE(s6000_gpiomux_gpios), -+ .idle = 0, -+}; -+ -+static struct platform_device s6000_i2cmux = { -+ .name = "gpio-i2cmux", -+ .id = 12, -+ .dev = { -+ .platform_data = &s6000_i2cmux_data, -+ }, -+}; -+ -+/************************************************************* -+ * -+ * Sensors on i2c-11 (See mux data above). -+ * -+ ************************************************************/ -+static struct i2c_board_info s6000_i2c_11_board_info[] = { -+ { I2C_BOARD_INFO("lm75", 0x4c) }, -+ { I2C_BOARD_INFO("lm75", 0x4d) }, -+ { I2C_BOARD_INFO("lm75", 0x4e) }, -+ { I2C_BOARD_INFO("ltc4215", 0x42) }, -+ { I2C_BOARD_INFO("ltc4215", 0x40) }, -+ { I2C_BOARD_INFO("max6620", 0x29) }, -+ { I2C_BOARD_INFO("max6620", 0x2A) }, -+ { I2C_BOARD_INFO("24c02", 0x51) }, -+ { I2C_BOARD_INFO("24c02", 0x52) }, -+ { I2C_BOARD_INFO("24c02", 0x53) }, -+}; -+ -+static int __init x86_64_dell_s6000_s1220_r0_init(void) -+{ -+ int i; -+ int rv = 0; -+ char const *vendor, *product; -+ struct i2c_adapter * i2ca; -+ -+ vendor = dmi_get_system_info(DMI_SYS_VENDOR); -+ product = dmi_get_system_info(DMI_PRODUCT_NAME); -+ -+ if(strcmp(vendor, "Dell Inc") || -+ (strcmp(product, "S6000 (SI)") && strcmp(product, "S6000-ON") && -+ strcmp(product, "S6000-ON (SI)"))) { -+ /* Not the S6000 */ -+ return -ENODEV; -+ } -+ -+ /** -+ * Register the GPIO mux for bus 0. -+ */ -+ rv = platform_device_register(&s6000_i2cmux); -+ if(rv < 0) { -+ pr_err("%s: platform_device_register() failed: %d", __FUNCTION__, rv); -+ return rv; -+ } -+ -+ /** -+ * Register I2C devices on new buses -+ */ -+ i2ca = i2c_get_adapter(11); -+ for(i = 0; i < ARRAY_SIZE(s6000_i2c_11_board_info); i++) { -+ if(i2c_new_device(i2ca, s6000_i2c_11_board_info+i) == NULL) { -+ pr_err("%s: i2c_new_device for bus 11:0x%x failed.", -+ __FUNCTION__, s6000_i2c_11_board_info[i].addr); -+ } -+ } -+ -+ return 0; -+ -+} -+ -+static void __exit x86_64_dell_s6000_s1220_r0_cleanup(void) -+{ -+ platform_device_unregister(&s6000_i2cmux); -+} -+ -+module_init(x86_64_dell_s6000_s1220_r0_init); -+module_exit(x86_64_dell_s6000_s1220_r0_cleanup); -+ -+MODULE_AUTHOR("Big Switch Networks (support@bigswitch.com)"); -+MODULE_VERSION("1.0"); -+MODULE_DESCRIPTION("Dell S6000"); -+MODULE_LICENSE("GPL"); -+ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-smsc-emc2305-hwmon.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-smsc-emc2305-hwmon.patch deleted file mode 100644 index 6c479544..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-smsc-emc2305-hwmon.patch +++ /dev/null @@ -1,1040 +0,0 @@ -HWMON driver for SMSC EMC2301, 2302, 2303, 2305 chips - -diff --git a/Documentation/devicetree/bindings/hwmon/emc2305.txt b/Documentation/devicetree/bindings/hwmon/emc2305.txt -new file mode 100644 -index 0000000..ee67372 ---- /dev/null -+++ b/Documentation/devicetree/bindings/hwmon/emc2305.txt -@@ -0,0 +1,60 @@ -+EMC2305 (I2C) -+ -+This device is a RPM-based PWM Fan Speed Controller for up to 5 fans. -+ -+Each fan can beconfigured individually: -+ -+ - pwm-enable defines the PWM mode: -+ 0: PWM is disabled -+ 3: RPM based PWM -+ -+ - fan-div sets the fan divisor (for RPM mesaurement) -+ 1, 2 ,4 or 8 -+ -+ - fan-target sets the target RPM speed (for RPM based PWM mode) -+ max 16000 (according to data sheet) -+ -+ -+1) The /emc2305 node -+ -+ Required properties: -+ -+ - compatible : must be "smsc,emc2305" -+ - reg : I2C bus address of the device -+ - #address-cells : must be <1> -+ - #size-cells : must be <0> -+ -+ The node may contain child nodes for each fan that the platform uses. -+ If no child nodes are given, all possible fan control channels are exposed. -+ If at least one child node is given, only the configured fans are exposed. -+ -+ Example EMC2305 node: -+ -+ emc2305@2C { -+ compatible = "smsc,emc2305"; -+ reg = <0x2C>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ [ child node definitions... ] -+ } -+ -+2) fan nodes -+ -+ Required properties: -+ -+ - reg : the fan number (0 based) -+ -+ Optional properties: -+ -+ - fan-div : the fan divisor setting -+ - fan-target : the fan target speed -+ - pwm-enable : PWM mode -+ -+ Example EMC2305 fan node: -+ -+ fan@1 { -+ reg = <1>; -+ fan-div = <4>; -+ pwm-enable = <0>; -+ }; -diff --git a/Documentation/hwmon/emc2305 b/Documentation/hwmon/emc2305 -new file mode 100644 -index 0000000..4de033b ---- /dev/null -+++ b/Documentation/hwmon/emc2305 -@@ -0,0 +1,33 @@ -+Kernel driver emc2305 -+===================== -+ -+Supported chips: -+ * SMSC EMC2305, EMC2303, EMC2302, EMC2301 -+ Adresses scanned: I2C 0x2c, 0x2d, 0x2e, 0x2f, 0x4c, 0x4d -+ Prefixes: 'emc2305', 'emc2303', 'emc2302', 'emc2301' -+ Datasheet: Publicly available at the SMSC website : -+ http://www.smsc.com/Products/Thermal_and_Power_Management/Fan_Controllers -+ -+Authors: -+ Reinhard Pfau, Guntermann & Drunck GmbH -+ -+Description -+----------- -+ -+The SMSC EMC2305 is a fan controller for up to 5 fans. -+The EMC2303 has the same functionality but supports only up to 3 fans. -+ -+The EMC2302 supports 2 fans and the EMC2301 1 fan. These chips support less -+possible I2C addresses. -+ -+Fan rotation speeds are reported in RPM. -+The driver supports the RPM based PWM control to keep a fan at a desired speed. -+To enable this function for a fan, write 3 to pwm_enable and the desired -+fan speed to fan_target. -+ -+ -+Devicetree -+---------- -+ -+Configuration is also possible via devicetree: -+Documentation/devicetree/bindings/hwmon/emc2305.txt -diff --git a/MAINTAINERS b/MAINTAINERS -index 6701e5a..4ea868c 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -6042,6 +6042,14 @@ S: Supported - F: Documentation/hwmon/emc2103 - F: drivers/hwmon/emc2103.c - -+SMSC EMC2305 HARDWARE MONITOR DRIVER -+M: Reinhard Pfau -+L: lm-sensors@lm-sensors.org -+S: Maintained -+F: Documentation/hwmon/emc2305 -+F: Documentation/devicetree/bindings/hwmon/emc2305.txt -+F: drivers/hwmon/emc2305.c -+ - SMSC SCH5627 HARDWARE MONITOR DRIVER - M: Hans de Goede - L: lm-sensors@lm-sensors.org -diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig -index fe87335..6b366b4 100644 ---- a/drivers/hwmon/Kconfig -+++ b/drivers/hwmon/Kconfig -@@ -984,6 +984,16 @@ config SENSORS_EMC2103 - This driver can also be built as a module. If so, the module - will be called emc2103. - -+config SENSORS_EMC2305 -+ tristate "SMSC EMC2305" -+ depends on I2C -+ help -+ If you say yes here you get support for the SMSC EMC2305/EMC2303 -+ fan controller chips. -+ -+ This driver can also be built as a module. If so, the module -+ will be called emc2305. -+ - config SENSORS_EMC6W201 - tristate "SMSC EMC6W201" - depends on I2C -diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile -index cf7f0b8..dba7a20 100644 ---- a/drivers/hwmon/Makefile -+++ b/drivers/hwmon/Makefile -@@ -49,6 +49,7 @@ obj-$(CONFIG_SENSORS_DS620) += ds620.o - obj-$(CONFIG_SENSORS_DS1621) += ds1621.o - obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o - obj-$(CONFIG_SENSORS_EMC2103) += emc2103.o -+obj-$(CONFIG_SENSORS_EMC2305) += emc2305.o - obj-$(CONFIG_SENSORS_EMC6W201) += emc6w201.o - obj-$(CONFIG_SENSORS_EXYNOS4_TMU) += exynos4_tmu.o - obj-$(CONFIG_SENSORS_F71805F) += f71805f.o -diff --git a/drivers/hwmon/emc2305.c b/drivers/hwmon/emc2305.c -new file mode 100644 -index 0000000..62f88e0 ---- /dev/null -+++ b/drivers/hwmon/emc2305.c -@@ -0,0 +1,875 @@ -+/* -+ * emc2305.c - hwmon driver for SMSC EMC2305 fan controller -+ * (C) Copyright 2013 -+ * Reinhard Pfau, Guntermann & Drunck GmbH -+ * -+ * Based on emc2103 driver by SMSC. -+ * -+ * Datasheet available at: -+ * http://www.smsc.com/Downloads/SMSC/Downloads_Public/Data_Sheets/2305.pdf -+ * -+ * Also supports the EMC2303 fan controller which has the same functionality -+ * and register layout as EMC2305, but supports only up to 3 fans instead of 5. -+ * -+ * Also supports EMC2302 (up to 2 fans) and EMC2301 (1 fan) fan controller. -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+/* -+ * TODO / IDEAS: -+ * - expose more of the configuration and features -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * Addresses scanned. -+ * Listed in the same order as they appear in the EMC2305, EMC2303 data sheets. -+ * -+ * Note: these are the I2C adresses which are possible for EMC2305 and EMC2303 -+ * chips. -+ * The EMC2302 supports only 0x2e (EMC2302-1) and 0x2f (EMC2302-2). -+ * The EMC2301 supports only 0x2f. -+ */ -+static const unsigned short i2c_adresses[] = { -+ 0x2E, -+ 0x2F, -+ 0x2C, -+ 0x2D, -+ 0x4C, -+ 0x4D, -+ I2C_CLIENT_END -+}; -+ -+/* -+ * global registers -+ */ -+enum { -+ REG_CONFIGURATION = 0x20, -+ REG_FAN_STATUS = 0x24, -+ REG_FAN_STALL_STATUS = 0x25, -+ REG_FAN_SPIN_STATUS = 0x26, -+ REG_DRIVE_FAIL_STATUS = 0x27, -+ REG_FAN_INTERRUPT_ENABLE = 0x29, -+ REG_PWM_POLARITY_CONFIG = 0x2a, -+ REG_PWM_OUTPUT_CONFIG = 0x2b, -+ REG_PWM_BASE_FREQ_1 = 0x2c, -+ REG_PWM_BASE_FREQ_2 = 0x2d, -+ REG_SOFTWARE_LOCK = 0xef, -+ REG_PRODUCT_FEATURES = 0xfc, -+ REG_PRODUCT_ID = 0xfd, -+ REG_MANUFACTURER_ID = 0xfe, -+ REG_REVISION = 0xff -+}; -+ -+/* -+ * fan specific registers -+ */ -+enum { -+ REG_FAN_SETTING = 0x30, -+ REG_PWM_DIVIDE = 0x31, -+ REG_FAN_CONFIGURATION_1 = 0x32, -+ REG_FAN_CONFIGURATION_2 = 0x33, -+ REG_GAIN = 0x35, -+ REG_FAN_SPIN_UP_CONFIG = 0x36, -+ REG_FAN_MAX_STEP = 0x37, -+ REG_FAN_MINIMUM_DRIVE = 0x38, -+ REG_FAN_VALID_TACH_COUNT = 0x39, -+ REG_FAN_DRIVE_FAIL_BAND_LOW = 0x3a, -+ REG_FAN_DRIVE_FAIL_BAND_HIGH = 0x3b, -+ REG_TACH_TARGET_LOW = 0x3c, -+ REG_TACH_TARGET_HIGH = 0x3d, -+ REG_TACH_READ_HIGH = 0x3e, -+ REG_TACH_READ_LOW = 0x3f, -+}; -+ -+#define SEL_FAN(fan, reg) (reg + fan * 0x10) -+ -+/* -+ * Factor by equations [2] and [3] from data sheet; valid for fans where the -+ * number of edges equals (poles * 2 + 1). -+ */ -+#define FAN_RPM_FACTOR 3932160 -+ -+ -+struct emc2305_fan_data { -+ bool enabled; -+ bool valid; -+ unsigned long last_updated; -+ bool rpm_control; -+ u8 multiplier; -+ u8 poles; -+ u16 target; -+ u16 tach; -+ u16 rpm_factor; -+ u8 pwm; -+}; -+ -+struct emc2305_data { -+ struct device *hwmon_dev; -+ struct mutex update_lock; -+ int fans; -+ struct emc2305_fan_data fan[5]; -+}; -+ -+static int read_u8_from_i2c(struct i2c_client *client, u8 i2c_reg, u8 *output) -+{ -+ int status = i2c_smbus_read_byte_data(client, i2c_reg); -+ if (status < 0) { -+ dev_warn(&client->dev, "reg 0x%02x, err %d\n", -+ i2c_reg, status); -+ } else { -+ *output = status; -+ } -+ return status; -+} -+ -+static void read_fan_from_i2c(struct i2c_client *client, u16 *output, -+ u8 hi_addr, u8 lo_addr) -+{ -+ u8 high_byte, lo_byte; -+ -+ if (read_u8_from_i2c(client, hi_addr, &high_byte) < 0) -+ return; -+ -+ if (read_u8_from_i2c(client, lo_addr, &lo_byte) < 0) -+ return; -+ -+ *output = ((u16)high_byte << 5) | (lo_byte >> 3); -+} -+ -+static void write_fan_target_to_i2c(struct i2c_client *client, int fan, -+ u16 new_target) -+{ -+ const u8 lo_reg = SEL_FAN(fan, REG_TACH_TARGET_LOW); -+ const u8 hi_reg = SEL_FAN(fan, REG_TACH_TARGET_HIGH); -+ u8 high_byte = (new_target & 0x1fe0) >> 5; -+ u8 low_byte = (new_target & 0x001f) << 3; -+ i2c_smbus_write_byte_data(client, lo_reg, low_byte); -+ i2c_smbus_write_byte_data(client, hi_reg, high_byte); -+} -+ -+static void read_fan_config_from_i2c(struct i2c_client *client, int fan) -+ -+{ -+ struct emc2305_data *data = i2c_get_clientdata(client); -+ u8 conf1; -+ -+ if (read_u8_from_i2c(client, SEL_FAN(fan, REG_FAN_CONFIGURATION_1), -+ &conf1) < 0) -+ return; -+ -+ data->fan[fan].rpm_control = (conf1 & 0x80) != 0; -+ data->fan[fan].multiplier = 1 << ((conf1 & 0x60) >> 5); -+ data->fan[fan].poles = ((conf1 & 0x18) >> 3) + 1; -+} -+ -+static void read_fan_setting(struct i2c_client *client, int fan) -+{ -+ struct emc2305_data *data = i2c_get_clientdata(client); -+ u8 setting; -+ -+ if (read_u8_from_i2c(client, SEL_FAN(fan, REG_FAN_SETTING), -+ &setting) < 0) -+ return; -+ -+ data->fan[fan].pwm = setting; -+} -+ -+static void read_fan_data(struct i2c_client *client, int fan_idx) -+{ -+ struct emc2305_data *data = i2c_get_clientdata(client); -+ -+ read_fan_from_i2c(client, &data->fan[fan_idx].target, -+ SEL_FAN(fan_idx, REG_TACH_TARGET_HIGH), -+ SEL_FAN(fan_idx, REG_TACH_TARGET_LOW)); -+ read_fan_from_i2c(client, &data->fan[fan_idx].tach, -+ SEL_FAN(fan_idx, REG_TACH_READ_HIGH), -+ SEL_FAN(fan_idx, REG_TACH_READ_LOW)); -+} -+ -+static struct emc2305_fan_data * -+emc2305_update_fan(struct i2c_client *client, int fan_idx) -+{ -+ struct emc2305_data *data = i2c_get_clientdata(client); -+ struct emc2305_fan_data *fan_data = &data->fan[fan_idx]; -+ -+ mutex_lock(&data->update_lock); -+ -+ if (time_after(jiffies, fan_data->last_updated + HZ + HZ / 2) -+ || !fan_data->valid) { -+ read_fan_config_from_i2c(client, fan_idx); -+ read_fan_data(client, fan_idx); -+ read_fan_setting(client, fan_idx); -+ fan_data->valid = true; -+ fan_data->last_updated = jiffies; -+ } -+ -+ mutex_unlock(&data->update_lock); -+ return fan_data; -+} -+ -+static struct emc2305_fan_data * -+emc2305_update_device_fan(struct device *dev, struct device_attribute *da) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ int fan_idx = to_sensor_dev_attr(da)->index; -+ -+ return emc2305_update_fan(client, fan_idx); -+} -+ -+/* -+ * set/ config functions -+ */ -+ -+/* -+ * Note: we also update the fan target here, because its value is -+ * determined in part by the fan clock divider. This follows the principle -+ * of least surprise; the user doesn't expect the fan target to change just -+ * because the divider changed. -+ */ -+static int -+emc2305_set_fan_div(struct i2c_client *client, int fan_idx, long new_div) -+{ -+ struct emc2305_data *data = i2c_get_clientdata(client); -+ struct emc2305_fan_data *fan = emc2305_update_fan(client, fan_idx); -+ const u8 reg_conf1 = SEL_FAN(fan_idx, REG_FAN_CONFIGURATION_1); -+ int new_range_bits, old_div = 8 / fan->multiplier; -+ int status = 0; -+ -+ if (new_div == old_div) /* No change */ -+ return 0; -+ -+ switch (new_div) { -+ case 1: -+ new_range_bits = 3; -+ break; -+ case 2: -+ new_range_bits = 2; -+ break; -+ case 4: -+ new_range_bits = 1; -+ break; -+ case 8: -+ new_range_bits = 0; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ mutex_lock(&data->update_lock); -+ -+ status = i2c_smbus_read_byte_data(client, reg_conf1); -+ if (status < 0) { -+ dev_dbg(&client->dev, "reg 0x%02x, err %d\n", -+ reg_conf1, status); -+ status = -EIO; -+ goto exit_unlock; -+ } -+ status &= 0x9F; -+ status |= (new_range_bits << 5); -+ status = i2c_smbus_write_byte_data(client, reg_conf1, status); -+ if (status < 0) { -+ status = -EIO; -+ goto exit_invalidate; -+ } -+ -+ fan->multiplier = 8 / new_div; -+ -+ /* update fan target if high byte is not disabled */ -+ if ((fan->target & 0x1fe0) != 0x1fe0) { -+ u16 new_target = (fan->target * old_div) / new_div; -+ fan->target = min_t(u16, new_target, 0x1fff); -+ write_fan_target_to_i2c(client, fan_idx, fan->target); -+ } -+ -+exit_invalidate: -+ /* invalidate fan data to force re-read from hardware */ -+ fan->valid = false; -+exit_unlock: -+ mutex_unlock(&data->update_lock); -+ return status; -+} -+ -+static int -+emc2305_set_fan_target(struct i2c_client *client, int fan_idx, long rpm_target) -+{ -+ struct emc2305_data *data = i2c_get_clientdata(client); -+ struct emc2305_fan_data *fan = emc2305_update_fan(client, fan_idx); -+ -+ /* -+ * Datasheet states 16000 as maximum RPM target -+ * (table 2.2 and section 4.3) -+ */ -+ if ((rpm_target < 0) || (rpm_target > 16000)) -+ return -EINVAL; -+ -+ mutex_lock(&data->update_lock); -+ -+ if (rpm_target == 0) -+ fan->target = 0x1fff; -+ else -+ fan->target = clamp_val( -+ (FAN_RPM_FACTOR * fan->multiplier) / rpm_target, -+ 0, 0x1fff); -+ -+ write_fan_target_to_i2c(client, fan_idx, fan->target); -+ -+ mutex_unlock(&data->update_lock); -+ return 0; -+} -+ -+static int -+emc2305_set_pwm_enable(struct i2c_client *client, int fan_idx, long enable) -+{ -+ struct emc2305_data *data = i2c_get_clientdata(client); -+ struct emc2305_fan_data *fan = emc2305_update_fan(client, fan_idx); -+ const u8 reg_fan_conf1 = SEL_FAN(fan_idx, REG_FAN_CONFIGURATION_1); -+ int status = 0; -+ u8 conf_reg; -+ -+ mutex_lock(&data->update_lock); -+ switch (enable) { -+ case 0: -+ fan->rpm_control = false; -+ break; -+ case 3: -+ fan->rpm_control = true; -+ break; -+ default: -+ status = -EINVAL; -+ goto exit_unlock; -+ } -+ -+ status = read_u8_from_i2c(client, reg_fan_conf1, &conf_reg); -+ if (status < 0) { -+ status = -EIO; -+ goto exit_unlock; -+ } -+ -+ if (fan->rpm_control) -+ conf_reg |= 0x80; -+ else -+ conf_reg &= ~0x80; -+ -+ status = i2c_smbus_write_byte_data(client, reg_fan_conf1, conf_reg); -+ if (status < 0) -+ status = -EIO; -+ -+exit_unlock: -+ mutex_unlock(&data->update_lock); -+ return status; -+} -+ -+static int -+emc2305_set_pwm(struct i2c_client *client, int fan_idx, long pwm) -+{ -+ struct emc2305_data *data = i2c_get_clientdata(client); -+ struct emc2305_fan_data *fan = emc2305_update_fan(client, fan_idx); -+ const u8 reg_fan_setting = SEL_FAN(fan_idx, REG_FAN_SETTING); -+ int status = 0; -+ -+ /* -+ * Datasheet states 255 as maximum PWM -+ * (section 5.7) -+ */ -+ if ((pwm < 0) || (pwm > 255)) -+ return -EINVAL; -+ -+ fan->pwm = pwm; -+ -+ mutex_lock(&data->update_lock); -+ -+ status = i2c_smbus_write_byte_data(client, reg_fan_setting, fan->pwm); -+ -+ mutex_unlock(&data->update_lock); -+ return status; -+} -+/* -+ * sysfs callback functions -+ * -+ * Note: -+ * Naming of the funcs is modelled after the naming scheme described in -+ * Documentation/hwmon/sysfs-interface: -+ * -+ * For a sysfs file _ the functions are named like this: -+ * the show function: show__ -+ * the store function: set__ -+ * For read only (RO) attributes of course only the show func is required. -+ * -+ * This convention allows us to define the sysfs attributes by using macros. -+ */ -+ -+static ssize_t -+show_fan_input(struct device *dev, struct device_attribute *da, char *buf) -+{ -+ struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da); -+ int rpm = 0; -+ if (fan->tach != 0) -+ rpm = (FAN_RPM_FACTOR * fan->multiplier) / fan->tach; -+ return sprintf(buf, "%d\n", rpm); -+} -+ -+static ssize_t -+show_fan_fault(struct device *dev, struct device_attribute *da, char *buf) -+{ -+ struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da); -+ bool fault = ((fan->tach & 0x1fe0) == 0x1fe0); -+ return sprintf(buf, "%d\n", fault ? 1 : 0); -+} -+ -+static ssize_t -+show_fan_div(struct device *dev, struct device_attribute *da, char *buf) -+{ -+ struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da); -+ int fan_div = 8 / fan->multiplier; -+ return sprintf(buf, "%d\n", fan_div); -+} -+ -+static ssize_t -+set_fan_div(struct device *dev, struct device_attribute *da, -+ const char *buf, size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ int fan_idx = to_sensor_dev_attr(da)->index; -+ long new_div; -+ int status; -+ -+ status = kstrtol(buf, 10, &new_div); -+ if (status < 0) -+ return -EINVAL; -+ -+ status = emc2305_set_fan_div(client, fan_idx, new_div); -+ if (status < 0) -+ return status; -+ -+ return count; -+} -+ -+static ssize_t -+show_fan_target(struct device *dev, struct device_attribute *da, char *buf) -+{ -+ struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da); -+ int rpm = 0; -+ -+ /* high byte of 0xff indicates disabled so return 0 */ -+ if ((fan->target != 0) && ((fan->target & 0x1fe0) != 0x1fe0)) -+ rpm = (FAN_RPM_FACTOR * fan->multiplier) -+ / fan->target; -+ -+ return sprintf(buf, "%d\n", rpm); -+} -+ -+static ssize_t set_fan_target(struct device *dev, struct device_attribute *da, -+ const char *buf, size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ int fan_idx = to_sensor_dev_attr(da)->index; -+ long rpm_target; -+ int status; -+ -+ status = kstrtol(buf, 10, &rpm_target); -+ if (status < 0) -+ return -EINVAL; -+ -+ status = emc2305_set_fan_target(client, fan_idx, rpm_target); -+ if (status < 0) -+ return status; -+ -+ return count; -+} -+ -+static ssize_t -+show_pwm_enable(struct device *dev, struct device_attribute *da, char *buf) -+{ -+ struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da); -+ return sprintf(buf, "%d\n", fan->rpm_control ? 3 : 0); -+} -+ -+static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, -+ const char *buf, size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ int fan_idx = to_sensor_dev_attr(da)->index; -+ long new_value; -+ int status; -+ -+ status = kstrtol(buf, 10, &new_value); -+ if (status < 0) -+ return -EINVAL; -+ status = emc2305_set_pwm_enable(client, fan_idx, new_value); -+ return count; -+} -+ -+static ssize_t show_pwm(struct device *dev, struct device_attribute *da, -+ char *buf) -+{ -+ struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da); -+ return sprintf(buf, "%d\n", fan->pwm); -+} -+ -+static ssize_t set_pwm(struct device *dev, struct device_attribute *da, -+ const char *buf, size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ int fan_idx = to_sensor_dev_attr(da)->index; -+ unsigned long val; -+ int ret; -+ int status; -+ -+ ret = kstrtoul(buf, 10, &val); -+ if (ret) -+ return ret; -+ if (val > 255) -+ return -EINVAL; -+ -+ status = emc2305_set_pwm(client, fan_idx, val); -+ return count; -+} -+ -+/* define a read only attribute */ -+#define EMC2305_ATTR_RO(_type, _item, _num) \ -+ SENSOR_ATTR(_type ## _num ## _ ## _item, S_IRUGO, \ -+ show_## _type ## _ ## _item, NULL, _num - 1) -+ -+/* define a read/write attribute */ -+#define EMC2305_ATTR_RW(_type, _item, _num) \ -+ SENSOR_ATTR(_type ## _num ## _ ## _item, S_IRUGO | S_IWUSR, \ -+ show_## _type ##_ ## _item, \ -+ set_## _type ## _ ## _item, _num - 1) -+ -+/* -+ * TODO: Ugly hack, but temporary as this whole logic needs -+ * to be rewritten as per standard HWMON sysfs registration -+ */ -+ -+/* define a read/write attribute */ -+#define EMC2305_ATTR_RW2(_type, _num) \ -+ SENSOR_ATTR(_type ## _num, S_IRUGO | S_IWUSR, \ -+ show_## _type, set_## _type, _num - 1) -+ -+/* defines the attributes for a single fan */ -+#define EMC2305_DEFINE_FAN_ATTRS(_num) \ -+ static const \ -+ struct sensor_device_attribute emc2305_attr_fan ## _num[] = { \ -+ EMC2305_ATTR_RO(fan, input, _num), \ -+ EMC2305_ATTR_RO(fan, fault, _num), \ -+ EMC2305_ATTR_RW(fan, div, _num), \ -+ EMC2305_ATTR_RW(fan, target, _num), \ -+ EMC2305_ATTR_RW(pwm, enable, _num), \ -+ EMC2305_ATTR_RW2(pwm, _num) \ -+ } -+ -+#define EMC2305_NUM_FAN_ATTRS ARRAY_SIZE(emc2305_attr_fan1) -+ -+/* common attributes for EMC2303 and EMC2305 */ -+static const struct sensor_device_attribute emc2305_attr_common[] = { -+}; -+ -+/* fan attributes for the single fans */ -+EMC2305_DEFINE_FAN_ATTRS(1); -+EMC2305_DEFINE_FAN_ATTRS(2); -+EMC2305_DEFINE_FAN_ATTRS(3); -+EMC2305_DEFINE_FAN_ATTRS(4); -+EMC2305_DEFINE_FAN_ATTRS(5); -+EMC2305_DEFINE_FAN_ATTRS(6); -+ -+/* fan attributes */ -+static const struct sensor_device_attribute *emc2305_fan_attrs[] = { -+ emc2305_attr_fan1, -+ emc2305_attr_fan2, -+ emc2305_attr_fan3, -+ emc2305_attr_fan4, -+ emc2305_attr_fan5, -+}; -+ -+/* -+ * driver interface -+ */ -+ -+static int emc2305_remove(struct i2c_client *client) -+{ -+ struct emc2305_data *data = i2c_get_clientdata(client); -+ int fan_idx, i; -+ -+ hwmon_device_unregister(data->hwmon_dev); -+ -+ for (fan_idx = 0; fan_idx < data->fans; ++fan_idx) -+ for (i = 0; i < EMC2305_NUM_FAN_ATTRS; ++i) -+ device_remove_file( -+ &client->dev, -+ &emc2305_fan_attrs[fan_idx][i].dev_attr); -+ -+ for (i = 0; i < ARRAY_SIZE(emc2305_attr_common); ++i) -+ device_remove_file(&client->dev, -+ &emc2305_attr_common[i].dev_attr); -+ -+ kfree(data); -+ return 0; -+} -+ -+ -+#ifdef CONFIG_OF -+/* -+ * device tree support -+ */ -+ -+struct of_fan_attribute { -+ const char *name; -+ int (*set)(struct i2c_client*, int, long); -+}; -+ -+struct of_fan_attribute of_fan_attributes[] = { -+ {"fan-div", emc2305_set_fan_div}, -+ {"fan-target", emc2305_set_fan_target}, -+ {"pwm-enable", emc2305_set_pwm_enable}, -+ {NULL, NULL} -+}; -+ -+static int emc2305_config_of(struct i2c_client *client) -+{ -+ struct emc2305_data *data = i2c_get_clientdata(client); -+ struct device_node *node; -+ unsigned int fan_idx; -+ -+ if (!client->dev.of_node) -+ return -EINVAL; -+ if (!of_get_next_child(client->dev.of_node, NULL)) -+ return 0; -+ -+ for (fan_idx = 0; fan_idx < data->fans; ++fan_idx) -+ data->fan[fan_idx].enabled = false; -+ -+ for_each_child_of_node(client->dev.of_node, node) { -+ const __be32 *property; -+ int len; -+ struct of_fan_attribute *attr; -+ -+ property = of_get_property(node, "reg", &len); -+ if (!property || len != sizeof(int)) { -+ dev_err(&client->dev, "invalid reg on %s\n", -+ node->full_name); -+ continue; -+ } -+ -+ fan_idx = be32_to_cpup(property); -+ if (fan_idx >= data->fans) { -+ dev_err(&client->dev, -+ "invalid fan index %d on %s\n", -+ fan_idx, node->full_name); -+ continue; -+ } -+ -+ data->fan[fan_idx].enabled = true; -+ -+ for (attr = of_fan_attributes; attr->name; ++attr) { -+ int status = 0; -+ long value; -+ property = of_get_property(node, attr->name, &len); -+ if (!property) -+ continue; -+ if (len != sizeof(int)) { -+ dev_err(&client->dev, "invalid %s on %s\n", -+ attr->name, node->full_name); -+ continue; -+ } -+ value = be32_to_cpup(property); -+ status = attr->set(client, fan_idx, value); -+ if (status == -EINVAL) { -+ dev_err(&client->dev, -+ "invalid value for %s on %s\n", -+ attr->name, node->full_name); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+#endif -+ -+static void emc2305_get_config(struct i2c_client *client) -+{ -+ int i; -+ struct emc2305_data *data = i2c_get_clientdata(client); -+ -+ for (i = 0; i < data->fans; ++i) { -+ data->fan[i].enabled = true; -+ emc2305_update_fan(client, i); -+ } -+ -+#ifdef CONFIG_OF -+ emc2305_config_of(client); -+#endif -+ -+} -+ -+static int -+emc2305_probe(struct i2c_client *client, const struct i2c_device_id *id) -+{ -+ struct emc2305_data *data; -+ int status; -+ int i; -+ int fan_idx; -+ -+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) -+ return -EIO; -+ -+ data = kzalloc(sizeof(struct emc2305_data), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ i2c_set_clientdata(client, data); -+ mutex_init(&data->update_lock); -+ -+ status = i2c_smbus_read_byte_data(client, REG_PRODUCT_ID); -+ switch (status) { -+ case 0x34: /* EMC2305 */ -+ data->fans = 5; -+ break; -+ case 0x35: /* EMC2303 */ -+ data->fans = 3; -+ break; -+ case 0x36: /* EMC2302 */ -+ data->fans = 2; -+ break; -+ case 0x37: /* EMC2301 */ -+ data->fans = 1; -+ break; -+ default: -+ if (status >= 0) -+ status = -EINVAL; -+ goto exit_free; -+ } -+ -+ emc2305_get_config(client); -+ -+ for (i = 0; i < ARRAY_SIZE(emc2305_attr_common); ++i) { -+ status = device_create_file(&client->dev, -+ &emc2305_attr_common[i].dev_attr); -+ if (status) -+ goto exit_remove; -+ } -+ for (fan_idx = 0; fan_idx < data->fans; ++fan_idx) -+ for (i = 0; i < EMC2305_NUM_FAN_ATTRS; ++i) { -+ if (!data->fan[fan_idx].enabled) -+ continue; -+ status = device_create_file( -+ &client->dev, -+ &emc2305_fan_attrs[fan_idx][i].dev_attr); -+ if (status) -+ goto exit_remove_fans; -+ } -+ -+ data->hwmon_dev = hwmon_device_register(&client->dev); -+ if (IS_ERR(data->hwmon_dev)) { -+ status = PTR_ERR(data->hwmon_dev); -+ goto exit_remove_fans; -+ } -+ -+ dev_info(&client->dev, "%s: sensor '%s'\n", -+ dev_name(data->hwmon_dev), client->name); -+ -+ return 0; -+ -+exit_remove_fans: -+ for (fan_idx = 0; fan_idx < data->fans; ++fan_idx) -+ for (i = 0; i < EMC2305_NUM_FAN_ATTRS; ++i) -+ device_remove_file( -+ &client->dev, -+ &emc2305_fan_attrs[fan_idx][i].dev_attr); -+ -+exit_remove: -+ for (i = 0; i < ARRAY_SIZE(emc2305_attr_common); ++i) -+ device_remove_file(&client->dev, -+ &emc2305_attr_common[i].dev_attr); -+exit_free: -+ kfree(data); -+ return status; -+} -+ -+static const struct i2c_device_id emc2305_id[] = { -+ { "emc2305", 0 }, -+ { "emc2303", 0 }, -+ { "emc2302", 0 }, -+ { "emc2301", 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, emc2305_id); -+ -+/* Return 0 if detection is successful, -ENODEV otherwise */ -+static int -+emc2305_detect(struct i2c_client *new_client, struct i2c_board_info *info) -+{ -+ struct i2c_adapter *adapter = new_client->adapter; -+ int manufacturer, product; -+ -+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) -+ return -ENODEV; -+ -+ manufacturer = -+ i2c_smbus_read_byte_data(new_client, REG_MANUFACTURER_ID); -+ if (manufacturer != 0x5D) -+ return -ENODEV; -+ -+ product = i2c_smbus_read_byte_data(new_client, REG_PRODUCT_ID); -+ -+ switch (product) { -+ case 0x34: -+ strlcpy(info->type, "emc2305", I2C_NAME_SIZE); -+ break; -+ case 0x35: -+ strlcpy(info->type, "emc2303", I2C_NAME_SIZE); -+ break; -+ case 0x36: -+ strlcpy(info->type, "emc2302", I2C_NAME_SIZE); -+ break; -+ case 0x37: -+ strlcpy(info->type, "emc2301", I2C_NAME_SIZE); -+ break; -+ default: -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static struct i2c_driver emc2305_driver = { -+ .class = I2C_CLASS_HWMON, -+ .driver = { -+ .name = "emc2305", -+ }, -+ .probe = emc2305_probe, -+ .remove = emc2305_remove, -+ .id_table = emc2305_id, -+ .detect = emc2305_detect, -+ .address_list = i2c_adresses, -+}; -+ -+module_i2c_driver(emc2305_driver); -+ -+MODULE_AUTHOR("Reinhard Pfau "); -+MODULE_DESCRIPTION("SMSC EMC2305 hwmon driver"); -+MODULE_LICENSE("GPL"); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-support-intel-igb-bcm54616-phy.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-support-intel-igb-bcm54616-phy.patch deleted file mode 100644 index af5bcb95..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-support-intel-igb-bcm54616-phy.patch +++ /dev/null @@ -1,77 +0,0 @@ -Support Broadcom 54616 phy in Intel IGB Ethernet Driver - -diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c -index ffdd020..a775254 100644 ---- a/drivers/net/ethernet/intel/igb/e1000_82575.c -+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c -@@ -217,6 +217,9 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw) - phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state_82580; - phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88; - break; -+ case BCM54616_E_PHY_ID: -+ phy->type = e1000_phy_bcm54616; -+ break; - default: - ret_val = -E1000_ERR_PHY; - goto out; -@@ -1464,6 +1467,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) - case e1000_i350: - case e1000_i210: - case e1000_i211: -+ case e1000_i354: - phpm_reg = rd32(E1000_82580_PHY_POWER_MGMT); - phpm_reg &= ~E1000_82580_PM_GO_LINKD; - wr32(E1000_82580_PHY_POWER_MGMT, phpm_reg); -@@ -1507,6 +1511,8 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) - case e1000_phy_82580: - ret_val = igb_copper_link_setup_82580(hw); - break; -+ case e1000_phy_bcm54616: -+ break; - default: - ret_val = -E1000_ERR_PHY; - break; -diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h -index 7459648..7a0cc00 100644 ---- a/drivers/net/ethernet/intel/igb/e1000_defines.h -+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h -@@ -786,6 +786,7 @@ - #define M88_VENDOR 0x0141 - #define I210_I_PHY_ID 0x01410C00 - #define M88E1543_E_PHY_ID 0x01410EA0 -+#define BCM54616_E_PHY_ID 0x3625D10 - - /* M88E1000 Specific Registers */ - #define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ -diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h -index 2e166b2..32b7c2f 100644 ---- a/drivers/net/ethernet/intel/igb/e1000_hw.h -+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h -@@ -133,6 +133,7 @@ enum e1000_phy_type { - e1000_phy_ife, - e1000_phy_82580, - e1000_phy_i210, -+ e1000_phy_bcm54616, - }; - - enum e1000_bus_type { -diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c -index 1675d7d..ad0f728 100644 ---- a/drivers/net/ethernet/intel/igb/igb_main.c -+++ b/drivers/net/ethernet/intel/igb/igb_main.c -@@ -112,6 +112,7 @@ static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = { - { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575GB_QUAD_COPPER), board_82575 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_SGMII), board_82575 }, - /* required last entry */ - {0, } - }; -@@ -1585,6 +1586,7 @@ void igb_power_up_link(struct igb_adapter *adapter) - igb_power_up_phy_copper(&adapter->hw); - else - igb_power_up_serdes_link_82575(&adapter->hw); -+ igb_setup_link(&adapter->hw); - } - - /** diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-support-intel-igb-bcm5461s-phy.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-support-intel-igb-bcm5461s-phy.patch deleted file mode 100644 index e9b12850..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-support-intel-igb-bcm5461s-phy.patch +++ /dev/null @@ -1,229 +0,0 @@ -patches the Intel IGB driver to add bcm5461s phy support - -diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c -index a775254..d05abb2 100644 ---- a/drivers/net/ethernet/intel/igb/e1000_82575.c -+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c -@@ -133,7 +133,10 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw) - ctrl_ext = rd32(E1000_CTRL_EXT); - - if (igb_sgmii_active_82575(hw)) { -- phy->ops.reset = igb_phy_hw_reset_sgmii_82575; -+ if(phy->type == e1000_phy_bcm5461s) -+ phy->ops.reset = igb_phy_hw_reset; -+ else -+ phy->ops.reset = igb_phy_hw_reset_sgmii_82575; - ctrl_ext |= E1000_CTRL_I2C_ENA; - } else { - phy->ops.reset = igb_phy_hw_reset; -@@ -220,6 +223,13 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw) - case BCM54616_E_PHY_ID: - phy->type = e1000_phy_bcm54616; - break; -+ case BCM5461S_PHY_ID: -+ phy->type = e1000_phy_bcm5461s; -+ phy->ops.check_polarity = NULL; -+ phy->ops.get_phy_info = igb_get_phy_info_5461s; -+ phy->ops.get_cable_length = NULL; -+ phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_82580; -+ break; - default: - ret_val = -E1000_ERR_PHY; - goto out; -@@ -758,6 +768,16 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw) - break; - } - ret_val = igb_get_phy_id(hw); -+ if (ret_val && hw->mac.type == e1000_i354) { -+ /* we do a special check for bcm5461s phy by setting -+ * the phy->addr to 5 and doing the phy check again. This -+ * call will succeed and retrieve a valid phy id if we have -+ * the bcm5461s phy -+ */ -+ phy->addr = 5; -+ phy->type = e1000_phy_bcm5461s; -+ ret_val = igb_get_phy_id(hw); -+ } - goto out; - } - -@@ -1141,6 +1161,9 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *hw) - (hw->phy.type == e1000_phy_igp_3)) - igb_phy_init_script_igp3(hw); - -+ if (hw->phy.type == e1000_phy_bcm5461s) -+ igb_phy_init_script_5461s(hw); -+ - return ret_val; - } - -@@ -1512,6 +1535,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) - ret_val = igb_copper_link_setup_82580(hw); - break; - case e1000_phy_bcm54616: -+ case e1000_phy_bcm5461s: - break; - default: - ret_val = -E1000_ERR_PHY; -diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h -index 7a0cc00..bee365f 100644 ---- a/drivers/net/ethernet/intel/igb/e1000_defines.h -+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h -@@ -787,6 +787,7 @@ - #define I210_I_PHY_ID 0x01410C00 - #define M88E1543_E_PHY_ID 0x01410EA0 - #define BCM54616_E_PHY_ID 0x3625D10 -+#define BCM5461S_PHY_ID 0x002060C0 - - /* M88E1000 Specific Registers */ - #define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ -diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h -index 32b7c2f..d7d3504 100644 ---- a/drivers/net/ethernet/intel/igb/e1000_hw.h -+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h -@@ -134,6 +134,7 @@ enum e1000_phy_type { - e1000_phy_82580, - e1000_phy_i210, - e1000_phy_bcm54616, -+ e1000_phy_bcm5461s, - }; - - enum e1000_bus_type { -diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c -index ad2b74d..0df0346 100644 ---- a/drivers/net/ethernet/intel/igb/e1000_phy.c -+++ b/drivers/net/ethernet/intel/igb/e1000_phy.c -@@ -152,6 +152,13 @@ s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) - * Control register. The MAC will take care of interfacing with the - * PHY to retrieve the desired data. - */ -+ if (phy->type == e1000_phy_bcm5461s) { -+ mdic = rd32(E1000_MDICNFG); -+ mdic &= ~E1000_MDICNFG_PHY_MASK; -+ mdic |= (phy->addr << E1000_MDICNFG_PHY_SHIFT); -+ wr32(E1000_MDICNFG, mdic); -+ } -+ - mdic = ((offset << E1000_MDIC_REG_SHIFT) | - (phy->addr << E1000_MDIC_PHY_SHIFT) | - (E1000_MDIC_OP_READ)); -@@ -208,6 +215,13 @@ s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) - * Control register. The MAC will take care of interfacing with the - * PHY to retrieve the desired data. - */ -+ if (phy->type == e1000_phy_bcm5461s) { -+ mdic = rd32(E1000_MDICNFG); -+ mdic &= ~E1000_MDICNFG_PHY_MASK; -+ mdic |= (phy->addr << E1000_MDICNFG_PHY_SHIFT); -+ wr32(E1000_MDICNFG, mdic); -+ } -+ - mdic = (((u32)data) | - (offset << E1000_MDIC_REG_SHIFT) | - (phy->addr << E1000_MDIC_PHY_SHIFT) | -@@ -2599,3 +2613,68 @@ static s32 igb_set_master_slave_mode(struct e1000_hw *hw) - - return hw->phy.ops.write_reg(hw, PHY_1000T_CTRL, phy_data); - } -+ -+ -+/** -+ * igb_phy_init_script_5461s - Inits the BCM5461S PHY -+ * @hw: pointer to the HW structure -+ * -+ * Initializes a Broadcom Gigabit PHY. -+ **/ -+s32 igb_phy_init_script_5461s(struct e1000_hw *hw) -+{ -+ u16 mii_reg_led = 0; -+ -+ /* 1. Speed LED (Set the Link LED mode), Shadow 00010, 0x1C.bit2=1 */ -+ hw->phy.ops.write_reg(hw, 0x1C, 0x0800); -+ hw->phy.ops.read_reg(hw, 0x1C, &mii_reg_led); -+ mii_reg_led |= 0x0004; -+ hw->phy.ops.write_reg(hw, 0x1C, mii_reg_led | 0x8000); -+ -+ /* 2. Active LED (Set the Link LED mode), Shadow 01001, 0x1C.bit4=1, 0x10.bit5=0 */ -+ hw->phy.ops.write_reg(hw, 0x1C, 0x2400); -+ hw->phy.ops.read_reg(hw, 0x1C, &mii_reg_led); -+ mii_reg_led |= 0x0010; -+ hw->phy.ops.write_reg(hw, 0x1C, mii_reg_led | 0x8000); -+ hw->phy.ops.read_reg(hw, 0x10, &mii_reg_led); -+ mii_reg_led &= 0xffdf; -+ hw->phy.ops.write_reg(hw, 0x10, mii_reg_led); -+ -+ return 0; -+} -+ -+ -+/** -+ * igb_get_phy_info_5461s - Retrieve 5461s PHY information -+ * @hw: pointer to the HW structure -+ * -+ * Read PHY status to determine if link is up. If link is up, then -+ * set/determine 10base-T extended distance and polarity correction. Read -+ * PHY port status to determine MDI/MDIx and speed. Based on the speed, -+ * determine on the cable length, local and remote receiver. -+ **/ -+s32 igb_get_phy_info_5461s(struct e1000_hw *hw) -+{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ bool link; -+ -+ ret_val = igb_phy_has_link(hw, 1, 0, &link); -+ if (ret_val) -+ goto out; -+ -+ if (!link) { -+ ret_val = -E1000_ERR_CONFIG; -+ goto out; -+ } -+ -+ phy->polarity_correction = true; -+ -+ phy->is_mdix = true; -+ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; -+ phy->local_rx = e1000_1000t_rx_status_ok; -+ phy->remote_rx = e1000_1000t_rx_status_ok; -+ -+out: -+ return ret_val; -+} -diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.h b/drivers/net/ethernet/intel/igb/e1000_phy.h -index 6a0873f..ca60225 100644 ---- a/drivers/net/ethernet/intel/igb/e1000_phy.h -+++ b/drivers/net/ethernet/intel/igb/e1000_phy.h -@@ -65,6 +65,8 @@ s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations, - void igb_power_up_phy_copper(struct e1000_hw *hw); - void igb_power_down_phy_copper(struct e1000_hw *hw); - s32 igb_phy_init_script_igp3(struct e1000_hw *hw); -+s32 igb_phy_init_script_5461s(struct e1000_hw *hw); -+s32 igb_get_phy_info_5461s(struct e1000_hw *hw); - s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data); - s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data); - s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data); -diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c -index ad0f728..0b8cb81 100644 ---- a/drivers/net/ethernet/intel/igb/igb_main.c -+++ b/drivers/net/ethernet/intel/igb/igb_main.c -@@ -6841,11 +6841,19 @@ static int igb_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) - data->phy_id = adapter->hw.phy.addr; - break; - case SIOCGMIIREG: -+ adapter->hw.phy.addr = data->phy_id; - if (igb_read_phy_reg(&adapter->hw, data->reg_num & 0x1F, - &data->val_out)) - return -EIO; - break; - case SIOCSMIIREG: -+ if (!capable(CAP_NET_ADMIN)) -+ return -EPERM; -+ adapter->hw.phy.addr = data->phy_id; -+ if (igb_write_phy_reg(&adapter->hw, data->reg_num & 0x1F, -+ data->val_in)) -+ return -EIO; -+ break; - default: - return -EOPNOTSUPP; - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-support-sff-8436-eeprom.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-support-sff-8436-eeprom.patch deleted file mode 100644 index 9483a03f..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-support-sff-8436-eeprom.patch +++ /dev/null @@ -1,1072 +0,0 @@ -Driver to expose eeprom information including DOM for QSFPs - -diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig -index 08c7a23..7c7b208 100644 ---- a/drivers/misc/eeprom/Kconfig -+++ b/drivers/misc/eeprom/Kconfig -@@ -106,4 +106,16 @@ config EEPROM_DIGSY_MTC_CFG - - If unsure, say N. - -+config EEPROM_SFF_8436 -+ tristate "SFF-8436 QSFP EEPROMs support" -+ depends on I2C && SYSFS -+ help -+ If you say yes here you get read-only support for the EEPROM of -+ the QSFPs which are implemented as per SFF-8436. -+ -+ All other features of this chip should be accessed via i2c-dev. -+ -+ This driver can also be built as a module. If so, the module -+ will be called sff_8436. -+ - endmenu -diff --git a/drivers/misc/eeprom/Makefile b/drivers/misc/eeprom/Makefile -index eabb373..9edd559 100644 ---- a/drivers/misc/eeprom/Makefile -+++ b/drivers/misc/eeprom/Makefile -@@ -6,3 +6,4 @@ obj-$(CONFIG_EEPROM_MAX6875) += max6875.o - obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o - obj-$(CONFIG_EEPROM_93XX46) += eeprom_93xx46.o - obj-$(CONFIG_EEPROM_DIGSY_MTC_CFG) += digsy_mtc_eeprom.o -+obj-$(CONFIG_EEPROM_SFF_8436) += sff_8436_eeprom.o -diff --git a/drivers/misc/eeprom/sff_8436_eeprom.c b/drivers/misc/eeprom/sff_8436_eeprom.c -new file mode 100644 -index 0000000..0b6bf31 ---- /dev/null -+++ b/drivers/misc/eeprom/sff_8436_eeprom.c -@@ -0,0 +1,995 @@ -+/* -+ * sff_8436_eeprom.c - handle most SFF-8436 based QSFP EEPROMs -+ * -+ * Copyright (C) 2014 Cumulus networks 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 Freeoftware Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+/* -+ * Description: -+ * a) SFF 8436 based qsfp read/write transactions are just like the at24 eeproms -+ * b) The register/memory layout is up to 5 128 byte pages defined by a "pages valid" -+ * register and switched via a "page select" register as explained in below diagram. -+ * c) 256 bytes are mapped at a time. page 0 is always mapped to the first 128 bytes and -+ * the other 4 pages are selectively mapped to the second 128 bytes -+ * -+ * SFF 8436 based QSFP Memory Map -+ * -+ * 2-Wire Serial Address: 1010000x -+ * -+ * Lower Page 00h (128 bytes) -+ * ===================== -+ * | | -+ * | | -+ * | | -+ * | | -+ * | | -+ * | | -+ * | | -+ * | | -+ * | | -+ * | | -+ * |Page Select Byte(127)| -+ * ===================== -+ * | -+ * | -+ * | -+ * | -+ * V -+ * ----------------------------------------------------------------- -+ * | | | | -+ * | | | | -+ * | | | | -+ * | | | | -+ * | | | | -+ * | | | | -+ * | | | | -+ * | | | | -+ * | | | | -+ * V V V V -+ * ------------- ---------------- ----------------- -------------- -+ * | | | | | | | | -+ * | Upper | | Upper | | Upper | | Upper | -+ * | Page 00h | | Page 01h | | Page 02h | | Page 03h | -+ * | | | (Optional) | | (Optional) | | (Optional | -+ * | | | | | | | for Cable | -+ * | | | | | | | Assemblies) | -+ * | ID | | AST | | User | | | -+ * | Fields | | Table | | EEPROM Data | | | -+ * | | | | | | | | -+ * | | | | | | | | -+ * | | | | | | | | -+ * ------------- ---------------- ----------------- -------------- -+ * -+ * -+ **/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define SFF_8436_EEPROM_SIZE 5*128 -+#define SFF_8436_MAX_PAGE_COUNT 5 -+#define SFF_8436_MMAP_SIZE 256 -+#define SFF_8436_PAGE_SELECT_REG 0x7F -+ -+#define SFF_8436_OPTION_4_OFFSET 0xC3 -+#define SFF_8436_PAGE_02_PRESENT (1 << 7) /* Memory Page 02 present */ -+#define SFF_8436_PAGE_01_PRESENT (1 << 6) /* Memory Page 01 present */ -+#define SFF_8436_STATUS_2_OFFSET 0x02 -+#define SFF_8436_STATUS_PAGE_03_PRESENT_L (1 << 2) /* Flat Memory:0- Paging, 1- Page 0 only */ -+ -+struct sff_8436_data { -+ struct sff_8436_platform_data chip; -+ struct memory_accessor macc; -+ int use_smbus; -+ -+ /* -+ * Lock protects against activities from other Linux tasks, -+ * but not from changes by other I2C masters. -+ */ -+ struct mutex lock; -+ struct bin_attribute bin; -+ -+ u8 *writebuf; -+ unsigned write_max; -+ -+ unsigned num_addresses; -+ -+ u8 data[SFF_8436_EEPROM_SIZE]; -+ struct eeprom_device *eeprom_dev; -+ -+ struct i2c_client *client[]; -+}; -+ -+typedef enum qsfp_opcode { -+ QSFP_READ_OP = 0, -+ QSFP_WRITE_OP = 1 -+} qsfp_opcode_e; -+ -+/* -+ * This parameter is to help this driver avoid blocking other drivers out -+ * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C -+ * clock, one 256 byte read takes about 1/43 second which is excessive; -+ * but the 1/170 second it takes at 400 kHz may be quite reasonable; and -+ * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. -+ * -+ * This value is forced to be a power of two so that writes align on pages. -+ */ -+static unsigned io_limit = 128; -+ -+/* -+ *pecs often allow 5 msec for a page write, sometimes 20 msec; -+ * it's important to recover from write timeouts. -+ */ -+static unsigned write_timeout = 25; -+ -+#define SFF_8436_PAGE_SIZE 128 -+#define SFF_8436_SIZE_BYTELEN 5 -+#define SFF_8436_SIZE_FLAGS 8 -+ -+#define SFF_8436_BITMASK(x) (BIT(x) - 1) -+ -+ -+/* create non-zero magic value for given eeprom parameters */ -+#define SFF_8436_DEVICE_MAGIC(_len, _flags) \ -+ ((1 << SFF_8436_SIZE_FLAGS | (_flags)) \ -+ << SFF_8436_SIZE_BYTELEN | ilog2(_len)) -+ -+static const struct i2c_device_id sff8436_ids[] = { -+ { "sff8436",SFF_8436_DEVICE_MAGIC(2048 / 8, 0) }, -+ { /* END OF LIST */ } -+}; -+MODULE_DEVICE_TABLE(i2c, sff8436_ids); -+ -+/*-------------------------------------------------------------------------*/ -+/* -+ * This routine computes the addressing information to be used for a given r/w request. -+ * Assumes that sanity checks for offset happened at sysfs-layer. -+ * Offset within Lower Page 00h and Upper Page 00h are not recomputed -+ */ -+static uint8_t sff_8436_translate_offset(struct sff_8436_data *sff_8436, -+ loff_t *offset) -+{ -+ unsigned page = 0; -+ -+ if (*offset < SFF_8436_MMAP_SIZE) { -+ return 0; -+ } -+ -+ page = (*offset >> 7)-1; -+ -+ if (page > 0 ) { -+ *offset = 0x80 + (*offset & 0x7f); -+ } else { -+ *offset &= 0xff; -+ } -+ -+ return page; -+} -+ -+static int sff_8436_read_reg(struct sff_8436_data *sff_8436, -+ uint8_t reg, uint8_t *val) -+{ -+ int count = 1, i = 0; -+ struct i2c_client *client = sff_8436->client[0]; -+ struct i2c_msg msg[2]; -+ u8 msgbuf[2]; -+ ssize_t status; -+ unsigned long timeout, read_time; -+ -+ memset(msg, 0, sizeof(msg)); -+ -+ /* -+ * Writes fail if the previous one didn't complete yet. We may -+ * loop a few times until this one succeeds, waiting at least -+ * long enough for one entire page write to work. -+ */ -+ timeout = jiffies + msecs_to_jiffies(write_timeout); -+ do { -+ read_time = jiffies; -+ switch (sff_8436->use_smbus) { -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ status = i2c_smbus_read_i2c_block_data(client, -+ reg, count, val); -+ break; -+ case I2C_SMBUS_WORD_DATA: -+ status = i2c_smbus_read_word_data(client, reg); -+ -+ if (status >= 0) { -+ *val = status & 0xff; -+ status = count; -+ } -+ break; -+ case I2C_SMBUS_BYTE_DATA: -+ status = i2c_smbus_read_byte_data(client, reg); -+ -+ if (status >= 0) { -+ *val = status; -+ status = count; -+ } -+ break; -+ -+ default: -+ i = 0; -+ msgbuf[i++] = reg; -+ -+ msg[0].addr = client->addr; -+ msg[0].buf = msgbuf; -+ msg[0].len = i; -+ -+ msg[1].addr = client->addr; -+ msg[1].flags = I2C_M_RD; -+ msg[1].buf = val; -+ msg[1].len = count; -+ -+ status = i2c_transfer(client->adapter, msg, 2); -+ if (status == 2) -+ status = count; -+ break; -+ } -+ dev_dbg(&client->dev, "read (using smbus %d) %d@%d --> %zd (%ld)\n", -+ sff_8436->use_smbus, count, reg, status, jiffies); -+ -+ if (status == count) -+ return count; -+ -+ /* REVISIT: at HZ=100, this is sloooow */ -+ msleep(1); -+ } while (time_before(read_time, timeout)); -+ -+ return -ETIMEDOUT; -+} -+ -+static int sff_8436_write_reg(struct sff_8436_data *sff_8436, -+ uint8_t reg, uint8_t val) -+{ -+ uint8_t data[2] = { reg, val }; -+ int count = 1; -+ struct i2c_client *client = sff_8436->client[0]; -+ struct i2c_msg msg; -+ ssize_t status; -+ unsigned long timeout, write_time; -+ -+ /* -+ * Writes fail if the previous one didn't complete yet. We may -+ * loop a few times until this one succeeds, waiting at least -+ * long enough for one entire page write to work. -+ */ -+ timeout = jiffies + msecs_to_jiffies(write_timeout); -+ do { -+ write_time = jiffies; -+ switch (sff_8436->use_smbus) { -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ status = i2c_smbus_write_i2c_block_data(client, -+ reg, count, &val); -+ if (status == 0) -+ status = count; -+ break; -+ case I2C_SMBUS_WORD_DATA: -+ case I2C_SMBUS_BYTE_DATA: -+ status = i2c_smbus_write_byte_data(client, reg, val); -+ -+ if (status == 0) -+ status = count; -+ break; -+ default: -+ msg.addr = client->addr; -+ msg.flags = 0; -+ msg.len = sizeof(data); -+ msg.buf = (char *) data; -+ -+ status = i2c_transfer(client->adapter, &msg, 1); -+ if (status == 1) -+ status = count; -+ break; -+ } -+ dev_dbg(&client->dev, "write (using smbus %d) %d@%d --> %zd (%ld)\n", -+ sff_8436->use_smbus, count, reg, status, jiffies); -+ -+ if (status == count) -+ return count; -+ -+ /* REVISIT: at HZ=100, this is sloooow */ -+ msleep(1); -+ } while (time_before(write_time, timeout)); -+ -+ return -ETIMEDOUT; -+} -+ -+static int sff_8436_write_page_reg(struct sff_8436_data *sff_8436, -+ uint8_t val) -+{ -+ return sff_8436_write_reg(sff_8436, SFF_8436_PAGE_SELECT_REG, val); -+} -+ -+static ssize_t sff_8436_eeprom_read(struct sff_8436_data *sff_8436, char *buf, -+ unsigned offset, size_t count) -+{ -+ struct i2c_msg msg[2]; -+ u8 msgbuf[2]; -+ struct i2c_client *client = sff_8436->client[0]; -+ unsigned long timeout, read_time; -+ int status, i; -+ -+ memset(msg, 0, sizeof(msg)); -+ -+ switch (sff_8436->use_smbus) { -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ /*smaller eeproms can work given some SMBus extension calls */ -+ if (count > I2C_SMBUS_BLOCK_MAX) -+ count = I2C_SMBUS_BLOCK_MAX; -+ break; -+ case I2C_SMBUS_WORD_DATA: -+ /* Check for odd length transaction */ -+ count = (count == 1) ? 1 : 2; -+ break; -+ case I2C_SMBUS_BYTE_DATA: -+ count = 1; -+ break; -+ default: -+ /* -+ * When we have a better choice than SMBus calls, use a -+ * combined I2C message. Write address; then read up to -+ * io_limit data bytes. Note that read page rollover helps us -+ * here (unlike writes). msgbuf is u8 and will cast to our -+ * needs. -+ */ -+ i = 0; -+ msgbuf[i++] = offset; -+ -+ msg[0].addr = client->addr; -+ msg[0].buf = msgbuf; -+ msg[0].len = i; -+ -+ msg[1].addr = client->addr; -+ msg[1].flags = I2C_M_RD; -+ msg[1].buf = buf; -+ msg[1].len = count; -+ } -+ -+ /* -+ * Reads fail if the previous write didn't complete yet. We may -+ * loop a few times until this one succeeds, waiting at least -+ * long enough for one entire page write to work. -+ */ -+ timeout = jiffies + msecs_to_jiffies(write_timeout); -+ do { -+ read_time = jiffies; -+ -+ switch (sff_8436->use_smbus) { -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ status = i2c_smbus_read_i2c_block_data(client, offset, -+ count, buf); -+ break; -+ case I2C_SMBUS_WORD_DATA: -+ status = i2c_smbus_read_word_data(client, offset); -+ if (status >= 0) { -+ buf[0] = status & 0xff; -+ if (count == 2) -+ buf[1] = status >> 8; -+ status = count; -+ } -+ break; -+ case I2C_SMBUS_BYTE_DATA: -+ status = i2c_smbus_read_byte_data(client, offset); -+ if (status >= 0) { -+ buf[0] = status; -+ status = count; -+ } -+ break; -+ default: -+ status = i2c_transfer(client->adapter, msg, 2); -+ if (status == 2) -+ status = count; -+ } -+ -+ dev_dbg(&client->dev, "eeprom read %zu@%d --> %d (%ld)\n", -+ count, offset, status, jiffies); -+ -+ if (status == count) -+ return count; -+ -+ /* REVISIT: at HZ=100, this is sloooow */ -+ msleep(1); -+ } while (time_before(read_time, timeout)); -+ -+ return -ETIMEDOUT; -+} -+ -+static ssize_t sff_8436_eeprom_write(struct sff_8436_data *sff_8436, const char *buf, -+ unsigned offset, size_t count) -+{ -+ struct i2c_client *client = sff_8436->client[0]; -+ struct i2c_msg msg; -+ ssize_t status; -+ unsigned long timeout, write_time; -+ unsigned next_page; -+ int i = 0; -+ -+ /* write max is at most a page */ -+ if (count > sff_8436->write_max) -+ count = sff_8436->write_max; -+ -+ /* Never roll over backwards, to the start of this page */ -+ next_page = roundup(offset + 1, SFF_8436_PAGE_SIZE); -+ if (offset + count > next_page) -+ count = next_page - offset; -+ -+ switch (sff_8436->use_smbus) { -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ /*smaller eeproms can work given some SMBus extension calls */ -+ if (count > I2C_SMBUS_BLOCK_MAX) -+ count = I2C_SMBUS_BLOCK_MAX; -+ break; -+ case I2C_SMBUS_WORD_DATA: -+ /* Check for odd length transaction */ -+ count = (count == 1) ? 1 : 2; -+ break; -+ case I2C_SMBUS_BYTE_DATA: -+ count = 1; -+ break; -+ default: -+ /* If we'll use I2C calls for I/O, set up the message */ -+ msg.addr = client->addr; -+ msg.flags = 0; -+ -+ /* msg.buf is u8 and casts will mask the values */ -+ msg.buf = sff_8436->writebuf; -+ -+ msg.buf[i++] = offset; -+ memcpy(&msg.buf[i], buf, count); -+ msg.len = i + count; -+ break; -+ } -+ -+ /* -+ * Reads fail if the previous write didn't complete yet. We may -+ * loop a few times until this one succeeds, waiting at least -+ * long enough for one entire page write to work. -+ */ -+ timeout = jiffies + msecs_to_jiffies(write_timeout); -+ do { -+ write_time = jiffies; -+ -+ switch (sff_8436->use_smbus) { -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ status = i2c_smbus_write_i2c_block_data(client, -+ offset, count, buf); -+ if (status == 0) -+ status = count; -+ break; -+ case I2C_SMBUS_WORD_DATA: -+ if (count == 2) { -+ status = i2c_smbus_write_word_data( -+ client,offset,(u16)((buf[0]) | -+ (buf[1] << 8))); -+ } else { -+ /* count = 1 */ -+ status = i2c_smbus_write_byte_data( -+ client, offset, buf[0]); -+ } -+ if (status == 0) -+ status = count; -+ break; -+ case I2C_SMBUS_BYTE_DATA: -+ status = i2c_smbus_write_byte_data(client, offset, buf[0]); -+ if (status == 0) -+ status = count; -+ break; -+ default: -+ status = i2c_transfer(client->adapter, &msg, 1); -+ if (status == 1) -+ status = count; -+ break; -+ } -+ -+ dev_dbg(&client->dev, "eeprom write %zu@%d --> %d (%ld)\n", -+ count, offset, status, jiffies); -+ -+ if (status == count) -+ return count; -+ -+ /* REVISIT: at HZ=100, this is sloooow */ -+ msleep(1); -+ } while (time_before(write_time, timeout)); -+ -+ return -ETIMEDOUT; -+} -+ -+static ssize_t sff_8436_eeprom_update_client(struct sff_8436_data *sff_8436, -+ loff_t off, size_t count, qsfp_opcode_e opcode) -+{ -+ struct i2c_client *client = sff_8436->client[0]; -+ ssize_t retval = 0; -+ u8 page = 0; -+ loff_t phy_offset = off; -+ int ret = 0; -+ -+ page = sff_8436_translate_offset(sff_8436, &phy_offset); -+ -+ dev_dbg(&client->dev, -+ "sff_8436_eeprom_update_client off %lld page:%d phy_offset:%lld, count:%d, opcode:%d\n", -+ off, page, phy_offset, count, opcode); -+ if (page > 0) { -+ ret = sff_8436_write_page_reg(sff_8436, page); -+ if (ret < 0) { -+ dev_err(&client->dev, -+ "sff_8436_write_page_reg for page %d failed ret:%d!\n", -+ page, ret); -+ return ret; -+ } -+ } -+ -+ while (count) { -+ ssize_t status; -+ -+ if (opcode == QSFP_READ_OP) { -+ status = sff_8436_eeprom_read(sff_8436, (char *)(&sff_8436->data[off]), phy_offset, count); -+ } else { -+ status = sff_8436_eeprom_write(sff_8436, (char *)(&sff_8436->data[off]), phy_offset, count); -+ } -+ if (status <= 0) { -+ if (retval == 0) -+ retval = status; -+ break; -+ } -+ phy_offset += status; -+ off += status; -+ count -= status; -+ retval += status; -+ } -+ -+ -+ if (page > 0) { -+ ret = sff_8436_write_page_reg(sff_8436, 0); -+ if (ret < 0) { -+ dev_err(&client->dev, -+ "sff_8436_write_page_reg for page 0 failed ret:%d!\n", ret); -+ return ret; -+ } -+ } -+ return retval; -+} -+ -+static ssize_t sff_8436_read_write(struct sff_8436_data *sff_8436, -+ char *buf, loff_t off, size_t len, qsfp_opcode_e opcode) -+{ -+ struct i2c_client *client = sff_8436->client[0]; -+ u8 page; -+ u8 refresh_page = 0; -+ int ret = 0; -+ u8 val = 0; -+ int err_timeout = 0; -+ size_t pending_len = 0, page_len = 0; -+ loff_t page_offset = 0, page_start_offset = 0; -+ -+ if (unlikely(!len)) -+ return len; -+ -+ if (off > SFF_8436_EEPROM_SIZE) -+ return 0; -+ -+ if (off + len > SFF_8436_EEPROM_SIZE) -+ len = SFF_8436_EEPROM_SIZE - off; -+ -+ if (opcode == QSFP_READ_OP) { -+ memset(sff_8436->data, 0xff, SFF_8436_EEPROM_SIZE); -+ } else if (opcode == QSFP_WRITE_OP) { -+ memcpy(&sff_8436->data[off], buf, len); -+ } -+ -+ /* -+ * Read data from chip, protecting against concurrent updates -+ * from this host, but not from other I2C masters. -+ */ -+ mutex_lock(&sff_8436->lock); -+ -+ /* -+ * Refresh pages which covers the requested data -+ * from offset to off + len -+ * Only refresh pages which contain requested bytes -+ * -+ */ -+ -+ pending_len = len; -+ -+ for (page = off >> 7; page <= (off + len - 1) >> 7; page++) { -+ refresh_page = 0; -+ switch (page) { -+ case 0: -+ /* Lower page 00h */ -+ refresh_page = 1; -+ err_timeout = 1; -+ break; -+ case 1: -+ /* Upper page 00h */ -+ refresh_page = 1; -+ err_timeout = 1; -+ break; -+ case 2: -+ /* Upper page 01h */ -+ ret = sff_8436_read_reg(sff_8436, SFF_8436_OPTION_4_OFFSET, &val); -+ if (ret < 0) { -+ dev_dbg(&client->dev, -+ "sff_8436_read_reg for page 01h status failed %d!\n", ret); -+ goto err; -+ } -+ if (val & SFF_8436_PAGE_01_PRESENT) { -+ refresh_page = 1; -+ } -+ break; -+ case 3: -+ /* Upper page 02h */ -+ ret = sff_8436_read_reg(sff_8436, SFF_8436_OPTION_4_OFFSET, &val); -+ if (ret < 0) { -+ dev_dbg(&client->dev, -+ "sff_8436_read_reg for page 02h status failed %d!\n", ret); -+ goto err; -+ } -+ if (val & SFF_8436_PAGE_02_PRESENT) { -+ refresh_page = 1; -+ } -+ break; -+ case 4: -+ /* Upper page 03h */ -+ ret = sff_8436_read_reg(sff_8436, SFF_8436_STATUS_2_OFFSET, &val); -+ if (ret < 0) { -+ dev_dbg(&client->dev, -+ "sff_8436_read_reg for page 03h status failed %d!\n", ret); -+ goto err; -+ } -+ if (!(val & SFF_8436_STATUS_PAGE_03_PRESENT_L)) { -+ refresh_page = 1; -+ } -+ break; -+ default: -+ /* Invalid page index */ -+ dev_err(&client->dev, "Invalid page %d!\n", page); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ if (!refresh_page) { -+ /* if page is not valid or already refreshed */ -+ continue; -+ } -+ -+ /* -+ * Compute the offset and number of bytes to be read/write -+ * w.r.t requested page -+ * -+ * 1. start at offset 0 (within the page), and read/write the entire page -+ * 2. start at offset 0 (within the page) and read/write less than entire page -+ * 3. start at an offset not equal to 0 and read/write the rest of the page -+ * 4. start at an offset not equal to 0 and read/write less than (end of page - offset) -+ * -+ */ -+ page_start_offset = page * SFF_8436_PAGE_SIZE; -+ -+ if (page_start_offset < off) { -+ page_offset = off; -+ if (off + pending_len < page_start_offset + SFF_8436_PAGE_SIZE) { -+ page_len = pending_len; -+ } else { -+ page_len = SFF_8436_PAGE_SIZE - off; -+ } -+ } else { -+ page_offset = page_start_offset; -+ if (pending_len > SFF_8436_PAGE_SIZE) { -+ page_len = SFF_8436_PAGE_SIZE; -+ } else { -+ page_len = pending_len; -+ } -+ } -+ -+ pending_len = pending_len - page_len; -+ -+ dev_dbg(&client->dev, -+ "sff_read off %lld len %d page_start_offset %lld page_offset %lld page_len %d pending_len %d\n", -+ off, len, page_start_offset, page_offset, page_len, pending_len); -+ -+ /* Refresh the data from offset for specified len */ -+ ret = sff_8436_eeprom_update_client(sff_8436, page_offset, page_len, opcode); -+ if (ret != page_len) { -+ if (err_timeout) { -+ dev_dbg(&client->dev, "sff_8436_update_client for %s page %d page_offset %lld page_len %d failed %d!\n", -+ (page ? "Upper" : "Lower"), (page ? (page-1) : page), page_offset, page_len, ret); -+ goto err; -+ } else { -+ dev_err(&client->dev, "sff_8436_update_client for %s page %d page_offset %lld page_len %d failed %d!\n", -+ (page ? "Upper" : "Lower"), (page ? (page-1) : page), page_offset, page_len, ret); -+ } -+ } -+ } -+ mutex_unlock(&sff_8436->lock); -+ -+ if (opcode == QSFP_READ_OP) { -+ memcpy(buf, &sff_8436->data[off], len); -+ } -+ return len; -+ -+err: -+ mutex_unlock(&sff_8436->lock); -+ -+ return ret; -+} -+ -+static ssize_t sff_8436_bin_read(struct file *filp, struct kobject *kobj, -+ struct bin_attribute *attr, -+ char *buf, loff_t off, size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); -+ struct sff_8436_data *sff_8436 = i2c_get_clientdata(client); -+ -+ return sff_8436_read_write(sff_8436, buf, off, count, QSFP_READ_OP); -+} -+ -+ -+static ssize_t sff_8436_bin_write(struct file *filp, struct kobject *kobj, -+ struct bin_attribute *attr, -+ char *buf, loff_t off, size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); -+ struct sff_8436_data *sff_8436 = i2c_get_clientdata(client); -+ -+ return sff_8436_read_write(sff_8436, buf, off, count, QSFP_WRITE_OP); -+} -+/*-------------------------------------------------------------------------*/ -+ -+/* -+ * This lets other kernel code access the eeprom data. For example, it -+ * might hold a board's Ethernet address, or board-specific calibration -+ * data generated on the manufacturing floor. -+ */ -+ -+static ssize_t sff_8436_macc_read(struct memory_accessor *macc, char *buf, -+ off_t offset, size_t count) -+{ -+ struct sff_8436_data *sff_8436 = container_of(macc, struct sff_8436_data, macc); -+ -+ return sff_8436_read_write(sff_8436, buf, offset, count, QSFP_READ_OP); -+} -+ -+static ssize_t sff_8436_macc_write(struct memory_accessor *macc, const char *buf, -+ off_t offset, size_t count) -+{ -+ struct sff_8436_data *sff_8436 = container_of(macc, struct sff_8436_data, macc); -+ -+ return sff_8436_read_write(sff_8436, buf, offset, count, QSFP_WRITE_OP); -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+static int __devexit sff_8436_remove(struct i2c_client *client) -+{ -+ struct sff_8436_data *sff_8436; -+ -+ sff_8436 = i2c_get_clientdata(client); -+ sysfs_remove_bin_file(&client->dev.kobj, &sff_8436->bin); -+ -+ eeprom_device_unregister(sff_8436->eeprom_dev); -+ -+ kfree(sff_8436->writebuf); -+ kfree(sff_8436); -+ return 0; -+} -+static int sff_8436_eeprom_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ int err; -+ int use_smbus = 0; -+ struct sff_8436_platform_data chip; -+ struct sff_8436_data *sff_8436; -+ kernel_ulong_t magic; -+ -+ if (client->dev.platform_data) { -+ chip = *(struct sff_8436_platform_data *)client->dev.platform_data; -+ } else { -+ /* -+ * SFF-8436 MMAP is 256 bytes long -+ */ -+ magic = SFF_8436_DEVICE_MAGIC(2048 / 8, 0); -+ chip.byte_len = BIT(magic & SFF_8436_BITMASK(SFF_8436_SIZE_BYTELEN)); -+ magic >>= SFF_8436_SIZE_BYTELEN; -+ chip.flags = magic & SFF_8436_BITMASK(SFF_8436_SIZE_FLAGS); -+ /* -+ * This is slow, but we can't know all eeproms, so we better -+ * play safe.pecifying custom eeprom-types via platform_data -+ * is recommended anyhow. -+ */ -+ chip.page_size = 1; -+ -+ chip.setup = NULL; -+ chip.context = NULL; -+ chip.eeprom_data = NULL; -+ } -+ -+ if (!is_power_of_2(chip.byte_len)) -+ dev_warn(&client->dev, -+ "byte_len looks suspicious (no power of 2)!\n"); -+ -+ if (!chip.page_size) { -+ dev_err(&client->dev, "page_size must not be 0!\n"); -+ err = -EINVAL; -+ goto exit; -+ } -+ if (!is_power_of_2(chip.page_size)) -+ dev_warn(&client->dev, -+ "page_size looks suspicious (no power of 2)!\n"); -+ -+ /* Use I2C operations unless we're stuck with SMBus extensions. */ -+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { -+ if (i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { -+ use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; -+ } else if (i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_READ_WORD_DATA)) { -+ use_smbus = I2C_SMBUS_WORD_DATA; -+ } else if (i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_READ_BYTE_DATA)) { -+ use_smbus = I2C_SMBUS_BYTE_DATA; -+ } else { -+ err = -EPFNOSUPPORT; -+ goto exit; -+ } -+ } -+ -+ if (!(sff_8436 = kzalloc(sizeof(struct sff_8436_data) + sizeof(struct i2c_client *), GFP_KERNEL))) { -+ err = -ENOMEM; -+ goto exit; -+ } -+ -+ mutex_init(&sff_8436->lock); -+ sff_8436->use_smbus = use_smbus; -+ sff_8436->chip = chip; -+ -+ /* -+ * Export the EEPROM bytes through sysfs, since that's convenient. -+ * By default, only root should see the data (maybe passwords etc) -+ */ -+ sysfs_bin_attr_init(&sff_8436->bin); -+ sff_8436->bin.attr.name = "eeprom"; -+ sff_8436->bin.attr.mode = SFF_8436_FLAG_IRUGO; -+ sff_8436->bin.read = sff_8436_bin_read; -+ sff_8436->bin.size = SFF_8436_EEPROM_SIZE; -+ -+ sff_8436->macc.read = sff_8436_macc_read; -+ -+ if (!use_smbus || -+ (i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) || -+ i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_WRITE_WORD_DATA) || -+ i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { -+ //unsigned write_max = chip.page_size; -+ /* -+ * NOTE: AN-2079 -+ * Finisar recommends that the host implement 1 byte writes only, -+ * since this module only supports 32 byte page boundaries. -+ * 2 byte writes are acceptable for PE and Vout changes per -+ * Application Note AN-2071. -+ */ -+ unsigned write_max = 1; -+ -+ sff_8436->macc.write = sff_8436_macc_write; -+ -+ sff_8436->bin.write = sff_8436_bin_write; -+ sff_8436->bin.attr.mode |= S_IWUSR; -+ -+ if (write_max > io_limit) -+ write_max = io_limit; -+ if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) -+ write_max = I2C_SMBUS_BLOCK_MAX; -+ sff_8436->write_max = write_max; -+ -+ /* buffer (data + address at the beginning) */ -+ sff_8436->writebuf = kmalloc(write_max + 2, GFP_KERNEL); -+ if (!sff_8436->writebuf) { -+ err = -ENOMEM; -+ goto exit_kfree; -+ } -+ } else { -+ dev_warn(&client->dev, -+ "cannot write due to controller restrictions."); -+ } -+ -+ memset(sff_8436->data, 0xff, SFF_8436_EEPROM_SIZE); -+ -+ sff_8436->client[0] = client; -+ -+ /* create the sysfs eeprom file */ -+ err = sysfs_create_bin_file(&client->dev.kobj, &sff_8436->bin); -+ if (err) -+ goto err_struct; -+ -+ sff_8436->eeprom_dev = eeprom_device_register(&client->dev, chip.eeprom_data); -+ if (IS_ERR(sff_8436->eeprom_dev)) { -+ dev_err(&client->dev, "error registering eeprom device.\n"); -+ err = PTR_ERR(sff_8436->eeprom_dev); -+ goto err_sysfs_cleanup; -+ } -+ -+ i2c_set_clientdata(client, sff_8436); -+ -+ dev_info(&client->dev, "%zu byte %s EEPROM, %s\n", -+ sff_8436->bin.size, client->name, -+ "read-only"); -+ -+ if (use_smbus == I2C_SMBUS_WORD_DATA || -+ use_smbus == I2C_SMBUS_BYTE_DATA) { -+ dev_notice(&client->dev, "Falling back to %s reads, " -+ "performance will suffer\n", use_smbus == -+ I2C_SMBUS_WORD_DATA ? "word" : "byte"); -+ } -+ -+ if (chip.setup) -+ chip.setup(&sff_8436->macc, chip.context); -+ -+ return 0; -+ -+err_sysfs_cleanup: -+ sysfs_remove_bin_file(&client->dev.kobj, &sff_8436->bin); -+err_struct: -+ kfree(sff_8436->writebuf); -+exit_kfree: -+ kfree(sff_8436); -+exit: -+ dev_dbg(&client->dev, "probe error %d\n", err); -+ -+ return err; -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+static struct i2c_driver sff_8436_driver = { -+ .driver = { -+ .name = "sff8436", -+ .owner = THIS_MODULE, -+ }, -+ .probe = sff_8436_eeprom_probe, -+ .remove = __devexit_p(sff_8436_remove), -+ .id_table = sff8436_ids, -+}; -+ -+static int __init sff_8436_init(void) -+{ -+ if (!io_limit) { -+ pr_err("sff_8436: io_limit must not be 0!\n"); -+ return -EINVAL; -+ } -+ -+ io_limit = rounddown_pow_of_two(io_limit); -+ return i2c_add_driver(&sff_8436_driver); -+} -+module_init(sff_8436_init); -+ -+static void __exit sff_8436_exit(void) -+{ -+ i2c_del_driver(&sff_8436_driver); -+} -+module_exit(sff_8436_exit); -+ -+MODULE_DESCRIPTION("Driver for SFF-8436 based QSFP EEPROMs"); -+MODULE_AUTHOR("VIDYA RAVIPATI "); -+MODULE_LICENSE("GPL"); -diff --git a/include/linux/i2c/sff-8436.h b/include/linux/i2c/sff-8436.h -new file mode 100644 -index 0000000..cd46896 ---- /dev/null -+++ b/include/linux/i2c/sff-8436.h -@@ -0,0 +1,33 @@ -+#ifndef _LINUX_SFF_8436_H -+#define _LINUX_SFF_8436_H -+ -+#include -+#include -+#include -+ -+/* -+ * As seen through Linux I2C, differences between the most common types of I2C -+ * memory include: -+ * - How much memory is available (usually specified in bit)? -+ * - What write page size does it support? -+ * - Special flags (read_only, world readable...)? -+ * -+ * If you set up a custom eeprom type, please double-check the parameters. -+ * Especially page_size needs extra care, as you risk data loss if your value -+ * is bigger than what the chip actually supports! -+ */ -+ -+struct sff_8436_platform_data { -+ u32 byte_len; /* size (sum of all addr) */ -+ u16 page_size; /* for writes */ -+ u8 flags; -+#define SFF_8436_FLAG_READONLY 0x40 /* sysfs-entry will be read-only */ -+#define SFF_8436_FLAG_IRUGO 0x20 /* sysfs-entry will be world-readable */ -+#define SFF_8436_FLAG_TAKE8ADDR 0x10 /* take always 8 addresses (24c00) */ -+ -+ void (*setup)(struct memory_accessor *, void *context); -+ void *context; -+ struct eeprom_platform_data *eeprom_data; /* extra data for the eeprom_class */ -+}; -+ -+#endif /* _LINUX_SFF_8436_H */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-watchdog-itco-wd.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-watchdog-itco-wd.patch deleted file mode 100644 index da449cd7..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/driver-watchdog-itco-wd.patch +++ /dev/null @@ -1,2150 +0,0 @@ -Upgrade to version 1.11 to support more chipsets - -diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c -index bdf401b..0ba1b7c 100644 ---- a/drivers/watchdog/iTCO_wdt.c -+++ b/drivers/watchdog/iTCO_wdt.c -@@ -37,16 +37,18 @@ - * document number TBD : DH89xxCC - * document number TBD : Panther Point - * document number TBD : Lynx Point -+ * document number TBD : Lynx Point-LP - */ - - /* - * Includes, defines, variables, module parameters, ... - */ - -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ - /* Module and version information */ - #define DRV_NAME "iTCO_wdt" --#define DRV_VERSION "1.07" --#define PFX DRV_NAME ": " -+#define DRV_VERSION "1.11" - - /* Includes */ - #include /* For module specific items */ -@@ -54,8 +56,6 @@ - #include /* For standard types (like size_t) */ - #include /* For the -ENODEV/... values */ - #include /* For printk/panic/... */ --#include /* For MODULE_ALIAS_MISCDEV -- (WATCHDOG_MINOR) */ - #include /* For the watchdog specific items */ - #include /* For __init/__exit/... */ - #include /* For file operations */ -@@ -65,316 +65,16 @@ - #include /* For spin_lock/spin_unlock/... */ - #include /* For copy_to_user/put_user/... */ - #include /* For inb/outb/... */ -+#include -+#include - - #include "iTCO_vendor.h" - --/* TCO related info */ --enum iTCO_chipsets { -- TCO_ICH = 0, /* ICH */ -- TCO_ICH0, /* ICH0 */ -- TCO_ICH2, /* ICH2 */ -- TCO_ICH2M, /* ICH2-M */ -- TCO_ICH3, /* ICH3-S */ -- TCO_ICH3M, /* ICH3-M */ -- TCO_ICH4, /* ICH4 */ -- TCO_ICH4M, /* ICH4-M */ -- TCO_CICH, /* C-ICH */ -- TCO_ICH5, /* ICH5 & ICH5R */ -- TCO_6300ESB, /* 6300ESB */ -- TCO_ICH6, /* ICH6 & ICH6R */ -- TCO_ICH6M, /* ICH6-M */ -- TCO_ICH6W, /* ICH6W & ICH6RW */ -- TCO_631XESB, /* 631xESB/632xESB */ -- TCO_ICH7, /* ICH7 & ICH7R */ -- TCO_ICH7DH, /* ICH7DH */ -- TCO_ICH7M, /* ICH7-M & ICH7-U */ -- TCO_ICH7MDH, /* ICH7-M DH */ -- TCO_NM10, /* NM10 */ -- TCO_ICH8, /* ICH8 & ICH8R */ -- TCO_ICH8DH, /* ICH8DH */ -- TCO_ICH8DO, /* ICH8DO */ -- TCO_ICH8M, /* ICH8M */ -- TCO_ICH8ME, /* ICH8M-E */ -- TCO_ICH9, /* ICH9 */ -- TCO_ICH9R, /* ICH9R */ -- TCO_ICH9DH, /* ICH9DH */ -- TCO_ICH9DO, /* ICH9DO */ -- TCO_ICH9M, /* ICH9M */ -- TCO_ICH9ME, /* ICH9M-E */ -- TCO_ICH10, /* ICH10 */ -- TCO_ICH10R, /* ICH10R */ -- TCO_ICH10D, /* ICH10D */ -- TCO_ICH10DO, /* ICH10DO */ -- TCO_PCH, /* PCH Desktop Full Featured */ -- TCO_PCHM, /* PCH Mobile Full Featured */ -- TCO_P55, /* P55 */ -- TCO_PM55, /* PM55 */ -- TCO_H55, /* H55 */ -- TCO_QM57, /* QM57 */ -- TCO_H57, /* H57 */ -- TCO_HM55, /* HM55 */ -- TCO_Q57, /* Q57 */ -- TCO_HM57, /* HM57 */ -- TCO_PCHMSFF, /* PCH Mobile SFF Full Featured */ -- TCO_QS57, /* QS57 */ -- TCO_3400, /* 3400 */ -- TCO_3420, /* 3420 */ -- TCO_3450, /* 3450 */ -- TCO_EP80579, /* EP80579 */ -- TCO_CPT, /* Cougar Point */ -- TCO_CPTD, /* Cougar Point Desktop */ -- TCO_CPTM, /* Cougar Point Mobile */ -- TCO_PBG, /* Patsburg */ -- TCO_DH89XXCC, /* DH89xxCC */ -- TCO_PPT, /* Panther Point */ -- TCO_LPT, /* Lynx Point */ --}; -- --static struct { -- char *name; -- unsigned int iTCO_version; --} iTCO_chipset_info[] __devinitdata = { -- {"ICH", 1}, -- {"ICH0", 1}, -- {"ICH2", 1}, -- {"ICH2-M", 1}, -- {"ICH3-S", 1}, -- {"ICH3-M", 1}, -- {"ICH4", 1}, -- {"ICH4-M", 1}, -- {"C-ICH", 1}, -- {"ICH5 or ICH5R", 1}, -- {"6300ESB", 1}, -- {"ICH6 or ICH6R", 2}, -- {"ICH6-M", 2}, -- {"ICH6W or ICH6RW", 2}, -- {"631xESB/632xESB", 2}, -- {"ICH7 or ICH7R", 2}, -- {"ICH7DH", 2}, -- {"ICH7-M or ICH7-U", 2}, -- {"ICH7-M DH", 2}, -- {"NM10", 2}, -- {"ICH8 or ICH8R", 2}, -- {"ICH8DH", 2}, -- {"ICH8DO", 2}, -- {"ICH8M", 2}, -- {"ICH8M-E", 2}, -- {"ICH9", 2}, -- {"ICH9R", 2}, -- {"ICH9DH", 2}, -- {"ICH9DO", 2}, -- {"ICH9M", 2}, -- {"ICH9M-E", 2}, -- {"ICH10", 2}, -- {"ICH10R", 2}, -- {"ICH10D", 2}, -- {"ICH10DO", 2}, -- {"PCH Desktop Full Featured", 2}, -- {"PCH Mobile Full Featured", 2}, -- {"P55", 2}, -- {"PM55", 2}, -- {"H55", 2}, -- {"QM57", 2}, -- {"H57", 2}, -- {"HM55", 2}, -- {"Q57", 2}, -- {"HM57", 2}, -- {"PCH Mobile SFF Full Featured", 2}, -- {"QS57", 2}, -- {"3400", 2}, -- {"3420", 2}, -- {"3450", 2}, -- {"EP80579", 2}, -- {"Cougar Point", 2}, -- {"Cougar Point Desktop", 2}, -- {"Cougar Point Mobile", 2}, -- {"Patsburg", 2}, -- {"DH89xxCC", 2}, -- {"Panther Point", 2}, -- {"Lynx Point", 2}, -- {NULL, 0} --}; -- --/* -- * This data only exists for exporting the supported PCI ids -- * via MODULE_DEVICE_TABLE. We do not actually register a -- * pci_driver, because the I/O Controller Hub has also other -- * functions that probably will be registered by other drivers. -- */ --static DEFINE_PCI_DEVICE_TABLE(iTCO_wdt_pci_tbl) = { -- { PCI_VDEVICE(INTEL, 0x2410), TCO_ICH}, -- { PCI_VDEVICE(INTEL, 0x2420), TCO_ICH0}, -- { PCI_VDEVICE(INTEL, 0x2440), TCO_ICH2}, -- { PCI_VDEVICE(INTEL, 0x244c), TCO_ICH2M}, -- { PCI_VDEVICE(INTEL, 0x2480), TCO_ICH3}, -- { PCI_VDEVICE(INTEL, 0x248c), TCO_ICH3M}, -- { PCI_VDEVICE(INTEL, 0x24c0), TCO_ICH4}, -- { PCI_VDEVICE(INTEL, 0x24cc), TCO_ICH4M}, -- { PCI_VDEVICE(INTEL, 0x2450), TCO_CICH}, -- { PCI_VDEVICE(INTEL, 0x24d0), TCO_ICH5}, -- { PCI_VDEVICE(INTEL, 0x25a1), TCO_6300ESB}, -- { PCI_VDEVICE(INTEL, 0x2640), TCO_ICH6}, -- { PCI_VDEVICE(INTEL, 0x2641), TCO_ICH6M}, -- { PCI_VDEVICE(INTEL, 0x2642), TCO_ICH6W}, -- { PCI_VDEVICE(INTEL, 0x2670), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x2671), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x2672), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x2673), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x2674), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x2675), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x2676), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x2677), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x2678), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x2679), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x267a), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x267b), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x267c), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x267d), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x267e), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x267f), TCO_631XESB}, -- { PCI_VDEVICE(INTEL, 0x27b8), TCO_ICH7}, -- { PCI_VDEVICE(INTEL, 0x27b0), TCO_ICH7DH}, -- { PCI_VDEVICE(INTEL, 0x27b9), TCO_ICH7M}, -- { PCI_VDEVICE(INTEL, 0x27bd), TCO_ICH7MDH}, -- { PCI_VDEVICE(INTEL, 0x27bc), TCO_NM10}, -- { PCI_VDEVICE(INTEL, 0x2810), TCO_ICH8}, -- { PCI_VDEVICE(INTEL, 0x2812), TCO_ICH8DH}, -- { PCI_VDEVICE(INTEL, 0x2814), TCO_ICH8DO}, -- { PCI_VDEVICE(INTEL, 0x2815), TCO_ICH8M}, -- { PCI_VDEVICE(INTEL, 0x2811), TCO_ICH8ME}, -- { PCI_VDEVICE(INTEL, 0x2918), TCO_ICH9}, -- { PCI_VDEVICE(INTEL, 0x2916), TCO_ICH9R}, -- { PCI_VDEVICE(INTEL, 0x2912), TCO_ICH9DH}, -- { PCI_VDEVICE(INTEL, 0x2914), TCO_ICH9DO}, -- { PCI_VDEVICE(INTEL, 0x2919), TCO_ICH9M}, -- { PCI_VDEVICE(INTEL, 0x2917), TCO_ICH9ME}, -- { PCI_VDEVICE(INTEL, 0x3a18), TCO_ICH10}, -- { PCI_VDEVICE(INTEL, 0x3a16), TCO_ICH10R}, -- { PCI_VDEVICE(INTEL, 0x3a1a), TCO_ICH10D}, -- { PCI_VDEVICE(INTEL, 0x3a14), TCO_ICH10DO}, -- { PCI_VDEVICE(INTEL, 0x3b00), TCO_PCH}, -- { PCI_VDEVICE(INTEL, 0x3b01), TCO_PCHM}, -- { PCI_VDEVICE(INTEL, 0x3b02), TCO_P55}, -- { PCI_VDEVICE(INTEL, 0x3b03), TCO_PM55}, -- { PCI_VDEVICE(INTEL, 0x3b06), TCO_H55}, -- { PCI_VDEVICE(INTEL, 0x3b07), TCO_QM57}, -- { PCI_VDEVICE(INTEL, 0x3b08), TCO_H57}, -- { PCI_VDEVICE(INTEL, 0x3b09), TCO_HM55}, -- { PCI_VDEVICE(INTEL, 0x3b0a), TCO_Q57}, -- { PCI_VDEVICE(INTEL, 0x3b0b), TCO_HM57}, -- { PCI_VDEVICE(INTEL, 0x3b0d), TCO_PCHMSFF}, -- { PCI_VDEVICE(INTEL, 0x3b0f), TCO_QS57}, -- { PCI_VDEVICE(INTEL, 0x3b12), TCO_3400}, -- { PCI_VDEVICE(INTEL, 0x3b14), TCO_3420}, -- { PCI_VDEVICE(INTEL, 0x3b16), TCO_3450}, -- { PCI_VDEVICE(INTEL, 0x5031), TCO_EP80579}, -- { PCI_VDEVICE(INTEL, 0x1c41), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c42), TCO_CPTD}, -- { PCI_VDEVICE(INTEL, 0x1c43), TCO_CPTM}, -- { PCI_VDEVICE(INTEL, 0x1c44), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c45), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c46), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c47), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c48), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c49), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c4a), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c4b), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c4c), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c4d), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c4e), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c4f), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c50), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c51), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c52), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c53), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c54), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c55), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c56), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c57), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c58), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c59), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c5a), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c5b), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c5c), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c5d), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c5e), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1c5f), TCO_CPT}, -- { PCI_VDEVICE(INTEL, 0x1d40), TCO_PBG}, -- { PCI_VDEVICE(INTEL, 0x1d41), TCO_PBG}, -- { PCI_VDEVICE(INTEL, 0x2310), TCO_DH89XXCC}, -- { PCI_VDEVICE(INTEL, 0x1e40), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e41), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e42), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e43), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e44), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e45), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e46), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e47), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e48), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e49), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e4a), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e4b), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e4c), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e4d), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e4e), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e4f), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e50), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e51), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e52), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e53), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e54), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e55), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e56), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e57), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e58), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e59), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e5a), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e5b), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e5c), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e5d), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e5e), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x1e5f), TCO_PPT}, -- { PCI_VDEVICE(INTEL, 0x8c40), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c41), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c42), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c43), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c44), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c45), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c46), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c47), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c48), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c49), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c4a), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c4b), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c4c), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c4d), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c4e), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c4f), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c50), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c51), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c52), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c53), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c54), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c55), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c56), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c57), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c58), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c59), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c5a), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c5b), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c5c), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c5d), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c5e), TCO_LPT}, -- { PCI_VDEVICE(INTEL, 0x8c5f), TCO_LPT}, -- { 0, }, /* End of list */ --}; --MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); -- - /* Address definitions for the TCO */ - /* TCO base address */ --#define TCOBASE (iTCO_wdt_private.ACPIBASE + 0x60) -+#define TCOBASE (iTCO_wdt_private.tco_res->start) - /* SMI Control and Enable Register */ --#define SMI_EN (iTCO_wdt_private.ACPIBASE + 0x30) -+#define SMI_EN (iTCO_wdt_private.smi_res->start) - - #define TCO_RLD (TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */ - #define TCOv1_TMR (TCOBASE + 0x01) /* TCOv1 Timer Initial Value */ -@@ -387,34 +87,34 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); - #define TCOv2_TMR (TCOBASE + 0x12) /* TCOv2 Timer Initial Value */ - - /* internal variables */ --static unsigned long is_active; --static char expect_release; - static struct { /* this is private data for the iTCO_wdt device */ - /* TCO version/generation */ - unsigned int iTCO_version; -- /* The device's ACPIBASE address (TCOBASE = ACPIBASE+0x60) */ -- unsigned long ACPIBASE; -- /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/ -- unsigned long __iomem *gcs; -+ struct resource *tco_res; -+ struct resource *smi_res; -+ /* -+ * NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2), -+ * or memory-mapped PMC register bit 4 (TCO version 3). -+ */ -+ struct resource *gcs_pmc_res; -+ unsigned long __iomem *gcs_pmc; - /* the lock for io operations */ - spinlock_t io_lock; -+ struct platform_device *dev; - /* the PCI-device */ - struct pci_dev *pdev; - } iTCO_wdt_private; - --/* the watchdog platform device */ --static struct platform_device *iTCO_wdt_platform_device; -- - /* module parameters */ --#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ --static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ -+#define WATCHDOG_TIMEOUT 30 /* 30 sec default heartbeat */ -+static int heartbeat = WATCHDOG_TIMEOUT; /* in seconds */ - module_param(heartbeat, int, 0); - MODULE_PARM_DESC(heartbeat, "Watchdog timeout in seconds. " - "5..76 (TCO v1) or 3..614 (TCO v2), default=" -- __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); -+ __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); - --static int nowayout = WATCHDOG_NOWAYOUT; --module_param(nowayout, int, 0); -+static bool nowayout = WATCHDOG_NOWAYOUT; -+module_param(nowayout, bool, 0); - MODULE_PARM_DESC(nowayout, - "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -@@ -428,11 +128,19 @@ MODULE_PARM_DESC(turn_SMI_watchdog_clear_off, - * Some TCO specific functions - */ - --static inline unsigned int seconds_to_ticks(int seconds) -+/* -+ * The iTCO v1 and v2's internal timer is stored as ticks which decrement -+ * every 0.6 seconds. v3's internal timer is stored as seconds (some -+ * datasheets incorrectly state 0.6 seconds). -+ */ -+static inline unsigned int seconds_to_ticks(int secs) - { -- /* the internal timer is stored as ticks which decrement -- * every 0.6 seconds */ -- return (seconds * 10) / 6; -+ return iTCO_wdt_private.iTCO_version == 3 ? secs : (secs * 10) / 6; -+} -+ -+static inline unsigned int ticks_to_seconds(int ticks) -+{ -+ return iTCO_wdt_private.iTCO_version == 3 ? ticks : (ticks * 6) / 10; - } - - static void iTCO_wdt_set_NO_REBOOT_bit(void) -@@ -440,10 +148,14 @@ static void iTCO_wdt_set_NO_REBOOT_bit(void) - u32 val32; - - /* Set the NO_REBOOT bit: this disables reboots */ -- if (iTCO_wdt_private.iTCO_version == 2) { -- val32 = readl(iTCO_wdt_private.gcs); -+ if (iTCO_wdt_private.iTCO_version == 3) { -+ val32 = readl(iTCO_wdt_private.gcs_pmc); -+ val32 |= 0x00000010; -+ writel(val32, iTCO_wdt_private.gcs_pmc); -+ } else if (iTCO_wdt_private.iTCO_version == 2) { -+ val32 = readl(iTCO_wdt_private.gcs_pmc); - val32 |= 0x00000020; -- writel(val32, iTCO_wdt_private.gcs); -+ writel(val32, iTCO_wdt_private.gcs_pmc); - } else if (iTCO_wdt_private.iTCO_version == 1) { - pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32); - val32 |= 0x00000002; -@@ -457,12 +169,20 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(void) - u32 val32; - - /* Unset the NO_REBOOT bit: this enables reboots */ -- if (iTCO_wdt_private.iTCO_version == 2) { -- val32 = readl(iTCO_wdt_private.gcs); -+ if (iTCO_wdt_private.iTCO_version == 3) { -+ val32 = readl(iTCO_wdt_private.gcs_pmc); -+ val32 &= 0xffffffef; -+ writel(val32, iTCO_wdt_private.gcs_pmc); -+ -+ val32 = readl(iTCO_wdt_private.gcs_pmc); -+ if (val32 & 0x00000010) -+ ret = -EIO; -+ } else if (iTCO_wdt_private.iTCO_version == 2) { -+ val32 = readl(iTCO_wdt_private.gcs_pmc); - val32 &= 0xffffffdf; -- writel(val32, iTCO_wdt_private.gcs); -+ writel(val32, iTCO_wdt_private.gcs_pmc); - -- val32 = readl(iTCO_wdt_private.gcs); -+ val32 = readl(iTCO_wdt_private.gcs_pmc); - if (val32 & 0x00000020) - ret = -EIO; - } else if (iTCO_wdt_private.iTCO_version == 1) { -@@ -478,25 +198,24 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(void) - return ret; /* returns: 0 = OK, -EIO = Error */ - } - --static int iTCO_wdt_start(void) -+static int iTCO_wdt_start(struct watchdog_device *wd_dev) - { - unsigned int val; - - spin_lock(&iTCO_wdt_private.io_lock); - -- iTCO_vendor_pre_start(iTCO_wdt_private.ACPIBASE, heartbeat); -+ iTCO_vendor_pre_start(iTCO_wdt_private.smi_res, wd_dev->timeout); - - /* disable chipset's NO_REBOOT bit */ - if (iTCO_wdt_unset_NO_REBOOT_bit()) { - spin_unlock(&iTCO_wdt_private.io_lock); -- printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " -- "reboot disabled by hardware/BIOS\n"); -+ pr_err("failed to reset NO_REBOOT flag, reboot disabled by hardware/BIOS\n"); - return -EIO; - } - - /* Force the timer to its reload value by writing to the TCO_RLD - register */ -- if (iTCO_wdt_private.iTCO_version == 2) -+ if (iTCO_wdt_private.iTCO_version >= 2) - outw(0x01, TCO_RLD); - else if (iTCO_wdt_private.iTCO_version == 1) - outb(0x01, TCO_RLD); -@@ -513,13 +232,13 @@ static int iTCO_wdt_start(void) - return 0; - } - --static int iTCO_wdt_stop(void) -+static int iTCO_wdt_stop(struct watchdog_device *wd_dev) - { - unsigned int val; - - spin_lock(&iTCO_wdt_private.io_lock); - -- iTCO_vendor_pre_stop(iTCO_wdt_private.ACPIBASE); -+ iTCO_vendor_pre_stop(iTCO_wdt_private.smi_res); - - /* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */ - val = inw(TCO1_CNT); -@@ -537,16 +256,16 @@ static int iTCO_wdt_stop(void) - return 0; - } - --static int iTCO_wdt_keepalive(void) -+static int iTCO_wdt_ping(struct watchdog_device *wd_dev) - { - spin_lock(&iTCO_wdt_private.io_lock); - -- iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat); -+ iTCO_vendor_pre_keepalive(iTCO_wdt_private.smi_res, wd_dev->timeout); - - /* Reload the timer by writing to the TCO Timer Counter register */ -- if (iTCO_wdt_private.iTCO_version == 2) -+ if (iTCO_wdt_private.iTCO_version >= 2) { - outw(0x01, TCO_RLD); -- else if (iTCO_wdt_private.iTCO_version == 1) { -+ } else if (iTCO_wdt_private.iTCO_version == 1) { - /* Reset the timeout status bit so that the timer - * needs to count down twice again before rebooting */ - outw(0x0008, TCO1_STS); /* write 1 to clear bit */ -@@ -558,7 +277,7 @@ static int iTCO_wdt_keepalive(void) - return 0; - } - --static int iTCO_wdt_set_heartbeat(int t) -+static int iTCO_wdt_set_timeout(struct watchdog_device *wd_dev, unsigned int t) - { - unsigned int val16; - unsigned char val8; -@@ -574,14 +293,14 @@ static int iTCO_wdt_set_heartbeat(int t) - /* "Values of 0h-3h are ignored and should not be attempted" */ - if (tmrval < 0x04) - return -EINVAL; -- if (((iTCO_wdt_private.iTCO_version == 2) && (tmrval > 0x3ff)) || -+ if (((iTCO_wdt_private.iTCO_version >= 2) && (tmrval > 0x3ff)) || - ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f))) - return -EINVAL; - - iTCO_vendor_pre_set_heartbeat(tmrval); - - /* Write new heartbeat to watchdog */ -- if (iTCO_wdt_private.iTCO_version == 2) { -+ if (iTCO_wdt_private.iTCO_version >= 2) { - spin_lock(&iTCO_wdt_private.io_lock); - val16 = inw(TCOv2_TMR); - val16 &= 0xfc00; -@@ -605,23 +324,24 @@ static int iTCO_wdt_set_heartbeat(int t) - return -EINVAL; - } - -- heartbeat = t; -+ wd_dev->timeout = t; - return 0; - } - --static int iTCO_wdt_get_timeleft(int *time_left) -+static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev) - { - unsigned int val16; - unsigned char val8; -+ unsigned int time_left = 0; - - /* read the TCO Timer */ -- if (iTCO_wdt_private.iTCO_version == 2) { -+ if (iTCO_wdt_private.iTCO_version >= 2) { - spin_lock(&iTCO_wdt_private.io_lock); - val16 = inw(TCO_RLD); - val16 &= 0x3ff; - spin_unlock(&iTCO_wdt_private.io_lock); - -- *time_left = (val16 * 6) / 10; -+ time_left = ticks_to_seconds(val16); - } else if (iTCO_wdt_private.iTCO_version == 1) { - spin_lock(&iTCO_wdt_private.io_lock); - val8 = inb(TCO_RLD); -@@ -630,331 +350,217 @@ static int iTCO_wdt_get_timeleft(int *time_left) - val8 += (inb(TCOv1_TMR) & 0x3f); - spin_unlock(&iTCO_wdt_private.io_lock); - -- *time_left = (val8 * 6) / 10; -- } else -- return -EINVAL; -- return 0; -+ time_left = ticks_to_seconds(val8); -+ } -+ return time_left; - } - - /* -- * /dev/watchdog handling -+ * Kernel Interfaces - */ - --static int iTCO_wdt_open(struct inode *inode, struct file *file) --{ -- /* /dev/watchdog can only be opened once */ -- if (test_and_set_bit(0, &is_active)) -- return -EBUSY; -+static const struct watchdog_info ident = { -+ .options = WDIOF_SETTIMEOUT | -+ WDIOF_KEEPALIVEPING | -+ WDIOF_MAGICCLOSE, -+ .firmware_version = 0, -+ .identity = DRV_NAME, -+}; - -- /* -- * Reload and activate timer -- */ -- iTCO_wdt_start(); -- return nonseekable_open(inode, file); --} -+static const struct watchdog_ops iTCO_wdt_ops = { -+ .owner = THIS_MODULE, -+ .start = iTCO_wdt_start, -+ .stop = iTCO_wdt_stop, -+ .ping = iTCO_wdt_ping, -+ .set_timeout = iTCO_wdt_set_timeout, -+ .get_timeleft = iTCO_wdt_get_timeleft, -+}; - --static int iTCO_wdt_release(struct inode *inode, struct file *file) --{ -- /* -- * Shut off the timer. -- */ -- if (expect_release == 42) { -- iTCO_wdt_stop(); -- } else { -- printk(KERN_CRIT PFX -- "Unexpected close, not stopping watchdog!\n"); -- iTCO_wdt_keepalive(); -- } -- clear_bit(0, &is_active); -- expect_release = 0; -- return 0; --} -+static struct watchdog_device iTCO_wdt_watchdog_dev = { -+ .info = &ident, -+ .ops = &iTCO_wdt_ops, -+}; - --static ssize_t iTCO_wdt_write(struct file *file, const char __user *data, -- size_t len, loff_t *ppos) -+/* -+ * Init & exit routines -+ */ -+ -+static void iTCO_wdt_cleanup(void) - { -- /* See if we got the magic character 'V' and reload the timer */ -- if (len) { -- if (!nowayout) { -- size_t i; -- -- /* note: just in case someone wrote the magic -- character five months ago... */ -- expect_release = 0; -- -- /* scan to see whether or not we got the -- magic character */ -- for (i = 0; i != len; i++) { -- char c; -- if (get_user(c, data + i)) -- return -EFAULT; -- if (c == 'V') -- expect_release = 42; -- } -- } -+ /* Stop the timer before we leave */ -+ if (!nowayout) -+ iTCO_wdt_stop(&iTCO_wdt_watchdog_dev); - -- /* someone wrote to us, we should reload the timer */ -- iTCO_wdt_keepalive(); -+ /* Deregister */ -+ watchdog_unregister_device(&iTCO_wdt_watchdog_dev); -+ -+ /* release resources */ -+ release_region(iTCO_wdt_private.tco_res->start, -+ resource_size(iTCO_wdt_private.tco_res)); -+ release_region(iTCO_wdt_private.smi_res->start, -+ resource_size(iTCO_wdt_private.smi_res)); -+ if (iTCO_wdt_private.iTCO_version >= 2) { -+ iounmap(iTCO_wdt_private.gcs_pmc); -+ release_mem_region(iTCO_wdt_private.gcs_pmc_res->start, -+ resource_size(iTCO_wdt_private.gcs_pmc_res)); - } -- return len; -+ -+ iTCO_wdt_private.tco_res = NULL; -+ iTCO_wdt_private.smi_res = NULL; -+ iTCO_wdt_private.gcs_pmc_res = NULL; -+ iTCO_wdt_private.gcs_pmc = NULL; - } - --static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd, -- unsigned long arg) -+static int iTCO_wdt_probe(struct platform_device *dev) - { -- int new_options, retval = -EINVAL; -- int new_heartbeat; -- void __user *argp = (void __user *)arg; -- int __user *p = argp; -- static const struct watchdog_info ident = { -- .options = WDIOF_SETTIMEOUT | -- WDIOF_KEEPALIVEPING | -- WDIOF_MAGICCLOSE, -- .firmware_version = 0, -- .identity = DRV_NAME, -- }; -- -- switch (cmd) { -- case WDIOC_GETSUPPORT: -- return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; -- case WDIOC_GETSTATUS: -- case WDIOC_GETBOOTSTATUS: -- return put_user(0, p); -- -- case WDIOC_SETOPTIONS: -- { -- if (get_user(new_options, p)) -- return -EFAULT; -- -- if (new_options & WDIOS_DISABLECARD) { -- iTCO_wdt_stop(); -- retval = 0; -- } -- if (new_options & WDIOS_ENABLECARD) { -- iTCO_wdt_keepalive(); -- iTCO_wdt_start(); -- retval = 0; -- } -- return retval; -- } -- case WDIOC_KEEPALIVE: -- iTCO_wdt_keepalive(); -- return 0; -- -- case WDIOC_SETTIMEOUT: -- { -- if (get_user(new_heartbeat, p)) -- return -EFAULT; -- if (iTCO_wdt_set_heartbeat(new_heartbeat)) -- return -EINVAL; -- iTCO_wdt_keepalive(); -- /* Fall */ -- } -- case WDIOC_GETTIMEOUT: -- return put_user(heartbeat, p); -- case WDIOC_GETTIMELEFT: -- { -- int time_left; -- if (iTCO_wdt_get_timeleft(&time_left)) -- return -EINVAL; -- return put_user(time_left, p); -- } -- default: -- return -ENOTTY; -- } --} -+ int ret = -ENODEV; -+ unsigned long val32; -+ struct lpc_ich_info *ich_info = dev_get_platdata(&dev->dev); - --/* -- * Kernel Interfaces -- */ -+ if (!ich_info) -+ goto out; - --static const struct file_operations iTCO_wdt_fops = { -- .owner = THIS_MODULE, -- .llseek = no_llseek, -- .write = iTCO_wdt_write, -- .unlocked_ioctl = iTCO_wdt_ioctl, -- .open = iTCO_wdt_open, -- .release = iTCO_wdt_release, --}; -+ spin_lock_init(&iTCO_wdt_private.io_lock); - --static struct miscdevice iTCO_wdt_miscdev = { -- .minor = WATCHDOG_MINOR, -- .name = "watchdog", -- .fops = &iTCO_wdt_fops, --}; -+ iTCO_wdt_private.tco_res = -+ platform_get_resource(dev, IORESOURCE_IO, ICH_RES_IO_TCO); -+ if (!iTCO_wdt_private.tco_res) -+ goto out; - --/* -- * Init & exit routines -- */ -+ iTCO_wdt_private.smi_res = -+ platform_get_resource(dev, IORESOURCE_IO, ICH_RES_IO_SMI); -+ if (!iTCO_wdt_private.smi_res) -+ goto out; - --static int __devinit iTCO_wdt_init(struct pci_dev *pdev, -- const struct pci_device_id *ent, struct platform_device *dev) --{ -- int ret; -- u32 base_address; -- unsigned long RCBA; -- unsigned long val32; -+ iTCO_wdt_private.iTCO_version = ich_info->iTCO_version; -+ iTCO_wdt_private.dev = dev; -+ iTCO_wdt_private.pdev = to_pci_dev(dev->dev.parent); - - /* -- * Find the ACPI/PM base I/O address which is the base -- * for the TCO registers (TCOBASE=ACPIBASE + 0x60) -- * ACPIBASE is bits [15:7] from 0x40-0x43 -+ * Get the Memory-Mapped GCS or PMC register, we need it for the -+ * NO_REBOOT flag (TCO v2 and v3). - */ -- pci_read_config_dword(pdev, 0x40, &base_address); -- base_address &= 0x0000ff80; -- if (base_address == 0x00000000) { -- /* Something's wrong here, ACPIBASE has to be set */ -- printk(KERN_ERR PFX "failed to get TCOBASE address, " -- "device disabled by hardware/BIOS\n"); -- return -ENODEV; -- } -- iTCO_wdt_private.iTCO_version = -- iTCO_chipset_info[ent->driver_data].iTCO_version; -- iTCO_wdt_private.ACPIBASE = base_address; -- iTCO_wdt_private.pdev = pdev; -- -- /* Get the Memory-Mapped GCS register, we need it for the -- NO_REBOOT flag (TCO v2). To get access to it you have to -- read RCBA from PCI Config space 0xf0 and use it as base. -- GCS = RCBA + ICH6_GCS(0x3410). */ -- if (iTCO_wdt_private.iTCO_version == 2) { -- pci_read_config_dword(pdev, 0xf0, &base_address); -- if ((base_address & 1) == 0) { -- printk(KERN_ERR PFX "RCBA is disabled by hardware" -- "/BIOS, device disabled\n"); -- ret = -ENODEV; -+ if (iTCO_wdt_private.iTCO_version >= 2) { -+ iTCO_wdt_private.gcs_pmc_res = platform_get_resource(dev, -+ IORESOURCE_MEM, -+ ICH_RES_MEM_GCS_PMC); -+ -+ if (!iTCO_wdt_private.gcs_pmc_res) -+ goto out; -+ -+ if (!request_mem_region(iTCO_wdt_private.gcs_pmc_res->start, -+ resource_size(iTCO_wdt_private.gcs_pmc_res), dev->name)) { -+ ret = -EBUSY; - goto out; - } -- RCBA = base_address & 0xffffc000; -- iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4); -+ iTCO_wdt_private.gcs_pmc = ioremap(iTCO_wdt_private.gcs_pmc_res->start, -+ resource_size(iTCO_wdt_private.gcs_pmc_res)); -+ if (!iTCO_wdt_private.gcs_pmc) { -+ ret = -EIO; -+ goto unreg_gcs_pmc; -+ } - } - - /* Check chipset's NO_REBOOT bit */ - if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { -- printk(KERN_INFO PFX "unable to reset NO_REBOOT flag, " -- "device disabled by hardware/BIOS\n"); -+ pr_info("unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n"); - ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ -- goto out_unmap; -+ goto unmap_gcs_pmc; - } - - /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ - iTCO_wdt_set_NO_REBOOT_bit(); - - /* The TCO logic uses the TCO_EN bit in the SMI_EN register */ -- if (!request_region(SMI_EN, 4, "iTCO_wdt")) { -- printk(KERN_ERR PFX -- "I/O address 0x%04lx already in use, " -- "device disabled\n", SMI_EN); -- ret = -EIO; -- goto out_unmap; -+ if (!request_region(iTCO_wdt_private.smi_res->start, -+ resource_size(iTCO_wdt_private.smi_res), dev->name)) { -+ pr_err("I/O address 0x%04llx already in use, device disabled\n", -+ (u64)SMI_EN); -+ ret = -EBUSY; -+ goto unmap_gcs_pmc; - } - if (turn_SMI_watchdog_clear_off >= iTCO_wdt_private.iTCO_version) { -- /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ -+ /* -+ * Bit 13: TCO_EN -> 0 -+ * Disables TCO logic generating an SMI# -+ */ - val32 = inl(SMI_EN); - val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ - outl(val32, SMI_EN); - } - -- /* The TCO I/O registers reside in a 32-byte range pointed to -- by the TCOBASE value */ -- if (!request_region(TCOBASE, 0x20, "iTCO_wdt")) { -- printk(KERN_ERR PFX "I/O address 0x%04lx already in use " -- "device disabled\n", TCOBASE); -- ret = -EIO; -- goto unreg_smi_en; -+ if (!request_region(iTCO_wdt_private.tco_res->start, -+ resource_size(iTCO_wdt_private.tco_res), dev->name)) { -+ pr_err("I/O address 0x%04llx already in use, device disabled\n", -+ (u64)TCOBASE); -+ ret = -EBUSY; -+ goto unreg_smi; - } - -- printk(KERN_INFO PFX -- "Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n", -- iTCO_chipset_info[ent->driver_data].name, -- iTCO_chipset_info[ent->driver_data].iTCO_version, -- TCOBASE); -+ pr_info("Found a %s TCO device (Version=%d, TCOBASE=0x%04llx)\n", -+ ich_info->name, ich_info->iTCO_version, (u64)TCOBASE); - - /* Clear out the (probably old) status */ -- outw(0x0008, TCO1_STS); /* Clear the Time Out Status bit */ -- outw(0x0002, TCO2_STS); /* Clear SECOND_TO_STS bit */ -- outw(0x0004, TCO2_STS); /* Clear BOOT_STS bit */ -+ if (iTCO_wdt_private.iTCO_version == 3) { -+ outl(0x20008, TCO1_STS); -+ } else { -+ outw(0x0008, TCO1_STS); /* Clear the Time Out Status bit */ -+ outw(0x0002, TCO2_STS); /* Clear SECOND_TO_STS bit */ -+ outw(0x0004, TCO2_STS); /* Clear BOOT_STS bit */ -+ } -+ -+ iTCO_wdt_watchdog_dev.bootstatus = 0; -+ iTCO_wdt_watchdog_dev.timeout = WATCHDOG_TIMEOUT; -+ watchdog_set_nowayout(&iTCO_wdt_watchdog_dev, nowayout); -+ iTCO_wdt_watchdog_dev.parent = &dev->dev; - - /* Make sure the watchdog is not running */ -- iTCO_wdt_stop(); -+ iTCO_wdt_stop(&iTCO_wdt_watchdog_dev); - - /* Check that the heartbeat value is within it's range; - if not reset to the default */ -- if (iTCO_wdt_set_heartbeat(heartbeat)) { -- iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT); -- printk(KERN_INFO PFX -- "timeout value out of range, using %d\n", heartbeat); -+ if (iTCO_wdt_set_timeout(&iTCO_wdt_watchdog_dev, heartbeat)) { -+ iTCO_wdt_set_timeout(&iTCO_wdt_watchdog_dev, WATCHDOG_TIMEOUT); -+ pr_info("timeout value out of range, using %d\n", -+ WATCHDOG_TIMEOUT); - } - -- ret = misc_register(&iTCO_wdt_miscdev); -+ ret = watchdog_register_device(&iTCO_wdt_watchdog_dev); - if (ret != 0) { -- printk(KERN_ERR PFX -- "cannot register miscdev on minor=%d (err=%d)\n", -- WATCHDOG_MINOR, ret); -- goto unreg_region; -+ pr_err("cannot register watchdog device (err=%d)\n", ret); -+ goto unreg_tco; - } - -- printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", -- heartbeat, nowayout); -+ pr_info("initialized. heartbeat=%d sec (nowayout=%d)\n", -+ heartbeat, nowayout); - - return 0; - --unreg_region: -- release_region(TCOBASE, 0x20); --unreg_smi_en: -- release_region(SMI_EN, 4); --out_unmap: -- if (iTCO_wdt_private.iTCO_version == 2) -- iounmap(iTCO_wdt_private.gcs); -+unreg_tco: -+ release_region(iTCO_wdt_private.tco_res->start, -+ resource_size(iTCO_wdt_private.tco_res)); -+unreg_smi: -+ release_region(iTCO_wdt_private.smi_res->start, -+ resource_size(iTCO_wdt_private.smi_res)); -+unmap_gcs_pmc: -+ if (iTCO_wdt_private.iTCO_version >= 2) -+ iounmap(iTCO_wdt_private.gcs_pmc); -+unreg_gcs_pmc: -+ if (iTCO_wdt_private.iTCO_version >= 2) -+ release_mem_region(iTCO_wdt_private.gcs_pmc_res->start, -+ resource_size(iTCO_wdt_private.gcs_pmc_res)); - out: -- iTCO_wdt_private.ACPIBASE = 0; -- return ret; --} -- --static void __devexit iTCO_wdt_cleanup(void) --{ -- /* Stop the timer before we leave */ -- if (!nowayout) -- iTCO_wdt_stop(); -- -- /* Deregister */ -- misc_deregister(&iTCO_wdt_miscdev); -- release_region(TCOBASE, 0x20); -- release_region(SMI_EN, 4); -- if (iTCO_wdt_private.iTCO_version == 2) -- iounmap(iTCO_wdt_private.gcs); -- pci_dev_put(iTCO_wdt_private.pdev); -- iTCO_wdt_private.ACPIBASE = 0; --} -- --static int __devinit iTCO_wdt_probe(struct platform_device *dev) --{ -- int ret = -ENODEV; -- int found = 0; -- struct pci_dev *pdev = NULL; -- const struct pci_device_id *ent; -- -- spin_lock_init(&iTCO_wdt_private.io_lock); -- -- for_each_pci_dev(pdev) { -- ent = pci_match_id(iTCO_wdt_pci_tbl, pdev); -- if (ent) { -- found++; -- ret = iTCO_wdt_init(pdev, ent, dev); -- if (!ret) -- break; -- } -- } -- -- if (!found) -- printk(KERN_INFO PFX "No device detected.\n"); -+ iTCO_wdt_private.tco_res = NULL; -+ iTCO_wdt_private.smi_res = NULL; -+ iTCO_wdt_private.gcs_pmc_res = NULL; -+ iTCO_wdt_private.gcs_pmc = NULL; - - return ret; - } - --static int __devexit iTCO_wdt_remove(struct platform_device *dev) -+static int iTCO_wdt_remove(struct platform_device *dev) - { -- if (iTCO_wdt_private.ACPIBASE) -+ if (iTCO_wdt_private.tco_res || iTCO_wdt_private.smi_res) - iTCO_wdt_cleanup(); - - return 0; -@@ -962,12 +568,12 @@ static int __devexit iTCO_wdt_remove(struct platform_device *dev) - - static void iTCO_wdt_shutdown(struct platform_device *dev) - { -- iTCO_wdt_stop(); -+ iTCO_wdt_stop(NULL); - } - - static struct platform_driver iTCO_wdt_driver = { - .probe = iTCO_wdt_probe, -- .remove = __devexit_p(iTCO_wdt_remove), -+ .remove = iTCO_wdt_remove, - .shutdown = iTCO_wdt_shutdown, - .driver = { - .owner = THIS_MODULE, -@@ -979,32 +585,19 @@ static int __init iTCO_wdt_init_module(void) - { - int err; - -- printk(KERN_INFO PFX "Intel TCO WatchDog Timer Driver v%s\n", -- DRV_VERSION); -+ pr_info("Intel TCO WatchDog Timer Driver v%s\n", DRV_VERSION); - - err = platform_driver_register(&iTCO_wdt_driver); - if (err) - return err; - -- iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME, -- -1, NULL, 0); -- if (IS_ERR(iTCO_wdt_platform_device)) { -- err = PTR_ERR(iTCO_wdt_platform_device); -- goto unreg_platform_driver; -- } -- - return 0; -- --unreg_platform_driver: -- platform_driver_unregister(&iTCO_wdt_driver); -- return err; - } - - static void __exit iTCO_wdt_cleanup_module(void) - { -- platform_device_unregister(iTCO_wdt_platform_device); - platform_driver_unregister(&iTCO_wdt_driver); -- printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); -+ pr_info("Watchdog Module Unloaded\n"); - } - - module_init(iTCO_wdt_init_module); -@@ -1014,4 +607,4 @@ MODULE_AUTHOR("Wim Van Sebroeck "); - MODULE_DESCRIPTION("Intel TCO WatchDog Timer Driver"); - MODULE_VERSION(DRV_VERSION); - MODULE_LICENSE("GPL"); --MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -+MODULE_ALIAS("platform:" DRV_NAME); -diff --git a/drivers/watchdog/watchdog_core.h b/drivers/watchdog/watchdog_core.h -new file mode 100644 -index 0000000..6c95141 ---- /dev/null -+++ b/drivers/watchdog/watchdog_core.h -@@ -0,0 +1,37 @@ -+/* -+ * watchdog_core.h -+ * -+ * (c) Copyright 2008-2011 Alan Cox , -+ * All Rights Reserved. -+ * -+ * (c) Copyright 2008-2011 Wim Van Sebroeck . -+ * -+ * This source code is part of the generic code that can be used -+ * by all the watchdog timer drivers. -+ * -+ * Based on source code of the following authors: -+ * Matt Domsch , -+ * Rob Radez , -+ * Rusty Lynch -+ * Satyam Sharma -+ * Randy Dunlap -+ * -+ * 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. -+ * -+ * Neither Alan Cox, CymruNet Ltd., Wim Van Sebroeck nor Iguana vzw. -+ * admit liability nor provide warranty for any of this software. -+ * This material is provided "AS-IS" and at no charge. -+ */ -+ -+#define MAX_DOGS 32 /* Maximum number of watchdog devices */ -+ -+/* -+ * Functions/procedures to be called by the core -+ */ -+extern int watchdog_dev_register(struct watchdog_device *); -+extern int watchdog_dev_unregister(struct watchdog_device *); -+extern int __init watchdog_dev_init(void); -+extern void __exit watchdog_dev_exit(void); -diff --git a/include/uapi/linux/watchdog.h b/include/uapi/linux/watchdog.h -new file mode 100644 -index 0000000..2babe72 ---- /dev/null -+++ b/include/uapi/linux/watchdog.h -@@ -0,0 +1,57 @@ -+/* -+ * Generic watchdog defines. Derived from.. -+ * -+ * Berkshire PC Watchdog Defines -+ * by Ken Hollis -+ * -+ */ -+ -+#ifndef _UAPI_LINUX_WATCHDOG_H -+#define _UAPI_LINUX_WATCHDOG_H -+ -+#include -+#include -+ -+#define WATCHDOG_IOCTL_BASE 'W' -+ -+struct watchdog_info { -+ __u32 options; /* Options the card/driver supports */ -+ __u32 firmware_version; /* Firmware version of the card */ -+ __u8 identity[32]; /* Identity of the board */ -+}; -+ -+#define WDIOC_GETSUPPORT _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info) -+#define WDIOC_GETSTATUS _IOR(WATCHDOG_IOCTL_BASE, 1, int) -+#define WDIOC_GETBOOTSTATUS _IOR(WATCHDOG_IOCTL_BASE, 2, int) -+#define WDIOC_GETTEMP _IOR(WATCHDOG_IOCTL_BASE, 3, int) -+#define WDIOC_SETOPTIONS _IOR(WATCHDOG_IOCTL_BASE, 4, int) -+#define WDIOC_KEEPALIVE _IOR(WATCHDOG_IOCTL_BASE, 5, int) -+#define WDIOC_SETTIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 6, int) -+#define WDIOC_GETTIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 7, int) -+#define WDIOC_SETPRETIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 8, int) -+#define WDIOC_GETPRETIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 9, int) -+#define WDIOC_GETTIMELEFT _IOR(WATCHDOG_IOCTL_BASE, 10, int) -+ -+#define WDIOF_UNKNOWN -1 /* Unknown flag error */ -+#define WDIOS_UNKNOWN -1 /* Unknown status error */ -+ -+#define WDIOF_OVERHEAT 0x0001 /* Reset due to CPU overheat */ -+#define WDIOF_FANFAULT 0x0002 /* Fan failed */ -+#define WDIOF_EXTERN1 0x0004 /* External relay 1 */ -+#define WDIOF_EXTERN2 0x0008 /* External relay 2 */ -+#define WDIOF_POWERUNDER 0x0010 /* Power bad/power fault */ -+#define WDIOF_CARDRESET 0x0020 /* Card previously reset the CPU */ -+#define WDIOF_POWEROVER 0x0040 /* Power over voltage */ -+#define WDIOF_SETTIMEOUT 0x0080 /* Set timeout (in seconds) */ -+#define WDIOF_MAGICCLOSE 0x0100 /* Supports magic close char */ -+#define WDIOF_PRETIMEOUT 0x0200 /* Pretimeout (in seconds), get/set */ -+#define WDIOF_ALARMONLY 0x0400 /* Watchdog triggers a management or -+ other external alarm not a reboot */ -+#define WDIOF_KEEPALIVEPING 0x8000 /* Keep alive ping reply */ -+ -+#define WDIOS_DISABLECARD 0x0001 /* Turn off the watchdog timer */ -+#define WDIOS_ENABLECARD 0x0002 /* Turn on the watchdog timer */ -+#define WDIOS_TEMPPANIC 0x0004 /* Kernel panic on temperature trip */ -+ -+ -+#endif /* _UAPI_LINUX_WATCHDOG_H */ -diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c -index cfa1a15..cec9b55 100644 ---- a/drivers/watchdog/watchdog_core.c -+++ b/drivers/watchdog/watchdog_core.c -@@ -34,8 +34,69 @@ - #include /* For printk/panic/... */ - #include /* For watchdog specific items */ - #include /* For __init/__exit/... */ -+#include /* For ida_* macros */ -+#include /* For IS_ERR macros */ -+#include /* For of_get_timeout_sec */ - --#include "watchdog_dev.h" /* For watchdog_dev_register/... */ -+#include "watchdog_core.h" /* For watchdog_dev_register/... */ -+ -+static DEFINE_IDA(watchdog_ida); -+static struct class *watchdog_class; -+ -+static void watchdog_check_min_max_timeout(struct watchdog_device *wdd) -+{ -+ /* -+ * Check that we have valid min and max timeout values, if -+ * not reset them both to 0 (=not used or unknown) -+ */ -+ if (wdd->min_timeout > wdd->max_timeout) { -+ pr_info("Invalid min and max timeout values, resetting to 0!\n"); -+ wdd->min_timeout = 0; -+ wdd->max_timeout = 0; -+ } -+} -+ -+/** -+ * watchdog_init_timeout() - initialize the timeout field -+ * @timeout_parm: timeout module parameter -+ * @dev: Device that stores the timeout-sec property -+ * -+ * Initialize the timeout field of the watchdog_device struct with either the -+ * timeout module parameter (if it is valid value) or the timeout-sec property -+ * (only if it is a valid value and the timeout_parm is out of bounds). -+ * If none of them are valid then we keep the old value (which should normally -+ * be the default timeout value. -+ * -+ * A zero is returned on success and -EINVAL for failure. -+ */ -+int watchdog_init_timeout(struct watchdog_device *wdd, -+ unsigned int timeout_parm, struct device *dev) -+{ -+ unsigned int t = 0; -+ int ret = 0; -+ -+ watchdog_check_min_max_timeout(wdd); -+ -+ /* try to get the timeout module parameter first */ -+ if (!watchdog_timeout_invalid(wdd, timeout_parm) && timeout_parm) { -+ wdd->timeout = timeout_parm; -+ return ret; -+ } -+ if (timeout_parm) -+ ret = -EINVAL; -+ -+ /* try to get the timeout_sec property */ -+ if (dev == NULL || dev->of_node == NULL) -+ return ret; -+ of_property_read_u32(dev->of_node, "timeout-sec", &t); -+ if (!watchdog_timeout_invalid(wdd, t) && t) -+ wdd->timeout = t; -+ else -+ ret = -EINVAL; -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(watchdog_init_timeout); - - /** - * watchdog_register_device() - register a watchdog device -@@ -49,7 +110,7 @@ - */ - int watchdog_register_device(struct watchdog_device *wdd) - { -- int ret; -+ int ret, id, devno; - - if (wdd == NULL || wdd->info == NULL || wdd->ops == NULL) - return -EINVAL; -@@ -58,15 +119,7 @@ int watchdog_register_device(struct watchdog_device *wdd) - if (wdd->ops->start == NULL || wdd->ops->stop == NULL) - return -EINVAL; - -- /* -- * Check that we have valid min and max timeout values, if -- * not reset them both to 0 (=not used or unknown) -- */ -- if (wdd->min_timeout > wdd->max_timeout) { -- pr_info("Invalid min and max timeout values, resetting to 0!\n"); -- wdd->min_timeout = 0; -- wdd->max_timeout = 0; -- } -+ watchdog_check_min_max_timeout(wdd); - - /* - * Note: now that all watchdog_device data has been verified, we -@@ -74,10 +127,38 @@ int watchdog_register_device(struct watchdog_device *wdd) - * corrupted in a later stage then we expect a kernel panic! - */ - -- /* We only support 1 watchdog device via the /dev/watchdog interface */ -+ mutex_init(&wdd->lock); -+ id = ida_simple_get(&watchdog_ida, 0, MAX_DOGS, GFP_KERNEL); -+ if (id < 0) -+ return id; -+ wdd->id = id; -+ - ret = watchdog_dev_register(wdd); - if (ret) { -- pr_err("error registering /dev/watchdog (err=%d).\n", ret); -+ ida_simple_remove(&watchdog_ida, id); -+ if (!(id == 0 && ret == -EBUSY)) -+ return ret; -+ -+ /* Retry in case a legacy watchdog module exists */ -+ id = ida_simple_get(&watchdog_ida, 1, MAX_DOGS, GFP_KERNEL); -+ if (id < 0) -+ return id; -+ wdd->id = id; -+ -+ ret = watchdog_dev_register(wdd); -+ if (ret) { -+ ida_simple_remove(&watchdog_ida, id); -+ return ret; -+ } -+ } -+ -+ devno = wdd->cdev.dev; -+ wdd->dev = device_create(watchdog_class, wdd->parent, devno, -+ NULL, "watchdog%d", wdd->id); -+ if (IS_ERR(wdd->dev)) { -+ watchdog_dev_unregister(wdd); -+ ida_simple_remove(&watchdog_ida, id); -+ ret = PTR_ERR(wdd->dev); - return ret; - } - -@@ -95,16 +176,50 @@ EXPORT_SYMBOL_GPL(watchdog_register_device); - void watchdog_unregister_device(struct watchdog_device *wdd) - { - int ret; -+ int devno; - - if (wdd == NULL) - return; - -+ devno = wdd->cdev.dev; - ret = watchdog_dev_unregister(wdd); - if (ret) -- pr_err("error unregistering /dev/watchdog (err=%d).\n", ret); -+ pr_err("error unregistering /dev/watchdog (err=%d)\n", ret); -+ device_destroy(watchdog_class, devno); -+ ida_simple_remove(&watchdog_ida, wdd->id); -+ wdd->dev = NULL; - } - EXPORT_SYMBOL_GPL(watchdog_unregister_device); - -+static int __init watchdog_init(void) -+{ -+ int err; -+ -+ watchdog_class = class_create(THIS_MODULE, "watchdog"); -+ if (IS_ERR(watchdog_class)) { -+ pr_err("couldn't create class\n"); -+ return PTR_ERR(watchdog_class); -+ } -+ -+ err = watchdog_dev_init(); -+ if (err < 0) { -+ class_destroy(watchdog_class); -+ return err; -+ } -+ -+ return 0; -+} -+ -+static void __exit watchdog_exit(void) -+{ -+ watchdog_dev_exit(); -+ class_destroy(watchdog_class); -+ ida_destroy(&watchdog_ida); -+} -+ -+subsys_initcall(watchdog_init); -+module_exit(watchdog_exit); -+ - MODULE_AUTHOR("Alan Cox "); - MODULE_AUTHOR("Wim Van Sebroeck "); - MODULE_DESCRIPTION("WatchDog Timer Driver Core"); -diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c -index 1199da0..6aaefba 100644 ---- a/drivers/watchdog/watchdog_dev.c -+++ b/drivers/watchdog/watchdog_dev.c -@@ -42,10 +42,12 @@ - #include /* For __init/__exit/... */ - #include /* For copy_to_user/put_user/... */ - --/* make sure we only register one /dev/watchdog device */ --static unsigned long watchdog_dev_busy; -+#include "watchdog_core.h" -+ -+/* the dev_t structure to store the dynamically allocated watchdog devices */ -+static dev_t watchdog_devt; - /* the watchdog device behind /dev/watchdog */ --static struct watchdog_device *wdd; -+static struct watchdog_device *old_wdd; - - /* - * watchdog_ping: ping the watchdog. -@@ -59,13 +61,26 @@ static struct watchdog_device *wdd; - - static int watchdog_ping(struct watchdog_device *wddev) - { -- if (test_bit(WDOG_ACTIVE, &wddev->status)) { -- if (wddev->ops->ping) -- return wddev->ops->ping(wddev); /* ping the watchdog */ -- else -- return wddev->ops->start(wddev); /* restart watchdog */ -+ int err = 0; -+ -+ mutex_lock(&wddev->lock); -+ -+ if (test_bit(WDOG_UNREGISTERED, &wddev->status)) { -+ err = -ENODEV; -+ goto out_ping; - } -- return 0; -+ -+ if (!watchdog_active(wddev)) -+ goto out_ping; -+ -+ if (wddev->ops->ping) -+ err = wddev->ops->ping(wddev); /* ping the watchdog */ -+ else -+ err = wddev->ops->start(wddev); /* restart watchdog */ -+ -+out_ping: -+ mutex_unlock(&wddev->lock); -+ return err; - } - - /* -@@ -79,16 +94,25 @@ static int watchdog_ping(struct watchdog_device *wddev) - - static int watchdog_start(struct watchdog_device *wddev) - { -- int err; -+ int err = 0; - -- if (!test_bit(WDOG_ACTIVE, &wddev->status)) { -- err = wddev->ops->start(wddev); -- if (err < 0) -- return err; -+ mutex_lock(&wddev->lock); - -- set_bit(WDOG_ACTIVE, &wddev->status); -+ if (test_bit(WDOG_UNREGISTERED, &wddev->status)) { -+ err = -ENODEV; -+ goto out_start; - } -- return 0; -+ -+ if (watchdog_active(wddev)) -+ goto out_start; -+ -+ err = wddev->ops->start(wddev); -+ if (err == 0) -+ set_bit(WDOG_ACTIVE, &wddev->status); -+ -+out_start: -+ mutex_unlock(&wddev->lock); -+ return err; - } - - /* -@@ -103,22 +127,154 @@ static int watchdog_start(struct watchdog_device *wddev) - - static int watchdog_stop(struct watchdog_device *wddev) - { -- int err = -EBUSY; -+ int err = 0; - -- if (test_bit(WDOG_NO_WAY_OUT, &wddev->status)) { -- pr_info("%s: nowayout prevents watchdog to be stopped!\n", -- wddev->info->identity); -- return err; -+ mutex_lock(&wddev->lock); -+ -+ if (test_bit(WDOG_UNREGISTERED, &wddev->status)) { -+ err = -ENODEV; -+ goto out_stop; - } - -- if (test_bit(WDOG_ACTIVE, &wddev->status)) { -- err = wddev->ops->stop(wddev); -- if (err < 0) -- return err; -+ if (!watchdog_active(wddev)) -+ goto out_stop; -+ -+ if (test_bit(WDOG_NO_WAY_OUT, &wddev->status)) { -+ dev_info(wddev->dev, "nowayout prevents watchdog being stopped!\n"); -+ err = -EBUSY; -+ goto out_stop; -+ } - -+ err = wddev->ops->stop(wddev); -+ if (err == 0) - clear_bit(WDOG_ACTIVE, &wddev->status); -+ -+out_stop: -+ mutex_unlock(&wddev->lock); -+ return err; -+} -+ -+/* -+ * watchdog_get_status: wrapper to get the watchdog status -+ * @wddev: the watchdog device to get the status from -+ * @status: the status of the watchdog device -+ * -+ * Get the watchdog's status flags. -+ */ -+ -+static int watchdog_get_status(struct watchdog_device *wddev, -+ unsigned int *status) -+{ -+ int err = 0; -+ -+ *status = 0; -+ if (!wddev->ops->status) -+ return -EOPNOTSUPP; -+ -+ mutex_lock(&wddev->lock); -+ -+ if (test_bit(WDOG_UNREGISTERED, &wddev->status)) { -+ err = -ENODEV; -+ goto out_status; - } -- return 0; -+ -+ *status = wddev->ops->status(wddev); -+ -+out_status: -+ mutex_unlock(&wddev->lock); -+ return err; -+} -+ -+/* -+ * watchdog_set_timeout: set the watchdog timer timeout -+ * @wddev: the watchdog device to set the timeout for -+ * @timeout: timeout to set in seconds -+ */ -+ -+static int watchdog_set_timeout(struct watchdog_device *wddev, -+ unsigned int timeout) -+{ -+ int err; -+ -+ if ((wddev->ops->set_timeout == NULL) || -+ !(wddev->info->options & WDIOF_SETTIMEOUT)) -+ return -EOPNOTSUPP; -+ -+ if (watchdog_timeout_invalid(wddev, timeout)) -+ return -EINVAL; -+ -+ mutex_lock(&wddev->lock); -+ -+ if (test_bit(WDOG_UNREGISTERED, &wddev->status)) { -+ err = -ENODEV; -+ goto out_timeout; -+ } -+ -+ err = wddev->ops->set_timeout(wddev, timeout); -+ -+out_timeout: -+ mutex_unlock(&wddev->lock); -+ return err; -+} -+ -+/* -+ * watchdog_get_timeleft: wrapper to get the time left before a reboot -+ * @wddev: the watchdog device to get the remaining time from -+ * @timeleft: the time that's left -+ * -+ * Get the time before a watchdog will reboot (if not pinged). -+ */ -+ -+static int watchdog_get_timeleft(struct watchdog_device *wddev, -+ unsigned int *timeleft) -+{ -+ int err = 0; -+ -+ *timeleft = 0; -+ if (!wddev->ops->get_timeleft) -+ return -EOPNOTSUPP; -+ -+ mutex_lock(&wddev->lock); -+ -+ if (test_bit(WDOG_UNREGISTERED, &wddev->status)) { -+ err = -ENODEV; -+ goto out_timeleft; -+ } -+ -+ *timeleft = wddev->ops->get_timeleft(wddev); -+ -+out_timeleft: -+ mutex_unlock(&wddev->lock); -+ return err; -+} -+ -+/* -+ * watchdog_ioctl_op: call the watchdog drivers ioctl op if defined -+ * @wddev: the watchdog device to do the ioctl on -+ * @cmd: watchdog command -+ * @arg: argument pointer -+ */ -+ -+static int watchdog_ioctl_op(struct watchdog_device *wddev, unsigned int cmd, -+ unsigned long arg) -+{ -+ int err; -+ -+ if (!wddev->ops->ioctl) -+ return -ENOIOCTLCMD; -+ -+ mutex_lock(&wddev->lock); -+ -+ if (test_bit(WDOG_UNREGISTERED, &wddev->status)) { -+ err = -ENODEV; -+ goto out_ioctl; -+ } -+ -+ err = wddev->ops->ioctl(wddev, cmd, arg); -+ -+out_ioctl: -+ mutex_unlock(&wddev->lock); -+ return err; - } - - /* -@@ -136,6 +292,7 @@ static int watchdog_stop(struct watchdog_device *wddev) - static ssize_t watchdog_write(struct file *file, const char __user *data, - size_t len, loff_t *ppos) - { -+ struct watchdog_device *wdd = file->private_data; - size_t i; - char c; - -@@ -175,23 +332,24 @@ static ssize_t watchdog_write(struct file *file, const char __user *data, - static long watchdog_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) - { -+ struct watchdog_device *wdd = file->private_data; - void __user *argp = (void __user *)arg; - int __user *p = argp; - unsigned int val; - int err; - -- if (wdd->ops->ioctl) { -- err = wdd->ops->ioctl(wdd, cmd, arg); -- if (err != -ENOIOCTLCMD) -- return err; -- } -+ err = watchdog_ioctl_op(wdd, cmd, arg); -+ if (err != -ENOIOCTLCMD) -+ return err; - - switch (cmd) { - case WDIOC_GETSUPPORT: - return copy_to_user(argp, wdd->info, - sizeof(struct watchdog_info)) ? -EFAULT : 0; - case WDIOC_GETSTATUS: -- val = wdd->ops->status ? wdd->ops->status(wdd) : 0; -+ err = watchdog_get_status(wdd, &val); -+ if (err == -ENODEV) -+ return err; - return put_user(val, p); - case WDIOC_GETBOOTSTATUS: - return put_user(wdd->bootstatus, p); -@@ -215,18 +373,11 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, - watchdog_ping(wdd); - return 0; - case WDIOC_SETTIMEOUT: -- if ((wdd->ops->set_timeout == NULL) || -- !(wdd->info->options & WDIOF_SETTIMEOUT)) -- return -EOPNOTSUPP; - if (get_user(val, p)) - return -EFAULT; -- if ((wdd->max_timeout != 0) && -- (val < wdd->min_timeout || val > wdd->max_timeout)) -- return -EINVAL; -- err = wdd->ops->set_timeout(wdd, val); -+ err = watchdog_set_timeout(wdd, val); - if (err < 0) - return err; -- wdd->timeout = val; - /* If the watchdog is active then we send a keepalive ping - * to make sure that the watchdog keep's running (and if - * possible that it takes the new timeout) */ -@@ -237,17 +388,22 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, - if (wdd->timeout == 0) - return -EOPNOTSUPP; - return put_user(wdd->timeout, p); -+ case WDIOC_GETTIMELEFT: -+ err = watchdog_get_timeleft(wdd, &val); -+ if (err) -+ return err; -+ return put_user(val, p); - default: - return -ENOTTY; - } - } - - /* -- * watchdog_open: open the /dev/watchdog device. -+ * watchdog_open: open the /dev/watchdog* devices. - * @inode: inode of device - * @file: file handle to device - * -- * When the /dev/watchdog device gets opened, we start the watchdog. -+ * When the /dev/watchdog* device gets opened, we start the watchdog. - * Watch out: the /dev/watchdog device is single open, so we make sure - * it can only be opened once. - */ -@@ -255,6 +411,13 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, - static int watchdog_open(struct inode *inode, struct file *file) - { - int err = -EBUSY; -+ struct watchdog_device *wdd; -+ -+ /* Get the corresponding watchdog device */ -+ if (imajor(inode) == MISC_MAJOR) -+ wdd = old_wdd; -+ else -+ wdd = container_of(inode->i_cdev, struct watchdog_device, cdev); - - /* the watchdog is single open! */ - if (test_and_set_bit(WDOG_DEV_OPEN, &wdd->status)) -@@ -271,6 +434,11 @@ static int watchdog_open(struct inode *inode, struct file *file) - if (err < 0) - goto out_mod; - -+ file->private_data = wdd; -+ -+ if (wdd->ops->ref) -+ wdd->ops->ref(wdd); -+ - /* dev/watchdog is a virtual (and thus non-seekable) filesystem */ - return nonseekable_open(inode, file); - -@@ -282,9 +450,9 @@ out: - } - - /* -- * watchdog_release: release the /dev/watchdog device. -- * @inode: inode of device -- * @file: file handle to device -+ * watchdog_release: release the watchdog device. -+ * @inode: inode of device -+ * @file: file handle to device - * - * This is the code for when /dev/watchdog gets closed. We will only - * stop the watchdog when we have received the magic char (and nowayout -@@ -293,6 +461,7 @@ out: - - static int watchdog_release(struct inode *inode, struct file *file) - { -+ struct watchdog_device *wdd = file->private_data; - int err = -EBUSY; - - /* -@@ -300,13 +469,18 @@ static int watchdog_release(struct inode *inode, struct file *file) - * or if WDIOF_MAGICCLOSE is not set. If nowayout was set then - * watchdog_stop will fail. - */ -- if (test_and_clear_bit(WDOG_ALLOW_RELEASE, &wdd->status) || -- !(wdd->info->options & WDIOF_MAGICCLOSE)) -+ if (!test_bit(WDOG_ACTIVE, &wdd->status)) -+ err = 0; -+ else if (test_and_clear_bit(WDOG_ALLOW_RELEASE, &wdd->status) || -+ !(wdd->info->options & WDIOF_MAGICCLOSE)) - err = watchdog_stop(wdd); - - /* If the watchdog was not stopped, send a keepalive ping */ - if (err < 0) { -- pr_crit("%s: watchdog did not stop!\n", wdd->info->identity); -+ mutex_lock(&wdd->lock); -+ if (!test_bit(WDOG_UNREGISTERED, &wdd->status)) -+ dev_crit(wdd->dev, "watchdog did not stop!\n"); -+ mutex_unlock(&wdd->lock); - watchdog_ping(wdd); - } - -@@ -316,6 +490,10 @@ static int watchdog_release(struct inode *inode, struct file *file) - /* make sure that /dev/watchdog can be re-opened */ - clear_bit(WDOG_DEV_OPEN, &wdd->status); - -+ /* Note wdd may be gone after this, do not use after this! */ -+ if (wdd->ops->unref) -+ wdd->ops->unref(wdd); -+ - return 0; - } - -@@ -334,62 +512,93 @@ static struct miscdevice watchdog_miscdev = { - }; - - /* -- * watchdog_dev_register: -+ * watchdog_dev_register: register a watchdog device - * @watchdog: watchdog device - * -- * Register a watchdog device as /dev/watchdog. /dev/watchdog -- * is actually a miscdevice and thus we set it up like that. -+ * Register a watchdog device including handling the legacy -+ * /dev/watchdog node. /dev/watchdog is actually a miscdevice and -+ * thus we set it up like that. - */ - - int watchdog_dev_register(struct watchdog_device *watchdog) - { -- int err; -- -- /* Only one device can register for /dev/watchdog */ -- if (test_and_set_bit(0, &watchdog_dev_busy)) { -- pr_err("only one watchdog can use /dev/watchdog.\n"); -- return -EBUSY; -+ int err, devno; -+ -+ if (watchdog->id == 0) { -+ old_wdd = watchdog; -+ watchdog_miscdev.parent = watchdog->parent; -+ err = misc_register(&watchdog_miscdev); -+ if (err != 0) { -+ pr_err("%s: cannot register miscdev on minor=%d (err=%d).\n", -+ watchdog->info->identity, WATCHDOG_MINOR, err); -+ if (err == -EBUSY) -+ pr_err("%s: a legacy watchdog module is probably present.\n", -+ watchdog->info->identity); -+ old_wdd = NULL; -+ return err; -+ } - } - -- wdd = watchdog; -- -- err = misc_register(&watchdog_miscdev); -- if (err != 0) { -- pr_err("%s: cannot register miscdev on minor=%d (err=%d).\n", -- watchdog->info->identity, WATCHDOG_MINOR, err); -- goto out; -+ /* Fill in the data structures */ -+ devno = MKDEV(MAJOR(watchdog_devt), watchdog->id); -+ cdev_init(&watchdog->cdev, &watchdog_fops); -+ watchdog->cdev.owner = watchdog->ops->owner; -+ -+ /* Add the device */ -+ err = cdev_add(&watchdog->cdev, devno, 1); -+ if (err) { -+ pr_err("watchdog%d unable to add device %d:%d\n", -+ watchdog->id, MAJOR(watchdog_devt), watchdog->id); -+ if (watchdog->id == 0) { -+ misc_deregister(&watchdog_miscdev); -+ old_wdd = NULL; -+ } - } -- -- return 0; -- --out: -- wdd = NULL; -- clear_bit(0, &watchdog_dev_busy); - return err; - } - - /* -- * watchdog_dev_unregister: -+ * watchdog_dev_unregister: unregister a watchdog device - * @watchdog: watchdog device - * -- * Deregister the /dev/watchdog device. -+ * Unregister the watchdog and if needed the legacy /dev/watchdog device. - */ - - int watchdog_dev_unregister(struct watchdog_device *watchdog) - { -- /* Check that a watchdog device was registered in the past */ -- if (!test_bit(0, &watchdog_dev_busy) || !wdd) -- return -ENODEV; -- -- /* We can only unregister the watchdog device that was registered */ -- if (watchdog != wdd) { -- pr_err("%s: watchdog was not registered as /dev/watchdog.\n", -- watchdog->info->identity); -- return -ENODEV; -+ mutex_lock(&watchdog->lock); -+ set_bit(WDOG_UNREGISTERED, &watchdog->status); -+ mutex_unlock(&watchdog->lock); -+ -+ cdev_del(&watchdog->cdev); -+ if (watchdog->id == 0) { -+ misc_deregister(&watchdog_miscdev); -+ old_wdd = NULL; - } -- -- misc_deregister(&watchdog_miscdev); -- wdd = NULL; -- clear_bit(0, &watchdog_dev_busy); - return 0; - } -+ -+/* -+ * watchdog_dev_init: init dev part of watchdog core -+ * -+ * Allocate a range of chardev nodes to use for watchdog devices -+ */ -+ -+int __init watchdog_dev_init(void) -+{ -+ int err = alloc_chrdev_region(&watchdog_devt, 0, MAX_DOGS, "watchdog"); -+ if (err < 0) -+ pr_err("watchdog: unable to allocate char dev region\n"); -+ return err; -+} -+ -+/* -+ * watchdog_dev_exit: exit dev part of watchdog core -+ * -+ * Release the range of chardev nodes used for watchdog devices -+ */ -+ -+void __exit watchdog_dev_exit(void) -+{ -+ unregister_chrdev_region(watchdog_devt, MAX_DOGS); -+} -diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h -index 111843f..395b70e 100644 ---- a/include/linux/watchdog.h -+++ b/include/linux/watchdog.h -@@ -5,59 +5,14 @@ - * by Ken Hollis - * - */ -- - #ifndef _LINUX_WATCHDOG_H - #define _LINUX_WATCHDOG_H - --#include --#include -- --#define WATCHDOG_IOCTL_BASE 'W' -- --struct watchdog_info { -- __u32 options; /* Options the card/driver supports */ -- __u32 firmware_version; /* Firmware version of the card */ -- __u8 identity[32]; /* Identity of the board */ --}; -- --#define WDIOC_GETSUPPORT _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info) --#define WDIOC_GETSTATUS _IOR(WATCHDOG_IOCTL_BASE, 1, int) --#define WDIOC_GETBOOTSTATUS _IOR(WATCHDOG_IOCTL_BASE, 2, int) --#define WDIOC_GETTEMP _IOR(WATCHDOG_IOCTL_BASE, 3, int) --#define WDIOC_SETOPTIONS _IOR(WATCHDOG_IOCTL_BASE, 4, int) --#define WDIOC_KEEPALIVE _IOR(WATCHDOG_IOCTL_BASE, 5, int) --#define WDIOC_SETTIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 6, int) --#define WDIOC_GETTIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 7, int) --#define WDIOC_SETPRETIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 8, int) --#define WDIOC_GETPRETIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 9, int) --#define WDIOC_GETTIMELEFT _IOR(WATCHDOG_IOCTL_BASE, 10, int) -- --#define WDIOF_UNKNOWN -1 /* Unknown flag error */ --#define WDIOS_UNKNOWN -1 /* Unknown status error */ - --#define WDIOF_OVERHEAT 0x0001 /* Reset due to CPU overheat */ --#define WDIOF_FANFAULT 0x0002 /* Fan failed */ --#define WDIOF_EXTERN1 0x0004 /* External relay 1 */ --#define WDIOF_EXTERN2 0x0008 /* External relay 2 */ --#define WDIOF_POWERUNDER 0x0010 /* Power bad/power fault */ --#define WDIOF_CARDRESET 0x0020 /* Card previously reset the CPU */ --#define WDIOF_POWEROVER 0x0040 /* Power over voltage */ --#define WDIOF_SETTIMEOUT 0x0080 /* Set timeout (in seconds) */ --#define WDIOF_MAGICCLOSE 0x0100 /* Supports magic close char */ --#define WDIOF_PRETIMEOUT 0x0200 /* Pretimeout (in seconds), get/set */ --#define WDIOF_KEEPALIVEPING 0x8000 /* Keep alive ping reply */ -- --#define WDIOS_DISABLECARD 0x0001 /* Turn off the watchdog timer */ --#define WDIOS_ENABLECARD 0x0002 /* Turn on the watchdog timer */ --#define WDIOS_TEMPPANIC 0x0004 /* Kernel panic on temperature trip */ -- --#ifdef __KERNEL__ -- --#ifdef CONFIG_WATCHDOG_NOWAYOUT --#define WATCHDOG_NOWAYOUT 1 --#else --#define WATCHDOG_NOWAYOUT 0 --#endif -+#include -+#include -+#include -+#include - - struct watchdog_ops; - struct watchdog_device; -@@ -70,6 +25,9 @@ struct watchdog_device; - * @ping: The routine that sends a keepalive ping to the watchdog device. - * @status: The routine that shows the status of the watchdog device. - * @set_timeout:The routine for setting the watchdog devices timeout value. -+ * @get_timeleft:The routine that get's the time that's left before a reset. -+ * @ref: The ref operation for dyn. allocated watchdog_device structs -+ * @unref: The unref operation for dyn. allocated watchdog_device structs - * @ioctl: The routines that handles extra ioctl calls. - * - * The watchdog_ops structure contains a list of low-level operations -@@ -86,11 +44,18 @@ struct watchdog_ops { - int (*ping)(struct watchdog_device *); - unsigned int (*status)(struct watchdog_device *); - int (*set_timeout)(struct watchdog_device *, unsigned int); -+ unsigned int (*get_timeleft)(struct watchdog_device *); -+ void (*ref)(struct watchdog_device *); -+ void (*unref)(struct watchdog_device *); - long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long); - }; - - /** struct watchdog_device - The structure that defines a watchdog device - * -+ * @id: The watchdog's ID. (Allocated by watchdog_register_device) -+ * @cdev: The watchdog's Character device. -+ * @dev: The device for our watchdog -+ * @parent: The parent bus device - * @info: Pointer to a watchdog_info structure. - * @ops: Pointer to the list of watchdog operations. - * @bootstatus: Status of the watchdog device at boot. -@@ -98,6 +63,7 @@ struct watchdog_ops { - * @min_timeout:The watchdog devices minimum timeout value. - * @max_timeout:The watchdog devices maximum timeout value. - * @driver-data:Pointer to the drivers private data. -+ * @lock: Lock for watchdog core internal use only. - * @status: Field that contains the devices internal status bits. - * - * The watchdog_device structure contains all information about a -@@ -105,8 +71,15 @@ struct watchdog_ops { - * - * The driver-data field may not be accessed directly. It must be accessed - * via the watchdog_set_drvdata and watchdog_get_drvdata helpers. -+ * -+ * The lock field is for watchdog core internal use only and should not be -+ * touched. - */ - struct watchdog_device { -+ int id; -+ struct cdev cdev; -+ struct device *dev; -+ struct device *parent; - const struct watchdog_info *info; - const struct watchdog_ops *ops; - unsigned int bootstatus; -@@ -114,14 +87,39 @@ struct watchdog_device { - unsigned int min_timeout; - unsigned int max_timeout; - void *driver_data; -+ struct mutex lock; - unsigned long status; - /* Bit numbers for status flags */ - #define WDOG_ACTIVE 0 /* Is the watchdog running/active */ - #define WDOG_DEV_OPEN 1 /* Opened via /dev/watchdog ? */ - #define WDOG_ALLOW_RELEASE 2 /* Did we receive the magic char ? */ - #define WDOG_NO_WAY_OUT 3 /* Is 'nowayout' feature set ? */ -+#define WDOG_UNREGISTERED 4 /* Has the device been unregistered */ - }; - -+#define WATCHDOG_NOWAYOUT IS_BUILTIN(CONFIG_WATCHDOG_NOWAYOUT) -+#define WATCHDOG_NOWAYOUT_INIT_STATUS (WATCHDOG_NOWAYOUT << WDOG_NO_WAY_OUT) -+ -+/* Use the following function to check whether or not the watchdog is active */ -+static inline bool watchdog_active(struct watchdog_device *wdd) -+{ -+ return test_bit(WDOG_ACTIVE, &wdd->status); -+} -+ -+/* Use the following function to set the nowayout feature */ -+static inline void watchdog_set_nowayout(struct watchdog_device *wdd, bool nowayout) -+{ -+ if (nowayout) -+ set_bit(WDOG_NO_WAY_OUT, &wdd->status); -+} -+ -+/* Use the following function to check if a timeout value is invalid */ -+static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigned int t) -+{ -+ return ((wdd->max_timeout != 0) && -+ (t < wdd->min_timeout || t > wdd->max_timeout)); -+} -+ - /* Use the following functions to manipulate watchdog driver specific data */ - static inline void watchdog_set_drvdata(struct watchdog_device *wdd, void *data) - { -@@ -133,10 +131,10 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd) - return wdd->driver_data; - } - --/* drivers/watchdog/core/watchdog_core.c */ -+/* drivers/watchdog/watchdog_core.c */ -+extern int watchdog_init_timeout(struct watchdog_device *wdd, -+ unsigned int timeout_parm, struct device *dev); - extern int watchdog_register_device(struct watchdog_device *); - extern void watchdog_unregister_device(struct watchdog_device *); - --#endif /* __KERNEL__ */ -- - #endif /* ifndef _LINUX_WATCHDOG_H */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/drivers-hwmon-adm1021-detect.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/drivers-hwmon-adm1021-detect.patch deleted file mode 100644 index 079fb085..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/drivers-hwmon-adm1021-detect.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/drivers/hwmon/adm1021.c 2014-12-14 08:24:02.000000000 -0800 -+++ b/drivers/hwmon/adm1021.c 2016-10-13 10:48:10.045055678 -0700 -@@ -105,6 +105,7 @@ static struct adm1021_data *adm1021_upda - /* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */ - static int read_only; - -+static int detect = 1; - - static const struct i2c_device_id adm1021_id[] = { - { "adm1021", adm1021 }, -@@ -295,6 +296,9 @@ static int adm1021_detect(struct i2c_cli - "smbus byte data not supported!\n"); - return -ENODEV; - } -+ if(detect == 0) { -+ return -ENODEV; -+ } - - status = i2c_smbus_read_byte_data(client, ADM1021_REG_STATUS); - conv_rate = i2c_smbus_read_byte_data(client, -@@ -510,6 +514,8 @@ MODULE_LICENSE("GPL"); - - module_param(read_only, bool, 0); - MODULE_PARM_DESC(read_only, "Don't set any values, read only mode"); -+module_param(detect, bool, 1); -+MODULE_PARM_DESC(detect, "Enable or disable device detection."); - - module_init(sensors_adm1021_init) - module_exit(sensors_adm1021_exit) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/drivers-i2c-busses-i2c-isch-timeout.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/drivers-i2c-busses-i2c-isch-timeout.patch deleted file mode 100644 index 013b3725..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/drivers-i2c-busses-i2c-isch-timeout.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- a/drivers/i2c/busses/i2c-isch.c 2014-12-14 08:24:02.000000000 -0800 -+++ b/drivers/i2c/busses/i2c-isch.c 2016-10-13 08:02:44.564840300 -0700 -@@ -47,7 +47,7 @@ - #define SMBBLKDAT (0x20 + sch_smba) - - /* Other settings */ --#define MAX_TIMEOUT 500 -+#define MAX_RETRIES 5000 - - /* I2C constants */ - #define SCH_QUICK 0x00 -@@ -68,7 +68,7 @@ static int sch_transaction(void) - { - int temp; - int result = 0; -- int timeout = 0; -+ int retries = 0; - - dev_dbg(&sch_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, " - "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb(SMBHSTCNT), -@@ -100,12 +100,12 @@ static int sch_transaction(void) - outb(inb(SMBHSTCNT) | 0x10, SMBHSTCNT); - - do { -- msleep(1); -+ usleep_range(100, 200); - temp = inb(SMBHSTSTS) & 0x0f; -- } while ((temp & 0x08) && (timeout++ < MAX_TIMEOUT)); -+ } while ((temp & 0x08) && (retries++ < MAX_RETRIES)); - - /* If the SMBus is still busy, we give up */ -- if (timeout > MAX_TIMEOUT) { -+ if (retries > MAX_RETRIES) { - dev_err(&sch_adapter.dev, "SMBus Timeout!\n"); - result = -ETIMEDOUT; - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/drivers-net-ethernet-broadcom-tg3-preamble-reset.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/drivers-net-ethernet-broadcom-tg3-preamble-reset.patch deleted file mode 100644 index 2610f9ed..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/drivers-net-ethernet-broadcom-tg3-preamble-reset.patch +++ /dev/null @@ -1,44 +0,0 @@ -diff -urpN a/drivers/net/ethernet/broadcom/tg3/tg3.c b/drivers/net/ethernet/broadcom/tg3/tg3.c ---- a/drivers/net/ethernet/broadcom/tg3/tg3.c 2017-01-03 10:58:35.130883468 -0800 -+++ b/drivers/net/ethernet/broadcom/tg3/tg3.c 2017-01-03 11:22:46.910914971 -0800 -@@ -324,6 +324,14 @@ module_param(tg3_disable_eee, int, 0); - MODULE_PARM_DESC(tg3_disable_eee, "Disable Energy Efficient Ethernet (EEE) support"); - #endif - -+static int short_preamble = 0; -+module_param(short_preamble, int, 0); -+MODULE_PARM_DESC(short_preamble, "Enable short preamble."); -+ -+static int bcm5718s_reset = 0; -+module_param(bcm5718s_reset, int, 0); -+MODULE_PARM_DESC(bcm5718s_reset, "Enable BCM5718S reset support."); -+ - #define TG3_DRV_DATA_FLAG_10_100_ONLY 0x0001 - #define TG3_DRV_DATA_FLAG_5705_10_100 0x0002 - -@@ -1628,6 +1635,12 @@ static void tg3_mdio_config_5785(struct - static void tg3_mdio_start(struct tg3 *tp) - { - tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL; -+ -+ if(short_preamble) { -+ netdev_info(tp->dev, "Setting short preamble..."); -+ tp->mi_mode |= MAC_MI_MODE_SHORT_PREAMBLE; -+ } -+ - tw32_f(MAC_MI_MODE, tp->mi_mode); - udelay(80); - -@@ -2899,6 +2911,12 @@ static int tg3_phy_reset(struct tg3 *tp) - } - } - -+ if (bcm5718s_reset && tp->phy_id == TG3_PHY_ID_BCM5718S) { -+ netdev_info(tp->dev, "BCM5718S reset..."); -+ __tg3_writephy(tp, 0x8, 0x10, 0x1d0); /* set internal phy 0x8 to make linkup */ -+ __tg3_writephy(tp, 0x1f, 0x4, 0x5e1); /* enable 10/100 cability of external phy */ -+ } -+ - if (tg3_flag(tp, 5717_PLUS) && - (tp->phy_flags & TG3_PHYFLG_MII_SERDES)) - return 0; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/ethtool-stats-fix-kzalloc-flags.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/ethtool-stats-fix-kzalloc-flags.patch deleted file mode 100644 index 719ca23e..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/ethtool-stats-fix-kzalloc-flags.patch +++ /dev/null @@ -1,24 +0,0 @@ -Use GFP_ATOMIC instead of GFP_KERNEL since interrupts are disabled. - -diff --git a/net/core/port.c b/net/core/port.c -index 0fa33bd..6fea48f 100644 ---- a/net/core/port.c -+++ b/net/core/port.c -@@ -69,7 +69,7 @@ static void __port_cache_init(int ifindex) - return; - } - -- port = kzalloc(sizeof(*port), GFP_KERNEL); -+ port = kzalloc(sizeof(*port), GFP_ATOMIC); - if (!port) { - spin_unlock_irqrestore(&port_cache_lock, flags); - return; -@@ -177,7 +177,7 @@ static void port_cache_set_stat_strings(int ifindex, int count, u8 *strings) - return; - } - -- new_strings = kmalloc(count * ETH_GSTRING_LEN, GFP_KERNEL); -+ new_strings = kmalloc(count * ETH_GSTRING_LEN, GFP_ATOMIC); - if (!new_strings) { - spin_unlock_irqrestore(&port_cache_lock, flags); - return; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/git-ignore.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/git-ignore.patch deleted file mode 100644 index 4eaa1497..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/git-ignore.patch +++ /dev/null @@ -1,37 +0,0 @@ -#Copyright 2012 Cumulus Networks, Inc. All rights reserved. - -Supplement the kernel's .gitignore - -- Ignore platform device tree blob files -- vmlinux.strip - -diff --git a/.gitignore b/.gitignore -index 57af07c..3eaa29a 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -40,6 +40,7 @@ modules.builtin - /TAGS - /linux - /vmlinux -+/vmlinux.strip - /vmlinuz - /System.map - /Module.markers -diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore -index 12da77e..652e35d 100644 ---- a/arch/powerpc/boot/.gitignore -+++ b/arch/powerpc/boot/.gitignore -@@ -21,6 +21,7 @@ uImage - cuImage.* - dtbImage.* - treeImage.* -+vmlinux.strip - zImage - zImage.initrd - zImage.bin.* -@@ -44,4 +45,4 @@ fdt_sw.c - fdt_wip.c - libfdt.h - libfdt_internal.h -- -+*.dtb diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-coredump-warn-about-unsafe-suid_dumpable-core_patter.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-coredump-warn-about-unsafe-suid_dumpable-core_patter.patch deleted file mode 100644 index 52eff31c..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-coredump-warn-about-unsafe-suid_dumpable-core_patter.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 54b501992dd2a839e94e76aa392c392b55080ce8 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] coredump: warn about unsafe suid_dumpable / core_pattern - combo - -When suid_dumpable=2, detect unsafe core_pattern settings and warn when -they are seen. - -Signed-off-by: Kees Cook -Suggested-by: Andrew Morton -Cc: Alexander Viro -Cc: Alan Cox -Cc: "Eric W. Biederman" -Cc: Doug Ledford -Cc: Serge Hallyn -Cc: James Morris -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds - -diff --git a/fs/exec.c b/fs/exec.c -index 9c5fb55..a9dbf33 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -2006,17 +2006,17 @@ static void coredump_finish(struct mm_struct *mm) - void set_dumpable(struct mm_struct *mm, int value) - { - switch (value) { -- case 0: -+ case SUID_DUMP_DISABLE: - clear_bit(MMF_DUMPABLE, &mm->flags); - smp_wmb(); - clear_bit(MMF_DUMP_SECURELY, &mm->flags); - break; -- case 1: -+ case SUID_DUMP_USER: - set_bit(MMF_DUMPABLE, &mm->flags); - smp_wmb(); - clear_bit(MMF_DUMP_SECURELY, &mm->flags); - break; -- case 2: -+ case SUID_DUMP_ROOT: - set_bit(MMF_DUMP_SECURELY, &mm->flags); - smp_wmb(); - set_bit(MMF_DUMPABLE, &mm->flags); -@@ -2029,7 +2029,7 @@ static int __get_dumpable(unsigned long mm_flags) - int ret; - - ret = mm_flags & MMF_DUMPABLE_MASK; -- return (ret >= 2) ? 2 : ret; -+ return (ret > SUID_DUMP_USER) ? SUID_DUMP_ROOT : ret; - } - - /* -@@ -2152,7 +2152,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) - * so we dump it as root in mode 2, and only into a controlled - * environment (pipe handler or fully qualified path). - */ -- if (__get_dumpable(cprm.mm_flags) == 2) { -+ if (__get_dumpable(cprm.mm_flags) == SUID_DUMP_ROOT) { - /* Setuid core dump mode */ - flag = O_EXCL; /* Stop rewrite attacks */ - cred->fsuid = 0; /* Dump root private */ -diff --git a/kernel/sysctl.c b/kernel/sysctl.c -index d6ff129..093f6c5 100644 ---- a/kernel/sysctl.c -+++ b/kernel/sysctl.c -@@ -170,6 +170,11 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos); - #endif - -+static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write, -+ void __user *buffer, size_t *lenp, loff_t *ppos); -+static int proc_dostring_coredump(struct ctl_table *table, int write, -+ void __user *buffer, size_t *lenp, loff_t *ppos); -+ - #ifdef CONFIG_MAGIC_SYSRQ - /* Note: sysrq code uses it's own private copy */ - static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE; -@@ -420,7 +425,7 @@ static struct ctl_table kern_table[] = { - .data = core_pattern, - .maxlen = CORENAME_MAX_SIZE, - .mode = 0644, -- .proc_handler = proc_dostring, -+ .proc_handler = proc_dostring_coredump, - }, - { - .procname = "core_pipe_limit", -@@ -1517,7 +1522,7 @@ static struct ctl_table fs_table[] = { - .data = &suid_dumpable, - .maxlen = sizeof(int), - .mode = 0644, -- .proc_handler = proc_dointvec_minmax, -+ .proc_handler = proc_dointvec_minmax_coredump, - .extra1 = &zero, - .extra2 = &two, - }, -@@ -2506,6 +2511,34 @@ int proc_dointvec_minmax(struct ctl_table *table, int write, - do_proc_dointvec_minmax_conv, ¶m); - } - -+static void validate_coredump_safety(void) -+{ -+ if (suid_dumpable == SUID_DUMP_ROOT && -+ core_pattern[0] != '/' && core_pattern[0] != '|') { -+ printk(KERN_WARNING "Unsafe core_pattern used with "\ -+ "suid_dumpable=2. Pipe handler or fully qualified "\ -+ "core dump path required.\n"); -+ } -+} -+ -+static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write, -+ void __user *buffer, size_t *lenp, loff_t *ppos) -+{ -+ int error = proc_dointvec_minmax(table, write, buffer, lenp, ppos); -+ if (!error) -+ validate_coredump_safety(); -+ return error; -+} -+ -+static int proc_dostring_coredump(struct ctl_table *table, int write, -+ void __user *buffer, size_t *lenp, loff_t *ppos) -+{ -+ int error = proc_dostring(table, write, buffer, lenp, ppos); -+ if (!error) -+ validate_coredump_safety(); -+ return error; -+} -+ - static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, - void __user *buffer, - size_t *lenp, loff_t *ppos, diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-enable-compiling-firmware-into-kernel-binary.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-enable-compiling-firmware-into-kernel-binary.patch deleted file mode 100644 index c5d8b94a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-enable-compiling-firmware-into-kernel-binary.patch +++ /dev/null @@ -1,301 +0,0 @@ -Enable building firmware into kernel binary - -The Debian kernel removes the ability of compiling device driver -firmware into the kernel image. - -This patch adds that capability back. - -See configuration options: - -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE -CONFIG_EXTRA_FIRMWARE_DIR - -diff --git a/Makefile b/Makefile -index 2800ffe..8d45e46 100644 ---- a/Makefile -+++ b/Makefile -@@ -505,7 +505,7 @@ scripts: scripts_basic include/config/auto.conf include/config/tristate.conf - - # Objects we will link into vmlinux / subdirs we need to visit - init-y := init/ --drivers-y := drivers/ sound/ -+drivers-y := drivers/ sound/ firmware/ - net-y := net/ - libs-y := lib/ - core-y := usr/ -diff --git a/firmware/.gitignore b/firmware/.gitignore -new file mode 100644 -index 0000000..d9c6901 ---- /dev/null -+++ b/firmware/.gitignore -@@ -0,0 +1,6 @@ -+*.gen.S -+*.fw -+*.bin -+*.csp -+*.dsp -+ihex2fw -diff --git a/firmware/Makefile b/firmware/Makefile -new file mode 100644 -index 0000000..93ce280 ---- /dev/null -+++ b/firmware/Makefile -@@ -0,0 +1,257 @@ -+# -+# kbuild file for firmware/ -+# -+ -+# Create $(fwabs) from $(CONFIG_EXTRA_FIRMWARE_DIR) -- if it doesn't have a -+# leading /, it's relative to $(srctree). -+fwdir := $(subst ",,$(CONFIG_EXTRA_FIRMWARE_DIR)) -+fwabs := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir)) -+ -+fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE)) -+ -+# There are three cases to care about: -+# 1. Building kernel with CONFIG_FIRMWARE_IN_KERNEL=y -- $(fw-shipped-y) should -+# include the firmware files to include, according to .config -+# 2. 'make modules_install', which will install firmware for modules, and -+# _also_ for the in-kernel drivers when CONFIG_FIRMWARE_IN_KERNEL=n -+# 3. 'make firmware_install', which installs all firmware, unconditionally. -+ -+# For the former two cases we want $(fw-shipped-y) and $(fw-shipped-m) to be -+# accurate. In the latter case it doesn't matter -- it'll use $(fw-shipped-all). -+# But be aware that the config file might not be included at all. -+ -+ifdef CONFIG_ACENIC_OMIT_TIGON_I -+acenic-objs := acenic/tg2.bin -+fw-shipped- += acenic/tg1.bin -+else -+acenic-objs := acenic/tg1.bin acenic/tg2.bin -+endif -+fw-shipped-$(CONFIG_3C359) += 3com/3C359.bin -+fw-shipped-$(CONFIG_ACENIC) += $(acenic-objs) -+fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \ -+ adaptec/starfire_tx.bin -+fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin -+fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw -+fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.2.9.0.fw \ -+ bnx2x/bnx2x-e1h-6.2.9.0.fw \ -+ bnx2x/bnx2x-e2-6.2.9.0.fw -+fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.2.1a.fw \ -+ bnx2/bnx2-rv2p-09-6.0.17.fw \ -+ bnx2/bnx2-rv2p-09ax-6.0.17.fw \ -+ bnx2/bnx2-mips-06-6.2.1.fw \ -+ bnx2/bnx2-rv2p-06-6.0.15.fw -+fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin -+fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin -+fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \ -+ cxgb3/t3c_psram-1.1.0.bin \ -+ cxgb3/t3fw-7.10.0.bin \ -+ cxgb3/ael2005_opt_edc.bin \ -+ cxgb3/ael2005_twx_edc.bin \ -+ cxgb3/ael2020_twx_edc.bin -+fw-shipped-$(CONFIG_DRM_MGA) += matrox/g200_warp.fw matrox/g400_warp.fw -+fw-shipped-$(CONFIG_DRM_R128) += r128/r128_cce.bin -+fw-shipped-$(CONFIG_DRM_RADEON) += radeon/R100_cp.bin radeon/R200_cp.bin \ -+ radeon/R300_cp.bin radeon/R420_cp.bin \ -+ radeon/RS690_cp.bin radeon/RS600_cp.bin \ -+ radeon/R520_cp.bin \ -+ radeon/R600_pfp.bin radeon/R600_me.bin \ -+ radeon/RV610_pfp.bin radeon/RV610_me.bin \ -+ radeon/RV630_pfp.bin radeon/RV630_me.bin \ -+ radeon/RV620_pfp.bin radeon/RV620_me.bin \ -+ radeon/RV635_pfp.bin radeon/RV635_me.bin \ -+ radeon/RV670_pfp.bin radeon/RV670_me.bin \ -+ radeon/RS780_pfp.bin radeon/RS780_me.bin \ -+ radeon/RV770_pfp.bin radeon/RV770_me.bin \ -+ radeon/RV730_pfp.bin radeon/RV730_me.bin \ -+ radeon/RV710_pfp.bin radeon/RV710_me.bin -+fw-shipped-$(CONFIG_DVB_AV7110) += av7110/bootcode.bin -+fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin -+fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \ -+ e100/d102e_ucode.bin -+fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin -+fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis \ -+ cis/DP83903.cis cis/NE2K.cis \ -+ cis/tamarack.cis cis/PE-200.cis \ -+ cis/PE520.cis -+fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis -+fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis -+fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis \ -+ cis/COMpad2.cis cis/COMpad4.cis \ -+ cis/SW_555_SER.cis cis/SW_7xx_SER.cis \ -+ cis/SW_8xx_SER.cis -+fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin -+fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \ -+ advansys/3550.bin advansys/38C0800.bin -+fw-shipped-$(CONFIG_SCSI_ISCI) += isci/isci_firmware.bin -+fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \ -+ qlogic/12160.bin -+fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.bin -+fw-shipped-$(CONFIG_INFINIBAND_QIB) += qlogic/sd7220.fw -+fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin -+fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp -+fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ -+ ess/maestro3_assp_minisrc.fw -+fw-shipped-$(CONFIG_SND_SB16_CSP) += sb16/mulaw_main.csp sb16/alaw_main.csp \ -+ sb16/ima_adpcm_init.csp \ -+ sb16/ima_adpcm_playback.csp \ -+ sb16/ima_adpcm_capture.csp -+fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \ -+ yamaha/ds1e_ctrl.fw -+fw-shipped-$(CONFIG_SND_WAVEFRONT) += yamaha/yss225_registers.bin -+fw-shipped-$(CONFIG_TEHUTI) += tehuti/bdx.bin -+fw-shipped-$(CONFIG_TIGON3) += tigon/tg3.bin tigon/tg3_tso.bin \ -+ tigon/tg3_tso5.bin -+fw-shipped-$(CONFIG_TYPHOON) += 3com/typhoon.bin -+fw-shipped-$(CONFIG_USB_DABUSB) += dabusb/firmware.fw dabusb/bitstream.bin -+fw-shipped-$(CONFIG_USB_EMI26) += emi26/loader.fw emi26/firmware.fw \ -+ emi26/bitstream.fw -+fw-shipped-$(CONFIG_USB_EMI62) += emi62/loader.fw emi62/bitstream.fw \ -+ emi62/spdif.fw emi62/midi.fw -+fw-shipped-$(CONFIG_USB_KAWETH) += kaweth/new_code.bin kaweth/trigger_code.bin \ -+ kaweth/new_code_fix.bin \ -+ kaweth/trigger_code_fix.bin -+ifdef CONFIG_FIRMWARE_IN_KERNEL -+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_MPR) += keyspan/mpr.fw -+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA18X) += keyspan/usa18x.fw -+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19) += keyspan/usa19.fw -+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19QI) += keyspan/usa19qi.fw -+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19QW) += keyspan/usa19qw.fw -+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19W) += keyspan/usa19w.fw -+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28) += keyspan/usa28.fw -+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28XA) += keyspan/usa28xa.fw -+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28XB) += keyspan/usa28xb.fw -+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28X) += keyspan/usa28x.fw -+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49W) += keyspan/usa49w.fw -+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49WLC) += keyspan/usa49wlc.fw -+else -+fw-shipped- += keyspan/mpr.fw keyspan/usa18x.fw keyspan/usa19.fw \ -+ keyspan/usa19qi.fw keyspan/usa19qw.fw keyspan/usa19w.fw \ -+ keyspan/usa28.fw keyspan/usa28xa.fw keyspan/usa28xb.fw \ -+ keyspan/usa28x.fw keyspan/usa49w.fw keyspan/usa49wlc.fw -+endif -+fw-shipped-$(CONFIG_USB_SERIAL_TI) += ti_3410.fw ti_5052.fw \ -+ mts_cdma.fw mts_gsm.fw mts_edge.fw -+fw-shipped-$(CONFIG_USB_SERIAL_EDGEPORT) += edgeport/boot.fw edgeport/boot2.fw \ -+ edgeport/down.fw edgeport/down2.fw -+fw-shipped-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += edgeport/down3.bin -+fw-shipped-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat_loader.fw whiteheat.fw \ -+ # whiteheat_loader_debug.fw -+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda/keyspan_pda.fw -+fw-shipped-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda/xircom_pgs.fw -+fw-shipped-$(CONFIG_USB_VICAM) += vicam/firmware.fw -+fw-shipped-$(CONFIG_VIDEO_CPIA2) += cpia2/stv0672_vp4.bin -+fw-shipped-$(CONFIG_YAM) += yam/1200.bin yam/9600.bin -+ -+fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) -+ -+# Directories which we _might_ need to create, so we have a rule for them. -+firmware-dirs := $(sort $(addprefix $(objtree)/$(obj)/,$(dir $(fw-external-y) $(fw-shipped-all)))) -+ -+quiet_cmd_mkdir = MKDIR $(patsubst $(objtree)/%,%,$@) -+ cmd_mkdir = mkdir -p $@ -+ -+quiet_cmd_ihex = IHEX $@ -+ cmd_ihex = $(OBJCOPY) -Iihex -Obinary $< $@ -+ -+quiet_cmd_ihex2fw = IHEX2FW $@ -+ cmd_ihex2fw = $(objtree)/$(obj)/ihex2fw $< $@ -+ -+quiet_cmd_h16tofw = H16TOFW $@ -+ cmd_h16tofw = $(objtree)/$(obj)/ihex2fw -w $< $@ -+ -+quiet_cmd_fwbin = MK_FW $@ -+ cmd_fwbin = FWNAME="$(patsubst firmware/%.gen.S,%,$@)"; \ -+ FWSTR="$(subst /,_,$(subst .,_,$(subst -,_,$(patsubst \ -+ firmware/%.gen.S,%,$@))))"; \ -+ ASM_WORD=$(if $(CONFIG_64BIT),.quad,.long); \ -+ ASM_ALIGN=$(if $(CONFIG_64BIT),3,2); \ -+ PROGBITS=$(if $(CONFIG_ARM),%,@)progbits; \ -+ echo "/* Generated by firmware/Makefile */" > $@;\ -+ echo " .section .rodata" >>$@;\ -+ echo " .p2align $${ASM_ALIGN}" >>$@;\ -+ echo "_fw_$${FWSTR}_bin:" >>$@;\ -+ echo " .incbin \"$(2)\"" >>$@;\ -+ echo "_fw_end:" >>$@;\ -+ echo " .section .rodata.str,\"aMS\",$${PROGBITS},1" >>$@;\ -+ echo " .p2align $${ASM_ALIGN}" >>$@;\ -+ echo "_fw_$${FWSTR}_name:" >>$@;\ -+ echo " .string \"$$FWNAME\"" >>$@;\ -+ echo " .section .builtin_fw,\"a\",$${PROGBITS}" >>$@;\ -+ echo " .p2align $${ASM_ALIGN}" >>$@;\ -+ echo " $${ASM_WORD} _fw_$${FWSTR}_name" >>$@;\ -+ echo " $${ASM_WORD} _fw_$${FWSTR}_bin" >>$@;\ -+ echo " $${ASM_WORD} _fw_end - _fw_$${FWSTR}_bin" >>$@; -+ -+# One of these files will change, or come into existence, whenever -+# the configuration changes between 32-bit and 64-bit. The .S files -+# need to change when that happens. -+wordsize_deps := $(wildcard include/config/64bit.h include/config/32bit.h \ -+ include/config/ppc32.h include/config/ppc64.h \ -+ include/config/superh32.h include/config/superh64.h \ -+ include/config/x86_32.h include/config/x86_64.h) -+ -+# Workaround for make < 3.81, where .SECONDEXPANSION doesn't work. -+# It'll end up depending on these targets, so make them a PHONY rule which -+# depends on _all_ the directories in $(firmware-dirs), and it'll work out OK. -+PHONY += $(objtree)/$$(%) $(objtree)/$(obj)/$$(%) -+$(objtree)/$$(%) $(objtree)/$(obj)/$$(%): $(firmware-dirs) -+ @true -+ -+# For the $$(dir %) trick, where we need % to be expanded first. -+.SECONDEXPANSION: -+ -+$(patsubst %,$(obj)/%.gen.S, $(fw-shipped-y)): %: $(wordsize_deps) \ -+ | $(objtree)/$$(dir %) -+ $(call cmd,fwbin,$(patsubst %.gen.S,%,$@)) -+$(patsubst %,$(obj)/%.gen.S, $(fw-external-y)): %: $(wordsize_deps) \ -+ include/config/extra/firmware/dir.h | $(objtree)/$$(dir %) -+ $(call cmd,fwbin,$(fwabs)/$(patsubst $(obj)/%.gen.S,%,$@)) -+ -+# The .o files depend on the binaries directly; the .S files don't. -+$(patsubst %,$(obj)/%.gen.o, $(fw-shipped-y)): %.gen.o: % -+$(patsubst %,$(obj)/%.gen.o, $(fw-external-y)): $(obj)/%.gen.o: $(fwdir)/% -+ -+# .ihex is used just as a simple way to hold binary files in a source tree -+# where binaries are frowned upon. They are directly converted with objcopy. -+$(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %) -+ $(call cmd,ihex) -+ -+# Don't depend on ihex2fw if we're installing and it already exists. -+# Putting it after | in the dependencies doesn't seem sufficient when -+# we're installing after a cross-compile, because ihex2fw has dependencies -+# on stuff like /usr/lib/gcc/ppc64-redhat-linux/4.3.0/include/stddef.h and -+# thus wants to be rebuilt. Which it can't be, if the prebuilt kernel tree -+# is exported read-only for someone to run 'make install'. -+ifeq ($(INSTALL):$(wildcard $(obj)/ihex2fw),install:$(obj)/ihex2fw) -+ihex2fw_dep := -+else -+ihex2fw_dep := $(obj)/ihex2fw -+endif -+ -+# .HEX is also Intel HEX, but where the offset and length in each record -+# is actually meaningful, because the firmware has to be loaded in a certain -+# order rather than as a single binary blob. Thus, we convert them into our -+# more compact binary representation of ihex records () -+$(obj)/%.fw: $(obj)/%.HEX $(ihex2fw_dep) | $(objtree)/$(obj)/$$(dir %) -+ $(call cmd,ihex2fw) -+ -+# .H16 is our own modified form of Intel HEX, with 16-bit length for records. -+$(obj)/%.fw: $(obj)/%.H16 $(ihex2fw_dep) | $(objtree)/$(obj)/$$(dir %) -+ $(call cmd,h16tofw) -+ -+$(firmware-dirs): -+ $(call cmd,mkdir) -+ -+obj-y += $(patsubst %,%.gen.o, $(fw-external-y)) -+obj-$(CONFIG_FIRMWARE_IN_KERNEL) += $(patsubst %,%.gen.o, $(fw-shipped-y)) -+ -+# Remove .S files and binaries created from ihex -+# (during 'make clean' .config isn't included so they're all in $(fw-shipped-)) -+targets := $(fw-shipped-) $(patsubst $(obj)/%,%, \ -+ $(shell find $(obj) -name \*.gen.S 2>/dev/null)) -+ -+# Without this, built-in.o won't be created when it's empty, and the -+# final vmlinux link will fail. -+obj-n := dummy -+ -+hostprogs-y := ihex2fw diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-fs-make-dumpable-2-require-fully-qualified-path.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-fs-make-dumpable-2-require-fully-qualified-path.patch deleted file mode 100644 index f1c3780b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-fs-make-dumpable-2-require-fully-qualified-path.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 9520628e8ceb69fa9a4aee6b57f22675d9e1b709 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] fs: make dumpable=2 require fully qualified path - -When the suid_dumpable sysctl is set to "2", and there is no core dump -pipe defined in the core_pattern sysctl, a local user can cause core files -to be written to root-writable directories, potentially with -user-controlled content. - -This means an admin can unknowningly reintroduce a variation of -CVE-2006-2451, allowing local users to gain root privileges. - - $ cat /proc/sys/fs/suid_dumpable - 2 - $ cat /proc/sys/kernel/core_pattern - core - $ ulimit -c unlimited - $ cd / - $ ls -l core - ls: cannot access core: No such file or directory - $ touch core - touch: cannot touch `core': Permission denied - $ OHAI="evil-string-here" ping localhost >/dev/null 2>&1 & - $ pid=$! - $ sleep 1 - $ kill -SEGV $pid - $ ls -l core - -rw------- 1 root kees 458752 Jun 21 11:35 core - $ sudo strings core | grep evil - OHAI=evil-string-here - -While cron has been fixed to abort reading a file when there is any -parse error, there are still other sensitive directories that will read -any file present and skip unparsable lines. - -Instead of introducing a suid_dumpable=3 mode and breaking all users of -mode 2, this only disables the unsafe portion of mode 2 (writing to disk -via relative path). Most users of mode 2 (e.g. Chrome OS) already use -a core dump pipe handler, so this change will not break them. For the -situations where a pipe handler is not defined but mode 2 is still -active, crash dumps will only be written to fully qualified paths. If a -relative path is defined (e.g. the default "core" pattern), dump -attempts will trigger a printk yelling about the lack of a fully -qualified path. - -Signed-off-by: Kees Cook -Cc: Alexander Viro -Cc: Alan Cox -Cc: "Eric W. Biederman" -Cc: Doug Ledford -Cc: Serge Hallyn -Cc: James Morris -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds - -diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt -index 9d29414..171c65a 100644 ---- a/Documentation/sysctl/fs.txt -+++ b/Documentation/sysctl/fs.txt -@@ -205,16 +205,22 @@ This value can be used to query and set the core dump mode for setuid - or otherwise protected/tainted binaries. The modes are - - 0 - (default) - traditional behaviour. Any process which has changed -- privilege levels or is execute only will not be dumped -+ privilege levels or is execute only will not be dumped. - 1 - (debug) - all processes dump core when possible. The core dump is - owned by the current user and no security is applied. This is - intended for system debugging situations only. Ptrace is unchecked. -+ This is insecure as it allows regular users to examine the memory -+ contents of privileged processes. - 2 - (suidsafe) - any binary which normally would not be dumped is dumped -- readable by root only. This allows the end user to remove -- such a dump but not access it directly. For security reasons -- core dumps in this mode will not overwrite one another or -- other files. This mode is appropriate when administrators are -- attempting to debug problems in a normal environment. -+ anyway, but only if the "core_pattern" kernel sysctl is set to -+ either a pipe handler or a fully qualified path. (For more details -+ on this limitation, see CVE-2006-2451.) This mode is appropriate -+ when administrators are attempting to debug problems in a normal -+ environment, and either have a core dump pipe handler that knows -+ to treat privileged core dumps with care, or specific directory -+ defined for catching core dumps. If a core dump happens without -+ a pipe handler or fully qualifid path, a message will be emitted -+ to syslog warning about the lack of a correct setting. - - ============================================================== - -diff --git a/fs/exec.c b/fs/exec.c -index 78199eb..9c5fb55 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -2121,6 +2121,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) - int retval = 0; - int flag = 0; - int ispipe; -+ bool need_nonrelative = false; - static atomic_t core_dump_count = ATOMIC_INIT(0); - struct coredump_params cprm = { - .signr = signr, -@@ -2146,14 +2147,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) - if (!cred) - goto fail; - /* -- * We cannot trust fsuid as being the "true" uid of the -- * process nor do we know its entire history. We only know it -- * was tainted so we dump it as root in mode 2. -+ * We cannot trust fsuid as being the "true" uid of the process -+ * nor do we know its entire history. We only know it was tainted -+ * so we dump it as root in mode 2, and only into a controlled -+ * environment (pipe handler or fully qualified path). - */ - if (__get_dumpable(cprm.mm_flags) == 2) { - /* Setuid core dump mode */ - flag = O_EXCL; /* Stop rewrite attacks */ - cred->fsuid = 0; /* Dump root private */ -+ need_nonrelative = true; - } - - retval = coredump_wait(exit_code, &core_state); -@@ -2233,6 +2236,14 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) - if (cprm.limit < binfmt->min_coredump) - goto fail_unlock; - -+ if (need_nonrelative && cn.corename[0] != '/') { -+ printk(KERN_WARNING "Pid %d(%s) can only dump core "\ -+ "to fully qualified path!\n", -+ task_tgid_vnr(current), current->comm); -+ printk(KERN_WARNING "Skipping core dump\n"); -+ goto fail_unlock; -+ } -+ - cprm.file = filp_open(cn.corename, - O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, - 0600); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-fs-overlayfs-inode.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-fs-overlayfs-inode.patch deleted file mode 100644 index 46f2e4e8..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-fs-overlayfs-inode.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -uNpr linux-3.2.65-deb7.a/fs/overlayfs/inode.c linux-3.2.65-deb7.b/fs/overlayfs/inode.c ---- linux-3.2.65-deb7.a/fs/overlayfs/inode.c 2015-04-07 13:55:17.487864270 -0700 -+++ linux-3.2.65-deb7.b/fs/overlayfs/inode.c 2015-04-07 13:56:24.948259512 -0700 -@@ -68,7 +68,7 @@ int ovl_permission(struct inode *inode, - spin_unlock(&inode->i_lock); - return -ENOENT; - } -- alias = list_entry(inode->i_dentry.next, struct dentry, d_alias); -+ alias = list_entry(inode->i_dentry.next, struct dentry, d_u.d_alias); - dget(alias); - spin_unlock(&inode->i_lock); - oe = alias->d_fsdata; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-generic-access-phys-null-check.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-generic-access-phys-null-check.patch deleted file mode 100644 index d8db45b2..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-generic-access-phys-null-check.patch +++ /dev/null @@ -1,22 +0,0 @@ -This patch adds null addr check for ioremap_prot return addr. -This fixes kernel crash seen in CM-934. - -Failure was seen when ioremap_prot fails with the below -error in arch/powerpc/mm/pgtable_32.c - -Jul 23 15:02:04 act-5652-24 kernel: __ioremap(): phys addr 0x7f46000 is RAM lr c00af1f4 - -diff --git a/mm/memory.c b/mm/memory.c -index 483e665..7f26814 100644 ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -3823,6 +3823,9 @@ int generic_access_phys(struct vm_area_struct *vma, unsigned long addr, - return -EINVAL; - - maddr = ioremap_prot(phys_addr, PAGE_SIZE, prot); -+ if (!maddr) -+ return -EFAULT; -+ - if (write) - memcpy_toio(maddr + offset, buf, len); - else diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-nowarn-sysctl.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-nowarn-sysctl.patch deleted file mode 100644 index 997137ab..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-nowarn-sysctl.patch +++ /dev/null @@ -1,28 +0,0 @@ -Change the warning for scan_unevictable_pages to DEBUG, since the warning is just annoying and serves no purpose. - -diff --git a/mm/vmscan.c b/mm/vmscan.c -index 313381c..de7701d 100644 ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -3493,7 +3493,7 @@ void check_move_unevictable_pages(struct page **pages, int nr_pages) - - static void warn_scan_unevictable_pages(void) - { -- printk_once(KERN_WARNING -+ printk_once(KERN_DEBUG - "The scan_unevictable_pages sysctl/node-interface has been " - "disabled for lack of a legitimate use case. If you have " - "one, please send an email to linux-mm@kvack.org.\n"); -diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c -index 319cd57..5c6399c 100644 ---- a/net/ipv6/ndisc.c -+++ b/net/ipv6/ndisc.c -@@ -1761,7 +1761,7 @@ static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl, - static int warned; - if (strcmp(warncomm, current->comm) && warned < 5) { - strcpy(warncomm, current->comm); -- printk(KERN_WARNING -+ printk(KERN_DEBUG - "process `%s' is using deprecated sysctl (%s) " - "net.ipv6.neigh.%s.%s; " - "Use net.ipv6.neigh.%s.%s_ms " diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-oom-proc-file-warning.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-oom-proc-file-warning.patch deleted file mode 100644 index 9b560631..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-oom-proc-file-warning.patch +++ /dev/null @@ -1,21 +0,0 @@ -#Copyright 2012 Cumulus Networks, Inc. All rights reserved. - -Reduce the log level of the oom_score_adj vs oom_adj usage warning - -Both files exist in the kernel, but they are trying to move people to -oom_score_adj. With that said, it's annoying for a warning to pop up -on normal boots. - -diff --git a/fs/proc/base.c b/fs/proc/base.c -index d851316..cbcff3e 100644 ---- a/fs/proc/base.c -+++ b/fs/proc/base.c -@@ -1076,7 +1076,7 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, - * Warn that /proc/pid/oom_adj is deprecated, see - * Documentation/feature-removal-schedule.txt. - */ -- printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n", -+ printk_once(KERN_DEBUG "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n", - current->comm, task_pid_nr(current), task_pid_nr(task), - task_pid_nr(task)); - task->signal->oom_adj = oom_adjust; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-overlayfs-v11.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-overlayfs-v11.patch deleted file mode 100644 index 851acd28..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-overlayfs-v11.patch +++ /dev/null @@ -1,3219 +0,0 @@ ---- /dev/null -+++ b/Documentation/filesystems/overlayfs.txt -@@ -0,0 +1,199 @@ -+Written by: Neil Brown -+ -+Overlay Filesystem -+================== -+ -+This document describes a prototype for a new approach to providing -+overlay-filesystem functionality in Linux (sometimes referred to as -+union-filesystems). An overlay-filesystem tries to present a -+filesystem which is the result over overlaying one filesystem on top -+of the other. -+ -+The result will inevitably fail to look exactly like a normal -+filesystem for various technical reasons. The expectation is that -+many use cases will be able to ignore these differences. -+ -+This approach is 'hybrid' because the objects that appear in the -+filesystem do not all appear to belong to that filesystem. In many -+cases an object accessed in the union will be indistinguishable -+from accessing the corresponding object from the original filesystem. -+This is most obvious from the 'st_dev' field returned by stat(2). -+ -+While directories will report an st_dev from the overlay-filesystem, -+all non-directory objects will report an st_dev from the lower or -+upper filesystem that is providing the object. Similarly st_ino will -+only be unique when combined with st_dev, and both of these can change -+over the lifetime of a non-directory object. Many applications and -+tools ignore these values and will not be affected. -+ -+Upper and Lower -+--------------- -+ -+An overlay filesystem combines two filesystems - an 'upper' filesystem -+and a 'lower' filesystem. When a name exists in both filesystems, the -+object in the 'upper' filesystem is visible while the object in the -+'lower' filesystem is either hidden or, in the case of directories, -+merged with the 'upper' object. -+ -+It would be more correct to refer to an upper and lower 'directory -+tree' rather than 'filesystem' as it is quite possible for both -+directory trees to be in the same filesystem and there is no -+requirement that the root of a filesystem be given for either upper or -+lower. -+ -+The lower filesystem can be any filesystem supported by Linux and does -+not need to be writable. The lower filesystem can even be another -+overlayfs. The upper filesystem will normally be writable and if it -+is it must support the creation of trusted.* extended attributes, and -+must provide valid d_type in readdir responses, at least for symbolic -+links - so NFS is not suitable. -+ -+A read-only overlay of two read-only filesystems may use any -+filesystem type. -+ -+Directories -+----------- -+ -+Overlaying mainly involved directories. If a given name appears in both -+upper and lower filesystems and refers to a non-directory in either, -+then the lower object is hidden - the name refers only to the upper -+object. -+ -+Where both upper and lower objects are directories, a merged directory -+is formed. -+ -+At mount time, the two directories given as mount options are combined -+into a merged directory: -+ -+ mount -t overlayfs overlayfs -olowerdir=/lower,upperdir=/upper /overlay -+ -+Then whenever a lookup is requested in such a merged directory, the -+lookup is performed in each actual directory and the combined result -+is cached in the dentry belonging to the overlay filesystem. If both -+actual lookups find directories, both are stored and a merged -+directory is created, otherwise only one is stored: the upper if it -+exists, else the lower. -+ -+Only the lists of names from directories are merged. Other content -+such as metadata and extended attributes are reported for the upper -+directory only. These attributes of the lower directory are hidden. -+ -+whiteouts and opaque directories -+-------------------------------- -+ -+In order to support rm and rmdir without changing the lower -+filesystem, an overlay filesystem needs to record in the upper filesystem -+that files have been removed. This is done using whiteouts and opaque -+directories (non-directories are always opaque). -+ -+The overlay filesystem uses extended attributes with a -+"trusted.overlay." prefix to record these details. -+ -+A whiteout is created as a symbolic link with target -+"(overlay-whiteout)" and with xattr "trusted.overlay.whiteout" set to "y". -+When a whiteout is found in the upper level of a merged directory, any -+matching name in the lower level is ignored, and the whiteout itself -+is also hidden. -+ -+A directory is made opaque by setting the xattr "trusted.overlay.opaque" -+to "y". Where the upper filesystem contains an opaque directory, any -+directory in the lower filesystem with the same name is ignored. -+ -+readdir -+------- -+ -+When a 'readdir' request is made on a merged directory, the upper and -+lower directories are each read and the name lists merged in the -+obvious way (upper is read first, then lower - entries that already -+exist are not re-added). This merged name list is cached in the -+'struct file' and so remains as long as the file is kept open. If the -+directory is opened and read by two processes at the same time, they -+will each have separate caches. A seekdir to the start of the -+directory (offset 0) followed by a readdir will cause the cache to be -+discarded and rebuilt. -+ -+This means that changes to the merged directory do not appear while a -+directory is being read. This is unlikely to be noticed by many -+programs. -+ -+seek offsets are assigned sequentially when the directories are read. -+Thus if -+ - read part of a directory -+ - remember an offset, and close the directory -+ - re-open the directory some time later -+ - seek to the remembered offset -+ -+there may be little correlation between the old and new locations in -+the list of filenames, particularly if anything has changed in the -+directory. -+ -+Readdir on directories that are not merged is simply handled by the -+underlying directory (upper or lower). -+ -+ -+Non-directories -+--------------- -+ -+Objects that are not directories (files, symlinks, device-special -+files etc.) are presented either from the upper or lower filesystem as -+appropriate. When a file in the lower filesystem is accessed in a way -+the requires write-access, such as opening for write access, changing -+some metadata etc., the file is first copied from the lower filesystem -+to the upper filesystem (copy_up). Note that creating a hard-link -+also requires copy_up, though of course creation of a symlink does -+not. -+ -+The copy_up may turn out to be unnecessary, for example if the file is -+opened for read-write but the data is not modified. -+ -+The copy_up process first makes sure that the containing directory -+exists in the upper filesystem - creating it and any parents as -+necessary. It then creates the object with the same metadata (owner, -+mode, mtime, symlink-target etc.) and then if the object is a file, the -+data is copied from the lower to the upper filesystem. Finally any -+extended attributes are copied up. -+ -+Once the copy_up is complete, the overlay filesystem simply -+provides direct access to the newly created file in the upper -+filesystem - future operations on the file are barely noticed by the -+overlay filesystem (though an operation on the name of the file such as -+rename or unlink will of course be noticed and handled). -+ -+ -+Non-standard behavior -+--------------------- -+ -+The copy_up operation essentially creates a new, identical file and -+moves it over to the old name. The new file may be on a different -+filesystem, so both st_dev and st_ino of the file may change. -+ -+Any open files referring to this inode will access the old data and -+metadata. Similarly any file locks obtained before copy_up will not -+apply to the copied up file. -+ -+On a file is opened with O_RDONLY fchmod(2), fchown(2), futimesat(2) -+and fsetxattr(2) will fail with EROFS. -+ -+If a file with multiple hard links is copied up, then this will -+"break" the link. Changes will not be propagated to other names -+referring to the same inode. -+ -+Symlinks in /proc/PID/ and /proc/PID/fd which point to a non-directory -+object in overlayfs will not contain vaid absolute paths, only -+relative paths leading up to the filesystem's root. This will be -+fixed in the future. -+ -+Some operations are not atomic, for example a crash during copy_up or -+rename will leave the filesystem in an inconsitent state. This will -+be addressed in the future. -+ -+Changes to underlying filesystems -+--------------------------------- -+ -+Offline changes, when the overlay is not mounted, are allowed to either -+the upper or the lower trees. -+ -+Changes to the underlying filesystems while part of a mounted overlay -+filesystem are not allowed. If the underlying filesystem is changed, -+the behavior of the overlay is undefined, though it will not result in -+a crash or deadlock. - -diff --git a/MAINTAINERS b/MAINTAINERS -index 768ceee..6701e5a 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -4910,6 +4910,13 @@ F: drivers/scsi/osd/ - F: include/scsi/osd_* - F: fs/exofs/ - -+OVERLAYFS FILESYSTEM -+M: Miklos Szeredi -+L: linux-fsdevel@vger.kernel.org -+S: Supported -+F: fs/overlayfs/* -+F: Documentation/filesystems/overlayfs.txt -+ - P54 WIRELESS DRIVER - M: Christian Lamparter - L: linux-wireless@vger.kernel.org -diff --git a/fs/Kconfig b/fs/Kconfig -index ded2ffb..7f618e9 100644 ---- a/fs/Kconfig -+++ b/fs/Kconfig -@@ -63,6 +63,7 @@ source "fs/quota/Kconfig" - - source "fs/autofs4/Kconfig" - source "fs/fuse/Kconfig" -+source "fs/overlayfs/Kconfig" - - config CUSE - tristate "Character device in Userspace support" -diff --git a/fs/Makefile b/fs/Makefile -index 680ad8a..1727784 100644 ---- a/fs/Makefile -+++ b/fs/Makefile -@@ -104,6 +104,7 @@ obj-$(CONFIG_QNX4FS_FS) += qnx4/ - obj-$(CONFIG_AUTOFS4_FS) += autofs4/ - obj-$(CONFIG_ADFS_FS) += adfs/ - obj-$(CONFIG_FUSE_FS) += fuse/ -+obj-$(CONFIG_OVERLAYFS_FS) += overlayfs/ - obj-$(CONFIG_UDF_FS) += udf/ - obj-$(CONFIG_SUN_OPENPROMFS) += openpromfs/ - obj-$(CONFIG_OMFS_FS) += omfs/ -diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c -index 94afdfd..ddee24c 100644 ---- a/fs/ecryptfs/main.c -+++ b/fs/ecryptfs/main.c -@@ -566,6 +566,13 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags - s->s_maxbytes = path.dentry->d_sb->s_maxbytes; - s->s_blocksize = path.dentry->d_sb->s_blocksize; - s->s_magic = ECRYPTFS_SUPER_MAGIC; -+ s->s_stack_depth = path.dentry->d_sb->s_stack_depth + 1; -+ -+ rc = -EINVAL; -+ if (s->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { -+ printk(KERN_ERR "eCryptfs: maximum fs stacking depth exceeded\n"); -+ goto out_free; -+ } - - inode = ecryptfs_get_inode(path.dentry->d_inode, s); - rc = PTR_ERR(inode); -diff --git a/fs/namespace.c b/fs/namespace.c -index 99d2154..0719c07 100644 ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -1493,6 +1493,23 @@ void drop_collected_mounts(struct vfsmount *mnt) - release_mounts(&umount_list); - } - -+struct vfsmount *clone_private_mount(struct path *path) -+{ -+ struct vfsmount *mnt; -+ -+ if (IS_MNT_UNBINDABLE(path->mnt)) -+ return ERR_PTR(-EINVAL); -+ -+ down_read(&namespace_sem); -+ mnt = clone_mnt(path->mnt, path->dentry, CL_PRIVATE); -+ up_read(&namespace_sem); -+ if (!mnt) -+ return ERR_PTR(-ENOMEM); -+ -+ return mnt; -+} -+EXPORT_SYMBOL_GPL(clone_private_mount); -+ - int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, - struct vfsmount *root) - { -diff --git a/fs/open.c b/fs/open.c -index a57313e..1d4de26 100644 ---- a/fs/open.c -+++ b/fs/open.c -@@ -645,8 +645,7 @@ static inline int __get_file_write_access(struct inode *inode, - return error; - } - --static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, -- struct file *f, -+static struct file *__dentry_open(struct path *path, struct file *f, - int (*open)(struct inode *, struct file *), - const struct cred *cred) - { -@@ -654,15 +653,16 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, - struct inode *inode; - int error; - -+ path_get(path); - f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK | - FMODE_PREAD | FMODE_PWRITE; - - if (unlikely(f->f_flags & O_PATH)) - f->f_mode = FMODE_PATH; - -- inode = dentry->d_inode; -+ inode = path->dentry->d_inode; - if (f->f_mode & FMODE_WRITE) { -- error = __get_file_write_access(inode, mnt); -+ error = __get_file_write_access(inode, path->mnt); - if (error) - goto cleanup_file; - if (!special_file(inode->i_mode)) -@@ -670,8 +670,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, - } - - f->f_mapping = inode->i_mapping; -- f->f_path.dentry = dentry; -- f->f_path.mnt = mnt; -+ f->f_path = *path; - f->f_pos = 0; - file_sb_list_add(f, inode->i_sb); - -@@ -728,7 +727,7 @@ cleanup_all: - * here, so just reset the state. - */ - file_reset_write(f); -- mnt_drop_write(mnt); -+ mnt_drop_write(path->mnt); - } - } - file_sb_list_del(f); -@@ -736,8 +735,7 @@ cleanup_all: - f->f_path.mnt = NULL; - cleanup_file: - put_filp(f); -- dput(dentry); -- mntput(mnt); -+ path_put(path); - return ERR_PTR(error); - } - -@@ -763,14 +761,14 @@ cleanup_file: - struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, - int (*open)(struct inode *, struct file *)) - { -+ struct path path = { .dentry = dentry, .mnt = nd->path.mnt }; - const struct cred *cred = current_cred(); - - if (IS_ERR(nd->intent.open.file)) - goto out; - if (IS_ERR(dentry)) - goto out_err; -- nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), -- nd->intent.open.file, -+ nd->intent.open.file = __dentry_open(&path, nd->intent.open.file, - open, cred); - out: - return nd->intent.open.file; -@@ -799,10 +797,17 @@ struct file *nameidata_to_filp(struct nameidata *nd) - - /* Has the filesystem initialised the file for us? */ - if (filp->f_path.dentry == NULL) { -- path_get(&nd->path); -- filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp, -- NULL, cred); -+ struct inode *inode = nd->path.dentry->d_inode; -+ -+ if (inode->i_op->open) { -+ int flags = filp->f_flags; -+ put_filp(filp); -+ filp = inode->i_op->open(nd->path.dentry, flags, cred); -+ } else { -+ filp = __dentry_open(&nd->path, filp, NULL, cred); -+ } - } -+ - return filp; - } - -@@ -813,26 +818,45 @@ struct file *nameidata_to_filp(struct nameidata *nd) - struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags, - const struct cred *cred) - { -- int error; -- struct file *f; -- -- validate_creds(cred); -+ struct path path = { .dentry = dentry, .mnt = mnt }; -+ struct file *ret; - - /* We must always pass in a valid mount pointer. */ - BUG_ON(!mnt); - -- error = -ENFILE; -+ ret = vfs_open(&path, flags, cred); -+ path_put(&path); -+ -+ return ret; -+} -+EXPORT_SYMBOL(dentry_open); -+ -+/** -+ * vfs_open - open the file at the given path -+ * @path: path to open -+ * @flags: open flags -+ * @cred: credentials to use -+ * -+ * Open the file. If successful, the returned file will have acquired -+ * an additional reference for path. -+ */ -+struct file *vfs_open(struct path *path, int flags, const struct cred *cred) -+{ -+ struct file *f; -+ struct inode *inode = path->dentry->d_inode; -+ -+ validate_creds(cred); -+ -+ if (inode->i_op->open) -+ return inode->i_op->open(path->dentry, flags, cred); - f = get_empty_filp(); -- if (f == NULL) { -- dput(dentry); -- mntput(mnt); -- return ERR_PTR(error); -- } -+ if (f == NULL) -+ return ERR_PTR(-ENFILE); - - f->f_flags = flags; -- return __dentry_open(dentry, mnt, f, NULL, cred); -+ return __dentry_open(path, f, NULL, cred); - } --EXPORT_SYMBOL(dentry_open); -+EXPORT_SYMBOL(vfs_open); - - static void __put_unused_fd(struct files_struct *files, unsigned int fd) - { -diff --git a/fs/overlayfs/Kconfig b/fs/overlayfs/Kconfig -new file mode 100644 -index 0000000..c4517da ---- /dev/null -+++ b/fs/overlayfs/Kconfig -@@ -0,0 +1,4 @@ -+config OVERLAYFS_FS -+ tristate "Overlay filesystem support" -+ help -+ Add support for overlay filesystem. -diff --git a/fs/overlayfs/Makefile b/fs/overlayfs/Makefile -new file mode 100644 -index 0000000..8f91889 ---- /dev/null -+++ b/fs/overlayfs/Makefile -@@ -0,0 +1,7 @@ -+# -+# Makefile for the overlay filesystem. -+# -+ -+obj-$(CONFIG_OVERLAYFS_FS) += overlayfs.o -+ -+overlayfs-objs := super.o inode.o dir.o readdir.o copy_up.o -diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c -new file mode 100644 -index 0000000..308a80a ---- /dev/null -+++ b/fs/overlayfs/copy_up.c -@@ -0,0 +1,383 @@ -+/* -+ * -+ * Copyright (C) 2011 Novell 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 "overlayfs.h" -+ -+#define OVL_COPY_UP_CHUNK_SIZE (1 << 20) -+ -+static int ovl_copy_up_xattr(struct dentry *old, struct dentry *new) -+{ -+ ssize_t list_size, size; -+ char *buf, *name, *value; -+ int error; -+ -+ if (!old->d_inode->i_op->getxattr || -+ !new->d_inode->i_op->getxattr) -+ return 0; -+ -+ list_size = vfs_listxattr(old, NULL, 0); -+ if (list_size <= 0) { -+ if (list_size == -EOPNOTSUPP) -+ return 0; -+ return list_size; -+ } -+ -+ buf = kzalloc(list_size, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ error = -ENOMEM; -+ value = kmalloc(XATTR_SIZE_MAX, GFP_KERNEL); -+ if (!value) -+ goto out; -+ -+ list_size = vfs_listxattr(old, buf, list_size); -+ if (list_size <= 0) { -+ error = list_size; -+ goto out_free_value; -+ } -+ -+ for (name = buf; name < (buf + list_size); name += strlen(name) + 1) { -+ size = vfs_getxattr(old, name, value, XATTR_SIZE_MAX); -+ if (size <= 0) { -+ error = size; -+ goto out_free_value; -+ } -+ error = vfs_setxattr(new, name, value, size, 0); -+ if (error) -+ goto out_free_value; -+ } -+ -+out_free_value: -+ kfree(value); -+out: -+ kfree(buf); -+ return error; -+} -+ -+static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len) -+{ -+ struct file *old_file; -+ struct file *new_file; -+ int error = 0; -+ -+ if (len == 0) -+ return 0; -+ -+ old_file = vfs_open(old, O_RDONLY, current_cred()); -+ if (IS_ERR(old_file)) -+ return PTR_ERR(old_file); -+ -+ new_file = vfs_open(new, O_WRONLY, current_cred()); -+ if (IS_ERR(new_file)) { -+ error = PTR_ERR(new_file); -+ goto out_fput; -+ } -+ -+ /* FIXME: copy up sparse files efficiently */ -+ while (len) { -+ loff_t offset = new_file->f_pos; -+ size_t this_len = OVL_COPY_UP_CHUNK_SIZE; -+ long bytes; -+ -+ if (len < this_len) -+ this_len = len; -+ -+ if (signal_pending_state(TASK_KILLABLE, current)) { -+ error = -EINTR; -+ break; -+ } -+ -+ bytes = do_splice_direct(old_file, &offset, new_file, this_len, -+ SPLICE_F_MOVE); -+ if (bytes <= 0) { -+ error = bytes; -+ break; -+ } -+ -+ len -= bytes; -+ } -+ -+ fput(new_file); -+out_fput: -+ fput(old_file); -+ return error; -+} -+ -+static char *ovl_read_symlink(struct dentry *realdentry) -+{ -+ int res; -+ char *buf; -+ struct inode *inode = realdentry->d_inode; -+ mm_segment_t old_fs; -+ -+ res = -EINVAL; -+ if (!inode->i_op->readlink) -+ goto err; -+ -+ res = -ENOMEM; -+ buf = (char *) __get_free_page(GFP_KERNEL); -+ if (!buf) -+ goto err; -+ -+ old_fs = get_fs(); -+ set_fs(get_ds()); -+ /* The cast to a user pointer is valid due to the set_fs() */ -+ res = inode->i_op->readlink(realdentry, -+ (char __user *)buf, PAGE_SIZE - 1); -+ set_fs(old_fs); -+ if (res < 0) { -+ free_page((unsigned long) buf); -+ goto err; -+ } -+ buf[res] = '\0'; -+ -+ return buf; -+ -+err: -+ return ERR_PTR(res); -+} -+ -+static int ovl_set_timestamps(struct dentry *upperdentry, struct kstat *stat) -+{ -+ struct iattr attr = { -+ .ia_valid = ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET, -+ .ia_atime = stat->atime, -+ .ia_mtime = stat->mtime, -+ }; -+ -+ return notify_change(upperdentry, &attr); -+} -+ -+static int ovl_set_mode(struct dentry *upperdentry, umode_t mode) -+{ -+ struct iattr attr = { -+ .ia_valid = ATTR_MODE, -+ .ia_mode = mode, -+ }; -+ -+ return notify_change(upperdentry, &attr); -+} -+ -+static int ovl_copy_up_locked(struct dentry *upperdir, struct dentry *dentry, -+ struct path *lowerpath, struct kstat *stat, -+ const char *link) -+{ -+ int err; -+ struct path newpath; -+ umode_t mode = stat->mode; -+ -+ /* Can't properly set mode on creation because of the umask */ -+ stat->mode &= S_IFMT; -+ -+ ovl_path_upper(dentry, &newpath); -+ WARN_ON(newpath.dentry); -+ newpath.dentry = ovl_upper_create(upperdir, dentry, stat, link); -+ if (IS_ERR(newpath.dentry)) -+ return PTR_ERR(newpath.dentry); -+ -+ if (S_ISREG(stat->mode)) { -+ err = ovl_copy_up_data(lowerpath, &newpath, stat->size); -+ if (err) -+ goto err_remove; -+ } -+ -+ err = ovl_copy_up_xattr(lowerpath->dentry, newpath.dentry); -+ if (err) -+ goto err_remove; -+ -+ mutex_lock(&newpath.dentry->d_inode->i_mutex); -+ if (!S_ISLNK(stat->mode)) -+ err = ovl_set_mode(newpath.dentry, mode); -+ if (!err) -+ err = ovl_set_timestamps(newpath.dentry, stat); -+ mutex_unlock(&newpath.dentry->d_inode->i_mutex); -+ if (err) -+ goto err_remove; -+ -+ ovl_dentry_update(dentry, newpath.dentry); -+ -+ /* -+ * Easiest way to get rid of the lower dentry reference is to -+ * drop this dentry. This is neither needed nor possible for -+ * directories. -+ */ -+ if (!S_ISDIR(stat->mode)) -+ d_drop(dentry); -+ -+ return 0; -+ -+err_remove: -+ if (S_ISDIR(stat->mode)) -+ vfs_rmdir(upperdir->d_inode, newpath.dentry); -+ else -+ vfs_unlink(upperdir->d_inode, newpath.dentry); -+ -+ dput(newpath.dentry); -+ -+ return err; -+} -+ -+/* -+ * Copy up a single dentry -+ * -+ * Directory renames only allowed on "pure upper" (already created on -+ * upper filesystem, never copied up). Directories which are on lower or -+ * are merged may not be renamed. For these -EXDEV is returned and -+ * userspace has to deal with it. This means, when copying up a -+ * directory we can rely on it and ancestors being stable. -+ * -+ * Non-directory renames start with copy up of source if necessary. The -+ * actual rename will only proceed once the copy up was successful. Copy -+ * up uses upper parent i_mutex for exclusion. Since rename can change -+ * d_parent it is possible that the copy up will lock the old parent. At -+ * that point the file will have already been copied up anyway. -+ */ -+static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, -+ struct path *lowerpath, struct kstat *stat) -+{ -+ int err; -+ struct kstat pstat; -+ struct path parentpath; -+ struct dentry *upperdir; -+ const struct cred *old_cred; -+ struct cred *override_cred; -+ char *link = NULL; -+ -+ ovl_path_upper(parent, &parentpath); -+ upperdir = parentpath.dentry; -+ -+ err = vfs_getattr(parentpath.mnt, parentpath.dentry, &pstat); -+ if (err) -+ return err; -+ -+ if (S_ISLNK(stat->mode)) { -+ link = ovl_read_symlink(lowerpath->dentry); -+ if (IS_ERR(link)) -+ return PTR_ERR(link); -+ } -+ -+ err = -ENOMEM; -+ override_cred = prepare_creds(); -+ if (!override_cred) -+ goto out_free_link; -+ -+ override_cred->fsuid = stat->uid; -+ override_cred->fsgid = stat->gid; -+ /* -+ * CAP_SYS_ADMIN for copying up extended attributes -+ * CAP_DAC_OVERRIDE for create -+ * CAP_FOWNER for chmod, timestamp update -+ * CAP_FSETID for chmod -+ * CAP_MKNOD for mknod -+ */ -+ cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); -+ cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE); -+ cap_raise(override_cred->cap_effective, CAP_FOWNER); -+ cap_raise(override_cred->cap_effective, CAP_FSETID); -+ cap_raise(override_cred->cap_effective, CAP_MKNOD); -+ old_cred = override_creds(override_cred); -+ -+ mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT); -+ if (ovl_path_type(dentry) != OVL_PATH_LOWER) { -+ err = 0; -+ } else { -+ err = ovl_copy_up_locked(upperdir, dentry, lowerpath, -+ stat, link); -+ if (!err) { -+ /* Restore timestamps on parent (best effort) */ -+ ovl_set_timestamps(upperdir, &pstat); -+ } -+ } -+ -+ mutex_unlock(&upperdir->d_inode->i_mutex); -+ -+ revert_creds(old_cred); -+ put_cred(override_cred); -+ -+out_free_link: -+ if (link) -+ free_page((unsigned long) link); -+ -+ return err; -+} -+ -+int ovl_copy_up(struct dentry *dentry) -+{ -+ int err; -+ -+ err = 0; -+ while (!err) { -+ struct dentry *next; -+ struct dentry *parent; -+ struct path lowerpath; -+ struct kstat stat; -+ enum ovl_path_type type = ovl_path_type(dentry); -+ -+ if (type != OVL_PATH_LOWER) -+ break; -+ -+ next = dget(dentry); -+ /* find the topmost dentry not yet copied up */ -+ for (;;) { -+ parent = dget_parent(next); -+ -+ type = ovl_path_type(parent); -+ if (type != OVL_PATH_LOWER) -+ break; -+ -+ dput(next); -+ next = parent; -+ } -+ -+ ovl_path_lower(next, &lowerpath); -+ err = vfs_getattr(lowerpath.mnt, lowerpath.dentry, &stat); -+ if (!err) -+ err = ovl_copy_up_one(parent, next, &lowerpath, &stat); -+ -+ dput(parent); -+ dput(next); -+ } -+ -+ return err; -+} -+ -+/* Optimize by not copying up the file first and truncating later */ -+int ovl_copy_up_truncate(struct dentry *dentry, loff_t size) -+{ -+ int err; -+ struct kstat stat; -+ struct path lowerpath; -+ struct dentry *parent = dget_parent(dentry); -+ -+ err = ovl_copy_up(parent); -+ if (err) -+ goto out_dput_parent; -+ -+ ovl_path_lower(dentry, &lowerpath); -+ err = vfs_getattr(lowerpath.mnt, lowerpath.dentry, &stat); -+ if (err) -+ goto out_dput_parent; -+ -+ if (size < stat.size) -+ stat.size = size; -+ -+ err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat); -+ -+out_dput_parent: -+ dput(parent); -+ return err; -+} -diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c -new file mode 100644 -index 0000000..834bed8 ---- /dev/null -+++ b/fs/overlayfs/dir.c -@@ -0,0 +1,596 @@ -+/* -+ * -+ * Copyright (C) 2011 Novell 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 "overlayfs.h" -+ -+static const char *ovl_whiteout_symlink = "(overlay-whiteout)"; -+ -+static int ovl_whiteout(struct dentry *upperdir, struct dentry *dentry) -+{ -+ int err; -+ struct dentry *newdentry; -+ const struct cred *old_cred; -+ struct cred *override_cred; -+ -+ /* FIXME: recheck lower dentry to see if whiteout is really needed */ -+ -+ err = -ENOMEM; -+ override_cred = prepare_creds(); -+ if (!override_cred) -+ goto out; -+ -+ /* -+ * CAP_SYS_ADMIN for setxattr -+ * CAP_DAC_OVERRIDE for symlink creation -+ * CAP_FOWNER for unlink in sticky directory -+ */ -+ cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); -+ cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE); -+ cap_raise(override_cred->cap_effective, CAP_FOWNER); -+ override_cred->fsuid = 0; -+ override_cred->fsgid = 0; -+ old_cred = override_creds(override_cred); -+ -+ newdentry = lookup_one_len(dentry->d_name.name, upperdir, -+ dentry->d_name.len); -+ err = PTR_ERR(newdentry); -+ if (IS_ERR(newdentry)) -+ goto out_put_cred; -+ -+ /* Just been removed within the same locked region */ -+ WARN_ON(newdentry->d_inode); -+ -+ err = vfs_symlink(upperdir->d_inode, newdentry, ovl_whiteout_symlink); -+ if (err) -+ goto out_dput; -+ -+ ovl_dentry_version_inc(dentry->d_parent); -+ -+ err = vfs_setxattr(newdentry, ovl_whiteout_xattr, "y", 1, 0); -+ if (err) -+ vfs_unlink(upperdir->d_inode, newdentry); -+ -+out_dput: -+ dput(newdentry); -+out_put_cred: -+ revert_creds(old_cred); -+ put_cred(override_cred); -+out: -+ if (err) { -+ /* -+ * There's no way to recover from failure to whiteout. -+ * What should we do? Log a big fat error and... ? -+ */ -+ printk(KERN_ERR "overlayfs: ERROR - failed to whiteout '%s'\n", -+ dentry->d_name.name); -+ } -+ -+ return err; -+} -+ -+static struct dentry *ovl_lookup_create(struct dentry *upperdir, -+ struct dentry *template) -+{ -+ int err; -+ struct dentry *newdentry; -+ struct qstr *name = &template->d_name; -+ -+ newdentry = lookup_one_len(name->name, upperdir, name->len); -+ if (IS_ERR(newdentry)) -+ return newdentry; -+ -+ if (newdentry->d_inode) { -+ const struct cred *old_cred; -+ struct cred *override_cred; -+ -+ /* No need to check whiteout if lower parent is non-existent */ -+ err = -EEXIST; -+ if (!ovl_dentry_lower(template->d_parent)) -+ goto out_dput; -+ -+ if (!S_ISLNK(newdentry->d_inode->i_mode)) -+ goto out_dput; -+ -+ err = -ENOMEM; -+ override_cred = prepare_creds(); -+ if (!override_cred) -+ goto out_dput; -+ -+ /* -+ * CAP_SYS_ADMIN for getxattr -+ * CAP_FOWNER for unlink in sticky directory -+ */ -+ cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); -+ cap_raise(override_cred->cap_effective, CAP_FOWNER); -+ old_cred = override_creds(override_cred); -+ -+ err = -EEXIST; -+ if (ovl_is_whiteout(newdentry)) -+ err = vfs_unlink(upperdir->d_inode, newdentry); -+ -+ revert_creds(old_cred); -+ put_cred(override_cred); -+ if (err) -+ goto out_dput; -+ -+ dput(newdentry); -+ newdentry = lookup_one_len(name->name, upperdir, name->len); -+ if (IS_ERR(newdentry)) { -+ ovl_whiteout(upperdir, template); -+ return newdentry; -+ } -+ -+ /* -+ * Whiteout just been successfully removed, parent -+ * i_mutex is still held, there's no way the lookup -+ * could return positive. -+ */ -+ WARN_ON(newdentry->d_inode); -+ } -+ -+ return newdentry; -+ -+out_dput: -+ dput(newdentry); -+ return ERR_PTR(err); -+} -+ -+struct dentry *ovl_upper_create(struct dentry *upperdir, struct dentry *dentry, -+ struct kstat *stat, const char *link) -+{ -+ int err; -+ struct dentry *newdentry; -+ struct inode *dir = upperdir->d_inode; -+ -+ newdentry = ovl_lookup_create(upperdir, dentry); -+ if (IS_ERR(newdentry)) -+ goto out; -+ -+ switch (stat->mode & S_IFMT) { -+ case S_IFREG: -+ err = vfs_create(dir, newdentry, stat->mode, NULL); -+ break; -+ -+ case S_IFDIR: -+ err = vfs_mkdir(dir, newdentry, stat->mode); -+ break; -+ -+ case S_IFCHR: -+ case S_IFBLK: -+ case S_IFIFO: -+ case S_IFSOCK: -+ err = vfs_mknod(dir, newdentry, stat->mode, stat->rdev); -+ break; -+ -+ case S_IFLNK: -+ err = vfs_symlink(dir, newdentry, link); -+ break; -+ -+ default: -+ err = -EPERM; -+ } -+ if (err) { -+ if (ovl_dentry_is_opaque(dentry)) -+ ovl_whiteout(upperdir, dentry); -+ dput(newdentry); -+ newdentry = ERR_PTR(err); -+ } else if (WARN_ON(!newdentry->d_inode)) { -+ /* -+ * Not quite sure if non-instantiated dentry is legal or not. -+ * VFS doesn't seem to care so check and warn here. -+ */ -+ dput(newdentry); -+ newdentry = ERR_PTR(-ENOENT); -+ } -+ -+out: -+ return newdentry; -+ -+} -+ -+static int ovl_set_opaque(struct dentry *upperdentry) -+{ -+ int err; -+ const struct cred *old_cred; -+ struct cred *override_cred; -+ -+ override_cred = prepare_creds(); -+ if (!override_cred) -+ return -ENOMEM; -+ -+ /* CAP_SYS_ADMIN for setxattr of "trusted" namespace */ -+ cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); -+ old_cred = override_creds(override_cred); -+ err = vfs_setxattr(upperdentry, ovl_opaque_xattr, "y", 1, 0); -+ revert_creds(old_cred); -+ put_cred(override_cred); -+ -+ return err; -+} -+ -+static int ovl_remove_opaque(struct dentry *upperdentry) -+{ -+ int err; -+ const struct cred *old_cred; -+ struct cred *override_cred; -+ -+ override_cred = prepare_creds(); -+ if (!override_cred) -+ return -ENOMEM; -+ -+ /* CAP_SYS_ADMIN for removexattr of "trusted" namespace */ -+ cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); -+ old_cred = override_creds(override_cred); -+ err = vfs_removexattr(upperdentry, ovl_opaque_xattr); -+ revert_creds(old_cred); -+ put_cred(override_cred); -+ -+ return err; -+} -+ -+static int ovl_dir_getattr(struct vfsmount *mnt, struct dentry *dentry, -+ struct kstat *stat) -+{ -+ int err; -+ enum ovl_path_type type; -+ struct path realpath; -+ -+ type = ovl_path_real(dentry, &realpath); -+ err = vfs_getattr(realpath.mnt, realpath.dentry, stat); -+ if (err) -+ return err; -+ -+ stat->dev = dentry->d_sb->s_dev; -+ stat->ino = dentry->d_inode->i_ino; -+ -+ /* -+ * It's probably not worth it to count subdirs to get the -+ * correct link count. nlink=1 seems to pacify 'find' and -+ * other utilities. -+ */ -+ if (type == OVL_PATH_MERGE) -+ stat->nlink = 1; -+ -+ return 0; -+} -+ -+static int ovl_create_object(struct dentry *dentry, int mode, dev_t rdev, -+ const char *link) -+{ -+ int err; -+ struct dentry *newdentry; -+ struct dentry *upperdir; -+ struct inode *inode; -+ struct kstat stat = { -+ .mode = mode, -+ .rdev = rdev, -+ }; -+ -+ err = -ENOMEM; -+ inode = ovl_new_inode(dentry->d_sb, mode, dentry->d_fsdata); -+ if (!inode) -+ goto out; -+ -+ err = ovl_copy_up(dentry->d_parent); -+ if (err) -+ goto out_iput; -+ -+ upperdir = ovl_dentry_upper(dentry->d_parent); -+ mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT); -+ -+ newdentry = ovl_upper_create(upperdir, dentry, &stat, link); -+ err = PTR_ERR(newdentry); -+ if (IS_ERR(newdentry)) -+ goto out_unlock; -+ -+ ovl_dentry_version_inc(dentry->d_parent); -+ if (ovl_dentry_is_opaque(dentry) && S_ISDIR(mode)) { -+ err = ovl_set_opaque(newdentry); -+ if (err) { -+ vfs_rmdir(upperdir->d_inode, newdentry); -+ ovl_whiteout(upperdir, dentry); -+ goto out_dput; -+ } -+ } -+ ovl_dentry_update(dentry, newdentry); -+ d_instantiate(dentry, inode); -+ inode = NULL; -+ newdentry = NULL; -+ err = 0; -+ -+out_dput: -+ dput(newdentry); -+out_unlock: -+ mutex_unlock(&upperdir->d_inode->i_mutex); -+out_iput: -+ iput(inode); -+out: -+ return err; -+} -+ -+static int ovl_create(struct inode *dir, struct dentry *dentry, int mode, -+ struct nameidata *nd) -+{ -+ return ovl_create_object(dentry, (mode & 07777) | S_IFREG, 0, NULL); -+} -+ -+static int ovl_mkdir(struct inode *dir, struct dentry *dentry, int mode) -+{ -+ return ovl_create_object(dentry, (mode & 07777) | S_IFDIR, 0, NULL); -+} -+ -+static int ovl_mknod(struct inode *dir, struct dentry *dentry, int mode, -+ dev_t rdev) -+{ -+ return ovl_create_object(dentry, mode, rdev, NULL); -+} -+ -+static int ovl_symlink(struct inode *dir, struct dentry *dentry, -+ const char *link) -+{ -+ return ovl_create_object(dentry, S_IFLNK, 0, link); -+} -+ -+static int ovl_do_remove(struct dentry *dentry, bool is_dir) -+{ -+ int err; -+ enum ovl_path_type type; -+ struct path realpath; -+ struct dentry *upperdir; -+ -+ err = ovl_copy_up(dentry->d_parent); -+ if (err) -+ return err; -+ -+ upperdir = ovl_dentry_upper(dentry->d_parent); -+ mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT); -+ type = ovl_path_real(dentry, &realpath); -+ if (type != OVL_PATH_LOWER) { -+ err = -ESTALE; -+ if (realpath.dentry->d_parent != upperdir) -+ goto out_d_drop; -+ -+ /* FIXME: create whiteout up front and rename to target */ -+ -+ if (is_dir) -+ err = vfs_rmdir(upperdir->d_inode, realpath.dentry); -+ else -+ err = vfs_unlink(upperdir->d_inode, realpath.dentry); -+ if (err) -+ goto out_d_drop; -+ -+ ovl_dentry_version_inc(dentry->d_parent); -+ } -+ -+ if (type != OVL_PATH_UPPER || ovl_dentry_is_opaque(dentry)) -+ err = ovl_whiteout(upperdir, dentry); -+ -+ /* -+ * Keeping this dentry hashed would mean having to release -+ * upperpath/lowerpath, which could only be done if we are the -+ * sole user of this dentry. Too tricky... Just unhash for -+ * now. -+ */ -+out_d_drop: -+ d_drop(dentry); -+ mutex_unlock(&upperdir->d_inode->i_mutex); -+ -+ return err; -+} -+ -+static int ovl_unlink(struct inode *dir, struct dentry *dentry) -+{ -+ return ovl_do_remove(dentry, false); -+} -+ -+ -+static int ovl_rmdir(struct inode *dir, struct dentry *dentry) -+{ -+ int err; -+ enum ovl_path_type type; -+ -+ type = ovl_path_type(dentry); -+ if (type != OVL_PATH_UPPER) { -+ err = ovl_check_empty_and_clear(dentry, type); -+ if (err) -+ return err; -+ } -+ -+ return ovl_do_remove(dentry, true); -+} -+ -+static int ovl_link(struct dentry *old, struct inode *newdir, -+ struct dentry *new) -+{ -+ int err; -+ struct dentry *olddentry; -+ struct dentry *newdentry; -+ struct dentry *upperdir; -+ -+ err = ovl_copy_up(old); -+ if (err) -+ goto out; -+ -+ err = ovl_copy_up(new->d_parent); -+ if (err) -+ goto out; -+ -+ upperdir = ovl_dentry_upper(new->d_parent); -+ mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT); -+ newdentry = ovl_lookup_create(upperdir, new); -+ err = PTR_ERR(newdentry); -+ if (IS_ERR(newdentry)) -+ goto out_unlock; -+ -+ olddentry = ovl_dentry_upper(old); -+ err = vfs_link(olddentry, upperdir->d_inode, newdentry); -+ if (!err) { -+ if (WARN_ON(!newdentry->d_inode)) { -+ dput(newdentry); -+ err = -ENOENT; -+ goto out_unlock; -+ } -+ -+ ovl_dentry_version_inc(new->d_parent); -+ ovl_dentry_update(new, newdentry); -+ -+ ihold(old->d_inode); -+ d_instantiate(new, old->d_inode); -+ } else { -+ if (ovl_dentry_is_opaque(new)) -+ ovl_whiteout(upperdir, new); -+ dput(newdentry); -+ } -+out_unlock: -+ mutex_unlock(&upperdir->d_inode->i_mutex); -+out: -+ return err; -+ -+} -+ -+static int ovl_rename(struct inode *olddir, struct dentry *old, -+ struct inode *newdir, struct dentry *new) -+{ -+ int err; -+ enum ovl_path_type old_type; -+ enum ovl_path_type new_type; -+ struct dentry *old_upperdir; -+ struct dentry *new_upperdir; -+ struct dentry *olddentry; -+ struct dentry *newdentry; -+ struct dentry *trap; -+ bool old_opaque; -+ bool new_opaque; -+ bool new_create = false; -+ bool is_dir = S_ISDIR(old->d_inode->i_mode); -+ -+ /* Don't copy up directory trees */ -+ old_type = ovl_path_type(old); -+ if (old_type != OVL_PATH_UPPER && is_dir) -+ return -EXDEV; -+ -+ if (new->d_inode) { -+ new_type = ovl_path_type(new); -+ -+ if (new_type == OVL_PATH_LOWER && old_type == OVL_PATH_LOWER) { -+ if (ovl_dentry_lower(old)->d_inode == -+ ovl_dentry_lower(new)->d_inode) -+ return 0; -+ } -+ if (new_type != OVL_PATH_LOWER && old_type != OVL_PATH_LOWER) { -+ if (ovl_dentry_upper(old)->d_inode == -+ ovl_dentry_upper(new)->d_inode) -+ return 0; -+ } -+ -+ if (new_type != OVL_PATH_UPPER && -+ S_ISDIR(new->d_inode->i_mode)) { -+ err = ovl_check_empty_and_clear(new, new_type); -+ if (err) -+ return err; -+ } -+ } else { -+ new_type = OVL_PATH_UPPER; -+ } -+ -+ err = ovl_copy_up(old); -+ if (err) -+ return err; -+ -+ err = ovl_copy_up(new->d_parent); -+ if (err) -+ return err; -+ -+ old_upperdir = ovl_dentry_upper(old->d_parent); -+ new_upperdir = ovl_dentry_upper(new->d_parent); -+ -+ trap = lock_rename(new_upperdir, old_upperdir); -+ -+ olddentry = ovl_dentry_upper(old); -+ newdentry = ovl_dentry_upper(new); -+ if (newdentry) { -+ dget(newdentry); -+ } else { -+ new_create = true; -+ newdentry = ovl_lookup_create(new_upperdir, new); -+ err = PTR_ERR(newdentry); -+ if (IS_ERR(newdentry)) -+ goto out_unlock; -+ } -+ -+ err = -ESTALE; -+ if (olddentry->d_parent != old_upperdir) -+ goto out_dput; -+ if (newdentry->d_parent != new_upperdir) -+ goto out_dput; -+ if (olddentry == trap) -+ goto out_dput; -+ if (newdentry == trap) -+ goto out_dput; -+ -+ old_opaque = ovl_dentry_is_opaque(old); -+ new_opaque = ovl_dentry_is_opaque(new) || new_type != OVL_PATH_UPPER; -+ -+ if (is_dir && !old_opaque && new_opaque) { -+ err = ovl_set_opaque(olddentry); -+ if (err) -+ goto out_dput; -+ } -+ -+ err = vfs_rename(old_upperdir->d_inode, olddentry, -+ new_upperdir->d_inode, newdentry); -+ -+ if (err) { -+ if (new_create && ovl_dentry_is_opaque(new)) -+ ovl_whiteout(new_upperdir, new); -+ if (is_dir && !old_opaque && new_opaque) -+ ovl_remove_opaque(olddentry); -+ goto out_dput; -+ } -+ -+ if (old_type != OVL_PATH_UPPER || old_opaque) -+ err = ovl_whiteout(old_upperdir, old); -+ if (is_dir && old_opaque && !new_opaque) -+ ovl_remove_opaque(olddentry); -+ -+ if (old_opaque != new_opaque) -+ ovl_dentry_set_opaque(old, new_opaque); -+ -+ ovl_dentry_version_inc(old->d_parent); -+ ovl_dentry_version_inc(new->d_parent); -+ -+out_dput: -+ dput(newdentry); -+out_unlock: -+ unlock_rename(new_upperdir, old_upperdir); -+ return err; -+} -+ -+const struct inode_operations ovl_dir_inode_operations = { -+ .lookup = ovl_lookup, -+ .mkdir = ovl_mkdir, -+ .symlink = ovl_symlink, -+ .unlink = ovl_unlink, -+ .rmdir = ovl_rmdir, -+ .rename = ovl_rename, -+ .link = ovl_link, -+ .setattr = ovl_setattr, -+ .create = ovl_create, -+ .mknod = ovl_mknod, -+ .permission = ovl_permission, -+ .getattr = ovl_dir_getattr, -+ .setxattr = ovl_setxattr, -+ .getxattr = ovl_getxattr, -+ .listxattr = ovl_listxattr, -+ .removexattr = ovl_removexattr, -+}; -diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c -new file mode 100644 -index 0000000..40b79d0 ---- /dev/null -+++ b/fs/overlayfs/inode.c -@@ -0,0 +1,383 @@ -+/* -+ * -+ * Copyright (C) 2011 Novell 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 "overlayfs.h" -+ -+int ovl_setattr(struct dentry *dentry, struct iattr *attr) -+{ -+ struct dentry *upperdentry; -+ int err; -+ -+ if ((attr->ia_valid & ATTR_SIZE) && !ovl_dentry_upper(dentry)) -+ err = ovl_copy_up_truncate(dentry, attr->ia_size); -+ else -+ err = ovl_copy_up(dentry); -+ if (err) -+ return err; -+ -+ upperdentry = ovl_dentry_upper(dentry); -+ -+ if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) -+ attr->ia_valid &= ~ATTR_MODE; -+ -+ mutex_lock(&upperdentry->d_inode->i_mutex); -+ err = notify_change(upperdentry, attr); -+ mutex_unlock(&upperdentry->d_inode->i_mutex); -+ -+ return err; -+} -+ -+static int ovl_getattr(struct vfsmount *mnt, struct dentry *dentry, -+ struct kstat *stat) -+{ -+ struct path realpath; -+ -+ ovl_path_real(dentry, &realpath); -+ return vfs_getattr(realpath.mnt, realpath.dentry, stat); -+} -+ -+int ovl_permission(struct inode *inode, int mask) -+{ -+ struct ovl_entry *oe; -+ struct dentry *alias = NULL; -+ struct inode *realinode; -+ struct dentry *realdentry; -+ bool is_upper; -+ int err; -+ -+ if (S_ISDIR(inode->i_mode)) { -+ oe = inode->i_private; -+ } else if (mask & MAY_NOT_BLOCK) { -+ return -ECHILD; -+ } else { -+ /* -+ * For non-directories find an alias and get the info -+ * from there. -+ */ -+ spin_lock(&inode->i_lock); -+ if (WARN_ON(list_empty(&inode->i_dentry))) { -+ spin_unlock(&inode->i_lock); -+ return -ENOENT; -+ } -+ alias = list_entry(inode->i_dentry.next, struct dentry, d_alias); -+ dget(alias); -+ spin_unlock(&inode->i_lock); -+ oe = alias->d_fsdata; -+ } -+ -+ realdentry = ovl_entry_real(oe, &is_upper); -+ -+ /* Careful in RCU walk mode */ -+ realinode = ACCESS_ONCE(realdentry->d_inode); -+ if (!realinode) { -+ WARN_ON(!(mask & MAY_NOT_BLOCK)); -+ err = -ENOENT; -+ goto out_dput; -+ } -+ -+ if (mask & MAY_WRITE) { -+ umode_t mode = realinode->i_mode; -+ -+ /* -+ * Writes will always be redirected to upper layer, so -+ * ignore lower layer being read-only. -+ * -+ * If the overlay itself is read-only then proceed -+ * with the permission check, don't return EROFS. -+ * This will only happen if this is the lower layer of -+ * another overlayfs. -+ * -+ * If upper fs becomes read-only after the overlay was -+ * constructed return EROFS to prevent modification of -+ * upper layer. -+ */ -+ err = -EROFS; -+ if (is_upper && !IS_RDONLY(inode) && IS_RDONLY(realinode) && -+ (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) -+ goto out_dput; -+ -+ /* -+ * Nobody gets write access to an immutable file. -+ */ -+ err = -EACCES; -+ if (IS_IMMUTABLE(realinode)) -+ goto out_dput; -+ } -+ -+ if (realinode->i_op->permission) -+ err = realinode->i_op->permission(realinode, mask); -+ else -+ err = generic_permission(realinode, mask); -+out_dput: -+ dput(alias); -+ return err; -+} -+ -+ -+struct ovl_link_data { -+ struct dentry *realdentry; -+ void *cookie; -+}; -+ -+static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd) -+{ -+ void *ret; -+ struct dentry *realdentry; -+ struct inode *realinode; -+ -+ realdentry = ovl_dentry_real(dentry); -+ realinode = realdentry->d_inode; -+ -+ if (WARN_ON(!realinode->i_op->follow_link)) -+ return ERR_PTR(-EPERM); -+ -+ ret = realinode->i_op->follow_link(realdentry, nd); -+ if (IS_ERR(ret)) -+ return ret; -+ -+ if (realinode->i_op->put_link) { -+ struct ovl_link_data *data; -+ -+ data = kmalloc(sizeof(struct ovl_link_data), GFP_KERNEL); -+ if (!data) { -+ realinode->i_op->put_link(realdentry, nd, ret); -+ return ERR_PTR(-ENOMEM); -+ } -+ data->realdentry = realdentry; -+ data->cookie = ret; -+ -+ return data; -+ } else { -+ return NULL; -+ } -+} -+ -+static void ovl_put_link(struct dentry *dentry, struct nameidata *nd, void *c) -+{ -+ struct inode *realinode; -+ struct ovl_link_data *data = c; -+ -+ if (!data) -+ return; -+ -+ realinode = data->realdentry->d_inode; -+ realinode->i_op->put_link(data->realdentry, nd, data->cookie); -+ kfree(data); -+} -+ -+static int ovl_readlink(struct dentry *dentry, char __user *buf, int bufsiz) -+{ -+ struct path realpath; -+ struct inode *realinode; -+ -+ ovl_path_real(dentry, &realpath); -+ realinode = realpath.dentry->d_inode; -+ -+ if (!realinode->i_op->readlink) -+ return -EINVAL; -+ -+ touch_atime(realpath.mnt, realpath.dentry); -+ -+ return realinode->i_op->readlink(realpath.dentry, buf, bufsiz); -+} -+ -+ -+static bool ovl_is_private_xattr(const char *name) -+{ -+ return strncmp(name, "trusted.overlay.", 14) == 0; -+} -+ -+int ovl_setxattr(struct dentry *dentry, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ int err; -+ struct dentry *upperdentry; -+ -+ if (ovl_is_private_xattr(name)) -+ return -EPERM; -+ -+ err = ovl_copy_up(dentry); -+ if (err) -+ return err; -+ -+ upperdentry = ovl_dentry_upper(dentry); -+ return vfs_setxattr(upperdentry, name, value, size, flags); -+} -+ -+ssize_t ovl_getxattr(struct dentry *dentry, const char *name, -+ void *value, size_t size) -+{ -+ if (ovl_path_type(dentry->d_parent) == OVL_PATH_MERGE && -+ ovl_is_private_xattr(name)) -+ return -ENODATA; -+ -+ return vfs_getxattr(ovl_dentry_real(dentry), name, value, size); -+} -+ -+ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) -+{ -+ ssize_t res; -+ int off; -+ -+ res = vfs_listxattr(ovl_dentry_real(dentry), list, size); -+ if (res <= 0 || size == 0) -+ return res; -+ -+ if (ovl_path_type(dentry->d_parent) != OVL_PATH_MERGE) -+ return res; -+ -+ /* filter out private xattrs */ -+ for (off = 0; off < res;) { -+ char *s = list + off; -+ size_t slen = strlen(s) + 1; -+ -+ BUG_ON(off + slen > res); -+ -+ if (ovl_is_private_xattr(s)) { -+ res -= slen; -+ memmove(s, s + slen, res - off); -+ } else { -+ off += slen; -+ } -+ } -+ -+ return res; -+} -+ -+int ovl_removexattr(struct dentry *dentry, const char *name) -+{ -+ int err; -+ struct path realpath; -+ enum ovl_path_type type; -+ -+ if (ovl_path_type(dentry->d_parent) == OVL_PATH_MERGE && -+ ovl_is_private_xattr(name)) -+ return -ENODATA; -+ -+ type = ovl_path_real(dentry, &realpath); -+ if (type == OVL_PATH_LOWER) { -+ err = vfs_getxattr(realpath.dentry, name, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ err = ovl_copy_up(dentry); -+ if (err) -+ return err; -+ -+ ovl_path_upper(dentry, &realpath); -+ } -+ -+ return vfs_removexattr(realpath.dentry, name); -+} -+ -+static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type, -+ struct dentry *realdentry) -+{ -+ if (type != OVL_PATH_LOWER) -+ return false; -+ -+ if (special_file(realdentry->d_inode->i_mode)) -+ return false; -+ -+ if (!(OPEN_FMODE(flags) & FMODE_WRITE) && !(flags & O_TRUNC)) -+ return false; -+ -+ return true; -+} -+ -+static struct file *ovl_open(struct dentry *dentry, int flags, -+ const struct cred *cred) -+{ -+ int err; -+ struct path realpath; -+ enum ovl_path_type type; -+ -+ type = ovl_path_real(dentry, &realpath); -+ if (ovl_open_need_copy_up(flags, type, realpath.dentry)) { -+ if (flags & O_TRUNC) -+ err = ovl_copy_up_truncate(dentry, 0); -+ else -+ err = ovl_copy_up(dentry); -+ if (err) -+ return ERR_PTR(err); -+ -+ ovl_path_upper(dentry, &realpath); -+ } -+ -+ return vfs_open(&realpath, flags, cred); -+} -+ -+static const struct inode_operations ovl_file_inode_operations = { -+ .setattr = ovl_setattr, -+ .permission = ovl_permission, -+ .getattr = ovl_getattr, -+ .setxattr = ovl_setxattr, -+ .getxattr = ovl_getxattr, -+ .listxattr = ovl_listxattr, -+ .removexattr = ovl_removexattr, -+ .open = ovl_open, -+}; -+ -+static const struct inode_operations ovl_symlink_inode_operations = { -+ .setattr = ovl_setattr, -+ .follow_link = ovl_follow_link, -+ .put_link = ovl_put_link, -+ .readlink = ovl_readlink, -+ .getattr = ovl_getattr, -+ .setxattr = ovl_setxattr, -+ .getxattr = ovl_getxattr, -+ .listxattr = ovl_listxattr, -+ .removexattr = ovl_removexattr, -+}; -+ -+struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, -+ struct ovl_entry *oe) -+{ -+ struct inode *inode; -+ -+ inode = new_inode(sb); -+ if (!inode) -+ return NULL; -+ -+ mode &= S_IFMT; -+ -+ inode->i_ino = get_next_ino(); -+ inode->i_mode = mode; -+ inode->i_flags |= S_NOATIME | S_NOCMTIME; -+ -+ switch (mode) { -+ case S_IFDIR: -+ inode->i_private = oe; -+ inode->i_op = &ovl_dir_inode_operations; -+ inode->i_fop = &ovl_dir_operations; -+ break; -+ -+ case S_IFLNK: -+ inode->i_op = &ovl_symlink_inode_operations; -+ break; -+ -+ case S_IFREG: -+ case S_IFSOCK: -+ case S_IFBLK: -+ case S_IFCHR: -+ case S_IFIFO: -+ inode->i_op = &ovl_file_inode_operations; -+ break; -+ -+ default: -+ WARN(1, "illegal file type: %i\n", mode); -+ inode = NULL; -+ } -+ -+ return inode; -+ -+} -diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h -new file mode 100644 -index 0000000..07a1fe9 ---- /dev/null -+++ b/fs/overlayfs/overlayfs.h -@@ -0,0 +1,63 @@ -+/* -+ * -+ * Copyright (C) 2011 Novell 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. -+ */ -+ -+struct ovl_entry; -+ -+enum ovl_path_type { -+ OVL_PATH_UPPER, -+ OVL_PATH_MERGE, -+ OVL_PATH_LOWER, -+}; -+ -+extern const char *ovl_opaque_xattr; -+extern const char *ovl_whiteout_xattr; -+extern const struct dentry_operations ovl_dentry_operations; -+ -+enum ovl_path_type ovl_path_type(struct dentry *dentry); -+u64 ovl_dentry_version_get(struct dentry *dentry); -+void ovl_dentry_version_inc(struct dentry *dentry); -+void ovl_path_upper(struct dentry *dentry, struct path *path); -+void ovl_path_lower(struct dentry *dentry, struct path *path); -+enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path); -+struct dentry *ovl_dentry_upper(struct dentry *dentry); -+struct dentry *ovl_dentry_lower(struct dentry *dentry); -+struct dentry *ovl_dentry_real(struct dentry *dentry); -+struct dentry *ovl_entry_real(struct ovl_entry *oe, bool *is_upper); -+bool ovl_dentry_is_opaque(struct dentry *dentry); -+void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque); -+bool ovl_is_whiteout(struct dentry *dentry); -+void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry); -+struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, -+ struct nameidata *nd); -+ -+struct dentry *ovl_upper_create(struct dentry *upperdir, struct dentry *dentry, -+ struct kstat *stat, const char *link); -+ -+/* readdir.c */ -+extern const struct file_operations ovl_dir_operations; -+int ovl_check_empty_and_clear(struct dentry *dentry, enum ovl_path_type type); -+ -+/* inode.c */ -+int ovl_setattr(struct dentry *dentry, struct iattr *attr); -+int ovl_permission(struct inode *inode, int mask); -+int ovl_setxattr(struct dentry *dentry, const char *name, -+ const void *value, size_t size, int flags); -+ssize_t ovl_getxattr(struct dentry *dentry, const char *name, -+ void *value, size_t size); -+ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); -+int ovl_removexattr(struct dentry *dentry, const char *name); -+ -+struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, -+ struct ovl_entry *oe); -+/* dir.c */ -+extern const struct inode_operations ovl_dir_inode_operations; -+ -+/* copy_up.c */ -+int ovl_copy_up(struct dentry *dentry); -+int ovl_copy_up_truncate(struct dentry *dentry, loff_t size); -diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c -new file mode 100644 -index 0000000..6fcda39 ---- /dev/null -+++ b/fs/overlayfs/readdir.c -@@ -0,0 +1,559 @@ -+/* -+ * -+ * Copyright (C) 2011 Novell 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 "overlayfs.h" -+ -+struct ovl_cache_entry { -+ const char *name; -+ unsigned int len; -+ unsigned int type; -+ u64 ino; -+ bool is_whiteout; -+ struct list_head l_node; -+ struct rb_node node; -+}; -+ -+struct ovl_readdir_data { -+ struct rb_root *root; -+ struct list_head *list; -+ struct list_head *middle; -+ struct dentry *dir; -+ int count; -+ int err; -+}; -+ -+struct ovl_dir_file { -+ bool is_real; -+ bool is_cached; -+ struct list_head cursor; -+ u64 cache_version; -+ struct list_head cache; -+ struct file *realfile; -+}; -+ -+static struct ovl_cache_entry *ovl_cache_entry_from_node(struct rb_node *n) -+{ -+ return container_of(n, struct ovl_cache_entry, node); -+} -+ -+static struct ovl_cache_entry *ovl_cache_entry_find(struct rb_root *root, -+ const char *name, int len) -+{ -+ struct rb_node *node = root->rb_node; -+ int cmp; -+ -+ while (node) { -+ struct ovl_cache_entry *p = ovl_cache_entry_from_node(node); -+ -+ cmp = strncmp(name, p->name, len); -+ if (cmp > 0) -+ node = p->node.rb_right; -+ else if (cmp < 0 || len < p->len) -+ node = p->node.rb_left; -+ else -+ return p; -+ } -+ -+ return NULL; -+} -+ -+static struct ovl_cache_entry *ovl_cache_entry_new(const char *name, int len, -+ u64 ino, unsigned int d_type) -+{ -+ struct ovl_cache_entry *p; -+ -+ p = kmalloc(sizeof(*p) + len + 1, GFP_KERNEL); -+ if (p) { -+ char *name_copy = (char *) (p + 1); -+ memcpy(name_copy, name, len); -+ name_copy[len] = '\0'; -+ p->name = name_copy; -+ p->len = len; -+ p->type = d_type; -+ p->ino = ino; -+ p->is_whiteout = false; -+ } -+ -+ return p; -+} -+ -+static int ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd, -+ const char *name, int len, u64 ino, -+ unsigned int d_type) -+{ -+ struct rb_node **newp = &rdd->root->rb_node; -+ struct rb_node *parent = NULL; -+ struct ovl_cache_entry *p; -+ -+ while (*newp) { -+ int cmp; -+ struct ovl_cache_entry *tmp; -+ -+ parent = *newp; -+ tmp = ovl_cache_entry_from_node(*newp); -+ cmp = strncmp(name, tmp->name, len); -+ if (cmp > 0) -+ newp = &tmp->node.rb_right; -+ else if (cmp < 0 || len < tmp->len) -+ newp = &tmp->node.rb_left; -+ else -+ return 0; -+ } -+ -+ p = ovl_cache_entry_new(name, len, ino, d_type); -+ if (p == NULL) -+ return -ENOMEM; -+ -+ list_add_tail(&p->l_node, rdd->list); -+ rb_link_node(&p->node, parent, newp); -+ rb_insert_color(&p->node, rdd->root); -+ -+ return 0; -+} -+ -+static int ovl_fill_lower(void *buf, const char *name, int namelen, -+ loff_t offset, u64 ino, unsigned int d_type) -+{ -+ struct ovl_readdir_data *rdd = buf; -+ struct ovl_cache_entry *p; -+ -+ rdd->count++; -+ p = ovl_cache_entry_find(rdd->root, name, namelen); -+ if (p) { -+ list_move_tail(&p->l_node, rdd->middle); -+ } else { -+ p = ovl_cache_entry_new(name, namelen, ino, d_type); -+ if (p == NULL) -+ rdd->err = -ENOMEM; -+ else -+ list_add_tail(&p->l_node, rdd->middle); -+ } -+ -+ return rdd->err; -+} -+ -+static void ovl_cache_free(struct list_head *list) -+{ -+ struct ovl_cache_entry *p; -+ struct ovl_cache_entry *n; -+ -+ list_for_each_entry_safe(p, n, list, l_node) -+ kfree(p); -+ -+ INIT_LIST_HEAD(list); -+} -+ -+static int ovl_fill_upper(void *buf, const char *name, int namelen, -+ loff_t offset, u64 ino, unsigned int d_type) -+{ -+ struct ovl_readdir_data *rdd = buf; -+ -+ rdd->count++; -+ return ovl_cache_entry_add_rb(rdd, name, namelen, ino, d_type); -+} -+ -+static inline int ovl_dir_read(struct path *realpath, -+ struct ovl_readdir_data *rdd, filldir_t filler) -+{ -+ struct file *realfile; -+ int err; -+ -+ realfile = vfs_open(realpath, O_RDONLY | O_DIRECTORY, current_cred()); -+ if (IS_ERR(realfile)) -+ return PTR_ERR(realfile); -+ -+ do { -+ rdd->count = 0; -+ rdd->err = 0; -+ err = vfs_readdir(realfile, filler, rdd); -+ if (err >= 0) -+ err = rdd->err; -+ } while (!err && rdd->count); -+ fput(realfile); -+ -+ return 0; -+} -+ -+static void ovl_dir_reset(struct file *file) -+{ -+ struct ovl_dir_file *od = file->private_data; -+ enum ovl_path_type type = ovl_path_type(file->f_path.dentry); -+ -+ if (ovl_dentry_version_get(file->f_path.dentry) != od->cache_version) { -+ list_del_init(&od->cursor); -+ ovl_cache_free(&od->cache); -+ od->is_cached = false; -+ } -+ WARN_ON(!od->is_real && type != OVL_PATH_MERGE); -+ if (od->is_real && type == OVL_PATH_MERGE) { -+ fput(od->realfile); -+ od->realfile = NULL; -+ od->is_real = false; -+ } -+} -+ -+static int ovl_dir_mark_whiteouts(struct ovl_readdir_data *rdd) -+{ -+ struct ovl_cache_entry *p; -+ struct dentry *dentry; -+ const struct cred *old_cred; -+ struct cred *override_cred; -+ -+ override_cred = prepare_creds(); -+ if (!override_cred) { -+ ovl_cache_free(rdd->list); -+ return -ENOMEM; -+ } -+ -+ /* -+ * CAP_SYS_ADMIN for getxattr -+ * CAP_DAC_OVERRIDE for lookup -+ */ -+ cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); -+ cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE); -+ old_cred = override_creds(override_cred); -+ -+ mutex_lock(&rdd->dir->d_inode->i_mutex); -+ list_for_each_entry(p, rdd->list, l_node) { -+ if (p->type != DT_LNK) -+ continue; -+ -+ dentry = lookup_one_len(p->name, rdd->dir, p->len); -+ if (IS_ERR(dentry)) -+ continue; -+ -+ p->is_whiteout = ovl_is_whiteout(dentry); -+ dput(dentry); -+ } -+ mutex_unlock(&rdd->dir->d_inode->i_mutex); -+ -+ revert_creds(old_cred); -+ put_cred(override_cred); -+ -+ return 0; -+} -+ -+static inline int ovl_dir_read_merged(struct path *upperpath, struct path *lowerpath, -+ struct ovl_readdir_data *rdd) -+{ -+ int err; -+ struct rb_root root = RB_ROOT; -+ struct list_head middle; -+ -+ rdd->root = &root; -+ if (upperpath->dentry) { -+ rdd->dir = upperpath->dentry; -+ err = ovl_dir_read(upperpath, rdd, ovl_fill_upper); -+ if (err) -+ goto out; -+ -+ err = ovl_dir_mark_whiteouts(rdd); -+ if (err) -+ goto out; -+ } -+ /* -+ * Insert lowerpath entries before upperpath ones, this allows -+ * offsets to be reasonably constant -+ */ -+ list_add(&middle, rdd->list); -+ rdd->middle = &middle; -+ err = ovl_dir_read(lowerpath, rdd, ovl_fill_lower); -+ list_del(&middle); -+out: -+ rdd->root = NULL; -+ -+ return err; -+} -+ -+static void ovl_seek_cursor(struct ovl_dir_file *od, loff_t pos) -+{ -+ struct list_head *l; -+ loff_t off; -+ -+ l = od->cache.next; -+ for (off = 0; off < pos; off++) { -+ if (l == &od->cache) -+ break; -+ l = l->next; -+ } -+ list_move_tail(&od->cursor, l); -+} -+ -+static int ovl_readdir(struct file *file, void *buf, filldir_t filler) -+{ -+ struct ovl_dir_file *od = file->private_data; -+ int res; -+ -+ if (!file->f_pos) -+ ovl_dir_reset(file); -+ -+ if (od->is_real) { -+ res = vfs_readdir(od->realfile, filler, buf); -+ file->f_pos = od->realfile->f_pos; -+ -+ return res; -+ } -+ -+ if (!od->is_cached) { -+ struct path lowerpath; -+ struct path upperpath; -+ struct ovl_readdir_data rdd = { .list = &od->cache }; -+ -+ ovl_path_lower(file->f_path.dentry, &lowerpath); -+ ovl_path_upper(file->f_path.dentry, &upperpath); -+ -+ res = ovl_dir_read_merged(&upperpath, &lowerpath, &rdd); -+ if (res) { -+ ovl_cache_free(rdd.list); -+ return res; -+ } -+ -+ od->cache_version = ovl_dentry_version_get(file->f_path.dentry); -+ od->is_cached = true; -+ -+ ovl_seek_cursor(od, file->f_pos); -+ } -+ -+ while (od->cursor.next != &od->cache) { -+ int over; -+ loff_t off; -+ struct ovl_cache_entry *p; -+ -+ p = list_entry(od->cursor.next, struct ovl_cache_entry, l_node); -+ off = file->f_pos; -+ if (!p->is_whiteout) { -+ over = filler(buf, p->name, p->len, off, p->ino, p->type); -+ if (over) -+ break; -+ } -+ file->f_pos++; -+ list_move(&od->cursor, &p->l_node); -+ } -+ -+ return 0; -+} -+ -+static loff_t ovl_dir_llseek(struct file *file, loff_t offset, int origin) -+{ -+ loff_t res; -+ struct ovl_dir_file *od = file->private_data; -+ -+ mutex_lock(&file->f_dentry->d_inode->i_mutex); -+ if (!file->f_pos) -+ ovl_dir_reset(file); -+ -+ if (od->is_real) { -+ res = vfs_llseek(od->realfile, offset, origin); -+ file->f_pos = od->realfile->f_pos; -+ } else { -+ res = -EINVAL; -+ -+ switch (origin) { -+ case SEEK_CUR: -+ offset += file->f_pos; -+ break; -+ case SEEK_SET: -+ break; -+ default: -+ goto out_unlock; -+ } -+ if (offset < 0) -+ goto out_unlock; -+ -+ if (offset != file->f_pos) { -+ file->f_pos = offset; -+ if (od->is_cached) -+ ovl_seek_cursor(od, offset); -+ } -+ res = offset; -+ } -+out_unlock: -+ mutex_unlock(&file->f_dentry->d_inode->i_mutex); -+ -+ return res; -+} -+ -+static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end, -+ int datasync) -+{ -+ struct ovl_dir_file *od = file->private_data; -+ -+ /* May need to reopen directory if it got copied up */ -+ if (!od->realfile) { -+ struct path upperpath; -+ -+ ovl_path_upper(file->f_path.dentry, &upperpath); -+ od->realfile = vfs_open(&upperpath, O_RDONLY, current_cred()); -+ if (IS_ERR(od->realfile)) -+ return PTR_ERR(od->realfile); -+ } -+ -+ return vfs_fsync_range(od->realfile, start, end, datasync); -+} -+ -+static int ovl_dir_release(struct inode *inode, struct file *file) -+{ -+ struct ovl_dir_file *od = file->private_data; -+ -+ list_del(&od->cursor); -+ ovl_cache_free(&od->cache); -+ if (od->realfile) -+ fput(od->realfile); -+ kfree(od); -+ -+ return 0; -+} -+ -+static int ovl_dir_open(struct inode *inode, struct file *file) -+{ -+ struct path realpath; -+ struct file *realfile; -+ struct ovl_dir_file *od; -+ enum ovl_path_type type; -+ -+ od = kzalloc(sizeof(struct ovl_dir_file), GFP_KERNEL); -+ if (!od) -+ return -ENOMEM; -+ -+ type = ovl_path_real(file->f_path.dentry, &realpath); -+ realfile = vfs_open(&realpath, file->f_flags, current_cred()); -+ if (IS_ERR(realfile)) { -+ kfree(od); -+ return PTR_ERR(realfile); -+ } -+ INIT_LIST_HEAD(&od->cache); -+ INIT_LIST_HEAD(&od->cursor); -+ od->is_cached = false; -+ od->realfile = realfile; -+ od->is_real = (type != OVL_PATH_MERGE); -+ file->private_data = od; -+ -+ return 0; -+} -+ -+const struct file_operations ovl_dir_operations = { -+ .read = generic_read_dir, -+ .open = ovl_dir_open, -+ .readdir = ovl_readdir, -+ .llseek = ovl_dir_llseek, -+ .fsync = ovl_dir_fsync, -+ .release = ovl_dir_release, -+}; -+ -+static int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) -+{ -+ int err; -+ struct path lowerpath; -+ struct path upperpath; -+ struct ovl_cache_entry *p; -+ struct ovl_readdir_data rdd = { .list = list }; -+ -+ ovl_path_upper(dentry, &upperpath); -+ ovl_path_lower(dentry, &lowerpath); -+ -+ err = ovl_dir_read_merged(&upperpath, &lowerpath, &rdd); -+ if (err) -+ return err; -+ -+ err = 0; -+ -+ list_for_each_entry(p, list, l_node) { -+ if (p->is_whiteout) -+ continue; -+ -+ if (p->name[0] == '.') { -+ if (p->len == 1) -+ continue; -+ if (p->len == 2 && p->name[1] == '.') -+ continue; -+ } -+ err = -ENOTEMPTY; -+ break; -+ } -+ -+ return err; -+} -+ -+static int ovl_remove_whiteouts(struct dentry *dir, struct list_head *list) -+{ -+ struct path upperpath; -+ struct dentry *upperdir; -+ struct ovl_cache_entry *p; -+ const struct cred *old_cred; -+ struct cred *override_cred; -+ int err; -+ -+ ovl_path_upper(dir, &upperpath); -+ upperdir = upperpath.dentry; -+ -+ override_cred = prepare_creds(); -+ if (!override_cred) -+ return -ENOMEM; -+ -+ /* -+ * CAP_DAC_OVERRIDE for lookup and unlink -+ * CAP_SYS_ADMIN for setxattr of "trusted" namespace -+ * CAP_FOWNER for unlink in sticky directory -+ */ -+ cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE); -+ cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); -+ cap_raise(override_cred->cap_effective, CAP_FOWNER); -+ old_cred = override_creds(override_cred); -+ -+ err = vfs_setxattr(upperdir, ovl_opaque_xattr, "y", 1, 0); -+ if (err) -+ goto out_revert_creds; -+ -+ mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT); -+ list_for_each_entry(p, list, l_node) { -+ struct dentry *dentry; -+ int ret; -+ -+ if (!p->is_whiteout) -+ continue; -+ -+ dentry = lookup_one_len(p->name, upperdir, p->len); -+ if (IS_ERR(dentry)) { -+ printk(KERN_WARNING "overlayfs: failed to lookup whiteout %.*s: %li\n", p->len, p->name, PTR_ERR(dentry)); -+ continue; -+ } -+ ret = vfs_unlink(upperdir->d_inode, dentry); -+ dput(dentry); -+ if (ret) -+ printk(KERN_WARNING "overlayfs: failed to unlink whiteout %.*s: %i\n", p->len, p->name, ret); -+ } -+ mutex_unlock(&upperdir->d_inode->i_mutex); -+ -+out_revert_creds: -+ revert_creds(old_cred); -+ put_cred(override_cred); -+ -+ return err; -+} -+ -+int ovl_check_empty_and_clear(struct dentry *dentry, enum ovl_path_type type) -+{ -+ int err; -+ LIST_HEAD(list); -+ -+ err = ovl_check_empty_dir(dentry, &list); -+ if (!err && type == OVL_PATH_MERGE) -+ err = ovl_remove_whiteouts(dentry, &list); -+ -+ ovl_cache_free(&list); -+ -+ return err; -+} -diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c -new file mode 100644 -index 0000000..508cf19 ---- /dev/null -+++ b/fs/overlayfs/super.c -@@ -0,0 +1,656 @@ -+/* -+ * -+ * Copyright (C) 2011 Novell 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 "overlayfs.h" -+ -+MODULE_AUTHOR("Miklos Szeredi "); -+MODULE_DESCRIPTION("Overlay filesystem"); -+MODULE_LICENSE("GPL"); -+ -+struct ovl_config { -+ char *lowerdir; -+ char *upperdir; -+}; -+ -+/* private information held for overlayfs's superblock */ -+struct ovl_fs { -+ struct vfsmount *upper_mnt; -+ struct vfsmount *lower_mnt; -+ /* pathnames of lower and upper dirs, for show_options */ -+ struct ovl_config config; -+}; -+ -+/* private information held for every overlayfs dentry */ -+struct ovl_entry { -+ /* -+ * Keep "double reference" on upper dentries, so that -+ * d_delete() doesn't think it's OK to reset d_inode to NULL. -+ */ -+ struct dentry *__upperdentry; -+ struct dentry *lowerdentry; -+ union { -+ struct { -+ u64 version; -+ bool opaque; -+ }; -+ struct rcu_head rcu; -+ }; -+}; -+ -+const char *ovl_whiteout_xattr = "trusted.overlay.whiteout"; -+const char *ovl_opaque_xattr = "trusted.overlay.opaque"; -+ -+ -+enum ovl_path_type ovl_path_type(struct dentry *dentry) -+{ -+ struct ovl_entry *oe = dentry->d_fsdata; -+ -+ if (oe->__upperdentry) { -+ if (oe->lowerdentry && S_ISDIR(dentry->d_inode->i_mode)) -+ return OVL_PATH_MERGE; -+ else -+ return OVL_PATH_UPPER; -+ } else { -+ return OVL_PATH_LOWER; -+ } -+} -+ -+static struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe) -+{ -+ struct dentry *upperdentry = ACCESS_ONCE(oe->__upperdentry); -+ smp_read_barrier_depends(); -+ return upperdentry; -+} -+ -+void ovl_path_upper(struct dentry *dentry, struct path *path) -+{ -+ struct ovl_fs *ofs = dentry->d_sb->s_fs_info; -+ struct ovl_entry *oe = dentry->d_fsdata; -+ -+ path->mnt = ofs->upper_mnt; -+ path->dentry = ovl_upperdentry_dereference(oe); -+} -+ -+void ovl_path_lower(struct dentry *dentry, struct path *path) -+{ -+ struct ovl_fs *ofs = dentry->d_sb->s_fs_info; -+ struct ovl_entry *oe = dentry->d_fsdata; -+ -+ path->mnt = ofs->lower_mnt; -+ path->dentry = oe->lowerdentry; -+} -+ -+enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path) -+{ -+ -+ enum ovl_path_type type = ovl_path_type(dentry); -+ -+ if (type == OVL_PATH_LOWER) -+ ovl_path_lower(dentry, path); -+ else -+ ovl_path_upper(dentry, path); -+ -+ return type; -+} -+ -+struct dentry *ovl_dentry_upper(struct dentry *dentry) -+{ -+ struct ovl_entry *oe = dentry->d_fsdata; -+ -+ return ovl_upperdentry_dereference(oe); -+} -+ -+struct dentry *ovl_dentry_lower(struct dentry *dentry) -+{ -+ struct ovl_entry *oe = dentry->d_fsdata; -+ -+ return oe->lowerdentry; -+} -+ -+struct dentry *ovl_dentry_real(struct dentry *dentry) -+{ -+ struct ovl_entry *oe = dentry->d_fsdata; -+ struct dentry *realdentry; -+ -+ realdentry = ovl_upperdentry_dereference(oe); -+ if (!realdentry) -+ realdentry = oe->lowerdentry; -+ -+ return realdentry; -+} -+ -+struct dentry *ovl_entry_real(struct ovl_entry *oe, bool *is_upper) -+{ -+ struct dentry *realdentry; -+ -+ realdentry = ovl_upperdentry_dereference(oe); -+ if (realdentry) { -+ *is_upper = true; -+ } else { -+ realdentry = oe->lowerdentry; -+ *is_upper = false; -+ } -+ return realdentry; -+} -+ -+bool ovl_dentry_is_opaque(struct dentry *dentry) -+{ -+ struct ovl_entry *oe = dentry->d_fsdata; -+ return oe->opaque; -+} -+ -+void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque) -+{ -+ struct ovl_entry *oe = dentry->d_fsdata; -+ oe->opaque = opaque; -+} -+ -+void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry) -+{ -+ struct ovl_entry *oe = dentry->d_fsdata; -+ -+ WARN_ON(!mutex_is_locked(&upperdentry->d_parent->d_inode->i_mutex)); -+ WARN_ON(oe->__upperdentry); -+ BUG_ON(!upperdentry->d_inode); -+ smp_wmb(); -+ oe->__upperdentry = dget(upperdentry); -+} -+ -+void ovl_dentry_version_inc(struct dentry *dentry) -+{ -+ struct ovl_entry *oe = dentry->d_fsdata; -+ -+ WARN_ON(!mutex_is_locked(&dentry->d_inode->i_mutex)); -+ oe->version++; -+} -+ -+u64 ovl_dentry_version_get(struct dentry *dentry) -+{ -+ struct ovl_entry *oe = dentry->d_fsdata; -+ -+ WARN_ON(!mutex_is_locked(&dentry->d_inode->i_mutex)); -+ return oe->version; -+} -+ -+bool ovl_is_whiteout(struct dentry *dentry) -+{ -+ int res; -+ char val; -+ -+ if (!dentry) -+ return false; -+ if (!dentry->d_inode) -+ return false; -+ if (!S_ISLNK(dentry->d_inode->i_mode)) -+ return false; -+ -+ res = vfs_getxattr(dentry, ovl_whiteout_xattr, &val, 1); -+ if (res == 1 && val == 'y') -+ return true; -+ -+ return false; -+} -+ -+static bool ovl_is_opaquedir(struct dentry *dentry) -+{ -+ int res; -+ char val; -+ -+ if (!S_ISDIR(dentry->d_inode->i_mode)) -+ return false; -+ -+ res = vfs_getxattr(dentry, ovl_opaque_xattr, &val, 1); -+ if (res == 1 && val == 'y') -+ return true; -+ -+ return false; -+} -+ -+static void ovl_entry_free(struct rcu_head *head) -+{ -+ struct ovl_entry *oe = container_of(head, struct ovl_entry, rcu); -+ kfree(oe); -+} -+ -+static void ovl_dentry_release(struct dentry *dentry) -+{ -+ struct ovl_entry *oe = dentry->d_fsdata; -+ -+ if (oe) { -+ dput(oe->__upperdentry); -+ dput(oe->__upperdentry); -+ dput(oe->lowerdentry); -+ call_rcu(&oe->rcu, ovl_entry_free); -+ } -+} -+ -+const struct dentry_operations ovl_dentry_operations = { -+ .d_release = ovl_dentry_release, -+}; -+ -+static struct ovl_entry *ovl_alloc_entry(void) -+{ -+ return kzalloc(sizeof(struct ovl_entry), GFP_KERNEL); -+} -+ -+static inline struct dentry *ovl_lookup_real(struct dentry *dir, struct qstr *name) -+{ -+ struct dentry *dentry; -+ -+ mutex_lock(&dir->d_inode->i_mutex); -+ dentry = lookup_one_len(name->name, dir, name->len); -+ mutex_unlock(&dir->d_inode->i_mutex); -+ -+ if (IS_ERR(dentry)) { -+ if (PTR_ERR(dentry) == -ENOENT) -+ dentry = NULL; -+ } else if (!dentry->d_inode) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+} -+ -+static int ovl_do_lookup(struct dentry *dentry) -+{ -+ struct ovl_entry *oe; -+ struct dentry *upperdir; -+ struct dentry *lowerdir; -+ struct dentry *upperdentry = NULL; -+ struct dentry *lowerdentry = NULL; -+ struct inode *inode = NULL; -+ int err; -+ -+ err = -ENOMEM; -+ oe = ovl_alloc_entry(); -+ if (!oe) -+ goto out; -+ -+ upperdir = ovl_dentry_upper(dentry->d_parent); -+ lowerdir = ovl_dentry_lower(dentry->d_parent); -+ -+ if (upperdir) { -+ upperdentry = ovl_lookup_real(upperdir, &dentry->d_name); -+ err = PTR_ERR(upperdentry); -+ if (IS_ERR(upperdentry)) -+ goto out_put_dir; -+ -+ if (lowerdir && upperdentry && -+ (S_ISLNK(upperdentry->d_inode->i_mode) || -+ S_ISDIR(upperdentry->d_inode->i_mode))) { -+ const struct cred *old_cred; -+ struct cred *override_cred; -+ -+ err = -ENOMEM; -+ override_cred = prepare_creds(); -+ if (!override_cred) -+ goto out_dput_upper; -+ -+ /* CAP_SYS_ADMIN needed for getxattr */ -+ cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); -+ old_cred = override_creds(override_cred); -+ -+ if (ovl_is_opaquedir(upperdentry)) { -+ oe->opaque = true; -+ } else if (ovl_is_whiteout(upperdentry)) { -+ dput(upperdentry); -+ upperdentry = NULL; -+ oe->opaque = true; -+ } -+ revert_creds(old_cred); -+ put_cred(override_cred); -+ } -+ } -+ if (lowerdir && !oe->opaque) { -+ lowerdentry = ovl_lookup_real(lowerdir, &dentry->d_name); -+ err = PTR_ERR(lowerdentry); -+ if (IS_ERR(lowerdentry)) -+ goto out_dput_upper; -+ } -+ -+ if (lowerdentry && upperdentry && -+ (!S_ISDIR(upperdentry->d_inode->i_mode) || -+ !S_ISDIR(lowerdentry->d_inode->i_mode))) { -+ dput(lowerdentry); -+ lowerdentry = NULL; -+ oe->opaque = true; -+ } -+ -+ if (lowerdentry || upperdentry) { -+ struct dentry *realdentry; -+ -+ realdentry = upperdentry ? upperdentry : lowerdentry; -+ err = -ENOMEM; -+ inode = ovl_new_inode(dentry->d_sb, realdentry->d_inode->i_mode, oe); -+ if (!inode) -+ goto out_dput; -+ } -+ -+ if (upperdentry) -+ oe->__upperdentry = dget(upperdentry); -+ -+ if (lowerdentry) -+ oe->lowerdentry = lowerdentry; -+ -+ dentry->d_fsdata = oe; -+ dentry->d_op = &ovl_dentry_operations; -+ d_add(dentry, inode); -+ -+ return 0; -+ -+out_dput: -+ dput(lowerdentry); -+out_dput_upper: -+ dput(upperdentry); -+out_put_dir: -+ kfree(oe); -+out: -+ return err; -+} -+ -+struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, -+ struct nameidata *nd) -+{ -+ int err = ovl_do_lookup(dentry); -+ -+ if (err) -+ return ERR_PTR(err); -+ -+ return NULL; -+} -+ -+static void ovl_put_super(struct super_block *sb) -+{ -+ struct ovl_fs *ufs = sb->s_fs_info; -+ -+ if (!(sb->s_flags & MS_RDONLY)) -+ mnt_drop_write(ufs->upper_mnt); -+ -+ mntput(ufs->upper_mnt); -+ mntput(ufs->lower_mnt); -+ -+ kfree(ufs->config.lowerdir); -+ kfree(ufs->config.upperdir); -+ kfree(ufs); -+} -+ -+static int ovl_remount_fs(struct super_block *sb, int *flagsp, char *data) -+{ -+ int flags = *flagsp; -+ struct ovl_fs *ufs = sb->s_fs_info; -+ -+ /* When remounting rw or ro, we need to adjust the write access to the -+ * upper fs. -+ */ -+ if (((flags ^ sb->s_flags) & MS_RDONLY) == 0) -+ /* No change to readonly status */ -+ return 0; -+ -+ if (flags & MS_RDONLY) { -+ mnt_drop_write(ufs->upper_mnt); -+ return 0; -+ } else -+ return mnt_want_write(ufs->upper_mnt); -+} -+ -+/** -+ * ovl_statfs -+ * @sb: The overlayfs super block -+ * @buf: The struct kstatfs to fill in with stats -+ * -+ * Get the filesystem statistics. As writes always target the upper layer -+ * filesystem pass the statfs to the same filesystem. -+ */ -+static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf) -+{ -+ struct dentry *root_dentry = dentry->d_sb->s_root; -+ struct path path; -+ ovl_path_upper(root_dentry, &path); -+ -+ if (!path.dentry->d_sb->s_op->statfs) -+ return -ENOSYS; -+ return path.dentry->d_sb->s_op->statfs(path.dentry, buf); -+} -+ -+/** -+ * ovl_show_options -+ * -+ * Prints the mount options for a given superblock. -+ * Returns zero; does not fail. -+ */ -+static int ovl_show_options(struct seq_file *m, struct vfsmount *mnt) -+{ -+ struct super_block *sb = mnt->mnt_sb; -+ struct ovl_fs *ufs = sb->s_fs_info; -+ -+ seq_printf(m, ",lowerdir=%s", ufs->config.lowerdir); -+ seq_printf(m, ",upperdir=%s", ufs->config.upperdir); -+ return 0; -+} -+ -+static const struct super_operations ovl_super_operations = { -+ .put_super = ovl_put_super, -+ .remount_fs = ovl_remount_fs, -+ .statfs = ovl_statfs, -+ .show_options = ovl_show_options, -+}; -+ -+enum { -+ Opt_lowerdir, -+ Opt_upperdir, -+ Opt_err, -+}; -+ -+static const match_table_t ovl_tokens = { -+ {Opt_lowerdir, "lowerdir=%s"}, -+ {Opt_upperdir, "upperdir=%s"}, -+ {Opt_err, NULL} -+}; -+ -+static int ovl_parse_opt(char *opt, struct ovl_config *config) -+{ -+ char *p; -+ -+ config->upperdir = NULL; -+ config->lowerdir = NULL; -+ -+ while ((p = strsep(&opt, ",")) != NULL) { -+ int token; -+ substring_t args[MAX_OPT_ARGS]; -+ -+ if (!*p) -+ continue; -+ -+ token = match_token(p, ovl_tokens, args); -+ switch (token) { -+ case Opt_upperdir: -+ kfree(config->upperdir); -+ config->upperdir = match_strdup(&args[0]); -+ if (!config->upperdir) -+ return -ENOMEM; -+ break; -+ -+ case Opt_lowerdir: -+ kfree(config->lowerdir); -+ config->lowerdir = match_strdup(&args[0]); -+ if (!config->lowerdir) -+ return -ENOMEM; -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ } -+ return 0; -+} -+ -+static int ovl_fill_super(struct super_block *sb, void *data, int silent) -+{ -+ struct path lowerpath; -+ struct path upperpath; -+ struct inode *root_inode; -+ struct dentry *root_dentry; -+ struct ovl_entry *oe; -+ struct ovl_fs *ufs; -+ int err; -+ -+ err = -ENOMEM; -+ ufs = kmalloc(sizeof(struct ovl_fs), GFP_KERNEL); -+ if (!ufs) -+ goto out; -+ -+ err = ovl_parse_opt((char *) data, &ufs->config); -+ if (err) -+ goto out_free_ufs; -+ -+ err = -EINVAL; -+ if (!ufs->config.upperdir || !ufs->config.lowerdir) { -+ printk(KERN_ERR "overlayfs: missing upperdir or lowerdir\n"); -+ goto out_free_config; -+ } -+ -+ oe = ovl_alloc_entry(); -+ if (oe == NULL) -+ goto out_free_config; -+ -+ root_inode = ovl_new_inode(sb, S_IFDIR, oe); -+ if (!root_inode) -+ goto out_free_oe; -+ -+ err = kern_path(ufs->config.upperdir, LOOKUP_FOLLOW, &upperpath); -+ if (err) -+ goto out_put_root; -+ -+ err = kern_path(ufs->config.lowerdir, LOOKUP_FOLLOW, &lowerpath); -+ if (err) -+ goto out_put_upperpath; -+ -+ err = -ENOTDIR; -+ if (!S_ISDIR(upperpath.dentry->d_inode->i_mode) || -+ !S_ISDIR(lowerpath.dentry->d_inode->i_mode)) -+ goto out_put_lowerpath; -+ -+ sb->s_stack_depth = max(upperpath.mnt->mnt_sb->s_stack_depth, -+ lowerpath.mnt->mnt_sb->s_stack_depth) + 1; -+ -+ err = -EINVAL; -+ if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { -+ printk(KERN_ERR "overlayfs: maximum fs stacking depth exceeded\n"); -+ goto out_put_lowerpath; -+ } -+ -+ -+ ufs->upper_mnt = clone_private_mount(&upperpath); -+ err = PTR_ERR(ufs->upper_mnt); -+ if (IS_ERR(ufs->upper_mnt)) { -+ printk(KERN_ERR "overlayfs: failed to clone upperpath\n"); -+ goto out_put_lowerpath; -+ } -+ -+ ufs->lower_mnt = clone_private_mount(&lowerpath); -+ err = PTR_ERR(ufs->lower_mnt); -+ if (IS_ERR(ufs->lower_mnt)) { -+ printk(KERN_ERR "overlayfs: failed to clone lowerpath\n"); -+ goto out_put_upper_mnt; -+ } -+ -+ /* -+ * Make lower_mnt R/O. That way fchmod/fchown on lower file -+ * will fail instead of modifying lower fs. -+ */ -+ ufs->lower_mnt->mnt_flags |= MNT_READONLY; -+ -+ /* If the upper fs is r/o, we mark overlayfs r/o too */ -+ if (ufs->upper_mnt->mnt_sb->s_flags & MS_RDONLY) -+ sb->s_flags |= MS_RDONLY; -+ -+ if (!(sb->s_flags & MS_RDONLY)) { -+ err = mnt_want_write(ufs->upper_mnt); -+ if (err) -+ goto out_put_lower_mnt; -+ } -+ -+ err = -ENOMEM; -+ root_dentry = d_alloc_root(root_inode); -+ if (!root_dentry) -+ goto out_drop_write; -+ -+ mntput(upperpath.mnt); -+ mntput(lowerpath.mnt); -+ -+ oe->__upperdentry = dget(upperpath.dentry); -+ oe->lowerdentry = lowerpath.dentry; -+ -+ root_dentry->d_fsdata = oe; -+ root_dentry->d_op = &ovl_dentry_operations; -+ -+ sb->s_op = &ovl_super_operations; -+ sb->s_root = root_dentry; -+ sb->s_fs_info = ufs; -+ -+ return 0; -+ -+out_drop_write: -+ if (!(sb->s_flags & MS_RDONLY)) -+ mnt_drop_write(ufs->upper_mnt); -+out_put_lower_mnt: -+ mntput(ufs->lower_mnt); -+out_put_upper_mnt: -+ mntput(ufs->upper_mnt); -+out_put_lowerpath: -+ path_put(&lowerpath); -+out_put_upperpath: -+ path_put(&upperpath); -+out_put_root: -+ iput(root_inode); -+out_free_oe: -+ kfree(oe); -+out_free_config: -+ kfree(ufs->config.lowerdir); -+ kfree(ufs->config.upperdir); -+out_free_ufs: -+ kfree(ufs); -+out: -+ return err; -+} -+ -+static struct dentry *ovl_mount(struct file_system_type *fs_type, int flags, -+ const char *dev_name, void *raw_data) -+{ -+ return mount_nodev(fs_type, flags, raw_data, ovl_fill_super); -+} -+ -+static struct file_system_type ovl_fs_type = { -+ .owner = THIS_MODULE, -+ .name = "overlayfs", -+ .mount = ovl_mount, -+ .kill_sb = kill_anon_super, -+}; -+ -+static int __init ovl_init(void) -+{ -+ return register_filesystem(&ovl_fs_type); -+} -+ -+static void __exit ovl_exit(void) -+{ -+ unregister_filesystem(&ovl_fs_type); -+} -+ -+module_init(ovl_init); -+module_exit(ovl_exit); -diff --git a/fs/splice.c b/fs/splice.c -index 3bd1700..a12a11f 100644 ---- a/fs/splice.c -+++ b/fs/splice.c -@@ -1329,6 +1329,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, - - return ret; - } -+EXPORT_SYMBOL(do_splice_direct); - - static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe, - struct pipe_inode_info *opipe, -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 269e920..2a1497c 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -488,6 +488,12 @@ struct iattr { - */ - #include - -+/* -+ * Maximum number of layers of fs stack. Needs to be limited to -+ * prevent kernel stack overflow -+ */ -+#define FILESYSTEM_MAX_STACK_DEPTH 2 -+ - /** - * enum positive_aop_returns - aop return codes with specific semantics - * -@@ -1499,6 +1505,11 @@ struct super_block { - int cleancache_poolid; - - struct shrinker s_shrink; /* per-sb shrinker handle */ -+ -+ /* -+ * Indicates how deep in a filesystem stack this SB is -+ */ -+ int s_stack_depth; - }; - - /* superblock cache pruning functions */ -@@ -1656,6 +1667,7 @@ struct inode_operations { - void (*truncate_range)(struct inode *, loff_t, loff_t); - int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, - u64 len); -+ struct file *(*open)(struct dentry *, int flags, const struct cred *); - } ____cacheline_aligned; - - struct seq_file; -@@ -2076,6 +2088,7 @@ extern long do_sys_open(int dfd, const char __user *filename, int flags, - extern struct file *filp_open(const char *, int, int); - extern struct file *file_open_root(struct dentry *, struct vfsmount *, - const char *, int); -+extern struct file *vfs_open(struct path *, int flags, const struct cred *); - extern struct file * dentry_open(struct dentry *, struct vfsmount *, int, - const struct cred *); - extern int filp_close(struct file *, fl_owner_t id); -diff --git a/include/linux/mount.h b/include/linux/mount.h -index 33fe53d..30cd21e 100644 ---- a/include/linux/mount.h -+++ b/include/linux/mount.h -@@ -100,6 +100,9 @@ extern void mnt_pin(struct vfsmount *mnt); - extern void mnt_unpin(struct vfsmount *mnt); - extern int __mnt_is_readonly(struct vfsmount *mnt); - -+struct path; -+extern struct vfsmount *clone_private_mount(struct path *path); -+ - extern struct vfsmount *do_kern_mount(const char *fstype, int flags, - const char *name, void *data); - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-panic-Make-panic_timeout-configurable.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-panic-Make-panic_timeout-configurable.patch deleted file mode 100644 index e8e82580..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-panic-Make-panic_timeout-configurable.patch +++ /dev/null @@ -1,68 +0,0 @@ -From efb2109f545b8881bc0b48aeaed787d6c91714a2 Mon Sep 17 00:00:00 2001 -Subject: [PATCH 1/2] panic: Make panic_timeout configurable - -The panic_timeout value can be set via the command line option -'panic=x', or via /proc/sys/kernel/panic, however that is not -sufficient when the panic occurs before we are able to set up -these values. Thus, add a CONFIG_PANIC_TIMEOUT so that we can -set the desired value from the .config. - -The default panic_timeout value continues to be 0 - wait -forever. Also adds set_arch_panic_timeout(new_timeout, -arch_default_timeout), which is intended to be used by arches in -arch_setup(). The idea being that the new_timeout is only set if -the user hasn't changed from the arch_default_timeout. - -Signed-off-by: Jason Baron -Cc: benh@kernel.crashing.org -Cc: paulus@samba.org -Cc: ralf@linux-mips.org -Cc: mpe@ellerman.id.au -Cc: felipe.contreras@gmail.com -Cc: Linus Torvalds -Cc: Andrew Morton -Cc: Peter Zijlstra -Cc: Thomas Gleixner -Link: http://lkml.kernel.org/r/1a1674daec27c534df409697025ac568ebcee91e.1385418410.git.jbaron@akamai.com -Signed-off-by: Ingo Molnar -(cherry picked from commit 5800dc3cff87c3a1548382298bb16e1fb4ec7e32) - -Conflicts: - include/linux/kernel.h - lib/Kconfig.debug - -Signed-off-by: Jonathan Toppins - -diff --git a/kernel/panic.c b/kernel/panic.c -index 3458469..8713b71 100644 ---- a/kernel/panic.c -+++ b/kernel/panic.c -@@ -33,7 +33,7 @@ static int pause_on_oops; - static int pause_on_oops_flag; - static DEFINE_SPINLOCK(pause_on_oops_lock); - --int panic_timeout; -+int panic_timeout = CONFIG_PANIC_TIMEOUT; - EXPORT_SYMBOL_GPL(panic_timeout); - - ATOMIC_NOTIFIER_HEAD(panic_notifier_list); -diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug -index 6cd177f..005f0b9 100644 ---- a/lib/Kconfig.debug -+++ b/lib/Kconfig.debug -@@ -286,6 +286,15 @@ config BOOTPARAM_HUNG_TASK_PANIC_VALUE - default 0 if !BOOTPARAM_HUNG_TASK_PANIC - default 1 if BOOTPARAM_HUNG_TASK_PANIC - -+config PANIC_TIMEOUT -+ int "panic timeout" -+ default 0 -+ help -+ Set the timeout value (in seconds) until a reboot occurs when the -+ the kernel panics. If n = 0, then we wait forever. A timeout -+ value n > 0 will wait n seconds before rebooting, while a timeout -+ value n < 0 will reboot immediately. -+ - config SCHED_DEBUG - bool "Collect scheduler debugging info" - depends on DEBUG_KERNEL && PROC_FS diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-ubifs-xattr-symlinks-bugs.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-ubifs-xattr-symlinks-bugs.patch deleted file mode 100644 index bfa54377..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/kernel-ubifs-xattr-symlinks-bugs.patch +++ /dev/null @@ -1,106 +0,0 @@ -ubifs - xattr - bugs - -An amalgam of patches posted to linux-mtd adding xattr support for symlinks and -related bugs in ubifs. - -http://lists.infradead.org/pipermail/linux-mtd/2013-February/045794.html - -diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c -index f9c234b..6b79020 100644 ---- a/fs/ubifs/file.c -+++ b/fs/ubifs/file.c -@@ -1575,6 +1575,12 @@ const struct inode_operations ubifs_symlink_inode_operations = { - .follow_link = ubifs_follow_link, - .setattr = ubifs_setattr, - .getattr = ubifs_getattr, -+#ifdef CONFIG_UBIFS_FS_XATTR -+ .setxattr = ubifs_setxattr, -+ .getxattr = ubifs_getxattr, -+ .listxattr = ubifs_listxattr, -+ .removexattr = ubifs_removexattr, -+#endif - }; - - const struct file_operations ubifs_file_operations = { -diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c -index cef0460..84dd0f4 100644 ---- a/fs/ubifs/journal.c -+++ b/fs/ubifs/journal.c -@@ -553,7 +553,8 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, - - dbg_jnl("ino %lu, dent '%.*s', data len %d in dir ino %lu", - inode->i_ino, nm->len, nm->name, ui->data_len, dir->i_ino); -- ubifs_assert(dir_ui->data_len == 0); -+ if (!xent) -+ ubifs_assert(dir_ui->data_len == 0); - ubifs_assert(mutex_is_locked(&dir_ui->ui_mutex)); - - dlen = UBIFS_DENT_NODE_SZ + nm->len + 1; -@@ -572,7 +573,12 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, - - aligned_dlen = ALIGN(dlen, 8); - aligned_ilen = ALIGN(ilen, 8); -- len = aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ; -+ /* -+ * Make sure to account for dir_ui+data_len in length -+ * calculation in case there is extended attribute. -+ */ -+ len = aligned_dlen + aligned_ilen + -+ UBIFS_INO_NODE_SZ + dir_ui->data_len; - dent = kmalloc(len, GFP_NOFS); - if (!dent) - return -ENOMEM; -@@ -649,7 +655,8 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, - - ino_key_init(c, &ino_key, dir->i_ino); - ino_offs += aligned_ilen; -- err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, UBIFS_INO_NODE_SZ); -+ err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, -+ UBIFS_INO_NODE_SZ + dir_ui->data_len); - if (err) - goto out_ro; - -diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c -index bf18f7a..2e1db01 100644 ---- a/fs/ubifs/xattr.c -+++ b/fs/ubifs/xattr.c -@@ -138,16 +138,15 @@ static int create_xattr(struct ubifs_info *c, struct inode *host, - ui = ubifs_inode(inode); - ui->xattr = 1; - ui->flags |= UBIFS_XATTR_FL; -- ui->data = kmalloc(size, GFP_NOFS); -+ ui->data = kmemdup(value, size, GFP_NOFS); - if (!ui->data) { - err = -ENOMEM; - goto out_free; - } -- memcpy(ui->data, value, size); -- inode->i_size = ui->ui_size = size; -- ui->data_len = size; - - mutex_lock(&host_ui->ui_mutex); -+ inode->i_size = ui->ui_size = size; -+ ui->data_len = size; - host->i_ctime = ubifs_current_time(host); - host_ui->xattr_cnt += 1; - host_ui->xattr_size += CALC_DENT_SIZE(nm->len); -@@ -204,16 +203,15 @@ static int change_xattr(struct ubifs_info *c, struct inode *host, - return err; - - kfree(ui->data); -- ui->data = kmalloc(size, GFP_NOFS); -+ ui->data = kmemdup(value, size, GFP_NOFS); - if (!ui->data) { - err = -ENOMEM; - goto out_free; - } -- memcpy(ui->data, value, size); -- inode->i_size = ui->ui_size = size; -- ui->data_len = size; - - mutex_lock(&host_ui->ui_mutex); -+ inode->i_size = ui->ui_size = size; -+ ui->data_len = size; - host->i_ctime = ubifs_current_time(host); - host_ui->xattr_size -= CALC_XATTR_BYTES(ui->data_len); - host_ui->xattr_size += CALC_XATTR_BYTES(size); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-add-port-genl.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-add-port-genl.patch deleted file mode 100644 index f163f0c2..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-add-port-genl.patch +++ /dev/null @@ -1,1399 +0,0 @@ -Add port generic netlink support - -diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h -index de33de1..02d9a42 100644 ---- a/include/linux/ethtool.h -+++ b/include/linux/ethtool.h -@@ -118,6 +118,23 @@ struct ethtool_eeprom { - }; - - /** -+ * struct ethtool_modinfo - plugin module eeprom information -+ * @cmd: %ETHTOOL_GMODULEINFO -+ * @type: Standard the module information conforms to %ETH_MODULE_SFF_xxxx -+ * @eeprom_len: Length of the eeprom -+ * -+ * This structure is used to return the information to -+ * properly size memory for a subsequent call to %ETHTOOL_GMODULEEEPROM. -+ * The type code indicates the eeprom data format -+ */ -+struct ethtool_modinfo { -+ __u32 cmd; -+ __u32 type; -+ __u32 eeprom_len; -+ __u32 reserved[8]; -+}; -+ -+/** - * struct ethtool_coalesce - coalescing parameters for IRQs and stats updates - * @cmd: ETHTOOL_{G,S}COALESCE - * @rx_coalesce_usecs: How many usecs to delay an RX interrupt after -@@ -338,9 +355,19 @@ struct ethtool_test { - __u64 data[0]; - }; - -+/** -+ * enum ethtool_stats_flags - flags definition of ethtool_stats -+ * @ETH_STATS_FL_CLEAR: if set clear device stats after read -+ */ -+ -+enum ethtool_stats_flags { -+ ETH_STATS_FL_CLEAR = (1 << 0), -+}; -+ - /* for dumping NIC-specific statistics */ - struct ethtool_stats { - __u32 cmd; /* ETHTOOL_GSTATS */ -+ __u32 flags; /* ETH_STATS_FL_xxx */ - __u32 n_stats; /* number of u64's being returned */ - __u64 data[0]; - }; -@@ -956,6 +983,10 @@ struct ethtool_ops { - int (*get_dump_data)(struct net_device *, - struct ethtool_dump *, void *); - int (*set_dump)(struct net_device *, struct ethtool_dump *); -+ int (*get_module_info)(struct net_device *, -+ struct ethtool_modinfo *); -+ int (*get_module_eeprom)(struct net_device *, -+ struct ethtool_eeprom *, u8 *); - - }; - #endif /* __KERNEL__ */ -@@ -1030,6 +1061,8 @@ struct ethtool_ops { - #define ETHTOOL_SET_DUMP 0x0000003e /* Set dump settings */ - #define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */ - #define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */ -+#define ETHTOOL_GMODULEINFO 0x00000042 /* Get plug-in module information */ -+#define ETHTOOL_GMODULEEEPROM 0x00000043 /* Get plug-in module eeprom */ - - /* compatibility with older code */ - #define SPARC_ETH_GSET ETHTOOL_GSET -diff --git a/include/linux/hashtable.h b/include/linux/hashtable.h -new file mode 100644 -index 0000000..227c624 ---- /dev/null -+++ b/include/linux/hashtable.h -@@ -0,0 +1,192 @@ -+/* -+ * Statically sized hash table implementation -+ * (C) 2012 Sasha Levin -+ */ -+ -+#ifndef _LINUX_HASHTABLE_H -+#define _LINUX_HASHTABLE_H -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define DEFINE_HASHTABLE(name, bits) \ -+ struct hlist_head name[1 << (bits)] = \ -+ { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT } -+ -+#define DECLARE_HASHTABLE(name, bits) \ -+ struct hlist_head name[1 << (bits)] -+ -+#define HASH_SIZE(name) (ARRAY_SIZE(name)) -+#define HASH_BITS(name) ilog2(HASH_SIZE(name)) -+ -+/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */ -+#define hash_min(val, bits) \ -+ (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)) -+ -+static inline void __hash_init(struct hlist_head *ht, unsigned int sz) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < sz; i++) -+ INIT_HLIST_HEAD(&ht[i]); -+} -+ -+/** -+ * hash_init - initialize a hash table -+ * @hashtable: hashtable to be initialized -+ * -+ * Calculates the size of the hashtable from the given parameter, otherwise -+ * same as hash_init_size. -+ * -+ * This has to be a macro since HASH_BITS() will not work on pointers since -+ * it calculates the size during preprocessing. -+ */ -+#define hash_init(hashtable) __hash_init(hashtable, HASH_SIZE(hashtable)) -+ -+/** -+ * hash_add - add an object to a hashtable -+ * @hashtable: hashtable to add to -+ * @node: the &struct hlist_node of the object to be added -+ * @key: the key of the object to be added -+ */ -+#define hash_add(hashtable, node, key) \ -+ hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))]) -+ -+/** -+ * hash_add_rcu - add an object to a rcu enabled hashtable -+ * @hashtable: hashtable to add to -+ * @node: the &struct hlist_node of the object to be added -+ * @key: the key of the object to be added -+ */ -+#define hash_add_rcu(hashtable, node, key) \ -+ hlist_add_head_rcu(node, &hashtable[hash_min(key, HASH_BITS(hashtable))]) -+ -+/** -+ * hash_hashed - check whether an object is in any hashtable -+ * @node: the &struct hlist_node of the object to be checked -+ */ -+static inline bool hash_hashed(struct hlist_node *node) -+{ -+ return !hlist_unhashed(node); -+} -+ -+static inline bool __hash_empty(struct hlist_head *ht, unsigned int sz) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < sz; i++) -+ if (!hlist_empty(&ht[i])) -+ return false; -+ -+ return true; -+} -+ -+/** -+ * hash_empty - check whether a hashtable is empty -+ * @hashtable: hashtable to check -+ * -+ * This has to be a macro since HASH_BITS() will not work on pointers since -+ * it calculates the size during preprocessing. -+ */ -+#define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable)) -+ -+/** -+ * hash_del - remove an object from a hashtable -+ * @node: &struct hlist_node of the object to remove -+ */ -+static inline void hash_del(struct hlist_node *node) -+{ -+ hlist_del_init(node); -+} -+ -+/** -+ * hash_del_rcu - remove an object from a rcu enabled hashtable -+ * @node: &struct hlist_node of the object to remove -+ */ -+static inline void hash_del_rcu(struct hlist_node *node) -+{ -+ hlist_del_init_rcu(node); -+} -+ -+/** -+ * hash_for_each - iterate over a hashtable -+ * @name: hashtable to iterate -+ * @bkt: integer to use as bucket loop cursor -+ * @node: the &struct list_head to use as a loop cursor for each entry -+ * @obj: the type * to use as a loop cursor for each entry -+ * @member: the name of the hlist_node within the struct -+ */ -+#define hash_for_each(name, bkt, node, obj, member) \ -+ for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\ -+ hlist_for_each_entry(obj, node, &name[bkt], member) -+ -+/** -+ * hash_for_each_rcu - iterate over a rcu enabled hashtable -+ * @name: hashtable to iterate -+ * @bkt: integer to use as bucket loop cursor -+ * @node: the &struct list_head to use as a loop cursor for each entry -+ * @obj: the type * to use as a loop cursor for each entry -+ * @member: the name of the hlist_node within the struct -+ */ -+#define hash_for_each_rcu(name, bkt, node, obj, member) \ -+ for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\ -+ hlist_for_each_entry_rcu(obj, node, &name[bkt], member) -+ -+/** -+ * hash_for_each_safe - iterate over a hashtable safe against removal of -+ * hash entry -+ * @name: hashtable to iterate -+ * @bkt: integer to use as bucket loop cursor -+ * @node: the &struct list_head to use as a loop cursor for each entry -+ * @tmp: a &struct used for temporary storage -+ * @obj: the type * to use as a loop cursor for each entry -+ * @member: the name of the hlist_node within the struct -+ */ -+#define hash_for_each_safe(name, bkt, node, tmp, obj, member) \ -+ for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\ -+ hlist_for_each_entry_safe(obj, node, tmp, &name[bkt], member) -+ -+/** -+ * hash_for_each_possible - iterate over all possible objects hashing to the -+ * same bucket -+ * @name: hashtable to iterate -+ * @obj: the type * to use as a loop cursor for each entry -+ * @node: the &struct list_head to use as a loop cursor for each entry -+ * @member: the name of the hlist_node within the struct -+ * @key: the key of the objects to iterate over -+ */ -+#define hash_for_each_possible(name, obj, node, member, key) \ -+ hlist_for_each_entry(obj, node, &name[hash_min(key, HASH_BITS(name))], member) -+ -+/** -+ * hash_for_each_possible_rcu - iterate over all possible objects hashing to the -+ * same bucket in an rcu enabled hashtable -+ * in a rcu enabled hashtable -+ * @name: hashtable to iterate -+ * @obj: the type * to use as a loop cursor for each entry -+ * @node: the &struct list_head to use as a loop cursor for each entry -+ * @member: the name of the hlist_node within the struct -+ * @key: the key of the objects to iterate over -+ */ -+#define hash_for_each_possible_rcu(name, obj, node, member, key) \ -+ hlist_for_each_entry_rcu(obj, node, &name[hash_min(key, HASH_BITS(name))], member) -+ -+/** -+ * hash_for_each_possible_safe - iterate over all possible objects hashing to the -+ * same bucket safe against removals -+ * @name: hashtable to iterate -+ * @obj: the type * to use as a loop cursor for each entry -+ * @node: the &struct list_head to use as a loop cursor for each entry -+ * @tmp: a &struct used for temporary storage -+ * @member: the name of the hlist_node within the struct -+ * @key: the key of the objects to iterate over -+ */ -+#define hash_for_each_possible_safe(name, obj, node, tmp, member, key) \ -+ hlist_for_each_entry_safe(obj, node, tmp, \ -+ &name[hash_min(key, HASH_BITS(name))], member) -+ -+ -+#endif -diff --git a/include/linux/port.h b/include/linux/port.h -new file mode 100644 -index 0000000..4e1c783 ---- /dev/null -+++ b/include/linux/port.h -@@ -0,0 +1,76 @@ -+/* -+ * port.h - defines for generic netlink port handler -+ * Copyright (C) 2013 Cumulus Networks -+ */ -+ -+#ifndef _LINUX_PORT_H -+#define _LINUX_PORT_H -+ -+#ifdef __KERNEL__ -+#include -+#endif -+#include -+ -+enum { -+ PORT_ATTR_UNSPEC, -+ PORT_ATTR_STATUS, -+ PORT_ATTR_IFINDEX, -+ PORT_ATTR_FLAGS, -+ PORT_ATTR_CARRIER, -+ PORT_ATTR_PHYS_ID_STATE, -+ PORT_ATTR_SETTINGS, -+ PORT_ATTR_PAUSE, -+ PORT_ATTR_MODINFO, -+ PORT_ATTR_EEPROM, -+ PORT_ATTR_EEPROM_DATA, -+ PORT_ATTR_STATS, -+ PORT_ATTR_STAT, -+ PORT_ATTR_STRINGS, -+ PORT_ATTR_STRING, -+ PORT_ATTR_SSET, -+ PORT_ATTR_SSET_COUNT, -+ __PORT_ATTR_MAX, -+}; -+#define PORT_ATTR_MAX (__PORT_ATTR_MAX - 1) -+ -+enum { -+ PORT_CMD_UNSPEC, -+ PORT_CMD_REPLY, -+ PORT_CMD_GET_SETTINGS, -+ PORT_CMD_SET_SETTINGS, -+ PORT_CMD_GET_PAUSE, -+ PORT_CMD_SET_PAUSE, -+ PORT_CMD_GET_MODULE_INFO, -+ PORT_CMD_GET_MODULE_EEPROM, -+ PORT_CMD_SET_STATS, -+ PORT_CMD_GET_STRINGS, -+ PORT_CMD_GET_SSET_COUNT, -+ PORT_CMD_SET_CARRIER, -+ PORT_CMD_SET_PHYS_ID_STATE, -+ __PORT_CMD_MAX, -+}; -+ -+#ifdef __KERNEL__ -+ -+#define PORT_ATTR_FLAG_STAT_RESTART (1 << 0) -+ -+int port_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); -+int port_set_settings(struct net_device *dev, struct ethtool_cmd *cmd); -+void port_get_pauseparam(struct net_device *dev, -+ struct ethtool_pauseparam *pause); -+int port_set_pauseparam(struct net_device *dev, -+ struct ethtool_pauseparam * pause); -+void port_get_ethtool_stats(struct net_device *dev, -+ struct ethtool_stats *stats, u64 *data); -+void port_get_ethtool_stats_clear(struct net_device *dev, -+ struct ethtool_stats *stats, u64 *data); -+void port_get_strings(struct net_device *dev, u32 stringset, u8 *data); -+int port_get_sset_count(struct net_device *dev, int sset); -+int port_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state); -+int port_get_module_info(struct net_device *dev, struct ethtool_modinfo *info); -+int port_get_module_eeprom(struct net_device *dev, -+ struct ethtool_eeprom *eeprom, u8 *data); -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* _LINUX_PORT_H */ -diff --git a/net/core/Makefile b/net/core/Makefile -index 7913f30..28c466f 100644 ---- a/net/core/Makefile -+++ b/net/core/Makefile -@@ -7,7 +7,7 @@ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ - - obj-$(CONFIG_SYSCTL) += sysctl_net_core.o - --obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \ -+obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o port.o \ - neighbour.o rtnetlink.o utils.o link_watch.o filter.o - - obj-$(CONFIG_XFRM) += flow.o -diff --git a/net/core/ethtool.c b/net/core/ethtool.c -index 2367246..a12af77 100644 ---- a/net/core/ethtool.c -+++ b/net/core/ethtool.c -@@ -1020,18 +1020,17 @@ static int ethtool_get_link(struct net_device *dev, char __user *useraddr) - return 0; - } - --static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) -+static int ethtool_get_any_eeprom(struct net_device *dev, void __user *useraddr, -+ int (*getter)(struct net_device *, -+ struct ethtool_eeprom *, u8 *), -+ u32 total_len) - { - struct ethtool_eeprom eeprom; -- const struct ethtool_ops *ops = dev->ethtool_ops; - void __user *userbuf = useraddr + sizeof(eeprom); - u32 bytes_remaining; - u8 *data; - int ret = 0; - -- if (!ops->get_eeprom || !ops->get_eeprom_len) -- return -EOPNOTSUPP; -- - if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) - return -EFAULT; - -@@ -1040,7 +1039,7 @@ static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) - return -EINVAL; - - /* Check for exceeding total eeprom len */ -- if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev)) -+ if (eeprom.offset + eeprom.len > total_len) - return -EINVAL; - - data = kmalloc(PAGE_SIZE, GFP_USER); -@@ -1051,7 +1050,7 @@ static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) - while (bytes_remaining > 0) { - eeprom.len = min(bytes_remaining, (u32)PAGE_SIZE); - -- ret = ops->get_eeprom(dev, &eeprom, data); -+ ret = getter(dev, &eeprom, data); - if (ret) - break; - if (copy_to_user(userbuf, data, eeprom.len)) { -@@ -1072,6 +1071,17 @@ static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) - return ret; - } - -+static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) -+{ -+ const struct ethtool_ops *ops = dev->ethtool_ops; -+ -+ if (!ops->get_eeprom || !ops->get_eeprom_len) -+ return -EOPNOTSUPP; -+ -+ return ethtool_get_any_eeprom(dev, useraddr, ops->get_eeprom, -+ ops->get_eeprom_len(dev)); -+} -+ - static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr) - { - struct ethtool_eeprom eeprom; -@@ -1635,6 +1645,47 @@ out: - return ret; - } - -+static int ethtool_get_module_info(struct net_device *dev, -+ void __user *useraddr) -+{ -+ int ret; -+ struct ethtool_modinfo modinfo; -+ const struct ethtool_ops *ops = dev->ethtool_ops; -+ -+ if (!ops->get_module_info) -+ return -EOPNOTSUPP; -+ -+ if (copy_from_user(&modinfo, useraddr, sizeof(modinfo))) -+ return -EFAULT; -+ -+ ret = ops->get_module_info(dev, &modinfo); -+ if (ret) -+ return ret; -+ -+ if (copy_to_user(useraddr, &modinfo, sizeof(modinfo))) -+ return -EFAULT; -+ -+ return 0; -+} -+ -+static int ethtool_get_module_eeprom(struct net_device *dev, -+ void __user *useraddr) -+{ -+ int ret; -+ struct ethtool_modinfo modinfo; -+ const struct ethtool_ops *ops = dev->ethtool_ops; -+ -+ if (!ops->get_module_info || !ops->get_module_eeprom) -+ return -EOPNOTSUPP; -+ -+ ret = ops->get_module_info(dev, &modinfo); -+ if (ret) -+ return ret; -+ -+ return ethtool_get_any_eeprom(dev, useraddr, ops->get_module_eeprom, -+ modinfo.eeprom_len); -+} -+ - /* The main entry point in this file. Called from net/core/dev.c */ - - int dev_ethtool(struct net *net, struct ifreq *ifr) -@@ -1858,6 +1909,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) - case ETHTOOL_GET_DUMP_DATA: - rc = ethtool_get_dump_data(dev, useraddr); - break; -+ case ETHTOOL_GMODULEINFO: -+ rc = ethtool_get_module_info(dev, useraddr); -+ break; -+ case ETHTOOL_GMODULEEEPROM: -+ rc = ethtool_get_module_eeprom(dev, useraddr); -+ break; - default: - rc = -EOPNOTSUPP; - } -diff --git a/net/core/port.c b/net/core/port.c -new file mode 100644 -index 0000000..74f35f8 ---- /dev/null -+++ b/net/core/port.c -@@ -0,0 +1,906 @@ -+/* -+ * net/core/port - generic netlink port handler -+ * Copyright (C) 2013 Cumulus Networks -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static DEFINE_HASHTABLE(port_cache, 10); -+static DEFINE_SPINLOCK(port_cache_lock); -+ -+struct port_node { -+ struct hlist_node hash_node; -+ spinlock_t lock; -+ int ifindex; -+ struct ethtool_cmd settings; -+ int settings_valid; -+ u32 sset_count[ETH_SS_FEATURES + 1]; -+ u64 *stat_data; -+ u64 *stat_data_old; /* snapshot of old stats */ -+ u8 *stat_strings; -+}; -+ -+static inline struct port_node *__port_cache_get(int ifindex) -+{ -+ struct port_node *port; -+ struct hlist_node *n; -+ unsigned long flags; -+ -+ rcu_read_lock(); -+ hash_for_each_possible_rcu(port_cache, port, n, hash_node, ifindex) -+ if (port->ifindex == ifindex) { -+ rcu_read_unlock(); -+ /* This works because ports aren't -+ deleted from cache */ -+ return port; -+ } -+ rcu_read_unlock(); -+ -+ port = kzalloc(sizeof(*port), GFP_KERNEL); -+ if (!port) -+ return NULL; -+ -+ port->ifindex = ifindex; -+ spin_lock_init(&port->lock); -+ -+ spin_lock_irqsave(&port_cache_lock, flags); -+ hash_add_rcu(port_cache, &port->hash_node, ifindex); -+ spin_unlock_irqrestore(&port_cache_lock, flags); -+ synchronize_rcu(); -+ -+ return port; -+} -+ -+static int port_cache_get_sset_count(int ifindex, int sset) -+{ -+ struct port_node *port; -+ -+ if (sset < ETH_SS_TEST || sset > ETH_SS_FEATURES) -+ return -EINVAL; -+ -+ port = __port_cache_get(ifindex); -+ if (!port) -+ return 0; -+ -+ return port->sset_count[sset]; -+} -+ -+static void port_cache_set_sset_count(int ifindex, int sset, int count) -+{ -+ struct port_node *port; -+ -+ if (sset < ETH_SS_TEST || sset > ETH_SS_FEATURES) -+ return; -+ -+ port = __port_cache_get(ifindex); -+ if (port) -+ port->sset_count[sset] = count; -+} -+ -+static int port_cache_get_stat_strings(int ifindex, int count, u8 *strings) -+{ -+ struct port_node *port; -+ u8* stat_strings; -+ int err = -ENODATA; -+ -+ memset(strings, 0, count * ETH_GSTRING_LEN); -+ -+ port = __port_cache_get(ifindex); -+ if (!port) -+ return -ENODATA; -+ -+ rcu_read_lock(); -+ stat_strings = rcu_dereference(port->stat_strings); -+ if (stat_strings) { -+ memcpy(strings, stat_strings, count * ETH_GSTRING_LEN); -+ err = 0; -+ } -+ rcu_read_unlock(); -+ -+ return err; -+} -+ -+static void port_cache_set_stat_strings(int ifindex, int count, u8 *strings) -+{ -+ struct port_node *port; -+ u8 *old_strings, *new_strings; -+ unsigned long flags; -+ -+ port = __port_cache_get(ifindex); -+ if (!port) -+ return; -+ -+ new_strings = kmalloc(count * ETH_GSTRING_LEN, GFP_KERNEL); -+ if (!new_strings) -+ return; -+ -+ memcpy(new_strings, strings, count * ETH_GSTRING_LEN); -+ -+ spin_lock_irqsave(&port->lock, flags); -+ old_strings = port->stat_strings; -+ rcu_assign_pointer(port->stat_strings, new_strings); -+ spin_unlock_irqrestore(&port->lock, flags); -+ synchronize_rcu(); -+ -+ kfree(old_strings); -+} -+ -+static void port_cache_clear_stats(int ifindex, int count) -+{ -+ struct port_node *port; -+ unsigned long flags; -+ int i; -+ -+ port = __port_cache_get(ifindex); -+ if (!port) -+ return; -+ -+ spin_lock_irqsave(&port->lock, flags); -+ if (port->stat_data) { -+ if (!port->stat_data_old) -+ rcu_assign_pointer(port->stat_data_old, -+ kzalloc(count * sizeof(u64), -+ GFP_ATOMIC)); -+ if (port->stat_data_old) -+ for (i = 0; i < count; i ++) -+ port->stat_data_old[i] = -port->stat_data[i]; -+ } -+ spin_unlock_irqrestore(&port->lock, flags); -+ synchronize_rcu(); -+} -+ -+static void port_cache_get_stats(int ifindex, struct ethtool_stats *stats, -+ u64* data, int clear) -+{ -+ struct port_node *port; -+ __u32 count = stats->n_stats; -+ u64 *stat_data, *stat_data_old; -+ int i; -+ -+ port = __port_cache_get(ifindex); -+ if (!port) -+ return; -+ -+ rcu_read_lock(); -+ -+ stat_data = rcu_dereference(port->stat_data); -+ stat_data_old = rcu_dereference(port->stat_data_old); -+ -+ if (stat_data) -+ memcpy(data, stat_data, count * sizeof(u64)); -+ -+ /* add in any earlier stats saved in snapshot */ -+ if (stat_data_old) -+ for (i = 0; i < count; i++) -+ data[i] += stat_data_old[i]; -+ -+ rcu_read_unlock(); -+ -+ /* if requested, clear stats */ -+ if (clear) -+ port_cache_clear_stats(ifindex, count); -+} -+ -+static void port_cache_set_stats(int ifindex, int count, u64* data, int restart) -+{ -+ struct port_node *port; -+ unsigned long flags; -+ int i; -+ -+ port = __port_cache_get(ifindex); -+ if (!port) -+ return; -+ -+ spin_lock_irqsave(&port->lock, flags); -+ -+ /* if restarting, take snapshot of stats */ -+ if (restart && port->stat_data) { -+ if (!port->stat_data_old) -+ rcu_assign_pointer(port->stat_data_old, -+ kzalloc(count * sizeof(u64), -+ GFP_ATOMIC)); -+ if (port->stat_data_old) -+ for (i = 0; i < count; i ++) -+ port->stat_data_old[i] += port->stat_data[i]; -+ } -+ -+ if (!port->stat_data) -+ rcu_assign_pointer(port->stat_data, -+ kmalloc(count * sizeof(u64), -+ GFP_ATOMIC)); -+ if (port->stat_data) -+ memcpy(port->stat_data, data, count * sizeof(u64)); -+ -+ spin_unlock_irqrestore(&port->lock, flags); -+ synchronize_rcu(); -+} -+ -+static void port_cache_clear_settings(int ifindex) -+{ -+ struct port_node *port; -+ unsigned long flags; -+ -+ port = __port_cache_get(ifindex); -+ if (!port) -+ return; -+ -+ spin_lock_irqsave(&port->lock, flags); -+ memset(&port->settings, 0, sizeof(port->settings)); -+ port->settings_valid = 0; -+ spin_unlock_irqrestore(&port->lock, flags); -+ synchronize_rcu(); -+} -+ -+static int port_cache_get_settings(int ifindex, struct ethtool_cmd *cmd) -+{ -+ struct port_node *port; -+ int valid; -+ -+ port = __port_cache_get(ifindex); -+ if (!port) -+ return -ENODATA; -+ -+ rcu_read_lock(); -+ valid = port->settings_valid; -+ if (valid) -+ memcpy(cmd, &port->settings, sizeof(*cmd)); -+ rcu_read_unlock(); -+ -+ return valid ? 0 : -ENODATA; -+} -+ -+static void port_cache_set_settings(int ifindex, struct ethtool_cmd *cmd) -+{ -+ struct port_node *port; -+ unsigned long flags; -+ -+ port = __port_cache_get(ifindex); -+ if (!port) -+ return; -+ -+ spin_lock_irqsave(&port->lock, flags); -+ memcpy(&port->settings, cmd, sizeof(*cmd)); -+ port->settings_valid = 1; -+ spin_unlock_irqrestore(&port->lock, flags); -+ synchronize_rcu(); -+} -+ -+static const struct nla_policy port_policy[PORT_ATTR_MAX + 1] = { -+ [PORT_ATTR_STATUS] = { .type = NLA_U32 }, -+ [PORT_ATTR_IFINDEX] = { .type = NLA_U32 }, -+ [PORT_ATTR_FLAGS] = { .type = NLA_U32 }, -+ [PORT_ATTR_CARRIER] = { .type = NLA_U8 }, -+ [PORT_ATTR_PHYS_ID_STATE] = { .type = NLA_U8 }, -+ [PORT_ATTR_SETTINGS] = { .type = NLA_BINARY, -+ .len = sizeof(struct ethtool_cmd) }, -+ [PORT_ATTR_PAUSE] = { .type = NLA_BINARY, -+ .len = sizeof(struct ethtool_pauseparam) }, -+ [PORT_ATTR_MODINFO] = { .type = NLA_BINARY, -+ .len = sizeof(struct ethtool_modinfo) }, -+ [PORT_ATTR_EEPROM] = { .type = NLA_BINARY, -+ .len = sizeof(struct ethtool_eeprom) }, -+ [PORT_ATTR_EEPROM_DATA] = { .type = NLA_BINARY }, -+ [PORT_ATTR_STATS] = { .type = NLA_NESTED }, -+ [PORT_ATTR_STAT] = { .type = NLA_U32 }, -+ [PORT_ATTR_STRINGS] = { .type = NLA_NESTED }, -+ [PORT_ATTR_STRING] = { .type = NLA_STRING, -+ .len = ETH_GSTRING_LEN }, -+ [PORT_ATTR_SSET] = { .type = NLA_U32 }, -+ [PORT_ATTR_SSET_COUNT] = { .type = NLA_U32 }, -+}; -+ -+static struct genl_family port_family = { -+ .id = GENL_ID_GENERATE, -+ .name = "port_family", -+ .version = 1, -+ .maxattr = PORT_ATTR_MAX, -+}; -+ -+static struct genl_multicast_group port_mcgrp = { -+ .name = "port_mc", -+}; -+ -+static LIST_HEAD(wq_list); -+ -+struct wq { -+ wait_queue_head_t wq; -+ int seq; -+ int hit; -+ struct nlattr **attrs; -+ struct list_head list; -+}; -+ -+static struct wq *alloc_wq(int seq) -+{ -+ struct wq *wq = kzalloc(sizeof(*wq), GFP_KERNEL); -+ -+ if (!wq) -+ return wq; -+ -+ init_waitqueue_head(&wq->wq); -+ INIT_LIST_HEAD(&wq->list); -+ wq->seq = seq; -+ -+ return wq; -+} -+ -+static struct wq *find_wq(int seq) -+{ -+ struct list_head *pos; -+ struct wq *wq; -+ -+ list_for_each(pos, &wq_list) { -+ wq = list_entry(pos, struct wq, list); -+ if (wq->seq == seq) -+ return wq; -+ } -+ -+ return NULL; -+} -+ -+static int port_wait(int seq, int wait, -+ int (*decode)(struct nlattr **attrs, -+ void *arg1, void *arg2), -+ void *arg1, void *arg2) -+{ -+ struct wq *wq; -+ int err, is_locked; -+ -+ wq = alloc_wq(seq); -+ if (!wq) -+ return -ENOMEM; -+ list_add(&wq->list, &wq_list); -+ -+ is_locked = rtnl_is_locked(); -+ if (is_locked) -+ rtnl_unlock(); -+ -+ err = wait_event_interruptible_timeout(wq->wq, wq->hit, wait * HZ); -+ -+ if (is_locked) -+ rtnl_lock(); -+ -+ if (err == 0) { /* timed out */ -+ err = -ETIMEDOUT; -+ goto err_out; -+ } -+ -+ if (err == -ERESTARTSYS) /* interrupted */ -+ goto err_out; -+ -+ if (wq->attrs[PORT_ATTR_STATUS]) { -+ err = nla_get_u32(wq->attrs[PORT_ATTR_STATUS]); -+ if (err) -+ goto err_out; -+ } -+ -+ if (decode) { -+ err = decode(wq->attrs, arg1, arg2); -+ if (err) -+ goto err_out; -+ } -+ -+ err = 0; -+ -+err_out: -+ list_del(&wq->list); -+ kfree(wq); -+ -+ return err; -+} -+ -+static int port_sleep(void) -+{ -+ struct wq wq = { .seq = -1 }; -+ int err, is_locked; -+ -+ init_waitqueue_head(&wq.wq); -+ -+ is_locked = rtnl_is_locked(); -+ if (is_locked) -+ rtnl_unlock(); -+ -+ err = wait_event_interruptible_timeout(wq.wq, wq.hit, HZ); -+ -+ if (is_locked) -+ rtnl_lock(); -+ -+ if (err == 0) /* timed out */ -+ err = -ETIMEDOUT; -+ -+ return err; -+} -+ -+static int port_send(struct net_device *dev, u8 cmd, int size, int wait, -+ int (*encode)(struct sk_buff *skb, void *arg1, void *arg2), -+ int (*decode)(struct nlattr **attrs, void *arg1, void *arg2), -+ void *arg1, void *arg2) -+{ -+ static atomic_t next_seq; -+ struct sk_buff *skb; -+ void *hdr; -+ int seq, err = -EMSGSIZE, retry = 0; -+ -+ size += nla_total_size(sizeof(u32)); /* PORT_ATTR_IFINDEX */ -+ -+retry: -+ skb = genlmsg_new(size, GFP_KERNEL); -+ if (!skb) -+ return -ENOMEM; -+ -+ /* use unique seq for each request */ -+ seq = atomic_inc_return(&next_seq); -+ hdr = genlmsg_put(skb, 0, seq, &port_family, 0, cmd); -+ if (!hdr) -+ goto err_out; -+ -+ NLA_PUT_U32(skb, PORT_ATTR_IFINDEX, dev->ifindex); -+ -+ if (encode) { -+ err = encode(skb, arg1, arg2); -+ if (err < 0) { -+nla_put_failure: -+ genlmsg_cancel(skb, hdr); -+ goto err_out; -+ } -+ } -+ -+ genlmsg_end(skb, hdr); -+ -+ err = genlmsg_multicast(skb, 0, port_mcgrp.id, GFP_KERNEL); -+ if (err < 0) -+ goto err_out_sent; -+ -+ if (wait) { -+ err = port_wait(seq, wait, decode, arg1, arg2); -+ retry += wait; -+ if (err == -EAGAIN && retry < 60) { -+ port_sleep(); -+ goto retry; -+ } -+ } -+ -+ return err; -+ -+err_out: -+ nlmsg_free(skb); -+err_out_sent: -+ return err; -+} -+ -+static int port_reply(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct wq *wq; -+ -+ rtnl_lock(); -+ wq = find_wq(info->snd_seq); -+ rtnl_unlock(); -+ -+ if (wq) { -+ wq->hit = 1; -+ wq->attrs = info->attrs; -+ wake_up_interruptible(&wq->wq); -+ } -+ -+ return 0; -+} -+ -+static int port_set_stats(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr **attrs = info->attrs; -+ int ifindex = 0, count = 0; -+ u32 flags = 0; -+ struct nlattr *attr; -+ u64 *data; -+ int i = 0, rem, restart; -+ -+ if (attrs[PORT_ATTR_IFINDEX]) -+ ifindex = nla_get_u32(attrs[PORT_ATTR_IFINDEX]); -+ -+ if (attrs[PORT_ATTR_FLAGS]) -+ flags = nla_get_u32(attrs[PORT_ATTR_FLAGS]); -+ -+ restart = !!(flags & PORT_ATTR_FLAG_STAT_RESTART); -+ -+ if (attrs[PORT_ATTR_SSET_COUNT]) -+ count = nla_get_u32(attrs[PORT_ATTR_SSET_COUNT]); -+ -+ data = kzalloc(count * sizeof(u64), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ if (attrs[PORT_ATTR_STATS]) -+ nla_for_each_nested(attr, attrs[PORT_ATTR_STATS], rem) -+ if (i < count) -+ data[i++] = nla_get_u64(attr); -+ -+ port_cache_set_sset_count(ifindex, ETH_SS_STATS, count); -+ port_cache_set_stats(ifindex, count, data, restart); -+ -+ kfree(data); -+ -+ return 0; -+} -+ -+static int port_set_settings_push(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr **attrs = info->attrs; -+ struct ethtool_cmd cmd = { 0, }; -+ int ifindex = 0; -+ -+ if (attrs[PORT_ATTR_IFINDEX]) -+ ifindex = nla_get_u32(attrs[PORT_ATTR_IFINDEX]); -+ -+ if (attrs[PORT_ATTR_SETTINGS]) -+ memcpy(&cmd, nla_data(attrs[PORT_ATTR_SETTINGS]), -+ sizeof(struct ethtool_cmd)); -+ -+ if (ifindex <= 0) -+ return -ENOTSUPP; -+ -+ port_cache_set_settings(ifindex, &cmd); -+ -+ return 0; -+} -+ -+static int port_set_carrier(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr **attrs = info->attrs; -+ struct net_device *dev; -+ struct net *net; -+ int ifindex = 0, carrier = 0; -+ -+ if (attrs[PORT_ATTR_IFINDEX]) -+ ifindex = nla_get_u32(attrs[PORT_ATTR_IFINDEX]); -+ -+ if (attrs[PORT_ATTR_CARRIER]) -+ carrier = nla_get_u8(attrs[PORT_ATTR_CARRIER]); -+ -+ if (ifindex <= 0) -+ return -ENOTSUPP; -+ -+ net = get_net(current->nsproxy->net_ns); -+ -+ dev = dev_get_by_index(net, ifindex); -+ if (dev) { -+ if (carrier) -+ netif_carrier_on(dev); -+ else -+ netif_carrier_off(dev); -+ dev_put(dev); -+ } -+ -+ put_net(net); -+ return 0; -+} -+ -+static struct genl_ops port_ops[] = { -+ { -+ .cmd = PORT_CMD_REPLY, -+ .policy = port_policy, -+ .doit = port_reply, -+ }, -+ { -+ .cmd = PORT_CMD_SET_STATS, -+ .policy = port_policy, -+ .doit = port_set_stats, -+ }, -+ { -+ .cmd = PORT_CMD_SET_SETTINGS, -+ .policy = port_policy, -+ .doit = port_set_settings_push, -+ }, -+ { -+ .cmd = PORT_CMD_SET_CARRIER, -+ .policy = port_policy, -+ .doit = port_set_carrier, -+ }, -+}; -+ -+static int encode_struct(struct sk_buff *skb, int attrtype, -+ size_t size, void *src) -+{ -+ NLA_PUT(skb, attrtype, size, src); -+ return 0; -+nla_put_failure: -+ return -EMSGSIZE; -+} -+ -+static int decode_struct(struct nlattr *attr, size_t size, void *dst) -+{ -+ if (!attr) -+ return -ENOSYS; -+ memcpy(dst, nla_data(attr), size); -+ return 0; -+ -+} -+ -+int port_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -+{ -+ int err, size = 0, wait = 20; -+ -+ int decode(struct nlattr **attrs, void *arg1, void *arg2) -+ { -+ return decode_struct(attrs[PORT_ATTR_SETTINGS], -+ sizeof(struct ethtool_cmd), arg1); -+ } -+ -+ err = port_cache_get_settings(dev->ifindex, cmd); -+ if (!err) -+ return 0; -+ -+ err = port_send(dev, PORT_CMD_GET_SETTINGS, size, wait, -+ NULL, decode, cmd, NULL); -+ if (err) -+ return err; -+ -+ port_cache_set_settings(dev->ifindex, cmd); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(port_get_settings); -+ -+int port_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -+{ -+ int size = nla_total_size(sizeof(struct ethtool_cmd)); -+ int wait = 20; -+ -+ int encode(struct sk_buff *skb, void *arg1, void *arg2) -+ { -+ return encode_struct(skb, PORT_ATTR_SETTINGS, -+ sizeof(struct ethtool_cmd), arg1); -+ } -+ -+ port_cache_clear_settings(dev->ifindex); -+ -+ return port_send(dev, PORT_CMD_SET_SETTINGS, size, wait, -+ encode, NULL, cmd, NULL); -+} -+EXPORT_SYMBOL_GPL(port_set_settings); -+ -+void port_get_pauseparam(struct net_device *dev, -+ struct ethtool_pauseparam *pause) -+{ -+ int size = 0, wait = 1; -+ -+ int decode(struct nlattr **attrs, void *arg1, void *arg2) -+ { -+ return decode_struct(attrs[PORT_ATTR_PAUSE], -+ sizeof(struct ethtool_pauseparam), -+ arg1); -+ } -+ -+ port_send(dev, PORT_CMD_GET_PAUSE, size, wait, -+ NULL, decode, pause, NULL); -+} -+EXPORT_SYMBOL_GPL(port_get_pauseparam); -+ -+int port_set_pauseparam(struct net_device *dev, -+ struct ethtool_pauseparam *pause) -+{ -+ int size = nla_total_size(sizeof(struct ethtool_pauseparam)); -+ int wait = 1; -+ -+ int encode(struct sk_buff *skb, void *arg1, void *arg2) -+ { -+ return encode_struct(skb, PORT_ATTR_PAUSE, -+ sizeof(struct ethtool_pauseparam), -+ arg1); -+ } -+ -+ return port_send(dev, PORT_CMD_SET_PAUSE, size, wait, -+ encode, NULL, pause, NULL); -+} -+EXPORT_SYMBOL_GPL(port_set_pauseparam); -+ -+void port_get_ethtool_stats(struct net_device *dev, -+ struct ethtool_stats *stats, -+ u64 *data) -+{ -+ memset(data, 0, stats->n_stats * sizeof(u64)); -+ port_cache_get_stats(dev->ifindex, stats, data, 0); -+} -+EXPORT_SYMBOL_GPL(port_get_ethtool_stats); -+ -+void port_get_ethtool_stats_clear(struct net_device *dev, -+ struct ethtool_stats *stats, -+ u64 *data) -+{ -+ memset(data, 0, stats->n_stats * sizeof(u64)); -+ port_cache_get_stats(dev->ifindex, stats, data, 1); -+} -+EXPORT_SYMBOL_GPL(port_get_ethtool_stats_clear); -+ -+void port_get_strings(struct net_device *dev, u32 stringset, u8 *data) -+{ -+ int size = nla_total_size(sizeof(u32)), wait = 1; -+ int err, count; -+ -+ int encode(struct sk_buff *skb, void *arg1, void *arg2) -+ { -+ u32 *stringset = arg1; -+ NLA_PUT_U32(skb, PORT_ATTR_SSET, *stringset); -+ return 0; -+ nla_put_failure: -+ return -EMSGSIZE; -+ } -+ -+ int decode(struct nlattr **attrs, void *arg1, void *arg2) -+ { -+ u8 *data = arg2; -+ struct nlattr *attr; -+ int rem; -+ if (!attrs[PORT_ATTR_STRINGS]) -+ return -EINVAL; -+ nla_for_each_nested(attr, attrs[PORT_ATTR_STRINGS], rem) { -+ memcpy(data, nla_data(attr), ETH_GSTRING_LEN); -+ data += ETH_GSTRING_LEN; -+ } -+ return 0; -+ } -+ -+ count = port_cache_get_sset_count(dev->ifindex, stringset); -+ if (count <= 0) -+ return; -+ -+ err = port_cache_get_stat_strings(dev->ifindex, count, data); -+ if (!err) -+ return; -+ -+ err = port_send(dev, PORT_CMD_GET_STRINGS, size, wait, -+ encode, decode, &stringset, data); -+ if (err) -+ return; -+ -+ port_cache_set_stat_strings(dev->ifindex, count, data); -+} -+EXPORT_SYMBOL_GPL(port_get_strings); -+ -+int port_get_sset_count(struct net_device *dev, int sset) -+{ -+ int size = nla_total_size(sizeof(u32)), wait = 1; -+ int count; -+ -+ int encode(struct sk_buff *skb, void *arg1, void *arg2) -+ { -+ int *sset = arg1; -+ NLA_PUT_U32(skb, PORT_ATTR_SSET, *sset); -+ return 0; -+ nla_put_failure: -+ return -EMSGSIZE; -+ } -+ -+ int decode(struct nlattr **attrs, void *arg1, void *arg2) -+ { -+ if (!attrs[PORT_ATTR_SSET_COUNT]) -+ return -EINVAL; -+ return nla_get_u32(attrs[PORT_ATTR_SSET_COUNT]); -+ } -+ -+ count = port_cache_get_sset_count(dev->ifindex, sset); -+ if (count >= 0) -+ return count; -+ -+ count = port_send(dev, PORT_CMD_GET_SSET_COUNT, size, wait, -+ encode, decode, &sset, NULL); -+ if (count < 0) -+ return count; -+ -+ port_cache_set_sset_count(dev->ifindex, sset, count); -+ -+ return count; -+} -+EXPORT_SYMBOL_GPL(port_get_sset_count); -+ -+int port_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state) -+{ -+ int size = nla_total_size(sizeof(u8)); -+ int wait = 0; -+ -+ int encode(struct sk_buff *skb, void *arg1, void *arg2) -+ { -+ enum ethtool_phys_id_state *state = arg1; -+ NLA_PUT_U8(skb, PORT_ATTR_PHYS_ID_STATE, *state); -+ return 0; -+ nla_put_failure: -+ return -EMSGSIZE; -+ } -+ -+ if (state == ETHTOOL_ID_ACTIVE) -+ return 1; /* 1 sec period */ -+ -+ return port_send(dev, PORT_CMD_SET_PHYS_ID_STATE, size, wait, -+ encode, NULL, &state, NULL); -+} -+EXPORT_SYMBOL_GPL(port_set_phys_id); -+ -+int port_get_module_info(struct net_device *dev, struct ethtool_modinfo *info) -+{ -+ int size = 0, wait = 30; -+ -+ int decode(struct nlattr **attrs, void *arg1, void *arg2) -+ { -+ return decode_struct(attrs[PORT_ATTR_MODINFO], -+ sizeof(struct ethtool_modinfo), arg1); -+ } -+ -+ return port_send(dev, PORT_CMD_GET_MODULE_INFO, size, wait, -+ NULL, decode, info, NULL); -+} -+EXPORT_SYMBOL_GPL(port_get_module_info); -+ -+int port_get_module_eeprom(struct net_device *dev, -+ struct ethtool_eeprom *eeprom, u8 *data) -+{ -+ int size = nla_total_size(sizeof(struct ethtool_eeprom)); -+ int wait = 30; -+ -+ int encode(struct sk_buff *skb, void *arg1, void *arg2) -+ { -+ return encode_struct(skb, PORT_ATTR_EEPROM, -+ sizeof(struct ethtool_eeprom), -+ arg1); -+ } -+ -+ int decode(struct nlattr **attrs, void *arg1, void *arg2) -+ { -+ if (!attrs[PORT_ATTR_EEPROM_DATA]) -+ return -EINVAL; -+ memcpy(arg2, nla_data(attrs[PORT_ATTR_EEPROM_DATA]), -+ nla_len(attrs[PORT_ATTR_EEPROM_DATA])); -+ return 0; -+ } -+ -+ return port_send(dev, PORT_CMD_GET_MODULE_EEPROM, size, wait, -+ encode, decode, eeprom, data); -+} -+EXPORT_SYMBOL_GPL(port_get_module_eeprom); -+ -+static int __init port_init(void) -+{ -+ int err; -+ -+ hash_init(port_cache); -+ -+ err = genl_register_family_with_ops(&port_family, -+ port_ops, ARRAY_SIZE(port_ops)); -+ if (err) -+ return err; -+ printk(KERN_DEBUG "port family register OK\n"); -+ -+ err = genl_register_mc_group(&port_family, -+ &port_mcgrp); -+ if (err) -+ goto err; -+ printk(KERN_DEBUG "port mc group register OK\n"); -+ -+ return 0; -+err: -+ genl_unregister_family(&port_family); -+ return err; -+} -+late_initcall(port_init); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-add-xtables-match-and-target-extensions.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-add-xtables-match-and-target-extensions.patch deleted file mode 100644 index 0092eb85..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-add-xtables-match-and-target-extensions.patch +++ /dev/null @@ -1,1402 +0,0 @@ -Add extensions modules for match and target for (x)tables. - -diff --git a/include/linux/netfilter/xt_ERSPAN.h b/include/linux/netfilter/xt_ERSPAN.h -new file mode 100644 -index 0000000..cc210cf ---- /dev/null -+++ b/include/linux/netfilter/xt_ERSPAN.h -@@ -0,0 +1,14 @@ -+#ifndef _XT_ERSPAN_TARGET_H -+#define _XT_ERSPAN_TARGET_H -+ -+struct xt_erspan_tginfo { -+ union nf_inet_addr src_ip; -+ union nf_inet_addr dst_ip; -+ __u8 ttl; -+ __u8 prec; -+ -+ /* used internally by the kernel */ -+ struct xt_erspan_priv *priv __attribute__((aligned(8))); -+}; -+ -+#endif /* _XT_ERSPAN_TARGET_H */ -diff --git a/include/linux/netfilter/xt_POLICE.h b/include/linux/netfilter/xt_POLICE.h -new file mode 100644 -index 0000000..d7918d1 ---- /dev/null -+++ b/include/linux/netfilter/xt_POLICE.h -@@ -0,0 +1,50 @@ -+#ifndef _XT_POLICE_TARGET_H -+#define _XT_POLICE_TARGET_H -+ -+#define XT_POLICE_CLASS 0x01 -+#define XT_POLICE_RATE 0x02 -+#define XT_POLICE_BURST 0x04 -+#define XT_POLICE_MODE 0x08 -+#define XT_POLICE_VIOLATE_ACTION 0x10 -+#define XT_POLICE_MASK (XT_POLICE_CLASS | XT_POLICE_RATE | XT_POLICE_BURST | XT_POLICE_MODE | \ -+ XT_POLICE_VIOLATE_ACTION) -+ -+#define XT_POLICE_MIN_CLASS 0 -+#define XT_POLICE_MAX_CLASS 7 -+ -+#define XT_POLICE_MIN_RATE 1 -+#define XT_POLICE_MAX_RATE 200000 -+ -+#define XT_POLICE_MIN_BURST 1 -+#define XT_POLICE_MAX_BURST 2000 -+ -+#define XT_POLICE_MODE_PPS 0 -+#define XT_POLICE_MODE_KB 1 -+ -+/* POLICE ACTION */ -+typedef enum { -+ XT_POLICE_ACTION_PERMIT = 0, -+ XT_POLICE_ACTION_DENY, -+ XT_POLICE_ACTION_MAX_FIELD -+} xt_police_action_e; -+ -+/* Action & DSCP value */ -+typedef struct xt_police_action { -+ xt_police_action_e type; -+} xt_police_action_t; -+ -+ -+struct xt_police_tginfo { -+ __u8 class; -+ __u8 mode; -+ __u16 rate; -+ __u16 burst; -+ __u32 bitmask; -+ -+ xt_police_action_t violate_action; -+ -+ /* used internally by the kernel */ -+ struct xt_police_priv *priv __attribute__((aligned(8))); -+}; -+ -+#endif /* _XT_POLICE_TARGET_H */ -diff --git a/include/linux/netfilter/xt_SETCLASS.h b/include/linux/netfilter/xt_SETCLASS.h -new file mode 100644 -index 0000000..be80cd5 ---- /dev/null -+++ b/include/linux/netfilter/xt_SETCLASS.h -@@ -0,0 +1,10 @@ -+#ifndef _XT_SETCLASS_H -+#define _XT_SETCLASS_H -+ -+#include -+ -+struct xt_setclass_target_info { -+ __u32 priority; -+}; -+ -+#endif /*_XT_SETCLASS_H */ -diff --git a/include/linux/netfilter/xt_SETQOS.h b/include/linux/netfilter/xt_SETQOS.h -new file mode 100644 -index 0000000..6a238ca ---- /dev/null -+++ b/include/linux/netfilter/xt_SETQOS.h -@@ -0,0 +1,22 @@ -+#ifndef _XT_SETQOS_H -+#define _XT_SETQOS_H -+ -+#include -+ -+#define XT_SETQOS_COS 0x01 -+#define XT_SETQOS_DSCP 0x02 -+ -+#define XT_SETQOS_MIN_COS 0 -+#define XT_SETQOS_MAX_COS 7 -+ -+#define XT_SETQOS_DSCP_MASK 0xfc /* 11111100 */ -+#define XT_SETQOS_DSCP_SHIFT 2 -+#define XT_SETQOS_DSCP_MAX 0x3f /* 00111111 */ -+ -+struct xt_setqos_target_info { -+ __u8 cos; -+ __u8 dscp; -+ __u8 bitmask; -+}; -+ -+#endif /*_XT_SETQOS_H */ -diff --git a/include/linux/netfilter/xt_SPAN.h b/include/linux/netfilter/xt_SPAN.h -new file mode 100644 -index 0000000..74e8cef ---- /dev/null -+++ b/include/linux/netfilter/xt_SPAN.h -@@ -0,0 +1,11 @@ -+#ifndef _XT_SPAN_TARGET_H -+#define _XT_SPAN_TARGET_H -+ -+struct xt_span_tginfo { -+ char dport[16]; -+ -+ /* used internally by the kernel */ -+ struct xt_span_priv *priv __attribute__((aligned(8))); -+}; -+ -+#endif /* _XT_SPAN_TARGET_H */ -diff --git a/include/linux/netfilter/xt_TRICOLORPOLICE.h b/include/linux/netfilter/xt_TRICOLORPOLICE.h -new file mode 100644 -index 0000000..6c242ce ---- /dev/null -+++ b/include/linux/netfilter/xt_TRICOLORPOLICE.h -@@ -0,0 +1,65 @@ -+#ifndef _XT_TRICOLORPOLICE_TARGET_H -+#define _XT_TRICOLORPOLICE_TARGET_H -+ -+#define XT_TRICOLOR_POLICE_COLOR_MODE 0x01 -+#define XT_TRICOLOR_POLICE_CIR 0x02 -+#define XT_TRICOLOR_POLICE_CBS 0x04 -+#define XT_TRICOLOR_POLICE_PIR 0x08 -+#define XT_TRICOLOR_POLICE_EBS 0x10 -+#define XT_TRICOLOR_POLICE_VIOLATE_ACTION 0x20 -+#define XT_TRICOLOR_POLICE_CONFORM_ACTION_DSCP 0x40 -+#define XT_TRICOLOR_POLICE_EXCEED_ACTION_DSCP 0x80 -+#define XT_TRICOLOR_POLICE_VIOLATE_ACTION_DSCP 0x100 -+#define XT_TRICOLOR_POLICE_MAX 0x200 -+ -+#define XT_TRICOLOR_POLICE_MASK (XT_TRICOLOR_POLICE_MAX - 1) -+ -+#define XT_TRICOLOR_POLICE_MIN_CLASS 0 -+#define XT_TRICOLOR_POLICE_MAX_CLASS 7 -+ -+#define XT_TRICOLOR_POLICE_MIN_CIR 0 -+#define XT_TRICOLOR_POLICE_MAX_CIR 0xFFFFFFFF -+ -+#define XT_TRICOLOR_POLICE_MIN_CBS 0 -+#define XT_TRICOLOR_POLICE_MAX_CBS 0xFFFFFFFF -+ -+#define XT_TRICOLOR_POLICE_MIN_PIR 0 -+#define XT_TRICOLOR_POLICE_MAX_PIR 0xFFFFFFFF -+ -+#define XT_TRICOLOR_POLICE_MIN_EBS 0 -+#define XT_TRICOLOR_POLICE_MAX_EBS 0xFFFFFFFF -+ -+#define XT_TRICOLOR_POLICE_COLOR_MODE_BLIND 0 -+#define XT_TRICOLOR_POLICE_COLOR_MODE_AWARE 1 -+ -+/* TRICOLOR_POLICE ACTION */ -+typedef enum { -+ XT_TRICOLOR_POLICE_ACTION_PERMIT = 0, -+ XT_TRICOLOR_POLICE_ACTION_DENY, -+ XT_TRICOLOR_POLICE_ACTION_MAX_FIELD -+} xt_tricolor_police_action_e; -+ -+/* Action & DSCP value */ -+typedef struct xt_tricolor_police_action { -+ xt_tricolor_police_action_e type; -+ __u8 dscp_value; -+} xt_tricolor_police_action_t; -+ -+ -+struct xt_tricolor_police_tginfo { -+ __u8 color_mode; -+ __u32 cir; -+ __u32 cbs; -+ __u32 pir; -+ __u32 ebs; -+ __u32 bitmask; -+ -+ xt_tricolor_police_action_t conform_action; -+ xt_tricolor_police_action_t exceed_action; -+ xt_tricolor_police_action_t violate_action; -+ -+ /* used internally by the kernel */ -+ struct xt_tricolor_police_priv *priv __attribute__((aligned(8))); -+}; -+ -+#endif /* _XT_TRICOLORPOLICE_TARGET_H */ -diff --git a/include/linux/netfilter/xt_addrtype.h b/include/linux/netfilter/xt_addrtype.h -index b156baa..30d1304 100644 ---- a/include/linux/netfilter/xt_addrtype.h -+++ b/include/linux/netfilter/xt_addrtype.h -@@ -25,6 +25,7 @@ enum { - XT_ADDRTYPE_THROW = 1 << 9, - XT_ADDRTYPE_NAT = 1 << 10, - XT_ADDRTYPE_XRESOLVE = 1 << 11, -+ XT_ADDRTYPE_IPROUTER = 1 << 12, - }; - - struct xt_addrtype_info_v1 { -diff --git a/include/linux/netfilter_bridge/ebt_erspan.h b/include/linux/netfilter_bridge/ebt_erspan.h -new file mode 100644 -index 0000000..b2962fc ---- /dev/null -+++ b/include/linux/netfilter_bridge/ebt_erspan.h -@@ -0,0 +1,20 @@ -+#ifndef __LINUX_BRIDGE_EBT_ERSPAN_H -+#define __LINUX_BRIDGE_EBT_ERSPAN_H -+ -+#define EBT_ERSPAN_SRC_IP 0x01 -+#define EBT_ERSPAN_DST_IP 0x02 -+#define EBT_ERSPAN_TTL 0x04 -+#define EBT_ERSPAN_PREC 0x08 -+#define EBT_ERSPAN_MASK (EBT_ERSPAN_SRC_IP | EBT_ERSPAN_DST_IP | EBT_ERSPAN_TTL | EBT_ERSPAN_PREC) -+ -+struct ebt_erspan_info { -+ __be32 src_ip; -+ __be32 dst_ip; -+ __u8 ttl; -+ __u8 prec; -+ __u8 bitmask; -+ int target; -+}; -+#define EBT_ERSPAN_TARGET "erspan" -+ -+#endif -diff --git a/include/linux/netfilter_bridge/ebt_police.h b/include/linux/netfilter_bridge/ebt_police.h -new file mode 100644 -index 0000000..8b8e11c ---- /dev/null -+++ b/include/linux/netfilter_bridge/ebt_police.h -@@ -0,0 +1,32 @@ -+#ifndef __LINUX_BRIDGE_EBT_POLICE_H -+#define __LINUX_BRIDGE_EBT_POLICE_H -+ -+#define EBT_POLICE_CLASS 0x01 -+#define EBT_POLICE_RATE 0x02 -+#define EBT_POLICE_BURST 0x04 -+#define EBT_POLICE_MODE 0x08 -+#define EBT_POLICE_MASK (EBT_POLICE_CLASS | EBT_POLICE_RATE | EBT_POLICE_BURST | EBT_POLICE_MODE) -+ -+#define EBT_POLICE_MIN_CLASS 0 -+#define EBT_POLICE_MAX_CLASS 7 -+ -+#define EBT_POLICE_MIN_RATE 1 -+#define EBT_POLICE_MAX_RATE 200000 -+ -+#define EBT_POLICE_MIN_BURST 1 -+#define EBT_POLICE_MAX_BURST 2000 -+ -+#define EBT_POLICE_MODE_PPS 0 -+#define EBT_POLICE_MODE_KB 1 -+ -+struct ebt_police_info { -+ __u8 class; -+ __u8 mode; -+ __u16 rate; -+ __u16 burst; -+ __u8 bitmask; -+ int target; -+}; -+#define EBT_POLICE_TARGET "police" -+ -+#endif -diff --git a/include/linux/netfilter_bridge/ebt_setclass.h b/include/linux/netfilter_bridge/ebt_setclass.h -new file mode 100644 -index 0000000..99a8d07 ---- /dev/null -+++ b/include/linux/netfilter_bridge/ebt_setclass.h -@@ -0,0 +1,16 @@ -+#ifndef __LINUX_BRIDGE_EBT_SETCLASS_H -+#define __LINUX_BRIDGE_EBT_SETCLASS_H -+ -+#define EBT_POLICE_CLASS 0x01 -+ -+#define EBT_POLICE_MIN_CLASS 0 -+#define EBT_POLICE_MAX_CLASS 7 -+ -+struct ebt_setclass_info { -+ __u8 class; -+ __u8 bitmask; -+ int target; -+}; -+#define EBT_SETCLASS_TARGET "setclass" -+ -+#endif -diff --git a/include/linux/netfilter_bridge/ebt_span.h b/include/linux/netfilter_bridge/ebt_span.h -new file mode 100644 -index 0000000..1f1b935 ---- /dev/null -+++ b/include/linux/netfilter_bridge/ebt_span.h -@@ -0,0 +1,14 @@ -+#ifndef __LINUX_BRIDGE_EBT_SPAN_H -+#define __LINUX_BRIDGE_EBT_SPAN_H -+ -+#define EBT_SPAN_DPORT 0x01 -+#define EBT_SPAN_MASK (EBT_ERSPAN_DPORT) -+ -+struct ebt_span_info { -+ char dport[16]; -+ __u8 bitmask; -+ int target; -+}; -+#define EBT_SPAN_TARGET "span" -+ -+#endif -diff --git a/include/linux/netfilter_bridge/ebt_tricolorpolice.h b/include/linux/netfilter_bridge/ebt_tricolorpolice.h -new file mode 100644 -index 0000000..78b65c5 ---- /dev/null -+++ b/include/linux/netfilter_bridge/ebt_tricolorpolice.h -@@ -0,0 +1,62 @@ -+#ifndef __LINUX_BRIDGE_EBT_TRICOLORPOLICE_H -+#define __LINUX_BRIDGE_EBT_TRICOLORPOLICE_H -+ -+#define EBT_TRICOLOR_POLICE_COLOR_MODE 0x01 -+#define EBT_TRICOLOR_POLICE_CIR 0x02 -+#define EBT_TRICOLOR_POLICE_CBS 0x04 -+#define EBT_TRICOLOR_POLICE_PIR 0x08 -+#define EBT_TRICOLOR_POLICE_EBS 0x10 -+#define EBT_TRICOLOR_POLICE_VIOLATE_ACTION 0x20 -+#define EBT_TRICOLOR_POLICE_CONFORM_ACTION_DSCP 0x40 -+#define EBT_TRICOLOR_POLICE_EXCEED_ACTION_DSCP 0x80 -+#define EBT_TRICOLOR_POLICE_VIOLATE_ACTION_DSCP 0x100 -+#define EBT_TRICOLOR_POLICE_MAX 0x200 -+ -+#define EBT_TRICOLOR_POLICE_MASK (EBT_TRICOLOR_POLICE_MAX - 1) -+ -+#define EBT_TRICOLOR_POLICE_MIN_CLASS 0 -+#define EBT_TRICOLOR_POLICE_MAX_CLASS 7 -+ -+#define EBT_TRICOLOR_POLICE_MIN_CIR 0 -+#define EBT_TRICOLOR_POLICE_MAX_CIR 0xFFFFFFFF -+ -+#define EBT_TRICOLOR_POLICE_MIN_CBS 0 -+#define EBT_TRICOLOR_POLICE_MAX_CBS 0xFFFFFFFF -+ -+#define EBT_TRICOLOR_POLICE_MIN_PIR 0 -+#define EBT_TRICOLOR_POLICE_MAX_PIR 0xFFFFFFFF -+ -+#define EBT_TRICOLOR_POLICE_MIN_EBS 0 -+#define EBT_TRICOLOR_POLICE_MAX_EBS 0xFFFFFFFF -+ -+#define EBT_TRICOLOR_POLICE_COLOR_MODE_BLIND 0 -+#define EBT_TRICOLOR_POLICE_COLOR_MODE_AWARE 1 -+ -+/* TRICOLOR_POLICE ACTION */ -+typedef enum { -+ EBT_TRICOLOR_POLICE_ACTION_PERMIT = 0, -+ EBT_TRICOLOR_POLICE_ACTION_DENY, -+ EBT_TRICOLOR_POLICE_ACTION_MAX_FIELD -+} ebt_tricolor_police_action_e; -+ -+/* Action & DSCP value */ -+typedef struct ebt_tricolor_police_action { -+ ebt_tricolor_police_action_e type; -+ __u8 dscp_value; -+} ebt_tricolor_police_action_t; -+ -+struct ebt_tricolor_police_info { -+ __u8 color_mode; -+ __u32 cir; -+ __u32 cbs; -+ __u32 pir; -+ __u32 ebs; -+ __u32 bitmask; -+ -+ ebt_tricolor_police_action_t conform_action; -+ ebt_tricolor_police_action_t exceed_action; -+ ebt_tricolor_police_action_t violate_action; -+}; -+#define EBT_TRICOLORPOLICE_TARGET "tricolorpolice" -+ -+#endif /* __LINUX_BRIDGE_EBT_TRICOLORPOLICE_H */ -diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig -index a9aff9c..f298b47 100644 ---- a/net/bridge/netfilter/Kconfig -+++ b/net/bridge/netfilter/Kconfig -@@ -218,4 +218,39 @@ config BRIDGE_EBT_NFLOG - - To compile it as a module, choose M here. If unsure, say N. - -+config BRIDGE_EBT_ERSPAN -+ tristate "ebt: erspan support" -+ help -+ This option enables the support for ERSPAN -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config BRIDGE_EBT_SPAN -+ tristate "ebt: span support" -+ help -+ This option enables the support for SPAN -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config BRIDGE_EBT_POLICE -+ tristate "ebt: traffic policing support" -+ help -+ This option enables the support for traffic policing -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config BRIDGE_EBT_TRICOLORPOLICE -+ tristate "ebt: traffic tricolorpolicing support" -+ help -+ This option enables the support for 3 color traffic policing -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config BRIDGE_EBT_SETCLASS -+ tristate "ebt: set ingress traffic class" -+ help -+ This option enables the support for setting ingress traffic class -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ - endif # BRIDGE_NF_EBTABLES -diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile -index 0718699..678094e 100644 ---- a/net/bridge/netfilter/Makefile -+++ b/net/bridge/netfilter/Makefile -@@ -27,6 +27,11 @@ obj-$(CONFIG_BRIDGE_EBT_MARK_T) += ebt_mark.o - obj-$(CONFIG_BRIDGE_EBT_DNAT) += ebt_dnat.o - obj-$(CONFIG_BRIDGE_EBT_REDIRECT) += ebt_redirect.o - obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o -+obj-$(CONFIG_BRIDGE_EBT_ERSPAN) += ebt_erspan.o -+obj-$(CONFIG_BRIDGE_EBT_SPAN) += ebt_span.o -+obj-$(CONFIG_BRIDGE_EBT_POLICE) += ebt_police.o -+obj-$(CONFIG_BRIDGE_EBT_TRICOLORPOLICE) += ebt_tricolorpolice.o -+obj-$(CONFIG_BRIDGE_EBT_SETCLASS) += ebt_setclass.o - - # watchers - obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o -diff --git a/net/bridge/netfilter/ebt_erspan.c b/net/bridge/netfilter/ebt_erspan.c -new file mode 100644 -index 0000000..d1503bf ---- /dev/null -+++ b/net/bridge/netfilter/ebt_erspan.c -@@ -0,0 +1,54 @@ -+/* -+ * ebt_erspan -+ * -+ * Copyright 2013 Cumulus Networks, LLC. All rights reserved. -+ * -+ * Authors: -+ * Wilson Kok -+ * -+ */ -+#include -+#include -+#include "../br_private.h" -+#include -+#include -+#include -+#include -+ -+static unsigned int -+ebt_erspan_tg(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ return EBT_CONTINUE; -+} -+ -+static int ebt_erspan_tg_check(const struct xt_tgchk_param *par) -+{ -+ return 0; -+} -+ -+static struct xt_target ebt_erspan_tg_reg __read_mostly = { -+ .name = "erspan", -+ .revision = 0, -+ .family = NFPROTO_BRIDGE, -+ .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_LOCAL_IN) | -+ (1 << NF_BR_FORWARD) | (1 << NF_BR_LOCAL_OUT), -+ .target = ebt_erspan_tg, -+ .checkentry = ebt_erspan_tg_check, -+ .targetsize = sizeof(struct ebt_erspan_info), -+ .me = THIS_MODULE, -+}; -+ -+static int __init ebt_erspan_init(void) -+{ -+ return xt_register_target(&ebt_erspan_tg_reg); -+} -+ -+static void __exit ebt_erspan_fini(void) -+{ -+ xt_unregister_target(&ebt_erspan_tg_reg); -+} -+ -+module_init(ebt_erspan_init); -+module_exit(ebt_erspan_fini); -+MODULE_DESCRIPTION("Ebtables: Encapsulated Remote Switch Port Analyzer"); -+MODULE_LICENSE("GPL"); -diff --git a/net/bridge/netfilter/ebt_police.c b/net/bridge/netfilter/ebt_police.c -new file mode 100644 -index 0000000..a0603cb ---- /dev/null -+++ b/net/bridge/netfilter/ebt_police.c -@@ -0,0 +1,51 @@ -+/* -+ * ebt_police -+ * -+ * Copyright 2013 Cumulus Networks, LLC. All rights reserved. -+ * -+ * Authors: -+ * Wilson Kok -+ * -+ */ -+#include -+#include -+#include -+#include -+ -+static unsigned int -+ebt_police_tg(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ return EBT_ACCEPT; -+} -+ -+static int ebt_police_tg_check(const struct xt_tgchk_param *par) -+{ -+ return 0; -+} -+ -+static struct xt_target ebt_police_tg_reg __read_mostly = { -+ .name = "police", -+ .revision = 0, -+ .family = NFPROTO_BRIDGE, -+ .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_LOCAL_IN) | -+ (1 << NF_BR_FORWARD), -+ .target = ebt_police_tg, -+ .checkentry = ebt_police_tg_check, -+ .targetsize = sizeof(struct ebt_police_info), -+ .me = THIS_MODULE, -+}; -+ -+static int __init ebt_police_init(void) -+{ -+ return xt_register_target(&ebt_police_tg_reg); -+} -+ -+static void __exit ebt_police_fini(void) -+{ -+ xt_unregister_target(&ebt_police_tg_reg); -+} -+ -+module_init(ebt_police_init); -+module_exit(ebt_police_fini); -+MODULE_DESCRIPTION("Ebtables: Packet policing support"); -+MODULE_LICENSE("GPL"); -diff --git a/net/bridge/netfilter/ebt_setclass.c b/net/bridge/netfilter/ebt_setclass.c -new file mode 100644 -index 0000000..317293b ---- /dev/null -+++ b/net/bridge/netfilter/ebt_setclass.c -@@ -0,0 +1,51 @@ -+/* -+ * ebt_setclass -+ * -+ * Copyright 2013 Cumulus Networks, LLC. All rights reserved. -+ * -+ * Authors: -+ * Wilson Kok -+ * -+ */ -+#include -+#include -+#include -+#include -+ -+static unsigned int -+ebt_setclass_tg(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ return EBT_ACCEPT; -+} -+ -+static int ebt_setclass_tg_check(const struct xt_tgchk_param *par) -+{ -+ return 0; -+} -+ -+static struct xt_target ebt_setclass_tg_reg __read_mostly = { -+ .name = "setclass", -+ .revision = 0, -+ .family = NFPROTO_BRIDGE, -+ .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_LOCAL_IN) | -+ (1 << NF_BR_FORWARD), -+ .target = ebt_setclass_tg, -+ .checkentry = ebt_setclass_tg_check, -+ .targetsize = sizeof(struct ebt_setclass_info), -+ .me = THIS_MODULE, -+}; -+ -+static int __init ebt_setclass_init(void) -+{ -+ return xt_register_target(&ebt_setclass_tg_reg); -+} -+ -+static void __exit ebt_setclass_fini(void) -+{ -+ xt_unregister_target(&ebt_setclass_tg_reg); -+} -+ -+module_init(ebt_setclass_init); -+module_exit(ebt_setclass_fini); -+MODULE_DESCRIPTION("Ebtables: Ingress classification"); -+MODULE_LICENSE("GPL"); -diff --git a/net/bridge/netfilter/ebt_span.c b/net/bridge/netfilter/ebt_span.c -new file mode 100644 -index 0000000..2846ba3 ---- /dev/null -+++ b/net/bridge/netfilter/ebt_span.c -@@ -0,0 +1,53 @@ -+/* -+ * ebt_span -+ * -+ * Copyright 2013 Cumulus Networks, LLC. All rights reserved. -+ * -+ * Authors: -+ * Wilson Kok -+ */ -+#include -+#include -+#include "../br_private.h" -+#include -+#include -+#include -+#include -+ -+static unsigned int -+ebt_span_tg(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ return EBT_CONTINUE; -+} -+ -+static int ebt_span_tg_check(const struct xt_tgchk_param *par) -+{ -+ return 0; -+} -+ -+static struct xt_target ebt_span_tg_reg __read_mostly = { -+ .name = "span", -+ .revision = 0, -+ .family = NFPROTO_BRIDGE, -+ .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_LOCAL_IN) | -+ (1 << NF_BR_FORWARD) | (1 << NF_BR_LOCAL_OUT), -+ .target = ebt_span_tg, -+ .checkentry = ebt_span_tg_check, -+ .targetsize = sizeof(struct ebt_span_info), -+ .me = THIS_MODULE, -+}; -+ -+static int __init ebt_span_init(void) -+{ -+ return xt_register_target(&ebt_span_tg_reg); -+} -+ -+static void __exit ebt_span_fini(void) -+{ -+ xt_unregister_target(&ebt_span_tg_reg); -+} -+ -+module_init(ebt_span_init); -+module_exit(ebt_span_fini); -+MODULE_DESCRIPTION("Ebtables: Switch Port Analyzer"); -+MODULE_LICENSE("GPL"); -diff --git a/net/bridge/netfilter/ebt_tricolorpolice.c b/net/bridge/netfilter/ebt_tricolorpolice.c -new file mode 100644 -index 0000000..9a878ca ---- /dev/null -+++ b/net/bridge/netfilter/ebt_tricolorpolice.c -@@ -0,0 +1,51 @@ -+/* -+ * ebt_tricolorpolice -+ * -+ * Copyright 2013 Cumulus Networks, LLC. All rights reserved. -+ * -+ * Authors: -+ * James Li -+ * -+ */ -+#include -+#include -+#include -+#include -+ -+static unsigned int -+ebt_tricolorpolice_tg(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ return EBT_ACCEPT; -+} -+ -+static int ebt_tricolorpolice_tg_check(const struct xt_tgchk_param *par) -+{ -+ return 0; -+} -+ -+static struct xt_target ebt_tricolorpolice_tg_reg __read_mostly = { -+ .name = "tricolorpolice", -+ .revision = 0, -+ .family = NFPROTO_BRIDGE, -+ .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_LOCAL_IN) | -+ (1 << NF_BR_FORWARD), -+ .target = ebt_tricolorpolice_tg, -+ .checkentry = ebt_tricolorpolice_tg_check, -+ .targetsize = sizeof(struct ebt_tricolor_police_info), -+ .me = THIS_MODULE, -+}; -+ -+static int __init ebt_tricolorpolice_init(void) -+{ -+ return xt_register_target(&ebt_tricolorpolice_tg_reg); -+} -+ -+static void __exit ebt_tricolorpolice_fini(void) -+{ -+ xt_unregister_target(&ebt_tricolorpolice_tg_reg); -+} -+ -+module_init(ebt_tricolorpolice_init); -+module_exit(ebt_tricolorpolice_fini); -+MODULE_DESCRIPTION("Ebtables: Packet three color policing support"); -+MODULE_LICENSE("GPL"); -diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig -index d5597b7..b3dd036 100644 ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -643,6 +643,48 @@ config NETFILTER_XT_TARGET_TCPOPTSTRIP - This option adds a "TCPOPTSTRIP" target, which allows you to strip - TCP options from TCP packets. - -+config NETFILTER_XT_TARGET_ERSPAN -+ tristate '"ERSPAN" - packet cloning to alternate destination' -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ This option adds a "ERSPAN" target with which a packet can be cloned and -+ this clone be rerouted to another nexthop. -+ -+config NETFILTER_XT_TARGET_SPAN -+ tristate '"SPAN" - packet cloning to a local port' -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ This option adds a "SPAN" target with which a packet can be cloned and -+ this clone be forwarded out of a designated local port. -+ -+config NETFILTER_XT_TARGET_POLICE -+ tristate '"POLICE" - policing packets' -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ This option adds a "POLICE" target with which the rate of traffic is -+ limited to a set rate and burst. -+ -+config NETFILTER_XT_TARGET_TRICOLORPOLICE -+ tristate '"TRICOLORPOLICE" - 3 color policing packets' -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ This option adds a "TRICOLORPOLICE" target -+ -+config NETFILTER_XT_TARGET_SETCLASS -+ tristate '"SETCLASS" - setting ingress traffic class' -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ This option adds a "SETCLASS" target with which the traffic class is -+ set at the ingress of the datapath. -+ -+config NETFILTER_XT_TARGET_SETQOS -+ tristate '"SETQOS" - setting ingress traffic class' -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ This option adds a "SETQOS" target with which the traffic class is -+ set at the ingress of the datapath. -+ -+ - # alphabetically ordered list of matches - - comment "Xtables matches" -diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile -index 1a02853..5016031 100644 ---- a/net/netfilter/Makefile -+++ b/net/netfilter/Makefile -@@ -66,6 +66,12 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o - obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o - obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o - obj-$(CONFIG_NETFILTER_XT_TARGET_TEE) += xt_TEE.o -+obj-$(CONFIG_NETFILTER_XT_TARGET_ERSPAN) += xt_ERSPAN.o -+obj-$(CONFIG_NETFILTER_XT_TARGET_SPAN) += xt_SPAN.o -+obj-$(CONFIG_NETFILTER_XT_TARGET_POLICE) += xt_POLICE.o -+obj-$(CONFIG_NETFILTER_XT_TARGET_TRICOLORPOLICE) += xt_TRICOLORPOLICE.o -+obj-$(CONFIG_NETFILTER_XT_TARGET_SETCLASS) += xt_SETCLASS.o -+obj-$(CONFIG_NETFILTER_XT_TARGET_SETQOS) += xt_SETQOS.o - obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o - obj-$(CONFIG_NETFILTER_XT_TARGET_IDLETIMER) += xt_IDLETIMER.o - -diff --git a/net/netfilter/xt_ERSPAN.c b/net/netfilter/xt_ERSPAN.c -new file mode 100644 -index 0000000..c2b8b5a ---- /dev/null -+++ b/net/netfilter/xt_ERSPAN.c -@@ -0,0 +1,135 @@ -+/* -+ * "ERSPAN" target extension for Xtables -+ * Copyright 2013 Cumulus Networks, LLC. 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 or later, as published by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) -+# define WITH_CONNTRACK 1 -+# include -+#endif -+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+# define WITH_IPV6 1 -+#endif -+ -+struct xt_erspan_priv { -+ struct notifier_block notifier; -+ struct xt_erspan_tginfo *tginfo; -+ int oif; -+}; -+ -+static const union nf_inet_addr erspan_zero_address; -+ -+static struct net *pick_net(struct sk_buff *skb) -+{ -+#ifdef CONFIG_NET_NS -+ const struct dst_entry *dst; -+ -+ if (skb->dev != NULL) -+ return dev_net(skb->dev); -+ dst = skb_dst(skb); -+ if (dst != NULL && dst->dev != NULL) -+ return dev_net(dst->dev); -+#endif -+ return &init_net; -+} -+ -+static unsigned int -+erspan_tg4(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ return XT_CONTINUE; -+} -+ -+#ifdef WITH_IPV6 -+static unsigned int -+erspan_tg6(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ return XT_CONTINUE; -+} -+#endif /* WITH_IPV6 */ -+ -+static int erspan_tg_check(const struct xt_tgchk_param *par) -+{ -+ struct xt_erspan_tginfo *info = par->targinfo; -+ -+ /* 0.0.0.0 and :: not allowed */ -+ if (memcmp(&info->src_ip, &erspan_zero_address, -+ sizeof(erspan_zero_address)) == 0) -+ return -EINVAL; -+ -+ if (memcmp(&info->dst_ip, &erspan_zero_address, -+ sizeof(erspan_zero_address)) == 0) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static void erspan_tg_destroy(const struct xt_tgdtor_param *par) -+{ -+ struct xt_erspan_tginfo *info = par->targinfo; -+ -+ if (info->priv) { -+ unregister_netdevice_notifier(&info->priv->notifier); -+ kfree(info->priv); -+ } -+} -+ -+static struct xt_target erspan_tg_reg[] __read_mostly = { -+ { -+ .name = "ERSPAN", -+ .revision = 1, -+ .family = NFPROTO_IPV4, -+ .target = erspan_tg4, -+ .targetsize = sizeof(struct xt_erspan_tginfo), -+ .checkentry = erspan_tg_check, -+ .destroy = erspan_tg_destroy, -+ .me = THIS_MODULE, -+ }, -+#ifdef WITH_IPV6 -+ { -+ .name = "ERSPAN", -+ .revision = 1, -+ .family = NFPROTO_IPV6, -+ .target = erspan_tg6, -+ .targetsize = sizeof(struct xt_erspan_tginfo), -+ .checkentry = erspan_tg_check, -+ .destroy = erspan_tg_destroy, -+ .me = THIS_MODULE, -+ }, -+#endif -+}; -+ -+static int __init erspan_tg_init(void) -+{ -+ return xt_register_targets(erspan_tg_reg, ARRAY_SIZE(erspan_tg_reg)); -+} -+ -+static void __exit erspan_tg_exit(void) -+{ -+ xt_unregister_targets(erspan_tg_reg, ARRAY_SIZE(erspan_tg_reg)); -+} -+ -+module_init(erspan_tg_init); -+module_exit(erspan_tg_exit); -+MODULE_AUTHOR("Wilson Kok "); -+MODULE_DESCRIPTION("Xtables: Encapsulated Remote Switch Port Analyzer"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("ipt_ERSPAN"); -+MODULE_ALIAS("ip6t_ERSPAN"); -diff --git a/net/netfilter/xt_POLICE.c b/net/netfilter/xt_POLICE.c -new file mode 100644 -index 0000000..fdd6415 ---- /dev/null -+++ b/net/netfilter/xt_POLICE.c -@@ -0,0 +1,82 @@ -+/* -+ * "POLICE" target extension for Xtables -+ * Copyright 2013 Cumulus Networks, LLC. 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 or later, as published by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct xt_police_priv { -+ struct notifier_block notifier; -+ struct xt_police_tginfo *tginfo; -+}; -+ -+static unsigned int -+police_tg(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ return NF_ACCEPT; -+} -+ -+static int police_tg_check(const struct xt_tgchk_param *par) -+{ -+ struct xt_police_tginfo *info = par->targinfo; -+ -+ if (info->class > XT_POLICE_MAX_CLASS) -+ return -EINVAL; -+ if (info->rate < XT_POLICE_MIN_RATE || info->rate > XT_POLICE_MAX_RATE) -+ return -EINVAL; -+ if (info->burst < XT_POLICE_MIN_BURST || info->burst > XT_POLICE_MAX_BURST) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static void police_tg_destroy(const struct xt_tgdtor_param *par) -+{ -+} -+ -+static struct xt_target police_tg_reg[] __read_mostly = { -+ { -+ .name = "POLICE", -+ .revision = 1, -+ .family = NFPROTO_UNSPEC, -+ .target = police_tg, -+ .targetsize = sizeof(struct xt_police_tginfo), -+ .checkentry = police_tg_check, -+ .destroy = police_tg_destroy, -+ .me = THIS_MODULE, -+ }, -+}; -+ -+static int __init police_tg_init(void) -+{ -+ return xt_register_targets(police_tg_reg, ARRAY_SIZE(police_tg_reg)); -+} -+ -+static void __exit police_tg_exit(void) -+{ -+ xt_unregister_targets(police_tg_reg, ARRAY_SIZE(police_tg_reg)); -+} -+ -+module_init(police_tg_init); -+module_exit(police_tg_exit); -+MODULE_AUTHOR("Wilson Kok "); -+MODULE_DESCRIPTION("Xtables: Policing"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("ipt_POLICE"); -+MODULE_ALIAS("ip6t_POLICE"); -diff --git a/net/netfilter/xt_SETCLASS.c b/net/netfilter/xt_SETCLASS.c -new file mode 100644 -index 0000000..6a1667a ---- /dev/null -+++ b/net/netfilter/xt_SETCLASS.c -@@ -0,0 +1,73 @@ -+/* -+ * "SETCLASS" target extension for Xtables -+ * Copyright 2013 Cumulus Networks, LLC. 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. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+MODULE_AUTHOR("Wilson Kok "); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Xtables: Ingress classification"); -+MODULE_ALIAS("ipt_SETCLASS"); -+MODULE_ALIAS("ip6t_SETCLASS"); -+MODULE_ALIAS("arpt_SETCLASS"); -+ -+static unsigned int -+setclass_tg(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ const struct xt_setclass_target_info *clinfo = par->targinfo; -+ -+ skb->priority = clinfo->priority; -+ -+ return NF_ACCEPT; -+} -+ -+static struct xt_target setclass_tg_reg[] __read_mostly = { -+ { -+ .name = "SETCLASS", -+ .revision = 0, -+ .family = NFPROTO_UNSPEC, -+ .hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) | -+ (1 << NF_INET_PRE_ROUTING), -+ .target = setclass_tg, -+ .targetsize = sizeof(struct xt_setclass_target_info), -+ .me = THIS_MODULE, -+ }, -+ { -+ .name = "SETCLASS", -+ .revision = 0, -+ .family = NFPROTO_ARP, -+ .hooks = (1 << NF_ARP_IN) | (1 << NF_ARP_FORWARD), -+ .target = setclass_tg, -+ .targetsize = sizeof(struct xt_setclass_target_info), -+ .me = THIS_MODULE, -+ }, -+}; -+ -+static int __init setclass_tg_init(void) -+{ -+ return xt_register_targets(setclass_tg_reg, ARRAY_SIZE(setclass_tg_reg)); -+} -+ -+static void __exit setclass_tg_exit(void) -+{ -+ xt_unregister_targets(setclass_tg_reg, ARRAY_SIZE(setclass_tg_reg)); -+} -+ -+module_init(setclass_tg_init); -+module_exit(setclass_tg_exit); -diff --git a/net/netfilter/xt_SETQOS.c b/net/netfilter/xt_SETQOS.c -new file mode 100644 -index 0000000..fe32312 ---- /dev/null -+++ b/net/netfilter/xt_SETQOS.c -@@ -0,0 +1,77 @@ -+/* -+ * "SETQOS" target extension for Xtables -+ * Copyright 2013 Cumulus Networks, LLC. 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. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+static unsigned int -+setqos_tg(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ return NF_ACCEPT; -+} -+ -+static int setqos_tg_check(const struct xt_tgchk_param *par) -+{ -+ struct xt_setqos_target_info *info = par->targinfo; -+ -+ if (info->cos < XT_SETQOS_MIN_COS || info->cos > XT_SETQOS_MAX_COS) -+ return -EINVAL; -+ -+ if (info->dscp > XT_SETQOS_DSCP_MAX) { -+ pr_info("dscp %x out of range\n", info->dscp); -+ return -EDOM; -+ } -+ -+ return 0; -+} -+ -+static void setqos_tg_destroy(const struct xt_tgdtor_param *par) -+{ -+} -+ -+static struct xt_target setqos_tg_reg[] __read_mostly = { -+ { -+ .name = "SETQOS", -+ .revision = 1, -+ .family = NFPROTO_UNSPEC, -+ .target = setqos_tg, -+ .targetsize = sizeof(struct xt_setqos_target_info), -+ .checkentry = setqos_tg_check, -+ .destroy = setqos_tg_destroy, -+ .me = THIS_MODULE, -+ }, -+}; -+ -+static int __init setqos_tg_init(void) -+{ -+ return xt_register_targets(setqos_tg_reg, ARRAY_SIZE(setqos_tg_reg)); -+} -+ -+static void __exit setqos_tg_exit(void) -+{ -+ xt_unregister_targets(setqos_tg_reg, ARRAY_SIZE(setqos_tg_reg)); -+} -+ -+module_init(setqos_tg_init); -+module_exit(setqos_tg_exit); -+MODULE_AUTHOR("Vidya Ravipati "); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Xtables: Ingress classification"); -+MODULE_ALIAS("ipt_SETQOS"); -+MODULE_ALIAS("ip6t_SETQOS"); -diff --git a/net/netfilter/xt_SPAN.c b/net/netfilter/xt_SPAN.c -new file mode 100644 -index 0000000..1120bb2 ---- /dev/null -+++ b/net/netfilter/xt_SPAN.c -@@ -0,0 +1,74 @@ -+/* -+ * "SPAN" target extension for Xtables -+ * Copyright 2013 Cumulus Networks, LLC. 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 or later, as published by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct xt_span_priv { -+ struct notifier_block notifier; -+ struct xt_span_tginfo *tginfo; -+}; -+ -+static unsigned int -+span_tg(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ return XT_CONTINUE; -+} -+ -+static int span_tg_check(const struct xt_tgchk_param *par) -+{ -+ return 0; -+} -+ -+static void span_tg_destroy(const struct xt_tgdtor_param *par) -+{ -+ return; -+} -+ -+static struct xt_target span_tg_reg[] __read_mostly = { -+ { -+ .name = "SPAN", -+ .revision = 1, -+ .family = NFPROTO_UNSPEC, -+ .target = span_tg, -+ .targetsize = sizeof(struct xt_span_tginfo), -+ .checkentry = span_tg_check, -+ .destroy = span_tg_destroy, -+ .me = THIS_MODULE, -+ }, -+}; -+ -+static int __init span_tg_init(void) -+{ -+ return xt_register_targets(span_tg_reg, ARRAY_SIZE(span_tg_reg)); -+} -+ -+static void __exit span_tg_exit(void) -+{ -+ xt_unregister_targets(span_tg_reg, ARRAY_SIZE(span_tg_reg)); -+} -+ -+module_init(span_tg_init); -+module_exit(span_tg_exit); -+MODULE_AUTHOR("Wilson Kok "); -+MODULE_DESCRIPTION("Xtables: Switch Port Analyzer"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("ipt_SPAN"); -+MODULE_ALIAS("ip6t_SPAN"); -diff --git a/net/netfilter/xt_TRICOLORPOLICE.c b/net/netfilter/xt_TRICOLORPOLICE.c -new file mode 100644 -index 0000000..7750aaa ---- /dev/null -+++ b/net/netfilter/xt_TRICOLORPOLICE.c -@@ -0,0 +1,95 @@ -+/* -+ * "TRICOLORPOLICE" target extension for Xtables -+ * Copyright 2013 Cumulus Networks, LLC. 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 or later, as published by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct xt_tricolor_police_priv { -+ struct notifier_block notifier; -+ struct xt_tricolor_police_tginfo *tginfo; -+}; -+ -+static unsigned int -+tricolor_police_tg(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ return NF_ACCEPT; -+} -+ -+static int tricolor_police_tg_check(const struct xt_tgchk_param *par) -+{ -+ struct xt_tricolor_police_tginfo *info = par->targinfo; -+ -+ if ((info->bitmask & XT_TRICOLOR_POLICE_CIR) && -+ (info->cir < XT_TRICOLOR_POLICE_MIN_CIR || -+ info->cir > XT_TRICOLOR_POLICE_MAX_CIR)) -+ return -EINVAL; -+ -+ if ((info->bitmask & XT_TRICOLOR_POLICE_CBS) && -+ (info->cbs < XT_TRICOLOR_POLICE_MIN_CBS || -+ info->cbs > XT_TRICOLOR_POLICE_MAX_CBS)) -+ return -EINVAL; -+ -+ if ((info->bitmask & XT_TRICOLOR_POLICE_PIR) && -+ (info->pir < XT_TRICOLOR_POLICE_MIN_PIR || -+ info->pir > XT_TRICOLOR_POLICE_MAX_PIR)) -+ return -EINVAL; -+ -+ if ((info->bitmask & XT_TRICOLOR_POLICE_EBS) && -+ (info->ebs < XT_TRICOLOR_POLICE_MIN_EBS || -+ info->ebs > XT_TRICOLOR_POLICE_MAX_EBS)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static void tricolor_police_tg_destroy(const struct xt_tgdtor_param *par) -+{ -+} -+ -+static struct xt_target tricolor_police_tg_reg[] __read_mostly = { -+ { -+ .name = "TRICOLORPOLICE", -+ .revision = 1, -+ .family = NFPROTO_UNSPEC, -+ .target = tricolor_police_tg, -+ .targetsize = sizeof(struct xt_tricolor_police_tginfo), -+ .checkentry = tricolor_police_tg_check, -+ .destroy = tricolor_police_tg_destroy, -+ .me = THIS_MODULE, -+ }, -+}; -+ -+static int __init tricolor_police_tg_init(void) -+{ -+ return xt_register_targets(tricolor_police_tg_reg, ARRAY_SIZE(tricolor_police_tg_reg)); -+} -+ -+static void __exit tricolor_police_tg_exit(void) -+{ -+ xt_unregister_targets(tricolor_police_tg_reg, ARRAY_SIZE(tricolor_police_tg_reg)); -+} -+ -+module_init(tricolor_police_tg_init); -+module_exit(tricolor_police_tg_exit); -+MODULE_AUTHOR("James Li "); -+MODULE_DESCRIPTION("Xtables: TriColorPolicing"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("ipt_TRICOLORPOLICE"); -+MODULE_ALIAS("ip6t_TRICOLORPOLICE"); -diff --git a/net/netfilter/xt_addrtype.c b/net/netfilter/xt_addrtype.c -index b77d383..32cf85d 100644 ---- a/net/netfilter/xt_addrtype.c -+++ b/net/netfilter/xt_addrtype.c -@@ -196,7 +196,8 @@ static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) - pr_err("ipv6 BLACKHOLE matching not supported\n"); - return -EINVAL; - } -- if ((info->source | info->dest) >= XT_ADDRTYPE_PROHIBIT) { -+ if (((info->source | info->dest) >= XT_ADDRTYPE_PROHIBIT) && -+ (info->dest & XT_ADDRTYPE_IPROUTER) == 0) { - pr_err("ipv6 PROHIBT (THROW, NAT ..) matching not supported\n"); - return -EINVAL; - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-arp-allow-per-if-arp_accept.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-arp-allow-per-if-arp_accept.patch deleted file mode 100644 index 3d939781..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-arp-allow-per-if-arp_accept.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 124d37e9f088a8f56494b0264d63d22555f53fef Mon Sep 17 00:00:00 2001 -Subject: [PATCH] arp: allow arp processing to honor per interface arp_accept - sysctl - -I found recently that the arp_process function which handles all of our received -arp frames, is using IPV4_DEVCONF_ALL macro to check the state of the arp_process -flag. This seems wrong, as it implies that either none or all of the network -interfaces accept gratuitous arps. This patch corrects that, allowing -per-interface arp_accept configuration to deviate from the all setting. Note -this also brings us into line with the way the arp_filter setting is handled -during arp_process execution. - -Tested this myself on my home network, and confirmed it works as expected. - -Signed-off-by: Neil Horman -CC: "David S. Miller" -Signed-off-by: David S. Miller - -diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h -index 85bb88e..0ced5ee 100644 ---- a/include/linux/inetdevice.h -+++ b/include/linux/inetdevice.h -@@ -139,6 +139,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev) - IN_DEV_ORCONF((in_dev), ACCEPT_REDIRECTS))) - - #define IN_DEV_ARPFILTER(in_dev) IN_DEV_ORCONF((in_dev), ARPFILTER) -+#define IN_DEV_ARP_ACCEPT(in_dev) IN_DEV_ORCONF((in_dev), ARP_ACCEPT) - #define IN_DEV_ARP_ANNOUNCE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE) - #define IN_DEV_ARP_IGNORE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_IGNORE) - #define IN_DEV_ARP_NOTIFY(in_dev) IN_DEV_MAXCONF((in_dev), ARP_NOTIFY) -diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c -index 59a7041..8042b80 100644 ---- a/net/ipv4/arp.c -+++ b/net/ipv4/arp.c -@@ -893,7 +893,7 @@ static int arp_process(struct sk_buff *skb) - - n = __neigh_lookup(&arp_tbl, &sip, dev, 0); - -- if (IPV4_DEVCONF_ALL(dev_net(dev), ARP_ACCEPT)) { -+ if (IN_DEV_ARP_ACCEPT(in_dev)) { - /* Unsolicited ARP is not accepted by default. - It is possible, that this option should be enabled for some - devices (strip is candidate) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-advertise-slave-activity.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-advertise-slave-activity.patch deleted file mode 100644 index 02c6e39a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-advertise-slave-activity.patch +++ /dev/null @@ -1,317 +0,0 @@ -Add slave membership notification via generic netlink. -Add /sys/class/net/bondX/bonding/ad_active_slaves node. - -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index 5af2a8f..173cdbc 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -78,6 +78,8 @@ - #include - #include - #include -+#include -+#include - #include "bonding.h" - #include "bond_3ad.h" - #include "bond_alb.h" -@@ -271,6 +273,160 @@ const char *bond_mode_name(int mode) - return names[mode]; - } - -+/*---------------------------- genl/bond -----------------------------*/ -+ -+enum { -+ BOND_GENL_ATTR_UNSPEC, -+ BOND_GENL_ATTR_BOND, -+ BOND_GENL_ATTR_SLAVE, -+ __BOND_GENL_ATTR_MAX, -+}; -+#define BOND_GENL_ATTR_MAX (__BOND_GENL_ATTR_MAX - 1) -+ -+enum { -+ BOND_GENL_CMD_UNSPEC, -+ BOND_GENL_CMD_GET, -+ BOND_GENL_CMD_ACTIVATE_EVENT, -+ BOND_GENL_CMD_DEACTIVATE_EVENT, -+ __BOND_GENL_CMD_MAX, -+}; -+ -+static struct genl_family bond_event_genl_family = { -+ .id = GENL_ID_GENERATE, -+ .name = "bond_event", -+ .version = 1, -+ .maxattr = BOND_GENL_ATTR_MAX, -+}; -+ -+static int fill_genlmsg(struct sk_buff *skb, u32 pid, u32 seq, -+ int flags, u8 cmd, struct bonding *bond, struct slave *slave) -+{ -+ void *hdr; -+ -+ hdr = genlmsg_put(skb, pid, seq, &bond_event_genl_family, -+ flags, cmd); -+ if (hdr == NULL) -+ return -EMSGSIZE; -+ -+ if (bond) -+ NLA_PUT_U32(skb, BOND_GENL_ATTR_BOND, bond->dev->ifindex); -+ else -+ NLA_PUT_U32(skb, BOND_GENL_ATTR_BOND, 0); -+ NLA_PUT_U32(skb, BOND_GENL_ATTR_SLAVE, slave->dev->ifindex); -+ -+ return genlmsg_end(skb, hdr); -+ -+nla_put_failure: -+ genlmsg_cancel(skb, hdr); -+ return -EMSGSIZE; -+} -+ -+static int bond_event_genl_dump(struct sk_buff *skb, -+ struct netlink_callback *cb) -+{ -+ struct bond_net *bn = net_generic(&init_net, bond_net_id); -+ struct slave *slave; -+ struct bonding *bond; -+ u32 pid = NETLINK_CB(cb->skb).pid; -+ u32 seq = cb->nlh->nlmsg_seq; -+ int bond_idx = 0, bond_start_idx = cb->args[0]; -+ int slave_idx = 0, slave_start_idx = cb->args[1]; -+ int i; -+ -+ rtnl_lock(); -+ -+ list_for_each_entry(bond, &bn->dev_list, bond_list) { -+ -+ if (bond_idx > bond_start_idx) -+ slave_start_idx = 0; -+ if (bond_idx++ < bond_start_idx) -+ continue; -+ -+ slave_idx = 0; -+ -+ read_lock(&bond->lock); -+ bond_for_each_slave(bond, slave, i) { -+ u8 cmd = bond_is_active_slave(slave) ? -+ BOND_GENL_CMD_ACTIVATE_EVENT : -+ BOND_GENL_CMD_DEACTIVATE_EVENT; -+ if (slave_idx++ < slave_start_idx) -+ continue; -+ if (fill_genlmsg(skb, pid, seq, NLM_F_MULTI, -+ cmd, bond, slave) < 0) { -+ read_unlock(&bond->lock); -+ goto out; -+ } -+ } -+ read_unlock(&bond->lock); -+ } -+ -+out: -+ rtnl_unlock(); -+ -+ cb->args[0] = bond_idx; -+ cb->args[1] = slave_idx; -+ -+ return skb->len; -+} -+ -+static struct genl_ops bond_event_get_ops = { -+ .cmd = BOND_GENL_CMD_GET, -+ .dumpit = bond_event_genl_dump, -+}; -+ -+static struct genl_multicast_group bond_event_mcgrp = { -+ .name = "bond_event_mc", -+}; -+ -+static int bond_netlink_event(struct bonding *bond, -+ struct slave *slave, -+ u8 cmd) -+{ -+ static atomic_t seq; -+ struct sk_buff *skb; -+ int msg_size = 2 * nla_total_size(sizeof(u32)); -+ -+ skb = genlmsg_new(msg_size, GFP_ATOMIC); -+ if (!skb) -+ return -ENOMEM; -+ -+ if (fill_genlmsg(skb, 0, atomic_add_return(1, &seq), -+ 0, cmd, bond, slave) < 0) -+ goto err_out; -+ -+ genlmsg_multicast(skb, 0, bond_event_mcgrp.id, GFP_ATOMIC); -+ -+ return 0; -+ -+err_out: -+ nlmsg_free(skb); -+ return -ENOMEM; -+} -+ -+static int bond_genl_init(void) -+{ -+ int res; -+ -+ res = genl_register_family(&bond_event_genl_family); -+ if (res) -+ return res; -+ -+ res = genl_register_ops(&bond_event_genl_family, -+ &bond_event_get_ops); -+ if (res) -+ goto err; -+ -+ res = genl_register_mc_group(&bond_event_genl_family, -+ &bond_event_mcgrp); -+ if (res) -+ goto err; -+ -+ return res; -+err: -+ genl_unregister_family(&bond_event_genl_family); -+ return res; -+} -+ - /*---------------------------------- VLAN -----------------------------------*/ - - /** -@@ -2080,6 +2236,11 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) - - slave_dev->priv_flags &= ~IFF_BONDING; - -+ /* deactivate slave in bond cache. bond ifindex for cache -+ * entry will be 0 (slave no longer in bond). -+ */ -+ bond_netlink_event(NULL, slave, BOND_GENL_CMD_DEACTIVATE_EVENT); -+ - kfree(slave); - - return 0; /* deletion OK */ -@@ -4882,6 +5043,18 @@ static struct pernet_operations bond_net_ops = { - .size = sizeof(struct bond_net), - }; - -+void bond_set_active_slave(struct slave *slave) -+{ -+ slave->backup = 0; -+ bond_netlink_event(slave->bond, slave, BOND_GENL_CMD_ACTIVATE_EVENT); -+} -+ -+void bond_set_backup_slave(struct slave *slave) -+{ -+ slave->backup = 1; -+ bond_netlink_event(slave->bond, slave, BOND_GENL_CMD_DEACTIVATE_EVENT); -+} -+ - static int __init bonding_init(void) - { - int i; -@@ -4901,6 +5074,10 @@ static int __init bonding_init(void) - if (res) - goto err_link; - -+ res = bond_genl_init(); -+ if (res) -+ goto err_genl; -+ - bond_create_debugfs(); - - for (i = 0; i < max_bonds; i++) { -@@ -4914,6 +5091,8 @@ static int __init bonding_init(void) - out: - return res; - err: -+ genl_unregister_family(&bond_event_genl_family); -+err_genl: - bond_destroy_debugfs(); - rtnl_link_unregister(&bond_link_ops); - err_link: -@@ -4929,6 +5108,7 @@ static void __exit bonding_exit(void) - - bond_destroy_debugfs(); - -+ genl_unregister_family(&bond_event_genl_family); - rtnl_link_unregister(&bond_link_ops); - unregister_pernet_subsys(&bond_net_ops); - -diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c -index cf95bd8..e894f2d 100644 ---- a/drivers/net/bonding/bond_sysfs.c -+++ b/drivers/net/bonding/bond_sysfs.c -@@ -1428,6 +1428,46 @@ static ssize_t bonding_show_ad_partner_mac(struct device *d, - static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL); - - /* -+ * Show the current 802.3ad active slaves. -+ */ -+static ssize_t bonding_show_ad_active_slaves(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct slave *slave; -+ int i, count = 0; -+ struct bonding *bond = to_bond(d); -+ -+ if (bond->params.mode != BOND_MODE_8023AD) -+ return count; -+ -+ if (!rtnl_trylock()) -+ return restart_syscall(); -+ -+ read_lock(&bond->lock); -+ bond_for_each_slave(bond, slave, i) { -+ int active; -+ if (count > (PAGE_SIZE - IFNAMSIZ - 6)) { -+ /* not enough space for another interface_name:status pair */ -+ if ((PAGE_SIZE - count) > 10) -+ count = PAGE_SIZE - 10; -+ count += sprintf(buf + count, "++more++ "); -+ break; -+ } -+ active = bond_is_active_slave(slave) ? 1 : 0; -+ count += sprintf(buf + count, "%s:%d ", -+ slave->dev->name, active); -+ } -+ read_unlock(&bond->lock); -+ if (count) -+ buf[count-1] = '\n'; /* eat the leftover space */ -+ rtnl_unlock(); -+ -+ return count; -+} -+static DEVICE_ATTR(ad_active_slaves, S_IRUGO, bonding_show_ad_active_slaves, NULL); -+ -+/* - * Show the queue_ids of the slaves in the current bond. - */ - static ssize_t bonding_show_queue_id(struct device *d, -@@ -1665,6 +1705,7 @@ static struct attribute *per_bond_attrs[] = { - &dev_attr_ad_actor_key.attr, - &dev_attr_ad_partner_key.attr, - &dev_attr_ad_partner_mac.attr, -+ &dev_attr_ad_active_slaves.attr, - &dev_attr_queue_id.attr, - &dev_attr_all_slaves_active.attr, - &dev_attr_resend_igmp.attr, -diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h -index 1aecc37..387f9f6 100644 ---- a/drivers/net/bonding/bonding.h -+++ b/drivers/net/bonding/bonding.h -@@ -293,15 +293,8 @@ static inline bool bond_is_lb(const struct bonding *bond) - bond->params.mode == BOND_MODE_ALB); - } - --static inline void bond_set_active_slave(struct slave *slave) --{ -- slave->backup = 0; --} -- --static inline void bond_set_backup_slave(struct slave *slave) --{ -- slave->backup = 1; --} -+void bond_set_active_slave(struct slave *slave); -+void bond_set_backup_slave(struct slave *slave); - - static inline int bond_slave_state(struct slave *slave) - { diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-advertise-speed-duplex.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-advertise-speed-duplex.patch deleted file mode 100644 index 519519e5..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-advertise-speed-duplex.patch +++ /dev/null @@ -1,143 +0,0 @@ -Advertise speed/duplex for 802.3ad mode. Basically add up all the active slave speeds, -and report duplex as FULL. - -diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c -index aaa7999..c7e3e53 100644 ---- a/drivers/net/bonding/bond_3ad.c -+++ b/drivers/net/bonding/bond_3ad.c -@@ -2354,15 +2354,7 @@ int bond_3ad_set_carrier(struct bonding *bond) - return 0; - } - --/** -- * bond_3ad_get_active_agg_info - get information of the active aggregator -- * @bond: bonding struct to work on -- * @ad_info: ad_info struct to fill with the bond's info -- * -- * Returns: 0 on success -- * < 0 on error -- */ --int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info) -+struct aggregator * bond_3ad_get_active_agg(struct bonding *bond) - { - struct aggregator *aggregator = NULL; - struct port *port; -@@ -2374,6 +2366,21 @@ int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info) - } - } - -+ return aggregator; -+} -+ -+/** -+ * bond_3ad_get_active_agg_info - get information of the active aggregator -+ * @bond: bonding struct to work on -+ * @ad_info: ad_info struct to fill with the bond's info -+ * -+ * Returns: 0 on success -+ * < 0 on error -+ */ -+int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info) -+{ -+ struct aggregator *aggregator = bond_3ad_get_active_agg(bond); -+ - if (aggregator) { - ad_info->aggregator_id = aggregator->aggregator_identifier; - ad_info->ports = aggregator->num_of_ports; -diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h -index 20d9c78..046bb1f 100644 ---- a/drivers/net/bonding/bond_3ad.h -+++ b/drivers/net/bonding/bond_3ad.h -@@ -273,6 +273,7 @@ void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout); - void bond_3ad_adapter_speed_changed(struct slave *slave); - void bond_3ad_adapter_duplex_changed(struct slave *slave); - void bond_3ad_handle_link_change(struct slave *slave, char link); -+struct aggregator *bond_3ad_get_active_agg(struct bonding *bond); - int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); - int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); - void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index 173cdbc..a986b86 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -2583,6 +2583,7 @@ static int bond_miimon_inspect(struct bonding *bond) - static void bond_miimon_commit(struct bonding *bond) - { - struct slave *slave; -+ struct ethtool_cmd ecmd; - int i; - - bond_for_each_slave(bond, slave, i) { -@@ -2605,9 +2606,11 @@ static void bond_miimon_commit(struct bonding *bond) - bond_set_backup_slave(slave); - } - -+ __ethtool_get_settings(slave->dev, &ecmd); - pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n", - bond->dev->name, slave->dev->name, -- slave->speed, slave->duplex ? "full" : "half"); -+ ethtool_cmd_speed(&ecmd), -+ ecmd.duplex == DUPLEX_FULL ? "full" : "half"); - - /* notify ad that the link status has changed */ - if (bond->params.mode == BOND_MODE_8023AD) -@@ -4414,6 +4417,36 @@ void bond_set_mode_ops(struct bonding *bond, int mode) - } - } - -+static int bond_get_settings(struct net_device *dev, -+ struct ethtool_cmd *ecmd) -+{ -+ struct bonding *bond = netdev_priv(dev); -+ u32 speed_mbps = SPEED_UNKNOWN; -+ -+ if (bond->params.mode != BOND_MODE_8023AD) -+ return -EOPNOTSUPP; -+ -+ if (bond->first_slave) -+ speed_mbps = bond->first_slave->speed; -+ -+ switch(speed_mbps) { -+ case SPEED_10: -+ case SPEED_100: -+ case SPEED_1000: -+ case SPEED_10000: -+ speed_mbps = speed_mbps * bond->slave_cnt; -+ break; -+ default: -+ speed_mbps = SPEED_UNKNOWN; -+ break; -+ } -+ -+ ethtool_cmd_speed_set(ecmd, speed_mbps); -+ ecmd->duplex = DUPLEX_FULL; -+ -+ return 0; -+} -+ - static void bond_ethtool_get_drvinfo(struct net_device *bond_dev, - struct ethtool_drvinfo *drvinfo) - { -@@ -4423,6 +4456,7 @@ static void bond_ethtool_get_drvinfo(struct net_device *bond_dev, - } - - static const struct ethtool_ops bond_ethtool_ops = { -+ .get_settings = bond_get_settings, - .get_drvinfo = bond_ethtool_get_drvinfo, - .get_link = ethtool_op_get_link, - }; -diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c -index e894f2d..67f9073 100644 ---- a/drivers/net/bonding/bond_sysfs.c -+++ b/drivers/net/bonding/bond_sysfs.c -@@ -1431,8 +1431,8 @@ static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL); - * Show the current 802.3ad active slaves. - */ - static ssize_t bonding_show_ad_active_slaves(struct device *d, -- struct device_attribute *attr, -- char *buf) -+ struct device_attribute *attr, -+ char *buf) - { - struct slave *slave; - int i, count = 0; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-clag-proto-down.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-clag-proto-down.patch deleted file mode 100644 index 092c289e..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-clag-proto-down.patch +++ /dev/null @@ -1,137 +0,0 @@ -Hold down the slaves for multi-chassis LAG enabled bonds. For such bonds the -slave state (dev_open/dev_close) is controlled by a MC-LAG application. This -change involves - -1. dev_close on all the cuurent slaves when clag_enable is set to 1. -2. dev_open on all the current slaves when clag_enable is set to 0. To resume -regular operation. -3. skip slave dev_open when a new slave is added to an MC-LAG bond (clag_enable -set to 1). - -Without this change in the following cases the slaves will start forwarding -traffic independent of the MC-LAG control protocol which could result in -duplicate packets, station moves, incorrect path changes (traffic black holes) -and loops (causing a network meltdown) - -1. On switch reboot prior to the MC-LAG app taking control of the MC-LAG bonds. -2. When a new slave is added to a bond (bond_enslave) - -CL Note: Is dependent on networking-bonding-clag.patch - -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index d08ed85..0356165 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -1810,7 +1810,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) - goto err_restore_mac; - } - -- /* open the slave since the application closed it */ -+ /* If the bond is multi-chassis LAG enabled the slave is placed in a -+ * proto_down state. This has to be done before device is opened and -+ * is needed to prevent the slaves from becoming active independent of -+ * the mc-lag control protocol run by the app. */ -+ if (bond->params.clag_enable) -+ dev_set_proto_down(slave_dev, IF_LINK_PROTO_DOWN_MLAG, -+ IF_LINK_PROTO_DOWN_MLAG); -+ - res = dev_open(slave_dev); - if (res) { - pr_debug("Opening slave %s failed\n", slave_dev->name); -@@ -2043,6 +2050,8 @@ err_close: - dev_close(slave_dev); - - err_unset_master: -+ if (bond->params.clag_enable) -+ dev_set_proto_down(slave_dev, 0, IF_LINK_PROTO_DOWN_MLAG); - netdev_set_bond_master(slave_dev, NULL); - - err_restore_mac: -@@ -2248,6 +2257,10 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) - /* close slave before restoring its mac address */ - dev_close(slave_dev); - -+ /* Clear MLAG proto_down state */ -+ if (bond->params.clag_enable) -+ dev_set_proto_down(slave_dev, 0, IF_LINK_PROTO_DOWN_MLAG); -+ - if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { - /* restore original ("permanent") mac address */ - memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); -@@ -5404,6 +5417,53 @@ void bond_set_backup_slave(struct slave *slave) - bond_netlink_event(slave->bond, slave, BOND_GENL_CMD_DEACTIVATE_EVENT); - } - -+static void bond_set_clag_proto_down_state(struct bonding *bond, u8 proto_down) -+{ -+ struct slave *slave; -+ struct net_device *slave_dev; -+ struct net_device *bond_dev = bond->dev; -+ int i; -+ -+ read_lock(&bond->lock); -+ bond_for_each_slave(bond, slave, i) { -+ slave_dev = slave->dev; -+ if (proto_down) -+ dev_set_proto_down(slave_dev, IF_LINK_PROTO_DOWN_MLAG, -+ IF_LINK_PROTO_DOWN_MLAG); -+ else -+ dev_set_proto_down(slave_dev, 0, -+ IF_LINK_PROTO_DOWN_MLAG); -+ } -+ read_unlock(&bond->lock); -+ -+ if (proto_down) -+ dev_set_proto_down(bond_dev, IF_LINK_PROTO_DOWN_MLAG, -+ IF_LINK_PROTO_DOWN_MLAG); -+ else -+ dev_set_proto_down(bond_dev, 0, -+ IF_LINK_PROTO_DOWN_MLAG); -+} -+ -+/* Enable/disable multi-chassis LAG on a bond. Once mc-lag is enabled on a bond -+ * the slaves are place in a proto_down state as the slaves' state will now be -+ * controlled by a mc-lag application. On mc-lag disable the bonding driver -+ * takes back slave state control and clears proto_down on slaves that may have -+ * been shutdown by the application */ -+void bond_set_clag_enable(struct bonding *bond, u8 clag_enable) -+{ -+ if (bond->params.clag_enable == clag_enable) -+ return; -+ -+ bond->params.clag_enable = clag_enable; -+ -+ if (clag_enable) -+ /* proto_down the bond and its slaves - they are now in -+ * MC-LAG app's control */ -+ bond_set_clag_proto_down_state(bond, 1); -+ else -+ bond_set_clag_proto_down_state(bond, 0); -+} -+ - static int __init bonding_init(void) - { - int i; -diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c -index 93a4db8..dc68bbc 100644 ---- a/drivers/net/bonding/bond_sysfs.c -+++ b/drivers/net/bonding/bond_sysfs.c -@@ -1012,7 +1012,7 @@ static ssize_t bonding_store_clag_enable(struct device *d, - return restart_syscall(); - pr_debug("%s: Setting clag enable to %u\n", - bond->dev->name, new_value); -- bond->params.clag_enable = new_value; -+ bond_set_clag_enable(bond, new_value); - call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - rtnl_unlock(); - return count; -diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h -index eefaa18..6f8b59c 100644 ---- a/drivers/net/bonding/bonding.h -+++ b/drivers/net/bonding/bonding.h -@@ -425,6 +425,7 @@ void bond_debug_register(struct bonding *bond); - void bond_debug_unregister(struct bonding *bond); - void bond_debug_reregister(struct bonding *bond); - const char *bond_mode_name(int mode); -+void bond_set_clag_enable(struct bonding *bond, u8 clag_enable); - - struct bond_net { - struct net * net; /* Associated network namespace */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-clag.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-clag.patch deleted file mode 100644 index e759f2c1..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-clag.patch +++ /dev/null @@ -1,108 +0,0 @@ -Introduces CLAG (multi-chassis lag) enable bond config. On its own this patch -doesn't provide any functionality. It was done just to add the "clag_enable" -param in 2.5.0. -Note: Associated functional changes were introduced in 2.5.1 via -networking-bonding-clag-proto-down.patch - -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index 70c865b..6e7f377 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -5071,6 +5071,7 @@ static size_t bond_get_size(const struct net_device *bond_dev) - nla_total_size(sizeof(u8)) + /* IFLA_BOND_CL_LACP_BYPASS_ALLOW */ - nla_total_size(sizeof(u8)) + /* IFLA_BOND_CL_LACP_BYPASS_ACTIVE */ - nla_total_size(sizeof(u32)) + /* IFLA_BOND_CL_LACP_BYPASS_PERIOD */ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_CL_CLAG_ENABLE */ - 0; - } - -@@ -5229,6 +5230,10 @@ static int bond_fill_info(struct sk_buff *skb, - if (nla_put_u32(skb, IFLA_BOND_CL_LACP_BYPASS_PERIOD, - bond->params.lacp_bypass_period)) - goto nla_put_failure; -+ -+ if (nla_put_u8(skb, IFLA_BOND_CL_CLAG_ENABLE, -+ bond->params.clag_enable)) -+ goto nla_put_failure; - } - - return 0; -diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c -index 4e377e0..93a4db8 100644 ---- a/drivers/net/bonding/bond_sysfs.c -+++ b/drivers/net/bonding/bond_sysfs.c -@@ -984,6 +984,42 @@ static ssize_t bonding_store_min_links(struct device *d, - static DEVICE_ATTR(min_links, S_IRUGO | S_IWUSR, - bonding_show_min_links, bonding_store_min_links); - -+static ssize_t bonding_show_clag_enable(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct bonding *bond = to_bond(d); -+ -+ return sprintf(buf, "%d\n", bond->params.clag_enable); -+} -+ -+static ssize_t bonding_store_clag_enable(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct bonding *bond = to_bond(d); -+ int ret; -+ u8 new_value; -+ -+ ret = kstrtou8(buf, 10, &new_value); -+ if (ret < 0) { -+ pr_err("%s: Ignoring invalid clag enable value %s.\n", -+ bond->dev->name, buf); -+ return ret; -+ } -+ -+ if (!rtnl_trylock()) -+ return restart_syscall(); -+ pr_debug("%s: Setting clag enable to %u\n", -+ bond->dev->name, new_value); -+ bond->params.clag_enable = new_value; -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ rtnl_unlock(); -+ return count; -+} -+static DEVICE_ATTR(clag_enable, S_IRUGO | S_IWUSR, -+ bonding_show_clag_enable, bonding_store_clag_enable); -+ - static ssize_t bonding_show_lacp_bypass_allow(struct device *d, - struct device_attribute *attr, - char *buf) -@@ -2095,6 +2131,7 @@ static struct attribute *per_bond_attrs[] = { - &dev_attr_lacp_bypass_allow.attr, - &dev_attr_lacp_bypass_active.attr, - &dev_attr_lacp_bypass_period.attr, -+ &dev_attr_clag_enable.attr, - NULL, - }; - -diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h -index b3594f7..eefaa18 100644 ---- a/drivers/net/bonding/bonding.h -+++ b/drivers/net/bonding/bonding.h -@@ -163,6 +163,7 @@ struct bond_params { - int lacp_bypass_allow; - int lacp_bypass_active; - u32 lacp_bypass_period; -+ u8 clag_enable; - }; - - struct bond_parm_tbl { -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index 086e2ad..b262ddd 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -357,6 +357,7 @@ enum { - IFLA_BOND_CL_LACP_BYPASS_ALLOW = IFLA_BOND_CL_START, - IFLA_BOND_CL_LACP_BYPASS_ACTIVE, - IFLA_BOND_CL_LACP_BYPASS_PERIOD, -+ IFLA_BOND_CL_CLAG_ENABLE, - __IFLA_BOND_MAX, - }; - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-create-netlink-event-when-bonding-option-changes.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-create-netlink-event-when-bonding-option-changes.patch deleted file mode 100644 index 3a0feefa..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-create-netlink-event-when-bonding-option-changes.patch +++ /dev/null @@ -1,372 +0,0 @@ -From 7faa104a7f66e35a8c9538ae8cd3a7a0ce5e5291 Mon Sep 17 00:00:00 2001 -Subject: [PATCH 3/4] bonding: create netlink event when bonding option is - changed - -Userspace needs to be notified if one changes some option. - -Signed-off-by: Jiri Pirko -Acked-by: Veaceslav Falico -Acked-by: Andy Gospodarek -Signed-off-by: David S. Miller -(cherry picked from commit d4261e5650004d6d51137553ea5433d5828562dc) - -Conflicts: - drivers/net/bonding/bond_options.c - include/linux/netdevice.h - -To prevent a deadlock (due to a nested lock) made sure all called to -call_netdevice_notifiers was outside a rw_lock critical section, this -because bond_fill_info also has a rw_lock critical section. - -Signed-off-by: Jonathan Toppins - -diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c -index 6d7ea50..6103587 100644 ---- a/drivers/net/bonding/bond_sysfs.c -+++ b/drivers/net/bonding/bond_sysfs.c -@@ -108,6 +108,7 @@ static ssize_t slave_store(struct kobject *kobj, - ret = slave_attr->store(slave, val); - if (ret == 0) - ret = count; -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, slave->bond->dev); - - rtnl_unlock(); - } -@@ -419,11 +420,15 @@ static ssize_t bonding_store_mode(struct device *d, - goto out; - } - -+ if (!rtnl_trylock()) -+ return restart_syscall(); - bond->params.mode = new_value; - bond_set_mode_ops(bond, bond->params.mode); - pr_info("%s: setting mode to %s (%d).\n", - bond->dev->name, bond_mode_tbl[new_value].modename, - new_value); -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ rtnl_unlock(); - out: - return ret; - } -@@ -466,13 +471,17 @@ static ssize_t bonding_store_xmit_hash(struct device *d, - (int)strlen(buf) - 1, buf); - ret = -EINVAL; - goto out; -- } else { -- bond->params.xmit_policy = new_value; -- bond_set_mode_ops(bond, bond->params.mode); -- pr_info("%s: setting xmit hash policy to %s (%d).\n", -+ } -+ -+ if (!rtnl_trylock()) -+ return restart_syscall(); -+ bond->params.xmit_policy = new_value; -+ bond_set_mode_ops(bond, bond->params.mode); -+ pr_info("%s: setting xmit hash policy to %s (%d).\n", - bond->dev->name, - xmit_hashtype_tbl[new_value].modename, new_value); -- } -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ rtnl_unlock(); - out: - return ret; - } -@@ -515,7 +524,11 @@ static ssize_t bonding_store_arp_validate(struct device *d, - bond->dev->name, arp_validate_tbl[new_value].modename, - new_value); - -+ if (!rtnl_trylock()) -+ return restart_syscall(); - bond->params.arp_validate = new_value; -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ rtnl_unlock(); - - return count; - } -@@ -558,10 +571,14 @@ static ssize_t bonding_store_fail_over_mac(struct device *d, - return -EINVAL; - } - -+ if (!rtnl_trylock()) -+ return restart_syscall(); - bond->params.fail_over_mac = new_value; - pr_info("%s: Setting fail_over_mac to %s (%d).\n", - bond->dev->name, fail_over_mac_tbl[new_value].modename, - new_value); -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ rtnl_unlock(); - - return count; - } -@@ -639,6 +656,7 @@ static ssize_t bonding_store_arp_interval(struct device *d, - queue_delayed_work(bond->wq, &bond->arp_work, 0); - } - } -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - out: - rtnl_unlock(); - return ret; -@@ -675,6 +693,8 @@ static ssize_t bonding_store_arp_targets(struct device *d, - struct bonding *bond = to_bond(d); - __be32 *targets; - -+ if (!rtnl_trylock()) -+ return restart_syscall(); - targets = bond->params.arp_targets; - newtarget = in_aton(buf + 1); - /* look for adds */ -@@ -739,8 +759,10 @@ static ssize_t bonding_store_arp_targets(struct device *d, - ret = -EPERM; - goto out; - } -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - - out: -+ rtnl_unlock(); - return ret; - } - static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets); -@@ -799,6 +821,7 @@ static ssize_t bonding_store_downdelay(struct device *d, - bond->params.downdelay * bond->params.miimon); - - } -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - - out: - rtnl_unlock(); -@@ -857,6 +880,7 @@ static ssize_t bonding_store_updelay(struct device *d, - bond->dev->name, - bond->params.updelay * bond->params.miimon); - } -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - - out: - rtnl_unlock(); -@@ -904,11 +928,15 @@ static ssize_t bonding_store_lacp(struct device *d, - new_value = bond_parse_parm(buf, bond_lacp_tbl); - - if ((new_value == 1) || (new_value == 0)) { -+ if (!rtnl_trylock()) -+ return restart_syscall(); - bond->params.lacp_fast = new_value; - bond_3ad_update_lacp_rate(bond); - pr_info("%s: Setting LACP rate to %s (%d).\n", - bond->dev->name, bond_lacp_tbl[new_value].modename, - new_value); -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ rtnl_unlock(); - } else { - pr_err("%s: Ignoring invalid LACP rate value %.*s.\n", - bond->dev->name, (int)strlen(buf) - 1, buf); -@@ -944,9 +972,13 @@ static ssize_t bonding_store_min_links(struct device *d, - return ret; - } - -+ if (!rtnl_trylock()) -+ return restart_syscall(); - pr_info("%s: Setting min links value to %u\n", - bond->dev->name, new_value); - bond->params.min_links = new_value; -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ rtnl_unlock(); - return count; - } - static DEVICE_ATTR(min_links, S_IRUGO | S_IWUSR, -@@ -976,9 +1008,13 @@ static ssize_t bonding_store_lacp_fallback_allow(struct device *d, - return ret; - } - -+ if (!rtnl_trylock()) -+ return restart_syscall(); - pr_debug("%s: Setting lacp_fallback_allow to %u\n", - bond->dev->name, new_value); - bond->params.lacp_fallback_allow = new_value; -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ rtnl_unlock(); - return count; - } - static DEVICE_ATTR(lacp_fallback_allow, S_IRUGO | S_IWUSR, -@@ -1008,9 +1044,13 @@ static ssize_t bonding_store_lacp_fallback_period(struct device *d, - return ret; - } - -+ if (!rtnl_trylock()) -+ return restart_syscall(); - pr_debug("%s: Setting lacp_fallback period to %u\n", - bond->dev->name, new_value); - bond->params.lacp_fallback_period = new_value; -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ rtnl_unlock(); - return count; - } - static DEVICE_ATTR(lacp_fallback_period, S_IRUGO | S_IWUSR, -@@ -1041,9 +1081,13 @@ static ssize_t bonding_store_lacp_fallback_active(struct device *d, - return ret; - } - -+ if (!rtnl_trylock()) -+ return restart_syscall(); - pr_debug("%s: Setting lacp_fallback active to %u\n", - bond->dev->name, new_value); - bond->params.lacp_fallback_active = new_value; -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ rtnl_unlock(); - return count; - } - static DEVICE_ATTR(lacp_fallback_active, S_IRUGO | S_IWUSR, -@@ -1079,10 +1123,14 @@ static ssize_t bonding_store_ad_select(struct device *d, - new_value = bond_parse_parm(buf, ad_select_tbl); - - if (new_value != -1) { -+ if (!rtnl_trylock()) -+ return restart_syscall(); - bond->params.ad_select = new_value; - pr_info("%s: Setting ad_select to %s (%d).\n", - bond->dev->name, ad_select_tbl[new_value].modename, - new_value); -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ rtnl_unlock(); - } else { - pr_err("%s: Ignoring invalid ad_select value %.*s.\n", - bond->dev->name, (int)strlen(buf) - 1, buf); -@@ -1110,8 +1158,19 @@ static ssize_t bonding_store_num_peer_notif(struct device *d, - const char *buf, size_t count) - { - struct bonding *bond = to_bond(d); -- int err = kstrtou8(buf, 10, &bond->params.num_peer_notif); -- return err ? err : count; -+ int err; -+ -+ if (!rtnl_trylock()) -+ return restart_syscall(); -+ -+ err = kstrtou8(buf, 10, &bond->params.num_peer_notif); -+ if (err) -+ goto out; -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ err = count; -+out: -+ rtnl_unlock(); -+ return err; - } - static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR, - bonding_show_num_peer_notif, bonding_store_num_peer_notif); -@@ -1185,6 +1244,7 @@ static ssize_t bonding_store_miimon(struct device *d, - queue_delayed_work(bond->wq, &bond->mii_work, 0); - } - } -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - out: - rtnl_unlock(); - return ret; -@@ -1261,6 +1321,7 @@ out: - write_unlock_bh(&bond->curr_slave_lock); - read_unlock(&bond->lock); - unblock_netpoll_tx(); -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - rtnl_unlock(); - - return count; -@@ -1313,6 +1374,7 @@ static ssize_t bonding_store_primary_reselect(struct device *d, - write_unlock_bh(&bond->curr_slave_lock); - read_unlock(&bond->lock); - unblock_netpoll_tx(); -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - out: - rtnl_unlock(); - return ret; -@@ -1348,9 +1410,13 @@ static ssize_t bonding_store_carrier(struct device *d, - goto out; - } - if ((new_value == 0) || (new_value == 1)) { -+ if (!rtnl_trylock()) -+ return restart_syscall(); - bond->params.use_carrier = new_value; - pr_info("%s: Setting use_carrier to %d.\n", - bond->dev->name, new_value); -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ rtnl_unlock(); - } else { - pr_info("%s: Ignoring invalid use_carrier value %d.\n", - bond->dev->name, new_value); -@@ -1460,7 +1526,7 @@ static ssize_t bonding_store_active_slave(struct device *d, - write_unlock_bh(&bond->curr_slave_lock); - read_unlock(&bond->lock); - unblock_netpoll_tx(); -- -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - rtnl_unlock(); - - return count; -@@ -1684,6 +1750,7 @@ static ssize_t bonding_store_ad_sys_priority(struct device *d, - bond->dev->name, new_value); - bond->params.sys_priority = new_value; - bond_3ad_update_sys_priority(bond); -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - - out_unlock: - rtnl_unlock(); -@@ -1739,6 +1806,7 @@ static ssize_t bonding_store_ad_sys_mac_addr(struct device *d, - bond->dev->name, new_mac); - memcpy(&(bond->params.sys_mac_addr), new_mac, ETH_ALEN); - bond_3ad_update_sys_mac_addr(bond); -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - - out_unlock: - rtnl_unlock(); -@@ -1845,8 +1913,8 @@ static ssize_t bonding_store_queue_id(struct device *d, - - /* Actually set the qids for the slave */ - update_slave->queue_id = qid; -- - read_unlock(&bond->lock); -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - out: - rtnl_unlock(); - return ret; -@@ -1884,6 +1952,9 @@ static ssize_t bonding_store_slaves_active(struct device *d, - struct bonding *bond = to_bond(d); - struct slave *slave; - -+ if (!rtnl_trylock()) -+ return restart_syscall(); -+ - if (sscanf(buf, "%d", &new_value) != 1) { - pr_err("%s: no all_slaves_active value specified.\n", - bond->dev->name); -@@ -1913,7 +1984,9 @@ static ssize_t bonding_store_slaves_active(struct device *d, - } - } - read_unlock(&bond->lock); -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - out: -+ rtnl_unlock(); - return ret; - } - static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR, -@@ -1952,9 +2025,13 @@ static ssize_t bonding_store_resend_igmp(struct device *d, - goto out; - } - -+ if (!rtnl_trylock()) -+ return restart_syscall(); - pr_info("%s: Setting resend_igmp to %d.\n", - bond->dev->name, new_value); - bond->params.resend_igmp = new_value; -+ call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); -+ rtnl_unlock(); - out: - return ret; - } -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index ec21a37..7e9cae6 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -1641,6 +1641,7 @@ struct pcpu_sw_netstats { - #define NETDEV_CHANGEUPPER 0x0015 - #define NETDEV_RESEND_IGMP 0x0016 - #define NETDEV_PRECHANGEMTU 0x0017 /* notify before mtu change happened */ -+#define NETDEV_CHANGEINFODATA 0x0018 - - extern int register_netdevice_notifier(struct notifier_block *nb); - extern int unregister_netdevice_notifier(struct notifier_block *nb); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-cumulus-add-support-for-RTM_GETLINK.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-cumulus-add-support-for-RTM_GETLINK.patch deleted file mode 100644 index 622ba44e..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-cumulus-add-support-for-RTM_GETLINK.patch +++ /dev/null @@ -1,412 +0,0 @@ -From acd711787be585716c57b2659a4ebcd8b5abab65 Mon Sep 17 00:00:00 2001 -Subject: [PATCH 2/4] cumulus: bonding: add support for RTM_GETLINK - -A "spirit" backport of a subset of the upstream (net-next tree) rtnetlink -support in bonding. All upstream commit hashes are from the net-next tree. -The actual code was copied from upstream commit -4daaab4f0c2b55adccab08da06e17acc270cb84a with the relavent upstream -commits being: - -3bad540 bonding: convert netlink to use slave data info api -1d3ee88 bonding: add netlink attributes to slave link dev -288db0a bonding: fix netlink msg size -4ee7ac7 bonding: add ad_info attribute netlink support -ec029fa bonding: add ad_select attribute netlink support -998e40b bonding: add lacp_rate attribute netlink support -7d10100 bonding: add min_links attribute netlink support -1cc0b1e bonding: add all_slaves_active attribute netlink support -2c9839c bonding: add num_grat_arp attribute netlink support -d8838de bonding: add resend_igmp attribute netlink support -f70161c bonding: add xmit_hash_policy attribute netlink support -8990197 bonding: add fail_over_mac attribute netlink support -8a41ae4 bonding: add primary_select attribute netlink support -0a98a0d bonding: add primary attribute netlink support -90af231 bonding: add Netlink support mode option - -Removed call to rtnl_dereference in bond_fill_info because -primary_slave has not been converted to using RCU. - -Signed-off-by: Jonathan Toppins - -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index 768b0de..14b8bc1 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -2015,7 +2015,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) - res = bond_sysfs_slave_add(new_slave); - if (res) { - pr_debug("Error %d calling bond_sysfs_slave_add\n", res); -- goto err_detach; -+ goto err_dest_symlinks; - } - - pr_info("%s: enslaving %s as a%s interface with a%s link.\n", -@@ -5036,12 +5036,259 @@ static int bond_get_tx_queues(struct net *net, struct nlattr *tb[], - return 0; - } - -+static size_t bond_get_size(const struct net_device *bond_dev) -+{ -+ return nla_total_size(sizeof(u8)) + /* IFLA_BOND_MODE */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_ACTIVE_SLAVE */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIIMON */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_UPDELAY */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_DOWNDELAY */ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_USE_CARRIER */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_ARP_INTERVAL */ -+ /* IFLA_BOND_ARP_IP_TARGET */ -+ nla_total_size(sizeof(struct nlattr)) + -+ nla_total_size(sizeof(u32)) * BOND_MAX_ARP_TARGETS + -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_ARP_VALIDATE */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_ARP_ALL_TARGETS */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_PRIMARY */ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_PRIMARY_RESELECT */ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_FAIL_OVER_MAC */ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_XMIT_HASH_POLICY */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_RESEND_IGMP */ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_NUM_PEER_NOTIF */ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_ALL_SLAVES_ACTIVE */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIN_LINKS */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_LP_INTERVAL */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_PACKETS_PER_SLAVE */ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_AD_LACP_RATE */ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_AD_SELECT */ -+ nla_total_size(sizeof(struct nlattr)) + /* IFLA_BOND_AD_INFO */ -+ nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_INFO_AGGREGATOR */ -+ nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_INFO_NUM_PORTS */ -+ nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_INFO_ACTOR_KEY */ -+ nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_INFO_PARTNER_KEY*/ -+ nla_total_size(ETH_ALEN) + /* IFLA_BOND_AD_INFO_PARTNER_MAC*/ -+ 0; -+} -+ -+static struct net_device *__bond_option_active_slave_get(struct bonding *bond, -+ struct slave *slave) -+{ -+ return bond_uses_primary(bond) && slave ? slave->dev : NULL; -+} -+ -+static int bond_option_active_slave_get_ifindex(struct bonding *bond) -+{ -+ const struct net_device *slave; -+ int ifindex; -+ -+ read_lock(&bond->lock); -+ read_lock(&bond->curr_slave_lock); -+ slave = __bond_option_active_slave_get(bond, bond->curr_active_slave); -+ ifindex = slave ? slave->ifindex : 0; -+ read_unlock(&bond->curr_slave_lock); -+ read_unlock(&bond->lock); -+ return ifindex; -+} -+ -+ -+static int bond_fill_info(struct sk_buff *skb, -+ const struct net_device *bond_dev) -+{ -+ struct bonding *bond = netdev_priv(bond_dev); -+ int ifindex, i, targets_added; -+ struct nlattr *targets; -+ struct slave *primary; -+ -+ if (nla_put_u8(skb, IFLA_BOND_MODE, BOND_MODE(bond))) -+ goto nla_put_failure; -+ -+ ifindex = bond_option_active_slave_get_ifindex(bond); -+ if (ifindex && nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, ifindex)) -+ goto nla_put_failure; -+ -+ if (nla_put_u32(skb, IFLA_BOND_MIIMON, bond->params.miimon)) -+ goto nla_put_failure; -+ -+ if (nla_put_u32(skb, IFLA_BOND_UPDELAY, -+ bond->params.updelay * bond->params.miimon)) -+ goto nla_put_failure; -+ -+ if (nla_put_u32(skb, IFLA_BOND_DOWNDELAY, -+ bond->params.downdelay * bond->params.miimon)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(skb, IFLA_BOND_USE_CARRIER, bond->params.use_carrier)) -+ goto nla_put_failure; -+ -+ if (nla_put_u32(skb, IFLA_BOND_ARP_INTERVAL, bond->params.arp_interval)) -+ goto nla_put_failure; -+ -+ targets = nla_nest_start(skb, IFLA_BOND_ARP_IP_TARGET); -+ if (!targets) -+ goto nla_put_failure; -+ -+ targets_added = 0; -+ for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) { -+ if (bond->params.arp_targets[i]) { -+ nla_put_be32(skb, i, bond->params.arp_targets[i]); -+ targets_added = 1; -+ } -+ } -+ -+ if (targets_added) -+ nla_nest_end(skb, targets); -+ else -+ nla_nest_cancel(skb, targets); -+ -+ if (nla_put_u32(skb, IFLA_BOND_ARP_VALIDATE, bond->params.arp_validate)) -+ goto nla_put_failure; -+ -+ primary = bond->primary_slave; -+ if (primary && -+ nla_put_u32(skb, IFLA_BOND_PRIMARY, primary->dev->ifindex)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(skb, IFLA_BOND_PRIMARY_RESELECT, -+ bond->params.primary_reselect)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(skb, IFLA_BOND_FAIL_OVER_MAC, -+ bond->params.fail_over_mac)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(skb, IFLA_BOND_XMIT_HASH_POLICY, -+ bond->params.xmit_policy)) -+ goto nla_put_failure; -+ -+ if (nla_put_u32(skb, IFLA_BOND_RESEND_IGMP, -+ bond->params.resend_igmp)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(skb, IFLA_BOND_NUM_PEER_NOTIF, -+ bond->params.num_peer_notif)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(skb, IFLA_BOND_ALL_SLAVES_ACTIVE, -+ bond->params.all_slaves_active)) -+ goto nla_put_failure; -+ -+ if (nla_put_u32(skb, IFLA_BOND_MIN_LINKS, -+ bond->params.min_links)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(skb, IFLA_BOND_AD_LACP_RATE, -+ bond->params.lacp_fast)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(skb, IFLA_BOND_AD_SELECT, -+ bond->params.ad_select)) -+ goto nla_put_failure; -+ -+ if (BOND_MODE(bond) == BOND_MODE_8023AD) { -+ struct ad_info info; -+ -+ if (!bond_3ad_get_active_agg_info(bond, &info)) { -+ struct nlattr *nest; -+ -+ nest = nla_nest_start(skb, IFLA_BOND_AD_INFO); -+ if (!nest) -+ goto nla_put_failure; -+ -+ if (nla_put_u16(skb, IFLA_BOND_AD_INFO_AGGREGATOR, -+ info.aggregator_id)) -+ goto nla_put_failure; -+ if (nla_put_u16(skb, IFLA_BOND_AD_INFO_NUM_PORTS, -+ info.ports)) -+ goto nla_put_failure; -+ if (nla_put_u16(skb, IFLA_BOND_AD_INFO_ACTOR_KEY, -+ info.actor_key)) -+ goto nla_put_failure; -+ if (nla_put_u16(skb, IFLA_BOND_AD_INFO_PARTNER_KEY, -+ info.partner_key)) -+ goto nla_put_failure; -+ if (nla_put(skb, IFLA_BOND_AD_INFO_PARTNER_MAC, -+ sizeof(info.partner_system), -+ &info.partner_system)) -+ goto nla_put_failure; -+ -+ nla_nest_end(skb, nest); -+ } -+ } -+ -+ return 0; -+ -+nla_put_failure: -+ return -EMSGSIZE; -+} -+ -+static size_t bond_get_slave_size(const struct net_device *bond_dev, -+ const struct net_device *slave_dev) -+{ -+ return nla_total_size(sizeof(u8)) + /* IFLA_BOND_SLAVE_STATE */ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_SLAVE_MII_STATUS */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_SLAVE_LINK_FAILURE_COUNT */ -+ nla_total_size(MAX_ADDR_LEN) + /* IFLA_BOND_SLAVE_PERM_HWADDR */ -+ nla_total_size(sizeof(u16)) + /* IFLA_BOND_SLAVE_QUEUE_ID */ -+ nla_total_size(sizeof(u16)) + /* IFLA_BOND_SLAVE_AD_AGGREGATOR_ID */ -+ 0; -+} -+ -+static int bond_fill_slave_info(struct sk_buff *skb, -+ const struct net_device *bond_dev, -+ const struct net_device *slave_dev) -+{ -+ struct slave *slave = bond_slave_get_rtnl(slave_dev); -+ -+ if (!slave) -+ return 0; -+ -+ if (nla_put_u8(skb, IFLA_BOND_SLAVE_STATE, bond_slave_state(slave))) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(skb, IFLA_BOND_SLAVE_MII_STATUS, slave->link)) -+ goto nla_put_failure; -+ -+ if (nla_put_u32(skb, IFLA_BOND_SLAVE_LINK_FAILURE_COUNT, -+ slave->link_failure_count)) -+ goto nla_put_failure; -+ -+ if (nla_put(skb, IFLA_BOND_SLAVE_PERM_HWADDR, -+ slave_dev->addr_len, slave->perm_hwaddr)) -+ goto nla_put_failure; -+ -+ if (nla_put_u16(skb, IFLA_BOND_SLAVE_QUEUE_ID, slave->queue_id)) -+ goto nla_put_failure; -+ -+ if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) { -+ const struct aggregator *agg; -+ -+ agg = SLAVE_AD_INFO(slave).port.aggregator; -+ if (agg) -+ if (nla_put_u16(skb, IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, -+ agg->aggregator_identifier)) -+ goto nla_put_failure; -+ } -+ -+ return 0; -+ -+nla_put_failure: -+ return -EMSGSIZE; -+} -+ -+ - static struct rtnl_link_ops bond_link_ops __read_mostly = { - .kind = "bond", - .priv_size = sizeof(struct bonding), - .setup = bond_setup, -+ .maxtype = IFLA_BOND_MAX, - .validate = bond_validate, -+ .get_size = bond_get_size, -+ .fill_info = bond_fill_info, - .get_tx_queues = bond_get_tx_queues, -+ .slave_maxtype = IFLA_BOND_SLAVE_MAX, -+ .get_slave_size = bond_get_slave_size, -+ .fill_slave_info= bond_fill_slave_info, - }; - - /* Create a new bond based on the specified name and bonding parameters. -diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h -index e70ce3e..af93ed4 100644 ---- a/drivers/net/bonding/bonding.h -+++ b/drivers/net/bonding/bonding.h -@@ -70,6 +70,8 @@ - set_fs(fs); \ - res; }) - -+#define BOND_MODE(bond) ((bond)->params.mode) -+ - /** - * bond_for_each_slave_from - iterate the slaves list from a starting point - * @bond: the bond holding this list. -@@ -268,6 +270,9 @@ static inline bool bond_vlan_used(struct bonding *bond) - #define bond_slave_get_rcu(dev) \ - ((struct slave *) rcu_dereference(dev->rx_handler_data)) - -+#define bond_slave_get_rtnl(dev) \ -+ ((struct slave *) rtnl_dereference(dev->rx_handler_data)) -+ - /** - * Returns NULL if the net_device does not belong to any of the bond's slaves - * -@@ -303,6 +308,17 @@ static inline bool bond_is_lb(const struct bonding *bond) - bond->params.mode == BOND_MODE_ALB); - } - -+static inline bool bond_mode_uses_primary(int mode) -+{ -+ return mode == BOND_MODE_ACTIVEBACKUP || mode == BOND_MODE_TLB || -+ mode == BOND_MODE_ALB; -+} -+ -+static inline bool bond_uses_primary(struct bonding *bond) -+{ -+ return bond_mode_uses_primary(BOND_MODE(bond)); -+} -+ - void bond_set_active_slave(struct slave *slave); - void bond_set_backup_slave(struct slave *slave); - -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index bb5739c..158b989 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -325,6 +325,63 @@ enum { - VXLAN_REPLICATION_SELF, /* self or head-end replication */ - }; - -+/* Bonding section */ -+ -+enum { -+ IFLA_BOND_UNSPEC, -+ IFLA_BOND_MODE, -+ IFLA_BOND_ACTIVE_SLAVE, -+ IFLA_BOND_MIIMON, -+ IFLA_BOND_UPDELAY, -+ IFLA_BOND_DOWNDELAY, -+ IFLA_BOND_USE_CARRIER, -+ IFLA_BOND_ARP_INTERVAL, -+ IFLA_BOND_ARP_IP_TARGET, -+ IFLA_BOND_ARP_VALIDATE, -+ IFLA_BOND_ARP_ALL_TARGETS, -+ IFLA_BOND_PRIMARY, -+ IFLA_BOND_PRIMARY_RESELECT, -+ IFLA_BOND_FAIL_OVER_MAC, -+ IFLA_BOND_XMIT_HASH_POLICY, -+ IFLA_BOND_RESEND_IGMP, -+ IFLA_BOND_NUM_PEER_NOTIF, -+ IFLA_BOND_ALL_SLAVES_ACTIVE, -+ IFLA_BOND_MIN_LINKS, -+ IFLA_BOND_LP_INTERVAL, -+ IFLA_BOND_PACKETS_PER_SLAVE, -+ IFLA_BOND_AD_LACP_RATE, -+ IFLA_BOND_AD_SELECT, -+ IFLA_BOND_AD_INFO, -+ __IFLA_BOND_MAX, -+}; -+ -+#define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1) -+ -+enum { -+ IFLA_BOND_AD_INFO_UNSPEC, -+ IFLA_BOND_AD_INFO_AGGREGATOR, -+ IFLA_BOND_AD_INFO_NUM_PORTS, -+ IFLA_BOND_AD_INFO_ACTOR_KEY, -+ IFLA_BOND_AD_INFO_PARTNER_KEY, -+ IFLA_BOND_AD_INFO_PARTNER_MAC, -+ __IFLA_BOND_AD_INFO_MAX, -+}; -+ -+#define IFLA_BOND_AD_INFO_MAX (__IFLA_BOND_AD_INFO_MAX - 1) -+ -+enum { -+ IFLA_BOND_SLAVE_UNSPEC, -+ IFLA_BOND_SLAVE_STATE, -+ IFLA_BOND_SLAVE_MII_STATUS, -+ IFLA_BOND_SLAVE_LINK_FAILURE_COUNT, -+ IFLA_BOND_SLAVE_PERM_HWADDR, -+ IFLA_BOND_SLAVE_QUEUE_ID, -+ IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, -+ __IFLA_BOND_SLAVE_MAX, -+}; -+ -+#define IFLA_BOND_SLAVE_MAX (__IFLA_BOND_SLAVE_MAX - 1) -+ - /* SR-IOV virtual function management section */ - - enum { diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-bond-open-slave-state.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-bond-open-slave-state.patch deleted file mode 100644 index 7d47bf4b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-bond-open-slave-state.patch +++ /dev/null @@ -1,17 +0,0 @@ -During bond_open(), the bonding driver always set the slave active flag to -true if the bond is not in active/backup mode. Bonding driver should let -the aggregator selection logic set the active flag. - -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index 3891c08..536d298 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -3648,7 +3648,7 @@ static int bond_open(struct net_device *bond_dev) - if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) - && (slave != bond->curr_active_slave)) { - bond_set_slave_inactive_flags(slave); -- } else { -+ } else if (bond->params.mode != BOND_MODE_8023AD) { - bond_set_slave_active_flags(slave); - } - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-inconsistent-stats.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-inconsistent-stats.patch deleted file mode 100644 index c8f8c43c..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-inconsistent-stats.patch +++ /dev/null @@ -1,177 +0,0 @@ -backport of the following upstream commit with changes to deal with -locking differences in 3.2: - -commit 5f0c5f73e5efaee2928c4cabcf48b03f6ba99fc8 -Author: Andy Gospodarek -Date: Sun Sep 28 22:34:37 2014 -0400 - - bonding: make global bonding stats more reliable - - As the code stands today, bonding stats are based simply on the stats - from the member interfaces. If a member was to be removed from a bond, - the stats would instantly drop. This would be confusing to an admin - would would suddonly see interface stats drop while traffic is still - flowing. - - In addition to preventing the stats drops mentioned above, new members - will now be added to the bond and only traffic received after the member - was added to the bond will be counted as part of bonding stats. Bonding - counters will also be updated when any slaves are dropped to make sure - the reported stats are reliable. - -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index c75b3ef..768b0de 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -254,6 +254,10 @@ struct bond_parm_tbl ad_select_tbl[] = { - - static int bond_init(struct net_device *bond_dev); - static void bond_uninit(struct net_device *bond_dev); -+static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev, -+ struct rtnl_link_stats64 *stats); -+static struct rtnl_link_stats64 *__bond_get_stats(struct net_device *bond_dev, -+ struct rtnl_link_stats64 *stats); - - /*---------------------------- General routines -----------------------------*/ - -@@ -1816,6 +1820,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) - new_slave->bond = bond; - new_slave->dev = slave_dev; - slave_dev->priv_flags |= IFF_BONDING; -+ /* initialize slave stats */ -+ dev_get_stats(new_slave->dev, &new_slave->slave_stats); - - if (bond_is_lb(bond)) { - /* bond_alb_init_slave() must be called before all other stages since -@@ -2135,6 +2141,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) - - /* release the slave from its bond */ - bond_sysfs_slave_del(slave); -+ /* recompute stats just before removing the slave */ -+ __bond_get_stats(bond->dev, &bond->bond_stats); -+ - bond_detach_slave(bond, slave); - - if (bond->primary_slave == slave) -@@ -3701,46 +3710,61 @@ static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev, - struct rtnl_link_stats64 *stats) - { - struct bonding *bond = netdev_priv(bond_dev); -- struct rtnl_link_stats64 temp; -- struct slave *slave; -- int i; -- -- memset(stats, 0, sizeof(*stats)); - - read_lock_bh(&bond->lock); - -- bond_for_each_slave(bond, slave, i) { -- const struct rtnl_link_stats64 *sstats = -- dev_get_stats(slave->dev, &temp); -+ stats = __bond_get_stats(bond_dev, stats); - -- stats->rx_packets += sstats->rx_packets; -- stats->rx_bytes += sstats->rx_bytes; -- stats->rx_errors += sstats->rx_errors; -- stats->rx_dropped += sstats->rx_dropped; -- -- stats->tx_packets += sstats->tx_packets; -- stats->tx_bytes += sstats->tx_bytes; -- stats->tx_errors += sstats->tx_errors; -- stats->tx_dropped += sstats->tx_dropped; -+ read_unlock_bh(&bond->lock); - -- stats->multicast += sstats->multicast; -- stats->collisions += sstats->collisions; -+ return stats; -+} - -- stats->rx_length_errors += sstats->rx_length_errors; -- stats->rx_over_errors += sstats->rx_over_errors; -- stats->rx_crc_errors += sstats->rx_crc_errors; -- stats->rx_frame_errors += sstats->rx_frame_errors; -- stats->rx_fifo_errors += sstats->rx_fifo_errors; -- stats->rx_missed_errors += sstats->rx_missed_errors; -+static struct rtnl_link_stats64 *__bond_get_stats(struct net_device *bond_dev, -+ struct rtnl_link_stats64 *stats) -+{ -+ struct bonding *bond = netdev_priv(bond_dev); -+ struct rtnl_link_stats64 temp; -+ struct slave *slave; -+ int i; - -- stats->tx_aborted_errors += sstats->tx_aborted_errors; -- stats->tx_carrier_errors += sstats->tx_carrier_errors; -- stats->tx_fifo_errors += sstats->tx_fifo_errors; -- stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors; -- stats->tx_window_errors += sstats->tx_window_errors; -- } -+ memcpy(stats, &bond->bond_stats, sizeof(*stats)); - -- read_unlock_bh(&bond->lock); -+ bond_for_each_slave(bond, slave, i) { -+ const struct rtnl_link_stats64 *sstats = -+ dev_get_stats(slave->dev, &temp); -+ struct rtnl_link_stats64 *pstats = &slave->slave_stats; -+ -+ stats->rx_packets += sstats->rx_packets - pstats->rx_packets; -+ stats->rx_bytes += sstats->rx_bytes - pstats->rx_bytes; -+ stats->rx_errors += sstats->rx_errors - pstats->rx_errors; -+ stats->rx_dropped += sstats->rx_dropped - pstats->rx_dropped; -+ -+ stats->tx_packets += sstats->tx_packets - pstats->tx_packets; -+ stats->tx_bytes += sstats->tx_bytes - pstats->tx_bytes; -+ stats->tx_errors += sstats->tx_errors - pstats->tx_errors; -+ stats->tx_dropped += sstats->tx_dropped - pstats->tx_dropped; -+ -+ stats->multicast += sstats->multicast - pstats->multicast; -+ stats->collisions += sstats->collisions - pstats->collisions; -+ -+ stats->rx_length_errors += sstats->rx_length_errors - pstats->rx_length_errors; -+ stats->rx_over_errors += sstats->rx_over_errors - pstats->rx_over_errors; -+ stats->rx_crc_errors += sstats->rx_crc_errors - pstats->rx_crc_errors; -+ stats->rx_frame_errors += sstats->rx_frame_errors - pstats->rx_frame_errors; -+ stats->rx_fifo_errors += sstats->rx_fifo_errors - pstats->rx_fifo_errors; -+ stats->rx_missed_errors += sstats->rx_missed_errors - pstats->rx_missed_errors; -+ -+ stats->tx_aborted_errors += sstats->tx_aborted_errors - pstats->tx_aborted_errors; -+ stats->tx_carrier_errors += sstats->tx_carrier_errors - pstats->tx_carrier_errors; -+ stats->tx_fifo_errors += sstats->tx_fifo_errors - pstats->tx_fifo_errors; -+ stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors - pstats->tx_heartbeat_errors; -+ stats->tx_window_errors += sstats->tx_window_errors - pstats->tx_window_errors; -+ -+ /* save off the slave stats for the next run */ -+ memcpy(pstats, sstats, sizeof(*sstats)); -+ } -+ memcpy(&bond->bond_stats, stats, sizeof(*stats)); - - return stats; - } -diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h -index 382947a..e70ce3e 100644 ---- a/drivers/net/bonding/bonding.h -+++ b/drivers/net/bonding/bonding.h -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include "bond_3ad.h" - #include "bond_alb.h" - -@@ -201,6 +202,7 @@ struct slave { - struct netpoll *np; - #endif - struct kobject kobj; -+ struct rtnl_link_stats64 slave_stats; - }; - - /* -@@ -255,6 +257,7 @@ struct bonding { - /* debugging suport via debugfs */ - struct dentry *debug_dir; - #endif /* CONFIG_DEBUG_FS */ -+ struct rtnl_link_stats64 bond_stats; - }; - - static inline bool bond_vlan_used(struct bonding *bond) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-min-links.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-min-links.patch deleted file mode 100644 index f8ea8000..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-min-links.patch +++ /dev/null @@ -1,56 +0,0 @@ -CM-1191: keep bond interface carrier off until bond has atleast one active member. -LACP will still do it's job while bond is carrier off, and if bond members become -active down the road, bond carrier will be turned back on, signaling higher- -level protocols that bond is viable. - -This patch is rushed for CL launch release and probably needs to be revisited -for better integration into the LACP state machines implemented in the bonding -driver. For now, the patch uses number of active slaves to compare against -min_links to know when to on/off bond carrier. Suggested setting of min_links -is 1, rather than the default of zero. Using min_links=1 says that atleast 1 -slave must be active within bond for bond to be carrier on. - -diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c -index c7e3e53..082a399 100644 ---- a/drivers/net/bonding/bond_3ad.c -+++ b/drivers/net/bonding/bond_3ad.c -@@ -224,6 +224,7 @@ static inline int __agg_has_partner(struct aggregator *agg) - static inline void __disable_port(struct port *port) - { - bond_set_slave_inactive_flags(port->slave); -+ bond_3ad_set_carrier(port->slave->bond); - } - - /** -@@ -235,8 +236,10 @@ static inline void __enable_port(struct port *port) - { - struct slave *slave = port->slave; - -- if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) -+ if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) { - bond_set_slave_active_flags(slave); -+ bond_3ad_set_carrier(slave->bond); -+ } - } - - /** -@@ -2331,11 +2334,17 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) - int bond_3ad_set_carrier(struct bonding *bond) - { - struct aggregator *active; -+ struct slave *slave; -+ int active_slaves = 0, i; -+ -+ bond_for_each_slave(bond, slave, i) -+ if (bond_is_active_slave(slave)) -+ active_slaves++; - - active = __get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator)); -- if (active) { -+ if (active && __agg_has_partner(active)) { - /* are enough slaves available to consider link up? */ -- if (active->num_of_ports < bond->params.min_links) { -+ if (active_slaves < bond->params.min_links) { - if (netif_carrier_ok(bond->dev)) { - netif_carrier_off(bond->dev); - return 1; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-race-between-sysfs-and-bond_enslave.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-race-between-sysfs-and-bond_enslave.patch deleted file mode 100644 index 7d451cae..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-race-between-sysfs-and-bond_enslave.patch +++ /dev/null @@ -1,39 +0,0 @@ -Backport of upstream patch: - -commit b59340c2c0508d280f10658ad662fa56a39c74c2 -Author: nikolay@redhat.com -Date: Mon Feb 18 07:59:02 2013 +0000 - - bonding: Fix race condition between bond_enslave() and bond_3ad_update_lacp_rate() - -for bond_3ad_update_lacp_rate and for similar functions we have added -that are not upstream. - -diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c -index c5ab398..25edb23 100644 ---- a/drivers/net/bonding/bond_3ad.c -+++ b/drivers/net/bonding/bond_3ad.c -@@ -2730,11 +2730,13 @@ void bond_3ad_update_lacp_rate(struct bonding *bond) - struct port *port = NULL; - int lacp_fast; - -- read_lock(&bond->lock); -+ write_lock_bh(&bond->lock); - lacp_fast = bond->params.lacp_fast; - - bond_for_each_slave(bond, slave, i) { - port = &(SLAVE_AD_INFO(slave).port); -+ if (port->slave == NULL) -+ continue; - __get_state_machine_lock(port); - if (lacp_fast) - port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT; -@@ -2743,7 +2745,7 @@ void bond_3ad_update_lacp_rate(struct bonding *bond) - __release_state_machine_lock(port); - } - -- read_unlock(&bond->lock); -+ write_unlock_bh(&bond->lock); - } - - /* diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-scheduling-while-atomic.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-scheduling-while-atomic.patch deleted file mode 100644 index b80468c0..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-fix-scheduling-while-atomic.patch +++ /dev/null @@ -1,57 +0,0 @@ -The main change here is to move the call to bond_sysfs_slave_del() in -bond_release() outside an area that is under a bh-lock since -bond_sysfs_slave_del() may sleep trying to take a mutex. The code in -bond_release() changed pretty dramatically between 3.2 and when the -upstream commit that added the sysfs slave info was added, so it was -easy to miss the fact that this call needed to be outside a bh-lock. I -also added back an error cleanup in bond_enslave() that was missed in -the first patch. We have probably never hit this, but it should be -there. - -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index d84b0b7..bc7b125 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -2020,7 +2020,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) - res = bond_sysfs_slave_add(new_slave); - if (res) { - pr_debug("Error %d calling bond_sysfs_slave_add\n", res); -- goto err_dest_symlinks; -+ goto err_unregister; - } - - pr_info("%s: enslaving %s as a%s interface with a%s link.\n", -@@ -2032,6 +2032,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) - return 0; - - /* Undo stages on error */ -+err_unregister: -+ netdev_rx_handler_unregister(slave_dev); -+ - err_dest_symlinks: - bond_destroy_slave_symlinks(bond_dev, slave_dev); - -@@ -2112,10 +2115,14 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) - } - - write_unlock_bh(&bond->lock); -+ -+ bond_sysfs_slave_del(slave); -+ - /* unregister rx_handler early so bond_handle_frame wouldn't be called - * for this slave anymore. - */ - netdev_rx_handler_unregister(slave_dev); -+ - write_lock_bh(&bond->lock); - - if (!bond->params.fail_over_mac) { -@@ -2144,8 +2151,6 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) - - bond->current_arp_slave = NULL; - -- /* release the slave from its bond */ -- bond_sysfs_slave_del(slave); - /* recompute stats just before removing the slave */ - __bond_get_stats(bond->dev, &bond->bond_stats); - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-lacp-fallback-check-bonding-mode.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-lacp-fallback-check-bonding-mode.patch deleted file mode 100644 index d9078640..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-lacp-fallback-check-bonding-mode.patch +++ /dev/null @@ -1,48 +0,0 @@ -Checkout bonding mode before allowing the fallback parameters to be set. - -diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c -index 6103587..4abf593 100644 ---- a/drivers/net/bonding/bond_sysfs.c -+++ b/drivers/net/bonding/bond_sysfs.c -@@ -1001,6 +1001,13 @@ static ssize_t bonding_store_lacp_fallback_allow(struct device *d, - int ret; - unsigned int new_value; - -+ if (bond->params.mode != BOND_MODE_8023AD) { -+ pr_err("%s: Unable to update lacp_fallback_allow because bond is not " -+ "in 802.3ad mode.\n", bond->dev->name); -+ ret = -EPERM; -+ return ret; -+ } -+ - ret = kstrtouint(buf, 0, &new_value); - if (ret < 0) { - pr_err("%s: Ignoring invalid lacp_fallback_allow value %s.\n", -@@ -1037,6 +1044,13 @@ static ssize_t bonding_store_lacp_fallback_period(struct device *d, - int ret; - unsigned int new_value; - -+ if (bond->params.mode != BOND_MODE_8023AD) { -+ pr_err("%s: Unable to update lacp_fallback_period because bond is not " -+ "in 802.3ad mode.\n", bond->dev->name); -+ ret = -EPERM; -+ return ret; -+ } -+ - ret = kstrtouint(buf, 0, &new_value); - if (ret < 0) { - pr_err("%s: Ignoring invalid lacp_fallback_period value %s.\n", -@@ -1074,6 +1088,13 @@ static ssize_t bonding_store_lacp_fallback_active(struct device *d, - int ret; - unsigned int new_value; - -+ if (bond->params.mode != BOND_MODE_8023AD) { -+ pr_err("%s: Unable to update lacp_fallback_active because bond is not " -+ "in 802.3ad mode.\n", bond->dev->name); -+ ret = -EPERM; -+ return ret; -+ } -+ - ret = kstrtouint(buf, 0, &new_value); - if (ret < 0) { - pr_err("%s: Ignoring invalid lacp_fallback_active value %s.\n", diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-lacp-fix-incorrect-mux-state.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-lacp-fix-incorrect-mux-state.patch deleted file mode 100644 index d4585195..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-lacp-fix-incorrect-mux-state.patch +++ /dev/null @@ -1,135 +0,0 @@ -This patch attempts to fix the following problems: - -1. a slave's lacp port state is marked as AD_STATE_SYNCHRONIZATION - even if it is attached to an inactive aggregator. LACP advertises - this state to the partner, making the partner think he can move - into COLLECTING_DISTRIBUTING state even though this link will not - pass traffic on the local side - -2. a slave goes into COLLECTING_DISTRIBUTING state without checking - if the aggregator is actually active - -3. when in COLLECTING_DISTRIBUTING state, the partner parameters may - change, e.g. the partner_oper_port_state.SYNCHRONIZATION. The local - mux machine is not reacting to the change and continue to keep the - slave and bond up - -diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c -index 74d00e9..bccced4 100644 ---- a/drivers/net/bonding/bond_3ad.c -+++ b/drivers/net/bonding/bond_3ad.c -@@ -624,10 +624,14 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port) - - // set the partner sync. to on if the partner is sync. and the port is matched - if ((port->sm_vars & AD_PORT_MATCHED) -- && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) -+ && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) { - partner->port_state |= AD_STATE_SYNCHRONIZATION; -- else -+ pr_debug("%s partner sync=1\n", port->slave->dev->name); -+ } -+ else { - partner->port_state &= ~AD_STATE_SYNCHRONIZATION; -+ pr_debug("%s partner sync=0\n", port->slave->dev->name); -+ } - } - } - -@@ -896,6 +900,8 @@ static inline void __update_lacpdu_from_port(struct port *port) - lacpdu->actor_port_priority = htons(port->actor_port_priority); - lacpdu->actor_port = htons(port->actor_port_number); - lacpdu->actor_state = port->actor_oper_port_state; -+ pr_debug("update lacpdu: %s, actor port state %x\n", -+ port->slave->dev->name, port->actor_oper_port_state); - - /* lacpdu->reserved_3_1 initialized - * lacpdu->tlv_type_partner_info initialized -@@ -1054,18 +1060,21 @@ static void ad_mux_machine(struct port *port) - case AD_MUX_ATTACHED: - // check also if agg_select_timer expired(so the edable port will take place only after this timer) - if ((port->sm_vars & AD_PORT_SELECTED) && (port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) && !__check_agg_selection_timer(port)) { -- port->sm_mux_state = AD_MUX_COLLECTING_DISTRIBUTING;// next state -+ if (port->aggregator->is_active) -+ port->sm_mux_state = AD_MUX_COLLECTING_DISTRIBUTING;// next state - } else if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { // if UNSELECTED or STANDBY - port->sm_vars &= ~AD_PORT_READY_N; - // in order to withhold the selection logic to check all ports READY_N value - // every callback cycle to update ready variable, we check READY_N and update READY here - __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); - port->sm_mux_state = AD_MUX_DETACHED;// next state -- } -+ } else if (port->aggregator->is_active) -+ port->actor_oper_port_state |= AD_STATE_SYNCHRONIZATION; - break; - case AD_MUX_COLLECTING_DISTRIBUTING: - if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY) || -- !(port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) -+ !(port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) || -+ !(port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION) - ) { - port->sm_mux_state = AD_MUX_ATTACHED;// next state - -@@ -1088,8 +1097,8 @@ static void ad_mux_machine(struct port *port) - - // check if the state machine was changed - if (port->sm_mux_state != last_state) { -- pr_debug("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n", -- port->actor_port_number, last_state, -+ pr_debug("Mux Machine: Port=%d (%s), Last State=%d, Curr State=%d\n", -+ port->actor_port_number, port->slave->dev->name, last_state, - port->sm_mux_state); - switch (port->sm_mux_state) { - case AD_MUX_DETACHED: -@@ -1105,7 +1114,10 @@ static void ad_mux_machine(struct port *port) - break; - case AD_MUX_ATTACHED: - __attach_bond_to_agg(port); -- port->actor_oper_port_state |= AD_STATE_SYNCHRONIZATION; -+ if (port->aggregator->is_active) -+ port->actor_oper_port_state |= AD_STATE_SYNCHRONIZATION; -+ else -+ port->actor_oper_port_state &= ~AD_STATE_SYNCHRONIZATION; - port->actor_oper_port_state &= ~AD_STATE_COLLECTING; - port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING; - ad_disable_collecting_distributing(port); -@@ -1114,6 +1126,7 @@ static void ad_mux_machine(struct port *port) - case AD_MUX_COLLECTING_DISTRIBUTING: - port->actor_oper_port_state |= AD_STATE_COLLECTING; - port->actor_oper_port_state |= AD_STATE_DISTRIBUTING; -+ port->actor_oper_port_state |= AD_STATE_SYNCHRONIZATION; - ad_enable_collecting_distributing(port); - port->ntt = true; - break; -@@ -1225,8 +1238,8 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - - // check if the State machine was changed or new lacpdu arrived - if ((port->sm_rx_state != last_state) || (lacpdu)) { -- pr_debug("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n", -- port->actor_port_number, last_state, -+ pr_debug("Rx Machine: Port=%d (%s), Last State=%d, Curr State=%d\n", -+ port->actor_port_number, port->slave->dev->name, last_state, - port->sm_rx_state); - switch (port->sm_rx_state) { - case AD_RX_INITIALIZE: -@@ -1330,9 +1343,9 @@ static void ad_tx_machine(struct port *port) - __update_lacpdu_from_port(port); - - if (ad_lacpdu_send(port) >= 0) { -- pr_debug("Sent LACPDU on port %d, bond %s slave %s\n", -+ pr_debug("Sent LACPDU on port %d, bond %s slave %s (actor port state %x)\n", - port->actor_port_number, bond ? bond->dev->name:"", -- slave ? slave->dev->name:""); -+ slave ? slave->dev->name:"", port->actor_oper_port_state); - - /* mark ntt as false, so it will not be sent again until - demanded */ -@@ -1572,6 +1585,9 @@ static void ad_port_selection_logic(struct port *port) - - aggregator = __get_first_agg(port); - ad_agg_selection_logic(aggregator); -+ -+ if (!port->aggregator->is_active) -+ port->actor_oper_port_state &= ~AD_STATE_SYNCHRONIZATION; - } - - /* diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-lacp-no-tx-full-duplex.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-lacp-no-tx-full-duplex.patch deleted file mode 100644 index bd1df42e..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-lacp-no-tx-full-duplex.patch +++ /dev/null @@ -1,79 +0,0 @@ -When a slave is added to a bond and it is not in full duplex mode, -AD_PORT_LACP_ENABLED flag is cleared, due to this LACP PDU is not sent -on slave. When the duplex is changed to full, the flag needs to be set -to send LACP PDU. - -diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c -index 00c349a..0b3ce2d 100644 ---- a/drivers/net/bonding/bond_3ad.c -+++ b/drivers/net/bonding/bond_3ad.c -@@ -1152,6 +1152,9 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - */ - static void ad_tx_machine(struct port *port) - { -+ struct bonding *bond = __get_bond_by_port(port); -+ struct slave *slave = port->slave; -+ - // check if tx timer expired, to verify that we do not send more than 3 packets per second - if (port->sm_tx_timer_counter && !(--port->sm_tx_timer_counter)) { - // check if there is something to send -@@ -1159,8 +1162,9 @@ static void ad_tx_machine(struct port *port) - __update_lacpdu_from_port(port); - - if (ad_lacpdu_send(port) >= 0) { -- pr_debug("Sent LACPDU on port %d\n", -- port->actor_port_number); -+ pr_debug("Sent LACPDU on port %d, bond %s slave %s\n", -+ port->actor_port_number, bond ? bond->dev->name:"", -+ slave ? slave->dev->name:""); - - /* mark ntt as false, so it will not be sent again until - demanded */ -@@ -2183,6 +2187,7 @@ re_arm: - static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length) - { - struct port *port; -+ struct bonding *bond; - - if (length >= sizeof(struct lacpdu)) { - -@@ -2193,11 +2198,13 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u - slave->dev->name, slave->dev->master->name); - return; - } -+ bond = __get_bond_by_port(port); - - switch (lacpdu->subtype) { - case AD_TYPE_LACPDU: -- pr_debug("Received LACPDU on port %d\n", -- port->actor_port_number); -+ pr_debug("Received LACPDU on port %d bond %s slave %s\n", -+ port->actor_port_number, (bond && bond->dev) ? bond->dev->name:"", -+ (port->slave && port->slave->dev) ? port->slave->dev->name:""); - /* Protect against concurrent state machines */ - __get_state_machine_lock(port); - ad_rx_machine(lacpdu, port); -@@ -2265,8 +2272,10 @@ void bond_3ad_adapter_speed_changed(struct slave *slave) - void bond_3ad_adapter_duplex_changed(struct slave *slave) - { - struct port *port; -+ struct bonding *bond; - - port = &(SLAVE_AD_INFO(slave).port); -+ bond = __get_bond_by_port(port); - - // if slave is null, the whole port is not initialized - if (!port->slave) { -@@ -2278,7 +2287,11 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave) - port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; - port->actor_oper_port_key = port->actor_admin_port_key |= - __get_duplex(port); -- pr_debug("Port %d changed duplex\n", port->actor_port_number); -+ pr_debug("Port %d bond %s slave %s changed duplex\n", port->actor_port_number, -+ (bond && bond->dev) ? bond->dev->name:"", -+ (port->slave && port->slave->dev) ? port->slave->dev->name:""); -+ if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS) -+ port->sm_vars |= AD_PORT_LACP_ENABLED; - // there is no need to reselect a new aggregator, just signal the - // state machines to reinitialize - port->sm_vars |= AD_PORT_BEGIN; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-no-initial-bond0.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-no-initial-bond0.patch deleted file mode 100644 index 5698e6a1..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-no-initial-bond0.patch +++ /dev/null @@ -1,19 +0,0 @@ -Set max_bonds=0 so when bonding driver is loaded, no bonds are created. Bonds -can be created once driver is loaded using ifenslave (and /etc/network/interfaces). - -The kernel default value is max_bonds=1 which creates an empty bond0 on bonding -driver load. - -diff --git a/include/linux/if_bonding.h b/include/linux/if_bonding.h -index a17edda..13f3ed0 100644 ---- a/include/linux/if_bonding.h -+++ b/include/linux/if_bonding.h -@@ -81,7 +81,7 @@ - #define BOND_STATE_ACTIVE 0 /* link is active */ - #define BOND_STATE_BACKUP 1 /* link is backup */ - --#define BOND_DEFAULT_MAX_BONDS 1 /* Default maximum number of devices to support */ -+#define BOND_DEFAULT_MAX_BONDS 0 /* Default maximum number of devices to support */ - - #define BOND_DEFAULT_TX_QUEUES 16 /* Default number of tx queues per device */ - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-rtnl-dump-lacp-fallback-support.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-rtnl-dump-lacp-fallback-support.patch deleted file mode 100644 index bda46781..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-rtnl-dump-lacp-fallback-support.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 5d87993c403c54852c9e7a6ed71eba1295ebf903 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] cumulus: bonding: netlink dump lacp fallback attributes - -Adds support for dumping the various lacp fallback attributes. - -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index 14b8bc1..3891c08 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -5068,6 +5068,9 @@ static size_t bond_get_size(const struct net_device *bond_dev) - nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_INFO_ACTOR_KEY */ - nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_INFO_PARTNER_KEY*/ - nla_total_size(ETH_ALEN) + /* IFLA_BOND_AD_INFO_PARTNER_MAC*/ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_CL_LACP_FB_ALLOW */ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_CL_LACP_FB_ACTIVE */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_CL_LACP_FB_PERIOD */ - 0; - } - -@@ -5214,6 +5217,18 @@ static int bond_fill_info(struct sk_buff *skb, - - nla_nest_end(skb, nest); - } -+ -+ if (nla_put_u8(skb, IFLA_BOND_CL_LACP_FB_ALLOW, -+ bond->params.lacp_fallback_allow)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(skb, IFLA_BOND_CL_LACP_FB_ACTIVE, -+ bond->params.lacp_fallback_active)) -+ goto nla_put_failure; -+ -+ if (nla_put_u32(skb, IFLA_BOND_CL_LACP_FB_PERIOD, -+ bond->params.lacp_fallback_period)) -+ goto nla_put_failure; - } - - return 0; -@@ -5231,6 +5246,7 @@ static size_t bond_get_slave_size(const struct net_device *bond_dev, - nla_total_size(MAX_ADDR_LEN) + /* IFLA_BOND_SLAVE_PERM_HWADDR */ - nla_total_size(sizeof(u16)) + /* IFLA_BOND_SLAVE_QUEUE_ID */ - nla_total_size(sizeof(u16)) + /* IFLA_BOND_SLAVE_AD_AGGREGATOR_ID */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_SLAVE_CL_LACP_FB_PRIO */ - 0; - } - -@@ -5268,6 +5284,10 @@ static int bond_fill_slave_info(struct sk_buff *skb, - if (nla_put_u16(skb, IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, - agg->aggregator_identifier)) - goto nla_put_failure; -+ -+ if (nla_put_u32(skb, IFLA_BOND_SLAVE_CL_LACP_FB_PRIO, -+ slave->lacp_fallback_priority)) -+ goto nla_put_failure; - } - - return 0; -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index 158b989..ee99f97 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -352,6 +352,11 @@ enum { - IFLA_BOND_AD_LACP_RATE, - IFLA_BOND_AD_SELECT, - IFLA_BOND_AD_INFO, -+ -+ IFLA_BOND_CL_START = 100, -+ IFLA_BOND_CL_LACP_FB_ALLOW = IFLA_BOND_CL_START, -+ IFLA_BOND_CL_LACP_FB_ACTIVE, -+ IFLA_BOND_CL_LACP_FB_PERIOD, - __IFLA_BOND_MAX, - }; - -@@ -377,6 +382,9 @@ enum { - IFLA_BOND_SLAVE_PERM_HWADDR, - IFLA_BOND_SLAVE_QUEUE_ID, - IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, -+ -+ IFLA_BOND_SLAVE_CL_START = 50, -+ IFLA_BOND_SLAVE_CL_LACP_FB_PRIO = IFLA_BOND_SLAVE_CL_START, - __IFLA_BOND_SLAVE_MAX, - }; - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-set-sys-mac-priority.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-set-sys-mac-priority.patch deleted file mode 100644 index 0bb18e88..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bonding-set-sys-mac-priority.patch +++ /dev/null @@ -1,298 +0,0 @@ -Allow the sys_priority and sys_mac_addr of 802.3ad bonds to be configured. - -sysfs objects are added to allow for the configuration of the sys_mac_addr -and sys_priority, called the System Identification in the 802.1AX standard. -This allows for decoupling of the System Identification from the mac address -used by the bond. If also avoids a problem where an assigned MAC address -to a bond is removed when the bond goes down. - -diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c -index 082a399..00c349a 100644 ---- a/drivers/net/bonding/bond_3ad.c -+++ b/drivers/net/bonding/bond_3ad.c -@@ -1297,6 +1297,7 @@ static void ad_port_selection_logic(struct port *port) - port->aggregator = NULL; - port->next_port_in_aggregator = NULL; - port->actor_port_aggregator_identifier = 0; -+ __disable_port(port); - - pr_debug("Port %d left LAG %d\n", - port->actor_port_number, -@@ -1866,14 +1867,19 @@ void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout) - */ - void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution) - { -+ // If user configured a sys_mac, use it -+ struct mac_addr *sys_mac = (struct mac_addr *)bond->dev->dev_addr; -+ if (MAC_ADDRESS_COMPARE(&(bond->params.sys_mac_addr), &(null_mac_addr))) -+ sys_mac = (struct mac_addr *)&(bond->params.sys_mac_addr); -+ - // check that the bond is not initialized yet - if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), -- bond->dev->dev_addr)) { -+ sys_mac)) { - - BOND_AD_INFO(bond).aggregator_identifier = 0; - -- BOND_AD_INFO(bond).system.sys_priority = 0xFFFF; -- BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr); -+ BOND_AD_INFO(bond).system.sys_priority = bond->params.sys_priority; -+ BOND_AD_INFO(bond).system.sys_mac_addr = *sys_mac; - - // initialize how many times this module is called in one second(should be about every 100ms) - ad_ticks_per_sec = tick_resolution; -@@ -2514,3 +2520,70 @@ void bond_3ad_update_lacp_rate(struct bonding *bond) - - read_unlock(&bond->lock); - } -+ -+/* -+ * When modify sys_priority parameter via sysfs, -+ * update the bond's sys_priority and the -+ * actor_system_priority of each port. -+ * -+ * Hold slave->state_machine_lock, -+ * so we can modify port->actor_system_priority -+ * no matter bond is up or down. -+ */ -+void bond_3ad_update_sys_priority(struct bonding *bond) -+{ -+ int i; -+ struct slave *slave; -+ struct port *port = NULL; -+ u16 sys_priority; -+ -+ write_lock_bh(&bond->lock); -+ sys_priority = bond->params.sys_priority; -+ BOND_AD_INFO(bond).system.sys_priority = sys_priority; -+ -+ bond_for_each_slave(bond, slave, i) { -+ port = &(SLAVE_AD_INFO(slave).port); -+ if (port->slave == NULL) -+ continue; -+ __get_state_machine_lock(port); -+ port->actor_system_priority = sys_priority; -+ __release_state_machine_lock(port); -+ } -+ -+ write_unlock_bh(&bond->lock); -+} -+ -+/* -+ * When modify sys_mac_addr parameter via sysfs, -+ * update the bond's sys_mac_addr and the -+ * actor_system of each port. -+ * -+ * Hold slave->state_machine_lock, -+ * so we can modify port->actor_system -+ * no matter bond is up or down. -+ */ -+void bond_3ad_update_sys_mac_addr(struct bonding *bond) -+{ -+ int i; -+ struct slave *slave; -+ struct port *port = NULL; -+ struct mac_addr sys_mac; -+ -+ write_lock_bh(&bond->lock); -+ sys_mac = *((struct mac_addr *)&(bond->params.sys_mac_addr)); -+ if (!MAC_ADDRESS_COMPARE(&(sys_mac), &(null_mac_addr))){ -+ sys_mac = *((struct mac_addr *)bond->dev->dev_addr); -+ } -+ BOND_AD_INFO(bond).system.sys_mac_addr = sys_mac; -+ -+ bond_for_each_slave(bond, slave, i) { -+ port = &(SLAVE_AD_INFO(slave).port); -+ if (port->slave == NULL) -+ continue; -+ __get_state_machine_lock(port); -+ port->actor_system = sys_mac; -+ __release_state_machine_lock(port); -+ } -+ -+ write_unlock_bh(&bond->lock); -+} -diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h -index 046bb1f..677c108 100644 ---- a/drivers/net/bonding/bond_3ad.h -+++ b/drivers/net/bonding/bond_3ad.h -@@ -280,5 +280,7 @@ void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, - struct slave *slave); - int bond_3ad_set_carrier(struct bonding *bond); - void bond_3ad_update_lacp_rate(struct bonding *bond); -+void bond_3ad_update_sys_priority(struct bonding *bond); -+void bond_3ad_update_sys_mac_addr(struct bonding *bond); - #endif //__BOND_3AD_H__ - -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index a986b86..342e647 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -4907,6 +4907,8 @@ static int bond_check_params(struct bond_params *params) - params->downdelay = downdelay; - params->use_carrier = use_carrier; - params->lacp_fast = lacp_fast; -+ params->sys_priority = 0xFFFF; -+ memset(¶ms->sys_mac_addr, 0, sizeof(params->sys_mac_addr)); - params->primary[0] = 0; - params->primary_reselect = primary_reselect_value; - params->fail_over_mac = fail_over_mac_value; -diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c -index ad284ba..4fa1b95 100644 ---- a/drivers/net/bonding/bond_procfs.c -+++ b/drivers/net/bonding/bond_procfs.c -@@ -129,6 +129,9 @@ static void bond_info_show_master(struct seq_file *seq) - seq_printf(seq, "Min links: %d\n", bond->params.min_links); - seq_printf(seq, "Aggregator selection policy (ad_select): %s\n", - ad_select_tbl[bond->params.ad_select].modename); -+ seq_printf(seq, "System Identification: %d %pM\n", -+ BOND_AD_INFO(bond).system.sys_priority, -+ &(BOND_AD_INFO(bond).system.sys_mac_addr)); - - if (bond_3ad_get_active_agg_info(bond, &ad_info)) { - seq_printf(seq, "bond %s has no active aggregator\n", -diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c -index 67f9073..b897b7b 100644 ---- a/drivers/net/bonding/bond_sysfs.c -+++ b/drivers/net/bonding/bond_sysfs.c -@@ -1468,6 +1468,118 @@ static ssize_t bonding_show_ad_active_slaves(struct device *d, - static DEVICE_ATTR(ad_active_slaves, S_IRUGO, bonding_show_ad_active_slaves, NULL); - - /* -+ * Show and set 802.3ad system priority. -+ */ -+static ssize_t bonding_show_ad_sys_priority(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct bonding *bond = to_bond(d); -+ int count = 0; -+ -+ if (bond->params.mode == BOND_MODE_8023AD) { -+ count = sprintf(buf, "%d\n", bond->params.sys_priority); -+ } -+ -+ return count; -+} -+ -+static ssize_t bonding_store_ad_sys_priority(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ u16 new_value; -+ int ret; -+ struct bonding *bond = to_bond(d); -+ -+ if (bond->params.mode != BOND_MODE_8023AD) { -+ pr_err("%s: Unable to update sys priority because bond is not in 802.3ad mode.\n", -+ bond->dev->name); -+ ret = -EPERM; -+ goto out; -+ } -+ -+ if (!rtnl_trylock()) -+ return restart_syscall(); -+ -+ ret = kstrtou16(buf, 0, &new_value); -+ if (ret < 0) { -+ pr_err("%s: Ignoring invalid sys priority value %s.\n", -+ bond->dev->name, buf); -+ goto out_unlock; -+ } -+ ret = count; -+ -+ pr_info("%s: Setting sys priority value to %u\n", -+ bond->dev->name, new_value); -+ bond->params.sys_priority = new_value; -+ bond_3ad_update_sys_priority(bond); -+ -+out_unlock: -+ rtnl_unlock(); -+out: -+ return ret; -+} -+static DEVICE_ATTR(ad_sys_priority, S_IRUGO | S_IWUSR, -+ bonding_show_ad_sys_priority, bonding_store_ad_sys_priority); -+ -+ -+/* -+ * Show and set 802.3ad system mac address. -+ */ -+static ssize_t bonding_show_ad_sys_mac_addr(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct bonding *bond = to_bond(d); -+ int count = 0; -+ -+ if (bond->params.mode == BOND_MODE_8023AD) -+ count = sprintf(buf, "%pM\n", bond->params.sys_mac_addr); -+ -+ return count; -+} -+ -+static ssize_t bonding_store_ad_sys_mac_addr(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ int ret = count; -+ struct bonding *bond = to_bond(d); -+ u8 new_mac[ETH_ALEN]; -+ -+ if (bond->params.mode != BOND_MODE_8023AD) { -+ pr_err("%s: Unable to update sys mac because bond is not in 802.3ad mode.\n", -+ bond->dev->name); -+ ret = -EPERM; -+ goto out; -+ } -+ -+ if (!rtnl_trylock()) -+ return restart_syscall(); -+ -+ if (!mac_pton(buf, new_mac)) { -+ pr_err("%s: Ignoring invalid sys mac value %s.\n", -+ bond->dev->name, buf); -+ ret = -EINVAL; -+ goto out_unlock; -+ } -+ -+ pr_info("%s: Setting sys mac value to %pM\n", -+ bond->dev->name, new_mac); -+ memcpy(&(bond->params.sys_mac_addr), new_mac, ETH_ALEN); -+ bond_3ad_update_sys_mac_addr(bond); -+ -+out_unlock: -+ rtnl_unlock(); -+out: -+ return ret; -+} -+static DEVICE_ATTR(ad_sys_mac_addr, S_IRUGO | S_IWUSR, -+ bonding_show_ad_sys_mac_addr, bonding_store_ad_sys_mac_addr); -+ -+ -+/* - * Show the queue_ids of the slaves in the current bond. - */ - static ssize_t bonding_show_queue_id(struct device *d, -@@ -1706,6 +1818,8 @@ static struct attribute *per_bond_attrs[] = { - &dev_attr_ad_partner_key.attr, - &dev_attr_ad_partner_mac.attr, - &dev_attr_ad_active_slaves.attr, -+ &dev_attr_ad_sys_priority.attr, -+ &dev_attr_ad_sys_mac_addr.attr, - &dev_attr_queue_id.attr, - &dev_attr_all_slaves_active.attr, - &dev_attr_resend_igmp.attr, -diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h -index 387f9f6..553f3ce 100644 ---- a/drivers/net/bonding/bonding.h -+++ b/drivers/net/bonding/bonding.h -@@ -149,6 +149,8 @@ struct bond_params { - int lacp_fast; - unsigned int min_links; - int ad_select; -+ u16 sys_priority; -+ u8 sys_mac_addr[ETH_ALEN]; - char primary[IFNAMSIZ]; - int primary_reselect; - __be32 arp_targets[BOND_MAX_ARP_TARGETS]; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Add-br_multicast_start_querier.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Add-br_multicast_start_querier.patch deleted file mode 100644 index 69436cab..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Add-br_multicast_start_querier.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 748572162a2bc3ce6f0b215e25ad601c3ec33e77 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: Add br_multicast_start_querier - -This patch adds the helper br_multicast_start_querier so that -the code which starts the queriers in br_multicast_toggle can -be reused elsewhere. - -Signed-off-by: Herbert Xu -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 0e82d23..a2fb74b 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1709,9 +1709,23 @@ unlock: - return err; - } - --int br_multicast_toggle(struct net_bridge *br, unsigned long val) -+static void br_multicast_start_querier(struct net_bridge *br) - { - struct net_bridge_port *port; -+ -+ br_multicast_open(br); -+ -+ list_for_each_entry(port, &br->port_list, list) { -+ if (port->state == BR_STATE_DISABLED || -+ port->state == BR_STATE_BLOCKING) -+ continue; -+ -+ __br_multicast_enable_port(port); -+ } -+} -+ -+int br_multicast_toggle(struct net_bridge *br, unsigned long val) -+{ - int err = 0; - struct net_bridge_mdb_htable *mdb; - -@@ -1741,14 +1755,7 @@ rollback: - goto rollback; - } - -- br_multicast_open(br); -- list_for_each_entry(port, &br->port_list, list) { -- if (port->state == BR_STATE_DISABLED || -- port->state == BR_STATE_BLOCKING) -- continue; -- -- __br_multicast_enable_port(port); -- } -+ br_multicast_start_querier(br); - - unlock: - spin_unlock_bh(&br->multicast_lock); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Add-multicast_querier-toggle-and-disable-quer.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Add-multicast_querier-toggle-and-disable-quer.patch deleted file mode 100644 index 6c0bc5a4..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Add-multicast_querier-toggle-and-disable-quer.patch +++ /dev/null @@ -1,122 +0,0 @@ -From c5c23260594c5701af66ef754916775ba6a46bbc Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: Add multicast_querier toggle and disable queries by - default - -Sending general queries was implemented as an optimisation to speed -up convergence on start-up. In order to prevent interference with -multicast routers a zero source address has to be used. - -Unfortunately these packets appear to cause some multicast-aware -switches to misbehave, e.g., by disrupting multicast packets to us. - -Since the multicast snooping feature still functions without sending -our own queries, this patch will change the default to not send -queries. - -For those that need queries in order to speed up convergence on start-up, -a toggle is provided to restore the previous behaviour. - -Signed-off-by: Herbert Xu -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 36c9721..3885e4d 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -793,6 +793,7 @@ static void br_multicast_send_query(struct net_bridge *br, - struct br_ip br_group; - - if (!netif_running(br->dev) || br->multicast_disabled || -+ !br->multicast_querier || - timer_pending(&br->multicast_querier_timer)) - return; - -@@ -1584,6 +1585,7 @@ void br_multicast_init(struct net_bridge *br) - br->hash_max = 512; - - br->multicast_router = 1; -+ br->multicast_querier = 0; - br->multicast_last_member_count = 2; - br->multicast_startup_query_count = 2; - -@@ -1781,6 +1783,24 @@ unlock: - return err; - } - -+int br_multicast_set_querier(struct net_bridge *br, unsigned long val) -+{ -+ val = !!val; -+ -+ spin_lock_bh(&br->multicast_lock); -+ if (br->multicast_querier == val) -+ goto unlock; -+ -+ br->multicast_querier = val; -+ if (val) -+ br_multicast_start_querier(br); -+ -+unlock: -+ spin_unlock_bh(&br->multicast_lock); -+ -+ return 0; -+} -+ - int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val) - { - int err = -ENOENT; -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 5f28201..6f48a78 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -229,6 +229,7 @@ struct net_bridge - unsigned char multicast_router; - - u8 multicast_disabled:1; -+ u8 multicast_querier:1; - - u32 hash_elasticity; - u32 hash_max; -@@ -432,6 +433,7 @@ extern int br_multicast_set_router(struct net_bridge *br, unsigned long val); - extern int br_multicast_set_port_router(struct net_bridge_port *p, - unsigned long val); - extern int br_multicast_toggle(struct net_bridge *br, unsigned long val); -+extern int br_multicast_set_querier(struct net_bridge *br, unsigned long val); - extern int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val); - extern struct net_bridge_mdb_entry *br_mdb_ip_get( - struct net_bridge_mdb_htable *mdb, -diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c -index c236c0e..a27243e 100644 ---- a/net/bridge/br_sysfs_br.c -+++ b/net/bridge/br_sysfs_br.c -@@ -379,6 +379,23 @@ static ssize_t store_multicast_snooping(struct device *d, - static DEVICE_ATTR(multicast_snooping, S_IRUGO | S_IWUSR, - show_multicast_snooping, store_multicast_snooping); - -+static ssize_t show_multicast_querier(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct net_bridge *br = to_bridge(d); -+ return sprintf(buf, "%d\n", br->multicast_querier); -+} -+ -+static ssize_t store_multicast_querier(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ return store_bridge_parm(d, buf, len, br_multicast_set_querier); -+} -+static DEVICE_ATTR(multicast_querier, S_IRUGO | S_IWUSR, -+ show_multicast_querier, store_multicast_querier); -+ - static ssize_t show_hash_elasticity(struct device *d, - struct device_attribute *attr, char *buf) - { -@@ -702,6 +719,7 @@ static struct attribute *bridge_attrs[] = { - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - &dev_attr_multicast_router.attr, - &dev_attr_multicast_snooping.attr, -+ &dev_attr_multicast_querier.attr, - &dev_attr_hash_elasticity.attr, - &dev_attr_hash_max.attr, - &dev_attr_multicast_last_member_count.attr, diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Correctly-encode-addresses-when-dumping-mdb-e.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Correctly-encode-addresses-when-dumping-mdb-e.patch deleted file mode 100644 index 6f6b8cba..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Correctly-encode-addresses-when-dumping-mdb-e.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 09d7cf7d931c627b227decd080f4528d003ddbe6 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: Correctly encode addresses when dumping mdb entries - -When dumping mdb table, set the addresses the kernel returns -based on the address protocol type. - -Signed-off-by: Vlad Yasevich -Acked-by: Cong Wang -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index 01ad6a1..28425d7 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -84,9 +84,11 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, - struct br_mdb_entry e; - e.ifindex = port->dev->ifindex; - e.state = p->state; -- e.addr.u.ip4 = p->addr.u.ip4; -+ if (p->addr.proto == htons(ETH_P_IP)) -+ e.addr.u.ip4 = p->addr.u.ip4; - #if IS_ENABLED(CONFIG_IPV6) -- e.addr.u.ip6 = p->addr.u.ip6; -+ if (p->addr.proto == htons(ETH_P_IPV6)) -+ e.addr.u.ip6 = p->addr.u.ip6; - #endif - e.addr.proto = p->addr.proto; - if (nla_put(skb, MDBA_MDB_ENTRY_INFO, sizeof(e), &e)) { diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Correctly-unregister-MDB-rtnetlink-handlers.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Correctly-unregister-MDB-rtnetlink-handlers.patch deleted file mode 100644 index 52aba010..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Correctly-unregister-MDB-rtnetlink-handlers.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 3ec8e9f085bcaef0de1077f555c2c5102c223390 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: Correctly unregister MDB rtnetlink handlers - -Commit 63233159fd4e596568f5f168ecb0879b61631d47: - bridge: Do not unregister all PF_BRIDGE rtnl operations -introduced a bug where a removal of a single bridge from a -multi-bridge system would remove MDB netlink handlers. -The handlers should only be removed once all bridges are gone, but -since we don't keep track of the number of bridge interfaces, it's -simpler to do it when the bridge module is unloaded. To make it -consistent, move the registration code into module initialization -code path. - -Signed-off-by: Vlad Yasevich -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 587c1cc..0e82d23 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1583,7 +1583,6 @@ void br_multicast_init(struct net_bridge *br) - br_multicast_local_router_expired, 0); - setup_timer(&br->multicast_query_timer, br_multicast_query_expired, - (unsigned long)br); -- br_mdb_init(); - } - - void br_multicast_open(struct net_bridge *br) -@@ -1608,7 +1607,6 @@ void br_multicast_stop(struct net_bridge *br) - del_timer_sync(&br->multicast_querier_timer); - del_timer_sync(&br->multicast_query_timer); - -- br_mdb_uninit(); - spin_lock_bh(&br->multicast_lock); - mdb = mlock_dereference(br->mdb, br); - if (!mdb) -diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c -index c3b04d3..47f5f56 100644 ---- a/net/bridge/br_netlink.c -+++ b/net/bridge/br_netlink.c -@@ -237,6 +237,7 @@ int __init br_netlink_init(void) - { - int err; - -+ br_mdb_init(); - err = rtnl_link_register(&br_link_ops); - if (err < 0) - goto err1; -@@ -257,6 +258,7 @@ err3: - err2: - rtnl_link_unregister(&br_link_ops); - err1: -+ br_mdb_uninit(); - return err; - } - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Do-not-unregister-all-PF_BRIDGE-rtnl-operatio.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Do-not-unregister-all-PF_BRIDGE-rtnl-operatio.patch deleted file mode 100644 index a9642402..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Do-not-unregister-all-PF_BRIDGE-rtnl-operatio.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 63233159fd4e596568f5f168ecb0879b61631d47 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: Do not unregister all PF_BRIDGE rtnl operations - -Bridge fdb and link rtnl operations are registered in -core/rtnetlink. Bridge mdb operations are registred -in bridge/mdb. When removing bridge module, do not -unregister ALL PF_BRIDGE ops since that would remove -the ops from rtnetlink as well. Do remove mdb ops when -bridge is destroyed. - -Signed-off-by: Vlad Yasevich -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index fc96d5c..01ad6a1 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -482,3 +482,10 @@ void br_mdb_init(void) - rtnl_register(PF_BRIDGE, RTM_NEWMDB, br_mdb_add, NULL, NULL); - rtnl_register(PF_BRIDGE, RTM_DELMDB, br_mdb_del, NULL, NULL); - } -+ -+void br_mdb_uninit(void) -+{ -+ rtnl_unregister(PF_BRIDGE, RTM_GETMDB); -+ rtnl_unregister(PF_BRIDGE, RTM_NEWMDB); -+ rtnl_unregister(PF_BRIDGE, RTM_DELMDB); -+} -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index c347e2f..7322157 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1603,6 +1603,7 @@ void br_multicast_stop(struct net_bridge *br) - del_timer_sync(&br->multicast_querier_timer); - del_timer_sync(&br->multicast_query_timer); - -+ br_mdb_uninit(); - spin_lock_bh(&br->multicast_lock); - mdb = mlock_dereference(br->mdb, br); - if (!mdb) -diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c -index 9c318a5..c3b04d3 100644 ---- a/net/bridge/br_netlink.c -+++ b/net/bridge/br_netlink.c -@@ -263,5 +263,4 @@ err1: - void __exit br_netlink_fini(void) - { - rtnl_link_unregister(&br_link_ops); -- rtnl_unregister_all(PF_BRIDGE); - } -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index bc9d922..f334219 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -445,6 +445,7 @@ extern struct net_bridge_port_group *br_multicast_new_port_group( - struct net_bridge_port_group __rcu *next, - unsigned char state); - extern void br_mdb_init(void); -+extern void br_mdb_uninit(void); - extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, - struct br_ip *group, int type); - -@@ -523,6 +524,12 @@ static inline bool br_multicast_is_router(struct net_bridge *br) - { - return 0; - } -+static inline void br_mdb_init(void) -+{ -+} -+static inline void br_mdb_uninit(void) -+{ -+} - #endif - - /* br_netfilter.c */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Fix-fatal-typo-in-setup-of-multicast_querier_.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Fix-fatal-typo-in-setup-of-multicast_querier_.patch deleted file mode 100644 index 27422e17..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Fix-fatal-typo-in-setup-of-multicast_querier_.patch +++ /dev/null @@ -1,36 +0,0 @@ -From bb63f1f8a08cf8028564ad04831ebd7a8ffb9cba Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: Fix fatal typo in setup of multicast_querier_expired - -Unfortunately it seems that I didn't properly test the case of -an expired external querier in the recent multicast bridge series. - -The setup of the timer in that case is completely broken and leads -to a NULL-pointer dereference. This patch fixes it. - -Signed-off-by: Herbert Xu -Acked-by: Stephen Hemminger -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 3885e4d..bb0d898 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -754,8 +754,7 @@ static void br_multicast_local_router_expired(unsigned long data) - - static void br_multicast_querier_expired(unsigned long data) - { -- struct net_bridge_port *port = (void *)data; -- struct net_bridge *br = port->br; -+ struct net_bridge *br = (void *)data; - - spin_lock(&br->multicast_lock); - if (!netif_running(br->dev) || br->multicast_disabled) -@@ -1600,7 +1599,7 @@ void br_multicast_init(struct net_bridge *br) - setup_timer(&br->multicast_router_timer, - br_multicast_local_router_expired, 0); - setup_timer(&br->multicast_querier_timer, -- br_multicast_querier_expired, 0); -+ br_multicast_querier_expired, (unsigned long)br); - setup_timer(&br->multicast_query_timer, br_multicast_query_expired, - (unsigned long)br); - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Restart-queries-when-last-querier-expires.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Restart-queries-when-last-querier-expires.patch deleted file mode 100644 index 657307c5..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-Restart-queries-when-last-querier-expires.patch +++ /dev/null @@ -1,59 +0,0 @@ -From c83b8fab06fc8c80d6440649f117bb7541df5fd0 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: Restart queries when last querier expires - -As it stands when we discover that a real querier (one that queries -with a non-zero source address) we stop querying. However, even -after said querier has fallen off the edge of the earth, we will -never restart querying (unless the bridge itself is restarted). - -This patch fixes this by kicking our own querier into gear when -the timer for other queriers expire. - -Signed-off-by: Herbert Xu -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index a2fb74b..36c9721 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -35,6 +35,9 @@ - - #define mlock_dereference(X, br) \ - rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) -+ -+static void br_multicast_start_querier(struct net_bridge *br); -+ - unsigned int br_mdb_rehash_seq; - - static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b) -@@ -749,6 +752,21 @@ static void br_multicast_local_router_expired(unsigned long data) - { - } - -+static void br_multicast_querier_expired(unsigned long data) -+{ -+ struct net_bridge_port *port = (void *)data; -+ struct net_bridge *br = port->br; -+ -+ spin_lock(&br->multicast_lock); -+ if (!netif_running(br->dev) || br->multicast_disabled) -+ goto out; -+ -+ br_multicast_start_querier(br); -+ -+out: -+ spin_unlock(&br->multicast_lock); -+} -+ - static void __br_multicast_send_query(struct net_bridge *br, - struct net_bridge_port *port, - struct br_ip *ip) -@@ -1580,7 +1598,7 @@ void br_multicast_init(struct net_bridge *br) - setup_timer(&br->multicast_router_timer, - br_multicast_local_router_expired, 0); - setup_timer(&br->multicast_querier_timer, -- br_multicast_local_router_expired, 0); -+ br_multicast_querier_expired, 0); - setup_timer(&br->multicast_query_timer, br_multicast_query_expired, - (unsigned long)br); - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-add-flags-to-distinguish-permanent-mdb-entire.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-add-flags-to-distinguish-permanent-mdb-entire.patch deleted file mode 100644 index 7c69f925..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-add-flags-to-distinguish-permanent-mdb-entire.patch +++ /dev/null @@ -1,112 +0,0 @@ -From ccb1c31a7a8744cd153a7d92b726a56b56ad61d3 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: add flags to distinguish permanent mdb entires - -This patch adds a flag to each mdb entry, so that we can distinguish -permanent entries with temporary entries. - -Cc: Herbert Xu -Cc: Stephen Hemminger -Cc: "David S. Miller" -Signed-off-by: Cong Wang -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index 2f9bb86..fc96d5c 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -83,6 +83,7 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, - if (port) { - struct br_mdb_entry e; - e.ifindex = port->dev->ifindex; -+ e.state = p->state; - e.addr.u.ip4 = p->addr.u.ip4; - #if IS_ENABLED(CONFIG_IPV6) - e.addr.u.ip6 = p->addr.u.ip6; -@@ -253,6 +254,8 @@ static bool is_valid_mdb_entry(struct br_mdb_entry *entry) - #endif - } else - return false; -+ if (entry->state != MDB_PERMANENT && entry->state != MDB_TEMPORARY) -+ return false; - - return true; - } -@@ -310,7 +313,7 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh, - } - - static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, -- struct br_ip *group) -+ struct br_ip *group, unsigned char state) - { - struct net_bridge_mdb_entry *mp; - struct net_bridge_port_group *p; -@@ -336,7 +339,7 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, - break; - } - -- p = br_multicast_new_port_group(port, group, *pp); -+ p = br_multicast_new_port_group(port, group, *pp, state); - if (unlikely(!p)) - return -ENOMEM; - rcu_assign_pointer(*pp, p); -@@ -373,7 +376,7 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br, - #endif - - spin_lock_bh(&br->multicast_lock); -- ret = br_mdb_add_group(br, p, &ip); -+ ret = br_mdb_add_group(br, p, &ip, entry->state); - spin_unlock_bh(&br->multicast_lock); - return ret; - } -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index a8cad95..c347e2f 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -281,7 +281,7 @@ static void br_multicast_port_group_expired(unsigned long data) - - spin_lock(&br->multicast_lock); - if (!netif_running(br->dev) || timer_pending(&pg->timer) || -- hlist_unhashed(&pg->mglist)) -+ hlist_unhashed(&pg->mglist) || pg->state & MDB_PERMANENT) - goto out; - - br_multicast_del_pg(br, pg); -@@ -624,7 +624,8 @@ out: - struct net_bridge_port_group *br_multicast_new_port_group( - struct net_bridge_port *port, - struct br_ip *group, -- struct net_bridge_port_group *next) -+ struct net_bridge_port_group *next, -+ unsigned char state) - { - struct net_bridge_port_group *p; - -@@ -634,6 +635,7 @@ struct net_bridge_port_group *br_multicast_new_port_group( - - p->addr = *group; - p->port = port; -+ p->state = state; - p->next = next; - hlist_add_head(&p->mglist, &port->mglist); - setup_timer(&p->timer, br_multicast_port_group_expired, -@@ -676,7 +678,7 @@ static int br_multicast_add_group(struct net_bridge *br, - break; - } - -- p = br_multicast_new_port_group(port, group, *pp); -+ p = br_multicast_new_port_group(port, group, *pp, MDB_TEMPORARY); - if (unlikely(!p)) - goto err; - rcu_assign_pointer(*pp, p); -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index ceb7ed6..bc9d922 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -83,6 +83,7 @@ struct net_bridge_port_group { - struct rcu_head rcu; - struct timer_list timer; - struct br_ip addr; -+ unsigned char state; - }; - - struct net_bridge_mdb_entry diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-add-per-vlan-igmp-querier-support.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-add-per-vlan-igmp-querier-support.patch deleted file mode 100644 index 8ad7be28..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-add-per-vlan-igmp-querier-support.patch +++ /dev/null @@ -1,411 +0,0 @@ -Add support for configuring igmp querier on a per vlan basis including -enabling/disabling querier and setting querier ip address. - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 0047db7..d72456e 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -370,15 +370,22 @@ out: - } - - static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br, -- __be32 group) -+ __be32 group, -+ __u16 vid, -+ bool tagged) - { - struct sk_buff *skb; - struct igmphdr *ih; - struct ethhdr *eth; - struct iphdr *iph; -+ int vh_size = 0; -+ -+ /* if vid is non-zero, insert the 1Q header also */ -+ if (vid && tagged) -+ vh_size = sizeof(struct vlan_hdr); - - skb = netdev_alloc_skb_ip_align(br->dev, sizeof(*eth) + sizeof(*iph) + -- sizeof(*ih) + 4); -+ vh_size + sizeof(*ih) + 4); - if (!skb) - goto out; - -@@ -397,6 +404,14 @@ static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br, - eth->h_proto = htons(ETH_P_IP); - skb_put(skb, sizeof(*eth)); - -+ if (vid && tagged) { -+ skb = vlan_put_tag(skb, vid); -+ if (!skb) { -+ pr_err("Error: failed to insert VLAN tag\n"); -+ return NULL; -+ } -+ } -+ - skb_set_network_header(skb, skb->len); - iph = ip_hdr(skb); - -@@ -408,8 +423,18 @@ static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br, - iph->frag_off = htons(IP_DF); - iph->ttl = 1; - iph->protocol = IPPROTO_IGMP; -- iph->saddr = br->multicast_query_use_ifaddr ? -- inet_dev_select_addr(br->dev, 0, RT_SCOPE_LINK) : 0; -+ if (vid == 0) { -+ iph->saddr = br->multicast_query_use_ifaddr ? -+ inet_dev_select_addr(br->dev, 0, RT_SCOPE_LINK) : 0; -+ } else { -+ struct bridge_mcast_querier_src *s; -+ list_for_each_entry(s, &br->ip4_querier.vlist, list) { -+ if (vid == s->src.vid) { -+ iph->saddr = htonl(s->src.u.ip4); -+ break; -+ } -+ } -+ } - iph->daddr = htonl(INADDR_ALLHOSTS_GROUP); - ((u8 *)&iph[1])[0] = IPOPT_RA; - ((u8 *)&iph[1])[1] = 4; -@@ -437,7 +462,9 @@ out: - - #if IS_ENABLED(CONFIG_IPV6) - static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, -- const struct in6_addr *group) -+ const struct in6_addr *group, -+ __u16 vid, -+ bool tagged) - { - struct sk_buff *skb; - struct ipv6hdr *ip6h; -@@ -446,8 +473,9 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, - u8 *hopopt; - unsigned long interval; - -- skb = netdev_alloc_skb_ip_align(br->dev, sizeof(*eth) + sizeof(*ip6h) + -- 8 + sizeof(*mldq)); -+ /* TBD: if vid is non-zero, insert a 1Q header */ -+ skb = netdev_alloc_skb_ip_align(br->dev, sizeof(*eth) + -+ sizeof(*ip6h) + 8 + sizeof(*mldq)); - if (!skb) - goto out; - -@@ -519,14 +547,17 @@ out: - #endif - - static struct sk_buff *br_multicast_alloc_query(struct net_bridge *br, -- struct br_ip *addr) -+ struct br_ip *addr, -+ bool tagged) - { - switch (addr->proto) { - case htons(ETH_P_IP): -- return br_ip4_multicast_alloc_query(br, addr->u.ip4); -+ return br_ip4_multicast_alloc_query(br, addr->u.ip4, addr->vid, -+ tagged); - #if IS_ENABLED(CONFIG_IPV6) - case htons(ETH_P_IPV6): -- return br_ip6_multicast_alloc_query(br, &addr->u.ip6); -+ return br_ip6_multicast_alloc_query(br, &addr->u.ip6, addr->vid, -+ tagged); - #endif - } - return NULL; -@@ -821,8 +852,15 @@ static void __br_multicast_send_query(struct net_bridge *br, - struct br_ip *ip) - { - struct sk_buff *skb; -+ bool tagged = false; - -- skb = br_multicast_alloc_query(br, ip); -+ if (port && ip->vid) { -+ if (!br->vlan_enabled || !nbp_vlan_find(port, ip->vid)) -+ return; -+ if (br_get_pvid(nbp_get_vlan_info(port)) != ip->vid) -+ tagged = true; -+ } -+ skb = br_multicast_alloc_query(br, ip, tagged); - if (!skb) - return; - -@@ -842,6 +880,8 @@ static void br_multicast_send_query(struct net_bridge *br, - unsigned long time; - struct br_ip br_group; - struct bridge_mcast_querier *querier = NULL; -+ struct bridge_mcast_querier_src *s; -+ int num_vlans = 0; - - if (!netif_running(br->dev) || br->multicast_disabled || - !br->multicast_querier) -@@ -863,7 +903,18 @@ static void br_multicast_send_query(struct net_bridge *br, - if (!querier || timer_pending(&querier->timer)) - return; - -- __br_multicast_send_query(br, port, &br_group); -+ if (br->vlan_enabled) { -+ /* for each vlan in the list, populate the br_group.vid -+ * and send a query -+ */ -+ list_for_each_entry(s, &querier->vlist, list) { -+ br_group.vid = s->src.vid; -+ __br_multicast_send_query(br, port, &br_group); -+ num_vlans++; -+ } -+ } -+ if (!br->vlan_enabled || num_vlans == 0) -+ __br_multicast_send_query(br, port, &br_group); - - time = jiffies; - time += query->startup_sent < br->multicast_startup_query_count ? -@@ -1399,6 +1450,9 @@ static void br_multicast_leave_group(struct net_bridge *br, - time = jiffies + br->multicast_last_member_count * - br->multicast_last_member_interval; - -+ /* Need to either maintain per vlan timer, or merge -+ * the time out -+ */ - mod_timer(&query->timer, time); - - for (p = mlock_dereference(mp->ports, br); -@@ -1803,6 +1857,8 @@ void br_multicast_init(struct net_bridge *br) - #if IS_ENABLED(CONFIG_IPV6) - br->ip6_querier.delay_time = 0; - #endif -+ INIT_LIST_HEAD(&br->ip4_querier.vlist); -+ INIT_LIST_HEAD(&br->ip6_querier.vlist); - - spin_lock_init(&br->multicast_lock); - setup_timer(&br->multicast_router_timer, -@@ -1854,10 +1910,21 @@ void br_multicast_dev_del(struct net_bridge *br) - struct net_bridge_mdb_htable *mdb; - struct net_bridge_mdb_entry *mp; - struct hlist_node *p, *n; -+ struct bridge_mcast_querier_src *ms, *mn; - u32 ver; - int i; - - spin_lock_bh(&br->multicast_lock); -+ /* delete the querier lists */ -+ list_for_each_entry_safe(ms, mn, &br->ip4_querier.vlist, list) { -+ list_del(&ms->list); -+ kfree(ms); -+ } -+ list_for_each_entry_safe(ms, mn, &br->ip6_querier.vlist, list) { -+ list_del(&ms->list); -+ kfree(ms); -+ } -+ - mdb = mlock_dereference(br->mdb, br); - if (!mdb) - goto out; -@@ -2113,3 +2180,58 @@ unlock: - - return err; - } -+ -+int br_multicast_add_querier_src(struct net_bridge *br, -+ struct br_ip *src) -+{ -+ struct bridge_mcast_querier_src *s; -+ int res = 1; -+ -+ spin_lock_bh(&br->multicast_lock); -+ if (src->proto == ETH_P_IP) { -+ list_for_each_entry(s, &br->ip4_querier.vlist, list) { -+ if (s->src.vid == src->vid) { -+ s->src.u.ip4 = src->u.ip4; -+ goto out; -+ } -+ } -+ s = kzalloc(sizeof(struct bridge_mcast_querier_src), GFP_ATOMIC); -+ if (!s) { -+ res = -ENOMEM; -+ goto out; -+ } -+ -+ s->src.u.ip4 = src->u.ip4; -+ s->src.proto = src->proto; -+ s->src.vid = src->vid; -+ list_add(&s->list, &br->ip4_querier.vlist); -+ -+ // not doing start_querier since each time we send -+ // on all vlans in the querier list, it will be unscalable -+ //br_multicast_start_querier(br, &br->ip4_query); -+ } -+out: -+ spin_unlock_bh(&br->multicast_lock); -+ return res; -+} -+ -+int br_multicast_del_querier_src(struct net_bridge *br, -+ struct br_ip *src) -+{ -+ struct bridge_mcast_querier_src *s; -+ int res = 1; -+ -+ spin_lock_bh(&br->multicast_lock); -+ if (src->proto == ETH_P_IP) { -+ list_for_each_entry(s, &br->ip4_querier.vlist, list) { -+ if (s->src.vid == src->vid) { -+ list_del(&s->list); -+ kfree(s); -+ goto out; -+ } -+ } -+ } -+out: -+ spin_unlock_bh(&br->multicast_lock); -+ return res; -+} -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 8f5273d..30ff5e1 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -73,10 +73,17 @@ struct bridge_mcast_query { - u32 startup_sent; - }; - -+struct bridge_mcast_querier_src { -+ struct list_head list; -+ struct br_ip src; -+}; -+ - /* other querier */ - struct bridge_mcast_querier { - struct timer_list timer; - unsigned long delay_time; -+ struct rcu_head rcu; -+ struct list_head vlist; - }; - #endif - -@@ -511,6 +518,12 @@ static inline bool br_multicast_querier_exists(struct net_bridge *br, - return false; - } - } -+ -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+int br_multicast_add_querier_src(struct net_bridge *br, struct br_ip *src); -+int br_multicast_del_querier_src(struct net_bridge *br, struct br_ip *src); -+#endif -+ - #else - static inline int br_multicast_rcv(struct net_bridge *br, - struct net_bridge_port *port, -diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c -index 951447a..e2e953a 100644 ---- a/net/bridge/br_sysfs_br.c -+++ b/net/bridge/br_sysfs_br.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - - #include "br_private.h" - -@@ -390,6 +391,95 @@ multicast_query_use_ifaddr_store(struct device *d, - } - static DEVICE_ATTR_RW(multicast_query_use_ifaddr); - -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+static ssize_t multicast_v4_queriers_show(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct bridge_mcast_querier_src *s; -+ struct net_bridge *br = to_bridge(d); -+ ssize_t len = 0; -+ -+ list_for_each_entry(s, &br->ip4_querier.vlist, list) { -+ len += sprintf(buf + len, "%d=%d.%d.%d.%d\n", s->src.vid, -+ (s->src.u.ip4 >> 24) & 0xFF, (s->src.u.ip4 >> 16) & 0xFF, -+ (s->src.u.ip4 >> 8) & 0xFF, (s->src.u.ip4) & 0xFF); -+ } -+ return len; -+} -+ -+static ssize_t -+multicast_v4_queriers_store(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ char vlan_info[128] = { 0, }; -+ struct net_bridge *br = to_bridge(d); -+ char *vp = NULL, *ip = NULL; -+ struct br_ip src; -+ int src_ip[4]; -+ int res = 0; -+ -+ if (!rtnl_trylock()) -+ return restart_syscall(); -+ -+ memset(&src, 0, sizeof(src)); -+ src.proto = ETH_P_IP; -+ sscanf(buf, "%s", vlan_info); -+ vp = &vlan_info[1]; -+ ip = strchr(vp, '='); -+ if (ip) { -+ *ip = '\0'; -+ ip++; -+ } -+ if ((kstrtou16(vp, 10, &src.vid) != 0) || (src.vid >= VLAN_N_VID)) { -+ res = -EINVAL; -+ goto out; -+ } -+ -+ switch (vlan_info[0]) { -+ case '+': -+ if (!ip) -+ src.u.ip4 = 0; -+ else if (sscanf(ip, "%d.%d.%d.%d", -+ &src_ip[0], &src_ip[1], &src_ip[2], &src_ip[3]) != 4) { -+ res = -EINVAL; -+ goto out; -+ } else { -+ src.u.ip4 = ((src_ip[0] & 0xFF) << 24) + -+ ((src_ip[1] & 0xFF) << 16) + -+ ((src_ip[2] & 0xFF) << 8) + -+ (src_ip[3] & 0xFF); -+ if (ipv4_is_multicast(src.u.ip4) || -+ ipv4_is_lbcast(src.u.ip4)) { -+ res = -EINVAL; -+ goto out; -+ } -+ } -+ res = br_multicast_add_querier_src(br, &src); -+ break; -+ case '-': -+ res = br_multicast_del_querier_src(br, &src); -+ break; -+ default: -+ goto err_no_cmd; -+ } -+ -+ if (res == 1) -+ goto out; -+err_no_cmd: -+ res = -EPERM; -+out: -+ rtnl_unlock(); -+ if (res == 1) -+ return len; -+ else -+ return res; -+} -+ -+static DEVICE_ATTR_RW(multicast_v4_queriers); -+#endif -+ - static ssize_t multicast_querier_show(struct device *d, - struct device_attribute *attr, - char *buf) -@@ -727,6 +817,9 @@ static struct attribute *bridge_attrs[] = { - &dev_attr_multicast_snooping.attr, - &dev_attr_multicast_querier.attr, - &dev_attr_multicast_query_use_ifaddr.attr, -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ &dev_attr_multicast_v4_queriers.attr, -+#endif - &dev_attr_hash_elasticity.attr, - &dev_attr_hash_max.attr, - &dev_attr_multicast_last_member_count.attr, diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-add-support-of-adding-and-deleting-mdb-entrie.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-add-support-of-adding-and-deleting-mdb-entrie.patch deleted file mode 100644 index b77977ad..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-add-support-of-adding-and-deleting-mdb-entrie.patch +++ /dev/null @@ -1,410 +0,0 @@ -From cfd567543590f71ca0af397437e2554f9756d750 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: add support of adding and deleting mdb entries - -This patch implents adding/deleting mdb entries via netlink. -Currently all entries are temp, we probably need a flag to distinguish -permanent entries too. - -Cc: Herbert Xu -Cc: Stephen Hemminger -Cc: "David S. Miller" -Cc: Thomas Graf -Signed-off-by: Cong Wang -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index 7add2cf..2f9bb86 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -4,6 +4,7 @@ - #include - #include - #include -+#include - #include - #include - #if IS_ENABLED(CONFIG_IPV6) -@@ -235,7 +236,246 @@ void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, - __br_mdb_notify(dev, &entry, type); - } - -+static bool is_valid_mdb_entry(struct br_mdb_entry *entry) -+{ -+ if (entry->ifindex == 0) -+ return false; -+ -+ if (entry->addr.proto == htons(ETH_P_IP)) { -+ if (!ipv4_is_multicast(entry->addr.u.ip4)) -+ return false; -+ if (ipv4_is_local_multicast(entry->addr.u.ip4)) -+ return false; -+#if IS_ENABLED(CONFIG_IPV6) -+ } else if (entry->addr.proto == htons(ETH_P_IPV6)) { -+ if (!ipv6_is_transient_multicast(&entry->addr.u.ip6)) -+ return false; -+#endif -+ } else -+ return false; -+ -+ return true; -+} -+ -+static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh, -+ struct net_device **pdev, struct br_mdb_entry **pentry) -+{ -+ struct net *net = sock_net(skb->sk); -+ struct br_mdb_entry *entry; -+ struct br_port_msg *bpm; -+ struct nlattr *tb[MDBA_SET_ENTRY_MAX+1]; -+ struct net_device *dev; -+ int err; -+ -+ if (!capable(CAP_NET_ADMIN)) -+ return -EPERM; -+ -+ err = nlmsg_parse(nlh, sizeof(*bpm), tb, MDBA_SET_ENTRY, NULL); -+ if (err < 0) -+ return err; -+ -+ bpm = nlmsg_data(nlh); -+ if (bpm->ifindex == 0) { -+ pr_info("PF_BRIDGE: br_mdb_parse() with invalid ifindex\n"); -+ return -EINVAL; -+ } -+ -+ dev = __dev_get_by_index(net, bpm->ifindex); -+ if (dev == NULL) { -+ pr_info("PF_BRIDGE: br_mdb_parse() with unknown ifindex\n"); -+ return -ENODEV; -+ } -+ -+ if (!(dev->priv_flags & IFF_EBRIDGE)) { -+ pr_info("PF_BRIDGE: br_mdb_parse() with non-bridge\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ *pdev = dev; -+ -+ if (!tb[MDBA_SET_ENTRY] || -+ nla_len(tb[MDBA_SET_ENTRY]) != sizeof(struct br_mdb_entry)) { -+ pr_info("PF_BRIDGE: br_mdb_parse() with invalid attr\n"); -+ return -EINVAL; -+ } -+ -+ entry = nla_data(tb[MDBA_SET_ENTRY]); -+ if (!is_valid_mdb_entry(entry)) { -+ pr_info("PF_BRIDGE: br_mdb_parse() with invalid entry\n"); -+ return -EINVAL; -+ } -+ -+ *pentry = entry; -+ return 0; -+} -+ -+static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, -+ struct br_ip *group) -+{ -+ struct net_bridge_mdb_entry *mp; -+ struct net_bridge_port_group *p; -+ struct net_bridge_port_group __rcu **pp; -+ struct net_bridge_mdb_htable *mdb; -+ int err; -+ -+ mdb = mlock_dereference(br->mdb, br); -+ mp = br_mdb_ip_get(mdb, group); -+ if (!mp) { -+ mp = br_multicast_new_group(br, port, group); -+ err = PTR_ERR(mp); -+ if (IS_ERR(mp)) -+ return err; -+ } -+ -+ for (pp = &mp->ports; -+ (p = mlock_dereference(*pp, br)) != NULL; -+ pp = &p->next) { -+ if (p->port == port) -+ return -EEXIST; -+ if ((unsigned long)p->port < (unsigned long)port) -+ break; -+ } -+ -+ p = br_multicast_new_port_group(port, group, *pp); -+ if (unlikely(!p)) -+ return -ENOMEM; -+ rcu_assign_pointer(*pp, p); -+ -+ br_mdb_notify(br->dev, port, group, RTM_NEWMDB); -+ return 0; -+} -+ -+static int __br_mdb_add(struct net *net, struct net_bridge *br, -+ struct br_mdb_entry *entry) -+{ -+ struct br_ip ip; -+ struct net_device *dev; -+ struct net_bridge_port *p; -+ int ret; -+ -+ if (!netif_running(br->dev) || br->multicast_disabled) -+ return -EINVAL; -+ -+ dev = __dev_get_by_index(net, entry->ifindex); -+ if (!dev) -+ return -ENODEV; -+ -+ p = br_port_get_rtnl(dev); -+ if (!p || p->br != br || p->state == BR_STATE_DISABLED) -+ return -EINVAL; -+ -+ ip.proto = entry->addr.proto; -+ if (ip.proto == htons(ETH_P_IP)) -+ ip.u.ip4 = entry->addr.u.ip4; -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ ip.u.ip6 = entry->addr.u.ip6; -+#endif -+ -+ spin_lock_bh(&br->multicast_lock); -+ ret = br_mdb_add_group(br, p, &ip); -+ spin_unlock_bh(&br->multicast_lock); -+ return ret; -+} -+ -+static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) -+{ -+ struct net *net = sock_net(skb->sk); -+ struct br_mdb_entry *entry; -+ struct net_device *dev; -+ struct net_bridge *br; -+ int err; -+ -+ err = br_mdb_parse(skb, nlh, &dev, &entry); -+ if (err < 0) -+ return err; -+ -+ br = netdev_priv(dev); -+ -+ err = __br_mdb_add(net, br, entry); -+ if (!err) -+ __br_mdb_notify(dev, entry, RTM_NEWMDB); -+ return err; -+} -+ -+static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry) -+{ -+ struct net_bridge_mdb_htable *mdb; -+ struct net_bridge_mdb_entry *mp; -+ struct net_bridge_port_group *p; -+ struct net_bridge_port_group __rcu **pp; -+ struct br_ip ip; -+ int err = -EINVAL; -+ -+ if (!netif_running(br->dev) || br->multicast_disabled) -+ return -EINVAL; -+ -+ if (timer_pending(&br->multicast_querier_timer)) -+ return -EBUSY; -+ -+ ip.proto = entry->addr.proto; -+ if (ip.proto == htons(ETH_P_IP)) -+ ip.u.ip4 = entry->addr.u.ip4; -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ ip.u.ip6 = entry->addr.u.ip6; -+#endif -+ -+ spin_lock_bh(&br->multicast_lock); -+ mdb = mlock_dereference(br->mdb, br); -+ -+ mp = br_mdb_ip_get(mdb, &ip); -+ if (!mp) -+ goto unlock; -+ -+ for (pp = &mp->ports; -+ (p = mlock_dereference(*pp, br)) != NULL; -+ pp = &p->next) { -+ if (!p->port || p->port->dev->ifindex != entry->ifindex) -+ continue; -+ -+ if (p->port->state == BR_STATE_DISABLED) -+ goto unlock; -+ -+ rcu_assign_pointer(*pp, p->next); -+ hlist_del_init(&p->mglist); -+ del_timer(&p->timer); -+ call_rcu_bh(&p->rcu, br_multicast_free_pg); -+ err = 0; -+ -+ if (!mp->ports && !mp->mglist && -+ netif_running(br->dev)) -+ mod_timer(&mp->timer, jiffies); -+ break; -+ } -+ -+unlock: -+ spin_unlock_bh(&br->multicast_lock); -+ return err; -+} -+ -+static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) -+{ -+ struct net_device *dev; -+ struct br_mdb_entry *entry; -+ struct net_bridge *br; -+ int err; -+ -+ err = br_mdb_parse(skb, nlh, &dev, &entry); -+ if (err < 0) -+ return err; -+ -+ br = netdev_priv(dev); -+ -+ err = __br_mdb_del(br, entry); -+ if (!err) -+ __br_mdb_notify(dev, entry, RTM_DELMDB); -+ return err; -+} -+ - void br_mdb_init(void) - { - rtnl_register(PF_BRIDGE, RTM_GETMDB, NULL, br_mdb_dump, NULL); -+ rtnl_register(PF_BRIDGE, RTM_NEWMDB, br_mdb_add, NULL, NULL); -+ rtnl_register(PF_BRIDGE, RTM_DELMDB, br_mdb_del, NULL, NULL); - } -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 8d0ee9b..a8cad95 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -36,14 +36,6 @@ - #define mlock_dereference(X, br) \ - rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) - unsigned int br_mdb_rehash_seq; --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) --static inline int ipv6_is_transient_multicast(const struct in6_addr *addr) --{ -- if (ipv6_addr_is_multicast(addr) && IPV6_ADDR_MC_FLAG_TRANSIENT(addr)) -- return 1; -- return 0; --} --#endif - - static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b) - { -@@ -101,8 +93,8 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get( - return NULL; - } - --static struct net_bridge_mdb_entry *br_mdb_ip_get( -- struct net_bridge_mdb_htable *mdb, struct br_ip *dst) -+struct net_bridge_mdb_entry *br_mdb_ip_get(struct net_bridge_mdb_htable *mdb, -+ struct br_ip *dst) - { - if (!mdb) - return NULL; -@@ -205,7 +197,7 @@ static int br_mdb_copy(struct net_bridge_mdb_htable *new, - return maxlen > elasticity ? -EINVAL : 0; - } - --static void br_multicast_free_pg(struct rcu_head *head) -+void br_multicast_free_pg(struct rcu_head *head) - { - struct net_bridge_port_group *p = - container_of(head, struct net_bridge_port_group, rcu); -@@ -581,9 +573,8 @@ err: - return mp; - } - --static struct net_bridge_mdb_entry *br_multicast_new_group( -- struct net_bridge *br, struct net_bridge_port *port, -- struct br_ip *group) -+struct net_bridge_mdb_entry *br_multicast_new_group(struct net_bridge *br, -+ struct net_bridge_port *port, struct br_ip *group) - { - struct net_bridge_mdb_htable *mdb; - struct net_bridge_mdb_entry *mp; -@@ -630,6 +621,26 @@ out: - return mp; - } - -+struct net_bridge_port_group *br_multicast_new_port_group( -+ struct net_bridge_port *port, -+ struct br_ip *group, -+ struct net_bridge_port_group *next) -+{ -+ struct net_bridge_port_group *p; -+ -+ p = kzalloc(sizeof(*p), GFP_ATOMIC); -+ if (unlikely(!p)) -+ return NULL; -+ -+ p->addr = *group; -+ p->port = port; -+ p->next = next; -+ hlist_add_head(&p->mglist, &port->mglist); -+ setup_timer(&p->timer, br_multicast_port_group_expired, -+ (unsigned long)p); -+ return p; -+} -+ - static int br_multicast_add_group(struct net_bridge *br, - struct net_bridge_port *port, - struct br_ip *group) -@@ -665,18 +676,9 @@ static int br_multicast_add_group(struct net_bridge *br, - break; - } - -- p = kzalloc(sizeof(*p), GFP_ATOMIC); -- err = -ENOMEM; -+ p = br_multicast_new_port_group(port, group, *pp); - if (unlikely(!p)) - goto err; -- -- p->addr = *group; -- p->port = port; -- p->next = *pp; -- hlist_add_head(&p->mglist, &port->mglist); -- setup_timer(&p->timer, br_multicast_port_group_expired, -- (unsigned long)p); -- - rcu_assign_pointer(*pp, p); - br_mdb_notify(br->dev, port, group, RTM_NEWMDB); - -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 48a0667..ceb7ed6 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -432,10 +432,34 @@ extern int br_multicast_set_port_router(struct net_bridge_port *p, - unsigned long val); - extern int br_multicast_toggle(struct net_bridge *br, unsigned long val); - extern int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val); -+extern struct net_bridge_mdb_entry *br_mdb_ip_get( -+ struct net_bridge_mdb_htable *mdb, -+ struct br_ip *dst); -+extern struct net_bridge_mdb_entry *br_multicast_new_group(struct net_bridge *br, -+ struct net_bridge_port *port, struct br_ip *group); -+extern void br_multicast_free_pg(struct rcu_head *head); -+extern struct net_bridge_port_group *br_multicast_new_port_group( -+ struct net_bridge_port *port, -+ struct br_ip *group, -+ struct net_bridge_port_group __rcu *next, -+ unsigned char state); - extern void br_mdb_init(void); - extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, - struct br_ip *group, int type); - -+#define mlock_dereference(X, br) \ -+ rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) -+ -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+static inline int ipv6_is_transient_multicast(const struct in6_addr *addr) -+{ -+ if (ipv6_addr_is_multicast(addr) && IPV6_ADDR_MC_FLAG_TRANSIENT(addr)) -+ return 1; -+ return 0; -+} -+#endif -+ - static inline bool br_multicast_is_router(struct net_bridge *br) - { - return br->multicast_router == 2 || diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-address-from-brport b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-address-from-brport deleted file mode 100644 index c1ed5239..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-address-from-brport +++ /dev/null @@ -1,20 +0,0 @@ -If the bond bridge port does not have a slave it would not be assigned a mac, -in that case the bridge mac would be all zero too. Avoid picking -a port which has all zero mac for the bridge address. - -diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c -index 4ed11ab..f440111 100644 ---- a/net/bridge/br_stp_if.c -+++ b/net/bridge/br_stp_if.c -@@ -246,8 +246,9 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br) - return false; - - list_for_each_entry(p, &br->port_list, list) { -- if (addr == br_mac_zero || -- memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0) -+ if ((addr == br_mac_zero || -+ memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0) && -+ !ether_addr_equal(p->dev->dev_addr, br_mac_zero)) - addr = p->dev->dev_addr; - - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-allow-fdb-replace-in-block-state.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-allow-fdb-replace-in-block-state.patch deleted file mode 100644 index 9e70cade..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-allow-fdb-replace-in-block-state.patch +++ /dev/null @@ -1,20 +0,0 @@ -When a bridge port is in blocking state, it does not learn -mac address. However, allows fdb replace to go through -assuming user knows what is needed. - -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 991f7a2..0311630 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -697,8 +697,9 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, - - /* skip add if the port is not up*/ - if (!(state & NUD_PERMANENT || state & NUD_NOARP) && -- !(source->state == BR_STATE_LEARNING -- || source->state == BR_STATE_FORWARDING)) -+ (!(source->state == BR_STATE_LEARNING -+ || source->state == BR_STATE_FORWARDING) && -+ !(flags & NLM_F_REPLACE))) - return 0; - - fdb = fdb_find(head, addr, vid); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-allow-unprivileged-users-add-delete-mdb.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-allow-unprivileged-users-add-delete-mdb.patch deleted file mode 100644 index 28697408..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-allow-unprivileged-users-add-delete-mdb.patch +++ /dev/null @@ -1,25 +0,0 @@ -From e4d343ea92bdce831f071d9706b2daf097e6d009 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] netns: bridge: allow unprivileged users add/delete mdb entry - -since the mdb table is belong to bridge device,and the -bridge device can only be seen in one netns. -So it's safe to allow unprivileged user which is the -creator of userns and netns to modify the mdb table. - -Signed-off-by: Gao feng -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index 28425d7..560cddb 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -272,9 +272,6 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh, - struct net_device *dev; - int err; - -- if (!capable(CAP_NET_ADMIN)) -- return -EPERM; -- - err = nlmsg_parse(nlh, sizeof(*bpm), tb, MDBA_SET_ENTRY, NULL); - if (err < 0) - return err; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-cdp-process.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-cdp-process.patch deleted file mode 100644 index da8036fe..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-cdp-process.patch +++ /dev/null @@ -1,32 +0,0 @@ - - -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index 61f60bb..1c52833 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -22,6 +22,7 @@ - /* Bridge group multicast address 802.1d (pg 51). */ - const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; - const u8 br_pvst_address[ETH_ALEN] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcd }; -+const u8 br_cdp_address[ETH_ALEN] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc }; - - /* Hook for brouter */ - br_should_route_hook_t __rcu *br_should_route_hook __read_mostly; -@@ -182,6 +183,17 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) - } - } - -+ if (!compare_ether_addr(br_cdp_address, dest)) { -+ /* Deliver packet to local host only */ -+ if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, -+ NULL, br_handle_local_finish)) { -+ return RX_HANDLER_CONSUMED; /* consumed by filter */ -+ } else { -+ *pskb = skb; -+ return RX_HANDLER_PASS; /* continue processing */ -+ } -+ } -+ - if (unlikely(is_link_local(dest))) { - /* - * See IEEE 802.1D Table 7-10 Reserved addresses diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-default-pvid.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-default-pvid.patch deleted file mode 100644 index 2f285adf..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-default-pvid.patch +++ /dev/null @@ -1,146 +0,0 @@ -This patch allows the user to set and retrieve default_pvid -value. A new value can only be stored when vlan filtering -is disabled. - -Signed-off-by: Vladislav Yasevich - -diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c -index 0f3b071..998d46d 100644 ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -90,7 +90,7 @@ drop: - static int br_dev_init(struct net_device *dev) - { - struct net_bridge *br = netdev_priv(dev); -- int i; -+ int i, err; - - br->stats = alloc_percpu(struct pcpu_sw_netstats); - if (!br->stats) -@@ -102,7 +102,11 @@ static int br_dev_init(struct net_device *dev) - u64_stats_init(&br_dev_stats->syncp); - } - -- return 0; -+ err = br_vlan_init(br); -+ if (err) -+ free_percpu(br->stats); -+ -+ return err; - } - - static void br_dev_uninit(struct net_device *dev) -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 50a2b46..796e50f 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -300,6 +300,7 @@ struct net_bridge - struct kobject *ifobj; - #ifdef CONFIG_BRIDGE_VLAN_FILTERING - u8 vlan_enabled; -+ u16 default_pvid; - struct net_port_vlans __rcu *vlan_info; - #endif - }; -@@ -622,6 +623,8 @@ int br_vlan_delete(struct net_bridge *br, u16 vid); - void br_vlan_flush(struct net_bridge *br); - bool br_vlan_find(struct net_bridge *br, u16 vid); - int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val); -+int br_vlan_init(struct net_bridge *br); -+int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val); - int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags); - int nbp_vlan_delete(struct net_bridge_port *port, u16 vid); - void nbp_vlan_flush(struct net_bridge_port *port); -diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c -index e2e953a..3b9af9d 100644 ---- a/net/bridge/br_sysfs_br.c -+++ b/net/bridge/br_sysfs_br.c -@@ -790,6 +790,22 @@ static ssize_t vlan_filtering_store(struct device *d, - return store_bridge_parm(d, buf, len, br_vlan_filter_toggle); - } - static DEVICE_ATTR_RW(vlan_filtering); -+ -+static ssize_t default_pvid_show(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct net_bridge *br = to_bridge(d); -+ return sprintf(buf, "%d\n", br->default_pvid); -+} -+ -+static ssize_t default_pvid_store(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ return store_bridge_parm(d, buf, len, br_vlan_set_default_pvid); -+} -+static DEVICE_ATTR_RW(default_pvid); - #endif - - static struct attribute *bridge_attrs[] = { -@@ -817,9 +833,6 @@ static struct attribute *bridge_attrs[] = { - &dev_attr_multicast_snooping.attr, - &dev_attr_multicast_querier.attr, - &dev_attr_multicast_query_use_ifaddr.attr, --#ifdef CONFIG_BRIDGE_VLAN_FILTERING -- &dev_attr_multicast_v4_queriers.attr, --#endif - &dev_attr_hash_elasticity.attr, - &dev_attr_hash_max.attr, - &dev_attr_multicast_last_member_count.attr, -@@ -838,6 +851,8 @@ static struct attribute *bridge_attrs[] = { - #endif - #ifdef CONFIG_BRIDGE_VLAN_FILTERING - &dev_attr_vlan_filtering.attr, -+ &dev_attr_default_pvid.attr, -+ &dev_attr_multicast_v4_queriers.attr, - #endif - NULL - }; -diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c -index dc00f12..e3efba0 100644 ---- a/net/bridge/br_vlan.c -+++ b/net/bridge/br_vlan.c -@@ -360,6 +360,42 @@ unlock: - return 0; - } - -+int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val) -+{ -+ u16 pvid = val; -+ int err = 0; -+ -+ if (val >= VLAN_VID_MASK) -+ return -EINVAL; -+ -+ if (!rtnl_trylock()) -+ return restart_syscall(); -+ -+ if (pvid == br->default_pvid) -+ goto unlock; -+ -+ /* Only allow default pvid change when filtering is disabled */ -+ if (br->vlan_enabled) { -+ pr_info_once("Please disable vlan filtering to change default_pvid\n"); -+ err = -EPERM; -+ goto unlock; -+ } -+ -+ if (!pvid) -+ br_vlan_disable_default_pvid(br); -+ else -+ err = __br_vlan_set_default_pvid(br, pvid); -+ -+unlock: -+ rtnl_unlock(); -+ return err; -+} -+ -+void br_vlan_init(struct net_bridge *br) -+{ -+ br->default_pvid = 1; -+} -+ - /* Must be protected by RTNL. - * Must be called with vid in range from 1 to 4094 inclusive. - */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-mixed-vlans.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-mixed-vlans.patch deleted file mode 100644 index 709a04d9..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-mixed-vlans.patch +++ /dev/null @@ -1,155 +0,0 @@ -Added a bridge sysctl to allow/disallow mixing vlans in a bridge. - -diff --git a/net/bridge/br.c b/net/bridge/br.c -index 80df1ac..8c0a4ad 100644 ---- a/net/bridge/br.c -+++ b/net/bridge/br.c -@@ -94,8 +94,47 @@ static struct ctl_path brstp_path[] = { - { .procname = "bridge", }, - { } - }; -+ -+static struct ctl_table_header *br_allow_multiple_vlans_sysctl_header; -+int br_allow_multiple_vlans __read_mostly = 0; -+ -+static -+int br_multiple_vlans_sysctl_call_tables(ctl_table * ctl, int write, -+ void __user * buffer, size_t * lenp, loff_t * ppos) -+{ -+ int ret; -+ int old_allow_multiple_vlans = br_allow_multiple_vlans; -+ -+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos); -+ if (old_allow_multiple_vlans != br_allow_multiple_vlans) { -+ printk(KERN_INFO "%s multiple vlans in bridge\n", -+ br_allow_multiple_vlans ? "allow" : "disallow"); -+ } -+ -+ return ret; -+} -+ -+static ctl_table br_allow_multiple_vlans_table[] = { -+ { -+ .procname = "bridge-allow-multiple-vlans", -+ .data = &br_allow_multiple_vlans, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = br_multiple_vlans_sysctl_call_tables, -+ }, -+ { } -+}; -+ -+static struct ctl_path br_allow_multiple_vlans_path[] = { -+ { .procname = "net", }, -+ { .procname = "bridge", }, -+ { } -+}; -+ -+ - #else - #define brstp_user_space 1 -+#define br_allow_multiple_vlans 0 - #endif - - static int __init br_init(void) -@@ -109,6 +148,15 @@ static int __init br_init(void) - "br_init: can't register to sysctl.\n"); - return -ENOMEM; - } -+ -+ br_allow_multiple_vlans_sysctl_header = register_sysctl_paths( -+ br_allow_multiple_vlans_path, -+ br_allow_multiple_vlans_table); -+ if (br_allow_multiple_vlans_sysctl_header == NULL) { -+ printk(KERN_WARNING -+ "br_init: can't register to sysctl.\n"); -+ return -ENOMEM; -+ } - #endif - - if (!brstp_user_space) { -@@ -159,6 +207,7 @@ err_out: - stp_proto_unregister(&br_stp_proto); - #ifdef CONFIG_SYSCTL - unregister_sysctl_table(brstp_sysctl_header); -+ unregister_sysctl_table(br_allow_multiple_vlans_sysctl_header); - #endif - return err; - } -@@ -169,6 +218,7 @@ static void __exit br_deinit(void) - stp_proto_unregister(&br_stp_proto); - #ifdef CONFIG_SYSCTL - unregister_sysctl_table(brstp_sysctl_header); -+ unregister_sysctl_table(br_allow_multiple_vlans_sysctl_header); - #endif - br_netlink_fini(); - unregister_netdevice_notifier(&br_device_notifier); -diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c -index 62c8fb2..48161b6 100644 ---- a/net/bridge/br_if.c -+++ b/net/bridge/br_if.c -@@ -27,6 +27,8 @@ - - #include "br_private.h" - -+extern int br_allow_multiple_vlans; -+ - /* - * Determine initial path cost based on speed. - * using recommendations from 802.1d standard -@@ -324,6 +326,44 @@ netdev_features_t br_features_recompute(struct net_bridge *br, - return features; - } - -+static bool bridge_has_multiple_vlans(struct net_bridge *br) -+{ -+ struct net_bridge_port *p; -+ u16 vlan_id = 0; -+ -+ list_for_each_entry_rcu(p, &br->port_list, list) { -+ if (!is_vlan_dev(p->dev)) -+ continue; -+ if (vlan_id != vlan_dev_vlan_id(p->dev)) { -+ if (vlan_id == 0) -+ vlan_id = vlan_dev_vlan_id(p->dev); -+ else -+ return true; -+ } -+ } -+ return false; -+} -+ -+static bool is_port_in_different_vlan(struct net_bridge *br, -+ struct net_device *dev) -+{ -+ struct net_bridge_port *p; -+ u16 vlan_id; -+ -+ if (!is_vlan_dev(dev)) -+ return false; -+ -+ vlan_id = vlan_dev_vlan_id(dev); -+ -+ list_for_each_entry_rcu(p, &br->port_list, list) { -+ if (!is_vlan_dev(p->dev)) -+ continue; -+ if (vlan_id != vlan_dev_vlan_id(p->dev)) -+ return true; -+ } -+ return false; -+} -+ - /* called with RTNL */ - int br_add_if(struct net_bridge *br, struct net_device *dev) - { -@@ -349,6 +389,10 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) - if (dev->priv_flags & IFF_DONT_BRIDGE) - return -EOPNOTSUPP; - -+ /* No bridgeing vlan devices that have different vlan id */ -+ if (!br_allow_multiple_vlans && is_port_in_different_vlan(br, dev)) -+ return -EINVAL; -+ - p = new_nbp(br, dev); - if (IS_ERR(p)) - return PTR_ERR(p); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-multiple-sub-intfs-on-same-port.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-multiple-sub-intfs-on-same-port.patch deleted file mode 100644 index 8c723065..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-multiple-sub-intfs-on-same-port.patch +++ /dev/null @@ -1,79 +0,0 @@ -This patch disallows multiple sub interfaces on the same -port in the same bridge - -ie swp1 and swp1.100 in the same bridge will be rejected. - -diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c -index 780076b..afaec72 100644 ---- a/net/bridge/br_if.c -+++ b/net/bridge/br_if.c -@@ -344,17 +344,47 @@ static bool bridge_has_multiple_vlans(struct net_bridge *br) - return false; - } - -+/* -+ * Returns true if we are adding more than -+ * one interface with the same real_dev -+ * example: eth0 and eth0.100 -+ */ -+static bool br_port_realdev_exists(struct net_bridge *br, -+ struct net_device *dev) -+{ -+ struct net_bridge_port *p; -+ struct net_device *real_dev; -+ struct net_device *in_dev; -+ -+ if (is_vlan_dev(dev)) -+ in_dev = vlan_dev_real_dev(dev); -+ else -+ in_dev = dev; -+ -+ list_for_each_entry_rcu(p, &br->port_list, list) { -+ if (in_dev == p->dev) -+ return true; -+ if (!is_vlan_dev(p->dev)) -+ continue; -+ real_dev = vlan_dev_real_dev(p->dev); -+ if (in_dev == real_dev) -+ return true; -+ } -+ -+ return false; -+} -+ - static bool is_port_in_different_vlan(struct net_bridge *br, - struct net_device *dev) - { - struct net_bridge_port *p; -+ struct net_device *real_dev; - u16 vlan_id; - - if (!is_vlan_dev(dev)) -- return false; -+ return false; - - vlan_id = vlan_dev_vlan_id(dev); -- - list_for_each_entry_rcu(p, &br->port_list, list) { - if (!is_vlan_dev(p->dev)) - continue; -@@ -389,9 +419,18 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) - if (dev->priv_flags & IFF_DONT_BRIDGE) - return -EOPNOTSUPP; - -+ if (br_port_realdev_exists(br, dev)) { -+ pr_info("%s: %s: cannot add port %s (realdev already exists)\n", -+ __func__, br->dev->name, dev->name); -+ return -EINVAL; -+ } -+ - /* No bridgeing vlan devices that have different vlan id */ -- if (!br_allow_multiple_vlans && is_port_in_different_vlan(br, dev)) -+ if (!br_allow_multiple_vlans && is_port_in_different_vlan(br, dev)) { -+ pr_info("%s: %s: cannot add port %s (multiple vlan check failed)\n", -+ __func__, br->dev->name, dev->name); - return -EINVAL; -+ } - - p = new_nbp(br, dev); - if (IS_ERR(p)) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-snooping-if-there-is-no-querier.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-snooping-if-there-is-no-querier.patch deleted file mode 100644 index 3eb6deff..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-snooping-if-there-is-no-querier.patch +++ /dev/null @@ -1,197 +0,0 @@ -From b00589af3b04736376f24625ab0b394642e89e29 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: disable snooping if there is no querier -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If there is no querier on a link then we won't get periodic reports and -therefore won't be able to learn about multicast listeners behind ports, -potentially leading to lost multicast packets, especially for multicast -listeners that joined before the creation of the bridge. - -These lost multicast packets can appear since c5c23260594 -("bridge: Add multicast_querier toggle and disable queries by default") -in particular. - -With this patch we are flooding multicast packets if our querier is -disabled and if we didn't detect any other querier. - -A grace period of the Maximum Response Delay of the querier is added to -give multicast responses enough time to arrive and to be learned from -before disabling the flooding behaviour again. - -Signed-off-by: Linus Lüssing -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c -index 9abea10..9baf277 100644 ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -62,7 +62,8 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) - } - - mdst = br_mdb_get(br, skb); -- if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) -+ if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && -+ br_multicast_querier_exists(br)) - br_multicast_deliver(mdst, skb); - else - br_flood_deliver(br, skb); -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index 8e0ca31..392bb58 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -86,7 +86,8 @@ int br_handle_frame_finish(struct sk_buff *skb) - skb2 = skb; - else if (is_multicast_ether_addr(dest)) { - mdst = br_mdb_get(br, skb); -- if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { -+ if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && -+ br_multicast_querier_exists(br)) { - if ((mdst && mdst->mglist) || - br_multicast_is_router(br)) - skb2 = skb; -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index e962ce3..399b21b 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1010,6 +1010,16 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, - } - #endif - -+static void br_multicast_update_querier_timer(struct net_bridge *br, -+ unsigned long max_delay) -+{ -+ if (!timer_pending(&br->multicast_querier_timer)) -+ br->multicast_querier_delay_time = jiffies + max_delay; -+ -+ mod_timer(&br->multicast_querier_timer, -+ jiffies + br->multicast_querier_interval); -+} -+ - /* - * Add port to rotuer_list - * list is maintained ordered by pointer value -@@ -1061,11 +1071,11 @@ timer: - - static void br_multicast_query_received(struct net_bridge *br, - struct net_bridge_port *port, -- int saddr) -+ int saddr, -+ unsigned long max_delay) - { - if (saddr) -- mod_timer(&br->multicast_querier_timer, -- jiffies + br->multicast_querier_interval); -+ br_multicast_update_querier_timer(br, max_delay); - else if (timer_pending(&br->multicast_querier_timer)) - return; - -@@ -1092,8 +1102,6 @@ static int br_ip4_multicast_query(struct net_bridge *br, - (port && port->state == BR_STATE_DISABLED)) - goto out; - -- br_multicast_query_received(br, port, !!iph->saddr); -- - group = ih->group; - - if (skb->len == sizeof(*ih)) { -@@ -1117,6 +1125,8 @@ static int br_ip4_multicast_query(struct net_bridge *br, - IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; - } - -+ br_multicast_query_received(br, port, !!iph->saddr, max_delay); -+ - if (!group) - goto out; - -@@ -1167,8 +1177,6 @@ static int br_ip6_multicast_query(struct net_bridge *br, - (port && port->state == BR_STATE_DISABLED)) - goto out; - -- br_multicast_query_received(br, port, !ipv6_addr_any(&ip6h->saddr)); -- - /* RFC2710+RFC3810 (MLDv1+MLDv2) require link-local source addresses */ - if (!(ipv6_addr_type(&ip6h->saddr) & IPV6_ADDR_LINKLOCAL)) { - err = -EINVAL; -@@ -1196,6 +1204,8 @@ static int br_ip6_multicast_query(struct net_bridge *br, - max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL); - } - -+ br_multicast_query_received(br, port, !ipv6_addr_any(&ip6h->saddr), -+ max_delay); - if (!group) - goto out; - -@@ -1645,6 +1655,8 @@ void br_multicast_init(struct net_bridge *br) - br->multicast_querier_interval = 255 * HZ; - br->multicast_membership_interval = 260 * HZ; - -+ br->multicast_querier_delay_time = 0; -+ - spin_lock_init(&br->multicast_lock); - setup_timer(&br->multicast_router_timer, - br_multicast_local_router_expired, 0); -@@ -1829,6 +1841,8 @@ unlock: - - int br_multicast_set_querier(struct net_bridge *br, unsigned long val) - { -+ unsigned long max_delay; -+ - val = !!val; - - spin_lock_bh(&br->multicast_lock); -@@ -1836,8 +1850,14 @@ int br_multicast_set_querier(struct net_bridge *br, unsigned long val) - goto unlock; - - br->multicast_querier = val; -- if (val) -- br_multicast_start_querier(br); -+ if (!val) -+ goto unlock; -+ -+ max_delay = br->multicast_query_response_interval; -+ if (!timer_pending(&br->multicast_querier_timer)) -+ br->multicast_querier_delay_time = jiffies + max_delay; -+ -+ br_multicast_start_querier(br); - - unlock: - spin_unlock_bh(&br->multicast_lock); -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 3b082a1..051673e 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -246,6 +246,7 @@ struct net_bridge - unsigned long multicast_query_interval; - unsigned long multicast_query_response_interval; - unsigned long multicast_startup_query_interval; -+ unsigned long multicast_querier_delay_time; - - spinlock_t multicast_lock; - struct net_bridge_mdb_htable __rcu *mdb; -@@ -474,6 +475,13 @@ static inline bool br_multicast_is_router(struct net_bridge *br) - (br->multicast_router == 1 && - timer_pending(&br->multicast_router_timer)); - } -+ -+static inline bool br_multicast_querier_exists(struct net_bridge *br) -+{ -+ return time_is_before_jiffies(br->multicast_querier_delay_time) && -+ (br->multicast_querier || -+ timer_pending(&br->multicast_querier_timer)); -+} - #else - static inline int br_multicast_rcv(struct net_bridge *br, - struct net_bridge_port *port, -@@ -530,6 +538,10 @@ static inline bool br_multicast_is_router(struct net_bridge *br) - { - return 0; - } -+static inline bool br_multicast_querier_exists(struct net_bridge *br) -+{ -+ return false; -+} - static inline void br_mdb_init(void) - { - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-sw-bridging.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-sw-bridging.patch deleted file mode 100644 index b1aace30..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-disable-sw-bridging.patch +++ /dev/null @@ -1,135 +0,0 @@ -Suppress the kernel bridging of frames that would have already been forwarded -in hardware. - -diff --git a/net/bridge/br.c b/net/bridge/br.c -index f20c4fd..d3f57c1 100644 ---- a/net/bridge/br.c -+++ b/net/bridge/br.c -@@ -22,6 +22,11 @@ - - #include "br_private.h" - -+int br_hw_fwding_enabled = 1; -+ -+MODULE_PARM_DESC(hw_fwding, "Enable hw forwarding"); -+module_param_named(hw_fwding, br_hw_fwding_enabled, int, 0644); -+ - static const struct stp_proto br_stp_proto = { - .rcv = br_stp_rcv, - }; -diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c -index e221f88..1c9ba1b 100644 ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -26,6 +26,8 @@ static int deliver_clone(const struct net_bridge_port *prev, - void (*__packet_hook)(const struct net_bridge_port *p, - struct sk_buff *skb)); - -+extern int br_hw_fwding_enabled; -+ - /* Don't forward packets to originating port or forwarding diasabled */ - static inline int should_deliver(const struct net_bridge_port *p, - const struct sk_buff *skb) -@@ -61,6 +63,12 @@ int br_forward_finish(struct sk_buff *skb) - - } - -+int br_hw_forward_finish(struct sk_buff *skb) -+{ -+ kfree_skb(skb); -+ return 0; -+ -+} - static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) - { - skb->dev = to->dev; -@@ -83,6 +91,12 @@ static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) - { - struct net_device *indev; - -+ if (br_hw_fwding_enabled) { -+ NF_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, skb->dev, to->dev, -+ br_hw_forward_finish); -+ return; -+ } -+ - if (skb_warn_if_lro(skb)) { - kfree_skb(skb); - return; -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index 5a31731..8e0ca31 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -26,6 +26,8 @@ const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; - br_should_route_hook_t __rcu *br_should_route_hook __read_mostly; - EXPORT_SYMBOL(br_should_route_hook); - -+extern int br_hw_fwding_enabled; -+ - static int br_pass_frame_up(struct sk_buff *skb) - { - struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; -@@ -59,7 +61,9 @@ int br_handle_frame_finish(struct sk_buff *skb) - - /* insert into forwarding database after filtering to avoid spoofing */ - br = p->br; -- br_fdb_update(br, p, eth_hdr(skb)->h_source); -+ -+ if (!br_hw_fwding_enabled) -+ br_fdb_update(br, p, eth_hdr(skb)->h_source); - - if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) && - br_multicast_rcv(br, p, skb)) -@@ -123,7 +127,9 @@ static int br_handle_local_finish(struct sk_buff *skb) - { - struct net_bridge_port *p = br_port_get_rcu(skb->dev); - -- br_fdb_update(p->br, p, eth_hdr(skb)->h_source); -+ if (!br_hw_fwding_enabled) -+ br_fdb_update(p->br, p, eth_hdr(skb)->h_source); -+ - return 0; /* process further */ - } - -diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c -index 7c1745d..fc08e8b 100644 ---- a/net/bridge/br_netfilter.c -+++ b/net/bridge/br_netfilter.c -@@ -42,6 +42,8 @@ - #include - #endif - -+extern int br_hw_fwding_enabled; -+ - #define skb_origaddr(skb) (((struct bridge_skb_cb *) \ - (skb->nf_bridge->data))->daddr.ipv4) - #define store_orig_dstaddr(skb) (skb_origaddr(skb) = ip_hdr(skb)->daddr) -@@ -712,8 +714,13 @@ static int br_nf_forward_finish(struct sk_buff *skb) - } - nf_bridge_push_encap_header(skb); - -- NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, in, -- skb->dev, br_forward_finish, 1); -+ if (br_hw_fwding_enabled) { -+ NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, in, -+ skb->dev, br_hw_forward_finish, 1); -+ } else { -+ NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, in, -+ skb->dev, br_forward_finish, 1); -+ } - return 0; - } - -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index b9bba8f..dc28e83 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -369,6 +369,8 @@ extern int br_dev_queue_push_xmit(struct sk_buff *skb); - extern void br_forward(const struct net_bridge_port *to, - struct sk_buff *skb, struct sk_buff *skb0); - extern int br_forward_finish(struct sk_buff *skb); -+extern int br_hw_forward_finish(struct sk_buff *skb); -+ - extern void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb); - extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, - struct sk_buff *skb2); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-don-t-try-to-update-timers-in-case-of-broken-.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-don-t-try-to-update-timers-in-case-of-broken-.patch deleted file mode 100644 index 507d750e..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-don-t-try-to-update-timers-in-case-of-broken-.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 248ba8ec05a2c3b118c2224e57eb10c128176ab1 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: don't try to update timers in case of broken MLD - queries -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Currently we are reading an uninitialized value for the max_delay -variable when snooping an MLD query message of invalid length and would -update our timers with that. - -Fixing this by simply ignoring such broken MLD queries (just like we do -for IGMP already). - -This is a regression introduced by: -"bridge: disable snooping if there is no querier" (b00589af3b04) - -Reported-by: Paul Bolle -Signed-off-by: Linus Lüssing -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 399b21b..bc10e6b 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1192,7 +1192,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, - max_delay = msecs_to_jiffies(ntohs(mld->mld_maxdelay)); - if (max_delay) - group = &mld->mld_mca; -- } else if (skb->len >= sizeof(*mld2q)) { -+ } else { - if (!pskb_may_pull(skb, sizeof(*mld2q))) { - err = -EINVAL; - goto out; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-dont-install-local-mac.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-dont-install-local-mac.patch deleted file mode 100644 index 0d197d13..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-dont-install-local-mac.patch +++ /dev/null @@ -1,148 +0,0 @@ -This patch by default suppresses the installation of bridge member local -port mac in the fdb, which creates a big scalability problem when the -number of ports and vlan membership is large. - -To ensure upper devices continue to receive packets destined to member port -mac that is different from the bridge or bridge upper devices's macs -(possible with current behavior albeit a rare use case), the local macs -are continued to be installed on vlan 0 (as 'my macs') and referenced for -the sole purpose of passing up the stack when fdb lookup by vlan results -in a miss. Note that vlan membership of ingress port and the bridge device -as egress are still being correctly enforced. - -A sysctl node is created to allow reverting back to existing behavior. - -diff --git a/net/bridge/br.c b/net/bridge/br.c -index 8c0a4ad..c8202a2 100644 ---- a/net/bridge/br.c -+++ b/net/bridge/br.c -@@ -131,10 +131,46 @@ static struct ctl_path br_allow_multiple_vlans_path[] = { - { } - }; - -+static struct ctl_table_header *br_ignore_local_fdb_sysctl_header; -+int br_ignore_local_fdb __read_mostly = 1; -+ -+static -+int br_ignore_local_fdb_sysctl_call_tables(ctl_table * ctl, int write, -+ void __user * buffer, size_t * lenp, loff_t * ppos) -+{ -+ int ret; -+ int old_ignore_local_fdb = br_ignore_local_fdb; -+ -+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos); -+ if (old_ignore_local_fdb != br_ignore_local_fdb) { -+ printk(KERN_INFO "%s local fdb installation\n", -+ br_ignore_local_fdb ? "disable" : "enable"); -+ } -+ -+ return ret; -+} -+ -+static ctl_table br_ignore_local_fdb_table[] = { -+ { -+ .procname = "bridge-ignore-local-fdb", -+ .data = &br_ignore_local_fdb, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = br_ignore_local_fdb_sysctl_call_tables, -+ }, -+ { } -+}; -+ -+static struct ctl_path br_ignore_local_fdb_path[] = { -+ { .procname = "net", }, -+ { .procname = "bridge", }, -+ { } -+}; - - #else - #define brstp_user_space 1 - #define br_allow_multiple_vlans 0 -+#define br_ignore_local_fdb 1 - #endif - - static int __init br_init(void) -@@ -157,6 +193,15 @@ static int __init br_init(void) - "br_init: can't register to sysctl.\n"); - return -ENOMEM; - } -+ -+ br_ignore_local_fdb_sysctl_header = register_sysctl_paths( -+ br_ignore_local_fdb_path, -+ br_ignore_local_fdb_table); -+ if (br_ignore_local_fdb_sysctl_header == NULL) { -+ printk(KERN_WARNING -+ "br_init: can't register to sysctl.\n"); -+ return -ENOMEM; -+ } - #endif - - if (!brstp_user_space) { -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 0311630..9063201 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -746,6 +746,10 @@ static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge_port *p, - { - int err = 0; - -+ if (p->br->vlan_enabled && br_ignore_local_fdb && -+ (ndm->ndm_state & NUD_PERMANENT)) -+ return err; -+ - if (ndm->ndm_flags & NTF_USE) { - rcu_read_lock(); - br_fdb_update(p->br, p, addr, vid); -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index 3894c99..d2f8c04 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -136,6 +136,11 @@ int br_handle_frame_finish(struct sk_buff *skb) - skb2 = skb; - /* Do not forward the packet since it's local. */ - skb = NULL; -+ } else if (br->vlan_enabled && br_ignore_local_fdb && -+ ((dst = __br_fdb_get(br, dest, 0)) && dst->is_local)) { -+ skb2 = skb; -+ /* Do not forward the packet since it's local. */ -+ skb = NULL; - } - - if (skb) { -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 2d70a48..e4ef7ca 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -817,6 +817,7 @@ unsigned long br_timer_value(const struct timer_list *timer); - #if IS_ENABLED(CONFIG_ATM_LANE) - extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr); - #endif -+extern int br_ignore_local_fdb; - - /* br_netlink.c */ - extern struct rtnl_link_ops br_link_ops; -diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c -index 5880138..db5a590 100644 ---- a/net/bridge/br_vlan.c -+++ b/net/bridge/br_vlan.c -@@ -66,12 +66,13 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) - if (err) - return err; - } -- -- err = br_fdb_insert(br, p, dev->dev_addr, vid); -- if (err) { -- br_err(br, "failed insert local address into bridge " -- "forwarding table\n"); -- goto out_filt; -+ if (!br_ignore_local_fdb || !v->port_idx) { -+ err = br_fdb_insert(br, p, dev->dev_addr, vid); -+ if (err) { -+ br_err(br, "failed insert local address into bridge " -+ "forwarding table\n"); -+ goto out_filt; -+ } - } - - set_bit(vid, v->vlan_bitmap); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-export-multicast-database-via-netlink.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-export-multicast-database-via-netlink.patch deleted file mode 100644 index 9c0e1bab..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-export-multicast-database-via-netlink.patch +++ /dev/null @@ -1,374 +0,0 @@ -From ee07c6e7a6f8a25c18f0a6b18152fbd7499245f6 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: export multicast database via netlink - -V5: fix two bugs pointed out by Thomas - remove seq check for now, mark it as TODO - -V4: remove some useless #include - some coding style fix - -V3: drop debugging printk's - update selinux perm table as well - -V2: drop patch 1/2, export ifindex directly - Redesign netlink attributes - Improve netlink seq check - Handle IPv6 addr as well - -This patch exports bridge multicast database via netlink -message type RTM_GETMDB. Similar to fdb, but currently bridge-specific. -We may need to support modify multicast database too (RTM_{ADD,DEL}MDB). - -(Thanks to Thomas for patient reviews) - -Cc: Herbert Xu -Cc: Stephen Hemminger -Cc: "David S. Miller" -Cc: Thomas Graf -Cc: Jesper Dangaard Brouer -Signed-off-by: Cong Wang -Acked-by: Thomas Graf -Signed-off-by: David S. Miller - -diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h -index dd3f201..bf53693 100644 ---- a/include/linux/if_bridge.h -+++ b/include/linux/if_bridge.h -@@ -14,6 +14,7 @@ - #define _LINUX_IF_BRIDGE_H - - #include -+#include - - #define SYSFS_BRIDGE_ATTR "bridge" - #define SYSFS_BRIDGE_FDB "brforward" -@@ -97,6 +98,72 @@ struct __fdb_entry { - __u16 unused; - }; - -+/* Bridge multicast database attributes -+ * [MDBA_MDB] = { -+ * [MDBA_MDB_ENTRY] = { -+ * [MDBA_MDB_ENTRY_INFO] -+ * } -+ * } -+ * [MDBA_ROUTER] = { -+ * [MDBA_ROUTER_PORT] -+ * } -+ */ -+enum { -+ MDBA_UNSPEC, -+ MDBA_MDB, -+ MDBA_ROUTER, -+ __MDBA_MAX, -+}; -+#define MDBA_MAX (__MDBA_MAX - 1) -+ -+enum { -+ MDBA_MDB_UNSPEC, -+ MDBA_MDB_ENTRY, -+ __MDBA_MDB_MAX, -+}; -+#define MDBA_MDB_MAX (__MDBA_MDB_MAX - 1) -+ -+enum { -+ MDBA_MDB_ENTRY_UNSPEC, -+ MDBA_MDB_ENTRY_INFO, -+ __MDBA_MDB_ENTRY_MAX, -+}; -+#define MDBA_MDB_ENTRY_MAX (__MDBA_MDB_ENTRY_MAX - 1) -+ -+enum { -+ MDBA_ROUTER_UNSPEC, -+ MDBA_ROUTER_PORT, -+ __MDBA_ROUTER_MAX, -+}; -+#define MDBA_ROUTER_MAX (__MDBA_ROUTER_MAX - 1) -+ -+struct br_port_msg { -+ __u8 family; -+ __u32 ifindex; -+}; -+ -+struct br_mdb_entry { -+ __u32 ifindex; -+#define MDB_TEMPORARY 0 -+#define MDB_PERMANENT 1 -+ __u8 state; -+ struct { -+ union { -+ __be32 ip4; -+ struct in6_addr ip6; -+ } u; -+ __be16 proto; -+ } addr; -+}; -+ -+enum { -+ MDBA_SET_ENTRY_UNSPEC, -+ MDBA_SET_ENTRY, -+ __MDBA_SET_ENTRY_MAX, -+}; -+#define MDBA_SET_ENTRY_MAX (__MDBA_SET_ENTRY_MAX - 1) -+ -+ - #ifdef __KERNEL__ - - #include -diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h -index 577592e..f38195c 100644 ---- a/include/linux/rtnetlink.h -+++ b/include/linux/rtnetlink.h -@@ -120,6 +120,18 @@ enum { - RTM_SETDCB, - #define RTM_SETDCB RTM_SETDCB - -+ RTM_NEWNETCONF = 80, -+#define RTM_NEWNETCONF RTM_NEWNETCONF -+ RTM_GETNETCONF = 82, -+#define RTM_GETNETCONF RTM_GETNETCONF -+ -+ RTM_NEWMDB = 84, -+#define RTM_NEWMDB RTM_NEWMDB -+ RTM_DELMDB = 85, -+#define RTM_DELMDB RTM_DELMDB -+ RTM_GETMDB = 86, -+#define RTM_GETMDB RTM_GETMDB -+ - __RTM_MAX, - #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) - }; -@@ -587,6 +599,12 @@ enum rtnetlink_groups { - #define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE - RTNLGRP_DCB, - #define RTNLGRP_DCB RTNLGRP_DCB -+ RTNLGRP_IPV4_NETCONF, -+#define RTNLGRP_IPV4_NETCONF RTNLGRP_IPV4_NETCONF -+ RTNLGRP_IPV6_NETCONF, -+#define RTNLGRP_IPV6_NETCONF RTNLGRP_IPV6_NETCONF -+ RTNLGRP_MDB, -+#define RTNLGRP_MDB RTNLGRP_MDB - __RTNLGRP_MAX - }; - #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) -diff --git a/net/bridge/Makefile b/net/bridge/Makefile -index d0359ea..e859098 100644 ---- a/net/bridge/Makefile -+++ b/net/bridge/Makefile -@@ -12,6 +12,6 @@ bridge-$(CONFIG_SYSFS) += br_sysfs_if.o br_sysfs_br.o - - bridge-$(CONFIG_BRIDGE_NETFILTER) += br_netfilter.o - --bridge-$(CONFIG_BRIDGE_IGMP_SNOOPING) += br_multicast.o -+bridge-$(CONFIG_BRIDGE_IGMP_SNOOPING) += br_multicast.o br_mdb.o - - obj-$(CONFIG_BRIDGE_NF_EBTABLES) += netfilter/ -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -new file mode 100644 -index 0000000..3eb4c92 ---- /dev/null -+++ b/net/bridge/br_mdb.c -@@ -0,0 +1,163 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#endif -+ -+#include "br_private.h" -+ -+static int br_rports_fill_info(struct sk_buff *skb, struct netlink_callback *cb, -+ struct net_device *dev) -+{ -+ struct net_bridge *br = netdev_priv(dev); -+ struct net_bridge_port *p; -+ struct hlist_node *n; -+ struct nlattr *nest; -+ -+ if (!br->multicast_router || hlist_empty(&br->router_list)) -+ return 0; -+ -+ nest = nla_nest_start(skb, MDBA_ROUTER); -+ if (nest == NULL) -+ return -EMSGSIZE; -+ -+ hlist_for_each_entry_rcu(p, n, &br->router_list, rlist) { -+ if (p && nla_put_u32(skb, MDBA_ROUTER_PORT, p->dev->ifindex)) -+ goto fail; -+ } -+ -+ nla_nest_end(skb, nest); -+ return 0; -+fail: -+ nla_nest_cancel(skb, nest); -+ return -EMSGSIZE; -+} -+ -+static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, -+ struct net_device *dev) -+{ -+ struct net_bridge *br = netdev_priv(dev); -+ struct net_bridge_mdb_htable *mdb; -+ struct nlattr *nest, *nest2; -+ int i, err = 0; -+ int idx = 0, s_idx = cb->args[1]; -+ -+ if (br->multicast_disabled) -+ return 0; -+ -+ mdb = rcu_dereference(br->mdb); -+ if (!mdb) -+ return 0; -+ -+ nest = nla_nest_start(skb, MDBA_MDB); -+ if (nest == NULL) -+ return -EMSGSIZE; -+ -+ for (i = 0; i < mdb->max; i++) { -+ struct hlist_node *h; -+ struct net_bridge_mdb_entry *mp; -+ struct net_bridge_port_group *p, **pp; -+ struct net_bridge_port *port; -+ -+ hlist_for_each_entry_rcu(mp, h, &mdb->mhash[i], hlist[mdb->ver]) { -+ if (idx < s_idx) -+ goto skip; -+ -+ nest2 = nla_nest_start(skb, MDBA_MDB_ENTRY); -+ if (nest2 == NULL) { -+ err = -EMSGSIZE; -+ goto out; -+ } -+ -+ for (pp = &mp->ports; -+ (p = rcu_dereference(*pp)) != NULL; -+ pp = &p->next) { -+ port = p->port; -+ if (port) { -+ struct br_mdb_entry e; -+ e.ifindex = port->dev->ifindex; -+ e.addr.u.ip4 = p->addr.u.ip4; -+#if IS_ENABLED(CONFIG_IPV6) -+ e.addr.u.ip6 = p->addr.u.ip6; -+#endif -+ e.addr.proto = p->addr.proto; -+ if (nla_put(skb, MDBA_MDB_ENTRY_INFO, sizeof(e), &e)) { -+ nla_nest_cancel(skb, nest2); -+ err = -EMSGSIZE; -+ goto out; -+ } -+ } -+ } -+ nla_nest_end(skb, nest2); -+ skip: -+ idx++; -+ } -+ } -+ -+out: -+ cb->args[1] = idx; -+ nla_nest_end(skb, nest); -+ return err; -+} -+ -+static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb) -+{ -+ struct net_device *dev; -+ struct net *net = sock_net(skb->sk); -+ struct nlmsghdr *nlh = NULL; -+ int idx = 0, s_idx; -+ -+ s_idx = cb->args[0]; -+ -+ rcu_read_lock(); -+ -+ /* TODO: in case of rehashing, we need to check -+ * consistency for dumping. -+ */ -+ cb->seq = net->dev_base_seq; -+ -+ for_each_netdev_rcu(net, dev) { -+ if (dev->priv_flags & IFF_EBRIDGE) { -+ struct br_port_msg *bpm; -+ -+ if (idx < s_idx) -+ goto skip; -+ -+ nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).pid, -+ cb->nlh->nlmsg_seq, RTM_GETMDB, -+ sizeof(*bpm), NLM_F_MULTI); -+ if (nlh == NULL) -+ break; -+ -+ bpm = nlmsg_data(nlh); -+ bpm->ifindex = dev->ifindex; -+ if (br_mdb_fill_info(skb, cb, dev) < 0) -+ goto out; -+ if (br_rports_fill_info(skb, cb, dev) < 0) -+ goto out; -+ -+ cb->args[1] = 0; -+ nlmsg_end(skb, nlh); -+ skip: -+ idx++; -+ } -+ } -+ -+out: -+ if (nlh) -+ nlmsg_end(skb, nlh); -+ rcu_read_unlock(); -+ cb->args[0] = idx; -+ return skb->len; -+} -+ -+void br_mdb_init(void) -+{ -+ rtnl_register(PF_BRIDGE, RTM_GETMDB, NULL, br_mdb_dump, NULL); -+} -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 398a297..c3433a8 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1572,6 +1572,7 @@ void br_multicast_init(struct net_bridge *br) - br_multicast_local_router_expired, 0); - setup_timer(&br->multicast_query_timer, br_multicast_query_expired, - (unsigned long)br); -+ br_mdb_init(); - } - - void br_multicast_open(struct net_bridge *br) -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 598f817..3ae0b3d 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -431,6 +431,7 @@ extern int br_multicast_set_port_router(struct net_bridge_port *p, - unsigned long val); - extern int br_multicast_toggle(struct net_bridge *br, unsigned long val); - extern int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val); -+extern void br_mdb_init(void); - - static inline bool br_multicast_is_router(struct net_bridge *br) - { -diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c -index 0920ea3..8974866 100644 ---- a/security/selinux/nlmsgtab.c -+++ b/security/selinux/nlmsgtab.c -@@ -68,6 +68,11 @@ static struct nlmsg_perm nlmsg_route_perms[] = - { RTM_GETADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_READ }, - { RTM_GETDCB, NETLINK_ROUTE_SOCKET__NLMSG_READ }, - { RTM_SETDCB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, -+ { RTM_NEWNETCONF, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, -+ { RTM_GETNETCONF, NETLINK_ROUTE_SOCKET__NLMSG_READ }, -+ { RTM_NEWMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, -+ { RTM_DELMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, -+ { RTM_GETMDB, NETLINK_ROUTE_SOCKET__NLMSG_READ }, - }; - - static struct nlmsg_perm nlmsg_firewall_perms[] = diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-add-check-port-status.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-add-check-port-status.patch deleted file mode 100644 index e5bc815a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-add-check-port-status.patch +++ /dev/null @@ -1,19 +0,0 @@ -check port status and skip fdb add if port is not in learning or forwading state - -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index f01ff2e..038ef86 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -683,6 +683,12 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, - struct net_bridge_fdb_entry *fdb; - bool modified = false; - -+ /* skip add if the port is not up*/ -+ if (!(state & NUD_PERMANENT || state & NUD_NOARP) && -+ !(source->state == BR_STATE_LEARNING -+ || source->state == BR_STATE_FORWARDING)) -+ return 0; -+ - fdb = fdb_find(head, addr, vid); - if (fdb == NULL) { - if (!(flags & NLM_F_CREATE)) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-add-self.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-add-self.patch deleted file mode 100644 index bb309e04..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-add-self.patch +++ /dev/null @@ -1,149 +0,0 @@ -This patch adds support to allow fdb add's on the -bridge device. - -Signed-off-by: Roopa Prabhu - -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 87c45dc..991f7a2 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -768,6 +768,7 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], - int err = 0; - struct net_port_vlans *pv; - unsigned short vid = VLAN_N_VID; -+ struct net_bridge *br = NULL; - - if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) { - pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state); -@@ -794,14 +795,20 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], - return -EINVAL; - } - -- p = br_port_get_rtnl(dev); -- if (p == NULL) { -- pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n", -- dev->name); -- return -EINVAL; -+ if (dev->priv_flags & IFF_EBRIDGE) { -+ br = netdev_priv(dev); -+ pv = br_get_vlan_info(br); -+ } else { -+ p = br_port_get_rtnl(dev); -+ if (p == NULL) { -+ pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n", -+ dev->name); -+ return -EINVAL; -+ } -+ -+ pv = nbp_get_vlan_info(p); - } - -- pv = nbp_get_vlan_info(p); - if (vid != VLAN_N_VID) { - if (!pv || !test_bit(vid, pv->vlan_bitmap)) { - pr_info("bridge: RTM_NEWNEIGH with unconfigured " -@@ -810,10 +817,16 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], - } - - /* VID was specified, so use it. */ -- err = __br_fdb_add(ndm, p, addr, nlh_flags, vid); -+ if (dev->priv_flags & IFF_EBRIDGE) -+ err = br_fdb_insert(br, NULL, addr, vid); -+ else -+ err = __br_fdb_add(ndm, p, addr, nlh_flags, vid); - } else { - if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) { -- err = __br_fdb_add(ndm, p, addr, nlh_flags, 0); -+ if (dev->priv_flags & IFF_EBRIDGE) -+ err = br_fdb_insert(br, NULL, addr, 0); -+ else -+ err = __br_fdb_add(ndm, p, addr, nlh_flags, 0); - goto out; - } - -@@ -822,7 +835,10 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], - * vlan on this port. - */ - for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { -- err = __br_fdb_add(ndm, p, addr, nlh_flags, vid); -+ if (dev->priv_flags & IFF_EBRIDGE) -+ err = br_fdb_insert(br, NULL, addr, vid); -+ else -+ err = __br_fdb_add(ndm, p, addr, nlh_flags, vid); - if (err) - goto out; - } -@@ -884,6 +900,7 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], - int err; - struct net_port_vlans *pv; - unsigned short vid = VLAN_N_VID; -+ struct net_bridge *br; - - if (tb[NDA_VLAN]) { - if (nla_len(tb[NDA_VLAN]) != sizeof(unsigned short)) { -@@ -899,14 +916,22 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], - return -EINVAL; - } - } -- p = br_port_get_rtnl(dev); -- if (p == NULL) { -- pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n", -- dev->name); -- return -EINVAL; -+ -+ if (dev->priv_flags & IFF_EBRIDGE) { -+ br = netdev_priv(dev); -+ pv = br_get_vlan_info(br); -+ } else { -+ -+ p = br_port_get_rtnl(dev); -+ if (p == NULL) { -+ pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n", -+ dev->name); -+ return -EINVAL; -+ } -+ -+ pv = nbp_get_vlan_info(p); - } - -- pv = nbp_get_vlan_info(p); - if (vid != VLAN_N_VID) { - /* vlan could have been deleted but we should still - * attempt to delete the fdb. Ideally, when vlan is -@@ -920,10 +945,20 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], - } - */ - -- err = __br_fdb_delete(p, addr, vid); -+ if (dev->priv_flags & IFF_EBRIDGE) { -+ spin_lock_bh(&br->hash_lock); -+ err = fdb_delete_by_addr(br, addr, vid); -+ spin_unlock_bh(&br->hash_lock); -+ } else -+ err = __br_fdb_delete(p, addr, vid); - } else { - if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) { -- err = __br_fdb_delete(p, addr, 0); -+ if (dev->priv_flags & IFF_EBRIDGE) { -+ spin_lock_bh(&br->hash_lock); -+ err = fdb_delete_by_addr(br, addr, 0); -+ spin_unlock_bh(&br->hash_lock); -+ } else -+ err = __br_fdb_delete(p, addr, 0); - goto out; - } - -@@ -933,7 +968,12 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], - */ - err = -ENOENT; - for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { -- err &= __br_fdb_delete(p, addr, vid); -+ if (dev->priv_flags & IFF_EBRIDGE) { -+ spin_lock_bh(&br->hash_lock); -+ err &= fdb_delete_by_addr(br, addr, vid); -+ spin_unlock_bh(&br->hash_lock); -+ } else -+ err &= __br_fdb_delete(p, addr, vid); - } - } - out: diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-del-fix.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-del-fix.patch deleted file mode 100644 index ccc21a12..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-del-fix.patch +++ /dev/null @@ -1,65 +0,0 @@ -When deleting an fdb as a result of a RTM_DELNEIGH message, check if the -dst matches so that it does not delete on behalf of the wrong interface. - -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 924e87d..eb16520 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -814,13 +814,30 @@ int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr, - return 0; - } - -+int fdb_delete_by_addr_and_port(struct net_bridge_port *p, -+ const unsigned char *addr, u16 vid) -+{ -+ struct hlist_head *head = &p->br->hash[br_mac_hash(addr, vid)]; -+ struct net_bridge_fdb_entry *fdb; -+ -+ fdb = fdb_find(head, addr, vid); -+ if (!fdb) -+ return -ENOENT; -+ -+ if (fdb->dst != p) -+ return -ENOENT; -+ -+ fdb_delete(p->br, fdb); -+ return 0; -+} -+ - static int __br_fdb_delete(struct net_bridge_port *p, - const unsigned char *addr, u16 vid) - { - int err; - - spin_lock_bh(&p->br->hash_lock); -- err = fdb_delete_by_addr(p->br, addr, vid); -+ err = fdb_delete_by_addr_and_port(p, addr, vid); - spin_unlock_bh(&p->br->hash_lock); - - return err; -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index a7f764d..cc204a1 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -397,6 +397,8 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, - const unsigned char *addr, u16 vid); - int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr, u16 vid); - -+int fdb_delete_by_addr_and_port(struct net_bridge_port *p, -+ const unsigned char *addr, u16 vid); - int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, const unsigned char *addr); - int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev, -diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c -index 6317f3c..90732f5 100644 ---- a/net/bridge/br_vlan.c -+++ b/net/bridge/br_vlan.c -@@ -363,7 +363,7 @@ int nbp_vlan_delete(struct net_bridge_port *port, u16 vid) - return -EINVAL; - - spin_lock_bh(&port->br->hash_lock); -- fdb_delete_by_addr(port->br, port->dev->dev_addr, vid); -+ fdb_delete_by_addr_and_port(port, port->dev->dev_addr, vid); - spin_unlock_bh(&port->br->hash_lock); - - return __vlan_del(pv, vid); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-learn-priority.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-learn-priority.patch deleted file mode 100644 index fa8c29ec..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-learn-priority.patch +++ /dev/null @@ -1,161 +0,0 @@ - - -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index 42a7c70..c71616e 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -219,6 +219,8 @@ enum { - IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */ - IFLA_BRPORT_LEARNING, /* mac learning */ - IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */ -+ IFLA_BRPORT_LEARN_PRIO = 253, /* fdb learn priority */ -+ IFLA_BRPORT_LEARN_FILTER, /* fdb learn filter */ - __IFLA_BRPORT_MAX - }; - #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 924e87d..f1b4eb1 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -466,10 +466,15 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, - /* address is already static (interface/bridge) so nop */ - return 0; - } else { -+ if ((fdb->dst != source) && source && fdb->dst && -+ source->learn_filter && -+ (fdb->dst->learn_prio > source->learn_prio)) -+ return 0; -+ - /* add an interface address over a learned one */ - br_warn(br, "adding interface %s with same address " - "as a received packet\n", -- source->dev->name); -+ source ? source->dev->name : br->dev->name); - } - fdb_delete(br, fdb); - } -@@ -520,6 +525,11 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, - source->dev->name); - } else { - /* fastpath: update of existing entry */ -+ if (fdb->dst && source && (fdb->dst != source) && -+ source->learn_filter && -+ (fdb->dst->learn_prio > source->learn_prio)) -+ return; -+ - fdb->dst = source; - fdb->updated = jiffies; - } -@@ -684,6 +694,10 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, - return -EEXIST; - - if (fdb->dst != source) { -+ if (source->learn_filter && source && fdb->dst && -+ (fdb->dst->learn_prio > source->learn_prio) && -+ !(flags & NLM_F_REPLACE)) -+ return 0; - fdb->dst = source; - modified = true; - } -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index 874907a..fcde1ca 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -152,8 +152,14 @@ static int br_handle_local_finish(struct sk_buff *skb) - u16 vid = 0; - - br_vlan_get_tag(skb, &vid); -- if (!br_hw_fwding_enabled && (p->flags & BR_LEARNING)) -+ if (!br_hw_fwding_enabled && (p->flags & BR_LEARNING)) { -+ if (vid == 0 && p->br->vlan_enabled) { -+ struct net_port_vlans *pv = nbp_get_vlan_info(p); -+ if (pv) -+ vid = br_get_pvid(pv); -+ } - br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid); -+ } - return 0; /* process further */ - } - -diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c -index 882072e..c86b0aa 100644 ---- a/net/bridge/br_netlink.c -+++ b/net/bridge/br_netlink.c -@@ -34,6 +34,8 @@ static inline size_t br_port_info_size(void) - + nla_total_size(1) /* IFLA_BRPORT_FAST_LEAVE */ - + nla_total_size(1) /* IFLA_BRPORT_LEARNING */ - + nla_total_size(1) /* IFLA_BRPORT_UNICAST_FLOOD */ -+ + nla_total_size(1) /* IFLA_BRPORT_LEARN_PRIO */ -+ + nla_total_size(1) /* IFLA_BRPORT_LEARN_FILTER */ - + 0; - } - -@@ -58,6 +60,8 @@ static int br_port_fill_attrs(struct sk_buff *skb, - nla_put_u16(skb, IFLA_BRPORT_PRIORITY, p->priority) || - nla_put_u32(skb, IFLA_BRPORT_COST, p->path_cost) || - nla_put_u8(skb, IFLA_BRPORT_MODE, mode) || -+ nla_put_u8(skb, IFLA_BRPORT_LEARN_PRIO, p->learn_prio) || -+ nla_put_u8(skb, IFLA_BRPORT_LEARN_FILTER, p->learn_filter) || - nla_put_u8(skb, IFLA_BRPORT_GUARD, !!(p->flags & BR_BPDU_GUARD)) || - nla_put_u8(skb, IFLA_BRPORT_PROTECT, !!(p->flags & BR_ROOT_BLOCK)) || - nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE, !!(p->flags & BR_MULTICAST_FAST_LEAVE)) || -@@ -384,6 +388,8 @@ static const struct nla_policy ifla_brport_policy[IFLA_BRPORT_MAX + 1] = { - [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 }, - [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 }, - [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_LEARN_PRIO] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_LEARN_FILTER] = { .type = NLA_U8 }, - }; - - /* Change the state of the port and notify spanning tree */ -@@ -418,6 +424,18 @@ static void br_set_port_flag(struct net_bridge_port *p, struct nlattr *tb[], - } - } - -+static int br_set_port_learn_prio(struct net_bridge_port *p, u8 prio) -+{ -+ p->learn_prio = prio; -+ return 0; -+} -+ -+static int br_set_port_learn_filter(struct net_bridge_port *p, u8 enable) -+{ -+ p->learn_filter = enable; -+ return 0; -+} -+ - /* Process bridge protocol info on port */ - static int br_setport(struct net_bridge_port *p, struct nlattr *tb[]) - { -@@ -447,6 +465,18 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[]) - if (err) - return err; - } -+ -+ if (tb[IFLA_BRPORT_LEARN_PRIO]) { -+ err = br_set_port_learn_prio(p, nla_get_u8(tb[IFLA_BRPORT_LEARN_PRIO])); -+ if (err) -+ return err; -+ } -+ -+ if (tb[IFLA_BRPORT_LEARN_FILTER]) { -+ err = br_set_port_learn_filter(p, nla_get_u8(tb[IFLA_BRPORT_LEARN_FILTER])); -+ if (err) -+ return err; -+ } - return 0; - } - -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index c80f94d..a0cc902 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -195,6 +195,8 @@ struct net_bridge_port - #ifdef CONFIG_BRIDGE_VLAN_FILTERING - struct net_port_vlans __rcu *vlan_info; - #endif -+ u8 learn_prio; -+ u8 learn_filter; - }; - - #define br_port_exists(dev) (dev->priv_flags & IFF_BRIDGE_PORT) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-mdb-vlan-fix.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-mdb-vlan-fix.patch deleted file mode 100644 index ffc719cb..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-mdb-vlan-fix.patch +++ /dev/null @@ -1,161 +0,0 @@ -Fixes for fdb and mdb for the new bridge driver. - -diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h -index 51eba88..cf81969 100644 ---- a/include/linux/if_bridge.h -+++ b/include/linux/if_bridge.h -@@ -95,7 +95,7 @@ struct __fdb_entry { - __u32 ageing_timer_value; - __u8 port_hi; - __u8 pad0; -- __u16 unused; -+ __u16 vlan; - }; - - /* Bridge Flags */ -@@ -171,6 +171,7 @@ enum { - - struct br_port_msg { - __u8 family; -+ __u16 vlan; - __u32 ifindex; - }; - -@@ -185,6 +186,7 @@ struct br_mdb_entry { - struct in6_addr ip6; - } u; - __be16 proto; -+ __be16 vlan_id; - } addr; - }; - -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index ac4c109..c0e733e 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -346,6 +346,7 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf, - fe->is_local = f->is_local; - if (!f->is_static) - fe->ageing_timer_value = jiffies_delta_to_clock_t(jiffies - f->updated); -+ fe->vlan = f->vlan_id; - ++fe; - ++num; - } -@@ -814,11 +815,17 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], - - pv = nbp_get_vlan_info(p); - if (vid != VLAN_N_VID) { -+ /* vlan could have been deleted but we should still -+ * attempt to delete the fdb. Ideally, when vlan is -+ * being deleted, all the fdb entries for the vlan should -+ * be flushed. Need to look into that. -+ - if (!pv || !test_bit(vid, pv->vlan_bitmap)) { - pr_info("bridge: RTM_DELNEIGH with unconfigured " - "vlan %d on port %s\n", vid, dev->name); - return -EINVAL; - } -+ */ - - err = __br_fdb_delete(p, addr, vid); - } else { -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index 29c7b96..c3d9406 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -94,6 +94,7 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, - e.addr.u.ip6 = p->addr.u.ip6; - #endif - e.addr.proto = p->addr.proto; -+ e.addr.vlan_id = p->addr.vid; - if (nla_put(skb, MDBA_MDB_ENTRY_INFO, sizeof(e), &e)) { - nla_nest_cancel(skb, nest2); - err = -EMSGSIZE; -@@ -238,6 +239,7 @@ void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, - memset(&entry, 0, sizeof(entry)); - entry.ifindex = port->dev->ifindex; - entry.addr.proto = group->proto; -+ entry.addr.vlan_id = group->vid; - entry.addr.u.ip4 = group->u.ip4; - #if IS_ENABLED(CONFIG_IPV6) - entry.addr.u.ip6 = group->u.ip6; -@@ -248,7 +250,7 @@ void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, - - static int nlmsg_populate_rtr_fill(struct sk_buff *skb, - struct net_device *dev, -- int ifindex, u32 pid, -+ int ifindex, u16 vid, u32 pid, - u32 seq, int type, unsigned int flags) - { - struct nlmsghdr *nlh; -@@ -263,6 +265,7 @@ static int nlmsg_populate_rtr_fill(struct sk_buff *skb, - memset(bpm, 0, sizeof(*bpm)); - bpm->family = AF_BRIDGE; - bpm->ifindex = dev->ifindex; -+ bpm->vlan = vid; - nest = nla_nest_start(skb, MDBA_ROUTER); - if (nest == NULL) - goto cancel; -@@ -293,18 +296,37 @@ void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, - struct sk_buff *skb; - int err = -ENOBUFS; - int ifindex = port ? port->dev->ifindex : 0; -+ struct net_port_vlans *pv = nbp_get_vlan_info(port); -+ u16 vid; -+ -+ if (!pv) { -+ skb = nlmsg_new(rtnl_rtr_nlmsg_size(), GFP_ATOMIC); -+ if (!skb) -+ goto errout; -+ -+ err = nlmsg_populate_rtr_fill(skb, dev, ifindex, 0, 0, 0, type, NTF_SELF); -+ if (err < 0) { -+ kfree_skb(skb); -+ goto errout; -+ } -+ -+ rtnl_notify(skb, net, 0, RTNLGRP_MDB, NULL, GFP_ATOMIC); -+ return; -+ } - -- skb = nlmsg_new(rtnl_rtr_nlmsg_size(), GFP_ATOMIC); -- if (!skb) -- goto errout; -+ for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { -+ skb = nlmsg_new(rtnl_rtr_nlmsg_size(), GFP_ATOMIC); -+ if (!skb) -+ goto errout; - -- err = nlmsg_populate_rtr_fill(skb, dev, ifindex, 0, 0, type, NTF_SELF); -- if (err < 0) { -- kfree_skb(skb); -- goto errout; -- } -+ err = nlmsg_populate_rtr_fill(skb, dev, ifindex, vid, 0, 0, type, NTF_SELF); -+ if (err < 0) { -+ kfree_skb(skb); -+ goto errout; -+ } - -- rtnl_notify(skb, net, 0, RTNLGRP_MDB, NULL, GFP_ATOMIC); -+ rtnl_notify(skb, net, 0, RTNLGRP_MDB, NULL, GFP_ATOMIC); -+ } - return; - errout: - rtnl_set_sk_err(net, RTNLGRP_MDB, err); -@@ -440,6 +462,7 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br, - return -EINVAL; - - ip.proto = entry->addr.proto; -+ ip.vid = entry->addr.vlan_id; - if (ip.proto == htons(ETH_P_IP)) - ip.u.ip4 = entry->addr.u.ip4; - #if IS_ENABLED(CONFIG_IPV6) -@@ -486,6 +509,7 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry) - return -EINVAL; - - ip.proto = entry->addr.proto; -+ ip.vid = entry->addr.vlan_id; - if (ip.proto == htons(ETH_P_IP)) { - if (timer_pending(&br->ip4_querier.timer)) - return -EBUSY; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-netlink-dump-interface-in-par-with-brctl.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-netlink-dump-interface-in-par-with-brctl.patch deleted file mode 100644 index 0cd4d43f..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-netlink-dump-interface-in-par-with-brctl.patch +++ /dev/null @@ -1,210 +0,0 @@ -(picked up from upstream: https://marc.info/?l=linux-netdev&m=140447512608549&w=2) - -[net-next-2.6 PATCH v6 2/2] bridge: netlink dump interface at par with brctl - -Actually better than brctl showmacs because we can filter by bridge -port in the kernel. -The current bridge netlink interface doesnt scale when you have many -bridges each with large fdbs or even bridges with many bridge ports - -And now for the science non-fiction novel you have all been -waiting for.. - -//lets see what bridge ports we have -root@moja-1:/configs/may30-iprt/bridge# ./bridge link show -8: eth1 state DOWN : mtu 1500 master br0 state -disabled priority 32 cost 19 -17: sw1-p1 state DOWN : mtu 1500 master br0 state -disabled priority 32 cost 100 - -// show all.. -root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show -33:33:00:00:00:01 dev bond0 self permanent -33:33:00:00:00:01 dev dummy0 self permanent -33:33:00:00:00:01 dev ifb0 self permanent -33:33:00:00:00:01 dev ifb1 self permanent -33:33:00:00:00:01 dev eth0 self permanent -01:00:5e:00:00:01 dev eth0 self permanent -33:33:ff:22:01:01 dev eth0 self permanent -02:00:00:12:01:02 dev eth1 vlan 0 master br0 permanent -00:17:42:8a:b4:05 dev eth1 vlan 0 master br0 permanent -00:17:42:8a:b4:07 dev eth1 self permanent -33:33:00:00:00:01 dev eth1 self permanent -33:33:00:00:00:01 dev gretap0 self permanent -da:ac:46:27:d9:53 dev sw1-p1 vlan 0 master br0 permanent -33:33:00:00:00:01 dev sw1-p1 self permanent - -//filter by bridge -root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show br br0 -02:00:00:12:01:02 dev eth1 vlan 0 master br0 permanent -00:17:42:8a:b4:05 dev eth1 vlan 0 master br0 permanent -00:17:42:8a:b4:07 dev eth1 self permanent -33:33:00:00:00:01 dev eth1 self permanent -da:ac:46:27:d9:53 dev sw1-p1 vlan 0 master br0 permanent -33:33:00:00:00:01 dev sw1-p1 self permanent - -// bridge sw1 has no ports attached.. -root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show br sw1 - -//filter by port -root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show brport eth1 -02:00:00:12:01:02 vlan 0 master br0 permanent -00:17:42:8a:b4:05 vlan 0 master br0 permanent -00:17:42:8a:b4:07 self permanent -33:33:00:00:00:01 self permanent - -// filter by port + bridge -root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show br br0 brport -sw1-p1 -da:ac:46:27:d9:53 vlan 0 master br0 permanent -33:33:00:00:00:01 self permanent - -// for shits and giggles (as they say in New Brunswick), lets -// change the mac that br0 uses -// Note: a magical fdb entry with no brport is added ... -root@moja-1:/configs/may30-iprt/bridge# ip link set dev br0 address -02:00:00:12:01:04 - -// lets see if we can see the unicorn .. -root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show -33:33:00:00:00:01 dev bond0 self permanent -33:33:00:00:00:01 dev dummy0 self permanent -33:33:00:00:00:01 dev ifb0 self permanent -33:33:00:00:00:01 dev ifb1 self permanent -33:33:00:00:00:01 dev eth0 self permanent -01:00:5e:00:00:01 dev eth0 self permanent -33:33:ff:22:01:01 dev eth0 self permanent -02:00:00:12:01:02 dev eth1 vlan 0 master br0 permanent -00:17:42:8a:b4:05 dev eth1 vlan 0 master br0 permanent -00:17:42:8a:b4:07 dev eth1 self permanent -33:33:00:00:00:01 dev eth1 self permanent -33:33:00:00:00:01 dev gretap0 self permanent -02:00:00:12:01:04 dev br0 vlan 0 master br0 permanent <=== there it is -da:ac:46:27:d9:53 dev sw1-p1 vlan 0 master br0 permanent -33:33:00:00:00:01 dev sw1-p1 self permanent - -//can we see it if we filter by bridge? -root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show br br0 -02:00:00:12:01:02 dev eth1 vlan 0 master br0 permanent -00:17:42:8a:b4:05 dev eth1 vlan 0 master br0 permanent -00:17:42:8a:b4:07 dev eth1 self permanent -33:33:00:00:00:01 dev eth1 self permanent -02:00:00:12:01:04 dev br0 vlan 0 master br0 permanent <=== there it is -da:ac:46:27:d9:53 dev sw1-p1 vlan 0 master br0 permanent -33:33:00:00:00:01 dev sw1-p1 self permanent - -Signed-off-by: Jamal Hadi Salim - -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 961fbfd..f01ff2e 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -646,9 +646,18 @@ int br_fdb_dump(struct sk_buff *skb, - if (idx < cb->args[0]) - goto skip; - -- if (filter_dev && (!f->dst || !f->dst->dev || -- f->dst->dev != filter_dev)) -- goto skip; -+ if (filter_dev && -+ (!f->dst || f->dst->dev != filter_dev)) { -+ if (filter_dev != dev) -+ goto skip; -+ /* !f->dst is a speacial case for bridge -+ * It means the MAC belongs to the bridge -+ * Therefore need a little more filtering -+ * we only want to dump the !f->dst case -+ */ -+ if (f->dst) -+ goto skip; -+ } - - if (fdb_fill_info(skb, br, f, - NETLINK_CB(cb->skb).pid, -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index b52d6e2..c3aa410 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -2252,26 +2252,67 @@ EXPORT_SYMBOL(ndo_dflt_fdb_dump); - - static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) - { -- int idx = 0; -- struct net *net = sock_net(skb->sk); - struct net_device *dev; -+ struct nlattr *tb[IFLA_MAX+1]; -+ struct net_device *bdev = NULL; -+ struct net_device *br_dev = NULL; -+ const struct net_device_ops *ops = NULL; -+ const struct net_device_ops *cops = NULL; -+ struct ifinfomsg *ifm = nlmsg_data(cb->nlh); -+ struct net *net = sock_net(skb->sk); -+ int brport_idx = 0; -+ int br_idx = 0; -+ int idx = 0; -+ -+ if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, -+ ifla_policy) == 0) { -+ if (tb[IFLA_MASTER]) -+ br_idx = nla_get_u32(tb[IFLA_MASTER]); -+ } - -- rcu_read_lock(); -- for_each_netdev_rcu(net, dev) { -- if (dev->priv_flags & IFF_BRIDGE_PORT) { -- struct net_device *master = dev->master; -- const struct net_device_ops *ops = master->netdev_ops; -+ brport_idx = ifm->ifi_index; - -- if (ops->ndo_fdb_dump) -- idx = ops->ndo_fdb_dump(skb, cb, dev, NULL, -- idx); -- } -+ if (br_idx) { -+ br_dev = __dev_get_by_index(net, br_idx); -+ if (!br_dev) -+ return -ENODEV; -+ -+ ops = br_dev->netdev_ops; -+ bdev = br_dev; -+ } -+ -+ for_each_netdev(net, dev) { -+ if (brport_idx && (dev->ifindex != brport_idx)) -+ continue; -+ -+ if (!br_idx) { /* user did not specify a specific bridge */ -+ if (dev->priv_flags & IFF_BRIDGE_PORT) { -+ br_dev = dev->master; -+ cops = br_dev->netdev_ops; -+ } -+ -+ bdev = dev; -+ } else { -+ if (dev != br_dev && -+ !(dev->priv_flags & IFF_BRIDGE_PORT)) -+ continue; -+ -+ if (br_dev != dev->master && -+ !(dev->priv_flags & IFF_EBRIDGE)) -+ continue; -+ -+ bdev = br_dev; -+ cops = ops; -+ } -+ -+ if (dev->priv_flags & IFF_BRIDGE_PORT) { -+ if (cops && cops->ndo_fdb_dump) -+ idx = cops->ndo_fdb_dump(skb, cb, br_dev, dev, -+ idx); -+ } - -- if (dev->netdev_ops->ndo_fdb_dump) -- idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, NULL, -- idx); -+ cops = NULL; - } -- rcu_read_unlock(); - - cb->args[0] = idx; - return skb->len; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-show-filter.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-show-filter.patch deleted file mode 100644 index 8db24977..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-show-filter.patch +++ /dev/null @@ -1,91 +0,0 @@ -(picked up from upstream: https://marc.info/?l=linux-netdev&m=140447512108548&w=2) - -[net-next-2.6 PATCH v6 1/2] bridge: fdb dumping takes a filter device - -Dumping a bridge fdb dumps every fdb entry -held. With this change we are going to filter -on selected bridge port. - -Signed-off-by: Jamal Hadi Salim > - -diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c -index 5c51530..2fdd4e8 100644 ---- a/drivers/net/vxlan.c -+++ b/drivers/net/vxlan.c -@@ -402,7 +402,7 @@ static int vxlan_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], - - /* Dump forwarding table */ - static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, -- struct net_device *dev, int idx) -+ struct net_device *dev, struct net_device *filter_dev, int idx) - { - struct vxlan_dev *vxlan = netdev_priv(dev); - unsigned int h; -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index c1f6a6e..ec21a37 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -990,6 +990,7 @@ struct net_device_ops { - int (*ndo_fdb_dump)(struct sk_buff *skb, - struct netlink_callback *cb, - struct net_device *dev, -+ struct net_device *filter_dev, - int idx); - int (*ndo_bridge_setlink)(struct net_device *dev, - struct nlmsghdr *nlh); -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index eb16520..961fbfd 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -629,6 +629,7 @@ errout: - int br_fdb_dump(struct sk_buff *skb, - struct netlink_callback *cb, - struct net_device *dev, -+ struct net_device *filter_dev, - int idx) - { - struct net_bridge *br = netdev_priv(dev); -@@ -645,6 +646,10 @@ int br_fdb_dump(struct sk_buff *skb, - if (idx < cb->args[0]) - goto skip; - -+ if (filter_dev && (!f->dst || !f->dst->dev || -+ f->dst->dev != filter_dev)) -+ goto skip; -+ - if (fdb_fill_info(skb, br, f, - NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index cc204a1..7ae7eeb 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -404,7 +404,7 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], - int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev, - const unsigned char *addr, u16 nlh_flags); - int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, -- struct net_device *dev, int idx); -+ struct net_device *dev, struct net_device *fdev, int idx); - - /* br_forward.c */ - void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb); -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 4f3d832..b52d6e2 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -2263,11 +2263,13 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) - const struct net_device_ops *ops = master->netdev_ops; - - if (ops->ndo_fdb_dump) -- idx = ops->ndo_fdb_dump(skb, cb, dev, idx); -+ idx = ops->ndo_fdb_dump(skb, cb, dev, NULL, -+ idx); - } - - if (dev->netdev_ops->ndo_fdb_dump) -- idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, idx); -+ idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, NULL, -+ idx); - } - rcu_read_unlock(); - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-show-fix-filter-by-bridge.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-show-fix-filter-by-bridge.patch deleted file mode 100644 index 9566cba8..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fdb-show-fix-filter-by-bridge.patch +++ /dev/null @@ -1,33 +0,0 @@ -This patch is a fix for bridge fdb show filter on -bridge device - -'bridge fdb show dev br0' after this patch will show -only fdb entries with bridge br0 as dev - -Signed-off-by: Roopa Prabhu - -net/core/rtnetlink.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 3d31428..296533f 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -2421,8 +2421,15 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) - cops = ops; - } - -- if (fdev && (fdev->master != br_dev)) -- continue; -+ if (fdev) { -+ if (fdev->priv_flags & IFF_EBRIDGE) { -+ if (fdev != br_dev) -+ continue; -+ } else { -+ if (fdev->master != br_dev) -+ continue; -+ } -+ } - - if (cops && cops->ndo_fdb_dump) - idx = cops->ndo_fdb_dump(skb, cb, br_dev, fdev, idx); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-filtering-support-for-default-pvid.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-filtering-support-for-default-pvid.patch deleted file mode 100644 index 3f33f541..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-filtering-support-for-default-pvid.patch +++ /dev/null @@ -1,210 +0,0 @@ -Currently when vlan filtering is turned on on the bridge, the bridge -will drop all traffic untill the user configures the filter. This -isn't very nice for ports that don't care about vlans and just -want untagged traffic. - -A concept of a default_pvid was recently introduced. This patch -adds filtering support for default_pvid. Now, ports that don't -care about vlans and don't define there own filter will belong -to the VLAN of the default_pvid and continue to receive untagged -traffic. - -This filtering can be disabled by setting default_pvid to 0. - -Signed-off-by: Vladislav Yasevich - -diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c -index 48161b6..780076b 100644 ---- a/net/bridge/br_if.c -+++ b/net/bridge/br_if.c -@@ -439,6 +439,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) - if (br->dev->needed_headroom < dev->needed_headroom) - br->dev->needed_headroom = dev->needed_headroom; - -+ if (nbp_vlan_init(p)) -+ netdev_err(dev, "failed to initialize vlan filtering on this port\n"); -+ - spin_lock_bh(&br->lock); - changed_addr = br_stp_recalculate_bridge_id(br); - -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 984935c..2d70a48 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -629,6 +629,7 @@ int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags); - int nbp_vlan_delete(struct net_bridge_port *port, u16 vid); - void nbp_vlan_flush(struct net_bridge_port *port); - bool nbp_vlan_find(struct net_bridge_port *port, u16 vid); -+int nbp_vlan_init(struct net_bridge_port *port); - - static inline struct net_port_vlans *br_get_vlan_info( - const struct net_bridge *br) -@@ -661,6 +662,9 @@ static inline int br_vlan_get_tag(const struct sk_buff *skb, u16 *vid) - - static inline u16 br_get_pvid(const struct net_port_vlans *v) - { -+ if (!v) -+ return 0; -+ - smp_rmb(); - return v->pvid; - } -@@ -713,6 +717,11 @@ static inline bool br_vlan_find(struct net_bridge *br, u16 vid) - return false; - } - -+static inline int br_vlan_init(struct net_bridge *br) -+{ -+ return 0; -+} -+ - static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) - { - return -EOPNOTSUPP; -@@ -743,6 +752,11 @@ static inline bool nbp_vlan_find(struct net_bridge_port *port, u16 vid) - return false; - } - -+static inline int nbp_vlan_init(struct net_bridge_port *port) -+{ -+ return 0; -+} -+ - static inline u16 br_vlan_get_tag(const struct sk_buff *skb, u16 *tag) - { - return 0; -diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c -index ac0ca81..8e87ef6 100644 ---- a/net/bridge/br_vlan.c -+++ b/net/bridge/br_vlan.c -@@ -360,6 +360,104 @@ unlock: - return 0; - } - -+static bool vlan_default_pvid(struct net_port_vlans *pv, u16 vid) -+{ -+ return pv && vid == pv->pvid && test_bit(vid, pv->untagged_bitmap); -+} -+ -+static void br_vlan_disable_default_pvid(struct net_bridge *br) -+{ -+ struct net_bridge_port *p; -+ u16 pvid = br->default_pvid; -+ -+ /* Disable default_pvid on all ports where it is still -+ * configured. -+ */ -+ if (vlan_default_pvid(br_get_vlan_info(br), pvid)) -+ br_vlan_delete(br, pvid); -+ -+ list_for_each_entry(p, &br->port_list, list) { -+ if (vlan_default_pvid(nbp_get_vlan_info(p), pvid)) -+ nbp_vlan_delete(p, pvid); -+ } -+ -+ br->default_pvid = 0; -+} -+ -+static int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid) -+{ -+ struct net_bridge_port *p; -+ u16 old_pvid; -+ int err = 0; -+ unsigned long *changed; -+ -+ changed = kcalloc(BITS_TO_LONGS(BR_MAX_PORTS), sizeof(unsigned long), -+ GFP_KERNEL); -+ if (!changed) -+ return -ENOMEM; -+ -+ old_pvid = br->default_pvid; -+ -+ /* Update default_pvid config only if we do not conflict with -+ * user configuration. -+ */ -+ if ((!old_pvid || vlan_default_pvid(br_get_vlan_info(br), old_pvid)) && -+ !br_vlan_find(br, pvid)) { -+ err = br_vlan_add(br, pvid, -+ BRIDGE_VLAN_INFO_PVID | -+ BRIDGE_VLAN_INFO_UNTAGGED); -+ if (err) -+ goto out; -+ br_vlan_delete(br, old_pvid); -+ set_bit(0, changed); -+ } -+ -+ list_for_each_entry(p, &br->port_list, list) { -+ /* Update default_pvid config only if we do not conflict with -+ * user configuration. -+ */ -+ if ((old_pvid && -+ !vlan_default_pvid(nbp_get_vlan_info(p), old_pvid)) || -+ nbp_vlan_find(p, pvid)) -+ continue; -+ -+ err = nbp_vlan_add(p, pvid, -+ BRIDGE_VLAN_INFO_PVID | -+ BRIDGE_VLAN_INFO_UNTAGGED); -+ if (err) -+ goto err_port; -+ nbp_vlan_delete(p, old_pvid); -+ set_bit(p->port_no, changed); -+ } -+ -+ br->default_pvid = pvid; -+ -+out: -+ kfree(changed); -+ return err; -+ -+err_port: -+ list_for_each_entry_continue_reverse(p, &br->port_list, list) { -+ if (!test_bit(p->port_no, changed)) -+ continue; -+ -+ if (old_pvid) -+ nbp_vlan_add(p, old_pvid, -+ BRIDGE_VLAN_INFO_PVID | -+ BRIDGE_VLAN_INFO_UNTAGGED); -+ nbp_vlan_delete(p, pvid); -+ } -+ -+ if (test_bit(0, changed)) { -+ if (old_pvid) -+ br_vlan_add(br, old_pvid, -+ BRIDGE_VLAN_INFO_PVID | -+ BRIDGE_VLAN_INFO_UNTAGGED); -+ br_vlan_delete(br, pvid); -+ } -+ goto out; -+} -+ - int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val) - { - u16 pvid = val; -@@ -391,9 +489,11 @@ unlock: - return err; - } - --void br_vlan_init(struct net_bridge *br) -+int br_vlan_init(struct net_bridge *br) - { - br->default_pvid = 1; -+ return br_vlan_add(br, 1, -+ BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED); - } - - /* Must be protected by RTNL. -@@ -487,3 +587,12 @@ out: - rcu_read_unlock(); - return found; - } -+ -+int nbp_vlan_init(struct net_bridge_port *p) -+{ -+ return p->br->default_pvid ? -+ nbp_vlan_add(p, p->br->default_pvid, -+ BRIDGE_VLAN_INFO_PVID | -+ BRIDGE_VLAN_INFO_UNTAGGED) : -+ 0; -+} diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-crash-when-set-mac-address-of-br-interfac.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-crash-when-set-mac-address-of-br-interfac.patch deleted file mode 100644 index 2f2106bd..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-crash-when-set-mac-address-of-br-interfac.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 9880f0b4fa0580224e8ca35be30bd64cde793965 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: fix crash when set mac address of br interface - -commit 9b46922e15f4d9d2aedcd320c3b7f7f54d956da7 upstream. - -When I tried to set mac address of a bridge interface to a mac -address which already learned on this bridge, I got system hang. - -The cause is straight forward: function br_fdb_change_mac_address -calls fdb_insert with NULL source nbp. Then an fdb lookup is -performed. If an fdb entry is found and it's local, it's OK. But -if it's not local, source is dereferenced for printk without NULL -check. - -Signed-off-by: Hong Zhiguo -Signed-off-by: David S. Miller - -Conflicts: - net/bridge/br_fdb.c - -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 9063201..91d7087 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -477,7 +477,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, - /* add an interface address over a learned one */ - br_warn(br, "adding interface %s with same address " - "as a received packet\n", -- source->dev->name); -+ source ? source->dev->name : br->dev->name); - } - fdb_delete(br, fdb); - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-endian.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-endian.patch deleted file mode 100644 index f1f3832b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-endian.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 4715213d9cf40285492fff4092bb1fa8e982f632 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: fix endian - -mld->mld_maxdelay is net endian, so we should use ntohs, not htons - -CC: YOSHIFUJI Hideaki -Signed-off-by: Li RongQing -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index bb0d898..f7165b4 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1179,7 +1179,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, - goto out; - } - mld = (struct mld_msg *) icmp6_hdr(skb); -- max_delay = msecs_to_jiffies(htons(mld->mld_maxdelay)); -+ max_delay = msecs_to_jiffies(ntohs(mld->mld_maxdelay)); - if (max_delay) - group = &mld->mld_mca; - } else if (skb->len >= sizeof(*mld2q)) { diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-fdb-show-filter.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-fdb-show-filter.patch deleted file mode 100644 index 8fad9e8b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-fdb-show-filter.patch +++ /dev/null @@ -1,129 +0,0 @@ -Fixed several fdb show filter issues. - -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 038ef86..5e93fc6 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -664,7 +664,7 @@ int br_fdb_dump(struct sk_buff *skb, - cb->nlh->nlmsg_seq, - RTM_NEWNEIGH, - NLM_F_MULTI) < 0) -- break; -+ return idx; - skip: - ++idx; - } -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index c3aa410..cff4cb9 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -2253,66 +2253,63 @@ EXPORT_SYMBOL(ndo_dflt_fdb_dump); - static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) - { - struct net_device *dev; -- struct nlattr *tb[IFLA_MAX+1]; -- struct net_device *bdev = NULL; -- struct net_device *br_dev = NULL; -- const struct net_device_ops *ops = NULL; -- const struct net_device_ops *cops = NULL; -- struct ifinfomsg *ifm = nlmsg_data(cb->nlh); -- struct net *net = sock_net(skb->sk); -- int brport_idx = 0; -- int br_idx = 0; -- int idx = 0; -- -- if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, -+ struct nlattr *tb[IFLA_MAX+1]; -+ struct net_device *fdev = NULL; -+ struct net_device *br_dev = NULL; -+ const struct net_device_ops *ops = NULL; -+ const struct net_device_ops *cops = NULL; -+ struct ifinfomsg *ifm = nlmsg_data(cb->nlh); -+ struct net *net = sock_net(skb->sk); -+ int brport_idx = 0; -+ int br_idx = 0; -+ int idx = 0; -+ -+ rcu_read_lock(); -+ if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, - ifla_policy) == 0) { -- if (tb[IFLA_MASTER]) -- br_idx = nla_get_u32(tb[IFLA_MASTER]); -- } -+ if (tb[IFLA_MASTER]) -+ br_idx = nla_get_u32(tb[IFLA_MASTER]); -+ } - -- brport_idx = ifm->ifi_index; -+ brport_idx = ifm->ifi_index; - -- if (br_idx) { -- br_dev = __dev_get_by_index(net, br_idx); -- if (!br_dev) -- return -ENODEV; -+ if (br_idx) { -+ br_dev = __dev_get_by_index(net, br_idx); -+ if (!br_dev) -+ return -ENODEV; - -- ops = br_dev->netdev_ops; -- bdev = br_dev; -- } -+ ops = br_dev->netdev_ops; -+ } - -- for_each_netdev(net, dev) { -- if (brport_idx && (dev->ifindex != brport_idx)) -- continue; -+ if (brport_idx) { -+ fdev = __dev_get_by_index(net, brport_idx); -+ if (!fdev) -+ return -ENODEV; -+ } - -+ for_each_netdev(net, dev) { -+ if (dev->priv_flags & IFF_EBRIDGE) { - if (!br_idx) { /* user did not specify a specific bridge */ -- if (dev->priv_flags & IFF_BRIDGE_PORT) { -- br_dev = dev->master; -- cops = br_dev->netdev_ops; -- } -- -- bdev = dev; -+ br_dev = dev; -+ cops = br_dev->netdev_ops; - } else { -- if (dev != br_dev && -- !(dev->priv_flags & IFF_BRIDGE_PORT)) -+ if (dev != br_dev) - continue; -- -- if (br_dev != dev->master && -- !(dev->priv_flags & IFF_EBRIDGE)) -- continue; -- -- bdev = br_dev; - cops = ops; - } - -- if (dev->priv_flags & IFF_BRIDGE_PORT) { -- if (cops && cops->ndo_fdb_dump) -- idx = cops->ndo_fdb_dump(skb, cb, br_dev, dev, -- idx); -- } -+ if (fdev && (fdev->master != br_dev)) -+ continue; -+ -+ if (cops && cops->ndo_fdb_dump) -+ idx = cops->ndo_fdb_dump(skb, cb, br_dev, fdev, idx); -+ continue; -+ } - -- cops = NULL; -+ if (dev->netdev_ops->ndo_fdb_dump) -+ idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, NULL, idx); - } -+ rcu_read_unlock(); - - cb->args[0] = idx; - return skb->len; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-fdb-update-notify.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-fdb-update-notify.patch deleted file mode 100644 index 6495422c..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-fdb-update-notify.patch +++ /dev/null @@ -1,70 +0,0 @@ -(Below patch is modified from upstream version: - changelog: upstream changes only fdb->used, if none - of the fdb fields change. Which seems right. - But we want the age shown by brctl showmacs - to update (we are using the - fdb update mechanism to update the age). - and brctl uses the fdb->updated field. - So, this patch has been modified to update - both fdb->used and fdb->updated -) - - -From b0a397fb352e65e3b6501dca9662617a18862ef1 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: Add fdb dst check during fdb update - -Current bridge fdb update code does not seem to update the port -during fdb update. This patch adds a check for fdb dst (port) -change during fdb update. Also rearranges the call to -fdb_notify to send only one notification for create and update. - -Changelog: -v2 - Change notify flag to bool - -Signed-off-by: Roopa Prabhu -Signed-off-by: Stephen Hemminger -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 6274732..d7ffc4b 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -566,6 +566,7 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, - struct net_bridge *br = source->br; - struct hlist_head *head = &br->hash[br_mac_hash(addr)]; - struct net_bridge_fdb_entry *fdb; -+ bool modified = false; - - fdb = fdb_find(head, addr); - if (fdb == NULL) { -@@ -575,10 +576,15 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, - fdb = fdb_create(head, source, addr); - if (!fdb) - return -ENOMEM; -- fdb_notify(br, fdb, RTM_NEWNEIGH); -+ modified = true; - } else { - if (flags & NLM_F_EXCL) - return -EEXIST; -+ -+ if (fdb->dst != source) { -+ fdb->dst = source; -+ modified = true; -+ } - } - - if (fdb_to_nud(fdb) != state) { -@@ -590,7 +596,12 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, - } else - fdb->is_local = fdb->is_static = 0; - -- fdb->updated = fdb->used = jiffies; -+ modified = true; -+ } -+ -+ fdb->used = jiffies; -+ if (modified) { -+ fdb->updated = jiffies; - fdb_notify(br, fdb, RTM_NEWNEIGH); - } - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-icmpv6-endian-bug-and-other-sparse-warnin.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-icmpv6-endian-bug-and-other-sparse-warnin.patch deleted file mode 100644 index 47ab9617..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-icmpv6-endian-bug-and-other-sparse-warnin.patch +++ /dev/null @@ -1,33 +0,0 @@ -From eca2a43bb0d2c6ebd528be6acb30a88435abe307 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: fix icmpv6 endian bug and other sparse warnings - -Fix the warnings reported by sparse on recent bridge multicast -changes. Mostly just rcu annotation issues but in this case -sparse found a real bug! The ICMPv6 mld2 query mrc -values is in network byte order. - -Signed-off-by: Stephen Hemminger -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index a3d1957..8c638d6 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -628,7 +628,7 @@ out: - struct net_bridge_port_group *br_multicast_new_port_group( - struct net_bridge_port *port, - struct br_ip *group, -- struct net_bridge_port_group *next, -+ struct net_bridge_port_group __rcu *next, - unsigned char state) - { - struct net_bridge_port_group *p; -@@ -640,7 +640,7 @@ struct net_bridge_port_group *br_multicast_new_port_group( - p->addr = *group; - p->port = port; - p->state = state; -- p->next = next; -+ rcu_assign_pointer(p->next, next); - hlist_add_head(&p->mglist, &port->mglist); - setup_timer(&p->timer, br_multicast_port_group_expired, - (unsigned long)p); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-link-local-rx-drop-count.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-link-local-rx-drop-count.patch deleted file mode 100644 index 52c989f2..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-link-local-rx-drop-count.patch +++ /dev/null @@ -1,44 +0,0 @@ -Link local L2 frames received on bridge member port are counted as dropped -on the interface even though they are actually delivered and consumed. -This is to fix the mis-accounting. - -diff --git a/net/core/dev.c b/net/core/dev.c -index 1b14767..ef84f5a 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -3241,6 +3241,8 @@ static int __netif_receive_skb(struct sk_buff *skb) - bool deliver_exact = false; - int ret = NET_RX_DROP; - __be16 type; -+ bool already_delivered = false; -+ bool rx_handler_passed = false; - - if (!netdev_tstamp_prequeue) - net_timestamp_check(skb); -@@ -3311,6 +3313,8 @@ ncls: - if (pt_prev) { - ret = deliver_skb(skb, pt_prev, orig_dev); - pt_prev = NULL; -+ if (ret == NET_RX_SUCCESS) -+ already_delivered = true; - } - switch (rx_handler(&skb)) { - case RX_HANDLER_CONSUMED: -@@ -3321,6 +3325,7 @@ ncls: - case RX_HANDLER_EXACT: - deliver_exact = true; - case RX_HANDLER_PASS: -+ rx_handler_passed = true; - break; - default: - BUG(); -@@ -3348,7 +3353,8 @@ ncls: - if (pt_prev) { - ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); - } else { -- atomic_long_inc(&skb->dev->rx_dropped); -+ if (!(already_delivered && rx_handler_passed)) -+ atomic_long_inc(&skb->dev->rx_dropped); - kfree_skb(skb); - /* Jamal, now you will not able to escape explaining - * me how you were going to use this. :-) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-pvid-delete.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-pvid-delete.patch deleted file mode 100644 index 038f7fc0..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-pvid-delete.patch +++ /dev/null @@ -1,96 +0,0 @@ -When pvid is changed on a port, the old pvid should become tagged. - -When a vlan is deleted from a port, and it is also the pvid of the port, -the pvid should revert to the default value. - -The default pvid should not be allowed to be deleted. - -Pvid and default pvid concept does not apply to bridge itself. - -diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c -index 882072e..7cb55c6 100644 ---- a/net/bridge/br_netlink.c -+++ b/net/bridge/br_netlink.c -@@ -158,7 +158,7 @@ static int br_fill_ifinfo(struct sk_buff *skb, - /* send the pvid separately first */ - pvid = br_get_pvid(pv); - -- if (pvid != VLAN_N_VID) { -+ if (pvid && (pvid != VLAN_N_VID)) { - memset(&vinfo, 0, sizeof(vinfo)); - vinfo.flags |= BRIDGE_VLAN_INFO_PVID; - if (test_bit(pvid, untagged_bmp_copy)) { -diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c -index 8e87ef6..6bedcc4 100644 ---- a/net/bridge/br_vlan.c -+++ b/net/bridge/br_vlan.c -@@ -11,6 +11,8 @@ static void __vlan_add_pvid(struct net_port_vlans *v, u16 vid) - return; - - smp_wmb(); -+ clear_bit(v->pvid, v->untagged_bitmap); -+ clear_bit(v->pvid, v->vlan_bitmap); - v->pvid = vid; - } - -@@ -89,6 +91,12 @@ static int __vlan_del(struct net_port_vlans *v, u16 vid) - if (!test_bit(vid, v->vlan_bitmap)) - return -EINVAL; - -+ if (v->port_idx) { -+ if ((v->parent.port->br->default_pvid == vid) && -+ (v->pvid == vid)) -+ return -EINVAL; -+ } -+ - __vlan_delete_pvid(v, vid); - clear_bit(vid, v->untagged_bitmap); - -@@ -97,6 +105,16 @@ static int __vlan_del(struct net_port_vlans *v, u16 vid) - - clear_bit(vid, v->vlan_bitmap); - v->num_vlans--; -+ -+ if (v->port_idx && (v->pvid == 0)) { -+ v->pvid = v->parent.port->br->default_pvid; -+ set_bit(v->pvid, v->untagged_bitmap); -+ if (!test_bit(v->pvid, v->vlan_bitmap)) { -+ set_bit(v->pvid, v->vlan_bitmap); -+ v->num_vlans++; -+ } -+ } -+ - if (bitmap_empty(v->vlan_bitmap, VLAN_N_VID)) { - if (v->port_idx) - rcu_assign_pointer(v->parent.port->vlan_info, NULL); -@@ -403,12 +421,14 @@ static int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid) - */ - if ((!old_pvid || vlan_default_pvid(br_get_vlan_info(br), old_pvid)) && - !br_vlan_find(br, pvid)) { -+/* - err = br_vlan_add(br, pvid, - BRIDGE_VLAN_INFO_PVID | - BRIDGE_VLAN_INFO_UNTAGGED); - if (err) - goto out; - br_vlan_delete(br, old_pvid); -+*/ - set_bit(0, changed); - } - -@@ -448,6 +468,7 @@ err_port: - nbp_vlan_delete(p, pvid); - } - -+/* - if (test_bit(0, changed)) { - if (old_pvid) - br_vlan_add(br, old_pvid, -@@ -455,6 +476,7 @@ err_port: - BRIDGE_VLAN_INFO_UNTAGGED); - br_vlan_delete(br, pvid); - } -+*/ - goto out; - } - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-seq-check-in-br_mdb_dump.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-seq-check-in-br_mdb_dump.patch deleted file mode 100644 index 485788d8..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-fix-seq-check-in-br_mdb_dump.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 2ce297fc24d1f0b70c756d1f593e7a089a2d888d Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: fix seq check in br_mdb_dump() - -In case of rehashing, introduce a global variable 'br_mdb_rehash_seq' -which gets increased every time when rehashing, and assign -net->dev_base_seq + br_mdb_rehash_seq to cb->seq. - -In theory cb->seq could be wrapped to zero, but this is not -easy to fix, as net->dev_base_seq is not visible inside -br_mdb_rehash(). In practice, this is rare. - -Cc: Herbert Xu -Cc: Stephen Hemminger -Cc: "David S. Miller" -Cc: Thomas Graf -Cc: Jesper Dangaard Brouer -Signed-off-by: Cong Wang -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index 3eb4c92..67d8b93 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -117,10 +117,8 @@ static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb) - - rcu_read_lock(); - -- /* TODO: in case of rehashing, we need to check -- * consistency for dumping. -- */ -- cb->seq = net->dev_base_seq; -+ /* In theory this could be wrapped to 0... */ -+ cb->seq = net->dev_base_seq + br_mdb_rehash_seq; - - for_each_netdev_rcu(net, dev) { - if (dev->priv_flags & IFF_EBRIDGE) { -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index c3433a8..735b451 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -35,7 +35,7 @@ - - #define mlock_dereference(X, br) \ - rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) -- -+unsigned int br_mdb_rehash_seq; - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - static inline int ipv6_is_transient_multicast(const struct in6_addr *addr) - { -@@ -336,6 +336,7 @@ static int br_mdb_rehash(struct net_bridge_mdb_htable __rcu **mdbp, int max, - return err; - } - -+ br_mdb_rehash_seq++; - call_rcu_bh(&mdb->rcu, br_mdb_free); - - out: -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 3ae0b3d..a4aa2d5 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -410,6 +410,7 @@ extern int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __us - - /* br_multicast.c */ - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING -+extern unsigned int br_mdb_rehash_seq; - extern int br_multicast_rcv(struct net_bridge *br, - struct net_bridge_port *port, - struct sk_buff *skb); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-get-default-pvid.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-get-default-pvid.patch deleted file mode 100644 index 5fa9b562..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-get-default-pvid.patch +++ /dev/null @@ -1,55 +0,0 @@ -Currently, if the pvid is not set, we return an illegal vlan value -even though the pvid value is set to 0. Since pvid of 0 is currently -invalid, just return 0 instead. This makes the current and future -checks simpler. - -Signed-off-by: Vladislav Yasevich - -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 796e50f..984935c 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -661,11 +661,8 @@ static inline int br_vlan_get_tag(const struct sk_buff *skb, u16 *vid) - - static inline u16 br_get_pvid(const struct net_port_vlans *v) - { -- /* Return just the VID if it is set, or VLAN_N_VID (invalid vid) if -- * vid wasn't set -- */ - smp_rmb(); -- return v->pvid ?: VLAN_N_VID; -+ return v->pvid; - } - - #else -@@ -752,7 +749,7 @@ static inline u16 br_vlan_get_tag(const struct sk_buff *skb, u16 *tag) - } - static inline u16 br_get_pvid(const struct net_port_vlans *v) - { -- return VLAN_N_VID; /* Returns invalid vid */ -+ return 0; - } - #endif - -diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c -index e3efba0..ac0ca81 100644 ---- a/net/bridge/br_vlan.c -+++ b/net/bridge/br_vlan.c -@@ -184,7 +184,7 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, - * See if pvid is set on this port. That tells us which - * vlan untagged or priority-tagged traffic belongs to. - */ -- if (pvid == VLAN_N_VID) -+ if (!pvid) - return false; - - /* PVID is set on this port. Any untagged or priority-tagged -@@ -249,7 +249,7 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) - br_vlan_get_tag(skb, vid); - if (!*vid) { - *vid = br_get_pvid(v); -- if (*vid == VLAN_N_VID) -+ if (!*vid) - return false; - - return true; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-igmp-fast-leave.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-igmp-fast-leave.patch deleted file mode 100644 index 3e36729a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-igmp-fast-leave.patch +++ /dev/null @@ -1,76 +0,0 @@ -When fast leave is configured on a bridge port and an IGMP leave is received for a group, the group is not deleted immediately if there is a router detected or if multicast querier is configured. Ideally the group should be deleted immediately when fast leave is configured. - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index ed5d394..b38315c 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1265,8 +1265,7 @@ static void br_multicast_leave_group(struct net_bridge *br, - - spin_lock(&br->multicast_lock); - if (!netif_running(br->dev) || -- (port && port->state == BR_STATE_DISABLED) || -- timer_pending(&br->multicast_querier_timer)) -+ (port && port->state == BR_STATE_DISABLED)) - goto out; - - mdb = mlock_dereference(br->mdb, br); -@@ -1274,6 +1273,31 @@ static void br_multicast_leave_group(struct net_bridge *br, - if (!mp) - goto out; - -+ if (port && port->multicast_fast_leave) { -+ struct net_bridge_port_group __rcu **pp; -+ -+ for (pp = &mp->ports; -+ (p = mlock_dereference(*pp, br)) != NULL; -+ pp = &p->next) { -+ if (p->port != port) -+ continue; -+ -+ br_mdb_notify(br->dev, p->port, group, RTM_DELMDB, MDB_TEMPORARY); -+ rcu_assign_pointer(*pp, p->next); -+ hlist_del_init(&p->mglist); -+ del_timer(&p->timer); -+ call_rcu_bh(&p->rcu, br_multicast_free_pg); -+ -+ if (!mp->ports && !mp->mglist && -+ netif_running(br->dev)) -+ mod_timer(&mp->timer, jiffies); -+ } -+ goto out; -+ } -+ -+ if (timer_pending(&br->multicast_querier_timer)) -+ goto out; -+ - if (br->multicast_querier && - !timer_pending(&br->multicast_querier_timer)) { - __br_multicast_send_query(br, port, &mp->addr); -@@ -1300,27 +1324,6 @@ static void br_multicast_leave_group(struct net_bridge *br, - } - } - -- if (port && port->multicast_fast_leave) { -- struct net_bridge_port_group __rcu **pp; -- -- for (pp = &mp->ports; -- (p = mlock_dereference(*pp, br)) != NULL; -- pp = &p->next) { -- if (p->port != port) -- continue; -- -- rcu_assign_pointer(*pp, p->next); -- hlist_del_init(&p->mglist); -- del_timer(&p->timer); -- call_rcu_bh(&p->rcu, br_multicast_free_pg); -- -- if (!mp->ports && !mp->mglist && -- netif_running(br->dev)) -- mod_timer(&mp->timer, jiffies); -- } -- goto out; -- } -- - now = jiffies; - time = now + br->multicast_last_member_count * - br->multicast_last_member_interval; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-igmp-ifupdown-fixes.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-igmp-ifupdown-fixes.patch deleted file mode 100644 index 8ba559d3..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-igmp-ifupdown-fixes.patch +++ /dev/null @@ -1,49 +0,0 @@ -There are a few cases where igmp snoooping config cannot be configured, when the bridge device is not running. Due to this at bootup time, configuration from ifupdown fails. - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 7870449..e962ce3 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1711,9 +1711,6 @@ int br_multicast_set_router(struct net_bridge *br, unsigned long val) - int err = -ENOENT; - - spin_lock_bh(&br->multicast_lock); -- if (!netif_running(br->dev)) -- goto unlock; -- - switch (val) { - case 0: - case 2: -@@ -1741,8 +1738,6 @@ int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val) - int err = -ENOENT; - - spin_lock(&br->multicast_lock); -- if (!netif_running(br->dev) || p->state == BR_STATE_DISABLED) -- goto unlock; - - switch (val) { - case 0: -@@ -1857,9 +1852,6 @@ int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val) - struct net_bridge_mdb_htable *mdb; - - spin_lock_bh(&br->multicast_lock); -- if (!netif_running(br->dev)) -- goto unlock; -- - err = -EINVAL; - if (!is_power_of_2(val)) - goto unlock; -diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c -index 94e63ff..9f1ee9a 100644 ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -172,9 +172,6 @@ static ssize_t show_multicast_fast_leave(struct net_bridge_port *p, - static int store_multicast_fast_leave(struct net_bridge_port *p, - unsigned long v) - { -- if (p->br->multicast_disabled) -- return -EINVAL; -- - p->multicast_fast_leave = !!v; - return 0; - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-igmpv3.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-igmpv3.patch deleted file mode 100644 index a6f54813..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-igmpv3.patch +++ /dev/null @@ -1,58 +0,0 @@ -igmpv3 reports/MLDv2 with include type with 0 sources should be treated as a leave. - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 622c082..11f4a71 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -41,7 +41,12 @@ static void br_multicast_start_querier(struct net_bridge *br); - static void br_multicast_add_router(struct net_bridge *br, - struct net_bridge_port *port); - static void br_multicast_del_grps(struct net_bridge *br); -- -+static void br_ip4_multicast_leave_group(struct net_bridge *br, -+ struct net_bridge_port *port, __be32 group); -+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+static void br_ip6_multicast_leave_group(struct net_bridge *br, -+ struct net_bridge_port *port, const struct in6_addr *group); -+#endif - unsigned int br_mdb_rehash_seq; - - static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b) -@@ -958,10 +963,14 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br, - default: - continue; - } -- -- err = br_ip4_multicast_add_group(br, port, group); -- if (err) -- break; -+ if (((type == IGMPV3_CHANGE_TO_INCLUDE) || -+ (type == IGMPV3_MODE_IS_INCLUDE)) && (ntohs(grec->grec_nsrcs) == 0)) { -+ br_ip4_multicast_leave_group(br, port, group); -+ } else { -+ err = br_ip4_multicast_add_group(br, port, group); -+ if (err) -+ break; -+ } - } - - return err; -@@ -1018,10 +1027,14 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, - default: - continue; - } -- -- err = br_ip6_multicast_add_group(br, port, &grec->grec_mca); -- if (!err) -- break; -+ if (((grec->grec_type == MLD2_CHANGE_TO_INCLUDE) || -+ (grec->grec_type == MLD2_MODE_IS_INCLUDE)) && (ntohs(*nsrcs) == 0)) { -+ br_ip6_multicast_leave_group(br, port, &grec->grec_mca); -+ } else { -+ err = br_ip6_multicast_add_group(br, port, &grec->grec_mca); -+ if (!err) -+ break; -+ } - } - - return err; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-implement-multicast-fast-leave.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-implement-multicast-fast-leave.patch deleted file mode 100644 index 8c57baf2..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-implement-multicast-fast-leave.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 50426b5925ff0d7f47c20e6886047f1bb6245901 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: implement multicast fast leave - -V2: make the toggle per-port - -Fast leave allows bridge to immediately stops the multicast -traffic on the port receives IGMP Leave when IGMP snooping is enabled, -no timeouts are observed. - -Cc: Herbert Xu -Cc: Stephen Hemminger -Cc: "David S. Miller" -Signed-off-by: Cong Wang -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index f7165b4..a3d1957 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1244,6 +1244,27 @@ static void br_multicast_leave_group(struct net_bridge *br, - if (!mp) - goto out; - -+ if (port && port->multicast_fast_leave) { -+ struct net_bridge_port_group __rcu **pp; -+ -+ for (pp = &mp->ports; -+ (p = mlock_dereference(*pp, br)) != NULL; -+ pp = &p->next) { -+ if (p->port != port) -+ continue; -+ -+ rcu_assign_pointer(*pp, p->next); -+ hlist_del_init(&p->mglist); -+ del_timer(&p->timer); -+ call_rcu_bh(&p->rcu, br_multicast_free_pg); -+ -+ if (!mp->ports && !mp->mglist && -+ netif_running(br->dev)) -+ mod_timer(&mp->timer, jiffies); -+ } -+ goto out; -+ } -+ - now = jiffies; - time = now + br->multicast_last_member_count * - br->multicast_last_member_interval; -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 6f48a78..f11323d 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -144,6 +144,7 @@ struct net_bridge_port - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - u32 multicast_startup_queries_sent; - unsigned char multicast_router; -+ unsigned char multicast_fast_leave; - struct timer_list multicast_router_timer; - struct timer_list multicast_query_timer; - struct hlist_head mglist; -diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c -index 6229b62..94e63ff 100644 ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -162,6 +162,25 @@ static int store_multicast_router(struct net_bridge_port *p, - } - static BRPORT_ATTR(multicast_router, S_IRUGO | S_IWUSR, show_multicast_router, - store_multicast_router); -+ -+static ssize_t show_multicast_fast_leave(struct net_bridge_port *p, -+ char *buf) -+{ -+ return sprintf(buf, "%d\n", p->multicast_fast_leave); -+} -+ -+static int store_multicast_fast_leave(struct net_bridge_port *p, -+ unsigned long v) -+{ -+ if (p->br->multicast_disabled) -+ return -EINVAL; -+ -+ p->multicast_fast_leave = !!v; -+ return 0; -+} -+ -+static BRPORT_ATTR(multicast_fast_leave, S_IRUGO | S_IWUSR, -+ show_multicast_fast_leave, store_multicast_fast_leave); - #endif - - static struct brport_attribute *brport_attrs[] = { -@@ -183,6 +202,7 @@ static struct brport_attribute *brport_attrs[] = { - &brport_attr_hairpin_mode, - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - &brport_attr_multicast_router, -+ &brport_attr_multicast_fast_leave, - #endif - NULL - }; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-initial-mac.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-initial-mac.patch deleted file mode 100644 index 581139e6..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-initial-mac.patch +++ /dev/null @@ -1,43 +0,0 @@ -Make sure that a new bridge is instantiated with the "all 0's" mac address - -This makes operations consistent with a bridge that has it's interfaces removed (CM-2510). - -diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c -index 7861354..aef0767 100644 ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -353,6 +353,7 @@ void br_dev_setup(struct net_device *dev) - struct net_bridge *br = netdev_priv(dev); - - eth_hw_addr_random(dev); -+ memcpy(br->initial_addr, dev->dev_addr, ETH_ALEN); - ether_setup(dev); - - dev->netdev_ops = &br_netdev_ops; -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 9699fdf..c80f94d 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -215,6 +215,7 @@ struct net_bridge - spinlock_t lock; - struct list_head port_list; - struct net_device *dev; -+ u8 initial_addr[ETH_ALEN]; - - struct pcpu_sw_netstats __percpu *stats; - spinlock_t hash_lock; -diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c -index 4f7fbbf..4ed11ab 100644 ---- a/net/bridge/br_stp_if.c -+++ b/net/bridge/br_stp_if.c -@@ -252,6 +252,10 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br) - - } - -+ /* no ports, re-instate the initial random address */ -+ if (addr == br_mac_zero) -+ addr = &br->initial_addr; -+ - if (ether_addr_equal(br->bridge_id.addr, addr)) - return false; /* no change */ - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-ipoptions-fix.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-ipoptions-fix.patch deleted file mode 100644 index 8b62c191..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-ipoptions-fix.patch +++ /dev/null @@ -1,43 +0,0 @@ -When IP options packet is received on bridge and ebtables module is present, options was being changed incorrectly, so IP stack was dropping the packet because it finds that checksum is incorrect - -diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c -index fc08e8b..a8d96c2 100644 ---- a/net/bridge/br_netfilter.c -+++ b/net/bridge/br_netfilter.c -@@ -242,7 +242,6 @@ static inline void nf_bridge_update_protocol(struct sk_buff *skb) - - static int br_parse_ip_options(struct sk_buff *skb) - { -- struct ip_options *opt; - const struct iphdr *iph; - struct net_device *dev = skb->dev; - u32 len; -@@ -251,7 +250,6 @@ static int br_parse_ip_options(struct sk_buff *skb) - goto inhdr_error; - - iph = ip_hdr(skb); -- opt = &(IPCB(skb)->opt); - - /* Basic sanity checks */ - if (iph->ihl < 5 || iph->version != 4) -@@ -280,20 +278,6 @@ static int br_parse_ip_options(struct sk_buff *skb) - if (iph->ihl == 5) - return 0; - -- opt->optlen = iph->ihl*4 - sizeof(struct iphdr); -- if (ip_options_compile(dev_net(dev), opt, skb)) -- goto inhdr_error; -- -- /* Check correct handling of SRR option */ -- if (unlikely(opt->srr)) { -- struct in_device *in_dev = __in_dev_get_rcu(dev); -- if (in_dev && !IN_DEV_SOURCE_ROUTE(in_dev)) -- goto drop; -- -- if (ip_options_rcv_srr(skb)) -- goto drop; -- } -- - return 0; - - inhdr_error: diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-lacp-fallback.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-lacp-fallback.patch deleted file mode 100644 index 8c0b84dd..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-lacp-fallback.patch +++ /dev/null @@ -1,820 +0,0 @@ -This patch adds LACP fall back support for bonds. Fall back is enabled -on a per bond basis and applicable only to bonds configured in 802.3ad -mode. When fall back is enabled on a bond, a slave of a bond will attempt -to run LACP, and if there is no LACP partner upon expiry, it will be made -active and the bond will be brought logical up. A grace period is started -for the fall back and upon expiry, the slave will be made inactive and the -bond will be brought logical down. In case an LACP partner is discovered -before the expiry of the grace period, the bond slave will exit fall back -state and proceed to continue LACP exchange. In case there are multiple -slaves in a bond, only one slave is allowed to be in fall back state and -a priority scheme is used to determine which one. - -diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c -index 0b3ce2d..c5ab398 100644 ---- a/drivers/net/bonding/bond_3ad.c -+++ b/drivers/net/bonding/bond_3ad.c -@@ -70,6 +70,7 @@ - #define AD_PORT_STANDBY 0x80 - #define AD_PORT_SELECTED 0x100 - #define AD_PORT_MOVED 0x200 -+#define AD_PORT_FALLBACK 0x400 - - // Port Key definitions - // key is determined according to the link speed, duplex and -@@ -223,6 +224,7 @@ static inline int __agg_has_partner(struct aggregator *agg) - */ - static inline void __disable_port(struct port *port) - { -+ pr_debug("Disable port %s\n", port->slave->dev->name); - bond_set_slave_inactive_flags(port->slave); - bond_3ad_set_carrier(port->slave->bond); - } -@@ -237,6 +239,7 @@ static inline void __enable_port(struct port *port) - struct slave *slave = port->slave; - - if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) { -+ pr_debug("Enable port %s\n", slave->dev->name); - bond_set_slave_active_flags(slave); - bond_3ad_set_carrier(slave->bond); - } -@@ -391,6 +394,113 @@ static u8 __get_duplex(struct port *port) - } - - /** -+ * is_lacp_fallback_eligible - is bond eligible to go into lacp fallback mode -+ * @bond: the bond we're looking at -+ * -+ * Return true if it is, false otherwise -+ */ -+static bool is_lacp_fallback_eligible(struct bonding *bond) -+{ -+ return (bond->params.lacp_fallback_allow && -+ bond->params.lacp_fallback_active); -+} -+ -+/** -+ * is_better_fallback_slave - compare between two slaves of the same bond -+ * and see which one is better for lacp fall back -+ * @slave1 -+ * @slave2 -+ * -+ * Return: true if slave1 is better, false otherwise -+ */ -+static bool is_better_fallback_slave(struct slave *slave1, struct slave *slave2) -+{ -+ if (!slave1) -+ return false; -+ -+ if (!slave2) -+ return true; -+ -+ if (slave1->bond != slave2->bond) -+ return false; -+ -+ if (slave1->lacp_fallback_priority > slave2->lacp_fallback_priority) -+ return true; -+ -+ if (slave2->lacp_fallback_priority > slave1->lacp_fallback_priority) -+ return false; -+ -+ return (strcmp(slave1->dev->name, slave2->dev->name) <= 0); -+} -+ -+/** -+ * __get_best_fallback_slave_in_bond - get the best slave when bond is in fallback mode -+ * @bond: the bond we're looking at -+ * Return the slave in the bond which is best for lacp fall back -+ */ -+static struct slave *__get_best_fallback_slave_in_bond(struct bonding *bond) -+{ -+ struct slave *slave, *best_slave = NULL; -+ int i; -+ -+ if (!is_lacp_fallback_eligible(bond)) -+ return NULL; -+ -+ bond_for_each_slave(bond, slave, i) { -+ if (IS_UP(slave->dev)) { -+ if (!best_slave) -+ best_slave = slave; -+ else if (is_better_fallback_slave(slave, best_slave)) -+ best_slave = slave; -+ } -+ } -+ return best_slave; -+} -+ -+static struct slave *__get_best_fallback_slave_in_agg(struct aggregator *agg) -+{ -+ struct slave *best_slave = NULL; -+ struct port *port; -+ -+ if (!is_lacp_fallback_eligible(agg->slave->bond)) -+ return NULL; -+ -+ for (port = agg->lag_ports; -+ port; -+ port = port->next_port_in_aggregator) { -+ -+ if (IS_UP(port->slave->dev)) { -+ if (!best_slave) -+ best_slave = port->slave; -+ else if (is_better_fallback_slave(port->slave, best_slave)) -+ best_slave = port->slave; -+ } -+ } -+ return best_slave; -+} -+ -+/** -+ * is_best_fallback_slave - is the given slave the best for lacp fallback -+ * @slave: the slave we're looking at -+ * Return true if it is, false otherwise -+ */ -+static bool is_best_fallback_slave(struct slave *slave) -+{ -+ return (slave == __get_best_fallback_slave_in_bond(slave->bond)); -+} -+ -+static bool is_agg_in_fallback(struct aggregator *agg) -+{ -+ struct slave *slave; -+ -+ if (!agg) -+ return false; -+ -+ slave = __get_best_fallback_slave_in_agg(agg); -+ return (slave && (SLAVE_AD_INFO(slave).port.sm_vars & AD_PORT_FALLBACK)); -+} -+ -+/** - * __initialize_port_locks - initialize a port's STATE machine spinlock - * @port: the port we're looking at - * -@@ -1040,15 +1150,45 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - /* next state */ - port->sm_rx_state = AD_RX_PORT_DISABLED; - // check if new lacpdu arrived -- else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT))) { -+ else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT) || (port->sm_rx_state == AD_RX_FALLBACK_EXPIRED))) { - port->sm_rx_timer_counter = 0; // zero timer - port->sm_rx_state = AD_RX_CURRENT; -+ } else if (port->sm_rx_state == AD_RX_FALLBACK) { -+ if (lacpdu) { -+ pr_debug("Fallback (%s): lacpdu received, disabling fallback\n", -+ port->slave->dev->name); -+ -+ port->sm_rx_fb_timer_counter = 0; -+ port->sm_rx_state = AD_RX_CURRENT; -+ __disable_port(port); // bring down the bond, let lacp runs its course -+ } else if (!is_best_fallback_slave(port->slave) || -+ !(port->sm_vars & AD_PORT_FALLBACK)) { -+ pr_debug("(%s) fallback allow %d active %d or no longer best\n", -+ port->slave->dev->name, -+ port->slave->bond->params.lacp_fallback_allow, -+ port->slave->bond->params.lacp_fallback_active); -+ port->sm_rx_fb_timer_counter = 0; -+ if (is_lacp_fallback_eligible(port->slave->bond)) -+ port->sm_rx_state = AD_RX_FALLBACK_EXPIRED; -+ else -+ port->sm_rx_state = AD_RX_DEFAULTED; -+ __disable_port(port); -+ } else if (port->sm_rx_fb_timer_counter && !(--port->sm_rx_fb_timer_counter)) { -+ pr_debug("(%s) Fallback grace period expired (%d)\n", port->slave->dev->name, -+ port->slave->inactive); -+ -+ port->sm_rx_state = AD_RX_FALLBACK_EXPIRED; // next state -+ __disable_port(port); -+ } - } else { - // if timer is on, and if it is expired - if (port->sm_rx_timer_counter && !(--port->sm_rx_timer_counter)) { - switch (port->sm_rx_state) { - case AD_RX_EXPIRED: -- port->sm_rx_state = AD_RX_DEFAULTED; // next state -+ if (is_best_fallback_slave(port->slave)) -+ port->sm_rx_state = AD_RX_FALLBACK; // next state -+ else -+ port->sm_rx_state = AD_RX_DEFAULTED; // next state - break; - case AD_RX_CURRENT: - port->sm_rx_state = AD_RX_EXPIRED; // next state -@@ -1058,6 +1198,7 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - } - } else { - // if no lacpdu arrived and no timer is on -+ //pr_debug("rx_machine: state %d\n", port->sm_rx_state); - switch (port->sm_rx_state) { - case AD_RX_PORT_DISABLED: - if (port->sm_vars & AD_PORT_MOVED) -@@ -1071,6 +1212,10 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - & AD_PORT_LACP_ENABLED) == 0)) - port->sm_rx_state = AD_RX_LACP_DISABLED; // next state - break; -+ case AD_RX_DEFAULTED: -+ if (is_best_fallback_slave(port->slave)) -+ port->sm_rx_state = AD_RX_FALLBACK; // next state -+ break; - default: //to silence the compiler - break; - -@@ -1099,9 +1244,13 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - - case AD_RX_PORT_DISABLED: - port->sm_vars &= ~AD_PORT_MATCHED; -+ port->sm_vars &= ~AD_PORT_FALLBACK; -+ port->sm_rx_fb_timer_counter = 0; - break; - case AD_RX_LACP_DISABLED: - port->sm_vars &= ~AD_PORT_SELECTED; -+ port->sm_vars &= ~AD_PORT_FALLBACK; -+ port->sm_rx_fb_timer_counter = 0; - __record_default(port); - port->partner_oper.port_state &= ~AD_STATE_AGGREGATION; - port->sm_vars |= AD_PORT_MATCHED; -@@ -1113,6 +1262,8 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - //mux machine in case of EXPIRED even if LINK_DOWN didn't arrive for the port. - port->partner_oper.port_state &= ~AD_STATE_SYNCHRONIZATION; - port->sm_vars &= ~AD_PORT_MATCHED; -+ port->sm_vars &= ~AD_PORT_FALLBACK; -+ port->sm_rx_fb_timer_counter = 0; - port->partner_oper.port_state |= - AD_STATE_LACP_ACTIVITY; - port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(AD_SHORT_TIMEOUT)); -@@ -1122,6 +1273,8 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - __update_default_selected(port); - __record_default(port); - port->sm_vars |= AD_PORT_MATCHED; -+ port->sm_vars &= ~AD_PORT_FALLBACK; -+ port->sm_rx_fb_timer_counter = 0; - port->actor_oper_port_state &= ~AD_STATE_EXPIRED; - break; - case AD_RX_CURRENT: -@@ -1138,6 +1291,21 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - __record_pdu(lacpdu, port); - port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)); - port->actor_oper_port_state &= ~AD_STATE_EXPIRED; -+ port->sm_vars &= ~AD_PORT_FALLBACK; -+ break; -+ case AD_RX_FALLBACK: -+ pr_debug("rx_machine: %s in fallback state (%d)\n", -+ port->slave->dev->name, port->sm_rx_fb_timer_counter); -+ -+ port->sm_rx_fb_timer_counter = -+ port->slave->bond->params.lacp_fallback_period * -+ ad_ticks_per_sec; -+ port->sm_vars &= ~AD_PORT_SELECTED; -+ port->sm_vars |= AD_PORT_FALLBACK; -+ break; -+ case AD_RX_FALLBACK_EXPIRED: -+ port->sm_vars &= ~AD_PORT_FALLBACK; -+ port->sm_rx_fb_timer_counter = 0; - break; - default: //to silence the compiler - break; -@@ -1279,7 +1447,7 @@ static void ad_port_selection_logic(struct port *port) - // if the port is already Selected, do nothing - if (port->sm_vars & AD_PORT_SELECTED) - return; -- -+ pr_debug("Running port selection (%s)\n", port->slave->dev->name); - // if the port is connected to other aggregator, detach it - if (port->aggregator) { - // detach the port from its former aggregator -@@ -1431,13 +1599,25 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, - * did reply, keep best. - * - * 4. Therefore, current and best both have partner replies or -- * both do not, so perform selection policy: -+ * both do not, so: -+ * -+ * 4a. If both have no partner and bond is fallback eligible and if -+ * current agg is a better fallback slave, select current. -+ * -+ * 4b. If both have no partner and bond is fallback eligible and if -+ * best agg is a better fallback, keep best. -+ * -+ * 5. Therefore, current and best both have partner replies or -+ * both do not and bond is not fallback eligible, perform -+ * selection policy: - * - * BOND_AD_COUNT: Select by count of ports. If count is equal, - * select by bandwidth. - * - * BOND_AD_STABLE, BOND_AD_BANDWIDTH: Select by bandwidth. - */ -+ struct slave *s1, *s2; -+ - if (!best) - return curr; - -@@ -1453,6 +1633,19 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, - if (!__agg_has_partner(curr) && __agg_has_partner(best)) - return best; - -+ if (is_lacp_fallback_eligible(curr->slave->bond) && -+ !__agg_has_partner(curr) && !__agg_has_partner(best)) { -+ -+ s1 = __get_best_fallback_slave_in_agg(curr); -+ s2 = __get_best_fallback_slave_in_agg(best); -+ -+ if (is_better_fallback_slave(s1, s2)) -+ return curr; -+ -+ if (is_better_fallback_slave(s2, s1)) -+ return best; -+ } -+ - switch (__get_agg_selection_mode(curr->lag_ports)) { - case BOND_AD_COUNT: - if (curr->num_of_ports > best->num_of_ports) -@@ -1517,6 +1710,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) - { - struct aggregator *best, *active, *origin; - struct port *port; -+ bool best_is_in_fallback = false; - - origin = agg; - active = __get_active_agg(agg); -@@ -1530,7 +1724,9 @@ static void ad_agg_selection_logic(struct aggregator *agg) - - } while ((agg = __get_next_agg(agg))); - -- if (best && -+ best_is_in_fallback = is_agg_in_fallback(best); -+ -+ if (best && !best_is_in_fallback && - __get_agg_selection_mode(best->lag_ports) == BOND_AD_STABLE) { - /* - * For the STABLE policy, don't replace the old active -@@ -1596,6 +1792,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) - for (port = active->lag_ports; port; - port = port->next_port_in_aggregator) { - __disable_port(port); -+ port->sm_vars &= ~AD_PORT_FALLBACK; - } - } - } -@@ -1608,9 +1805,14 @@ static void ad_agg_selection_logic(struct aggregator *agg) - - if (active) { - if (!__agg_has_partner(active)) { -+ bool is_fallback_eligible = is_lacp_fallback_eligible(active->slave->bond); - for (port = active->lag_ports; port; - port = port->next_port_in_aggregator) { -- __enable_port(port); -+ if (!is_fallback_eligible || -+ (is_best_fallback_slave(port->slave))) { -+ pr_debug("(%s) agg active and no partner\n", port->slave->dev->name); -+ __enable_port(port); -+ } - } - } - } -@@ -1725,6 +1927,9 @@ static void ad_initialize_port(struct port *port, int lacp_fast) - port->next_port_in_aggregator = NULL; - port->transaction_id = 0; - -+ // fallback -+ port->sm_rx_fb_timer_counter = 0; -+ - memcpy(&port->lacpdu, &lacpdu, sizeof(lacpdu)); - } - } -@@ -2355,21 +2560,28 @@ int bond_3ad_set_carrier(struct bonding *bond) - struct aggregator *active; - struct slave *slave; - int active_slaves = 0, i; -+ bool fallback = false; - - bond_for_each_slave(bond, slave, i) - if (bond_is_active_slave(slave)) - active_slaves++; - - active = __get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator)); -- if (active && __agg_has_partner(active)) { -+ fallback = is_agg_in_fallback(active); -+ pr_debug("%s %s active id: %d #actives: %d fallback: %d\n", __FUNCTION__, -+ bond->dev->name, active ? active->aggregator_identifier : 0, -+ active_slaves, fallback); -+ if (active && (fallback || __agg_has_partner(active))) { - /* are enough slaves available to consider link up? */ - if (active_slaves < bond->params.min_links) { - if (netif_carrier_ok(bond->dev)) { - netif_carrier_off(bond->dev); -+ pr_debug("Setting bond %s off\n", bond->dev->name); - return 1; - } - } else if (!netif_carrier_ok(bond->dev)) { - netif_carrier_on(bond->dev); -+ pr_debug("Setting bond %s on\n", bond->dev->name); - return 1; - } - return 0; -diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h -index 677c108..bd844cc 100644 ---- a/drivers/net/bonding/bond_3ad.h -+++ b/drivers/net/bonding/bond_3ad.h -@@ -55,7 +55,9 @@ typedef enum { - AD_RX_LACP_DISABLED, // rx Machine - AD_RX_EXPIRED, // rx Machine - AD_RX_DEFAULTED, // rx Machine -- AD_RX_CURRENT // rx Machine -+ AD_RX_CURRENT, // rx Machine -+ AD_RX_FALLBACK, // rx Machine -+ AD_RX_FALLBACK_EXPIRED // rx Machine - } rx_states_t; - - // periodic machine states(43.4.12 in the 802.3ad standard) -@@ -100,7 +102,8 @@ typedef enum { - AD_ACTOR_CHURN_TIMER, - AD_PERIODIC_TIMER, - AD_PARTNER_CHURN_TIMER, -- AD_WAIT_WHILE_TIMER -+ AD_WAIT_WHILE_TIMER, -+ AD_FALLBACK_TIMER, - } ad_timers_t; - - #pragma pack(1) -@@ -223,6 +226,7 @@ typedef struct port { - u16 sm_vars; // all state machines variables for this port - rx_states_t sm_rx_state; // state machine rx state - u16 sm_rx_timer_counter; // state machine rx timer counter -+ u16 sm_rx_fb_timer_counter; // state machine rx fallback timer counter - periodic_states_t sm_periodic_state;// state machine periodic state - u16 sm_periodic_timer_counter; // state machine periodic timer counter - mux_states_t sm_mux_state; // state machine mux state -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index 342e647..c75b3ef 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -89,6 +89,8 @@ - /* monitor all links that often (in milliseconds). <=0 disables monitoring */ - #define BOND_LINK_MON_INTERV 0 - #define BOND_LINK_ARP_INTERV 0 -+#define BOND_LACP_FALLBACK_PERIOD 0 -+#define BOND_LACP_FALLBACK_ACTIVE_DEFAULT 1 - - static int max_bonds = BOND_DEFAULT_MAX_BONDS; - static int tx_queues = BOND_DEFAULT_TX_QUEUES; -@@ -1164,13 +1166,13 @@ static bool bond_should_notify_peers(struct bonding *bond) - { - struct slave *slave = bond->curr_active_slave; - -- pr_debug("bond_should_notify_peers: bond %s slave %s\n", -- bond->dev->name, slave ? slave->dev->name : "NULL"); -- - if (!slave || !bond->send_peer_notif || - test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state)) - return false; - -+ pr_debug("bond_should_notify_peers: bond %s slave %s\n", -+ bond->dev->name, slave ? slave->dev->name : "NULL"); -+ - bond->send_peer_notif--; - return true; - } -@@ -2004,6 +2006,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) - goto err_dest_symlinks; - } - -+ res = bond_sysfs_slave_add(new_slave); -+ if (res) { -+ pr_debug("Error %d calling bond_sysfs_slave_add\n", res); -+ goto err_detach; -+ } -+ - pr_info("%s: enslaving %s as a%s interface with a%s link.\n", - bond_dev->name, slave_dev->name, - bond_is_active_slave(new_slave) ? "n active" : " backup", -@@ -2126,6 +2134,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) - bond->current_arp_slave = NULL; - - /* release the slave from its bond */ -+ bond_sysfs_slave_del(slave); - bond_detach_slave(bond, slave); - - if (bond->primary_slave == slave) -@@ -2316,6 +2325,7 @@ static int bond_release_all(struct net_device *bond_dev) - bond_alb_deinit_slave(bond, slave); - } - -+ bond_sysfs_slave_del(slave); - bond_destroy_slave_symlinks(bond_dev, slave_dev); - bond_del_vlans_from_slave(bond, slave_dev); - -@@ -4916,6 +4926,8 @@ static int bond_check_params(struct bond_params *params) - params->all_slaves_active = all_slaves_active; - params->resend_igmp = resend_igmp; - params->min_links = min_links; -+ params->lacp_fallback_period = BOND_LACP_FALLBACK_PERIOD; -+ params->lacp_fallback_active = BOND_LACP_FALLBACK_ACTIVE_DEFAULT; - - if (primary) { - strncpy(params->primary, primary, IFNAMSIZ); -diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c -index 4fa1b95..13217bf 100644 ---- a/drivers/net/bonding/bond_procfs.c -+++ b/drivers/net/bonding/bond_procfs.c -@@ -150,6 +150,12 @@ static void bond_info_show_master(struct seq_file *seq) - seq_printf(seq, "\tPartner Mac Address: %pM\n", - ad_info.partner_system); - } -+ -+ seq_printf(seq, "Fall back Info:\n"); -+ seq_printf(seq, "\tAllowed: %d\n", -+ bond->params.lacp_fallback_allow); -+ seq_printf(seq, "\tTimeout: %d\n", -+ bond->params.lacp_fallback_period); - } - } - -@@ -185,6 +191,12 @@ static void bond_info_show_slave(struct seq_file *seq, - agg->aggregator_identifier); - else - seq_puts(seq, "Aggregator ID: N/A\n"); -+ seq_printf(seq, "Lacp fall back priority: %d\n", -+ slave->lacp_fallback_priority); -+ if (SLAVE_AD_INFO(slave).port.sm_rx_state == AD_RX_FALLBACK) -+ seq_printf(seq, "LACP fall back: on\n"); -+ if (SLAVE_AD_INFO(slave).port.sm_rx_state == AD_RX_FALLBACK_EXPIRED) -+ seq_printf(seq, "LACP fall back: expired\n"); - } - seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id); - } -diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c -index b897b7b..6d7ea50 100644 ---- a/drivers/net/bonding/bond_sysfs.c -+++ b/drivers/net/bonding/bond_sysfs.c -@@ -47,6 +47,78 @@ - #define to_dev(obj) container_of(obj, struct device, kobj) - #define to_bond(cd) ((struct bonding *)(netdev_priv(to_net_dev(cd)))) - -+struct slave_attribute { -+ struct attribute attr; -+ ssize_t (*show)(struct slave *, char *); -+ int (*store)(struct slave *, unsigned long); -+}; -+ -+static ssize_t show_lacp_fallback_priority(struct slave *slave, char *buf) -+{ -+ return sprintf(buf, "%d\n", slave->lacp_fallback_priority); -+} -+ -+static int store_lacp_fallback_priority(struct slave *slave, unsigned long val) -+{ -+ slave->lacp_fallback_priority = val; -+ return 0; -+} -+ -+static const struct slave_attribute slave_lacp_fallback_priority = { -+ .attr = { -+ .name = "lacp_fallback_priority", -+ .mode = S_IWUSR | S_IRUGO, -+ }, -+ .show = show_lacp_fallback_priority, -+ .store = store_lacp_fallback_priority, -+}; -+ -+static const struct slave_attribute *slave_attrs[] = { -+ &slave_lacp_fallback_priority, -+ NULL -+}; -+ -+#define to_slave_attr(_at) container_of(_at, struct slave_attribute, attr) -+#define to_slave(obj) container_of(obj, struct slave, kobj) -+ -+static ssize_t slave_show(struct kobject *kobj, -+ struct attribute *attr, char *buf) -+{ -+ struct slave_attribute *slave_attr = to_slave_attr(attr); -+ struct slave *slave = to_slave(kobj); -+ -+ return slave_attr->show(slave, buf); -+} -+ -+static ssize_t slave_store(struct kobject *kobj, -+ struct attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct slave_attribute *slave_attr = to_slave_attr(attr); -+ struct slave *slave = to_slave(kobj); -+ ssize_t ret = -EINVAL; -+ char *endp; -+ unsigned long val; -+ -+ val = simple_strtoul(buf, &endp, 0); -+ if (endp != buf) { -+ if (!rtnl_trylock()) -+ return restart_syscall(); -+ -+ ret = slave_attr->store(slave, val); -+ if (ret == 0) -+ ret = count; -+ -+ rtnl_unlock(); -+ } -+ return ret; -+} -+ -+const struct sysfs_ops slave_sysfs_ops = { -+ .show = slave_show, -+ .store = slave_store, -+}; -+ - /* - * "show" function for the bond_masters attribute. - * The class parameter is ignored. -@@ -880,6 +952,104 @@ static ssize_t bonding_store_min_links(struct device *d, - static DEVICE_ATTR(min_links, S_IRUGO | S_IWUSR, - bonding_show_min_links, bonding_store_min_links); - -+static ssize_t bonding_show_lacp_fallback_allow(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct bonding *bond = to_bond(d); -+ -+ return sprintf(buf, "%d\n", bond->params.lacp_fallback_allow); -+} -+ -+static ssize_t bonding_store_lacp_fallback_allow(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct bonding *bond = to_bond(d); -+ int ret; -+ unsigned int new_value; -+ -+ ret = kstrtouint(buf, 0, &new_value); -+ if (ret < 0) { -+ pr_err("%s: Ignoring invalid lacp_fallback_allow value %s.\n", -+ bond->dev->name, buf); -+ return ret; -+ } -+ -+ pr_debug("%s: Setting lacp_fallback_allow to %u\n", -+ bond->dev->name, new_value); -+ bond->params.lacp_fallback_allow = new_value; -+ return count; -+} -+static DEVICE_ATTR(lacp_fallback_allow, S_IRUGO | S_IWUSR, -+ bonding_show_lacp_fallback_allow, bonding_store_lacp_fallback_allow); -+ -+static ssize_t bonding_show_lacp_fallback_period(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct bonding *bond = to_bond(d); -+ -+ return sprintf(buf, "%d\n", bond->params.lacp_fallback_period); -+} -+ -+static ssize_t bonding_store_lacp_fallback_period(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct bonding *bond = to_bond(d); -+ int ret; -+ unsigned int new_value; -+ -+ ret = kstrtouint(buf, 0, &new_value); -+ if (ret < 0) { -+ pr_err("%s: Ignoring invalid lacp_fallback_period value %s.\n", -+ bond->dev->name, buf); -+ return ret; -+ } -+ -+ pr_debug("%s: Setting lacp_fallback period to %u\n", -+ bond->dev->name, new_value); -+ bond->params.lacp_fallback_period = new_value; -+ return count; -+} -+static DEVICE_ATTR(lacp_fallback_period, S_IRUGO | S_IWUSR, -+ bonding_show_lacp_fallback_period, -+ bonding_store_lacp_fallback_period); -+ -+static ssize_t bonding_show_lacp_fallback_active(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct bonding *bond = to_bond(d); -+ -+ return sprintf(buf, "%d\n", bond->params.lacp_fallback_active); -+} -+ -+static ssize_t bonding_store_lacp_fallback_active(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct bonding *bond = to_bond(d); -+ int ret; -+ unsigned int new_value; -+ -+ ret = kstrtouint(buf, 0, &new_value); -+ if (ret < 0) { -+ pr_err("%s: Ignoring invalid lacp_fallback_active value %s.\n", -+ bond->dev->name, buf); -+ return ret; -+ } -+ -+ pr_debug("%s: Setting lacp_fallback active to %u\n", -+ bond->dev->name, new_value); -+ bond->params.lacp_fallback_active = new_value; -+ return count; -+} -+static DEVICE_ATTR(lacp_fallback_active, S_IRUGO | S_IWUSR, -+ bonding_show_lacp_fallback_active, -+ bonding_store_lacp_fallback_active); -+ - static ssize_t bonding_show_ad_select(struct device *d, - struct device_attribute *attr, - char *buf) -@@ -1824,6 +1994,9 @@ static struct attribute *per_bond_attrs[] = { - &dev_attr_all_slaves_active.attr, - &dev_attr_resend_igmp.attr, - &dev_attr_min_links.attr, -+ &dev_attr_lacp_fallback_allow.attr, -+ &dev_attr_lacp_fallback_active.attr, -+ &dev_attr_lacp_fallback_period.attr, - NULL, - }; - -@@ -1885,3 +2058,39 @@ void bond_prepare_sysfs_group(struct bonding *bond) - bond->dev->sysfs_groups[0] = &bonding_group; - } - -+static struct kobj_type slave_ktype = { -+#ifdef CONFIG_SYSFS -+ .sysfs_ops = &slave_sysfs_ops, -+#endif -+}; -+ -+int bond_sysfs_slave_add(struct slave *slave) -+{ -+ const struct slave_attribute **a; -+ int err; -+ -+ err = kobject_init_and_add(&slave->kobj, &slave_ktype, -+ &(slave->dev->dev.kobj), "bonding_slave"); -+ if (err) -+ return err; -+ -+ for (a = slave_attrs; *a; ++a) { -+ err = sysfs_create_file(&slave->kobj, &((*a)->attr)); -+ if (err) { -+ kobject_del(&slave->kobj); -+ return err; -+ } -+ } -+ -+ return 0; -+} -+ -+void bond_sysfs_slave_del(struct slave *slave) -+{ -+ const struct slave_attribute **a; -+ -+ for (a = slave_attrs; *a; ++a) -+ sysfs_remove_file(&slave->kobj, &((*a)->attr)); -+ -+ kobject_del(&slave->kobj); -+} -diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h -index 553f3ce..382947a 100644 ---- a/drivers/net/bonding/bonding.h -+++ b/drivers/net/bonding/bonding.h -@@ -157,6 +157,9 @@ struct bond_params { - int tx_queues; - int all_slaves_active; - int resend_igmp; -+ int lacp_fallback_allow; -+ int lacp_fallback_active; -+ u32 lacp_fallback_period; - }; - - struct bond_parm_tbl { -@@ -191,11 +194,13 @@ struct slave { - u32 speed; - u16 queue_id; - u8 perm_hwaddr[ETH_ALEN]; -+ int lacp_fallback_priority; - struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */ - struct tlb_slave_info tlb_info; - #ifdef CONFIG_NET_POLL_CONTROLLER - struct netpoll *np; - #endif -+ struct kobject kobj; - }; - - /* -@@ -381,6 +386,8 @@ int bond_create(struct net *net, const char *name); - int bond_create_sysfs(struct bond_net *net); - void bond_destroy_sysfs(struct bond_net *net); - void bond_prepare_sysfs_group(struct bonding *bond); -+int bond_sysfs_slave_add(struct slave *slave); -+void bond_sysfs_slave_del(struct slave *slave); - int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave); - void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave); - int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-local-fdb-delete-check.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-local-fdb-delete-check.patch deleted file mode 100644 index 5603fc56..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-local-fdb-delete-check.patch +++ /dev/null @@ -1,139 +0,0 @@ -ge: Fix the way to check if a local fdb entry can be deleted - -hould take into account the followings when deleting a local fdb -y. - -p_vlan_find() can be used only when vid != 0 to check if an entry is -letable, because a fdb entry with vid 0 can exist at any time while -p_vlan_find() always return false with vid 0. - -ample of problematic case: -ip link set eth0 address 12:34:56:78:90:ab -ip link set eth1 address 12:34:56:78:90:ab -brctl addif br0 eth0 -brctl addif br0 eth1 -ip link set eth0 address aa:bb:cc:dd:ee:ff -en, the fdb entry 12:34:56:78:90:ab will be deleted even though the -idge port eth1 still has that address. - -e port to which the bridge device is attached might needs a local entry - its mac address is set manually. - -ample of problematic case: -ip link set eth0 address 12:34:56:78:90:ab -brctl addif br0 eth0 -ip link set br0 address 12:34:56:78:90:ab -ip link set eth0 address aa:bb:cc:dd:ee:ff -en, the fdb still must have the entry 12:34:56:78:90:ab, but it will be -leted. - -an use br->dev->addr_assign_type to check if the address is manually -or not, but I propose another approach. - -e we delete and insert local entries whenever changing mac address -he bridge device, we can change dst of the entry to NULL regardless of -_assign_type when deleting an entry associated with a certain port, -if it is found to be unnecessary later, then delete it. - is, if changing mac address of a port, the entry might be changed -ts dst being NULL first, but is eventually deleted when recalculating -changing bridge id. - - approach is especially useful when we want to share the code with -ting vlan in which the bridge device might want such an entry regardless -ddr_assign_type, and makes things easy because we don't have to consider -ac address of the bridge device will be changed or not at the time we -te a local entry of a port, which means fdb code will not be bothered - if the bridge id calculating logic is changed in the future. - -, this change reduces inconsistent state, where frames whose dst is the -address of the bridge, can't reach the bridge because of premature fdb -y deletion. This change reduces the possibility that the bridge device -ies unreachable mac address to arp requests, which could occur during -short window between calling del_nbp() and br_stp_recalculate_bridge_id() -r_del_if(). This will effective after br_fdb_delete_by_port() starts to -the same code by following patch. - -ed-off-by: Toshiaki Makita -d-by: Vlad Yasevich -ed-off-by: David S. Miller - -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 8b300e6..87c45dc 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -112,12 +112,20 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) - if (op != p && - ether_addr_equal(op->dev->dev_addr, - f->addr.addr) && -- nbp_vlan_find(op, vid)) { -+ (!vid || nbp_vlan_find(op, vid))) { - f->dst = op; - goto insert; - } - } - -+ /* maybe bridge device has same hw addr? */ -+ if (ether_addr_equal(br->dev->dev_addr, -+ f->addr.addr) && -+ (!vid || br_vlan_find(br, vid))) { -+ f->dst = NULL; -+ goto insert; -+ } -+ - /* delete old one */ - fdb_delete(br, f); - insert: -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index ff58204..b0c527e 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -619,6 +619,7 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br, - int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags); - int br_vlan_delete(struct net_bridge *br, u16 vid); - void br_vlan_flush(struct net_bridge *br); -+bool br_vlan_find(struct net_bridge *br, u16 vid); - int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val); - int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags); - int nbp_vlan_delete(struct net_bridge_port *port, u16 vid); -@@ -700,6 +701,11 @@ static inline void br_vlan_flush(struct net_bridge *br) - { - } - -+static inline bool br_vlan_find(struct net_bridge *br, u16 vid) -+{ -+ return false; -+} -+ - static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) - { - return -EOPNOTSUPP; -diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c -index 90732f5..655c2e9 100644 ---- a/net/bridge/br_vlan.c -+++ b/net/bridge/br_vlan.c -@@ -298,6 +298,25 @@ void br_vlan_flush(struct net_bridge *br) - __vlan_flush(pv); - } - -+bool br_vlan_find(struct net_bridge *br, u16 vid) -+{ -+ struct net_port_vlans *pv; -+ bool found = false; -+ -+ rcu_read_lock(); -+ pv = rcu_dereference(br->vlan_info); -+ -+ if (!pv) -+ goto out; -+ -+ if (test_bit(vid, pv->vlan_bitmap)) -+ found = true; -+ -+out: -+ rcu_read_unlock(); -+ return found; -+} -+ - int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) - { - if (!rtnl_trylock()) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mac-move-notify-vm.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mac-move-notify-vm.patch deleted file mode 100644 index 593f0345..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mac-move-notify-vm.patch +++ /dev/null @@ -1,26 +0,0 @@ -FDB notify netlink notification on a mac move when software forwarding/VM - -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 5e93fc6..8b300e6 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -500,6 +500,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, - { - struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)]; - struct net_bridge_fdb_entry *fdb; -+ struct net_bridge_port *old_src = NULL; - - /* some users want to always flood. */ - if (hold_time(br) == 0) -@@ -520,8 +521,11 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, - source->dev->name); - } else { - /* fastpath: update of existing entry */ -+ old_src = fdb->dst; - fdb->dst = source; - fdb->updated = jiffies; -+ if (old_src != source) -+ fdb_notify(br, fdb, RTM_NEWNEIGH); - } - } else { - spin_lock(&br->hash_lock); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-make-master-index-partof-rtmneigh-msh.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-make-master-index-partof-rtmneigh-msh.patch deleted file mode 100644 index 9f1a44b4..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-make-master-index-partof-rtmneigh-msh.patch +++ /dev/null @@ -1,34 +0,0 @@ -bridge: Add master index to fdb RTM_NEWNEIGH msg - -diff --git a/include/linux/neighbour.h b/include/linux/neighbour.h -index a7003b7..5016559 100644 ---- a/include/linux/neighbour.h -+++ b/include/linux/neighbour.h -@@ -20,6 +20,7 @@ enum { - NDA_LLADDR, - NDA_CACHEINFO, - NDA_PROBES, -+ NDA_MASTER, - __NDA_MAX - }; - -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 2a4eac0..039d6ac 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -472,6 +472,7 @@ static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br, - ndm->ndm_state = fdb_to_nud(fdb); - - NLA_PUT(skb, NDA_LLADDR, ETH_ALEN, &fdb->addr); -+ NLA_PUT_U32(skb, NDA_MASTER, br->dev->ifindex); - - ci.ndm_used = jiffies_to_clock_t(now - fdb->used); - ci.ndm_confirmed = 0; -@@ -490,6 +491,7 @@ static inline size_t fdb_nlmsg_size(void) - { - return NLMSG_ALIGN(sizeof(struct ndmsg)) - + nla_total_size(ETH_ALEN) /* NDA_LLADDR */ -+ + nla_total_size(4) /* NDA_MASTER */ - + nla_total_size(sizeof(struct nda_cacheinfo)); - } - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-make-path-cost-setting-persistent.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-make-path-cost-setting-persistent.patch deleted file mode 100644 index 5affc352..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-make-path-cost-setting-persistent.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 8f3359bdc83f1abb1989e0817ab0e0b18667c828 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: make user modified path cost sticky - -Keep a STP port path cost value if it was set by a user. -Don't replace it with the link-speed based path cost -whenever the link goes down and comes back up. - -Reported-by: Roopa Prabhu -Signed-off-by: Stephen Hemminger -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c -index 56693c3..a73bcd5 100644 ---- a/net/bridge/br_if.c -+++ b/net/bridge/br_if.c -@@ -66,7 +66,8 @@ void br_port_carrier_check(struct net_bridge_port *p) - struct net_device *dev = p->dev; - struct net_bridge *br = p->br; - -- if (netif_running(dev) && netif_carrier_ok(dev)) -+ if (!(p->flags & BR_ADMIN_COST) && -+ netif_running(dev) && netif_carrier_ok(dev)) - p->path_cost = port_cost(dev); - - if (!netif_running(br->dev)) -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index dc28e83..82aed23 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -135,6 +135,10 @@ struct net_bridge_port - - unsigned long flags; - #define BR_HAIRPIN_MODE 0x00000001 -+#define BR_BPDU_GUARD 0x00000002 -+#define BR_ROOT_BLOCK 0x00000004 -+#define BR_MULTICAST_FAST_LEAVE 0x00000008 -+#define BR_ADMIN_COST 0x00000010 - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - u32 multicast_startup_queries_sent; -diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c -index 19308e3..b88a256 100644 ---- a/net/bridge/br_stp_if.c -+++ b/net/bridge/br_stp_if.c -@@ -290,6 +290,7 @@ int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost) - path_cost > BR_MAX_PATH_COST) - return -ERANGE; - -+ p->flags |= BR_ADMIN_COST; - p->path_cost = path_cost; - br_configuration_update(p->br); - br_port_state_selection(p->br); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-dump-vlan.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-dump-vlan.patch deleted file mode 100644 index 2fc8dbbf..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-dump-vlan.patch +++ /dev/null @@ -1,46 +0,0 @@ -Send 1 netlink message for a vlan with list of groups and router ports - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index 257e0f0..a049696 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -49,7 +49,7 @@ fail: - } - - static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, -- struct net_device *dev) -+ struct net_device *dev, __u16 old_vid) - { - struct net_bridge *br = netdev_priv(dev); - struct net_bridge_mdb_htable *mdb; -@@ -92,6 +92,13 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, - if (port) { - struct br_mdb_entry e; - memset(&e, 0, sizeof(e)); -+ if (old_vid == 0) -+ old_vid = p->addr.vid; -+ else if (old_vid != p->addr.vid) { -+ nla_nest_cancel(skb, nest2); -+ err = -EMSGSIZE; -+ goto out; -+ } - e.ifindex = port->dev->ifindex; - e.state = p->state; - if (p->addr.proto == htons(ETH_P_IP)) -@@ -128,6 +135,7 @@ static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb) - struct net *net = sock_net(skb->sk); - struct nlmsghdr *nlh = NULL; - int idx = 0, s_idx; -+ __u16 old_vid = 0; - - s_idx = cb->args[0]; - -@@ -152,7 +160,7 @@ static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb) - bpm = nlmsg_data(nlh); - memset(bpm, 0, sizeof(*bpm)); - bpm->ifindex = dev->ifindex; -- if (br_mdb_fill_info(skb, cb, dev) < 0) -+ if (br_mdb_fill_info(skb, cb, dev, old_vid) < 0) - goto out; - if (br_rports_fill_info(skb, cb, dev) < 0) - goto out; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-hash.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-hash.patch deleted file mode 100644 index d425ff1d..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-hash.patch +++ /dev/null @@ -1,26 +0,0 @@ -Change defaults for hash_max and elasticity. Fix to initialize the values when mdb is created too. - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 4feb18a..ed5d394 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -593,7 +593,7 @@ struct net_bridge_mdb_entry *br_multicast_new_group(struct net_bridge *br, - - mdb = rcu_dereference_protected(br->mdb, 1); - if (!mdb) { -- err = br_mdb_rehash(&br->mdb, BR_HASH_SIZE, 0); -+ err = br_mdb_rehash(&br->mdb, br->hash_max, br->hash_elasticity); - if (err) - return ERR_PTR(err); - goto rehash; -@@ -1657,8 +1657,8 @@ static void br_multicast_query_expired(unsigned long data) - - void br_multicast_init(struct net_bridge *br) - { -- br->hash_elasticity = 4; -- br->hash_max = 512; -+ br->hash_elasticity = 4096; -+ br->hash_max = 4096; - - br->multicast_router = 1; - br->multicast_querier = 0; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-leave-dually-connected.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-leave-dually-connected.patch deleted file mode 100644 index ecb51628..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-leave-dually-connected.patch +++ /dev/null @@ -1,21 +0,0 @@ -When an IGMP leave message is received, the querier will send a group specific -query message which will cause all snooping switches to reduce the timeout of -that group for all ports to be last membership count, due to which the port -group could age out incorrectly on one of the CLAG switch. Fix: dont age out -port group faster for dually connected hosts or if learnt on peer link - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 72b35dc..0996c69 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1313,8 +1313,9 @@ static int br_ip4_multicast_query(struct net_bridge *br, - pp = &p->next) { - if (timer_pending(&p->timer) ? - time_after(p->timer.expires, now + max_delay) : -- try_to_del_timer_sync(&p->timer) >= 0) -+ try_to_del_timer_sync(&p->timer) >= 0) { - mod_timer(&p->timer, now + max_delay); -+ } - } - - out: diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-notify.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-notify.patch deleted file mode 100644 index 43314a2f..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-notify.patch +++ /dev/null @@ -1,152 +0,0 @@ -Add support del_mdb(router/receiver ports) and add_mdb(router ports). - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index 560cddb..3807e00 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -239,6 +239,70 @@ void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, - __br_mdb_notify(dev, &entry, type); - } - -+static int nlmsg_populate_rtr_fill(struct sk_buff *skb, -+ struct net_device *dev, -+ int ifindex, u32 pid, -+ u32 seq, int type, unsigned int flags) -+{ -+ struct nlmsghdr *nlh; -+ struct br_port_msg *bpm; -+ struct nlattr *nest; -+ -+ nlh = nlmsg_put(skb, pid, seq, type, sizeof(*bpm), NLM_F_MULTI); -+ if (!nlh) -+ return -EMSGSIZE; -+ -+ bpm = nlmsg_data(nlh); -+ memset(bpm, 0, sizeof(*bpm)); -+ bpm->family = AF_BRIDGE; -+ bpm->ifindex = dev->ifindex; -+ nest = nla_nest_start(skb, MDBA_ROUTER); -+ if (nest == NULL) -+ goto cancel; -+ -+ if (nla_put_u32(skb, MDBA_ROUTER_PORT, ifindex)) -+ goto end; -+ -+ nla_nest_end(skb, nest); -+ return nlmsg_end(skb, nlh); -+ -+end: -+ nla_nest_end(skb, nest); -+cancel: -+ nlmsg_cancel(skb, nlh); -+ return -EMSGSIZE; -+} -+ -+static inline size_t rtnl_rtr_nlmsg_size(void) -+{ -+ return NLMSG_ALIGN(sizeof(struct br_port_msg)) -+ + nla_total_size(sizeof(__u32)); -+} -+ -+void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, -+ int type) -+{ -+ struct net *net = dev_net(dev); -+ struct sk_buff *skb; -+ int err = -ENOBUFS; -+ int ifindex = port ? port->dev->ifindex : 0; -+ -+ skb = nlmsg_new(rtnl_rtr_nlmsg_size(), GFP_ATOMIC); -+ if (!skb) -+ goto errout; -+ -+ err = nlmsg_populate_rtr_fill(skb, dev, ifindex, 0, 0, type, NTF_SELF); -+ if (err < 0) { -+ kfree_skb(skb); -+ goto errout; -+ } -+ -+ rtnl_notify(skb, net, 0, RTNLGRP_MDB, NULL, GFP_ATOMIC); -+ return; -+errout: -+ rtnl_set_sk_err(net, RTNLGRP_MDB, err); -+} -+ - static bool is_valid_mdb_entry(struct br_mdb_entry *entry) - { - if (entry->ifindex == 0) -@@ -343,7 +407,6 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, - return -ENOMEM; - rcu_assign_pointer(*pp, p); - -- br_mdb_notify(br->dev, port, group, RTM_NEWMDB); - return 0; - } - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 7322157..587c1cc 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -259,6 +259,7 @@ static void br_multicast_del_pg(struct net_bridge *br, - if (p != pg) - continue; - -+ br_mdb_notify(br->dev, p->port, &pg->addr, RTM_DELMDB); - rcu_assign_pointer(*pp, p->next); - hlist_del_init(&p->mglist); - del_timer(&p->timer); -@@ -738,6 +739,7 @@ static void br_multicast_router_expired(unsigned long data) - goto out; - - hlist_del_init_rcu(&port->rlist); -+ br_rtr_notify(br->dev, port, RTM_DELMDB); - - out: - spin_unlock(&br->multicast_lock); -@@ -863,8 +865,10 @@ void br_multicast_disable_port(struct net_bridge_port *port) - hlist_for_each_entry_safe(pg, p, n, &port->mglist, mglist) - br_multicast_del_pg(br, pg); - -- if (!hlist_unhashed(&port->rlist)) -+ if (!hlist_unhashed(&port->rlist)) { - hlist_del_init_rcu(&port->rlist); -+ br_rtr_notify(br->dev, port, RTM_DELMDB); -+ } - del_timer(&port->multicast_router_timer); - del_timer(&port->multicast_query_timer); - spin_unlock(&br->multicast_lock); -@@ -1007,6 +1011,7 @@ static void br_multicast_add_router(struct net_bridge *br, - hlist_add_after_rcu(slot, &port->rlist); - else - hlist_add_head_rcu(&port->rlist, &br->router_list); -+ br_rtr_notify(br->dev, port, RTM_NEWMDB); - } - - static void br_multicast_mark_router(struct net_bridge *br, -@@ -1679,8 +1684,10 @@ int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val) - p->multicast_router = val; - err = 0; - -- if (val < 2 && !hlist_unhashed(&p->rlist)) -+ if (val < 2 && !hlist_unhashed(&p->rlist)) { - hlist_del_init_rcu(&p->rlist); -+ br_rtr_notify(br->dev, p, RTM_DELMDB); -+ } - - if (val == 1) - break; -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index f334219..5f28201 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -447,7 +447,9 @@ extern struct net_bridge_port_group *br_multicast_new_port_group( - extern void br_mdb_init(void); - extern void br_mdb_uninit(void); - extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, -- struct br_ip *group, int type); -+ struct br_ip *group, int type); -+extern void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, -+ int type); - - #define mlock_dereference(X, br) \ - rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-replace.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-replace.patch deleted file mode 100644 index af513f58..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-replace.patch +++ /dev/null @@ -1,15 +0,0 @@ -Add replace command for mdb entries - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index d186c09..257e0f0 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -531,6 +531,8 @@ static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - if (!err) - __br_mdb_notify(dev, entry, RTM_NEWMDB); - } -+ if ((nlh->nlmsg_flags & NLM_F_REPLACE) && (err == -EEXIST)) -+ err = 0; - return err; - } - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-rtrport-opt.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-rtrport-opt.patch deleted file mode 100644 index 54814ebd..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-rtrport-opt.patch +++ /dev/null @@ -1,27 +0,0 @@ -When a port is detected/configured as router port, dont process -queries/leaves on that port - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index b16f5cd..fb59cd3 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -731,7 +731,8 @@ static int br_multicast_add_group(struct net_bridge *br, - - spin_lock(&br->multicast_lock); - if (!netif_running(br->dev) || -- (port && port->state == BR_STATE_DISABLED)) -+ (port && (port->state == BR_STATE_DISABLED || -+ !hlist_unhashed(&port->rlist)))) - goto out; - - mp = br_multicast_new_group(br, port, group); -@@ -1431,7 +1432,8 @@ static void br_multicast_leave_group(struct net_bridge *br, - - spin_lock(&br->multicast_lock); - if (!netif_running(br->dev) || -- (port && port->state == BR_STATE_DISABLED)) -+ (port && (port->state == BR_STATE_DISABLED || -+ !hlist_unhashed(&port->rlist)))) - goto out; - - mdb = mlock_dereference(br->mdb, br); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-static-del.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-static-del.patch deleted file mode 100644 index 467b84b0..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-static-del.patch +++ /dev/null @@ -1,22 +0,0 @@ -When querier is detected, static MDB entries cannot be deleted, fix this. - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index c0b8bbc..50b5e76 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -535,15 +535,9 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry) - ip.proto = entry->addr.proto; - ip.vid = entry->addr.vlan_id; - if (ip.proto == htons(ETH_P_IP)) { -- if (timer_pending(&br->ip4_querier.timer)) -- return -EBUSY; -- - ip.u.ip4 = entry->addr.u.ip4; - #if IS_ENABLED(CONFIG_IPV6) - } else { -- if (timer_pending(&br->ip6_querier.timer)) -- return -EBUSY; -- - ip.u.ip6 = entry->addr.u.ip6; - #endif - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-timer.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-timer.patch deleted file mode 100644 index 4276efef..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-timer.patch +++ /dev/null @@ -1,162 +0,0 @@ -Add capability to display timer info for mdb and router port entries. - -Add command to configure a temporary router port entry. - -diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h -index cf81969..f903106 100644 ---- a/include/linux/if_bridge.h -+++ b/include/linux/if_bridge.h -@@ -188,6 +188,15 @@ struct br_mdb_entry { - __be16 proto; - __be16 vlan_id; - } addr; -+ __u32 timer; -+}; -+ -+struct br_mdb_rtr_entry { -+ __u32 ifindex; -+ __u32 timer; -+#define MDB_RTR_TEMPORARY 0 -+#define MDB_RTR_PERMANENT 1 -+ __u8 state; - }; - - enum { -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index 50b5e76..d186c09 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -29,8 +29,16 @@ static int br_rports_fill_info(struct sk_buff *skb, struct netlink_callback *cb, - return -EMSGSIZE; - - hlist_for_each_entry_rcu(p, n, &br->router_list, rlist) { -- if (p && nla_put_u32(skb, MDBA_ROUTER_PORT, p->dev->ifindex)) -- goto fail; -+ if (p) { -+ struct br_mdb_rtr_entry e; -+ memset(&e, 0, sizeof(e)); -+ e.ifindex = p->dev->ifindex; -+ e.timer = br_timer_value(&p->multicast_router_timer); -+ e.state = (p->multicast_router == 2) ? -+ MDB_RTR_PERMANENT : MDB_RTR_TEMPORARY; -+ if (nla_put(skb, MDBA_ROUTER_PORT, sizeof(e), &e)) -+ goto fail; -+ } - } - - nla_nest_end(skb, nest); -@@ -94,6 +102,7 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, - #endif - e.addr.proto = p->addr.proto; - e.addr.vlan_id = p->addr.vid; -+ e.timer = br_timer_value(&p->timer); - if (nla_put(skb, MDBA_MDB_ENTRY_INFO, sizeof(e), &e)) { - nla_nest_cancel(skb, nest2); - err = -EMSGSIZE; -@@ -204,7 +213,9 @@ cancel: - static inline size_t rtnl_mdb_nlmsg_size(void) - { - return NLMSG_ALIGN(sizeof(struct br_port_msg)) -- + nla_total_size(sizeof(struct br_mdb_entry)); -+ + nla_total_size(sizeof(struct br_mdb_entry)) -+ + nla_total_size(sizeof(struct nlattr)) -+ + nla_total_size(sizeof(struct nlattr)); - } - - static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry, -@@ -425,8 +436,11 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, - for (pp = &mp->ports; - (p = mlock_dereference(*pp, br)) != NULL; - pp = &p->next) { -- if (p->port == port) -+ if (p->port == port) { -+ if (p->state == MDB_TEMPORARY) -+ mod_timer(&p->timer, now + br->multicast_membership_interval); - return -EEXIST; -+ } - if ((unsigned long)p->port < (unsigned long)port) - break; - } -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index fec8e6a..72b35dc 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -801,13 +801,16 @@ static void br_multicast_router_expired(unsigned long data) - struct net_bridge *br = port->br; - - spin_lock(&br->multicast_lock); -- if (port->multicast_router != 1 || -+ if (port->multicast_router == 0 || -+ port->multicast_router == 2 || - timer_pending(&port->multicast_router_timer) || - hlist_unhashed(&port->rlist)) - goto out; - - hlist_del_init_rcu(&port->rlist); - br_rtr_notify(br->dev, port, RTM_DELMDB); -+ if (port->multicast_router == 3) -+ port->multicast_router = 1; - - out: - spin_unlock(&br->multicast_lock); -@@ -1029,6 +1032,8 @@ void br_multicast_disable_port(struct net_bridge_port *port) - if (!hlist_unhashed(&port->rlist)) { - hlist_del_init_rcu(&port->rlist); - br_rtr_notify(br->dev, port, RTM_DELMDB); -+ if (port->multicast_router == 3) -+ port->multicast_router = 1; - } - del_timer(&port->multicast_router_timer); - del_timer(&port->ip4_query.timer); -@@ -1187,6 +1192,8 @@ static void br_multicast_add_router(struct net_bridge *br, - struct net_bridge_port *p; - struct hlist_node *n, *slot = NULL; - -+ if (!hlist_unhashed(&port->rlist)) -+ return; - hlist_for_each_entry(p, n, &br->router_list, rlist) { - if ((unsigned long) port >= (unsigned long) p) - break; -@@ -1212,7 +1219,7 @@ static void br_multicast_mark_router(struct net_bridge *br, - return; - } - -- if (port->multicast_router != 1) -+ if (port->multicast_router == 0 || port->multicast_router == 2) - return; - - if (!hlist_unhashed(&port->rlist)) -@@ -1999,9 +2006,13 @@ int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val) - { - struct net_bridge *br = p->br; - int err = -ENOENT; -+ unsigned long now = jiffies; - - spin_lock(&br->multicast_lock); - if (p->multicast_router == val) { -+ if (p->multicast_router == 3) -+ mod_timer(&p->multicast_router_timer, -+ now + br->multicast_querier_interval); - err = 0; - goto unlock; - } -@@ -2010,6 +2021,7 @@ int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val) - case 0: - case 1: - case 2: -+ case 3: - p->multicast_router = val; - err = 0; - -@@ -2021,6 +2033,11 @@ int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val) - if (val == 1) - break; - -+ if (val == 3) { -+ br_multicast_mark_router(br, p); -+ break; -+ } -+ - del_timer(&p->multicast_router_timer); - - if (val == 0) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-unspecified-vlan.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-unspecified-vlan.patch deleted file mode 100644 index 74f1ad5b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mdb-unspecified-vlan.patch +++ /dev/null @@ -1,98 +0,0 @@ -Install MDB entry in all vlans when vlan is not specified and vlan filtering -is enabled. - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index 80f648f..c0b8bbc 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -482,6 +482,10 @@ static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - struct net_device *dev; - struct net_bridge *br; - int err; -+ struct net_port_vlans *pv; -+ unsigned short vid = VLAN_N_VID; -+ struct net_device *pdev; -+ struct net_bridge_port *p; - - err = br_mdb_parse(skb, nlh, &dev, &entry); - if (err < 0) -@@ -489,9 +493,30 @@ static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - - br = netdev_priv(dev); - -- err = __br_mdb_add(net, br, entry); -- if (!err) -- __br_mdb_notify(dev, entry, RTM_NEWMDB); -+ /* If vlan filtering is enabled and VLAN is not specified -+ * install mdb entry on all vlans configured on the port. -+ */ -+ pdev = __dev_get_by_index(net, entry->ifindex); -+ if (!pdev) -+ return -ENODEV; -+ -+ p = br_port_get_rtnl(pdev); -+ if (!p || p->br != br || p->state == BR_STATE_DISABLED) -+ return -EINVAL; -+ -+ pv = nbp_get_vlan_info(p); -+ if (br->vlan_enabled && pv && (entry->addr.vlan_id == 0)) { -+ for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { -+ entry->addr.vlan_id = vid; -+ err = __br_mdb_add(net, br, entry); -+ if (!err) -+ __br_mdb_notify(dev, entry, RTM_NEWMDB); -+ } -+ } else { -+ err = __br_mdb_add(net, br, entry); -+ if (!err) -+ __br_mdb_notify(dev, entry, RTM_NEWMDB); -+ } - return err; - } - -@@ -562,16 +587,41 @@ static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - struct br_mdb_entry *entry; - struct net_bridge *br; - int err; -- -+ struct net *net = sock_net(skb->sk); -+ struct net_port_vlans *pv; -+ unsigned short vid = VLAN_N_VID; -+ struct net_device *pdev; -+ struct net_bridge_port *p; - err = br_mdb_parse(skb, nlh, &dev, &entry); - if (err < 0) - return err; - - br = netdev_priv(dev); - -- err = __br_mdb_del(br, entry); -- if (!err) -- __br_mdb_notify(dev, entry, RTM_DELMDB); -+ /* If vlan filtering is enabled and VLAN is not specified -+ * delete mdb entry on all vlans configured on the port. -+ */ -+ pdev = __dev_get_by_index(net, entry->ifindex); -+ if (!pdev) -+ return -ENODEV; -+ -+ p = br_port_get_rtnl(pdev); -+ if (!p || p->br != br) -+ return -EINVAL; -+ -+ pv = nbp_get_vlan_info(p); -+ if (br->vlan_enabled && pv && (entry->addr.vlan_id == 0)) { -+ for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { -+ entry->addr.vlan_id = vid; -+ err = __br_mdb_del(br, entry); -+ if (!err) -+ __br_mdb_notify(dev, entry, RTM_DELMDB); -+ } -+ } else { -+ err = __br_mdb_del(br, entry); -+ if (!err) -+ __br_mdb_notify(dev, entry, RTM_DELMDB); -+ } - return err; - } - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mlag-peer-dual-link.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mlag-peer-dual-link.patch deleted file mode 100644 index 3ba036e4..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mlag-peer-dual-link.patch +++ /dev/null @@ -1,113 +0,0 @@ -Added MLAG peerlink and duallink bridge port attributes - -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index b262ddd..45736db 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -219,6 +219,8 @@ enum { - IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */ - IFLA_BRPORT_LEARNING, /* mac learning */ - IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */ -+ IFLA_BRPORT_PEER_LINK = 253, /* MLAG peer link */ -+ IFLA_BRPORT_DUAL_LINK, /* MLAG Dual Connected link */ - __IFLA_BRPORT_MAX - }; - #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) -diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c -index 79ab806..2bcb63f 100644 ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -112,6 +112,11 @@ static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) - /* flood forward IGMP/MLD report/leave when hardware forwarded */ - if (br_hw_fwding_enabled && br_multicast_is_rep_leave(skb)) - igmp_report_leave_forward = 1; -+ /* don't forward IGMP/MLD report/leave when received on MLAG peer_link -+ * and being sent to dual_link interface -+ */ -+ if (igmp_report_leave_forward && p->peer_link && to->dual_link) -+ igmp_report_leave_forward = 0; - - if (br_hw_fwding_enabled && !stp_disabled_forward && - !igmp_report_leave_forward) { -diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c -index 4544c7b..77666db 100644 ---- a/net/bridge/br_netlink.c -+++ b/net/bridge/br_netlink.c -@@ -34,6 +34,8 @@ static inline size_t br_port_info_size(void) - + nla_total_size(1) /* IFLA_BRPORT_FAST_LEAVE */ - + nla_total_size(1) /* IFLA_BRPORT_LEARNING */ - + nla_total_size(1) /* IFLA_BRPORT_UNICAST_FLOOD */ -+ + nla_total_size(1) /* IFLA_BRPORT_PEER_LINK */ -+ + nla_total_size(1) /* IFLA_BRPORT_DUAL_LINK */ - + 0; - } - -@@ -58,6 +60,8 @@ static int br_port_fill_attrs(struct sk_buff *skb, - nla_put_u16(skb, IFLA_BRPORT_PRIORITY, p->priority) || - nla_put_u32(skb, IFLA_BRPORT_COST, p->path_cost) || - nla_put_u8(skb, IFLA_BRPORT_MODE, mode) || -+ nla_put_u8(skb, IFLA_BRPORT_PEER_LINK, p->peer_link) || -+ nla_put_u8(skb, IFLA_BRPORT_DUAL_LINK, p->dual_link) || - nla_put_u8(skb, IFLA_BRPORT_GUARD, !!(p->flags & BR_BPDU_GUARD)) || - nla_put_u8(skb, IFLA_BRPORT_PROTECT, !!(p->flags & BR_ROOT_BLOCK)) || - nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE, !!(p->flags & BR_MULTICAST_FAST_LEAVE)) || -@@ -387,6 +391,8 @@ static const struct nla_policy ifla_brport_policy[IFLA_BRPORT_MAX + 1] = { - [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 }, - [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 }, - [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_PEER_LINK] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_DUAL_LINK] = { .type = NLA_U8 }, - }; - - /* Change the state of the port and notify spanning tree */ -@@ -421,6 +427,18 @@ static void br_set_port_flag(struct net_bridge_port *p, struct nlattr *tb[], - } - } - -+static int br_set_port_peer_link(struct net_bridge_port *p, u8 enable) -+{ -+ p->peer_link = enable; -+ return 0; -+} -+ -+static int br_set_port_dual_link(struct net_bridge_port *p, u8 enable) -+{ -+ p->dual_link = enable; -+ return 0; -+} -+ - /* Process bridge protocol info on port */ - static int br_setport(struct net_bridge_port *p, struct nlattr *tb[]) - { -@@ -450,6 +468,18 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[]) - if (err) - return err; - } -+ -+ if (tb[IFLA_BRPORT_PEER_LINK]) { -+ err = br_set_port_peer_link(p, nla_get_u8(tb[IFLA_BRPORT_PEER_LINK])); -+ if (err) -+ return err; -+ } -+ -+ if (tb[IFLA_BRPORT_DUAL_LINK]) { -+ err = br_set_port_dual_link(p, nla_get_u8(tb[IFLA_BRPORT_DUAL_LINK])); -+ if (err) -+ return err; -+ } - return 0; - } - -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index c5fe7c0..75068b7 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -202,6 +202,8 @@ struct net_bridge_port - #ifdef CONFIG_BRIDGE_VLAN_FILTERING - struct net_port_vlans __rcu *vlan_info; - #endif -+ u8 peer_link; -+ u8 dual_link; - }; - - #define br_port_exists(dev) (dev->priv_flags & IFF_BRIDGE_PORT) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mld-get-rid-of-MLDV2_MRC-and-simplify-calcu.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mld-get-rid-of-MLDV2_MRC-and-simplify-calcu.patch deleted file mode 100644 index 6748e57d..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mld-get-rid-of-MLDV2_MRC-and-simplify-calcu.patch +++ /dev/null @@ -1,100 +0,0 @@ -From e3f5b17047dec4acd8957dad053e70d87f18d97e Mon Sep 17 00:00:00 2001 -Subject: [PATCH] net: ipv6: mld: get rid of MLDV2_MRC and simplify - calculation - -Get rid of MLDV2_MRC and use our new macros for mantisse and -exponent to calculate Maximum Response Delay out of the Maximum -Response Code. - -Signed-off-by: Daniel Borkmann -Cc: Hannes Frederic Sowa -Acked-by: Hannes Frederic Sowa -Signed-off-by: David S. Miller - -diff --git a/include/net/mld.h b/include/net/mld.h -index 467143c..faa1d16 100644 ---- a/include/net/mld.h -+++ b/include/net/mld.h -@@ -63,13 +63,48 @@ struct mld2_query { - #define mld2q_mrc mld2q_hdr.icmp6_maxdelay - #define mld2q_resv1 mld2q_hdr.icmp6_dataun.un_data16[1] - --/* Max Response Code */ --#define MLDV2_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value)) --#define MLDV2_EXP(thresh, nbmant, nbexp, value) \ -- ((value) < (thresh) ? (value) : \ -- ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \ -- (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp)))) -- --#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) -+/* RFC3810, 5.1.3. Maximum Response Code: -+ * -+ * If Maximum Response Code >= 32768, Maximum Response Code represents a -+ * floating-point value as follows: -+ * -+ * 0 1 2 3 4 5 6 7 8 9 A B C D E F -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * |1| exp | mant | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ */ -+#define MLDV2_MRC_EXP(value) (((value) >> 12) & 0x0007) -+#define MLDV2_MRC_MAN(value) ((value) & 0x0fff) -+ -+/* RFC3810, 5.1.9. QQIC (Querier's Query Interval Code): -+ * -+ * If QQIC >= 128, QQIC represents a floating-point value as follows: -+ * -+ * 0 1 2 3 4 5 6 7 -+ * +-+-+-+-+-+-+-+-+ -+ * |1| exp | mant | -+ * +-+-+-+-+-+-+-+-+ -+ */ -+#define MLDV2_QQIC_EXP(value) (((value) >> 4) & 0x07) -+#define MLDV2_QQIC_MAN(value) ((value) & 0x0f) -+ -+static inline unsigned long mldv2_mrc(const struct mld2_query *mlh2) -+{ -+ /* RFC3810, 5.1.3. Maximum Response Code */ -+ unsigned long ret, mc_mrc = ntohs(mlh2->mld2q_mrc); -+ -+ if (mc_mrc < 32768) { -+ ret = mc_mrc; -+ } else { -+ unsigned long mc_man, mc_exp; -+ -+ mc_exp = MLDV2_MRC_EXP(mc_mrc); -+ mc_man = MLDV2_MRC_MAN(mc_mrc); -+ -+ ret = (mc_man | 0x1000) << (mc_exp + 3); -+ } -+ -+ return ret; -+} - - #endif -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 96f876e..7870449 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1193,7 +1193,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, - if (!mld2q->mld2q_nsrcs) - group = &mld2q->mld2q_mca; - -- max_delay = max(msecs_to_jiffies(MLDV2_MRC(ntohs(mld2q->mld2q_mrc))), 1UL); -+ max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL); - } - - if (!group) -diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c -index 4f12b66..72e50a2 100644 ---- a/net/ipv6/mcast.c -+++ b/net/ipv6/mcast.c -@@ -1165,7 +1165,7 @@ int igmp6_event_query(struct sk_buff *skb) - return -EINVAL; - - mlh2 = (struct mld2_query *)skb_transport_header(skb); -- max_delay = (MLDV2_MRC(ntohs(mlh2->mld2q_mrc))*HZ)/1000; -+ max_delay = max(msecs_to_jiffies(mldv2_mrc(mlh2)), 1UL); - if (!max_delay) - max_delay = 1; - idev->mc_maxdelay = max_delay; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-move-logging-to-pr-debug.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-move-logging-to-pr-debug.patch deleted file mode 100644 index ecd4567a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-move-logging-to-pr-debug.patch +++ /dev/null @@ -1,15 +0,0 @@ -Move all bridge driver logging to dynamic logging (pr_debug) - -diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c -index 4a36459..9ad8595 100644 ---- a/net/bridge/br_stp.c -+++ b/net/bridge/br_stp.c -@@ -31,7 +31,7 @@ static const char *const br_port_state_names[] = { - - void br_log_state(const struct net_bridge_port *p) - { -- br_info(p->br, "port %u(%s) entered %s state\n", -+ br_debug(p->br, "port %u(%s) entered %s state\n", - (unsigned int) p->port_no, p->dev->name, - br_port_state_names[p->state]); - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mrouter-fix.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mrouter-fix.patch deleted file mode 100644 index 9c0b7d71..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-mrouter-fix.patch +++ /dev/null @@ -1,61 +0,0 @@ -static router port was not being marked after port down/up. Querier functionality was not being enabled, if userspace STP was being run. For redundant configuration of router port, the node was being added to router list every time. - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index bc10e6b..206e6c9 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -38,6 +38,8 @@ - rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) - - static void br_multicast_start_querier(struct net_bridge *br); -+static void br_multicast_add_router(struct net_bridge *br, -+ struct net_bridge_port *port); - - unsigned int br_mdb_rehash_seq; - -@@ -870,6 +872,8 @@ void br_multicast_enable_port(struct net_bridge_port *port) - goto out; - - __br_multicast_enable_port(port); -+ if ((port->multicast_router == 2) && hlist_unhashed(&port->rlist)) -+ br_multicast_add_router(br, port); - - out: - spin_unlock(&br->multicast_lock); -@@ -1723,6 +1727,11 @@ int br_multicast_set_router(struct net_bridge *br, unsigned long val) - int err = -ENOENT; - - spin_lock_bh(&br->multicast_lock); -+ if (br->multicast_router == val) { -+ err = 0; -+ goto unlock; -+ } -+ - switch (val) { - case 0: - case 2: -@@ -1750,6 +1759,10 @@ int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val) - int err = -ENOENT; - - spin_lock(&br->multicast_lock); -+ if (p->multicast_router == val) { -+ err = 0; -+ goto unlock; -+ } - - switch (val) { - case 0: -diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c -index 3fb4de8..542180a 100644 ---- a/net/bridge/br_stp.c -+++ b/net/bridge/br_stp.c -@@ -420,6 +420,9 @@ void br_port_state_selection(struct net_bridge *br) - p->topology_change_ack = 0; - br_make_blocking(p); - } -+ } else if ((br->stp_enabled == BR_USER_STP) && -+ (p->state == BR_STATE_FORWARDING)) { -+ br_multicast_enable_port(p); - } - - if (p->state == BR_STATE_FORWARDING) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-notify-mdb-changes-via-netlink.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-notify-mdb-changes-via-netlink.patch deleted file mode 100644 index d01c2a5b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-notify-mdb-changes-via-netlink.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 37a393bc4932d7bac360f40064aaafc01ab44901 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: notify mdb changes via netlink - -As Stephen mentioned, we need to monitor the mdb -changes in user-space, so add notifications via netlink too. - -Cc: Herbert Xu -Cc: Stephen Hemminger -Cc: "David S. Miller" -Cc: Thomas Graf -Signed-off-by: Cong Wang -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index 67d8b93..7add2cf 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -155,6 +155,86 @@ out: - return skb->len; - } - -+static int nlmsg_populate_mdb_fill(struct sk_buff *skb, -+ struct net_device *dev, -+ struct br_mdb_entry *entry, u32 pid, -+ u32 seq, int type, unsigned int flags) -+{ -+ struct nlmsghdr *nlh; -+ struct br_port_msg *bpm; -+ struct nlattr *nest, *nest2; -+ -+ nlh = nlmsg_put(skb, pid, seq, type, sizeof(*bpm), NLM_F_MULTI); -+ if (!nlh) -+ return -EMSGSIZE; -+ -+ bpm = nlmsg_data(nlh); -+ bpm->family = AF_BRIDGE; -+ bpm->ifindex = dev->ifindex; -+ nest = nla_nest_start(skb, MDBA_MDB); -+ if (nest == NULL) -+ goto cancel; -+ nest2 = nla_nest_start(skb, MDBA_MDB_ENTRY); -+ if (nest2 == NULL) -+ goto end; -+ -+ if (nla_put(skb, MDBA_MDB_ENTRY_INFO, sizeof(*entry), entry)) -+ goto end; -+ -+ nla_nest_end(skb, nest2); -+ nla_nest_end(skb, nest); -+ return nlmsg_end(skb, nlh); -+ -+end: -+ nla_nest_end(skb, nest); -+cancel: -+ nlmsg_cancel(skb, nlh); -+ return -EMSGSIZE; -+} -+ -+static inline size_t rtnl_mdb_nlmsg_size(void) -+{ -+ return NLMSG_ALIGN(sizeof(struct br_port_msg)) -+ + nla_total_size(sizeof(struct br_mdb_entry)); -+} -+ -+static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry, -+ int type) -+{ -+ struct net *net = dev_net(dev); -+ struct sk_buff *skb; -+ int err = -ENOBUFS; -+ -+ skb = nlmsg_new(rtnl_mdb_nlmsg_size(), GFP_ATOMIC); -+ if (!skb) -+ goto errout; -+ -+ err = nlmsg_populate_mdb_fill(skb, dev, entry, 0, 0, type, NTF_SELF); -+ if (err < 0) { -+ kfree_skb(skb); -+ goto errout; -+ } -+ -+ rtnl_notify(skb, net, 0, RTNLGRP_MDB, NULL, GFP_ATOMIC); -+ return; -+errout: -+ rtnl_set_sk_err(net, RTNLGRP_MDB, err); -+} -+ -+void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, -+ struct br_ip *group, int type) -+{ -+ struct br_mdb_entry entry; -+ -+ entry.ifindex = port->dev->ifindex; -+ entry.addr.proto = group->proto; -+ entry.addr.u.ip4 = group->u.ip4; -+#if IS_ENABLED(CONFIG_IPV6) -+ entry.addr.u.ip6 = group->u.ip6; -+#endif -+ __br_mdb_notify(dev, &entry, type); -+} -+ - void br_mdb_init(void) - { - rtnl_register(PF_BRIDGE, RTM_GETMDB, NULL, br_mdb_dump, NULL); -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 735b451..8d0ee9b 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -678,6 +678,7 @@ static int br_multicast_add_group(struct net_bridge *br, - (unsigned long)p); - - rcu_assign_pointer(*pp, p); -+ br_mdb_notify(br->dev, port, group, RTM_NEWMDB); - - found: - mod_timer(&p->timer, now + br->multicast_membership_interval); -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index a4aa2d5..48a0667 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -433,6 +433,8 @@ extern int br_multicast_set_port_router(struct net_bridge_port *p, - extern int br_multicast_toggle(struct net_bridge *br, unsigned long val); - extern int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val); - extern void br_mdb_init(void); -+extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, -+ struct br_ip *group, int type); - - static inline bool br_multicast_is_router(struct net_bridge *br) - { diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-porting-new-driver.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-porting-new-driver.patch deleted file mode 100644 index 5da962f8..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-porting-new-driver.patch +++ /dev/null @@ -1,9687 +0,0 @@ -Porting new bridge driver and 8021q driver from kernel 3.14 - -diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c -index 6cb0112..1c55aec 100644 ---- a/drivers/net/vxlan.c -+++ b/drivers/net/vxlan.c -@@ -357,7 +357,8 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], - } - - /* Delete entry (via netlink) */ --static int vxlan_fdb_delete(struct ndmsg *ndm, struct net_device *dev, -+static int vxlan_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], -+ struct net_device *dev, - const unsigned char *addr) - { - struct vxlan_dev *vxlan = netdev_priv(dev); -diff --git a/include/linux/bitops.h b/include/linux/bitops.h -index 87a375f..2fe4e79 100644 ---- a/include/linux/bitops.h -+++ b/include/linux/bitops.h -@@ -26,6 +26,23 @@ extern unsigned long __sw_hweight64(__u64 w); - (bit) < (size); \ - (bit) = find_next_bit((addr), (size), (bit) + 1)) - -+/* same as for_each_set_bit() but use bit as value to start with */ -+#define for_each_set_bit_from(bit, addr, size) \ -+ for ((bit) = find_next_bit((addr), (size), (bit)); \ -+ (bit) < (size); \ -+ (bit) = find_next_bit((addr), (size), (bit) + 1)) -+ -+#define for_each_clear_bit(bit, addr, size) \ -+ for ((bit) = find_first_zero_bit((addr), (size)); \ -+ (bit) < (size); \ -+ (bit) = find_next_zero_bit((addr), (size), (bit) + 1)) -+ -+/* same as for_each_clear_bit() but use bit as value to start with */ -+#define for_each_clear_bit_from(bit, addr, size) \ -+ for ((bit) = find_next_zero_bit((addr), (size), (bit)); \ -+ (bit) < (size); \ -+ (bit) = find_next_zero_bit((addr), (size), (bit) + 1)) -+ - static __inline__ int get_bitmask_order(unsigned int count) - { - int order; -diff --git a/include/linux/device.h b/include/linux/device.h -index ae97e46..efc7ba2 100644 ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -503,6 +503,12 @@ ssize_t device_store_int(struct device *dev, struct device_attribute *attr, - - #define DEVICE_ATTR(_name, _mode, _show, _store) \ - struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) -+#define DEVICE_ATTR_RW(_name) \ -+ struct device_attribute dev_attr_##_name = __ATTR_RW(_name) -+#define DEVICE_ATTR_RO(_name) \ -+ struct device_attribute dev_attr_##_name = __ATTR_RO(_name) -+#define DEVICE_ATTR_WO(_name) \ -+ struct device_attribute dev_attr_##_name = __ATTR_WO(_name) - #define DEVICE_ULONG_ATTR(_name, _mode, _var) \ - struct dev_ext_attribute dev_attr_##_name = \ - { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } -diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h -index ef121eb..ae9c1f6 100644 ---- a/include/linux/etherdevice.h -+++ b/include/linux/etherdevice.h -@@ -53,6 +53,33 @@ extern struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, - #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1) - #define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count) - -+/* Reserved Ethernet Addresses per IEEE 802.1Q */ -+static const u8 eth_reserved_addr_base[ETH_ALEN] __aligned(2) = -+{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; -+ -+/** -+ * is_link_local_ether_addr - Determine if given Ethernet address is link-local -+ * @addr: Pointer to a six-byte array containing the Ethernet address -+ * -+ * Return true if address is link local reserved addr (01:80:c2:00:00:0X) per -+ * IEEE 802.1Q 8.6.3 Frame filtering. -+ * -+ * Please note: addr must be aligned to u16. -+ */ -+static inline bool is_link_local_ether_addr(const u8 *addr) -+{ -+ __be16 *a = (__be16 *)addr; -+ static const __be16 *b = (const __be16 *)eth_reserved_addr_base; -+ static const __be16 m = cpu_to_be16(0xfff0); -+ -+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) -+ return (((*(const u32 *)addr) ^ (*(const u32 *)b)) | -+ ((a[2] ^ b[2]) & m)) == 0; -+#else -+ return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0; -+#endif -+} -+ - /** - * is_zero_ether_addr - Determine if give Ethernet address is all zeros. - * @addr: Pointer to a six-byte array containing the Ethernet address -@@ -182,6 +209,43 @@ static inline void eth_hw_addr_random(struct net_device *dev) - } - - /** -+ * ether_addr_copy - Copy an Ethernet address -+ * @dst: Pointer to a six-byte array Ethernet address destination -+ * @src: Pointer to a six-byte array Ethernet address source -+ * -+ * Please note: dst & src must both be aligned to u16. -+ */ -+static inline void ether_addr_copy(u8 *dst, const u8 *src) -+{ -+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) -+ *(u32 *)dst = *(const u32 *)src; -+ *(u16 *)(dst + 4) = *(const u16 *)(src + 4); -+#else -+ u16 *a = (u16 *)dst; -+ const u16 *b = (const u16 *)src; -+ -+ a[0] = b[0]; -+ a[1] = b[1]; -+ a[2] = b[2]; -+#endif -+} -+ -+/** -+ * eth_hw_addr_inherit - Copy dev_addr from another net_device -+ * @dst: pointer to net_device to copy dev_addr to -+ * @src: pointer to net_device to copy dev_addr from -+ * -+ * Copy the Ethernet address from one net_device to another along with -+ * the address attributes (addr_assign_type). -+ */ -+static inline void eth_hw_addr_inherit(struct net_device *dst, -+ struct net_device *src) -+{ -+ dst->addr_assign_type = src->addr_assign_type; -+ ether_addr_copy(dst->dev_addr, src->dev_addr); -+} -+ -+/** - * compare_ether_addr - Compare two Ethernet addresses - * @addr1: Pointer to a six-byte array containing the Ethernet address - * @addr2: Pointer other six-byte array containing the Ethernet address -diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h -index bf53693..d72ce1c 100644 ---- a/include/linux/if_bridge.h -+++ b/include/linux/if_bridge.h -@@ -98,6 +98,37 @@ struct __fdb_entry { - __u16 unused; - }; - -+/* Bridge Flags */ -+#define BRIDGE_FLAGS_MASTER 1 /* Bridge command to/from master */ -+#define BRIDGE_FLAGS_SELF 2 /* Bridge command to/from lowerdev */ -+ -+#define BRIDGE_MODE_VEB 0 /* Default loopback mode */ -+#define BRIDGE_MODE_VEPA 1 /* 802.1Qbg defined VEPA mode */ -+ -+/* Bridge management nested attributes -+ * [IFLA_AF_SPEC] = { -+ * [IFLA_BRIDGE_FLAGS] -+ * [IFLA_BRIDGE_MODE] -+ * [IFLA_BRIDGE_VLAN_INFO] -+ * } -+ */ -+enum { -+ IFLA_BRIDGE_FLAGS, -+ IFLA_BRIDGE_MODE, -+ IFLA_BRIDGE_VLAN_INFO, -+ __IFLA_BRIDGE_MAX, -+}; -+#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1) -+ -+#define BRIDGE_VLAN_INFO_MASTER (1<<0) /* Operate on Bridge device as well */ -+#define BRIDGE_VLAN_INFO_PVID (1<<1) /* VLAN is PVID, ingress untagged */ -+#define BRIDGE_VLAN_INFO_UNTAGGED (1<<2) /* VLAN egresses untagged */ -+ -+struct bridge_vlan_info { -+ __u16 flags; -+ __u16 vid; -+}; -+ - /* Bridge multicast database attributes - * [MDBA_MDB] = { - * [MDBA_MDB_ENTRY] = { -diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h -index e473003..2d21664 100644 ---- a/include/linux/if_ether.h -+++ b/include/linux/if_ether.h -@@ -91,6 +91,9 @@ - #define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */ - #define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */ - -+#define ETH_P_802_3_MIN 0x0600 /* If the value in the ethernet type is less than this value -+ * then the frame is Ethernet II. Else it is 802.3 */ -+ - /* - * Non DIX types. Won't clash for 1500 types. - */ -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index 8b03450..42a7c70 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -203,6 +203,26 @@ enum { - - #define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1) - -+enum { -+ BRIDGE_MODE_UNSPEC, -+ BRIDGE_MODE_HAIRPIN, -+}; -+ -+enum { -+ IFLA_BRPORT_UNSPEC, -+ IFLA_BRPORT_STATE, /* Spanning tree state */ -+ IFLA_BRPORT_PRIORITY, /* " priority */ -+ IFLA_BRPORT_COST, /* " cost */ -+ IFLA_BRPORT_MODE, /* mode (hairpin) */ -+ IFLA_BRPORT_GUARD, /* bpdu guard */ -+ IFLA_BRPORT_PROTECT, /* root port protection */ -+ IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */ -+ IFLA_BRPORT_LEARNING, /* mac learning */ -+ IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */ -+ __IFLA_BRPORT_MAX -+}; -+#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) -+ - struct ifla_cacheinfo { - __u32 max_reasm_len; - __u32 tstamp; /* ipv6InterfaceTable updated timestamp */ -@@ -228,6 +248,7 @@ enum { - IFLA_VLAN_FLAGS, - IFLA_VLAN_EGRESS_QOS, - IFLA_VLAN_INGRESS_QOS, -+ IFLA_VLAN_PROTOCOL, - __IFLA_VLAN_MAX, - }; - -diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h -index c944c4f..7471fd2 100644 ---- a/include/linux/if_vlan.h -+++ b/include/linux/if_vlan.h -@@ -74,22 +74,7 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb) - /* found in socket.c */ - extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *)); - --/* if this changes, algorithm will have to be reworked because this -- * depends on completely exhausting the VLAN identifier space. Thus -- * it gives constant time look-up, but in many cases it wastes memory. -- */ --#define VLAN_GROUP_ARRAY_SPLIT_PARTS 8 --#define VLAN_GROUP_ARRAY_PART_LEN (VLAN_N_VID/VLAN_GROUP_ARRAY_SPLIT_PARTS) -- --struct vlan_group { -- struct net_device *real_dev; /* The ethernet(like) device -- * the vlan is attached to. -- */ -- unsigned int nr_vlans; -- struct hlist_node hlist; /* linked list */ -- struct net_device **vlan_devices_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS]; -- struct rcu_head rcu; --}; -+struct vlan_info; - - static inline int is_vlan_dev(struct net_device *dev) - { -@@ -100,6 +85,29 @@ static inline int is_vlan_dev(struct net_device *dev) - #define vlan_tx_nonzero_tag_present(__skb) \ - (vlan_tx_tag_present(__skb) && ((__skb)->vlan_tci & VLAN_VID_MASK)) - #define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT) -+#define vlan_tx_tag_get_id(__skb) ((__skb)->vlan_tci & VLAN_VID_MASK) -+ -+/** -+ * struct vlan_pcpu_stats - VLAN percpu rx/tx stats -+ * @rx_packets: number of received packets -+ * @rx_bytes: number of received bytes -+ * @rx_multicast: number of received multicast packets -+ * @tx_packets: number of transmitted packets -+ * @tx_bytes: number of transmitted bytes -+ * @syncp: synchronization point for 64bit counters -+ * @rx_errors: number of rx errors -+ * @tx_dropped: number of tx drops -+ */ -+struct vlan_pcpu_stats { -+ u64 rx_packets; -+ u64 rx_bytes; -+ u64 rx_multicast; -+ u64 tx_packets; -+ u64 tx_bytes; -+ struct u64_stats_sync syncp; -+ u32 rx_errors; -+ u32 tx_dropped; -+}; - - #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) - -@@ -108,9 +116,90 @@ extern struct net_device *__vlan_find_dev_deep(struct net_device *real_dev, - extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); - extern u16 vlan_dev_vlan_id(const struct net_device *dev); - -+/** -+ * struct vlan_priority_tci_mapping - vlan egress priority mappings -+ * @priority: skb priority -+ * @vlan_qos: vlan priority: (skb->priority << 13) & 0xE000 -+ * @next: pointer to next struct -+ */ -+struct vlan_priority_tci_mapping { -+ u32 priority; -+ u16 vlan_qos; -+ struct vlan_priority_tci_mapping *next; -+}; -+ -+struct proc_dir_entry; -+struct netpoll; -+ -+/** -+ * struct vlan_dev_priv - VLAN private device data -+ * @nr_ingress_mappings: number of ingress priority mappings -+ * @ingress_priority_map: ingress priority mappings -+ * @nr_egress_mappings: number of egress priority mappings -+ * @egress_priority_map: hash of egress priority mappings -+ * @vlan_proto: VLAN encapsulation protocol -+ * @vlan_id: VLAN identifier -+ * @flags: device flags -+ * @real_dev: underlying netdevice -+ * @real_dev_addr: address of underlying netdevice -+ * @dent: proc dir entry -+ * @vlan_pcpu_stats: ptr to percpu rx stats -+ */ -+struct vlan_dev_priv { -+ unsigned int nr_ingress_mappings; -+ u32 ingress_priority_map[8]; -+ unsigned int nr_egress_mappings; -+ struct vlan_priority_tci_mapping *egress_priority_map[16]; -+ -+ __be16 vlan_proto; -+ u16 vlan_id; -+ u16 flags; -+ -+ struct net_device *real_dev; -+ unsigned char real_dev_addr[ETH_ALEN]; -+ -+ struct proc_dir_entry *dent; -+ struct vlan_pcpu_stats __percpu *vlan_pcpu_stats; -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ struct netpoll *netpoll; -+#endif -+}; -+ -+static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev) -+{ -+ return netdev_priv(dev); -+} -+ -+static inline u16 -+vlan_dev_get_egress_qos_mask(struct net_device *dev, u32 skprio) -+{ -+ struct vlan_priority_tci_mapping *mp; -+ -+ smp_rmb(); /* coupled with smp_wmb() in vlan_dev_set_egress_priority() */ -+ -+ mp = vlan_dev_priv(dev)->egress_priority_map[(skprio & 0xF)]; -+ while (mp) { -+ if (mp->priority == skprio) { -+ return mp->vlan_qos; /* This should already be shifted -+ * to mask correctly with the -+ * VLAN's TCI */ -+ } -+ mp = mp->next; -+ } -+ return 0; -+} -+ - extern bool vlan_do_receive(struct sk_buff **skb); - extern struct sk_buff *vlan_untag(struct sk_buff *skb); -+extern int vlan_vid_add(struct net_device *dev, __be16 proto, u16 vid); -+extern void vlan_vid_del(struct net_device *dev, __be16 proto, u16 vid); -+ -+extern int vlan_vids_add_by_dev(struct net_device *dev, -+ const struct net_device *by_dev); -+extern void vlan_vids_del_by_dev(struct net_device *dev, -+ const struct net_device *by_dev); - -+extern bool vlan_uses_dev(const struct net_device *dev); - #else - static inline struct net_device * - __vlan_find_dev_deep(struct net_device *real_dev, u16 vlan_id) -@@ -139,6 +228,31 @@ static inline struct sk_buff *vlan_untag(struct sk_buff *skb) - { - return skb; - } -+ -+static inline int vlan_vid_add(struct net_device *dev, __be16 proto, u16 vid) -+{ -+ return 0; -+} -+ -+static inline void vlan_vid_del(struct net_device *dev, __be16 proto, u16 vid) -+{ -+} -+ -+static inline int vlan_vids_add_by_dev(struct net_device *dev, -+ const struct net_device *by_dev) -+{ -+ return 0; -+} -+ -+static inline void vlan_vids_del_by_dev(struct net_device *dev, -+ const struct net_device *by_dev) -+{ -+} -+ -+static inline bool vlan_uses_dev(const struct net_device *dev) -+{ -+ return false; -+} - #endif - - /** -@@ -310,6 +424,40 @@ static inline __be16 vlan_get_protocol(const struct sk_buff *skb) - - return protocol; - } -+ -+static inline void vlan_set_encap_proto(struct sk_buff *skb, -+ struct vlan_hdr *vhdr) -+{ -+ __be16 proto; -+ unsigned short *rawp; -+ -+ /* -+ * Was a VLAN packet, grab the encapsulated protocol, which the layer -+ * three protocols care about. -+ */ -+ -+ proto = vhdr->h_vlan_encapsulated_proto; -+ if (ntohs(proto) >= ETH_P_802_3_MIN) { -+ skb->protocol = proto; -+ return; -+ } -+ -+ rawp = (unsigned short *)(vhdr + 1); -+ if (*rawp == 0xFFFF) -+ /* -+ * This is a magic hack to spot IPX packets. Older Novell -+ * breaks the protocol design and runs IPX over 802.3 without -+ * an 802.2 LLC layer. We look for FFFF which isn't a used -+ * 802.2 SSAP/DSAP. This won't work for fault tolerant netware -+ * but does for the rest. -+ */ -+ skb->protocol = htons(ETH_P_802_3); -+ else -+ /* -+ * Real 802.2 LLC -+ */ -+ skb->protocol = htons(ETH_P_802_2); -+} - #endif /* __KERNEL__ */ - - /* VLAN IOCTLs are found in sockios.h */ -@@ -332,6 +480,7 @@ enum vlan_flags { - VLAN_FLAG_REORDER_HDR = 0x1, - VLAN_FLAG_GVRP = 0x2, - VLAN_FLAG_LOOSE_BINDING = 0x4, -+ VLAN_FLAG_MVRP = 0x8, - }; - - enum vlan_name_types { -diff --git a/include/linux/neighbour.h b/include/linux/neighbour.h -index d2299b8..232e5fa 100644 ---- a/include/linux/neighbour.h -+++ b/include/linux/neighbour.h -@@ -20,6 +20,7 @@ enum { - NDA_LLADDR, - NDA_CACHEINFO, - NDA_PROBES, -+ NDA_VLAN, - NDA_MASTER, - __NDA_MAX - }; -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index fb7f658..c1f6a6e 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -55,7 +55,6 @@ - #include - - --struct vlan_group; - struct netpoll_info; - struct phy_device; - /* 802.11 specific */ -@@ -70,6 +69,8 @@ typedef u32 netdev_features_t; - #define NET_ADDR_PERM 0 /* address is permanent (default) */ - #define NET_ADDR_RANDOM 1 /* address is generated randomly */ - #define NET_ADDR_STOLEN 2 /* address is stolen from other device */ -+#define NET_ADDR_SET 3 /* address is set using -+ * dev_set_mac_address() */ - - /* Backlog congestion levels */ - #define NET_RX_SUCCESS 0 /* keep 'em coming, baby */ -@@ -977,18 +978,27 @@ struct net_device_ops { - u32 features); - int (*ndo_set_features)(struct net_device *dev, - u32 features); -- int (*ndo_fdb_add)(struct ndmsg *ndm, -- struct nlattr *tb[], -- struct net_device *dev, -- const unsigned char *addr, -- u16 flags); -- int (*ndo_fdb_del)(struct ndmsg *ndm, -- struct net_device *dev, -- const unsigned char *addr); -- int (*ndo_fdb_dump)(struct sk_buff *skb, -- struct netlink_callback *cb, -- struct net_device *dev, -- int idx); -+ int (*ndo_fdb_add)(struct ndmsg *ndm, -+ struct nlattr *tb[], -+ struct net_device *dev, -+ const unsigned char *addr, -+ u16 flags); -+ int (*ndo_fdb_del)(struct ndmsg *ndm, -+ struct nlattr *tb[], -+ struct net_device *dev, -+ const unsigned char *addr); -+ int (*ndo_fdb_dump)(struct sk_buff *skb, -+ struct netlink_callback *cb, -+ struct net_device *dev, -+ int idx); -+ int (*ndo_bridge_setlink)(struct net_device *dev, -+ struct nlmsghdr *nlh); -+ int (*ndo_bridge_getlink)(struct sk_buff *skb, -+ u32 pid, u32 seq, -+ struct net_device *dev, -+ u32 filter_mask); -+ int (*ndo_bridge_dellink)(struct net_device *dev, -+ struct nlmsghdr *nlh); - }; - - /* -@@ -1192,8 +1202,8 @@ struct net_device { - - /* Protocol specific pointers */ - --#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -- struct vlan_group __rcu *vlgrp; /* VLAN group */ -+#if IS_ENABLED(CONFIG_VLAN_8021Q) -+ struct vlan_info __rcu *vlan_info; /* VLAN info */ - #endif - #ifdef CONFIG_NET_DSA - void *dsa_ptr; /* dsa specific data */ -@@ -1569,6 +1579,35 @@ struct packet_type { - struct list_head list; - }; - -+struct offload_callbacks { -+ struct sk_buff *(*gso_segment)(struct sk_buff *skb, -+ netdev_features_t features); -+ int (*gso_send_check)(struct sk_buff *skb); -+ struct sk_buff **(*gro_receive)(struct sk_buff **head, -+ struct sk_buff *skb); -+ int (*gro_complete)(struct sk_buff *skb, int nhoff); -+}; -+ -+struct packet_offload { -+ __be16 type; /* This is really htons(ether_type). */ -+ struct offload_callbacks callbacks; -+ struct list_head list; -+}; -+ -+struct udp_offload { -+ __be16 port; -+ struct offload_callbacks callbacks; -+}; -+ -+/* often modified stats are per cpu, other are shared (netdev->stats) */ -+struct pcpu_sw_netstats { -+ u64 rx_packets; -+ u64 rx_bytes; -+ u64 tx_packets; -+ u64 tx_bytes; -+ struct u64_stats_sync syncp; -+}; -+ - #include - - /* netdevice notifier chain. Please remember to update the rtnetlink -@@ -1598,9 +1637,34 @@ struct packet_type { - #define NETDEV_RELEASE 0x0012 - #define NETDEV_NOTIFY_PEERS 0x0013 - #define NETDEV_JOIN 0x0014 -+#define NETDEV_CHANGEUPPER 0x0015 -+#define NETDEV_RESEND_IGMP 0x0016 -+#define NETDEV_PRECHANGEMTU 0x0017 /* notify before mtu change happened */ - - extern int register_netdevice_notifier(struct notifier_block *nb); - extern int unregister_netdevice_notifier(struct notifier_block *nb); -+ -+struct netdev_notifier_info { -+ struct net_device *dev; -+}; -+ -+struct netdev_notifier_change_info { -+ struct netdev_notifier_info info; /* must be first */ -+ unsigned int flags_changed; -+}; -+ -+static inline void netdev_notifier_info_init(struct netdev_notifier_info *info, -+ struct net_device *dev) -+{ -+ info->dev = dev; -+} -+ -+static inline struct net_device * -+netdev_notifier_info_to_dev(const struct netdev_notifier_info *info) -+{ -+ return info->dev; -+} -+ - extern int call_netdevice_notifiers(unsigned long val, struct net_device *dev); - - -diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h -index f38195c..0c693d9 100644 ---- a/include/linux/rtnetlink.h -+++ b/include/linux/rtnetlink.h -@@ -622,6 +622,7 @@ struct tcamsg { - - /* New extended info filters for IFLA_EXT_MASK */ - #define RTEXT_FILTER_VF (1 << 0) -+#define RTEXT_FILTER_BRVLAN (1 << 1) - - /* End of information exported to user level */ - -diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h -index ffbb4f0..9714436 100644 ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -463,6 +463,7 @@ struct sk_buff { - #endif - }; - -+ __be16 vlan_proto; - __u16 vlan_tci; - - sk_buff_data_t transport_header; -diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h -index dac0859..270878b 100644 ---- a/include/linux/sysfs.h -+++ b/include/linux/sysfs.h -@@ -78,6 +78,14 @@ struct attribute_group { - .show = _name##_show, \ - } - -+#define __ATTR_WO(_name) { \ -+ .attr = { .name = __stringify(_name), .mode = S_IWUSR }, \ -+ .store = _name##_store, \ -+} -+ -+#define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \ -+ _name##_show, _name##_store) -+ - #define __ATTR_NULL { .attr = { .name = NULL } } - - #define attr_name(_attr) (_attr).attr.name -diff --git a/include/linux/u64_stats_sync.h b/include/linux/u64_stats_sync.h -index 8da8c4e..3dc2be5 100644 ---- a/include/linux/u64_stats_sync.h -+++ b/include/linux/u64_stats_sync.h -@@ -67,6 +67,12 @@ struct u64_stats_sync { - #endif - }; - -+#if BITS_PER_LONG == 32 && defined(CONFIG_SMP) -+# define u64_stats_init(syncp) seqcount_init(syncp.seq) -+#else -+# define u64_stats_init(syncp) do { } while (0) -+#endif -+ - static inline void u64_stats_update_begin(struct u64_stats_sync *syncp) - { - #if BITS_PER_LONG==32 && defined(CONFIG_SMP) -diff --git a/include/net/dst.h b/include/net/dst.h -index 86ef78d..c0238f5 100644 ---- a/include/net/dst.h -+++ b/include/net/dst.h -@@ -406,6 +406,13 @@ static inline struct neighbour *dst_neigh_lookup(const struct dst_entry *dst, co - return dst->ops->neigh_lookup(dst, daddr); - } - -+static inline struct neighbour *dst_neigh_lookup_skb(const struct dst_entry *dst, -+ struct sk_buff *skb) -+{ -+ struct neighbour *n = dst->ops->neigh_lookup(dst, NULL); -+ return IS_ERR(n) ? NULL : n; -+} -+ - static inline void dst_link_failure(struct sk_buff *skb) - { - struct dst_entry *dst = skb_dst(skb); -diff --git a/include/net/netlink.h b/include/net/netlink.h -index 4fc2d2d..4565c27 100644 ---- a/include/net/netlink.h -+++ b/include/net/netlink.h -@@ -807,6 +807,17 @@ static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value) - } - - /** -+ * nla_put_be16 - Add a __be16 netlink attribute to a socket buffer -+ * @skb: socket buffer to add attribute to -+ * @attrtype: attribute type -+ * @value: numeric value -+ */ -+static inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value) -+{ -+ return nla_put(skb, attrtype, sizeof(__be16), &value); -+} -+ -+/** - * nla_put_u32 - Add a u32 netlink attribute to a socket buffer - * @skb: socket buffer to add attribute to - * @attrtype: attribute type -diff --git a/mm/backing-dev.c b/mm/backing-dev.c -index 2b49dd2..de77b4f 100644 ---- a/mm/backing-dev.c -+++ b/mm/backing-dev.c -@@ -225,7 +225,7 @@ static ssize_t max_ratio_store(struct device *dev, - } - BDI_SHOW(max_ratio, bdi->max_ratio) - --#define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store) -+//#define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store) - - static struct device_attribute bdi_dev_attrs[] = { - __ATTR_RW(read_ahead_kb), -diff --git a/net/8021q/Kconfig b/net/8021q/Kconfig -index fa073a5..4232018 100644 ---- a/net/8021q/Kconfig -+++ b/net/8021q/Kconfig -@@ -3,14 +3,14 @@ - # - - config VLAN_8021Q -- tristate "802.1Q VLAN Support" -+ tristate "802.1Q/802.1ad VLAN Support" - ---help--- - Select this and you will be able to create 802.1Q VLAN interfaces -- on your ethernet interfaces. 802.1Q VLAN supports almost -- everything a regular ethernet interface does, including -- firewalling, bridging, and of course IP traffic. You will need -- the 'vconfig' tool from the VLAN project in order to effectively -- use VLANs. See the VLAN web page for more information: -+ on your Ethernet interfaces. 802.1Q VLAN supports almost -+ everything a regular Ethernet interface does, including -+ firewalling, bridging, and of course IP traffic. You will need -+ the 'ip' utility in order to effectively use VLANs. -+ See the VLAN web page for more information: - - - To compile this code as a module, choose M here: the module -@@ -27,3 +27,14 @@ config VLAN_8021Q_GVRP - automatic propagation of registered VLANs to switches. - - If unsure, say N. -+ -+config VLAN_8021Q_MVRP -+ bool "MVRP (Multiple VLAN Registration Protocol) support" -+ depends on VLAN_8021Q -+ select MRP -+ help -+ Select this to enable MVRP end-system support. MVRP is used for -+ automatic propagation of registered VLANs to switches; it -+ supersedes GVRP and is not backwards-compatible. -+ -+ If unsure, say N. -diff --git a/net/8021q/Makefile b/net/8021q/Makefile -index 9f4f174..7bc8db0 100644 ---- a/net/8021q/Makefile -+++ b/net/8021q/Makefile -@@ -6,5 +6,6 @@ obj-$(CONFIG_VLAN_8021Q) += 8021q.o - - 8021q-y := vlan.o vlan_dev.o vlan_netlink.o - 8021q-$(CONFIG_VLAN_8021Q_GVRP) += vlan_gvrp.o -+8021q-$(CONFIG_VLAN_8021Q_MVRP) += vlan_mvrp.o - 8021q-$(CONFIG_PROC_FS) += vlanproc.o - -diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c -index 963f285..1e7051f 100644 ---- a/net/8021q/vlan.c -+++ b/net/8021q/vlan.c -@@ -51,35 +51,18 @@ const char vlan_version[] = DRV_VERSION; - - /* End of global variables definitions. */ - --static void vlan_group_free(struct vlan_group *grp) --{ -- int i; -- -- for (i = 0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) -- kfree(grp->vlan_devices_arrays[i]); -- kfree(grp); --} -- --static struct vlan_group *vlan_group_alloc(struct net_device *real_dev) --{ -- struct vlan_group *grp; -- -- grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL); -- if (!grp) -- return NULL; -- -- grp->real_dev = real_dev; -- return grp; --} -- --static int vlan_group_prealloc_vid(struct vlan_group *vg, u16 vlan_id) -+static int vlan_group_prealloc_vid(struct vlan_group *vg, -+ __be16 vlan_proto, u16 vlan_id) - { - struct net_device **array; -+ unsigned int pidx, vidx; - unsigned int size; - - ASSERT_RTNL(); - -- array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; -+ pidx = vlan_proto_idx(vlan_proto); -+ vidx = vlan_id / VLAN_GROUP_ARRAY_PART_LEN; -+ array = vg->vlan_devices_arrays[pidx][vidx]; - if (array != NULL) - return 0; - -@@ -88,78 +71,68 @@ static int vlan_group_prealloc_vid(struct vlan_group *vg, u16 vlan_id) - if (array == NULL) - return -ENOBUFS; - -- vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN] = array; -+ vg->vlan_devices_arrays[pidx][vidx] = array; - return 0; - } - --static void vlan_rcu_free(struct rcu_head *rcu) --{ -- vlan_group_free(container_of(rcu, struct vlan_group, rcu)); --} -- - void unregister_vlan_dev(struct net_device *dev, struct list_head *head) - { -- struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - struct net_device *real_dev = vlan->real_dev; -- const struct net_device_ops *ops = real_dev->netdev_ops; -+ struct vlan_info *vlan_info; - struct vlan_group *grp; - u16 vlan_id = vlan->vlan_id; - - ASSERT_RTNL(); - -- grp = rtnl_dereference(real_dev->vlgrp); -- BUG_ON(!grp); -+ vlan_info = rtnl_dereference(real_dev->vlan_info); -+ BUG_ON(!vlan_info); -+ -+ grp = &vlan_info->grp; - -- grp->nr_vlans--; -+ grp->nr_vlan_devs--; - -+ if (vlan->flags & VLAN_FLAG_MVRP) -+ vlan_mvrp_request_leave(dev); - if (vlan->flags & VLAN_FLAG_GVRP) - vlan_gvrp_request_leave(dev); - -- vlan_group_set_device(grp, vlan_id, NULL); -+ vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, NULL); -+ -+ //netdev_upper_dev_unlink(real_dev, dev); - /* Because unregister_netdevice_queue() makes sure at least one rcu - * grace period is respected before device freeing, - * we dont need to call synchronize_net() here. - */ - unregister_netdevice_queue(dev, head); - -- /* If the group is now empty, kill off the group. */ -- if (grp->nr_vlans == 0) { -+ if (grp->nr_vlan_devs == 0) { -+ vlan_mvrp_uninit_applicant(real_dev); - vlan_gvrp_uninit_applicant(real_dev); -- -- RCU_INIT_POINTER(real_dev->vlgrp, NULL); -- -- /* Free the group, after all cpu's are done. */ -- call_rcu(&grp->rcu, vlan_rcu_free); - } - - /* Take it out of our own structures, but be sure to interlock with - * HW accelerating devices or SW vlan input packet processing if - * VLAN is not 0 (leave it there for 802.1p). - */ -- if (vlan_id && (real_dev->features & NETIF_F_HW_VLAN_FILTER)) -- ops->ndo_vlan_rx_kill_vid(real_dev, vlan_id); -+ if (vlan_id) -+ vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id); - - /* Get rid of the vlan's reference to real_dev */ - dev_put(real_dev); - } - --int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id) -+int vlan_check_real_dev(struct net_device *real_dev, -+ __be16 protocol, u16 vlan_id) - { - const char *name = real_dev->name; -- const struct net_device_ops *ops = real_dev->netdev_ops; - - if (real_dev->features & NETIF_F_VLAN_CHALLENGED) { - pr_info("VLANs not supported on %s\n", name); - return -EOPNOTSUPP; - } - -- if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) && -- (!ops->ndo_vlan_rx_add_vid || !ops->ndo_vlan_rx_kill_vid)) { -- pr_info("Device %s has buggy VLAN hw accel\n", name); -- return -EOPNOTSUPP; -- } -- -- if (vlan_find_dev(real_dev, vlan_id) != NULL) -+ if (vlan_find_dev(real_dev, protocol, vlan_id) != NULL) - return -EEXIST; - - return 0; -@@ -167,32 +140,44 @@ int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id) - - int register_vlan_dev(struct net_device *dev) - { -- struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - struct net_device *real_dev = vlan->real_dev; -- const struct net_device_ops *ops = real_dev->netdev_ops; - u16 vlan_id = vlan->vlan_id; -- struct vlan_group *grp, *ngrp = NULL; -+ struct vlan_info *vlan_info; -+ struct vlan_group *grp; - int err; - -- grp = rtnl_dereference(real_dev->vlgrp); -- if (!grp) { -- ngrp = grp = vlan_group_alloc(real_dev); -- if (!grp) -- return -ENOBUFS; -+ err = vlan_vid_add(real_dev, vlan->vlan_proto, vlan_id); -+ if (err) -+ return err; -+ -+ vlan_info = rtnl_dereference(real_dev->vlan_info); -+ /* vlan_info should be there now. vlan_vid_add took care of it */ -+ BUG_ON(!vlan_info); -+ -+ grp = &vlan_info->grp; -+ if (grp->nr_vlan_devs == 0) { - err = vlan_gvrp_init_applicant(real_dev); - if (err < 0) -- goto out_free_group; -+ goto out_vid_del; -+ err = vlan_mvrp_init_applicant(real_dev); -+ if (err < 0) -+ goto out_uninit_gvrp; - } - -- err = vlan_group_prealloc_vid(grp, vlan_id); -+ err = vlan_group_prealloc_vid(grp, vlan->vlan_proto, vlan_id); - if (err < 0) -- goto out_uninit_applicant; -+ goto out_uninit_mvrp; - - err = register_netdevice(dev); - if (err < 0) -- goto out_uninit_applicant; -+ goto out_uninit_mvrp; - -- /* Account for reference in struct vlan_dev_info */ -+ //err = netdev_upper_dev_link(real_dev, dev); -+ //if (err) -+ // goto out_unregister_netdev; -+ -+ /* Account for reference in struct vlan_dev_priv */ - dev_hold(real_dev); - - netif_stacked_transfer_operstate(real_dev, dev); -@@ -201,25 +186,21 @@ int register_vlan_dev(struct net_device *dev) - /* So, got the sucker initialized, now lets place - * it into our local structure. - */ -- vlan_group_set_device(grp, vlan_id, dev); -- grp->nr_vlans++; -- -- if (ngrp) { -- rcu_assign_pointer(real_dev->vlgrp, ngrp); -- } -- if (real_dev->features & NETIF_F_HW_VLAN_FILTER) -- ops->ndo_vlan_rx_add_vid(real_dev, vlan_id); -+ vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, dev); -+ grp->nr_vlan_devs++; - - return 0; - --out_uninit_applicant: -- if (ngrp) -+//out_unregister_netdev: -+// unregister_netdevice(dev); -+out_uninit_mvrp: -+ if (grp->nr_vlan_devs == 0) -+ vlan_mvrp_uninit_applicant(real_dev); -+out_uninit_gvrp: -+ if (grp->nr_vlan_devs == 0) - vlan_gvrp_uninit_applicant(real_dev); --out_free_group: -- if (ngrp) { -- /* Free the group, after all cpu's are done. */ -- call_rcu(&ngrp->rcu, vlan_rcu_free); -- } -+out_vid_del: -+ vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id); - return err; - } - -@@ -229,6 +210,7 @@ out_free_group: - static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) - { - struct net_device *new_dev; -+ struct vlan_dev_priv *vlan; - struct net *net = dev_net(real_dev); - struct vlan_net *vn = net_generic(net, vlan_net_id); - char name[IFNAMSIZ]; -@@ -237,7 +219,7 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) - if (vlan_id >= VLAN_VID_MASK) - return -ERANGE; - -- err = vlan_check_real_dev(real_dev, vlan_id); -+ err = vlan_check_real_dev(real_dev, htons(ETH_P_8021Q), vlan_id); - if (err < 0) - return err; - -@@ -267,7 +249,7 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) - snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id); - } - -- new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name, vlan_setup); -+ new_dev = alloc_netdev(sizeof(struct vlan_dev_priv), name, vlan_setup); - - if (new_dev == NULL) - return -ENOBUFS; -@@ -277,11 +259,14 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) - * hope the underlying device can handle it. - */ - new_dev->mtu = real_dev->mtu; -+ new_dev->priv_flags |= (real_dev->priv_flags & IFF_UNICAST_FLT); - -- vlan_dev_info(new_dev)->vlan_id = vlan_id; -- vlan_dev_info(new_dev)->real_dev = real_dev; -- vlan_dev_info(new_dev)->dent = NULL; -- vlan_dev_info(new_dev)->flags = VLAN_FLAG_REORDER_HDR; -+ vlan = vlan_dev_priv(new_dev); -+ vlan->vlan_proto = htons(ETH_P_8021Q); -+ vlan->vlan_id = vlan_id; -+ vlan->real_dev = real_dev; -+ vlan->dent = NULL; -+ vlan->flags = VLAN_FLAG_REORDER_HDR; - - new_dev->rtnl_link_ops = &vlan_link_ops; - err = register_vlan_dev(new_dev); -@@ -298,25 +283,25 @@ out_free_newdev: - static void vlan_sync_address(struct net_device *dev, - struct net_device *vlandev) - { -- struct vlan_dev_info *vlan = vlan_dev_info(vlandev); -+ struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev); - - /* May be called without an actual change */ -- if (!compare_ether_addr(vlan->real_dev_addr, dev->dev_addr)) -+ if (ether_addr_equal(vlan->real_dev_addr, dev->dev_addr)) - return; - - /* vlan address was different from the old address and is equal to - * the new address */ -- if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && -- !compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) -+ if (!ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) && -+ ether_addr_equal(vlandev->dev_addr, dev->dev_addr)) - dev_uc_del(dev, vlandev->dev_addr); - - /* vlan address was equal to the old address and is different from - * the new address */ -- if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && -- compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) -+ if (ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) && -+ !ether_addr_equal(vlandev->dev_addr, dev->dev_addr)) - dev_uc_add(dev, vlandev->dev_addr); - -- memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); -+ ether_addr_copy(vlan->real_dev_addr, dev->dev_addr); - } - - static void vlan_transfer_features(struct net_device *dev, -@@ -324,12 +309,13 @@ static void vlan_transfer_features(struct net_device *dev, - { - vlandev->gso_max_size = dev->gso_max_size; - -+ //if (dev->features & NETIF_F_HW_VLAN_CTAG_TX) - if (dev->features & NETIF_F_HW_VLAN_TX) - vlandev->hard_header_len = dev->hard_header_len; - else - vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN; - --#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) -+#if IS_ENABLED(CONFIG_FCOE) - vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid; - #endif - -@@ -360,25 +346,28 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, - { - struct net_device *dev = ptr; - struct vlan_group *grp; -+ struct vlan_info *vlan_info; - int i, flgs; - struct net_device *vlandev; -- struct vlan_dev_info *vlan; -+ struct vlan_dev_priv *vlan; -+ bool last = false; - LIST_HEAD(list); - - if (is_vlan_dev(dev)) - __vlan_device_event(dev, event); - - if ((event == NETDEV_UP) && -- (dev->features & NETIF_F_HW_VLAN_FILTER) && -- dev->netdev_ops->ndo_vlan_rx_add_vid) { -+ //(dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) { -+ (dev->features & NETIF_F_HW_VLAN_FILTER)) { - pr_info("adding VLAN 0 to HW filter on device %s\n", - dev->name); -- dev->netdev_ops->ndo_vlan_rx_add_vid(dev, 0); -+ vlan_vid_add(dev, htons(ETH_P_8021Q), 0); - } - -- grp = rtnl_dereference(dev->vlgrp); -- if (!grp) -+ vlan_info = rtnl_dereference(dev->vlan_info); -+ if (!vlan_info) - goto out; -+ grp = &vlan_info->grp; - - /* It is OK that we do not hold the group lock right now, - * as we run under the RTNL lock. -@@ -387,22 +376,13 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, - switch (event) { - case NETDEV_CHANGE: - /* Propagate real device state to vlan devices */ -- for (i = 0; i < VLAN_N_VID; i++) { -- vlandev = vlan_group_get_device(grp, i); -- if (!vlandev) -- continue; -- -+ vlan_group_for_each_dev(grp, i, vlandev) - netif_stacked_transfer_operstate(dev, vlandev); -- } - break; - - case NETDEV_CHANGEADDR: - /* Adjust unicast filters on underlying device */ -- for (i = 0; i < VLAN_N_VID; i++) { -- vlandev = vlan_group_get_device(grp, i); -- if (!vlandev) -- continue; -- -+ vlan_group_for_each_dev(grp, i, vlandev) { - flgs = vlandev->flags; - if (!(flgs & IFF_UP)) - continue; -@@ -412,11 +392,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, - break; - - case NETDEV_CHANGEMTU: -- for (i = 0; i < VLAN_N_VID; i++) { -- vlandev = vlan_group_get_device(grp, i); -- if (!vlandev) -- continue; -- -+ vlan_group_for_each_dev(grp, i, vlandev) { - if (vlandev->mtu <= dev->mtu) - continue; - -@@ -426,28 +402,22 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, - - case NETDEV_FEAT_CHANGE: - /* Propagate device features to underlying device */ -- for (i = 0; i < VLAN_N_VID; i++) { -- vlandev = vlan_group_get_device(grp, i); -- if (!vlandev) -- continue; -- -+ vlan_group_for_each_dev(grp, i, vlandev) - vlan_transfer_features(dev, vlandev); -- } -- - break; - - case NETDEV_DOWN: -- /* Put all VLANs for this dev in the down state too. */ -- for (i = 0; i < VLAN_N_VID; i++) { -- vlandev = vlan_group_get_device(grp, i); -- if (!vlandev) -- continue; -+ //if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) -+ if (dev->features & NETIF_F_HW_VLAN_FILTER) -+ vlan_vid_del(dev, htons(ETH_P_8021Q), 0); - -+ /* Put all VLANs for this dev in the down state too. */ -+ vlan_group_for_each_dev(grp, i, vlandev) { - flgs = vlandev->flags; - if (!(flgs & IFF_UP)) - continue; - -- vlan = vlan_dev_info(vlandev); -+ vlan = vlan_dev_priv(vlandev); - if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) - dev_change_flags(vlandev, flgs & ~IFF_UP); - netif_stacked_transfer_operstate(dev, vlandev); -@@ -456,16 +426,12 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, - - case NETDEV_UP: - /* Put all VLANs for this dev in the up state too. */ -- for (i = 0; i < VLAN_N_VID; i++) { -- vlandev = vlan_group_get_device(grp, i); -- if (!vlandev) -- continue; -- -+ vlan_group_for_each_dev(grp, i, vlandev) { - flgs = vlandev->flags; - if (flgs & IFF_UP) - continue; - -- vlan = vlan_dev_info(vlandev); -+ vlan = vlan_dev_priv(vlandev); - if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) - dev_change_flags(vlandev, flgs | IFF_UP); - netif_stacked_transfer_operstate(dev, vlandev); -@@ -477,35 +443,31 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, - if (dev->reg_state != NETREG_UNREGISTERING) - break; - -- for (i = 0; i < VLAN_N_VID; i++) { -- vlandev = vlan_group_get_device(grp, i); -- if (!vlandev) -- continue; -- -- /* unregistration of last vlan destroys group, abort -+ vlan_group_for_each_dev(grp, i, vlandev) { -+ /* removal of last vid destroys vlan_info, abort - * afterwards */ -- if (grp->nr_vlans == 1) -- i = VLAN_N_VID; -+ if (vlan_info->nr_vids == 1) -+ last = true; - - unregister_vlan_dev(vlandev, &list); -+ if (last) -+ break; - } - unregister_netdevice_many(&list); - break; - - case NETDEV_PRE_TYPE_CHANGE: - /* Forbid underlaying device to change its type. */ -- return NOTIFY_BAD; -+ if (vlan_uses_dev(dev)) -+ return NOTIFY_BAD; -+ break; - - case NETDEV_NOTIFY_PEERS: - case NETDEV_BONDING_FAILOVER: -+ case NETDEV_RESEND_IGMP: - /* Propagate to vlan devices */ -- for (i = 0; i < VLAN_N_VID; i++) { -- vlandev = vlan_group_get_device(grp, i); -- if (!vlandev) -- continue; -- -+ vlan_group_for_each_dev(grp, i, vlandev) - call_netdevice_notifiers(event, vlandev); -- } - break; - } - -@@ -558,6 +520,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg) - switch (args.cmd) { - case SET_VLAN_INGRESS_PRIORITY_CMD: - err = -EPERM; -+ //if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - break; - vlan_dev_set_ingress_priority(dev, -@@ -568,6 +531,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg) - - case SET_VLAN_EGRESS_PRIORITY_CMD: - err = -EPERM; -+ //if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - break; - err = vlan_dev_set_egress_priority(dev, -@@ -577,6 +541,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg) - - case SET_VLAN_FLAG_CMD: - err = -EPERM; -+ //if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - break; - err = vlan_dev_change_flags(dev, -@@ -586,6 +551,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg) - - case SET_VLAN_NAME_TYPE_CMD: - err = -EPERM; -+ //if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - break; - if ((args.u.name_type >= 0) && -@@ -602,6 +568,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg) - - case ADD_VLAN_CMD: - err = -EPERM; -+ //if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - break; - err = register_vlan_device(dev, args.u.VID); -@@ -609,6 +576,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg) - - case DEL_VLAN_CMD: - err = -EPERM; -+ //if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - break; - unregister_vlan_dev(dev, NULL); -@@ -682,13 +650,19 @@ static int __init vlan_proto_init(void) - if (err < 0) - goto err3; - -- err = vlan_netlink_init(); -+ err = vlan_mvrp_init(); - if (err < 0) - goto err4; - -+ err = vlan_netlink_init(); -+ if (err < 0) -+ goto err5; -+ - vlan_ioctl_set(vlan_ioctl_handler); - return 0; - -+err5: -+ vlan_mvrp_uninit(); - err4: - vlan_gvrp_uninit(); - err3: -@@ -709,6 +683,7 @@ static void __exit vlan_cleanup_module(void) - unregister_pernet_subsys(&vlan_net_ops); - rcu_barrier(); /* Wait for completion of call_rcu()'s */ - -+ vlan_mvrp_uninit(); - vlan_gvrp_uninit(); - } - -diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h -index 9fd45f3..5704ed9 100644 ---- a/net/8021q/vlan.h -+++ b/net/8021q/vlan.h -@@ -3,108 +3,99 @@ - - #include - #include -+#include - -- --/** -- * struct vlan_priority_tci_mapping - vlan egress priority mappings -- * @priority: skb priority -- * @vlan_qos: vlan priority: (skb->priority << 13) & 0xE000 -- * @next: pointer to next struct -+/* if this changes, algorithm will have to be reworked because this -+ * depends on completely exhausting the VLAN identifier space. Thus -+ * it gives constant time look-up, but in many cases it wastes memory. - */ --struct vlan_priority_tci_mapping { -- u32 priority; -- u16 vlan_qos; -- struct vlan_priority_tci_mapping *next; --}; -- -+#define VLAN_GROUP_ARRAY_SPLIT_PARTS 8 -+#define VLAN_GROUP_ARRAY_PART_LEN (VLAN_N_VID/VLAN_GROUP_ARRAY_SPLIT_PARTS) - --/** -- * struct vlan_pcpu_stats - VLAN percpu rx/tx stats -- * @rx_packets: number of received packets -- * @rx_bytes: number of received bytes -- * @rx_multicast: number of received multicast packets -- * @tx_packets: number of transmitted packets -- * @tx_bytes: number of transmitted bytes -- * @syncp: synchronization point for 64bit counters -- * @rx_errors: number of rx errors -- * @tx_dropped: number of tx drops -- */ --struct vlan_pcpu_stats { -- u64 rx_packets; -- u64 rx_bytes; -- u64 rx_multicast; -- u64 tx_packets; -- u64 tx_bytes; -- struct u64_stats_sync syncp; -- u32 rx_errors; -- u32 tx_dropped; -+enum vlan_protos { -+ VLAN_PROTO_8021Q = 0, -+ VLAN_PROTO_8021AD, -+ VLAN_PROTO_NUM, - }; - --/** -- * struct vlan_dev_info - VLAN private device data -- * @nr_ingress_mappings: number of ingress priority mappings -- * @ingress_priority_map: ingress priority mappings -- * @nr_egress_mappings: number of egress priority mappings -- * @egress_priority_map: hash of egress priority mappings -- * @vlan_id: VLAN identifier -- * @flags: device flags -- * @real_dev: underlying netdevice -- * @real_dev_addr: address of underlying netdevice -- * @dent: proc dir entry -- * @vlan_pcpu_stats: ptr to percpu rx stats -- */ --struct vlan_dev_info { -- unsigned int nr_ingress_mappings; -- u32 ingress_priority_map[8]; -- unsigned int nr_egress_mappings; -- struct vlan_priority_tci_mapping *egress_priority_map[16]; -- -- u16 vlan_id; -- u16 flags; -- -- struct net_device *real_dev; -- unsigned char real_dev_addr[ETH_ALEN]; -+struct vlan_group { -+ unsigned int nr_vlan_devs; -+ struct hlist_node hlist; /* linked list */ -+ struct net_device **vlan_devices_arrays[VLAN_PROTO_NUM] -+ [VLAN_GROUP_ARRAY_SPLIT_PARTS]; -+}; - -- struct proc_dir_entry *dent; -- struct vlan_pcpu_stats __percpu *vlan_pcpu_stats; -+struct vlan_info { -+ struct net_device *real_dev; /* The ethernet(like) device -+ * the vlan is attached to. -+ */ -+ struct vlan_group grp; -+ struct list_head vid_list; -+ unsigned int nr_vids; -+ struct rcu_head rcu; - }; - --static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev) -+static inline unsigned int vlan_proto_idx(__be16 proto) - { -- return netdev_priv(dev); -+ switch (proto) { -+ case __constant_htons(ETH_P_8021Q): -+ return VLAN_PROTO_8021Q; -+ case __constant_htons(ETH_P_8021AD): -+ return VLAN_PROTO_8021AD; -+ default: -+ BUG(); -+ return 0; -+ } - } - --static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, -- u16 vlan_id) -+static inline struct net_device *__vlan_group_get_device(struct vlan_group *vg, -+ unsigned int pidx, -+ u16 vlan_id) - { - struct net_device **array; -- array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; -+ -+ array = vg->vlan_devices_arrays[pidx] -+ [vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; - return array ? array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] : NULL; - } - -+static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, -+ __be16 vlan_proto, -+ u16 vlan_id) -+{ -+ return __vlan_group_get_device(vg, vlan_proto_idx(vlan_proto), vlan_id); -+} -+ - static inline void vlan_group_set_device(struct vlan_group *vg, -- u16 vlan_id, -+ __be16 vlan_proto, u16 vlan_id, - struct net_device *dev) - { - struct net_device **array; - if (!vg) - return; -- array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; -+ array = vg->vlan_devices_arrays[vlan_proto_idx(vlan_proto)] -+ [vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; - array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev; - } - - /* Must be invoked with rcu_read_lock or with RTNL. */ - static inline struct net_device *vlan_find_dev(struct net_device *real_dev, -- u16 vlan_id) -+ __be16 vlan_proto, u16 vlan_id) - { -- struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp); -+ struct vlan_info *vlan_info = rcu_dereference_rtnl(real_dev->vlan_info); - -- if (grp) -- return vlan_group_get_device(grp, vlan_id); -+ if (vlan_info) -+ return vlan_group_get_device(&vlan_info->grp, -+ vlan_proto, vlan_id); - - return NULL; - } - -+#define vlan_group_for_each_dev(grp, i, dev) \ -+ for ((i) = 0; i < VLAN_PROTO_NUM * VLAN_N_VID; i++) \ -+ if (((dev) = __vlan_group_get_device((grp), (i) / VLAN_N_VID, \ -+ (i) % VLAN_N_VID))) -+ - /* found in vlan_dev.c */ - void vlan_dev_set_ingress_priority(const struct net_device *dev, - u32 skb_prio, u16 vlan_prio); -@@ -113,7 +104,8 @@ int vlan_dev_set_egress_priority(const struct net_device *dev, - int vlan_dev_change_flags(const struct net_device *dev, u32 flag, u32 mask); - void vlan_dev_get_realdev_name(const struct net_device *dev, char *result); - --int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id); -+int vlan_check_real_dev(struct net_device *real_dev, -+ __be16 protocol, u16 vlan_id); - void vlan_setup(struct net_device *dev); - int register_vlan_dev(struct net_device *dev); - void unregister_vlan_dev(struct net_device *dev, struct list_head *head); -@@ -121,18 +113,18 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head); - static inline u32 vlan_get_ingress_priority(struct net_device *dev, - u16 vlan_tci) - { -- struct vlan_dev_info *vip = vlan_dev_info(dev); -+ struct vlan_dev_priv *vip = vlan_dev_priv(dev); - - return vip->ingress_priority_map[(vlan_tci >> VLAN_PRIO_SHIFT) & 0x7]; - } - - #ifdef CONFIG_VLAN_8021Q_GVRP --extern int vlan_gvrp_request_join(const struct net_device *dev); --extern void vlan_gvrp_request_leave(const struct net_device *dev); --extern int vlan_gvrp_init_applicant(struct net_device *dev); --extern void vlan_gvrp_uninit_applicant(struct net_device *dev); --extern int vlan_gvrp_init(void); --extern void vlan_gvrp_uninit(void); -+int vlan_gvrp_request_join(const struct net_device *dev); -+void vlan_gvrp_request_leave(const struct net_device *dev); -+int vlan_gvrp_init_applicant(struct net_device *dev); -+void vlan_gvrp_uninit_applicant(struct net_device *dev); -+int vlan_gvrp_init(void); -+void vlan_gvrp_uninit(void); - #else - static inline int vlan_gvrp_request_join(const struct net_device *dev) { return 0; } - static inline void vlan_gvrp_request_leave(const struct net_device *dev) {} -@@ -142,10 +134,26 @@ static inline int vlan_gvrp_init(void) { return 0; } - static inline void vlan_gvrp_uninit(void) {} - #endif - -+#ifdef CONFIG_VLAN_8021Q_MVRP -+int vlan_mvrp_request_join(const struct net_device *dev); -+void vlan_mvrp_request_leave(const struct net_device *dev); -+int vlan_mvrp_init_applicant(struct net_device *dev); -+void vlan_mvrp_uninit_applicant(struct net_device *dev); -+int vlan_mvrp_init(void); -+void vlan_mvrp_uninit(void); -+#else -+static inline int vlan_mvrp_request_join(const struct net_device *dev) { return 0; } -+static inline void vlan_mvrp_request_leave(const struct net_device *dev) {} -+static inline int vlan_mvrp_init_applicant(struct net_device *dev) { return 0; } -+static inline void vlan_mvrp_uninit_applicant(struct net_device *dev) {} -+static inline int vlan_mvrp_init(void) { return 0; } -+static inline void vlan_mvrp_uninit(void) {} -+#endif -+ - extern const char vlan_fullname[]; - extern const char vlan_version[]; --extern int vlan_netlink_init(void); --extern void vlan_netlink_fini(void); -+int vlan_netlink_init(void); -+void vlan_netlink_fini(void); - - extern struct rtnl_link_ops vlan_link_ops; - -diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c -index e860a4f..1727499 100644 ---- a/net/8021q/vlan_core.c -+++ b/net/8021q/vlan_core.c -@@ -8,11 +8,12 @@ - bool vlan_do_receive(struct sk_buff **skbp) - { - struct sk_buff *skb = *skbp; -- u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK; -+ __be16 vlan_proto = skb->vlan_proto; -+ u16 vlan_id = vlan_tx_tag_get_id(skb); - struct net_device *vlan_dev; - struct vlan_pcpu_stats *rx_stats; - -- vlan_dev = vlan_find_dev(skb->dev, vlan_id); -+ vlan_dev = vlan_find_dev(skb->dev, vlan_proto, vlan_id); - if (!vlan_dev) - return false; - -@@ -25,12 +26,11 @@ bool vlan_do_receive(struct sk_buff **skbp) - /* Our lower layer thinks this is not local, let's make sure. - * This allows the VLAN to have a different MAC than the - * underlying device, and still route correctly. */ -- if (!compare_ether_addr(eth_hdr(skb)->h_dest, -- vlan_dev->dev_addr)) -+ if (ether_addr_equal(eth_hdr(skb)->h_dest, vlan_dev->dev_addr)) - skb->pkt_type = PACKET_HOST; - } - -- if (!(vlan_dev_info(vlan_dev)->flags & VLAN_FLAG_REORDER_HDR)) { -+ if (!(vlan_dev_priv(vlan_dev)->flags & VLAN_FLAG_REORDER_HDR)) { - unsigned int offset = skb->data - skb_mac_header(skb); - - /* -@@ -49,7 +49,7 @@ bool vlan_do_receive(struct sk_buff **skbp) - skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci); - skb->vlan_tci = 0; - -- rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_pcpu_stats); -+ rx_stats = this_cpu_ptr(vlan_dev_priv(vlan_dev)->vlan_pcpu_stats); - - u64_stats_update_begin(&rx_stats->syncp); - rx_stats->rx_packets++; -@@ -61,21 +61,28 @@ bool vlan_do_receive(struct sk_buff **skbp) - return true; - } - --/* Must be invoked with rcu_read_lock or with RTNL. */ --struct net_device *__vlan_find_dev_deep(struct net_device *real_dev, -- u16 vlan_id) -+/* Must be invoked with rcu_read_lock. */ -+struct net_device *__vlan_find_dev_deep(struct net_device *dev, u16 vlan_id) - { -- struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp); -+ struct vlan_info *vlan_info = rcu_dereference(dev->vlan_info); - -- if (grp) { -- return vlan_group_get_device(grp, vlan_id); -+ if (vlan_info) { -+ return vlan_group_get_device(&vlan_info->grp, -+ htons(ETH_P_8021Q), vlan_id); - } else { - /* -- * Bonding slaves do not have grp assigned to themselves. -- * Grp is assigned to bonding master instead. -+ * Lower devices of master uppers (bonding, team) do not have -+ * grp assigned to themselves. Grp is assigned to upper device -+ * instead. - */ -- if (netif_is_bond_slave(real_dev)) -- return __vlan_find_dev_deep(real_dev->master, vlan_id); -+ //struct net_device *upper_dev; -+ -+ //upper_dev = netdev_master_upper_dev_get_rcu(dev); -+ //if (upper_dev) -+ //return __vlan_find_dev_deep(upper_dev, vlan_id); -+ -+ if (netif_is_bond_slave(dev)) -+ return __vlan_find_dev_deep(dev->master, vlan_id); - } - - return NULL; -@@ -84,13 +91,18 @@ EXPORT_SYMBOL(__vlan_find_dev_deep); - - struct net_device *vlan_dev_real_dev(const struct net_device *dev) - { -- return vlan_dev_info(dev)->real_dev; -+ struct net_device *ret = vlan_dev_priv(dev)->real_dev; -+ -+ while (is_vlan_dev(ret)) -+ ret = vlan_dev_priv(ret)->real_dev; -+ -+ return ret; - } - EXPORT_SYMBOL(vlan_dev_real_dev); - - u16 vlan_dev_vlan_id(const struct net_device *dev) - { -- return vlan_dev_info(dev)->vlan_id; -+ return vlan_dev_priv(dev)->vlan_id; - } - EXPORT_SYMBOL(vlan_dev_vlan_id); - -@@ -103,39 +115,6 @@ static struct sk_buff *vlan_reorder_header(struct sk_buff *skb) - return skb; - } - --static void vlan_set_encap_proto(struct sk_buff *skb, struct vlan_hdr *vhdr) --{ -- __be16 proto; -- unsigned char *rawp; -- -- /* -- * Was a VLAN packet, grab the encapsulated protocol, which the layer -- * three protocols care about. -- */ -- -- proto = vhdr->h_vlan_encapsulated_proto; -- if (ntohs(proto) >= 1536) { -- skb->protocol = proto; -- return; -- } -- -- rawp = skb->data; -- if (*(unsigned short *) rawp == 0xFFFF) -- /* -- * This is a magic hack to spot IPX packets. Older Novell -- * breaks the protocol design and runs IPX over 802.3 without -- * an 802.2 LLC layer. We look for FFFF which isn't a used -- * 802.2 SSAP/DSAP. This won't work for fault tolerant netware -- * but does for the rest. -- */ -- skb->protocol = htons(ETH_P_802_3); -- else -- /* -- * Real 802.2 LLC -- */ -- skb->protocol = htons(ETH_P_802_2); --} -- - struct sk_buff *vlan_untag(struct sk_buff *skb) - { - struct vlan_hdr *vhdr; -@@ -155,6 +134,7 @@ struct sk_buff *vlan_untag(struct sk_buff *skb) - - vhdr = (struct vlan_hdr *) skb->data; - vlan_tci = ntohs(vhdr->h_vlan_TCI); -+ skb->vlan_proto = htons(ETH_P_8021Q); - __vlan_hwaccel_put_tag(skb, vlan_tci); - - skb_pull_rcsum(skb, VLAN_HLEN); -@@ -174,3 +154,240 @@ err_free: - kfree_skb(skb); - return NULL; - } -+EXPORT_SYMBOL(vlan_untag); -+ -+ -+/* -+ * vlan info and vid list -+ */ -+ -+static void vlan_group_free(struct vlan_group *grp) -+{ -+ int i, j; -+ -+ for (i = 0; i < VLAN_PROTO_NUM; i++) -+ for (j = 0; j < VLAN_GROUP_ARRAY_SPLIT_PARTS; j++) -+ kfree(grp->vlan_devices_arrays[i][j]); -+} -+ -+static void vlan_info_free(struct vlan_info *vlan_info) -+{ -+ vlan_group_free(&vlan_info->grp); -+ kfree(vlan_info); -+} -+ -+static void vlan_info_rcu_free(struct rcu_head *rcu) -+{ -+ vlan_info_free(container_of(rcu, struct vlan_info, rcu)); -+} -+ -+static struct vlan_info *vlan_info_alloc(struct net_device *dev) -+{ -+ struct vlan_info *vlan_info; -+ -+ vlan_info = kzalloc(sizeof(struct vlan_info), GFP_KERNEL); -+ if (!vlan_info) -+ return NULL; -+ -+ vlan_info->real_dev = dev; -+ INIT_LIST_HEAD(&vlan_info->vid_list); -+ return vlan_info; -+} -+ -+struct vlan_vid_info { -+ struct list_head list; -+ __be16 proto; -+ u16 vid; -+ int refcount; -+}; -+ -+static bool vlan_hw_filter_capable(const struct net_device *dev, -+ const struct vlan_vid_info *vid_info) -+{ -+#if 0 /* TBD: use the old logic instead */ -+ if (vid_info->proto == htons(ETH_P_8021Q) && -+ dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) -+ return true; -+ if (vid_info->proto == htons(ETH_P_8021AD) && -+ dev->features & NETIF_F_HW_VLAN_STAG_FILTER) -+ return true; -+#endif -+ if (dev->features & NETIF_F_HW_VLAN_FILTER) -+ return true; -+ -+ return false; -+} -+ -+static struct vlan_vid_info *vlan_vid_info_get(struct vlan_info *vlan_info, -+ __be16 proto, u16 vid) -+{ -+ struct vlan_vid_info *vid_info; -+ -+ list_for_each_entry(vid_info, &vlan_info->vid_list, list) { -+ if (vid_info->proto == proto && vid_info->vid == vid) -+ return vid_info; -+ } -+ return NULL; -+} -+ -+static struct vlan_vid_info *vlan_vid_info_alloc(__be16 proto, u16 vid) -+{ -+ struct vlan_vid_info *vid_info; -+ -+ vid_info = kzalloc(sizeof(struct vlan_vid_info), GFP_KERNEL); -+ if (!vid_info) -+ return NULL; -+ vid_info->proto = proto; -+ vid_info->vid = vid; -+ -+ return vid_info; -+} -+ -+static int __vlan_vid_add(struct vlan_info *vlan_info, __be16 proto, u16 vid, -+ struct vlan_vid_info **pvid_info) -+{ -+ struct net_device *dev = vlan_info->real_dev; -+ const struct net_device_ops *ops = dev->netdev_ops; -+ struct vlan_vid_info *vid_info; -+ -+ vid_info = vlan_vid_info_alloc(proto, vid); -+ if (!vid_info) -+ return -ENOMEM; -+ -+ if (vlan_hw_filter_capable(dev, vid_info)) { -+ ops->ndo_vlan_rx_add_vid(dev, vid); -+ } -+ list_add(&vid_info->list, &vlan_info->vid_list); -+ vlan_info->nr_vids++; -+ *pvid_info = vid_info; -+ return 0; -+} -+ -+int vlan_vid_add(struct net_device *dev, __be16 proto, u16 vid) -+{ -+ struct vlan_info *vlan_info; -+ struct vlan_vid_info *vid_info; -+ bool vlan_info_created = false; -+ -+ ASSERT_RTNL(); -+ -+ vlan_info = rtnl_dereference(dev->vlan_info); -+ if (!vlan_info) { -+ vlan_info = vlan_info_alloc(dev); -+ if (!vlan_info) -+ return -ENOMEM; -+ vlan_info_created = true; -+ } -+ vid_info = vlan_vid_info_get(vlan_info, proto, vid); -+ if (!vid_info) { -+ __vlan_vid_add(vlan_info, proto, vid, &vid_info); -+ } -+ vid_info->refcount++; -+ -+ if (vlan_info_created) -+ rcu_assign_pointer(dev->vlan_info, vlan_info); -+ -+ return 0; -+} -+EXPORT_SYMBOL(vlan_vid_add); -+ -+static void __vlan_vid_del(struct vlan_info *vlan_info, -+ struct vlan_vid_info *vid_info) -+{ -+ struct net_device *dev = vlan_info->real_dev; -+ const struct net_device_ops *ops = dev->netdev_ops; -+ u16 vid = vid_info->vid; -+ -+ if (vlan_hw_filter_capable(dev, vid_info)) { -+ ops->ndo_vlan_rx_kill_vid(dev, vid); -+ } -+ list_del(&vid_info->list); -+ kfree(vid_info); -+ vlan_info->nr_vids--; -+} -+ -+void vlan_vid_del(struct net_device *dev, __be16 proto, u16 vid) -+{ -+ struct vlan_info *vlan_info; -+ struct vlan_vid_info *vid_info; -+ -+ ASSERT_RTNL(); -+ -+ vlan_info = rtnl_dereference(dev->vlan_info); -+ if (!vlan_info) -+ return; -+ -+ vid_info = vlan_vid_info_get(vlan_info, proto, vid); -+ if (!vid_info) -+ return; -+ vid_info->refcount--; -+ if (vid_info->refcount == 0) { -+ __vlan_vid_del(vlan_info, vid_info); -+ if (vlan_info->nr_vids == 0) { -+ RCU_INIT_POINTER(dev->vlan_info, NULL); -+ call_rcu(&vlan_info->rcu, vlan_info_rcu_free); -+ } -+ } -+} -+EXPORT_SYMBOL(vlan_vid_del); -+ -+int vlan_vids_add_by_dev(struct net_device *dev, -+ const struct net_device *by_dev) -+{ -+ struct vlan_vid_info *vid_info; -+ struct vlan_info *vlan_info; -+ int err; -+ -+ ASSERT_RTNL(); -+ -+ vlan_info = rtnl_dereference(by_dev->vlan_info); -+ if (!vlan_info) -+ return 0; -+ -+ list_for_each_entry(vid_info, &vlan_info->vid_list, list) { -+ err = vlan_vid_add(dev, vid_info->proto, vid_info->vid); -+ if (err) -+ goto unwind; -+ } -+ return 0; -+ -+unwind: -+ list_for_each_entry_continue_reverse(vid_info, -+ &vlan_info->vid_list, -+ list) { -+ vlan_vid_del(dev, vid_info->proto, vid_info->vid); -+ } -+ -+ return err; -+} -+EXPORT_SYMBOL(vlan_vids_add_by_dev); -+ -+void vlan_vids_del_by_dev(struct net_device *dev, -+ const struct net_device *by_dev) -+{ -+ struct vlan_vid_info *vid_info; -+ struct vlan_info *vlan_info; -+ -+ ASSERT_RTNL(); -+ -+ vlan_info = rtnl_dereference(by_dev->vlan_info); -+ if (!vlan_info) -+ return; -+ -+ list_for_each_entry(vid_info, &vlan_info->vid_list, list) -+ vlan_vid_del(dev, vid_info->proto, vid_info->vid); -+} -+EXPORT_SYMBOL(vlan_vids_del_by_dev); -+ -+bool vlan_uses_dev(const struct net_device *dev) -+{ -+ struct vlan_info *vlan_info; -+ -+ ASSERT_RTNL(); -+ -+ vlan_info = rtnl_dereference(dev->vlan_info); -+ if (!vlan_info) -+ return false; -+ return vlan_info->grp.nr_vlan_devs ? true : false; -+} -+EXPORT_SYMBOL(vlan_uses_dev); -diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c -index c43a788..8bb4aa3 100644 ---- a/net/8021q/vlan_dev.c -+++ b/net/8021q/vlan_dev.c -@@ -33,6 +33,7 @@ - #include "vlan.h" - #include "vlanproc.h" - #include -+#include - - /* - * Rebuild the Ethernet MAC header. This is called after an ARP -@@ -60,32 +61,13 @@ static int vlan_dev_rebuild_header(struct sk_buff *skb) - pr_debug("%s: unable to resolve type %X addresses\n", - dev->name, ntohs(veth->h_vlan_encapsulated_proto)); - -- memcpy(veth->h_source, dev->dev_addr, ETH_ALEN); -+ ether_addr_copy(veth->h_source, dev->dev_addr); - break; - } - - return 0; - } - --static inline u16 --vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb) --{ -- struct vlan_priority_tci_mapping *mp; -- -- smp_rmb(); /* coupled with smp_wmb() in vlan_dev_set_egress_priority() */ -- -- mp = vlan_dev_info(dev)->egress_priority_map[(skb->priority & 0xF)]; -- while (mp) { -- if (mp->priority == skb->priority) { -- return mp->vlan_qos; /* This should already be shifted -- * to mask correctly with the -- * VLAN's TCI */ -- } -- mp = mp->next; -- } -- return 0; --} -- - /* - * Create the VLAN header for an arbitrary protocol layer - * -@@ -100,16 +82,17 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, - const void *daddr, const void *saddr, - unsigned int len) - { -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - struct vlan_hdr *vhdr; - unsigned int vhdrlen = 0; - u16 vlan_tci = 0; - int rc; - -- if (!(vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR)) { -+ if (!(vlan->flags & VLAN_FLAG_REORDER_HDR)) { - vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN); - -- vlan_tci = vlan_dev_info(dev)->vlan_id; -- vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); -+ vlan_tci = vlan->vlan_id; -+ vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb->priority); - vhdr->h_vlan_TCI = htons(vlan_tci); - - /* -@@ -121,8 +104,8 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, - else - vhdr->h_vlan_encapsulated_proto = htons(len); - -- skb->protocol = htons(ETH_P_8021Q); -- type = ETH_P_8021Q; -+ skb->protocol = vlan->vlan_proto; -+ type = ntohs(vlan->vlan_proto); - vhdrlen = VLAN_HLEN; - } - -@@ -131,16 +114,28 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, - saddr = dev->dev_addr; - - /* Now make the underlying real hard header */ -- dev = vlan_dev_info(dev)->real_dev; -+ dev = vlan->real_dev; - rc = dev_hard_header(skb, dev, type, daddr, saddr, len + vhdrlen); - if (rc > 0) - rc += vhdrlen; - return rc; - } - -+static inline netdev_tx_t vlan_netpoll_send_skb(struct vlan_dev_priv *vlan, struct sk_buff *skb) -+{ -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ if (vlan->netpoll) -+ netpoll_send_skb(vlan->netpoll, skb); -+#else -+ BUG(); -+#endif -+ return NETDEV_TX_OK; -+} -+ - static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, - struct net_device *dev) - { -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); - unsigned int len; - int ret; -@@ -150,28 +145,33 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, - * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING - * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... - */ -- if (veth->h_vlan_proto != htons(ETH_P_8021Q) || -- vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) { -+ if (veth->h_vlan_proto != vlan->vlan_proto || -+ vlan->flags & VLAN_FLAG_REORDER_HDR) { - u16 vlan_tci; -- vlan_tci = vlan_dev_info(dev)->vlan_id; -- vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); -+ vlan_tci = vlan->vlan_id; -+ vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb->priority); -+ //skb = __vlan_hwaccel_put_tag(skb, vlan->vlan_proto, vlan_tci); -+ skb->vlan_proto = vlan->vlan_proto; - skb = __vlan_hwaccel_put_tag(skb, vlan_tci); - } - -- skb->dev = vlan_dev_info(dev)->real_dev; -+ skb->dev = vlan->real_dev; - len = skb->len; -+ if (unlikely(netpoll_tx_running(dev))) -+ return vlan_netpoll_send_skb(vlan, skb); -+ - ret = dev_queue_xmit(skb); - - if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { - struct vlan_pcpu_stats *stats; - -- stats = this_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats); -+ stats = this_cpu_ptr(vlan->vlan_pcpu_stats); - u64_stats_update_begin(&stats->syncp); - stats->tx_packets++; - stats->tx_bytes += len; - u64_stats_update_end(&stats->syncp); - } else { -- this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped); -+ this_cpu_inc(vlan->vlan_pcpu_stats->tx_dropped); - } - - return ret; -@@ -182,7 +182,7 @@ static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) - /* TODO: gotta make sure the underlying layer can handle it, - * maybe an IFF_VLAN_CAPABLE flag for devices? - */ -- if (vlan_dev_info(dev)->real_dev->mtu < new_mtu) -+ if (vlan_dev_priv(dev)->real_dev->mtu < new_mtu) - return -ERANGE; - - dev->mtu = new_mtu; -@@ -193,7 +193,7 @@ static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) - void vlan_dev_set_ingress_priority(const struct net_device *dev, - u32 skb_prio, u16 vlan_prio) - { -- struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - - if (vlan->ingress_priority_map[vlan_prio & 0x7] && !skb_prio) - vlan->nr_ingress_mappings--; -@@ -206,7 +206,7 @@ void vlan_dev_set_ingress_priority(const struct net_device *dev, - int vlan_dev_set_egress_priority(const struct net_device *dev, - u32 skb_prio, u16 vlan_prio) - { -- struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - struct vlan_priority_tci_mapping *mp = NULL; - struct vlan_priority_tci_mapping *np; - u32 vlan_qos = (vlan_prio << VLAN_PRIO_SHIFT) & VLAN_PRIO_MASK; -@@ -248,11 +248,11 @@ int vlan_dev_set_egress_priority(const struct net_device *dev, - /* Flags are defined in the vlan_flags enum in include/linux/if_vlan.h file. */ - int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask) - { -- struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - u32 old_flags = vlan->flags; - - if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP | -- VLAN_FLAG_LOOSE_BINDING)) -+ VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP)) - return -EINVAL; - - vlan->flags = (old_flags & ~mask) | (flags & mask); -@@ -263,17 +263,24 @@ int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask) - else - vlan_gvrp_request_leave(dev); - } -+ -+ if (netif_running(dev) && (vlan->flags ^ old_flags) & VLAN_FLAG_MVRP) { -+ if (vlan->flags & VLAN_FLAG_MVRP) -+ vlan_mvrp_request_join(dev); -+ else -+ vlan_mvrp_request_leave(dev); -+ } - return 0; - } - - void vlan_dev_get_realdev_name(const struct net_device *dev, char *result) - { -- strncpy(result, vlan_dev_info(dev)->real_dev->name, 23); -+ strncpy(result, vlan_dev_priv(dev)->real_dev->name, 23); - } - - static int vlan_dev_open(struct net_device *dev) - { -- struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - struct net_device *real_dev = vlan->real_dev; - int err; - -@@ -281,7 +288,7 @@ static int vlan_dev_open(struct net_device *dev) - !(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) - return -ENETDOWN; - -- if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { -+ if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) { - err = dev_uc_add(real_dev, dev->dev_addr); - if (err < 0) - goto out; -@@ -298,11 +305,14 @@ static int vlan_dev_open(struct net_device *dev) - goto clear_allmulti; - } - -- memcpy(vlan->real_dev_addr, real_dev->dev_addr, ETH_ALEN); -+ ether_addr_copy(vlan->real_dev_addr, real_dev->dev_addr); - - if (vlan->flags & VLAN_FLAG_GVRP) - vlan_gvrp_request_join(dev); - -+ if (vlan->flags & VLAN_FLAG_MVRP) -+ vlan_mvrp_request_join(dev); -+ - if (netif_carrier_ok(real_dev)) - netif_carrier_on(dev); - return 0; -@@ -311,7 +321,7 @@ clear_allmulti: - if (dev->flags & IFF_ALLMULTI) - dev_set_allmulti(real_dev, -1); - del_unicast: -- if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) -+ if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) - dev_uc_del(real_dev, dev->dev_addr); - out: - netif_carrier_off(dev); -@@ -320,7 +330,7 @@ out: - - static int vlan_dev_stop(struct net_device *dev) - { -- struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - struct net_device *real_dev = vlan->real_dev; - - dev_mc_unsync(real_dev, dev); -@@ -330,7 +340,7 @@ static int vlan_dev_stop(struct net_device *dev) - if (dev->flags & IFF_PROMISC) - dev_set_promiscuity(real_dev, -1); - -- if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) -+ if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) - dev_uc_del(real_dev, dev->dev_addr); - - netif_carrier_off(dev); -@@ -339,7 +349,7 @@ static int vlan_dev_stop(struct net_device *dev) - - static int vlan_dev_set_mac_address(struct net_device *dev, void *p) - { -- struct net_device *real_dev = vlan_dev_info(dev)->real_dev; -+ struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; - struct sockaddr *addr = p; - int err; - -@@ -349,23 +359,23 @@ static int vlan_dev_set_mac_address(struct net_device *dev, void *p) - if (!(dev->flags & IFF_UP)) - goto out; - -- if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { -+ if (!ether_addr_equal(addr->sa_data, real_dev->dev_addr)) { - err = dev_uc_add(real_dev, addr->sa_data); - if (err < 0) - return err; - } - -- if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) -+ if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) - dev_uc_del(real_dev, dev->dev_addr); - - out: -- memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); -+ ether_addr_copy(dev->dev_addr, addr->sa_data); - return 0; - } - - static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) - { -- struct net_device *real_dev = vlan_dev_info(dev)->real_dev; -+ struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; - const struct net_device_ops *ops = real_dev->netdev_ops; - struct ifreq ifrr; - int err = -EOPNOTSUPP; -@@ -390,7 +400,7 @@ static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) - - static int vlan_dev_neigh_setup(struct net_device *dev, struct neigh_parms *pa) - { -- struct net_device *real_dev = vlan_dev_info(dev)->real_dev; -+ struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; - const struct net_device_ops *ops = real_dev->netdev_ops; - int err = 0; - -@@ -400,11 +410,11 @@ static int vlan_dev_neigh_setup(struct net_device *dev, struct neigh_parms *pa) - return err; - } - --#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) -+#if IS_ENABLED(CONFIG_FCOE) - static int vlan_dev_fcoe_ddp_setup(struct net_device *dev, u16 xid, - struct scatterlist *sgl, unsigned int sgc) - { -- struct net_device *real_dev = vlan_dev_info(dev)->real_dev; -+ struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; - const struct net_device_ops *ops = real_dev->netdev_ops; - int rc = 0; - -@@ -416,7 +426,7 @@ static int vlan_dev_fcoe_ddp_setup(struct net_device *dev, u16 xid, - - static int vlan_dev_fcoe_ddp_done(struct net_device *dev, u16 xid) - { -- struct net_device *real_dev = vlan_dev_info(dev)->real_dev; -+ struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; - const struct net_device_ops *ops = real_dev->netdev_ops; - int len = 0; - -@@ -428,7 +438,7 @@ static int vlan_dev_fcoe_ddp_done(struct net_device *dev, u16 xid) - - static int vlan_dev_fcoe_enable(struct net_device *dev) - { -- struct net_device *real_dev = vlan_dev_info(dev)->real_dev; -+ struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; - const struct net_device_ops *ops = real_dev->netdev_ops; - int rc = -EINVAL; - -@@ -439,7 +449,7 @@ static int vlan_dev_fcoe_enable(struct net_device *dev) - - static int vlan_dev_fcoe_disable(struct net_device *dev) - { -- struct net_device *real_dev = vlan_dev_info(dev)->real_dev; -+ struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; - const struct net_device_ops *ops = real_dev->netdev_ops; - int rc = -EINVAL; - -@@ -450,7 +460,7 @@ static int vlan_dev_fcoe_disable(struct net_device *dev) - - static int vlan_dev_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type) - { -- struct net_device *real_dev = vlan_dev_info(dev)->real_dev; -+ struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; - const struct net_device_ops *ops = real_dev->netdev_ops; - int rc = -EINVAL; - -@@ -462,7 +472,7 @@ static int vlan_dev_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type) - static int vlan_dev_fcoe_ddp_target(struct net_device *dev, u16 xid, - struct scatterlist *sgl, unsigned int sgc) - { -- struct net_device *real_dev = vlan_dev_info(dev)->real_dev; -+ struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; - const struct net_device_ops *ops = real_dev->netdev_ops; - int rc = 0; - -@@ -475,7 +485,7 @@ static int vlan_dev_fcoe_ddp_target(struct net_device *dev, u16 xid, - - static void vlan_dev_change_rx_flags(struct net_device *dev, int change) - { -- struct net_device *real_dev = vlan_dev_info(dev)->real_dev; -+ struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; - - if (dev->flags & IFF_UP) { - if (change & IFF_ALLMULTI) -@@ -487,8 +497,8 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change) - - static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) - { -- dev_mc_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev); -- dev_uc_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev); -+ dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); -+ dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); - } - - /* -@@ -527,7 +537,8 @@ static int vlan_passthru_hard_header(struct sk_buff *skb, struct net_device *dev - const void *daddr, const void *saddr, - unsigned int len) - { -- struct net_device *real_dev = vlan_dev_info(dev)->real_dev; -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); -+ struct net_device *real_dev = vlan->real_dev; - - if (saddr == NULL) - saddr = dev->dev_addr; -@@ -541,12 +552,16 @@ static const struct header_ops vlan_passthru_header_ops = { - .parse = eth_header_parse, - }; - -+static struct device_type vlan_type = { -+ .name = "vlan", -+}; -+ - static const struct net_device_ops vlan_netdev_ops; - - static int vlan_dev_init(struct net_device *dev) - { -- struct net_device *real_dev = vlan_dev_info(dev)->real_dev; -- int subclass = 0; -+ struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; -+ int subclass = 0, i; - - netif_carrier_off(dev); - -@@ -570,15 +585,16 @@ static int vlan_dev_init(struct net_device *dev) - dev->dev_id = real_dev->dev_id; - - if (is_zero_ether_addr(dev->dev_addr)) -- memcpy(dev->dev_addr, real_dev->dev_addr, dev->addr_len); -+ eth_hw_addr_inherit(dev, real_dev); - if (is_zero_ether_addr(dev->broadcast)) - memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); - --#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) -+#if IS_ENABLED(CONFIG_FCOE) - dev->fcoe_ddp_xid = real_dev->fcoe_ddp_xid; - #endif - - dev->needed_headroom = real_dev->needed_headroom; -+ //if (real_dev->features & NETIF_F_HW_VLAN_CTAG_TX) { - if (real_dev->features & NETIF_F_HW_VLAN_TX) { - dev->header_ops = &vlan_passthru_header_ops; - dev->hard_header_len = real_dev->hard_header_len; -@@ -589,22 +605,31 @@ static int vlan_dev_init(struct net_device *dev) - - dev->netdev_ops = &vlan_netdev_ops; - -+ SET_NETDEV_DEVTYPE(dev, &vlan_type); -+ - if (is_vlan_dev(real_dev)) - subclass = 1; - - vlan_dev_set_lockdep_class(dev, subclass); - -- vlan_dev_info(dev)->vlan_pcpu_stats = alloc_percpu(struct vlan_pcpu_stats); -- if (!vlan_dev_info(dev)->vlan_pcpu_stats) -+ vlan_dev_priv(dev)->vlan_pcpu_stats = alloc_percpu(struct vlan_pcpu_stats); -+ if (!vlan_dev_priv(dev)->vlan_pcpu_stats) - return -ENOMEM; - -+ for_each_possible_cpu(i) { -+ struct vlan_pcpu_stats *vlan_stat; -+ vlan_stat = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i); -+ u64_stats_init(&vlan_stat->syncp); -+ } -+ -+ - return 0; - } - - static void vlan_dev_uninit(struct net_device *dev) - { - struct vlan_priority_tci_mapping *pm; -- struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - int i; - - free_percpu(vlan->vlan_pcpu_stats); -@@ -617,18 +642,17 @@ static void vlan_dev_uninit(struct net_device *dev) - } - } - --static u32 vlan_dev_fix_features(struct net_device *dev, u32 features) -+static netdev_features_t vlan_dev_fix_features(struct net_device *dev, -+ netdev_features_t features) - { -- struct net_device *real_dev = vlan_dev_info(dev)->real_dev; -- u32 old_features = features; -+ struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; -+ netdev_features_t old_features = features; - -- features &= real_dev->features; - features &= real_dev->vlan_features; -+ features |= NETIF_F_RXCSUM; -+ features &= real_dev->features; - - features |= old_features & NETIF_F_SOFT_FEATURES; -- -- if (dev_ethtool_get_rx_csum(real_dev)) -- features |= NETIF_F_RXCSUM; - features |= NETIF_F_LLTX; - - return features; -@@ -637,7 +661,7 @@ static u32 vlan_dev_fix_features(struct net_device *dev, u32 features) - static int vlan_ethtool_get_settings(struct net_device *dev, - struct ethtool_cmd *cmd) - { -- const struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - - return __ethtool_get_settings(vlan->real_dev, cmd); - } -@@ -645,15 +669,15 @@ static int vlan_ethtool_get_settings(struct net_device *dev, - static void vlan_ethtool_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) - { -- strcpy(info->driver, vlan_fullname); -- strcpy(info->version, vlan_version); -- strcpy(info->fw_version, "N/A"); -+ strlcpy(info->driver, vlan_fullname, sizeof(info->driver)); -+ strlcpy(info->version, vlan_version, sizeof(info->version)); -+ strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); - } - - static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - -- if (vlan_dev_info(dev)->vlan_pcpu_stats) { -+ if (vlan_dev_priv(dev)->vlan_pcpu_stats) { - struct vlan_pcpu_stats *p; - u32 rx_errors = 0, tx_dropped = 0; - int i; -@@ -662,7 +686,7 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st - u64 rxpackets, rxbytes, rxmulticast, txpackets, txbytes; - unsigned int start; - -- p = per_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats, i); -+ p = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i); - do { - start = u64_stats_fetch_begin_bh(&p->syncp); - rxpackets = p->rx_packets; -@@ -687,6 +711,59 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st - return stats; - } - -+#ifdef CONFIG_NET_POLL_CONTROLLER -+static void vlan_dev_poll_controller(struct net_device *dev) -+{ -+ return; -+} -+ -+static int vlan_dev_netpoll_setup(struct net_device *dev, struct netpoll_info *npinfo) -+{ -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); -+ struct net_device *real_dev = vlan->real_dev; -+ struct netpoll *netpoll; -+ int err = 0; -+ -+ netpoll = kzalloc(sizeof(*netpoll), GFP_KERNEL); -+ err = -ENOMEM; -+ if (!netpoll) -+ goto out; -+ -+ //err = __netpoll_setup(netpoll, real_dev, gfp); -+ netpoll->dev = real_dev; -+ strlcpy(netpoll->dev_name, real_dev->name, IFNAMSIZ); -+ err = __netpoll_setup(netpoll); -+ if (err) { -+ kfree(netpoll); -+ goto out; -+ } -+ -+ vlan->netpoll = netpoll; -+ -+out: -+ return err; -+} -+ -+static void vlan_dev_netpoll_cleanup(struct net_device *dev) -+{ -+ struct vlan_dev_priv *vlan= vlan_dev_priv(dev); -+ struct netpoll *netpoll = vlan->netpoll; -+ -+ if (!netpoll) -+ return; -+ -+ vlan->netpoll = NULL; -+ -+ //__netpoll_free_async(netpoll); -+ // TBD: this is the same way the old br_netpoll_cleanup works -+ /* Wait for transmitting packets to finish before freeing. */ -+ synchronize_rcu_bh(); -+ -+ __netpoll_cleanup(netpoll); -+ kfree(netpoll); -+} -+#endif /* CONFIG_NET_POLL_CONTROLLER */ -+ - static const struct ethtool_ops vlan_ethtool_ops = { - .get_settings = vlan_ethtool_get_settings, - .get_drvinfo = vlan_ethtool_get_drvinfo, -@@ -707,7 +784,7 @@ static const struct net_device_ops vlan_netdev_ops = { - .ndo_do_ioctl = vlan_dev_ioctl, - .ndo_neigh_setup = vlan_dev_neigh_setup, - .ndo_get_stats64 = vlan_dev_get_stats64, --#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) -+#if IS_ENABLED(CONFIG_FCOE) - .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, - .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, - .ndo_fcoe_enable = vlan_dev_fcoe_enable, -@@ -715,6 +792,11 @@ static const struct net_device_ops vlan_netdev_ops = { - .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, - .ndo_fcoe_ddp_target = vlan_dev_fcoe_ddp_target, - #endif -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ .ndo_poll_controller = vlan_dev_poll_controller, -+ .ndo_netpoll_setup = vlan_dev_netpoll_setup, -+ .ndo_netpoll_cleanup = vlan_dev_netpoll_cleanup, -+#endif - .ndo_fix_features = vlan_dev_fix_features, - }; - -diff --git a/net/8021q/vlan_gvrp.c b/net/8021q/vlan_gvrp.c -index 061cece..66a8032 100644 ---- a/net/8021q/vlan_gvrp.c -+++ b/net/8021q/vlan_gvrp.c -@@ -29,18 +29,22 @@ static struct garp_application vlan_gvrp_app __read_mostly = { - - int vlan_gvrp_request_join(const struct net_device *dev) - { -- const struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - __be16 vlan_id = htons(vlan->vlan_id); - -+ if (vlan->vlan_proto != htons(ETH_P_8021Q)) -+ return 0; - return garp_request_join(vlan->real_dev, &vlan_gvrp_app, - &vlan_id, sizeof(vlan_id), GVRP_ATTR_VID); - } - - void vlan_gvrp_request_leave(const struct net_device *dev) - { -- const struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - __be16 vlan_id = htons(vlan->vlan_id); - -+ if (vlan->vlan_proto != htons(ETH_P_8021Q)) -+ return; - garp_request_leave(vlan->real_dev, &vlan_gvrp_app, - &vlan_id, sizeof(vlan_id), GVRP_ATTR_VID); - } -diff --git a/net/8021q/vlan_mvrp.c b/net/8021q/vlan_mvrp.c -new file mode 100644 -index 0000000..e0fe091 ---- /dev/null -+++ b/net/8021q/vlan_mvrp.c -@@ -0,0 +1,76 @@ -+/* -+ * IEEE 802.1Q Multiple VLAN Registration Protocol (MVRP) -+ * -+ * Copyright (c) 2012 Massachusetts Institute of Technology -+ * -+ * Adapted from code in net/8021q/vlan_gvrp.c -+ * Copyright (c) 2008 Patrick McHardy -+ * -+ * 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 "vlan.h" -+ -+#define MRP_MVRP_ADDRESS { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x21 } -+ -+enum mvrp_attributes { -+ MVRP_ATTR_INVALID, -+ MVRP_ATTR_VID, -+ __MVRP_ATTR_MAX -+}; -+#define MVRP_ATTR_MAX (__MVRP_ATTR_MAX - 1) -+ -+static struct mrp_application vlan_mrp_app __read_mostly = { -+ .type = MRP_APPLICATION_MVRP, -+ .maxattr = MVRP_ATTR_MAX, -+ .pkttype.type = htons(ETH_P_MVRP), -+ .group_address = MRP_MVRP_ADDRESS, -+ .version = 0, -+}; -+ -+int vlan_mvrp_request_join(const struct net_device *dev) -+{ -+ const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); -+ __be16 vlan_id = htons(vlan->vlan_id); -+ -+ if (vlan->vlan_proto != htons(ETH_P_8021Q)) -+ return 0; -+ return mrp_request_join(vlan->real_dev, &vlan_mrp_app, -+ &vlan_id, sizeof(vlan_id), MVRP_ATTR_VID); -+} -+ -+void vlan_mvrp_request_leave(const struct net_device *dev) -+{ -+ const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); -+ __be16 vlan_id = htons(vlan->vlan_id); -+ -+ if (vlan->vlan_proto != htons(ETH_P_8021Q)) -+ return; -+ mrp_request_leave(vlan->real_dev, &vlan_mrp_app, -+ &vlan_id, sizeof(vlan_id), MVRP_ATTR_VID); -+} -+ -+int vlan_mvrp_init_applicant(struct net_device *dev) -+{ -+ return mrp_init_applicant(dev, &vlan_mrp_app); -+} -+ -+void vlan_mvrp_uninit_applicant(struct net_device *dev) -+{ -+ mrp_uninit_applicant(dev, &vlan_mrp_app); -+} -+ -+int __init vlan_mvrp_init(void) -+{ -+ return mrp_register_application(&vlan_mrp_app); -+} -+ -+void vlan_mvrp_uninit(void) -+{ -+ mrp_unregister_application(&vlan_mrp_app); -+} -diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c -index c705612..29329c1 100644 ---- a/net/8021q/vlan_netlink.c -+++ b/net/8021q/vlan_netlink.c -@@ -23,6 +23,7 @@ static const struct nla_policy vlan_policy[IFLA_VLAN_MAX + 1] = { - [IFLA_VLAN_FLAGS] = { .len = sizeof(struct ifla_vlan_flags) }, - [IFLA_VLAN_EGRESS_QOS] = { .type = NLA_NESTED }, - [IFLA_VLAN_INGRESS_QOS] = { .type = NLA_NESTED }, -+ [IFLA_VLAN_PROTOCOL] = { .type = NLA_U16 }, - }; - - static const struct nla_policy vlan_map_policy[IFLA_VLAN_QOS_MAX + 1] = { -@@ -53,6 +54,16 @@ static int vlan_validate(struct nlattr *tb[], struct nlattr *data[]) - if (!data) - return -EINVAL; - -+ if (data[IFLA_VLAN_PROTOCOL]) { -+ switch (nla_get_be16(data[IFLA_VLAN_PROTOCOL])) { -+ case __constant_htons(ETH_P_8021Q): -+ case __constant_htons(ETH_P_8021AD): -+ break; -+ default: -+ return -EPROTONOSUPPORT; -+ } -+ } -+ - if (data[IFLA_VLAN_ID]) { - id = nla_get_u16(data[IFLA_VLAN_ID]); - if (id >= VLAN_VID_MASK) -@@ -62,7 +73,7 @@ static int vlan_validate(struct nlattr *tb[], struct nlattr *data[]) - flags = nla_data(data[IFLA_VLAN_FLAGS]); - if ((flags->flags & flags->mask) & - ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP | -- VLAN_FLAG_LOOSE_BINDING)) -+ VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP)) - return -EINVAL; - } - -@@ -105,8 +116,9 @@ static int vlan_changelink(struct net_device *dev, - static int vlan_newlink(struct net *src_net, struct net_device *dev, - struct nlattr *tb[], struct nlattr *data[]) - { -- struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - struct net_device *real_dev; -+ __be16 proto; - int err; - - if (!data[IFLA_VLAN_ID]) -@@ -118,11 +130,17 @@ static int vlan_newlink(struct net *src_net, struct net_device *dev, - if (!real_dev) - return -ENODEV; - -- vlan->vlan_id = nla_get_u16(data[IFLA_VLAN_ID]); -- vlan->real_dev = real_dev; -- vlan->flags = VLAN_FLAG_REORDER_HDR; -+ if (data[IFLA_VLAN_PROTOCOL]) -+ proto = nla_get_be16(data[IFLA_VLAN_PROTOCOL]); -+ else -+ proto = htons(ETH_P_8021Q); - -- err = vlan_check_real_dev(real_dev, vlan->vlan_id); -+ vlan->vlan_proto = proto; -+ vlan->vlan_id = nla_get_u16(data[IFLA_VLAN_ID]); -+ vlan->real_dev = real_dev; -+ vlan->flags = VLAN_FLAG_REORDER_HDR; -+ -+ err = vlan_check_real_dev(real_dev, vlan->vlan_proto, vlan->vlan_id); - if (err < 0) - return err; - -@@ -149,9 +167,10 @@ static inline size_t vlan_qos_map_size(unsigned int n) - - static size_t vlan_get_size(const struct net_device *dev) - { -- struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - -- return nla_total_size(2) + /* IFLA_VLAN_ID */ -+ return nla_total_size(2) + /* IFLA_VLAN_PROTOCOL */ -+ nla_total_size(2) + /* IFLA_VLAN_ID */ - nla_total_size(sizeof(struct ifla_vlan_flags)) + /* IFLA_VLAN_FLAGS */ - vlan_qos_map_size(vlan->nr_ingress_mappings) + - vlan_qos_map_size(vlan->nr_egress_mappings); -@@ -159,18 +178,21 @@ static size_t vlan_get_size(const struct net_device *dev) - - static int vlan_fill_info(struct sk_buff *skb, const struct net_device *dev) - { -- struct vlan_dev_info *vlan = vlan_dev_info(dev); -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - struct vlan_priority_tci_mapping *pm; - struct ifla_vlan_flags f; - struct ifla_vlan_qos_mapping m; - struct nlattr *nest; - unsigned int i; - -- NLA_PUT_U16(skb, IFLA_VLAN_ID, vlan_dev_info(dev)->vlan_id); -+ if (nla_put_be16(skb, IFLA_VLAN_PROTOCOL, vlan->vlan_proto) || -+ nla_put_u16(skb, IFLA_VLAN_ID, vlan->vlan_id)) -+ goto nla_put_failure; - if (vlan->flags) { - f.flags = vlan->flags; - f.mask = ~0; -- NLA_PUT(skb, IFLA_VLAN_FLAGS, sizeof(f), &f); -+ if (nla_put(skb, IFLA_VLAN_FLAGS, sizeof(f), &f)) -+ goto nla_put_failure; - } - if (vlan->nr_ingress_mappings) { - nest = nla_nest_start(skb, IFLA_VLAN_INGRESS_QOS); -@@ -183,8 +205,9 @@ static int vlan_fill_info(struct sk_buff *skb, const struct net_device *dev) - - m.from = i; - m.to = vlan->ingress_priority_map[i]; -- NLA_PUT(skb, IFLA_VLAN_QOS_MAPPING, -- sizeof(m), &m); -+ if (nla_put(skb, IFLA_VLAN_QOS_MAPPING, -+ sizeof(m), &m)) -+ goto nla_put_failure; - } - nla_nest_end(skb, nest); - } -@@ -202,8 +225,9 @@ static int vlan_fill_info(struct sk_buff *skb, const struct net_device *dev) - - m.from = pm->priority; - m.to = (pm->vlan_qos >> 13) & 0x7; -- NLA_PUT(skb, IFLA_VLAN_QOS_MAPPING, -- sizeof(m), &m); -+ if (nla_put(skb, IFLA_VLAN_QOS_MAPPING, -+ sizeof(m), &m)) -+ goto nla_put_failure; - } - } - nla_nest_end(skb, nest); -@@ -218,7 +242,7 @@ struct rtnl_link_ops vlan_link_ops __read_mostly = { - .kind = "vlan", - .maxtype = IFLA_VLAN_MAX, - .policy = vlan_policy, -- .priv_size = sizeof(struct vlan_dev_info), -+ .priv_size = sizeof(struct vlan_dev_priv), - .setup = vlan_setup, - .validate = vlan_validate, - .newlink = vlan_newlink, -diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c -index d34b6da..4cfae7c 100644 ---- a/net/8021q/vlanproc.c -+++ b/net/8021q/vlanproc.c -@@ -105,7 +105,7 @@ static const struct file_operations vlandev_fops = { - }; - - /* -- * Proc filesystem derectory entries. -+ * Proc filesystem directory entries. - */ - - /* Strings */ -@@ -131,7 +131,7 @@ void vlan_proc_cleanup(struct net *net) - remove_proc_entry(name_conf, vn->proc_vlan_dir); - - if (vn->proc_vlan_dir) -- proc_net_remove(net, name_root); -+ remove_proc_entry(name_root, net->proc_net); - - /* Dynamically added entries should be cleaned up as their vlan_device - * is removed, so we should not have to take care of it here... -@@ -168,13 +168,13 @@ err: - - int vlan_proc_add_dev(struct net_device *vlandev) - { -- struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); -+ struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev); - struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id); - -- dev_info->dent = -+ vlan->dent = - proc_create_data(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR, - vn->proc_vlan_dir, &vlandev_fops, vlandev); -- if (!dev_info->dent) -+ if (!vlan->dent) - return -ENOBUFS; - return 0; - } -@@ -184,13 +184,17 @@ int vlan_proc_add_dev(struct net_device *vlandev) - */ - int vlan_proc_rem_dev(struct net_device *vlandev) - { -+ /** NOTE: This will consume the memory pointed to by dent, it seems. */ -+ //proc_remove(vlan_dev_priv(vlandev)->dent); -+ //vlan_dev_priv(vlandev)->dent = NULL; -+ -+ /* TBD: restore to old logic */ - struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id); - -- /** NOTE: This will consume the memory pointed to by dent, it seems. */ -- if (vlan_dev_info(vlandev)->dent) { -- remove_proc_entry(vlan_dev_info(vlandev)->dent->name, -+ if (vlan_dev_priv(vlandev)->dent) { -+ remove_proc_entry(vlan_dev_priv(vlandev)->dent->name, - vn->proc_vlan_dir); -- vlan_dev_info(vlandev)->dent = NULL; -+ vlan_dev_priv(vlandev)->dent = NULL; - } - return 0; - } -@@ -268,10 +272,10 @@ static int vlan_seq_show(struct seq_file *seq, void *v) - nmtype ? nmtype : "UNKNOWN"); - } else { - const struct net_device *vlandev = v; -- const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); -+ const struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev); - - seq_printf(seq, "%-15s| %d | %s\n", vlandev->name, -- dev_info->vlan_id, dev_info->real_dev->name); -+ vlan->vlan_id, vlan->real_dev->name); - } - return 0; - } -@@ -279,7 +283,7 @@ static int vlan_seq_show(struct seq_file *seq, void *v) - static int vlandev_seq_show(struct seq_file *seq, void *offset) - { - struct net_device *vlandev = (struct net_device *) seq->private; -- const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); -+ const struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev); - struct rtnl_link_stats64 temp; - const struct rtnl_link_stats64 *stats; - static const char fmt64[] = "%30s %12llu\n"; -@@ -291,8 +295,8 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset) - stats = dev_get_stats(vlandev, &temp); - seq_printf(seq, - "%s VID: %d REORDER_HDR: %i dev->priv_flags: %hx\n", -- vlandev->name, dev_info->vlan_id, -- (int)(dev_info->flags & 1), vlandev->priv_flags); -+ vlandev->name, vlan->vlan_id, -+ (int)(vlan->flags & 1), vlandev->priv_flags); - - seq_printf(seq, fmt64, "total frames received", stats->rx_packets); - seq_printf(seq, fmt64, "total bytes received", stats->rx_bytes); -@@ -300,23 +304,23 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset) - seq_puts(seq, "\n"); - seq_printf(seq, fmt64, "total frames transmitted", stats->tx_packets); - seq_printf(seq, fmt64, "total bytes transmitted", stats->tx_bytes); -- seq_printf(seq, "Device: %s", dev_info->real_dev->name); -+ seq_printf(seq, "Device: %s", vlan->real_dev->name); - /* now show all PRIORITY mappings relating to this VLAN */ - seq_printf(seq, "\nINGRESS priority mappings: " - "0:%u 1:%u 2:%u 3:%u 4:%u 5:%u 6:%u 7:%u\n", -- dev_info->ingress_priority_map[0], -- dev_info->ingress_priority_map[1], -- dev_info->ingress_priority_map[2], -- dev_info->ingress_priority_map[3], -- dev_info->ingress_priority_map[4], -- dev_info->ingress_priority_map[5], -- dev_info->ingress_priority_map[6], -- dev_info->ingress_priority_map[7]); -+ vlan->ingress_priority_map[0], -+ vlan->ingress_priority_map[1], -+ vlan->ingress_priority_map[2], -+ vlan->ingress_priority_map[3], -+ vlan->ingress_priority_map[4], -+ vlan->ingress_priority_map[5], -+ vlan->ingress_priority_map[6], -+ vlan->ingress_priority_map[7]); - - seq_printf(seq, " EGRESS priority mappings: "); - for (i = 0; i < 16; i++) { - const struct vlan_priority_tci_mapping *mp -- = dev_info->egress_priority_map[i]; -+ = vlan->egress_priority_map[i]; - while (mp) { - seq_printf(seq, "%u:%hu ", - mp->priority, ((mp->vlan_qos >> 13) & 0x7)); -diff --git a/net/bridge/Kconfig b/net/bridge/Kconfig -index 6dee7bf..aa0d3b2 100644 ---- a/net/bridge/Kconfig -+++ b/net/bridge/Kconfig -@@ -46,3 +46,17 @@ config BRIDGE_IGMP_SNOOPING - Say N to exclude this support and reduce the binary size. - - If unsure, say Y. -+ -+config BRIDGE_VLAN_FILTERING -+ bool "VLAN filtering" -+ depends on BRIDGE -+ depends on VLAN_8021Q -+ default n -+ ---help--- -+ If you say Y here, then the Ethernet bridge will be able selectively -+ receive and forward traffic based on VLAN information in the packet -+ any VLAN information configured on the bridge port or bridge device. -+ -+ Say N to exclude this support and reduce the binary size. -+ -+ If unsure, say Y. -diff --git a/net/bridge/Makefile b/net/bridge/Makefile -index e859098..e85498b 100644 ---- a/net/bridge/Makefile -+++ b/net/bridge/Makefile -@@ -14,4 +14,6 @@ bridge-$(CONFIG_BRIDGE_NETFILTER) += br_netfilter.o - - bridge-$(CONFIG_BRIDGE_IGMP_SNOOPING) += br_multicast.o br_mdb.o - -+bridge-$(CONFIG_BRIDGE_VLAN_FILTERING) += br_vlan.o -+ - obj-$(CONFIG_BRIDGE_NF_EBTABLES) += netfilter/ -diff --git a/net/bridge/br.c b/net/bridge/br.c -index 9058381..80df1ac 100644 ---- a/net/bridge/br.c -+++ b/net/bridge/br.c -@@ -27,21 +27,35 @@ int br_hw_fwding_enabled = 1; - MODULE_PARM_DESC(hw_fwding, "Enable hw forwarding"); - module_param_named(hw_fwding, br_hw_fwding_enabled, int, 0644); - --static const struct stp_proto br_stp_proto = { -- .rcv = br_stp_rcv, --}; -+static void __net_exit br_net_exit(struct net *net) -+{ -+ struct net_device *dev; -+ LIST_HEAD(list); -+ -+ rtnl_lock(); -+ for_each_netdev(net, dev) -+ if (dev->priv_flags & IFF_EBRIDGE) -+ br_dev_delete(dev, &list); -+ -+ unregister_netdevice_many(&list); -+ rtnl_unlock(); -+} - - static struct pernet_operations br_net_ops = { - .exit = br_net_exit, - }; - -+static const struct stp_proto br_stp_proto = { -+ .rcv = br_stp_rcv, -+}; -+ - #ifdef CONFIG_SYSCTL - static struct ctl_table_header *brstp_sysctl_header; - int brstp_user_space __read_mostly = 1; - - static - int brstp_sysctl_call_tables(ctl_table * ctl, int write, -- void __user * buffer, size_t * lenp, loff_t * ppos) -+ void __user * buffer, size_t * lenp, loff_t * ppos) - { - int ret; - int old_brstp_user_space = brstp_user_space; -@@ -66,11 +80,11 @@ int brstp_sysctl_call_tables(ctl_table * ctl, int write, - - static ctl_table brstp_table[] = { - { -- .procname = "bridge-stp-user-space", -- .data = &brstp_user_space, -- .maxlen = sizeof(int), -- .mode = 0644, -- .proc_handler = brstp_sysctl_call_tables, -+ .procname = "bridge-stp-user-space", -+ .data = &brstp_user_space, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = brstp_sysctl_call_tables, - }, - { } - }; -@@ -127,7 +141,7 @@ static int __init br_init(void) - - brioctl_set(br_ioctl_deviceless_stub); - --#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) -+#if IS_ENABLED(CONFIG_ATM_LANE) - br_fdb_test_addr_hook = br_fdb_test_addr; - #endif - -@@ -165,7 +179,7 @@ static void __exit br_deinit(void) - rcu_barrier(); /* Wait for completion of call_rcu()'s */ - - br_netfilter_fini(); --#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) -+#if IS_ENABLED(CONFIG_ATM_LANE) - br_fdb_test_addr_hook = NULL; - #endif - -diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c -index 9baf277..7861354 100644 ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -22,6 +22,9 @@ - #include - #include "br_private.h" - -+#define COMMON_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | \ -+ NETIF_F_GSO_MASK | NETIF_F_HW_CSUM) -+ - /* net device transmit always called with BH disabled */ - netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) - { -@@ -29,11 +32,14 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) - const unsigned char *dest = skb->data; - struct net_bridge_fdb_entry *dst; - struct net_bridge_mdb_entry *mdst; -- struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats); -+ struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats); -+ u16 vid = 0; - -+ rcu_read_lock(); - #ifdef CONFIG_BRIDGE_NETFILTER - if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) { - br_nf_pre_routing_finish_bridge_slow(skb); -+ rcu_read_unlock(); - return NETDEV_TX_OK; - } - #endif -@@ -43,48 +49,58 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) - brstats->tx_bytes += skb->len; - u64_stats_update_end(&brstats->syncp); - -+ if (!br_allowed_ingress(br, br_get_vlan_info(br), skb, &vid)) -+ goto drop; -+ - BR_INPUT_SKB_CB(skb)->brdev = dev; - - skb_reset_mac_header(skb); - skb_pull(skb, ETH_HLEN); - -- rcu_read_lock(); - if (is_broadcast_ether_addr(dest)) -- br_flood_deliver(br, skb); -+ br_flood_deliver(br, skb, false); - else if (is_multicast_ether_addr(dest)) { - if (unlikely(netpoll_tx_running(dev))) { -- br_flood_deliver(br, skb); -- goto out; -- } -- if (br_multicast_rcv(br, NULL, skb)) { -- kfree_skb(skb); -+ br_flood_deliver(br, skb, false); - goto out; - } -+ if (br_multicast_rcv(br, NULL, skb, vid)) -+ goto drop; - -- mdst = br_mdb_get(br, skb); -+ mdst = br_mdb_get(br, skb, vid); - if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && -- br_multicast_querier_exists(br)) -+ br_multicast_querier_exists(br, eth_hdr(skb))) - br_multicast_deliver(mdst, skb); - else -- br_flood_deliver(br, skb); -- } else if ((dst = __br_fdb_get(br, dest)) != NULL) -+ br_flood_deliver(br, skb, false); -+ } else if ((dst = __br_fdb_get(br, dest, vid)) != NULL) - br_deliver(dst->dst, skb); - else -- br_flood_deliver(br, skb); -+ br_flood_deliver(br, skb, true); - - out: - rcu_read_unlock(); - return NETDEV_TX_OK; -+drop: -+ kfree_skb(skb); -+ goto out; - } - - static int br_dev_init(struct net_device *dev) - { - struct net_bridge *br = netdev_priv(dev); -+ int i; - -- br->stats = alloc_percpu(struct br_cpu_netstats); -+ br->stats = alloc_percpu(struct pcpu_sw_netstats); - if (!br->stats) - return -ENOMEM; - -+ for_each_possible_cpu(i) { -+ struct pcpu_sw_netstats *br_dev_stats; -+ br_dev_stats = per_cpu_ptr(br->stats, i); -+ u64_stats_init(&br_dev_stats->syncp); -+ } -+ - return 0; - } - -@@ -120,17 +136,17 @@ static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *stats) - { - struct net_bridge *br = netdev_priv(dev); -- struct br_cpu_netstats tmp, sum = { 0 }; -+ struct pcpu_sw_netstats tmp, sum = { 0 }; - unsigned int cpu; - - for_each_possible_cpu(cpu) { - unsigned int start; -- const struct br_cpu_netstats *bstats -+ const struct pcpu_sw_netstats *bstats - = per_cpu_ptr(br->stats, cpu); - do { -- start = u64_stats_fetch_begin(&bstats->syncp); -+ start = u64_stats_fetch_begin_bh(&bstats->syncp); - memcpy(&tmp, bstats, sizeof(tmp)); -- } while (u64_stats_fetch_retry(&bstats->syncp, start)); -+ } while (u64_stats_fetch_retry_bh(&bstats->syncp, start)); - sum.tx_bytes += tmp.tx_bytes; - sum.tx_packets += tmp.tx_packets; - sum.rx_bytes += tmp.rx_bytes; -@@ -168,12 +184,14 @@ static int br_set_mac_address(struct net_device *dev, void *p) - struct sockaddr *addr = p; - - if (!is_valid_ether_addr(addr->sa_data)) -- return -EINVAL; -+ return -EADDRNOTAVAIL; - - spin_lock_bh(&br->lock); -- memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); -- br_stp_change_bridge_id(br, addr->sa_data); -- br->flags |= BR_SET_MAC_ADDR; -+ if (!ether_addr_equal(dev->dev_addr, addr->sa_data)) { -+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); -+ br_fdb_change_mac_address(br, addr->sa_data); -+ br_stp_change_bridge_id(br, addr->sa_data); -+ } - spin_unlock_bh(&br->lock); - - return 0; -@@ -181,13 +199,14 @@ static int br_set_mac_address(struct net_device *dev, void *p) - - static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info) - { -- strcpy(info->driver, "bridge"); -- strcpy(info->version, BR_VERSION); -- strcpy(info->fw_version, "N/A"); -- strcpy(info->bus_info, "N/A"); -+ strlcpy(info->driver, "bridge", sizeof(info->driver)); -+ strlcpy(info->version, BR_VERSION, sizeof(info->version)); -+ strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); -+ strlcpy(info->bus_info, "N/A", sizeof(info->bus_info)); - } - --static u32 br_fix_features(struct net_device *dev, u32 features) -+static netdev_features_t br_fix_features(struct net_device *dev, -+ netdev_features_t features) - { - struct net_bridge *br = netdev_priv(dev); - -@@ -202,23 +221,21 @@ static void br_poll_controller(struct net_device *br_dev) - static void br_netpoll_cleanup(struct net_device *dev) - { - struct net_bridge *br = netdev_priv(dev); -- struct net_bridge_port *p, *n; -+ struct net_bridge_port *p; - -- list_for_each_entry_safe(p, n, &br->port_list, list) { -+ list_for_each_entry(p, &br->port_list, list) - br_netpoll_disable(p); -- } - } - - static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni) - { - struct net_bridge *br = netdev_priv(dev); -- struct net_bridge_port *p, *n; -+ struct net_bridge_port *p; - int err = 0; - -- list_for_each_entry_safe(p, n, &br->port_list, list) { -+ list_for_each_entry(p, &br->port_list, list) { - if (!p->dev) - continue; -- - err = br_netpoll_enable(p); - if (err) - goto fail; -@@ -235,25 +252,26 @@ fail: - int br_netpoll_enable(struct net_bridge_port *p) - { - struct netpoll *np; -- int err = 0; -+ int err; -+ -+ if (!p->br->dev->npinfo) -+ return 0; - - np = kzalloc(sizeof(*p->np), GFP_KERNEL); -- err = -ENOMEM; - if (!np) -- goto out; -+ return -ENOMEM; - -+ //err = __netpoll_setup(np, p->dev, gfp); - np->dev = p->dev; - strlcpy(np->dev_name, p->dev->name, IFNAMSIZ); - - err = __netpoll_setup(np); - if (err) { - kfree(np); -- goto out; -+ return err; - } - - p->np = np; -- --out: - return err; - } - -@@ -266,11 +284,8 @@ void br_netpoll_disable(struct net_bridge_port *p) - - p->np = NULL; - -- /* Wait for transmitting packets to finish before freeing. */ -- synchronize_rcu_bh(); -- -+ //__netpoll_free_async(np); - __netpoll_cleanup(np); -- kfree(np); - } - - #endif -@@ -313,9 +328,12 @@ static const struct net_device_ops br_netdev_ops = { - .ndo_add_slave = br_add_slave, - .ndo_del_slave = br_del_slave, - .ndo_fix_features = br_fix_features, -- .ndo_fdb_add = br_fdb_add, -- .ndo_fdb_del = br_fdb_delete, -- .ndo_fdb_dump = br_fdb_dump, -+ .ndo_fdb_add = br_fdb_add, -+ .ndo_fdb_del = br_fdb_delete, -+ .ndo_fdb_dump = br_fdb_dump, -+ .ndo_bridge_getlink = br_getlink, -+ .ndo_bridge_setlink = br_setlink, -+ .ndo_bridge_dellink = br_dellink, - }; - - static void br_dev_free(struct net_device *dev) -@@ -334,7 +352,7 @@ void br_dev_setup(struct net_device *dev) - { - struct net_bridge *br = netdev_priv(dev); - -- random_ether_addr(dev->dev_addr); -+ eth_hw_addr_random(dev); - ether_setup(dev); - - dev->netdev_ops = &br_netdev_ops; -@@ -344,12 +362,10 @@ void br_dev_setup(struct net_device *dev) - dev->tx_queue_len = 0; - dev->priv_flags = IFF_EBRIDGE; - -- dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | -- NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX | -- NETIF_F_NETNS_LOCAL | NETIF_F_HW_VLAN_TX; -- dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | -- NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | -- NETIF_F_HW_VLAN_TX; -+ dev->features = COMMON_FEATURES | NETIF_F_LLTX | NETIF_F_NETNS_LOCAL | -+ NETIF_F_HW_VLAN_TX; -+ dev->hw_features = COMMON_FEATURES | NETIF_F_HW_VLAN_TX; -+ dev->vlan_features = COMMON_FEATURES; - - br->dev = dev; - spin_lock_init(&br->lock); -@@ -359,7 +375,7 @@ void br_dev_setup(struct net_device *dev) - br->bridge_id.prio[0] = 0x80; - br->bridge_id.prio[1] = 0x00; - -- memcpy(br->group_addr, br_group_address, ETH_ALEN); -+ memcpy(br->group_addr, eth_reserved_addr_base, ETH_ALEN); - - br->stp_enabled = BR_NO_STP; - br->group_fwd_mask = BR_GROUPFWD_DEFAULT; -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 30019c5..ac4c109 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -23,12 +23,14 @@ - #include - #include - #include -+#include - #include "br_private.h" - - static struct kmem_cache *br_fdb_cache __read_mostly; - static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, -- const unsigned char *addr); --static void fdb_notify(struct net_bridge *br, const struct net_bridge_fdb_entry *, int); -+ const unsigned char *addr, u16 vid); -+static void fdb_notify(struct net_bridge *br, -+ const struct net_bridge_fdb_entry *, int); - - static u32 fdb_salt __read_mostly; - -@@ -66,11 +68,11 @@ static inline int has_expired(const struct net_bridge *br, - time_before_eq(fdb->updated + hold_time(br), jiffies); - } - --static inline int br_mac_hash(const unsigned char *mac) -+static inline int br_mac_hash(const unsigned char *mac, __u16 vid) - { -- /* use 1 byte of OUI cnd 3 bytes of NIC */ -+ /* use 1 byte of OUI and 3 bytes of NIC */ - u32 key = get_unaligned((u32 *)(mac + 2)); -- return jhash_1word(key, fdb_salt) & (BR_HASH_SIZE - 1); -+ return jhash_2words(key, vid, fdb_salt) & (BR_HASH_SIZE - 1); - } - - static void fdb_rcu_free(struct rcu_head *head) -@@ -80,7 +82,7 @@ static void fdb_rcu_free(struct rcu_head *head) - kmem_cache_free(br_fdb_cache, ent); - } - --static inline void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f) -+static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f) - { - hlist_del_rcu(&f->hlist); - fdb_notify(br, f, RTM_DELNEIGH); -@@ -90,6 +92,7 @@ static inline void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry - void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) - { - struct net_bridge *br = p->br; -+ bool no_vlan = (nbp_get_vlan_info(p) == NULL) ? true : false; - int i; - - spin_lock_bh(&br->hash_lock); -@@ -104,10 +107,12 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) - if (f->dst == p && f->is_local) { - /* maybe another port has same hw addr? */ - struct net_bridge_port *op; -+ u16 vid = f->vlan_id; - list_for_each_entry(op, &br->port_list, list) { - if (op != p && - ether_addr_equal(op->dev->dev_addr, -- f->addr.addr)) { -+ f->addr.addr) && -+ nbp_vlan_find(op, vid)) { - f->dst = op; - goto insert; - } -@@ -115,27 +120,53 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) - - /* delete old one */ - fdb_delete(br, f); -- goto insert; -+insert: -+ /* insert new address, may fail if invalid -+ * address or dup. -+ */ -+ fdb_insert(br, p, newaddr, vid); -+ -+ /* if this port has no vlan information -+ * configured, we can safely be done at -+ * this point. -+ */ -+ if (no_vlan) -+ goto done; - } - } - } -- insert: -- /* insert new address, may fail if invalid address or dup. */ -- fdb_insert(br, p, newaddr); - -+done: - spin_unlock_bh(&br->hash_lock); - } - - void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) - { - struct net_bridge_fdb_entry *f; -+ struct net_port_vlans *pv; -+ u16 vid = 0; - - /* If old entry was unassociated with any port, then delete it. */ -- f = __br_fdb_get(br, br->dev->dev_addr); -+ f = __br_fdb_get(br, br->dev->dev_addr, 0); - if (f && f->is_local && !f->dst) - fdb_delete(br, f); - -- fdb_insert(br, NULL, newaddr); -+ fdb_insert(br, NULL, newaddr, 0); -+ -+ /* Now remove and add entries for every VLAN configured on the -+ * bridge. This function runs under RTNL so the bitmap will not -+ * change from under us. -+ */ -+ pv = br_get_vlan_info(br); -+ if (!pv) -+ return; -+ -+ for_each_set_bit_from(vid, pv->vlan_bitmap, VLAN_N_VID) { -+ f = __br_fdb_get(br, br->dev->dev_addr, vid); -+ if (f && f->is_local && !f->dst) -+ fdb_delete(br, f); -+ fdb_insert(br, NULL, newaddr, vid); -+ } - } - - void br_fdb_cleanup(unsigned long _data) -@@ -230,13 +261,16 @@ void br_fdb_delete_by_port(struct net_bridge *br, - - /* No locking or refcounting, assumes caller has rcu_read_lock */ - struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br, -- const unsigned char *addr) -+ const unsigned char *addr, -+ __u16 vid) - { - struct hlist_node *h; - struct net_bridge_fdb_entry *fdb; - -- hlist_for_each_entry_rcu(fdb, h, &br->hash[br_mac_hash(addr)], hlist) { -- if (ether_addr_equal(fdb->addr.addr, addr)) { -+ hlist_for_each_entry_rcu(fdb, h, -+ &br->hash[br_mac_hash(addr, vid)], hlist) { -+ if (ether_addr_equal(fdb->addr.addr, addr) && -+ fdb->vlan_id == vid) { - if (unlikely(has_expired(br, fdb))) - break; - return fdb; -@@ -260,7 +294,7 @@ int br_fdb_test_addr(struct net_device *dev, unsigned char *addr) - if (!port) - ret = 0; - else { -- fdb = __br_fdb_get(port->br, addr); -+ fdb = __br_fdb_get(port->br, addr, 0); - ret = fdb && fdb->dst && fdb->dst->dev != dev && - fdb->dst->state == BR_STATE_FORWARDING; - } -@@ -324,26 +358,30 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf, - } - - static struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head, -- const unsigned char *addr) -+ const unsigned char *addr, -+ __u16 vid) - { - struct hlist_node *h; - struct net_bridge_fdb_entry *fdb; - - hlist_for_each_entry(fdb, h, head, hlist) { -- if (ether_addr_equal(fdb->addr.addr, addr)) -+ if (ether_addr_equal(fdb->addr.addr, addr) && -+ fdb->vlan_id == vid) - return fdb; - } - return NULL; - } - - static struct net_bridge_fdb_entry *fdb_find_rcu(struct hlist_head *head, -- const unsigned char *addr) -+ const unsigned char *addr, -+ __u16 vid) - { - struct hlist_node *h; - struct net_bridge_fdb_entry *fdb; - - hlist_for_each_entry_rcu(fdb, h, head, hlist) { -- if (ether_addr_equal(fdb->addr.addr, addr)) -+ if (ether_addr_equal(fdb->addr.addr, addr) && -+ fdb->vlan_id == vid) - return fdb; - } - return NULL; -@@ -351,7 +389,8 @@ static struct net_bridge_fdb_entry *fdb_find_rcu(struct hlist_head *head, - - static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, - struct net_bridge_port *source, -- const unsigned char *addr) -+ const unsigned char *addr, -+ __u16 vid) - { - struct net_bridge_fdb_entry *fdb; - -@@ -359,6 +398,7 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, - if (fdb) { - memcpy(fdb->addr.addr, addr, ETH_ALEN); - fdb->dst = source; -+ fdb->vlan_id = vid; - fdb->is_local = 0; - fdb->is_static = 0; - fdb->updated = fdb->used = jiffies; -@@ -368,15 +408,15 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, - } - - static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, -- const unsigned char *addr) -+ const unsigned char *addr, u16 vid) - { -- struct hlist_head *head = &br->hash[br_mac_hash(addr)]; -+ struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)]; - struct net_bridge_fdb_entry *fdb; - - if (!is_valid_ether_addr(addr)) - return -EINVAL; - -- fdb = fdb_find(head, addr); -+ fdb = fdb_find(head, addr, vid); - if (fdb) { - /* it is okay to have multiple ports with same - * address, just use the first one. -@@ -385,11 +425,11 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, - return 0; - br_warn(br, "adding interface %s with same address " - "as a received packet\n", -- source->dev->name); -+ source ? source->dev->name : br->dev->name); - fdb_delete(br, fdb); - } - -- fdb = fdb_create(head, source, addr); -+ fdb = fdb_create(head, source, addr, vid); - if (!fdb) - return -ENOMEM; - -@@ -400,20 +440,20 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, - - /* Add entry for local address of interface */ - int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source, -- const unsigned char *addr) -+ const unsigned char *addr, u16 vid) - { - int ret; - - spin_lock_bh(&br->hash_lock); -- ret = fdb_insert(br, source, addr); -+ ret = fdb_insert(br, source, addr, vid); - spin_unlock_bh(&br->hash_lock); - return ret; - } - - void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, -- const unsigned char *addr) -+ const unsigned char *addr, u16 vid) - { -- struct hlist_head *head = &br->hash[br_mac_hash(addr)]; -+ struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)]; - struct net_bridge_fdb_entry *fdb; - - /* some users want to always flood. */ -@@ -425,7 +465,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, - source->state == BR_STATE_FORWARDING)) - return; - -- fdb = fdb_find_rcu(head, addr); -+ fdb = fdb_find_rcu(head, addr, vid); - if (likely(fdb)) { - /* attempt to update an entry for a local interface */ - if (unlikely(fdb->is_local)) { -@@ -440,12 +480,11 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, - } - } else { - spin_lock(&br->hash_lock); -- if (likely(!fdb_find(head, addr))) { -- fdb = fdb_create(head, source, addr); -+ if (likely(!fdb_find(head, addr, vid))) { -+ fdb = fdb_create(head, source, addr, vid); - if (fdb) - fdb_notify(br, fdb, RTM_NEWNEIGH); - } -- - /* else we lose race and someone else inserts - * it first, don't bother updating - */ -@@ -467,18 +506,17 @@ static int fdb_to_nud(const struct net_bridge_fdb_entry *fdb) - - static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br, - const struct net_bridge_fdb_entry *fdb, -- u32 pid, u32 seq, int type, unsigned int flags) -+ u32 portid, u32 seq, int type, unsigned int flags) - { - unsigned long now = jiffies; - struct nda_cacheinfo ci; - struct nlmsghdr *nlh; - struct ndmsg *ndm; - -- nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags); -+ nlh = nlmsg_put(skb, portid, seq, type, sizeof(*ndm), flags); - if (nlh == NULL) - return -EMSGSIZE; - -- - ndm = nlmsg_data(nlh); - ndm->ndm_family = AF_BRIDGE; - ndm->ndm_pad1 = 0; -@@ -490,9 +528,8 @@ static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br, - - if (nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->addr)) - goto nla_put_failure; -- if (nla_put_u32(skb, NDA_MASTER, br->dev->ifindex)) -+ if (nla_put(skb, NDA_MASTER, sizeof(u32), &br->dev->ifindex)) - goto nla_put_failure; -- - ci.ndm_used = jiffies_to_clock_t(now - fdb->used); - ci.ndm_confirmed = 0; - ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated); -@@ -500,6 +537,9 @@ static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br, - if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci)) - goto nla_put_failure; - -+ if (nla_put(skb, NDA_VLAN, sizeof(u16), &fdb->vlan_id)) -+ goto nla_put_failure; -+ - return nlmsg_end(skb, nlh); - - nla_put_failure: -@@ -511,7 +551,8 @@ static inline size_t fdb_nlmsg_size(void) - { - return NLMSG_ALIGN(sizeof(struct ndmsg)) - + nla_total_size(ETH_ALEN) /* NDA_LLADDR */ -- + nla_total_size(4) /* NDA_MASTER */ -+ + nla_total_size(sizeof(u16)) /* NDA_VLAN */ -+ + nla_total_size(sizeof(u32)) /* NDA_MASTER */ - + nla_total_size(sizeof(struct nda_cacheinfo)); - } - -@@ -536,13 +577,12 @@ static void fdb_notify(struct net_bridge *br, - rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); - return; - errout: -- if (err < 0) -- rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); -+ rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); - } - - /* Dump information about entries, in response to GETNEIGH */ - int br_fdb_dump(struct sk_buff *skb, -- struct netlink_callback *cb, -+ struct netlink_callback *cb, - struct net_device *dev, - int idx) - { -@@ -577,21 +617,22 @@ out: - - /* Update (create or replace) forwarding database entry */ - static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, -- __u16 state, __u16 flags) -+ __u16 state, __u16 flags, __u16 vid) - { - struct net_bridge *br = source->br; -- struct hlist_head *head = &br->hash[br_mac_hash(addr)]; -+ struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)]; - struct net_bridge_fdb_entry *fdb; - bool modified = false; - -- fdb = fdb_find(head, addr); -+ fdb = fdb_find(head, addr, vid); - if (fdb == NULL) { - if (!(flags & NLM_F_CREATE)) - return -ENOENT; - -- fdb = fdb_create(head, source, addr); -+ fdb = fdb_create(head, source, addr, vid); - if (!fdb) - return -ENOMEM; -+ - modified = true; - } else { - if (flags & NLM_F_EXCL) -@@ -622,20 +663,60 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, - return 0; - } - -+static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge_port *p, -+ const unsigned char *addr, u16 nlh_flags, u16 vid) -+{ -+ int err = 0; -+ -+ if (ndm->ndm_flags & NTF_USE) { -+ rcu_read_lock(); -+ br_fdb_update(p->br, p, addr, vid); -+ rcu_read_unlock(); -+ } else { -+ spin_lock_bh(&p->br->hash_lock); -+ err = fdb_add_entry(p, addr, ndm->ndm_state, -+ nlh_flags, vid); -+ spin_unlock_bh(&p->br->hash_lock); -+ } -+ -+ return err; -+} -+ - /* Add new permanent fdb entry with RTM_NEWNEIGH */ - int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, - const unsigned char *addr, u16 nlh_flags) - { - struct net_bridge_port *p; -- - int err = 0; -+ struct net_port_vlans *pv; -+ unsigned short vid = VLAN_N_VID; - - if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) { - pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state); - return -EINVAL; - } - -+ if (tb[NDA_VLAN]) { -+ if (nla_len(tb[NDA_VLAN]) != sizeof(unsigned short)) { -+ pr_info("bridge: RTM_NEWNEIGH with invalid vlan\n"); -+ return -EINVAL; -+ } -+ -+ vid = nla_get_u16(tb[NDA_VLAN]); -+ -+ if (!vid || vid >= VLAN_VID_MASK) { -+ pr_info("bridge: RTM_NEWNEIGH with invalid vlan id %d\n", -+ vid); -+ return -EINVAL; -+ } -+ } -+ -+ if (is_zero_ether_addr(addr)) { -+ pr_info("bridge: RTM_NEWNEIGH with invalid ether address\n"); -+ return -EINVAL; -+ } -+ - p = br_port_get_rtnl(dev); - if (p == NULL) { - pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n", -@@ -643,25 +724,44 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], - return -EINVAL; - } - -- if (ndm->ndm_flags & NTF_USE) { -- rcu_read_lock(); -- br_fdb_update(p->br, p, addr); -- rcu_read_unlock(); -+ pv = nbp_get_vlan_info(p); -+ if (vid != VLAN_N_VID) { -+ if (!pv || !test_bit(vid, pv->vlan_bitmap)) { -+ pr_info("bridge: RTM_NEWNEIGH with unconfigured " -+ "vlan %d on port %s\n", vid, dev->name); -+ return -EINVAL; -+ } -+ -+ /* VID was specified, so use it. */ -+ err = __br_fdb_add(ndm, p, addr, nlh_flags, vid); - } else { -- spin_lock_bh(&p->br->hash_lock); -- err = fdb_add_entry(p, addr, ndm->ndm_state, nlh_flags); -- spin_unlock_bh(&p->br->hash_lock); -+ if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) { -+ err = __br_fdb_add(ndm, p, addr, nlh_flags, 0); -+ goto out; -+ } -+ -+ /* We have vlans configured on this port and user didn't -+ * specify a VLAN. To be nice, add/update entry for every -+ * vlan on this port. -+ */ -+ for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { -+ err = __br_fdb_add(ndm, p, addr, nlh_flags, vid); -+ if (err) -+ goto out; -+ } - } - -+out: - return err; - } - --static int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr) -+int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr, -+ u16 vlan) - { -- struct hlist_head *head = &br->hash[br_mac_hash(addr)]; -+ struct hlist_head *head = &br->hash[br_mac_hash(addr, vlan)]; - struct net_bridge_fdb_entry *fdb; - -- fdb = fdb_find(head, addr); -+ fdb = fdb_find(head, addr, vlan); - if (!fdb) - return -ENOENT; - -@@ -669,13 +769,42 @@ static int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr) - return 0; - } - -+static int __br_fdb_delete(struct net_bridge_port *p, -+ const unsigned char *addr, u16 vid) -+{ -+ int err; -+ -+ spin_lock_bh(&p->br->hash_lock); -+ err = fdb_delete_by_addr(p->br, addr, vid); -+ spin_unlock_bh(&p->br->hash_lock); -+ -+ return err; -+} -+ - /* Remove neighbor entry with RTM_DELNEIGH */ --int br_fdb_delete(struct ndmsg *ndm, struct net_device *dev, -+int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], -+ struct net_device *dev, - const unsigned char *addr) - { - struct net_bridge_port *p; - int err; -+ struct net_port_vlans *pv; -+ unsigned short vid = VLAN_N_VID; -+ -+ if (tb[NDA_VLAN]) { -+ if (nla_len(tb[NDA_VLAN]) != sizeof(unsigned short)) { -+ pr_info("bridge: RTM_NEWNEIGH with invalid vlan\n"); -+ return -EINVAL; -+ } -+ -+ vid = nla_get_u16(tb[NDA_VLAN]); - -+ if (!vid || vid >= VLAN_VID_MASK) { -+ pr_info("bridge: RTM_NEWNEIGH with invalid vlan id %d\n", -+ vid); -+ return -EINVAL; -+ } -+ } - p = br_port_get_rtnl(dev); - if (p == NULL) { - pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n", -@@ -683,9 +812,30 @@ int br_fdb_delete(struct ndmsg *ndm, struct net_device *dev, - return -EINVAL; - } - -- spin_lock_bh(&p->br->hash_lock); -- err = fdb_delete_by_addr(p->br, addr); -- spin_unlock_bh(&p->br->hash_lock); -+ pv = nbp_get_vlan_info(p); -+ if (vid != VLAN_N_VID) { -+ if (!pv || !test_bit(vid, pv->vlan_bitmap)) { -+ pr_info("bridge: RTM_DELNEIGH with unconfigured " -+ "vlan %d on port %s\n", vid, dev->name); -+ return -EINVAL; -+ } -+ -+ err = __br_fdb_delete(p, addr, vid); -+ } else { -+ if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) { -+ err = __br_fdb_delete(p, addr, 0); -+ goto out; -+ } - -+ /* We have vlans configured on this port and user didn't -+ * specify a VLAN. To be nice, add/update entry for every -+ * vlan on this port. -+ */ -+ err = -ENOENT; -+ for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { -+ err &= __br_fdb_delete(p, addr, vid); -+ } -+ } -+out: - return err; - } -diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c -index 1c9ba1b..6b32e27 100644 ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -28,15 +28,16 @@ static int deliver_clone(const struct net_bridge_port *prev, - - extern int br_hw_fwding_enabled; - --/* Don't forward packets to originating port or forwarding diasabled */ -+/* Don't forward packets to originating port or forwarding disabled */ - static inline int should_deliver(const struct net_bridge_port *p, - const struct sk_buff *skb) - { -- return (((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) && -- p->state == BR_STATE_FORWARDING); -+ return ((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) && -+ br_allowed_egress(p->br, nbp_get_vlan_info(p), skb) && -+ p->state == BR_STATE_FORWARDING; - } - --static inline unsigned packet_length(const struct sk_buff *skb) -+static inline unsigned int packet_length(const struct sk_buff *skb) - { - return skb->len - (skb->protocol == htons(ETH_P_8021Q) ? VLAN_HLEN : 0); - } -@@ -69,11 +70,16 @@ int br_hw_forward_finish(struct sk_buff *skb) - return 0; - - } -+ - static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) - { -+ skb = br_handle_vlan(to->br, nbp_get_vlan_info(to), skb); -+ if (!skb) -+ return; -+ - skb->dev = to->dev; - -- if (unlikely(netpoll_tx_running(to->dev))) { -+ if (unlikely(netpoll_tx_running(to->br->dev))) { - if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb)) - kfree_skb(skb); - else { -@@ -102,6 +108,10 @@ static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) - return; - } - -+ skb = br_handle_vlan(to->br, nbp_get_vlan_info(to), skb); -+ if (!skb) -+ return; -+ - indev = skb->dev; - skb->dev = to->dev; - skb_forward_csum(skb); -@@ -113,7 +123,7 @@ static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) - /* called with rcu_read_lock */ - void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) - { -- if (should_deliver(to, skb)) { -+ if (to && should_deliver(to, skb)) { - __br_deliver(to, skb); - return; - } -@@ -179,7 +189,8 @@ out: - static void br_flood(struct net_bridge *br, struct sk_buff *skb, - struct sk_buff *skb0, - void (*__packet_hook)(const struct net_bridge_port *p, -- struct sk_buff *skb)) -+ struct sk_buff *skb), -+ bool unicast) - { - struct net_bridge_port *p; - struct net_bridge_port *prev; -@@ -187,6 +198,9 @@ static void br_flood(struct net_bridge *br, struct sk_buff *skb, - prev = NULL; - - list_for_each_entry_rcu(p, &br->port_list, list) { -+ /* Do not flood unicast traffic to ports that turn it off */ -+ if (unicast && !(p->flags & BR_FLOOD)) -+ continue; - prev = maybe_deliver(prev, p, skb, __packet_hook); - if (IS_ERR(prev)) - goto out; -@@ -208,16 +222,16 @@ out: - - - /* called with rcu_read_lock */ --void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb) -+void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb, bool unicast) - { -- br_flood(br, skb, NULL, __br_deliver); -+ br_flood(br, skb, NULL, __br_deliver, unicast); - } - - /* called under bridge lock */ - void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, -- struct sk_buff *skb2) -+ struct sk_buff *skb2, bool unicast) - { -- br_flood(br, skb, skb2, __br_forward); -+ br_flood(br, skb, skb2, __br_forward, unicast); - } - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING -diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c -index c60121c..62c8fb2 100644 ---- a/net/bridge/br_if.c -+++ b/net/bridge/br_if.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include "br_private.h" - -@@ -60,21 +61,21 @@ static int port_cost(struct net_device *dev) - } - - --/* Check for port carrier transistions. */ -+/* Check for port carrier transitions. */ - void br_port_carrier_check(struct net_bridge_port *p) - { - struct net_device *dev = p->dev; - struct net_bridge *br = p->br; - - if (!(p->flags & BR_ADMIN_COST) && -- netif_running(dev) && netif_carrier_ok(dev)) -+ netif_running(dev) && netif_oper_up(dev)) - p->path_cost = port_cost(dev); - - if (!netif_running(br->dev)) - return; - - spin_lock_bh(&br->lock); -- if (netif_running(dev) && netif_carrier_ok(dev)) { -+ if (netif_running(dev) && netif_oper_up(dev)) { - if (p->state == BR_STATE_DISABLED) - br_stp_enable_port(p); - } else { -@@ -140,15 +141,18 @@ static void del_nbp(struct net_bridge_port *p) - - br_ifinfo_notify(RTM_DELLINK, p); - -+ nbp_vlan_flush(p); - br_fdb_delete_by_port(br, p, 1); - br_multicast_del_port(p); -+ - list_del_rcu(&p->list); - - dev->priv_flags &= ~IFF_BRIDGE_PORT; - - netdev_rx_handler_unregister(dev); -- synchronize_net(); - -+ //netdev_upper_dev_unlink(dev, br->dev); -+ synchronize_net(); - netdev_set_master(dev, NULL); - - kobject_uevent(&p->kobj, KOBJ_REMOVE); -@@ -171,6 +175,7 @@ void br_dev_delete(struct net_device *dev, struct list_head *head) - - br_fdb_delete_by_port(br, NULL, 1); - -+ br_vlan_flush(br); - br_multicast_dev_del(br); - del_timer_sync(&br->gc_timer); - -@@ -221,7 +226,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, - p->path_cost = port_cost(dev); - p->priority = 0x8000 >> BR_PORT_BITS; - p->port_no = index; -- p->flags = 0; -+ p->flags = BR_LEARNING | BR_FLOOD; - br_init_port(p); - p->state = BR_STATE_DISABLED; - br_stp_port_timer_init(p); -@@ -299,10 +304,11 @@ int br_min_mtu(const struct net_bridge *br) - /* - * Recomputes features using slave's features - */ --u32 br_features_recompute(struct net_bridge *br, u32 features) -+netdev_features_t br_features_recompute(struct net_bridge *br, -+ netdev_features_t features) - { - struct net_bridge_port *p; -- u32 mask; -+ netdev_features_t mask; - - if (list_empty(&br->port_list)) - return features; -@@ -362,15 +368,20 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) - if (err) - goto err2; - -- if (br_netpoll_info(br) && ((err = br_netpoll_enable(p)))) -+#ifdef CONFIG_NETPOLL -+ //err = br_netpoll_enable(p, GFP_KERNEL); -+ if (br->dev->npinfo && ((err = br_netpoll_enable(p)))) - goto err3; -+#endif - -+ //err = netdev_master_upper_dev_link(dev, br->dev); - err = netdev_set_master(dev, br->dev); - if (err) -- goto err3; -+ goto err4; - - err = netdev_rx_handler_register(dev, br_handle_frame, p); - if (err) -+ //goto err5; - goto err4; - - dev->priv_flags |= IFF_BRIDGE_PORT; -@@ -381,10 +392,13 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) - - netdev_update_features(br->dev); - -+ if (br->dev->needed_headroom < dev->needed_headroom) -+ br->dev->needed_headroom = dev->needed_headroom; -+ - spin_lock_bh(&br->lock); - changed_addr = br_stp_recalculate_bridge_id(br); - -- if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && -+ if (netif_running(dev) && netif_oper_up(dev) && - (br->dev->flags & IFF_UP)) - br_stp_enable_port(p); - spin_unlock_bh(&br->lock); -@@ -396,15 +410,17 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) - - dev_set_mtu(br->dev, br_min_mtu(br)); - -- if (br_fdb_insert(br, p, dev->dev_addr)) -+ if (br_fdb_insert(br, p, dev->dev_addr, 0)) - netdev_err(dev, "failed insert local address bridge forwarding table\n"); - - kobject_uevent(&p->kobj, KOBJ_ADD); - - return 0; - -+//err5: -+// netdev_upper_dev_unlink(dev, br->dev); - err4: -- netdev_set_master(dev, NULL); -+ br_netpoll_disable(p); - err3: - sysfs_remove_link(br->ifobj, p->dev->name); - err2: -@@ -428,6 +444,10 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) - if (!p || p->br != br) - return -EINVAL; - -+ /* Since more than one interface can be attached to a bridge, -+ * there still maybe an alternate path for netconsole to use; -+ * therefore there is no reason for a NETDEV_RELEASE event. -+ */ - del_nbp(p); - - spin_lock_bh(&br->lock); -@@ -441,18 +461,3 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) - - return 0; - } -- --void __net_exit br_net_exit(struct net *net) --{ -- struct net_device *dev; -- LIST_HEAD(list); -- -- rtnl_lock(); -- for_each_netdev(net, dev) -- if (dev->priv_flags & IFF_EBRIDGE) -- br_dev_delete(dev, &list); -- -- unregister_netdevice_many(&list); -- rtnl_unlock(); -- --} -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index 1c52833..874907a 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -17,10 +17,9 @@ - #include - #include - #include -+#include - #include "br_private.h" - --/* Bridge group multicast address 802.1d (pg 51). */ --const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; - const u8 br_pvst_address[ETH_ALEN] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcd }; - const u8 br_cdp_address[ETH_ALEN] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc }; - -@@ -34,13 +33,27 @@ static int br_pass_frame_up(struct sk_buff *skb) - { - struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; - struct net_bridge *br = netdev_priv(brdev); -- struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats); -+ struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats); - - u64_stats_update_begin(&brstats->syncp); - brstats->rx_packets++; - brstats->rx_bytes += skb->len; - u64_stats_update_end(&brstats->syncp); - -+ /* Bridge is just like any other port. Make sure the -+ * packet is allowed except in promisc modue when someone -+ * may be running packet capture. -+ */ -+ if (!(brdev->flags & IFF_PROMISC) && -+ !br_allowed_egress(br, br_get_vlan_info(br), skb)) { -+ kfree_skb(skb); -+ return NET_RX_DROP; -+ } -+ -+ skb = br_handle_vlan(br, br_get_vlan_info(br), skb); -+ if (!skb) -+ return NET_RX_DROP; -+ - indev = skb->dev; - skb->dev = brdev; - -@@ -57,18 +70,22 @@ int br_handle_frame_finish(struct sk_buff *skb) - struct net_bridge_fdb_entry *dst; - struct net_bridge_mdb_entry *mdst; - struct sk_buff *skb2; -+ bool unicast = true; -+ u16 vid = 0; - - if (!p || p->state == BR_STATE_DISABLED) - goto drop; - -+ if (!br_allowed_ingress(p->br, nbp_get_vlan_info(p), skb, &vid)) -+ goto drop; -+ - /* insert into forwarding database after filtering to avoid spoofing */ - br = p->br; -- -- if (!br_hw_fwding_enabled) -- br_fdb_update(br, p, eth_hdr(skb)->h_source); -+ if (!br_hw_fwding_enabled && (p->flags & BR_LEARNING)) -+ br_fdb_update(br, p, eth_hdr(skb)->h_source, vid); - - if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) && -- br_multicast_rcv(br, p, skb)) -+ br_multicast_rcv(br, p, skb, vid)) - goto drop; - - if (p->state == BR_STATE_LEARNING) -@@ -84,12 +101,13 @@ int br_handle_frame_finish(struct sk_buff *skb) - - dst = NULL; - -- if (is_broadcast_ether_addr(dest)) -+ if (is_broadcast_ether_addr(dest)) { - skb2 = skb; -- else if (is_multicast_ether_addr(dest)) { -- mdst = br_mdb_get(br, skb); -+ unicast = false; -+ } else if (is_multicast_ether_addr(dest)) { -+ mdst = br_mdb_get(br, skb, vid); - if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && -- br_multicast_querier_exists(br)) { -+ br_multicast_querier_exists(br, eth_hdr(skb))) { - if ((mdst && mdst->mglist) || - br_multicast_is_router(br)) - skb2 = skb; -@@ -100,8 +118,10 @@ int br_handle_frame_finish(struct sk_buff *skb) - } else - skb2 = skb; - -+ unicast = false; - br->dev->stats.multicast++; -- } else if ((dst = __br_fdb_get(br, dest)) && dst->is_local) { -+ } else if ((dst = __br_fdb_get(br, dest, vid)) && -+ dst->is_local) { - skb2 = skb; - /* Do not forward the packet since it's local. */ - skb = NULL; -@@ -112,7 +132,7 @@ int br_handle_frame_finish(struct sk_buff *skb) - dst->used = jiffies; - br_forward(dst->dst, skb, skb2); - } else -- br_flood_forward(br, skb, skb2); -+ br_flood_forward(br, skb, skb2, unicast); - } - - if (skb2) -@@ -129,25 +149,14 @@ drop: - static int br_handle_local_finish(struct sk_buff *skb) - { - struct net_bridge_port *p = br_port_get_rcu(skb->dev); -+ u16 vid = 0; - -- if (!br_hw_fwding_enabled) -- br_fdb_update(p->br, p, eth_hdr(skb)->h_source); -- -+ br_vlan_get_tag(skb, &vid); -+ if (!br_hw_fwding_enabled && (p->flags & BR_LEARNING)) -+ br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid); - return 0; /* process further */ - } - --/* Does address match the link local multicast address. -- * 01:80:c2:00:00:0X -- */ --static inline int is_link_local(const unsigned char *dest) --{ -- __be16 *a = (__be16 *)dest; -- static const __be16 *b = (const __be16 *)br_group_address; -- static const __be16 m = cpu_to_be16(0xfff0); -- -- return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0; --} -- - /* - * Return NULL if skb is handled - * note: already called with rcu_read_lock -@@ -179,7 +188,7 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) - return RX_HANDLER_CONSUMED; /* consumed by filter */ - } else { - *pskb = skb; -- return RX_HANDLER_PASS; /* continue processing */ -+ return RX_HANDLER_PASS; /* continue processing */ - } - } - -@@ -190,11 +199,11 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) - return RX_HANDLER_CONSUMED; /* consumed by filter */ - } else { - *pskb = skb; -- return RX_HANDLER_PASS; /* continue processing */ -+ return RX_HANDLER_PASS; /* continue processing */ - } - } - -- if (unlikely(is_link_local(dest))) { -+ if (unlikely(is_link_local_ether_addr(dest))) { - /* - * See IEEE 802.1D Table 7-10 Reserved addresses - * -@@ -248,7 +257,7 @@ forward: - } - /* fall through */ - case BR_STATE_LEARNING: -- if (!compare_ether_addr(p->br->dev->dev_addr, dest)) -+ if (ether_addr_equal(p->br->dev->dev_addr, dest)) - skb->pkt_type = PACKET_HOST; - - NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, -diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c -index 7222fe1..0f36751 100644 ---- a/net/bridge/br_ioctl.c -+++ b/net/bridge/br_ioctl.c -@@ -85,13 +85,15 @@ static int get_fdb_entries(struct net_bridge *br, void __user *userbuf, - /* called with RTNL */ - static int add_del_if(struct net_bridge *br, int ifindex, int isadd) - { -+ struct net *net = dev_net(br->dev); - struct net_device *dev; - int ret; - -+ //if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - -- dev = __dev_get_by_index(dev_net(br->dev), ifindex); -+ dev = __dev_get_by_index(net, ifindex); - if (dev == NULL) - return -EINVAL; - -@@ -178,24 +180,28 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) - } - - case BRCTL_SET_BRIDGE_FORWARD_DELAY: -+ //if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - return br_set_forward_delay(br, args[1]); - - case BRCTL_SET_BRIDGE_HELLO_TIME: -+ //if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - return br_set_hello_time(br, args[1]); - - case BRCTL_SET_BRIDGE_MAX_AGE: -+ //if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - return br_set_max_age(br, args[1]); - - case BRCTL_SET_AGEING_TIME: -+ //if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - -@@ -236,6 +242,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) - } - - case BRCTL_SET_BRIDGE_STP_STATE: -+ //if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - -@@ -243,6 +250,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) - return 0; - - case BRCTL_SET_BRIDGE_PRIORITY: -+ //if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - -@@ -256,6 +264,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) - struct net_bridge_port *p; - int ret; - -+ //if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - -@@ -273,6 +282,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) - struct net_bridge_port *p; - int ret; - -+ //if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - -@@ -330,6 +340,7 @@ static int old_deviceless(struct net *net, void __user *uarg) - { - char buf[IFNAMSIZ]; - -+ //if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - -@@ -360,6 +371,7 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uar - { - char buf[IFNAMSIZ]; - -+ //if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - -@@ -380,7 +392,7 @@ int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) - { - struct net_bridge *br = netdev_priv(dev); - -- switch(cmd) { -+ switch (cmd) { - case SIOCDEVPRIVATE: - return old_dev_ioctl(dev, rq, cmd); - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index 99ab620..29c7b96 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -9,6 +9,7 @@ - #include - #if IS_ENABLED(CONFIG_IPV6) - #include -+#include - #endif - - #include "br_private.h" -@@ -63,7 +64,8 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, - for (i = 0; i < mdb->max; i++) { - struct hlist_node *h; - struct net_bridge_mdb_entry *mp; -- struct net_bridge_port_group *p, **pp; -+ struct net_bridge_port_group *p; -+ struct net_bridge_port_group __rcu **pp; - struct net_bridge_port *port; - - hlist_for_each_entry_rcu(mp, h, &mdb->mhash[i], hlist[mdb->ver]) { -@@ -82,6 +84,7 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, - port = p->port; - if (port) { - struct br_mdb_entry e; -+ memset(&e, 0, sizeof(e)); - e.ifindex = port->dev->ifindex; - e.state = p->state; - if (p->addr.proto == htons(ETH_P_IP)) -@@ -138,6 +141,7 @@ static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb) - break; - - bpm = nlmsg_data(nlh); -+ memset(bpm, 0, sizeof(*bpm)); - bpm->ifindex = dev->ifindex; - if (br_mdb_fill_info(skb, cb, dev) < 0) - goto out; -@@ -173,6 +177,7 @@ static int nlmsg_populate_mdb_fill(struct sk_buff *skb, - return -EMSGSIZE; - - bpm = nlmsg_data(nlh); -+ memset(bpm, 0, sizeof(*bpm)); - bpm->family = AF_BRIDGE; - bpm->ifindex = dev->ifindex; - nest = nla_nest_start(skb, MDBA_MDB); -@@ -230,6 +235,7 @@ void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, - { - struct br_mdb_entry entry; - -+ memset(&entry, 0, sizeof(entry)); - entry.ifindex = port->dev->ifindex; - entry.addr.proto = group->proto; - entry.addr.u.ip4 = group->u.ip4; -@@ -241,9 +247,9 @@ void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, - } - - static int nlmsg_populate_rtr_fill(struct sk_buff *skb, -- struct net_device *dev, -- int ifindex, u32 pid, -- u32 seq, int type, unsigned int flags) -+ struct net_device *dev, -+ int ifindex, u32 pid, -+ u32 seq, int type, unsigned int flags) - { - struct nlmsghdr *nlh; - struct br_port_msg *bpm; -@@ -281,7 +287,7 @@ static inline size_t rtnl_rtr_nlmsg_size(void) - } - - void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, -- int type) -+ int type) - { - struct net *net = dev_net(dev); - struct sk_buff *skb; -@@ -316,7 +322,7 @@ static bool is_valid_mdb_entry(struct br_mdb_entry *entry) - return false; - #if IS_ENABLED(CONFIG_IPV6) - } else if (entry->addr.proto == htons(ETH_P_IPV6)) { -- if (!ipv6_is_transient_multicast(&entry->addr.u.ip6)) -+ if (ipv6_addr_is_ll_all_nodes(&entry->addr.u.ip6)) - return false; - #endif - } else -@@ -479,16 +485,20 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry) - if (!netif_running(br->dev) || br->multicast_disabled) - return -EINVAL; - -- if (timer_pending(&br->multicast_querier_timer)) -- return -EBUSY; -- - ip.proto = entry->addr.proto; -- if (ip.proto == htons(ETH_P_IP)) -+ if (ip.proto == htons(ETH_P_IP)) { -+ if (timer_pending(&br->ip4_querier.timer)) -+ return -EBUSY; -+ - ip.u.ip4 = entry->addr.u.ip4; - #if IS_ENABLED(CONFIG_IPV6) -- else -+ } else { -+ if (timer_pending(&br->ip6_querier.timer)) -+ return -EBUSY; -+ - ip.u.ip6 = entry->addr.u.ip6; - #endif -+ } - - spin_lock_bh(&br->multicast_lock); - mdb = mlock_dereference(br->mdb, br); -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 11f4a71..0047db7 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -25,38 +25,50 @@ - #include - #include - #include --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+#if IS_ENABLED(CONFIG_IPV6) - #include - #include --#include - #include -+#include - #endif - - #include "br_private.h" - --#define mlock_dereference(X, br) \ -- rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) -- --static void br_multicast_start_querier(struct net_bridge *br); -+static void br_multicast_start_querier(struct net_bridge *br, -+ struct bridge_mcast_query *query); - static void br_multicast_add_router(struct net_bridge *br, - struct net_bridge_port *port); - static void br_multicast_del_grps(struct net_bridge *br); - static void br_ip4_multicast_leave_group(struct net_bridge *br, -- struct net_bridge_port *port, __be32 group); -+ struct net_bridge_port *port, __be32 group, __u16 vid); - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - static void br_ip6_multicast_leave_group(struct net_bridge *br, -- struct net_bridge_port *port, const struct in6_addr *group); -+ struct net_bridge_port *port, const struct in6_addr *group, __u16 vid); - #endif - unsigned int br_mdb_rehash_seq; - -+/* ported from net/ipv6/addrconf.c */ -+static u32 ipv6_addr_hash(const struct in6_addr *addr) -+{ -+ /* -+ * We perform the hash function over the last 64 bits of the address -+ * This will include the IEEE address token on links that support it. -+ */ -+ return jhash_2words((__force u32)addr->s6_addr32[2], -+ (__force u32)addr->s6_addr32[3], 0) -+ & (IN6_ADDR_HSIZE - 1); -+} -+ - static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b) - { - if (a->proto != b->proto) - return 0; -+ if (a->vid != b->vid) -+ return 0; - switch (a->proto) { - case htons(ETH_P_IP): - return a->u.ip4 == b->u.ip4; --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+#if IS_ENABLED(CONFIG_IPV6) - case htons(ETH_P_IPV6): - return ipv6_addr_equal(&a->u.ip6, &b->u.ip6); - #endif -@@ -64,16 +76,19 @@ static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b) - return 0; - } - --static inline int __br_ip4_hash(struct net_bridge_mdb_htable *mdb, __be32 ip) -+static inline int __br_ip4_hash(struct net_bridge_mdb_htable *mdb, __be32 ip, -+ __u16 vid) - { -- return jhash_1word(mdb->secret, (__force u32)ip) & (mdb->max - 1); -+ return jhash_2words((__force u32)ip, vid, mdb->secret) & (mdb->max - 1); - } - --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+#if IS_ENABLED(CONFIG_IPV6) - static inline int __br_ip6_hash(struct net_bridge_mdb_htable *mdb, -- const struct in6_addr *ip) -+ const struct in6_addr *ip, -+ __u16 vid) - { -- return jhash2((__force u32 *)ip->s6_addr32, 4, mdb->secret) & (mdb->max - 1); -+ return jhash_2words(ipv6_addr_hash(ip), vid, -+ mdb->secret) & (mdb->max - 1); - } - #endif - -@@ -82,10 +97,10 @@ static inline int br_ip_hash(struct net_bridge_mdb_htable *mdb, - { - switch (ip->proto) { - case htons(ETH_P_IP): -- return __br_ip4_hash(mdb, ip->u.ip4); --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+ return __br_ip4_hash(mdb, ip->u.ip4, ip->vid); -+#if IS_ENABLED(CONFIG_IPV6) - case htons(ETH_P_IPV6): -- return __br_ip6_hash(mdb, &ip->u.ip6); -+ return __br_ip6_hash(mdb, &ip->u.ip6, ip->vid); - #endif - } - return 0; -@@ -115,31 +130,34 @@ struct net_bridge_mdb_entry *br_mdb_ip_get(struct net_bridge_mdb_htable *mdb, - } - - static struct net_bridge_mdb_entry *br_mdb_ip4_get( -- struct net_bridge_mdb_htable *mdb, __be32 dst) -+ struct net_bridge_mdb_htable *mdb, __be32 dst, __u16 vid) - { - struct br_ip br_dst; - - br_dst.u.ip4 = dst; - br_dst.proto = htons(ETH_P_IP); -+ br_dst.vid = vid; - - return br_mdb_ip_get(mdb, &br_dst); - } - --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+#if IS_ENABLED(CONFIG_IPV6) - static struct net_bridge_mdb_entry *br_mdb_ip6_get( -- struct net_bridge_mdb_htable *mdb, const struct in6_addr *dst) -+ struct net_bridge_mdb_htable *mdb, const struct in6_addr *dst, -+ __u16 vid) - { - struct br_ip br_dst; - -- ipv6_addr_copy(&br_dst.u.ip6, dst); -+ br_dst.u.ip6 = *dst; - br_dst.proto = htons(ETH_P_IPV6); -+ br_dst.vid = vid; - - return br_mdb_ip_get(mdb, &br_dst); - } - #endif - - struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, -- struct sk_buff *skb) -+ struct sk_buff *skb, u16 vid) - { - struct net_bridge_mdb_htable *mdb = rcu_dereference(br->mdb); - struct br_ip ip; -@@ -151,14 +169,15 @@ struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, - return NULL; - - ip.proto = skb->protocol; -+ ip.vid = vid; - - switch (skb->protocol) { - case htons(ETH_P_IP): - ip.u.ip4 = ip_hdr(skb)->daddr; - break; --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+#if IS_ENABLED(CONFIG_IPV6) - case htons(ETH_P_IPV6): -- ipv6_addr_copy(&ip.u.ip6, &ipv6_hdr(skb)->daddr); -+ ip.u.ip6 = ipv6_hdr(skb)->daddr; - break; - #endif - default: -@@ -368,7 +387,7 @@ static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br, - skb_reset_mac_header(skb); - eth = eth_hdr(skb); - -- memcpy(eth->h_source, br->dev->dev_addr, 6); -+ memcpy(eth->h_source, br->dev->dev_addr, ETH_ALEN); - eth->h_dest[0] = 1; - eth->h_dest[1] = 0; - eth->h_dest[2] = 0x5e; -@@ -416,7 +435,7 @@ out: - return skb; - } - --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+#if IS_ENABLED(CONFIG_IPV6) - static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, - const struct in6_addr *group) - { -@@ -438,7 +457,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, - skb_reset_mac_header(skb); - eth = eth_hdr(skb); - -- memcpy(eth->h_source, br->dev->dev_addr, 6); -+ memcpy(eth->h_source, br->dev->dev_addr, ETH_ALEN); - eth->h_proto = htons(ETH_P_IPV6); - skb_put(skb, sizeof(*eth)); - -@@ -483,7 +502,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, - mldq->mld_cksum = 0; - mldq->mld_maxdelay = htons((u16)jiffies_to_msecs(interval)); - mldq->mld_reserved = 0; -- ipv6_addr_copy(&mldq->mld_mca, group); -+ mldq->mld_mca = *group; - - /* checksum */ - mldq->mld_cksum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, -@@ -505,7 +524,7 @@ static struct sk_buff *br_multicast_alloc_query(struct net_bridge *br, - switch (addr->proto) { - case htons(ETH_P_IP): - return br_ip4_multicast_alloc_query(br, addr->u.ip4); --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+#if IS_ENABLED(CONFIG_IPV6) - case htons(ETH_P_IPV6): - return br_ip6_multicast_alloc_query(br, &addr->u.ip6); - #endif -@@ -520,8 +539,8 @@ static struct net_bridge_mdb_entry *br_multicast_get_group( - struct net_bridge_mdb_htable *mdb; - struct net_bridge_mdb_entry *mp; - struct hlist_node *p; -- unsigned count = 0; -- unsigned max; -+ unsigned int count = 0; -+ unsigned int max; - int elasticity; - int err; - -@@ -546,10 +565,11 @@ static struct net_bridge_mdb_entry *br_multicast_get_group( - - if (mdb->size >= max) { - max *= 2; -- if (unlikely(max >= br->hash_max)) { -- br_warn(br, "Multicast hash table maximum " -- "reached, disabling snooping: %s, %d\n", -- port ? port->dev->name : br->dev->name, max); -+ if (unlikely(max > br->hash_max)) { -+ br_warn(br, "Multicast hash table maximum of %d " -+ "reached, disabling snooping: %s\n", -+ br->hash_max, -+ port ? port->dev->name : br->dev->name); - err = -E2BIG; - disable: - br->multicast_disabled = 1; -@@ -711,7 +731,8 @@ err: - - static int br_ip4_multicast_add_group(struct net_bridge *br, - struct net_bridge_port *port, -- __be32 group) -+ __be32 group, -+ __u16 vid) - { - struct br_ip br_group; - -@@ -720,22 +741,25 @@ static int br_ip4_multicast_add_group(struct net_bridge *br, - - br_group.u.ip4 = group; - br_group.proto = htons(ETH_P_IP); -+ br_group.vid = vid; - - return br_multicast_add_group(br, port, &br_group); - } - --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+#if IS_ENABLED(CONFIG_IPV6) - static int br_ip6_multicast_add_group(struct net_bridge *br, - struct net_bridge_port *port, -- const struct in6_addr *group) -+ const struct in6_addr *group, -+ __u16 vid) - { - struct br_ip br_group; - -- if (!ipv6_is_transient_multicast(group)) -+ if (ipv6_addr_is_ll_all_nodes(group)) - return 0; - -- ipv6_addr_copy(&br_group.u.ip6, group); -+ br_group.u.ip6 = *group; - br_group.proto = htons(ETH_P_IPV6); -+ br_group.vid = vid; - - return br_multicast_add_group(br, port, &br_group); - } -@@ -763,20 +787,35 @@ static void br_multicast_local_router_expired(unsigned long data) - { - } - --static void br_multicast_querier_expired(unsigned long data) -+static void br_multicast_querier_expired(struct net_bridge *br, -+ struct bridge_mcast_query *query) - { -- struct net_bridge *br = (void *)data; -- - spin_lock(&br->multicast_lock); - if (!netif_running(br->dev) || br->multicast_disabled) - goto out; - -- br_multicast_start_querier(br); -+ br_multicast_start_querier(br, query); - - out: - spin_unlock(&br->multicast_lock); - } - -+static void br_ip4_multicast_querier_expired(unsigned long data) -+{ -+ struct net_bridge *br = (void *)data; -+ -+ br_multicast_querier_expired(br, &br->ip4_query); -+} -+ -+#if IS_ENABLED(CONFIG_IPV6) -+static void br_ip6_multicast_querier_expired(unsigned long data) -+{ -+ struct net_bridge *br = (void *)data; -+ -+ br_multicast_querier_expired(br, &br->ip6_query); -+} -+#endif -+ - static void __br_multicast_send_query(struct net_bridge *br, - struct net_bridge_port *port, - struct br_ip *ip) -@@ -797,37 +836,45 @@ static void __br_multicast_send_query(struct net_bridge *br, - } - - static void br_multicast_send_query(struct net_bridge *br, -- struct net_bridge_port *port, u32 sent) -+ struct net_bridge_port *port, -+ struct bridge_mcast_query *query) - { - unsigned long time; - struct br_ip br_group; -+ struct bridge_mcast_querier *querier = NULL; - - if (!netif_running(br->dev) || br->multicast_disabled || -- !br->multicast_querier || -- timer_pending(&br->multicast_querier_timer)) -+ !br->multicast_querier) - return; - - memset(&br_group.u, 0, sizeof(br_group.u)); - -- br_group.proto = htons(ETH_P_IP); -- __br_multicast_send_query(br, port, &br_group); -+ if (port ? (query == &port->ip4_query) : -+ (query == &br->ip4_query)) { -+ querier = &br->ip4_querier; -+ br_group.proto = htons(ETH_P_IP); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ querier = &br->ip6_querier; -+ br_group.proto = htons(ETH_P_IPV6); -+#endif -+ } -+ -+ if (!querier || timer_pending(&querier->timer)) -+ return; - --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -- br_group.proto = htons(ETH_P_IPV6); - __br_multicast_send_query(br, port, &br_group); --#endif - - time = jiffies; -- time += sent < br->multicast_startup_query_count ? -+ time += query->startup_sent < br->multicast_startup_query_count ? - br->multicast_startup_query_interval : - br->multicast_query_interval; -- mod_timer(port ? &port->multicast_query_timer : -- &br->multicast_query_timer, time); -+ mod_timer(&query->timer, time); - } - --static void br_multicast_port_query_expired(unsigned long data) -+static void br_multicast_port_query_expired(struct net_bridge_port *port, -+ struct bridge_mcast_query *query) - { -- struct net_bridge_port *port = (void *)data; - struct net_bridge *br = port->br; - - spin_lock(&br->multicast_lock); -@@ -835,25 +882,43 @@ static void br_multicast_port_query_expired(unsigned long data) - port->state == BR_STATE_BLOCKING) - goto out; - -- if (port->multicast_startup_queries_sent < -- br->multicast_startup_query_count) -- port->multicast_startup_queries_sent++; -+ if (query->startup_sent < br->multicast_startup_query_count) -+ query->startup_sent++; - -- br_multicast_send_query(port->br, port, -- port->multicast_startup_queries_sent); -+ br_multicast_send_query(port->br, port, query); - - out: - spin_unlock(&br->multicast_lock); - } - -+static void br_ip4_multicast_port_query_expired(unsigned long data) -+{ -+ struct net_bridge_port *port = (void *)data; -+ -+ br_multicast_port_query_expired(port, &port->ip4_query); -+} -+ -+#if IS_ENABLED(CONFIG_IPV6) -+static void br_ip6_multicast_port_query_expired(unsigned long data) -+{ -+ struct net_bridge_port *port = (void *)data; -+ -+ br_multicast_port_query_expired(port, &port->ip6_query); -+} -+#endif -+ - void br_multicast_add_port(struct net_bridge_port *port) - { - port->multicast_router = 1; - - setup_timer(&port->multicast_router_timer, br_multicast_router_expired, - (unsigned long)port); -- setup_timer(&port->multicast_query_timer, -- br_multicast_port_query_expired, (unsigned long)port); -+ setup_timer(&port->ip4_query.timer, br_ip4_multicast_port_query_expired, -+ (unsigned long)port); -+#if IS_ENABLED(CONFIG_IPV6) -+ setup_timer(&port->ip6_query.timer, br_ip6_multicast_port_query_expired, -+ (unsigned long)port); -+#endif - } - - void br_multicast_del_port(struct net_bridge_port *port) -@@ -871,13 +936,13 @@ void br_multicast_del_port(struct net_bridge_port *port) - del_timer_sync(&port->multicast_router_timer); - } - --static void __br_multicast_enable_port(struct net_bridge_port *port) -+static void br_multicast_enable(struct bridge_mcast_query *query) - { -- port->multicast_startup_queries_sent = 0; -+ query->startup_sent = 0; - -- if (try_to_del_timer_sync(&port->multicast_query_timer) >= 0 || -- del_timer(&port->multicast_query_timer)) -- mod_timer(&port->multicast_query_timer, jiffies); -+ if (try_to_del_timer_sync(&query->timer) >= 0 || -+ del_timer(&query->timer)) -+ mod_timer(&query->timer, jiffies); - } - - void br_multicast_enable_port(struct net_bridge_port *port) -@@ -888,7 +953,10 @@ void br_multicast_enable_port(struct net_bridge_port *port) - if (br->multicast_disabled || !netif_running(br->dev)) - goto out; - -- __br_multicast_enable_port(port); -+ br_multicast_enable(&port->ip4_query); -+#if IS_ENABLED(CONFIG_IPV6) -+ br_multicast_enable(&port->ip6_query); -+#endif - if ((port->multicast_router == 2) && hlist_unhashed(&port->rlist)) - br_multicast_add_router(br, port); - -@@ -913,13 +981,17 @@ void br_multicast_disable_port(struct net_bridge_port *port) - br_rtr_notify(br->dev, port, RTM_DELMDB); - } - del_timer(&port->multicast_router_timer); -- del_timer(&port->multicast_query_timer); -+ del_timer(&port->ip4_query.timer); -+#if IS_ENABLED(CONFIG_IPV6) -+ del_timer(&port->ip6_query.timer); -+#endif - spin_unlock(&br->multicast_lock); - } - - static int br_ip4_multicast_igmp3_report(struct net_bridge *br, - struct net_bridge_port *port, -- struct sk_buff *skb) -+ struct sk_buff *skb, -+ u16 vid) - { - struct igmpv3_report *ih; - struct igmpv3_grec *grec; -@@ -965,9 +1037,9 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br, - } - if (((type == IGMPV3_CHANGE_TO_INCLUDE) || - (type == IGMPV3_MODE_IS_INCLUDE)) && (ntohs(grec->grec_nsrcs) == 0)) { -- br_ip4_multicast_leave_group(br, port, group); -+ br_ip4_multicast_leave_group(br, port, group, vid); - } else { -- err = br_ip4_multicast_add_group(br, port, group); -+ err = br_ip4_multicast_add_group(br, port, group, vid); - if (err) - break; - } -@@ -976,10 +1048,11 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br, - return err; - } - --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+#if IS_ENABLED(CONFIG_IPV6) - static int br_ip6_multicast_mld2_report(struct net_bridge *br, - struct net_bridge_port *port, -- struct sk_buff *skb) -+ struct sk_buff *skb, -+ u16 vid) - { - struct icmp6hdr *icmp6h; - struct mld2_grec *grec; -@@ -1027,11 +1100,12 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, - default: - continue; - } -+ - if (((grec->grec_type == MLD2_CHANGE_TO_INCLUDE) || - (grec->grec_type == MLD2_MODE_IS_INCLUDE)) && (ntohs(*nsrcs) == 0)) { -- br_ip6_multicast_leave_group(br, port, &grec->grec_mca); -+ br_ip6_multicast_leave_group(br, port, &grec->grec_mca, vid); - } else { -- err = br_ip6_multicast_add_group(br, port, &grec->grec_mca); -+ err = br_ip6_multicast_add_group(br, port, &grec->grec_mca, vid); - if (!err) - break; - } -@@ -1041,18 +1115,19 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, - } - #endif - --static void br_multicast_update_querier_timer(struct net_bridge *br, -- unsigned long max_delay) -+static void -+br_multicast_update_querier_timer(struct net_bridge *br, -+ struct bridge_mcast_querier *querier, -+ unsigned long max_delay) - { -- if (!timer_pending(&br->multicast_querier_timer)) -- br->multicast_querier_delay_time = jiffies + max_delay; -+ if (!timer_pending(&querier->timer)) -+ querier->delay_time = jiffies + max_delay; - -- mod_timer(&br->multicast_querier_timer, -- jiffies + br->multicast_querier_interval); -+ mod_timer(&querier->timer, jiffies + br->multicast_querier_interval); - } - - /* -- * Add port to rotuer_list -+ * Add port to router_list - * list is maintained ordered by pointer value - * and locked by br->multicast_lock and RCU - */ -@@ -1065,7 +1140,7 @@ static void br_multicast_add_router(struct net_bridge *br, - hlist_for_each_entry(p, n, &br->router_list, rlist) { - if ((unsigned long) port >= (unsigned long) p) - break; -- slot = n; -+ slot = &p->rlist; - } - - if (slot) -@@ -1102,12 +1177,13 @@ timer: - - static void br_multicast_query_received(struct net_bridge *br, - struct net_bridge_port *port, -+ struct bridge_mcast_querier *querier, - int saddr, - unsigned long max_delay) - { - if (saddr) -- br_multicast_update_querier_timer(br, max_delay); -- else if (timer_pending(&br->multicast_querier_timer)) -+ br_multicast_update_querier_timer(br, querier, max_delay); -+ else if (timer_pending(&querier->timer)) - return; - - br_multicast_mark_router(br, port); -@@ -1115,7 +1191,8 @@ static void br_multicast_query_received(struct net_bridge *br, - - static int br_ip4_multicast_query(struct net_bridge *br, - struct net_bridge_port *port, -- struct sk_buff *skb) -+ struct sk_buff *skb, -+ u16 vid) - { - const struct iphdr *iph = ip_hdr(skb); - struct igmphdr *ih = igmp_hdr(skb); -@@ -1156,12 +1233,13 @@ static int br_ip4_multicast_query(struct net_bridge *br, - IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; - } - -- br_multicast_query_received(br, port, !!iph->saddr, max_delay); -+ br_multicast_query_received(br, port, &br->ip4_querier, !!iph->saddr, -+ max_delay); - - if (!group) - goto out; - -- mp = br_mdb_ip4_get(mlock_dereference(br->mdb, br), group); -+ mp = br_mdb_ip4_get(mlock_dereference(br->mdb, br), group, vid); - if (!mp) - goto out; - -@@ -1187,10 +1265,11 @@ out: - return err; - } - --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+#if IS_ENABLED(CONFIG_IPV6) - static int br_ip6_multicast_query(struct net_bridge *br, - struct net_bridge_port *port, -- struct sk_buff *skb) -+ struct sk_buff *skb, -+ u16 vid) - { - const struct ipv6hdr *ip6h = ipv6_hdr(skb); - struct mld_msg *mld = (struct mld_msg *) icmp6_hdr(skb); -@@ -1235,12 +1314,13 @@ static int br_ip6_multicast_query(struct net_bridge *br, - max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL); - } - -- br_multicast_query_received(br, port, !ipv6_addr_any(&ip6h->saddr), -- max_delay); -+ br_multicast_query_received(br, port, &br->ip6_querier, -+ !ipv6_addr_any(&ip6h->saddr), max_delay); -+ - if (!group) - goto out; - -- mp = br_mdb_ip6_get(mlock_dereference(br->mdb, br), group); -+ mp = br_mdb_ip6_get(mlock_dereference(br->mdb, br), group, vid); - if (!mp) - goto out; - -@@ -1268,7 +1348,9 @@ out: - - static void br_multicast_leave_group(struct net_bridge *br, - struct net_bridge_port *port, -- struct br_ip *group) -+ struct br_ip *group, -+ struct bridge_mcast_querier *querier, -+ struct bridge_mcast_query *query) - { - struct net_bridge_mdb_htable *mdb; - struct net_bridge_mdb_entry *mp; -@@ -1286,7 +1368,7 @@ static void br_multicast_leave_group(struct net_bridge *br, - if (!mp) - goto out; - -- if (port && port->multicast_fast_leave) { -+ if (port && (port->flags & BR_MULTICAST_FAST_LEAVE)) { - struct net_bridge_port_group __rcu **pp; - - for (pp = &mp->ports; -@@ -1311,14 +1393,13 @@ static void br_multicast_leave_group(struct net_bridge *br, - if (timer_pending(&br->multicast_querier_timer)) - goto out; - -- if (br->multicast_querier && -- !timer_pending(&br->multicast_querier_timer)) { -+ if (br->multicast_querier) { - __br_multicast_send_query(br, port, &mp->addr); - - time = jiffies + br->multicast_last_member_count * - br->multicast_last_member_interval; -- mod_timer(port ? &port->multicast_query_timer : -- &br->multicast_query_timer, time); -+ -+ mod_timer(&query->timer, time); - - for (p = mlock_dereference(mp->ports, br); - p != NULL; -@@ -1367,52 +1448,61 @@ static void br_multicast_leave_group(struct net_bridge *br, - - break; - } -- - out: - spin_unlock(&br->multicast_lock); - } - - static void br_ip4_multicast_leave_group(struct net_bridge *br, - struct net_bridge_port *port, -- __be32 group) -+ __be32 group, -+ __u16 vid) - { - struct br_ip br_group; -+ struct bridge_mcast_query *query = port ? &port->ip4_query : -+ &br->ip4_query; - - if (ipv4_is_local_multicast(group)) - return; - - br_group.u.ip4 = group; - br_group.proto = htons(ETH_P_IP); -+ br_group.vid = vid; - -- br_multicast_leave_group(br, port, &br_group); -+ br_multicast_leave_group(br, port, &br_group, &br->ip4_querier, query); - } - --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+#if IS_ENABLED(CONFIG_IPV6) - static void br_ip6_multicast_leave_group(struct net_bridge *br, - struct net_bridge_port *port, -- const struct in6_addr *group) -+ const struct in6_addr *group, -+ __u16 vid) - { - struct br_ip br_group; -+ struct bridge_mcast_query *query = port ? &port->ip6_query : -+ &br->ip6_query; - -- if (!ipv6_is_transient_multicast(group)) -+ -+ if (ipv6_addr_is_ll_all_nodes(group)) - return; - -- ipv6_addr_copy(&br_group.u.ip6, group); -+ br_group.u.ip6 = *group; - br_group.proto = htons(ETH_P_IPV6); -+ br_group.vid = vid; - -- br_multicast_leave_group(br, port, &br_group); -+ br_multicast_leave_group(br, port, &br_group, &br->ip6_querier, query); - } - #endif - - static int br_multicast_ipv4_rcv(struct net_bridge *br, - struct net_bridge_port *port, -- struct sk_buff *skb) -+ struct sk_buff *skb, -+ u16 vid) - { - struct sk_buff *skb2 = skb; - const struct iphdr *iph; - struct igmphdr *ih; -- unsigned len; -- unsigned offset; -+ unsigned int len; -+ unsigned int offset; - int err; - - /* We treat OOM as packet loss for now. */ -@@ -1481,16 +1571,16 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, - case IGMP_HOST_MEMBERSHIP_REPORT: - case IGMPV2_HOST_MEMBERSHIP_REPORT: - BR_INPUT_SKB_CB(skb)->mrouters_only = 1; -- err = br_ip4_multicast_add_group(br, port, ih->group); -+ err = br_ip4_multicast_add_group(br, port, ih->group, vid); - break; - case IGMPV3_HOST_MEMBERSHIP_REPORT: -- err = br_ip4_multicast_igmp3_report(br, port, skb2); -+ err = br_ip4_multicast_igmp3_report(br, port, skb2, vid); - break; - case IGMP_HOST_MEMBERSHIP_QUERY: -- err = br_ip4_multicast_query(br, port, skb2); -+ err = br_ip4_multicast_query(br, port, skb2, vid); - break; - case IGMP_HOST_LEAVE_MESSAGE: -- br_ip4_multicast_leave_group(br, port, ih->group); -+ br_ip4_multicast_leave_group(br, port, ih->group, vid); - break; - } - -@@ -1502,16 +1592,17 @@ err_out: - return err; - } - --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+#if IS_ENABLED(CONFIG_IPV6) - static int br_multicast_ipv6_rcv(struct net_bridge *br, - struct net_bridge_port *port, -- struct sk_buff *skb) -+ struct sk_buff *skb, -+ u16 vid) - { - struct sk_buff *skb2; - const struct ipv6hdr *ip6h; - u8 icmp6_type; - u8 nexthdr; -- unsigned len; -+ unsigned int len; - int offset; - int err; - -@@ -1526,8 +1617,14 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, - * - MLD has always Router Alert hop-by-hop option - * - But we do not support jumbrograms. - */ -- if (ip6h->version != 6 || -- ip6h->nexthdr != IPPROTO_HOPOPTS || -+ if (ip6h->version != 6) -+ return 0; -+ -+ /* Prevent flooding this packet if there is no listener present */ -+ if (!ipv6_addr_is_ll_all_nodes(&ip6h->daddr)) -+ BR_INPUT_SKB_CB(skb)->mrouters_only = 1; -+ -+ if (ip6h->nexthdr != IPPROTO_HOPOPTS || - ip6h->payload_len == 0) - return 0; - -@@ -1609,14 +1706,14 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, - } - mld = (struct mld_msg *)skb_transport_header(skb2); - BR_INPUT_SKB_CB(skb)->mrouters_only = 1; -- err = br_ip6_multicast_add_group(br, port, &mld->mld_mca); -+ err = br_ip6_multicast_add_group(br, port, &mld->mld_mca, vid); - break; - } - case ICMPV6_MLD2_REPORT: -- err = br_ip6_multicast_mld2_report(br, port, skb2); -+ err = br_ip6_multicast_mld2_report(br, port, skb2, vid); - break; - case ICMPV6_MGM_QUERY: -- err = br_ip6_multicast_query(br, port, skb2); -+ err = br_ip6_multicast_query(br, port, skb2, vid); - break; - case ICMPV6_MGM_REDUCTION: - { -@@ -1626,7 +1723,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, - goto out; - } - mld = (struct mld_msg *)skb_transport_header(skb2); -- br_ip6_multicast_leave_group(br, port, &mld->mld_mca); -+ br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid); - } - } - -@@ -1637,7 +1734,7 @@ out: - #endif - - int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, -- struct sk_buff *skb) -+ struct sk_buff *skb, u16 vid) - { - BR_INPUT_SKB_CB(skb)->igmp = 0; - BR_INPUT_SKB_CB(skb)->mrouters_only = 0; -@@ -1647,29 +1744,42 @@ int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, - - switch (skb->protocol) { - case htons(ETH_P_IP): -- return br_multicast_ipv4_rcv(br, port, skb); --#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+ return br_multicast_ipv4_rcv(br, port, skb, vid); -+#if IS_ENABLED(CONFIG_IPV6) - case htons(ETH_P_IPV6): -- return br_multicast_ipv6_rcv(br, port, skb); -+ return br_multicast_ipv6_rcv(br, port, skb, vid); - #endif - } - - return 0; - } - --static void br_multicast_query_expired(unsigned long data) -+static void br_multicast_query_expired(struct net_bridge *br, -+ struct bridge_mcast_query *query) -+{ -+ spin_lock(&br->multicast_lock); -+ if (query->startup_sent < br->multicast_startup_query_count) -+ query->startup_sent++; -+ -+ br_multicast_send_query(br, NULL, query); -+ spin_unlock(&br->multicast_lock); -+} -+ -+static void br_ip4_multicast_query_expired(unsigned long data) - { - struct net_bridge *br = (void *)data; - -- spin_lock(&br->multicast_lock); -- if (br->multicast_startup_queries_sent < -- br->multicast_startup_query_count) -- br->multicast_startup_queries_sent++; -+ br_multicast_query_expired(br, &br->ip4_query); -+} - -- br_multicast_send_query(br, NULL, br->multicast_startup_queries_sent); -+#if IS_ENABLED(CONFIG_IPV6) -+static void br_ip6_multicast_query_expired(unsigned long data) -+{ -+ struct net_bridge *br = (void *)data; - -- spin_unlock(&br->multicast_lock); -+ br_multicast_query_expired(br, &br->ip6_query); - } -+#endif - - void br_multicast_init(struct net_bridge *br) - { -@@ -1689,32 +1799,54 @@ void br_multicast_init(struct net_bridge *br) - br->multicast_querier_interval = 255 * HZ; - br->multicast_membership_interval = 260 * HZ; - -- br->multicast_querier_delay_time = 0; -+ br->ip4_querier.delay_time = 0; -+#if IS_ENABLED(CONFIG_IPV6) -+ br->ip6_querier.delay_time = 0; -+#endif - - spin_lock_init(&br->multicast_lock); - setup_timer(&br->multicast_router_timer, - br_multicast_local_router_expired, 0); -- setup_timer(&br->multicast_querier_timer, -- br_multicast_querier_expired, (unsigned long)br); -- setup_timer(&br->multicast_query_timer, br_multicast_query_expired, -+ setup_timer(&br->ip4_querier.timer, br_ip4_multicast_querier_expired, -+ (unsigned long)br); -+ setup_timer(&br->ip4_query.timer, br_ip4_multicast_query_expired, -+ (unsigned long)br); -+#if IS_ENABLED(CONFIG_IPV6) -+ setup_timer(&br->ip6_querier.timer, br_ip6_multicast_querier_expired, - (unsigned long)br); -+ setup_timer(&br->ip6_query.timer, br_ip6_multicast_query_expired, -+ (unsigned long)br); -+#endif - } - --void br_multicast_open(struct net_bridge *br) -+static void __br_multicast_open(struct net_bridge *br, -+ struct bridge_mcast_query *query) - { -- br->multicast_startup_queries_sent = 0; -+ query->startup_sent = 0; - - if (br->multicast_disabled) - return; - -- mod_timer(&br->multicast_query_timer, jiffies); -+ mod_timer(&query->timer, jiffies); -+} -+ -+void br_multicast_open(struct net_bridge *br) -+{ -+ __br_multicast_open(br, &br->ip4_query); -+#if IS_ENABLED(CONFIG_IPV6) -+ __br_multicast_open(br, &br->ip6_query); -+#endif - } - - void br_multicast_stop(struct net_bridge *br) - { - del_timer_sync(&br->multicast_router_timer); -- del_timer_sync(&br->multicast_querier_timer); -- del_timer_sync(&br->multicast_query_timer); -+ del_timer_sync(&br->ip4_querier.timer); -+ del_timer_sync(&br->ip4_query.timer); -+#if IS_ENABLED(CONFIG_IPV6) -+ del_timer_sync(&br->ip6_querier.timer); -+ del_timer_sync(&br->ip6_query.timer); -+#endif - } - - void br_multicast_dev_del(struct net_bridge *br) -@@ -1754,6 +1886,7 @@ void br_multicast_dev_del(struct net_bridge *br) - out: - spin_unlock_bh(&br->multicast_lock); - } -+ - int br_multicast_set_router(struct net_bridge *br, unsigned long val) - { - int err = -ENOENT; -@@ -1785,6 +1918,18 @@ unlock: - return err; - } - -+static void br_multicast_del_grps(struct net_bridge *br) -+{ -+ struct net_bridge_port *port, *bn; -+ struct net_bridge_port_group *pg; -+ struct hlist_node *p, *n; -+ -+ list_for_each_entry_safe(port, bn, &br->port_list, list) { -+ hlist_for_each_entry_safe(pg, p, n, &port->mglist, mglist) -+ br_multicast_del_pg(br, pg); -+ } -+} -+ - int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val) - { - struct net_bridge *br = p->br; -@@ -1830,30 +1975,24 @@ unlock: - return err; - } - --static void br_multicast_start_querier(struct net_bridge *br) -+static void br_multicast_start_querier(struct net_bridge *br, -+ struct bridge_mcast_query *query) - { - struct net_bridge_port *port; - -- br_multicast_open(br); -+ __br_multicast_open(br, query); - - list_for_each_entry(port, &br->port_list, list) { - if (port->state == BR_STATE_DISABLED || - port->state == BR_STATE_BLOCKING) - continue; - -- __br_multicast_enable_port(port); -- } --} -- --static void br_multicast_del_grps(struct net_bridge *br) --{ -- struct net_bridge_port *port, *bn; -- struct net_bridge_port_group *pg; -- struct hlist_node *p, *n; -- -- list_for_each_entry_safe(port, bn, &br->port_list, list) { -- hlist_for_each_entry_safe(pg, p, n, &port->mglist, mglist) -- br_multicast_del_pg(br, pg); -+ if (query == &br->ip4_query) -+ br_multicast_enable(&port->ip4_query); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ br_multicast_enable(&port->ip6_query); -+#endif - } - } - -@@ -1890,7 +2029,10 @@ rollback: - goto rollback; - } - -- br_multicast_start_querier(br); -+ br_multicast_start_querier(br, &br->ip4_query); -+#if IS_ENABLED(CONFIG_IPV6) -+ br_multicast_start_querier(br, &br->ip6_query); -+#endif - - unlock: - spin_unlock_bh(&br->multicast_lock); -@@ -1913,10 +2055,18 @@ int br_multicast_set_querier(struct net_bridge *br, unsigned long val) - goto unlock; - - max_delay = br->multicast_query_response_interval; -- if (!timer_pending(&br->multicast_querier_timer)) -- br->multicast_querier_delay_time = jiffies + max_delay; - -- br_multicast_start_querier(br); -+ if (!timer_pending(&br->ip4_querier.timer)) -+ br->ip4_querier.delay_time = jiffies + max_delay; -+ -+ br_multicast_start_querier(br, &br->ip4_query); -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (!timer_pending(&br->ip6_querier.timer)) -+ br->ip6_querier.delay_time = jiffies + max_delay; -+ -+ br_multicast_start_querier(br, &br->ip6_query); -+#endif - - unlock: - spin_unlock_bh(&br->multicast_lock); -diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c -index a8d96c2..2710379 100644 ---- a/net/bridge/br_netfilter.c -+++ b/net/bridge/br_netfilter.c -@@ -56,14 +56,25 @@ static int brnf_call_ip6tables __read_mostly = 1; - static int brnf_call_arptables __read_mostly = 1; - static int brnf_filter_vlan_tagged __read_mostly = 0; - static int brnf_filter_pppoe_tagged __read_mostly = 0; -+static int brnf_pass_vlan_indev __read_mostly = 0; - #else - #define brnf_call_iptables 1 - #define brnf_call_ip6tables 1 - #define brnf_call_arptables 1 - #define brnf_filter_vlan_tagged 0 - #define brnf_filter_pppoe_tagged 0 -+#define brnf_pass_vlan_indev 0 - #endif - -+#define IS_IP(skb) \ -+ (!vlan_tx_tag_present(skb) && skb->protocol == htons(ETH_P_IP)) -+ -+#define IS_IPV6(skb) \ -+ (!vlan_tx_tag_present(skb) && skb->protocol == htons(ETH_P_IPV6)) -+ -+#define IS_ARP(skb) \ -+ (!vlan_tx_tag_present(skb) && skb->protocol == htons(ETH_P_ARP)) -+ - static inline __be16 vlan_proto(const struct sk_buff *skb) - { - if (vlan_tx_tag_present(skb)) -@@ -106,12 +117,18 @@ static void fake_update_pmtu(struct dst_entry *dst, u32 mtu) - { - } - -+static void fake_redirect(struct dst_entry *dst, struct sock *sk, -+ struct sk_buff *skb) -+{ -+} -+ - static u32 *fake_cow_metrics(struct dst_entry *dst, unsigned long old) - { - return NULL; - } - --static struct neighbour *fake_neigh_lookup(const struct dst_entry *dst, const void *daddr) -+static struct neighbour *fake_neigh_lookup(const struct dst_entry *dst, -+ const void *daddr) - { - return NULL; - } -@@ -125,6 +142,7 @@ static struct dst_ops fake_dst_ops = { - .family = AF_INET, - .protocol = cpu_to_be16(ETH_P_IP), - .update_pmtu = fake_update_pmtu, -+ //.redirect = fake_redirect, - .cow_metrics = fake_cow_metrics, - .neigh_lookup = fake_neigh_lookup, - .mtu = fake_mtu, -@@ -351,19 +369,29 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) - if (!skb->dev) - goto free_skb; - dst = skb_dst(skb); -- neigh = dst_get_neighbour(dst); -- if (neigh->hh.hh_len) { -- neigh_hh_bridge(&neigh->hh, skb); -- skb->dev = nf_bridge->physindev; -- return br_handle_frame_finish(skb); -- } else { -- /* the neighbour function below overwrites the complete -- * MAC header, so we save the Ethernet source address and -- * protocol number. */ -- skb_copy_from_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN), skb->nf_bridge->data, ETH_HLEN-ETH_ALEN); -- /* tell br_dev_xmit to continue with forwarding */ -- nf_bridge->mask |= BRNF_BRIDGED_DNAT; -- return neigh->output(neigh, skb); -+ neigh = dst_neigh_lookup_skb(dst, skb); -+ if (neigh) { -+ int ret; -+ -+ if (neigh->hh.hh_len) { -+ neigh_hh_bridge(&neigh->hh, skb); -+ skb->dev = nf_bridge->physindev; -+ ret = br_handle_frame_finish(skb); -+ } else { -+ /* the neighbour function below overwrites the complete -+ * MAC header, so we save the Ethernet source address and -+ * protocol number. -+ */ -+ skb_copy_from_linear_data_offset(skb, -+ -(ETH_HLEN-ETH_ALEN), -+ skb->nf_bridge->data, -+ ETH_HLEN-ETH_ALEN); -+ /* tell br_dev_xmit to continue with forwarding */ -+ nf_bridge->mask |= BRNF_BRIDGED_DNAT; -+ ret = neigh->output(neigh, skb); -+ } -+ neigh_release(neigh); -+ return ret; - } - free_skb: - kfree_skb(skb); -@@ -483,6 +511,22 @@ bridged_dnat: - return 0; - } - -+#if 0 -+static struct net_device *brnf_get_logical_dev(struct sk_buff *skb, const struct net_device *dev) -+{ -+ struct net_device *vlan, *br; -+ -+ br = bridge_parent(dev); -+ if (brnf_pass_vlan_indev == 0 || !vlan_tx_tag_present(skb)) -+ return br; -+ -+ vlan = __vlan_find_dev_deep(br, skb->vlan_proto, -+ vlan_tx_tag_get(skb) & VLAN_VID_MASK); -+ -+ return vlan ? vlan : br; -+} -+#endif -+ - /* Some common code for IPv4/IPv6 */ - static struct net_device *setup_pre_routing(struct sk_buff *skb) - { -@@ -495,12 +539,15 @@ static struct net_device *setup_pre_routing(struct sk_buff *skb) - - nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING; - nf_bridge->physindev = skb->dev; -+ //skb->dev = brnf_get_logical_dev(skb, skb->dev); - skb->dev = bridge_parent(skb->dev); - if (skb->protocol == htons(ETH_P_8021Q)) - nf_bridge->mask |= BRNF_8021Q; - else if (skb->protocol == htons(ETH_P_PPP_SES)) - nf_bridge->mask |= BRNF_PPPoE; - -+ /* Must drop socket now because of tproxy. */ -+ skb_orphan(skb); - return skb->dev; - } - -@@ -561,7 +608,7 @@ bad: - - /* Replicate the checks that IPv6 does on packet reception and pass the packet - * to ip6tables, which doesn't support NAT, so things are fairly simple. */ --static unsigned int br_nf_pre_routing_ipv6(unsigned int hook, -+static unsigned int br_nf_pre_routing_ipv6(unsigned int hooknum, - struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, -@@ -611,7 +658,8 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook, - * receiving device) to make netfilter happy, the REDIRECT - * target in particular. Save the original destination IP - * address to be able to detect DNAT afterwards. */ --static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb, -+static unsigned int br_nf_pre_routing(unsigned int hooknum, -+ struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) -@@ -628,20 +676,18 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb, - return NF_DROP; - br = p->br; - -- if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) || -- IS_PPPOE_IPV6(skb)) { -+ if (IS_IPV6(skb) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb)) { - if (!brnf_call_ip6tables && !br->nf_call_ip6tables) - return NF_ACCEPT; - - nf_bridge_pull_encap_header_rcsum(skb); -- return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn); -+ return br_nf_pre_routing_ipv6(hooknum, skb, in, out, okfn); - } - - if (!brnf_call_iptables && !br->nf_call_iptables) - return NF_ACCEPT; - -- if (skb->protocol != htons(ETH_P_IP) && !IS_VLAN_IP(skb) && -- !IS_PPPOE_IP(skb)) -+ if (!IS_IP(skb) && !IS_VLAN_IP(skb) && !IS_PPPOE_IP(skb)) - return NF_ACCEPT; - - nf_bridge_pull_encap_header_rcsum(skb); -@@ -671,7 +717,8 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb, - * took place when the packet entered the bridge), but we - * register an IPv4 PRE_ROUTING 'sabotage' hook that will - * prevent this from happening. */ --static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff *skb, -+static unsigned int br_nf_local_in(unsigned int hooknum, -+ struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) -@@ -686,7 +733,7 @@ static int br_nf_forward_finish(struct sk_buff *skb) - struct nf_bridge_info *nf_bridge = skb->nf_bridge; - struct net_device *in; - -- if (skb->protocol != htons(ETH_P_ARP) && !IS_VLAN_ARP(skb)) { -+ if (!IS_ARP(skb) && !IS_VLAN_ARP(skb)) { - in = nf_bridge->physindev; - if (nf_bridge->mask & BRNF_PKT_TYPE) { - skb->pkt_type = PACKET_OTHERHOST; -@@ -703,17 +750,19 @@ static int br_nf_forward_finish(struct sk_buff *skb) - skb->dev, br_hw_forward_finish, 1); - } else { - NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, in, -- skb->dev, br_forward_finish, 1); -+ skb->dev, br_forward_finish, 1); - } - return 0; - } - -+ - /* This is the 'purely bridged' case. For IP, we pass the packet to - * netfilter with indev and outdev set to the bridge device, - * but we are still able to filter on the 'real' indev/outdev - * because of the physdev module. For ARP, indev and outdev are the - * bridge ports. */ --static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb, -+static unsigned int br_nf_forward_ip(unsigned int hooknum, -+ struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) -@@ -734,12 +783,10 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb, - if (!parent) - return NF_DROP; - -- if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb) || -- IS_PPPOE_IP(skb)) -- pf = PF_INET; -- else if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) || -- IS_PPPOE_IPV6(skb)) -- pf = PF_INET6; -+ if (IS_IP(skb) || IS_VLAN_IP(skb) || IS_PPPOE_IP(skb)) -+ pf = NFPROTO_IPV4; -+ else if (IS_IPV6(skb) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb)) -+ pf = NFPROTO_IPV6; - else - return NF_ACCEPT; - -@@ -751,24 +798,26 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb, - nf_bridge->mask |= BRNF_PKT_TYPE; - } - -- if (pf == PF_INET && br_parse_ip_options(skb)) -+ if (pf == NFPROTO_IPV4 && br_parse_ip_options(skb)) - return NF_DROP; - - /* The physdev module checks on this */ - nf_bridge->mask |= BRNF_BRIDGED; - nf_bridge->physoutdev = skb->dev; -- if (pf == PF_INET) -+ if (pf == NFPROTO_IPV4) - skb->protocol = htons(ETH_P_IP); - else - skb->protocol = htons(ETH_P_IPV6); - -+ //NF_HOOK(pf, NF_INET_FORWARD, skb, brnf_get_logical_dev(skb, in), parent, - NF_HOOK(pf, NF_INET_FORWARD, skb, bridge_parent(in), parent, - br_nf_forward_finish); - - return NF_STOLEN; - } - --static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb, -+static unsigned int br_nf_forward_arp(unsigned int hooknum, -+ struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) -@@ -785,7 +834,7 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb, - if (!brnf_call_arptables && !br->nf_call_arptables) - return NF_ACCEPT; - -- if (skb->protocol != htons(ETH_P_ARP)) { -+ if (!IS_ARP(skb)) { - if (!IS_VLAN_ARP(skb)) - return NF_ACCEPT; - nf_bridge_pull_encap_header(skb); -@@ -803,7 +852,7 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb, - return NF_STOLEN; - } - --#if defined(CONFIG_NF_CONNTRACK_IPV4) || defined(CONFIG_NF_CONNTRACK_IPV4_MODULE) -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV4) - static int br_nf_dev_queue_xmit(struct sk_buff *skb) - { - int ret; -@@ -828,7 +877,8 @@ static int br_nf_dev_queue_xmit(struct sk_buff *skb) - #endif - - /* PF_BRIDGE/POST_ROUTING ********************************************/ --static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb, -+static unsigned int br_nf_post_routing(unsigned int hooknum, -+ struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) -@@ -843,12 +893,10 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb, - if (!realoutdev) - return NF_DROP; - -- if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb) || -- IS_PPPOE_IP(skb)) -- pf = PF_INET; -- else if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) || -- IS_PPPOE_IPV6(skb)) -- pf = PF_INET6; -+ if (IS_IP(skb) || IS_VLAN_IP(skb) || IS_PPPOE_IP(skb)) -+ pf = NFPROTO_IPV4; -+ else if (IS_IPV6(skb) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb)) -+ pf = NFPROTO_IPV6; - else - return NF_ACCEPT; - -@@ -861,7 +909,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb, - - nf_bridge_pull_encap_header(skb); - nf_bridge_save_header(skb); -- if (pf == PF_INET) -+ if (pf == NFPROTO_IPV4) - skb->protocol = htons(ETH_P_IP); - else - skb->protocol = htons(ETH_P_IPV6); -@@ -875,7 +923,8 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb, - /* IP/SABOTAGE *****************************************************/ - /* Don't hand locally destined packets to PF_INET(6)/PRE_ROUTING - * for the second time. */ --static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff *skb, -+static unsigned int ip_sabotage_in(unsigned int hooknum, -+ struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) -@@ -894,49 +943,49 @@ static struct nf_hook_ops br_nf_ops[] __read_mostly = { - { - .hook = br_nf_pre_routing, - .owner = THIS_MODULE, -- .pf = PF_BRIDGE, -+ .pf = NFPROTO_BRIDGE, - .hooknum = NF_BR_PRE_ROUTING, - .priority = NF_BR_PRI_BRNF, - }, - { - .hook = br_nf_local_in, - .owner = THIS_MODULE, -- .pf = PF_BRIDGE, -+ .pf = NFPROTO_BRIDGE, - .hooknum = NF_BR_LOCAL_IN, - .priority = NF_BR_PRI_BRNF, - }, - { - .hook = br_nf_forward_ip, - .owner = THIS_MODULE, -- .pf = PF_BRIDGE, -+ .pf = NFPROTO_BRIDGE, - .hooknum = NF_BR_FORWARD, - .priority = NF_BR_PRI_BRNF - 1, - }, - { - .hook = br_nf_forward_arp, - .owner = THIS_MODULE, -- .pf = PF_BRIDGE, -+ .pf = NFPROTO_BRIDGE, - .hooknum = NF_BR_FORWARD, - .priority = NF_BR_PRI_BRNF, - }, - { - .hook = br_nf_post_routing, - .owner = THIS_MODULE, -- .pf = PF_BRIDGE, -+ .pf = NFPROTO_BRIDGE, - .hooknum = NF_BR_POST_ROUTING, - .priority = NF_BR_PRI_LAST, - }, - { - .hook = ip_sabotage_in, - .owner = THIS_MODULE, -- .pf = PF_INET, -+ .pf = NFPROTO_IPV4, - .hooknum = NF_INET_PRE_ROUTING, - .priority = NF_IP_PRI_FIRST, - }, - { - .hook = ip_sabotage_in, - .owner = THIS_MODULE, -- .pf = PF_INET6, -+ .pf = NFPROTO_IPV6, - .hooknum = NF_INET_PRE_ROUTING, - .priority = NF_IP6_PRI_FIRST, - }, -@@ -944,8 +993,8 @@ static struct nf_hook_ops br_nf_ops[] __read_mostly = { - - #ifdef CONFIG_SYSCTL - static --int brnf_sysctl_call_tables(ctl_table * ctl, int write, -- void __user * buffer, size_t * lenp, loff_t * ppos) -+int brnf_sysctl_call_tables(struct ctl_table *ctl, int write, -+ void __user *buffer, size_t *lenp, loff_t *ppos) - { - int ret; - -@@ -956,7 +1005,7 @@ int brnf_sysctl_call_tables(ctl_table * ctl, int write, - return ret; - } - --static ctl_table brnf_table[] = { -+static struct ctl_table brnf_table[] = { - { - .procname = "bridge-nf-call-arptables", - .data = &brnf_call_arptables, -@@ -992,6 +1041,13 @@ static ctl_table brnf_table[] = { - .mode = 0644, - .proc_handler = brnf_sysctl_call_tables, - }, -+ { -+ .procname = "bridge-nf-pass-vlan-input-dev", -+ .data = &brnf_pass_vlan_indev, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = brnf_sysctl_call_tables, -+ }, - { } - }; - -@@ -1016,6 +1072,7 @@ int __init br_netfilter_init(void) - return ret; - } - #ifdef CONFIG_SYSCTL -+ //brnf_sysctl_header = register_net_sysctl(&init_net, "net/bridge", brnf_table); - brnf_sysctl_header = register_sysctl_paths(brnf_path, brnf_table); - if (brnf_sysctl_header == NULL) { - printk(KERN_WARNING -@@ -1033,7 +1090,7 @@ void br_netfilter_fini(void) - { - nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops)); - #ifdef CONFIG_SYSCTL -- unregister_sysctl_table(brnf_sysctl_header); -+ unregister_net_sysctl_table(brnf_sysctl_header); - #endif - dst_entries_destroy(&fake_dst_ops); - } -diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c -index 47f5f56..4fd0735 100644 ---- a/net/bridge/br_netlink.c -+++ b/net/bridge/br_netlink.c -@@ -16,38 +16,86 @@ - #include - #include - #include -+//#include - - #include "br_private.h" - #include "br_private_stp.h" - -+static size_t br_get_link_af_size(const struct net_device *dev); -+ -+static inline size_t br_port_info_size(void) -+{ -+ return nla_total_size(1) /* IFLA_BRPORT_STATE */ -+ + nla_total_size(2) /* IFLA_BRPORT_PRIORITY */ -+ + nla_total_size(4) /* IFLA_BRPORT_COST */ -+ + nla_total_size(1) /* IFLA_BRPORT_MODE */ -+ + nla_total_size(1) /* IFLA_BRPORT_GUARD */ -+ + nla_total_size(1) /* IFLA_BRPORT_PROTECT */ -+ + nla_total_size(1) /* IFLA_BRPORT_FAST_LEAVE */ -+ + nla_total_size(1) /* IFLA_BRPORT_LEARNING */ -+ + nla_total_size(1) /* IFLA_BRPORT_UNICAST_FLOOD */ -+ + 0; -+} -+ - static inline size_t br_nlmsg_size(void) - { - return NLMSG_ALIGN(sizeof(struct ifinfomsg)) -- + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ -- + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ -- + nla_total_size(4) /* IFLA_MASTER */ -- + nla_total_size(4) /* IFLA_MTU */ -- + nla_total_size(4) /* IFLA_LINK */ -- + nla_total_size(1) /* IFLA_OPERSTATE */ -- + nla_total_size(1); /* IFLA_PROTINFO */ -+ + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ -+ + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ -+ + nla_total_size(4) /* IFLA_MASTER */ -+ + nla_total_size(4) /* IFLA_MTU */ -+ + nla_total_size(4) /* IFLA_LINK */ -+ + nla_total_size(1) /* IFLA_OPERSTATE */ -+ + nla_total_size(br_port_info_size()); /* IFLA_PROTINFO */ - } - -+static int br_port_fill_attrs(struct sk_buff *skb, -+ const struct net_bridge_port *p) -+{ -+ u8 mode = !!(p->flags & BR_HAIRPIN_MODE); -+ -+ if (nla_put_u8(skb, IFLA_BRPORT_STATE, p->state) || -+ nla_put_u16(skb, IFLA_BRPORT_PRIORITY, p->priority) || -+ nla_put_u32(skb, IFLA_BRPORT_COST, p->path_cost) || -+ nla_put_u8(skb, IFLA_BRPORT_MODE, mode) || -+ nla_put_u8(skb, IFLA_BRPORT_GUARD, !!(p->flags & BR_BPDU_GUARD)) || -+ nla_put_u8(skb, IFLA_BRPORT_PROTECT, !!(p->flags & BR_ROOT_BLOCK)) || -+ nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE, !!(p->flags & BR_MULTICAST_FAST_LEAVE)) || -+ nla_put_u8(skb, IFLA_BRPORT_LEARNING, !!(p->flags & BR_LEARNING)) || -+ nla_put_u8(skb, IFLA_BRPORT_UNICAST_FLOOD, !!(p->flags & BR_FLOOD))) -+ return -EMSGSIZE; -+ -+ return 0; -+} -+ -+static unsigned long vlan_bmp_copy[BR_VLAN_BITMAP_LEN]; -+static unsigned long untagged_bmp_copy[BR_VLAN_BITMAP_LEN]; -+ - /* - * Create one netlink message for one interface - * Contains port and master info as well as carrier and bridge state. - */ --static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *port, -- u32 pid, u32 seq, int event, unsigned int flags) -+static int br_fill_ifinfo(struct sk_buff *skb, -+ const struct net_bridge_port *port, -+ u32 pid, u32 seq, int event, unsigned int flags, -+ u32 filter_mask, const struct net_device *dev) - { -- const struct net_bridge *br = port->br; -- const struct net_device *dev = port->dev; -+ const struct net_bridge *br; - struct ifinfomsg *hdr; - struct nlmsghdr *nlh; - u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN; - -+ if (port) -+ br = port->br; -+ else -+ br = netdev_priv(dev); -+ - br_debug(br, "br_fill_info event %d port %s master %s\n", - event, dev->name, br->dev->name); - -+ if (!br) -+ return -EMSGSIZE; -+ - nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); - if (nlh == NULL) - return -EMSGSIZE; -@@ -60,20 +108,69 @@ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *por - hdr->ifi_flags = dev_get_flags(dev); - hdr->ifi_change = 0; - -- NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name); -- NLA_PUT_U32(skb, IFLA_MASTER, br->dev->ifindex); -- NLA_PUT_U32(skb, IFLA_MTU, dev->mtu); -- NLA_PUT_U8(skb, IFLA_OPERSTATE, operstate); -- -- if (dev->addr_len) -- NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr); -- -- if (dev->ifindex != dev->iflink) -- NLA_PUT_U32(skb, IFLA_LINK, dev->iflink); -+ if (nla_put_string(skb, IFLA_IFNAME, dev->name) || -+ nla_put_u32(skb, IFLA_MASTER, br->dev->ifindex) || -+ nla_put_u32(skb, IFLA_MTU, dev->mtu) || -+ nla_put_u8(skb, IFLA_OPERSTATE, operstate) || -+ (dev->addr_len && -+ nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) || -+ (dev->ifindex != dev->iflink && -+ nla_put_u32(skb, IFLA_LINK, dev->iflink))) -+ goto nla_put_failure; -+ -+ if (event == RTM_NEWLINK && port) { -+ struct nlattr *nest -+ = nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED); -+ -+ if (nest == NULL || br_port_fill_attrs(skb, port) < 0) -+ goto nla_put_failure; -+ nla_nest_end(skb, nest); -+ } - -- if (event == RTM_NEWLINK) -- NLA_PUT_U8(skb, IFLA_PROTINFO, port->state); -+ /* Check if the VID information is requested */ -+ if (filter_mask & RTEXT_FILTER_BRVLAN) { -+ struct nlattr *af; -+ const struct net_port_vlans *pv; -+ struct bridge_vlan_info vinfo; -+ u16 vid; -+ u16 pvid; -+ -+ memset(vlan_bmp_copy, 0, -+ sizeof(unsigned long) * BR_VLAN_BITMAP_LEN); -+ memset(untagged_bmp_copy, 0, -+ sizeof(unsigned long) * BR_VLAN_BITMAP_LEN); -+ -+ if (port) -+ pv = nbp_get_vlan_info(port); -+ else -+ pv = br_get_vlan_info(br); -+ -+ if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) -+ goto done; -+ -+ af = nla_nest_start(skb, IFLA_AF_SPEC); -+ if (!af) -+ goto nla_put_failure; -+ -+ pvid = br_get_pvid(pv); -+ for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { -+ vinfo.vid = vid; -+ vinfo.flags = 0; -+ if (vid == pvid) -+ vinfo.flags |= BRIDGE_VLAN_INFO_PVID; -+ -+ if (test_bit(vid, pv->untagged_bitmap)) -+ vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED; -+ -+ if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO, -+ sizeof(vinfo), &vinfo)) -+ goto nla_put_failure; -+ } -+ -+ nla_nest_end(skb, af); -+ } - -+done: - return nlmsg_end(skb, nlh); - - nla_put_failure: -@@ -86,18 +183,28 @@ nla_put_failure: - */ - void br_ifinfo_notify(int event, struct net_bridge_port *port) - { -- struct net *net = dev_net(port->dev); -+ struct net *net; - struct sk_buff *skb; - int err = -ENOBUFS; -+ size_t total_size = 0; -+ -+ if (!port) -+ return; - -+ net = dev_net(port->dev); - br_debug(port->br, "port %u(%s) event %d\n", -- (unsigned)port->port_no, port->dev->name, event); -+ (unsigned int)port->port_no, port->dev->name, event); - -- skb = nlmsg_new(br_nlmsg_size(), GFP_ATOMIC); -+ total_size = br_nlmsg_size() + -+ nla_total_size(sizeof(struct nlattr)) + -+ nla_total_size(sizeof(struct nlattr)) + -+ br_get_link_af_size(port->dev); -+ -+ skb = nlmsg_new(total_size, GFP_ATOMIC); - if (skb == NULL) - goto errout; - -- err = br_fill_ifinfo(skb, port, 0, 0, event, 0); -+ err = br_fill_ifinfo(skb, port, 0, 0, event, 0, 0, port->dev); - if (err < 0) { - /* -EMSGSIZE implies BUG in br_nlmsg_size() */ - WARN_ON(err == -EMSGSIZE); -@@ -107,97 +214,257 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port) - rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); - return; - errout: -- if (err < 0) -- rtnl_set_sk_err(net, RTNLGRP_LINK, err); -+ rtnl_set_sk_err(net, RTNLGRP_LINK, err); - } - -+ - /* - * Dump information about all ports, in response to GETLINK - */ --static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) -+int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, -+ struct net_device *dev, u32 filter_mask) - { -- struct net *net = sock_net(skb->sk); -- struct net_device *dev; -- int idx; -- -- idx = 0; -- rcu_read_lock(); -- for_each_netdev_rcu(net, dev) { -- struct net_bridge_port *port = br_port_get_rcu(dev); -- -- /* not a bridge port */ -- if (!port || idx < cb->args[0]) -- goto skip; -- -- if (br_fill_ifinfo(skb, port, -- NETLINK_CB(cb->skb).pid, -- cb->nlh->nlmsg_seq, RTM_NEWLINK, -- NLM_F_MULTI) < 0) -- break; --skip: -- ++idx; -- } -- rcu_read_unlock(); -- cb->args[0] = idx; -+ int err = 0; -+ struct net_bridge_port *port = br_port_get_rtnl(dev); -+ -+ /* not a bridge port and */ -+ if (!port && !(filter_mask & RTEXT_FILTER_BRVLAN)) -+ goto out; - -- return skb->len; -+ err = br_fill_ifinfo(skb, port, pid, seq, RTM_NEWLINK, NLM_F_MULTI, -+ filter_mask, dev); -+out: -+ return err; - } - --/* -- * Change state of port (ie from forwarding to blocking etc) -- * Used by spanning tree in user space. -- */ --static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) -+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 br_afspec(struct net_bridge *br, -+ struct net_bridge_port *p, -+ struct nlattr *af_spec, -+ int cmd) - { -- struct net *net = sock_net(skb->sk); -- struct ifinfomsg *ifm; -- struct nlattr *protinfo; -- struct net_device *dev; -- struct net_bridge_port *p; -- u8 new_state; -+ struct nlattr *tb[IFLA_BRIDGE_MAX+1]; -+ int err = 0; - -- if (nlmsg_len(nlh) < sizeof(*ifm)) -- return -EINVAL; -+ err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, af_spec, ifla_br_policy); -+ if (err) -+ return err; - -- ifm = nlmsg_data(nlh); -- if (ifm->ifi_family != AF_BRIDGE) -- return -EPFNOSUPPORT; -+ if (tb[IFLA_BRIDGE_VLAN_INFO]) { -+ struct bridge_vlan_info *vinfo; - -- protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO); -- if (!protinfo || nla_len(protinfo) < sizeof(u8)) -- return -EINVAL; -+ vinfo = nla_data(tb[IFLA_BRIDGE_VLAN_INFO]); - -- new_state = nla_get_u8(protinfo); -- if (new_state > BR_STATE_BLOCKING) -- return -EINVAL; -+ if (!vinfo->vid || vinfo->vid >= VLAN_VID_MASK) -+ return -EINVAL; - -- dev = __dev_get_by_index(net, ifm->ifi_index); -- if (!dev) -- return -ENODEV; -+ switch (cmd) { -+ case RTM_SETLINK: -+ if (p) { -+ err = nbp_vlan_add(p, vinfo->vid, vinfo->flags); -+ if (err) -+ break; - -- p = br_port_get_rtnl(dev); -- if (!p) -+ if (vinfo->flags & BRIDGE_VLAN_INFO_MASTER) -+ err = br_vlan_add(p->br, vinfo->vid, -+ vinfo->flags); -+ } else -+ err = br_vlan_add(br, vinfo->vid, vinfo->flags); -+ -+ if (err) -+ break; -+ -+ break; -+ -+ case RTM_DELLINK: -+ if (p) { -+ nbp_vlan_delete(p, vinfo->vid); -+ if (vinfo->flags & BRIDGE_VLAN_INFO_MASTER) -+ br_vlan_delete(p->br, vinfo->vid); -+ } else -+ br_vlan_delete(br, vinfo->vid); -+ break; -+ } -+ } -+ -+ return err; -+} -+ -+static const struct nla_policy ifla_brport_policy[IFLA_BRPORT_MAX + 1] = { -+ [IFLA_BRPORT_STATE] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_COST] = { .type = NLA_U32 }, -+ [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 }, -+ [IFLA_BRPORT_MODE] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_GUARD] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 }, -+}; -+ -+/* Change the state of the port and notify spanning tree */ -+static int br_set_port_state(struct net_bridge_port *p, u8 state) -+{ -+ if (state > BR_STATE_BLOCKING) - return -EINVAL; - - /* if kernel STP is running, don't allow changes */ - if (p->br->stp_enabled == BR_KERNEL_STP) - return -EBUSY; - -- if (p->state == new_state) -+ if (p->state == state) - return 0; - -- p->state = new_state; -+ p->state = state; - br_log_state(p); -- -- spin_lock_bh(&p->br->lock); - br_port_state_selection(p->br); -- spin_unlock_bh(&p->br->lock); -+ return 0; -+} - -- br_ifinfo_notify(RTM_NEWLINK, p); -+/* Set/clear or port flags based on attribute */ -+static void br_set_port_flag(struct net_bridge_port *p, struct nlattr *tb[], -+ int attrtype, unsigned long mask) -+{ -+ if (tb[attrtype]) { -+ u8 flag = nla_get_u8(tb[attrtype]); -+ if (flag) -+ p->flags |= mask; -+ else -+ p->flags &= ~mask; -+ } -+} - -+/* Process bridge protocol info on port */ -+static int br_setport(struct net_bridge_port *p, struct nlattr *tb[]) -+{ -+ int err; -+ -+ br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE); -+ br_set_port_flag(p, tb, IFLA_BRPORT_GUARD, BR_BPDU_GUARD); -+ br_set_port_flag(p, tb, IFLA_BRPORT_FAST_LEAVE, BR_MULTICAST_FAST_LEAVE); -+ br_set_port_flag(p, tb, IFLA_BRPORT_PROTECT, BR_ROOT_BLOCK); -+ br_set_port_flag(p, tb, IFLA_BRPORT_LEARNING, BR_LEARNING); -+ br_set_port_flag(p, tb, IFLA_BRPORT_UNICAST_FLOOD, BR_FLOOD); -+ -+ if (tb[IFLA_BRPORT_COST]) { -+ err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST])); -+ if (err) -+ return err; -+ } -+ -+ if (tb[IFLA_BRPORT_PRIORITY]) { -+ err = br_stp_set_port_priority(p, nla_get_u16(tb[IFLA_BRPORT_PRIORITY])); -+ if (err) -+ return err; -+ } -+ -+ if (tb[IFLA_BRPORT_STATE]) { -+ err = br_set_port_state(p, nla_get_u8(tb[IFLA_BRPORT_STATE])); -+ if (err) -+ return err; -+ } - return 0; - } - -+/* Change state and parameters on port. */ -+int br_setlink(struct net_device *dev, struct nlmsghdr *nlh) -+{ -+ struct nlattr *protinfo; -+ struct nlattr *afspec; -+ struct net_bridge_port *p; -+ struct nlattr *tb[IFLA_BRPORT_MAX + 1]; -+ int err = 0; -+ -+ protinfo = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_PROTINFO); -+ afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); -+ if (!protinfo && !afspec) -+ return 0; -+ -+ p = br_port_get_rtnl(dev); -+ /* We want to accept dev as bridge itself if the AF_SPEC -+ * is set to see if someone is setting vlan info on the bridge -+ */ -+ if (!p && !afspec) -+ return -EINVAL; -+ -+ if (p && protinfo) { -+ if (protinfo->nla_type & NLA_F_NESTED) { -+ err = nla_parse_nested(tb, IFLA_BRPORT_MAX, -+ protinfo, ifla_brport_policy); -+ if (err) -+ return err; -+ -+ spin_lock_bh(&p->br->lock); -+ err = br_setport(p, tb); -+ spin_unlock_bh(&p->br->lock); -+ } else { -+ /* Binary compatibility with old RSTP */ -+ if (nla_len(protinfo) < sizeof(u8)) -+ return -EINVAL; -+ -+ spin_lock_bh(&p->br->lock); -+ err = br_set_port_state(p, nla_get_u8(protinfo)); -+ spin_unlock_bh(&p->br->lock); -+ } -+ if (err) -+ goto out; -+ } -+ -+ if (afspec) { -+ err = br_afspec((struct net_bridge *)netdev_priv(dev), p, -+ afspec, RTM_SETLINK); -+ } -+ -+ if (err == 0) -+ br_ifinfo_notify(RTM_NEWLINK, p); -+ -+out: -+ return err; -+} -+ -+/* Delete port information */ -+int br_dellink(struct net_device *dev, struct nlmsghdr *nlh) -+{ -+ struct nlattr *afspec; -+ struct net_bridge_port *p; -+ int err; -+ -+ afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); -+ if (!afspec) -+ return 0; -+ -+ p = br_port_get_rtnl(dev); -+ /* We want to accept dev as bridge itself as well */ -+ if (!p && !(dev->priv_flags & IFF_EBRIDGE)) -+ return -EINVAL; -+ -+ err = br_afspec((struct net_bridge *)netdev_priv(dev), p, -+ afspec, RTM_DELLINK); -+ -+ return err; -+} -+ -+/* XXX this is deprecated in upstream, double check if really need it -+static int br_dev_newlink(struct net *src_net, struct net_device *dev, -+ struct nlattr *tb[], struct nlattr *data[]) -+{ -+ struct net_bridge *br = netdev_priv(dev); -+ -+ if (tb[IFLA_ADDRESS]) { -+ spin_lock_bh(&br->lock); -+ br_stp_change_bridge_id(br, nla_data(tb[IFLA_ADDRESS])); -+ spin_unlock_bh(&br->lock); -+ } -+ -+ return register_netdevice(dev); -+} -+*/ -+ - static int br_validate(struct nlattr *tb[], struct nlattr *data[]) - { - if (tb[IFLA_ADDRESS]) { -@@ -210,26 +477,35 @@ static int br_validate(struct nlattr *tb[], struct nlattr *data[]) - return 0; - } - --static int br_dev_newlink(struct net *src_net, struct net_device *dev, -- struct nlattr *tb[], struct nlattr *data[]) -+static size_t br_get_link_af_size(const struct net_device *dev) - { -- struct net_bridge *br = netdev_priv(dev); -+ struct net_port_vlans *pv; - -- if (tb[IFLA_ADDRESS]) { -- spin_lock_bh(&br->lock); -- br_stp_change_bridge_id(br, nla_data(tb[IFLA_ADDRESS])); -- spin_unlock_bh(&br->lock); -- } -+ if (br_port_exists(dev)) -+ pv = nbp_get_vlan_info(br_port_get_rtnl(dev)); -+ else if (dev->priv_flags & IFF_EBRIDGE) -+ pv = br_get_vlan_info((struct net_bridge *)netdev_priv(dev)); -+ else -+ return 0; -+ -+ if (!pv) -+ return 0; - -- return register_netdevice(dev); -+ /* Each VLAN is returned in bridge_vlan_info along with flags */ -+ return pv->num_vlans * nla_total_size(sizeof(struct bridge_vlan_info)); - } - -+static struct rtnl_af_ops br_af_ops = { -+ .family = AF_BRIDGE, -+ .get_link_af_size = br_get_link_af_size, -+}; -+ - struct rtnl_link_ops br_link_ops __read_mostly = { - .kind = "bridge", - .priv_size = sizeof(struct net_bridge), - .setup = br_dev_setup, - .validate = br_validate, -- .newlink = br_dev_newlink, -+ //.newlink = br_dev_newlink, - .dellink = br_dev_delete, - }; - -@@ -238,31 +514,23 @@ int __init br_netlink_init(void) - int err; - - br_mdb_init(); -- err = rtnl_link_register(&br_link_ops); -- if (err < 0) -- goto err1; -+ rtnl_af_register(&br_af_ops); - -- err = __rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, -- br_dump_ifinfo, NULL); -- if (err) -- goto err2; -- err = __rtnl_register(PF_BRIDGE, RTM_SETLINK, -- br_rtm_setlink, NULL, NULL); -+ err = rtnl_link_register(&br_link_ops); - if (err) -- goto err3; -+ goto out_af; - - return 0; - --err3: -- rtnl_unregister_all(PF_BRIDGE); --err2: -- rtnl_link_unregister(&br_link_ops); --err1: -+out_af: -+ rtnl_af_unregister(&br_af_ops); - br_mdb_uninit(); - return err; - } - - void __exit br_netlink_fini(void) - { -+ br_mdb_uninit(); -+ rtnl_af_unregister(&br_af_ops); - rtnl_link_unregister(&br_link_ops); - } -diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c -index a76b621..7800ad8 100644 ---- a/net/bridge/br_notify.c -+++ b/net/bridge/br_notify.c -@@ -82,7 +82,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v - break; - - case NETDEV_UP: -- if (netif_carrier_ok(dev) && (br->dev->flags & IFF_UP)) { -+ if (netif_running(br->dev) && netif_oper_up(dev)) { - spin_lock_bh(&br->lock); - br_stp_enable_port(p); - spin_unlock_bh(&br->lock); -@@ -102,6 +102,11 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v - case NETDEV_PRE_TYPE_CHANGE: - /* Forbid underlaying device to change its type. */ - return NOTIFY_BAD; -+ -+ case NETDEV_RESEND_IGMP: -+ /* Propagate to master device */ -+ call_netdevice_notifiers(event, br->dev); -+ break; - } - - /* Events that may cause spanning tree to refresh */ -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 5c2b927..9699fdf 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - - #define BR_HASH_BITS 8 - #define BR_HASH_SIZE (1 << BR_HASH_BITS) -@@ -26,6 +27,7 @@ - - #define BR_PORT_BITS 10 - #define BR_MAX_PORTS (1<priv_flags & IFF_BRIDGE_PORT) - - static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev) - { -- struct net_bridge_port *port = rcu_dereference(dev->rx_handler_data); -- return br_port_exists(dev) ? port : NULL; -+ return rcu_dereference(dev->rx_handler_data); - } - --static inline struct net_bridge_port *br_port_get_rtnl(struct net_device *dev) -+static inline struct net_bridge_port *br_port_get_rtnl(const struct net_device *dev) - { - return br_port_exists(dev) ? - rtnl_dereference(dev->rx_handler_data) : NULL; - } - --struct br_cpu_netstats { -- u64 rx_packets; -- u64 rx_bytes; -- u64 tx_packets; -- u64 tx_bytes; -- struct u64_stats_sync syncp; --}; -- - struct net_bridge - { - spinlock_t lock; - struct list_head port_list; - struct net_device *dev; - -- struct br_cpu_netstats __percpu *stats; -+ struct pcpu_sw_netstats __percpu *stats; - spinlock_t hash_lock; - struct hlist_head hash[BR_HASH_SIZE]; - #ifdef CONFIG_BRIDGE_NETFILTER -@@ -197,9 +225,6 @@ struct net_bridge - bool nf_call_ip6tables; - bool nf_call_arptables; - #endif -- unsigned long flags; --#define BR_SET_MAC_ADDR 0x00000001 -- - u16 group_fwd_mask; - - /* STP */ -@@ -237,7 +262,6 @@ struct net_bridge - u32 hash_max; - - u32 multicast_last_member_count; -- u32 multicast_startup_queries_sent; - u32 multicast_startup_query_count; - - unsigned long multicast_last_member_interval; -@@ -246,15 +270,19 @@ struct net_bridge - unsigned long multicast_query_interval; - unsigned long multicast_query_response_interval; - unsigned long multicast_startup_query_interval; -- unsigned long multicast_querier_delay_time; - - spinlock_t multicast_lock; - struct net_bridge_mdb_htable __rcu *mdb; - struct hlist_head router_list; - - struct timer_list multicast_router_timer; -- struct timer_list multicast_querier_timer; -- struct timer_list multicast_query_timer; -+ struct timer_list multicast_querier_timer; -+ struct bridge_mcast_querier ip4_querier; -+ struct bridge_mcast_query ip4_query; -+#if IS_ENABLED(CONFIG_IPV6) -+ struct bridge_mcast_querier ip6_querier; -+ struct bridge_mcast_query ip6_query; -+#endif /* IS_ENABLED(CONFIG_IPV6) */ - #endif - - struct timer_list hello_timer; -@@ -262,6 +290,10 @@ struct net_bridge - struct timer_list topology_change_timer; - struct timer_list gc_timer; - struct kobject *ifobj; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ u8 vlan_enabled; -+ struct net_port_vlans __rcu *vlan_info; -+#endif - }; - - struct br_input_skb_cb { -@@ -296,7 +328,6 @@ struct br_input_skb_cb { - pr_debug("%s: " format, (br)->dev->name, ##args) - - extern struct notifier_block br_device_notifier; --extern const u8 br_group_address[ETH_ALEN]; - - /* called under bridge lock */ - static inline int br_is_root_bridge(const struct net_bridge *br) -@@ -305,16 +336,10 @@ static inline int br_is_root_bridge(const struct net_bridge *br) - } - - /* br_device.c */ --extern void br_dev_setup(struct net_device *dev); --extern void br_dev_delete(struct net_device *dev, struct list_head *list); --extern netdev_tx_t br_dev_xmit(struct sk_buff *skb, -- struct net_device *dev); -+void br_dev_setup(struct net_device *dev); -+void br_dev_delete(struct net_device *dev, struct list_head *list); -+netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev); - #ifdef CONFIG_NET_POLL_CONTROLLER --static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br) --{ -- return br->dev->npinfo; --} -- - static inline void br_netpoll_send_skb(const struct net_bridge_port *p, - struct sk_buff *skb) - { -@@ -324,20 +349,15 @@ static inline void br_netpoll_send_skb(const struct net_bridge_port *p, - netpoll_send_skb(np, skb); - } - --extern int br_netpoll_enable(struct net_bridge_port *p); --extern void br_netpoll_disable(struct net_bridge_port *p); -+int br_netpoll_enable(struct net_bridge_port *p); -+void br_netpoll_disable(struct net_bridge_port *p); - #else --static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br) --{ -- return NULL; --} -- - static inline void br_netpoll_send_skb(const struct net_bridge_port *p, - struct sk_buff *skb) - { - } - --static inline int br_netpoll_enable(struct net_bridge_port *p) -+static inline int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp) - { - return 0; - } -@@ -348,128 +368,117 @@ static inline void br_netpoll_disable(struct net_bridge_port *p) - #endif - - /* br_fdb.c */ --extern int br_fdb_init(void); --extern void br_fdb_fini(void); --extern void br_fdb_flush(struct net_bridge *br); --extern void br_fdb_changeaddr(struct net_bridge_port *p, -- const unsigned char *newaddr); --extern void br_fdb_cleanup(unsigned long arg); --extern void br_fdb_delete_by_port(struct net_bridge *br, -- const struct net_bridge_port *p, int do_all); --extern struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br, -- const unsigned char *addr); --extern int br_fdb_test_addr(struct net_device *dev, unsigned char *addr); --extern int br_fdb_fillbuf(struct net_bridge *br, void *buf, -- unsigned long count, unsigned long off); --extern int br_fdb_insert(struct net_bridge *br, -- struct net_bridge_port *source, -- const unsigned char *addr); --extern void br_fdb_update(struct net_bridge *br, -- struct net_bridge_port *source, -- const unsigned char *addr); --extern int br_fdb_delete(struct ndmsg *ndm, -- struct net_device *dev, -- const unsigned char *addr); --extern int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], -- struct net_device *dev, -- const unsigned char *addr, -- u16 nlh_flags); --extern int br_fdb_dump(struct sk_buff *skb, -- struct netlink_callback *cb, -- struct net_device *dev, -- int idx); -- -+int br_fdb_init(void); -+void br_fdb_fini(void); -+void br_fdb_flush(struct net_bridge *br); -+void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr); -+void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr); -+void br_fdb_cleanup(unsigned long arg); -+void br_fdb_delete_by_port(struct net_bridge *br, -+ const struct net_bridge_port *p, int do_all); -+struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br, -+ const unsigned char *addr, __u16 vid); -+int br_fdb_test_addr(struct net_device *dev, unsigned char *addr); -+int br_fdb_fillbuf(struct net_bridge *br, void *buf, unsigned long count, -+ unsigned long off); -+int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source, -+ const unsigned char *addr, u16 vid); -+void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, -+ const unsigned char *addr, u16 vid); -+int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr, u16 vid); -+ -+int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], -+ struct net_device *dev, const unsigned char *addr); -+int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev, -+ const unsigned char *addr, u16 nlh_flags); -+int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, -+ struct net_device *dev, int idx); - - /* br_forward.c */ --extern void br_deliver(const struct net_bridge_port *to, -- struct sk_buff *skb); --extern int br_dev_queue_push_xmit(struct sk_buff *skb); --extern void br_forward(const struct net_bridge_port *to, -+void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb); -+int br_dev_queue_push_xmit(struct sk_buff *skb); -+void br_forward(const struct net_bridge_port *to, - struct sk_buff *skb, struct sk_buff *skb0); --extern int br_forward_finish(struct sk_buff *skb); --extern int br_hw_forward_finish(struct sk_buff *skb); -- --extern void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb); --extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, -- struct sk_buff *skb2); -+int br_forward_finish(struct sk_buff *skb); -+void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb, bool unicast); -+void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, -+ struct sk_buff *skb2, bool unicast); -+int br_hw_forward_finish(struct sk_buff *skb); - - /* br_if.c */ --extern void br_port_carrier_check(struct net_bridge_port *p); --extern int br_add_bridge(struct net *net, const char *name); --extern int br_del_bridge(struct net *net, const char *name); --extern void br_net_exit(struct net *net); --extern int br_add_if(struct net_bridge *br, -- struct net_device *dev); --extern int br_del_if(struct net_bridge *br, -- struct net_device *dev); --extern int br_min_mtu(const struct net_bridge *br); --extern u32 br_features_recompute(struct net_bridge *br, u32 features); -+void br_port_carrier_check(struct net_bridge_port *p); -+int br_add_bridge(struct net *net, const char *name); -+int br_del_bridge(struct net *net, const char *name); -+int br_add_if(struct net_bridge *br, struct net_device *dev); -+int br_del_if(struct net_bridge *br, struct net_device *dev); -+int br_min_mtu(const struct net_bridge *br); -+netdev_features_t br_features_recompute(struct net_bridge *br, -+ netdev_features_t features); - - /* br_input.c */ --extern int br_handle_frame_finish(struct sk_buff *skb); --extern rx_handler_result_t br_handle_frame(struct sk_buff **pskb); -+int br_handle_frame_finish(struct sk_buff *skb); -+rx_handler_result_t br_handle_frame(struct sk_buff **pskb); -+ -+static inline bool br_rx_handler_check_rcu(const struct net_device *dev) -+{ -+ return rcu_dereference(dev->rx_handler) == br_handle_frame; -+} -+ -+static inline struct net_bridge_port *br_port_get_check_rcu(const struct net_device *dev) -+{ -+ return br_rx_handler_check_rcu(dev) ? br_port_get_rcu(dev) : NULL; -+} - - /* br_ioctl.c */ --extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); --extern int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *arg); -+int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -+int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, -+ void __user *arg); - - /* br_multicast.c */ - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - extern unsigned int br_mdb_rehash_seq; --extern int br_multicast_rcv(struct net_bridge *br, -- struct net_bridge_port *port, -- struct sk_buff *skb); --extern struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, -- struct sk_buff *skb); --extern void br_multicast_add_port(struct net_bridge_port *port); --extern void br_multicast_del_port(struct net_bridge_port *port); --extern void br_multicast_enable_port(struct net_bridge_port *port); --extern void br_multicast_disable_port(struct net_bridge_port *port); --extern void br_multicast_init(struct net_bridge *br); --extern void br_multicast_open(struct net_bridge *br); --extern void br_multicast_stop(struct net_bridge *br); --extern void br_multicast_dev_del(struct net_bridge *br); --extern void br_multicast_deliver(struct net_bridge_mdb_entry *mdst, -- struct sk_buff *skb); --extern void br_multicast_forward(struct net_bridge_mdb_entry *mdst, -- struct sk_buff *skb, struct sk_buff *skb2); --extern int br_multicast_set_router(struct net_bridge *br, unsigned long val); --extern int br_multicast_set_port_router(struct net_bridge_port *p, -- unsigned long val); --extern int br_multicast_toggle(struct net_bridge *br, unsigned long val); --extern int br_multicast_set_querier(struct net_bridge *br, unsigned long val); --extern int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val); --extern struct net_bridge_mdb_entry *br_mdb_ip_get( -- struct net_bridge_mdb_htable *mdb, -- struct br_ip *dst); --extern struct net_bridge_mdb_entry *br_multicast_new_group(struct net_bridge *br, -- struct net_bridge_port *port, struct br_ip *group); --extern void br_multicast_free_pg(struct rcu_head *head); --extern struct net_bridge_port_group *br_multicast_new_port_group( -- struct net_bridge_port *port, -- struct br_ip *group, -- struct net_bridge_port_group __rcu *next, -- unsigned char state); --extern void br_mdb_init(void); --extern void br_mdb_uninit(void); --extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, -- struct br_ip *group, int type, u8 state); -+int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, -+ struct sk_buff *skb, u16 vid); -+struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, -+ struct sk_buff *skb, u16 vid); -+void br_multicast_add_port(struct net_bridge_port *port); -+void br_multicast_del_port(struct net_bridge_port *port); -+void br_multicast_enable_port(struct net_bridge_port *port); -+void br_multicast_disable_port(struct net_bridge_port *port); -+void br_multicast_init(struct net_bridge *br); -+void br_multicast_open(struct net_bridge *br); -+void br_multicast_stop(struct net_bridge *br); -+void br_multicast_dev_del(struct net_bridge *br); -+void br_multicast_deliver(struct net_bridge_mdb_entry *mdst, -+ struct sk_buff *skb); -+void br_multicast_forward(struct net_bridge_mdb_entry *mdst, -+ struct sk_buff *skb, struct sk_buff *skb2); -+int br_multicast_set_router(struct net_bridge *br, unsigned long val); -+int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val); -+int br_multicast_toggle(struct net_bridge *br, unsigned long val); -+int br_multicast_set_querier(struct net_bridge *br, unsigned long val); -+int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val); -+struct net_bridge_mdb_entry * -+br_mdb_ip_get(struct net_bridge_mdb_htable *mdb, struct br_ip *dst); -+struct net_bridge_mdb_entry * -+br_multicast_new_group(struct net_bridge *br, struct net_bridge_port *port, -+ struct br_ip *group); -+void br_multicast_free_pg(struct rcu_head *head); -+struct net_bridge_port_group * -+br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group, -+ struct net_bridge_port_group __rcu *next, -+ unsigned char state); -+void br_mdb_init(void); -+void br_mdb_uninit(void); -+void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, -+ struct br_ip *group, int type, u8 state); -+ - extern void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, - int type); - - #define mlock_dereference(X, br) \ - rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) - --#if IS_ENABLED(CONFIG_IPV6) --#include --static inline int ipv6_is_transient_multicast(const struct in6_addr *addr) --{ -- if (ipv6_addr_is_multicast(addr) && IPV6_ADDR_MC_FLAG_TRANSIENT(addr)) -- return 1; -- return 0; --} --#endif -- - static inline bool br_multicast_is_router(struct net_bridge *br) - { - return br->multicast_router == 2 || -@@ -477,22 +486,39 @@ static inline bool br_multicast_is_router(struct net_bridge *br) - timer_pending(&br->multicast_router_timer)); - } - --static inline bool br_multicast_querier_exists(struct net_bridge *br) -+static inline bool -+__br_multicast_querier_exists(struct net_bridge *br, -+ struct bridge_mcast_querier *querier) - { -- return time_is_before_jiffies(br->multicast_querier_delay_time) && -- (br->multicast_querier || -- timer_pending(&br->multicast_querier_timer)); -+ return time_is_before_jiffies(querier->delay_time) && -+ (br->multicast_querier || timer_pending(&querier->timer)); -+} -+ -+static inline bool br_multicast_querier_exists(struct net_bridge *br, -+ struct ethhdr *eth) -+{ -+ switch (eth->h_proto) { -+ case (htons(ETH_P_IP)): -+ return __br_multicast_querier_exists(br, &br->ip4_querier); -+#if IS_ENABLED(CONFIG_IPV6) -+ case (htons(ETH_P_IPV6)): -+ return __br_multicast_querier_exists(br, &br->ip6_querier); -+#endif -+ default: -+ return false; -+ } - } - #else - static inline int br_multicast_rcv(struct net_bridge *br, - struct net_bridge_port *port, -- struct sk_buff *skb) -+ struct sk_buff *skb, -+ u16 vid) - { - return 0; - } - - static inline struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, -- struct sk_buff *skb) -+ struct sk_buff *skb, u16 vid) - { - return NULL; - } -@@ -539,7 +565,8 @@ static inline bool br_multicast_is_router(struct net_bridge *br) - { - return 0; - } --static inline bool br_multicast_querier_exists(struct net_bridge *br) -+static inline bool br_multicast_querier_exists(struct net_bridge *br, -+ struct ethhdr *eth) - { - return false; - } -@@ -551,82 +578,216 @@ static inline void br_mdb_uninit(void) - } - #endif - -+/* br_vlan.c */ -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, -+ struct sk_buff *skb, u16 *vid); -+bool br_allowed_egress(struct net_bridge *br, const struct net_port_vlans *v, -+ const struct sk_buff *skb); -+struct sk_buff *br_handle_vlan(struct net_bridge *br, -+ const struct net_port_vlans *v, -+ struct sk_buff *skb); -+int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags); -+int br_vlan_delete(struct net_bridge *br, u16 vid); -+void br_vlan_flush(struct net_bridge *br); -+int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val); -+int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags); -+int nbp_vlan_delete(struct net_bridge_port *port, u16 vid); -+void nbp_vlan_flush(struct net_bridge_port *port); -+bool nbp_vlan_find(struct net_bridge_port *port, u16 vid); -+ -+static inline struct net_port_vlans *br_get_vlan_info( -+ const struct net_bridge *br) -+{ -+ return rcu_dereference_rtnl(br->vlan_info); -+} -+ -+static inline struct net_port_vlans *nbp_get_vlan_info( -+ const struct net_bridge_port *p) -+{ -+ return rcu_dereference_rtnl(p->vlan_info); -+} -+ -+/* Since bridge now depends on 8021Q module, but the time bridge sees the -+ * skb, the vlan tag will always be present if the frame was tagged. -+ */ -+static inline int br_vlan_get_tag(const struct sk_buff *skb, u16 *vid) -+{ -+ int err = 0; -+ -+ if (vlan_tx_tag_present(skb)) -+ *vid = vlan_tx_tag_get(skb) & VLAN_VID_MASK; -+ else { -+ *vid = 0; -+ err = -EINVAL; -+ } -+ -+ return err; -+} -+ -+static inline u16 br_get_pvid(const struct net_port_vlans *v) -+{ -+ /* Return just the VID if it is set, or VLAN_N_VID (invalid vid) if -+ * vid wasn't set -+ */ -+ smp_rmb(); -+ return v->pvid ?: VLAN_N_VID; -+} -+ -+#else -+static inline bool br_allowed_ingress(struct net_bridge *br, -+ struct net_port_vlans *v, -+ struct sk_buff *skb, -+ u16 *vid) -+{ -+ return true; -+} -+ -+static inline bool br_allowed_egress(struct net_bridge *br, -+ const struct net_port_vlans *v, -+ const struct sk_buff *skb) -+{ -+ return true; -+} -+ -+static inline struct sk_buff *br_handle_vlan(struct net_bridge *br, -+ const struct net_port_vlans *v, -+ struct sk_buff *skb) -+{ -+ return skb; -+} -+ -+static inline int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int br_vlan_delete(struct net_bridge *br, u16 vid) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline void br_vlan_flush(struct net_bridge *br) -+{ -+} -+ -+static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int nbp_vlan_delete(struct net_bridge_port *port, u16 vid) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline void nbp_vlan_flush(struct net_bridge_port *port) -+{ -+} -+ -+static inline struct net_port_vlans *br_get_vlan_info( -+ const struct net_bridge *br) -+{ -+ return NULL; -+} -+static inline struct net_port_vlans *nbp_get_vlan_info( -+ const struct net_bridge_port *p) -+{ -+ return NULL; -+} -+ -+static inline bool nbp_vlan_find(struct net_bridge_port *port, u16 vid) -+{ -+ return false; -+} -+ -+static inline u16 br_vlan_get_tag(const struct sk_buff *skb, u16 *tag) -+{ -+ return 0; -+} -+static inline u16 br_get_pvid(const struct net_port_vlans *v) -+{ -+ return VLAN_N_VID; /* Returns invalid vid */ -+} -+#endif -+ - /* br_netfilter.c */ - #ifdef CONFIG_BRIDGE_NETFILTER --extern int br_netfilter_init(void); --extern void br_netfilter_fini(void); --extern void br_netfilter_rtable_init(struct net_bridge *); -+int br_netfilter_init(void); -+void br_netfilter_fini(void); -+void br_netfilter_rtable_init(struct net_bridge *); - #else - #define br_netfilter_init() (0) --#define br_netfilter_fini() do { } while(0) -+#define br_netfilter_fini() do { } while (0) - #define br_netfilter_rtable_init(x) - #endif - - /* br_stp.c */ --extern void br_log_state(const struct net_bridge_port *p); --extern struct net_bridge_port *br_get_port(struct net_bridge *br, -- u16 port_no); --extern void br_init_port(struct net_bridge_port *p); --extern void br_become_designated_port(struct net_bridge_port *p); -+void br_log_state(const struct net_bridge_port *p); -+struct net_bridge_port *br_get_port(struct net_bridge *br, u16 port_no); -+void br_init_port(struct net_bridge_port *p); -+void br_become_designated_port(struct net_bridge_port *p); - --extern int br_set_forward_delay(struct net_bridge *br, unsigned long x); --extern int br_set_hello_time(struct net_bridge *br, unsigned long x); --extern int br_set_max_age(struct net_bridge *br, unsigned long x); -+void __br_set_forward_delay(struct net_bridge *br, unsigned long t); -+int br_set_forward_delay(struct net_bridge *br, unsigned long x); -+int br_set_hello_time(struct net_bridge *br, unsigned long x); -+int br_set_max_age(struct net_bridge *br, unsigned long x); - - - /* br_stp_if.c */ --extern void br_stp_enable_bridge(struct net_bridge *br); --extern void br_stp_disable_bridge(struct net_bridge *br); --extern void br_stp_set_enabled(struct net_bridge *br, unsigned long val); --extern void br_stp_enable_port(struct net_bridge_port *p); --extern void br_stp_disable_port(struct net_bridge_port *p); --extern bool br_stp_recalculate_bridge_id(struct net_bridge *br); --extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a); --extern void br_stp_set_bridge_priority(struct net_bridge *br, -- u16 newprio); --extern int br_stp_set_port_priority(struct net_bridge_port *p, -- unsigned long newprio); --extern int br_stp_set_path_cost(struct net_bridge_port *p, -- unsigned long path_cost); --extern ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id); -+void br_stp_enable_bridge(struct net_bridge *br); -+void br_stp_disable_bridge(struct net_bridge *br); -+void br_stp_set_enabled(struct net_bridge *br, unsigned long val); -+void br_stp_enable_port(struct net_bridge_port *p); -+void br_stp_disable_port(struct net_bridge_port *p); -+bool br_stp_recalculate_bridge_id(struct net_bridge *br); -+void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a); -+void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio); -+int br_stp_set_port_priority(struct net_bridge_port *p, unsigned long newprio); -+int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost); -+ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id); - - /* br_stp_bpdu.c */ - struct stp_proto; --extern void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, -- struct net_device *dev); -+void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, -+ struct net_device *dev); - - /* br_stp_timer.c */ --extern void br_stp_timer_init(struct net_bridge *br); --extern void br_stp_port_timer_init(struct net_bridge_port *p); --extern unsigned long br_timer_value(const struct timer_list *timer); -+void br_stp_timer_init(struct net_bridge *br); -+void br_stp_port_timer_init(struct net_bridge_port *p); -+unsigned long br_timer_value(const struct timer_list *timer); - - /* br.c */ --#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) -+#if IS_ENABLED(CONFIG_ATM_LANE) - extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr); - #endif - - /* br_netlink.c */ - extern struct rtnl_link_ops br_link_ops; --extern int br_netlink_init(void); --extern void br_netlink_fini(void); --extern void br_ifinfo_notify(int event, struct net_bridge_port *port); -+int br_netlink_init(void); -+void br_netlink_fini(void); -+void br_ifinfo_notify(int event, struct net_bridge_port *port); -+int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg); -+int br_dellink(struct net_device *dev, struct nlmsghdr *nlmsg); -+int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, struct net_device *dev, -+ u32 filter_mask); - - #ifdef CONFIG_SYSFS - /* br_sysfs_if.c */ - extern const struct sysfs_ops brport_sysfs_ops; --extern int br_sysfs_addif(struct net_bridge_port *p); --extern int br_sysfs_renameif(struct net_bridge_port *p); -+int br_sysfs_addif(struct net_bridge_port *p); -+int br_sysfs_renameif(struct net_bridge_port *p); - - /* br_sysfs_br.c */ --extern int br_sysfs_addbr(struct net_device *dev); --extern void br_sysfs_delbr(struct net_device *dev); -+int br_sysfs_addbr(struct net_device *dev); -+void br_sysfs_delbr(struct net_device *dev); - - #else - --#define br_sysfs_addif(p) (0) --#define br_sysfs_renameif(p) (0) --#define br_sysfs_addbr(dev) (0) --#define br_sysfs_delbr(dev) do { } while(0) -+static inline int br_sysfs_addif(struct net_bridge_port *p) { return 0; } -+static inline int br_sysfs_renameif(struct net_bridge_port *p) { return 0; } -+static inline int br_sysfs_addbr(struct net_device *dev) { return 0; } -+static inline void br_sysfs_delbr(struct net_device *dev) { return; } - #endif /* CONFIG_SYSFS */ - - #endif -diff --git a/net/bridge/br_private_stp.h b/net/bridge/br_private_stp.h -index 05ed9bc..2fe910c 100644 ---- a/net/bridge/br_private_stp.h -+++ b/net/bridge/br_private_stp.h -@@ -29,10 +29,9 @@ - #define BR_MIN_PATH_COST 1 - #define BR_MAX_PATH_COST 65535 - --struct br_config_bpdu --{ -- unsigned topology_change:1; -- unsigned topology_change_ack:1; -+struct br_config_bpdu { -+ unsigned int topology_change:1; -+ unsigned int topology_change_ack:1; - bridge_id root; - int root_path_cost; - bridge_id bridge_id; -@@ -52,19 +51,19 @@ static inline int br_is_designated_port(const struct net_bridge_port *p) - - - /* br_stp.c */ --extern void br_become_root_bridge(struct net_bridge *br); --extern void br_config_bpdu_generation(struct net_bridge *); --extern void br_configuration_update(struct net_bridge *); --extern void br_port_state_selection(struct net_bridge *); --extern void br_received_config_bpdu(struct net_bridge_port *p, -- const struct br_config_bpdu *bpdu); --extern void br_received_tcn_bpdu(struct net_bridge_port *p); --extern void br_transmit_config(struct net_bridge_port *p); --extern void br_transmit_tcn(struct net_bridge *br); --extern void br_topology_change_detection(struct net_bridge *br); -+void br_become_root_bridge(struct net_bridge *br); -+void br_config_bpdu_generation(struct net_bridge *); -+void br_configuration_update(struct net_bridge *); -+void br_port_state_selection(struct net_bridge *); -+void br_received_config_bpdu(struct net_bridge_port *p, -+ const struct br_config_bpdu *bpdu); -+void br_received_tcn_bpdu(struct net_bridge_port *p); -+void br_transmit_config(struct net_bridge_port *p); -+void br_transmit_tcn(struct net_bridge *br); -+void br_topology_change_detection(struct net_bridge *br); - - /* br_stp_bpdu.c */ --extern void br_send_config_bpdu(struct net_bridge_port *, struct br_config_bpdu *); --extern void br_send_tcn_bpdu(struct net_bridge_port *); -+void br_send_config_bpdu(struct net_bridge_port *, struct br_config_bpdu *); -+void br_send_tcn_bpdu(struct net_bridge_port *); - - #endif -diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c -index 542180a..4a36459 100644 ---- a/net/bridge/br_stp.c -+++ b/net/bridge/br_stp.c -@@ -17,9 +17,9 @@ - #include "br_private_stp.h" - - /* since time values in bpdu are in jiffies and then scaled (1/256) -- * before sending, make sure that is at least one. -+ * before sending, make sure that is at least one STP tick. - */ --#define MESSAGE_AGE_INCR ((HZ < 256) ? 1 : (HZ/256)) -+#define MESSAGE_AGE_INCR ((HZ / 256) + 1) - - static const char *const br_port_state_names[] = { - [BR_STATE_DISABLED] = "disabled", -@@ -31,9 +31,9 @@ static const char *const br_port_state_names[] = { - - void br_log_state(const struct net_bridge_port *p) - { -- br_info(p->br, "port %u(%s) entering %s state\n", -- (unsigned) p->port_no, p->dev->name, -- br_port_state_names[p->state]); -+ br_info(p->br, "port %u(%s) entered %s state\n", -+ (unsigned int) p->port_no, p->dev->name, -+ br_port_state_names[p->state]); - } - - /* called under bridge lock */ -@@ -100,6 +100,21 @@ static int br_should_become_root_port(const struct net_bridge_port *p, - return 0; - } - -+static void br_root_port_block(const struct net_bridge *br, -+ struct net_bridge_port *p) -+{ -+ -+ br_notice(br, "port %u(%s) tried to become root port (blocked)", -+ (unsigned int) p->port_no, p->dev->name); -+ -+ p->state = BR_STATE_LISTENING; -+ br_log_state(p); -+ br_ifinfo_notify(RTM_NEWLINK, p); -+ -+ if (br->forward_delay > 0) -+ mod_timer(&p->forward_delay_timer, jiffies + br->forward_delay); -+} -+ - /* called under bridge lock */ - static void br_root_selection(struct net_bridge *br) - { -@@ -107,7 +122,12 @@ static void br_root_selection(struct net_bridge *br) - u16 root_port = 0; - - list_for_each_entry(p, &br->port_list, list) { -- if (br_should_become_root_port(p, root_port)) -+ if (!br_should_become_root_port(p, root_port)) -+ continue; -+ -+ if (p->flags & BR_ROOT_BLOCK) -+ br_root_port_block(br, p); -+ else - root_port = p->port_no; - } - -@@ -173,7 +193,8 @@ void br_transmit_config(struct net_bridge_port *p) - br_send_config_bpdu(p, &bpdu); - p->topology_change_ack = 0; - p->config_pending = 0; -- -+ mod_timer(&p->hold_timer, -+ round_jiffies(jiffies + BR_HOLD_TIME)); - if (p->br->stp_enabled == BR_KERNEL_STP) { - mod_timer(&p->hold_timer, - round_jiffies(jiffies + BR_HOLD_TIME)); -@@ -189,7 +210,7 @@ static void br_record_config_information(struct net_bridge_port *p, - p->designated_cost = bpdu->root_path_cost; - p->designated_bridge = bpdu->bridge_id; - p->designated_port = bpdu->port_id; -- p->designated_age = jiffies + bpdu->message_age; -+ p->designated_age = jiffies - bpdu->message_age; - - mod_timer(&p->message_age_timer, jiffies - + (bpdu->max_age - bpdu->message_age)); -@@ -208,7 +229,14 @@ static void br_record_config_timeout_values(struct net_bridge *br, - /* called under bridge lock */ - void br_transmit_tcn(struct net_bridge *br) - { -- br_send_tcn_bpdu(br_get_port(br, br->root_port)); -+ struct net_bridge_port *p; -+ -+ p = br_get_port(br, br->root_port); -+ if (p) -+ br_send_tcn_bpdu(p); -+ else -+ br_notice(br, "root port %u not found for topology notice\n", -+ br->root_port); - } - - /* called under bridge lock */ -@@ -422,6 +450,7 @@ void br_port_state_selection(struct net_bridge *br) - } - } else if ((br->stp_enabled == BR_USER_STP) && - (p->state == BR_STATE_FORWARDING)) { -+ - br_multicast_enable_port(p); - } - -@@ -484,7 +513,7 @@ void br_received_tcn_bpdu(struct net_bridge_port *p) - { - if (br_is_designated_port(p)) { - br_info(p->br, "port %u(%s) received tcn bpdu\n", -- (unsigned) p->port_no, p->dev->name); -+ (unsigned int) p->port_no, p->dev->name); - - br_topology_change_detection(p->br); - br_topology_change_acknowledge(p); -@@ -523,18 +552,27 @@ int br_set_max_age(struct net_bridge *br, unsigned long val) - - } - -+void __br_set_forward_delay(struct net_bridge *br, unsigned long t) -+{ -+ br->bridge_forward_delay = t; -+ if (br_is_root_bridge(br)) -+ br->forward_delay = br->bridge_forward_delay; -+} -+ - int br_set_forward_delay(struct net_bridge *br, unsigned long val) - { - unsigned long t = clock_t_to_jiffies(val); -+ int err = -ERANGE; - -+ spin_lock_bh(&br->lock); - if (br->stp_enabled != BR_NO_STP && - (t < BR_MIN_FORWARD_DELAY || t > BR_MAX_FORWARD_DELAY)) -- return -ERANGE; -+ goto unlock; - -- spin_lock_bh(&br->lock); -- br->bridge_forward_delay = t; -- if (br_is_root_bridge(br)) -- br->forward_delay = br->bridge_forward_delay; -+ __br_set_forward_delay(br, t); -+ err = 0; -+ -+unlock: - spin_unlock_bh(&br->lock); -- return 0; -+ return err; - } -diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c -index 718cbe8..bdb459d 100644 ---- a/net/bridge/br_stp_bpdu.c -+++ b/net/bridge/br_stp_bpdu.c -@@ -153,7 +153,7 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, - if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0) - goto err; - -- p = br_port_get_rcu(dev); -+ p = br_port_get_check_rcu(dev); - if (!p) - goto err; - -@@ -169,9 +169,16 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, - if (p->state == BR_STATE_DISABLED) - goto out; - -- if (compare_ether_addr(dest, br->group_addr) != 0) -+ if (!ether_addr_equal(dest, br->group_addr)) - goto out; - -+ if (p->flags & BR_BPDU_GUARD) { -+ br_notice(br, "BPDU received on blocked port %u(%s)\n", -+ (unsigned int) p->port_no, p->dev->name); -+ br_stp_disable_port(p); -+ goto out; -+ } -+ - buf = skb_pull(skb, 3); - - if (buf[0] == BPDU_TYPE_CONFIG) { -diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c -index 28c2b97..4f7fbbf 100644 ---- a/net/bridge/br_stp_if.c -+++ b/net/bridge/br_stp_if.c -@@ -48,16 +48,15 @@ void br_stp_enable_bridge(struct net_bridge *br) - struct net_bridge_port *p; - - spin_lock_bh(&br->lock); -- - if (br->stp_enabled == BR_KERNEL_STP) { -- mod_timer(&br->hello_timer, jiffies + br->hello_time); -+ mod_timer(&br->hello_timer, jiffies + br->hello_time); - } - mod_timer(&br->gc_timer, jiffies + HZ/10); - - br_config_bpdu_generation(br); - - list_for_each_entry(p, &br->port_list, list) { -- if ((p->dev->flags & IFF_UP) && netif_carrier_ok(p->dev)) -+ if (netif_running(p->dev) && netif_oper_up(p->dev)) - br_stp_enable_port(p); - - } -@@ -101,14 +100,13 @@ void br_stp_disable_port(struct net_bridge_port *p) - struct net_bridge *br = p->br; - int wasroot; - -- br_log_state(p); -- - wasroot = br_is_root_bridge(br); - br_become_designated_port(p); - p->state = BR_STATE_DISABLED; - p->topology_change_ack = 0; - p->config_pending = 0; - -+ br_log_state(p); - br_ifinfo_notify(RTM_NEWLINK, p); - - del_timer(&p->message_age_timer); -@@ -133,6 +131,15 @@ static void br_stp_start(struct net_bridge *br) - struct net_bridge_port *p; - extern int brstp_user_space; - -+ spin_lock_bh(&br->lock); -+ -+ if (br->bridge_forward_delay < BR_MIN_FORWARD_DELAY) -+ __br_set_forward_delay(br, BR_MIN_FORWARD_DELAY); -+ else if (br->bridge_forward_delay > BR_MAX_FORWARD_DELAY) -+ __br_set_forward_delay(br, BR_MAX_FORWARD_DELAY); -+ -+ spin_unlock_bh(&br->lock); -+ - if (brstp_user_space) { - call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); - br->stp_enabled = BR_USER_STP; -@@ -153,6 +160,7 @@ static void br_stp_start(struct net_bridge *br) - br_port_state_selection(br); - spin_unlock_bh(&br->lock); - } -+ - } - - static void br_stp_stop(struct net_bridge *br) -@@ -170,7 +178,7 @@ static void br_stp_stop(struct net_bridge *br) - spin_lock_bh(&br->lock); - mod_timer(&br->hello_timer, jiffies + br->hello_time); - list_for_each_entry(p, &br->port_list, list) { -- mod_timer(&p->hold_timer, -+ mod_timer(&p->hold_timer, - round_jiffies(jiffies + BR_HOLD_TIME)); - } - br_port_state_selection(br); -@@ -196,7 +204,7 @@ void br_stp_set_enabled(struct net_bridge *br, unsigned long val) - /* called under bridge lock */ - void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr) - { -- /* should be aligned on 2 bytes for compare_ether_addr() */ -+ /* should be aligned on 2 bytes for ether_addr_equal() */ - unsigned short oldaddr_aligned[ETH_ALEN >> 1]; - unsigned char *oldaddr = (unsigned char *)oldaddr_aligned; - struct net_bridge_port *p; -@@ -209,12 +217,11 @@ void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr) - memcpy(br->dev->dev_addr, addr, ETH_ALEN); - - list_for_each_entry(p, &br->port_list, list) { -- if (!compare_ether_addr(p->designated_bridge.addr, oldaddr)) -+ if (ether_addr_equal(p->designated_bridge.addr, oldaddr)) - memcpy(p->designated_bridge.addr, addr, ETH_ALEN); - -- if (!compare_ether_addr(p->designated_root.addr, oldaddr)) -+ if (ether_addr_equal(p->designated_root.addr, oldaddr)) - memcpy(p->designated_root.addr, addr, ETH_ALEN); -- - } - - br_configuration_update(br); -@@ -223,7 +230,7 @@ void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr) - br_become_root_bridge(br); - } - --/* should be aligned on 2 bytes for compare_ether_addr() */ -+/* should be aligned on 2 bytes for ether_addr_equal() */ - static const unsigned short br_mac_zero_aligned[ETH_ALEN >> 1]; - - /* called under bridge lock */ -@@ -235,7 +242,7 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br) - struct net_bridge_port *p; - - /* user has chosen a value so keep it */ -- if (br->flags & BR_SET_MAC_ADDR) -+ if (br->dev->addr_assign_type == NET_ADDR_SET) - return false; - - list_for_each_entry(p, &br->port_list, list) { -@@ -245,7 +252,7 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br) - - } - -- if (compare_ether_addr(br->bridge_id.addr, addr) == 0) -+ if (ether_addr_equal(br->bridge_id.addr, addr)) - return false; /* no change */ - - br_stp_change_bridge_id(br, addr); -diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c -index c83ee79..558c46d 100644 ---- a/net/bridge/br_stp_timer.c -+++ b/net/bridge/br_stp_timer.c -@@ -56,7 +56,7 @@ static void br_message_age_timer_expired(unsigned long arg) - return; - - br_info(br, "port %u(%s) neighbor %.2x%.2x.%pM lost\n", -- (unsigned) p->port_no, p->dev->name, -+ (unsigned int) p->port_no, p->dev->name, - id->prio[0], id->prio[1], &id->addr); - - /* -@@ -84,7 +84,7 @@ static void br_forward_delay_timer_expired(unsigned long arg) - struct net_bridge *br = p->br; - - br_debug(br, "port %u(%s) forward delay timer\n", -- (unsigned) p->port_no, p->dev->name); -+ (unsigned int) p->port_no, p->dev->name); - spin_lock(&br->lock); - if (p->state == BR_STATE_LISTENING) { - p->state = BR_STATE_LEARNING; -@@ -110,7 +110,7 @@ static void br_tcn_timer_expired(unsigned long arg) - if (!br_is_root_bridge(br) && (br->dev->flags & IFF_UP)) { - br_transmit_tcn(br); - -- mod_timer(&br->tcn_timer,jiffies + br->bridge_hello_time); -+ mod_timer(&br->tcn_timer, jiffies + br->bridge_hello_time); - } - spin_unlock(&br->lock); - } -@@ -131,7 +131,7 @@ static void br_hold_timer_expired(unsigned long arg) - struct net_bridge_port *p = (struct net_bridge_port *) arg; - - br_debug(p->br, "port %u(%s) hold timer expired\n", -- (unsigned) p->port_no, p->dev->name); -+ (unsigned int) p->port_no, p->dev->name); - - spin_lock(&p->br->lock); - if (p->config_pending) -@@ -170,5 +170,5 @@ void br_stp_port_timer_init(struct net_bridge_port *p) - unsigned long br_timer_value(const struct timer_list *timer) - { - return timer_pending(timer) -- ? jiffies_to_clock_t(timer->expires - jiffies) : 0; -+ ? jiffies_delta_to_clock_t(timer->expires - jiffies) : 0; - } -diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c -index 8e12281..951447a 100644 ---- a/net/bridge/br_sysfs_br.c -+++ b/net/bridge/br_sysfs_br.c -@@ -1,5 +1,5 @@ - /* -- * Sysfs attributes of bridge ports -+ * Sysfs attributes of bridge - * Linux ethernet bridge - * - * Authors: -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -48,53 +49,51 @@ static ssize_t store_bridge_parm(struct device *d, - } - - --static ssize_t show_forward_delay(struct device *d, -+static ssize_t forward_delay_show(struct device *d, - struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); - return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->forward_delay)); - } - --static ssize_t store_forward_delay(struct device *d, -+static ssize_t forward_delay_store(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) - { - return store_bridge_parm(d, buf, len, br_set_forward_delay); - } --static DEVICE_ATTR(forward_delay, S_IRUGO | S_IWUSR, -- show_forward_delay, store_forward_delay); -+static DEVICE_ATTR_RW(forward_delay); - --static ssize_t show_hello_time(struct device *d, struct device_attribute *attr, -+static ssize_t hello_time_show(struct device *d, struct device_attribute *attr, - char *buf) - { - return sprintf(buf, "%lu\n", - jiffies_to_clock_t(to_bridge(d)->hello_time)); - } - --static ssize_t store_hello_time(struct device *d, -+static ssize_t hello_time_store(struct device *d, - struct device_attribute *attr, const char *buf, - size_t len) - { - return store_bridge_parm(d, buf, len, br_set_hello_time); - } --static DEVICE_ATTR(hello_time, S_IRUGO | S_IWUSR, show_hello_time, -- store_hello_time); -+static DEVICE_ATTR_RW(hello_time); - --static ssize_t show_max_age(struct device *d, struct device_attribute *attr, -+static ssize_t max_age_show(struct device *d, struct device_attribute *attr, - char *buf) - { - return sprintf(buf, "%lu\n", - jiffies_to_clock_t(to_bridge(d)->max_age)); - } - --static ssize_t store_max_age(struct device *d, struct device_attribute *attr, -+static ssize_t max_age_store(struct device *d, struct device_attribute *attr, - const char *buf, size_t len) - { - return store_bridge_parm(d, buf, len, br_set_max_age); - } --static DEVICE_ATTR(max_age, S_IRUGO | S_IWUSR, show_max_age, store_max_age); -+static DEVICE_ATTR_RW(max_age); - --static ssize_t show_ageing_time(struct device *d, -+static ssize_t ageing_time_show(struct device *d, - struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); -@@ -107,16 +106,15 @@ static int set_ageing_time(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_ageing_time(struct device *d, -+static ssize_t ageing_time_store(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) - { - return store_bridge_parm(d, buf, len, set_ageing_time); - } --static DEVICE_ATTR(ageing_time, S_IRUGO | S_IWUSR, show_ageing_time, -- store_ageing_time); -+static DEVICE_ATTR_RW(ageing_time); - --static ssize_t show_stp_state(struct device *d, -+static ssize_t stp_state_show(struct device *d, - struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); -@@ -124,7 +122,7 @@ static ssize_t show_stp_state(struct device *d, - } - - --static ssize_t store_stp_state(struct device *d, -+static ssize_t stp_state_store(struct device *d, - struct device_attribute *attr, const char *buf, - size_t len) - { -@@ -146,20 +144,21 @@ static ssize_t store_stp_state(struct device *d, - - return len; - } --static DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state, -- store_stp_state); -+static DEVICE_ATTR_RW(stp_state); - --static ssize_t show_group_fwd_mask(struct device *d, -- struct device_attribute *attr, char *buf) -+static ssize_t group_fwd_mask_show(struct device *d, -+ struct device_attribute *attr, -+ char *buf) - { - struct net_bridge *br = to_bridge(d); - return sprintf(buf, "%#x\n", br->group_fwd_mask); - } - - --static ssize_t store_group_fwd_mask(struct device *d, -- struct device_attribute *attr, const char *buf, -- size_t len) -+static ssize_t group_fwd_mask_store(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, -+ size_t len) - { - struct net_bridge *br = to_bridge(d); - char *endp; -@@ -179,10 +178,9 @@ static ssize_t store_group_fwd_mask(struct device *d, - - return len; - } --static DEVICE_ATTR(group_fwd_mask, S_IRUGO | S_IWUSR, show_group_fwd_mask, -- store_group_fwd_mask); -+static DEVICE_ATTR_RW(group_fwd_mask); - --static ssize_t show_priority(struct device *d, struct device_attribute *attr, -+static ssize_t priority_show(struct device *d, struct device_attribute *attr, - char *buf) - { - struct net_bridge *br = to_bridge(d); -@@ -196,93 +194,91 @@ static int set_priority(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_priority(struct device *d, struct device_attribute *attr, -- const char *buf, size_t len) -+static ssize_t priority_store(struct device *d, struct device_attribute *attr, -+ const char *buf, size_t len) - { - return store_bridge_parm(d, buf, len, set_priority); - } --static DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, show_priority, store_priority); -+static DEVICE_ATTR_RW(priority); - --static ssize_t show_root_id(struct device *d, struct device_attribute *attr, -+static ssize_t root_id_show(struct device *d, struct device_attribute *attr, - char *buf) - { - return br_show_bridge_id(buf, &to_bridge(d)->designated_root); - } --static DEVICE_ATTR(root_id, S_IRUGO, show_root_id, NULL); -+static DEVICE_ATTR_RO(root_id); - --static ssize_t show_bridge_id(struct device *d, struct device_attribute *attr, -+static ssize_t bridge_id_show(struct device *d, struct device_attribute *attr, - char *buf) - { - return br_show_bridge_id(buf, &to_bridge(d)->bridge_id); - } --static DEVICE_ATTR(bridge_id, S_IRUGO, show_bridge_id, NULL); -+static DEVICE_ATTR_RO(bridge_id); - --static ssize_t show_root_port(struct device *d, struct device_attribute *attr, -+static ssize_t root_port_show(struct device *d, struct device_attribute *attr, - char *buf) - { - return sprintf(buf, "%d\n", to_bridge(d)->root_port); - } --static DEVICE_ATTR(root_port, S_IRUGO, show_root_port, NULL); -+static DEVICE_ATTR_RO(root_port); - --static ssize_t show_root_path_cost(struct device *d, -+static ssize_t root_path_cost_show(struct device *d, - struct device_attribute *attr, char *buf) - { - return sprintf(buf, "%d\n", to_bridge(d)->root_path_cost); - } --static DEVICE_ATTR(root_path_cost, S_IRUGO, show_root_path_cost, NULL); -+static DEVICE_ATTR_RO(root_path_cost); - --static ssize_t show_topology_change(struct device *d, -+static ssize_t topology_change_show(struct device *d, - struct device_attribute *attr, char *buf) - { - return sprintf(buf, "%d\n", to_bridge(d)->topology_change); - } --static DEVICE_ATTR(topology_change, S_IRUGO, show_topology_change, NULL); -+static DEVICE_ATTR_RO(topology_change); - --static ssize_t show_topology_change_detected(struct device *d, -+static ssize_t topology_change_detected_show(struct device *d, - struct device_attribute *attr, - char *buf) - { - struct net_bridge *br = to_bridge(d); - return sprintf(buf, "%d\n", br->topology_change_detected); - } --static DEVICE_ATTR(topology_change_detected, S_IRUGO, -- show_topology_change_detected, NULL); -+static DEVICE_ATTR_RO(topology_change_detected); - --static ssize_t show_hello_timer(struct device *d, -+static ssize_t hello_timer_show(struct device *d, - struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); - return sprintf(buf, "%ld\n", br_timer_value(&br->hello_timer)); - } --static DEVICE_ATTR(hello_timer, S_IRUGO, show_hello_timer, NULL); -+static DEVICE_ATTR_RO(hello_timer); - --static ssize_t show_tcn_timer(struct device *d, struct device_attribute *attr, -+static ssize_t tcn_timer_show(struct device *d, struct device_attribute *attr, - char *buf) - { - struct net_bridge *br = to_bridge(d); - return sprintf(buf, "%ld\n", br_timer_value(&br->tcn_timer)); - } --static DEVICE_ATTR(tcn_timer, S_IRUGO, show_tcn_timer, NULL); -+static DEVICE_ATTR_RO(tcn_timer); - --static ssize_t show_topology_change_timer(struct device *d, -+static ssize_t topology_change_timer_show(struct device *d, - struct device_attribute *attr, - char *buf) - { - struct net_bridge *br = to_bridge(d); - return sprintf(buf, "%ld\n", br_timer_value(&br->topology_change_timer)); - } --static DEVICE_ATTR(topology_change_timer, S_IRUGO, show_topology_change_timer, -- NULL); -+static DEVICE_ATTR_RO(topology_change_timer); - --static ssize_t show_gc_timer(struct device *d, struct device_attribute *attr, -+static ssize_t gc_timer_show(struct device *d, struct device_attribute *attr, - char *buf) - { - struct net_bridge *br = to_bridge(d); - return sprintf(buf, "%ld\n", br_timer_value(&br->gc_timer)); - } --static DEVICE_ATTR(gc_timer, S_IRUGO, show_gc_timer, NULL); -+static DEVICE_ATTR_RO(gc_timer); - --static ssize_t show_group_addr(struct device *d, -+static ssize_t group_addr_show(struct device *d, - struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); -@@ -292,28 +288,23 @@ static ssize_t show_group_addr(struct device *d, - br->group_addr[4], br->group_addr[5]); - } - --static ssize_t store_group_addr(struct device *d, -+static ssize_t group_addr_store(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) - { - struct net_bridge *br = to_bridge(d); -- unsigned new_addr[6]; -+ u8 new_addr[6]; - int i; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - -- if (sscanf(buf, "%x:%x:%x:%x:%x:%x", -+ if (sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - &new_addr[0], &new_addr[1], &new_addr[2], - &new_addr[3], &new_addr[4], &new_addr[5]) != 6) - return -EINVAL; - -- /* Must be 01:80:c2:00:00:0X */ -- for (i = 0; i < 5; i++) -- if (new_addr[i] != br_group_address[i]) -- return -EINVAL; -- -- if (new_addr[5] & ~0xf) -+ if (!is_link_local_ether_addr(new_addr)) - return -EINVAL; - - if (new_addr[5] == 1 || /* 802.3x Pause address */ -@@ -328,10 +319,9 @@ static ssize_t store_group_addr(struct device *d, - return len; - } - --static DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR, -- show_group_addr, store_group_addr); -+static DEVICE_ATTR_RW(group_addr); - --static ssize_t store_flush(struct device *d, -+static ssize_t flush_store(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) - { -@@ -343,26 +333,25 @@ static ssize_t store_flush(struct device *d, - br_fdb_flush(br); - return len; - } --static DEVICE_ATTR(flush, S_IWUSR, NULL, store_flush); -+static DEVICE_ATTR_WO(flush); - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING --static ssize_t show_multicast_router(struct device *d, -+static ssize_t multicast_router_show(struct device *d, - struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); - return sprintf(buf, "%d\n", br->multicast_router); - } - --static ssize_t store_multicast_router(struct device *d, -+static ssize_t multicast_router_store(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) - { - return store_bridge_parm(d, buf, len, br_multicast_set_router); - } --static DEVICE_ATTR(multicast_router, S_IRUGO | S_IWUSR, show_multicast_router, -- store_multicast_router); -+static DEVICE_ATTR_RW(multicast_router); - --static ssize_t show_multicast_snooping(struct device *d, -+static ssize_t multicast_snooping_show(struct device *d, - struct device_attribute *attr, - char *buf) - { -@@ -370,18 +359,17 @@ static ssize_t show_multicast_snooping(struct device *d, - return sprintf(buf, "%d\n", !br->multicast_disabled); - } - --static ssize_t store_multicast_snooping(struct device *d, -+static ssize_t multicast_snooping_store(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) - { - return store_bridge_parm(d, buf, len, br_multicast_toggle); - } --static DEVICE_ATTR(multicast_snooping, S_IRUGO | S_IWUSR, -- show_multicast_snooping, store_multicast_snooping); -+static DEVICE_ATTR_RW(multicast_snooping); - --static ssize_t show_multicast_query_use_ifaddr(struct device *d, -- struct device_attribute *attr, -- char *buf) -+static ssize_t multicast_query_use_ifaddr_show(struct device *d, -+ struct device_attribute *attr, -+ char *buf) - { - struct net_bridge *br = to_bridge(d); - return sprintf(buf, "%d\n", br->multicast_query_use_ifaddr); -@@ -394,17 +382,15 @@ static int set_query_use_ifaddr(struct net_bridge *br, unsigned long val) - } - - static ssize_t --store_multicast_query_use_ifaddr(struct device *d, -+multicast_query_use_ifaddr_store(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) - { - return store_bridge_parm(d, buf, len, set_query_use_ifaddr); - } --static DEVICE_ATTR(multicast_query_use_ifaddr, S_IRUGO | S_IWUSR, -- show_multicast_query_use_ifaddr, -- store_multicast_query_use_ifaddr); -+static DEVICE_ATTR_RW(multicast_query_use_ifaddr); - --static ssize_t show_multicast_querier(struct device *d, -+static ssize_t multicast_querier_show(struct device *d, - struct device_attribute *attr, - char *buf) - { -@@ -412,16 +398,15 @@ static ssize_t show_multicast_querier(struct device *d, - return sprintf(buf, "%d\n", br->multicast_querier); - } - --static ssize_t store_multicast_querier(struct device *d, -+static ssize_t multicast_querier_store(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) - { - return store_bridge_parm(d, buf, len, br_multicast_set_querier); - } --static DEVICE_ATTR(multicast_querier, S_IRUGO | S_IWUSR, -- show_multicast_querier, store_multicast_querier); -+static DEVICE_ATTR_RW(multicast_querier); - --static ssize_t show_hash_elasticity(struct device *d, -+static ssize_t hash_elasticity_show(struct device *d, - struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); -@@ -434,31 +419,29 @@ static int set_elasticity(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_hash_elasticity(struct device *d, -+static ssize_t hash_elasticity_store(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) - { - return store_bridge_parm(d, buf, len, set_elasticity); - } --static DEVICE_ATTR(hash_elasticity, S_IRUGO | S_IWUSR, show_hash_elasticity, -- store_hash_elasticity); -+static DEVICE_ATTR_RW(hash_elasticity); - --static ssize_t show_hash_max(struct device *d, struct device_attribute *attr, -+static ssize_t hash_max_show(struct device *d, struct device_attribute *attr, - char *buf) - { - struct net_bridge *br = to_bridge(d); - return sprintf(buf, "%u\n", br->hash_max); - } - --static ssize_t store_hash_max(struct device *d, struct device_attribute *attr, -+static ssize_t hash_max_store(struct device *d, struct device_attribute *attr, - const char *buf, size_t len) - { - return store_bridge_parm(d, buf, len, br_multicast_set_hash_max); - } --static DEVICE_ATTR(hash_max, S_IRUGO | S_IWUSR, show_hash_max, -- store_hash_max); -+static DEVICE_ATTR_RW(hash_max); - --static ssize_t show_multicast_last_member_count(struct device *d, -+static ssize_t multicast_last_member_count_show(struct device *d, - struct device_attribute *attr, - char *buf) - { -@@ -472,17 +455,15 @@ static int set_last_member_count(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_multicast_last_member_count(struct device *d, -+static ssize_t multicast_last_member_count_store(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) - { - return store_bridge_parm(d, buf, len, set_last_member_count); - } --static DEVICE_ATTR(multicast_last_member_count, S_IRUGO | S_IWUSR, -- show_multicast_last_member_count, -- store_multicast_last_member_count); -+static DEVICE_ATTR_RW(multicast_last_member_count); - --static ssize_t show_multicast_startup_query_count( -+static ssize_t multicast_startup_query_count_show( - struct device *d, struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); -@@ -495,17 +476,15 @@ static int set_startup_query_count(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_multicast_startup_query_count( -+static ssize_t multicast_startup_query_count_store( - struct device *d, struct device_attribute *attr, const char *buf, - size_t len) - { - return store_bridge_parm(d, buf, len, set_startup_query_count); - } --static DEVICE_ATTR(multicast_startup_query_count, S_IRUGO | S_IWUSR, -- show_multicast_startup_query_count, -- store_multicast_startup_query_count); -+static DEVICE_ATTR_RW(multicast_startup_query_count); - --static ssize_t show_multicast_last_member_interval( -+static ssize_t multicast_last_member_interval_show( - struct device *d, struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); -@@ -519,17 +498,15 @@ static int set_last_member_interval(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_multicast_last_member_interval( -+static ssize_t multicast_last_member_interval_store( - struct device *d, struct device_attribute *attr, const char *buf, - size_t len) - { - return store_bridge_parm(d, buf, len, set_last_member_interval); - } --static DEVICE_ATTR(multicast_last_member_interval, S_IRUGO | S_IWUSR, -- show_multicast_last_member_interval, -- store_multicast_last_member_interval); -+static DEVICE_ATTR_RW(multicast_last_member_interval); - --static ssize_t show_multicast_membership_interval( -+static ssize_t multicast_membership_interval_show( - struct device *d, struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); -@@ -543,17 +520,15 @@ static int set_membership_interval(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_multicast_membership_interval( -+static ssize_t multicast_membership_interval_store( - struct device *d, struct device_attribute *attr, const char *buf, - size_t len) - { - return store_bridge_parm(d, buf, len, set_membership_interval); - } --static DEVICE_ATTR(multicast_membership_interval, S_IRUGO | S_IWUSR, -- show_multicast_membership_interval, -- store_multicast_membership_interval); -+static DEVICE_ATTR_RW(multicast_membership_interval); - --static ssize_t show_multicast_querier_interval(struct device *d, -+static ssize_t multicast_querier_interval_show(struct device *d, - struct device_attribute *attr, - char *buf) - { -@@ -568,17 +543,15 @@ static int set_querier_interval(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_multicast_querier_interval(struct device *d, -+static ssize_t multicast_querier_interval_store(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) - { - return store_bridge_parm(d, buf, len, set_querier_interval); - } --static DEVICE_ATTR(multicast_querier_interval, S_IRUGO | S_IWUSR, -- show_multicast_querier_interval, -- store_multicast_querier_interval); -+static DEVICE_ATTR_RW(multicast_querier_interval); - --static ssize_t show_multicast_query_interval(struct device *d, -+static ssize_t multicast_query_interval_show(struct device *d, - struct device_attribute *attr, - char *buf) - { -@@ -593,17 +566,15 @@ static int set_query_interval(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_multicast_query_interval(struct device *d, -+static ssize_t multicast_query_interval_store(struct device *d, - struct device_attribute *attr, - const char *buf, size_t len) - { - return store_bridge_parm(d, buf, len, set_query_interval); - } --static DEVICE_ATTR(multicast_query_interval, S_IRUGO | S_IWUSR, -- show_multicast_query_interval, -- store_multicast_query_interval); -+static DEVICE_ATTR_RW(multicast_query_interval); - --static ssize_t show_multicast_query_response_interval( -+static ssize_t multicast_query_response_interval_show( - struct device *d, struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); -@@ -618,17 +589,15 @@ static int set_query_response_interval(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_multicast_query_response_interval( -+static ssize_t multicast_query_response_interval_store( - struct device *d, struct device_attribute *attr, const char *buf, - size_t len) - { - return store_bridge_parm(d, buf, len, set_query_response_interval); - } --static DEVICE_ATTR(multicast_query_response_interval, S_IRUGO | S_IWUSR, -- show_multicast_query_response_interval, -- store_multicast_query_response_interval); -+static DEVICE_ATTR_RW(multicast_query_response_interval); - --static ssize_t show_multicast_startup_query_interval( -+static ssize_t multicast_startup_query_interval_show( - struct device *d, struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); -@@ -643,18 +612,16 @@ static int set_startup_query_interval(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_multicast_startup_query_interval( -+static ssize_t multicast_startup_query_interval_store( - struct device *d, struct device_attribute *attr, const char *buf, - size_t len) - { - return store_bridge_parm(d, buf, len, set_startup_query_interval); - } --static DEVICE_ATTR(multicast_startup_query_interval, S_IRUGO | S_IWUSR, -- show_multicast_startup_query_interval, -- store_multicast_startup_query_interval); -+static DEVICE_ATTR_RW(multicast_startup_query_interval); - #endif - #ifdef CONFIG_BRIDGE_NETFILTER --static ssize_t show_nf_call_iptables( -+static ssize_t nf_call_iptables_show( - struct device *d, struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); -@@ -667,16 +634,15 @@ static int set_nf_call_iptables(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_nf_call_iptables( -+static ssize_t nf_call_iptables_store( - struct device *d, struct device_attribute *attr, const char *buf, - size_t len) - { - return store_bridge_parm(d, buf, len, set_nf_call_iptables); - } --static DEVICE_ATTR(nf_call_iptables, S_IRUGO | S_IWUSR, -- show_nf_call_iptables, store_nf_call_iptables); -+static DEVICE_ATTR_RW(nf_call_iptables); - --static ssize_t show_nf_call_ip6tables( -+static ssize_t nf_call_ip6tables_show( - struct device *d, struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); -@@ -689,16 +655,15 @@ static int set_nf_call_ip6tables(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_nf_call_ip6tables( -+static ssize_t nf_call_ip6tables_store( - struct device *d, struct device_attribute *attr, const char *buf, - size_t len) - { - return store_bridge_parm(d, buf, len, set_nf_call_ip6tables); - } --static DEVICE_ATTR(nf_call_ip6tables, S_IRUGO | S_IWUSR, -- show_nf_call_ip6tables, store_nf_call_ip6tables); -+static DEVICE_ATTR_RW(nf_call_ip6tables); - --static ssize_t show_nf_call_arptables( -+static ssize_t nf_call_arptables_show( - struct device *d, struct device_attribute *attr, char *buf) - { - struct net_bridge *br = to_bridge(d); -@@ -711,14 +676,30 @@ static int set_nf_call_arptables(struct net_bridge *br, unsigned long val) - return 0; - } - --static ssize_t store_nf_call_arptables( -+static ssize_t nf_call_arptables_store( - struct device *d, struct device_attribute *attr, const char *buf, - size_t len) - { - return store_bridge_parm(d, buf, len, set_nf_call_arptables); - } --static DEVICE_ATTR(nf_call_arptables, S_IRUGO | S_IWUSR, -- show_nf_call_arptables, store_nf_call_arptables); -+static DEVICE_ATTR_RW(nf_call_arptables); -+#endif -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+static ssize_t vlan_filtering_show(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct net_bridge *br = to_bridge(d); -+ return sprintf(buf, "%d\n", br->vlan_enabled); -+} -+ -+static ssize_t vlan_filtering_store(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ return store_bridge_parm(d, buf, len, br_vlan_filter_toggle); -+} -+static DEVICE_ATTR_RW(vlan_filtering); - #endif - - static struct attribute *bridge_attrs[] = { -@@ -762,6 +743,9 @@ static struct attribute *bridge_attrs[] = { - &dev_attr_nf_call_ip6tables.attr, - &dev_attr_nf_call_arptables.attr, - #endif -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ &dev_attr_vlan_filtering.attr, -+#endif - NULL - }; - -diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c -index 9f1ee9a..81ddab5 100644 ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -26,14 +26,36 @@ struct brport_attribute { - int (*store)(struct net_bridge_port *, unsigned long); - }; - --#define BRPORT_ATTR(_name,_mode,_show,_store) \ --struct brport_attribute brport_attr_##_name = { \ -+#define BRPORT_ATTR(_name, _mode, _show, _store) \ -+const struct brport_attribute brport_attr_##_name = { \ - .attr = {.name = __stringify(_name), \ - .mode = _mode }, \ - .show = _show, \ - .store = _store, \ - }; - -+#define BRPORT_ATTR_FLAG(_name, _mask) \ -+static ssize_t show_##_name(struct net_bridge_port *p, char *buf) \ -+{ \ -+ return sprintf(buf, "%d\n", !!(p->flags & _mask)); \ -+} \ -+static int store_##_name(struct net_bridge_port *p, unsigned long v) \ -+{ \ -+ unsigned long flags = p->flags; \ -+ if (v) \ -+ flags |= _mask; \ -+ else \ -+ flags &= ~_mask; \ -+ if (flags != p->flags) { \ -+ p->flags = flags; \ -+ br_ifinfo_notify(RTM_NEWLINK, p); \ -+ } \ -+ return 0; \ -+} \ -+static BRPORT_ATTR(_name, S_IRUGO | S_IWUSR, \ -+ show_##_name, store_##_name) -+ -+ - static ssize_t show_path_cost(struct net_bridge_port *p, char *buf) - { - return sprintf(buf, "%d\n", p->path_cost); -@@ -126,28 +148,85 @@ static ssize_t show_hold_timer(struct net_bridge_port *p, - } - static BRPORT_ATTR(hold_timer, S_IRUGO, show_hold_timer, NULL); - --static int store_flush(struct net_bridge_port *p, unsigned long v) -+static ssize_t show_pvid(struct net_bridge_port *p, char *buf) - { -- br_fdb_delete_by_port(p->br, p, 0); // Don't delete local entry -- return 0; -+ struct net_port_vlans *pv; -+ ssize_t ret = 0; -+ -+ rcu_read_lock(); -+ pv = rtnl_dereference(p->vlan_info); -+ -+ if (pv && (pv->pvid != 0)) -+ ret = sprintf(buf, "%d\n", pv->pvid); -+ rcu_read_unlock(); -+ -+ return ret; - } --static BRPORT_ATTR(flush, S_IWUSR, NULL, store_flush); -+static BRPORT_ATTR(pvid, S_IRUGO, show_pvid, NULL); - --static ssize_t show_hairpin_mode(struct net_bridge_port *p, char *buf) -+static ssize_t show_vlan_bitmap(unsigned long *bmp, char *buf) - { -- int hairpin_mode = (p->flags & BR_HAIRPIN_MODE) ? 1 : 0; -- return sprintf(buf, "%d\n", hairpin_mode); -+ int i, m = sizeof(unsigned long) / sizeof(u32); -+ char *ptr = buf; -+ u32 *h = (u32 *)bmp; -+ -+ ssize_t size = 0; -+ -+ for (i = 0; i < BR_VLAN_BITMAP_LEN * m; i++) { -+ size += sprintf(ptr, "0x%08lx\n", h[i]); -+ ptr = buf + size; -+ } -+ return size; - } --static int store_hairpin_mode(struct net_bridge_port *p, unsigned long v) -+ -+static ssize_t show_untagged_vlans(struct net_bridge_port *p, char *buf) - { -- if (v) -- p->flags |= BR_HAIRPIN_MODE; -- else -- p->flags &= ~BR_HAIRPIN_MODE; -+ struct net_port_vlans *pv; -+ ssize_t ret = 0; -+ -+ rcu_read_lock(); -+ pv = rcu_dereference(p->vlan_info); -+ -+ if (!pv) -+ goto out; -+ -+ ret = show_vlan_bitmap(pv->untagged_bitmap, buf); -+out: -+ rcu_read_unlock(); -+ return ret; -+} -+static BRPORT_ATTR(untagged_vlans, S_IRUGO, show_untagged_vlans, NULL); -+ -+static ssize_t show_vlans(struct net_bridge_port *p, char *buf) -+{ -+ struct net_port_vlans *pv; -+ ssize_t ret = 0; -+ -+ rcu_read_lock(); -+ pv = rcu_dereference(p->vlan_info); -+ -+ if (!pv) -+ goto out; -+ -+ ret = show_vlan_bitmap(pv->vlan_bitmap, buf); -+out: -+ rcu_read_unlock(); -+ return ret; -+} -+static BRPORT_ATTR(vlans, S_IRUGO, show_vlans, NULL); -+ -+static int store_flush(struct net_bridge_port *p, unsigned long v) -+{ -+ br_fdb_delete_by_port(p->br, p, 0); // Don't delete local entry - return 0; - } --static BRPORT_ATTR(hairpin_mode, S_IRUGO | S_IWUSR, -- show_hairpin_mode, store_hairpin_mode); -+static BRPORT_ATTR(flush, S_IWUSR, NULL, store_flush); -+ -+BRPORT_ATTR_FLAG(hairpin_mode, BR_HAIRPIN_MODE); -+BRPORT_ATTR_FLAG(bpdu_guard, BR_BPDU_GUARD); -+BRPORT_ATTR_FLAG(root_block, BR_ROOT_BLOCK); -+BRPORT_ATTR_FLAG(learning, BR_LEARNING); -+BRPORT_ATTR_FLAG(unicast_flood, BR_FLOOD); - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) -@@ -163,24 +242,10 @@ static int store_multicast_router(struct net_bridge_port *p, - static BRPORT_ATTR(multicast_router, S_IRUGO | S_IWUSR, show_multicast_router, - store_multicast_router); - --static ssize_t show_multicast_fast_leave(struct net_bridge_port *p, -- char *buf) --{ -- return sprintf(buf, "%d\n", p->multicast_fast_leave); --} -- --static int store_multicast_fast_leave(struct net_bridge_port *p, -- unsigned long v) --{ -- p->multicast_fast_leave = !!v; -- return 0; --} -- --static BRPORT_ATTR(multicast_fast_leave, S_IRUGO | S_IWUSR, -- show_multicast_fast_leave, store_multicast_fast_leave); -+BRPORT_ATTR_FLAG(multicast_fast_leave, BR_MULTICAST_FAST_LEAVE); - #endif - --static struct brport_attribute *brport_attrs[] = { -+static const struct brport_attribute *brport_attrs[] = { - &brport_attr_path_cost, - &brport_attr_priority, - &brport_attr_port_id, -@@ -197,31 +262,38 @@ static struct brport_attribute *brport_attrs[] = { - &brport_attr_hold_timer, - &brport_attr_flush, - &brport_attr_hairpin_mode, -+ &brport_attr_bpdu_guard, -+ &brport_attr_root_block, -+ &brport_attr_learning, -+ &brport_attr_unicast_flood, - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - &brport_attr_multicast_router, - &brport_attr_multicast_fast_leave, - #endif -+ &brport_attr_pvid, -+ &brport_attr_untagged_vlans, -+ &brport_attr_vlans, - NULL - }; - - #define to_brport_attr(_at) container_of(_at, struct brport_attribute, attr) - #define to_brport(obj) container_of(obj, struct net_bridge_port, kobj) - --static ssize_t brport_show(struct kobject * kobj, -- struct attribute * attr, char * buf) -+static ssize_t brport_show(struct kobject *kobj, -+ struct attribute *attr, char *buf) - { -- struct brport_attribute * brport_attr = to_brport_attr(attr); -- struct net_bridge_port * p = to_brport(kobj); -+ struct brport_attribute *brport_attr = to_brport_attr(attr); -+ struct net_bridge_port *p = to_brport(kobj); - - return brport_attr->show(p, buf); - } - --static ssize_t brport_store(struct kobject * kobj, -- struct attribute * attr, -- const char * buf, size_t count) -+static ssize_t brport_store(struct kobject *kobj, -+ struct attribute *attr, -+ const char *buf, size_t count) - { -- struct brport_attribute * brport_attr = to_brport_attr(attr); -- struct net_bridge_port * p = to_brport(kobj); -+ struct brport_attribute *brport_attr = to_brport_attr(attr); -+ struct net_bridge_port *p = to_brport(kobj); - ssize_t ret = -EINVAL; - char *endp; - unsigned long val; -@@ -258,7 +330,7 @@ const struct sysfs_ops brport_sysfs_ops = { - int br_sysfs_addif(struct net_bridge_port *p) - { - struct net_bridge *br = p->br; -- struct brport_attribute **a; -+ const struct brport_attribute **a; - int err; - - err = sysfs_create_link(&p->kobj, &br->dev->dev.kobj, -diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c -new file mode 100644 -index 0000000..6317f3c ---- /dev/null -+++ b/net/bridge/br_vlan.c -@@ -0,0 +1,406 @@ -+#include -+#include -+#include -+#include -+ -+#include "br_private.h" -+ -+static void __vlan_add_pvid(struct net_port_vlans *v, u16 vid) -+{ -+ if (v->pvid == vid) -+ return; -+ -+ smp_wmb(); -+ v->pvid = vid; -+} -+ -+static void __vlan_delete_pvid(struct net_port_vlans *v, u16 vid) -+{ -+ if (v->pvid != vid) -+ return; -+ -+ smp_wmb(); -+ v->pvid = 0; -+} -+ -+static void __vlan_add_flags(struct net_port_vlans *v, u16 vid, u16 flags) -+{ -+ if (flags & BRIDGE_VLAN_INFO_PVID) -+ __vlan_add_pvid(v, vid); -+ -+ if (flags & BRIDGE_VLAN_INFO_UNTAGGED) -+ set_bit(vid, v->untagged_bitmap); -+} -+ -+static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) -+{ -+ struct net_bridge_port *p = NULL; -+ struct net_bridge *br; -+ struct net_device *dev; -+ int err; -+ -+ if (test_bit(vid, v->vlan_bitmap)) { -+ __vlan_add_flags(v, vid, flags); -+ return 0; -+ } -+ -+ if (v->port_idx) { -+ p = v->parent.port; -+ br = p->br; -+ dev = p->dev; -+ } else { -+ br = v->parent.br; -+ dev = br->dev; -+ } -+ -+ if (p) { -+ /* Add VLAN to the device filter if it is supported. -+ * Stricly speaking, this is not necessary now, since -+ * devices are made promiscuous by the bridge, but if -+ * that ever changes this code will allow tagged -+ * traffic to enter the bridge. -+ */ -+ err = vlan_vid_add(dev, htons(ETH_P_8021Q), vid); -+ if (err) -+ return err; -+ } -+ -+ err = br_fdb_insert(br, p, dev->dev_addr, vid); -+ if (err) { -+ br_err(br, "failed insert local address into bridge " -+ "forwarding table\n"); -+ goto out_filt; -+ } -+ -+ set_bit(vid, v->vlan_bitmap); -+ v->num_vlans++; -+ __vlan_add_flags(v, vid, flags); -+ -+ return 0; -+ -+out_filt: -+ if (p) -+ vlan_vid_del(dev, htons(ETH_P_8021Q), vid); -+ return err; -+} -+ -+static int __vlan_del(struct net_port_vlans *v, u16 vid) -+{ -+ if (!test_bit(vid, v->vlan_bitmap)) -+ return -EINVAL; -+ -+ __vlan_delete_pvid(v, vid); -+ clear_bit(vid, v->untagged_bitmap); -+ -+ if (v->port_idx) -+ vlan_vid_del(v->parent.port->dev, htons(ETH_P_8021Q), vid); -+ -+ clear_bit(vid, v->vlan_bitmap); -+ v->num_vlans--; -+ if (bitmap_empty(v->vlan_bitmap, VLAN_N_VID)) { -+ if (v->port_idx) -+ rcu_assign_pointer(v->parent.port->vlan_info, NULL); -+ else -+ rcu_assign_pointer(v->parent.br->vlan_info, NULL); -+ kfree_rcu(v, rcu); -+ } -+ return 0; -+} -+ -+static void __vlan_flush(struct net_port_vlans *v) -+{ -+ smp_wmb(); -+ v->pvid = 0; -+ bitmap_zero(v->vlan_bitmap, VLAN_N_VID); -+ if (v->port_idx) -+ rcu_assign_pointer(v->parent.port->vlan_info, NULL); -+ else -+ rcu_assign_pointer(v->parent.br->vlan_info, NULL); -+ kfree_rcu(v, rcu); -+} -+ -+/* Strip the tag from the packet. Will return skb with tci set 0. */ -+static struct sk_buff *br_vlan_untag(struct sk_buff *skb) -+{ -+ if (skb->protocol != htons(ETH_P_8021Q)) { -+ skb->vlan_tci = 0; -+ return skb; -+ } -+ -+ skb->vlan_tci = 0; -+ skb = vlan_untag(skb); -+ if (skb) -+ skb->vlan_tci = 0; -+ -+ return skb; -+} -+ -+struct sk_buff *br_handle_vlan(struct net_bridge *br, -+ const struct net_port_vlans *pv, -+ struct sk_buff *skb) -+{ -+ u16 vid; -+ -+ if (!br->vlan_enabled) -+ goto out; -+ -+ if (!pv) -+ goto out; -+ -+ /* At this point, we know that the frame was filtered and contains -+ * a valid vlan id. If the vlan id is set in the untagged bitmap, -+ * send untagged; otherwise, send tagged. -+ */ -+ br_vlan_get_tag(skb, &vid); -+ if (test_bit(vid, pv->untagged_bitmap)) -+ skb = br_vlan_untag(skb); -+ -+out: -+ return skb; -+} -+ -+/* Called under RCU */ -+bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, -+ struct sk_buff *skb, u16 *vid) -+{ -+ int err; -+ -+ /* If VLAN filtering is disabled on the bridge, all packets are -+ * permitted. -+ */ -+ if (!br->vlan_enabled) -+ return true; -+ -+ /* If there are no vlan in the permitted list, all packets are -+ * rejected. -+ */ -+ if (!v) -+ return false; -+ err = br_vlan_get_tag(skb, vid); -+ if (!*vid) { -+ u16 pvid = br_get_pvid(v); -+ -+ /* Frame had a tag with VID 0 or did not have a tag. -+ * See if pvid is set on this port. That tells us which -+ * vlan untagged or priority-tagged traffic belongs to. -+ */ -+ if (pvid == VLAN_N_VID) -+ return false; -+ -+ /* PVID is set on this port. Any untagged or priority-tagged -+ * ingress frame is considered to belong to this vlan. -+ */ -+ *vid = pvid; -+ if (likely(err)) { -+ /* Untagged Frame. */ -+ //__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), pvid); -+ skb->vlan_proto = htons(ETH_P_8021Q); -+ __vlan_hwaccel_put_tag(skb, pvid); -+ } else -+ /* Priority-tagged Frame. -+ * At this point, We know that skb->vlan_tci had -+ * VLAN_TAG_PRESENT bit and its VID field was 0x000. -+ * We update only VID field and preserve PCP field. -+ */ -+ skb->vlan_tci |= pvid; -+ -+ return true; -+ } -+ -+ /* Frame had a valid vlan tag. See if vlan is allowed */ -+ if (test_bit(*vid, v->vlan_bitmap)) -+ return true; -+ return false; -+} -+ -+/* Called under RCU. */ -+bool br_allowed_egress(struct net_bridge *br, -+ const struct net_port_vlans *v, -+ const struct sk_buff *skb) -+{ -+ u16 vid; -+ -+ if (!br->vlan_enabled) -+ return true; -+ -+ if (!v) -+ return false; -+ -+ br_vlan_get_tag(skb, &vid); -+ if (test_bit(vid, v->vlan_bitmap)) -+ return true; -+ -+ return false; -+} -+ -+/* Must be protected by RTNL. -+ * Must be called with vid in range from 1 to 4094 inclusive. -+ */ -+int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags) -+{ -+ struct net_port_vlans *pv = NULL; -+ int err; -+ -+ ASSERT_RTNL(); -+ -+ pv = rtnl_dereference(br->vlan_info); -+ if (pv) -+ return __vlan_add(pv, vid, flags); -+ -+ /* Create port vlan infomration -+ */ -+ pv = kzalloc(sizeof(*pv), GFP_KERNEL); -+ if (!pv) -+ return -ENOMEM; -+ -+ pv->parent.br = br; -+ err = __vlan_add(pv, vid, flags); -+ if (err) -+ goto out; -+ -+ rcu_assign_pointer(br->vlan_info, pv); -+ return 0; -+out: -+ kfree(pv); -+ return err; -+} -+ -+/* Must be protected by RTNL. -+ * Must be called with vid in range from 1 to 4094 inclusive. -+ */ -+int br_vlan_delete(struct net_bridge *br, u16 vid) -+{ -+ struct net_port_vlans *pv; -+ -+ ASSERT_RTNL(); -+ -+ pv = rtnl_dereference(br->vlan_info); -+ if (!pv) -+ return -EINVAL; -+ -+ spin_lock_bh(&br->hash_lock); -+ fdb_delete_by_addr(br, br->dev->dev_addr, vid); -+ spin_unlock_bh(&br->hash_lock); -+ -+ __vlan_del(pv, vid); -+ return 0; -+} -+ -+void br_vlan_flush(struct net_bridge *br) -+{ -+ struct net_port_vlans *pv; -+ -+ ASSERT_RTNL(); -+ pv = rtnl_dereference(br->vlan_info); -+ if (!pv) -+ return; -+ -+ __vlan_flush(pv); -+} -+ -+int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) -+{ -+ if (!rtnl_trylock()) -+ return restart_syscall(); -+ -+ if (br->vlan_enabled == val) -+ goto unlock; -+ -+ br->vlan_enabled = val; -+ -+unlock: -+ rtnl_unlock(); -+ return 0; -+} -+ -+/* Must be protected by RTNL. -+ * Must be called with vid in range from 1 to 4094 inclusive. -+ */ -+int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) -+{ -+ struct net_port_vlans *pv = NULL; -+ int err; -+ -+ ASSERT_RTNL(); -+ -+ pv = rtnl_dereference(port->vlan_info); -+ if (pv) -+ return __vlan_add(pv, vid, flags); -+ -+ /* Create port vlan infomration -+ */ -+ pv = kzalloc(sizeof(*pv), GFP_KERNEL); -+ if (!pv) { -+ err = -ENOMEM; -+ goto clean_up; -+ } -+ -+ pv->port_idx = port->port_no; -+ pv->parent.port = port; -+ err = __vlan_add(pv, vid, flags); -+ if (err) -+ goto clean_up; -+ -+ rcu_assign_pointer(port->vlan_info, pv); -+ return 0; -+ -+clean_up: -+ kfree(pv); -+ return err; -+} -+ -+/* Must be protected by RTNL. -+ * Must be called with vid in range from 1 to 4094 inclusive. -+ */ -+int nbp_vlan_delete(struct net_bridge_port *port, u16 vid) -+{ -+ struct net_port_vlans *pv; -+ -+ ASSERT_RTNL(); -+ -+ pv = rtnl_dereference(port->vlan_info); -+ if (!pv) -+ return -EINVAL; -+ -+ spin_lock_bh(&port->br->hash_lock); -+ fdb_delete_by_addr(port->br, port->dev->dev_addr, vid); -+ spin_unlock_bh(&port->br->hash_lock); -+ -+ return __vlan_del(pv, vid); -+} -+ -+void nbp_vlan_flush(struct net_bridge_port *port) -+{ -+ struct net_port_vlans *pv; -+ u16 vid; -+ -+ ASSERT_RTNL(); -+ -+ pv = rtnl_dereference(port->vlan_info); -+ if (!pv) -+ return; -+ -+ for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) -+ vlan_vid_del(port->dev, htons(ETH_P_8021Q), vid); -+ -+ __vlan_flush(pv); -+} -+ -+bool nbp_vlan_find(struct net_bridge_port *port, u16 vid) -+{ -+ struct net_port_vlans *pv; -+ bool found = false; -+ -+ rcu_read_lock(); -+ pv = rcu_dereference(port->vlan_info); -+ -+ if (!pv) -+ goto out; -+ -+ if (test_bit(vid, pv->vlan_bitmap)) -+ found = true; -+ -+out: -+ rcu_read_unlock(); -+ return found; -+} -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index c2d619b..1fc0006 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -2130,6 +2131,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - { - struct net *net = sock_net(skb->sk); - struct ndmsg *ndm; -+ struct nlattr *tb[NDA_MAX+1]; - struct nlattr *llattr; - struct net_device *dev; - int err = -EINVAL; -@@ -2138,6 +2140,10 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - if (nlmsg_len(nlh) < sizeof(*ndm)) - return -EINVAL; - -+ err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); -+ if (err < 0) -+ return err; -+ - ndm = nlmsg_data(nlh); - if (ndm->ndm_ifindex == 0) { - pr_info("PF_BRIDGE: RTM_DELNEIGH with invalid ifindex\n"); -@@ -2165,7 +2171,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - struct net_device *master = dev->master; - - if (master->netdev_ops->ndo_fdb_del) -- err = master->netdev_ops->ndo_fdb_del(ndm, dev, addr); -+ err = master->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr); - - if (err) - goto out; -@@ -2175,7 +2181,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - - /* Embedded bridge, macvlan, and any other device support */ - if ((ndm->ndm_flags & NTF_SELF) && dev->netdev_ops->ndo_fdb_del) { -- err = dev->netdev_ops->ndo_fdb_del(ndm, dev, addr); -+ err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr); - - if (!err) { - /* In all cases the netdev fdb_add handler -@@ -2267,6 +2273,296 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) - return skb->len; - } - -+int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, -+ struct net_device *dev, u16 mode) -+{ -+ struct nlmsghdr *nlh; -+ struct ifinfomsg *ifm; -+ struct nlattr *br_afspec; -+ u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN; -+ //struct net_device *br_dev = netdev_master_upper_dev_get(dev); -+ struct net_device *br_dev = dev->master; -+ -+ nlh = nlmsg_put(skb, pid, seq, RTM_NEWLINK, sizeof(*ifm), NLM_F_MULTI); -+ if (nlh == NULL) -+ return -EMSGSIZE; -+ -+ ifm = nlmsg_data(nlh); -+ ifm->ifi_family = AF_BRIDGE; -+ ifm->__ifi_pad = 0; -+ ifm->ifi_type = dev->type; -+ ifm->ifi_index = dev->ifindex; -+ ifm->ifi_flags = dev_get_flags(dev); -+ ifm->ifi_change = 0; -+ -+ -+ if (nla_put_string(skb, IFLA_IFNAME, dev->name) || -+ nla_put_u32(skb, IFLA_MTU, dev->mtu) || -+ nla_put_u8(skb, IFLA_OPERSTATE, operstate) || -+ (br_dev && -+ nla_put_u32(skb, IFLA_MASTER, br_dev->ifindex)) || -+ (dev->addr_len && -+ nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) || -+ (dev->ifindex != dev->iflink && -+ nla_put_u32(skb, IFLA_LINK, dev->iflink))) -+ goto nla_put_failure; -+ -+ br_afspec = nla_nest_start(skb, IFLA_AF_SPEC); -+ if (!br_afspec) -+ goto nla_put_failure; -+ -+ if (nla_put_u16(skb, IFLA_BRIDGE_FLAGS, BRIDGE_FLAGS_SELF) || -+ nla_put_u16(skb, IFLA_BRIDGE_MODE, mode)) { -+ nla_nest_cancel(skb, br_afspec); -+ goto nla_put_failure; -+ } -+ nla_nest_end(skb, br_afspec); -+ -+ return nlmsg_end(skb, nlh); -+nla_put_failure: -+ nlmsg_cancel(skb, nlh); -+ return -EMSGSIZE; -+} -+EXPORT_SYMBOL(ndo_dflt_bridge_getlink); -+ -+static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb) -+{ -+ struct net *net = sock_net(skb->sk); -+ struct net_device *dev; -+ int idx = 0; -+ u32 portid = NETLINK_CB(cb->skb).pid; -+ u32 seq = cb->nlh->nlmsg_seq; -+ struct nlattr *extfilt; -+ u32 filter_mask = 0; -+ -+ extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg), -+ IFLA_EXT_MASK); -+ if (extfilt) -+ filter_mask = nla_get_u32(extfilt); -+ -+ rcu_read_lock(); -+ for_each_netdev_rcu(net, dev) { -+ const struct net_device_ops *ops = dev->netdev_ops; -+ //struct net_device *br_dev = netdev_master_upper_dev_get(dev); -+ struct net_device *br_dev = dev->master; -+ -+ if (br_dev && br_dev->netdev_ops->ndo_bridge_getlink) { -+ if (idx >= cb->args[0] && -+ br_dev->netdev_ops->ndo_bridge_getlink( -+ skb, portid, seq, dev, filter_mask) < 0) -+ break; -+ idx++; -+ } -+ -+ if (ops->ndo_bridge_getlink) { -+ if (idx >= cb->args[0] && -+ ops->ndo_bridge_getlink(skb, portid, seq, dev, -+ filter_mask) < 0) -+ break; -+ idx++; -+ } -+ } -+ rcu_read_unlock(); -+ cb->args[0] = idx; -+ -+ return skb->len; -+} -+ -+static inline size_t bridge_nlmsg_size(void) -+{ -+ return NLMSG_ALIGN(sizeof(struct ifinfomsg)) -+ + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ -+ + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ -+ + nla_total_size(sizeof(u32)) /* IFLA_MASTER */ -+ + nla_total_size(sizeof(u32)) /* IFLA_MTU */ -+ + nla_total_size(sizeof(u32)) /* IFLA_LINK */ -+ + nla_total_size(sizeof(u32)) /* IFLA_OPERSTATE */ -+ + nla_total_size(sizeof(u8)) /* IFLA_PROTINFO */ -+ + nla_total_size(sizeof(struct nlattr)) /* IFLA_AF_SPEC */ -+ + nla_total_size(sizeof(u16)) /* IFLA_BRIDGE_FLAGS */ -+ + nla_total_size(sizeof(u16)); /* IFLA_BRIDGE_MODE */ -+} -+ -+static int rtnl_bridge_notify(struct net_device *dev, u16 flags) -+{ -+ struct net *net = dev_net(dev); -+ //struct net_device *br_dev = netdev_master_upper_dev_get(dev); -+ struct net_device *br_dev = dev->master; -+ struct sk_buff *skb; -+ int err = -EOPNOTSUPP; -+ size_t total_size; -+ -+ total_size = bridge_nlmsg_size() + rtnl_link_get_af_size(dev); -+ skb = nlmsg_new(total_size, GFP_ATOMIC); -+ if (!skb) { -+ err = -ENOMEM; -+ goto errout; -+ } -+ -+ if ((!flags || (flags & BRIDGE_FLAGS_MASTER)) && -+ br_dev && br_dev->netdev_ops->ndo_bridge_getlink) { -+ err = br_dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev, 0); -+ if (err < 0) -+ goto errout; -+ } -+ -+ if ((flags & BRIDGE_FLAGS_SELF) && -+ dev->netdev_ops->ndo_bridge_getlink) { -+ err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev, 0); -+ if (err < 0) -+ goto errout; -+ } -+ -+ rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); -+ return 0; -+errout: -+ WARN_ON(err == -EMSGSIZE); -+ kfree_skb(skb); -+ rtnl_set_sk_err(net, RTNLGRP_LINK, err); -+ return err; -+} -+ -+static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) -+{ -+ struct net *net = sock_net(skb->sk); -+ struct ifinfomsg *ifm; -+ struct net_device *dev; -+ struct nlattr *br_spec, *attr = NULL; -+ int rem, err = -EOPNOTSUPP; -+ u16 oflags, flags = 0; -+ bool have_flags = false; -+ -+ if (nlmsg_len(nlh) < sizeof(*ifm)) -+ return -EINVAL; -+ -+ ifm = nlmsg_data(nlh); -+ if (ifm->ifi_family != AF_BRIDGE) -+ return -EPFNOSUPPORT; -+ -+ dev = __dev_get_by_index(net, ifm->ifi_index); -+ if (!dev) { -+ pr_info("PF_BRIDGE: RTM_SETLINK with unknown ifindex\n"); -+ return -ENODEV; -+ } -+ -+ br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); -+ if (br_spec) { -+ nla_for_each_nested(attr, br_spec, rem) { -+ if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { -+ have_flags = true; -+ flags = nla_get_u16(attr); -+ break; -+ } -+ } -+ } -+ -+ oflags = flags; -+ -+ if (!flags || (flags & BRIDGE_FLAGS_MASTER)) { -+ //struct net_device *br_dev = netdev_master_upper_dev_get(dev); -+ struct net_device *br_dev = dev->master; -+ -+ if (!br_dev || !br_dev->netdev_ops->ndo_bridge_setlink) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ err = br_dev->netdev_ops->ndo_bridge_setlink(dev, nlh); -+ if (err) -+ goto out; -+ -+ flags &= ~BRIDGE_FLAGS_MASTER; -+ } -+ -+ if ((flags & BRIDGE_FLAGS_SELF)) { -+ if (!dev->netdev_ops->ndo_bridge_setlink) -+ err = -EOPNOTSUPP; -+ else -+ err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh); -+ -+ if (!err) -+ flags &= ~BRIDGE_FLAGS_SELF; -+ } -+ -+ if (have_flags) -+ memcpy(nla_data(attr), &flags, sizeof(flags)); -+ /* Generate event to notify upper layer of bridge change */ -+ if (!err) -+ err = rtnl_bridge_notify(dev, oflags); -+out: -+ return err; -+} -+ -+static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) -+{ -+ struct net *net = sock_net(skb->sk); -+ struct ifinfomsg *ifm; -+ struct net_device *dev; -+ struct nlattr *br_spec, *attr = NULL; -+ int rem, err = -EOPNOTSUPP; -+ u16 oflags, flags = 0; -+ bool have_flags = false; -+ -+ if (nlmsg_len(nlh) < sizeof(*ifm)) -+ return -EINVAL; -+ -+ ifm = nlmsg_data(nlh); -+ if (ifm->ifi_family != AF_BRIDGE) -+ return -EPFNOSUPPORT; -+ -+ dev = __dev_get_by_index(net, ifm->ifi_index); -+ if (!dev) { -+ pr_info("PF_BRIDGE: RTM_SETLINK with unknown ifindex\n"); -+ return -ENODEV; -+ } -+ -+ br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); -+ if (br_spec) { -+ nla_for_each_nested(attr, br_spec, rem) { -+ if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { -+ have_flags = true; -+ flags = nla_get_u16(attr); -+ break; -+ } -+ } -+ } -+ -+ oflags = flags; -+ -+ if (!flags || (flags & BRIDGE_FLAGS_MASTER)) { -+ //struct net_device *br_dev = netdev_master_upper_dev_get(dev); -+ struct net_device *br_dev = dev->master; -+ -+ if (!br_dev || !br_dev->netdev_ops->ndo_bridge_dellink) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ err = br_dev->netdev_ops->ndo_bridge_dellink(dev, nlh); -+ if (err) -+ goto out; -+ -+ flags &= ~BRIDGE_FLAGS_MASTER; -+ } -+ -+ if ((flags & BRIDGE_FLAGS_SELF)) { -+ if (!dev->netdev_ops->ndo_bridge_dellink) -+ err = -EOPNOTSUPP; -+ else -+ err = dev->netdev_ops->ndo_bridge_dellink(dev, nlh); -+ -+ if (!err) -+ flags &= ~BRIDGE_FLAGS_SELF; -+ } -+ -+ if (have_flags) -+ memcpy(nla_data(attr), &flags, sizeof(flags)); -+ /* Generate event to notify upper layer of bridge change */ -+ if (!err) -+ err = rtnl_bridge_notify(dev, oflags); -+out: -+ return err; -+} - - /* Protected by RTNL sempahore. */ - static struct rtattr **rta_buf; -@@ -2438,8 +2734,12 @@ void __init rtnetlink_init(void) - rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, NULL); - rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, NULL); - -- rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL); -- rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL); -- rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL); -+ rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL); -+ rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL); -+ rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL); -+ -+ rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, NULL); -+ rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, NULL); -+ rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, NULL); - } - -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index f61872f..4d379d5 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -544,6 +544,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) - new->tc_verd = old->tc_verd; - #endif - #endif -+ new->vlan_proto = old->vlan_proto; - new->vlan_tci = old->vlan_tci; - - skb_copy_secmark(new, old); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-prevent-fdb-insert-in-disallowed-vlan.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-prevent-fdb-insert-in-disallowed-vlan.patch deleted file mode 100644 index 44afe77c..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-prevent-fdb-insert-in-disallowed-vlan.patch +++ /dev/null @@ -1,107 +0,0 @@ -commit e0d7968ab6c8bce2437b36fa7f04117e333f196d - -From: Wilson Kok - -bridge: Prevent insertion of FDB entry with disallowed vlan - -br_handle_local_finish() is allowing us to insert an FDB entry with -disallowed vlan. For example, when port 1 and 2 are communicating in -vlan 10, and even if vlan 10 is disallowed on port 3, port 3 can -interfere with their communication by spoofed src mac address with -vlan id 10. - -Note: Even if it is judged that a frame should not be learned, it should -not be dropped because it is destined for not forwarding layer but higher -layer. See IEEE 802.1Q-2011 8.13.10. - -Signed-off-by: Toshiaki Makita -Acked-by: Vlad Yasevich -Signed-off-by: David S. Miller ---- - net/bridge/br_input.c | 7 +++++-- - net/bridge/br_private.h | 7 +++++++ - net/bridge/br_vlan.c | 28 ++++++++++++++++++++++++++++ - 3 files changed, 40 insertions(+), 2 deletions(-) - -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index fc48161..3894c99 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -162,8 +162,11 @@ static int br_handle_local_finish(struct sk_buff *skb) - struct net_bridge_port *p = br_port_get_rcu(skb->dev); - u16 vid = 0; - -- br_vlan_get_tag(skb, &vid); -- if (!br_hw_fwding_enabled && (p->flags & BR_LEARNING)) -+ if (br_hw_fwding_enabled) -+ return 0; -+ -+ /* check if vlan is allowed, to avoid spoofing */ -+ if (p->flags & BR_LEARNING && br_should_learn(p, skb, &vid)) - br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid); - return 0; /* process further */ - } -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index b0c527e..50a2b46 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -613,6 +613,7 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, - struct sk_buff *skb, u16 *vid); - bool br_allowed_egress(struct net_bridge *br, const struct net_port_vlans *v, - const struct sk_buff *skb); -+bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid); - struct sk_buff *br_handle_vlan(struct net_bridge *br, - const struct net_port_vlans *v, - struct sk_buff *skb); -@@ -680,6 +681,12 @@ static inline bool br_allowed_egress(struct net_bridge *br, - return true; - } - -+static inline bool br_should_learn(struct net_bridge_port *p, -+ struct sk_buff *skb, u16 *vid) -+{ -+ return true; -+} -+ - static inline struct sk_buff *br_handle_vlan(struct net_bridge *br, - const struct net_port_vlans *v, - struct sk_buff *skb) -diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c -index 655c2e9..dc00f12 100644 ---- a/net/bridge/br_vlan.c -+++ b/net/bridge/br_vlan.c -@@ -233,6 +233,34 @@ bool br_allowed_egress(struct net_bridge *br, - return false; - } - -+/* Called under RCU */ -+bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) -+{ -+ struct net_bridge *br = p->br; -+ struct net_port_vlans *v; -+ -+ if (!br->vlan_enabled) -+ return true; -+ -+ v = rcu_dereference(p->vlan_info); -+ if (!v) -+ return false; -+ -+ br_vlan_get_tag(skb, vid); -+ if (!*vid) { -+ *vid = br_get_pvid(v); -+ if (*vid == VLAN_N_VID) -+ return false; -+ -+ return true; -+ } -+ -+ if (test_bit(*vid, v->vlan_bitmap)) -+ return true; -+ -+ return false; -+} -+ - /* Must be protected by RTNL. - * Must be called with vid in range from 1 to 4094 inclusive. - */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-pvst.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-pvst.patch deleted file mode 100644 index 422dbe9b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-pvst.patch +++ /dev/null @@ -1,33 +0,0 @@ -For Cisco STP MAC, do similar processing as IEEE STP MAC - -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index 392bb58..61f60bb 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -21,6 +21,7 @@ - - /* Bridge group multicast address 802.1d (pg 51). */ - const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; -+const u8 br_pvst_address[ETH_ALEN] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcd }; - - /* Hook for brouter */ - br_should_route_hook_t __rcu *br_should_route_hook __read_mostly; -@@ -168,6 +169,18 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) - return RX_HANDLER_CONSUMED; - - p = br_port_get_rcu(skb->dev); -+ if (!compare_ether_addr(br_pvst_address, dest)) { -+ if (p->br->stp_enabled == BR_NO_STP) -+ goto forward; -+ /* Deliver packet to local host only */ -+ if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, -+ NULL, br_handle_local_finish)) { -+ return RX_HANDLER_CONSUMED; /* consumed by filter */ -+ } else { -+ *pskb = skb; -+ return RX_HANDLER_PASS; /* continue processing */ -+ } -+ } - - if (unlikely(is_link_local(dest))) { - /* diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-querier-ifaddr.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-querier-ifaddr.patch deleted file mode 100644 index ea798702..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-querier-ifaddr.patch +++ /dev/null @@ -1,66 +0,0 @@ -When querier is configured and IP address is got only from the bridge device and not from management/loopback interfaces - -diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h -index 5f81466..85bb88e 100644 ---- a/include/linux/inetdevice.h -+++ b/include/linux/inetdevice.h -@@ -172,6 +172,7 @@ extern int devinet_ioctl(struct net *net, unsigned int cmd, void __user *); - extern void devinet_init(void); - extern struct in_device *inetdev_by_index(struct net *, int); - extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope); -+extern __be32 inet_dev_select_addr(const struct net_device *dev, __be32 dst, int scope); - extern __be32 inet_confirm_addr(struct in_device *in_dev, __be32 dst, __be32 local, int scope); - extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, __be32 mask); - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index b38315c..622c082 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -385,7 +385,7 @@ static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br, - iph->ttl = 1; - iph->protocol = IPPROTO_IGMP; - iph->saddr = br->multicast_query_use_ifaddr ? -- inet_select_addr(br->dev, 0, RT_SCOPE_LINK) : 0; -+ inet_dev_select_addr(br->dev, 0, RT_SCOPE_LINK) : 0; - iph->daddr = htonl(INADDR_ALLHOSTS_GROUP); - ((u8 *)&iph[1])[0] = IPOPT_RA; - ((u8 *)&iph[1])[1] = 4; -diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c -index e41c40f..f9e6a35 100644 ---- a/net/ipv4/devinet.c -+++ b/net/ipv4/devinet.c -@@ -1011,6 +1011,34 @@ out_unlock: - } - EXPORT_SYMBOL(inet_select_addr); - -+__be32 inet_dev_select_addr(const struct net_device *dev, __be32 dst, int scope) -+{ -+ __be32 addr = 0; -+ struct in_device *in_dev; -+ struct net *net = dev_net(dev); -+ -+ rcu_read_lock(); -+ in_dev = __in_dev_get_rcu(dev); -+ if (!in_dev) -+ goto no_in_dev; -+ -+ for_primary_ifa(in_dev) { -+ if (ifa->ifa_scope > scope) -+ continue; -+ if (!dst || inet_ifa_match(dst, ifa)) { -+ addr = ifa->ifa_local; -+ break; -+ } -+ if (!addr) -+ addr = ifa->ifa_local; -+ } endfor_ifa(in_dev); -+ -+no_in_dev: -+ rcu_read_unlock(); -+ return addr; -+} -+EXPORT_SYMBOL(inet_dev_select_addr); -+ - static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst, - __be32 local, int scope) - { diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-rearrange-fdb-notifications.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-rearrange-fdb-notifications.patch deleted file mode 100644 index 33fcd868..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-rearrange-fdb-notifications.patch +++ /dev/null @@ -1,214 +0,0 @@ -This patch is a pull of the following upstream patch: - -"31e8a49c161b00c648e960903512c9cbaee777b1 bridge: rearrange fdb notifications (v2)" - -http://patchwork.ozlabs.org/patch/130198/ - -Pulled this patch to get the right fdb state propagated in fdb notify during -bridge fdb entry creation - -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index c8e7861..6274732 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -28,7 +28,7 @@ - static struct kmem_cache *br_fdb_cache __read_mostly; - static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, - const unsigned char *addr); --static void fdb_notify(const struct net_bridge_fdb_entry *, int); -+static void fdb_notify(struct net_bridge *br, const struct net_bridge_fdb_entry *, int); - - static u32 fdb_salt __read_mostly; - -@@ -80,10 +80,10 @@ static void fdb_rcu_free(struct rcu_head *head) - kmem_cache_free(br_fdb_cache, ent); - } - --static inline void fdb_delete(struct net_bridge_fdb_entry *f) -+static inline void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f) - { -- fdb_notify(f, RTM_DELNEIGH); - hlist_del_rcu(&f->hlist); -+ fdb_notify(br, f, RTM_DELNEIGH); - call_rcu(&f->rcu, fdb_rcu_free); - } - -@@ -114,7 +114,7 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) - } - - /* delete old one */ -- fdb_delete(f); -+ fdb_delete(br, f); - goto insert; - } - } -@@ -144,7 +144,7 @@ void br_fdb_cleanup(unsigned long _data) - continue; - this_timer = f->updated + delay; - if (time_before_eq(this_timer, jiffies)) -- fdb_delete(f); -+ fdb_delete(br, f); - else if (time_before(this_timer, next_timer)) - next_timer = this_timer; - } -@@ -165,7 +165,7 @@ void br_fdb_flush(struct net_bridge *br) - struct hlist_node *h, *n; - hlist_for_each_entry_safe(f, h, n, &br->hash[i], hlist) { - if (!f->is_static) -- fdb_delete(f); -+ fdb_delete(br, f); - } - } - spin_unlock_bh(&br->hash_lock); -@@ -209,7 +209,7 @@ void br_fdb_delete_by_port(struct net_bridge *br, - } - } - -- fdb_delete(f); -+ fdb_delete(br, f); - skip_delete: ; - } - } -@@ -347,7 +347,6 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, - fdb->is_static = 0; - fdb->updated = fdb->used = jiffies; - hlist_add_head_rcu(&fdb->hlist, head); -- fdb_notify(fdb, RTM_NEWNEIGH); - } - return fdb; - } -@@ -371,7 +370,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, - br_warn(br, "adding interface %s with same address " - "as a received packet\n", - source->dev->name); -- fdb_delete(fdb); -+ fdb_delete(br, fdb); - } - - fdb = fdb_create(head, source, addr); -@@ -379,6 +378,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, - return -ENOMEM; - - fdb->is_local = fdb->is_static = 1; -+ fdb_notify(br, fdb, RTM_NEWNEIGH); - return 0; - } - -@@ -419,13 +419,15 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, - source->dev->name); - } else { - /* fastpath: update of existing entry */ -- fdb->dst = source; - fdb->updated = jiffies; - } - } else { - spin_lock(&br->hash_lock); -- if (likely(!fdb_find(head, addr))) -- fdb_create(head, source, addr); -+ if (likely(!fdb_find(head, addr))) { -+ fdb = fdb_create(head, source, addr); -+ if (fdb) -+ fdb_notify(br, fdb, RTM_NEWNEIGH); -+ } - - /* else we lose race and someone else inserts - * it first, don't bother updating -@@ -446,7 +448,7 @@ static int fdb_to_nud(const struct net_bridge_fdb_entry *fdb) - return NUD_REACHABLE; - } - --static int fdb_fill_info(struct sk_buff *skb, -+static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br, - const struct net_bridge_fdb_entry *fdb, - u32 pid, u32 seq, int type, unsigned int flags) - { -@@ -491,7 +493,8 @@ static inline size_t fdb_nlmsg_size(void) - + nla_total_size(sizeof(struct nda_cacheinfo)); - } - --static void fdb_notify(const struct net_bridge_fdb_entry *fdb, int type) -+static void fdb_notify(struct net_bridge *br, -+ const struct net_bridge_fdb_entry *fdb, int type) - { - struct net *net = dev_net(fdb->dst->dev); - struct sk_buff *skb; -@@ -501,7 +504,7 @@ static void fdb_notify(const struct net_bridge_fdb_entry *fdb, int type) - if (skb == NULL) - goto errout; - -- err = fdb_fill_info(skb, fdb, 0, 0, type, 0); -+ err = fdb_fill_info(skb, br, fdb, 0, 0, type, 0); - if (err < 0) { - /* -EMSGSIZE implies BUG in fdb_nlmsg_size() */ - WARN_ON(err == -EMSGSIZE); -@@ -538,7 +541,7 @@ int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) - if (idx < cb->args[0]) - goto skip; - -- if (fdb_fill_info(skb, f, -+ if (fdb_fill_info(skb, br, f, - NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, - RTM_NEWNEIGH, -@@ -572,19 +575,25 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, - fdb = fdb_create(head, source, addr); - if (!fdb) - return -ENOMEM; -+ fdb_notify(br, fdb, RTM_NEWNEIGH); - } else { - if (flags & NLM_F_EXCL) - return -EEXIST; -+ } -+ -+ if (fdb_to_nud(fdb) != state) { -+ if (state & NUD_PERMANENT) -+ fdb->is_local = fdb->is_static = 1; -+ else if (state & NUD_NOARP) { -+ fdb->is_local = 0; -+ fdb->is_static = 1; -+ } else -+ fdb->is_local = fdb->is_static = 0; - -- if (flags & NLM_F_REPLACE) -- fdb->updated = fdb->used = jiffies; -- fdb->is_local = fdb->is_static = 0; -+ fdb->updated = fdb->used = jiffies; -+ fdb_notify(br, fdb, RTM_NEWNEIGH); - } - -- if (state & NUD_PERMANENT) -- fdb->is_local = fdb->is_static = 1; -- else if (state & NUD_NOARP) -- fdb->is_static = 1; - return 0; - } - -@@ -641,9 +650,8 @@ int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - return err; - } - --static int fdb_delete_by_addr(struct net_bridge_port *p, const u8 *addr) -+static int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr) - { -- struct net_bridge *br = p->br; - struct hlist_head *head = &br->hash[br_mac_hash(addr)]; - struct net_bridge_fdb_entry *fdb; - -@@ -651,7 +659,7 @@ static int fdb_delete_by_addr(struct net_bridge_port *p, const u8 *addr) - if (!fdb) - return -ENOENT; - -- fdb_delete(fdb); -+ fdb_delete(br, fdb); - return 0; - } - -@@ -698,7 +706,7 @@ int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - } - - spin_lock_bh(&p->br->hash_lock); -- err = fdb_delete_by_addr(p, addr); -+ err = fdb_delete_by_addr(p->br, addr); - spin_unlock_bh(&p->br->hash_lock); - - return err; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-remove-vid-end-check.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-remove-vid-end-check.patch deleted file mode 100644 index 015fecf8..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-remove-vid-end-check.patch +++ /dev/null @@ -1,21 +0,0 @@ -bridge: remove check for vid_end - -If range not specified, make vid_end same as vid. -This will prevent upstream `bridge vlan add` from failing with -EINVAL - -diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c -index 7cb55c6..4544c7b 100644 ---- a/net/bridge/br_netlink.c -+++ b/net/bridge/br_netlink.c -@@ -337,7 +337,10 @@ static int br_afspec(struct net_bridge *br, - if (!vinfo->vid || vinfo->vid >= VLAN_VID_MASK) - return -EINVAL; - -- if (!vinfo->vid_end || vinfo->vid_end >= VLAN_VID_MASK) -+ if (!vinfo->vid_end) -+ vinfo->vid_end = vinfo->vid; -+ -+ if (vinfo->vid_end >= VLAN_VID_MASK) - return -EINVAL; - - switch (cmd) { diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-report-supression.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-report-supression.patch deleted file mode 100644 index e82cf3eb..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-report-supression.patch +++ /dev/null @@ -1,269 +0,0 @@ -1. IGMP/MLD reports need to be software forwarded towards router ports -2. When IGMP snooping is disabled, IGMP/MLD packets need to be flooded -3. When a router port is detected or statically configured, it should - be treated as if a querier exists in the network to do multicast - forwarding to router ports for IGMP/MLD reports - -diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c -index 998d46d..34cf90d 100644 ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -70,7 +70,8 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) - - mdst = br_mdb_get(br, skb, vid); - if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && -- br_multicast_querier_exists(br, eth_hdr(skb))) -+ (br_multicast_querier_exists(br, eth_hdr(skb)) || -+ !hlist_empty(&br->router_list))) - br_multicast_deliver(mdst, skb); - else - br_flood_deliver(br, skb, false); -diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c -index d6854a4..79ab806 100644 ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -100,6 +100,8 @@ static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) - const unsigned char *dest = eth_hdr(skb)->h_dest; - struct net_bridge_port *p = br_port_get_rcu(skb->dev); - struct net_bridge *br = p->br; -+ __u8 igmp_report_leave_forward = 0; -+ - - /* flood forward STP/PVST BPDU when received and STP is disabled */ - if ((!compare_ether_addr(br_group_address, dest) || -@@ -107,8 +109,12 @@ static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) - (br->stp_enabled == BR_NO_STP)) { - stp_disabled_forward = 1; - } -+ /* flood forward IGMP/MLD report/leave when hardware forwarded */ -+ if (br_hw_fwding_enabled && br_multicast_is_rep_leave(skb)) -+ igmp_report_leave_forward = 1; - -- if (br_hw_fwding_enabled && !stp_disabled_forward) { -+ if (br_hw_fwding_enabled && !stp_disabled_forward && -+ !igmp_report_leave_forward) { - NF_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, skb->dev, to->dev, - br_hw_forward_finish); - return; -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index d2f8c04..602a0fc 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -117,8 +117,11 @@ int br_handle_frame_finish(struct sk_buff *skb) - unicast = false; - } else if (is_multicast_ether_addr(dest) || stp_disabled_forward) { - mdst = br_mdb_get(br, skb, vid); -- if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && -- br_multicast_querier_exists(br, eth_hdr(skb))) { -+ if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb) || -+ (BR_INPUT_SKB_CB(skb)->igmp_mld_rep_leave_fwd && -+ br_hw_fwding_enabled)) && -+ (br_multicast_querier_exists(br, eth_hdr(skb)) || -+ !hlist_empty(&br->router_list))) { - if ((mdst && mdst->mglist) || - br_multicast_is_router(br)) - skb2 = skb; -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 000cc59..7fc1f1b 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -45,6 +45,7 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br, - struct net_bridge_port *port, const struct in6_addr *group, __u16 vid); - #endif - unsigned int br_mdb_rehash_seq; -+extern int br_hw_fwding_enabled; - - /* ported from net/ipv6/addrconf.c */ - static u32 ipv6_addr_hash(const struct in6_addr *addr) -@@ -1655,20 +1656,39 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, - - BR_INPUT_SKB_CB(skb)->igmp = 1; - ih = igmp_hdr(skb2); -+ /* When IGMP snooping is disabled, flood forward all IGMP packets */ -+ if (br->multicast_disabled) { -+ switch (ih->type) { -+ case IGMP_HOST_MEMBERSHIP_REPORT: -+ case IGMPV2_HOST_MEMBERSHIP_REPORT: -+ case IGMPV3_HOST_MEMBERSHIP_REPORT: -+ case IGMP_HOST_LEAVE_MESSAGE: -+ if (br_hw_fwding_enabled) -+ BR_INPUT_SKB_CB(skb)->igmp_mld_rep_leave_fwd = 1; -+ break; -+ case IGMP_HOST_MEMBERSHIP_QUERY: -+ break; -+ } -+ goto out; -+ } - - switch (ih->type) { - case IGMP_HOST_MEMBERSHIP_REPORT: - case IGMPV2_HOST_MEMBERSHIP_REPORT: - BR_INPUT_SKB_CB(skb)->mrouters_only = 1; -+ /* Mark report/leaves to be forwarded */ -+ BR_INPUT_SKB_CB(skb)->igmp_mld_rep_leave_fwd = 1; - err = br_ip4_multicast_add_group(br, port, ih->group, vid); - break; - case IGMPV3_HOST_MEMBERSHIP_REPORT: -+ BR_INPUT_SKB_CB(skb)->igmp_mld_rep_leave_fwd = 1; - err = br_ip4_multicast_igmp3_report(br, port, skb2, vid); - break; - case IGMP_HOST_MEMBERSHIP_QUERY: - err = br_ip4_multicast_query(br, port, skb2, vid); - break; - case IGMP_HOST_LEAVE_MESSAGE: -+ BR_INPUT_SKB_CB(skb)->igmp_mld_rep_leave_fwd = 1; - br_ip4_multicast_leave_group(br, port, ih->group, vid); - break; - } -@@ -1803,6 +1823,21 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, - - BR_INPUT_SKB_CB(skb)->igmp = 1; - -+ /* When IGMP snooping is disabled, flood forward all MLD packets */ -+ if (br->multicast_disabled) { -+ switch (icmp6_type) { -+ case ICMPV6_MGM_REPORT: -+ case ICMPV6_MLD2_REPORT: -+ case ICMPV6_MGM_REDUCTION: -+ if (br_hw_fwding_enabled) -+ BR_INPUT_SKB_CB(skb)->igmp_mld_rep_leave_fwd = 1; -+ break; -+ case ICMPV6_MGM_QUERY: -+ break; -+ } -+ goto out; -+ } -+ - switch (icmp6_type) { - case ICMPV6_MGM_REPORT: - { -@@ -1813,10 +1848,13 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, - } - mld = (struct mld_msg *)skb_transport_header(skb2); - BR_INPUT_SKB_CB(skb)->mrouters_only = 1; -+ /* Mark report/leaves to be forwarded */ -+ BR_INPUT_SKB_CB(skb)->igmp_mld_rep_leave_fwd = 1; - err = br_ip6_multicast_add_group(br, port, &mld->mld_mca, vid); - break; - } - case ICMPV6_MLD2_REPORT: -+ BR_INPUT_SKB_CB(skb)->igmp_mld_rep_leave_fwd = 1; - err = br_ip6_multicast_mld2_report(br, port, skb2, vid); - break; - case ICMPV6_MGM_QUERY: -@@ -1829,6 +1867,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, - err = -EINVAL; - goto out; - } -+ BR_INPUT_SKB_CB(skb)->igmp_mld_rep_leave_fwd = 1; - mld = (struct mld_msg *)skb_transport_header(skb2); - br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid); - } -@@ -1846,9 +1885,6 @@ int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, - BR_INPUT_SKB_CB(skb)->igmp = 0; - BR_INPUT_SKB_CB(skb)->mrouters_only = 0; - -- if (br->multicast_disabled) -- return 0; -- - switch (skb->protocol) { - case htons(ETH_P_IP): - return br_multicast_ipv4_rcv(br, port, skb, vid); -@@ -2451,3 +2487,28 @@ void br_mdb_leave_topology_change(struct net_bridge *br, - } - } - } -+ -+/* check if the SKB is an IGMP/MLD report/leave -+ */ -+bool br_multicast_is_rep_leave(struct sk_buff *skb) -+{ -+ const struct iphdr *iph; -+ struct igmphdr *ih; -+ -+ if (BR_INPUT_SKB_CB(skb)->igmp_mld_rep_leave_fwd) -+ return true; -+ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ iph = ip_hdr(skb); -+ if (iph->protocol == IPPROTO_IGMP) { -+ ih = igmp_hdr(skb); -+ if ((ih->type == IGMP_HOST_MEMBERSHIP_REPORT) || -+ (ih->type == IGMPV2_HOST_MEMBERSHIP_REPORT) || -+ (ih->type == IGMPV3_HOST_MEMBERSHIP_REPORT) || -+ (ih->type == IGMP_HOST_LEAVE_MESSAGE)) -+ return true; -+ } -+ } -+ -+ return false; -+} -diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c -index 2710379..63d473e 100644 ---- a/net/bridge/br_netfilter.c -+++ b/net/bridge/br_netfilter.c -@@ -732,6 +732,7 @@ static int br_nf_forward_finish(struct sk_buff *skb) - { - struct nf_bridge_info *nf_bridge = skb->nf_bridge; - struct net_device *in; -+ __u8 igmp_report_leave_forward = 0; - - if (!IS_ARP(skb) && !IS_VLAN_ARP(skb)) { - in = nf_bridge->physindev; -@@ -744,8 +745,11 @@ static int br_nf_forward_finish(struct sk_buff *skb) - in = *((struct net_device **)(skb->cb)); - } - nf_bridge_push_encap_header(skb); -+ /* flood forward IGMP/MLD report/leave when hardware forwarded */ -+ if (br_hw_fwding_enabled && br_multicast_is_rep_leave(skb)) -+ igmp_report_leave_forward = 1; - -- if (br_hw_fwding_enabled) { -+ if (br_hw_fwding_enabled && !igmp_report_leave_forward) { - NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, in, - skb->dev, br_hw_forward_finish, 1); - } else { -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index e4ef7ca..c5fe7c0 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -310,6 +310,7 @@ struct br_input_skb_cb { - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - int igmp; - int mrouters_only; -+ int igmp_mld_rep_leave_fwd; - #endif - }; - -@@ -514,8 +515,11 @@ static inline bool - __br_multicast_querier_exists(struct net_bridge *br, - struct bridge_mcast_querier *querier) - { -- return time_is_before_jiffies(querier->delay_time) && -- (br->multicast_querier || timer_pending(&querier->timer)); -+ /* check if multicast querier is configured, detected dynamically -+ * or configured statically -+ */ -+ return ((time_is_before_jiffies(querier->delay_time) && -+ (br->multicast_querier || timer_pending(&querier->timer)))); - } - - static inline bool br_multicast_querier_exists(struct net_bridge *br, -@@ -537,6 +541,7 @@ static inline bool br_multicast_querier_exists(struct net_bridge *br, - int br_multicast_add_querier_src(struct net_bridge *br, struct br_ip *src); - int br_multicast_del_querier_src(struct net_bridge *br, struct br_ip *src); - #endif -+bool br_multicast_is_rep_leave(struct sk_buff *skb); - - #else - static inline int br_multicast_rcv(struct net_bridge *br, -@@ -606,6 +611,9 @@ static inline void br_mdb_init(void) - static inline void br_mdb_uninit(void) - { - } -+static inline bool br_multicast_is_rep_leave(struct sk_buff *skb) -+{ -+} - #endif - - /* br_vlan.c */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-revert-v6-link-local-snoop.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-revert-v6-link-local-snoop.patch deleted file mode 100644 index 65f9176c..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-revert-v6-link-local-snoop.patch +++ /dev/null @@ -1,98 +0,0 @@ -This commit reverts the below commit in upstream bridge driver, -for cumulus linux. - -commit 3c3769e63301fd92fcaf51870c371583dd0282ce -Author: Linus Lüssing -Date: Wed Sep 4 02:13:39 2013 +0200 - - bridge: apply multicast snooping to IPv6 link-local, too - - The multicast snooping code should have matured enough to be safely - applicable to IPv6 link-local multicast addresses (excluding the - link-local all nodes address, ff02::1), too. - - Signed-off-by: Linus Lüssing - Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index c3d9406..80f648f 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -9,7 +9,6 @@ - #include - #if IS_ENABLED(CONFIG_IPV6) - #include --#include - #endif - - #include "br_private.h" -@@ -344,7 +343,7 @@ static bool is_valid_mdb_entry(struct br_mdb_entry *entry) - return false; - #if IS_ENABLED(CONFIG_IPV6) - } else if (entry->addr.proto == htons(ETH_P_IPV6)) { -- if (ipv6_addr_is_ll_all_nodes(&entry->addr.u.ip6)) -+ if (!ipv6_is_transient_multicast(&entry->addr.u.ip6)) - return false; - #endif - } else -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index d72456e..fec8e6a 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -29,7 +29,6 @@ - #include - #include - #include --#include - #endif - - #include "br_private.h" -@@ -785,7 +784,7 @@ static int br_ip6_multicast_add_group(struct net_bridge *br, - { - struct br_ip br_group; - -- if (ipv6_addr_is_ll_all_nodes(group)) -+ if (!ipv6_is_transient_multicast(group)) - return 0; - - br_group.u.ip6 = *group; -@@ -1535,8 +1534,7 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br, - struct bridge_mcast_query *query = port ? &port->ip6_query : - &br->ip6_query; - -- -- if (ipv6_addr_is_ll_all_nodes(group)) -+ if (!ipv6_is_transient_multicast(group)) - return; - - br_group.u.ip6 = *group; -@@ -1675,7 +1673,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, - return 0; - - /* Prevent flooding this packet if there is no listener present */ -- if (!ipv6_addr_is_ll_all_nodes(&ip6h->daddr)) -+ if (!ipv6_is_transient_multicast(&ip6h->daddr)) - BR_INPUT_SKB_CB(skb)->mrouters_only = 1; - - if (ip6h->nexthdr != IPPROTO_HOPOPTS || -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 30ff5e1..a7f764d 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -489,6 +489,16 @@ extern void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, - #define mlock_dereference(X, br) \ - rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) - -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+static inline int ipv6_is_transient_multicast(const struct in6_addr *addr) -+{ -+ if (ipv6_addr_is_multicast(addr) && IPV6_ADDR_MC_FLAG_TRANSIENT(addr)) -+ return 1; -+ return 0; -+} -+#endif -+ - static inline bool br_multicast_is_router(struct net_bridge *br) - { - return br->multicast_router == 2 || diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-send-query-as-soon-as-leave-is-received.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-send-query-as-soon-as-leave-is-received.patch deleted file mode 100644 index 3554a0d5..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-send-query-as-soon-as-leave-is-received.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 6b7df111ece130fa979a0c4f58e53674c1e47d3e Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: send query as soon as leave is received - -Continue sending queries when leave is received if the user marks -it as a querier. - -Cc: Herbert Xu -Cc: Stephen Hemminger -Cc: "David S. Miller" -Cc: Adam Baker -Signed-off-by: Cong Wang -Acked-by: Herbert Xu -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 5977be7..96f876e 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1246,6 +1246,32 @@ static void br_multicast_leave_group(struct net_bridge *br, - if (!mp) - goto out; - -+ if (br->multicast_querier && -+ !timer_pending(&br->multicast_querier_timer)) { -+ __br_multicast_send_query(br, port, &mp->addr); -+ -+ time = jiffies + br->multicast_last_member_count * -+ br->multicast_last_member_interval; -+ mod_timer(port ? &port->multicast_query_timer : -+ &br->multicast_query_timer, time); -+ -+ for (p = mlock_dereference(mp->ports, br); -+ p != NULL; -+ p = mlock_dereference(p->next, br)) { -+ if (p->port != port) -+ continue; -+ -+ if (!hlist_unhashed(&p->mglist) && -+ (timer_pending(&p->timer) ? -+ time_after(p->timer.expires, time) : -+ try_to_del_timer_sync(&p->timer) >= 0)) { -+ mod_timer(&p->timer, time); -+ } -+ -+ break; -+ } -+ } -+ - if (port && port->multicast_fast_leave) { - struct net_bridge_port_group __rcu **pp; - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-single-stp.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-single-stp.patch deleted file mode 100644 index 7522111b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-single-stp.patch +++ /dev/null @@ -1,308 +0,0 @@ -Added support for single stp mode. In this mode, all bridges are enabled - -with user mode spanningtree by default. - -diff --git a/net/bridge/br.c b/net/bridge/br.c -index 2736e3d..9387007 100644 ---- a/net/bridge/br.c -+++ b/net/bridge/br.c -@@ -27,6 +27,13 @@ int br_hw_fwding_enabled = 1; - MODULE_PARM_DESC(hw_fwding, "Enable hw forwarding"); - module_param_named(hw_fwding, br_hw_fwding_enabled, int, 0644); - -+int br_allow_multiple_vlans = 0; -+ -+MODULE_PARM_DESC(allow_multiple_vlans, "Allow multiple vlans in a bridge"); -+module_param_named(allow_multiple_vlans, br_allow_multiple_vlans, int, 0644); -+ -+struct bridge_list bridges; -+ - static void __net_exit br_net_exit(struct net *net) - { - struct net_device *dev; -@@ -53,13 +60,15 @@ static const struct stp_proto br_stp_proto = { - #ifdef CONFIG_SYSCTL - static struct ctl_table_header *brstp_sysctl_header; - int brstp_user_space __read_mostly = 1; -- -+int brstp_user_space_single __read_mostly = 0; -+int brstp_stp_state_logging = 0; - static - int brstp_sysctl_call_tables(ctl_table * ctl, int write, - void __user * buffer, size_t * lenp, loff_t * ppos) - { - int ret; - int old_brstp_user_space = brstp_user_space; -+ int old_brstp_user_space_single = brstp_user_space_single; - - ret = proc_dointvec(ctl, write, buffer, lenp, ppos); - if (old_brstp_user_space != brstp_user_space) { -@@ -76,6 +85,9 @@ int brstp_sysctl_call_tables(ctl_table * ctl, int write, - } - } - -+ if (old_brstp_user_space_single != brstp_user_space_single) -+ br_set_single_stp_mode(brstp_user_space_single); -+ - return ret; - } - -@@ -87,6 +99,20 @@ static ctl_table brstp_table[] = { - .mode = 0644, - .proc_handler = brstp_sysctl_call_tables, - }, -+ { -+ .procname = "bridge-stp-user-space-single", -+ .data = &brstp_user_space_single, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = brstp_sysctl_call_tables, -+ }, -+ { -+ .procname = "bridge-stp-state-logging", -+ .data = &brstp_stp_state_logging, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = brstp_sysctl_call_tables, -+ }, - { } - }; - -@@ -97,6 +123,8 @@ static struct ctl_path brstp_path[] = { - }; - #else - #define brstp_user_space 1 -+#define brstp_user_space_single 1 -+#define brstp_stp_state_logging 0 - #endif - - static int __init br_init(void) -@@ -120,6 +148,9 @@ static int __init br_init(void) - } - } - -+ memset(&bridges, 0, sizeof(bridges)); -+ INIT_LIST_HEAD(&bridges); -+ - err = br_fdb_init(); - if (err) - goto err_out; -diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c -index 4218709..7ea60d9 100644 ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -391,7 +391,10 @@ void br_dev_setup(struct net_device *dev) - - memcpy(br->group_addr, eth_reserved_addr_base, ETH_ALEN); - -- br->stp_enabled = BR_NO_STP; -+ if (brstp_user_space_single) -+ br->stp_enabled = BR_USER_STP; -+ else -+ br->stp_enabled = BR_NO_STP; - br->group_fwd_mask = BR_GROUPFWD_DEFAULT; - - br->designated_root = br->bridge_id; -@@ -403,4 +406,6 @@ void br_dev_setup(struct net_device *dev) - br_netfilter_rtable_init(br); - br_stp_timer_init(br); - br_multicast_init(br); -+ -+ list_add_rcu(&br->list, &bridges.list); - } -diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c -index c11df2d..004b220 100644 ---- a/net/bridge/br_if.c -+++ b/net/bridge/br_if.c -@@ -169,6 +169,8 @@ void br_dev_delete(struct net_device *dev, struct list_head *head) - struct net_bridge *br = netdev_priv(dev); - struct net_bridge_port *p, *n; - -+ list_del_rcu(&br->list); -+ - list_for_each_entry_safe(p, n, &br->port_list, list) { - del_nbp(p); - } -@@ -324,6 +326,49 @@ netdev_features_t br_features_recompute(struct net_bridge *br, - return features; - } - -+static bool is_dev_in_same_vlan(struct net_bridge *br, -+ struct net_device *dev) -+{ -+ struct net_bridge_port *p; -+ u16 vlan_id; -+ -+ if (!is_vlan_dev(dev)) -+ return true; -+ -+ vlan_id = vlan_dev_vlan_id(dev); -+ -+ list_for_each_entry_rcu(p, &br->port_list, list) { -+ if (!is_vlan_dev(p->dev)) -+ continue; -+ if (vlan_id != vlan_dev_vlan_id(p->dev)) -+ return false; -+ } -+ return true; -+} -+ -+static bool is_dev_vlan_in_conflict(struct net_bridge *br, -+ struct net_device *dev) -+{ -+ struct net_bridge_port *p; -+ struct net_bridge *b; -+ u16 vlan_id; -+ -+ vlan_id = vlan_dev_vlan_id(dev); -+ -+ list_for_each_entry_rcu(b, &bridges.list, list) { -+ if (b == br || dev_net(b->dev) != dev_net(br->dev)) -+ continue; -+ list_for_each_entry_rcu(p, &b->port_list, list) { -+ if (!is_vlan_dev(p->dev)) -+ continue; -+ if (vlan_dev_vlan_id(p->dev) == vlan_id) -+ return true; -+ } -+ } -+ return false; -+} -+ -+ - /* called with RTNL */ - int br_add_if(struct net_bridge *br, struct net_device *dev) - { -@@ -349,6 +394,11 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) - if (dev->priv_flags & IFF_DONT_BRIDGE) - return -EOPNOTSUPP; - -+ /* Disallow vlan devices of same vlan but added to different bridges */ -+ if (!br_allow_multiple_vlans && is_vlan_dev(dev) && -+ is_dev_vlan_in_conflict(br, dev)) -+ return -EINVAL; -+ - p = new_nbp(br, dev); - if (IS_ERR(p)) - return PTR_ERR(p); -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index c80f94d..49eb2a6 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -213,6 +213,7 @@ static inline struct net_bridge_port *br_port_get_rtnl(const struct net_device * - struct net_bridge - { - spinlock_t lock; -+ struct list_head list; - struct list_head port_list; - struct net_device *dev; - u8 initial_addr[ETH_ALEN]; -@@ -297,6 +298,10 @@ struct net_bridge - #endif - }; - -+struct bridge_list { -+ struct list_head list; -+}; -+ - struct br_input_skb_cb { - struct net_device *brdev; - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING -@@ -336,6 +341,12 @@ static inline int br_is_root_bridge(const struct net_bridge *br) - return !memcmp(&br->bridge_id, &br->designated_root, 8); - } - -+extern int brstp_user_space; -+extern int brstp_user_space_single; -+extern int brstp_stp_state_logging; -+extern int br_allow_multiple_vlans; -+extern struct bridge_list bridges; -+ - /* br_device.c */ - void br_dev_setup(struct net_device *dev); - void br_dev_delete(struct net_device *dev, struct list_head *list); -@@ -747,6 +758,7 @@ void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio); - int br_stp_set_port_priority(struct net_bridge_port *p, unsigned long newprio); - int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost); - ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id); -+void br_set_single_stp_mode(int mode); - - /* br_stp_bpdu.c */ - struct stp_proto; -diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c -index 4a36459..75f2d1e 100644 ---- a/net/bridge/br_stp.c -+++ b/net/bridge/br_stp.c -@@ -31,6 +31,9 @@ static const char *const br_port_state_names[] = { - - void br_log_state(const struct net_bridge_port *p) - { -+ if (!brstp_stp_state_logging) -+ return; -+ - br_info(p->br, "port %u(%s) entered %s state\n", - (unsigned int) p->port_no, p->dev->name, - br_port_state_names[p->state]); -diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c -index 4ed11ab..9c5ccd4 100644 ---- a/net/bridge/br_stp_if.c -+++ b/net/bridge/br_stp_if.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #include "br_private.h" - #include "br_private_stp.h" -@@ -170,6 +171,11 @@ static void br_stp_stop(struct net_bridge *br) - char *envp[] = { NULL }; - struct net_bridge_port *p; - -+ if (brstp_user_space_single) { -+ br_info(br, "single mode STP is on, cannot disable STP\n"); -+ return; -+ } -+ - if (br->stp_enabled == BR_USER_STP) { - r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); - br_info(br, "userspace STP stopped, return code %d\n", r); -@@ -181,8 +187,10 @@ static void br_stp_stop(struct net_bridge *br) - mod_timer(&p->hold_timer, - round_jiffies(jiffies + BR_HOLD_TIME)); - } -+ br->stp_enabled = BR_NO_STP; - br_port_state_selection(br); - spin_unlock_bh(&br->lock); -+ return; - } - - br->stp_enabled = BR_NO_STP; -@@ -201,6 +209,27 @@ void br_stp_set_enabled(struct net_bridge *br, unsigned long val) - } - } - -+void br_set_single_stp_mode(int mode) -+{ -+ int r; -+ char *argv[] = { BR_STP_PROG, "_single_mode_stp_", "stop", NULL }; -+ char *envp[] = { NULL }; -+ -+ if (mode) { -+ /* loop through all bridges, make sure stp is enabled */ -+ struct net_bridge *br; -+ -+ list_for_each_entry(br, &bridges.list, list) { -+ if (br->stp_enabled != BR_USER_STP) -+ br_stp_start(br); -+ } -+ argv[2] = "start"; -+ } -+ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); -+ printk(KERN_INFO "Single STP mode: %s, return code %d\n", -+ mode?"on":"off", r); -+} -+ - /* called under bridge lock */ - void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr) - { diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-solicited-node-forward.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-solicited-node-forward.patch deleted file mode 100644 index 2edb4417..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-solicited-node-forward.patch +++ /dev/null @@ -1,45 +0,0 @@ -Since solicited node and IPv4 link local multicast MDB group is not created, we -exclude optimized router forwarding for solicited node and link local multicast -packets - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index b16f5cd..000cc59 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1682,6 +1682,23 @@ err_out: - } - - #if IS_ENABLED(CONFIG_IPV6) -+/* Check if addr is solicited node multicast FF02::1:FFxx:xxxx -+ */ -+static inline int is_solicited_node_mcast(const struct in6_addr *addr) -+{ -+ return ((((addr->s6_addr32[0] ^ htonl(0xff020000)) | -+ addr->s6_addr32[1] | (addr->s6_addr32[2] ^ htonl(0x00000001))) == 0) -+ && (addr->s6_addr[12] == 0xff)); -+} -+ -+/* Check if addr is link local multicast FF02::xx -+ */ -+static inline int is_link_local_ipv6_mcast(const struct in6_addr *addr) -+{ -+ return (((addr->s6_addr32[0] ^ htonl(0xff020000)) | -+ addr->s6_addr32[1] | addr->s6_addr16[6] | addr->s6_addr[14]) == 0); -+} -+ - static int br_multicast_ipv6_rcv(struct net_bridge *br, - struct net_bridge_port *port, - struct sk_buff *skb, -@@ -1710,9 +1727,10 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, - return 0; - - /* Prevent flooding this packet if there is no listener present */ -- if (!ipv6_is_transient_multicast(&ip6h->daddr)) -+ if (!ipv6_addr_is_ll_all_nodes(&ip6h->daddr) && -+ !(is_solicited_node_mcast(&ip6h->daddr)) && -+ !(is_link_local_ipv6_mcast(&ip6h->daddr))) - BR_INPUT_SKB_CB(skb)->mrouters_only = 1; -- - if (ip6h->nexthdr != IPPROTO_HOPOPTS || - ip6h->payload_len == 0) - return 0; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-static-addr.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-static-addr.patch deleted file mode 100644 index 4d8d1b4f..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-static-addr.patch +++ /dev/null @@ -1,194 +0,0 @@ -Realized the expected behavior when setting the address of the bridge device - -Prior to this patch, a user could set the address of a bridge device using... - - ip link set addr xx:xx:xx:xx:xx:xx dev brX - -however, frames destined to that address do not propagate to the bridge device -because an entry is not formulated in the bridge fdb (forwarding data base). - -This patch makes sure that an explicitly set (static) address is always -installed in the fdb, pointing to the bridge device, regardless of any interface -or dynamically learned address. It allows users to resume the traditional -behavior of inheriting an interface address by specifying a static address of -00:00:00:00:00:00. - -diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c -index aef0767..88d6172 100644 ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -181,17 +181,33 @@ static int br_change_mtu(struct net_device *dev, int new_mtu) - static int br_set_mac_address(struct net_device *dev, void *p) - { - struct net_bridge *br = netdev_priv(dev); -- struct sockaddr *addr = p; -+ const unsigned char *addr = ((struct sockaddr *)p)->sa_data; - -- if (!is_valid_ether_addr(addr->sa_data)) -+ if (is_multicast_ether_addr(addr)) - return -EADDRNOTAVAIL; - -+ if ((br->dev->addr_assign_type == NET_ADDR_SET) && -+ ether_addr_equal(addr, dev->dev_addr)) -+ return 0; -+ - spin_lock_bh(&br->lock); -- if (!ether_addr_equal(dev->dev_addr, addr->sa_data)) { -- memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); -- br_fdb_change_mac_address(br, addr->sa_data); -- br_stp_change_bridge_id(br, addr->sa_data); -- } -+ if (!ether_addr_equal(dev->dev_addr, addr)) { -+ if (is_zero_ether_addr(addr)) { -+ br_fdb_change_mac_address(br, addr); -+ br->dev->addr_assign_type = NET_ADDR_PERM; -+ br_stp_recalculate_bridge_id(br); -+ } else { -+ br_fdb_change_mac_address(br, addr); -+ memcpy(dev->dev_addr, addr, ETH_ALEN); -+ br_stp_change_bridge_id(br, addr); -+ br->dev->addr_assign_type = NET_ADDR_SET; -+ } -+ br_warn(br, "set br mac %02x:%02x:%02x:%02x:%02x:%02x", -+ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], -+ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); -+ } else -+ br->dev->addr_assign_type = NET_ADDR_SET; -+ - spin_unlock_bh(&br->lock); - - return 0; -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index c0e733e..924e87d 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -144,12 +144,28 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) - { - struct net_bridge_fdb_entry *f; - struct net_port_vlans *pv; -- u16 vid = 0; -+ u16 vid = 1; - -- /* If old entry was unassociated with any port, then delete it. */ -- f = __br_fdb_get(br, br->dev->dev_addr, 0); -- if (f && f->is_local && !f->dst) -- fdb_delete(br, f); -+ /* if address is already static, remove from the fdb */ -+ if (br->dev->addr_assign_type == NET_ADDR_SET) { -+ struct net_bridge_port *p; -+ -+ /* If old entry was unassociated with any port, then delete it. */ -+ f = __br_fdb_get(br, br->dev->dev_addr, 0); -+ if (f && f->is_local && !f->dst) -+ fdb_delete(br, f); -+ -+ /* re-add in case static address overloaded a port address*/ -+ list_for_each_entry(p, &br->port_list, list) { -+ if (ether_addr_equal(p->dev->dev_addr, br->dev->dev_addr)) { -+ fdb_insert(br, p, p->dev->dev_addr, 0); -+ break; -+ } -+ } -+ } -+ -+ if (is_zero_ether_addr(newaddr)) -+ return; - - fdb_insert(br, NULL, newaddr, 0); - -@@ -162,10 +178,25 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) - return; - - for_each_set_bit_from(vid, pv->vlan_bitmap, VLAN_N_VID) { -- f = __br_fdb_get(br, br->dev->dev_addr, vid); -- if (f && f->is_local && !f->dst) -- fdb_delete(br, f); -- fdb_insert(br, NULL, newaddr, vid); -+ if (br->dev->addr_assign_type == NET_ADDR_SET) { -+ struct net_bridge_port *p; -+ -+ f = __br_fdb_get(br, br->dev->dev_addr, vid); -+ if (f && f->is_local && !f->dst) -+ fdb_delete(br, f); -+ -+ list_for_each_entry(p, &br->port_list, list) { -+ if (ether_addr_equal(p->dev->dev_addr, br->dev->dev_addr)) { -+ if (nbp_vlan_find(p, vid)) -+ fdb_insert(br, p, p->dev->dev_addr, vid); -+ else -+ fdb_insert(br, NULL, p->dev->dev_addr, vid); -+ break; -+ } -+ } -+ -+ fdb_insert(br, NULL, newaddr, vid); -+ } - } - } - -@@ -420,13 +451,26 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, - fdb = fdb_find(head, addr, vid); - if (fdb) { - /* it is okay to have multiple ports with same -- * address, just use the first one. -+ * address, just follow the logic below... - */ -- if (fdb->is_local) -+ if (ether_addr_equal(addr, br->dev->dev_addr) && -+ (br->dev->addr_assign_type == NET_ADDR_SET)) { -+ /* don't replace a static bridge address */ -+ if (fdb->is_local && (fdb->dst == NULL)) -+ return 0; -+ /* warn when replacing dynamic or if addr w bridge addr */ -+ br_warn(br, "replacing %02x:%02x:%02x:%02x:%02x:%02x" -+ "with static bridge address\n", addr[0], -+ addr[1], addr[2], addr[3], addr[4], addr[5]); -+ } else if (fdb->is_local) { -+ /* address is already static (interface/bridge) so nop */ - return 0; -- br_warn(br, "adding interface %s with same address " -- "as a received packet\n", -- source ? source->dev->name : br->dev->name); -+ } else { -+ /* add an interface address over a learned one */ -+ br_warn(br, "adding interface %s with same address " -+ "as a received packet\n", -+ source->dev->name); -+ } - fdb_delete(br, fdb); - } - -diff --git a/net/core/dev.c b/net/core/dev.c -index d27774f..1b14767 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -4882,8 +4882,10 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) - if (!netif_device_present(dev)) - return -ENODEV; - err = ops->ndo_set_mac_address(dev, sa); -- if (!err) -- call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); -+ if (err) -+ return err; -+ dev->addr_assign_type = NET_ADDR_SET; -+ call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); - add_device_randomness(dev->dev_addr, dev->addr_len); - return err; - } -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 1fc0006..4f3d832 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -1673,9 +1673,11 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net, - - if (tb[IFLA_MTU]) - dev->mtu = nla_get_u32(tb[IFLA_MTU]); -- if (tb[IFLA_ADDRESS]) -+ if (tb[IFLA_ADDRESS]) { - memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]), - nla_len(tb[IFLA_ADDRESS])); -+ dev->addr_assign_type = NET_ADDR_SET; -+ } - if (tb[IFLA_BROADCAST]) - memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]), - nla_len(tb[IFLA_BROADCAST])); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-static-mcgrp-fix.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-static-mcgrp-fix.patch deleted file mode 100644 index 69f701fc..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-static-mcgrp-fix.patch +++ /dev/null @@ -1,222 +0,0 @@ -fixes for "bridge mdb add" command - -diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c -index a73bcd5..c60121c 100644 ---- a/net/bridge/br_if.c -+++ b/net/bridge/br_if.c -@@ -141,7 +141,7 @@ static void del_nbp(struct net_bridge_port *p) - br_ifinfo_notify(RTM_DELLINK, p); - - br_fdb_delete_by_port(br, p, 1); -- -+ br_multicast_del_port(p); - list_del_rcu(&p->list); - - dev->priv_flags &= ~IFF_BRIDGE_PORT; -@@ -151,8 +151,6 @@ static void del_nbp(struct net_bridge_port *p) - - netdev_set_master(dev, NULL); - -- br_multicast_del_port(p); -- - kobject_uevent(&p->kobj, KOBJ_REMOVE); - kobject_del(&p->kobj); - -@@ -173,6 +171,7 @@ void br_dev_delete(struct net_device *dev, struct list_head *head) - - br_fdb_delete_by_port(br, NULL, 1); - -+ br_multicast_dev_del(br); - del_timer_sync(&br->gc_timer); - - br_sysfs_delbr(br->dev); -diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c -index 3807e00..99ab620 100644 ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -226,7 +226,7 @@ errout: - } - - void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, -- struct br_ip *group, int type) -+ struct br_ip *group, int type, u8 state) - { - struct br_mdb_entry entry; - -@@ -236,6 +236,7 @@ void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, - #if IS_ENABLED(CONFIG_IPV6) - entry.addr.u.ip6 = group->u.ip6; - #endif -+ entry.state = state; - __br_mdb_notify(dev, &entry, type); - } - -@@ -383,6 +384,7 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, - struct net_bridge_port_group __rcu **pp; - struct net_bridge_mdb_htable *mdb; - int err; -+ unsigned long now = jiffies; - - mdb = mlock_dereference(br->mdb, br); - mp = br_mdb_ip_get(mdb, group); -@@ -406,6 +408,8 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, - if (unlikely(!p)) - return -ENOMEM; - rcu_assign_pointer(*pp, p); -+ if (state == MDB_TEMPORARY) -+ mod_timer(&p->timer, now + br->multicast_membership_interval); - - return 0; - } -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 206e6c9..4feb18a 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -40,6 +40,7 @@ - static void br_multicast_start_querier(struct net_bridge *br); - static void br_multicast_add_router(struct net_bridge *br, - struct net_bridge_port *port); -+static void br_multicast_del_grps(struct net_bridge *br); - - unsigned int br_mdb_rehash_seq; - -@@ -265,7 +266,7 @@ static void br_multicast_del_pg(struct net_bridge *br, - if (p != pg) - continue; - -- br_mdb_notify(br->dev, p->port, &pg->addr, RTM_DELMDB); -+ br_mdb_notify(br->dev, p->port, &pg->addr, RTM_DELMDB, pg->state); - rcu_assign_pointer(*pp, p->next); - hlist_del_init(&p->mglist); - del_timer(&p->timer); -@@ -547,6 +548,7 @@ static struct net_bridge_mdb_entry *br_multicast_get_group( - err = -E2BIG; - disable: - br->multicast_disabled = 1; -+ br_multicast_del_grps(br); - goto err; - } - } -@@ -690,7 +692,7 @@ static int br_multicast_add_group(struct net_bridge *br, - if (unlikely(!p)) - goto err; - rcu_assign_pointer(*pp, p); -- br_mdb_notify(br->dev, port, group, RTM_NEWMDB); -+ br_mdb_notify(br->dev, port, group, RTM_NEWMDB, MDB_TEMPORARY); - - found: - mod_timer(&p->timer, now + br->multicast_membership_interval); -@@ -851,6 +853,16 @@ void br_multicast_add_port(struct net_bridge_port *port) - - void br_multicast_del_port(struct net_bridge_port *port) - { -+ struct net_bridge *br = port->br; -+ struct net_bridge_port_group *pg; -+ struct hlist_node *p, *n; -+ -+ spin_lock_bh(&br->multicast_lock); -+ hlist_for_each_entry_safe(pg, p, n, &port->mglist, mglist) { -+ if (pg->state == MDB_PERMANENT) -+ br_multicast_del_pg(br, pg); -+ } -+ spin_unlock_bh(&br->multicast_lock); - del_timer_sync(&port->multicast_router_timer); - } - -@@ -886,8 +898,10 @@ void br_multicast_disable_port(struct net_bridge_port *port) - struct hlist_node *p, *n; - - spin_lock(&br->multicast_lock); -- hlist_for_each_entry_safe(pg, p, n, &port->mglist, mglist) -- br_multicast_del_pg(br, pg); -+ hlist_for_each_entry_safe(pg, p, n, &port->mglist, mglist) { -+ if (pg->state == MDB_TEMPORARY) -+ br_multicast_del_pg(br, pg); -+ } - - if (!hlist_unhashed(&port->rlist)) { - hlist_del_init_rcu(&port->rlist); -@@ -1682,16 +1696,19 @@ void br_multicast_open(struct net_bridge *br) - - void br_multicast_stop(struct net_bridge *br) - { -+ del_timer_sync(&br->multicast_router_timer); -+ del_timer_sync(&br->multicast_querier_timer); -+ del_timer_sync(&br->multicast_query_timer); -+} -+ -+void br_multicast_dev_del(struct net_bridge *br) -+{ - struct net_bridge_mdb_htable *mdb; - struct net_bridge_mdb_entry *mp; - struct hlist_node *p, *n; - u32 ver; - int i; - -- del_timer_sync(&br->multicast_router_timer); -- del_timer_sync(&br->multicast_querier_timer); -- del_timer_sync(&br->multicast_query_timer); -- - spin_lock_bh(&br->multicast_lock); - mdb = mlock_dereference(br->mdb, br); - if (!mdb) -@@ -1721,7 +1738,6 @@ void br_multicast_stop(struct net_bridge *br) - out: - spin_unlock_bh(&br->multicast_lock); - } -- - int br_multicast_set_router(struct net_bridge *br, unsigned long val) - { - int err = -ENOENT; -@@ -1813,6 +1829,18 @@ static void br_multicast_start_querier(struct net_bridge *br) - } - } - -+static void br_multicast_del_grps(struct net_bridge *br) -+{ -+ struct net_bridge_port *port, *bn; -+ struct net_bridge_port_group *pg; -+ struct hlist_node *p, *n; -+ -+ list_for_each_entry_safe(port, bn, &br->port_list, list) { -+ hlist_for_each_entry_safe(pg, p, n, &port->mglist, mglist) -+ br_multicast_del_pg(br, pg); -+ } -+} -+ - int br_multicast_toggle(struct net_bridge *br, unsigned long val) - { - int err = 0; -@@ -1823,8 +1851,10 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val) - goto unlock; - - br->multicast_disabled = !val; -- if (br->multicast_disabled) -+ if (br->multicast_disabled) { -+ br_multicast_del_grps(br); - goto unlock; -+ } - - if (!netif_running(br->dev)) - goto unlock; -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 051673e..5c2b927 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -428,6 +428,7 @@ extern void br_multicast_disable_port(struct net_bridge_port *port); - extern void br_multicast_init(struct net_bridge *br); - extern void br_multicast_open(struct net_bridge *br); - extern void br_multicast_stop(struct net_bridge *br); -+extern void br_multicast_dev_del(struct net_bridge *br); - extern void br_multicast_deliver(struct net_bridge_mdb_entry *mdst, - struct sk_buff *skb); - extern void br_multicast_forward(struct net_bridge_mdb_entry *mdst, -@@ -452,7 +453,7 @@ extern struct net_bridge_port_group *br_multicast_new_port_group( - extern void br_mdb_init(void); - extern void br_mdb_uninit(void); - extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, -- struct br_ip *group, int type); -+ struct br_ip *group, int type, u8 state); - extern void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, - int type); - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-carrier-check.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-carrier-check.patch deleted file mode 100644 index bab50954..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-carrier-check.patch +++ /dev/null @@ -1,18 +0,0 @@ -Remove the carrier_ok check when setting STP state - -diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c -index 79f8e75..9c318a5 100644 ---- a/net/bridge/br_netlink.c -+++ b/net/bridge/br_netlink.c -@@ -183,9 +183,8 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - if (p->br->stp_enabled == BR_KERNEL_STP) - return -EBUSY; - -- if (!netif_running(dev) || -- (!netif_carrier_ok(dev) && new_state != BR_STATE_DISABLED)) -- return -ENETDOWN; -+ if (p->state == new_state) -+ return 0; - - p->state = new_state; - br_log_state(p); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-changes.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-changes.patch deleted file mode 100644 index 25c8e1ea..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-changes.patch +++ /dev/null @@ -1,80 +0,0 @@ -Changes for supporting userspace STP - -diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c -index 8ac946f..03ff405 100644 ---- a/net/bridge/br_stp.c -+++ b/net/bridge/br_stp.c -@@ -173,8 +173,11 @@ void br_transmit_config(struct net_bridge_port *p) - br_send_config_bpdu(p, &bpdu); - p->topology_change_ack = 0; - p->config_pending = 0; -- mod_timer(&p->hold_timer, -- round_jiffies(jiffies + BR_HOLD_TIME)); -+ -+ if (p->br->stp_enabled == BR_KERNEL_STP) { -+ mod_timer(&p->hold_timer, -+ round_jiffies(jiffies + BR_HOLD_TIME)); -+ } - } - } - -diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c -index b88a256..ae80d6d 100644 ---- a/net/bridge/br_stp_if.c -+++ b/net/bridge/br_stp_if.c -@@ -48,7 +48,10 @@ void br_stp_enable_bridge(struct net_bridge *br) - struct net_bridge_port *p; - - spin_lock_bh(&br->lock); -- mod_timer(&br->hello_timer, jiffies + br->hello_time); -+ -+ if (br->stp_enabled == BR_KERNEL_STP) { -+ mod_timer(&br->hello_timer, jiffies + br->hello_time); -+ } - mod_timer(&br->gc_timer, jiffies + HZ/10); - - br_config_bpdu_generation(br); -@@ -128,14 +131,22 @@ static void br_stp_start(struct net_bridge *br) - int r; - char *argv[] = { BR_STP_PROG, br->dev->name, "start", NULL }; - char *envp[] = { NULL }; -+ struct net_bridge_port *p; - - r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); - if (r == 0) { - br->stp_enabled = BR_USER_STP; - br_debug(br, "userspace STP started\n"); -+ /* Stop hello and hold timer */ -+ spin_lock_bh(&br->lock); -+ del_timer(&br->hello_timer); -+ list_for_each_entry(p, &br->port_list, list) { -+ del_timer(&p->hold_timer); -+ } -+ spin_unlock_bh(&br->lock); - } else { - br->stp_enabled = BR_KERNEL_STP; -- br_debug(br, "using kernel STP\n"); -+ br_info(br, "using kernel STP\n"); - - /* To start timers on any ports left in blocking */ - spin_lock_bh(&br->lock); -@@ -149,6 +160,7 @@ static void br_stp_stop(struct net_bridge *br) - int r; - char *argv[] = { BR_STP_PROG, br->dev->name, "stop", NULL }; - char *envp[] = { NULL }; -+ struct net_bridge_port *p; - - if (br->stp_enabled == BR_USER_STP) { - r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); -@@ -156,6 +168,11 @@ static void br_stp_stop(struct net_bridge *br) - - /* To start timers on any ports left in blocking */ - spin_lock_bh(&br->lock); -+ mod_timer(&br->hello_timer, jiffies + br->hello_time); -+ list_for_each_entry(p, &br->port_list, list) { -+ mod_timer(&p->hold_timer, -+ round_jiffies(jiffies + BR_HOLD_TIME)); -+ } - br_port_state_selection(br); - spin_unlock_bh(&br->lock); - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-disabled-bpdu-forward.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-disabled-bpdu-forward.patch deleted file mode 100644 index 9b697aaf..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-disabled-bpdu-forward.patch +++ /dev/null @@ -1,93 +0,0 @@ -When STP is disabled and BPDU is received, the STP BPDU needs to be - -flood forwarded to other bridge ports. - -diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c -index 6b32e27..d6854a4 100644 ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -96,8 +96,19 @@ static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) - static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) - { - struct net_device *indev; -+ __u8 stp_disabled_forward = 0; -+ const unsigned char *dest = eth_hdr(skb)->h_dest; -+ struct net_bridge_port *p = br_port_get_rcu(skb->dev); -+ struct net_bridge *br = p->br; -+ -+ /* flood forward STP/PVST BPDU when received and STP is disabled */ -+ if ((!compare_ether_addr(br_group_address, dest) || -+ !compare_ether_addr(br_pvst_address, dest)) && -+ (br->stp_enabled == BR_NO_STP)) { -+ stp_disabled_forward = 1; -+ } - -- if (br_hw_fwding_enabled) { -+ if (br_hw_fwding_enabled && !stp_disabled_forward) { - NF_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, skb->dev, to->dev, - br_hw_forward_finish); - return; -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index 874907a..fc48161 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -20,6 +20,8 @@ - #include - #include "br_private.h" - -+/* Bridge group multicast address 802.1d (pg 51). */ -+const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; - const u8 br_pvst_address[ETH_ALEN] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcd }; - const u8 br_cdp_address[ETH_ALEN] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc }; - -@@ -70,6 +72,7 @@ int br_handle_frame_finish(struct sk_buff *skb) - struct net_bridge_fdb_entry *dst; - struct net_bridge_mdb_entry *mdst; - struct sk_buff *skb2; -+ __u8 stp_disabled_forward = 0; - bool unicast = true; - u16 vid = 0; - -@@ -81,11 +84,19 @@ int br_handle_frame_finish(struct sk_buff *skb) - - /* insert into forwarding database after filtering to avoid spoofing */ - br = p->br; -+ -+ /* flood forward STP/PVST BPDU when received and STP is disabled */ -+ if ((!compare_ether_addr(br_group_address, dest) || -+ !compare_ether_addr(br_pvst_address, dest)) && -+ (br->stp_enabled == BR_NO_STP)) { -+ stp_disabled_forward = 1; -+ } -+ - if (!br_hw_fwding_enabled && (p->flags & BR_LEARNING)) - br_fdb_update(br, p, eth_hdr(skb)->h_source, vid); - - if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) && -- br_multicast_rcv(br, p, skb, vid)) -+ br_multicast_rcv(br, p, skb, vid) && !stp_disabled_forward) - goto drop; - - if (p->state == BR_STATE_LEARNING) -@@ -104,7 +115,7 @@ int br_handle_frame_finish(struct sk_buff *skb) - if (is_broadcast_ether_addr(dest)) { - skb2 = skb; - unicast = false; -- } else if (is_multicast_ether_addr(dest)) { -+ } else if (is_multicast_ether_addr(dest) || stp_disabled_forward) { - mdst = br_mdb_get(br, skb, vid); - if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && - br_multicast_querier_exists(br, eth_hdr(skb))) { -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index c80f94d..8f5273d 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -329,6 +329,8 @@ struct br_input_skb_cb { - pr_debug("%s: " format, (br)->dev->name, ##args) - - extern struct notifier_block br_device_notifier; -+extern const u8 br_group_address[ETH_ALEN]; -+extern const u8 br_pvst_address[ETH_ALEN]; - - /* called under bridge lock */ - static inline int br_is_root_bridge(const struct net_bridge *br) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-logging.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-logging.patch deleted file mode 100644 index 0b2f4de7..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-stp-logging.patch +++ /dev/null @@ -1,64 +0,0 @@ -Added support for not logging STP state transitions if needed. - -diff --git a/net/bridge/br.c b/net/bridge/br.c -index 2736e3d..effe3b7 100644 ---- a/net/bridge/br.c -+++ b/net/bridge/br.c -@@ -53,7 +53,7 @@ static const struct stp_proto br_stp_proto = { - #ifdef CONFIG_SYSCTL - static struct ctl_table_header *brstp_sysctl_header; - int brstp_user_space __read_mostly = 1; -- -+int brstp_stp_state_logging = 0; - static - int brstp_sysctl_call_tables(ctl_table * ctl, int write, - void __user * buffer, size_t * lenp, loff_t * ppos) -@@ -87,6 +87,13 @@ static ctl_table brstp_table[] = { - .mode = 0644, - .proc_handler = brstp_sysctl_call_tables, - }, -+ { -+ .procname = "bridge-stp-state-logging", -+ .data = &brstp_stp_state_logging, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = brstp_sysctl_call_tables, -+ }, - { } - }; - -@@ -97,6 +104,7 @@ static struct ctl_path brstp_path[] = { - }; - #else - #define brstp_user_space 1 -+#define brstp_stp_state_logging 0 - #endif - - static int __init br_init(void) -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index c80f94d..21ea7e8 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -336,6 +336,8 @@ static inline int br_is_root_bridge(const struct net_bridge *br) - return !memcmp(&br->bridge_id, &br->designated_root, 8); - } - -+extern int brstp_stp_state_logging; -+ - /* br_device.c */ - void br_dev_setup(struct net_device *dev); - void br_dev_delete(struct net_device *dev, struct list_head *list); -diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c -index 4a36459..75f2d1e 100644 ---- a/net/bridge/br_stp.c -+++ b/net/bridge/br_stp.c -@@ -31,6 +31,9 @@ static const char *const br_port_state_names[] = { - - void br_log_state(const struct net_bridge_port *p) - { -+ if (!brstp_stp_state_logging) -+ return; -+ - br_info(p->br, "port %u(%s) entered %s state\n", - (unsigned int) p->port_no, p->dev->name, - br_port_state_names[p->state]); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-use-ipv4_is_local_multicast-helper.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-use-ipv4_is_local_multicast-helper.patch deleted file mode 100644 index 7198f46a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-use-ipv4_is_local_multicast-helper.patch +++ /dev/null @@ -1,21 +0,0 @@ -From bf5e4dd6b26058d1a31864ea1a7002172023b147 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: use ipv4_is_local_multicast() helper - -Cc: Stephen Hemminger -Cc: "David S. Miller" -Signed-off-by: Cong Wang -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 8c638d6..c83ef7b 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1361,7 +1361,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, - return -EINVAL; - - if (iph->protocol != IPPROTO_IGMP) { -- if ((iph->daddr & IGMP_LOCAL_GROUP_MASK) != IGMP_LOCAL_GROUP) -+ if (!ipv4_is_local_multicast(iph->daddr)) - BR_INPUT_SKB_CB(skb)->mrouters_only = 1; - return 0; - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-use-the-bridge-IP-addr-as-source-addr-for-que.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-use-the-bridge-IP-addr-as-source-addr-for-que.patch deleted file mode 100644 index 0434999b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-use-the-bridge-IP-addr-as-source-addr-for-que.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 1c8ad5bfa2be5025b0c81e3c2decd0574d453ab1 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] bridge: use the bridge IP addr as source addr for querier - -Quote from Adam: -"If it is believed that the use of 0.0.0.0 -as the IP address is what is causing strange behaviour on other devices -then is there a good reason that a bridge rather than a router shouldn't -be the active querier? If not then using the bridge IP address and -having the querier enabled by default may be a reasonable solution -(provided that our querier obeys the election rules and shuts up if it -sees a query from a lower IP address that isn't 0.0.0.0). Just because a -device is the elected querier for IGMP doesn't appear to mean it is -required to perform any other routing functions." - -And introduce a new troggle for it, as suggested by Herbert. - -Suggested-by: Adam Baker -Cc: Herbert Xu -Cc: Stephen Hemminger -Cc: "David S. Miller" -Cc: Adam Baker -Signed-off-by: Cong Wang -Acked-by: Herbert Xu -Signed-off-by: David S. Miller - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index c83ef7b..5977be7 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - #include -@@ -380,7 +381,8 @@ static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br, - iph->frag_off = htons(IP_DF); - iph->ttl = 1; - iph->protocol = IPPROTO_IGMP; -- iph->saddr = 0; -+ iph->saddr = br->multicast_query_use_ifaddr ? -+ inet_select_addr(br->dev, 0, RT_SCOPE_LINK) : 0; - iph->daddr = htonl(INADDR_ALLHOSTS_GROUP); - ((u8 *)&iph[1])[0] = IPOPT_RA; - ((u8 *)&iph[1])[1] = 4; -@@ -1606,6 +1608,7 @@ void br_multicast_init(struct net_bridge *br) - - br->multicast_router = 1; - br->multicast_querier = 0; -+ br->multicast_query_use_ifaddr = 0; - br->multicast_last_member_count = 2; - br->multicast_startup_query_count = 2; - -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index f11323d..3b082a1 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -231,6 +231,7 @@ struct net_bridge - - u8 multicast_disabled:1; - u8 multicast_querier:1; -+ u8 multicast_query_use_ifaddr:1; - - u32 hash_elasticity; - u32 hash_max; -diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c -index a27243e..8e12281 100644 ---- a/net/bridge/br_sysfs_br.c -+++ b/net/bridge/br_sysfs_br.c -@@ -379,6 +379,31 @@ static ssize_t store_multicast_snooping(struct device *d, - static DEVICE_ATTR(multicast_snooping, S_IRUGO | S_IWUSR, - show_multicast_snooping, store_multicast_snooping); - -+static ssize_t show_multicast_query_use_ifaddr(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct net_bridge *br = to_bridge(d); -+ return sprintf(buf, "%d\n", br->multicast_query_use_ifaddr); -+} -+ -+static int set_query_use_ifaddr(struct net_bridge *br, unsigned long val) -+{ -+ br->multicast_query_use_ifaddr = !!val; -+ return 0; -+} -+ -+static ssize_t -+store_multicast_query_use_ifaddr(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ return store_bridge_parm(d, buf, len, set_query_use_ifaddr); -+} -+static DEVICE_ATTR(multicast_query_use_ifaddr, S_IRUGO | S_IWUSR, -+ show_multicast_query_use_ifaddr, -+ store_multicast_query_use_ifaddr); -+ - static ssize_t show_multicast_querier(struct device *d, - struct device_attribute *attr, - char *buf) -@@ -720,6 +745,7 @@ static struct attribute *bridge_attrs[] = { - &dev_attr_multicast_router.attr, - &dev_attr_multicast_snooping.attr, - &dev_attr_multicast_querier.attr, -+ &dev_attr_multicast_query_use_ifaddr.attr, - &dev_attr_hash_elasticity.attr, - &dev_attr_hash_max.attr, - &dev_attr_multicast_last_member_count.attr, diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-vlan-filter-auto-enable.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-vlan-filter-auto-enable.patch deleted file mode 100644 index 599e14b2..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-vlan-filter-auto-enable.patch +++ /dev/null @@ -1,136 +0,0 @@ -This patch automatically enables vlan filtering on a bridge when the -first vlan configuration is applied to a bridge port. This also includes -adding the default pvid on all the bridge ports. - -diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c -index 6bedcc4..5880138 100644 ---- a/net/bridge/br_vlan.c -+++ b/net/bridge/br_vlan.c -@@ -279,6 +279,18 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) - return false; - } - -+static void __check_and_enable_vlan_filter(struct net_bridge *br) -+{ -+ /* implicitly enable vlan filtering on the bridge as it is -+ * very easy to forget to set the sysfs variable -+ */ -+ if (br && (br->vlan_enabled == 0)) { -+ br->vlan_enabled = 1; -+ br_vlan_init(br); -+ } -+} -+ -+ - /* Must be protected by RTNL. - * Must be called with vid in range from 1 to 4094 inclusive. - */ -@@ -300,11 +312,14 @@ int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags) - return -ENOMEM; - - pv->parent.br = br; -+ rcu_assign_pointer(br->vlan_info, pv); -+ __check_and_enable_vlan_filter(br); - err = __vlan_add(pv, vid, flags); -- if (err) -+ if (err) { -+ rcu_assign_pointer(br->vlan_info, NULL); - goto out; -+ } - -- rcu_assign_pointer(br->vlan_info, pv); - return 0; - out: - kfree(pv); -@@ -365,6 +380,8 @@ out: - - int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) - { -+ struct net_bridge_port *p; -+ - if (!rtnl_trylock()) - return restart_syscall(); - -@@ -372,6 +389,23 @@ int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) - goto unlock; - - br->vlan_enabled = val; -+ if (!br->vlan_enabled) -+ goto unlock; -+ -+ br_vlan_init(br); -+ list_for_each_entry(p, &br->port_list, list) { -+ struct net_port_vlans *pv = nbp_get_vlan_info(p); -+ u16 pvid = br->default_pvid; -+ -+ if (pv && -+ ((pv->pvid && (pv->pvid != pvid)) || -+ nbp_vlan_find(p, pvid))) -+ continue; -+ -+ nbp_vlan_add(p, pvid, -+ BRIDGE_VLAN_INFO_PVID | -+ BRIDGE_VLAN_INFO_UNTAGGED); -+ } - - unlock: - rtnl_unlock(); -@@ -513,9 +547,28 @@ unlock: - - int br_vlan_init(struct net_bridge *br) - { -- br->default_pvid = 1; -- return br_vlan_add(br, 1, -- BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED); -+ struct net_bridge_port *p; -+ -+ if (br->default_pvid == 0) -+ br->default_pvid = 1; -+ -+ if (!br->vlan_enabled) -+ return 0; -+ -+ list_for_each_entry(p, &br->port_list, list) { -+ struct net_port_vlans *pv = nbp_get_vlan_info(p); -+ u16 pvid = br->default_pvid; -+ -+ if (pv && -+ ((pv->pvid && (pv->pvid != pvid)) || -+ nbp_vlan_find(p, pvid))) -+ continue; -+ nbp_vlan_add(p, pvid, -+ BRIDGE_VLAN_INFO_PVID | -+ BRIDGE_VLAN_INFO_UNTAGGED); -+ } -+ -+ return 0; - } - - /* Must be protected by RTNL. -@@ -542,11 +595,14 @@ int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) - - pv->port_idx = port->port_no; - pv->parent.port = port; -+ rcu_assign_pointer(port->vlan_info, pv); -+ __check_and_enable_vlan_filter(port->br); - err = __vlan_add(pv, vid, flags); -- if (err) -+ if (err) { -+ rcu_assign_pointer(port->vlan_info, NULL); - goto clean_up; -+ } - -- rcu_assign_pointer(port->vlan_info, pv); - return 0; - - clean_up: -@@ -612,6 +668,9 @@ out: - - int nbp_vlan_init(struct net_bridge_port *p) - { -+ if (!p->br->vlan_enabled) -+ return 0; -+ - return p->br->default_pvid ? - nbp_vlan_add(p, p->br->default_pvid, - BRIDGE_VLAN_INFO_PVID | diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-vlan-range-support.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-vlan-range-support.patch deleted file mode 100644 index 63b14d6a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-bridge-vlan-range-support.patch +++ /dev/null @@ -1,196 +0,0 @@ -Support configuring and querying bridge vlan in ranges. - -diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h -index d72ce1c..51eba88 100644 ---- a/include/linux/if_bridge.h -+++ b/include/linux/if_bridge.h -@@ -127,6 +127,7 @@ enum { - struct bridge_vlan_info { - __u16 flags; - __u16 vid; -+ __u16 vid_end; - }; - - /* Bridge multicast database attributes -diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c -index 4fd0735..882072e 100644 ---- a/net/bridge/br_netlink.c -+++ b/net/bridge/br_netlink.c -@@ -128,11 +128,11 @@ static int br_fill_ifinfo(struct sk_buff *skb, - } - - /* Check if the VID information is requested */ -- if (filter_mask & RTEXT_FILTER_BRVLAN) { -+ if ((filter_mask & RTEXT_FILTER_BRVLAN) || (filter_mask == 0)) { - struct nlattr *af; - const struct net_port_vlans *pv; - struct bridge_vlan_info vinfo; -- u16 vid; -+ u16 vid, start, end; - u16 pvid; - - memset(vlan_bmp_copy, 0, -@@ -152,21 +152,93 @@ static int br_fill_ifinfo(struct sk_buff *skb, - if (!af) - goto nla_put_failure; - -+ bitmap_copy(vlan_bmp_copy, pv->vlan_bitmap, VLAN_N_VID); -+ bitmap_copy(untagged_bmp_copy, pv->untagged_bitmap, VLAN_N_VID); -+ -+ /* send the pvid separately first */ - pvid = br_get_pvid(pv); -- for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { -- vinfo.vid = vid; -- vinfo.flags = 0; -- if (vid == pvid) -- vinfo.flags |= BRIDGE_VLAN_INFO_PVID; - -- if (test_bit(vid, pv->untagged_bitmap)) -+ if (pvid != VLAN_N_VID) { -+ memset(&vinfo, 0, sizeof(vinfo)); -+ vinfo.flags |= BRIDGE_VLAN_INFO_PVID; -+ if (test_bit(pvid, untagged_bmp_copy)) { - vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED; -+ clear_bit(pvid, untagged_bmp_copy); -+ } -+ clear_bit(pvid, vlan_bmp_copy); -+ vinfo.vid = pvid; -+ vinfo.vid_end = pvid; -+ if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO, -+ sizeof(vinfo), &vinfo)) -+ goto nla_put_failure; -+ } -+ -+ /* handle the untagged */ -+ start = end = 0; -+ for_each_set_bit(vid, untagged_bmp_copy, VLAN_N_VID) { -+ if (start == 0) { -+ start = vid; -+ end = vid; -+ } - -+ if ((vid - end) > 1) { -+ memset(&vinfo, 0, sizeof(vinfo)); -+ vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED; -+ vinfo.vid = start; -+ vinfo.vid_end = end; -+ if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO, -+ sizeof(vinfo), &vinfo)) -+ goto nla_put_failure; -+ -+ start = vid; -+ end = vid; -+ } else -+ end = vid; -+ -+ clear_bit(vid, vlan_bmp_copy); -+ } -+ -+ if (start != 0 && end != 0) { -+ memset(&vinfo, 0, sizeof(vinfo)); -+ vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED; -+ vinfo.vid = start; -+ vinfo.vid_end = end; - if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO, - sizeof(vinfo), &vinfo)) - goto nla_put_failure; - } - -+ /* handle the tagged */ -+ start = end = 0; -+ for_each_set_bit(vid, vlan_bmp_copy, VLAN_N_VID) { -+ if (start == 0) { -+ start = vid; -+ end = vid; -+ } -+ -+ if ((vid - end) > 1) { -+ memset(&vinfo, 0, sizeof(vinfo)); -+ vinfo.vid = start; -+ vinfo.vid_end = end; -+ if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO, -+ sizeof(vinfo), &vinfo)) -+ goto nla_put_failure; -+ -+ start = vid; -+ end = vid; -+ } else -+ end = vid; -+ } -+ -+ if (start != 0 && end != 0) { -+ memset(&vinfo, 0, sizeof(vinfo)); -+ vinfo.vid = start; -+ vinfo.vid_end = end; -+ if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO, -+ sizeof(vinfo), &vinfo)) -+ goto nla_put_failure; -+ } -+ - nla_nest_end(skb, af); - } - -@@ -251,6 +323,7 @@ static int br_afspec(struct net_bridge *br, - { - struct nlattr *tb[IFLA_BRIDGE_MAX+1]; - int err = 0; -+ __u16 vid; - - err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, af_spec, ifla_br_policy); - if (err) -@@ -264,31 +337,37 @@ static int br_afspec(struct net_bridge *br, - if (!vinfo->vid || vinfo->vid >= VLAN_VID_MASK) - return -EINVAL; - -+ if (!vinfo->vid_end || vinfo->vid_end >= VLAN_VID_MASK) -+ return -EINVAL; -+ - switch (cmd) { - case RTM_SETLINK: -- if (p) { -- err = nbp_vlan_add(p, vinfo->vid, vinfo->flags); -+ for (vid = vinfo->vid; vid <= vinfo->vid_end; vid++) { -+ if (p) { -+ err = nbp_vlan_add(p, vid, vinfo->flags); -+ if (err) -+ break; -+ -+ if (vinfo->flags & BRIDGE_VLAN_INFO_MASTER) -+ err = br_vlan_add(p->br, vid, -+ vinfo->flags); -+ } else -+ err = br_vlan_add(br, vid, vinfo->flags); -+ - if (err) - break; -- -- if (vinfo->flags & BRIDGE_VLAN_INFO_MASTER) -- err = br_vlan_add(p->br, vinfo->vid, -- vinfo->flags); -- } else -- err = br_vlan_add(br, vinfo->vid, vinfo->flags); -- -- if (err) -- break; -- -+ } - break; - - case RTM_DELLINK: -- if (p) { -- nbp_vlan_delete(p, vinfo->vid); -- if (vinfo->flags & BRIDGE_VLAN_INFO_MASTER) -- br_vlan_delete(p->br, vinfo->vid); -- } else -- br_vlan_delete(br, vinfo->vid); -+ for (vid = vinfo->vid; vid <= vinfo->vid_end; vid++) { -+ if (p) { -+ nbp_vlan_delete(p, vid); -+ if (vinfo->flags & BRIDGE_VLAN_INFO_MASTER) -+ br_vlan_delete(p->br, vid); -+ } else -+ br_vlan_delete(br, vid); -+ } - break; - } - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-core-fix-notify-for-move-RTM_DELLINK-to-until-after-ndo-uninit.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-core-fix-notify-for-move-RTM_DELLINK-to-until-after-ndo-uninit.patch deleted file mode 100644 index 6d22a766..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-core-fix-notify-for-move-RTM_DELLINK-to-until-after-ndo-uninit.patch +++ /dev/null @@ -1,171 +0,0 @@ -backport of upstream "commit 395eea6ccf2b253f81b4718ffbcae67d36fe2e69" - - rtnetlink: delay RTM_DELLINK notification until after ndo_uninit() - - The commit 56bfa7ee7c ("unregister_netdevice : move RTM_DELLINK to - until after ndo_uninit") tried to do this ealier but while doing so - it created a problem. Unfortunately the delayed rtmsg_ifinfo() also - delayed call to fill_info(). So this translated into asking driver - to remove private state and then query it's private state. This - could have catastropic consequences. - - This change breaks the rtmsg_ifinfo() into two parts - one takes the - precise snapshot of the device by called fill_info() before calling - the ndo_uninit() and the second part sends the notification using - collected snapshot. - - It was brought to notice when last link is deleted from an ipvlan device - when it has free-ed the port and the subsequent .fill_info() call is - trying to get the info from the port. - -kernel: [ 255.139429] ------------[ cut here ]------------ - kernel: [ 255.139439] WARNING: CPU: 12 PID: 11173 at net/core/rtnetlink.c:2238 rtmsg_ifinfo+0x100/0x110() - kernel: [ 255.139493] Modules linked in: ipvlan bonding w1_therm ds2482 wire cdc_acm ehci_pci ehci_hcd i2c - kernel: [ 255.139513] CPU: 12 PID: 11173 Comm: ip Not tainted 3.18.0-smp-DEV #167 - kernel: [ 255.139514] Hardware name: Intel RML,PCH/Ibis_QC_18, BIOS 1.0.10 05/15/2012 - kernel: [ 255.139515] 0000000000000009 ffff880851b6b828 ffffffff815d87f4 00000000000000e0 - kernel: [ 255.139516] 0000000000000000 ffff880851b6b868 ffffffff8109c29c 0000000000000000 - kernel: [ 255.139518] 00000000ffffffa6 00000000000000d0 ffffffff81aaf580 0000000000000011 - kernel: [ 255.139520] Call Trace: - kernel: [ 255.139527] [] dump_stack+0x46/0x58 - kernel: [ 255.139531] [] warn_slowpath_common+0x8c/0xc0 - kernel: [ 255.139540] [] warn_slowpath_null+0x1a/0x20 - kernel: [ 255.139544] [] rtmsg_ifinfo+0x100/0x110 - kernel: [ 255.139547] [] rollback_registered_many+0x1d5/0x2d0 - kernel: [ 255.139549] [] unregister_netdevice_many+0x1f/0xb0 - kernel: [ 255.139551] [] rtnl_dellink+0xbb/0x110 - kernel: [ 255.139553] [] rtnetlink_rcv_msg+0xa0/0x240 - kernel: [ 255.139557] [] ? rhashtable_lookup_compare+0x43/0x80 - kernel: [ 255.139558] [] ? __rtnl_unlock+0x20/0x20 - kernel: [ 255.139562] [] netlink_rcv_skb+0xb1/0xc0 - kernel: [ 255.139563] [] rtnetlink_rcv+0x25/0x40 - kernel: [ 255.139565] [] netlink_unicast+0x178/0x230 - kernel: [ 255.139567] [] netlink_sendmsg+0x30f/0x420 - kernel: [ 255.139571] [] sock_sendmsg+0x9c/0xd0 - kernel: [ 255.139575] [] ? rw_copy_check_uvector+0x6f/0x130 - kernel: [ 255.139577] [] ? copy_msghdr_from_user+0x139/0x1b0 - kernel: [ 255.139578] [] ___sys_sendmsg+0x304/0x310 - kernel: [ 255.139581] [] ? handle_mm_fault+0xca3/0xde0 - kernel: [ 255.139585] [] ? destroy_inode+0x3c/0x70 - kernel: [ 255.139589] [] ? __do_page_fault+0x20c/0x500 - kernel: [ 255.139597] [] ? dput+0xb6/0x190 - kernel: [ 255.139606] [] ? mntput+0x26/0x40 - kernel: [ 255.139611] [] ? __fput+0x174/0x1e0 - kernel: [ 255.139613] [] __sys_sendmsg+0x49/0x90 - kernel: [ 255.139615] [] SyS_sendmsg+0x12/0x20 - kernel: [ 255.139617] [] system_call_fastpath+0x12/0x17 - kernel: [ 255.139619] ---[ end trace 5e6703e87d984f6b ]--- - - Signed-off-by: Mahesh Bandewar - Reported-by: Toshiaki Makita - Cc: Eric Dumazet - Cc: Roopa Prabhu - Cc: David S. Miller - Acked-by: Eric Dumazet - Acked-by: Thomas Graf - Signed-off-by: David S. Miller - -diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h -index 549b574..2aa8240 100644 ---- a/include/linux/rtnetlink.h -+++ b/include/linux/rtnetlink.h -@@ -766,6 +766,10 @@ __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen) - __rta_reserve(skb, attrtype, attrlen); }) - - extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change); -+struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev, -+ unsigned change, gfp_t flags); -+void rtmsg_ifinfo_send(struct sk_buff *skb, struct net_device *dev, -+ gfp_t flags); - - /* RTNL is used as a global lock for all changes to network configuration */ - extern void rtnl_lock(void); -diff --git a/net/core/dev.c b/net/core/dev.c -index 99c51e7..d2d0076 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -5323,6 +5323,8 @@ static void rollback_registered_many(struct list_head *head) - synchronize_net(); - - list_for_each_entry(dev, head, unreg_list) { -+ struct sk_buff *skb = NULL; -+ - /* Shutdown queueing discipline. */ - dev_shutdown(dev); - -@@ -5332,6 +5334,11 @@ static void rollback_registered_many(struct list_head *head) - */ - call_netdevice_notifiers(NETDEV_UNREGISTER, dev); - -+ if (!dev->rtnl_link_ops || -+ dev->rtnl_link_state == RTNL_LINK_INITIALIZED) -+ skb = rtmsg_ifinfo_build_skb(RTM_DELLINK, dev, ~0U, -+ GFP_KERNEL); -+ - /* - * Flush the unicast and multicast chains - */ -@@ -5341,6 +5348,9 @@ static void rollback_registered_many(struct list_head *head) - if (dev->netdev_ops->ndo_uninit) - dev->netdev_ops->ndo_uninit(dev); - -+ if (skb) -+ rtmsg_ifinfo_send(skb, dev, GFP_KERNEL); -+ - if (!dev->rtnl_link_ops || - dev->rtnl_link_state == RTNL_LINK_INITIALIZED) - rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 296533f..0ac7a53 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -2092,14 +2092,15 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) - return skb->len; - } - --void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) -+struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev, -+ unsigned int change, gfp_t flags) - { - struct net *net = dev_net(dev); - struct sk_buff *skb; - int err = -ENOBUFS; - size_t if_info_size; - -- skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), GFP_KERNEL); -+ skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), flags); - if (skb == NULL) - goto errout; - -@@ -2110,12 +2111,29 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) - kfree_skb(skb); - goto errout; - } -- rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_KERNEL); -- return; -+ return skb; - errout: - if (err < 0) - rtnl_set_sk_err(net, RTNLGRP_LINK, err); -+ return NULL; -+} -+ -+void rtmsg_ifinfo_send(struct sk_buff *skb, struct net_device *dev, gfp_t flags) -+{ -+ struct net *net = dev_net(dev); -+ -+ rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, flags); -+} -+ -+void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change) -+{ -+ struct sk_buff *skb; -+ -+ skb = rtmsg_ifinfo_build_skb(type, dev, change, GFP_KERNEL); -+ if (skb) -+ rtmsg_ifinfo_send(skb, dev, GFP_KERNEL); - } -+EXPORT_SYMBOL(rtmsg_ifinfo); - - static int nlmsg_populate_fdb_fill(struct sk_buff *skb, - struct net_device *dev, diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-core-move-RTM_DELLINK-to-until-after-ndo-uninit.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-core-move-RTM_DELLINK-to-until-after-ndo-uninit.patch deleted file mode 100644 index 6eb7a719..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-core-move-RTM_DELLINK-to-until-after-ndo-uninit.patch +++ /dev/null @@ -1,54 +0,0 @@ -From f7bf58718bf885ee3f2f026a2cd05859904a6acb Mon Sep 17 00:00:00 2001 -Subject: [PATCH net-next] unregister_netdevice : move RTM_DELLINK to until after - ndo_uninit -To: roopa@cumulusnetworks.com - -This patch fixes ordering of rtnl notifications during unregister_netdevice -by moving RTM_DELLINK notification to until after ndo_uninit. - -The problem was seen with unregistering bond netdevices. - -bond ndo_uninit callback generates a few RTM_NEWLINK notifications for -NETDEV_CHANGEADDR and NETDEV_FEAT_CHANGE. This is seen mostly when the -bond is deleted with slaves still enslaved to the bond. - -During unregister netdevice (rollback_registered_many to be specific) -bond ndo_uninit is called after RTM_DELLINK notification goes out. -This results in userspace seeing RTM_DELLINK followed by a couple of -RTM_NEWLINK's. - -In userspace problem was seen with libnl. libnl cache deletes the bond -when it sees RTM_DELLINK and re-adds the bond with the following -RTM_NEWLINK. Resulting in a stale bond entry in libnl cache when the kernel -has already deleted the bond. - -This patch has been tested for bond, bridges and vlan devices. - -Signed-off-by: Roopa Prabhu - -diff --git a/net/core/dev.c b/net/core/dev.c -index 79bdb33..d27774f 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -5322,10 +5322,6 @@ static void rollback_registered_many(struct list_head *head) - */ - call_netdevice_notifiers(NETDEV_UNREGISTER, dev); - -- if (!dev->rtnl_link_ops || -- dev->rtnl_link_state == RTNL_LINK_INITIALIZED) -- rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); -- - /* - * Flush the unicast and multicast chains - */ -@@ -5335,6 +5331,10 @@ static void rollback_registered_many(struct list_head *head) - if (dev->netdev_ops->ndo_uninit) - dev->netdev_ops->ndo_uninit(dev); - -+ if (!dev->rtnl_link_ops || -+ dev->rtnl_link_state == RTNL_LINK_INITIALIZED) -+ rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); -+ - /* Notifier chain MUST detach us from master device. */ - WARN_ON(dev->master); - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-core-proto-down.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-core-proto-down.patch deleted file mode 100644 index f535873a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-core-proto-down.patch +++ /dev/null @@ -1,254 +0,0 @@ -This patch introduces the proto_down (errDisabled) state - - -1. proto_down is a bitmap and bits are tyically set/unset by applications. -Setting it is intended to oper-down and carrier-down the device independent -of admin-down/IFF_UP. -2. oper-down handing is done by netdev core (in a dev-type agnostic fashion); -carrier-down handling is done by drivers interested in handling that state -(currently switchd and virtio). -3. Currently the only application that uses proto_down is MLAG -(IF_LINK_PROTO_DOWN_MLAG). In later releases STP and PTM also have use for -this state (IF_LINK_PROTO_DOWN_STP and IF_LINK_PROTO_DOWN_PTM can be introduced - at that time). Also see iproute2 patch for ip link see interface. -2. clagd will set the proto_down (IF_LINK_PROTO_DOWN_MLAG bit) via rtnl -attribute IFLA_LINKPROTODOWN. This attribute allow individual proto_down bits -to be set or unset (also see libnl patch for proto_down). -3. Setting of proto_down is handled by netdev core via the state flag -IFF_PROTO_DOWN. IFF_PROTO_DOWN is used to hold down the operstate of a device -(use case is MLAG-VxLAN where a virtual device would need to be held oper-down). -4. Whenever IFF_PROTO_DOWN is set or cleared a linkwatch event is fired as the -operstate of the device may need to be re-evaluated. In addition a -NETDEV_CHANGE notification and rtnl _NEWLINK update is also sent. -5. The NETDEV_CHANGE notification is currently used by the virtio driver to -hold back the carrier (this way the softnode and hard node function in the same -fashion). -6. The rtnl update is used by switchd to "bcm port down" the device (which -will result in the expected carrier down) - -diff --git a/include/linux/if.h b/include/linux/if.h -index db20bd4..1d7525f 100644 ---- a/include/linux/if.h -+++ b/include/linux/if.h -@@ -52,9 +52,11 @@ - #define IFF_DORMANT 0x20000 /* driver signals dormant */ - - #define IFF_ECHO 0x40000 /* echo sent packets */ -+#define IFF_PROTO_DOWN 0x1000000 /* protocol is down on the interface */ - - #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\ -- IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) -+ IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT|\ -+ IFF_PROTO_DOWN) - - /* Private (from user) interface flags (netdevice->priv_flags). */ - #define IFF_802_1Q_VLAN 0x1 /* 802.1Q VLAN device. */ -@@ -124,6 +126,9 @@ enum { - IF_LINK_MODE_DORMANT, /* limit upward transition to dormant */ - }; - -+/* list of protocols that want to hold the device in a proto_down state */ -+#define IF_LINK_PROTO_DOWN_MLAG 0x1 -+ - /* - * Device mapping structure. I'd just gone off and designed a - * beautiful scheme using only loadable modules with arguments -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index 45736db..b4c35ee 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -80,6 +80,13 @@ struct rtnl_link_ifmap { - __u8 port; - }; - -+/* link protodown */ -+struct rtnl_link_protodown { -+ __u32 proto_down; /* Bit mask of protocols that want to hold the -+ * device down */ -+ __u32 proto_down_change; /* Change mask for proto_down */ -+}; -+ - /* - * IFLA_AF_SPEC - * Contains nested attributes for address family specific attributes. -@@ -140,6 +147,8 @@ enum { - #ifndef __GENKSYMS__ - IFLA_EXT_MASK, /* Extended info mask, VFs, etc */ - #endif -+ IFLA_LINKPROTODOWN = 200, /* Bit mask of protocols that want to -+ * hold the device down */ - __IFLA_MAX - }; - -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index b7c8918..70f43fb 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -1380,6 +1380,7 @@ struct net_device { - - /* group the device belongs to */ - int group; -+ unsigned int proto_down; /* protocol bits to hold down the operstate */ - }; - #define to_net_dev(d) container_of(d, struct net_device, dev) - -@@ -2281,6 +2282,9 @@ extern int dev_hard_start_xmit(struct sk_buff *skb, - struct netdev_queue *txq); - extern int dev_forward_skb(struct net_device *dev, - struct sk_buff *skb); -+extern void dev_set_proto_down(struct net_device *dev, -+ unsigned int proto_down, -+ unsigned int proto_down_change); - - extern int netdev_budget; - extern int kill_routes_on_linkdown; -diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c -index 91c9248..fc1739a 100644 ---- a/net/8021q/vlan_dev.c -+++ b/net/8021q/vlan_dev.c -@@ -568,7 +568,7 @@ static int vlan_dev_init(struct net_device *dev) - - /* IFF_BROADCAST|IFF_MULTICAST; ??? */ - dev->flags = real_dev->flags & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | -- IFF_MASTER | IFF_SLAVE); -+ IFF_MASTER | IFF_SLAVE | IFF_PROTO_DOWN); - dev->iflink = real_dev->ifindex; - dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | - (1<<__LINK_STATE_DORMANT))) | -diff --git a/net/core/dev.c b/net/core/dev.c -index 3073f84..4e67c83 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -4827,6 +4827,43 @@ int dev_change_flags(struct net_device *dev, unsigned flags) - EXPORT_SYMBOL(dev_change_flags); - - /** -+ * dev_set_proto_down - Set the link protocol state -+ * @dev: device -+ * @proto_down: bitmap of protocols that want to hold the link down -+ * @proto_down_change: bitmap of protocols that need to be changed -+ * -+ */ -+void dev_set_proto_down(struct net_device *dev, unsigned int proto_down, -+ unsigned int proto_down_change) -+{ -+ int err; -+ int old_flags; -+ -+ proto_down = (proto_down & proto_down_change) | -+ (dev->proto_down & ~proto_down_change); -+ if (proto_down == dev->proto_down) -+ return 0; -+ -+ old_flags = dev->flags & IFF_PROTO_DOWN; -+ write_lock_bh(&dev_base_lock); -+ dev->proto_down = proto_down; -+ if (dev->proto_down) -+ dev->flags |= IFF_PROTO_DOWN; -+ else -+ dev->flags &= ~IFF_PROTO_DOWN; -+ write_unlock_bh(&dev_base_lock); -+ -+ if (old_flags != (dev->flags & IFF_PROTO_DOWN)) { -+ rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_PROTO_DOWN); -+ call_netdevice_notifiers(NETDEV_CHANGE, dev); -+ -+ /* the operstate may need to be re-evaluated */ -+ linkwatch_fire_event(dev); -+ } -+} -+EXPORT_SYMBOL(dev_set_proto_down); -+ -+/** - * dev_set_mtu - Change maximum transfer unit - * @dev: device - * @new_mtu: new transfer unit -diff --git a/net/core/link_watch.c b/net/core/link_watch.c -index c3519c6..818a003 100644 ---- a/net/core/link_watch.c -+++ b/net/core/link_watch.c -@@ -39,7 +39,7 @@ static DEFINE_SPINLOCK(lweventlist_lock); - - static unsigned char default_operstate(const struct net_device *dev) - { -- if (!netif_carrier_ok(dev)) -+ if (!netif_carrier_ok(dev) || (dev->flags & IFF_PROTO_DOWN)) - return (dev->ifindex != dev->iflink ? - IF_OPER_LOWERLAYERDOWN : IF_OPER_DOWN); - -diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c -index 474a665..c783418 100644 ---- a/net/core/net-sysfs.c -+++ b/net/core/net-sysfs.c -@@ -104,6 +104,7 @@ NETDEVICE_SHOW(iflink, fmt_dec); - NETDEVICE_SHOW(ifindex, fmt_dec); - NETDEVICE_SHOW(type, fmt_dec); - NETDEVICE_SHOW(link_mode, fmt_dec); -+NETDEVICE_SHOW(proto_down, fmt_dec); - - /* use same locking rules as GIFHWADDR ioctl's */ - static ssize_t show_address(struct device *dev, struct device_attribute *attr, -@@ -327,6 +328,7 @@ static struct device_attribute net_class_attributes[] = { - __ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, - store_tx_queue_len), - __ATTR(netdev_group, S_IRUGO | S_IWUSR, show_group, store_group), -+ __ATTR(proto_down, S_IRUGO, show_proto_down, NULL), - {} - }; - -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 0ac7a53..61a2c93 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -873,6 +873,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev, - + nla_total_size(4) /* IFLA_MASTER */ - + nla_total_size(1) /* IFLA_OPERSTATE */ - + nla_total_size(1) /* IFLA_LINKMODE */ -+ + nla_total_size(sizeof(struct rtnl_link_protodown)) - + nla_total_size(ext_filter_mask - & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */ - + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */ -@@ -990,6 +991,13 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, - NLA_PUT_U32(skb, IFLA_MTU, dev->mtu); - NLA_PUT_U32(skb, IFLA_GROUP, dev->group); - -+ struct rtnl_link_protodown link_proto_down = { -+ .proto_down = dev->proto_down, -+ .proto_down_change = ~0, -+ }; -+ NLA_PUT(skb, IFLA_LINKPROTODOWN, sizeof(link_proto_down), -+ &link_proto_down); -+ - if (dev->ifindex != dev->iflink) - NLA_PUT_U32(skb, IFLA_LINK, dev->iflink); - -@@ -1214,6 +1222,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { - #ifndef __GENKSYMS__ - [IFLA_EXT_MASK] = { .type = NLA_U32 }, - #endif -+ [IFLA_LINKPROTODOWN] = { .len = sizeof(struct rtnl_link_protodown) }, - }; - EXPORT_SYMBOL(ifla_policy); - -@@ -1538,6 +1547,13 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, - write_unlock_bh(&dev_base_lock); - } - -+ if (tb[IFLA_LINKPROTODOWN]) { -+ struct rtnl_link_protodown *link_proto_down; -+ link_proto_down = nla_data(tb[IFLA_LINKPROTODOWN]); -+ dev_set_proto_down(dev, link_proto_down->proto_down, -+ link_proto_down->proto_down_change); -+ } -+ - if (tb[IFLA_VFINFO_LIST]) { - struct nlattr *attr; - int rem; -@@ -1772,6 +1788,8 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net, - dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); - if (tb[IFLA_GROUP]) - dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP])); -+ if (tb[IFLA_LINKPROTODOWN]) -+ dev->proto_down = nla_get_u32(tb[IFLA_LINKPROTODOWN]); - - return dev; - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-dev-net-call-notifiers-for-mtu-change-even-if-iface-is-not-up.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-dev-net-call-notifiers-for-mtu-change-even-if-iface-is-not-up.patch deleted file mode 100644 index 971ca18e..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-dev-net-call-notifiers-for-mtu-change-even-if-iface-is-not-up.patch +++ /dev/null @@ -1,23 +0,0 @@ -From e3d8fabee3b66ce158b2603f270479b84b6e4ba7 Mon Sep 17 00:00:00 2001 -Subject: [PATCH net-next] net: call notifiers for mtu change even if iface is - not up - -Do the same thing as in set mac. Call notifiers every time. - -Signed-off-by: Jiri Pirko -Acked-by: Neil Horman -Signed-off-by: David S. Miller - -diff --git a/net/core/dev.c b/net/core/dev.c -index d2d0076..3073f84 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -4854,7 +4854,7 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) - else - dev->mtu = new_mtu; - -- if (!err && dev->flags & IFF_UP) -+ if (!err) - call_netdevice_notifiers(NETDEV_CHANGEMTU, dev); - return err; - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-disable-hw-aclstats.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-disable-hw-aclstats.patch deleted file mode 100644 index 8e3ec485..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-disable-hw-aclstats.patch +++ /dev/null @@ -1,138 +0,0 @@ -Disable Incrementing of ACL HW stats in kernel as HW already increments this coutner - -diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c -index 45f93f8..54be1cc 100644 ---- a/net/bridge/netfilter/ebtables.c -+++ b/net/bridge/netfilter/ebtables.c -@@ -186,6 +186,8 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb, - const struct net_device *in, const struct net_device *out, - struct ebt_table *table) - { -+ static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); -+ - int i, nentries; - struct ebt_entry *point; - struct ebt_counter *counter_base, *cb_base; -@@ -196,6 +198,10 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb, - const char *base; - const struct ebt_table_info *private; - struct xt_action_param acpar; -+ const char *indev, *outdev; -+ -+ indev = in ? in->name : nulldevname; -+ outdev = out ? out->name : nulldevname; - - acpar.family = NFPROTO_BRIDGE; - acpar.in = in; -@@ -219,6 +225,8 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb, - base = private->entries; - i = 0; - while (i < nentries) { -+ bool no_incflag = false; -+ - if (ebt_basic_match(point, skb, in, out)) - goto letscontinue; - -@@ -229,9 +237,25 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb, - return NF_DROP; - } - -- /* increase counter */ -- (*(counter_base + i)).pcnt++; -- (*(counter_base + i)).bcnt += skb->len; -+ /* -+ * Kernel should increment traffic -+ * only for eth interfaces -+ * TODO:This check will be modified to group check -+ */ -+ if ((hook == NF_BR_LOCAL_IN) || (hook == NF_BR_FORWARD)) { -+ if (((strstr(indev, "eth") == NULL) && -+ strcmp(indev, nulldevname)) || -+ ((strstr(outdev, "eth") == NULL) && -+ strcmp(outdev, nulldevname))) { -+ no_incflag = true; -+ } -+ } -+ -+ if (!no_incflag) { -+ /* increase counter */ -+ (*(counter_base + i)).pcnt++; -+ (*(counter_base + i)).bcnt += skb->len; -+ } - - /* these should only watch: not modify, nor tell us - what to do with the packet */ -diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c -index f98a1cf..8882964 100644 ---- a/net/ipv4/netfilter/ip_tables.c -+++ b/net/ipv4/netfilter/ip_tables.c -@@ -341,6 +341,7 @@ ipt_do_table(struct sk_buff *skb, - do { - const struct xt_entry_target *t; - const struct xt_entry_match *ematch; -+ bool no_incflag = false; - - IP_NF_ASSERT(e); - if (!ip_packet_match(ip, indev, outdev, -@@ -357,7 +358,23 @@ ipt_do_table(struct sk_buff *skb, - goto no_match; - } - -- ADD_COUNTER(e->counters, skb->len, 1); -+ /* -+ * Kernel should increment traffic -+ * only for eth interfaces -+ * TODO:This check will be modified to group check -+ */ -+ if ((hook == NF_INET_LOCAL_IN) || (hook == NF_INET_FORWARD)) { -+ if (((strstr(indev, "eth") == NULL) && -+ strcmp(indev, nulldevname)) || -+ ((strstr(outdev, "eth") == NULL) && -+ strcmp(outdev, nulldevname))) { -+ no_incflag = true; -+ } -+ } -+ -+ if (!no_incflag) { -+ ADD_COUNTER(e->counters, skb->len, 1); -+ } - - t = ipt_get_target(e); - IP_NF_ASSERT(t->u.kernel.target); -diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c -index 2e752b2..d84bd7c 100644 ---- a/net/ipv6/netfilter/ip6_tables.c -+++ b/net/ipv6/netfilter/ip6_tables.c -@@ -373,6 +373,7 @@ ip6t_do_table(struct sk_buff *skb, - do { - const struct xt_entry_target *t; - const struct xt_entry_match *ematch; -+ bool no_incflag = false; - - IP_NF_ASSERT(e); - if (!ip6_packet_match(skb, indev, outdev, &e->ipv6, -@@ -389,7 +390,23 @@ ip6t_do_table(struct sk_buff *skb, - goto no_match; - } - -- ADD_COUNTER(e->counters, skb->len, 1); -+ /* -+ * Kernel should increment traffic -+ * only for eth interfaces -+ * TODO:This check will be modified to group check -+ */ -+ if ((hook == NF_INET_LOCAL_IN) || (hook == NF_INET_FORWARD)) { -+ if (((strstr(indev, "eth") == NULL) && -+ strcmp(indev, nulldevname)) || -+ ((strstr(outdev, "eth") == NULL) && -+ strcmp(outdev, nulldevname))) { -+ no_incflag = true; -+ } -+ } -+ -+ if (!no_incflag) { -+ ADD_COUNTER(e->counters, skb->len, 1); -+ } - - t = ip6t_get_target_c(e); - IP_NF_ASSERT(t->u.kernel.target); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-disable-mixed-vlans-bridge.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-disable-mixed-vlans-bridge.patch deleted file mode 100644 index 99164913..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-disable-mixed-vlans-bridge.patch +++ /dev/null @@ -1,87 +0,0 @@ -Added a bridge module parameter to allow/disallow mixing vlans in a bridge. - -diff --git a/net/bridge/br.c b/net/bridge/br.c -index d3f57c1..b569fdb 100644 ---- a/net/bridge/br.c -+++ b/net/bridge/br.c -@@ -27,6 +27,11 @@ int br_hw_fwding_enabled = 1; - MODULE_PARM_DESC(hw_fwding, "Enable hw forwarding"); - module_param_named(hw_fwding, br_hw_fwding_enabled, int, 0644); - -+int br_allow_multiple_vlans = 0; -+ -+MODULE_PARM_DESC(allow_multiple_vlans, "Allow multiple vlans in a bridge"); -+module_param_named(allow_multiple_vlans, br_allow_multiple_vlans, int, 0644); -+ - static const struct stp_proto br_stp_proto = { - .rcv = br_stp_rcv, - }; -diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c -index a73bcd5..bffc49a 100644 ---- a/net/bridge/br_if.c -+++ b/net/bridge/br_if.c -@@ -21,11 +21,14 @@ - #include - #include - #include -+#include - #include - #include - - #include "br_private.h" - -+extern int br_allow_multiple_vlans; -+ - /* - * Determine initial path cost based on speed. - * using recommendations from 802.1d standard -@@ -319,6 +322,26 @@ u32 br_features_recompute(struct net_bridge *br, u32 features) - return features; - } - -+static bool is_port_in_different_vlan(struct net_bridge *br, -+ struct net_device *dev) -+{ -+ struct net_bridge_port *p; -+ u16 vlan_id; -+ -+ if (!is_vlan_dev(dev)) -+ return false; -+ -+ vlan_id = vlan_dev_vlan_id(dev); -+ -+ list_for_each_entry_rcu(p, &br->port_list, list) { -+ if (!is_vlan_dev(p->dev)) -+ continue; -+ if (vlan_id != vlan_dev_vlan_id(p->dev)) -+ return true; -+ } -+ return false; -+} -+ - /* called with RTNL */ - int br_add_if(struct net_bridge *br, struct net_device *dev) - { -@@ -344,6 +367,10 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) - if (dev->priv_flags & IFF_DONT_BRIDGE) - return -EOPNOTSUPP; - -+ /* No bridgeing vlan devices that have different vlan id */ -+ if (!br_allow_multiple_vlans && is_port_in_different_vlan(br, dev)) -+ return -EINVAL; -+ - p = new_nbp(br, dev); - if (IS_ERR(p)) - return PTR_ERR(p); -diff --git a/net/netfilter/xt_SPAN.c b/net/netfilter/xt_SPAN.c -index 751e4ed..1120bb2 100644 ---- a/net/netfilter/xt_SPAN.c -+++ b/net/netfilter/xt_SPAN.c -@@ -1,6 +1,6 @@ - /* - * "SPAN" target extension for Xtables -- * Copyright 2013 Cumulus Networks, LLC. All rights reserved. */ -+ * Copyright 2013 Cumulus Networks, LLC. 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 diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ethtool-sfp-gang-support.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ethtool-sfp-gang-support.patch deleted file mode 100644 index 5f5462f6..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ethtool-sfp-gang-support.patch +++ /dev/null @@ -1,17 +0,0 @@ -Add support for number of eeproms in the ethtool_modinfo structure. -This is needed to support more than one sfp eeproms in ganged ports. - -diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h -index 6d2ad9e..ff9d5ec 100644 ---- a/include/linux/ethtool.h -+++ b/include/linux/ethtool.h -@@ -131,7 +131,8 @@ struct ethtool_modinfo { - __u32 cmd; - __u32 type; - __u32 eeprom_len; -- __u32 reserved[8]; -+ __u32 eeprom_nums; -+ __u32 reserved[7]; - }; - - /** diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-fix-dead-route-issues.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-fix-dead-route-issues.patch deleted file mode 100644 index a44516dd..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-fix-dead-route-issues.patch +++ /dev/null @@ -1,266 +0,0 @@ -net: fix issues with dead routes - -Done: -- Fix an issue where a dead nexthop prevents a v4 route from being - added. -- Rename sysctl 'delete_dead_routes' to 'kill_routes_on_linkdown' - -To Do: -- Make v4 and v6 functionality identical. - -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index 2a75139..b7c8918 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -2283,7 +2283,7 @@ extern int dev_forward_skb(struct net_device *dev, - struct sk_buff *skb); - - extern int netdev_budget; --extern int delete_dead_routes; -+extern int kill_routes_on_linkdown; - - /* Called by rtnetlink.c:rtnl_unlock() */ - extern void netdev_run_todo(void); -diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h -index d0db95e..4154bd4 100644 ---- a/include/linux/sysctl.h -+++ b/include/linux/sysctl.h -@@ -275,7 +275,7 @@ enum - NET_CORE_AEVENT_ETIME=20, - NET_CORE_AEVENT_RSEQTH=21, - NET_CORE_WARNINGS=22, -- NET_CORE_DELETE_DEAD_ROUTES=23, -+ NET_CORE_KILL_ROUTES_ON_LINKDOWN=23, - }; - - /* /proc/sys/net/ethernet */ -diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c -index 12a46f7..513c406 100644 ---- a/kernel/sysctl_binary.c -+++ b/kernel/sysctl_binary.c -@@ -195,7 +195,7 @@ static const struct bin_table bin_net_core_table[] = { - { CTL_INT, NET_CORE_AEVENT_ETIME, "xfrm_aevent_etime" }, - { CTL_INT, NET_CORE_AEVENT_RSEQTH, "xfrm_aevent_rseqth" }, - { CTL_INT, NET_CORE_WARNINGS, "warnings" }, -- { CTL_INT, NET_CORE_DELETE_DEAD_ROUTES, "delete_dead_routes" }, -+ { CTL_INT, NET_CORE_KILL_ROUTES_ON_LINKDOWN, "kill_routes_on_linkdown" }, - {}, - }; - -diff --git a/net/core/dev.c b/net/core/dev.c -index 725ac59..99c51e7 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -2575,8 +2575,8 @@ int netdev_max_backlog __read_mostly = 1000; - int netdev_tstamp_prequeue __read_mostly = 1; - int netdev_budget __read_mostly = 300; - int weight_p __read_mostly = 64; /* old backlog weight */ --int delete_dead_routes = 0; --EXPORT_SYMBOL(delete_dead_routes); -+int kill_routes_on_linkdown = 0; -+EXPORT_SYMBOL(kill_routes_on_linkdown); - - /* Called with irq disabled */ - static inline void ____napi_schedule(struct softnet_data *sd, -diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c -index 9aa94d0..6665582 100644 ---- a/net/core/sysctl_net_core.c -+++ b/net/core/sysctl_net_core.c -@@ -187,8 +187,8 @@ static struct ctl_table net_core_table[] = { - .proc_handler = proc_dointvec - }, - { -- .procname = "delete_dead_routes", -- .data = &delete_dead_routes, -+ .procname = "kill_routes_on_linkdown", -+ .data = &kill_routes_on_linkdown, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec -diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c -index 482dbea..4a30791 100644 ---- a/net/ipv4/fib_frontend.c -+++ b/net/ipv4/fib_frontend.c -@@ -1016,14 +1016,16 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo - rt_cache_flush(dev_net(dev), -1); - break; - case NETDEV_DOWN: -- fib_disable_ip(dev, 0, 0); -+ fib_disable_ip(dev, 1, 0); - break; - case NETDEV_CHANGE: -- flags = dev_get_flags(dev); -- if (!(flags & IFF_RUNNING)) -- fib_sync_down_dev(dev, 0); -- else if (flags & IFF_RUNNING) -- fib_sync_up(dev); -+ if (kill_routes_on_linkdown) { -+ flags = dev_get_flags(dev); -+ if (flags & (IFF_RUNNING|IFF_LOWER_UP)) -+ fib_sync_up(dev); -+ else -+ fib_sync_down_dev(dev, 0); -+ } - case NETDEV_CHANGEMTU: - rt_cache_flush(dev_net(dev), 0); - break; -diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c -index 02fcc81..f305b9f 100644 ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -199,7 +199,7 @@ static inline int nh_comp(const struct fib_info *fi, const struct fib_info *ofi) - #ifdef CONFIG_IP_ROUTE_CLASSID - nh->nh_tclassid != onh->nh_tclassid || - #endif -- ((nh->nh_flags ^ onh->nh_flags) & ~RTNH_F_DEAD)) -+ ((nh->nh_flags ^ onh->nh_flags) & ~(RTNH_F_DEAD|RTNH_F_DEAD_LINKDOWN))) - return -1; - onh++; - } endfor_nexthops(fi); -@@ -251,7 +251,7 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi) - nfi->fib_priority == fi->fib_priority && - memcmp(nfi->fib_metrics, fi->fib_metrics, - sizeof(u32) * RTAX_MAX) == 0 && -- ((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_F_DEAD) == 0 && -+ ((nfi->fib_flags ^ fi->fib_flags) & ~(RTNH_F_DEAD|RTNH_F_DEAD_LINKDOWN)) == 0 && - (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0)) - return fi; - } -@@ -552,7 +552,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, - return -ENODEV; - if (!(dev->flags & IFF_UP)) - return -ENETDOWN; -- if (!netif_carrier_ok(dev) && delete_dead_routes) -+ if (!netif_carrier_ok(dev) && kill_routes_on_linkdown) - nh->nh_flags |= RTNH_F_DEAD; - nh->nh_dev = dev; - dev_hold(dev); -@@ -585,7 +585,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, - if (!dev) - goto out; - dev_hold(dev); -- if (!netif_carrier_ok(dev) && delete_dead_routes) -+ if (!netif_carrier_ok(dev) && kill_routes_on_linkdown) - nh->nh_flags |= RTNH_F_DEAD; - err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN; - } else { -@@ -605,7 +605,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, - nh->nh_dev = in_dev->dev; - dev_hold(nh->nh_dev); - nh->nh_scope = RT_SCOPE_HOST; -- if (!netif_carrier_ok(nh->nh_dev) && delete_dead_routes) -+ if (!netif_carrier_ok(nh->nh_dev) && kill_routes_on_linkdown) - nh->nh_flags |= RTNH_F_DEAD; - err = 0; - } -@@ -864,7 +864,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg) - if (nexthop_nh->nh_flags & RTNH_F_DEAD) - dead++; - } endfor_nexthops(fi) -- if ((dead == fi->fib_nhs) && delete_dead_routes) { -+ if ((dead == fi->fib_nhs)) { - fi->fib_flags |= RTNH_F_DEAD; - fi->fib_flags |= RTNH_F_DEAD_LINKDOWN; - } -@@ -1088,10 +1088,7 @@ int fib_sync_down_dev(struct net_device *dev, int force) - } endfor_nexthops(fi) - if (dead == fi->fib_nhs) { - fi->fib_flags |= RTNH_F_DEAD; -- /* -- * force marks route down due to other reasons. -- * We honor that and don't set dead due to linkdown. -- */ -+ /* force marks route down due to admin down and device removal. */ - if (!force) - fi->fib_flags |= RTNH_F_DEAD_LINKDOWN; - else -@@ -1178,7 +1175,7 @@ int fib_sync_up(struct net_device *dev) - if (!(dev->flags & IFF_UP)) - return 0; - -- link_up = netif_carrier_ok(dev) || !delete_dead_routes; -+ link_up = netif_carrier_ok(dev); - prev_fi = NULL; - hash = fib_devindex_hashfn(dev->ifindex); - head = &fib_info_devhash[hash]; -@@ -1211,6 +1208,7 @@ int fib_sync_up(struct net_device *dev) - alive++; - } else - nexthop_nh->nh_flags |= RTNH_F_DEAD; -+ - spin_lock_bh(&fib_multipath_lock); - nexthop_nh->nh_power = 0; - spin_unlock_bh(&fib_multipath_lock); -diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c -index 9384158..17bd9ce 100644 ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -1386,13 +1386,17 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l, - #endif - return err; - } -- if (fi->fib_flags & RTNH_F_DEAD) -+ /* allow routes to be added if link is down */ -+ if ((fi->fib_flags & RTNH_F_DEAD) && !(fi->fib_flags & RTNH_F_DEAD_LINKDOWN)) - continue; -+ - for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) { - const struct fib_nh *nh = &fi->fib_nh[nhsel]; - -- if (nh->nh_flags & RTNH_F_DEAD) -+ /* allow next-hop to be added if link is down */ -+ if ((nh->nh_flags & RTNH_F_DEAD) && !(fi->fib_flags & RTNH_F_DEAD_LINKDOWN)) - continue; -+ - if (flp->flowi4_oif && flp->flowi4_oif != nh->nh_oif) - continue; - -@@ -1728,10 +1732,10 @@ static int trie_flush_list(struct fib_table *tb, struct leaf *l, - - list_for_each_entry_safe(fa, fa_node, &li->falh, fa_list) { - struct fib_info *fi = fa->fa_info; -+ bool ok_to_flush = !(fi->fib_flags & RTNH_F_DEAD_LINKDOWN); - - /* Do not flush route if marked dead and link is down */ -- if (fi && (fi->fib_flags & RTNH_F_DEAD) && -- !(fi->fib_flags & RTNH_F_DEAD_LINKDOWN) && delete_dead_routes) { -+ if (fi && (fi->fib_flags & RTNH_F_DEAD) && ok_to_flush) { - struct nl_info nlinfo = { .nl_net = fi->fib_net, }; - - rtmsg_fib(RTM_DELROUTE, htonl(l->key), fa, li->plen, -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index b688e41..e9309c5 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -406,7 +406,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net, - for (sprt = rt; sprt; sprt = sprt->dst.rt6_next) { - struct net_device *dev = sprt->rt6i_dev; - -- if (!netif_carrier_ok(dev) && delete_dead_routes) -+ if (!netif_carrier_ok(dev)) - continue; - - if (oif) { -@@ -574,11 +574,11 @@ static struct rt6_info *find_rr_leaf(struct fib6_node *fn, - match = NULL; - for (rt = rr_head; rt && rt->rt6i_metric == metric; - rt = rt->dst.rt6_next) -- if (netif_carrier_ok(rt->rt6i_dev) || !delete_dead_routes) -+ if (netif_carrier_ok(rt->rt6i_dev)) - match = find_match(rt, oif, strict, &mpri, match); - for (rt = fn->leaf; rt && rt != rr_head && rt->rt6i_metric == metric; - rt = rt->dst.rt6_next) -- if (netif_carrier_ok(rt->rt6i_dev) || !delete_dead_routes) -+ if (netif_carrier_ok(rt->rt6i_dev)) - match = find_match(rt, oif, strict, &mpri, match); - - return match; -@@ -2595,7 +2595,7 @@ static int rt6_fill_node(struct net *net, - if (rt->rt6i_flags&RTF_CACHE) - rtm->rtm_flags |= RTM_F_CLONED; - -- if (rt->rt6i_dev && !netif_carrier_ok(rt->rt6i_dev) && delete_dead_routes) -+ if (rt->rt6i_dev && !netif_carrier_ok(rt->rt6i_dev)) - rtm->rtm_flags |= RTNH_F_DEAD; - if (dst) { - NLA_PUT(skb, RTA_DST, 16, dst); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-fix-route-lookup-failures-when-link-down.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-fix-route-lookup-failures-when-link-down.patch deleted file mode 100644 index 2d44c194..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-fix-route-lookup-failures-when-link-down.patch +++ /dev/null @@ -1,131 +0,0 @@ -net: fix errors on route lookup when links were down - -The current code in 2.5 has a problem where software route lookups will -not honor the fact that a route is dead when doing the lookup. This is -a problem for CPU generated frames, but not for those whose forwarding -is offloaded. - -The problem with ipv4 before the change: -$ ip route show -10.0.0.0/24 dev eth1 proto kernel scope link src 10.0.0.1 -20.0.0.0/24 dev eth2 proto kernel scope link src 20.0.0.1 dead -20.0.0.0/24 via 10.0.0.2 dev eth1 metric 2 -30.0.0.0/24 dev eth3 proto kernel scope link src 30.0.0.1 -$ ip route get 20.0.0.20 -20.0.0.20 dev eth2 src 20.0.0.1 - -after the patch: -$ ip route get 20.0.0.20 -20.0.0.20 via 10.0.0.2 dev eth1 src 10.0.0.1 - -The problem with ipv6 before the change: -$ ip -6 route show -2100::/8 dev eth1 proto kernel metric 256 -2200::/8 dev eth2 proto kernel metric 256 dead -2200::/8 via 2100::2 dev eth1 metric 256 -fe80::/64 dev eth1 proto kernel metric 256 -fe80::/64 dev eth2 proto kernel metric 256 dead -fe80::/64 dev eth0 proto kernel metric 256 -$ ip -6 route get 2200::1234 -2200::1234 from :: via 2200::1234 dev eth2 src 2200::1 metric 0 - -after the patch: -$ ip -6 route get 2200:1234 -2200::1234 from :: via 2100::2 dev eth1 src 2100::1 metric 0 - -diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h -index 075f1e3..d99c19b 100644 ---- a/include/net/fib_rules.h -+++ b/include/net/fib_rules.h -@@ -33,6 +33,7 @@ struct fib_lookup_arg { - struct fib_rule *rule; - int flags; - #define FIB_LOOKUP_NOREF 1 -+#define FIB_LOOKUP_ALLOWDEAD 2 - }; - - struct fib_rules_ops { -diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h -index 2124004..2a661b7 100644 ---- a/include/net/ip_fib.h -+++ b/include/net/ip_fib.h -@@ -217,6 +217,7 @@ extern u32 fib_rules_tclass(const struct fib_result *res); - #endif - - extern int fib_lookup(struct net *n, struct flowi4 *flp, struct fib_result *res); -+extern int fib_lookup_flags(struct net *n, struct flowi4 *flp, struct fib_result *res, int flags); - - extern struct fib_table *fib_new_table(struct net *net, u32 id); - extern struct fib_table *fib_get_table(struct net *net, u32 id); -diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c -index 46339ba..593dbae 100644 ---- a/net/ipv4/fib_rules.c -+++ b/net/ipv4/fib_rules.c -@@ -56,9 +56,14 @@ u32 fib_rules_tclass(const struct fib_result *res) - - int fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res) - { -+ return fib_lookup_flags(net, flp, res, 0); -+} -+ -+int fib_lookup_flags(struct net *net, struct flowi4 *flp, struct fib_result *res, int flags) -+{ - struct fib_lookup_arg arg = { - .result = res, -- .flags = FIB_LOOKUP_NOREF, -+ .flags = FIB_LOOKUP_NOREF | flags, - }; - int err; - -diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c -index f305b9f..c5d9338 100644 ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -570,7 +570,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, - /* It is not necessary, but requires a bit of thinking */ - if (fl4.flowi4_scope < RT_SCOPE_LINK) - fl4.flowi4_scope = RT_SCOPE_LINK; -- err = fib_lookup(net, &fl4, &res); -+ err = fib_lookup_flags(net, &fl4, &res, FIB_LOOKUP_ALLOWDEAD); - if (err) { - rcu_read_unlock(); - return err; -diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c -index 17bd9ce..60c161f 100644 ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -1386,10 +1386,12 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l, - #endif - return err; - } -- /* allow routes to be added if link is down */ -- if ((fi->fib_flags & RTNH_F_DEAD) && !(fi->fib_flags & RTNH_F_DEAD_LINKDOWN)) -- continue; - -+ if (!(fib_flags & FIB_LOOKUP_ALLOWDEAD)) { -+ /* if route is dead and link is down, keep looking */ -+ if ((fi->fib_flags & RTNH_F_DEAD) && (fi->fib_flags & RTNH_F_DEAD_LINKDOWN)) -+ continue; -+ } - for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) { - const struct fib_nh *nh = &fi->fib_nh[nhsel]; - -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index 4cdf821..97015d4 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -569,12 +569,12 @@ static struct rt6_info *find_rr_leaf(struct fib6_node *fn, - int mpri = -1; - - match = NULL; -- for (rt = rr_head; rt && rt->rt6i_metric == metric; -+ for (rt = rr_head; rt; - rt = rt->dst.rt6_next) { - if (netif_carrier_ok(rt->rt6i_dev) || !kill_routes_on_linkdown) - match = find_match(rt, oif, strict, &mpri, match); - } -- for (rt = fn->leaf; rt && rt != rr_head && rt->rt6i_metric == metric; -+ for (rt = fn->leaf; rt && rt != rr_head; - rt = rt->dst.rt6_next) { - if (netif_carrier_ok(rt->rt6i_dev) || !kill_routes_on_linkdown) - match = find_match(rt, oif, strict, &mpri, match); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-fixup-ipv6-route-link-issues.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-fixup-ipv6-route-link-issues.patch deleted file mode 100644 index e244c090..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-fixup-ipv6-route-link-issues.patch +++ /dev/null @@ -1,72 +0,0 @@ -net: fix ipv6 link issues - -This honors the sysctl config option kill_routes_on_linkdown and also -make sure that a route can be properly added on an interface when the -link is down, but will not use that interface/route for forwarding. - -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index 017795c..96b5a74 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -2660,13 +2660,15 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, - } else { - if (!addrconf_qdisc_ok(dev)) { - /* device is still not ready. */ -- rt6_link_change(dev_net(dev), dev); -+ if (kill_routes_on_linkdown) -+ rt6_link_change(dev_net(dev), dev); - break; - } - - if (idev) { - if (idev->if_flags & IF_READY) { -- rt6_link_change(dev_net(dev), dev); -+ if (kill_routes_on_linkdown) -+ rt6_link_change(dev_net(dev), dev); - /* device is already configured. */ - break; - } -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index e9309c5..4cdf821 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -406,9 +406,6 @@ static inline struct rt6_info *rt6_device_match(struct net *net, - for (sprt = rt; sprt; sprt = sprt->dst.rt6_next) { - struct net_device *dev = sprt->rt6i_dev; - -- if (!netif_carrier_ok(dev)) -- continue; -- - if (oif) { - if (dev->ifindex == oif) - return sprt; -@@ -573,14 +570,15 @@ static struct rt6_info *find_rr_leaf(struct fib6_node *fn, - - match = NULL; - for (rt = rr_head; rt && rt->rt6i_metric == metric; -- rt = rt->dst.rt6_next) -- if (netif_carrier_ok(rt->rt6i_dev)) -+ rt = rt->dst.rt6_next) { -+ if (netif_carrier_ok(rt->rt6i_dev) || !kill_routes_on_linkdown) - match = find_match(rt, oif, strict, &mpri, match); -+ } - for (rt = fn->leaf; rt && rt != rr_head && rt->rt6i_metric == metric; -- rt = rt->dst.rt6_next) -- if (netif_carrier_ok(rt->rt6i_dev)) -+ rt = rt->dst.rt6_next) { -+ if (netif_carrier_ok(rt->rt6i_dev) || !kill_routes_on_linkdown) - match = find_match(rt, oif, strict, &mpri, match); -- -+ } - return match; - } - -@@ -2595,7 +2593,7 @@ static int rt6_fill_node(struct net *net, - if (rt->rt6i_flags&RTF_CACHE) - rtm->rtm_flags |= RTM_F_CLONED; - -- if (rt->rt6i_dev && !netif_carrier_ok(rt->rt6i_dev)) -+ if (rt->rt6i_dev && !netif_carrier_ok(rt->rt6i_dev) && kill_routes_on_linkdown) - rtm->rtm_flags |= RTNH_F_DEAD; - if (dst) { - NLA_PUT(skb, RTA_DST, 16, dst); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-increase-max-igmp-groups.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-increase-max-igmp-groups.patch deleted file mode 100644 index 5d18dfa9..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-increase-max-igmp-groups.patch +++ /dev/null @@ -1,23 +0,0 @@ -#Copyright 2012 Cumulus Networks, Inc. All rights reserved. - -The kernel limits the number of IGMP (IP multicast) groups that a host can join. -There is a sysctl field, igmp_max_memberships, that both adjusts this as well as -can change away from the default. - -Since we're a router with about 64 ports and OSPF, the most popular IGP, uses IP -multicast for hellos, the default number of groups that we can joing has been -increased to 96. - -diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c -index 75b0860..79c0977 100644 ---- a/net/ipv4/igmp.c -+++ b/net/ipv4/igmp.c -@@ -106,7 +106,7 @@ - #include - #endif - --#define IP_MAX_MEMBERSHIPS 20 -+#define IP_MAX_MEMBERSHIPS 96 - #define IP_MAX_MSF 10 - - #ifdef CONFIG_IP_MULTICAST diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-fib-flush-dead-routes-notify.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-fib-flush-dead-routes-notify.patch deleted file mode 100644 index 2d44061f..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-fib-flush-dead-routes-notify.patch +++ /dev/null @@ -1,59 +0,0 @@ -This notification is missing in IPv4 (in IPv6, deleted routes are -notified). - -Signed-off-by: Nicolas Dichtel - -diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c -index c7c6724..17d4d47 100644 ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -1717,15 +1717,20 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) - return 0; - } - --static int trie_flush_list(struct list_head *head) -+static int trie_flush_list(struct fib_table *tb, struct leaf *l, -+ struct leaf_info *li) - { - struct fib_alias *fa, *fa_node; - int found = 0; - -- list_for_each_entry_safe(fa, fa_node, head, fa_list) { -+ list_for_each_entry_safe(fa, fa_node, &li->falh, fa_list) { - struct fib_info *fi = fa->fa_info; - - if (fi && (fi->fib_flags & RTNH_F_DEAD)) { -+ struct nl_info nlinfo = { .nl_net = fi->fib_net, }; -+ -+ rtmsg_fib(RTM_DELROUTE, htonl(l->key), fa, li->plen, -+ tb->tb_id, &nlinfo, 0); - list_del_rcu(&fa->fa_list); - fib_release_info(fa->fa_info); - alias_free_mem_rcu(fa); -@@ -1735,7 +1740,7 @@ static int trie_flush_list(struct list_head *head) - return found; - } - --static int trie_flush_leaf(struct leaf *l) -+static int trie_flush_leaf(struct fib_table *tb, struct leaf *l) - { - int found = 0; - struct hlist_head *lih = &l->list; -@@ -1743,7 +1748,7 @@ static int trie_flush_leaf(struct leaf *l) - struct leaf_info *li = NULL; - - hlist_for_each_entry_safe(li, node, tmp, lih, hlist) { -- found += trie_flush_list(&li->falh); -+ found += trie_flush_list(tb, l, li); - - if (list_empty(&li->falh)) { - hlist_del_rcu(&li->hlist); -@@ -1832,7 +1837,7 @@ int fib_table_flush(struct fib_table *tb) - int found = 0; - - for (l = trie_firstleaf(t); l; l = trie_nextleaf(l)) { -- found += trie_flush_leaf(l); -+ found += trie_flush_leaf(tb, l); - - if (ll && hlist_empty(&ll->list)) - trie_leaf_remove(t, ll); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-igmp-use-in_dev_put-in-timer-handlers.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-igmp-use-in_dev_put-in-timer-handlers.patch deleted file mode 100644 index 7fd8e684..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-igmp-use-in_dev_put-in-timer-handlers.patch +++ /dev/null @@ -1,46 +0,0 @@ -Backport of commit 003efcca2ad3e471e9103688a715bd33e29cb37b from 3.2.y linux -stable kernel branch - -From 003efcca2ad3e471e9103688a715bd33e29cb37b Mon Sep 17 00:00:00 2001 -Subject: [PATCH 1/2] ipv4 igmp: use in_dev_put in timer handlers instead of - __in_dev_put - -[ Upstream commit e2401654dd0f5f3fb7a8d80dad9554d73d7ca394 ] - -It is possible for the timer handlers to run after the call to -ip_mc_down so use in_dev_put instead of __in_dev_put in the handler -function in order to do proper cleanup when the refcnt reaches 0. -Otherwise, the refcnt can reach zero without the in_device being -destroyed and we end up leaking a reference to the net_device and -see messages like the following, - -unregister_netdevice: waiting for eth0 to become free. Usage count = 1 - -Tested on linux-3.4.43. - -Signed-off-by: Salam Noureddine -Signed-off-by: David S. Miller -Signed-off-by: Ben Hutchings - -diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c -index 08f6847..b60935a 100644 ---- a/net/ipv4/igmp.c -+++ b/net/ipv4/igmp.c -@@ -705,7 +705,7 @@ static void igmp_gq_timer_expire(unsigned long data) - - in_dev->mr_gq_running = 0; - igmpv3_send_report(in_dev, NULL); -- __in_dev_put(in_dev); -+ in_dev_put(in_dev); - } - - static void igmp_ifc_timer_expire(unsigned long data) -@@ -717,7 +717,7 @@ static void igmp_ifc_timer_expire(unsigned long data) - in_dev->mr_ifc_count--; - igmp_ifc_start_timer(in_dev, IGMP_Unsolicited_Report_Interval); - } -- __in_dev_put(in_dev); -+ in_dev_put(in_dev); - } - - static void igmp_ifc_event(struct in_device *in_dev) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-include-append-flag-in-notification.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-include-append-flag-in-notification.patch deleted file mode 100644 index 9d5b4d95..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-include-append-flag-in-notification.patch +++ /dev/null @@ -1,32 +0,0 @@ -Add support in kernel to send append flag for ipv4 route append - -diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c -index 17d4d47..948ee5c 100644 ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -1194,6 +1194,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) - u32 key, mask; - int err; - struct leaf *l; -+ unsigned int flags = 0; - - if (plen > 32) - return -EINVAL; -@@ -1304,6 +1305,8 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) - - if (!(cfg->fc_nlflags & NLM_F_APPEND)) - fa = fa_first; -+ else -+ flags |= NLM_F_APPEND; - } - err = -ENOENT; - if (!(cfg->fc_nlflags & NLM_F_CREATE)) -@@ -1338,7 +1341,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) - - rt_cache_flush(cfg->fc_nlinfo.nl_net, -1); - rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, -- &cfg->fc_nlinfo, 0); -+ &cfg->fc_nlinfo, flags); - succeeded: - return 0; - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-send-nlflags-in-route-insert-notify-msg.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-send-nlflags-in-route-insert-notify-msg.patch deleted file mode 100644 index 718c3c38..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv4-send-nlflags-in-route-insert-notify-msg.patch +++ /dev/null @@ -1,15 +0,0 @@ -route: Send flags in new route notify - -diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c -index 06172d6..10bbea4 100644 ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -1339,7 +1339,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) - - rt_cache_flush(cfg->fc_nlinfo.nl_net, -1); - rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, -- &cfg->fc_nlinfo, 0); -+ &cfg->fc_nlinfo, cfg->fc_nlflags); - succeeded: - return 0; - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-add-ecmp-support.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-add-ecmp-support.patch deleted file mode 100644 index 479cee29..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-add-ecmp-support.patch +++ /dev/null @@ -1,348 +0,0 @@ -From 51ebd3181572af8d5076808dab2682d800f6da5d Mon Sep 17 00:00:00 2001 -Subject: ipv6: add support of equal cost multipath (ECMP) - -Each nexthop is added like a single route in the routing table. All routes -that have the same metric/weight and destination but not the same gateway -are considering as ECMP routes. They are linked together, through a list called -rt6i_siblings. - -ECMP routes can be added in one shot, with RTA_MULTIPATH attribute or one after -the other (in both case, the flag NLM_F_EXCL should not be set). - -The patch is based on a previous work from -Luc Saillard . - -Signed-off-by: Nicolas Dichtel -Signed-off-by: David S. Miller - -diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h -index cbae4c5..b60e6ca 100644 ---- a/include/net/ip6_fib.h -+++ b/include/net/ip6_fib.h -@@ -47,6 +47,8 @@ struct fib6_config { - unsigned long fc_expires; - struct nlattr *fc_mx; - int fc_mx_len; -+ int fc_mp_len; -+ struct nlattr *fc_mp; - - struct nl_info fc_nlinfo; - }; -@@ -100,6 +102,14 @@ struct rt6_info { - - struct in6_addr rt6i_gateway; - -+ /* Multipath routes: -+ * siblings is a list of rt6_info that have the the same metric/weight, -+ * destination, but not the same gateway. nsiblings is just a cache -+ * to speed up lookup. -+ */ -+ struct list_head rt6i_siblings; -+ unsigned int rt6i_nsiblings; -+ - atomic_t rt6i_ref; - - /* These are in a separate cache line. */ -diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c -index 443724f..15de060 100644 ---- a/net/ipv6/ip6_fib.c -+++ b/net/ipv6/ip6_fib.c -@@ -631,6 +631,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, - iter->rt6i_idev == rt->rt6i_idev && - ipv6_addr_equal(&iter->rt6i_gateway, - &rt->rt6i_gateway)) { -+ if (rt->rt6i_nsiblings) -+ rt->rt6i_nsiblings = 0; - if (!(iter->rt6i_flags&RTF_EXPIRES)) - return -EEXIST; - iter->rt6i_expires = rt->rt6i_expires; -@@ -640,6 +642,21 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, - } - return -EEXIST; - } -+ /* If we have the same destination and the same metric, -+ * but not the same gateway, then the route we try to -+ * add is sibling to this route, increment our counter -+ * of siblings, and later we will add our route to the -+ * list. -+ * Only static routes (which don't have flag -+ * RTF_EXPIRES) are used for ECMPv6. -+ * -+ * To avoid long list, we only had siblings if the -+ * route have a gateway. -+ */ -+ if (rt->rt6i_flags & RTF_GATEWAY && -+ !(rt->rt6i_flags & RTF_EXPIRES) && -+ !(iter->rt6i_flags & RTF_EXPIRES)) -+ rt->rt6i_nsiblings++; - } - - if (iter->rt6i_metric > rt->rt6i_metric) -@@ -652,6 +669,35 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, - if (ins == &fn->leaf) - fn->rr_ptr = NULL; - -+ /* Link this route to others same route. */ -+ if (rt->rt6i_nsiblings) { -+ unsigned int rt6i_nsiblings; -+ struct rt6_info *sibling, *temp_sibling; -+ -+ /* Find the first route that have the same metric */ -+ sibling = fn->leaf; -+ while (sibling) { -+ if (sibling->rt6i_metric == rt->rt6i_metric) { -+ list_add_tail(&rt->rt6i_siblings, -+ &sibling->rt6i_siblings); -+ break; -+ } -+ sibling = sibling->dst.rt6_next; -+ } -+ /* For each sibling in the list, increment the counter of -+ * siblings. BUG() if counters does not match, list of siblings -+ * is broken! -+ */ -+ rt6i_nsiblings = 0; -+ list_for_each_entry_safe(sibling, temp_sibling, -+ &rt->rt6i_siblings, rt6i_siblings) { -+ sibling->rt6i_nsiblings++; -+ BUG_ON(sibling->rt6i_nsiblings != rt->rt6i_nsiblings); -+ rt6i_nsiblings++; -+ } -+ BUG_ON(rt6i_nsiblings != rt->rt6i_nsiblings); -+ } -+ - /* - * insert node - */ -@@ -1123,6 +1169,17 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, - if (fn->rr_ptr == rt) - fn->rr_ptr = NULL; - -+ /* Remove this entry from other siblings */ -+ if (rt->rt6i_nsiblings) { -+ struct rt6_info *sibling, *next_sibling; -+ -+ list_for_each_entry_safe(sibling, next_sibling, -+ &rt->rt6i_siblings, rt6i_siblings) -+ sibling->rt6i_nsiblings--; -+ rt->rt6i_nsiblings = 0; -+ list_del_init(&rt->rt6i_siblings); -+ } -+ - /* Adjust walkers */ - read_lock(&fib6_walker_lock); - FOR_WALKERS(w) { -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index a5d346a..c3be1a3 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -55,6 +55,7 @@ - #include - #include - #include -+#include - - #include - -@@ -247,10 +248,12 @@ static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops, - { - struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, flags); - -- if (rt != NULL) -+ if (rt != NULL) { - memset(&rt->rt6i_table, 0, - sizeof(*rt) - sizeof(struct dst_entry)); -- -+ INIT_LIST_HEAD(&rt->rt6i_siblings); -+ rt->rt6i_nsiblings = 0; -+ } - return rt; - } - -@@ -321,6 +324,69 @@ static inline int rt6_need_strict(const struct in6_addr *daddr) - (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); - } - -+/* Multipath route selection: -+ * Hash based function using packet header and flowlabel. -+ * Adapted from fib_info_hashfn() -+ */ -+static int rt6_info_hash_nhsfn(unsigned int candidate_count, -+ const struct flowi6 *fl6) -+{ -+ unsigned int val = fl6->flowi6_proto; -+ -+ val ^= fl6->daddr.s6_addr32[0]; -+ val ^= fl6->daddr.s6_addr32[1]; -+ val ^= fl6->daddr.s6_addr32[2]; -+ val ^= fl6->daddr.s6_addr32[3]; -+ -+ val ^= fl6->saddr.s6_addr32[0]; -+ val ^= fl6->saddr.s6_addr32[1]; -+ val ^= fl6->saddr.s6_addr32[2]; -+ val ^= fl6->saddr.s6_addr32[3]; -+ -+ /* Work only if this not encapsulated */ -+ switch (fl6->flowi6_proto) { -+ case IPPROTO_UDP: -+ case IPPROTO_TCP: -+ case IPPROTO_SCTP: -+ val ^= fl6->fl6_sport; -+ val ^= fl6->fl6_dport; -+ break; -+ -+ case IPPROTO_ICMPV6: -+ val ^= fl6->fl6_icmp_type; -+ val ^= fl6->fl6_icmp_code; -+ break; -+ } -+ /* RFC6438 recommands to use flowlabel */ -+ val ^= fl6->flowlabel; -+ -+ /* Perhaps, we need to tune, this function? */ -+ val = val ^ (val >> 7) ^ (val >> 12); -+ return val % candidate_count; -+} -+ -+static struct rt6_info *rt6_multipath_select(struct rt6_info *match, -+ struct flowi6 *fl6) -+{ -+ struct rt6_info *sibling, *next_sibling; -+ int route_choosen; -+ -+ route_choosen = rt6_info_hash_nhsfn(match->rt6i_nsiblings + 1, fl6); -+ /* Don't change the route, if route_choosen == 0 -+ * (siblings does not include ourself) -+ */ -+ if (route_choosen) -+ list_for_each_entry_safe(sibling, next_sibling, -+ &match->rt6i_siblings, rt6i_siblings) { -+ route_choosen--; -+ if (route_choosen == 0) { -+ match = sibling; -+ break; -+ } -+ } -+ return match; -+} -+ - /* - * Route lookup. Any table->tb6_lock is implied. - */ -@@ -653,6 +719,8 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net, - restart: - rt = fn->leaf; - rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags); -+ if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0) -+ rt = rt6_multipath_select(rt, fl6); - BACKTRACK(net, &fl6->saddr); - out: - dst_use(&rt->dst, jiffies); -@@ -816,7 +884,8 @@ restart_2: - - restart: - rt = rt6_select(fn, oif, strict | reachable); -- -+ if (rt->rt6i_nsiblings && oif == 0) -+ rt = rt6_multipath_select(rt, fl6); - BACKTRACK(net, &fl6->saddr); - if (rt == net->ipv6.ip6_null_entry || - rt->rt6i_flags & RTF_CACHE) -@@ -2244,6 +2313,7 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = { - [RTA_IIF] = { .type = NLA_U32 }, - [RTA_PRIORITY] = { .type = NLA_U32 }, - [RTA_METRICS] = { .type = NLA_NESTED }, -+ [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) }, - }; - - static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, -@@ -2320,11 +2390,65 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, - if (tb[RTA_TABLE]) - cfg->fc_table = nla_get_u32(tb[RTA_TABLE]); - -+ if (tb[RTA_MULTIPATH]) { -+ cfg->fc_mp = nla_data(tb[RTA_MULTIPATH]); -+ cfg->fc_mp_len = nla_len(tb[RTA_MULTIPATH]); -+ } -+ - err = 0; - errout: - return err; - } - -+static int ip6_route_multipath(struct fib6_config *cfg, int add) -+{ -+ struct fib6_config r_cfg; -+ struct rtnexthop *rtnh; -+ int remaining; -+ int attrlen; -+ int err = 0, last_err = 0; -+ -+beginning: -+ rtnh = (struct rtnexthop *)cfg->fc_mp; -+ remaining = cfg->fc_mp_len; -+ -+ /* Parse a Multipath Entry */ -+ while (rtnh_ok(rtnh, remaining)) { -+ memcpy(&r_cfg, cfg, sizeof(*cfg)); -+ if (rtnh->rtnh_ifindex) -+ r_cfg.fc_ifindex = rtnh->rtnh_ifindex; -+ -+ attrlen = rtnh_attrlen(rtnh); -+ if (attrlen > 0) { -+ struct nlattr *nla, *attrs = rtnh_attrs(rtnh); -+ -+ nla = nla_find(attrs, attrlen, RTA_GATEWAY); -+ if (nla) { -+ nla_memcpy(&r_cfg.fc_gateway, nla, 16); -+ r_cfg.fc_flags |= RTF_GATEWAY; -+ } -+ } -+ err = add ? ip6_route_add(&r_cfg) : ip6_route_del(&r_cfg); -+ if (err) { -+ last_err = err; -+ /* If we are trying to remove a route, do not stop the -+ * loop when ip6_route_del() fails (because next hop is -+ * already gone), we should try to remove all next hops. -+ */ -+ if (add) { -+ /* If add fails, we should try to delete all -+ * next hops that have been already added. -+ */ -+ add = 0; -+ goto beginning; -+ } -+ } -+ rtnh = rtnh_next(rtnh, &remaining); -+ } -+ -+ return last_err; -+} -+ - static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) - { - struct fib6_config cfg; -@@ -2334,7 +2458,10 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a - if (err < 0) - return err; - -- return ip6_route_del(&cfg); -+ if (cfg.fc_mp) -+ return ip6_route_multipath(&cfg, 0); -+ else -+ return ip6_route_del(&cfg); - } - - static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) -@@ -2346,7 +2473,10 @@ static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a - if (err < 0) - return err; - -- return ip6_route_add(&cfg); -+ if (cfg.fc_mp) -+ return ip6_route_multipath(&cfg, 1); -+ else -+ return ip6_route_add(&cfg); - } - - static inline size_t rt6_nlmsg_size(void) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-add-knob-to-send-unsolicited-ND-on-link-layer-address-change.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-add-knob-to-send-unsolicited-ND-on-link-layer-address-change.patch deleted file mode 100644 index 8d1f63b3..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-add-knob-to-send-unsolicited-ND-on-link-layer-address-change.patch +++ /dev/null @@ -1,89 +0,0 @@ -[This is upstream patch with a small change. The enum change -in upstream version is in the uapi header file. -uapi is not present in debian and i did not want to bring in that -change] - -commit 5cb04436eef62aa8f5c482f8ec8deba391dea465 -Author: Hannes Frederic Sowa -Date: Tue Nov 6 16:46:20 2012 +0000 - - ipv6: add knob to send unsolicited ND on link-layer address change - - This patch introduces a new knob ndisc_notify. If enabled, the kernel - will transmit an unsolicited neighbour advertisement on link-layer address - change to update the neighbour tables of the corresponding hosts more quickly. - - This is the equivalent to arp_notify in ipv4 world. - - Signed-off-by: Hannes Frederic Sowa - Signed-off-by: David S. Miller - -diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h -index 84b1447..2857039 100644 ---- a/include/linux/ipv6.h -+++ b/include/linux/ipv6.h -@@ -172,6 +172,7 @@ struct ipv6_devconf { - __s32 disable_ipv6; - __s32 accept_dad; - __s32 force_tllao; -+ __s32 ndisc_notify; - void *sysctl; - }; - -@@ -213,6 +214,7 @@ enum { - DEVCONF_DISABLE_IPV6, - DEVCONF_ACCEPT_DAD, - DEVCONF_FORCE_TLLAO, -+ DEVCONF_NDISC_NOTIFY, - DEVCONF_MAX - }; - -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index b9edff0..b42d74a 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -3953,6 +3953,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, - array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6; - array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad; - array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; -+ array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify; - } - - static inline size_t inet6_ifla6_size(void) -@@ -4607,6 +4608,13 @@ static struct addrconf_sysctl_table - .proc_handler = proc_dointvec - }, - { -+ .procname = "ndisc_notify", -+ .data = &ipv6_devconf.ndisc_notify, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = proc_dointvec -+ }, -+ { - /* sentinel */ - } - }, -diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c -index 5c6399c..aaa5961 100644 ---- a/net/ipv6/ndisc.c -+++ b/net/ipv6/ndisc.c -@@ -1729,11 +1729,18 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, - { - struct net_device *dev = ptr; - struct net *net = dev_net(dev); -+ struct inet6_dev *idev; - - switch (event) { - case NETDEV_CHANGEADDR: - neigh_changeaddr(&nd_tbl, dev); - fib6_run_gc(~0UL, net); -+ idev = in6_dev_get(dev); -+ if (!idev) -+ break; -+ if (idev->cnf.ndisc_notify) -+ ndisc_send_unsol_na(dev); -+ in6_dev_put(idev); - break; - case NETDEV_DOWN: - neigh_ifdown(&nd_tbl, dev); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-assign-rt6_info-to-inet6_ifaddr.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-assign-rt6_info-to-inet6_ifaddr.patch deleted file mode 100644 index bf28e707..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-assign-rt6_info-to-inet6_ifaddr.patch +++ /dev/null @@ -1,38 +0,0 @@ -Backport of commit 192b2d2a8319dbfa1b7b57d4cc873b09ada9f507from 3.2.y linux -stable kernel branch - -From 192b2d2a8319dbfa1b7b57d4cc873b09ada9f507 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] ipv6: assign rt6_info to inet6_ifaddr in init_loopback - -[ Upstream commit 534c877928a16ae5f9776436a497109639bf67dc ] - -Commit 25fb6ca4ed9cad72f14f61629b68dc03c0d9713f -"net IPv6 : Fix broken IPv6 routing table after loopback down-up" -forgot to assign rt6_info to the inet6_ifaddr. -When disable the net device, the rt6_info which allocated -in init_loopback will not be destroied in __ipv6_ifa_notify. - -This will trigger the waring message below -[23527.916091] unregister_netdevice: waiting for tap0 to become free. Usage count = 1 - -Reported-by: Arkadiusz Miskiewicz -Signed-off-by: Gao feng -Signed-off-by: David S. Miller -Signed-off-by: Ben Hutchings - -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index 34e6f0e..8490339 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -2439,8 +2439,10 @@ static void init_loopback(struct net_device *dev) - sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); - - /* Failure cases are ignored */ -- if (!IS_ERR(sp_rt)) -+ if (!IS_ERR(sp_rt)) { -+ sp_ifa->rt = sp_rt; - ip6_ins_rt(sp_rt); -+ } - } - read_unlock_bh(&idev->lock); - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-blackhole-route-support.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-blackhole-route-support.patch deleted file mode 100644 index e2508db4..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-blackhole-route-support.patch +++ /dev/null @@ -1,107 +0,0 @@ -Support for blackhole routes for ipv6 - -Pulling upstream patch from latest kernel - -Upstream commit log: -"commit ef2c7d7b59708d54213c7556a82d14de9a7e4475 -Author: Nicolas Dichtel -Date: Wed Sep 5 02:12:42 2012 +0000 - - ipv6: fix handling of blackhole and prohibit routes - - When adding a blackhole or a prohibit route, they were handling like classic - routes. Moreover, it was only possible to add this kind of routes by specifying - an interface. - - Bug already reported here: - http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=498498 - - Before the patch: - $ ip route add blackhole 2001::1/128 - RTNETLINK answers: No such device - $ ip route add blackhole 2001::1/128 dev eth0 - $ ip -6 route | grep 2001 - 2001::1 dev eth0 metric 1024 - - After: - $ ip route add blackhole 2001::1/128 - $ ip -6 route | grep 2001 - blackhole 2001::1 dev lo metric 1024 error -22 - - v2: wrong patch - v3: add a field fc_type in struct fib6_config to store RTN_* type - - Signed-off-by: Nicolas Dichtel - Signed-off-by: David S. Miller " - -diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h -index 5735a0f..cbae4c5 100644 ---- a/include/net/ip6_fib.h -+++ b/include/net/ip6_fib.h -@@ -37,6 +37,7 @@ struct fib6_config { - int fc_ifindex; - u32 fc_flags; - u32 fc_protocol; -+ u32 fc_type; /* only 8 bits are used */ - - struct in6_addr fc_dst; - struct in6_addr fc_src; -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index 782f67a..a5d346a 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -1320,8 +1320,18 @@ int ip6_route_add(struct fib6_config *cfg) - } - rt->dst.output = ip6_pkt_discard_out; - rt->dst.input = ip6_pkt_discard; -- rt->dst.error = -ENETUNREACH; - rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; -+ switch (cfg->fc_type) { -+ case RTN_BLACKHOLE: -+ rt->dst.error = -EINVAL; -+ break; -+ case RTN_PROHIBIT: -+ rt->dst.error = -EACCES; -+ break; -+ default: -+ rt->dst.error = -ENETUNREACH; -+ break; -+ } - goto install_route; - } - -@@ -2256,8 +2266,11 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, - cfg->fc_src_len = rtm->rtm_src_len; - cfg->fc_flags = RTF_UP; - cfg->fc_protocol = rtm->rtm_protocol; -+ cfg->fc_type = rtm->rtm_type; - -- if (rtm->rtm_type == RTN_UNREACHABLE) -+ if (rtm->rtm_type == RTN_UNREACHABLE || -+ rtm->rtm_type == RTN_BLACKHOLE || -+ rtm->rtm_type == RTN_PROHIBIT) - cfg->fc_flags |= RTF_REJECT; - - if (rtm->rtm_type == RTN_LOCAL) -@@ -2385,8 +2398,19 @@ static int rt6_fill_node(struct net *net, - table = RT6_TABLE_UNSPEC; - rtm->rtm_table = table; - NLA_PUT_U32(skb, RTA_TABLE, table); -- if (rt->rt6i_flags&RTF_REJECT) -- rtm->rtm_type = RTN_UNREACHABLE; -+ if (rt->rt6i_flags & RTF_REJECT) { -+ switch (rt->dst.error) { -+ case -EINVAL: -+ rtm->rtm_type = RTN_BLACKHOLE; -+ break; -+ case -EACCES: -+ rtm->rtm_type = RTN_PROHIBIT; -+ break; -+ default: -+ rtm->rtm_type = RTN_UNREACHABLE; -+ break; -+ } -+ } - else if (rt->rt6i_flags&RTF_LOCAL) - rtm->rtm_type = RTN_LOCAL; - else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK)) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-dont-call-addrconf_dst_alloc-again-when-enable.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-dont-call-addrconf_dst_alloc-again-when-enable.patch deleted file mode 100644 index 794bcfa1..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-dont-call-addrconf_dst_alloc-again-when-enable.patch +++ /dev/null @@ -1,37 +0,0 @@ -Backport of commit 7d854d8b7d7eb9994259b8edc414baccd697ae8a 3.2.y linux -stable kernel branch - -From 7d854d8b7d7eb9994259b8edc414baccd697ae8a Mon Sep 17 00:00:00 2001 -Subject: [PATCH] ipv6: don't call addrconf_dst_alloc again when enable lo - -[ Upstream commit a881ae1f625c599b460cc8f8a7fcb1c438f699ad ] - -If we disable all of the net interfaces, and enable -un-lo interface before lo interface, we already allocated -the addrconf dst in ipv6_add_addr. So we shouldn't allocate -it again when we enable lo interface. - -Otherwise the message below will be triggered. -unregister_netdevice: waiting for sit1 to become free. Usage count = 1 - -This problem is introduced by commit 25fb6ca4ed9cad72f14f61629b68dc03c0d9713f -"net IPv6 : Fix broken IPv6 routing table after loopback down-up" - -Signed-off-by: Gao feng -Signed-off-by: David S. Miller -Signed-off-by: Ben Hutchings - -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index 8490339..688ab77 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -2436,6 +2436,9 @@ static void init_loopback(struct net_device *dev) - if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) - continue; - -+ if (sp_ifa->rt) -+ continue; -+ - sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); - - /* Failure cases are ignored */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-dont-disable-interface-with-no-addrs.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-dont-disable-interface-with-no-addrs.patch deleted file mode 100644 index 19c702fb..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-dont-disable-interface-with-no-addrs.patch +++ /dev/null @@ -1,27 +0,0 @@ -ipv6: don't disable interface if last ipv6 address is removed - -Backport of upstream commit: - -commit 876fd05ddbae03166e7037fca957b55bb3be6594 -Author: Hannes Frederic Sowa -Date: Mon Jun 24 00:22:20 2013 +0200 - - ipv6: don't disable interface if last ipv6 address is removed - -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index 96b5a74..57375fd 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -2290,12 +2290,6 @@ static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *p - read_unlock_bh(&idev->lock); - - ipv6_del_addr(ifp); -- -- /* If the last address is deleted administratively, -- disable IPv6 on this interface. -- */ -- if (list_empty(&idev->addr_list)) -- addrconf_ifdown(idev->dev, 1); - return 0; - } - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-fib-fix-fib-dump-restart-next-node.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-fib-fix-fib-dump-restart-next-node.patch deleted file mode 100644 index 49488a87..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-fib-fix-fib-dump-restart-next-node.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 1c2658545816088477e91860c3a645053719cb54 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] ipv6: fib: fix fib dump restart - -When the ipv6 fib changes during a table dump, the walk is -restarted and the number of nodes dumped are skipped. But the existing -code doesn't advance to the next node after a node is skipped. This can -cause the dump to loop or produce lots of duplicates when the fib -is modified during the dump. - -This change advances the walk to the next node if the current node is -skipped after a restart. - -Signed-off-by: Kumar Sundararajan -Signed-off-by: Chris Mason -Signed-off-by: David S. Miller - -diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c -index f7fba99..82e8033 100644 ---- a/net/ipv6/ip6_fib.c -+++ b/net/ipv6/ip6_fib.c -@@ -1335,7 +1335,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w) - - if (w->skip) { - w->skip--; -- continue; -+ goto skip; - } - - err = w->func(w); -@@ -1345,6 +1345,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w) - w->count++; - continue; - } -+skip: - w->state = FWS_U; - case FWS_U: - if (fn == w->root) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-fib-fix-fib-dump-restart.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-fib-fix-fib-dump-restart.patch deleted file mode 100644 index 2a6092a4..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-fib-fix-fib-dump-restart.patch +++ /dev/null @@ -1,33 +0,0 @@ -From fa809e2fd6e317226c046202a88520962672eac0 Mon Sep 17 00:00:00 2001 -Subject: [PATCH] ipv6: fib: fix fib dump restart - -Commit 2bec5a369ee79576a3 (ipv6: fib: fix crash when changing large fib -while dumping it) introduced ability to restart the dump at tree root, -but failed to skip correctly a count of already dumped entries. Code -didn't match Patrick intent. - -We must skip exactly the number of already dumped entries. - -Note that like other /proc/net files or netlink producers, we could -still dump some duplicates entries. - -Reported-by: Debabrata Banerjee -Reported-by: Josh Hunt -Signed-off-by: Eric Dumazet -Signed-off-by: David S. Miller - -diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c -index 15de060..f7fba99 100644 ---- a/net/ipv6/ip6_fib.c -+++ b/net/ipv6/ip6_fib.c -@@ -1333,8 +1333,8 @@ static int fib6_walk_continue(struct fib6_walker_t *w) - if (w->leaf && fn->fn_flags&RTN_RTINFO) { - int err; - -- if (w->count < w->skip) { -- w->count++; -+ if (w->skip) { -+ w->skip--; - continue; - } - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-mcast-use-in6_dev_put-in-timer-handlers.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-mcast-use-in6_dev_put-in-timer-handlers.patch deleted file mode 100644 index 6466f60f..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-mcast-use-in6_dev_put-in-timer-handlers.patch +++ /dev/null @@ -1,46 +0,0 @@ -Backport of commit 765844f8edd831563fc646c7f747abf89eef4d4d 3.2.y linux -stable kernel branch - -From 765844f8edd831563fc646c7f747abf89eef4d4d Mon Sep 17 00:00:00 2001 -Subject: [PATCH 2/2] ipv6 mcast: use in6_dev_put in timer handlers instead of - __in6_dev_put - -[ Upstream commit 9260d3e1013701aa814d10c8fc6a9f92bd17d643 ] - -It is possible for the timer handlers to run after the call to -ipv6_mc_down so use in6_dev_put instead of __in6_dev_put in the -handler function in order to do proper cleanup when the refcnt -reaches 0. Otherwise, the refcnt can reach zero without the -inet6_dev being destroyed and we end up leaking a reference to -the net_device and see messages like the following, - -unregister_netdevice: waiting for eth0 to become free. Usage count = 1 - -Tested on linux-3.4.43. - -Signed-off-by: Salam Noureddine -Signed-off-by: David S. Miller -Signed-off-by: Ben Hutchings - -diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c -index 1c1b3c7..e7b3457 100644 ---- a/net/ipv6/mcast.c -+++ b/net/ipv6/mcast.c -@@ -2157,7 +2157,7 @@ static void mld_gq_timer_expire(unsigned long data) - - idev->mc_gq_running = 0; - mld_send_report(idev, NULL); -- __in6_dev_put(idev); -+ in6_dev_put(idev); - } - - static void mld_ifc_timer_expire(unsigned long data) -@@ -2170,7 +2170,7 @@ static void mld_ifc_timer_expire(unsigned long data) - if (idev->mc_ifc_count) - mld_ifc_start_timer(idev, idev->mc_maxdelay); - } -- __in6_dev_put(idev); -+ in6_dev_put(idev); - } - - static void mld_ifc_event(struct inet6_dev *idev) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-route-fix-multipath-duplicate-nexthops.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-route-fix-multipath-duplicate-nexthops.patch deleted file mode 100644 index 80cb87ed..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-route-fix-multipath-duplicate-nexthops.patch +++ /dev/null @@ -1,71 +0,0 @@ -Problem: -(route output trimmed to show example): -# ip -6 route add 2001:10:1:3::/64 nexthop via 2001:10:1:2::99 - -# ip -6 route show -2001:10:1:3::/64 via 2001:10:1:2::99 dev swp26 metric 1024 - -# ip -6 route add 2001:10:1:3::/64 nexthop via 2001:10:1:2::99 -RTNETLINK answers: File exists - -# ip route show -# -/* Previously added route vanished */ - -When the route add fails with -EXISTS, kernel in its cleanup path tries -to delete all nexthops added so far. This cleanup logic has a bug. -It tries to delete all the nexthops given by user. In the above case though -the route was added by the user in his previous attempts, just because it -matches with the nexthop in the new request, the previously added route is -deleted. The patch fixes this cleanup handling by introducing a few flags. -Did not want to change the function too much. - -The other problem is the misleading error code (-ESRCH): -# ip -6 route add 2001:10:1:3::/64 nexthop via 2001:10:1:2::99 nexthop via 2001:10:1:2::99 -RTNETLINK answers: No such process - -In the above case, the second nexthop add fails with -EXIST, -but when it tries to delete all the nexthops the first one deletes fine, -and the second nexthop results in -ESRCH (which is returned to the user). - -This patch does not fix the return code yet. Its a remote error case. -The code is used by both add and delete. And did not want to change the -error code specific for this case. It is fixable though. -Still debating about the fix. We could also add a high level check for -duplicate nexthops in the kernel. - -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index c3be1a3..2ec2865 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -2407,10 +2407,13 @@ static int ip6_route_multipath(struct fib6_config *cfg, int add) - int remaining; - int attrlen; - int err = 0, last_err = 0; -+ int nh_processed_cnt, nh_processed_cnt_last = 0; -+ int rollback = 0; - - beginning: - rtnh = (struct rtnexthop *)cfg->fc_mp; - remaining = cfg->fc_mp_len; -+ nh_processed_cnt = 0; - - /* Parse a Multipath Entry */ - while (rtnh_ok(rtnh, remaining)) { -@@ -2440,9 +2443,16 @@ beginning: - * next hops that have been already added. - */ - add = 0; -+ rollback = 1; -+ if (!nh_processed_cnt) -+ break; -+ nh_processed_cnt_last = nh_processed_cnt; - goto beginning; - } - } -+ if (rollback && nh_processed_cnt == nh_processed_cnt_last) -+ break; -+ nh_processed_cnt++; - rtnh = rtnh_next(rtnh, &remaining); - } - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-use-addrconf-get-prefix-route-for-prefix-route-lookup.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-use-addrconf-get-prefix-route-for-prefix-route-lookup.patch deleted file mode 100644 index 37870d3d..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-ipv6-use-addrconf-get-prefix-route-for-prefix-route-lookup.patch +++ /dev/null @@ -1,79 +0,0 @@ -Gitweb: http://git.kernel.org/linus/;a=commit;h=21caa6622b36190a32b19dfa734822c2eb93e1fd -Commit: 21caa6622b36190a32b19dfa734822c2eb93e1fd -Parent: 85da53bf1c336bb07ac038fb951403ab0478d2c5 -Author: Romain Kuntz -AuthorDate: Wed Jan 9 21:06:03 2013 +0000 -Committer: David S. Miller -CommitDate: Thu Jan 10 14:22:54 2013 -0800 - - ipv6: use addrconf_get_prefix_route for prefix route lookup [v2] - - Replace ip6_route_lookup() with addrconf_get_prefix_route() when - looking up for a prefix route. This ensures that the connected prefix - is looked up in the main table, and avoids the selection of other - matching routes located in different tables as well as blackhole - or prohibited entries. - - In addition, this fixes an Opps introduced by commit 64c6d08e (ipv6: - del unreachable route when an addr is deleted on lo), that would occur - when a blackhole or prohibited entry is selected by ip6_route_lookup(). - Such entries have a NULL rt6i_table argument, which is accessed by - __ip6_del_rt() when trying to lock rt6i_table->tb6_lock. - - The function addrconf_is_prefix_route() is not used anymore and is - removed. - - [v2] Minor indentation cleanup and log updates. - - Signed-off-by: Romain Kuntz - Acked-by: Nicolas Dichtel - Acked-by: YOSHIFUJI Hideaki - Signed-off-by: David S. Miller - -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index b42d74a..e6c48a1 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -149,6 +149,11 @@ static void addrconf_type_change(struct net_device *dev, - unsigned long event); - static int addrconf_ifdown(struct net_device *dev, int how); - -+static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, -+ int plen, -+ const struct net_device *dev, -+ u32 flags, u32 noflags); -+ - static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags); - static void addrconf_dad_timer(unsigned long data); - static void addrconf_dad_completed(struct inet6_ifaddr *ifp); -@@ -245,12 +250,6 @@ static inline bool addrconf_qdisc_ok(const struct net_device *dev) - return !qdisc_tx_is_noop(dev); - } - --/* Check if a route is valid prefix route */ --static inline int addrconf_is_prefix_route(const struct rt6_info *rt) --{ -- return (rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0; --} -- - static void addrconf_del_timer(struct inet6_ifaddr *ifp) - { - if (del_timer(&ifp->timer)) -@@ -800,11 +799,14 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) - if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) { - struct in6_addr prefix; - struct rt6_info *rt; -- struct net *net = dev_net(ifp->idev->dev); -+ - ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); -- rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1); - -- if (rt && addrconf_is_prefix_route(rt)) { -+ rt = addrconf_get_prefix_route(&prefix, -+ ifp->prefix_len, -+ ifp->idev->dev, -+ 0, RTF_GATEWAY | RTF_DEFAULT); -+ if (rt) { - if (onlink == 0) { - ip6_del_rt(rt); - rt = NULL; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-link-routes-and-carrier.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-link-routes-and-carrier.patch deleted file mode 100644 index a7e9752b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-link-routes-and-carrier.patch +++ /dev/null @@ -1,356 +0,0 @@ -net: link route status to port carrier status - -Initial patches from Dinesh including sysctl bits. - -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index 7e9cae6..2a75139 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -2283,6 +2283,7 @@ extern int dev_forward_skb(struct net_device *dev, - struct sk_buff *skb); - - extern int netdev_budget; -+extern int delete_dead_routes; - - /* Called by rtnetlink.c:rtnl_unlock() */ - extern void netdev_run_todo(void); -diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h -index 0c693d9..549b574 100644 ---- a/include/linux/rtnetlink.h -+++ b/include/linux/rtnetlink.h -@@ -324,6 +324,8 @@ struct rtnexthop { - #define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */ - #define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */ - #define RTNH_F_ONLINK 4 /* Gateway is forced on link */ -+/* Skipping a few bits in between to avoid any conflict with upstream */ -+#define RTNH_F_DEAD_LINKDOWN 64 /* Nexthop is dead due to no carrier */ - - /* Macros to handle hexthops */ - -diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h -index 703cfa3..d0db95e 100644 ---- a/include/linux/sysctl.h -+++ b/include/linux/sysctl.h -@@ -275,6 +275,7 @@ enum - NET_CORE_AEVENT_ETIME=20, - NET_CORE_AEVENT_RSEQTH=21, - NET_CORE_WARNINGS=22, -+ NET_CORE_DELETE_DEAD_ROUTES=23, - }; - - /* /proc/sys/net/ethernet */ -diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h -index 4913dac..e50385e 100644 ---- a/include/net/ip6_route.h -+++ b/include/net/ip6_route.h -@@ -149,6 +149,7 @@ struct rt6_rtnl_dump_arg { - - extern int rt6_dump_route(struct rt6_info *rt, void *p_arg); - extern void rt6_ifdown(struct net *net, struct net_device *dev); -+extern void rt6_link_change(struct net *net, struct net_device *dev); - extern void rt6_mtu_change(struct net_device *dev, unsigned mtu); - extern void rt6_remove_prefsrc(struct inet6_ifaddr *ifp); - -diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c -index 9f9aa32..12a46f7 100644 ---- a/kernel/sysctl_binary.c -+++ b/kernel/sysctl_binary.c -@@ -195,6 +195,7 @@ static const struct bin_table bin_net_core_table[] = { - { CTL_INT, NET_CORE_AEVENT_ETIME, "xfrm_aevent_etime" }, - { CTL_INT, NET_CORE_AEVENT_RSEQTH, "xfrm_aevent_rseqth" }, - { CTL_INT, NET_CORE_WARNINGS, "warnings" }, -+ { CTL_INT, NET_CORE_DELETE_DEAD_ROUTES, "delete_dead_routes" }, - {}, - }; - -diff --git a/net/core/dev.c b/net/core/dev.c -index ef84f5a..725ac59 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -2575,6 +2575,8 @@ int netdev_max_backlog __read_mostly = 1000; - int netdev_tstamp_prequeue __read_mostly = 1; - int netdev_budget __read_mostly = 300; - int weight_p __read_mostly = 64; /* old backlog weight */ -+int delete_dead_routes = 0; -+EXPORT_SYMBOL(delete_dead_routes); - - /* Called with irq disabled */ - static inline void ____napi_schedule(struct softnet_data *sd, -diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c -index f0bdd36..9aa94d0 100644 ---- a/net/core/sysctl_net_core.c -+++ b/net/core/sysctl_net_core.c -@@ -186,6 +186,13 @@ static struct ctl_table net_core_table[] = { - .mode = 0644, - .proc_handler = proc_dointvec - }, -+ { -+ .procname = "delete_dead_routes", -+ .data = &delete_dead_routes, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = proc_dointvec -+ }, - { } - }; - -diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c -index 92fc5f6..482dbea 100644 ---- a/net/ipv4/fib_frontend.c -+++ b/net/ipv4/fib_frontend.c -@@ -994,6 +994,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo - struct net_device *dev = ptr; - struct in_device *in_dev = __in_dev_get_rtnl(dev); - struct net *net = dev_net(dev); -+ unsigned flags; - - if (event == NETDEV_UNREGISTER) { - fib_disable_ip(dev, 2, -1); -@@ -1017,8 +1018,13 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo - case NETDEV_DOWN: - fib_disable_ip(dev, 0, 0); - break; -- case NETDEV_CHANGEMTU: - case NETDEV_CHANGE: -+ flags = dev_get_flags(dev); -+ if (!(flags & IFF_RUNNING)) -+ fib_sync_down_dev(dev, 0); -+ else if (flags & IFF_RUNNING) -+ fib_sync_up(dev); -+ case NETDEV_CHANGEMTU: - rt_cache_flush(dev_net(dev), 0); - break; - case NETDEV_UNREGISTER_BATCH: -diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c -index 76da979..02fcc81 100644 ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -552,6 +552,8 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, - return -ENODEV; - if (!(dev->flags & IFF_UP)) - return -ENETDOWN; -+ if (!netif_carrier_ok(dev) && delete_dead_routes) -+ nh->nh_flags |= RTNH_F_DEAD; - nh->nh_dev = dev; - dev_hold(dev); - nh->nh_scope = RT_SCOPE_LINK; -@@ -583,6 +585,8 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, - if (!dev) - goto out; - dev_hold(dev); -+ if (!netif_carrier_ok(dev) && delete_dead_routes) -+ nh->nh_flags |= RTNH_F_DEAD; - err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN; - } else { - struct in_device *in_dev; -@@ -601,6 +605,8 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, - nh->nh_dev = in_dev->dev; - dev_hold(nh->nh_dev); - nh->nh_scope = RT_SCOPE_HOST; -+ if (!netif_carrier_ok(nh->nh_dev) && delete_dead_routes) -+ nh->nh_flags |= RTNH_F_DEAD; - err = 0; - } - out: -@@ -711,6 +717,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg) - struct fib_info *ofi; - int nhs = 1; - struct net *net = cfg->fc_nlinfo.nl_net; -+ int dead; - - if (cfg->fc_type > RTN_MAX) - goto err_inval; -@@ -849,11 +856,18 @@ struct fib_info *fib_create_info(struct fib_config *cfg) - if (nh->nh_dev == NULL) - goto failure; - } else { -+ dead = 0; - change_nexthops(fi) { - err = fib_check_nh(cfg, fi, nexthop_nh); - if (err != 0) - goto failure; -+ if (nexthop_nh->nh_flags & RTNH_F_DEAD) -+ dead++; - } endfor_nexthops(fi) -+ if ((dead == fi->fib_nhs) && delete_dead_routes) { -+ fi->fib_flags |= RTNH_F_DEAD; -+ fi->fib_flags |= RTNH_F_DEAD_LINKDOWN; -+ } - } - - if (fi->fib_prefsrc) { -@@ -1021,6 +1035,8 @@ int fib_sync_down_addr(struct net *net, __be32 local) - continue; - if (fi->fib_prefsrc == local) { - fi->fib_flags |= RTNH_F_DEAD; -+ /* Addr is gone, more serious than a linkdown */ -+ fi->fib_flags &= ~RTNH_F_DEAD_LINKDOWN; - ret++; - } - } -@@ -1072,6 +1088,14 @@ int fib_sync_down_dev(struct net_device *dev, int force) - } endfor_nexthops(fi) - if (dead == fi->fib_nhs) { - fi->fib_flags |= RTNH_F_DEAD; -+ /* -+ * force marks route down due to other reasons. -+ * We honor that and don't set dead due to linkdown. -+ */ -+ if (!force) -+ fi->fib_flags |= RTNH_F_DEAD_LINKDOWN; -+ else -+ fi->fib_flags &= ~RTNH_F_DEAD_LINKDOWN; - ret++; - } - } -@@ -1149,10 +1173,12 @@ int fib_sync_up(struct net_device *dev) - struct hlist_node *node; - struct fib_nh *nh; - int ret; -+ int link_up; - - if (!(dev->flags & IFF_UP)) - return 0; - -+ link_up = netif_carrier_ok(dev) || !delete_dead_routes; - prev_fi = NULL; - hash = fib_devindex_hashfn(dev->ifindex); - head = &fib_info_devhash[hash]; -@@ -1179,16 +1205,26 @@ int fib_sync_up(struct net_device *dev) - if (nexthop_nh->nh_dev != dev || - !__in_dev_get_rtnl(dev)) - continue; -- alive++; -+ if (link_up) { -+ /* Link is up, so mark NH as alive */ -+ nexthop_nh->nh_flags &= ~RTNH_F_DEAD; -+ alive++; -+ } else -+ nexthop_nh->nh_flags |= RTNH_F_DEAD; - spin_lock_bh(&fib_multipath_lock); - nexthop_nh->nh_power = 0; -- nexthop_nh->nh_flags &= ~RTNH_F_DEAD; - spin_unlock_bh(&fib_multipath_lock); - } endfor_nexthops(fi) - - if (alive > 0) { -+ /* Some NHs are alive, unmark the route as dead */ -+ fi->fib_flags &= ~RTNH_F_DEAD_LINKDOWN; - fi->fib_flags &= ~RTNH_F_DEAD; - ret++; -+ } else { -+ /* No NHs are alive, mark the route as dead */ -+ fi->fib_flags |= RTNH_F_DEAD_LINKDOWN; -+ fi->fib_flags |= RTNH_F_DEAD; - } - } - -diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c -index 948ee5c..9384158 100644 ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -1729,7 +1729,9 @@ static int trie_flush_list(struct fib_table *tb, struct leaf *l, - list_for_each_entry_safe(fa, fa_node, &li->falh, fa_list) { - struct fib_info *fi = fa->fa_info; - -- if (fi && (fi->fib_flags & RTNH_F_DEAD)) { -+ /* Do not flush route if marked dead and link is down */ -+ if (fi && (fi->fib_flags & RTNH_F_DEAD) && -+ !(fi->fib_flags & RTNH_F_DEAD_LINKDOWN) && delete_dead_routes) { - struct nl_info nlinfo = { .nl_net = fi->fib_net, }; - - rtmsg_fib(RTM_DELROUTE, htonl(l->key), fa, li->plen, -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index e6c48a1..017795c 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -2660,13 +2660,16 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, - } else { - if (!addrconf_qdisc_ok(dev)) { - /* device is still not ready. */ -+ rt6_link_change(dev_net(dev), dev); - break; - } - - if (idev) { -- if (idev->if_flags & IF_READY) -+ if (idev->if_flags & IF_READY) { -+ rt6_link_change(dev_net(dev), dev); - /* device is already configured. */ - break; -+ } - idev->if_flags |= IF_READY; - } - -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index 2ec2865..b688e41 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -406,6 +406,9 @@ static inline struct rt6_info *rt6_device_match(struct net *net, - for (sprt = rt; sprt; sprt = sprt->dst.rt6_next) { - struct net_device *dev = sprt->rt6i_dev; - -+ if (!netif_carrier_ok(dev) && delete_dead_routes) -+ continue; -+ - if (oif) { - if (dev->ifindex == oif) - return sprt; -@@ -571,10 +574,12 @@ static struct rt6_info *find_rr_leaf(struct fib6_node *fn, - match = NULL; - for (rt = rr_head; rt && rt->rt6i_metric == metric; - rt = rt->dst.rt6_next) -- match = find_match(rt, oif, strict, &mpri, match); -+ if (netif_carrier_ok(rt->rt6i_dev) || !delete_dead_routes) -+ match = find_match(rt, oif, strict, &mpri, match); - for (rt = fn->leaf; rt && rt != rr_head && rt->rt6i_metric == metric; - rt = rt->dst.rt6_next) -- match = find_match(rt, oif, strict, &mpri, match); -+ if (netif_carrier_ok(rt->rt6i_dev) || !delete_dead_routes) -+ match = find_match(rt, oif, strict, &mpri, match); - - return match; - } -@@ -2241,6 +2246,15 @@ static int fib6_ifdown(struct rt6_info *rt, void *arg) - return 0; - } - -+static int fib6_linkdown(struct rt6_info *rt, void *arg) -+{ -+ if (rt->rt6i_flags & RTF_CACHE) { -+ RT6_TRACE("deleted by ifdown %p\n", rt); -+ return -1; -+ } -+ return 0; -+} -+ - void rt6_ifdown(struct net *net, struct net_device *dev) - { - struct arg_dev_net adn = { -@@ -2252,6 +2266,17 @@ void rt6_ifdown(struct net *net, struct net_device *dev) - icmp6_clean_all(fib6_ifdown, &adn); - } - -+void rt6_link_change(struct net *net, struct net_device *dev) -+{ -+ struct arg_dev_net adn = { -+ .dev = dev, -+ .net = net, -+ }; -+ -+ fib6_clean_all(net, fib6_linkdown, 0, &adn); -+ icmp6_clean_all(fib6_linkdown, &adn); -+} -+ - struct rt6_mtu_change_arg - { - struct net_device *dev; -@@ -2570,6 +2595,8 @@ static int rt6_fill_node(struct net *net, - if (rt->rt6i_flags&RTF_CACHE) - rtm->rtm_flags |= RTM_F_CLONED; - -+ if (rt->rt6i_dev && !netif_carrier_ok(rt->rt6i_dev) && delete_dead_routes) -+ rtm->rtm_flags |= RTNH_F_DEAD; - if (dst) { - NLA_PUT(skb, RTA_DST, 16, dst); - rtm->rtm_dst_len = 128; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-mcast-maxvifs.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-mcast-maxvifs.patch deleted file mode 100644 index be82e1fb..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-mcast-maxvifs.patch +++ /dev/null @@ -1,15 +0,0 @@ -Change the compile-time MAXVIFS constant for more mcast interfaces - -diff --git a/include/linux/mroute.h b/include/linux/mroute.h -index 46caaf4..3287cb1 100644 ---- a/include/linux/mroute.h -+++ b/include/linux/mroute.h -@@ -34,7 +34,7 @@ - #define SIOCGETSGCNT (SIOCPROTOPRIVATE+1) - #define SIOCGETRPF (SIOCPROTOPRIVATE+2) - --#define MAXVIFS 32 -+#define MAXVIFS 256 - typedef unsigned long vifbitmap_t; /* User mode code depends on this lot */ - typedef unsigned short vifi_t; - #define ALL_VIFS ((vifi_t)(-1)) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-mdb-top-change.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-mdb-top-change.patch deleted file mode 100644 index 21d1f543..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-mdb-top-change.patch +++ /dev/null @@ -1,288 +0,0 @@ -On a topology change, send a general leave to router port to have the querier -send out a general query to reduce multicast group convergence time. - -When a leave is received and when querier is configured, dont send a query -when the switch is not an active querier. - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 0996c69..b16f5cd 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -471,10 +471,14 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, - struct ethhdr *eth; - u8 *hopopt; - unsigned long interval; -+ int vh_size = 0; -+ -+ /* if vid is non-zero, insert the 1Q header also */ -+ if (vid && tagged) -+ vh_size = sizeof(struct vlan_hdr); - -- /* TBD: if vid is non-zero, insert a 1Q header */ - skb = netdev_alloc_skb_ip_align(br->dev, sizeof(*eth) + -- sizeof(*ip6h) + 8 + sizeof(*mldq)); -+ vh_size + sizeof(*ip6h) + 8 + sizeof(*mldq)); - if (!skb) - goto out; - -@@ -488,6 +492,13 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, - eth->h_proto = htons(ETH_P_IPV6); - skb_put(skb, sizeof(*eth)); - -+ if (vid && tagged) { -+ skb = vlan_put_tag(skb, vid); -+ if (!skb) { -+ pr_err("Error: failed to insert VLAN tag\n"); -+ return NULL; -+ } -+ } - /* IPv6 header + HbH option */ - skb_set_network_header(skb, skb->len); - ip6h = ipv6_hdr(skb); -@@ -889,7 +900,7 @@ static void br_multicast_send_query(struct net_bridge *br, - !br->multicast_querier) - return; - -- memset(&br_group.u, 0, sizeof(br_group.u)); -+ memset(&br_group, 0, sizeof(br_group)); - - if (port ? (query == &port->ip4_query) : - (query == &br->ip4_query)) { -@@ -909,7 +920,7 @@ static void br_multicast_send_query(struct net_bridge *br, - /* for each vlan in the list, populate the br_group.vid - * and send a query - */ -- list_for_each_entry(s, &querier->vlist, list) { -+ list_for_each_entry(s, &br->ip4_querier.vlist, list) { - br_group.vid = s->src.vid; - __br_multicast_send_query(br, port, &br_group); - num_vlans++; -@@ -1415,6 +1426,8 @@ static void br_multicast_leave_group(struct net_bridge *br, - struct net_bridge_port_group *p; - unsigned long now; - unsigned long time; -+ bool querier_vlan = false; -+ struct bridge_mcast_querier_src *s; - - spin_lock(&br->multicast_lock); - if (!netif_running(br->dev) || -@@ -1423,8 +1436,24 @@ static void br_multicast_leave_group(struct net_bridge *br, - - mdb = mlock_dereference(br->mdb, br); - mp = br_mdb_ip_get(mdb, group); -- if (!mp) -+ if (!mp) { -+ /* When a general leave is received for multicast querier, -+ * send an igmp query -+ */ -+ if (br->multicast_querier && port && !timer_pending(&querier->timer)) { -+ if (!br->vlan_enabled) -+ querier_vlan = true; -+ else -+ list_for_each_entry(s, &br->ip4_querier.vlist, list) { -+ if (group->vid == s->src.vid) -+ querier_vlan = true; -+ } -+ if (querier_vlan && (ntohs(group->proto) == ETH_P_IP) && -+ ipv4_is_zeronet(group->u.ip4)) -+ __br_multicast_send_query(br, port, group); -+ } - goto out; -+ } - - if (port && (port->flags & BR_MULTICAST_FAST_LEAVE)) { - struct net_bridge_port_group __rcu **pp; -@@ -1451,7 +1480,7 @@ static void br_multicast_leave_group(struct net_bridge *br, - if (timer_pending(&br->multicast_querier_timer)) - goto out; - -- if (br->multicast_querier) { -+ if (br->multicast_querier && !timer_pending(&querier->timer)) { - __br_multicast_send_query(br, port, &mp->addr); - - time = jiffies + br->multicast_last_member_count * -@@ -2251,3 +2280,156 @@ out: - spin_unlock_bh(&br->multicast_lock); - return res; - } -+ -+static struct sk_buff *br_ip4_multicast_alloc_leave(struct net_bridge *br, -+ __be32 group, -+ __u16 vid, -+ bool tagged) -+{ -+ struct sk_buff *skb; -+ struct igmphdr *ih; -+ struct ethhdr *eth; -+ struct iphdr *iph; -+ int vh_size = 0; -+ -+ /* if vid is non-zero, insert the 1Q header also */ -+ if (vid && tagged) -+ vh_size = sizeof(struct vlan_hdr); -+ skb = netdev_alloc_skb_ip_align(br->dev, sizeof(*eth) + sizeof(*iph) + -+ vh_size + sizeof(*ih) + 4); -+ if (!skb) -+ goto out; -+ -+ skb->protocol = htons(ETH_P_IP); -+ -+ skb_reset_mac_header(skb); -+ eth = eth_hdr(skb); -+ -+ memcpy(eth->h_source, br->dev->dev_addr, 6); -+ eth->h_dest[0] = 1; -+ eth->h_dest[1] = 0; -+ eth->h_dest[2] = 0x5e; -+ eth->h_dest[3] = 0; -+ eth->h_dest[4] = 0; -+ eth->h_dest[5] = 2; -+ eth->h_proto = htons(ETH_P_IP); -+ skb_put(skb, sizeof(*eth)); -+ -+ if (vid && tagged) { -+ skb = vlan_put_tag(skb, vid); -+ if (!skb) { -+ pr_err("Error: failed to insert VLAN tag\n"); -+ return NULL; -+ } -+ } -+ skb_set_network_header(skb, skb->len); -+ iph = ip_hdr(skb); -+ -+ iph->version = 4; -+ iph->ihl = 6; -+ iph->tos = 0xc0; -+ iph->tot_len = htons(sizeof(*iph) + sizeof(*ih) + 4); -+ iph->id = 0; -+ iph->frag_off = htons(IP_DF); -+ iph->ttl = 1; -+ iph->protocol = IPPROTO_IGMP; -+ iph->saddr = 0; -+ iph->daddr = htonl(INADDR_ALLRTRS_GROUP); -+ ((u8 *)&iph[1])[0] = IPOPT_RA; -+ ((u8 *)&iph[1])[1] = 4; -+ ((u8 *)&iph[1])[2] = 0; -+ ((u8 *)&iph[1])[3] = 0; -+ ip_send_check(iph); -+ skb_put(skb, 24); -+ -+ skb_set_transport_header(skb, skb->len); -+ ih = igmp_hdr(skb); -+ ih->type = IGMP_HOST_LEAVE_MESSAGE; -+ ih->code = 0; -+ ih->group = group; -+ ih->csum = 0; -+ ih->csum = ip_compute_csum((void *)ih, sizeof(struct igmphdr)); -+ skb_put(skb, sizeof(*ih)); -+ -+ __skb_pull(skb, sizeof(*eth)); -+ -+out: -+ return skb; -+} -+ -+static struct sk_buff *br_multicast_alloc_leave(struct net_bridge *br, -+ struct br_ip *addr, -+ bool tagged) -+{ -+ switch (addr->proto) { -+ case htons(ETH_P_IP): -+ return br_ip4_multicast_alloc_leave(br, addr->u.ip4, addr->vid, -+ tagged); -+ } -+ return NULL; -+} -+ -+static void __br_multicast_send_leave(struct net_bridge *br, -+ struct net_bridge_port *port, -+ struct br_ip *ip) -+{ -+ struct sk_buff *skb; -+ bool tagged = false; -+ -+ if (port && ip->vid) { -+ if (!br->vlan_enabled || !nbp_vlan_find(port, ip->vid)) -+ return; -+ if (br_get_pvid(nbp_get_vlan_info(port)) != ip->vid) -+ tagged = true; -+ } -+ skb = br_multicast_alloc_leave(br, ip, tagged); -+ if (!skb) -+ return; -+ -+ if (port) { -+ __skb_push(skb, sizeof(struct ethhdr)); -+ skb->dev = port->dev; -+ NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, -+ dev_queue_xmit); -+ } else -+ netif_rx(skb); -+} -+ -+/* Send an IGMP general leave message to router ports, -+ * so that the upstream querier sends an IGMP query in return. -+ */ -+void br_mdb_leave_topology_change(struct net_bridge *br, -+ struct net_bridge_port *port) -+{ -+ struct br_ip br_group; -+ struct net_bridge_port *rport = NULL; -+ unsigned short vid = VLAN_N_VID; -+ struct net_port_vlans *pv; -+ -+ if (!netif_running(br->dev) || (br->stp_enabled != BR_USER_STP) || -+ br->multicast_disabled || (!netif_running(port->dev)) || -+ br->multicast_querier) { -+ return; -+ } -+ memset(&br_group, 0, sizeof(br_group)); -+ -+ list_for_each_entry(rport, &br->port_list, list) { -+ if ((rport->multicast_router == 0) || (rport == port)) -+ continue; -+ if ((rport->multicast_router == 1) && (hlist_unhashed(&rport->rlist))) -+ continue; -+ pv = nbp_get_vlan_info(rport); -+ if (br->vlan_enabled && pv) { -+ /* for each vlan in the list, send a leave -+ */ -+ for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { -+ br_group.vid = vid; -+ br_group.proto = htons(ETH_P_IP); -+ __br_multicast_send_leave(br, rport, &br_group); -+ } -+ } else { -+ br_group.proto = htons(ETH_P_IP); -+ __br_multicast_send_leave(br, rport, &br_group); -+ } -+ } -+} -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 7ae7eeb..ff58204 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -484,7 +484,8 @@ void br_mdb_init(void); - void br_mdb_uninit(void); - void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, - struct br_ip *group, int type, u8 state); -- -+void br_mdb_leave_topology_change(struct net_bridge *br, -+ struct net_bridge_port *port); - extern void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, - int type); - -diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c -index 81ddab5..3ba9949 100644 ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -217,6 +217,9 @@ static BRPORT_ATTR(vlans, S_IRUGO, show_vlans, NULL); - - static int store_flush(struct net_bridge_port *p, unsigned long v) - { -+#ifdef CONFIG_BRIDGE_IGMP_SNOOPING -+ br_mdb_leave_topology_change(p->br, p); -+#endif - br_fdb_delete_by_port(p->br, p, 0); // Don't delete local entry - return 0; - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-neigh-fix-neigh-update-notify.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-neigh-fix-neigh-update-notify.patch deleted file mode 100644 index 4709a21f..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-neigh-fix-neigh-update-notify.patch +++ /dev/null @@ -1,14 +0,0 @@ -neigh: Add notify on state change in neigh_update - -diff --git a/net/core/neighbour.c b/net/core/neighbour.c -index 0ea3fd3..6f89364 100644 ---- a/net/core/neighbour.c -+++ b/net/core/neighbour.c -@@ -1140,6 +1140,7 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, - neigh->parms->reachable_time : - 0))); - neigh->nud_state = new; -+ notify = 1; - } - - if (lladdr != neigh->ha) { diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-neighbour-update-neighbour-h-to-latest-upstream.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-neighbour-update-neighbour-h-to-latest-upstream.patch deleted file mode 100644 index 446aa579..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-neighbour-update-neighbour-h-to-latest-upstream.patch +++ /dev/null @@ -1,18 +0,0 @@ -Update neighbour.h to upstream latest to fix abi -incompatibility. So that our version of NDA_MASTER is compatible with -upstream. - -diff --git a/include/linux/neighbour.h b/include/linux/neighbour.h -index 232e5fa..f457dd6 100644 ---- a/include/linux/neighbour.h -+++ b/include/linux/neighbour.h -@@ -21,6 +21,9 @@ enum { - NDA_CACHEINFO, - NDA_PROBES, - NDA_VLAN, -+ NDA_PORT, -+ NDA_VNI, -+ NDA_IFINDEX, - NDA_MASTER, - __NDA_MAX - }; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-ethtool-get-return-success-on-enodata.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-ethtool-get-return-success-on-enodata.patch deleted file mode 100644 index 7fad0250..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-ethtool-get-return-success-on-enodata.patch +++ /dev/null @@ -1,25 +0,0 @@ -debug - -diff --git a/net/core/port.c b/net/core/port.c -index ac4fc82..e931617 100644 ---- a/net/core/port.c -+++ b/net/core/port.c -@@ -735,7 +735,17 @@ err_out: - - int port_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) - { -- return port_cache_get_settings(dev->ifindex, cmd); -+ int err; -+ -+ err = port_cache_get_settings(dev->ifindex, cmd); -+ /* If we dont have ethtool data from the driver, its better to return zero -+ * to the caller instead of returning an err. Because this is really -+ * not an error and sets can really go through at this point. -+ */ -+ if (err == -ENODATA) -+ return 0; -+ -+ return err; - } - EXPORT_SYMBOL_GPL(port_get_settings); - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-ethtool-handle-errors.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-ethtool-handle-errors.patch deleted file mode 100644 index 37392153..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-ethtool-handle-errors.patch +++ /dev/null @@ -1,44 +0,0 @@ -parse and propagate errors to the user. - -diff --git a/net/core/port.c b/net/core/port.c -index e931617..e13c26b 100644 ---- a/net/core/port.c -+++ b/net/core/port.c -@@ -359,6 +359,7 @@ struct wq { - int hit; - int (*decode)(struct nlattr **attrs, void *arg1, void *arg2); - void *arg1, *arg2; -+ int status; - struct list_head list; - }; - -@@ -424,10 +425,12 @@ static int port_wait(int seq, int wait, - if (err == 0) { /* timed out */ - err = -ETIMEDOUT; - goto err_out; -+ } else if (wq->status) { -+ err = wq->status; -+ } else { -+ err = 0; - } - -- err = 0; -- - err_out: - write_lock(&port_wq_lock); - list_del(&wq->list); -@@ -492,8 +495,12 @@ static int port_reply(struct sk_buff *skb, struct genl_info *info) - wq->hit = 1; - if (info->attrs[PORT_ATTR_STATUS]) { - err = nla_get_u32(info->attrs[PORT_ATTR_STATUS]); -- if (!err && wq->decode) -- wq->decode(info->attrs, wq->arg1, wq->arg2); -+ if (!err) { -+ if (wq->decode) -+ wq->decode(info->attrs, wq->arg1, wq->arg2); -+ } else { -+ wq->status = err; -+ } - } - wake_up_interruptible(&wq->wq); - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-ethtool-rtnl-lock-handling-fixes.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-ethtool-rtnl-lock-handling-fixes.patch deleted file mode 100644 index 0f3ae76a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-ethtool-rtnl-lock-handling-fixes.patch +++ /dev/null @@ -1,484 +0,0 @@ -First attempt to fix port locking issues around ethtool - - Ticket: CM-4028 - Reviewed By: CCR-2209 - Testing Done: Precommit and directed testing - - The current solution for handling locking when issuing commands to user space has two major bugs as detailed in 4028. - - A global lock is released for most situations without regard to the calling context - A pointer to freed memory is being held and used after the free - - This patch attempts to solve them with the following logic - - All accesses to the low level function is now separated into calls from ethtool context and others. For others we always - answer from a local cache, this avoid the need to sleep thus avoiding the release of the lock. For the ethtool context we - know we can release and do so .. the re-acquire of the lock is still a weakness here - - For the pointer to memory we call the decode functions in the context of the reply method, thus avoiding the need to reference later. - -diff --git a/net/core/port.c b/net/core/port.c -index 6fea48f..ac4fc82 100644 ---- a/net/core/port.c -+++ b/net/core/port.c -@@ -31,6 +31,7 @@ - - static DEFINE_HASHTABLE(port_cache, 10); - static DEFINE_SPINLOCK(port_cache_lock); -+static DEFINE_RWLOCK(port_wq_lock); - - struct port_node { - struct hlist_node hash_node; -@@ -280,38 +281,19 @@ static void port_cache_set_stats(int ifindex, int count, u64* data, int restart) - synchronize_rcu(); - } - --static void port_cache_clear_settings(int ifindex) --{ -- struct port_node *port; -- unsigned long flags; -- -- spin_lock_irqsave(&port_cache_lock, flags); -- port = __port_cache_get(ifindex); -- if (!port) { -- spin_unlock_irqrestore(&port_cache_lock, flags); -- return; -- } -- -- memset(&port->settings, 0, sizeof(port->settings)); -- port->settings_valid = 0; -- spin_unlock_irqrestore(&port_cache_lock, flags); -- synchronize_rcu(); --} -- - static int port_cache_get_settings(int ifindex, struct ethtool_cmd *cmd) - { - struct port_node *port; - int valid = 0; -- unsigned long flags; - -- spin_lock_irqsave(&port_cache_lock, flags); -+ rcu_read_lock(); - port = __port_cache_get(ifindex); - if (port) { - valid = port->settings_valid; - if (valid) - memcpy(cmd, &port->settings, sizeof(*cmd)); - } -- spin_unlock_irqrestore(&port_cache_lock, flags); -+ rcu_read_unlock(); - - return valid ? 0 : -ENODATA; - } -@@ -375,24 +357,11 @@ struct wq { - wait_queue_head_t wq; - int seq; - int hit; -- struct nlattr **attrs; -+ int (*decode)(struct nlattr **attrs, void *arg1, void *arg2); -+ void *arg1, *arg2; - struct list_head list; - }; - --static struct wq *alloc_wq(int seq) --{ -- struct wq *wq = kzalloc(sizeof(*wq), GFP_KERNEL); -- -- if (!wq) -- return wq; -- -- init_waitqueue_head(&wq->wq); -- INIT_LIST_HEAD(&wq->list); -- wq->seq = seq; -- -- return wq; --} -- - static struct wq *find_wq(int seq) - { - struct list_head *pos; -@@ -407,98 +376,82 @@ static struct wq *find_wq(int seq) - return NULL; - } - -+static struct wq *alloc_wq(int seq) -+{ -+ struct wq *wq = kzalloc(sizeof(*wq), GFP_KERNEL); -+ -+ if (!wq) -+ return wq; -+ -+ init_waitqueue_head(&wq->wq); -+ INIT_LIST_HEAD(&wq->list); -+ wq->seq = seq; -+ -+ return wq; -+} -+ - static int port_wait(int seq, int wait, - int (*decode)(struct nlattr **attrs, - void *arg1, void *arg2), - void *arg1, void *arg2) - { - struct wq *wq; -- int err, is_locked; -+ int err; -+ -+ write_lock(&port_wq_lock); - - wq = alloc_wq(seq); -- if (!wq) -+ if (!wq) { -+ write_unlock(&port_wq_lock); - return -ENOMEM; -+ } -+ - list_add(&wq->list, &wq_list); -+ wq->decode = decode; -+ wq->arg1 = arg1; -+ wq->arg2 = arg2; - -- is_locked = rtnl_is_locked(); -- if (is_locked) -- rtnl_unlock(); -+ write_unlock(&port_wq_lock); -+ -+ ASSERT_RTNL(); -+ rtnl_unlock(); /* unconditionally rtnl_unlock here as we -+ * should not be here with rtnl not held */ - - err = wait_event_interruptible_timeout(wq->wq, wq->hit, wait * HZ); - -- if (is_locked) -- rtnl_lock(); -+ rtnl_lock(); /* re-grab rtnl lock */ - -- if (err == 0) { /* timed out */ -+ if (err == 0) { /* timed out */ - err = -ETIMEDOUT; - goto err_out; - } - -- if (err == -ERESTARTSYS) /* interrupted */ -- goto err_out; -- -- if (wq->attrs[PORT_ATTR_STATUS]) { -- err = nla_get_u32(wq->attrs[PORT_ATTR_STATUS]); -- if (err) -- goto err_out; -- } -- -- if (decode) { -- err = decode(wq->attrs, arg1, arg2); -- if (err) -- goto err_out; -- } -- - err = 0; - - err_out: -+ write_lock(&port_wq_lock); - list_del(&wq->list); - kfree(wq); -+ write_unlock(&port_wq_lock); - - return err; - } - --static int port_sleep(void) --{ -- struct wq wq = { .seq = -1 }; -- int err, is_locked; -- -- init_waitqueue_head(&wq.wq); -- -- is_locked = rtnl_is_locked(); -- if (is_locked) -- rtnl_unlock(); -- -- err = wait_event_interruptible_timeout(wq.wq, wq.hit, HZ); -- -- if (is_locked) -- rtnl_lock(); -- -- if (err == 0) /* timed out */ -- err = -ETIMEDOUT; -- -- return err; --} -- --static int port_send(struct net_device *dev, u8 cmd, int size, int wait, -+static int port_send(struct net_device *dev, u8 cmd, int seq, int size, - int (*encode)(struct sk_buff *skb, void *arg1, void *arg2), - int (*decode)(struct nlattr **attrs, void *arg1, void *arg2), - void *arg1, void *arg2) - { -- static atomic_t next_seq; - struct sk_buff *skb; - void *hdr; -- int seq, err = -EMSGSIZE, retry = 0; -+ int err = -EMSGSIZE; - - size += nla_total_size(sizeof(u32)); /* PORT_ATTR_IFINDEX */ - --retry: - skb = genlmsg_new(size, GFP_KERNEL); - if (!skb) - return -ENOMEM; - -- /* use unique seq for each request */ -- seq = atomic_inc_return(&next_seq); - hdr = genlmsg_put(skb, 0, seq, &port_family, 0, cmd); - if (!hdr) - goto err_out; -@@ -520,15 +473,6 @@ nla_put_failure: - if (err < 0) - goto err_out_sent; - -- if (wait) { -- err = port_wait(seq, wait, decode, arg1, arg2); -- retry += wait; -- if (err == -EAGAIN && retry < 60) { -- port_sleep(); -- goto retry; -- } -- } -- - return err; - - err_out: -@@ -540,16 +484,20 @@ err_out_sent: - static int port_reply(struct sk_buff *skb, struct genl_info *info) - { - struct wq *wq; -+ int err; - -- rtnl_lock(); -+ read_lock(&port_wq_lock); - wq = find_wq(info->snd_seq); -- rtnl_unlock(); -- - if (wq) { - wq->hit = 1; -- wq->attrs = info->attrs; -+ if (info->attrs[PORT_ATTR_STATUS]) { -+ err = nla_get_u32(info->attrs[PORT_ATTR_STATUS]); -+ if (!err && wq->decode) -+ wq->decode(info->attrs, wq->arg1, wq->arg2); -+ } - wake_up_interruptible(&wq->wq); - } -+ read_unlock(&port_wq_lock); - - return 0; - } -@@ -703,6 +651,7 @@ static int decode_struct(struct nlattr *attr, size_t size, void *dst) - { - if (!attr) - return -ENOSYS; -+ - memcpy(dst, nla_data(attr), size); - return 0; - -@@ -720,28 +669,73 @@ void port_uninit_ethtool_stats(struct net_device *dev) - } - EXPORT_SYMBOL_GPL(port_uninit_ethtool_stats); - --int port_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -+static int handle_remote_ops(struct net_device *dev, u8 cmd, int size, -+ int wait, -+ int (*encode)(struct sk_buff *skb, void *arg1, void *arg2), -+ int (*decode)(struct nlattr **attrs, void *arg1, void *arg2), -+ void *arg1, void *arg2) - { -- int err, size = 0, wait = 20; -+ int err = 0, count, scount = 0, seq; -+ static atomic_t next_seq; - -- int decode(struct nlattr **attrs, void *arg1, void *arg2) -- { -- return decode_struct(attrs[PORT_ATTR_SETTINGS], -- sizeof(struct ethtool_cmd), arg1); -- } -+ /* these follow a simple model -+ since they can call port_wait we will unlock rtnl_lock -+ before we call the underlying function -+ -+ subsequently we will trylock and restart_syscall when -+ we wake up and process returned data. Only works -+ for the case where we think the cmd came from ethtool -+ */ - -- err = port_cache_get_settings(dev->ifindex, cmd); -- if (!err) -- return 0; -+ /* use unique seq for each request */ -+ seq = atomic_inc_return(&next_seq); -+ dev_hold(dev); - -- err = port_send(dev, PORT_CMD_GET_SETTINGS, size, wait, -- NULL, decode, cmd, NULL); -- if (err) -- return err; -+ scount = port_send(dev, cmd, seq, size, -+ encode, decode/*XXX*/, arg1, arg2); -+ if (scount < 0) { -+ err = scount; -+ goto err_out; -+ } - -- port_cache_set_settings(dev->ifindex, cmd); -+ if (wait) { -+ err = port_wait(seq, wait, decode, arg1, arg2); -+ if (err < 0) -+ goto err_out; -+ } -+ -+ switch(cmd) { -+ case PORT_CMD_GET_STRINGS: -+ count = port_cache_get_sset_count(dev->ifindex, *(int *)arg1); -+ port_cache_set_stat_strings(dev->ifindex, count, arg2); -+ break; -+ case PORT_CMD_GET_SSET_COUNT: -+ err = scount; -+ port_cache_set_sset_count(dev->ifindex, *(int *)arg1, scount); -+ break; -+ case PORT_CMD_SET_SETTINGS: -+ port_cache_set_settings(dev->ifindex, arg1); -+ break; -+ case PORT_CMD_GET_MODULE_INFO: -+ case PORT_CMD_GET_MODULE_EEPROM: -+ case PORT_CMD_SET_PHYS_ID_STATE: -+ case PORT_CMD_GET_PAUSE: -+ case PORT_CMD_SET_PAUSE: -+ /* nothing to see here */ -+ break; -+ default: -+ break; -+ } - -- return 0; -+err_out: -+ dev_put(dev); -+ -+ return err; -+} -+ -+int port_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -+{ -+ return port_cache_get_settings(dev->ifindex, cmd); - } - EXPORT_SYMBOL_GPL(port_get_settings); - -@@ -749,7 +743,6 @@ int port_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) - { - int size = nla_total_size(sizeof(struct ethtool_cmd)); - int wait = 20; -- int err = 0; - - int encode(struct sk_buff *skb, void *arg1, void *arg2) - { -@@ -757,14 +750,8 @@ int port_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) - sizeof(struct ethtool_cmd), arg1); - } - -- err = port_send(dev, PORT_CMD_SET_SETTINGS, size, wait, -- encode, NULL, cmd, NULL); -- if (err < 0) -- return err; -- -- port_cache_set_settings(dev->ifindex, cmd); -- -- return err; -+ return handle_remote_ops(dev, PORT_CMD_SET_SETTINGS, size, wait, -+ encode, NULL, cmd, NULL); - } - EXPORT_SYMBOL_GPL(port_set_settings); - -@@ -780,8 +767,8 @@ void port_get_pauseparam(struct net_device *dev, - arg1); - } - -- port_send(dev, PORT_CMD_GET_PAUSE, size, wait, -- NULL, decode, pause, NULL); -+ handle_remote_ops(dev, PORT_CMD_GET_PAUSE, size, wait, -+ NULL, decode, pause, NULL); - } - EXPORT_SYMBOL_GPL(port_get_pauseparam); - -@@ -797,9 +784,9 @@ int port_set_pauseparam(struct net_device *dev, - sizeof(struct ethtool_pauseparam), - arg1); - } -- -- return port_send(dev, PORT_CMD_SET_PAUSE, size, wait, -- encode, NULL, pause, NULL); -+/* XXX we want to ensure this handling in switchd is done right */ -+ return handle_remote_ops(dev, PORT_CMD_SET_PAUSE, size, wait, -+ encode, NULL, pause, NULL); - } - EXPORT_SYMBOL_GPL(port_set_pauseparam); - -@@ -857,12 +844,10 @@ void port_get_strings(struct net_device *dev, u32 stringset, u8 *data) - if (!err) - return; - -- err = port_send(dev, PORT_CMD_GET_STRINGS, size, wait, -- encode, decode, &stringset, data); -+ err = handle_remote_ops(dev, PORT_CMD_GET_STRINGS, size, wait, -+ encode, decode, &stringset, data); - if (err) - return; -- -- port_cache_set_stat_strings(dev->ifindex, count, data); - } - EXPORT_SYMBOL_GPL(port_get_strings); - -@@ -891,13 +876,8 @@ int port_get_sset_count(struct net_device *dev, int sset) - if (count >= 0) - return count; - -- count = port_send(dev, PORT_CMD_GET_SSET_COUNT, size, wait, -+ handle_remote_ops(dev, PORT_CMD_GET_SSET_COUNT, size, wait, - encode, decode, &sset, NULL); -- if (count < 0) -- return count; -- -- port_cache_set_sset_count(dev->ifindex, sset, count); -- - return count; - } - EXPORT_SYMBOL_GPL(port_get_sset_count); -@@ -919,8 +899,8 @@ int port_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state) - if (state == ETHTOOL_ID_ACTIVE) - return 1; /* 1 sec period */ - -- return port_send(dev, PORT_CMD_SET_PHYS_ID_STATE, size, wait, -- encode, NULL, &state, NULL); -+ return handle_remote_ops(dev, PORT_CMD_SET_PHYS_ID_STATE, size, wait, -+ encode, NULL, &state, NULL); - } - EXPORT_SYMBOL_GPL(port_set_phys_id); - -@@ -934,8 +914,8 @@ int port_get_module_info(struct net_device *dev, struct ethtool_modinfo *info) - sizeof(struct ethtool_modinfo), arg1); - } - -- return port_send(dev, PORT_CMD_GET_MODULE_INFO, size, wait, -- NULL, decode, info, NULL); -+ return handle_remote_ops(dev, PORT_CMD_GET_MODULE_INFO, size, wait, -+ NULL, decode, info, NULL); - } - EXPORT_SYMBOL_GPL(port_get_module_info); - -@@ -961,8 +941,8 @@ int port_get_module_eeprom(struct net_device *dev, - return 0; - } - -- return port_send(dev, PORT_CMD_GET_MODULE_EEPROM, size, wait, -- encode, decode, eeprom, data); -+ return handle_remote_ops(dev, PORT_CMD_GET_MODULE_EEPROM, size, wait, -+ encode, decode, eeprom, data); - } - EXPORT_SYMBOL_GPL(port_get_module_eeprom); - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-genl-add-ethtool-settings-pull.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-genl-add-ethtool-settings-pull.patch deleted file mode 100644 index 2db296ab..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-port-genl-add-ethtool-settings-pull.patch +++ /dev/null @@ -1,171 +0,0 @@ -Add a new port genl command PORT_CMD_GET_CACHED_SETTINGS -for userspace to pull cached ethtool settings from kernel. - -It echo's back a reponse with the required settings data. - -diff --git a/include/linux/port.h b/include/linux/port.h -index fb01a28..6389048 100644 ---- a/include/linux/port.h -+++ b/include/linux/port.h -@@ -47,6 +47,7 @@ enum { - PORT_CMD_GET_SSET_COUNT, - PORT_CMD_SET_CARRIER, - PORT_CMD_SET_PHYS_ID_STATE, -+ PORT_CMD_GET_CACHED_SETTINGS, - __PORT_CMD_MAX, - }; - -diff --git a/net/core/port.c b/net/core/port.c -index b829228..0fa33bd 100644 ---- a/net/core/port.c -+++ b/net/core/port.c -@@ -302,15 +302,16 @@ static int port_cache_get_settings(int ifindex, struct ethtool_cmd *cmd) - { - struct port_node *port; - int valid = 0; -+ unsigned long flags; - -- rcu_read_lock(); -+ spin_lock_irqsave(&port_cache_lock, flags); - port = __port_cache_get(ifindex); - if (port) { - valid = port->settings_valid; - if (valid) - memcpy(cmd, &port->settings, sizeof(*cmd)); - } -- rcu_read_unlock(); -+ spin_unlock_irqrestore(&port_cache_lock, flags); - - return valid ? 0 : -ENODATA; - } -@@ -642,6 +643,25 @@ static int port_set_carrier(struct sk_buff *skb, struct genl_info *info) - return 0; - } - -+static int port_send_cached_settings(int, struct genl_info *, -+ struct ethtool_cmd *, int); -+static int port_cache_settings_pull(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr **attrs = info->attrs; -+ struct ethtool_cmd cmd = { 0, }; -+ int err = 0, ifindex = 0; -+ -+ if (attrs[PORT_ATTR_IFINDEX]) -+ ifindex = nla_get_u32(attrs[PORT_ATTR_IFINDEX]); -+ -+ if (ifindex <= 0) -+ return -ENOTSUPP; -+ -+ err = port_cache_get_settings(ifindex, &cmd); -+ -+ return port_send_cached_settings(ifindex, info, &cmd, err); -+} -+ - static struct genl_ops port_ops[] = { - { - .cmd = PORT_CMD_REPLY, -@@ -663,6 +683,11 @@ static struct genl_ops port_ops[] = { - .policy = port_policy, - .doit = port_set_carrier, - }, -+ { -+ .cmd = PORT_CMD_GET_CACHED_SETTINGS, -+ .policy = port_policy, -+ .doit = port_cache_settings_pull, -+ }, - }; - - static int encode_struct(struct sk_buff *skb, int attrtype, -@@ -706,7 +731,7 @@ int port_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) - } - - err = port_cache_get_settings(dev->ifindex, cmd); -- if (!err) -+ if (!err) - return 0; - - err = port_send(dev, PORT_CMD_GET_SETTINGS, size, wait, -@@ -724,6 +749,7 @@ int port_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) - { - int size = nla_total_size(sizeof(struct ethtool_cmd)); - int wait = 20; -+ int err = 0; - - int encode(struct sk_buff *skb, void *arg1, void *arg2) - { -@@ -731,10 +757,14 @@ int port_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) - sizeof(struct ethtool_cmd), arg1); - } - -- port_cache_clear_settings(dev->ifindex); -- -- return port_send(dev, PORT_CMD_SET_SETTINGS, size, wait, -+ err = port_send(dev, PORT_CMD_SET_SETTINGS, size, wait, - encode, NULL, cmd, NULL); -+ if (err < 0) -+ return err; -+ -+ port_cache_set_settings(dev->ifindex, cmd); -+ -+ return err; - } - EXPORT_SYMBOL_GPL(port_set_settings); - -@@ -936,6 +966,57 @@ int port_get_module_eeprom(struct net_device *dev, - } - EXPORT_SYMBOL_GPL(port_get_module_eeprom); - -+static int port_send_cached_settings(int ifindex, -+ struct genl_info *info, -+ struct ethtool_cmd *cmd, -+ int status) -+{ -+ struct sk_buff *skb; -+ int err, size = 0; -+ void *hdr; -+ -+ /* Uses unicast reply to requester. This function can be -+ * generalized -+ */ -+ size += nla_total_size(sizeof(u32)) + -+ nla_total_size(sizeof(u32)) + -+ nla_total_size(sizeof(struct ethtool_cmd)); -+ -+ skb = genlmsg_new(size, GFP_KERNEL); -+ if (!skb) -+ return -ENOMEM; -+ -+ hdr = genlmsg_put(skb, info->snd_pid, info->snd_seq, &port_family, 0, -+ PORT_CMD_GET_CACHED_SETTINGS); -+ if (!hdr) -+ goto err_out; -+ -+ NLA_PUT_U32(skb, PORT_ATTR_IFINDEX, ifindex); -+ NLA_PUT_U32(skb, PORT_ATTR_STATUS, status); -+ -+ err = encode_struct(skb, PORT_ATTR_SETTINGS, sizeof(struct ethtool_cmd), -+ cmd); -+ if (err < 0) { -+nla_put_failure: -+ genlmsg_cancel(skb, hdr); -+ goto err_out; -+ } -+ -+ genlmsg_end(skb, hdr); -+ -+ err = genlmsg_reply(skb, info); -+ if (err < 0) -+ goto err_out_sent; -+ -+ return err; -+ -+err_out: -+ nlmsg_free(skb); -+ -+err_out_sent: -+ return err; -+} -+ - static int __init port_init(void) - { - int err; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-restore-default-tun-behavior.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-restore-default-tun-behavior.patch deleted file mode 100644 index 0996e79b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-restore-default-tun-behavior.patch +++ /dev/null @@ -1,79 +0,0 @@ -Retore default behavior for tuntap. This change requires that switchd -also know to set IFF_TUN_SET_CARRIER so it behaves properly. - -diff --git a/drivers/net/tun.c b/drivers/net/tun.c -index 078c36c..05ff14d 100644 ---- a/drivers/net/tun.c -+++ b/drivers/net/tun.c -@@ -176,6 +176,8 @@ static int tun_attach(struct tun_struct *tun, struct file *file) - tfile->tun = tun; - tun->tfile = tfile; - tun->socket.file = file; -+ if (!(tun->flags & TUN_SET_CARRIER)) -+ netif_carrier_on(tun->dev); - dev_hold(tun->dev); - sock_hold(tun->socket.sk); - atomic_inc(&tfile->count); -@@ -189,6 +191,8 @@ static void __tun_detach(struct tun_struct *tun) - { - /* Detach from net device */ - netif_tx_lock_bh(tun->dev); -+ if (!(tun->flags & TUN_SET_CARRIER)) -+ netif_carrier_off(tun->dev); - tun->tfile = NULL; - tun->socket.file = NULL; - netif_tx_unlock_bh(tun->dev); -@@ -1208,7 +1212,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) - if (err < 0) - goto failed; - -- netif_carrier_off(tun->dev); -+ if (tun->flags & TUN_SET_CARRIER) -+ netif_carrier_off(tun->dev); - } - - tun_debug(KERN_INFO, tun, "tun_set_iff\n"); -@@ -1228,6 +1233,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) - else - tun->flags &= ~TUN_VNET_HDR; - -+ if (ifr->ifr_flags & IFF_TUN_SET_CARRIER) -+ tun->flags |= TUN_SET_CARRIER; -+ else -+ tun->flags &= ~TUN_SET_CARRIER; -+ - /* Make sure persistent devices do not get stuck in - * xoff state. - */ -diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h -index 06b1829..3da0107 100644 ---- a/include/linux/if_tun.h -+++ b/include/linux/if_tun.h -@@ -34,6 +34,7 @@ - #define TUN_ONE_QUEUE 0x0080 - #define TUN_PERSIST 0x0100 - #define TUN_VNET_HDR 0x0200 -+#define TUN_SET_CARRIER 0x0400 - - /* Ioctl defines */ - #define TUNSETNOCSUM _IOW('T', 200, int) -@@ -55,12 +56,13 @@ - #define TUNSETVNETHDRSZ _IOW('T', 216, int) - - /* TUNSETIFF ifr flags */ --#define IFF_TUN 0x0001 --#define IFF_TAP 0x0002 --#define IFF_NO_PI 0x1000 --#define IFF_ONE_QUEUE 0x2000 --#define IFF_VNET_HDR 0x4000 --#define IFF_TUN_EXCL 0x8000 -+#define IFF_TUN 0x0001 -+#define IFF_TAP 0x0002 -+#define IFF_NO_PI 0x1000 -+#define IFF_ONE_QUEUE 0x2000 -+#define IFF_VNET_HDR 0x4000 -+#define IFF_TUN_EXCL 0x8000 -+#define IFF_TUN_SET_CARRIER 0x0008 - - /* Features for GSO (TUNSETOFFLOAD). */ - #define TUN_F_CSUM 0x01 /* You can hand me unchecksummed packets. */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-rtnetlink-provide-api-for-getting-and-setting-slave-info.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-rtnetlink-provide-api-for-getting-and-setting-slave-info.patch deleted file mode 100644 index 969a99f6..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-rtnetlink-provide-api-for-getting-and-setting-slave-info.patch +++ /dev/null @@ -1,308 +0,0 @@ -From a3aeff9e10fd50064109ec4d2ed85829f1781163 Mon Sep 17 00:00:00 2001 -Subject: [PATCH 1/4] rtnetlink: provide api for getting and setting slave - info - -Recent patch -bonding: add netlink attributes to slave link dev (1d3ee88ae0d6) - -Introduced yet another device specific way to access slave information -over rtnetlink. There is one already there for bridge. - -This patch introduces generic way to do this, for getting and setting -info as well by extending link_ops. Later on, this new interface will -be used for bridge ports as well. - -Signed-off-by: Jiri Pirko -Signed-off-by: David S. Miller -(cherry picked from commit ba7d49b1f0f8e5f24294a880ed576964059af5ef) - -Conflicts: - include/net/rtnetlink.h - include/uapi/linux/if_link.h - net/core/rtnetlink.c - -Signed-off-by: Jonathan Toppins - -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index 7097794..bb5739c 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -235,6 +235,8 @@ enum { - IFLA_INFO_KIND, - IFLA_INFO_DATA, - IFLA_INFO_XSTATS, -+ IFLA_INFO_SLAVE_KIND, -+ IFLA_INFO_SLAVE_DATA, - __IFLA_INFO_MAX, - }; - -diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h -index 678f1ff..a3adb85 100644 ---- a/include/net/rtnetlink.h -+++ b/include/net/rtnetlink.h -@@ -78,6 +78,19 @@ struct rtnl_link_ops { - int (*get_tx_queues)(struct net *net, struct nlattr *tb[], - unsigned int *tx_queues, - unsigned int *real_tx_queues); -+ int slave_maxtype; -+ const struct nla_policy *slave_policy; -+ int (*slave_validate)(struct nlattr *tb[], -+ struct nlattr *data[]); -+ int (*slave_changelink)(struct net_device *dev, -+ struct net_device *slave_dev, -+ struct nlattr *tb[], -+ struct nlattr *data[]); -+ size_t (*get_slave_size)(const struct net_device *dev, -+ const struct net_device *slave_dev); -+ int (*fill_slave_info)(struct sk_buff *skb, -+ const struct net_device *dev, -+ const struct net_device *slave_dev); - }; - - extern int __rtnl_link_register(struct rtnl_link_ops *ops); -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index cff4cb9..3d31428 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -352,6 +352,22 @@ void rtnl_link_unregister(struct rtnl_link_ops *ops) - } - EXPORT_SYMBOL_GPL(rtnl_link_unregister); - -+static size_t rtnl_link_get_slave_info_data_size(const struct net_device *dev) -+{ -+ struct net_device *master_dev; -+ const struct rtnl_link_ops *ops; -+ -+ master_dev = dev->master; -+ if (!master_dev) -+ return 0; -+ ops = master_dev->rtnl_link_ops; -+ if (!ops->get_slave_size) -+ return 0; -+ /* IFLA_INFO_SLAVE_DATA + nested data */ -+ return nla_total_size(sizeof(struct nlattr)) + -+ ops->get_slave_size(master_dev, dev); -+} -+ - static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind) - { - const struct rtnl_link_ops *ops; -@@ -383,6 +399,8 @@ static size_t rtnl_link_get_size(const struct net_device *dev) - /* IFLA_INFO_XSTATS */ - size += nla_total_size(ops->get_xstats_size(dev)); - -+ size += rtnl_link_get_slave_info_data_size(dev); -+ - return size; - } - -@@ -475,38 +493,101 @@ static size_t rtnl_link_get_af_size(const struct net_device *dev) - return size; - } - --static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev) -+static bool rtnl_have_link_slave_info(const struct net_device *dev) - { -- const struct rtnl_link_ops *ops = dev->rtnl_link_ops; -- struct nlattr *linkinfo, *data; -- int err = -EMSGSIZE; -+ struct net_device *master_dev; - -- linkinfo = nla_nest_start(skb, IFLA_LINKINFO); -- if (linkinfo == NULL) -- goto out; -+ master_dev = dev->master; -+ if (master_dev && master_dev->rtnl_link_ops && -+ master_dev->rtnl_link_ops->fill_slave_info) -+ return true; -+ return false; -+} - -+static int rtnl_link_slave_info_fill(struct sk_buff *skb, -+ const struct net_device *dev) -+{ -+ struct net_device *master_dev; -+ const struct rtnl_link_ops *ops; -+ struct nlattr *slave_data; -+ int err; -+ -+ master_dev = dev->master; -+ if (!master_dev) -+ return 0; -+ ops = master_dev->rtnl_link_ops; -+ if (!ops) -+ return 0; -+ if (nla_put_string(skb, IFLA_INFO_SLAVE_KIND, ops->kind) < 0) -+ return -EMSGSIZE; -+ if (ops->fill_slave_info) { -+ slave_data = nla_nest_start(skb, IFLA_INFO_SLAVE_DATA); -+ if (!slave_data) -+ return -EMSGSIZE; -+ err = ops->fill_slave_info(skb, master_dev, dev); -+ if (err < 0) -+ goto err_cancel_slave_data; -+ nla_nest_end(skb, slave_data); -+ } -+ return 0; -+ -+err_cancel_slave_data: -+ nla_nest_cancel(skb, slave_data); -+ return err; -+} -+ -+static int rtnl_link_info_fill(struct sk_buff *skb, -+ const struct net_device *dev) -+{ -+ const struct rtnl_link_ops *ops = dev->rtnl_link_ops; -+ struct nlattr *data; -+ int err; -+ -+ if (!ops) -+ return 0; - if (nla_put_string(skb, IFLA_INFO_KIND, ops->kind) < 0) -- goto err_cancel_link; -+ return -EMSGSIZE; - if (ops->fill_xstats) { - err = ops->fill_xstats(skb, dev); - if (err < 0) -- goto err_cancel_link; -+ return err; - } - if (ops->fill_info) { - data = nla_nest_start(skb, IFLA_INFO_DATA); - if (data == NULL) -- goto err_cancel_link; -+ return -EMSGSIZE; - err = ops->fill_info(skb, dev); - if (err < 0) - goto err_cancel_data; - nla_nest_end(skb, data); - } -- -- nla_nest_end(skb, linkinfo); - return 0; - - err_cancel_data: - nla_nest_cancel(skb, data); -+ return err; -+} -+ -+static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev) -+{ -+ struct nlattr *linkinfo; -+ int err = -EMSGSIZE; -+ -+ linkinfo = nla_nest_start(skb, IFLA_LINKINFO); -+ if (linkinfo == NULL) -+ goto out; -+ -+ err = rtnl_link_info_fill(skb, dev); -+ if (err < 0) -+ goto err_cancel_link; -+ -+ err = rtnl_link_slave_info_fill(skb, dev); -+ if (err < 0) -+ goto err_cancel_link; -+ -+ nla_nest_end(skb, linkinfo); -+ return 0; -+ - err_cancel_link: - nla_nest_cancel(skb, linkinfo); - out: -@@ -1011,7 +1092,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, - if (rtnl_port_fill(skb, dev, ext_filter_mask)) - goto nla_put_failure; - -- if (dev->rtnl_link_ops) { -+ if (dev->rtnl_link_ops || rtnl_have_link_slave_info(dev)) { - if (rtnl_link_fill(skb, dev) < 0) - goto nla_put_failure; - } -@@ -1139,6 +1220,8 @@ EXPORT_SYMBOL(ifla_policy); - static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { - [IFLA_INFO_KIND] = { .type = NLA_STRING }, - [IFLA_INFO_DATA] = { .type = NLA_NESTED }, -+ [IFLA_INFO_SLAVE_KIND] = { .type = NLA_STRING }, -+ [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED }, - }; - - static const struct nla_policy ifla_vfinfo_policy[IFLA_VF_INFO_MAX+1] = { -@@ -1719,7 +1802,9 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - { - struct net *net = sock_net(skb->sk); - const struct rtnl_link_ops *ops; -+ const struct rtnl_link_ops *m_ops = NULL; - struct net_device *dev; -+ struct net_device *master_dev = NULL; - struct ifinfomsg *ifm; - char kind[MODULE_NAME_LEN]; - char ifname[IFNAMSIZ]; -@@ -1749,6 +1834,12 @@ replay: - dev = NULL; - } - -+ if (dev) { -+ master_dev = dev->master; -+ if (master_dev) -+ m_ops = master_dev->rtnl_link_ops; -+ } -+ - err = validate_linkmsg(dev, tb); - if (err < 0) - return err; -@@ -1770,7 +1861,10 @@ replay: - } - - if (1) { -- struct nlattr *attr[ops ? ops->maxtype + 1 : 0], **data = NULL; -+ struct nlattr *attr[ops ? ops->maxtype + 1 : 0]; -+ struct nlattr *slave_attr[m_ops ? m_ops->slave_maxtype + 1 : 0]; -+ struct nlattr **data = NULL; -+ struct nlattr **slave_data = NULL; - struct net *dest_net; - - if (ops) { -@@ -1789,6 +1883,24 @@ replay: - } - } - -+ if (m_ops) { -+ if (m_ops->slave_maxtype && -+ linkinfo[IFLA_INFO_SLAVE_DATA]) { -+ err = nla_parse_nested(slave_attr, -+ m_ops->slave_maxtype, -+ linkinfo[IFLA_INFO_SLAVE_DATA], -+ m_ops->slave_policy); -+ if (err < 0) -+ return err; -+ slave_data = slave_attr; -+ } -+ if (m_ops->slave_validate) { -+ err = m_ops->slave_validate(tb, slave_data); -+ if (err < 0) -+ return err; -+ } -+ } -+ - if (dev) { - int modified = 0; - -@@ -1808,6 +1920,17 @@ replay: - modified = 1; - } - -+ if (linkinfo[IFLA_INFO_SLAVE_DATA]) { -+ if (!m_ops || !m_ops->slave_changelink) -+ return -EOPNOTSUPP; -+ -+ err = m_ops->slave_changelink(master_dev, dev, -+ tb, slave_data); -+ if (err < 0) -+ return err; -+ modified = 1; -+ } -+ - return do_setlink(dev, ifm, tb, ifname, modified); - } - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-rtnl-fdb-add-del-remove-redundant-notification.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-rtnl-fdb-add-del-remove-redundant-notification.patch deleted file mode 100644 index ba09be4b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-rtnl-fdb-add-del-remove-redundant-notification.patch +++ /dev/null @@ -1,30 +0,0 @@ -vxlan fixes - -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 329bb72..c2d619b 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -2115,7 +2115,10 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - nlh->nlmsg_flags); - - if (!err) { -- rtnl_fdb_notify(dev, addr, dst, RTM_NEWNEIGH); -+ /* In all cases the netdev fdb_add handler -+ * sends a netlink notification. So we dont need -+ * it here again. -+ * rtnl_fdb_notify(dev, addr, dst, RTM_NEWNEIGH); */ - ndm->ndm_flags &= ~NTF_SELF; - } - } -@@ -2175,7 +2178,10 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - err = dev->netdev_ops->ndo_fdb_del(ndm, dev, addr); - - if (!err) { -- rtnl_fdb_notify(dev, addr, NULL, RTM_DELNEIGH); -+ /* In all cases the netdev fdb_add handler -+ * sends a netlink notification. So we dont need -+ * it here again. -+ * rtnl_fdb_notify(dev, addr, NULL, RTM_DELNEIGH); */ - ndm->ndm_flags &= ~NTF_SELF; - } - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-stp-sysctl.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-stp-sysctl.patch deleted file mode 100644 index 28001d0e..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-stp-sysctl.patch +++ /dev/null @@ -1,146 +0,0 @@ -Add sysctl to decide if STP is in userspace/kernel - -diff --git a/net/bridge/br.c b/net/bridge/br.c -index d3f57c1..9058381 100644 ---- a/net/bridge/br.c -+++ b/net/bridge/br.c -@@ -35,14 +35,74 @@ static struct pernet_operations br_net_ops = { - .exit = br_net_exit, - }; - -+#ifdef CONFIG_SYSCTL -+static struct ctl_table_header *brstp_sysctl_header; -+int brstp_user_space __read_mostly = 1; -+ -+static -+int brstp_sysctl_call_tables(ctl_table * ctl, int write, -+ void __user * buffer, size_t * lenp, loff_t * ppos) -+{ -+ int ret; -+ int old_brstp_user_space = brstp_user_space; -+ -+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos); -+ if (old_brstp_user_space != brstp_user_space) { -+ printk(KERN_INFO "set stp state - %s\n", -+ brstp_user_space ? "user" : "kernel"); -+ if (!brstp_user_space) { -+ ret = stp_proto_register(&br_stp_proto); -+ if (ret < 0) { -+ pr_err("bridge: can't register sap for STP\n"); -+ return ret; -+ } -+ } else { -+ stp_proto_unregister(&br_stp_proto); -+ } -+ } -+ -+ return ret; -+} -+ -+static ctl_table brstp_table[] = { -+ { -+ .procname = "bridge-stp-user-space", -+ .data = &brstp_user_space, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = brstp_sysctl_call_tables, -+ }, -+ { } -+}; -+ -+static struct ctl_path brstp_path[] = { -+ { .procname = "net", }, -+ { .procname = "bridge", }, -+ { } -+}; -+#else -+#define brstp_user_space 1 -+#endif -+ - static int __init br_init(void) - { - int err; - -- err = stp_proto_register(&br_stp_proto); -- if (err < 0) { -- pr_err("bridge: can't register sap for STP\n"); -- return err; -+#ifdef CONFIG_SYSCTL -+ brstp_sysctl_header = register_sysctl_paths(brstp_path, brstp_table); -+ if (brstp_sysctl_header == NULL) { -+ printk(KERN_WARNING -+ "br_init: can't register to sysctl.\n"); -+ return -ENOMEM; -+ } -+#endif -+ -+ if (!brstp_user_space) { -+ err = stp_proto_register(&br_stp_proto); -+ if (err < 0) { -+ pr_err("bridge: can't register sap for STP\n"); -+ return err; -+ } - } - - err = br_fdb_init(); -@@ -81,14 +141,21 @@ err_out2: - err_out1: - br_fdb_fini(); - err_out: -- stp_proto_unregister(&br_stp_proto); -+ if (!brstp_user_space) -+ stp_proto_unregister(&br_stp_proto); -+#ifdef CONFIG_SYSCTL -+ unregister_sysctl_table(brstp_sysctl_header); -+#endif - return err; - } - - static void __exit br_deinit(void) - { -- stp_proto_unregister(&br_stp_proto); -- -+ if (!brstp_user_space) -+ stp_proto_unregister(&br_stp_proto); -+#ifdef CONFIG_SYSCTL -+ unregister_sysctl_table(brstp_sysctl_header); -+#endif - br_netlink_fini(); - unregister_netdevice_notifier(&br_device_notifier); - brioctl_set(NULL); -diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c -index 03ff405..3fb4de8 100644 ---- a/net/bridge/br_stp.c -+++ b/net/bridge/br_stp.c -@@ -32,8 +32,8 @@ static const char *const br_port_state_names[] = { - void br_log_state(const struct net_bridge_port *p) - { - br_info(p->br, "port %u(%s) entering %s state\n", -- (unsigned) p->port_no, p->dev->name, -- br_port_state_names[p->state]); -+ (unsigned) p->port_no, p->dev->name, -+ br_port_state_names[p->state]); - } - - /* called under bridge lock */ -diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c -index ae80d6d..28c2b97 100644 ---- a/net/bridge/br_stp_if.c -+++ b/net/bridge/br_stp_if.c -@@ -128,13 +128,13 @@ void br_stp_disable_port(struct net_bridge_port *p) - - static void br_stp_start(struct net_bridge *br) - { -- int r; - char *argv[] = { BR_STP_PROG, br->dev->name, "start", NULL }; - char *envp[] = { NULL }; - struct net_bridge_port *p; -+ extern int brstp_user_space; - -- r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); -- if (r == 0) { -+ if (brstp_user_space) { -+ call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); - br->stp_enabled = BR_USER_STP; - br_debug(br, "userspace STP started\n"); - /* Stop hello and hold timer */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tcp-md5sig-debug.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tcp-md5sig-debug.patch deleted file mode 100644 index bca1c552..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tcp-md5sig-debug.patch +++ /dev/null @@ -1,436 +0,0 @@ -network: ipv4 tcp md5sig debugging code - -There is a problem with ipv4 tcp md5 signatures (RFC 2385) on some -powerpc processors (seen on 85xx series at least). This debugging -code helped in the investigation. - -This code is best used with the dynamic debug feature of the kernel -enabled, CONFIG_DYNAMIC_DEBUG=y. - -If using dynamic debug do the following once the device has booted: - export DEBUGFS=/sys/kernel/debug - mount -t debugfs none "${DEBUGFS}" - echo 'file crypto/ahash.c +p' >${DEBUGFS}/dynamic_debug/control - echo 'file crypto/shash.c +p' >${DEBUGFS}/dynamic_debug/control - echo 'file crypto/md5.c +p' >${DEBUGFS}/dynamic_debug/control - echo 'file net/ipv4/tcp.c +p' >${DEBUGFS}/dynamic_debug/control - echo 'file net/ipv4/tcp_ipv4.c +p' >${DEBUGFS}/dynamic_debug/control - -diff --git a/crypto/ahash.c b/crypto/ahash.c -index 7fe1752..2b338ca 100644 ---- a/crypto/ahash.c -+++ b/crypto/ahash.c -@@ -26,6 +26,43 @@ - - #include "internal.h" - -+#if defined(CONFIG_DYNAMIC_DEBUG) -+inline void __ahash_debug_walk(const char *_func, const unsigned long _line, -+ const struct crypto_hash_walk *walkptr, -+ const unsigned long len, -+ const char *tag, -+ const bool hexdump) -+{ -+ pr_debug("%s:%lu - %s%sstruct crypto_hash_walk *walk: (hexdump: %s)\n" -+ "\twalk->data: 0x%pK\n" -+ "\twalk->offset: 0x%016lx\n" -+ "\twalk->alignmask: 0x%016lx\n" -+ "\twalk->pg: 0x%pK\n" -+ "\twalk->entrylen: %lu\n" -+ "\twalk->total: %lu\n" -+ "\twalk->sg: 0x%pK\n" -+ "\twalk->flags: 0x%016lx\n", -+ _func, _line, tag, (strlen(tag)) ? " - " : "", -+ (hexdump) ? "true" : "false", -+ (walkptr)->data, -+ (unsigned long) (walkptr)->offset, -+ (unsigned long) (walkptr)->alignmask, -+ (walkptr)->pg, -+ (unsigned long) (walkptr)->entrylen, -+ (unsigned long) (walkptr)->total, -+ (walkptr)->sg, -+ (unsigned long) (walkptr)->flags); -+ if (hexdump && (walkptr)->data) { -+ print_block_debug("walk->data:", (walkptr)->data, (len)); -+ } -+} -+ -+#define ahash_debug_walk(walkptr, len, tag, hexdump) \ -+ __ahash_debug_walk(__FUNCTION__, __LINE__, walkptr, len, tag, hexdump) -+#else -+#define ahash_debug_walk(...) -+#endif -+ - struct ahash_request_priv { - crypto_completion_t complete; - void *data; -@@ -46,6 +83,7 @@ static int hash_walk_next(struct crypto_hash_walk *walk) - unsigned int nbytes = min(walk->entrylen, - ((unsigned int)(PAGE_SIZE)) - offset); - -+ ahash_debug_walk(walk, nbytes, "BEFORE kmap()", false); - walk->data = crypto_kmap(walk->pg, 0); - walk->data += offset; - -@@ -56,6 +94,7 @@ static int hash_walk_next(struct crypto_hash_walk *walk) - } - - walk->entrylen -= nbytes; -+ ahash_debug_walk(walk, nbytes, "AFTER kmap()", true); - return nbytes; - } - -@@ -72,6 +111,7 @@ static int hash_walk_new_entry(struct crypto_hash_walk *walk) - walk->entrylen = walk->total; - walk->total -= walk->entrylen; - -+ ahash_debug_walk(walk, 0, "", false); - return hash_walk_next(walk); - } - -@@ -80,6 +120,8 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err) - unsigned int alignmask = walk->alignmask; - unsigned int nbytes = walk->entrylen; - -+ ahash_debug_walk(walk, nbytes, "", true); -+ - walk->data -= walk->offset; - - if (nbytes && walk->offset & alignmask && !err) { -@@ -90,6 +132,7 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err) - ((unsigned int)(PAGE_SIZE)) - walk->offset); - walk->entrylen -= nbytes; - -+ ahash_debug_walk(walk, walk->entrylen, "alignment", true); - return nbytes; - } - -@@ -110,6 +153,7 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err) - - walk->sg = scatterwalk_sg_next(walk->sg); - -+ ahash_debug_walk(walk, 0, "", false); - return hash_walk_new_entry(walk); - } - EXPORT_SYMBOL_GPL(crypto_hash_walk_done); -@@ -143,6 +187,7 @@ int crypto_hash_walk_first_compat(struct hash_desc *hdesc, - walk->sg = sg; - walk->flags = hdesc->flags; - -+ ahash_debug_walk(walk, 0, "", false); - return hash_walk_new_entry(walk); - } - -diff --git a/crypto/md5.c b/crypto/md5.c -index 7febeaa..c3a8335 100644 ---- a/crypto/md5.c -+++ b/crypto/md5.c -@@ -65,29 +65,58 @@ static int md5_update(struct shash_desc *desc, const u8 *data, unsigned int len) - struct md5_state *mctx = shash_desc_ctx(desc); - const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); - -+ pr_debug("%s:%d - desc: %pK\n\tdata: %pK\n\tlen: %llu\n\tmctx: %pK\n\t" -+ "sizeof(mctx->block): %llu\n\tmctx->byte_count: %llu\n\tavail: %llu\n", -+ __FUNCTION__, __LINE__, -+ desc, -+ data, -+ (unsigned long long) len, -+ mctx, -+ sizeof(mctx->block), -+ (unsigned long long) mctx->byte_count, -+ (unsigned long long) avail); -+ print_block_debug("data", data, len); -+ print_block_debug("initial block", mctx->block, sizeof(mctx->block)); -+ - mctx->byte_count += len; - - if (avail > len) { - memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), - data, len); -+ print_block_debug("avail > len block", mctx->block, sizeof(mctx->block)); - return 0; - } - - memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), - data, avail); - -+ -+ print_block_debug("pre init md5_transform_helper block", mctx->block, sizeof(mctx->block)); -+ print_block_debug("pre init md5_transform_helper hash", mctx->hash, sizeof(mctx->hash)); -+ - md5_transform_helper(mctx); - data += avail; - len -= avail; - -+ print_block_debug("post md5_transform_helper block", mctx->block, sizeof(mctx->block)); -+ print_block_debug("post md5_transform_helper hash", mctx->hash, sizeof(mctx->hash)); -+ - while (len >= sizeof(mctx->block)) { -+ print_block_debug("md5 block", mctx->block, sizeof(mctx->block)); -+ print_block_debug("md5 hash", mctx->hash, sizeof(mctx->hash)); - memcpy(mctx->block, data, sizeof(mctx->block)); -+ print_block_debug("md5 block", mctx->block, sizeof(mctx->block)); -+ print_block_debug("md5 hash", mctx->hash, sizeof(mctx->hash)); - md5_transform_helper(mctx); - data += sizeof(mctx->block); - len -= sizeof(mctx->block); -+ print_block_debug("md5 block", mctx->block, sizeof(mctx->block)); -+ print_block_debug("md5 hash", mctx->hash, sizeof(mctx->hash)); - } - - memcpy(mctx->block, data, len); -+ print_block_debug("md5 block final", mctx->block, sizeof(mctx->block)); -+ print_block_debug("md5 hash final", mctx->hash, sizeof(mctx->hash)); - - return 0; - } -diff --git a/crypto/shash.c b/crypto/shash.c -index f507294..6049fbc 100644 ---- a/crypto/shash.c -+++ b/crypto/shash.c -@@ -101,6 +101,8 @@ int crypto_shash_update(struct shash_desc *desc, const u8 *data, - struct shash_alg *shash = crypto_shash_alg(tfm); - unsigned long alignmask = crypto_shash_alignmask(tfm); - -+ print_block_debug("before update", data, len); -+ - if ((unsigned long)data & alignmask) - return shash_update_unaligned(desc, data, len); - -@@ -393,6 +395,11 @@ static int shash_compat_update(struct hash_desc *hdesc, struct scatterlist *sg, - struct crypto_hash_walk walk; - int nbytes; - -+ pr_debug("%s:%d\n" -+ "\twalk: %pK\n" -+ "\tdesc: %pk\n" -+ "\tdescp: %pK\n", __FUNCTION__, __LINE__, &walk, desc, descp); -+ - for (nbytes = crypto_hash_walk_first_compat(hdesc, &walk, sg, len); - nbytes > 0; nbytes = crypto_hash_walk_done(&walk, nbytes)) - nbytes = crypto_shash_update(desc, walk.data, nbytes); -diff --git a/include/linux/printk.h b/include/linux/printk.h -index 8815d9d..8ab912f 100644 ---- a/include/linux/printk.h -+++ b/include/linux/printk.h -@@ -292,9 +292,15 @@ extern void print_hex_dump(const char *level, const char *prefix_str, - int prefix_type, int rowsize, int groupsize, - const void *buf, size_t len, bool ascii); - #if defined(CONFIG_DYNAMIC_DEBUG) -+#define print_block_debug(str, buf, len) \ -+ do { \ -+ pr_debug("%s:%d - %s:\n", __FUNCTION__, __LINE__, (str)); \ -+ print_hex_dump_bytes(" ", DUMP_PREFIX_ADDRESS, (buf), (len)); \ -+ } while(0) - #define print_hex_dump_bytes(prefix_str, prefix_type, buf, len) \ - dynamic_hex_dump(prefix_str, prefix_type, 16, 1, buf, len, true) - #else -+#define print_block_debug(str, buf, len) do { } while(0) - extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type, - const void *buf, size_t len); - #endif /* defined(CONFIG_DYNAMIC_DEBUG) */ -@@ -309,6 +315,7 @@ static inline void print_hex_dump_bytes(const char *prefix_str, int prefix_type, - { - } - -+#define print_block_debug(str, buf, len) do { } while(0) - #endif - - #endif -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index fe381c2..864515f 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -277,6 +277,27 @@ - #include - #include - -+#include -+#include -+#include -+#include -+ -+#if defined(CONFIG_DYNAMIC_DEBUG) -+#define print_sg_block_debug(header, sg) \ -+ do { \ -+ pr_debug("%s:%d - %s%sstruct scatterlist sg:\n" \ -+ "\tsg addr: %pK\n" \ -+ "\tsg->page_link: %016lx\n" \ -+ "\tsg->offset: %016lx\n" \ -+ "\tsg->length: %016lx\n", \ -+ __FUNCTION__, __LINE__, (header), \ -+ (strlen(header)) ? " - " : "", \ -+ (sg), (sg)->page_link, (unsigned long) (sg)->offset, (unsigned long) (sg)->length); \ -+ } while(0) -+#else -+#define print_sg_block_debug(header, sg) -+#endif -+ - int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT; - - struct percpu_counter tcp_orphan_count; -@@ -3005,14 +3026,24 @@ int tcp_md5_hash_header(struct tcp_md5sig_pool *hp, - struct scatterlist sg; - struct tcphdr hdr; - int err; -+ struct md5_state *mctx; - - /* We are not allowed to change tcphdr, make a local copy */ - memcpy(&hdr, th, sizeof(hdr)); - hdr.check = 0; - -+ print_block_debug("input", &hdr, sizeof(hdr)); -+ - /* options aren't included in the hash */ - sg_init_one(&sg, &hdr, sizeof(hdr)); -+ print_sg_block_debug("sg on stack", &sg); - err = crypto_hash_update(&hp->md5_desc, &sg, sizeof(hdr)); -+ -+ mctx = shash_desc_ctx((struct shash_desc *) &(hp->md5_desc)); -+ pr_debug("%s:%d - mctx: %pK\n", __func__, __LINE__, mctx); -+ print_block_debug("md5 block", mctx->block, sizeof(mctx->block)); -+ print_block_debug("md5 hash", mctx->hash, sizeof(mctx->hash)); -+ - return err; - } - EXPORT_SYMBOL(tcp_md5_hash_header); -@@ -3029,7 +3060,10 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp, - const struct skb_shared_info *shi = skb_shinfo(skb); - struct sk_buff *frag_iter; - -+ pr_debug("%s:%d - head_data_len %llu\n", __FUNCTION__, __LINE__, -+ (unsigned long long) head_data_len); - sg_init_table(&sg, 1); -+ print_sg_block_debug("sg on stack", &sg); - - sg_set_buf(&sg, ((u8 *) tp) + header_len, head_data_len); - if (crypto_hash_update(desc, &sg, head_data_len)) -@@ -3054,9 +3088,21 @@ EXPORT_SYMBOL(tcp_md5_hash_skb_data); - int tcp_md5_hash_key(struct tcp_md5sig_pool *hp, const struct tcp_md5sig_key *key) - { - struct scatterlist sg; -+ int err; -+ struct md5_state *mctx; -+ -+ print_block_debug("input", key->key, key->keylen); - - sg_init_one(&sg, key->key, key->keylen); -- return crypto_hash_update(&hp->md5_desc, &sg, key->keylen); -+ print_sg_block_debug("sg on stack", &sg); -+ err = crypto_hash_update(&hp->md5_desc, &sg, key->keylen); -+ -+ mctx = shash_desc_ctx((struct shash_desc *) &(hp->md5_desc)); -+ pr_debug("%s:%d - mctx: %pK\n", __func__, __LINE__, mctx); -+ print_block_debug("md5 block", mctx->block, sizeof(mctx->block)); -+ print_block_debug("md5 hash", mctx->hash, sizeof(mctx->hash)); -+ -+ return err; - } - EXPORT_SYMBOL(tcp_md5_hash_key); - -diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index a97c9ad..3d7b3b5 100644 ---- a/net/ipv4/tcp_ipv4.c -+++ b/net/ipv4/tcp_ipv4.c -@@ -83,6 +83,10 @@ - #include - #include - -+#include -+#include -+#include -+ - int sysctl_tcp_tw_reuse __read_mostly; - int sysctl_tcp_low_latency __read_mostly; - EXPORT_SYMBOL(sysctl_tcp_low_latency); -@@ -93,6 +97,22 @@ static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, - __be32 addr); - static int tcp_v4_md5_hash_hdr(char *md5_hash, struct tcp_md5sig_key *key, - __be32 daddr, __be32 saddr, const struct tcphdr *th); -+ -+#if defined(CONFIG_DYNAMIC_DEBUG) -+#define print_sg_block_debug(header, sg) \ -+ do { \ -+ pr_debug("%s:%d - %s%sstruct scatterlist sg:\n" \ -+ "\tsg addr: %pK\n" \ -+ "\tsg->page_link: %016lx\n" \ -+ "\tsg->offset: %016lx\n" \ -+ "\tsg->length: %016lx\n", \ -+ __FUNCTION__, __LINE__, (header), \ -+ (strlen(header)) ? " - " : "", \ -+ (sg), (sg)->page_link, (unsigned long) (sg)->offset, (unsigned long) (sg)->length); \ -+ } while(0) -+#else -+#define print_sg_block_debug(header, sg) -+#endif - #else - static inline - struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, __be32 addr) -@@ -1094,7 +1114,13 @@ static int tcp_v4_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp, - bp->protocol = IPPROTO_TCP; - bp->len = cpu_to_be16(nbytes); - -+ pr_debug("%s:%d - virt & phys addrs\n" -+ "\tvirt_to_page(bp): %pK\n" -+ "\tvirt_to_phys(bp): %pK\n", -+ __FUNCTION__, __LINE__, virt_to_page(bp), (void *) virt_to_phys(bp)); - sg_init_one(&sg, bp, sizeof(*bp)); -+ print_block_debug("pseudoheader - bp", bp, sizeof(*bp)); -+ print_sg_block_debug("sg on stack", &sg); - return crypto_hash_update(&hp->md5_desc, &sg, sizeof(*bp)); - } - -@@ -1156,17 +1182,32 @@ int tcp_v4_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key, - goto clear_hash_noput; - desc = &hp->md5_desc; - -+ pr_debug("%s:%d:%s() - hp = 0x%pK", __FILE__, __LINE__, __func__, hp); -+ print_block_debug("(struct tcp_md5sig_pool) hp", hp, sizeof(*hp)); -+ - if (crypto_hash_init(desc)) - goto clear_hash; - -+ pr_debug("%s:%d Begin MD5 calculation - tcp_v4_md5_hash_pseudoheader\n", -+ __FUNCTION__, __LINE__); - if (tcp_v4_md5_hash_pseudoheader(hp, daddr, saddr, skb->len)) - goto clear_hash; -+ pr_debug("%s:%d:%s() - hp = 0x%pK", __FILE__, __LINE__, __func__, hp); -+ print_block_debug("(struct tcp_md5sig_pool) hp", hp, sizeof(*hp)); -+ pr_debug("%s:%d tcp_md5_hash_header\n", __FUNCTION__, __LINE__); - if (tcp_md5_hash_header(hp, th)) - goto clear_hash; -+ pr_debug("%s:%d:%s() - hp = 0x%pK", __FILE__, __LINE__, __func__, hp); -+ print_block_debug("(struct tcp_md5sig_pool) hp", hp, sizeof(*hp)); -+ pr_debug("%s:%d tcp_md5_hash_skb_data\n", __FUNCTION__, __LINE__); - if (tcp_md5_hash_skb_data(hp, skb, th->doff << 2)) - goto clear_hash; -+ pr_debug("%s:%d:%s() - hp = 0x%pK", __FILE__, __LINE__, __func__, hp); -+ print_block_debug("(struct tcp_md5sig_pool) hp", hp, sizeof(*hp)); -+ pr_debug("%s:%d tcp_md5_hash_key\n", __FUNCTION__, __LINE__); - if (tcp_md5_hash_key(hp, key)) - goto clear_hash; -+ pr_debug("%s:%d crypto_hash_final\n", __FUNCTION__, __LINE__); - if (crypto_hash_final(desc, md5_hash)) - goto clear_hash; - -@@ -1215,6 +1256,8 @@ static int tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) - return 1; - } - -+ pr_debug("vvvvvvvvvvvvvvvv START MD5 TCP Calc START vvvvvvvvvvvvvvvv\n"); -+ - /* Okay, so this is hash_expected and hash_location - - * so we need to calculate the checksum. - */ -@@ -1222,6 +1265,11 @@ static int tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) - hash_expected, - NULL, NULL, skb); - -+ print_block_debug("MD5 Hash (hash_expected)", hash_expected->key, hash_expected->keylen); -+ print_block_debug("MD5 Hash calculated (newhash)", newhash, sizeof(newhash)); -+ print_block_debug("MD5 Hash pkt (hash_location)", hash_location, 16); -+ pr_debug("^^^^^^^^^^^^^^^^ END MD5 TCP Calc END ^^^^^^^^^^^^^^^^^\n"); -+ - if (genhash || memcmp(hash_location, newhash, 16) != 0) { - if (net_ratelimit()) { - printk(KERN_INFO "MD5 Hash failed for (%pI4, %d)->(%pI4, %d)%s\n", diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tcp-md5sig-pseudoheader-calc-workaround.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tcp-md5sig-pseudoheader-calc-workaround.patch deleted file mode 100644 index 325b213e..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tcp-md5sig-pseudoheader-calc-workaround.patch +++ /dev/null @@ -1,89 +0,0 @@ -network: tcp_v4_md5_hash_pseudoheader calculates wrong result - -This is a workaround for what seems to be a bug in the powerpc architecture -SMP or page table code. The issue is caused by what seems to be an incorrect -page table mapping for a per-cpu structure `tcp_md5sig_pool` defined at -"net/ipv4/tcp.c" line 2888. Following the receive side of the ipv4 TCP stack. -What happens is the variable `bp` in `tcp_v4_md5_hash_pseudoheader()` is -assigned `&hp->md5_blk.ip4` where `hp` is assigned a per-cpu member of -the pool in `tcp_v4_md5_hash_skb()`. -The point is when `bp` is mapped to a scatterlist `sg` part of this process -is to figure out what memory page `bp` maps to and store this in sg->page_link. -When this scatterlist is sent down through the crypto API and eventually to the -MD5 code `md5_update()` ('crypto/md5.c') the kmap()'ped (page -> -virtual address) does not point to the original `bp` data. A trace using -the debug code demonstrates this. - -NOTE: The scatter list uses the least significant nibble for flags - so one needs to do the following math (addr & (~0xF)) - ---------- - tcp_v4_md5_hash_pseudoheader:1121 - pseudoheader - bp: - ff6f4ddc: 0a 00 01 83 0a 00 01 55 00 06 00 2c .......U..., - tcp_v4_md5_hash_pseudoheader:1122 - sg on stack - struct scatterlist sg: - sg addr: eff2fca0 - sg->page_link: 00000000c0e2fe82 - sg->offset: 0000000000000ddc - sg->length: 000000000000000c - -... code trace trimmed - unimportant ... - - hash_walk_next:102 - AFTER kmap() - struct crypto_hash_walk *walk: (hexdump: true) - walk->data: 0xfffdfddc /* <- this address is wrong - or the page we were given is */ - walk->offset: 0x0000000000000ddc - walk->alignmask: 0x0000000000000000 - walk->pg: 0xc0e2fe80 /* <- this was the page used to do the mapping */ - walk->entrylen: 0 - walk->total: 0 - walk->sg: 0xeff2fca0 - walk->flags: 0x0000000000000000 - __ahash_debug_walk:56 - walk->data:: /* vv this data doesn't look like what we passed in!! */ - fffdfddc: c6 9c 36 90 ae 94 91 1e 75 ae df ca ..6.....u... - crypto_shash_update:104 - before update: - fffdfddc: c6 9c 36 90 ae 94 91 1e 75 ae df ca ..6.....u... - md5_update:77 - desc: efbfff00 - data: fffdfddc - len: 12 - mctx: efbfff08 - sizeof(mctx->block): 0 - mctx->byte_count: 64 - avail: 17275807075376430556 - md5_update:78 - data: - fffdfddc: c6 9c 36 90 ae 94 91 1e 75 ae df ca ..6.....u... - md5_update:79 - initial block: - efbfff18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - efbfff28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - efbfff38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - efbfff48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - md5_update:86 - avail > len block: - efbfff18: c6 9c 36 90 ae 94 91 1e 75 ae df ca 00 00 00 00 ..6.....u....... - efbfff28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - efbfff38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - efbfff48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ---------- - -Using this per-cpu pool to store the structure is done so that a lock doesn't -have to be held while processing this packet, however, interrupts are disabled -on this CPU while the calculation takes place. It is unclear why the -pseudoheader was included in the pool, presumably to mitigate against -cache thrashing. The solution is to just use a psudoheader allocated on the -stack since this is able to be correctly mapped. - -diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index 92d7138..d5bad8a 100644 ---- a/net/ipv4/tcp_ipv4.c -+++ b/net/ipv4/tcp_ipv4.c -@@ -1078,11 +1078,10 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval, - static int tcp_v4_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp, - __be32 daddr, __be32 saddr, int nbytes) - { -- struct tcp4_pseudohdr *bp; -+ struct tcp4_pseudohdr scratch; -+ struct tcp4_pseudohdr *bp = &scratch; - struct scatterlist sg; - -- bp = &hp->md5_blk.ip4; -- - /* - * 1. the TCP pseudo-header (in the order: source IP address, - * destination IP address, zero-padded protocol number, and diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-64-bit-statistics.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-64-bit-statistics.patch deleted file mode 100644 index adcf395a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-64-bit-statistics.patch +++ /dev/null @@ -1,130 +0,0 @@ -Add support for 64-bit interface statistics. - -diff --git a/drivers/net/tun.c b/drivers/net/tun.c -index ee1aab0..0c31f58 100644 ---- a/drivers/net/tun.c -+++ b/drivers/net/tun.c -@@ -64,6 +64,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -134,6 +135,10 @@ struct tun_struct { - - int vnet_hdr_sz; - -+ spinlock_t stat_lock; -+ struct u64_stats_sync stat_sync; -+ struct rtnl_link_stats64 stats; -+ - #ifdef TUN_DEBUG - int debug; - #endif -@@ -376,6 +381,15 @@ static int tun_net_close(struct net_device *dev) - return 0; - } - -+static inline void tun_stat64_inc(struct tun_struct *tun, u64 *stat) -+{ -+ spin_lock_bh(&tun->stat_lock); -+ u64_stats_update_begin(&tun->stat_sync); -+ (*stat)++; -+ u64_stats_update_end(&tun->stat_sync); -+ spin_unlock_bh(&tun->stat_lock); -+} -+ - /* Net device start xmit */ - static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) - { -@@ -405,7 +419,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) - - /* We won't see all dropped packets individually, so overrun - * error is more appropriate. */ -- dev->stats.tx_fifo_errors++; -+ tun_stat64_inc(tun, &tun->stats.tx_fifo_errors); - } else { - /* Single queue mode. - * Driver handles dropping of all packets itself. */ -@@ -430,7 +444,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) - return NETDEV_TX_OK; - - drop: -- dev->stats.tx_dropped++; -+ tun_stat64_inc(tun, &tun->stats.tx_dropped); - kfree_skb(skb); - return NETDEV_TX_OK; - } -@@ -650,12 +664,12 @@ static ssize_t tun_get_user(struct tun_struct *tun, - skb = tun_alloc_skb(tun, align, len, gso.hdr_len, noblock); - if (IS_ERR(skb)) { - if (PTR_ERR(skb) != -EAGAIN) -- tun->dev->stats.rx_dropped++; -+ tun_stat64_inc(tun, &tun->stats.rx_dropped); - return PTR_ERR(skb); - } - - if (skb_copy_datagram_from_iovec(skb, 0, iv, offset, len)) { -- tun->dev->stats.rx_dropped++; -+ tun_stat64_inc(tun, &tun->stats.rx_dropped); - kfree_skb(skb); - return -EFAULT; - } -@@ -663,7 +677,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, - if (gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { - if (!skb_partial_csum_set(skb, gso.csum_start, - gso.csum_offset)) { -- tun->dev->stats.rx_frame_errors++; -+ tun_stat64_inc(tun, &tun->stats.rx_frame_errors); - kfree_skb(skb); - return -EINVAL; - } -@@ -680,7 +694,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, - pi.proto = htons(ETH_P_IPV6); - break; - default: -- tun->dev->stats.rx_dropped++; -+ tun_stat64_inc(tun, &tun->stats.rx_dropped); - kfree_skb(skb); - return -EINVAL; - } -@@ -708,7 +722,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, - skb_shinfo(skb)->gso_type = SKB_GSO_UDP; - break; - default: -- tun->dev->stats.rx_frame_errors++; -+ tun_stat64_inc(tun, &tun->stats.rx_frame_errors); - kfree_skb(skb); - return -EINVAL; - } -@@ -718,7 +732,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, - - skb_shinfo(skb)->gso_size = gso.gso_size; - if (skb_shinfo(skb)->gso_size == 0) { -- tun->dev->stats.rx_frame_errors++; -+ tun_stat64_inc(tun, &tun->stats.rx_frame_errors); - kfree_skb(skb); - return -EINVAL; - } -@@ -730,9 +744,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, - - netif_rx_ni(skb); - -- tun->dev->stats.rx_packets++; -- tun->dev->stats.rx_bytes += len; -- - return count; - } - -@@ -830,9 +841,6 @@ static ssize_t tun_put_user(struct tun_struct *tun, - skb_copy_datagram_const_iovec(skb, 0, iv, total, len); - total += skb->len; - -- tun->dev->stats.tx_packets++; -- tun->dev->stats.tx_bytes += len; -- - return total; - } - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-ethtool.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-ethtool.patch deleted file mode 100644 index 0a6efebe..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-ethtool.patch +++ /dev/null @@ -1,248 +0,0 @@ -Enable tun ethtool using new port library - -diff --git a/drivers/net/tun.c b/drivers/net/tun.c -index f895245..adc6269 100644 ---- a/drivers/net/tun.c -+++ b/drivers/net/tun.c -@@ -54,6 +54,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -491,6 +492,52 @@ static void tun_poll_controller(struct net_device *dev) - return; - } - #endif -+ -+struct rtnl_link_stats64* tun_net_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) -+{ -+ struct tun_struct *tun = netdev_priv(dev); -+ struct rtnl_link_stats64 tun_stats; -+ struct ethtool_stats estats = { 0, }; -+ unsigned int start; -+ int count; -+ u64 *hw_stats; -+ -+ do { -+ start = u64_stats_fetch_begin(&tun->stat_sync); -+ memcpy(&tun_stats, &tun->stats, sizeof(struct rtnl_link_stats64)); -+ } while (u64_stats_fetch_retry(&tun->stat_sync, start)); -+ -+ -+ count = port_get_sset_count(dev, ETH_SS_STATS); -+ if (count <= 0) -+ goto err_out; -+ -+ hw_stats = kmalloc(count * sizeof(u64), GFP_ATOMIC); -+ if (!hw_stats) -+ goto err_out; -+ -+ estats.n_stats = count; -+ port_get_ethtool_stats(dev, &estats, hw_stats); -+ -+ stats->rx_packets = hw_stats[1] + hw_stats[2] + hw_stats[3]; -+ stats->rx_bytes = hw_stats[0]; -+ stats->multicast = hw_stats[3]; -+ stats->rx_errors = hw_stats[12] + hw_stats[13]; -+ stats->rx_dropped = hw_stats[8] + tun_stats.rx_dropped; -+ stats->rx_frame_errors = tun_stats.rx_frame_errors; -+ -+ stats->tx_packets = hw_stats[5] + hw_stats[6] + hw_stats[7]; -+ stats->tx_bytes = hw_stats[4]; -+ stats->tx_errors = hw_stats[18] + tun_stats.tx_fifo_errors; -+ stats->tx_dropped = hw_stats[17] + tun_stats.tx_dropped; -+ -+ kfree(hw_stats); -+ -+err_out: -+ return stats; -+} -+ - static const struct net_device_ops tun_netdev_ops = { - .ndo_uninit = tun_net_uninit, - .ndo_open = tun_net_open, -@@ -501,6 +548,7 @@ static const struct net_device_ops tun_netdev_ops = { - #ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = tun_poll_controller, - #endif -+ .ndo_get_stats64 = tun_net_get_stats64, - }; - - static const struct net_device_ops tap_netdev_ops = { -@@ -516,6 +564,7 @@ static const struct net_device_ops tap_netdev_ops = { - #ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = tun_poll_controller, - #endif -+ .ndo_get_stats64 = tun_net_get_stats64, - }; - - /* Initialize net device. */ -@@ -1584,21 +1633,6 @@ static struct miscdevice tun_miscdev = { - - /* ethtool interface */ - --static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) --{ -- cmd->supported = 0; -- cmd->advertising = 0; -- ethtool_cmd_speed_set(cmd, SPEED_10); -- cmd->duplex = DUPLEX_FULL; -- cmd->port = PORT_TP; -- cmd->phy_address = 0; -- cmd->transceiver = XCVR_INTERNAL; -- cmd->autoneg = AUTONEG_DISABLE; -- cmd->maxtxpkt = 0; -- cmd->maxrxpkt = 0; -- return 0; --} -- - static void tun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) - { - struct tun_struct *tun = netdev_priv(dev); -@@ -1623,7 +1657,7 @@ static u32 tun_get_msglevel(struct net_device *dev) - struct tun_struct *tun = netdev_priv(dev); - return tun->debug; - #else -- return -EOPNOTSUPP; -+ return 0; - #endif - } - -@@ -1635,12 +1669,48 @@ static void tun_set_msglevel(struct net_device *dev, u32 value) - #endif - } - -+static void tun_get_ethtool_stats(struct net_device *dev, -+ struct ethtool_stats *stats, -+ u64 *data) -+{ -+ struct tun_struct *tun = netdev_priv(dev); -+ -+ port_get_ethtool_stats(dev, stats, data); -+} -+ -+static void tun_get_ethtool_stats_clear(struct net_device *dev, -+ struct ethtool_stats *stats, -+ u64 *data) -+{ -+ struct tun_struct *tun = netdev_priv(dev); -+ -+ port_get_ethtool_stats_clear(dev, stats, data); -+ -+ spin_lock_bh(&tun->stat_lock); -+ u64_stats_update_begin(&tun->stat_sync); -+ tun->stats.rx_dropped = 0; -+ tun->stats.rx_frame_errors = 0; -+ tun->stats.tx_fifo_errors = 0; -+ tun->stats.tx_dropped = 0; -+ u64_stats_update_end(&tun->stat_sync); -+ spin_unlock_bh(&tun->stat_lock); -+ atomic_long_set(&dev->rx_dropped, 0); -+} -+ - static const struct ethtool_ops tun_ethtool_ops = { -- .get_settings = tun_get_settings, -- .get_drvinfo = tun_get_drvinfo, -- .get_msglevel = tun_get_msglevel, -- .set_msglevel = tun_set_msglevel, -- .get_link = ethtool_op_get_link, -+ .get_settings = port_get_settings, -+ .set_settings = port_set_settings, -+ .get_drvinfo = tun_get_drvinfo, -+ .get_msglevel = tun_get_msglevel, -+ .set_msglevel = tun_set_msglevel, -+ .get_link = ethtool_op_get_link, -+ .get_strings = port_get_strings, -+ .get_ethtool_stats = tun_get_ethtool_stats, -+ .get_ethtool_stats_clear = tun_get_ethtool_stats_clear, -+ .get_sset_count = port_get_sset_count, -+ .set_phys_id = port_set_phys_id, -+ .get_module_info = port_get_module_info, -+ .get_module_eeprom = port_get_module_eeprom, - }; - - -diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h -index 02d9a42..6d2ad9e 100644 ---- a/include/linux/ethtool.h -+++ b/include/linux/ethtool.h -@@ -355,19 +355,9 @@ struct ethtool_test { - __u64 data[0]; - }; - --/** -- * enum ethtool_stats_flags - flags definition of ethtool_stats -- * @ETH_STATS_FL_CLEAR: if set clear device stats after read -- */ -- --enum ethtool_stats_flags { -- ETH_STATS_FL_CLEAR = (1 << 0), --}; -- - /* for dumping NIC-specific statistics */ - struct ethtool_stats { - __u32 cmd; /* ETHTOOL_GSTATS */ -- __u32 flags; /* ETH_STATS_FL_xxx */ - __u32 n_stats; /* number of u64's being returned */ - __u64 data[0]; - }; -@@ -957,6 +947,8 @@ struct ethtool_ops { - int (*set_phys_id)(struct net_device *, enum ethtool_phys_id_state); - void (*get_ethtool_stats)(struct net_device *, - struct ethtool_stats *, u64 *); -+ void (*get_ethtool_stats_clear)(struct net_device *, -+ struct ethtool_stats *, u64 *); - int (*begin)(struct net_device *); - void (*complete)(struct net_device *); - u32 (*get_ufo)(struct net_device *); -@@ -1064,6 +1056,8 @@ struct ethtool_ops { - #define ETHTOOL_GMODULEINFO 0x00000042 /* Get plug-in module information */ - #define ETHTOOL_GMODULEEEPROM 0x00000043 /* Get plug-in module eeprom */ - -+#define ETHTOOL_GSTATS_CLEAR 0x1000001d /* get NIC-specific statistics and clear */ -+ - /* compatibility with older code */ - #define SPARC_ETH_GSET ETHTOOL_GSET - #define SPARC_ETH_SSET ETHTOOL_SSET -diff --git a/net/core/ethtool.c b/net/core/ethtool.c -index a12af77..904bf1e 100644 ---- a/net/core/ethtool.c -+++ b/net/core/ethtool.c -@@ -1447,7 +1447,8 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) - return rc; - } - --static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) -+static int ethtool_get_stats(struct net_device *dev, void __user *useraddr, -+ int clear) - { - struct ethtool_stats stats; - const struct ethtool_ops *ops = dev->ethtool_ops; -@@ -1470,7 +1471,10 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) - if (!data) - return -ENOMEM; - -- ops->get_ethtool_stats(dev, &stats, data); -+ if (clear && ops->get_ethtool_stats_clear) -+ ops->get_ethtool_stats_clear(dev, &stats, data); -+ else -+ ops->get_ethtool_stats(dev, &stats, data); - - ret = -EFAULT; - if (copy_to_user(useraddr, &stats, sizeof(stats))) -@@ -1818,7 +1822,10 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) - rc = ethtool_phys_id(dev, useraddr); - break; - case ETHTOOL_GSTATS: -- rc = ethtool_get_stats(dev, useraddr); -+ rc = ethtool_get_stats(dev, useraddr, 0); -+ break; -+ case ETHTOOL_GSTATS_CLEAR: -+ rc = ethtool_get_stats(dev, useraddr, 1); - break; - case ETHTOOL_GPERMADDR: - rc = ethtool_get_perm_addr(dev, useraddr); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-max-mtu.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-max-mtu.patch deleted file mode 100644 index 4441f0e2..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-max-mtu.patch +++ /dev/null @@ -1,21 +0,0 @@ -Set the MAX_MTU to 9216 - -diff --git a/drivers/net/tun.c b/drivers/net/tun.c -index 0c31f58..8ac0b56 100644 ---- a/drivers/net/tun.c -+++ b/drivers/net/tun.c -@@ -459,12 +459,12 @@ static void tun_net_mclist(struct net_device *dev) - } - - #define MIN_MTU 68 --#define MAX_MTU 65535 -+#define MAX_MTU 9216 - - static int - tun_net_change_mtu(struct net_device *dev, int new_mtu) - { -- if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU) -+ if (new_mtu < MIN_MTU || new_mtu > MAX_MTU) - return -EINVAL; - dev->mtu = new_mtu; - return 0; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-no-carrier.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-no-carrier.patch deleted file mode 100644 index d3c3541a..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-tun-no-carrier.patch +++ /dev/null @@ -1,34 +0,0 @@ -Decouple carrier state from attach/detach. Also, clear carrier when tap is -first created. The idea is to let switchd attach and later set carrier -based on HW link state. If switchd dies, tap interface retains last-known -carrier state. When switchd is back up, it can adjust carrier accordingly. - -diff --git a/drivers/net/tun.c b/drivers/net/tun.c -index 8ac0b56..f895245 100644 ---- a/drivers/net/tun.c -+++ b/drivers/net/tun.c -@@ -175,7 +175,6 @@ static int tun_attach(struct tun_struct *tun, struct file *file) - tfile->tun = tun; - tun->tfile = tfile; - tun->socket.file = file; -- netif_carrier_on(tun->dev); - dev_hold(tun->dev); - sock_hold(tun->socket.sk); - atomic_inc(&tfile->count); -@@ -189,7 +188,6 @@ static void __tun_detach(struct tun_struct *tun) - { - /* Detach from net device */ - netif_tx_lock_bh(tun->dev); -- netif_carrier_off(tun->dev); - tun->tfile = NULL; - tun->socket.file = NULL; - netif_tx_unlock_bh(tun->dev); -@@ -1156,6 +1154,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) - err = tun_attach(tun, file); - if (err < 0) - goto failed; -+ -+ netif_carrier_off(tun->dev); - } - - tun_debug(KERN_INFO, tun, "tun_set_iff\n"); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virt-ethtool.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virt-ethtool.patch deleted file mode 100644 index b5205893..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virt-ethtool.patch +++ /dev/null @@ -1,703 +0,0 @@ -temp - -diff --git a/drivers/net/tun.c b/drivers/net/tun.c -index adc6269..078c36c 100644 ---- a/drivers/net/tun.c -+++ b/drivers/net/tun.c -@@ -350,6 +350,9 @@ static void tun_net_uninit(struct net_device *dev) - struct tun_struct *tun = netdev_priv(dev); - struct tun_file *tfile = tun->tfile; - -+ void port_uninit_ethtool_stats(struct net_device *dev); -+ port_uninit_ethtool_stats(dev); -+ - /* Inform the methods they need to stop using the dev. - */ - if (tfile) { -@@ -473,6 +476,9 @@ static u32 tun_net_fix_features(struct net_device *dev, u32 features) - { - struct tun_struct *tun = netdev_priv(dev); - -+ void port_init_ethtool_stats(struct net_device *dev); -+ port_init_ethtool_stats(dev); -+ - return (features & tun->set_features) | (features & ~TUN_USER_FEATURES); - } - #ifdef CONFIG_NET_POLL_CONTROLLER -diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c -index d4ce65e..0b7c26f 100644 ---- a/drivers/net/vxlan.c -+++ b/drivers/net/vxlan.c -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - - #define VXLAN_VERSION "0.1" - -@@ -963,6 +964,11 @@ static int vxlan_init(struct net_device *dev) - return 0; - } - -+static int vxlan_uninit(struct net_device *dev) -+{ -+ port_uninit_ethtool_stats(dev); -+} -+ - /* Start ageing timer and join group when device is brought up */ - static int vxlan_open(struct net_device *dev) - { -@@ -1013,6 +1019,26 @@ static int vxlan_stop(struct net_device *dev) - return 0; - } - -+static void vxlan_dev_get_hw_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats, int count) -+{ -+ u64 *hw_stats; -+ struct ethtool_stats estats = { 0, }; -+ -+ hw_stats = kmalloc(count * sizeof(u64), GFP_ATOMIC); -+ if (!hw_stats) -+ return; -+ -+ estats.n_stats = count; -+ port_get_ethtool_stats(dev, &estats, hw_stats); -+ -+ stats->rx_bytes = hw_stats[0]; -+ stats->rx_packets = hw_stats[1]; -+ stats->tx_bytes = hw_stats[2]; -+ stats->tx_packets = hw_stats[3]; -+ kfree(hw_stats); -+} -+ - /* Merge per-cpu statistics */ - static struct rtnl_link_stats64 *vxlan_stats64(struct net_device *dev, - struct rtnl_link_stats64 *stats) -@@ -1020,6 +1046,11 @@ static struct rtnl_link_stats64 *vxlan_stats64(struct net_device *dev, - struct vxlan_dev *vxlan = netdev_priv(dev); - struct vxlan_stats tmp, sum = { 0 }; - unsigned int cpu; -+ int count; -+ -+ count = port_get_sset_count(dev, ETH_SS_STATS); -+ if (count > 0) -+ vxlan_dev_get_hw_stats64(dev, stats, count); - - for_each_possible_cpu(cpu) { - unsigned int start; -@@ -1033,14 +1064,10 @@ static struct rtnl_link_stats64 *vxlan_stats64(struct net_device *dev, - - sum.tx_bytes += tmp.tx_bytes; - sum.tx_packets += tmp.tx_packets; -- sum.rx_bytes += tmp.rx_bytes; -- sum.rx_packets += tmp.rx_packets; - } - -- stats->tx_bytes = sum.tx_bytes; -- stats->tx_packets = sum.tx_packets; -- stats->rx_bytes = sum.rx_bytes; -- stats->rx_packets = sum.rx_packets; -+ stats->tx_bytes += sum.tx_bytes; -+ stats->tx_packets += sum.tx_packets; - - stats->multicast = dev->stats.multicast; - stats->rx_length_errors = dev->stats.rx_length_errors; -@@ -1063,6 +1090,7 @@ static void vxlan_set_multicast_list(struct net_device *dev) - - static const struct net_device_ops vxlan_netdev_ops = { - .ndo_init = vxlan_init, -+ .ndo_uninit = vxlan_uninit, - .ndo_open = vxlan_open, - .ndo_stop = vxlan_stop, - .ndo_start_xmit = vxlan_xmit, -@@ -1267,8 +1295,10 @@ static int vxlan_newlink(struct net *net, struct net_device *dev, - vxlan->repl_type = VXLAN_REPLICATION_NONE; - - err = register_netdevice(dev); -- if (!err) -+ if (!err) { - hlist_add_head_rcu(&vxlan->hlist, vni_head(net, vxlan->vni)); -+ port_init_ethtool_stats(dev); -+ } - - return err; - } -diff --git a/include/linux/port.h b/include/linux/port.h -index 4e1c783..fb01a28 100644 ---- a/include/linux/port.h -+++ b/include/linux/port.h -@@ -54,6 +54,8 @@ enum { - - #define PORT_ATTR_FLAG_STAT_RESTART (1 << 0) - -+void port_init_ethtool_stats(struct net_device *dev); -+void port_uninit_ethtool_stats(struct net_device *dev); - int port_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); - int port_set_settings(struct net_device *dev, struct ethtool_cmd *cmd); - void port_get_pauseparam(struct net_device *dev, -diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c -index 8bb4aa3..91c9248 100644 ---- a/net/8021q/vlan_dev.c -+++ b/net/8021q/vlan_dev.c -@@ -34,6 +34,7 @@ - #include "vlanproc.h" - #include - #include -+#include - - /* - * Rebuild the Ethernet MAC header. This is called after an ARP -@@ -632,6 +633,8 @@ static void vlan_dev_uninit(struct net_device *dev) - struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - int i; - -+ port_uninit_ethtool_stats(dev); -+ - free_percpu(vlan->vlan_pcpu_stats); - vlan->vlan_pcpu_stats = NULL; - for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) { -@@ -648,6 +651,8 @@ static netdev_features_t vlan_dev_fix_features(struct net_device *dev, - struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; - netdev_features_t old_features = features; - -+ port_init_ethtool_stats(dev); -+ - features &= real_dev->vlan_features; - features |= NETIF_F_RXCSUM; - features &= real_dev->features; -@@ -674,8 +679,33 @@ static void vlan_ethtool_get_drvinfo(struct net_device *dev, - strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); - } - -+static void vlan_dev_get_hw_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats, int count) -+{ -+ u64 *hw_stats; -+ struct ethtool_stats estats = { 0, }; -+ -+ hw_stats = kmalloc(count * sizeof(u64), GFP_ATOMIC); -+ if (!hw_stats) -+ return; -+ -+ estats.n_stats = count; -+ port_get_ethtool_stats(dev, &estats, hw_stats); -+ -+ stats->rx_bytes = hw_stats[0]; -+ stats->rx_packets = hw_stats[1]; -+ stats->tx_bytes = hw_stats[2]; -+ stats->tx_packets = hw_stats[3]; -+ kfree(hw_stats); -+} -+ - static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { -+ int count; -+ -+ count = port_get_sset_count(dev, ETH_SS_STATS); -+ if (count > 0) -+ vlan_dev_get_hw_stats64(dev, stats, count); - - if (vlan_dev_priv(dev)->vlan_pcpu_stats) { - struct vlan_pcpu_stats *p; -@@ -683,22 +713,16 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st - int i; - - for_each_possible_cpu(i) { -- u64 rxpackets, rxbytes, rxmulticast, txpackets, txbytes; -+ u64 txpackets, txbytes; - unsigned int start; - - p = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i); - do { - start = u64_stats_fetch_begin_bh(&p->syncp); -- rxpackets = p->rx_packets; -- rxbytes = p->rx_bytes; -- rxmulticast = p->rx_multicast; - txpackets = p->tx_packets; - txbytes = p->tx_bytes; - } while (u64_stats_fetch_retry_bh(&p->syncp, start)); - -- stats->rx_packets += rxpackets; -- stats->rx_bytes += rxbytes; -- stats->multicast += rxmulticast; - stats->tx_packets += txpackets; - stats->tx_bytes += txbytes; - /* rx_errors & tx_dropped are u32 */ -@@ -708,6 +732,7 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st - stats->rx_errors = rx_errors; - stats->tx_dropped = tx_dropped; - } -+ - return stats; - } - -diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c -index 88d6172..0f3b071 100644 ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - - #include - #include "br_private.h" -@@ -104,6 +105,11 @@ static int br_dev_init(struct net_device *dev) - return 0; - } - -+static void br_dev_uninit(struct net_device *dev) -+{ -+ port_uninit_ethtool_stats(dev); -+} -+ - static int br_dev_open(struct net_device *dev) - { - struct net_bridge *br = netdev_priv(dev); -@@ -132,12 +138,37 @@ static int br_dev_stop(struct net_device *dev) - return 0; - } - -+static void br_get_hw_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats, int count) -+{ -+ u64 *hw_stats; -+ struct ethtool_stats estats = { 0, }; -+ -+ hw_stats = kmalloc(count * sizeof(u64), GFP_ATOMIC); -+ if (!hw_stats) -+ return; -+ -+ estats.n_stats = count; -+ port_get_ethtool_stats(dev, &estats, hw_stats); -+ -+ stats->rx_bytes = hw_stats[0]; -+ stats->rx_packets = hw_stats[1]; -+ stats->tx_bytes = hw_stats[2]; -+ stats->tx_packets = hw_stats[3]; -+ kfree(hw_stats); -+} -+ - static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *stats) - { - struct net_bridge *br = netdev_priv(dev); - struct pcpu_sw_netstats tmp, sum = { 0 }; - unsigned int cpu; -+ int count; -+ -+ count = port_get_sset_count(dev, ETH_SS_STATS); -+ if (count > 0) -+ br_get_hw_stats64(dev, stats, count); - - for_each_possible_cpu(cpu) { - unsigned int start; -@@ -153,10 +184,16 @@ static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev, - sum.rx_packets += tmp.rx_packets; - } - -- stats->tx_bytes = sum.tx_bytes; -- stats->tx_packets = sum.tx_packets; -- stats->rx_bytes = sum.rx_bytes; -- stats->rx_packets = sum.rx_packets; -+ if (count > 0) { -+ /* stats has hw_stats - add in cpu originated tx traffic */ -+ stats->tx_bytes += sum.tx_bytes; -+ stats->tx_packets += sum.tx_packets; -+ } else { -+ stats->tx_bytes = sum.tx_bytes; -+ stats->tx_packets = sum.tx_packets; -+ stats->rx_bytes = sum.rx_bytes; -+ stats->rx_packets = sum.rx_packets; -+ } - - return stats; - } -@@ -226,6 +263,8 @@ static netdev_features_t br_fix_features(struct net_device *dev, - { - struct net_bridge *br = netdev_priv(dev); - -+ port_init_ethtool_stats(dev); -+ - return br_features_recompute(br, features); - } - -@@ -330,6 +369,7 @@ static const struct net_device_ops br_netdev_ops = { - .ndo_open = br_dev_open, - .ndo_stop = br_dev_stop, - .ndo_init = br_dev_init, -+ .ndo_uninit = br_dev_uninit, - .ndo_start_xmit = br_dev_xmit, - .ndo_get_stats64 = br_get_stats64, - .ndo_set_mac_address = br_set_mac_address, -diff --git a/net/core/port.c b/net/core/port.c -index 74f35f8..b829228 100644 ---- a/net/core/port.c -+++ b/net/core/port.c -@@ -34,7 +34,6 @@ static DEFINE_SPINLOCK(port_cache_lock); - - struct port_node { - struct hlist_node hash_node; -- spinlock_t lock; - int ifindex; - struct ethtool_cmd settings; - int settings_valid; -@@ -44,61 +43,103 @@ struct port_node { - u8 *stat_strings; - }; - -+/* must be invoked with rcu_read_lock or port_cache_lock */ - static inline struct port_node *__port_cache_get(int ifindex) - { - struct port_node *port; - struct hlist_node *n; -- unsigned long flags; - -- rcu_read_lock(); - hash_for_each_possible_rcu(port_cache, port, n, hash_node, ifindex) - if (port->ifindex == ifindex) { -- rcu_read_unlock(); -- /* This works because ports aren't -- deleted from cache */ - return port; - } -- rcu_read_unlock(); -+ -+ return NULL; -+} -+ -+static void __port_cache_init(int ifindex) -+{ -+ struct port_node *port; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&port_cache_lock, flags); -+ port = __port_cache_get(ifindex); -+ if (port) { -+ spin_unlock_irqrestore(&port_cache_lock, flags); -+ return; -+ } - - port = kzalloc(sizeof(*port), GFP_KERNEL); -- if (!port) -- return NULL; -+ if (!port) { -+ spin_unlock_irqrestore(&port_cache_lock, flags); -+ return; -+ } - - port->ifindex = ifindex; -- spin_lock_init(&port->lock); - -- spin_lock_irqsave(&port_cache_lock, flags); - hash_add_rcu(port_cache, &port->hash_node, ifindex); - spin_unlock_irqrestore(&port_cache_lock, flags); - synchronize_rcu(); -+} - -- return port; -+static void __port_cache_uninit(int ifindex) -+{ -+ struct port_node *port; -+ unsigned long flags; -+ u64 *stat_data = NULL; -+ u64 *stat_data_old = NULL; -+ u8 *stat_strings = NULL; -+ -+ spin_lock_irqsave(&port_cache_lock, flags); -+ port = __port_cache_get(ifindex); -+ if (!port) { -+ spin_unlock_irqrestore(&port_cache_lock, flags); -+ return; -+ } -+ -+ stat_data = port->stat_data; -+ stat_data_old = port->stat_data_old; -+ stat_strings = port->stat_strings; -+ hash_del_rcu(&port->hash_node); -+ spin_unlock_irqrestore(&port_cache_lock, flags); -+ synchronize_rcu(); -+ -+ kfree(stat_data); -+ kfree(stat_data_old); -+ kfree(stat_strings); -+ kfree(port); - } - - static int port_cache_get_sset_count(int ifindex, int sset) - { - struct port_node *port; -+ int count = 0; - - if (sset < ETH_SS_TEST || sset > ETH_SS_FEATURES) - return -EINVAL; - -+ rcu_read_lock(); - port = __port_cache_get(ifindex); -- if (!port) -- return 0; -+ if (port) -+ count = port->sset_count[sset]; -+ rcu_read_unlock(); - -- return port->sset_count[sset]; -+ return count; - } - - static void port_cache_set_sset_count(int ifindex, int sset, int count) - { - struct port_node *port; -+ unsigned long flags; - - if (sset < ETH_SS_TEST || sset > ETH_SS_FEATURES) - return; - -+ spin_lock_irqsave(&port_cache_lock, flags); - port = __port_cache_get(ifindex); - if (port) - port->sset_count[sset] = count; -+ spin_unlock_irqrestore(&port_cache_lock, flags); - } - - static int port_cache_get_stat_strings(int ifindex, int count, u8 *strings) -@@ -109,15 +150,14 @@ static int port_cache_get_stat_strings(int ifindex, int count, u8 *strings) - - memset(strings, 0, count * ETH_GSTRING_LEN); - -- port = __port_cache_get(ifindex); -- if (!port) -- return -ENODATA; -- - rcu_read_lock(); -- stat_strings = rcu_dereference(port->stat_strings); -- if (stat_strings) { -- memcpy(strings, stat_strings, count * ETH_GSTRING_LEN); -- err = 0; -+ port = __port_cache_get(ifindex); -+ if (port) { -+ stat_strings = rcu_dereference(port->stat_strings); -+ if (stat_strings) { -+ memcpy(strings, stat_strings, count * ETH_GSTRING_LEN); -+ err = 0; -+ } - } - rcu_read_unlock(); - -@@ -130,20 +170,24 @@ static void port_cache_set_stat_strings(int ifindex, int count, u8 *strings) - u8 *old_strings, *new_strings; - unsigned long flags; - -+ spin_lock_irqsave(&port_cache_lock, flags); - port = __port_cache_get(ifindex); -- if (!port) -+ if (!port) { -+ spin_unlock_irqrestore(&port_cache_lock, flags); - return; -+ } - - new_strings = kmalloc(count * ETH_GSTRING_LEN, GFP_KERNEL); -- if (!new_strings) -+ if (!new_strings) { -+ spin_unlock_irqrestore(&port_cache_lock, flags); - return; -+ } - - memcpy(new_strings, strings, count * ETH_GSTRING_LEN); - -- spin_lock_irqsave(&port->lock, flags); - old_strings = port->stat_strings; - rcu_assign_pointer(port->stat_strings, new_strings); -- spin_unlock_irqrestore(&port->lock, flags); -+ spin_unlock_irqrestore(&port_cache_lock, flags); - synchronize_rcu(); - - kfree(old_strings); -@@ -155,21 +199,22 @@ static void port_cache_clear_stats(int ifindex, int count) - unsigned long flags; - int i; - -+ spin_lock_irqsave(&port_cache_lock, flags); - port = __port_cache_get(ifindex); -- if (!port) -+ if (!port) { -+ spin_unlock_irqrestore(&port_cache_lock, flags); - return; -- -- spin_lock_irqsave(&port->lock, flags); -+ } - if (port->stat_data) { - if (!port->stat_data_old) - rcu_assign_pointer(port->stat_data_old, - kzalloc(count * sizeof(u64), - GFP_ATOMIC)); - if (port->stat_data_old) -- for (i = 0; i < count; i ++) -+ for (i = 0; i < count; i++) - port->stat_data_old[i] = -port->stat_data[i]; - } -- spin_unlock_irqrestore(&port->lock, flags); -+ spin_unlock_irqrestore(&port_cache_lock, flags); - synchronize_rcu(); - } - -@@ -181,23 +226,20 @@ static void port_cache_get_stats(int ifindex, struct ethtool_stats *stats, - u64 *stat_data, *stat_data_old; - int i; - -- port = __port_cache_get(ifindex); -- if (!port) -- return; -- - rcu_read_lock(); -+ port = __port_cache_get(ifindex); -+ if (port) { -+ stat_data = rcu_dereference(port->stat_data); -+ stat_data_old = rcu_dereference(port->stat_data_old); - -- stat_data = rcu_dereference(port->stat_data); -- stat_data_old = rcu_dereference(port->stat_data_old); -- -- if (stat_data) -- memcpy(data, stat_data, count * sizeof(u64)); -- -- /* add in any earlier stats saved in snapshot */ -- if (stat_data_old) -- for (i = 0; i < count; i++) -- data[i] += stat_data_old[i]; -+ if (stat_data) -+ memcpy(data, stat_data, count * sizeof(u64)); - -+ /* add in any earlier stats saved in snapshot */ -+ if (stat_data_old) -+ for (i = 0; i < count; i++) -+ data[i] += stat_data_old[i]; -+ } - rcu_read_unlock(); - - /* if requested, clear stats */ -@@ -211,31 +253,30 @@ static void port_cache_set_stats(int ifindex, int count, u64* data, int restart) - unsigned long flags; - int i; - -+ spin_lock_irqsave(&port_cache_lock, flags); - port = __port_cache_get(ifindex); -- if (!port) -+ if (!port) { -+ spin_unlock_irqrestore(&port_cache_lock, flags); - return; -- -- spin_lock_irqsave(&port->lock, flags); -+ } - - /* if restarting, take snapshot of stats */ - if (restart && port->stat_data) { - if (!port->stat_data_old) - rcu_assign_pointer(port->stat_data_old, -- kzalloc(count * sizeof(u64), -- GFP_ATOMIC)); -+ kzalloc(count * sizeof(u64), -+ GFP_ATOMIC)); - if (port->stat_data_old) -- for (i = 0; i < count; i ++) -+ for (i = 0; i < count; i++) - port->stat_data_old[i] += port->stat_data[i]; - } - - if (!port->stat_data) - rcu_assign_pointer(port->stat_data, -- kmalloc(count * sizeof(u64), -- GFP_ATOMIC)); -+ kmalloc(count * sizeof(u64), GFP_ATOMIC)); - if (port->stat_data) - memcpy(port->stat_data, data, count * sizeof(u64)); -- -- spin_unlock_irqrestore(&port->lock, flags); -+ spin_unlock_irqrestore(&port_cache_lock, flags); - synchronize_rcu(); - } - -@@ -244,30 +285,31 @@ static void port_cache_clear_settings(int ifindex) - struct port_node *port; - unsigned long flags; - -+ spin_lock_irqsave(&port_cache_lock, flags); - port = __port_cache_get(ifindex); -- if (!port) -+ if (!port) { -+ spin_unlock_irqrestore(&port_cache_lock, flags); - return; -+ } - -- spin_lock_irqsave(&port->lock, flags); - memset(&port->settings, 0, sizeof(port->settings)); - port->settings_valid = 0; -- spin_unlock_irqrestore(&port->lock, flags); -+ spin_unlock_irqrestore(&port_cache_lock, flags); - synchronize_rcu(); - } - - static int port_cache_get_settings(int ifindex, struct ethtool_cmd *cmd) - { - struct port_node *port; -- int valid; -- -- port = __port_cache_get(ifindex); -- if (!port) -- return -ENODATA; -+ int valid = 0; - - rcu_read_lock(); -- valid = port->settings_valid; -- if (valid) -- memcpy(cmd, &port->settings, sizeof(*cmd)); -+ port = __port_cache_get(ifindex); -+ if (port) { -+ valid = port->settings_valid; -+ if (valid) -+ memcpy(cmd, &port->settings, sizeof(*cmd)); -+ } - rcu_read_unlock(); - - return valid ? 0 : -ENODATA; -@@ -278,14 +320,16 @@ static void port_cache_set_settings(int ifindex, struct ethtool_cmd *cmd) - struct port_node *port; - unsigned long flags; - -+ spin_lock_irqsave(&port_cache_lock, flags); - port = __port_cache_get(ifindex); -- if (!port) -+ if (!port) { -+ spin_unlock_irqrestore(&port_cache_lock, flags); - return; -+ } - -- spin_lock_irqsave(&port->lock, flags); - memcpy(&port->settings, cmd, sizeof(*cmd)); - port->settings_valid = 1; -- spin_unlock_irqrestore(&port->lock, flags); -+ spin_unlock_irqrestore(&port_cache_lock, flags); - synchronize_rcu(); - } - -@@ -639,6 +683,18 @@ static int decode_struct(struct nlattr *attr, size_t size, void *dst) - - } - -+void port_init_ethtool_stats(struct net_device *dev) -+{ -+ __port_cache_init(dev->ifindex); -+} -+EXPORT_SYMBOL_GPL(port_init_ethtool_stats); -+ -+void port_uninit_ethtool_stats(struct net_device *dev) -+{ -+ __port_cache_uninit(dev->ifindex); -+} -+EXPORT_SYMBOL_GPL(port_uninit_ethtool_stats); -+ - int port_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) - { - int err, size = 0, wait = 20; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virtio-net-ethtool-set-settings.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virtio-net-ethtool-set-settings.patch deleted file mode 100644 index 00279695..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virtio-net-ethtool-set-settings.patch +++ /dev/null @@ -1,104 +0,0 @@ -Add support for ethtool set settings in virtio-net driver. - -Details in the bug: -https://tickets.cumulusnetworks.com/browse/CA-268 - -XXX: This is a hack and temporary arrangement. The upstream driver -does not support set settings. We have to do this to make -VM's in our sim environment work with 1G and 10G hardnodes. - -More details on the ssim problem: -"In clag test where a vci node (A) has a bond with 2 slaves, one slave -connected to a 1G hard node (B), and one slave connected to another vci -node (C), node A will see different peer port speeds as reported by LACP -exchange with B and C. This mismatch causes the bond on A to never be -able to have both slaves in active state. - -In normal bond test, multiple ports connect the same two nodes, so all LACP -sessions between them report consistent port speeds, and all slaves can join -the same aggregator and be active. - -Also, currently automation tests only support 1 hard node. This limits -the clag tests to 10G boxes." - - -Open Issue: The default speed settings is being changed by one of our internal -patches. The right thing to do is to keep the default as SPEED_10 (upstream default) -and make the sim change it to 10G and 1G as required. But that is going to -break existing sim tests. So, moving that to later. - -diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c -index 689ce1c..9238fac 100644 ---- a/drivers/net/virtio_net.c -+++ b/drivers/net/virtio_net.c -@@ -77,6 +77,11 @@ struct virtnet_info { - /* fragments + linear part + virtio header */ - struct scatterlist rx_sg[MAX_SKB_FRAGS + 2]; - struct scatterlist tx_sg[MAX_SKB_FRAGS + 2]; -+ -+ /* ethtool settings */ -+ __u32 speed; -+ __u8 duplex; -+ __u8 autoneg; - }; - - struct skb_vnet_hdr { -@@ -881,8 +886,27 @@ static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) - static int virtnet_get_settings(struct net_device *dev, - struct ethtool_cmd *ecmd) - { -- ethtool_cmd_speed_set(ecmd, SPEED_10000); -- ecmd->duplex = DUPLEX_FULL; -+ struct virtnet_info *vi = netdev_priv(dev); -+ -+ ethtool_cmd_speed_set(ecmd, vi->speed); -+ ecmd->duplex = vi->duplex; -+ ecmd->autoneg = vi->autoneg; -+ -+ return 0; -+} -+ -+static int virtnet_set_settings(struct net_device *dev, -+ struct ethtool_cmd *ecmd) -+{ -+ struct virtnet_info *vi = netdev_priv(dev); -+ int speed = ethtool_cmd_speed(ecmd); -+ -+ if (speed < SPEED_10 || speed > SPEED_10000) -+ return -EINVAL; -+ -+ vi->speed = speed; -+ vi->duplex = ecmd->duplex; -+ vi->autoneg = ecmd->autoneg; - - return 0; - } -@@ -899,8 +923,19 @@ static void virtnet_get_ringparam(struct net_device *dev, - - } - -+static void virtnet_init_settings(struct net_device *dev) -+{ -+ struct virtnet_info *vi = netdev_priv(dev); -+ -+ /* XXX: Set init speed to SPEED_10 the default virtio net speed; */ -+ vi->speed = SPEED_10000; -+ vi->duplex = DUPLEX_FULL; -+ vi->autoneg = 0; -+} -+ - static const struct ethtool_ops virtnet_ethtool_ops = { - .get_settings = virtnet_get_settings, -+ .set_settings = virtnet_set_settings, - .get_link = ethtool_op_get_link, - .get_ringparam = virtnet_get_ringparam, - }; -@@ -1064,6 +1099,8 @@ static int virtnet_probe(struct virtio_device *vdev) - dev->features |= NETIF_F_HW_VLAN_FILTER; - } - -+ virtnet_init_settings(dev); -+ - err = register_netdev(dev); - if (err) { - pr_debug("virtio_net: registering device failed\n"); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virtio-net-speed-duplex.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virtio-net-speed-duplex.patch deleted file mode 100644 index a63b9501..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virtio-net-speed-duplex.patch +++ /dev/null @@ -1,32 +0,0 @@ -Give virtio_net driver (used in VCI) ethtool support for speed/duplex -so bonding driver can get slave interface speed/duplex when configuring -bond. (Required for bonding mode 802.3ad). - -diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c -index f13a673..689ce1c 100644 ---- a/drivers/net/virtio_net.c -+++ b/drivers/net/virtio_net.c -@@ -878,6 +878,15 @@ static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) - dev_warn(&dev->dev, "Failed to kill VLAN ID %d.\n", vid); - } - -+static int virtnet_get_settings(struct net_device *dev, -+ struct ethtool_cmd *ecmd) -+{ -+ ethtool_cmd_speed_set(ecmd, SPEED_10000); -+ ecmd->duplex = DUPLEX_FULL; -+ -+ return 0; -+} -+ - static void virtnet_get_ringparam(struct net_device *dev, - struct ethtool_ringparam *ring) - { -@@ -891,6 +900,7 @@ static void virtnet_get_ringparam(struct net_device *dev, - } - - static const struct ethtool_ops virtnet_ethtool_ops = { -+ .get_settings = virtnet_get_settings, - .get_link = ethtool_op_get_link, - .get_ringparam = virtnet_get_ringparam, - }; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virtio-proto-down.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virtio-proto-down.patch deleted file mode 100644 index 415225e2..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-virtio-proto-down.patch +++ /dev/null @@ -1,96 +0,0 @@ -This is a hack to make the softnode look like the hardnode in its handling of -proto_down i.e. on proto_down notification the carrier setting is cleared. - -Also see network-core-proto-down.patch for details on the proto_down. - -diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c -index 9238fac..da384f7 100644 ---- a/drivers/net/virtio_net.c -+++ b/drivers/net/virtio_net.c -@@ -985,8 +985,10 @@ static void virtnet_update_status(struct virtnet_info *vi) - vi->status = v; - - if (vi->status & VIRTIO_NET_S_LINK_UP) { -- netif_carrier_on(vi->dev); -- netif_wake_queue(vi->dev); -+ if (!(vi->dev->flags & IFF_PROTO_DOWN)) { -+ netif_carrier_on(vi->dev); -+ netif_wake_queue(vi->dev); -+ } - } else { - netif_carrier_off(vi->dev); - netif_stop_queue(vi->dev); -@@ -1123,7 +1125,8 @@ static int virtnet_probe(struct virtio_device *vdev) - virtnet_update_status(vi); - } else { - vi->status = VIRTIO_NET_S_LINK_UP; -- netif_carrier_on(dev); -+ if (!(dev->flags & IFF_PROTO_DOWN)) -+ netif_carrier_on(dev); - } - - pr_debug("virtnet: registered device %s\n", dev->name); -@@ -1212,13 +1215,62 @@ static struct virtio_driver virtio_net_driver = { - .config_changed = virtnet_config_changed, - }; - -+/* virtio_netdev_event: handle netdev notifier chain events. */ -+static int virtio_netdev_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ struct net_device *dev = (struct net_device *)ptr; -+ struct virtnet_info *vi; -+ -+ if (dev->netdev_ops != &virtnet_netdev) -+ return NOTIFY_DONE; -+ -+ vi = netdev_priv(dev); -+ -+ switch (event) { -+ case NETDEV_CHANGE: -+ /* check if carrier state needs to be updated based -+ * on the proto_down state */ -+ if (vi->status & VIRTIO_NET_S_LINK_UP) { -+ if (dev->flags & IFF_PROTO_DOWN) { -+ if (netif_carrier_ok(dev)) { -+ netif_carrier_off(dev); -+ } -+ } else { -+ if (!netif_carrier_ok(dev)) { -+ netif_carrier_on(dev); -+ netif_wake_queue(dev); -+ } -+ } -+ } -+ default: -+ break; -+ } -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block virtio_netdev_notifier = { -+ .notifier_call = virtio_netdev_event, -+}; -+ - static int __init init(void) - { -- return register_virtio_driver(&virtio_net_driver); -+ int ret; -+ -+ ret = register_virtio_driver(&virtio_net_driver); -+ if (ret) -+ goto err_misc; -+ -+ register_netdevice_notifier(&virtio_netdev_notifier); -+ -+err_misc: -+ return ret; - } - - static void __exit fini(void) - { -+ unregister_netdevice_notifier(&virtio_netdev_notifier); - unregister_virtio_driver(&virtio_net_driver); - } - module_init(init); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vlan-sysctl-tune.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vlan-sysctl-tune.patch deleted file mode 100644 index d6136d1b..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vlan-sysctl-tune.patch +++ /dev/null @@ -1,35 +0,0 @@ -Tune out the sysctl entries for large vlan count - -diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c -index 963f285..66cb2ef 100644 ---- a/net/8021q/vlan.c -+++ b/net/8021q/vlan.c -@@ -188,6 +188,8 @@ int register_vlan_dev(struct net_device *dev) - if (err < 0) - goto out_uninit_applicant; - -+ dev->vlan_features |= NETIF_F_HIGHDMA; -+ - err = register_netdevice(dev); - if (err < 0) - goto out_uninit_applicant; -diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c -index f9e6a35..dc49a02 100644 ---- a/net/ipv4/devinet.c -+++ b/net/ipv4/devinet.c -@@ -1720,9 +1720,12 @@ static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf) - - static void devinet_sysctl_register(struct in_device *idev) - { -- neigh_sysctl_register(idev->dev, idev->arp_parms, "ipv4", NULL); -- __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name, -- &idev->cnf); -+ -+ if (!(idev->dev->vlan_features & NETIF_F_HIGHDMA)) { -+ neigh_sysctl_register(idev->dev, idev->arp_parms, "ipv4", NULL); -+ __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name, -+ &idev->cnf); -+ } - } - - static void devinet_sysctl_unregister(struct in_device *idev) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fdb-update-hardware-forwarding.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fdb-update-hardware-forwarding.patch deleted file mode 100644 index a2bf3848..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fdb-update-hardware-forwarding.patch +++ /dev/null @@ -1,21 +0,0 @@ -In case of hardware forwarding with aging in kernel, update fdb "used" on receiving rtnl message for hit bit update in the hardware. - -diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c -index b89901c..85dfad8 100644 ---- a/drivers/net/vxlan.c -+++ b/drivers/net/vxlan.c -@@ -283,6 +283,14 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, - static int vxlan_fdb_replace(struct vxlan_fdb *f, __be32 ip) - { - f->remote_ip = ip; -+ /* In case of hardware forwarding with aging in kernel, update -+ * fdb when the corresponding entry in hardware gets used. As -+ * there is no flag to identify hardware or software forwarding, -+ * this has the side effect of updating "used" in software forwarding -+ * as well if there is any change in the entry. Also, update happens -+ * for mac move from one remote node to another. -+ */ -+ f->used = jiffies; - return 1; - } - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fdb-update-used.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fdb-update-used.patch deleted file mode 100644 index 457f3ad5..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fdb-update-used.patch +++ /dev/null @@ -1,52 +0,0 @@ -[ Upstream commit 014be2c8eac3381e202f684c1f35ae184a8b152b ] -[PATCH 067/105] vxlan: Update vxlan fdb 'used' field after each usage - -diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c -index 0b7c26f..b89901c 100644 ---- a/drivers/net/vxlan.c -+++ b/drivers/net/vxlan.c -@@ -251,7 +251,7 @@ static inline struct hlist_head *vxlan_fdb_head(struct vxlan_dev *vxlan, - } - - /* Look up Ethernet address in forwarding table */ --static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, -+static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan, - const u8 *mac) - - { -@@ -267,6 +267,18 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, - return NULL; - } - -+static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, -+ const u8 *mac) -+{ -+ struct vxlan_fdb *f; -+ -+ f = __vxlan_find_mac(vxlan, mac); -+ if (f) -+ f->used = jiffies; -+ -+ return f; -+} -+ - /* Replace destination of unicast mac */ - static int vxlan_fdb_replace(struct vxlan_fdb *f, __be32 ip) - { -@@ -282,7 +294,7 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan, - struct vxlan_fdb *f; - int notify = 0; - -- f = vxlan_find_mac(vxlan, mac); -+ f = __vxlan_find_mac(vxlan, mac); - if (f) { - if (flags & NLM_F_EXCL) { - netdev_dbg(vxlan->dev, -@@ -444,7 +456,6 @@ static void vxlan_snoop(struct net_device *dev, - - f = vxlan_find_mac(vxlan, src_mac); - if (likely(f)) { -- f->used = jiffies; - if (likely(f->remote_ip == src_ip)) - return; - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fix-fdb-update.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fix-fdb-update.patch deleted file mode 100644 index 8ff9193e..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fix-fdb-update.patch +++ /dev/null @@ -1,49 +0,0 @@ -VXLAN driver should enforce the fdb state correctly when deciding -to add or update an existing fdb. Static fdb should not be replaced -by dynamic fdb. - -diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c -index 1c55aec..fc1b0d9 100644 ---- a/drivers/net/vxlan.c -+++ b/drivers/net/vxlan.c -@@ -265,6 +265,13 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, - return NULL; - } - -+/* Replace destination of unicast mac */ -+static int vxlan_fdb_replace(struct vxlan_fdb *f, __be32 ip) -+{ -+ f->remote_ip = ip; -+ return 1; -+} -+ - /* Add new entry to forwarding table -- assumes lock held */ - static int vxlan_fdb_create(struct vxlan_dev *vxlan, - const u8 *mac, __be32 ip, -@@ -281,10 +288,26 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan, - return -EEXIST; - } - if (f->state != state) { -+ if ((f->state & NUD_PERMANENT) && -+ !(state & NUD_PERMANENT)) -+ return -EINVAL; -+ - f->state = state; - f->updated = jiffies; - notify = 1; - } -+ if ((flags & NLM_F_REPLACE)) { -+ /* Only change unicasts */ -+ if (!(is_multicast_ether_addr(f->eth_addr) || -+ is_zero_ether_addr(f->eth_addr))) { -+ int rc = vxlan_fdb_replace(f, ip); -+ -+ if (rc < 0) -+ return rc; -+ notify |= rc; -+ } else -+ return -EOPNOTSUPP; -+ } - } else { - if (!(flags & NLM_F_CREATE)) - return -ENOENT; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fix-incomplete-backport.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fix-incomplete-backport.patch deleted file mode 100644 index 32a097bf..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-fix-incomplete-backport.patch +++ /dev/null @@ -1,19 +0,0 @@ -Missing change from upstream kernel commit -43598813386f6205edf3c21f1fe97f731ccb4f15 introduced by Cumulus commit -a9f6f3172cb6384dc7dec7b2aeb046e75577cb26. This patch should be removed -to complete CM-3094 and the original upstream patch should be added to -the patch stack. - -diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c -index 66a6f25..5b28ba9 100644 ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -124,7 +124,7 @@ static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) - /* called with rcu_read_lock */ - void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) - { -- if (should_deliver(to, skb)) { -+ if (to && should_deliver(to, skb)) { - __br_deliver(to, skb); - return; - } diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-ip-select-ident-parameter-iph-to-skb.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-ip-select-ident-parameter-iph-to-skb.patch deleted file mode 100644 index b0db2642..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-ip-select-ident-parameter-iph-to-skb.patch +++ /dev/null @@ -1,15 +0,0 @@ -With kernel-3.2.57, ip_select_ident first agrument changed from "struct iphdr *iph" to struct sk_buff *skb. Changing the usage in vxlan_driver to reflect the same. - -diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c -index 2fdd4e8..d4ce65e 100644 ---- a/drivers/net/vxlan.c -+++ b/drivers/net/vxlan.c -@@ -813,7 +813,7 @@ static netdev_tx_t vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, _ - - /* See __IPTUNNEL_XMIT */ - skb->ip_summed = CHECKSUM_NONE; -- ip_select_ident(iph, &rt->dst, NULL); -+ ip_select_ident(skb, &rt->dst, NULL); - - err = ip_local_out(skb); - if (likely(net_xmit_eval(err) == 0)) { diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-self-replication.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-self-replication.patch deleted file mode 100644 index 4f7dd890..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-self-replication.patch +++ /dev/null @@ -1,350 +0,0 @@ -Changes to support self replication (head end replication). - -diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c -index fc1b0d9..5c51530 100644 ---- a/drivers/net/vxlan.c -+++ b/drivers/net/vxlan.c -@@ -118,7 +118,8 @@ struct vxlan_dev { - unsigned int addrcnt; - unsigned int addrmax; - unsigned int addrexceeded; -- __u32 service_nodes[MAX_VXLAN_SERVICE_NODE_ADDRS]; -+ __u8 repl_type; -+ __u32 repl_nodes[MAX_VXLAN_REPLICATION_NODE_ADDRS]; - - struct hlist_head fdb_head[FDB_HASH_SIZE]; - }; -@@ -664,11 +665,11 @@ static __be32 vxlan_find_dst(struct vxlan_dev *vxlan, struct sk_buff *skb) - /* TBD: we should do some flow hash to spread, and also - * consider bfd status. for now just pick the first one - */ -- for (i = 0; i < MAX_VXLAN_SERVICE_NODE_ADDRS; i++) { -- if (vxlan->service_nodes[i] == 0) -+ for (i = 0; i < MAX_VXLAN_REPLICATION_NODE_ADDRS; i++) { -+ if (vxlan->repl_nodes[i] == 0) - break; - else -- return vxlan->service_nodes[i]; -+ return vxlan->repl_nodes[i]; - } - return 0; - } -@@ -677,11 +678,11 @@ static __be32 vxlan_find_dst(struct vxlan_dev *vxlan, struct sk_buff *skb) - if (f) - return f->remote_ip; - else { -- for (i = 0; i < MAX_VXLAN_SERVICE_NODE_ADDRS; i++) { -- if (vxlan->service_nodes[i] == 0) -+ for (i = 0; i < MAX_VXLAN_REPLICATION_NODE_ADDRS; i++) { -+ if (vxlan->repl_nodes[i] == 0) - break; - else -- return vxlan->service_nodes[i]; -+ return vxlan->repl_nodes[i]; - } - return vxlan->gaddr; - } -@@ -722,13 +723,7 @@ static u16 vxlan_src_port(const struct vxlan_dev *vxlan, struct sk_buff *skb) - return (((u64) hash * range) >> 32) + vxlan->port_min; - } - --/* Transmit local packets over Vxlan -- * -- * Outer IP header inherits ECN and DF from inner header. -- * Outer UDP destination is the VXLAN assigned port. -- * source port is based on hash of flow -- */ --static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) -+static netdev_tx_t vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, __be32 dst) - { - struct vxlan_dev *vxlan = netdev_priv(dev); - struct rtable *rt; -@@ -738,13 +733,11 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) - struct udphdr *uh; - struct flowi4 fl4; - unsigned int pkt_len = skb->len; -- __be32 dst; - __u16 src_port; - __be16 df = 0; - __u8 tos, ttl; - int err; - -- dst = vxlan_find_dst(vxlan, skb); - if (!dst) - goto drop; - -@@ -847,6 +840,80 @@ tx_free: - return NETDEV_TX_OK; - } - -+ -+/* Transmit local packets over Vxlan -+ * -+ * Outer IP header inherits ECN and DF from inner header. -+ * Outer UDP destination is the VXLAN assigned port. -+ * source port is based on hash of flow -+ */ -+static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ const struct ethhdr *eth = (struct ethhdr *) skb->data; -+ const struct vxlan_fdb *f; -+ struct sk_buff* nskb; -+ int i; -+ netdev_tx_t ret = NETDEV_TX_OK; -+ -+ if (is_multicast_ether_addr(eth->h_dest)) { -+ if (vxlan->gaddr) -+ return (vxlan_xmit_one(skb, dev, vxlan->gaddr)); -+ -+ if (vxlan->repl_type == VXLAN_REPLICATION_SERVICE_NODE) { -+ /* no group address defined, try service nodes */ -+ /* TBD: we should do some flow hash to spread, and also -+ * consider bfd status. for now just pick the first one -+ */ -+ return (vxlan_xmit_one(skb, dev, vxlan->repl_nodes[0])); -+ } -+ else if (vxlan->repl_type == VXLAN_REPLICATION_SELF) { -+ /* self replication so replicate packets to each of the peer nodes -+ * in the list -+ */ -+ for (i = 0; i < MAX_VXLAN_REPLICATION_NODE_ADDRS; i++) { -+ if (vxlan->repl_nodes[i] == 0) -+ break; -+ nskb = skb_clone(skb, GFP_ATOMIC); -+ ret = vxlan_xmit_one(nskb, dev, vxlan->repl_nodes[i]); -+ } -+ goto tx_free; -+ } -+ else -+ goto drop; -+ } -+ -+ f = vxlan_find_mac(vxlan, eth->h_dest); -+ if (f) -+ return (vxlan_xmit_one(skb, dev, f->remote_ip)); -+ else { -+ if (vxlan->repl_type == VXLAN_REPLICATION_SERVICE_NODE) -+ return (vxlan_xmit_one(skb, dev, vxlan->repl_nodes[0])); -+ else if (vxlan->repl_type == VXLAN_REPLICATION_SELF) { -+ /* self replication so replicate packets to each of the peer nodes -+ * in the list. If list is empty, send to gaddr -+ */ -+ for (i = 0; i < MAX_VXLAN_REPLICATION_NODE_ADDRS; i++) { -+ if (vxlan->repl_nodes[i] == 0) -+ break; -+ nskb = skb_clone(skb, GFP_ATOMIC); -+ ret = vxlan_xmit_one(nskb, dev, vxlan->repl_nodes[i]); -+ } -+ goto tx_free; -+ } -+ else { -+ /* use service node first for unknown unicast, if not xmit to gaddr */ -+ return (vxlan_xmit_one(skb, dev, vxlan->gaddr)); -+ } -+ } -+drop: -+ dev->stats.tx_dropped++; -+ -+tx_free: -+ dev_kfree_skb(skb); -+ return ret; -+} -+ - /* Walk the forwarding table and purge stale entries */ - static void vxlan_cleanup(unsigned long arg) - { -@@ -1069,7 +1136,8 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = { - [IFLA_VXLAN_AGEING] = { .type = NLA_U32 }, - [IFLA_VXLAN_LIMIT] = { .type = NLA_U32 }, - [IFLA_VXLAN_PORT_RANGE] = { .len = sizeof(struct ifla_vxlan_port_range) }, -- [IFLA_VXLAN_SERVICE_NODE] = { .len = sizeof(struct ifla_vxlan_svc_node_addrs) }, -+ [IFLA_VXLAN_REPLICATION_NODE] = { .len = sizeof(struct ifla_vxlan_repl_node_addrs) }, -+ [IFLA_VXLAN_REPLICATION_TYPE] = { .type = NLA_U8 }, - }; - - static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[]) -@@ -1113,10 +1181,18 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[]) - return -EINVAL; - } - } -+ if (data[IFLA_VXLAN_REPLICATION_TYPE]) { -+ u8 repl_type = nla_get_u8(data[IFLA_VXLAN_REPLICATION_TYPE]); -+ if ((repl_type != VXLAN_REPLICATION_SERVICE_NODE) -+ && (repl_type != VXLAN_REPLICATION_SELF)) { -+ pr_debug("replication is neither based on service node nor peer node \n"); -+ return -EINVAL; -+ } -+ } - #if 0 -- if (data[IFLA_VXLAN_SERVICE_NODE]) { -- const struct ifla_vxlan_svc_node_addrs *p -- = nla_data(data[IFLA_VXLAN_SERVICE_NODE]); -+ if (data[IFLA_VXLAN_REPLICATION_NODE]) { -+ const struct ifla_vxlan_repl_node_addrs *p -+ = nla_data(data[IFLA_VXLAN_REPLICATION_NODE]); - /* TBD: check for mcast and bcast */ - } - #endif -@@ -1181,11 +1257,14 @@ static int vxlan_newlink(struct net *net, struct net_device *dev, - vxlan->port_max = ntohs(p->high); - } - -- if (data[IFLA_VXLAN_SERVICE_NODE]) { -- const struct ifla_vxlan_svc_node_addrs *p -- = nla_data(data[IFLA_VXLAN_SERVICE_NODE]); -- memcpy(vxlan->service_nodes, p, sizeof(*p)); -+ if (data[IFLA_VXLAN_REPLICATION_TYPE] && data[IFLA_VXLAN_REPLICATION_NODE]) { -+ const struct ifla_vxlan_repl_node_addrs *p -+ = nla_data(data[IFLA_VXLAN_REPLICATION_NODE]); -+ memcpy(vxlan->repl_nodes, p, sizeof(*p)); -+ vxlan->repl_type = nla_get_u8(data[IFLA_VXLAN_REPLICATION_TYPE]); - } -+ else -+ vxlan->repl_type = VXLAN_REPLICATION_NONE; - - err = register_netdevice(dev); - if (!err) -@@ -1218,7 +1297,8 @@ static size_t vxlan_get_size(const struct net_device *dev) - nla_total_size(sizeof(__u32)) + /* IFLA_VXLAN_AGEING */ - nla_total_size(sizeof(__u32)) + /* IFLA_VXLAN_LIMIT */ - nla_total_size(sizeof(struct ifla_vxlan_port_range)) + -- nla_total_size(sizeof(struct ifla_vxlan_svc_node_addrs)) + -+ nla_total_size(sizeof(struct ifla_vxlan_repl_node_addrs)) + -+ nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_REPLICATION_TYPE */ - 0; - } - -@@ -1229,7 +1309,7 @@ static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev) - .low = htons(vxlan->port_min), - .high = htons(vxlan->port_max), - }; -- struct ifla_vxlan_svc_node_addrs svcaddrs; -+ struct ifla_vxlan_repl_node_addrs repladdrs; - - if (nla_put_u32(skb, IFLA_VXLAN_ID, vxlan->vni)) - goto nla_put_failure; -@@ -1253,9 +1333,14 @@ static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev) - if (nla_put(skb, IFLA_VXLAN_PORT_RANGE, sizeof(ports), &ports)) - goto nla_put_failure; - -- memcpy(&svcaddrs, vxlan->service_nodes, sizeof(svcaddrs)); -- if (nla_put(skb, IFLA_VXLAN_SERVICE_NODE, sizeof(svcaddrs), &svcaddrs)) -- goto nla_put_failure; -+ if ((vxlan->repl_type != VXLAN_REPLICATION_NONE) && vxlan->repl_nodes[0]) { -+ if (nla_put_u8(skb, IFLA_VXLAN_REPLICATION_TYPE, vxlan->repl_type)) -+ goto nla_put_failure; -+ -+ memcpy(&repladdrs, vxlan->repl_nodes, sizeof(repladdrs)); -+ if (nla_put(skb, IFLA_VXLAN_REPLICATION_NODE, sizeof(repladdrs), &repladdrs)) -+ goto nla_put_failure; -+ } - - return 0; - -@@ -1263,6 +1348,64 @@ nla_put_failure: - return -EMSGSIZE; - } - -+static int vxlan_changelink(struct net_device *dev, -+ struct nlattr *tb[], struct nlattr *data[]) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ -+ if (data[IFLA_VXLAN_ID] || data[IFLA_VXLAN_LINK]) { -+ pr_err("cannot change VNI or phys dev \n"); -+ return -EINVAL; -+ } -+ -+ if (data[IFLA_VXLAN_GROUP]) -+ vxlan->gaddr = nla_get_be32(data[IFLA_VXLAN_GROUP]); -+ -+ if (data[IFLA_VXLAN_LOCAL]) -+ vxlan->saddr = nla_get_be32(data[IFLA_VXLAN_LOCAL]); -+ -+ if (data[IFLA_VXLAN_TOS]) -+ vxlan->tos = nla_get_u8(data[IFLA_VXLAN_TOS]); -+ -+ if (data[IFLA_VXLAN_LEARNING]) { -+ if (nla_get_u8(data[IFLA_VXLAN_LEARNING])) -+ vxlan->learn = true; -+ else -+ vxlan->learn = false; -+ } -+ -+ if (data[IFLA_VXLAN_AGEING]) -+ vxlan->age_interval = nla_get_u32(data[IFLA_VXLAN_AGEING]); -+ -+ if (data[IFLA_VXLAN_LIMIT]) -+ vxlan->addrmax = nla_get_u32(data[IFLA_VXLAN_LIMIT]); -+ -+ if (data[IFLA_VXLAN_PORT_RANGE]) { -+ const struct ifla_vxlan_port_range *p -+ = nla_data(data[IFLA_VXLAN_PORT_RANGE]); -+ vxlan->port_min = ntohs(p->low); -+ vxlan->port_max = ntohs(p->high); -+ } -+ -+ /* semantics of peernode/svcnode missing in "ip link set" command is to remove -+ * addresses if they have been configured before -+ */ -+ if (data[IFLA_VXLAN_REPLICATION_TYPE] && data[IFLA_VXLAN_REPLICATION_NODE]) { -+ const struct ifla_vxlan_repl_node_addrs *p -+ = nla_data(data[IFLA_VXLAN_REPLICATION_NODE]); -+ memcpy(vxlan->repl_nodes, p, sizeof(*p)); -+ vxlan->repl_type = nla_get_u8(data[IFLA_VXLAN_REPLICATION_TYPE]); -+ } -+ else { -+ memset(vxlan->repl_nodes, 0, sizeof(struct ifla_vxlan_repl_node_addrs)); -+ vxlan->repl_type = VXLAN_REPLICATION_NONE; -+ } -+ -+ /* call notifier chains and send link msg */ -+ netdev_state_change(dev); -+ return 0; -+} -+ - static struct rtnl_link_ops vxlan_link_ops __read_mostly = { - .kind = "vxlan", - .maxtype = IFLA_VXLAN_MAX, -@@ -1271,6 +1414,7 @@ static struct rtnl_link_ops vxlan_link_ops __read_mostly = { - .setup = vxlan_setup, - .validate = vxlan_validate, - .newlink = vxlan_newlink, -+ .changelink = vxlan_changelink, - .dellink = vxlan_dellink, - .get_size = vxlan_get_size, - .fill_info = vxlan_fill_info, -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index 42a7c70..7097794 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -301,7 +301,8 @@ enum { - IFLA_VXLAN_AGEING, - IFLA_VXLAN_LIMIT, - IFLA_VXLAN_PORT_RANGE, -- IFLA_VXLAN_SERVICE_NODE, -+ IFLA_VXLAN_REPLICATION_NODE = 253, -+ IFLA_VXLAN_REPLICATION_TYPE, - __IFLA_VXLAN_MAX - }; - #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) -@@ -311,9 +312,15 @@ struct ifla_vxlan_port_range { - __be16 high; - }; - --#define MAX_VXLAN_SERVICE_NODE_ADDRS 16 --struct ifla_vxlan_svc_node_addrs { -- __u32 addrs[MAX_VXLAN_SERVICE_NODE_ADDRS]; -+#define MAX_VXLAN_REPLICATION_NODE_ADDRS 64 -+struct ifla_vxlan_repl_node_addrs { -+ __u32 addrs[MAX_VXLAN_REPLICATION_NODE_ADDRS]; -+}; -+ -+enum { -+ VXLAN_REPLICATION_NONE = 0, -+ VXLAN_REPLICATION_SERVICE_NODE, /* service node based replication */ -+ VXLAN_REPLICATION_SELF, /* self or head-end replication */ - }; - - /* SR-IOV virtual function management section */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-support.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-support.patch deleted file mode 100644 index 0296ae5c..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/network-vxlan-support.patch +++ /dev/null @@ -1,2426 +0,0 @@ -Added vxlan support. - -diff --git a/arch/powerpc/boot/dts/cumulus_p2020.dts b/arch/powerpc/boot/dts/cumulus_p2020.dts -index 398b11b..a14c0a5 100644 ---- a/arch/powerpc/boot/dts/cumulus_p2020.dts -+++ b/arch/powerpc/boot/dts/cumulus_p2020.dts -@@ -93,9 +93,10 @@ - compatible = "stm,m41st85"; - reg = <0x68>; - }; -- eeprom@50 { -+ board_eeprom@50 { - compatible = "at,24c08"; - reg = <0x50>; -+ label = "board_eeprom"; - }; - temp@4c { - compatible = "adi,adt7461"; -diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig -index c1384c7..4cf31dd 100644 ---- a/drivers/net/Kconfig -+++ b/drivers/net/Kconfig -@@ -152,6 +152,20 @@ config MACVTAP - To compile this driver as a module, choose M here: the module - will be called macvtap. - -+config VXLAN -+ tristate "Virtual eXtensible Local Area Network (VXLAN)" -+ depends on EXPERIMENTAL -+ ---help--- -+ This allows one to create vxlan virtual interfaces that provide -+ Layer 2 Networks over Layer 3 Networks. VXLAN is often used -+ to tunnel virtual network infrastructure in virtualized environments. -+ For more information see: -+ http://tools.ietf.org/html/draft-mahalingam-dutt-dcops-vx... -+ -+ To compile this driver as a module, choose M here: the module -+ will be called vxlan. -+ -+ - config NETCONSOLE - tristate "Network console logging support" - ---help--- -diff --git a/drivers/net/Makefile b/drivers/net/Makefile -index 435771c..3e78eeb 100644 ---- a/drivers/net/Makefile -+++ b/drivers/net/Makefile -@@ -20,6 +20,7 @@ obj-$(CONFIG_RIONET) += rionet.o - obj-$(CONFIG_TUN) += tun.o - obj-$(CONFIG_VETH) += veth.o - obj-$(CONFIG_VIRTIO_NET) += virtio_net.o -+obj-$(CONFIG_VXLAN) += vxlan.o - - # - # Networking Drivers -diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c -new file mode 100644 -index 0000000..6cb0112 ---- /dev/null -+++ b/drivers/net/vxlan.c -@@ -0,0 +1,1352 @@ -+/* -+ * VXLAN: Virtual eXtensiable Local Area Network -+ * -+ * Copyright (c) 2012 Vyatta 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. -+ * -+ * TODO -+ * - use IANA UDP port number (when defined) -+ * - IPv6 (not in RFC) -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define VXLAN_VERSION "0.1" -+ -+#define VNI_HASH_BITS 10 -+#define VNI_HASH_SIZE (1<vni_list[hash_32(id, VNI_HASH_BITS)]; -+} -+ -+/* Look up VNI in a per net namespace table */ -+static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id) -+{ -+ struct vxlan_dev *vxlan; -+ struct hlist_node *node; -+ -+ hlist_for_each_entry_rcu(vxlan, node, vni_head(net, id), hlist) { -+ if (vxlan->vni == id) -+ return vxlan; -+ } -+ -+ return NULL; -+} -+ -+/* Fill in neighbour message in skbuff. */ -+static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan, -+ const struct vxlan_fdb *fdb, -+ u32 portid, u32 seq, int type, unsigned int flags) -+{ -+ unsigned long now = jiffies; -+ struct nda_cacheinfo ci; -+ struct nlmsghdr *nlh; -+ struct ndmsg *ndm; -+ -+ nlh = nlmsg_put(skb, portid, seq, type, sizeof(*ndm), flags); -+ if (nlh == NULL) -+ return -EMSGSIZE; -+ -+ ndm = nlmsg_data(nlh); -+ memset(ndm, 0, sizeof(*ndm)); -+ ndm->ndm_family = AF_BRIDGE; -+ ndm->ndm_state = fdb->state; -+ ndm->ndm_ifindex = vxlan->dev->ifindex; -+ ndm->ndm_flags = NTF_SELF; -+ ndm->ndm_type = NDA_DST; -+ -+ if (nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->eth_addr)) -+ goto nla_put_failure; -+ -+ /* -+ if (nla_put_be32(skb, NDA_DST, fdb->remote_ip)) -+ goto nla_put_failure; -+ */ -+ NLA_PUT(skb, NDA_DST, 4, (u8 *)(&fdb->remote_ip)); -+ -+ ci.ndm_used = jiffies_to_clock_t(now - fdb->used); -+ ci.ndm_confirmed = 0; -+ ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated); -+ ci.ndm_refcnt = 0; -+ -+ if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci)) -+ goto nla_put_failure; -+ -+ return nlmsg_end(skb, nlh); -+ -+nla_put_failure: -+ nlmsg_cancel(skb, nlh); -+ return -EMSGSIZE; -+} -+ -+static inline size_t vxlan_nlmsg_size(void) -+{ -+ return NLMSG_ALIGN(sizeof(struct ndmsg)) -+ + nla_total_size(ETH_ALEN) /* NDA_LLADDR */ -+ + nla_total_size(sizeof(__be32)) /* NDA_DST */ -+ + nla_total_size(sizeof(struct nda_cacheinfo)); -+} -+ -+static void vxlan_fdb_notify(struct vxlan_dev *vxlan, -+ const struct vxlan_fdb *fdb, int type) -+{ -+ struct net *net = dev_net(vxlan->dev); -+ struct sk_buff *skb; -+ int err = -ENOBUFS; -+ -+ skb = nlmsg_new(vxlan_nlmsg_size(), GFP_ATOMIC); -+ if (skb == NULL) -+ goto errout; -+ -+ err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0); -+ if (err < 0) { -+ /* -EMSGSIZE implies BUG in vxlan_nlmsg_size() */ -+ WARN_ON(err == -EMSGSIZE); -+ kfree_skb(skb); -+ goto errout; -+ } -+ -+ rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); -+ return; -+errout: -+ if (err < 0) -+ rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); -+} -+ -+/* Hash Ethernet address */ -+static u32 eth_hash(const unsigned char *addr) -+{ -+ u64 value = get_unaligned((u64 *)addr); -+ -+ /* only want 6 bytes */ -+#ifdef __BIG_ENDIAN -+ value >>= 16; -+#else -+ value <<= 16; -+#endif -+ return hash_64(value, FDB_HASH_BITS); -+} -+ -+/* Hash chain to use given mac address */ -+static inline struct hlist_head *vxlan_fdb_head(struct vxlan_dev *vxlan, -+ const u8 *mac) -+{ -+ return &vxlan->fdb_head[eth_hash(mac)]; -+} -+ -+/* Look up Ethernet address in forwarding table */ -+static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, -+ const u8 *mac) -+ -+{ -+ struct hlist_head *head = vxlan_fdb_head(vxlan, mac); -+ struct vxlan_fdb *f; -+ struct hlist_node *node; -+ -+ hlist_for_each_entry_rcu(f, node, head, hlist) { -+ if (compare_ether_addr(mac, f->eth_addr) == 0) -+ return f; -+ } -+ -+ return NULL; -+} -+ -+/* Add new entry to forwarding table -- assumes lock held */ -+static int vxlan_fdb_create(struct vxlan_dev *vxlan, -+ const u8 *mac, __be32 ip, -+ __u16 state, __u16 flags) -+{ -+ struct vxlan_fdb *f; -+ int notify = 0; -+ -+ f = vxlan_find_mac(vxlan, mac); -+ if (f) { -+ if (flags & NLM_F_EXCL) { -+ netdev_dbg(vxlan->dev, -+ "lost race to create %pM\n", mac); -+ return -EEXIST; -+ } -+ if (f->state != state) { -+ f->state = state; -+ f->updated = jiffies; -+ notify = 1; -+ } -+ } else { -+ if (!(flags & NLM_F_CREATE)) -+ return -ENOENT; -+ -+ if (vxlan->addrmax && vxlan->addrcnt >= vxlan->addrmax) -+ return -ENOSPC; -+ -+ netdev_dbg(vxlan->dev, "add %pM -> %pI4\n", mac, &ip); -+ f = kmalloc(sizeof(*f), GFP_ATOMIC); -+ if (!f) -+ return -ENOMEM; -+ -+ notify = 1; -+ f->remote_ip = ip; -+ f->state = state; -+ f->updated = f->used = jiffies; -+ memcpy(f->eth_addr, mac, ETH_ALEN); -+ -+ ++vxlan->addrcnt; -+ hlist_add_head_rcu(&f->hlist, -+ vxlan_fdb_head(vxlan, mac)); -+ } -+ -+ if (notify) -+ vxlan_fdb_notify(vxlan, f, RTM_NEWNEIGH); -+ -+ return 0; -+} -+ -+static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f) -+{ -+ netdev_dbg(vxlan->dev, -+ "delete %pM\n", f->eth_addr); -+ -+ --vxlan->addrcnt; -+ vxlan_fdb_notify(vxlan, f, RTM_DELNEIGH); -+ -+ hlist_del_rcu(&f->hlist); -+ kfree_rcu(f, rcu); -+} -+ -+/* Add static entry (via netlink) */ -+static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], -+ struct net_device *dev, -+ const unsigned char *addr, u16 flags) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ __be32 ip; -+ int err; -+ -+ if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) { -+ pr_info("RTM_NEWNEIGH with invalid state %#x\n", -+ ndm->ndm_state); -+ return -EINVAL; -+ } -+ -+ if (tb[NDA_DST] == NULL) -+ return -EINVAL; -+ -+ if (nla_len(tb[NDA_DST]) != sizeof(__be32)) -+ return -EAFNOSUPPORT; -+ -+ ip = nla_get_be32(tb[NDA_DST]); -+ -+ spin_lock_bh(&vxlan->hash_lock); -+ err = vxlan_fdb_create(vxlan, addr, ip, ndm->ndm_state, flags); -+ spin_unlock_bh(&vxlan->hash_lock); -+ -+ return err; -+} -+ -+/* Delete entry (via netlink) */ -+static int vxlan_fdb_delete(struct ndmsg *ndm, struct net_device *dev, -+ const unsigned char *addr) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ struct vxlan_fdb *f; -+ int err = -ENOENT; -+ -+ spin_lock_bh(&vxlan->hash_lock); -+ f = vxlan_find_mac(vxlan, addr); -+ if (f) { -+ vxlan_fdb_destroy(vxlan, f); -+ err = 0; -+ } -+ spin_unlock_bh(&vxlan->hash_lock); -+ -+ return err; -+} -+ -+/* Dump forwarding table */ -+static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, -+ struct net_device *dev, int idx) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ unsigned int h; -+ -+ for (h = 0; h < FDB_HASH_SIZE; ++h) { -+ struct vxlan_fdb *f; -+ struct hlist_node *n; -+ int err; -+ -+ hlist_for_each_entry_rcu(f, n, &vxlan->fdb_head[h], hlist) { -+ if (idx < cb->args[0]) -+ goto skip; -+ -+ err = vxlan_fdb_info(skb, vxlan, f, -+ NETLINK_CB(cb->skb).pid, -+ cb->nlh->nlmsg_seq, -+ RTM_NEWNEIGH, -+ NLM_F_MULTI); -+ if (err < 0) -+ break; -+skip: -+ ++idx; -+ } -+ } -+ -+ return idx; -+} -+ -+/* Watch incoming packets to learn mapping between Ethernet address -+ * and Tunnel endpoint. -+ */ -+static void vxlan_snoop(struct net_device *dev, -+ __be32 src_ip, const u8 *src_mac) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ struct vxlan_fdb *f; -+ int err; -+ -+ f = vxlan_find_mac(vxlan, src_mac); -+ if (likely(f)) { -+ f->used = jiffies; -+ if (likely(f->remote_ip == src_ip)) -+ return; -+ -+ if (net_ratelimit()) -+ netdev_info(dev, -+ "%pM migrated from %pI4 to %pI4\n", -+ src_mac, &f->remote_ip, &src_ip); -+ -+ f->remote_ip = src_ip; -+ f->updated = jiffies; -+ vxlan_fdb_notify(vxlan, f, RTM_NEWNEIGH); -+ } else { -+ /* learned new entry */ -+ spin_lock(&vxlan->hash_lock); -+ err = vxlan_fdb_create(vxlan, src_mac, src_ip, -+ NUD_REACHABLE, -+ NLM_F_EXCL|NLM_F_CREATE); -+ spin_unlock(&vxlan->hash_lock); -+ } -+} -+ -+ -+/* See if multicast group is already in use by other ID */ -+static bool vxlan_group_used(struct vxlan_net *vn, -+ const struct vxlan_dev *this) -+{ -+ const struct vxlan_dev *vxlan; -+ struct hlist_node *node; -+ unsigned h; -+ -+ for (h = 0; h < VNI_HASH_SIZE; ++h) -+ hlist_for_each_entry(vxlan, node, &vn->vni_list[h], hlist) { -+ if (vxlan == this) -+ continue; -+ -+ if (!netif_running(vxlan->dev)) -+ continue; -+ -+ if (vxlan->gaddr == this->gaddr) -+ return true; -+ } -+ -+ return false; -+} -+ -+/* kernel equivalent to IP_ADD_MEMBERSHIP */ -+static int vxlan_join_group(struct net_device *dev) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id); -+ struct sock *sk = vn->sock->sk; -+ struct ip_mreqn mreq = { -+ .imr_multiaddr.s_addr = vxlan->gaddr, -+ }; -+ int err; -+ -+ /* Already a member of group */ -+ if (vxlan_group_used(vn, vxlan)) -+ return 0; -+ -+ /* Need to drop RTNL to call multicast join */ -+ rtnl_unlock(); -+ lock_sock(sk); -+ err = ip_mc_join_group(sk, &mreq); -+ release_sock(sk); -+ rtnl_lock(); -+ -+ return err; -+} -+ -+ -+/* kernel equivalent to IP_DROP_MEMBERSHIP */ -+static int vxlan_leave_group(struct net_device *dev) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id); -+ int err = 0; -+ struct sock *sk = vn->sock->sk; -+ struct ip_mreqn mreq = { -+ .imr_multiaddr.s_addr = vxlan->gaddr, -+ }; -+ -+ /* Only leave group when last vxlan is done. */ -+ if (vxlan_group_used(vn, vxlan)) -+ return 0; -+ -+ /* Need to drop RTNL to call multicast leave */ -+ rtnl_unlock(); -+ lock_sock(sk); -+ err = ip_mc_leave_group(sk, &mreq); -+ release_sock(sk); -+ rtnl_lock(); -+ -+ return err; -+} -+ -+/* Callback from net/ipv4/udp.c to receive packets */ -+static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) -+{ -+ struct iphdr *oip; -+ struct vxlanhdr *vxh; -+ struct vxlan_dev *vxlan; -+ struct vxlan_stats *stats; -+ __u32 vni; -+ int err; -+ -+ /* pop off outer UDP header */ -+ __skb_pull(skb, sizeof(struct udphdr)); -+ -+ /* Need Vxlan and inner Ethernet header to be present */ -+ if (!pskb_may_pull(skb, sizeof(struct vxlanhdr))) -+ goto error; -+ -+ /* Drop packets with reserved bits set */ -+ vxh = (struct vxlanhdr *) skb->data; -+ if (vxh->vx_flags != htonl(VXLAN_FLAGS) || -+ (vxh->vx_vni & htonl(0xff))) { -+ netdev_dbg(skb->dev, "invalid vxlan flags=%#x vni=%#x\n", -+ ntohl(vxh->vx_flags), ntohl(vxh->vx_vni)); -+ goto error; -+ } -+ -+ __skb_pull(skb, sizeof(struct vxlanhdr)); -+ -+ /* Is this VNI defined? */ -+ vni = ntohl(vxh->vx_vni) >> 8; -+ vxlan = vxlan_find_vni(sock_net(sk), vni); -+ if (!vxlan) { -+ netdev_dbg(skb->dev, "unknown vni %d\n", vni); -+ goto drop; -+ } -+ -+ if (!pskb_may_pull(skb, ETH_HLEN)) { -+ vxlan->dev->stats.rx_length_errors++; -+ vxlan->dev->stats.rx_errors++; -+ goto drop; -+ } -+ -+ /* Re-examine inner Ethernet packet */ -+ oip = ip_hdr(skb); -+ skb->protocol = eth_type_trans(skb, vxlan->dev); -+ -+ /* Ignore packet loops (and multicast echo) */ -+ if (compare_ether_addr(eth_hdr(skb)->h_source, -+ vxlan->dev->dev_addr) == 0) -+ goto drop; -+ -+ if (vxlan->learn) -+ vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source); -+ -+ __skb_tunnel_rx(skb, vxlan->dev); -+ skb_reset_network_header(skb); -+ skb->ip_summed = CHECKSUM_NONE; -+ -+ err = IP_ECN_decapsulate(oip, skb); -+ if (unlikely(err)) { -+ if (log_ecn_error) -+ net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n", -+ &oip->saddr, oip->tos); -+ if (err > 1) { -+ ++vxlan->dev->stats.rx_frame_errors; -+ ++vxlan->dev->stats.rx_errors; -+ goto drop; -+ } -+ } -+ -+ stats = this_cpu_ptr(vxlan->stats); -+ u64_stats_update_begin(&stats->syncp); -+ stats->rx_packets++; -+ stats->rx_bytes += skb->len; -+ u64_stats_update_end(&stats->syncp); -+ -+ netif_rx(skb); -+ -+ return 0; -+error: -+ /* Put UDP header back */ -+ __skb_push(skb, sizeof(struct udphdr)); -+ -+ return 1; -+drop: -+ /* Consume bad packet */ -+ kfree_skb(skb); -+ return 0; -+} -+ -+/* Extract dsfield from inner protocol */ -+static inline u8 vxlan_get_dsfield(const struct iphdr *iph, -+ const struct sk_buff *skb) -+{ -+ if (skb->protocol == htons(ETH_P_IP)) -+ return iph->tos; -+ else if (skb->protocol == htons(ETH_P_IPV6)) -+ return ipv6_get_dsfield((const struct ipv6hdr *)iph); -+ else -+ return 0; -+} -+ -+/* Propogate ECN bits out */ -+static inline u8 vxlan_ecn_encap(u8 tos, -+ const struct iphdr *iph, -+ const struct sk_buff *skb) -+{ -+ u8 inner = vxlan_get_dsfield(iph, skb); -+ -+ return INET_ECN_encapsulate(tos, inner); -+} -+ -+static __be32 vxlan_find_dst(struct vxlan_dev *vxlan, struct sk_buff *skb) -+{ -+ const struct ethhdr *eth = (struct ethhdr *) skb->data; -+ const struct vxlan_fdb *f; -+ int i; -+ -+ if (is_multicast_ether_addr(eth->h_dest)) { -+ if (vxlan->gaddr) -+ return vxlan->gaddr; -+ /* no group address defined, try service nodes */ -+ /* TBD: we should do some flow hash to spread, and also -+ * consider bfd status. for now just pick the first one -+ */ -+ for (i = 0; i < MAX_VXLAN_SERVICE_NODE_ADDRS; i++) { -+ if (vxlan->service_nodes[i] == 0) -+ break; -+ else -+ return vxlan->service_nodes[i]; -+ } -+ return 0; -+ } -+ -+ f = vxlan_find_mac(vxlan, eth->h_dest); -+ if (f) -+ return f->remote_ip; -+ else { -+ for (i = 0; i < MAX_VXLAN_SERVICE_NODE_ADDRS; i++) { -+ if (vxlan->service_nodes[i] == 0) -+ break; -+ else -+ return vxlan->service_nodes[i]; -+ } -+ return vxlan->gaddr; -+ } -+} -+ -+static void vxlan_sock_free(struct sk_buff *skb) -+{ -+ sock_put(skb->sk); -+} -+ -+/* On transmit, associate with the tunnel socket */ -+static void vxlan_set_owner(struct net_device *dev, struct sk_buff *skb) -+{ -+ struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id); -+ struct sock *sk = vn->sock->sk; -+ -+ skb_orphan(skb); -+ sock_hold(sk); -+ skb->sk = sk; -+ skb->destructor = vxlan_sock_free; -+} -+ -+/* Compute source port for outgoing packet -+ * first choice to use L4 flow hash since it will spread -+ * better and maybe available from hardware -+ * secondary choice is to use jhash on the Ethernet header -+ */ -+static u16 vxlan_src_port(const struct vxlan_dev *vxlan, struct sk_buff *skb) -+{ -+ unsigned int range = (vxlan->port_max - vxlan->port_min) + 1; -+ u32 hash; -+ -+ hash = skb_get_rxhash(skb); -+ if (!hash) -+ hash = jhash(skb->data, 2 * ETH_ALEN, -+ (__force u32) skb->protocol); -+ -+ return (((u64) hash * range) >> 32) + vxlan->port_min; -+} -+ -+/* Transmit local packets over Vxlan -+ * -+ * Outer IP header inherits ECN and DF from inner header. -+ * Outer UDP destination is the VXLAN assigned port. -+ * source port is based on hash of flow -+ */ -+static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ struct rtable *rt; -+ const struct iphdr *old_iph; -+ struct iphdr *iph; -+ struct vxlanhdr *vxh; -+ struct udphdr *uh; -+ struct flowi4 fl4; -+ unsigned int pkt_len = skb->len; -+ __be32 dst; -+ __u16 src_port; -+ __be16 df = 0; -+ __u8 tos, ttl; -+ int err; -+ -+ dst = vxlan_find_dst(vxlan, skb); -+ if (!dst) -+ goto drop; -+ -+ /* Need space for new headers (invalidates iph ptr) */ -+ if (skb_cow_head(skb, VXLAN_HEADROOM)) -+ goto drop; -+ -+ old_iph = ip_hdr(skb); -+ -+ ttl = vxlan->ttl; -+ if (!ttl && IN_MULTICAST(ntohl(dst))) -+ ttl = 1; -+ -+ tos = vxlan->tos; -+ if (tos == 1) -+ tos = vxlan_get_dsfield(old_iph, skb); -+ -+ src_port = vxlan_src_port(vxlan, skb); -+ -+ memset(&fl4, 0, sizeof(fl4)); -+ fl4.flowi4_oif = vxlan->link; -+ fl4.flowi4_tos = RT_TOS(tos); -+ fl4.daddr = dst; -+ fl4.saddr = vxlan->saddr; -+ -+ rt = ip_route_output_key(dev_net(dev), &fl4); -+ if (IS_ERR(rt)) { -+ netdev_dbg(dev, "no route to %pI4\n", &dst); -+ dev->stats.tx_carrier_errors++; -+ goto tx_error; -+ } -+ -+ if (rt->dst.dev == dev) { -+ netdev_dbg(dev, "circular route to %pI4\n", &dst); -+ ip_rt_put(rt); -+ dev->stats.collisions++; -+ goto tx_error; -+ } -+ -+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); -+ IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | -+ IPSKB_REROUTED); -+ skb_dst_drop(skb); -+ skb_dst_set(skb, &rt->dst); -+ -+ vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); -+ vxh->vx_flags = htonl(VXLAN_FLAGS); -+ vxh->vx_vni = htonl(vxlan->vni << 8); -+ -+ __skb_push(skb, sizeof(*uh)); -+ skb_reset_transport_header(skb); -+ uh = udp_hdr(skb); -+ -+ uh->dest = htons(vxlan_port); -+ uh->source = htons(src_port); -+ -+ uh->len = htons(skb->len); -+ uh->check = 0; -+ -+ __skb_push(skb, sizeof(*iph)); -+ skb_reset_network_header(skb); -+ iph = ip_hdr(skb); -+ iph->version = 4; -+ iph->ihl = sizeof(struct iphdr) >> 2; -+ iph->frag_off = df; -+ iph->protocol = IPPROTO_UDP; -+ iph->tos = vxlan_ecn_encap(tos, old_iph, skb); -+ iph->daddr = dst; -+ iph->saddr = fl4.saddr; -+ iph->ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); -+ -+ vxlan_set_owner(dev, skb); -+ -+ /* See __IPTUNNEL_XMIT */ -+ skb->ip_summed = CHECKSUM_NONE; -+ ip_select_ident(iph, &rt->dst, NULL); -+ -+ err = ip_local_out(skb); -+ if (likely(net_xmit_eval(err) == 0)) { -+ struct vxlan_stats *stats = this_cpu_ptr(vxlan->stats); -+ -+ u64_stats_update_begin(&stats->syncp); -+ stats->tx_packets++; -+ stats->tx_bytes += pkt_len; -+ u64_stats_update_end(&stats->syncp); -+ } else { -+ dev->stats.tx_errors++; -+ dev->stats.tx_aborted_errors++; -+ } -+ return NETDEV_TX_OK; -+ -+drop: -+ dev->stats.tx_dropped++; -+ goto tx_free; -+ -+tx_error: -+ dev->stats.tx_errors++; -+tx_free: -+ dev_kfree_skb(skb); -+ return NETDEV_TX_OK; -+} -+ -+/* Walk the forwarding table and purge stale entries */ -+static void vxlan_cleanup(unsigned long arg) -+{ -+ struct vxlan_dev *vxlan = (struct vxlan_dev *) arg; -+ unsigned long next_timer = jiffies + FDB_AGE_INTERVAL; -+ unsigned int h; -+ -+ if (!netif_running(vxlan->dev)) -+ return; -+ -+ spin_lock_bh(&vxlan->hash_lock); -+ for (h = 0; h < FDB_HASH_SIZE; ++h) { -+ struct hlist_node *p, *n; -+ hlist_for_each_safe(p, n, &vxlan->fdb_head[h]) { -+ struct vxlan_fdb *f -+ = container_of(p, struct vxlan_fdb, hlist); -+ unsigned long timeout; -+ -+ if (f->state & NUD_PERMANENT) -+ continue; -+ -+ timeout = f->used + vxlan->age_interval * HZ; -+ if (time_before_eq(timeout, jiffies)) { -+ netdev_dbg(vxlan->dev, -+ "garbage collect %pM\n", -+ f->eth_addr); -+ f->state = NUD_STALE; -+ vxlan_fdb_destroy(vxlan, f); -+ } else if (time_before(timeout, next_timer)) -+ next_timer = timeout; -+ } -+ } -+ spin_unlock_bh(&vxlan->hash_lock); -+ -+ mod_timer(&vxlan->age_timer, next_timer); -+} -+ -+/* Setup stats when device is created */ -+static int vxlan_init(struct net_device *dev) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ -+ vxlan->stats = alloc_percpu(struct vxlan_stats); -+ if (!vxlan->stats) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+/* Start ageing timer and join group when device is brought up */ -+static int vxlan_open(struct net_device *dev) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ int err; -+ -+ if (vxlan->gaddr) { -+ err = vxlan_join_group(dev); -+ if (err) -+ return err; -+ } -+ -+ if (vxlan->age_interval) -+ mod_timer(&vxlan->age_timer, jiffies + FDB_AGE_INTERVAL); -+ -+ return 0; -+} -+ -+/* Purge the forwarding table */ -+static void vxlan_flush(struct vxlan_dev *vxlan) -+{ -+ unsigned h; -+ -+ spin_lock_bh(&vxlan->hash_lock); -+ for (h = 0; h < FDB_HASH_SIZE; ++h) { -+ struct hlist_node *p, *n; -+ hlist_for_each_safe(p, n, &vxlan->fdb_head[h]) { -+ struct vxlan_fdb *f -+ = container_of(p, struct vxlan_fdb, hlist); -+ vxlan_fdb_destroy(vxlan, f); -+ } -+ } -+ spin_unlock_bh(&vxlan->hash_lock); -+} -+ -+/* Cleanup timer and forwarding table on shutdown */ -+static int vxlan_stop(struct net_device *dev) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ -+ if (vxlan->gaddr) -+ vxlan_leave_group(dev); -+ -+ del_timer_sync(&vxlan->age_timer); -+ -+ vxlan_flush(vxlan); -+ -+ return 0; -+} -+ -+/* Merge per-cpu statistics */ -+static struct rtnl_link_stats64 *vxlan_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ struct vxlan_stats tmp, sum = { 0 }; -+ unsigned int cpu; -+ -+ for_each_possible_cpu(cpu) { -+ unsigned int start; -+ const struct vxlan_stats *stats -+ = per_cpu_ptr(vxlan->stats, cpu); -+ -+ do { -+ start = u64_stats_fetch_begin_bh(&stats->syncp); -+ memcpy(&tmp, stats, sizeof(tmp)); -+ } while (u64_stats_fetch_retry_bh(&stats->syncp, start)); -+ -+ sum.tx_bytes += tmp.tx_bytes; -+ sum.tx_packets += tmp.tx_packets; -+ sum.rx_bytes += tmp.rx_bytes; -+ sum.rx_packets += tmp.rx_packets; -+ } -+ -+ stats->tx_bytes = sum.tx_bytes; -+ stats->tx_packets = sum.tx_packets; -+ stats->rx_bytes = sum.rx_bytes; -+ stats->rx_packets = sum.rx_packets; -+ -+ stats->multicast = dev->stats.multicast; -+ stats->rx_length_errors = dev->stats.rx_length_errors; -+ stats->rx_frame_errors = dev->stats.rx_frame_errors; -+ stats->rx_errors = dev->stats.rx_errors; -+ -+ stats->tx_dropped = dev->stats.tx_dropped; -+ stats->tx_carrier_errors = dev->stats.tx_carrier_errors; -+ stats->tx_aborted_errors = dev->stats.tx_aborted_errors; -+ stats->collisions = dev->stats.collisions; -+ stats->tx_errors = dev->stats.tx_errors; -+ -+ return stats; -+} -+ -+/* Stub, nothing needs to be done. */ -+static void vxlan_set_multicast_list(struct net_device *dev) -+{ -+} -+ -+static const struct net_device_ops vxlan_netdev_ops = { -+ .ndo_init = vxlan_init, -+ .ndo_open = vxlan_open, -+ .ndo_stop = vxlan_stop, -+ .ndo_start_xmit = vxlan_xmit, -+ .ndo_get_stats64 = vxlan_stats64, -+ .ndo_set_rx_mode = vxlan_set_multicast_list, -+ .ndo_change_mtu = eth_change_mtu, -+ .ndo_validate_addr = eth_validate_addr, -+ .ndo_set_mac_address = eth_mac_addr, -+ .ndo_fdb_add = vxlan_fdb_add, -+ .ndo_fdb_del = vxlan_fdb_delete, -+ .ndo_fdb_dump = vxlan_fdb_dump, -+}; -+ -+/* Info for udev, that this is a virtual tunnel endpoint */ -+static struct device_type vxlan_type = { -+ .name = "vxlan", -+}; -+ -+static void vxlan_free(struct net_device *dev) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ -+ free_percpu(vxlan->stats); -+ free_netdev(dev); -+} -+ -+/* Initialize the device structure. */ -+static void vxlan_setup(struct net_device *dev) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ unsigned h; -+ int low, high; -+ -+ eth_hw_addr_random(dev); -+ ether_setup(dev); -+ dev->hard_header_len = ETH_HLEN + VXLAN_HEADROOM; -+ -+ dev->netdev_ops = &vxlan_netdev_ops; -+ dev->destructor = vxlan_free; -+ SET_NETDEV_DEVTYPE(dev, &vxlan_type); -+ -+ dev->tx_queue_len = 0; -+ dev->features |= NETIF_F_LLTX; -+ dev->features |= NETIF_F_NETNS_LOCAL; -+ dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; -+ -+ spin_lock_init(&vxlan->hash_lock); -+ -+ init_timer_deferrable(&vxlan->age_timer); -+ vxlan->age_timer.function = vxlan_cleanup; -+ vxlan->age_timer.data = (unsigned long) vxlan; -+ -+ inet_get_local_port_range(&low, &high); -+ vxlan->port_min = low; -+ vxlan->port_max = high; -+ -+ vxlan->dev = dev; -+ -+ for (h = 0; h < FDB_HASH_SIZE; ++h) -+ INIT_HLIST_HEAD(&vxlan->fdb_head[h]); -+} -+ -+static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = { -+ [IFLA_VXLAN_ID] = { .type = NLA_U32 }, -+ [IFLA_VXLAN_GROUP] = { .len = FIELD_SIZEOF(struct iphdr, daddr) }, -+ [IFLA_VXLAN_LINK] = { .type = NLA_U32 }, -+ [IFLA_VXLAN_LOCAL] = { .len = FIELD_SIZEOF(struct iphdr, saddr) }, -+ [IFLA_VXLAN_TOS] = { .type = NLA_U8 }, -+ [IFLA_VXLAN_TTL] = { .type = NLA_U8 }, -+ [IFLA_VXLAN_LEARNING] = { .type = NLA_U8 }, -+ [IFLA_VXLAN_AGEING] = { .type = NLA_U32 }, -+ [IFLA_VXLAN_LIMIT] = { .type = NLA_U32 }, -+ [IFLA_VXLAN_PORT_RANGE] = { .len = sizeof(struct ifla_vxlan_port_range) }, -+ [IFLA_VXLAN_SERVICE_NODE] = { .len = sizeof(struct ifla_vxlan_svc_node_addrs) }, -+}; -+ -+static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[]) -+{ -+ if (tb[IFLA_ADDRESS]) { -+ if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) { -+ pr_debug("invalid link address (not ethernet)\n"); -+ return -EINVAL; -+ } -+ -+ if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) { -+ pr_debug("invalid all zero ethernet address\n"); -+ return -EADDRNOTAVAIL; -+ } -+ } -+ -+ if (!data) -+ return -EINVAL; -+ -+ if (data[IFLA_VXLAN_ID]) { -+ __u32 id = nla_get_u32(data[IFLA_VXLAN_ID]); -+ if (id >= VXLAN_VID_MASK) -+ return -ERANGE; -+ } -+ -+ if (data[IFLA_VXLAN_GROUP]) { -+ __be32 gaddr = nla_get_be32(data[IFLA_VXLAN_GROUP]); -+ if (!IN_MULTICAST(ntohl(gaddr))) { -+ pr_debug("group address is not IPv4 multicast\n"); -+ return -EADDRNOTAVAIL; -+ } -+ } -+ -+ if (data[IFLA_VXLAN_PORT_RANGE]) { -+ const struct ifla_vxlan_port_range *p -+ = nla_data(data[IFLA_VXLAN_PORT_RANGE]); -+ -+ if (ntohs(p->high) < ntohs(p->low)) { -+ pr_debug("port range %u .. %u not valid\n", -+ ntohs(p->low), ntohs(p->high)); -+ return -EINVAL; -+ } -+ } -+#if 0 -+ if (data[IFLA_VXLAN_SERVICE_NODE]) { -+ const struct ifla_vxlan_svc_node_addrs *p -+ = nla_data(data[IFLA_VXLAN_SERVICE_NODE]); -+ /* TBD: check for mcast and bcast */ -+ } -+#endif -+ return 0; -+} -+ -+static int vxlan_newlink(struct net *net, struct net_device *dev, -+ struct nlattr *tb[], struct nlattr *data[]) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ __u32 vni; -+ int err; -+ -+ if (!data[IFLA_VXLAN_ID]) -+ return -EINVAL; -+ -+ vni = nla_get_u32(data[IFLA_VXLAN_ID]); -+ if (vxlan_find_vni(net, vni)) { -+ pr_info("duplicate VNI %u\n", vni); -+ return -EEXIST; -+ } -+ vxlan->vni = vni; -+ -+ if (data[IFLA_VXLAN_GROUP]) -+ vxlan->gaddr = nla_get_be32(data[IFLA_VXLAN_GROUP]); -+ -+ if (data[IFLA_VXLAN_LOCAL]) -+ vxlan->saddr = nla_get_be32(data[IFLA_VXLAN_LOCAL]); -+ -+ if (data[IFLA_VXLAN_LINK] && -+ (vxlan->link = nla_get_u32(data[IFLA_VXLAN_LINK]))) { -+ struct net_device *lowerdev -+ = __dev_get_by_index(net, vxlan->link); -+ -+ if (!lowerdev) { -+ pr_info("ifindex %d does not exist\n", vxlan->link); -+ return -ENODEV; -+ } -+ -+ if (!tb[IFLA_MTU]) -+ dev->mtu = lowerdev->mtu - VXLAN_HEADROOM; -+ } -+ -+ if (data[IFLA_VXLAN_TOS]) -+ vxlan->tos = nla_get_u8(data[IFLA_VXLAN_TOS]); -+ -+ if (!data[IFLA_VXLAN_LEARNING] || nla_get_u8(data[IFLA_VXLAN_LEARNING])) -+ vxlan->learn = true; -+ -+ if (data[IFLA_VXLAN_AGEING]) -+ vxlan->age_interval = nla_get_u32(data[IFLA_VXLAN_AGEING]); -+ else -+ vxlan->age_interval = FDB_AGE_DEFAULT; -+ -+ if (data[IFLA_VXLAN_LIMIT]) -+ vxlan->addrmax = nla_get_u32(data[IFLA_VXLAN_LIMIT]); -+ -+ if (data[IFLA_VXLAN_PORT_RANGE]) { -+ const struct ifla_vxlan_port_range *p -+ = nla_data(data[IFLA_VXLAN_PORT_RANGE]); -+ vxlan->port_min = ntohs(p->low); -+ vxlan->port_max = ntohs(p->high); -+ } -+ -+ if (data[IFLA_VXLAN_SERVICE_NODE]) { -+ const struct ifla_vxlan_svc_node_addrs *p -+ = nla_data(data[IFLA_VXLAN_SERVICE_NODE]); -+ memcpy(vxlan->service_nodes, p, sizeof(*p)); -+ } -+ -+ err = register_netdevice(dev); -+ if (!err) -+ hlist_add_head_rcu(&vxlan->hlist, vni_head(net, vxlan->vni)); -+ -+ return err; -+} -+ -+static void vxlan_dellink(struct net_device *dev, struct list_head *head) -+{ -+ struct vxlan_dev *vxlan = netdev_priv(dev); -+ -+ vxlan_stop(dev); -+ -+ hlist_del_rcu(&vxlan->hlist); -+ -+ unregister_netdevice_queue(dev, head); -+} -+ -+static size_t vxlan_get_size(const struct net_device *dev) -+{ -+ -+ return nla_total_size(sizeof(__u32)) + /* IFLA_VXLAN_ID */ -+ nla_total_size(sizeof(__be32)) +/* IFLA_VXLAN_GROUP */ -+ nla_total_size(sizeof(__u32)) + /* IFLA_VXLAN_LINK */ -+ nla_total_size(sizeof(__be32))+ /* IFLA_VXLAN_LOCAL */ -+ nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_TTL */ -+ nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_TOS */ -+ nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_LEARNING */ -+ nla_total_size(sizeof(__u32)) + /* IFLA_VXLAN_AGEING */ -+ nla_total_size(sizeof(__u32)) + /* IFLA_VXLAN_LIMIT */ -+ nla_total_size(sizeof(struct ifla_vxlan_port_range)) + -+ nla_total_size(sizeof(struct ifla_vxlan_svc_node_addrs)) + -+ 0; -+} -+ -+static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev) -+{ -+ const struct vxlan_dev *vxlan = netdev_priv(dev); -+ struct ifla_vxlan_port_range ports = { -+ .low = htons(vxlan->port_min), -+ .high = htons(vxlan->port_max), -+ }; -+ struct ifla_vxlan_svc_node_addrs svcaddrs; -+ -+ if (nla_put_u32(skb, IFLA_VXLAN_ID, vxlan->vni)) -+ goto nla_put_failure; -+ -+ if (vxlan->gaddr && nla_put_be32(skb, IFLA_VXLAN_GROUP, vxlan->gaddr)) -+ goto nla_put_failure; -+ -+ if (vxlan->link && nla_put_u32(skb, IFLA_VXLAN_LINK, vxlan->link)) -+ goto nla_put_failure; -+ -+ if (vxlan->saddr && nla_put_be32(skb, IFLA_VXLAN_LOCAL, vxlan->saddr)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(skb, IFLA_VXLAN_TTL, vxlan->ttl) || -+ nla_put_u8(skb, IFLA_VXLAN_TOS, vxlan->tos) || -+ nla_put_u8(skb, IFLA_VXLAN_LEARNING, vxlan->learn) || -+ nla_put_u32(skb, IFLA_VXLAN_AGEING, vxlan->age_interval) || -+ nla_put_u32(skb, IFLA_VXLAN_LIMIT, vxlan->addrmax)) -+ goto nla_put_failure; -+ -+ if (nla_put(skb, IFLA_VXLAN_PORT_RANGE, sizeof(ports), &ports)) -+ goto nla_put_failure; -+ -+ memcpy(&svcaddrs, vxlan->service_nodes, sizeof(svcaddrs)); -+ if (nla_put(skb, IFLA_VXLAN_SERVICE_NODE, sizeof(svcaddrs), &svcaddrs)) -+ goto nla_put_failure; -+ -+ return 0; -+ -+nla_put_failure: -+ return -EMSGSIZE; -+} -+ -+static struct rtnl_link_ops vxlan_link_ops __read_mostly = { -+ .kind = "vxlan", -+ .maxtype = IFLA_VXLAN_MAX, -+ .policy = vxlan_policy, -+ .priv_size = sizeof(struct vxlan_dev), -+ .setup = vxlan_setup, -+ .validate = vxlan_validate, -+ .newlink = vxlan_newlink, -+ .dellink = vxlan_dellink, -+ .get_size = vxlan_get_size, -+ .fill_info = vxlan_fill_info, -+}; -+ -+static __net_init int vxlan_init_net(struct net *net) -+{ -+ struct vxlan_net *vn = net_generic(net, vxlan_net_id); -+ struct sock *sk; -+ struct sockaddr_in vxlan_addr = { -+ .sin_family = AF_INET, -+ .sin_addr.s_addr = htonl(INADDR_ANY), -+ }; -+ int rc; -+ unsigned h; -+ -+ /* Create UDP socket for encapsulation receive. */ -+ rc = sock_create_kern(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &vn->sock); -+ if (rc < 0) { -+ pr_debug("UDP socket create failed\n"); -+ return rc; -+ } -+ /* Put in proper namespace */ -+ sk = vn->sock->sk; -+ sk_change_net(sk, net); -+ -+ vxlan_addr.sin_port = htons(vxlan_port); -+ -+ rc = kernel_bind(vn->sock, (struct sockaddr *) &vxlan_addr, -+ sizeof(vxlan_addr)); -+ if (rc < 0) { -+ pr_debug("bind for UDP socket %pI4:%u (%d)\n", -+ &vxlan_addr.sin_addr, ntohs(vxlan_addr.sin_port), rc); -+ sk_release_kernel(sk); -+ vn->sock = NULL; -+ return rc; -+ } -+ -+ /* Disable multicast loopback */ -+ inet_sk(sk)->mc_loop = 0; -+ -+ /* Mark socket as an encapsulation socket. */ -+ udp_sk(sk)->encap_type = 1; -+ udp_sk(sk)->encap_rcv = vxlan_udp_encap_recv; -+// udp_encap_enable(); -+ -+ for (h = 0; h < VNI_HASH_SIZE; ++h) -+ INIT_HLIST_HEAD(&vn->vni_list[h]); -+ -+ return 0; -+} -+ -+static __net_exit void vxlan_exit_net(struct net *net) -+{ -+ struct vxlan_net *vn = net_generic(net, vxlan_net_id); -+ -+ if (vn->sock) { -+ sk_release_kernel(vn->sock->sk); -+ vn->sock = NULL; -+ } -+} -+ -+static struct pernet_operations vxlan_net_ops = { -+ .init = vxlan_init_net, -+ .exit = vxlan_exit_net, -+ .id = &vxlan_net_id, -+ .size = sizeof(struct vxlan_net), -+}; -+ -+static int __init vxlan_init_module(void) -+{ -+ int rc; -+ -+ get_random_bytes(&vxlan_salt, sizeof(vxlan_salt)); -+ -+ rc = register_pernet_device(&vxlan_net_ops); -+ if (rc) -+ goto out1; -+ -+ rc = rtnl_link_register(&vxlan_link_ops); -+ if (rc) -+ goto out2; -+ -+ return 0; -+ -+out2: -+ unregister_pernet_device(&vxlan_net_ops); -+out1: -+ return rc; -+} -+module_init(vxlan_init_module); -+ -+static void __exit vxlan_cleanup_module(void) -+{ -+ rtnl_link_unregister(&vxlan_link_ops); -+ unregister_pernet_device(&vxlan_net_ops); -+} -+module_exit(vxlan_cleanup_module); -+ -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(VXLAN_VERSION); -+MODULE_AUTHOR("Stephen Hemminger "); -+MODULE_ALIAS_RTNL_LINK("vxlan"); -diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h -index 71929cd..ef121eb 100644 ---- a/include/linux/etherdevice.h -+++ b/include/linux/etherdevice.h -@@ -139,6 +139,8 @@ static inline void random_ether_addr(u8 *addr) - addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ - } - -+#define eth_random_addr(addr) random_ether_addr(addr) -+ - /** - * dev_hw_addr_random - Create random MAC and set device flag - * @dev: pointer to net_device structure -@@ -175,8 +177,8 @@ static inline void eth_zero_addr(u8 *addr) - */ - static inline void eth_hw_addr_random(struct net_device *dev) - { -- dev->addr_assign_type |= NET_ADDR_RANDOM; -- random_ether_addr(dev->dev_addr); -+ dev->addr_assign_type |= NET_ADDR_RANDOM; -+ eth_random_addr(dev->dev_addr); - } - - /** -@@ -195,6 +197,18 @@ static inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2) - return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0; - } - -+/** -+ * ether_addr_equal - Compare two Ethernet addresses -+ * @addr1: Pointer to a six-byte array containing the Ethernet address -+ * @addr2: Pointer other six-byte array containing the Ethernet address -+ * -+ * Compare two Ethernet addresses, returns true if equal -+ */ -+static inline bool ether_addr_equal(const u8 *addr1, const u8 *addr2) -+{ -+ return !compare_ether_addr(addr1, addr2); -+} -+ - static inline unsigned long zap_last_2bytes(unsigned long value) - { - #ifdef __BIG_ENDIAN -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index 3b04a2a..8b03450 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -267,6 +267,34 @@ enum macvlan_mode { - MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */ - }; - -+/* VXLAN section */ -+enum { -+ IFLA_VXLAN_UNSPEC, -+ IFLA_VXLAN_ID, -+ IFLA_VXLAN_GROUP, -+ IFLA_VXLAN_LINK, -+ IFLA_VXLAN_LOCAL, -+ IFLA_VXLAN_TTL, -+ IFLA_VXLAN_TOS, -+ IFLA_VXLAN_LEARNING, -+ IFLA_VXLAN_AGEING, -+ IFLA_VXLAN_LIMIT, -+ IFLA_VXLAN_PORT_RANGE, -+ IFLA_VXLAN_SERVICE_NODE, -+ __IFLA_VXLAN_MAX -+}; -+#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) -+ -+struct ifla_vxlan_port_range { -+ __be16 low; -+ __be16 high; -+}; -+ -+#define MAX_VXLAN_SERVICE_NODE_ADDRS 16 -+struct ifla_vxlan_svc_node_addrs { -+ __u32 addrs[MAX_VXLAN_SERVICE_NODE_ADDRS]; -+}; -+ - /* SR-IOV virtual function management section */ - - enum { -diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h -index f5df3dc..90440dd 100644 ---- a/include/linux/jiffies.h -+++ b/include/linux/jiffies.h -@@ -304,6 +304,11 @@ extern unsigned long timeval_to_jiffies(const struct timeval *value); - extern void jiffies_to_timeval(const unsigned long jiffies, - struct timeval *value); - extern clock_t jiffies_to_clock_t(unsigned long x); -+static inline clock_t jiffies_delta_to_clock_t(long delta) -+{ -+ return jiffies_to_clock_t(max(0L, delta)); -+} -+ - extern unsigned long clock_t_to_jiffies(unsigned long x); - extern u64 jiffies_64_to_clock_t(u64 x); - extern u64 nsec_to_clock_t(u64 x); -diff --git a/include/linux/neighbour.h b/include/linux/neighbour.h -index 5016559..d2299b8 100644 ---- a/include/linux/neighbour.h -+++ b/include/linux/neighbour.h -@@ -34,6 +34,9 @@ enum { - #define NTF_PROXY 0x08 /* == ATF_PUBL */ - #define NTF_ROUTER 0x80 - -+#define NTF_SELF 0x02 -+#define NTF_MASTER 0x04 -+ - /* - * Neighbor Cache Entry States. - */ -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index af46f21..fb7f658 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -52,6 +52,9 @@ - #include - #endif - -+#include -+ -+ - struct vlan_group; - struct netpoll_info; - struct phy_device; -@@ -974,6 +977,18 @@ struct net_device_ops { - u32 features); - int (*ndo_set_features)(struct net_device *dev, - u32 features); -+ int (*ndo_fdb_add)(struct ndmsg *ndm, -+ struct nlattr *tb[], -+ struct net_device *dev, -+ const unsigned char *addr, -+ u16 flags); -+ int (*ndo_fdb_del)(struct ndmsg *ndm, -+ struct net_device *dev, -+ const unsigned char *addr); -+ int (*ndo_fdb_dump)(struct sk_buff *skb, -+ struct netlink_callback *cb, -+ struct net_device *dev, -+ int idx); - }; - - /* -diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h -index 2fa1469..53371b7 100644 ---- a/include/net/inet_ecn.h -+++ b/include/net/inet_ecn.h -@@ -145,4 +145,80 @@ static inline int INET_ECN_set_ce(struct sk_buff *skb) - return 0; - } - -+/* -+ * RFC 6080 4.2 -+ * To decapsulate the inner header at the tunnel egress, a compliant -+ * tunnel egress MUST set the outgoing ECN field to the codepoint at the -+ * intersection of the appropriate arriving inner header (row) and outer -+ * header (column) in Figure 4 -+ * -+ * +---------+------------------------------------------------+ -+ * |Arriving | Arriving Outer Header | -+ * | Inner +---------+------------+------------+------------+ -+ * | Header | Not-ECT | ECT(0) | ECT(1) | CE | -+ * +---------+---------+------------+------------+------------+ -+ * | Not-ECT | Not-ECT |Not-ECT(!!!)|Not-ECT(!!!)| (!!!)| -+ * | ECT(0) | ECT(0) | ECT(0) | ECT(1) | CE | -+ * | ECT(1) | ECT(1) | ECT(1) (!) | ECT(1) | CE | -+ * | CE | CE | CE | CE(!!!)| CE | -+ * +---------+---------+------------+------------+------------+ -+ * -+ * Figure 4: New IP in IP Decapsulation Behaviour -+ * -+ * returns 0 on success -+ * 1 if something is broken and should be logged (!!! above) -+ * 2 if packet should be dropped -+ */ -+static inline int INET_ECN_decapsulate(struct sk_buff *skb, -+ __u8 outer, __u8 inner) -+{ -+ if (INET_ECN_is_not_ect(inner)) { -+ switch (outer & INET_ECN_MASK) { -+ case INET_ECN_NOT_ECT: -+ return 0; -+ case INET_ECN_ECT_0: -+ case INET_ECN_ECT_1: -+ return 1; -+ case INET_ECN_CE: -+ return 2; -+ } -+ } -+ -+ if (INET_ECN_is_ce(outer)) -+ INET_ECN_set_ce(skb); -+ -+ return 0; -+} -+ -+static inline int IP_ECN_decapsulate(const struct iphdr *oiph, -+ struct sk_buff *skb) -+{ -+ __u8 inner; -+ -+ if (skb->protocol == htons(ETH_P_IP)) -+ inner = ip_hdr(skb)->tos; -+ else if (skb->protocol == htons(ETH_P_IPV6)) -+ inner = ipv6_get_dsfield(ipv6_hdr(skb)); -+ else -+ return 0; -+ -+ return INET_ECN_decapsulate(skb, oiph->tos, inner); -+} -+ -+static inline int IP6_ECN_decapsulate(const struct ipv6hdr *oipv6h, -+ struct sk_buff *skb) -+{ -+ __u8 inner; -+ -+ if (skb->protocol == htons(ETH_P_IP)) -+ inner = ip_hdr(skb)->tos; -+ else if (skb->protocol == htons(ETH_P_IPV6)) -+ inner = ipv6_get_dsfield(ipv6_hdr(skb)); -+ else -+ return 0; -+ -+ return INET_ECN_decapsulate(skb, ipv6_get_dsfield(oipv6h), inner); -+} -+ -+ - #endif -diff --git a/include/net/netlink.h b/include/net/netlink.h -index cb1f350..4fc2d2d 100644 ---- a/include/net/netlink.h -+++ b/include/net/netlink.h -@@ -818,6 +818,39 @@ static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value) - } - - /** -+ * nla_put_be32 - Add a __be32 netlink attribute to a socket buffer -+ * @skb: socket buffer to add attribute to -+ * @attrtype: attribute type -+ * @value: numeric value -+ */ -+static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value) -+{ -+ return nla_put(skb, attrtype, sizeof(__be32), &value); -+} -+ -+/** -+ * nla_put_net32 - Add 32-bit network byte order netlink attribute to a socket buffer -+ * @skb: socket buffer to add attribute to -+ * @attrtype: attribute type -+ * @value: numeric value -+ */ -+static inline int nla_put_net32(struct sk_buff *skb, int attrtype, __be32 value) -+{ -+ return nla_put_be32(skb, attrtype | NLA_F_NET_BYTEORDER, value); -+} -+ -+/** -+ * nla_put_le32 - Add a __le32 netlink attribute to a socket buffer -+ * @skb: socket buffer to add attribute to -+ * @attrtype: attribute type -+ * @value: numeric value -+ */ -+static inline int nla_put_le32(struct sk_buff *skb, int attrtype, __le32 value) -+{ -+ return nla_put(skb, attrtype, sizeof(__le32), &value); -+} -+ -+/** - * nla_put_64 - Add a u64 netlink attribute to a socket buffer - * @skb: socket buffer to add attribute to - * @attrtype: attribute type -diff --git a/include/net/udp.h b/include/net/udp.h -index e158330..008bcc8 100644 ---- a/include/net/udp.h -+++ b/include/net/udp.h -@@ -260,4 +260,6 @@ extern void udp_init(void); - - extern int udp4_ufo_send_check(struct sk_buff *skb); - extern struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, u32 features); -+extern void udp_encap_enable(void); -+ - #endif /* _UDP_H */ -diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c -index feb77ea..9abea10 100644 ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -312,6 +312,9 @@ static const struct net_device_ops br_netdev_ops = { - .ndo_add_slave = br_add_slave, - .ndo_del_slave = br_del_slave, - .ndo_fix_features = br_fix_features, -+ .ndo_fdb_add = br_fdb_add, -+ .ndo_fdb_del = br_fdb_delete, -+ .ndo_fdb_dump = br_fdb_dump, - }; - - static void br_dev_free(struct net_device *dev) -diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -index 039d6ac..30019c5 100644 ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -106,8 +106,8 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) - struct net_bridge_port *op; - list_for_each_entry(op, &br->port_list, list) { - if (op != p && -- !compare_ether_addr(op->dev->dev_addr, -- f->addr.addr)) { -+ ether_addr_equal(op->dev->dev_addr, -+ f->addr.addr)) { - f->dst = op; - goto insert; - } -@@ -126,6 +126,18 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) - spin_unlock_bh(&br->hash_lock); - } - -+void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) -+{ -+ struct net_bridge_fdb_entry *f; -+ -+ /* If old entry was unassociated with any port, then delete it. */ -+ f = __br_fdb_get(br, br->dev->dev_addr); -+ if (f && f->is_local && !f->dst) -+ fdb_delete(br, f); -+ -+ fdb_insert(br, NULL, newaddr); -+} -+ - void br_fdb_cleanup(unsigned long _data) - { - struct net_bridge *br = (struct net_bridge *)_data; -@@ -133,7 +145,7 @@ void br_fdb_cleanup(unsigned long _data) - unsigned long next_timer = jiffies + br->ageing_time; - int i; - -- spin_lock_bh(&br->hash_lock); -+ spin_lock(&br->hash_lock); - for (i = 0; i < BR_HASH_SIZE; i++) { - struct net_bridge_fdb_entry *f; - struct hlist_node *h, *n; -@@ -149,7 +161,7 @@ void br_fdb_cleanup(unsigned long _data) - next_timer = this_timer; - } - } -- spin_unlock_bh(&br->hash_lock); -+ spin_unlock(&br->hash_lock); - - mod_timer(&br->gc_timer, round_jiffies_up(next_timer)); - } -@@ -201,8 +213,8 @@ void br_fdb_delete_by_port(struct net_bridge *br, - struct net_bridge_port *op; - list_for_each_entry(op, &br->port_list, list) { - if (op != p && -- !compare_ether_addr(op->dev->dev_addr, -- f->addr.addr)) { -+ ether_addr_equal(op->dev->dev_addr, -+ f->addr.addr)) { - f->dst = op; - goto skip_delete; - } -@@ -224,7 +236,7 @@ struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br, - struct net_bridge_fdb_entry *fdb; - - hlist_for_each_entry_rcu(fdb, h, &br->hash[br_mac_hash(addr)], hlist) { -- if (!compare_ether_addr(fdb->addr.addr, addr)) { -+ if (ether_addr_equal(fdb->addr.addr, addr)) { - if (unlikely(has_expired(br, fdb))) - break; - return fdb; -@@ -234,7 +246,7 @@ struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br, - return NULL; - } - --#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) -+#if IS_ENABLED(CONFIG_ATM_LANE) - /* Interface used by ATM LANE hook to test - * if an addr is on some other bridge port */ - int br_fdb_test_addr(struct net_device *dev, unsigned char *addr) -@@ -249,7 +261,7 @@ int br_fdb_test_addr(struct net_device *dev, unsigned char *addr) - ret = 0; - else { - fdb = __br_fdb_get(port->br, addr); -- ret = fdb && fdb->dst->dev != dev && -+ ret = fdb && fdb->dst && fdb->dst->dev != dev && - fdb->dst->state == BR_STATE_FORWARDING; - } - rcu_read_unlock(); -@@ -281,6 +293,10 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf, - if (has_expired(br, f)) - continue; - -+ /* ignore pseudo entry for local MAC address */ -+ if (!f->dst) -+ continue; -+ - if (skip) { - --skip; - continue; -@@ -295,7 +311,7 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf, - - fe->is_local = f->is_local; - if (!f->is_static) -- fe->ageing_timer_value = jiffies_to_clock_t(jiffies - f->updated); -+ fe->ageing_timer_value = jiffies_delta_to_clock_t(jiffies - f->updated); - ++fe; - ++num; - } -@@ -314,7 +330,7 @@ static struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head, - struct net_bridge_fdb_entry *fdb; - - hlist_for_each_entry(fdb, h, head, hlist) { -- if (!compare_ether_addr(fdb->addr.addr, addr)) -+ if (ether_addr_equal(fdb->addr.addr, addr)) - return fdb; - } - return NULL; -@@ -327,7 +343,7 @@ static struct net_bridge_fdb_entry *fdb_find_rcu(struct hlist_head *head, - struct net_bridge_fdb_entry *fdb; - - hlist_for_each_entry_rcu(fdb, h, head, hlist) { -- if (!compare_ether_addr(fdb->addr.addr, addr)) -+ if (ether_addr_equal(fdb->addr.addr, addr)) - return fdb; - } - return NULL; -@@ -419,6 +435,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, - source->dev->name); - } else { - /* fastpath: update of existing entry */ -+ fdb->dst = source; - fdb->updated = jiffies; - } - } else { -@@ -468,17 +485,20 @@ static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br, - ndm->ndm_pad2 = 0; - ndm->ndm_flags = 0; - ndm->ndm_type = 0; -- ndm->ndm_ifindex = fdb->dst->dev->ifindex; -+ ndm->ndm_ifindex = fdb->dst ? fdb->dst->dev->ifindex : br->dev->ifindex; - ndm->ndm_state = fdb_to_nud(fdb); - -- NLA_PUT(skb, NDA_LLADDR, ETH_ALEN, &fdb->addr); -- NLA_PUT_U32(skb, NDA_MASTER, br->dev->ifindex); -+ if (nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->addr)) -+ goto nla_put_failure; -+ if (nla_put_u32(skb, NDA_MASTER, br->dev->ifindex)) -+ goto nla_put_failure; - - ci.ndm_used = jiffies_to_clock_t(now - fdb->used); - ci.ndm_confirmed = 0; - ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated); - ci.ndm_refcnt = 0; -- NLA_PUT(skb, NDA_CACHEINFO, sizeof(ci), &ci); -+ if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci)) -+ goto nla_put_failure; - - return nlmsg_end(skb, nlh); - -@@ -498,7 +518,7 @@ static inline size_t fdb_nlmsg_size(void) - static void fdb_notify(struct net_bridge *br, - const struct net_bridge_fdb_entry *fdb, int type) - { -- struct net *net = dev_net(fdb->dst->dev); -+ struct net *net = dev_net(br->dev); - struct sk_buff *skb; - int err = -ENOBUFS; - -@@ -521,47 +541,41 @@ errout: - } - - /* Dump information about entries, in response to GETNEIGH */ --int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) -+int br_fdb_dump(struct sk_buff *skb, -+ struct netlink_callback *cb, -+ struct net_device *dev, -+ int idx) - { -- struct net *net = sock_net(skb->sk); -- struct net_device *dev; -- int idx = 0; -- -- rcu_read_lock(); -- for_each_netdev_rcu(net, dev) { -- struct net_bridge *br = netdev_priv(dev); -- int i; -- -- if (!(dev->priv_flags & IFF_EBRIDGE)) -- continue; -+ struct net_bridge *br = netdev_priv(dev); -+ int i; - -- for (i = 0; i < BR_HASH_SIZE; i++) { -- struct hlist_node *h; -- struct net_bridge_fdb_entry *f; -+ if (!(dev->priv_flags & IFF_EBRIDGE)) -+ goto out; - -- hlist_for_each_entry_rcu(f, h, &br->hash[i], hlist) { -- if (idx < cb->args[0]) -- goto skip; -+ for (i = 0; i < BR_HASH_SIZE; i++) { -+ struct hlist_node *h; -+ struct net_bridge_fdb_entry *f; - -- if (fdb_fill_info(skb, br, f, -- NETLINK_CB(cb->skb).pid, -- cb->nlh->nlmsg_seq, -- RTM_NEWNEIGH, -- NLM_F_MULTI) < 0) -- break; -+ hlist_for_each_entry_rcu(f, h, &br->hash[i], hlist) { -+ if (idx < cb->args[0]) -+ goto skip; -+ -+ if (fdb_fill_info(skb, br, f, -+ NETLINK_CB(cb->skb).pid, -+ cb->nlh->nlmsg_seq, -+ RTM_NEWNEIGH, -+ NLM_F_MULTI) < 0) -+ break; - skip: -- ++idx; -- } -+ ++idx; - } - } -- rcu_read_unlock(); -- -- cb->args[0] = idx; - -- return skb->len; -+out: -+ return idx; - } - --/* Create new static fdb entry */ -+/* Update (create or replace) forwarding database entry */ - static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, - __u16 state, __u16 flags) - { -@@ -609,41 +623,16 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, - } - - /* Add new permanent fdb entry with RTM_NEWNEIGH */ --int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) -+int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], -+ struct net_device *dev, -+ const unsigned char *addr, u16 nlh_flags) - { -- struct net *net = sock_net(skb->sk); -- struct ndmsg *ndm; -- struct nlattr *tb[NDA_MAX+1]; -- struct net_device *dev; - struct net_bridge_port *p; -- const __u8 *addr; -- int err; -- -- ASSERT_RTNL(); -- err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); -- if (err < 0) -- return err; -- -- ndm = nlmsg_data(nlh); -- if (ndm->ndm_ifindex == 0) { -- pr_info("bridge: RTM_NEWNEIGH with invalid ifindex\n"); -- return -EINVAL; -- } -- -- dev = __dev_get_by_index(net, ndm->ndm_ifindex); -- if (dev == NULL) { -- pr_info("bridge: RTM_NEWNEIGH with unknown ifindex\n"); -- return -ENODEV; -- } - -- if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) { -- pr_info("bridge: RTM_NEWNEIGH with invalid address\n"); -- return -EINVAL; -- } -+ int err = 0; - -- addr = nla_data(tb[NDA_LLADDR]); -- if (!is_valid_ether_addr(addr)) { -- pr_info("bridge: RTM_NEWNEIGH with invalid ether address\n"); -+ if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) { -+ pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state); - return -EINVAL; - } - -@@ -654,9 +643,15 @@ int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) - return -EINVAL; - } - -- spin_lock_bh(&p->br->hash_lock); -- err = fdb_add_entry(p, addr, ndm->ndm_state, nlh->nlmsg_flags); -- spin_unlock_bh(&p->br->hash_lock); -+ if (ndm->ndm_flags & NTF_USE) { -+ rcu_read_lock(); -+ br_fdb_update(p->br, p, addr); -+ rcu_read_unlock(); -+ } else { -+ spin_lock_bh(&p->br->hash_lock); -+ err = fdb_add_entry(p, addr, ndm->ndm_state, nlh_flags); -+ spin_unlock_bh(&p->br->hash_lock); -+ } - - return err; - } -@@ -675,40 +670,12 @@ static int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr) - } - - /* Remove neighbor entry with RTM_DELNEIGH */ --int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) -+int br_fdb_delete(struct ndmsg *ndm, struct net_device *dev, -+ const unsigned char *addr) - { -- struct net *net = sock_net(skb->sk); -- struct ndmsg *ndm; - struct net_bridge_port *p; -- struct nlattr *llattr; -- const __u8 *addr; -- struct net_device *dev; - int err; - -- ASSERT_RTNL(); -- if (nlmsg_len(nlh) < sizeof(*ndm)) -- return -EINVAL; -- -- ndm = nlmsg_data(nlh); -- if (ndm->ndm_ifindex == 0) { -- pr_info("bridge: RTM_DELNEIGH with invalid ifindex\n"); -- return -EINVAL; -- } -- -- dev = __dev_get_by_index(net, ndm->ndm_ifindex); -- if (dev == NULL) { -- pr_info("bridge: RTM_DELNEIGH with unknown ifindex\n"); -- return -ENODEV; -- } -- -- llattr = nlmsg_find_attr(nlh, sizeof(*ndm), NDA_LLADDR); -- if (llattr == NULL || nla_len(llattr) != ETH_ALEN) { -- pr_info("bridge: RTM_DELNEIGH with invalid address\n"); -- return -EINVAL; -- } -- -- addr = nla_data(llattr); -- - p = br_port_get_rtnl(dev); - if (p == NULL) { - pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n", -diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c -index 99a48a3..79f8e75 100644 ---- a/net/bridge/br_netlink.c -+++ b/net/bridge/br_netlink.c -@@ -250,18 +250,6 @@ int __init br_netlink_init(void) - br_rtm_setlink, NULL, NULL); - if (err) - goto err3; -- err = __rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, -- br_fdb_add, NULL, NULL); -- if (err) -- goto err3; -- err = __rtnl_register(PF_BRIDGE, RTM_DELNEIGH, -- br_fdb_delete, NULL, NULL); -- if (err) -- goto err3; -- err = __rtnl_register(PF_BRIDGE, RTM_GETNEIGH, -- NULL, br_fdb_dump, NULL); -- if (err) -- goto err3; - - return 0; - -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index 82aed23..598f817 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -362,9 +362,18 @@ extern int br_fdb_insert(struct net_bridge *br, - extern void br_fdb_update(struct net_bridge *br, - struct net_bridge_port *source, - const unsigned char *addr); --extern int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb); --extern int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); --extern int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); -+extern int br_fdb_delete(struct ndmsg *ndm, -+ struct net_device *dev, -+ const unsigned char *addr); -+extern int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], -+ struct net_device *dev, -+ const unsigned char *addr, -+ u16 nlh_flags); -+extern int br_fdb_dump(struct sk_buff *skb, -+ struct netlink_callback *cb, -+ struct net_device *dev, -+ int idx); -+ - - /* br_forward.c */ - extern void br_deliver(const struct net_bridge_port *to, -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index a255f6c..329bb72 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -1990,6 +1991,277 @@ errout: - rtnl_set_sk_err(net, RTNLGRP_LINK, err); - } - -+static int nlmsg_populate_fdb_fill(struct sk_buff *skb, -+ struct net_device *dev, -+ u8 *addr, u8 *dst, u32 pid, u32 seq, -+ int type, unsigned int flags) -+{ -+ struct nlmsghdr *nlh; -+ struct ndmsg *ndm; -+ -+ nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), NLM_F_MULTI); -+ if (!nlh) -+ return -EMSGSIZE; -+ -+ ndm = nlmsg_data(nlh); -+ ndm->ndm_family = AF_BRIDGE; -+ ndm->ndm_pad1 = 0; -+ ndm->ndm_pad2 = 0; -+ ndm->ndm_flags = flags; -+ ndm->ndm_type = 0; -+ ndm->ndm_ifindex = dev->ifindex; -+ ndm->ndm_state = NUD_PERMANENT; -+ -+ if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr)) -+ goto nla_put_failure; -+ -+ if (dst) -+ NLA_PUT(skb, NDA_DST, 4, dst); -+ -+ return nlmsg_end(skb, nlh); -+ -+nla_put_failure: -+ nlmsg_cancel(skb, nlh); -+ return -EMSGSIZE; -+} -+ -+static inline size_t rtnl_fdb_nlmsg_size(void) -+{ -+ return NLMSG_ALIGN(sizeof(struct ndmsg)) + nla_total_size(ETH_ALEN) + -+ nla_total_size(4); -+} -+ -+static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u8 *dst, int type) -+{ -+ struct net *net = dev_net(dev); -+ struct sk_buff *skb; -+ int err = -ENOBUFS; -+ -+ skb = nlmsg_new(rtnl_fdb_nlmsg_size(), GFP_ATOMIC); -+ if (!skb) -+ goto errout; -+ -+ err = nlmsg_populate_fdb_fill(skb, dev, addr, dst, 0, 0, type, NTF_SELF); -+ if (err < 0) { -+ kfree_skb(skb); -+ goto errout; -+ } -+ -+ rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); -+ return; -+errout: -+ rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); -+} -+ -+static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) -+{ -+ struct net *net = sock_net(skb->sk); -+ struct net_device *master = NULL; -+ struct ndmsg *ndm; -+ struct nlattr *tb[NDA_MAX+1]; -+ struct net_device *dev; -+ u8 *addr; -+ u8 *dst; -+ int err; -+ -+ err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); -+ if (err < 0) -+ return err; -+ -+ ndm = nlmsg_data(nlh); -+ if (ndm->ndm_ifindex == 0) { -+ pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid ifindex\n"); -+ return -EINVAL; -+ } -+ -+ dev = __dev_get_by_index(net, ndm->ndm_ifindex); -+ if (dev == NULL) { -+ pr_info("PF_BRIDGE: RTM_NEWNEIGH with unknown ifindex\n"); -+ return -ENODEV; -+ } -+ -+ if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) { -+ pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid address\n"); -+ return -EINVAL; -+ } -+ -+ addr = nla_data(tb[NDA_LLADDR]); -+ if (!is_valid_ether_addr(addr)) { -+ pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid ether address\n"); -+ return -EINVAL; -+ } -+ -+ dst = nla_data(tb[NDA_DST]); -+ -+ err = -EOPNOTSUPP; -+ -+ /* Support fdb on master device the net/bridge default case */ -+ if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) && -+ (dev->priv_flags & IFF_BRIDGE_PORT)) { -+ master = dev->master; -+ err = master->netdev_ops->ndo_fdb_add(ndm, tb, -+ dev, addr, -+ nlh->nlmsg_flags); -+ if (err) -+ goto out; -+ else -+ ndm->ndm_flags &= ~NTF_MASTER; -+ } -+ -+ /* Embedded bridge, macvlan, and any other device support */ -+ if ((ndm->ndm_flags & NTF_SELF) && dev->netdev_ops->ndo_fdb_add) { -+ err = dev->netdev_ops->ndo_fdb_add(ndm, tb, -+ dev, addr, -+ nlh->nlmsg_flags); -+ -+ if (!err) { -+ rtnl_fdb_notify(dev, addr, dst, RTM_NEWNEIGH); -+ ndm->ndm_flags &= ~NTF_SELF; -+ } -+ } -+out: -+ return err; -+} -+ -+static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) -+{ -+ struct net *net = sock_net(skb->sk); -+ struct ndmsg *ndm; -+ struct nlattr *llattr; -+ struct net_device *dev; -+ int err = -EINVAL; -+ __u8 *addr; -+ -+ if (nlmsg_len(nlh) < sizeof(*ndm)) -+ return -EINVAL; -+ -+ ndm = nlmsg_data(nlh); -+ if (ndm->ndm_ifindex == 0) { -+ pr_info("PF_BRIDGE: RTM_DELNEIGH with invalid ifindex\n"); -+ return -EINVAL; -+ } -+ -+ dev = __dev_get_by_index(net, ndm->ndm_ifindex); -+ if (dev == NULL) { -+ pr_info("PF_BRIDGE: RTM_DELNEIGH with unknown ifindex\n"); -+ return -ENODEV; -+ } -+ -+ llattr = nlmsg_find_attr(nlh, sizeof(*ndm), NDA_LLADDR); -+ if (llattr == NULL || nla_len(llattr) != ETH_ALEN) { -+ pr_info("PF_BRIGDE: RTM_DELNEIGH with invalid address\n"); -+ return -EINVAL; -+ } -+ -+ addr = nla_data(llattr); -+ err = -EOPNOTSUPP; -+ -+ /* Support fdb on master device the net/bridge default case */ -+ if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) && -+ (dev->priv_flags & IFF_BRIDGE_PORT)) { -+ struct net_device *master = dev->master; -+ -+ if (master->netdev_ops->ndo_fdb_del) -+ err = master->netdev_ops->ndo_fdb_del(ndm, dev, addr); -+ -+ if (err) -+ goto out; -+ else -+ ndm->ndm_flags &= ~NTF_MASTER; -+ } -+ -+ /* Embedded bridge, macvlan, and any other device support */ -+ if ((ndm->ndm_flags & NTF_SELF) && dev->netdev_ops->ndo_fdb_del) { -+ err = dev->netdev_ops->ndo_fdb_del(ndm, dev, addr); -+ -+ if (!err) { -+ rtnl_fdb_notify(dev, addr, NULL, RTM_DELNEIGH); -+ ndm->ndm_flags &= ~NTF_SELF; -+ } -+ } -+out: -+ return err; -+} -+ -+static int nlmsg_populate_fdb(struct sk_buff *skb, -+ struct netlink_callback *cb, -+ struct net_device *dev, -+ int *idx, -+ struct netdev_hw_addr_list *list) -+{ -+ struct netdev_hw_addr *ha; -+ int err; -+ u32 portid, seq; -+ -+ portid = NETLINK_CB(cb->skb).pid; -+ seq = cb->nlh->nlmsg_seq; -+ -+ list_for_each_entry(ha, &list->list, list) { -+ if (*idx < cb->args[0]) -+ goto skip; -+ -+ err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, NULL, -+ portid, seq, 0, NTF_SELF); -+ if (err < 0) -+ return err; -+skip: -+ *idx += 1; -+ } -+ return 0; -+} -+ -+/** -+ * ndo_dflt_fdb_dump - default netdevice operation to dump an FDB table. -+ * @nlh: netlink message header -+ * @dev: netdevice -+ * -+ * Default netdevice operation to dump the existing unicast address list. -+ * Returns zero on success. -+ */ -+int ndo_dflt_fdb_dump(struct sk_buff *skb, -+ struct netlink_callback *cb, -+ struct net_device *dev, -+ int idx) -+{ -+ int err; -+ -+ netif_addr_lock_bh(dev); -+ err = nlmsg_populate_fdb(skb, cb, dev, &idx, &dev->uc); -+ if (err) -+ goto out; -+ nlmsg_populate_fdb(skb, cb, dev, &idx, &dev->mc); -+out: -+ netif_addr_unlock_bh(dev); -+ return idx; -+} -+EXPORT_SYMBOL(ndo_dflt_fdb_dump); -+ -+static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) -+{ -+ int idx = 0; -+ struct net *net = sock_net(skb->sk); -+ struct net_device *dev; -+ -+ rcu_read_lock(); -+ for_each_netdev_rcu(net, dev) { -+ if (dev->priv_flags & IFF_BRIDGE_PORT) { -+ struct net_device *master = dev->master; -+ const struct net_device_ops *ops = master->netdev_ops; -+ -+ if (ops->ndo_fdb_dump) -+ idx = ops->ndo_fdb_dump(skb, cb, dev, idx); -+ } -+ -+ if (dev->netdev_ops->ndo_fdb_dump) -+ idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, idx); -+ } -+ rcu_read_unlock(); -+ -+ cb->args[0] = idx; -+ return skb->len; -+} -+ -+ - /* Protected by RTNL sempahore. */ - static struct rtattr **rta_buf; - static int rtattr_max; -@@ -2159,5 +2431,9 @@ void __init rtnetlink_init(void) - - rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, NULL); - rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, NULL); -+ -+ rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL); -+ rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL); -+ rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL); - } - -diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c -index 79c0977..9b61b32 100644 ---- a/net/ipv4/igmp.c -+++ b/net/ipv4/igmp.c -@@ -1892,6 +1892,7 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) - rtnl_unlock(); - return ret; - } -+EXPORT_SYMBOL(ip_mc_leave_group); - - int ip_mc_source(int add, int omode, struct sock *sk, struct - ip_mreq_source *mreqs, int ifindex) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/overlayfs_notify.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/overlayfs_notify.patch deleted file mode 100644 index e5af6d21..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/overlayfs_notify.patch +++ /dev/null @@ -1,264 +0,0 @@ -Fix issues with OverlayFS not interacting correctly with the notify system - -diff --git a/fs/notify/inotify/Kconfig b/fs/notify/inotify/Kconfig -index b981fc0..137d3fa 100644 ---- a/fs/notify/inotify/Kconfig -+++ b/fs/notify/inotify/Kconfig -@@ -15,3 +15,13 @@ config INOTIFY_USER - For more information, see - - If unsure, say Y. -+ -+ -+config INOTIFY_STACKFS -+ bool "Inotify support for stackable filesystem" -+ select INOTIFY_USER -+ default y -+ ---help--- -+ Say Y here to enable inotify support for stackable filesystem. -+ -+ If unsure, say N. -diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c -index f255d37..e555ac5 100644 ---- a/fs/notify/inotify/inotify_user.c -+++ b/fs/notify/inotify/inotify_user.c -@@ -24,6 +24,7 @@ - - #include - #include /* struct inode */ -+#include - #include - #include - #include /* module_init */ -@@ -86,6 +87,93 @@ ctl_table inotify_table[] = { - }; - #endif /* CONFIG_SYSCTL */ - -+#ifdef CONFIG_INOTIFY_STACKFS -+ -+static DEFINE_RWLOCK(inotify_fs_lock); -+static LIST_HEAD(inotify_fs_list); -+ -+static inline struct file_system_type* peek_fs_type(struct path *path) -+{ -+ return path->mnt->mnt_sb->s_type; -+} -+ -+static struct inotify_stackfs* inotify_get_stackfs(struct path *path) -+{ -+ struct file_system_type *fs; -+ struct inotify_stackfs *fse, *ret = NULL; -+ -+ fs = peek_fs_type(path); -+ -+ read_lock(&inotify_fs_lock); -+ list_for_each_entry(fse, &inotify_fs_list, list) { -+ if (fse->fs_type == fs) { -+ ret = fse; -+ break; -+ } -+ } -+ read_unlock(&inotify_fs_lock); -+ -+ return ret; -+} -+ -+static inline void inotify_put_stackfs(struct inotify_stackfs *fs) -+{ -+} -+ -+int inotify_register_stackfs(struct inotify_stackfs *fs) -+{ -+ int ret = 0; -+ struct inotify_stackfs *fse; -+ -+ BUG_ON(IS_ERR_OR_NULL(fs->fs_type)); -+ BUG_ON(IS_ERR_OR_NULL(fs->func)); -+ -+ INIT_LIST_HEAD(&fs->list); -+ -+ write_lock(&inotify_fs_lock); -+ list_for_each_entry(fse, &inotify_fs_list, list) { -+ if (fse->fs_type == fs->fs_type) { -+ write_unlock(&inotify_fs_lock); -+ ret = -EBUSY; -+ goto out; -+ } -+ } -+ list_add_tail(&fs->list, &inotify_fs_list); -+ write_unlock(&inotify_fs_lock); -+ -+out: -+ return ret; -+} -+EXPORT_SYMBOL_GPL(inotify_register_stackfs); -+ -+void inotify_unregister_stackfs(struct inotify_stackfs *fs) -+{ -+ struct inotify_stackfs *fse, *n; -+ -+ write_lock(&inotify_fs_lock); -+ list_for_each_entry_safe(fse, n, &inotify_fs_list, list) { -+ if (fse == fs) { -+ list_del(&fse->list); -+ break; -+ } -+ } -+ write_unlock(&inotify_fs_lock); -+} -+EXPORT_SYMBOL_GPL(inotify_unregister_stackfs); -+ -+#else -+ -+static inline struct inotify_stackfs* inotify_get_stackfs(struct path *path) -+{ -+ return NULL; -+} -+ -+static inline void inotify_put_stackfs(struct inotify_stackfs *fs) -+{ -+} -+ -+#endif /* CONFIG_INOTIFY_STACKFS */ -+ - static inline __u32 inotify_arg_to_mask(u32 arg) - { - __u32 mask; -@@ -348,7 +436,7 @@ static const struct file_operations inotify_fops = { - /* - * find_inode - resolve a user-given path to a specific inode - */ --static int inotify_find_inode(const char __user *dirname, struct path *path, unsigned flags) -+static inline int __inotify_find_inode(const char __user *dirname, struct path *path, unsigned flags) - { - int error; - -@@ -362,6 +450,27 @@ static int inotify_find_inode(const char __user *dirname, struct path *path, uns - return error; - } - -+static int inotify_find_inode(const char __user *dirname, struct path *path, unsigned flags) -+{ -+ int ret; -+ struct path tpath; -+ struct inotify_stackfs *fse; -+ -+ ret = __inotify_find_inode(dirname, &tpath, flags); -+ if (ret) -+ return ret; -+ fse = inotify_get_stackfs(&tpath); -+ if (fse == NULL) { -+ *path = tpath; -+ return 0; -+ } -+ ret = fse->func(path, &tpath); -+ inotify_put_stackfs(fse); -+ path_put(&tpath); -+ -+ return ret; -+} -+ - static int inotify_add_to_idr(struct idr *idr, spinlock_t *idr_lock, - int *last_wd, - struct inotify_inode_mark *i_mark) -diff --git a/overlayfs/super.c b/fs/overlayfs/super.c -index 508cf19..cb39ec9 100644 ---- a/fs/overlayfs/super.c -+++ b/fs/overlayfs/super.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include "overlayfs.h" - - MODULE_AUTHOR("Miklos Szeredi "); -@@ -642,14 +643,40 @@ static struct file_system_type ovl_fs_type = { - .kill_sb = kill_anon_super, - }; - -+static int ovl_inotify_path(struct path *dst, struct path *src) -+{ -+ ovl_path_real(src->dentry, dst); -+ -+ path_get(dst); -+ -+ return 0; -+} -+ -+static struct inotify_stackfs ovl_inotify = { -+ .fs_type = &ovl_fs_type, -+ .func = ovl_inotify_path, -+}; -+ - static int __init ovl_init(void) - { -- return register_filesystem(&ovl_fs_type); -+ int ret; -+ -+ ret = register_filesystem(&ovl_fs_type); -+ if (ret) -+ return ret; -+ ret = inotify_register_stackfs(&ovl_inotify); -+ if (ret) { -+ pr_err("overlayfs: hook inotify error\n"); -+ unregister_filesystem(&ovl_fs_type); -+ } -+ -+ return ret; - } - - static void __exit ovl_exit(void) - { -- unregister_filesystem(&ovl_fs_type); -+ inotify_unregister_stackfs(&ovl_inotify); -+ unregister_filesystem(&ovl_fs_type); - } - - module_init(ovl_init); -diff --git a/include/linux/inotify.h b/include/linux/inotify.h -index d33041e..9d7e36f 100644 ---- a/include/linux/inotify.h -+++ b/include/linux/inotify.h -@@ -10,6 +10,8 @@ - /* For O_CLOEXEC and O_NONBLOCK */ - #include - #include -+#include -+#include - - /* - * struct inotify_event - structure read from the inotify device for each event -@@ -82,6 +84,32 @@ extern struct ctl_table inotify_table[]; /* for sysctl */ - IN_DONT_FOLLOW | IN_EXCL_UNLINK | IN_MASK_ADD | \ - IN_ISDIR | IN_ONESHOT) - -+typedef int (*inotify_path_proc)(struct path *dst, struct path *src); -+ -+struct inotify_stackfs { -+ struct list_head list; /* entry in inotify_fs_list */ -+ struct file_system_type *fs_type; /* registed file_system_type */ -+ inotify_path_proc func; /* registed callback function */ -+}; -+ -+#ifdef CONFIG_INOTIFY_STACKFS -+ -+extern int inotify_register_stackfs(struct inotify_stackfs *fs); -+extern void inotify_unregister_stackfs(struct inotify_stackfs *fs); -+ -+#else -+ -+static inline int inotify_register_stackfs(struct inotify_stackfs *fs) -+{ -+ return 0; -+} -+ -+static inline void inotify_unregister_stackfs(struct inotify_stackfs *fs) -+{ -+} -+ -+#endif /* CONFIG_INOTIFY_STACKFS */ -+ - #endif - - #endif /* _LINUX_INOTIFY_H */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-5652.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-5652.patch deleted file mode 100644 index 2b22e31e..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-5652.patch +++ /dev/null @@ -1,1252 +0,0 @@ -Support for the Accton ES5652BT1 networking platform. - -diff --git a/arch/powerpc/boot/dts/accton_5652.dts b/arch/powerpc/boot/dts/accton_5652.dts -new file mode 100644 -index 0000000..fe61f0a ---- /dev/null -+++ b/arch/powerpc/boot/dts/accton_5652.dts -@@ -0,0 +1,1021 @@ -+/* -+ * Accton Technology ES5652BT1 Device Tree Source -+ * -+ * Copyright 2012, Cumulus Networks, 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. -+ * -+ * Note: On current rev of Accton box eth mgmt PHY does not work at 1Gb. -+ * See PHY property accton,broken_1000 and use in gianfar.c. -+ */ -+ -+/dts-v1/; -+ -+/ { -+ model = "accton,es5652bt1"; -+ compatible = "accton,5652"; -+ #address-cells = <0x2>; -+ #size-cells = <0x2>; -+ interrupt-parent = <&MPIC>; -+ aliases { -+ ethernet0 = &ENET0; -+ serial0 = &SERIAL0; -+ pci1 = &PCI1; -+ }; -+ cpus { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ PowerPC,P2020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <0x1>; -+ }; -+ PowerPC,P2020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <0x1>; -+ }; -+ }; -+ memory { -+ device_type = "memory"; -+ }; -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ localbus@ff705000 { -+ #address-cells = <0x2>; -+ #size-cells = <0x1>; -+ compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus"; -+ reg = <0x0 0xff705000 0x0 0x00001000>; -+ interrupts = <19 0x2>; -+ ranges = <0x0 0x0 0x0 0xefc00000 0x00400000 -+ 0x1 0x0 0x0 0xea000000 0x00000100>; -+ flash@0,0 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x00400000>; -+ bank-width = <0x1>; -+ device-width = <0x1>; -+ partition@0 { -+ /* Entire flash minus (u-boot + info) */ -+ reg = <0x00000000 0x00360000>; -+ label = "onie"; -+ }; -+ partition@1 { -+ reg = <0x00360000 0x00010000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@2 { -+ reg = <0x00370000 0x00010000>; -+ label = "board_eeprom"; -+ }; -+ partition@3 { -+ reg = <0x00380000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ cpld@1,0 { -+ compatible = "accton,5652-cpld"; -+ reg = <0x1 0x0 0x0000100>; -+ }; -+ }; -+ -+ soc@ff700000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ device_type = "soc"; -+ compatible = "fsl,p2020-immr", "simple-bus"; -+ ranges = <0x0 0x0 0xff700000 0x100000>; -+ bus-frequency = <0x0>; -+ memory-controller@2000 { -+ compatible = "fsl,p2020-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <0x12 0x2>; -+ }; -+ I2C0: i2c@3000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ cell-index = <0x0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <0x2b 0x2>; -+ dfsrr; -+ clock-frequency = <400000>; -+ fsl,timeout = <10000>; -+ mux@70 { -+ compatible = "ti,pca9548"; -+ reg = <0x70>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ rtc@51 { -+ compatible = "epson,rtc8564"; -+ reg = <0x51>; -+ }; -+ -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ /* Not sure what the two addr per PSU are for */ -+ /* -+ ** The eeprom utilities look for a label that -+ ** ends with "_eeprom". -+ */ -+ psu_eeprom@39 { -+ compatible = "at,24c02"; -+ reg = <0x39>; -+ /* Haven't seen this one work yet */ -+ label = "psu1_eeprom"; -+ read-only; -+ }; -+ psu_unknown@3d { -+ compatible = "at,24c02"; -+ reg = <0x3d>; -+ /* Haven't seen this one work yet */ -+ // label = "psu1_eeprom2"; -+ read-only; -+ }; -+ psu_eeprom@3a { -+ compatible = "at,24c02"; -+ reg = <0x3a>; -+ /* This one contains valid data */ -+ label = "psu2_eeprom"; -+ read-only; -+ }; -+ psu_unknown@3e { -+ compatible = "at,24c02"; -+ reg = <0x3e>; -+ /* This one is unformatted */ -+ // label = "psu2_eeprom2"; -+ read-only; -+ }; -+ -+ }; -+ // No devices on bus 2 -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ }; -+ // No devices on bus 3 -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ // SMSC USB2513i - USB Hub. -+ // Handled by u-boot, leave blank here. -+ // addr 0x2C -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ // VT1165M Voltage monitor -+ // Leave blank here. -+ // addr 0x71 -+ }; -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ // ICS83905I PCIe clock buffer -+ // Leave blank here. -+ // addr 0x6E -+ }; -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ -+ hwmon@29 { -+ compatible = "winbond,w83782d"; -+ reg = <0x29>; -+ // write 0 to 0x5c and 0x45c -+ accton,es5652bt1,clksel = <1>; -+ }; -+ tmon@18 { -+ compatible = "nxp,max1617"; -+ reg = <0x18>; -+ }; -+ tmon@1a { -+ compatible = "nxp,max1617"; -+ reg = <0x1a>; -+ }; -+ tmon@4c { -+ compatible = "nxp,max1617"; -+ reg = <0x4c>; -+ }; -+ }; -+ }; -+ }; -+ I2C1: i2c@3100 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ cell-index = <0x1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <0x2b 0x2>; -+ dfsrr; -+ mux@75 { -+ compatible = "ti,pca9546"; -+ reg = <0x75>; -+ deselect-on-exit; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ mux@74 { -+ compatible = "ti,pca9548"; -+ reg = <0x74>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port1"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port2"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port3"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port4"; -+ }; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port5"; -+ }; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port6"; -+ }; -+ }; -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port7"; -+ }; -+ }; -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port8"; -+ }; -+ }; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ mux@74 { -+ compatible = "ti,pca9548"; -+ reg = <0x74>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port9"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port10"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port11"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port12"; -+ }; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port13"; -+ }; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port14"; -+ }; -+ }; -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port15"; -+ }; -+ }; -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port16"; -+ }; -+ }; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ mux@74 { -+ compatible = "ti,pca9548"; -+ reg = <0x74>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port17"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port18"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port19"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port20"; -+ }; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port21"; -+ }; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port22"; -+ }; -+ }; -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port23"; -+ }; -+ }; -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port24"; -+ }; -+ }; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ mux@74 { -+ compatible = "ti,pca9548"; -+ reg = <0x74>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port25"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port26"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port27"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port28"; -+ }; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port29"; -+ }; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port30"; -+ }; -+ }; -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port31"; -+ }; -+ }; -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port32"; -+ }; -+ }; -+ }; -+ }; -+ }; -+ mux@76 { -+ // 4 channel mux -+ compatible = "ti,pca9546"; -+ reg = <0x76>; -+ deselect-on-exit; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ mux@74 { -+ compatible = "ti,pca9548"; -+ reg = <0x74>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port33"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port34"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port35"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port36"; -+ }; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port37"; -+ }; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port38"; -+ }; -+ }; -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port39"; -+ }; -+ }; -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port40"; -+ }; -+ }; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ mux@74 { -+ // 8 channel mux -+ compatible = "ti,pca9548"; -+ reg = <0x74>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port41"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port42"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port43"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port44"; -+ }; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port45"; -+ }; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port46"; -+ }; -+ }; -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port47"; -+ }; -+ }; -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port48"; -+ }; -+ }; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ gpio@20 { -+ // SFP+ RX/TX rate select 0..19 -+ compatible = "ti,pca9506"; -+ reg = <0x20>; -+ }; -+ gpio@21 { -+ // SFP+ RX/TX rate select 20..39 -+ compatible = "ti,pca9506"; -+ reg = <0x21>; -+ }; -+ gpio@70 { -+ // LPMODE QSFP+ 0..3 -+ compatible = "ti,pca9538"; -+ reg = <0x70>; -+ }; -+ gpio@71 { -+ // RESET QSFP+ 0..3, MDOESEL QSFP+ 0..3 -+ compatible = "ti,pca9538"; -+ reg = <0x71>; -+ }; -+ gpio@72 { -+ // SFP+ RX rate select 40..47 -+ compatible = "ti,pca9538"; -+ reg = <0x72>; -+ }; -+ gpio@73 { -+ // SFP+ TX rate select 40..47 -+ compatible = "ti,pca9538"; -+ reg = <0x73>; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ gpio@20 { -+ // SFP+ MOD_ABS 0..39 -+ compatible = "ti,pca9506"; -+ reg = <0x20>; -+ }; -+ gpio@22 { -+ // SFP+ OPRXLOSS 0..39 -+ compatible = "ti,pca9506"; -+ reg = <0x22>; -+ }; -+ gpio@71 { -+ // SFP+ MOD_ABS 40..47 -+ compatible = "ti,pca9538"; -+ reg = <0x71>; -+ }; -+ gpio@72 { -+ // QSFP+ PRSNT 0..3 -+ compatible = "ti,pca9538"; -+ reg = <0x72>; -+ }; -+ gpio@73 { -+ // SFP+ OPRXLOSS 40..47 -+ compatible = "ti,pca9538"; -+ reg = <0x73>; -+ }; -+ }; -+ }; -+ mux@77 { -+ // 4 channel mux -+ compatible = "ti,pca9546"; -+ reg = <0x77>; -+ deselect-on-exit; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port50"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port49"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port52"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port51"; -+ }; -+ }; -+ }; -+ }; -+ SERIAL0: serial@4500 { -+ cell-index = <0x0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0x0>; -+ interrupts = <0x2a 0x2>; -+ }; -+/* -+ SERIAL1: serial@4600 { -+ cell-index = <0x1>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4600 0x100>; -+ clock-frequency = <0x0>; -+ interrupts = <0x2a 0x2>; -+ }; -+*/ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,p2020-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <0x20>; -+ cache-size = <0x80000>; -+ interrupts = <0x10 0x2>; -+ }; -+ -+ USB: usb@22000 { -+ compatible = "fsl-usb2-dr"; -+ reg = <0x22000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = <28 0x2>; -+ phy_type = "ulpi"; -+ dr_mode = "host"; -+ }; -+ -+ MDIO1: mdio@24520 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ PHY1: ethernet-phy@1 { -+ reg = <0x1>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ -+ ENET0: ethernet@24000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ cell-index = <0x1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x24000 0x1000>; -+ ranges = <0x0 0x24000 0x1000>; -+ interrupts = < -+ 0x1d 0x2 -+ 0x1e 0x2 -+ 0x22 0x2>; -+ phy-handle = <&PHY1>; -+ phy-connection-type = "rgmii"; -+ }; -+ MPIC: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0x0>; -+ #interrupt-cells = <0x2>; -+ reg = <0x40000 0x40000>; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ }; -+ global-utilities@e0000 { -+ compatible = "fsl,p2020-guts", "fsl,mpc8548-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ }; -+ -+ PCI1: pcie@ff70a000 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #interrupt-cells = <0x1>; -+ #size-cells = <0x2>; -+ #address-cells = <0x3>; -+ reg = <0x0 0xff70a000 0x0 0x1000>; -+ bus-range = <0x0 0xff>; -+ ranges = <0x2000000 0x0 0xa0000000 0x0 0xa0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0x0 0xffc20000 0x0 0x00010000>; -+ clock-frequency = <0x5f5e100>; -+ interrupts = <0x1a 0x2>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0x0 0x0 0x0 0x1 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x2 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x3 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x4 &MPIC 0x0 0x1>; -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <0x2>; -+ #address-cells = <0x3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xa0000000 0x2000000 0x0 0xa0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0x1000000 0x0 0x00000000 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/accton_5652.c b/arch/powerpc/platforms/85xx/accton_5652.c -new file mode 100644 -index 0000000..6192a2c ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/accton_5652.c -@@ -0,0 +1,217 @@ -+/* -+ * Accton es5652bt1 setup and early boot code plus other random bits. -+ * -+ * Copyright 2012 Cumulus Networks, 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 -+ -+#include -+#include -+ -+// #undef DEBUG -+ -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+/* -+ * Enough of the CPLD to reset the system... full driver loads as a module -+*/ -+static uint8_t __iomem * cpld_regs; -+static uint32_t CPLD_RESET_REG = 0x10; -+ -+/******************************************************************************* -+ * -+ * Platform initialization functions -+ * -+ ******************************************************************************* -+*/ -+ -+/* -+ * Initialize the interrupt controller -+ */ -+static void __init accton_5652_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np; -+ -+ np = of_find_node_by_type(NULL, "open-pic"); -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | -+ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | -+ MPIC_SINGLE_DEST_CPU, -+ 0, 256, " OpenPIC "); -+ -+ BUG_ON(mpic == NULL); -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+#ifdef CONFIG_SMP -+extern void __init mpc85xx_smp_init(void); -+#endif -+ -+static void __init accton_5652_setup_arch(void) -+{ -+ struct device_node *cpu; -+ const unsigned int *fp; -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ struct device_node *cpld; -+ -+ if (ppc_md.progress) -+ ppc_md.progress("accton_5652_setup_arch()", 0); -+ -+ cpu = of_find_node_by_type(NULL, "cpu"); -+ if (cpu != 0) { -+ fp = of_get_property(cpu, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(cpu); -+ } -+ -+#ifdef CONFIG_PCI -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8548-pcie")) -+ fsl_add_bridge(np, 0); -+ } -+#endif -+ -+ cpld = of_find_compatible_node(NULL, NULL, "accton,5652-cpld"); -+ if (!cpld) { -+ printk(KERN_ERR "Can not find accton,5652-cpld node in device tree\n"); -+ cpld_regs = NULL; -+ } else { -+ cpld_regs = of_iomap(cpld, 0); -+ of_node_put(cpld); -+ } -+ -+ powersave_nap = 0; -+ -+#ifdef CONFIG_SMP -+ mpc85xx_smp_init(); -+#endif -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+} -+ -+static struct of_device_id __initdata accton_5652_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ { .compatible = "gianfar", }, -+ {}, -+}; -+ -+static int __init accton_5652_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, accton_5652_ids, NULL); -+} -+machine_device_initcall(accton_5652, accton_5652_publish_devices); -+ -+static void accton_5652_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu Pll setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+/* -+ * Platform specific restart... need to use the CPLD -+ */ -+static void accton_5652_restart(char *cmd) -+{ -+ printk (KERN_EMERG "Reset via the platform CPLD\n"); -+ -+ local_irq_disable(); -+ writeb(0, (cpld_regs + CPLD_RESET_REG)); -+ while (1); -+} -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init accton_5652_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "accton,5652")) -+ return 1; -+ -+ return 0; -+} -+ -+define_machine(accton_5652) { -+ .name = "Accton Technology Corporation ES5652BT1", -+ .probe = accton_5652_probe, -+ .setup_arch = accton_5652_setup_arch, -+ .init_IRQ = accton_5652_pic_init, -+ .show_cpuinfo = accton_5652_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = accton_5652_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as4600_54t.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as4600_54t.patch deleted file mode 100644 index 2f09aa29..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as4600_54t.patch +++ /dev/null @@ -1,574 +0,0 @@ -platform accton 4654 patch - -Add platform support for the Accton ES4654BF platform. - -diff --git a/arch/powerpc/boot/dts/accton_as4600_54t.dts b/arch/powerpc/boot/dts/accton_as4600_54t.dts -new file mode 100644 -index 0000000..2614fe9 ---- /dev/null -+++ b/arch/powerpc/boot/dts/accton_as4600_54t.dts -@@ -0,0 +1,343 @@ -+/* -+ * Accton Technology AS4600_54T Device Tree Source -+ * -+ * 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/; -+ -+/ { -+ model = "accton,as4600_54t"; -+ compatible = "accton,as4600_54t"; -+ #address-cells = <0x2>; -+ #size-cells = <0x2>; -+ interrupt-parent = <&MPIC>; -+ aliases { -+ ethernet0 = &ENET1; -+ serial0 = &SERIAL0; -+ pci1 = &PCI1; -+ }; -+ cpus { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ PowerPC,P2020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <0x1>; -+ }; -+ PowerPC,P2020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <0x1>; -+ }; -+ }; -+ memory { -+ device_type = "memory"; -+ }; -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ localbus@ff705000 { -+ #address-cells = <0x2>; -+ #size-cells = <0x1>; -+ compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus"; -+ reg = <0x0 0xff705000 0x0 0x00001000>; -+ interrupts = <19 0x2>; -+ ranges = <0x0 0x0 0x0 0xef800000 0x00800000 -+ 0x1 0x0 0x0 0xea000000 0x00000100>; -+ flash@0,0 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x00800000>; -+ bank-width = <0x1>; -+ device-width = <0x1>; -+ partition@0 { -+ /* Entire flash minus (u-boot + onie) */ -+ reg = <0x00000000 0x00360000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x00360000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ reg = <0x00760000 0x00010000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ reg = <0x00770000 0x00010000>; -+ label = "board_eeprom"; -+ }; -+ partition@4 { -+ reg = <0x00780000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ cpld@1,0 { -+ compatible = "accton,as4600_54t-cpld"; -+ reg = <0x1 0x0 0x0000100>; -+ }; -+ }; -+ -+ soc@ff700000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ device_type = "soc"; -+ compatible = "fsl,p2020-immr", "simple-bus"; -+ ranges = <0x0 0x0 0xff700000 0x100000>; -+ bus-frequency = <0x0>; -+ memory-controller@2000 { -+ compatible = "fsl,p2020-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <0x12 0x2>; -+ }; -+ I2C0: i2c@3000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ cell-index = <0x0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <0x2b 0x2>; -+ dfsrr; -+ clock-frequency = <400000>; -+ fsl,timeout = <10000>; -+ mux@70 { -+ compatible = "ti,pca9548"; -+ reg = <0x70>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ // SFP+ 0 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port49"; -+ }; -+ }; -+ -+ // SFP+ 1 -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port50"; -+ }; -+ }; -+ -+ // SFP+ 2 -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port51"; -+ }; -+ }; -+ -+ // SFP+ 3 -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port52"; -+ }; -+ }; -+ -+ /* Nothing on 4 through 6 */ -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ }; -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ }; -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ tmon@49 { -+ compatible = "ti,tmp75"; -+ reg = <0x49>; -+ }; -+ }; -+ }; -+ }; -+ I2C1: i2c@3100 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ cell-index = <0x1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <0x2b 0x2>; -+ dfsrr; -+ // unknown@19 { -+ /* do not know what this is */ -+ // reg = <0x19>; -+ //}; -+ hwmon@2e { -+ compatible = "onsemi,adt7473"; -+ reg = <0x2e>; -+ }; -+ psu_eeprom@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ label = "psu1_eeprom"; -+ read-only; -+ }; -+ psu_eeprom@52 { -+ compatible = "at,24c02"; -+ reg = <0x52>; -+ label = "psu2_eeprom"; -+ read-only; -+ }; -+ rtc@68 { -+ compatible = "maxim,ds1672"; -+ reg = <0x68>; -+ }; -+ }; -+ -+ SERIAL0: serial@4500 { -+ cell-index = <0x0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0x0>; -+ interrupts = <0x2a 0x2>; -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,p2020-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <0x20>; -+ cache-size = <0x80000>; -+ interrupts = <0x10 0x2>; -+ }; -+ -+ USB: usb@22000 { -+ compatible = "fsl-usb2-dr"; -+ reg = <0x22000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = <28 0x2>; -+ phy_type = "ulpi"; -+ dr_mode = "host"; -+ }; -+ -+ MDIO0: mdio@24520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ PHY1: ethernet-phy@1 { -+ interrupt-parent = <&MPIC>; -+ interrupts = <3 1>; -+ reg = <0x1>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ -+ ENET1: ethernet@25000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ cell-index = <0x1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x25000 0x1000>; -+ ranges = <0x0 0x25000 0x1000>; -+ interrupts = < -+ 0x23 0x2 -+ 0x24 0x2 -+ 0x28 0x2>; -+ interrupt-parent = <&MPIC>; -+ tbi-handle = <&TBI1>; -+ phy-handle = <&PHY1>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ MDIO1: mdio@25520 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ compatible = "fsl,gianfar-tbi"; -+ reg = <0x520 0x20>; -+ TBI1: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ MPIC: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0x0>; -+ #interrupt-cells = <0x2>; -+ reg = <0x40000 0x40000>; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ }; -+ -+ global-utilities@e0000 { -+ compatible = "fsl,p2020-guts", "fsl,mpc8548-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ }; -+ -+ PCI1: pcie@ff70a000 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #interrupt-cells = <0x1>; -+ #size-cells = <0x2>; -+ #address-cells = <0x3>; -+ reg = <0x0 0xff70a000 0x0 0x1000>; -+ bus-range = <0x0 0xff>; -+ ranges = <0x2000000 0x0 0xa0000000 0x0 0xa0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0x0 0xffc20000 0x0 0x00010000>; -+ clock-frequency = <0x5f5e100>; -+ interrupts = <0x1a 0x2>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0x0 0x0 0x0 0x1 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x2 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x3 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x4 &MPIC 0x0 0x1>; -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <0x2>; -+ #address-cells = <0x3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xa0000000 0x2000000 0x0 0xa0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0x1000000 0x0 0x00000000 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/accton_as4600_54t.c b/arch/powerpc/platforms/85xx/accton_as4600_54t.c -new file mode 100644 -index 0000000..967698c ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/accton_as4600_54t.c -@@ -0,0 +1,215 @@ -+/* -+ * Accton as4600_54t setup and early boot code plus other random bits. -+ * -+ * 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 -+ -+#include -+#include -+ -+// #undef DEBUG -+ -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+/* -+ * Enough of the CPLD to reset the system... full driver loads as a module -+*/ -+static uint8_t __iomem * cpld_regs; -+static uint32_t CPLD_RESET_REG = 0x01; -+ -+/******************************************************************************* -+ * -+ * Platform initialization functions -+ * -+ ******************************************************************************* -+*/ -+ -+/* -+ * Initialize the interrupt controller -+ */ -+static void __init accton_as4600_54t_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np; -+ -+ np = of_find_node_by_type(NULL, "open-pic"); -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | -+ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | -+ MPIC_SINGLE_DEST_CPU, -+ 0, 256, " OpenPIC "); -+ -+ BUG_ON(mpic == NULL); -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+#ifdef CONFIG_SMP -+extern void __init mpc85xx_smp_init(void); -+#endif -+ -+static void __init accton_as4600_54t_setup_arch(void) -+{ -+ struct device_node *cpu; -+ const unsigned int *fp; -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ struct device_node *cpld; -+ -+ if (ppc_md.progress) -+ ppc_md.progress("accton_as4600_54t_setup_arch()", 0); -+ -+ cpu = of_find_node_by_type(NULL, "cpu"); -+ if (cpu != 0) { -+ fp = of_get_property(cpu, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(cpu); -+ } -+ -+#ifdef CONFIG_PCI -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8548-pcie")) -+ fsl_add_bridge(np, 0); -+ } -+#endif -+ -+ cpld = of_find_compatible_node(NULL, NULL, "accton,as4600_54t-cpld"); -+ if (!cpld) { -+ printk(KERN_ERR "Can not find accton,as4600_54t-cpld node in device tree\n"); -+ cpld_regs = NULL; -+ } else { -+ cpld_regs = of_iomap(cpld, 0); -+ of_node_put(cpld); -+ } -+ -+ powersave_nap = 0; -+ -+#ifdef CONFIG_SMP -+ mpc85xx_smp_init(); -+#endif -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+} -+ -+static struct of_device_id __initdata accton_as4600_54t_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ { .compatible = "gianfar", }, -+ {}, -+}; -+ -+static int __init accton_as4600_54t_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, accton_as4600_54t_ids, NULL); -+} -+machine_device_initcall(as4600_54t, accton_as4600_54t_publish_devices); -+ -+static void accton_as4600_54t_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu Pll setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+/* -+ * Platform specific restart... need to use the CPLD -+ */ -+static void accton_as4600_54t_restart(char *cmd) -+{ -+ printk (KERN_EMERG "Reset via the platform CPLD\n"); -+ -+ local_irq_disable(); -+ writeb(0x7F, (cpld_regs + CPLD_RESET_REG)); -+ while (1); -+} -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init accton_as4600_54t_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "accton,as4600_54t")) -+ return 1; -+ -+ return 0; -+} -+ -+define_machine(as4600_54t) { -+ .name = "Accton Technology Corporation AS4600_54T", -+ .probe = accton_as4600_54t_probe, -+ .setup_arch = accton_as4600_54t_setup_arch, -+ .init_IRQ = accton_as4600_54t_pic_init, -+ .show_cpuinfo = accton_as4600_54t_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = accton_as4600_54t_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as5610_52x.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as5610_52x.patch deleted file mode 100644 index 7b13b3bb..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as5610_52x.patch +++ /dev/null @@ -1,1443 +0,0 @@ -Patch for accton AS5610_52X - -diff --git a/arch/powerpc/boot/dts/accton_as5610_52x.dts b/arch/powerpc/boot/dts/accton_as5610_52x.dts -new file mode 100644 -index 0000000..76e7368 ---- /dev/null -+++ b/arch/powerpc/boot/dts/accton_as5610_52x.dts -@@ -0,0 +1,1241 @@ -+/* -+ * Accton Technology AS5610_52X Device Tree Source -+ * -+ * Copyright 2014, Cumulus Networks, 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. -+ * -+ * Note: On current rev of Accton box eth mgmt PHY does not work at 1Gb. -+ * See PHY property accton,broken_1000 and use in gianfar.c. -+ */ -+ -+/dts-v1/; -+ -+/ { -+ model = "accton,as5610_52x"; -+ compatible = "accton,as5610_52x"; -+ #address-cells = <0x2>; -+ #size-cells = <0x2>; -+ interrupt-parent = <&MPIC>; -+ -+ aliases { -+ ethernet0 = &ENET0; -+ serial0 = &SERIAL0; -+ pci1 = &PCI1; -+ }; -+ cpus { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ PowerPC,P2020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <0x1>; -+ }; -+ PowerPC,P2020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <0x1>; -+ }; -+ }; -+ memory { -+ device_type = "memory"; -+ }; -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ localbus@ff705000 { -+ #address-cells = <0x2>; -+ #size-cells = <0x1>; -+ compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus"; -+ reg = <0x0 0xff705000 0x0 0x00001000>; -+ interrupts = <19 0x2>; -+ ranges = <0x0 0x0 0x0 0xefc00000 0x00400000 -+ 0x1 0x0 0x0 0xea000000 0x00000100>; -+ flash@0,0 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x00400000>; -+ bank-width = <0x1>; -+ device-width = <0x1>; -+ partition@0 { -+ /* Entire flash minus (u-boot info) */ -+ reg = <0x00000000 0x00360000>; -+ label = "onie"; -+ }; -+ partition@1 { -+ reg = <0x00360000 0x00010000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@2 { -+ reg = <0x00370000 0x00010000>; -+ label = "board_eeprom"; -+ }; -+ partition@3 { -+ reg = <0x00380000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ cpld@1,0 { -+ compatible = "accton,accton_as5610_52x-cpld"; -+ reg = <0x1 0x0 0x0000100>; -+ }; -+ }; -+ -+ soc@ff700000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ device_type = "soc"; -+ compatible = "fsl,p2020-immr", "simple-bus"; -+ ranges = <0x0 0x0 0xff700000 0x100000>; -+ bus-frequency = <0x0>; -+ memory-controller@2000 { -+ compatible = "fsl,p2020-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <0x12 0x2>; -+ }; -+ I2C0: i2c@3000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ cell-index = <0x0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <0x2b 0x2>; -+ dfsrr; -+ fsl,timeout = <10000>; -+ fsl,preserve-clocking; -+ -+ mux@70 { -+ compatible = "ti,pca9548"; -+ reg = <0x70>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ rtc@51 { -+ compatible = "epson,rtc8564"; -+ reg = <0x51>; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ /* Not sure what the two addr per PSU are for */ -+ /* -+ ** The eeprom utilities look for a label that -+ ** ends with "_eeprom". -+ */ -+ psu_eeprom@3a { -+ compatible = "at,24c02"; -+ reg = <0x3a>; -+ label = "psu1_eeprom"; -+ read-only; -+ }; -+ psu_unknown@3e { -+ compatible = "at,24c02"; -+ reg = <0x3e>; -+ label = "psu1_eeprom"; -+ read-only; -+ }; -+ psu_eeprom@78 { -+ compatible = "at,24c02"; -+ reg = <0x78>; -+ label = "psu1_eeprom"; -+ read-only; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ /* Not sure what the two addr per PSU are for */ -+ /* -+ ** The eeprom utilities look for a label that -+ ** ends with "_eeprom". -+ */ -+ psu_eeprom@0c { -+ compatible = "at,24c02"; -+ reg = <0x0c>; -+ label = "psu2_eeprom"; -+ read-only; -+ }; -+ psu_unknown@39 { -+ compatible = "at,24c02"; -+ reg = <0x39>; -+ label = "psu2_eeprom2"; -+ read-only; -+ }; -+ psu_eeprom@3d { -+ compatible = "at,24c02"; -+ reg = <0x3d>; -+ label = "psu2_eeprom"; -+ read-only; -+ }; -+ psu_eeprom@78 { -+ compatible = "at,24c02"; -+ reg = <0x78>; -+ label = "psu2_eeprom"; -+ read-only; -+ }; -+ -+ }; -+ // No devices on bus 3 -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ }; -+ // No devices on bus 4 -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ // VT1165M Voltage monitor -+ // Leave blank here. -+ // addr 0x71 -+ }; -+ // No devices on bus 6 -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ }; -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ hwmon@4d { -+ compatible = "nxp,max6697"; -+ reg = <0x4d>; -+ }; -+ tmon@18 { -+ compatible = "nxp,max1617"; -+ reg = <0x18>; -+ }; -+ }; -+ }; -+ }; -+ I2C1: i2c@3100 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ cell-index = <0x1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <0x2b 0x2>; -+ dfsrr; -+ fsl,preserve-clocking; -+ -+ mux@75 { -+ compatible = "ti,pca9546"; -+ reg = <0x75>; -+ deselect-on-exit; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ // SFP+ 0-7 and retimer RX EQ 0-3 -+ mux@74 { -+ compatible = "ti,pca9548"; -+ reg = <0x74>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port1"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_rx_eq_0"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port2"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_rx_eq_1"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port3"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_rx_eq_2"; -+ }; -+ }; -+ i2c@3 { -+ // SFP+ 3 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port4"; -+ }; -+ // RX EQ 3 -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_rx_eq_3"; -+ }; -+ }; -+ // SFP+ 4 -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port5"; -+ }; -+ }; -+ // SFP+ 5 -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port6"; -+ }; -+ }; -+ // SFP+ 6 -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port7"; -+ }; -+ }; -+ // SFP+ 7 -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port8"; -+ }; -+ }; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ // SFP+ 8-15 and retimer RX EQ 4-7 -+ mux@74 { -+ compatible = "ti,pca9548"; -+ reg = <0x74>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ // SFP+ 8 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port9"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_rx_eq_4"; -+ }; -+ }; -+ i2c@1 { -+ // SFP+ 9 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port10"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_rx_eq_5"; -+ }; -+ }; -+ i2c@2 { -+ // SFP+ 10 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port11"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_rx_eq_6"; -+ }; -+ }; -+ i2c@3 { -+ // SFP+ 11 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port12"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_rx_eq_7"; -+ }; -+ }; -+ // SFP+ 12 -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port13"; -+ }; -+ }; -+ // SFP+ 13 -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port14"; -+ }; -+ }; -+ // SFP+ 14 -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port15"; -+ }; -+ }; -+ // SFP+ 15 -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port16"; -+ }; -+ }; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ // SFP+ 16-23 and retimer RX EQ 8-11 -+ mux@74 { -+ compatible = "ti,pca9548"; -+ reg = <0x74>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ // SFP+ 16 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port17"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_rx_eq_8"; -+ }; -+ }; -+ i2c@1 { -+ // SFP+ 17 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port18"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_rx_eq_9"; -+ }; -+ }; -+ i2c@2 { -+ // SFP+ 18 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port19"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_rx_eq_10"; -+ }; -+ }; -+ i2c@3 { -+ // SFP+ 19 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port20"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_rx_eq_11"; -+ }; -+ }; -+ // SFP+ 20 -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port21"; -+ }; -+ }; -+ // SFP+ 21 -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port22"; -+ }; -+ }; -+ // SFP+ 22 -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port23"; -+ }; -+ }; -+ // SFP+ 23 -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port24"; -+ }; -+ }; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ // SFP+ 24-31 and retimer TX EQ 0-3 -+ mux@74 { -+ compatible = "ti,pca9548"; -+ reg = <0x74>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ // SFP+ 24 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port25"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_tx_eq_0"; -+ }; -+ }; -+ i2c@1 { -+ // SFP+ 25 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port26"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_tx_eq_1"; -+ }; -+ }; -+ i2c@2 { -+ // SFP+ 26 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port27"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_tx_eq_2"; -+ }; -+ }; -+ i2c@3 { -+ // SFP+ 27 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port28"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_tx_eq_3"; -+ }; -+ }; -+ // SFP+ 28 -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port29"; -+ }; -+ }; -+ // SFP+ 29 -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port30"; -+ }; -+ }; -+ // SFP+ 30 -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port31"; -+ }; -+ }; -+ // SFP+ 31 -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port32"; -+ }; -+ }; -+ }; -+ }; -+ }; -+ mux@76 { -+ // 4 channel mux -+ compatible = "ti,pca9546"; -+ reg = <0x76>; -+ deselect-on-exit; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ // SFP+ 32-39 and retimer TX EQ 4-7 -+ mux@74 { -+ compatible = "ti,pca9548"; -+ reg = <0x74>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ // SFP+ 32 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port33"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_tx_eq_4"; -+ }; -+ }; -+ i2c@1 { -+ // SFP+ 33 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port34"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_tx_eq_5"; -+ }; -+ }; -+ i2c@2 { -+ // SFP+ 34 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port35"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_tx_eq_6"; -+ }; -+ }; -+ i2c@3 { -+ // SFP+ 34 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port36"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_tx_eq_7"; -+ }; -+ }; -+ // SFP+ 36 -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port37"; -+ }; -+ }; -+ // SFP+ 37 -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port38"; -+ }; -+ }; -+ // SFP+ 38 -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port39"; -+ }; -+ }; -+ // SFP+ 39 -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port40"; -+ }; -+ }; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ // SFP+ 40-47, retimer TX EQ 8-11, retimer QSFP TX EQ 0-3 -+ mux@74 { -+ compatible = "ti,pca9548"; -+ reg = <0x74>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ // SFP+ 40 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port41"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_tx_eq_8"; -+ }; -+ }; -+ i2c@1 { -+ // SFP+ 41 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port42"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_tx_eq_9"; -+ }; -+ }; -+ i2c@2 { -+ // SFP+ 42 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port43"; -+ }; -+ // TX EQ 10 -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_tx_eq_10"; -+ }; -+ }; -+ i2c@3 { -+ // SFP+ 43 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port44"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "sfp_tx_eq_11"; -+ }; -+ }; -+ i2c@4 { -+ // SFP+ 44 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port45"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "qsfp_tx_eq_0"; -+ }; -+ -+ }; -+ i2c@5 { -+ // SFP+ 45 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port46"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "qsfp_tx_eq_1"; -+ }; -+ }; -+ i2c@6 { -+ // SFP+ 46 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port47"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "qsfp_tx_eq_2"; -+ }; -+ }; -+ i2c@7 { -+ // SFP+ 47 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port48"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "qsfp_tx_eq_3"; -+ }; -+ }; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ gpio@20 { -+ // SFP+ RX/TX rate select 0..19 -+ compatible = "ti,pca9506"; -+ reg = <0x20>; -+ }; -+ gpio@21 { -+ // SFP+ RX/TX rate select 20..39 -+ compatible = "ti,pca9506"; -+ reg = <0x21>; -+ }; -+ gpio@70 { -+ // LPMODE QSFP+ 0..3 -+ compatible = "ti,pca9538"; -+ reg = <0x70>; -+ }; -+ gpio@71 { -+ // RESET QSFP+ 0..3, MDOESEL QSFP+ 0..3 -+ compatible = "ti,pca9538"; -+ reg = <0x71>; -+ }; -+ gpio@72 { -+ // SFP+ RX rate select 40..47 -+ compatible = "ti,pca9538"; -+ reg = <0x72>; -+ }; -+ gpio@73 { -+ // SFP+ TX rate select 40..47 -+ compatible = "ti,pca9538"; -+ reg = <0x73>; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ gpio@20 { -+ // SFP+ MOD_ABS 0..39 -+ compatible = "ti,pca9506"; -+ reg = <0x20>; -+ }; -+ // Running out of GPIOs (max 256) so -+ // disabling these gpios as we are not -+ // using them. -+/* -+ gpio@21 { -+ // SFP+ OPTXFLT 0..39 -+ compatible = "ti,pca9506"; -+ reg = <0x21>; -+ }; -+ gpio@22 { -+ // SFP+ OPRXLOSS 0..39 -+ compatible = "ti,pca9506"; -+ reg = <0x22>; -+ }; -+*/ -+ gpio@23 { -+ // SFP+ OPRXLOSS 40..47, -+ // SFP+ MOD_ABS 40..47, -+ // QSFP+ PRSNT 0..3 -+ // SFP+ OPTXFLT 40..47 -+ // SFP+ OPTXENB 40..47 -+ compatible = "ti,pca9506"; -+ reg = <0x23>; -+ }; -+ gpio@24 { -+ // SFP+ OPTXENB 0..39 -+ compatible = "ti,pca9506"; -+ reg = <0x24>; -+ }; -+ }; -+ }; -+ mux@77 { -+ // 4 channel mux -+ compatible = "ti,pca9546"; -+ reg = <0x77>; -+ deselect-on-exit; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ // QSFP+ 0 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port49"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "qsfp_rx_eq_0"; -+ }; -+ }; -+ i2c@1 { -+ // QSFP+ 1 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port50"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "qsfp_rx_eq_1"; -+ }; -+ }; -+ i2c@2 { -+ // QSFP+ 2 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port51"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "qsfp_rx_eq_2"; -+ }; -+ }; -+ i2c@3 { -+ // QSFP+ 3 -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port52"; -+ }; -+ retimer@27 { -+ compatible = "ti,ds100df410"; -+ reg = <0x27>; -+ label = "qsfp_rx_eq_3"; -+ }; -+ }; -+ }; -+ }; -+ SERIAL0: serial@4500 { -+ cell-index = <0x0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0x0>; -+ interrupts = <0x2a 0x2>; -+ }; -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,p2020-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <0x20>; -+ cache-size = <0x80000>; -+ interrupts = <0x10 0x2>; -+ }; -+ USB: usb@22000 { -+ compatible = "fsl-usb2-dr"; -+ reg = <0x22000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = <28 0x2>; -+ phy_type = "ulpi"; -+ dr_mode = "host"; -+ }; -+ MDIO1: mdio@24520 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ PHY1: ethernet-phy@1 { -+ reg = <0x1>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ ENET0: ethernet@24000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ cell-index = <0x1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x24000 0x1000>; -+ ranges = <0x0 0x24000 0x1000>; -+ interrupts = < -+ 0x1d 0x2 -+ 0x1e 0x2 -+ 0x22 0x2>; -+ phy-handle = <&PHY1>; -+ phy-connection-type = "rgmii"; -+ }; -+ MPIC: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0x0>; -+ #interrupt-cells = <0x2>; -+ reg = <0x40000 0x40000>; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ }; -+ global-utilities@e0000 { -+ compatible = "fsl,p2020-guts", "fsl,mpc8548-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ -+ }; -+ -+ PCI1: pcie@ff70a000 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #interrupt-cells = <0x1>; -+ #size-cells = <0x2>; -+ #address-cells = <0x3>; -+ reg = <0x0 0xff70a000 0x0 0x1000>; -+ bus-range = <0x0 0xff>; -+ ranges = <0x2000000 0x0 0xa0000000 0x0 0xa0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0x0 0xffc20000 0x0 0x00010000>; -+ clock-frequency = <0x5f5e100>; -+ interrupts = <0x1a 0x2>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0x0 0x0 0x0 0x1 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x2 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x3 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x4 &MPIC 0x0 0x1>; -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <0x2>; -+ #address-cells = <0x3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xa0000000 0x2000000 0x0 0xa0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0x1000000 0x0 0x00000000 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/accton_as5610_52x.c b/arch/powerpc/platforms/85xx/accton_as5610_52x.c -new file mode 100644 -index 0000000..a19d35f ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/accton_as5610_52x.c -@@ -0,0 +1,188 @@ -+/* -+ * Accton as5610_52x setup and early boot code plus other random bits. -+ * -+ * Copyright 2014 Cumulus Networks, 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 -+ -+#include -+#include -+ -+// #undef DEBUG -+ -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+/******************************************************************************* -+ * -+ * Platform initialization functions -+ * -+ ******************************************************************************* -+*/ -+ -+/* -+ * Initialize the interrupt controller -+ */ -+static void __init as5610_52x_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np; -+ -+ np = of_find_node_by_type(NULL, "open-pic"); -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | -+ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | -+ MPIC_SINGLE_DEST_CPU, -+ 0, 256, " OpenPIC "); -+ -+ BUG_ON(mpic == NULL); -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+#ifdef CONFIG_SMP -+extern void __init mpc85xx_smp_init(void); -+#endif -+ -+static void __init as5610_52x_setup_arch(void) -+{ -+ struct device_node *cpu; -+ const unsigned int *fp; -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ if (ppc_md.progress) -+ ppc_md.progress("as5610_52x_setup_arch()", 0); -+ -+ cpu = of_find_node_by_type(NULL, "cpu"); -+ if (cpu != 0) { -+ fp = of_get_property(cpu, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(cpu); -+ } -+ -+#ifdef CONFIG_PCI -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8548-pcie")) -+ fsl_add_bridge(np, 0); -+ } -+#endif -+ powersave_nap = 0; -+ -+#ifdef CONFIG_SMP -+ mpc85xx_smp_init(); -+#endif -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+} -+ -+static struct of_device_id __initdata as5610_52x_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ { .compatible = "gianfar", }, -+ {}, -+}; -+ -+static int __init as5610_52x_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, as5610_52x_ids, NULL); -+} -+machine_device_initcall(as5610_52x, as5610_52x_publish_devices); -+ -+static void as5610_52x_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu Pll setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init as5610_52x_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "accton,as5610_52x")) -+ return 1; -+ -+ return 0; -+} -+ -+define_machine(as5610_52x) { -+ .name = "Accton Technology Corporation AS5610_52X", -+ .probe = as5610_52x_probe, -+ .setup_arch = as5610_52x_setup_arch, -+ .init_IRQ = as5610_52x_pic_init, -+ .show_cpuinfo = as5610_52x_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = fsl_rstcr_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as6700_32x.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as6700_32x.patch deleted file mode 100644 index bbf3d883..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as6700_32x.patch +++ /dev/null @@ -1,1142 +0,0 @@ -Accton AS6700_32X - -diff --git a/arch/powerpc/boot/dts/accton_as6700_32x.dts b/arch/powerpc/boot/dts/accton_as6700_32x.dts -new file mode 100644 -index 0000000..cab8483 ---- /dev/null -+++ b/arch/powerpc/boot/dts/accton_as6700_32x.dts -@@ -0,0 +1,349 @@ -+/* -+ * Accton AS6700_32X Device Tree Source -+ * -+ * 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. -+ */ -+ -+/include/ "fsl/p2041si-pre.dtsi" -+ -+/ { -+ model = "accton,as6700_32x"; -+ compatible = "accton,as6700_32x"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ interrupt-parent = <&mpic>; -+ -+ aliases { -+ ethernet0 = &enet3; -+ ethernet1 = &enet0; -+ phy_sgmii_2 = &phy_sgmii_2; -+ phy_sgmii_1 = &phy_sgmii_1; -+ -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ -+ dcsr: dcsr@f00000000 { -+ ranges = <0x00000000 0xf 0x00000000 0x01008000>; -+ }; -+ -+ bportals: bman-portals@ff4000000 { -+ ranges = <0x0 0xf 0xf4000000 0x200000>; -+ }; -+ -+ qportals: qman-portals@ff4200000 { -+ ranges = <0x0 0xf 0xf4200000 0x200000>; -+ }; -+ -+ soc: soc@ffe000000 { -+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>; -+ reg = <0xf 0xfe000000 0 0x00001000>; -+ -+ spi@110000 { -+ flash@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "micron,n25q512"; -+ reg = <0>; -+ spi-max-frequency = <12000000>; /* input clock */ -+ partition@uboot { -+ label = "uboot"; -+ reg = <0x00000000 0x00100000>; -+ }; -+ partition@uboot-env { -+ label = "uboot-env"; -+ reg = <0x00100000 0x00010000>; -+ env_size = <0x2000>; -+ }; -+ partition@Fman-FW { -+ label = "Fman-FW"; -+ reg = <0x00110000 0x00010000>; -+ read-only; -+ }; -+ partition@board_eeprom { -+ label = "board_eeprom"; -+ reg = <0x00120000 0x00010000>; -+ }; -+ partition@onie { -+ label = "onie"; -+ reg = <0x00130000 0x00800000>; -+ }; -+ partition@diag { -+ label = "diag"; -+ reg = <0x00930000 0x02000000>; -+ }; -+ partition@reserved { -+ label = "reserved"; -+ reg = <0x02930000 0x016d0000>; -+ }; -+ }; -+ }; -+ -+ i2c@118000 { -+ fsl,preserve-clocking; -+ -+ rtc@68 { -+ compatible = "maxim,ds1672"; -+ reg = <0x68>; -+ }; -+ spd@50 { -+ compatible = "at24,spd"; -+ reg = <0x50>; -+ }; -+ }; -+ -+ i2c@118100 { -+ fsl,preserve-clocking; -+ -+ /include/ "accton_as670x_baseboard_i2c.dtsi" -+ }; -+ -+ i2c@119100 { -+ fsl,preserve-clocking; -+ -+ mux@70 { -+ compatible = "ti,pca9546"; -+ reg = <0x70>; -+ deselect-on-exit; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ temp@4d { -+ compatible = "maxim,max6581"; -+ reg = <0x4d>; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ -+ power@34 { -+ compatible = "ti,ucd9090"; -+ reg = <0x34>; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ /* Not sure what the two addr per PSU are for */ -+ /* -+ ** The eeprom utilities look for a label that -+ ** ends with "_eeprom". -+ */ -+ psu_eeprom@39 { -+ compatible = "at,24c02"; -+ reg = <0x39>; -+ /* Haven't seen this one work yet */ -+ label = "psu1_eeprom"; -+ read-only; -+ }; -+ psu_unknown@3d { -+ compatible = "at,24c02"; -+ reg = <0x3d>; -+ /* Haven't seen this one work yet */ -+ // label = "psu1_eeprom2"; -+ read-only; -+ }; -+ psu_eeprom@3a { -+ compatible = "at,24c02"; -+ reg = <0x3a>; -+ /* This one contains valid data */ -+ label = "psu2_eeprom"; -+ read-only; -+ }; -+ psu_unknown@3e { -+ compatible = "at,24c02"; -+ reg = <0x3e>; -+ /* This one is unformatted */ -+ // label = "psu2_eeprom2"; -+ read-only; -+ }; -+ }; -+ }; -+ }; -+ -+ usb1: usb@211000 { -+ dr_mode = "host"; -+ }; -+ -+ fman0: fman@400000 { -+ enet0: ethernet@e0000 { -+ tbi-handle = <&tbi0>; -+ phy-handle = <&phy_sgmii_2>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ mdio0: mdio@e1120 { -+ tbi0: tbi-phy@8 { -+ reg = <0x8>; -+ device_type = "tbi-phy"; -+ }; -+ -+ phy_sgmii_2: ethernet-phy@2 { -+ reg = <0x2>; -+ }; -+ -+ phy_sgmii_1: ethernet-phy@1 { -+ reg = <0x1>; -+ }; -+ }; -+ -+ ethernet@e4000 { -+ status = "disabled"; -+ }; -+ -+ enet3: ethernet@e6000 { -+ tbi-handle = <&tbi3>; -+ phy-handle = <&phy_sgmii_1>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ mdio@e7120 { -+ tbi3: tbi-phy@8 { -+ reg = <8>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ }; -+ }; -+ -+ rio: rapidio@ffe0c0000 { -+ reg = <0xf 0xfe0c0000 0 0x11000>; -+ -+ port1 { -+ ranges = <0 0 0xc 0x20000000 0 0x10000000>; -+ }; -+ port2 { -+ ranges = <0 0 0xc 0x30000000 0 0x10000000>; -+ }; -+ }; -+ -+ -+ lbc: localbus@ffe124000 { -+ reg = <0xf 0xfe124000 0 0x1000>; -+ ranges = <0 0 0xf 0xec000000 0x04000000>; -+ }; -+ -+ pci0: pcie@ffe200000 { -+ reg = <0xf 0xfe200000 0 0x1000>; -+ ranges = <0x02000000 0x0 0xe0000000 -+ 0x0 0xd0000000 -+ 0x0 0x08000000 -+ -+ 0x01000000 0x0 0x00000000 -+ 0x0 0xf8000000 -+ 0x0 0x00010000>; -+ pcie@0 { -+ ranges = <0x02000000 0 0xe0000000 -+ 0x02000000 0 0xe0000000 -+ 0 0x08000000 -+ -+ 0x01000000 0 0x00000000 -+ 0x01000000 0 0x00000000 -+ 0 0x00010000>; -+ }; -+ }; -+ -+ pci1: pcie@ffe201000 { -+ reg = <0xf 0xfe201000 0 0x1000>; -+ ranges = <0x02000000 0x0 0xe0000000 -+ 0x0 0xd8000000 -+ 0x0 0x08000000 -+ -+ 0x01000000 0x0 0x00000000 -+ 0x0 0xf8010000 -+ 0x0 0x00010000>; -+ pcie@0 { -+ ranges = <0x02000000 0 0xe0000000 -+ 0x02000000 0 0xe0000000 -+ 0 0x08000000 -+ -+ 0x01000000 0 0x00000000 -+ 0x01000000 0 0x00000000 -+ 0 0x00010000>; -+ }; -+ }; -+ -+ pci2: pcie@ffe202000 { -+ reg = <0xf 0xfe202000 0 0x1000>; -+ ranges = <0x02000000 0x0 0xe0000000 -+ 0x0 0xe0000000 -+ 0x0 0x08000000 -+ -+ 0x01000000 0x0 0x00000000 -+ 0x0 0xf8020000 -+ 0x0 0x00010000>; -+ -+ pcie@0 { -+ ranges = <0x02000000 0 0xe0000000 -+ 0x02000000 0 0xe0000000 -+ 0 0x08000000 -+ -+ 0x01000000 0 0x00000000 -+ 0x01000000 0 0x00000000 -+ 0 0x00010000>; -+ }; -+ }; -+ -+ fsl,dpaa { -+ compatible = "fsl,p2041-dpaa", "fsl,dpaa"; -+ -+ ethernet@0 { -+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet3>; -+ }; -+ -+ ethernet@1 { -+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet0>; -+ }; -+ }; -+}; -+ -+/include/ "fsl/p2041si-post.dtsi" -+/include/ "fsl/qoriq-dpaa-res1.dtsi" -diff --git a/arch/powerpc/boot/dts/accton_as670x_baseboard_i2c.dtsi b/arch/powerpc/boot/dts/accton_as670x_baseboard_i2c.dtsi -new file mode 100644 -index 0000000..8bd4c3a ---- /dev/null -+++ b/arch/powerpc/boot/dts/accton_as670x_baseboard_i2c.dtsi -@@ -0,0 +1,696 @@ -+/* -+ * Accton AS670X Baseboard I2C devices. -+ * -+ * Copyright 2014 Cumulus Networks, 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. -+ */ -+ -+fanpld@35 { -+ compatible = "accton,as670x_32x_fanpld"; -+ reg = <0x35>; -+}; -+ -+/* XXX - decode-syseeprom can't handle i2c nodes labeled "cpld" */ -+syspld@31 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "accton,as670x_32x_syspld"; -+ reg = <0x31>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port1"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port1_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port1_rx"; -+ }; -+ rx_retimer@19 { -+ compatible = "ti,ds100df410"; -+ reg = <0x19>; -+ label = "port21_rx"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port2"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port2_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port2_rx"; -+ }; -+ rx_retimer@19 { -+ compatible = "ti,ds100df410"; -+ reg = <0x19>; -+ label = "port22_rx"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port3"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port3_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port3_rx"; -+ }; -+ rx_retimer@19 { -+ compatible = "ti,ds100df410"; -+ reg = <0x19>; -+ label = "port23_rx"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port4"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port4_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port4_rx"; -+ }; -+ rx_retimer@19 { -+ compatible = "ti,ds100df410"; -+ reg = <0x19>; -+ label = "port24_rx"; -+ }; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port5"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port5_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port5_rx"; -+ }; -+ rx_retimer@19 { -+ compatible = "ti,ds100df410"; -+ reg = <0x19>; -+ label = "port25_rx"; -+ }; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port6"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port6_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port6_rx"; -+ }; -+ rx_retimer@19 { -+ compatible = "ti,ds100df410"; -+ reg = <0x19>; -+ label = "port26_rx"; -+ }; -+ }; -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port7"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port7_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port7_rx"; -+ }; -+ rx_retimer@19 { -+ compatible = "ti,ds100df410"; -+ reg = <0x19>; -+ label = "port27_rx"; -+ }; -+ }; -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port8"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port8_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port8_rx"; -+ }; -+ rx_retimer@19 { -+ compatible = "ti,ds100df410"; -+ reg = <0x19>; -+ label = "port28_rx"; -+ }; -+ }; -+ i2c@8 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port9"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port9_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port9_rx"; -+ }; -+ rx_retimer@19 { -+ compatible = "ti,ds100df410"; -+ reg = <0x19>; -+ label = "port29_rx"; -+ }; -+ }; -+ i2c@9 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port10"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port10_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port10_rx"; -+ }; -+ rx_retimer@19 { -+ compatible = "ti,ds100df410"; -+ reg = <0x19>; -+ label = "port30_rx"; -+ }; -+ }; -+ i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port11"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port11_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port11_rx"; -+ }; -+ rx_retimer@19 { -+ compatible = "ti,ds100df410"; -+ reg = <0x19>; -+ label = "port31_rx"; -+ }; -+ }; -+ i2c@11 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port12"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port12_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port12_rx"; -+ }; -+ rx_retimer@19 { -+ compatible = "ti,ds100df410"; -+ reg = <0x19>; -+ label = "port32_rx"; -+ }; -+ }; -+ i2c@12 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port13"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port13_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port13_rx"; -+ }; -+ }; -+ i2c@13 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port14"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port14_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port14_rx"; -+ }; -+ }; -+ i2c@14 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port15"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port15_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port15_rx"; -+ }; -+ }; -+ i2c@15 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port16"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port16_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port16_tx"; -+ }; -+ }; -+ i2c@16 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <16>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port17"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port17_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port17_rx"; -+ }; -+ }; -+ i2c@17 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <17>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port18"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port18_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port18_rx"; -+ }; -+ }; -+ i2c@18 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <18>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port19"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port19_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port19_rx"; -+ }; -+ }; -+ i2c@19 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <19>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port20"; -+ }; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x1a>; -+ label = "port20_tx"; -+ }; -+ rx_retimer@18 { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port20_rx"; -+ }; -+ }; -+ i2c@20 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <20>; -+ gpio@20 { -+ // QSFP+ discrete signals -+ compatible = "ti,pca9506"; -+ reg = <0x20>; -+ }; -+ mux@70 { -+ compatible = "ti,pca9548"; -+ reg = <0x70>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port21_tx"; -+ }; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port21"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port22_tx"; -+ }; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port22"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port23_tx"; -+ }; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port23"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port24_tx"; -+ }; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port24"; -+ }; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port25_tx"; -+ }; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port25"; -+ }; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port26_tx"; -+ }; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port26"; -+ }; -+ }; -+ }; -+ }; -+ i2c@21 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <21>; -+ gpio@20 { -+ // QSFP+ discrete signals -+ compatible = "ti,pca9506"; -+ reg = <0x20>; -+ }; -+ mux@70 { -+ compatible = "ti,pca9548"; -+ reg = <0x70>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port27_tx"; -+ }; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port27"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port28_tx"; -+ }; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port28"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port29_tx"; -+ }; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port29"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port30_tx"; -+ }; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port30"; -+ }; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port31_tx"; -+ }; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port31"; -+ }; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ tx_retimer@1a { -+ compatible = "ti,ds100df410"; -+ reg = <0x18>; -+ label = "port32_tx"; -+ }; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port32"; -+ }; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/accton_as6700_32x.c b/arch/powerpc/platforms/85xx/accton_as6700_32x.c -new file mode 100644 -index 0000000..c3c4474 ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/accton_as6700_32x.c -@@ -0,0 +1,77 @@ -+/* -+ * Accton AS6700_32X Setup -+ * -+ * Copyright 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. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "corenet_ds.h" -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init accton_as6700_32x_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "accton,as6700_32x")) -+ return 1; -+ -+ return 0; -+} -+ -+static void __init accton_as6700_32x_setup_arch(void) { -+ corenet_ds_setup_arch(); -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+} -+ -+ -+define_machine(accton_as6700_32x) { -+ .name = "Accton AS6700_32X", -+ .probe = accton_as6700_32x_probe, -+ .setup_arch = accton_as6700_32x_setup_arch, -+ .init_IRQ = corenet_ds_pic_init, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_coreint_irq, -+ .restart = fsl_rstcr_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+ .power_save = e500_idle, -+ .init_early = corenet_ds_init_early, -+}; -+ -+machine_device_initcall(accton_as6700_32x, corenet_ds_publish_devices); -+ -+#ifdef CONFIG_SWIOTLB -+machine_arch_initcall(accton_as6700_32x, swiotlb_setup_bus_notifier); -+#endif diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as6701-32x.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as6701-32x.patch deleted file mode 100644 index 0b1f6232..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as6701-32x.patch +++ /dev/null @@ -1,436 +0,0 @@ -Platform Accton AS6701-32X patch - -Support for the Accton AS6701-32X networking platform. - -diff --git a/arch/powerpc/boot/dts/accton_as6701_32x.dts b/arch/powerpc/boot/dts/accton_as6701_32x.dts -new file mode 100644 -index 0000000..2d21e97 ---- /dev/null -+++ b/arch/powerpc/boot/dts/accton_as6701_32x.dts -@@ -0,0 +1,237 @@ -+/* -+ * Accton Technology AS6701_32X Device Tree Source -+ * -+ * 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/ "p2020si.dtsi" -+ -+/ { -+ model = "accton,as6701_32x"; -+ compatible = "accton,as6701_32x"; -+ -+ aliases { -+ ethernet0 = &enet1; -+ serial0 = &serial0; -+ pci2 = &pci2; -+ }; -+ memory { -+ device_type = "memory"; -+ }; -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ localbus@ffe05000 { -+ ranges = <0x0 0x0 0x0 0xec000000 0x04000000>; -+ flash@0,0 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x04000000>; -+ bank-width = <0x2>; -+ device-width = <0x2>; -+ partition@0 { -+ reg = <0x00000000 0x00020000>; -+ label = "Reserved P0"; -+ }; -+ partition@1 { -+ reg = <0x00020000 0x00020000>; -+ label = "board_eeprom"; -+ }; -+ partition@2 { -+ reg = <0x00040000 0x00d00000>; -+ label = "onie"; -+ }; -+ partition@3 { -+ reg = <0x00d40000 0x02000000>; -+ label = "diag"; -+ }; -+ partition@4 { -+ reg = <0x02d40000 0x01200000>; -+ label = "open"; -+ }; -+ partition@5 { -+ reg = <0x03f40000 0x00020000>; -+ label = "Reserved P5"; -+ }; -+ partition@6 { -+ reg = <0x03f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@7 { -+ reg = <0x03f80000 0x00080000>; -+ label = "uboot"; -+ read-only; -+ }; -+ }; -+ }; -+ -+ soc@ffe00000 { -+ i2c@3000 { -+ fsl,preserve-clocking; -+ -+ mux@70 { -+ compatible = "ti,pca9548"; -+ reg = <0x70>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ rtc@51 { -+ compatible = "epson,rtc8564"; -+ reg = <0x51>; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ -+ spd_eeprom@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ /* Not sure what the two addr per PSU are for */ -+ /* -+ ** The eeprom utilities look for a label that -+ ** ends with "_eeprom". -+ */ -+ psu_eeprom@39 { -+ compatible = "at,24c02"; -+ reg = <0x39>; -+ /* Haven't seen this one work yet */ -+ label = "psu1_eeprom"; -+ read-only; -+ }; -+ psu_unknown@3d { -+ compatible = "at,24c02"; -+ reg = <0x3d>; -+ /* Haven't seen this one work yet */ -+ // label = "psu1_eeprom2"; -+ read-only; -+ }; -+ psu_eeprom@3a { -+ compatible = "at,24c02"; -+ reg = <0x3a>; -+ /* This one contains valid data */ -+ label = "psu2_eeprom"; -+ read-only; -+ }; -+ psu_unknown@3e { -+ compatible = "at,24c02"; -+ reg = <0x3e>; -+ /* This one is unformatted */ -+ // label = "psu2_eeprom2"; -+ read-only; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ -+ temp@4d { -+ compatible = "maxim,max6581"; -+ reg = <0x4d>; -+ }; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ -+ // SMSC USB2513i - USB Hub. -+ // Handled by u-boot, leave blank here. -+ // addr 0x2C -+ }; -+ }; -+ }; -+ i2c@3100 { -+ fsl,preserve-clocking; -+ -+ /include/ "accton_as670x_baseboard_i2c.dtsi" -+ }; -+ serial1: serial@4600 { -+ status = "disabled"; -+ }; -+ -+ usb@22000 { -+ status = "disabled"; -+ phy_type = "ulpi"; -+ dr_mode = "host"; -+ }; -+ -+ mdio@24520 { -+ phy0: ethernet-phy@1 { -+ reg = <0x1>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ -+ enet0: ethernet@24000 { -+ status = "disabled"; -+ }; -+ -+ enet1: ethernet@25000 { -+ phy-handle = <&phy0>; -+ tbi-handle = <&tbi0>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ mdio@25520 { -+ tbi0: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ enet2: ethernet@26000 { -+ status = "disabled"; -+ }; -+ }; -+ -+ pci0: pcie@ffe08000 { -+ status = "disabled"; -+ }; -+ -+ pci1: pcie@ffe09000 { -+ status = "disabled"; -+ }; -+ -+ pci2: pcie@ffe0a000 { -+ ranges = <0x2000000 0x0 0x80000000 0x0 0x80000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x00010000>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0x0 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0x0 0x0 0x0 0x2 &mpic 0x1 0x1 -+ 0x0 0x0 0x0 0x3 &mpic 0x2 0x1 -+ 0x0 0x0 0x0 0x4 &mpic 0x3 0x1>; -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <0x2>; -+ #address-cells = <0x3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0x80000000 0x2000000 0x0 0x80000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0x1000000 0x0 0x00000000 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/accton_as6701_32x.c b/arch/powerpc/platforms/85xx/accton_as6701_32x.c -new file mode 100644 -index 0000000..aba43c3 ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/accton_as6701_32x.c -@@ -0,0 +1,183 @@ -+/* -+ * Accton AS6701-32X setup and early boot code plus other random bits. -+ * -+ * 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 -+ -+#include -+#include -+ -+// #undef DEBUG -+ -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+/******************************************************************************* -+ * -+ * Platform initialization functions -+ * -+ ******************************************************************************* -+*/ -+ -+/* -+ * Initialize the interrupt controller -+ */ -+static void __init as6701_32x_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np; -+ -+ np = of_find_node_by_type(NULL, "open-pic"); -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | -+ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | -+ MPIC_SINGLE_DEST_CPU, -+ 0, 256, " OpenPIC "); -+ -+ BUG_ON(mpic == NULL); -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+#ifdef CONFIG_SMP -+extern void __init mpc85xx_smp_init(void); -+#endif -+ -+static void __init as6701_32x_setup_arch(void) -+{ -+ struct device_node *cpu; -+ const unsigned int *fp; -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ -+ cpu = of_find_node_by_type(NULL, "cpu"); -+ if (cpu != 0) { -+ fp = of_get_property(cpu, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(cpu); -+ } -+ -+#ifdef CONFIG_PCI -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8548-pcie")) -+ fsl_add_bridge(np, 0); -+ } -+#endif -+ powersave_nap = 0; -+ -+#ifdef CONFIG_SMP -+ mpc85xx_smp_init(); -+#endif -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+} -+ -+static struct of_device_id __initdata as6701_32x_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ { .compatible = "gianfar", }, -+ {}, -+}; -+ -+static int __init as6701_32x_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, as6701_32x_ids, NULL); -+} -+machine_device_initcall(as6701_32x, as6701_32x_publish_devices); -+ -+static void as6701_32x_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu Pll setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init as6701_32x_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "accton,as6701_32x")) -+ return 1; -+ -+ return 0; -+} -+ -+define_machine(as6701_32x) { -+ .name = "Accton Technology Corporation AS6701-32X", -+ .probe = as6701_32x_probe, -+ .setup_arch = as6701_32x_setup_arch, -+ .init_IRQ = as6701_32x_pic_init, -+ .show_cpuinfo = as6701_32x_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = fsl_rstcr_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-bcm98548xmc-fix-reset-init.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-bcm98548xmc-fix-reset-init.patch deleted file mode 100644 index 62711f40..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-bcm98548xmc-fix-reset-init.patch +++ /dev/null @@ -1,54 +0,0 @@ -Move reset register setup from an arch_init call to within the machine setup -function. - -diff --git a/arch/powerpc/platforms/85xx/bcm98548xmc.c b/arch/powerpc/platforms/85xx/bcm98548xmc.c -index 79d4e92..392f231 100644 ---- a/arch/powerpc/platforms/85xx/bcm98548xmc.c -+++ b/arch/powerpc/platforms/85xx/bcm98548xmc.c -@@ -114,6 +114,18 @@ static int __init bcm98548xmc_publish_devices(void) - } - machine_device_initcall(bcm98548xmc, bcm98548xmc_publish_devices); - -+static __be32 __iomem *rstcr; -+static __be32 __iomem *rstdr; -+ -+static int __init bcm98548xmc_init_rstcr(void) -+{ -+ /* map reset control register */ -+ printk(KERN_INFO "bcm98548xmc : map reset control register.\n"); -+ rstdr = ioremap(get_immrbase() + 0xE0040, 0xff); -+ rstcr = ioremap(get_immrbase() + 0xE0030, 0xff); -+ return 0; -+} -+ - /* - * Setup the architecture - */ -@@ -151,6 +163,8 @@ static void __init bcm98548xmc_setup_arch(void) - #endif - - powersave_nap = 0; -+ -+ bcm98548xmc_init_rstcr(); - } - - static void bcm98548xmc_show_cpuinfo(struct seq_file *m) -@@ -173,18 +187,6 @@ static void bcm98548xmc_show_cpuinfo(struct seq_file *m) - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); - } - --static __be32 __iomem *rstcr; --static __be32 __iomem *rstdr; --static int __init bcm98548xmc_init_rstcr(void) --{ -- /* map reset control register */ -- printk(KERN_INFO "bcm98548xmc : map reset control register.\n"); -- rstdr = ioremap(get_immrbase() + 0xE0040, 0xff); -- rstcr = ioremap(get_immrbase() + 0xE0030, 0xff); -- return 0; --} --arch_initcall(bcm98548xmc_init_rstcr); -- - void bcm98548xmc_restart(char *cmd) - { - local_irq_disable(); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-bcm98548xmc.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-bcm98548xmc.patch deleted file mode 100644 index 4fc72c86..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-bcm98548xmc.patch +++ /dev/null @@ -1,580 +0,0 @@ - - -diff --git a/arch/powerpc/boot/dts/bcm98548xmc.dts b/arch/powerpc/boot/dts/bcm98548xmc.dts -new file mode 100644 -index 0000000..98b35a6 ---- /dev/null -+++ b/arch/powerpc/boot/dts/bcm98548xmc.dts -@@ -0,0 +1,338 @@ -+/* -+ * BCM98548XMC Device Tree Source -+ * -+ * Copyright 2008 Wind River System 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/; -+ -+/ { -+ model = "bcm,bcm98548xmc"; -+ compatible = "bcm,BCM98548XMC"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ cpus { -+ #cpus = <1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8548@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ d-cache-line-size = <32>; // 32 bytes -+ i-cache-line-size = <32>; // 32 bytes -+ d-cache-size = <0x8000>; // L1, 32K -+ i-cache-size = <0x8000>; // L1, 32K -+ timebase-frequency = <0x2f90838>; -+ bus-frequency = <0x17c841c0>; -+ clock-frequency = <0x3b74a460>; -+ next-level-cache = <&L2>; -+ 32-bit; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <00000000 0x20000000>; // 512M at 0x0 -+ }; -+ -+ chosen { -+ name = "chosen"; -+ bootargs = "console=ttyS0,9600 "; -+ linux,initrd-start = <0>; -+ linux,initrd-end = <0>; -+ }; -+ soc8548@e0000000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ #interrupt-cells = <2>; -+ device_type = "soc"; -+ ranges = <00000000 0xe0000000 0x00100000>; -+ reg = <0xe0000000 0x00100000>; // CCSRBAR -+ bus-frequency = <0x17c841c0>; -+ -+ memory-controller@2000 { -+ compatible = "fsl,mpc8548-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <18 2>; -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,mpc8548-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x80000>; // L2, 512K -+ interrupt-parent = <&mpic>; -+ interrupts = <16 2>; -+ }; -+ -+ mpic: pic@40000 { -+ clock-frequency = <0x17c841c0>; -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ reg = <0x40000 0x40000>; -+ built-in; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ big-endian; -+ }; -+ -+ msi@41600 { -+ compatible = "fsl,mpic-msi"; -+ reg = <0x41600 0x80>; -+ msi-available-ranges = <0 0x100>; -+ interrupts = < -+ 0x3c 0 -+ 0x3d 0 -+ 0x3e 0 -+ 0x3f 0 -+ 0x40 0 -+ 0x41 0 -+ 0x42 0 -+ 0x43 0>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ mdio@24520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ device_type = "mdio"; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ phy0: ethernet-phy@0 { -+ reg = <0x1>; -+ device_type = "ethernet-phy"; -+ }; -+ phy1: ethernet-phy@1 { -+ reg = <0x2>; -+ device_type = "ethernet-phy"; -+ }; -+ phy2: ethernet-phy@2 { -+ reg = <0x3>; -+ device_type = "ethernet-phy"; -+ }; -+ phy3: ethernet-phy@3 { -+ reg = <0x4>; -+ device_type = "ethernet-phy"; -+ }; -+ tbi0: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ ethernet@24000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x24000 0x1000>; -+ local-mac-address = [ 00 01 85 48 e0 10 ]; -+ interrupts = <13 2 14 2 18 2>; -+ interrupt-parent = <&mpic>; -+ phy-handle = <&phy0>; -+ }; -+ -+ ethernet@25000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x25000 0x1000>; -+ local-mac-address = [ 00 01 85 48 e1 10 ]; -+ interrupts = <19 2 20 2 24 2>; -+ interrupt-parent = <&mpic>; -+ phy-handle = <&phy1>; -+ }; -+ -+ ethernet@26000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x26000 0x1000>; -+ local-mac-address = [ 00 01 85 48 e2 10 ]; -+ interrupts = <15 2 16 2 17 2>; -+ interrupt-parent = <&mpic>; -+ phy-handle = <&phy2>; -+ }; -+ -+ ethernet@27000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x27000 0x1000>; -+ local-mac-address = [ 00 01 85 48 e2 10 ]; -+ interrupts = <5 2 22 2 23 2>; -+ interrupt-parent = <&mpic>; -+ phy-handle = <&phy3>; -+ }; -+ -+ serial@4500 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; // reg base, size -+ clock-frequency = <0x17c841c0>; -+ interrupts = <26 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ serial@4600 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4600 0x100>; // reg base, size -+ clock-frequency = <0x17c841c0>; -+ interrupts = <26 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <27 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ rtc@68 { -+ compatible = "rtc,m41t81"; -+ reg = <0x68>; -+ }; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <27 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ }; -+ -+ }; -+ -+ pci@e0008000 { -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x12 (AD[18]) on BCM956820 boards */ -+ 0x9000 0x0 0x0 0x1 &mpic 0x30 0x1 -+ /* IDSEL 0x1e (AD[30]) on BCM956636 boards */ -+ 0xf000 0x0 0x0 0x1 &mpic 0x30 0x1>; -+ -+ interrupt-parent = <&mpic>; -+ interrupts = <24 2>; -+ bus-range = <0 0>; -+ ranges = <0x02000000 0x0 0x50000000 0x50000000 0x0 0x10000000 -+ 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x04000000>; -+ clock-frequency = <0x3b74a460>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0xe0008000 0x1000>; -+ compatible = "85xx"; -+ device_type = "pci"; -+ -+ }; -+ -+ /* PCI Express */ -+ pcie@e000a000 { -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ -+ /* IDSEL 0x0 (PEX) */ -+ 00000 0x0 0x0 0x1 &mpic 0x30 0x1 -+ 00000 0x0 0x0 0x2 &mpic 0x31 0x1 -+ 00000 0x0 0x0 0x3 &mpic 0x32 0x1 -+ 00000 0x0 0x0 0x4 &mpic 0x33 0x1>; -+ -+ interrupt-parent = <&mpic>; -+ interrupts = <0xa 0x2>; -+ bus-range = <0x80 0xff>; -+ ranges = <0x02000000 0x0 0x60000000 0x60000000 0x0 0x10000000 -+ 0x01000000 0x0 0x00000000 0xe8000000 0x0 0x10000000>; -+ clock-frequency = <33333333>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0xe000a000 0x1000>; -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ }; -+ -+ localbus@0xe0005000 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,elbc", "simple-bus"; -+ reg = <0xe0005000 0x1000>; -+ interrupt-parent = <&mpic>; -+ -+ ranges = <0x0 0x0 0xf0000000 0x08000000 -+ 0x1 0x0 0xf8000000 0x08000000>; -+ -+ flash@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x08000000>; -+ bank-width = <2>; -+ device-width = <1>; -+ -+ partition@0 { -+ label = "kernel"; -+ reg = <0x00000000 0x003e0000>; -+ }; -+ partition@1 { -+ label = "device-tree"; -+ reg = <0x003e0000 0x00020000>; -+ }; -+ partition@2 { -+ label = "root-overlay"; -+ reg = <0x00400000 0x07b00000>; -+ }; -+ partition@3 { -+ label = "recovery-cfe-bootloader"; -+ reg = <0x07f00000 0x00100000>; -+ readonly; -+ }; -+ }; -+ -+ flash@1,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x1 0x0 0x08000000>; -+ bank-width = <2>; -+ device-width = <1>; -+ -+ partition@0 { -+ label = "root"; -+ reg = <0x00000000 0x07f00000>; -+ }; -+ partition@1 { -+ label = "root-ro"; -+ reg = <0x00000000 0x07f00000>; -+ }; -+ partition@2 { -+ label = "cfe-bootloader"; -+ reg = <0x07f00000 0x00100000>; -+ readonly; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/bcm98548xmc.c b/arch/powerpc/platforms/85xx/bcm98548xmc.c -new file mode 100644 -index 0000000..79d4e92 ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/bcm98548xmc.c -@@ -0,0 +1,228 @@ -+/* -+ * MPC85xx setup and early boot code plus other random bits. -+ * -+ * Maintained by Kumar Gala (see MAINTAINERS for contact information) -+ * -+ * Copyright 2005 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 -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifndef CONFIG_PCI -+unsigned long isa_io_base = 0; -+unsigned long isa_mem_base = 0; -+#endif -+ -+static void __init bcm98548xmc_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np = NULL; -+ -+ np = of_find_node_by_type(np, "open-pic"); -+ -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, -+ 4, 0, " OpenPIC "); -+ BUG_ON(mpic == NULL); -+ -+ /* Return the mpic node */ -+ of_node_put(np); -+ -+ mpic_assign_isu(mpic, 0, r.start + 0x10200); -+ mpic_assign_isu(mpic, 1, r.start + 0x10280); -+ mpic_assign_isu(mpic, 2, r.start + 0x10300); -+ mpic_assign_isu(mpic, 3, r.start + 0x10380); -+ mpic_assign_isu(mpic, 4, r.start + 0x10400); -+ mpic_assign_isu(mpic, 5, r.start + 0x10480); -+ mpic_assign_isu(mpic, 6, r.start + 0x10500); -+ mpic_assign_isu(mpic, 7, r.start + 0x10580); -+ -+ /* Used only for 8548 so far, but no harm in -+ * allocating them for everyone */ -+ mpic_assign_isu(mpic, 8, r.start + 0x10600); -+ mpic_assign_isu(mpic, 9, r.start + 0x10680); -+ mpic_assign_isu(mpic, 10, r.start + 0x10700); -+ mpic_assign_isu(mpic, 11, r.start + 0x10780); -+ -+ /* External Interrupts */ -+ mpic_assign_isu(mpic, 12, r.start + 0x10000); -+ mpic_assign_isu(mpic, 13, r.start + 0x10080); -+ mpic_assign_isu(mpic, 14, r.start + 0x10100); -+ -+ mpic_init(mpic); -+ -+} -+ -+static struct of_device_id __initdata bcm98548xmc_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ {}, -+}; -+ -+static int __init bcm98548xmc_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, bcm98548xmc_ids, NULL); -+} -+machine_device_initcall(bcm98548xmc, bcm98548xmc_publish_devices); -+ -+/* -+ * Setup the architecture -+ */ -+static void __init bcm98548xmc_setup_arch(void) -+{ -+ struct device_node *cpu; -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ -+ if (ppc_md.progress) -+ ppc_md.progress("bcm98548xmc_setup_arch()", 0); -+ -+ cpu = of_find_node_by_type(NULL, "cpu"); -+ if (cpu != 0) { -+ const unsigned int *fp; -+ -+ fp = of_get_property(cpu, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(cpu); -+ } -+ -+#ifdef CONFIG_PCI -+ for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) { -+ struct resource rsrc; -+ of_address_to_resource(np, 0, &rsrc); -+ if ((rsrc.start & 0xfffff) == 0x8000) -+ fsl_add_bridge(np, 1); -+ else -+ fsl_add_bridge(np, 0); -+ } -+#endif -+ -+ powersave_nap = 0; -+} -+ -+static void bcm98548xmc_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu Pll setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+static __be32 __iomem *rstcr; -+static __be32 __iomem *rstdr; -+static int __init bcm98548xmc_init_rstcr(void) -+{ -+ /* map reset control register */ -+ printk(KERN_INFO "bcm98548xmc : map reset control register.\n"); -+ rstdr = ioremap(get_immrbase() + 0xE0040, 0xff); -+ rstcr = ioremap(get_immrbase() + 0xE0030, 0xff); -+ return 0; -+} -+arch_initcall(bcm98548xmc_init_rstcr); -+ -+void bcm98548xmc_restart(char *cmd) -+{ -+ local_irq_disable(); -+ if (rstcr && rstdr) { -+ /* set reset control register */ -+ out_be32(rstdr, ~0x0); /* HRESET_REQ */ -+ out_be32(rstcr, 0x200); /* HRESET_REQ */ -+ out_be32(rstdr, ~0x1); /* HRESET_REQ */ -+ out_be32(rstdr, ~0x3); /* HRESET_REQ */ -+ } else -+ printk (KERN_EMERG "Error: reset control register not mapped." -+ "Please power cycle board manually!\n"); -+ while(1); -+} -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init bcm98548xmc_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "bcm,BCM98548XMC")) { -+ return 1; -+ } -+ -+ return 0; -+} -+ -+define_machine(bcm98548xmc) { -+ .name = "BCM98548 XMC", -+ .probe = bcm98548xmc_probe, -+ .setup_arch = bcm98548xmc_setup_arch, -+ .init_IRQ = bcm98548xmc_pic_init, -+ .show_cpuinfo = bcm98548xmc_show_cpuinfo, -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = bcm98548xmc_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-cel-p2020.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-cel-p2020.patch deleted file mode 100644 index 2676fc21..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-cel-p2020.patch +++ /dev/null @@ -1,2151 +0,0 @@ - - -diff --git a/arch/powerpc/boot/dts/cel_kennisis.dts b/arch/powerpc/boot/dts/cel_kennisis.dts -new file mode 100644 -index 0000000..49e24b4 ---- /dev/null -+++ b/arch/powerpc/boot/dts/cel_kennisis.dts -@@ -0,0 +1,243 @@ -+/* -+ * Celestica Kennesis Device Tree Source -+ * -+ * Copyright 2013 Cumulus Networks, 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/ "p2020si.dtsi" -+ -+/ { -+ model = "cel,kennisis"; -+ compatible = "cel,kennisis"; -+ -+ aliases { -+ ethernet0 = &enet1; -+ serial0 = &serial0; -+ pci2 = &pci2; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ -+ localbus@ffe05000 { -+ /* NOR and NAND Flashes, CPLD */ -+ ranges = <0x0 0x0 0x0 0xec000000 0x04000000 -+ 0x1 0x0 0x0 0xffa00000 0x00100000 -+ 0x2 0x0 0x0 0xffb00000 0x00100000>; -+ -+ nor@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x04000000>; -+ bank-width = <2>; -+ device-width = <1>; -+ -+ partition@0 { -+ /* Entire flash minus (u-boot + onie) */ -+ reg = <0x00000000 0x03b60000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x03b60000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x03f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ /* 512KB u-boot */ -+ reg = <0x03f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ -+ nand@1,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,p2020-fcm-nand", -+ "fsl,elbc-fcm-nand"; -+ reg = <0x1 0x0 0x40000>; -+ -+ partition@0 { -+ reg = <0x0 0x40000000>; -+ label = "open2"; -+ }; -+ }; -+ -+ CPLD@2,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cel,kennisis-cpld"; -+ reg = <0x2 0x0 0x40000>; -+ }; -+ }; -+ -+ soc@ffe00000 { -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ fsl,preserve-clocking; -+ -+ rtc@68 { -+ compatible = "dallas,ds1337"; -+ reg = <0x68>; -+ }; -+ board_eeprom@50 { -+ compatible = "at,24c64"; -+ reg = <0x50>; -+ label = "board_eeprom"; -+ }; -+ temp_ambient2@4b { -+ compatible = "nxp,lm75a"; -+ reg = <0x4b>; -+ interrupt-parent = <&mpic>; -+ interrupts = <3 3>; -+ }; -+ temp_bcm@4d { -+ compatible = "nxp,lm75a"; -+ reg = <0x4d>; -+ interrupt-parent = <&mpic>; -+ interrupts = <3 3>; -+ }; -+ psu_eeprom@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ label = "psu2_eeprom"; -+ read-only; -+ }; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ fsl,preserve-clocking; -+ -+ pwm@4d { -+ compatible = "smsc,emc2305"; -+ reg = <0x4d>; -+ interrupt-parent = <&mpic>; -+ interrupts = <2 3>; -+ }; -+ temp_ambient1@4f { -+ compatible = "nxp,lm75a"; -+ reg = <0x4f>; -+ interrupt-parent = <&mpic>; -+ interrupts = <3 3>; -+ }; -+ temp_systemoutlet@4e { -+ compatible = "nxp,lm75a"; -+ reg = <0x4e>; -+ interrupt-parent = <&mpic>; -+ interrupts = <3 3>; -+ }; -+ temp_p2020@48 { -+ compatible = "nxp,lm75a"; -+ reg = <0x48>; -+ interrupt-parent = <&mpic>; -+ interrupts = <3 3>; -+ }; -+ power@60 { -+ compatible = "ons,ncp4200"; -+ reg = <0x60>; -+ }; -+ psu_eeprom@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ label = "psu1_eeprom"; -+ read-only; -+ }; -+ }; -+ -+ serial1: serial@4600 { -+ status = "disabled"; -+ }; -+ -+ usb@22000 { -+ phy_type = "ulpi"; -+ }; -+ -+ mdio@24520 { -+ phy0: ethernet-phy@3 { -+ reg = <0x3>; -+ }; -+ }; -+ -+ mdio@25520 { -+ tbi0: tbi-phy@11 { -+ reg = <0x10>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ enet0: ethernet@24000 { -+ status = "disabled"; -+ }; -+ -+ enet1: ethernet@25000 { -+ tbi-handle = <&tbi0>; -+ phy-handle = <&phy0>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ enet2: ethernet@26000 { -+ status = "disabled"; -+ }; -+ -+ sdhci@2e000 { -+ status = "disabled"; -+ }; -+ }; -+ -+ pci0: pcie@ffe08000 { -+ status = "disabled"; -+ }; -+ -+ pci1: pcie@ffe09000 { -+ status = "disabled"; -+ }; -+ -+ pci2: pcie@ffe0a000 { -+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 -+ >; -+ -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xa0000000 -+ 0x2000000 0x0 0xa0000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/cel_redstone.dts b/arch/powerpc/boot/dts/cel_redstone.dts -new file mode 100644 -index 0000000..4716020 ---- /dev/null -+++ b/arch/powerpc/boot/dts/cel_redstone.dts -@@ -0,0 +1,923 @@ -+/* -+ * Celestica Redstone Device Tree Source -+ * -+ * Copyright 2013 Cumulus Networks, 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/ "p2020si.dtsi" -+ -+/ { -+ model = "cel,redstone"; -+ compatible = "cel,redstone"; -+ -+ aliases { -+ ethernet0 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci2 = &pci2; -+ }; -+ -+ cpus { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ PowerPC,P2020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <0x1>; -+ }; -+ PowerPC,P2020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <0x1>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ -+ localbus@ffe05000 { -+ /* NOR and NAND Flashes, CPLD */ -+ ranges = <0x0 0x0 0x0 0xec000000 0x04000000 -+ 0x1 0x0 0x0 0xffa00000 0x00100000 -+ 0x2 0x0 0x0 0xffb80000 0x00020000 -+ 0x3 0x0 0x0 0xffb00000 0x00000400 -+ 0x4 0x0 0x0 0xffb40000 0x00000400>; -+ -+ nor@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x04000000>; -+ bank-width = <2>; -+ device-width = <1>; -+ -+ partition@0 { -+ /* Entire flash minus (u-boot + onie) */ -+ reg = <0x00000000 0x03b60000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x03b60000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x03f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ /* 512KB u-boot */ -+ reg = <0x03f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ -+ nand@1,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,p2020-fcm-nand", -+ "fsl,elbc-fcm-nand"; -+ reg = <0x1 0x0 0x40000>; -+ -+ partition@0 { -+ reg = <0x0 0x40000000>; -+ label = "open2"; -+ }; -+ }; -+ lpsram@2,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "redstone_lpsram"; -+ reg = <0x2 0x0 0x20000>; -+ -+ partition@0 { -+ reg = <0x0 0x20000>; -+ label = "open3"; -+ }; -+ }; -+ CPLD1@3,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "redstone_cpld1"; -+ label = "cpld_1"; -+ reg = <0x3 0x0 0x400>; -+ }; -+ CPLD234@4,0 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "redstone_cpld234"; -+ label = "cpld_234"; -+ reg = <0x4 0x0 0x400>; -+ cpld_i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "cel,cpld-i2c-bus"; -+ reg = <0x4 0x10 0x30>; -+ clock-frequency = <100000>; -+ cel_cpld,timeout = <10000>; -+ mux@1 { -+ compatible = "cel,cpld-i2c-mux"; -+ reg = <0x1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ /* SFP+ 1 */ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port1"; -+ }; -+ }; -+ /* SFP+ 2 */ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port2"; -+ }; -+ }; -+ /* SFP+ 3 */ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port3"; -+ }; -+ }; -+ /* SFP+ 4 */ -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port4"; -+ }; -+ }; -+ /* SFP+ 5 */ -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port5"; -+ }; -+ }; -+ /* SFP+ 6 */ -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port6"; -+ }; -+ }; -+ /* SFP+ 7 */ -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port7"; -+ }; -+ }; -+ /* SFP+ 8 */ -+ i2c@8 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port8"; -+ }; -+ }; -+ /* SFP+ 9 */ -+ i2c@9 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port9"; -+ }; -+ }; -+ /* SFP+ 10 */ -+ i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port10"; -+ }; -+ }; -+ /* SFP+ 11 */ -+ i2c@11 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port11"; -+ }; -+ }; -+ /* SFP+ 12 */ -+ i2c@12 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port12"; -+ }; -+ }; -+ /* SFP+ 13 */ -+ i2c@13 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port13"; -+ }; -+ }; -+ /* SFP+ 14 */ -+ i2c@14 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port14"; -+ }; -+ }; -+ /* SFP+ 15 */ -+ i2c@15 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port15"; -+ }; -+ }; -+ /* SFP+ 16 */ -+ i2c@16 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <16>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port16"; -+ }; -+ }; -+ /* SFP+ 17 */ -+ i2c@17 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <17>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port17"; -+ }; -+ }; -+ /* SFP+ 18 */ -+ i2c@18 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <18>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port18"; -+ }; -+ }; -+ }; -+ }; -+ cpld_i2c@40 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "cel,cpld-i2c-bus"; -+ reg = <0x4 0x40 0x30>; -+ clock-frequency = <100000>; -+ cel_cpld,timeout = <10000>; -+ mux@2 { -+ compatible = "cel,cpld-i2c-mux"; -+ reg = <0x2>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ /* SFP+ 19 */ -+ i2c@19 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <19>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port19"; -+ }; -+ }; -+ /* SFP+ 20 */ -+ i2c@20 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <20>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port20"; -+ }; -+ }; -+ /* SFP+ 21 */ -+ i2c@21 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <21>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port21"; -+ }; -+ }; -+ /* SFP+ 22 */ -+ i2c@22 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <22>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port22"; -+ }; -+ }; -+ /* SFP+ 23 */ -+ i2c@23 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <23>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port23"; -+ }; -+ }; -+ /* SFP+ 24 */ -+ i2c@24 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <24>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port24"; -+ }; -+ }; -+ /* SFP+ 25 */ -+ i2c@25 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <25>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port25"; -+ }; -+ }; -+ /* SFP+ 26 */ -+ i2c@26 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <26>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port26"; -+ }; -+ }; -+ /* SFP+ 27 */ -+ i2c@27 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <27>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port27"; -+ }; -+ }; -+ /* SFP+ 28 */ -+ i2c@28 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <28>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port28"; -+ }; -+ }; -+ /* SFP+ 29 */ -+ i2c@29 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <29>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port29"; -+ }; -+ }; -+ /* SFP+ 30 */ -+ i2c@30 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <30>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port30"; -+ }; -+ }; -+ /* SFP+ 31 */ -+ i2c@31 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <31>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port31"; -+ }; -+ }; -+ /* SFP+ 32 */ -+ i2c@32 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <32>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port32"; -+ }; -+ }; -+ /* SFP+ 33 */ -+ i2c@33 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <33>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port33"; -+ }; -+ }; -+ /* SFP+ 34 */ -+ i2c@34 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <34>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port34"; -+ }; -+ }; -+ /* SFP+ 35 */ -+ i2c@35 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <35>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port35"; -+ }; -+ }; -+ /* SFP+ 36 */ -+ i2c@36 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <36>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port36"; -+ }; -+ }; -+ }; -+ }; -+ cpld_i2c@80 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <2>; -+ compatible = "cel,cpld-i2c-bus"; -+ reg = <0x4 0x80 0x30>; -+ clock-frequency = <100000>; -+ cel_cpld,timeout = <10000>; -+ mux@3 { -+ compatible = "cel,cpld-i2c-mux"; -+ reg = <0x3>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ /* SFP+ 37 */ -+ i2c@37 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <37>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port37"; -+ }; -+ }; -+ /* SFP+ 38 */ -+ i2c@38 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <38>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port38"; -+ }; -+ }; -+ /* SFP+ 39 */ -+ i2c@39 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <39>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port39"; -+ }; -+ }; -+ /* SFP+ 40 */ -+ i2c@40 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <40>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port40"; -+ }; -+ }; -+ /* SFP+ 41 */ -+ i2c@41 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <41>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port41"; -+ }; -+ }; -+ /* SFP+ 42 */ -+ i2c@42 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <42>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port42"; -+ }; -+ }; -+ /* SFP+ 43 */ -+ i2c@43 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <43>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port43"; -+ }; -+ }; -+ /* SFP+ 44 */ -+ i2c@44 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <44>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port44"; -+ }; -+ }; -+ /* SFP+ 45 */ -+ i2c@45 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <45>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port45"; -+ }; -+ }; -+ /* SFP+ 46 */ -+ i2c@46 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <46>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port46"; -+ }; -+ }; -+ /* SFP+ 47 */ -+ i2c@47 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <47>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port47"; -+ }; -+ }; -+ /* SFP+ 48 */ -+ i2c@48 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <48>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port48"; -+ }; -+ }; -+ /* QSFP 1 */ -+ i2c@49 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <49>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port49"; -+ }; -+ }; -+ /* QSFP 2 */ -+ i2c@50 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <50>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port50"; -+ }; -+ }; -+ /* QSFP 3 */ -+ i2c@51 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <51>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port51"; -+ }; -+ }; -+ /* QSFP 4 */ -+ i2c@52 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <52>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port52"; -+ }; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ soc@ffe00000 { -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl-i2c"; -+ fsl,preserve-clocking; -+ -+ rtc@68 { -+ compatible = "dallas,ds1337"; -+ reg = <0x68>; -+ }; -+ board_eeprom@50 { -+ compatible = "at,24c64"; -+ reg = <0x50>; -+ label = "board_eeprom"; -+ }; -+ temp_ambient2@4b { -+ compatible = "nxp,lm75a"; -+ reg = <0x4b>; -+ interrupt-parent = <&mpic>; -+ interrupts = <5 3>; -+ }; -+ temp_bcm@4e { -+ compatible = "nxp,lm75a"; -+ reg = <0x4e>; -+ interrupt-parent = <&mpic>; -+ interrupts = <5 3>; -+ }; -+ psu_eeprom@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ label = "psu2_eeprom"; -+ read-only; -+ }; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl-i2c"; -+ fsl,preserve-clocking; -+ -+ temp_p2020@48 { -+ compatible = "nxp,lm75a"; -+ reg = <0x48>; -+ interrupt-parent = <&mpic>; -+ interrupts = <5 3>; -+ }; -+ temp_rearoutput@49 { -+ compatible = "nxp,lm75a"; -+ reg = <0x49>; -+ interrupt-parent = <&mpic>; -+ interrupts = <5 3>; -+ }; -+ pwm@4d { -+ compatible = "smsc,emc2305"; -+ reg = <0x4d>; -+ interrupt-parent = <&mpic>; -+ interrupts = <6 3>; -+ }; -+ temp_ambient1@4f { -+ compatible = "nxp,lm75a"; -+ reg = <0x4f>; -+ interrupt-parent = <&mpic>; -+ interrupts = <5 3>; -+ }; -+ psu_eeprom@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ label = "psu1_eeprom"; -+ read-only; -+ }; -+ power@60 { -+ compatible = "ons,ncp4200"; -+ reg = <0x60>; -+ }; -+ }; -+ -+ usb@22000 { -+ phy_type = "ulpi"; -+ }; -+ -+ enet0: ethernet@24000 { -+ status = "disabled"; -+ }; -+ -+ mdio0: mdio@24520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ phy0: ethernet-phy@3 { -+ /* -+ * CPLD Status change bit for phys need to be cleared, for -+ * interrupts to work properly, hence instead of modifying -+ * phy driver code to clear status change bits.So commenting -+ * out for now. -+ * interrupts = < 5 1>; -+ */ -+ reg = <0x3>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ -+ enet1: ethernet@25000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ cell-index = <0x1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x25000 0x1000>; -+ ranges = <0x0 0x25000 0x1000>; -+ interrupts = < -+ 0x23 0x2 -+ 0x24 0x2 -+ 0x28 0x2>; -+ interrupt-parent = <&mpic>; -+ tbi-handle = <&tbi0>; -+ phy-handle = <&phy0>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ mdio1: mdio@25520 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ compatible = "fsl,gianfar-tbi"; -+ reg = <0x25520 0x20>; -+ tbi0: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ enet2: ethernet@26000 { -+ status = "disabled"; -+ }; -+ -+ sdhci@2e000 { -+ status = "disabled"; -+ }; -+ }; -+ -+ pci0: pcie@ffe08000 { -+ status = "disabled"; -+ }; -+ -+ pci1: pcie@ffe09000 { -+ status = "disabled"; -+ }; -+ -+ pci2: pcie@ffe0a000 { -+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc30000 0x0 0x10000>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 -+ >; -+ -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xa0000000 -+ 0x2000000 0x0 0xa0000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/cel_smallstone.dts b/arch/powerpc/boot/dts/cel_smallstone.dts -new file mode 100644 -index 0000000..dfce176 ---- /dev/null -+++ b/arch/powerpc/boot/dts/cel_smallstone.dts -@@ -0,0 +1,675 @@ -+/* -+ * Celestica Smallstone Device Tree Source -+ * -+ * Copyright 2013 Cumulus Networks, 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/ "p2020si.dtsi" -+ -+/ { -+ model = "cel,smallstone"; -+ compatible = "cel,smallstone"; -+ -+ aliases { -+ ethernet0 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci2 = &pci2; -+ }; -+ -+ cpus { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ PowerPC,P2020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <0x1>; -+ }; -+ PowerPC,P2020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <0x1>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ -+ localbus@ffe05000 { -+ /* NOR and NAND Flashes, CPLD */ -+ ranges = <0x0 0x0 0x0 0xec000000 0x04000000 -+ 0x1 0x0 0x0 0xffa00000 0x00100000 -+ 0x2 0x0 0x0 0xffb80000 0x00020000 -+ 0x3 0x0 0x0 0xffb00000 0x00000400 -+ 0x4 0x0 0x0 0xffb40000 0x00000400>; -+ -+ nor@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x04000000>; -+ bank-width = <2>; -+ device-width = <1>; -+ -+ partition@0 { -+ /* Entire flash minus (u-boot + onie) */ -+ reg = <0x00000000 0x03b60000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x03b60000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x03f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ /* 512KB u-boot */ -+ reg = <0x03f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ -+ nand@1,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,p2020-fcm-nand", -+ "fsl,elbc-fcm-nand"; -+ reg = <0x1 0x0 0x40000>; -+ -+ partition@0 { -+ reg = <0x0 0x40000000>; -+ label = "open2"; -+ }; -+ }; -+ lpsram@2,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "smallstone_lpsram"; -+ reg = <0x2 0x0 0x20000>; -+ -+ partition@0 { -+ reg = <0x0 0x20000>; -+ label = "open3"; -+ }; -+ }; -+ CPLD1@3,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "smallstone_cpld1"; -+ label = "cpld_1"; -+ reg = <0x3 0x0 0x400>; -+ }; -+ CPLD23@4,0 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "smallstone_cpld23"; -+ label = "cpld_23"; -+ reg = <0x4 0x0 0x400>; -+ cpld_i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "cel,cpld-i2c-bus"; -+ reg = <0x4 0x10 0x30>; -+ clock-frequency = <100000>; -+ cel_cpld,timeout = <10000>; -+ mux@1 { -+ compatible = "cel,cpld-i2c-mux"; -+ reg = <0x1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ /* QSFP 1 */ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port1"; -+ }; -+ }; -+ /* QSFP 2 */ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port2"; -+ }; -+ }; -+ /* QSFP 3 */ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port3"; -+ }; -+ }; -+ /* QSFP 4 */ -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port4"; -+ }; -+ }; -+ /* QSFP 5 */ -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port5"; -+ }; -+ }; -+ /* QSFP 6 */ -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port6"; -+ }; -+ }; -+ /* QSFP 7 */ -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port7"; -+ }; -+ }; -+ /* QSFP 8 */ -+ i2c@8 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port8"; -+ }; -+ }; -+ /* QSFP 9 */ -+ i2c@9 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port9"; -+ }; -+ }; -+ /* QSFP 10 */ -+ i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port10"; -+ }; -+ }; -+ /* QSFP 11 */ -+ i2c@11 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port11"; -+ }; -+ }; -+ /* QSFP 12 */ -+ i2c@12 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port12"; -+ }; -+ }; -+ /* QSFP 13 */ -+ i2c@13 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port13"; -+ }; -+ }; -+ /* QSFP 14 */ -+ i2c@14 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port14"; -+ }; -+ }; -+ /* QSFP 15 */ -+ i2c@15 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port15"; -+ }; -+ }; -+ /* QSFP 16 */ -+ i2c@16 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <16>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port16"; -+ }; -+ }; -+ }; -+ }; -+ cpld_i2c@40 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "cel,cpld-i2c-bus"; -+ reg = <0x4 0x40 0x30>; -+ clock-frequency = <100000>; -+ cel_cpld,timeout = <10000>; -+ mux@2 { -+ compatible = "cel,cpld-i2c-mux"; -+ reg = <0x2>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ /* QSFP 17 */ -+ i2c@17 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <17>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port17"; -+ }; -+ }; -+ /* QSFP 18 */ -+ i2c@18 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <18>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port18"; -+ }; -+ }; -+ /* QSFP 19 */ -+ i2c@19 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <19>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port19"; -+ }; -+ }; -+ /* QSFP 20 */ -+ i2c@20 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <20>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port20"; -+ }; -+ }; -+ /* QSFP 21 */ -+ i2c@21 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <21>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port21"; -+ }; -+ }; -+ /* QSFP 22 */ -+ i2c@22 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <22>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port22"; -+ }; -+ }; -+ /* QSFP 23 */ -+ i2c@23 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <23>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port23"; -+ }; -+ }; -+ /* QSFP 24 */ -+ i2c@24 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <24>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port24"; -+ }; -+ }; -+ /* QSFP 25 */ -+ i2c@25 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <25>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port25"; -+ }; -+ }; -+ /* QSFP 26 */ -+ i2c@26 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <26>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port26"; -+ }; -+ }; -+ /* QSFP 27 */ -+ i2c@27 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <27>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port27"; -+ }; -+ }; -+ /* QSFP 28 */ -+ i2c@28 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <28>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port28"; -+ }; -+ }; -+ /* QSFP 29 */ -+ i2c@29 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <29>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port29"; -+ }; -+ }; -+ /* QSFP 30 */ -+ i2c@30 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <30>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port30"; -+ }; -+ }; -+ /* QSFP 31 */ -+ i2c@31 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <31>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port31"; -+ }; -+ }; -+ /* QSFP 32 */ -+ i2c@32 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <32>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port32"; -+ }; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ soc@ffe00000 { -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl-i2c"; -+ fsl,preserve-clocking; -+ -+ rtc@68 { -+ compatible = "dallas,ds1337"; -+ reg = <0x68>; -+ }; -+ board_eeprom@50 { -+ compatible = "at,24c64"; -+ reg = <0x50>; -+ label = "board_eeprom"; -+ }; -+ temp_ambient2@4b { -+ compatible = "nxp,lm75a"; -+ reg = <0x4b>; -+ }; -+ psu_eeprom@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ label = "psu2_eeprom"; -+ read-only; -+ }; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl-i2c"; -+ fsl,preserve-clocking; -+ -+ temp_p2020@48 { -+ compatible = "nxp,lm75a"; -+ reg = <0x48>; -+ }; -+ temp_rearoutput@49 { -+ compatible = "nxp,lm75a"; -+ reg = <0x49>; -+ }; -+ pwm@4d { -+ compatible = "smsc,emc2305"; -+ reg = <0x4d>; -+ }; -+ temp_bcm@4e { -+ compatible = "nxp,lm75a"; -+ reg = <0x4e>; -+ }; -+ temp_ambient1@4f { -+ compatible = "nxp,lm75a"; -+ reg = <0x4f>; -+ }; -+ psu_eeprom@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ label = "psu1_eeprom"; -+ }; -+ power@60 { -+ compatible = "ons,ncp4200"; -+ reg = <0x60>; -+ }; -+ }; -+ -+ usb@22000 { -+ phy_type = "ulpi"; -+ }; -+ -+ enet0: ethernet@24000 { -+ status = "disabled"; -+ }; -+ -+ mdio0: mdio@24520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ phy0: ethernet-phy@3 { -+ /* -+ * CPLD Status change bit for phys need to be cleared, for -+ * interrupts to work properly, hence instead of modifying -+ * phy driver code to clear status change bits.So commenting -+ * out for now. -+ * interrupts = < 5 1>; -+ */ -+ reg = <0x3>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ -+ enet1: ethernet@25000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ cell-index = <0x1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x25000 0x1000>; -+ ranges = <0x0 0x25000 0x1000>; -+ interrupts = < -+ 0x23 0x2 -+ 0x24 0x2 -+ 0x28 0x2>; -+ interrupt-parent = <&mpic>; -+ tbi-handle = <&tbi0>; -+ phy-handle = <&phy0>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ mdio1: mdio@25520 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ compatible = "fsl,gianfar-tbi"; -+ reg = <0x25520 0x20>; -+ tbi0: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ enet2: ethernet@26000 { -+ status = "disabled"; -+ }; -+ -+ sdhci@2e000 { -+ status = "disabled"; -+ }; -+ }; -+ -+ pci0: pcie@ffe08000 { -+ status = "disabled"; -+ }; -+ -+ pci1: pcie@ffe09000 { -+ status = "disabled"; -+ }; -+ -+ pci2: pcie@ffe0a000 { -+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc30000 0x0 0x10000>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 -+ >; -+ -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xa0000000 -+ 0x2000000 0x0 0xa0000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig -index 2c1aa86..0b37a01 100644 ---- a/arch/powerpc/platforms/85xx/Kconfig -+++ b/arch/powerpc/platforms/85xx/Kconfig -@@ -257,6 +257,37 @@ config BCM98548XMC - help - This option enables support for the Broadcom BCM98548XMC board used on reference platforms - -+config CEL_P2020 -+ bool "Celestica P2020" -+ select DEFAULT_UIMAGE -+ help -+ This option enables support for Celestica P2020 based -+ networking platforms -+ -+config CEL_REDSTONE -+ bool "Celestica Redstone" -+ select DEFAULT_UIMAGE -+ select CEL_P2020 -+ help -+ This option enables support for the Celestica Redstone 48x10G -+ 4x40G networking platform -+ -+config CEL_KENNISIS -+ bool "Celestica Kennisis" -+ select DEFAULT_UIMAGE -+ select CEL_P2020 -+ help -+ This option enables support for the Celestica Kennisis 48x1G -+ 4x10G networking platform -+ -+config CEL_SMALLSTONE -+ bool "Celestica Smallstone" -+ select DEFAULT_UIMAGE -+ select CEL_P2020 -+ help -+ This option enables support for the Celestica Smallstone -+ 32x40G networking platform -+ - config CUMULUS_P2020 - bool "Cumulus Networks P2020" - select DEFAULT_UIMAGE -diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile -index d04e66c..c4653e2 100644 ---- a/arch/powerpc/platforms/85xx/Makefile -+++ b/arch/powerpc/platforms/85xx/Makefile -@@ -30,6 +30,7 @@ obj-$(CONFIG_ACCTON_AS5610_52X) += accton_as5610_52x.o - obj-$(CONFIG_ACCTON_AS6701_32X) += accton_as6701_32x.o - obj-$(CONFIG_ACCTON_5652) += accton_5652.o - obj-$(CONFIG_BCM98548XMC) += bcm98548xmc.o -+obj-$(CONFIG_CEL_P2020) += cel_p2020.o - obj-$(CONFIG_CUMULUS_P2020) += cumulus_p2020.o - obj-$(CONFIG_DNI_6448) += dni_6448.o - obj-$(CONFIG_DNI_7448) += dni_7448.o -diff --git a/arch/powerpc/platforms/85xx/cel_p2020.c b/arch/powerpc/platforms/85xx/cel_p2020.c -new file mode 100644 -index 0000000..ec6023f ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/cel_p2020.c -@@ -0,0 +1,230 @@ -+/* -+ * Celestica P2020 setup and early boot code plus other random bits. -+ * -+ * Copyright 2013 Cumulus Networks, Inc. -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_EARLY_DMA_ALLOC -+# include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#undef DEBUG -+ -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+/******************************************************************************* -+ * -+ * Platform initialization functions -+ * -+ ******************************************************************************* -+*/ -+ -+/* -+ * Initialize the interrupt controller -+ */ -+static void __init celestica_p2020_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np; -+ -+ np = of_find_node_by_type(NULL, "open-pic"); -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | -+ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | -+ MPIC_SINGLE_DEST_CPU, -+ 0, 256, " OpenPIC "); -+ -+ BUG_ON(mpic == NULL); -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+#ifdef CONFIG_SMP -+extern void __init mpc85xx_smp_init(void); -+#endif -+ -+static void __init celestica_p2020_setup_arch(void) -+{ -+ struct device_node *cpu; -+ const unsigned int *fp; -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ -+ if (ppc_md.progress) -+ ppc_md.progress("celestica_p2020_setup_arch()", 0); -+ -+ cpu = of_find_node_by_type(NULL, "cpu"); -+ if (cpu != 0) { -+ fp = of_get_property(cpu, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(cpu); -+ } -+ -+#ifdef CONFIG_PCI -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8548-pcie")) -+ fsl_add_bridge(np, 0); -+ } -+#endif -+ -+ powersave_nap = 0; -+ -+#ifdef CONFIG_SMP -+ mpc85xx_smp_init(); -+#endif -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+} -+ -+static struct of_device_id __initdata celestica_p2020_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ { .compatible = "gianfar", }, -+ { .compatible = "redstone_cpld234", }, -+ { .compatible = "smallstone_cpld23", }, -+ {}, -+}; -+ -+static int __init celestica_p2020_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, celestica_p2020_ids, NULL); -+} -+ -+machine_device_initcall(cel_kennisis, celestica_p2020_publish_devices); -+machine_device_initcall(cel_redstone, celestica_p2020_publish_devices); -+machine_device_initcall(cel_smallstone, celestica_p2020_publish_devices); -+ -+static void celestica_p2020_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu Pll setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init celestica_kennisis_probe(void) -+{ -+ return of_flat_dt_is_compatible(of_get_flat_dt_root(), "cel,kennisis"); -+} -+ -+static int __init celestica_redstone_probe(void) -+{ -+ return of_flat_dt_is_compatible(of_get_flat_dt_root(), "cel,redstone"); -+} -+ -+static int __init celestica_smallstone_probe(void) -+{ -+ return of_flat_dt_is_compatible(of_get_flat_dt_root(), "cel,smallstone"); -+} -+ -+define_machine(cel_kennisis) { -+ .name = "Celestica, Inc. Kennisis", -+ .probe = celestica_kennisis_probe, -+ .setup_arch = celestica_p2020_setup_arch, -+ .init_IRQ = celestica_p2020_pic_init, -+ .show_cpuinfo = celestica_p2020_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = fsl_rstcr_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; -+ -+define_machine(cel_redstone) { -+ .name = "Celestica, Inc. Redstone", -+ .probe = celestica_redstone_probe, -+ .setup_arch = celestica_p2020_setup_arch, -+ .init_IRQ = celestica_p2020_pic_init, -+ .show_cpuinfo = celestica_p2020_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = fsl_rstcr_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; -+ -+define_machine(cel_smallstone) { -+ .name = "Celestica, Inc. Smallstone", -+ .probe = celestica_smallstone_probe, -+ .setup_arch = celestica_p2020_setup_arch, -+ .init_IRQ = celestica_p2020_pic_init, -+ .show_cpuinfo = celestica_p2020_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = fsl_rstcr_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-celestica-cpld-i2c.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-celestica-cpld-i2c.patch deleted file mode 100644 index 7d8f2280..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-celestica-cpld-i2c.patch +++ /dev/null @@ -1,701 +0,0 @@ -platform celestica cpld i2c patch - -Add driver for the Celestica CPLD-based I2C controller. - -diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig -index 8f29057..36756f8 100644 ---- a/drivers/i2c/busses/Kconfig -+++ b/drivers/i2c/busses/Kconfig -@@ -340,6 +340,17 @@ config I2C_BLACKFIN_TWI_CLK_KHZ - help - The unit of the TWI clock is kHz. - -+config I2C_CEL_CPLD -+ tristate "Celestica CPLD I2C Driver" -+ depends on CEL_REDSTONE -+ help -+ If you say yes to this option, support will be included for -+ the Celestica CPLD I2C interface. This interface is for -+ interacting with SFP+ and QSFP modules. -+ -+ This driver can also be built as a module. If so, the module -+ will be called i2c-cel-cpld. -+ - config I2C_CPM - tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)" - depends on (CPM1 || CPM2) && OF_I2C -diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile -index 070adee..b3f56c8 100644 ---- a/drivers/i2c/busses/Makefile -+++ b/drivers/i2c/busses/Makefile -@@ -32,6 +32,7 @@ obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o - obj-$(CONFIG_I2C_AT91) += i2c-at91.o - obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o - obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o -+obj-$(CONFIG_I2C_CEL_CPLD) += i2c-cel-cpld.o - obj-$(CONFIG_I2C_CPM) += i2c-cpm.o - obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o - obj-$(CONFIG_I2C_DESIGNWARE_CORE) += i2c-designware-core.o -diff --git a/drivers/i2c/busses/i2c-cel-cpld.c b/drivers/i2c/busses/i2c-cel-cpld.c -new file mode 100644 -index 0000000..c46bc21 ---- /dev/null -+++ b/drivers/i2c/busses/i2c-cel-cpld.c -@@ -0,0 +1,657 @@ -+/* -+ * Copyright (C) 2013 Cumulus Networks, Inc. -+ * Author: Curt Brune -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define BUS_DRV_NAME "cel-cpld-i2c-bus" -+#define BUS_MUX_DRV_VERSION "1.1" -+ -+/* -+ * The CEL_CPLD_I2C_XXX offsets are relative to the start of the "I2C -+ * block" within each CPLD: -+ * -+ * CPLD2 -- 0x10 -+ * CPLD3 -- 0x40 -+ * CPLD4 -- 0x80 -+ * -+ */ -+#define CEL_CPLD_I2C_PORT_ID 0x00 -+#define CEL_CPLD_I2C_OPCODE 0x02 -+#define CEL_CPLD_I2C_DEV_ADDR 0x04 -+#define CEL_CPLD_I2C_CMD_BYTE0 0x08 -+#define CEL_CPLD_I2C_CMD_BYTE1 0x0A -+#define CEL_CPLD_I2C_CMD_BYTE2 0x0C -+#define CEL_CPLD_I2C_CSR 0x0E -+#define CEL_CPLD_I2C_WRITE_DATA 0x10 -+#define WRITE_DATA(x) (CEL_CPLD_I2C_WRITE_DATA + (2*x)) -+#define CEL_CPLD_I2C_READ_DATA 0x20 -+#define READ_DATA(x) (CEL_CPLD_I2C_READ_DATA + (2*x)) -+ -+#define CEL_CPLD_I2C_CLK_50KHZ 0x00 -+#define CEL_CPLD_I2C_CLK_100KHZ 0x40 -+ -+#define CSR_MASTER_ERROR 0x80 -+#define CSR_BUSY 0x40 -+#define CSR_MASTER_RESET_L 0x01 -+ -+#define OPCODE_DATA_LENGTH_SHIFT 4 -+#define OPCODE_CMD_LENGTH 1 -+ -+#define DEV_ADDR_READ_OP 0x1 -+#define DEV_ADDR_WRITE_OP 0x0 -+ -+struct cel_cpld_i2c { -+ struct device *m_dev; -+ void __iomem *m_base; -+ struct i2c_adapter m_adap; -+ u8 m_clk_freq; -+}; -+ -+static inline void cel_cpld_set_mux_reg(struct cel_cpld_i2c *i2c, int channel) -+{ -+ writeb(i2c->m_clk_freq | (channel & 0x3F), -+ i2c->m_base + CEL_CPLD_I2C_PORT_ID); -+} -+ -+/* -+ * Wait up to 1 second for the controller to be come non-busy. -+ * -+ * Returns: -+ * - success: 0 -+ * - failure: negative status code -+ */ -+static int cel_cpld_wait(struct cel_cpld_i2c *i2c) -+{ -+ unsigned long orig_jiffies = jiffies; -+ int rc = 0; -+ u8 csr; -+ -+ /* Allow bus up to 1s to become not busy */ -+ while ((csr = readb(i2c->m_base + CEL_CPLD_I2C_CSR)) & CSR_BUSY) { -+ if (signal_pending(current)) { -+ return -EINTR; -+ } -+ if (time_after(jiffies, orig_jiffies + HZ)) { -+ dev_warn(i2c->m_dev, "Bus busy timeout\n"); -+ rc = -ETIMEDOUT; -+ break; -+ } -+ schedule(); -+ } -+ -+ if (csr & CSR_MASTER_ERROR) { -+ /* Typically this means the SFP+ device is not present. */ -+ /* Clear master error with the master reset. */ -+ writeb(~CSR_MASTER_RESET_L, -+ i2c->m_base + CEL_CPLD_I2C_CSR); -+ udelay(3000); -+ writeb(CSR_MASTER_RESET_L, -+ i2c->m_base + CEL_CPLD_I2C_CSR); -+ rc = rc ? rc : -EIO; -+ } -+ -+ return rc; -+} -+ -+static int cel_cpld_i2c_write(struct cel_cpld_i2c *i2c, int target, -+ u8 offset, const u8 *data, int length) -+{ -+ u8 tmp, xfer_len, i; -+ int ret, total_xfer = 0; -+ -+ /* The CEL-CPLD I2C master writes in units of 8 bytes */ -+ while (length > 0) { -+ -+ /* Configure byte offset within device */ -+ writeb(offset + total_xfer, -+ i2c->m_base + CEL_CPLD_I2C_CMD_BYTE0); -+ -+ /* Configure transfer length - max of 8 bytes */ -+ xfer_len = (length > 8) ? 8 : length; -+ tmp = (xfer_len << OPCODE_DATA_LENGTH_SHIFT); -+ tmp |= OPCODE_CMD_LENGTH; -+ writeb(tmp, i2c->m_base + CEL_CPLD_I2C_OPCODE); -+ -+ /* Load the transmit data into the send buffer */ -+ for (i = 0; i < xfer_len; i++) -+ writeb(data[total_xfer + i], i2c->m_base + WRITE_DATA(i)); -+ -+ /* Initiate write transaction */ -+ tmp = (target << 1) | DEV_ADDR_WRITE_OP; -+ writeb(tmp, i2c->m_base + CEL_CPLD_I2C_DEV_ADDR); -+ -+ /* Wait for transfer completion */ -+ ret = cel_cpld_wait(i2c); -+ if (ret) -+ return ret; -+ -+ total_xfer += xfer_len; -+ length -= xfer_len; -+ } -+ -+ return 0; -+} -+ -+static int cel_cpld_i2c_read(struct cel_cpld_i2c *i2c, int target, -+ u8 offset, u8 *data, int length) -+{ -+ u8 tmp, xfer_len, i; -+ int ret, total_xfer = 0; -+ -+ /* The CEL-CPLD I2C master reads in units of 8 bytes */ -+ while (length > 0) { -+ -+ /* Configure byte offset within device */ -+ writeb(offset + total_xfer, -+ i2c->m_base + CEL_CPLD_I2C_CMD_BYTE0); -+ -+ /* Configure transfer length - max of 8 bytes */ -+ xfer_len = (length > 8) ? 8 : length; -+ tmp = (xfer_len << OPCODE_DATA_LENGTH_SHIFT); -+ tmp |= OPCODE_CMD_LENGTH; -+ writeb(tmp, i2c->m_base + CEL_CPLD_I2C_OPCODE); -+ -+ /* Initiate read transaction */ -+ tmp = (target << 1) | DEV_ADDR_READ_OP; -+ writeb(tmp, i2c->m_base + CEL_CPLD_I2C_DEV_ADDR); -+ -+ /* Wait for transfer completion */ -+ ret = cel_cpld_wait(i2c); -+ if (ret) -+ return ret; -+ -+ /* Gather up the results */ -+ for (i = 0; i < xfer_len; i++) -+ data[total_xfer + i] = readb(i2c->m_base + READ_DATA(i)); -+ -+ total_xfer += xfer_len; -+ length -= xfer_len; -+ } -+ -+ return 0; -+} -+ -+static int cel_cpld_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) -+{ -+ struct i2c_msg *pmsg; -+ int ret = 0; -+ struct cel_cpld_i2c *i2c = i2c_get_adapdata(adap); -+ u8 offset; -+ -+ /* Allow bus to become not busy */ -+ ret = cel_cpld_wait(i2c); -+ if (ret) -+ return ret; -+ -+ /* -+ * This is somewhat gimpy. -+ * -+ * The CEL-CPLD I2C master is special built to read/write SFP+ -+ * EEPROMs only. It is *not* a general purpose I2C master. -+ * The clients of this master are *always* expected to be -+ * "at,24c04" or "sff-8436 based qsfp" compatible EEPROMs. -+ * -+ * As such we have the following expectations for READ operation: -+ * -+ * - number of messages is "2" -+ * - msg[0] contains info about the offset within the 512-byte EEPROM -+ * - msg[0].len = 1 -+ * - msg[0].buf[0] contains the offset -+ * - msg[1] contains info about the read payload -+ * -+ * As such we have the following expectations for WRITE operation: -+ * -+ * - number of messages is "1" -+ * - msg[0] contains info about the offset within the 512-byte EEPROM -+ * - msg[0].buf[0] contains the offset -+ * - msg[0] also contains info about the write payload -+ */ -+ -+ /* -+ * The offset within the EEPROM is stored in msg[0].buf[0]. -+ */ -+ offset = msgs[0].buf[0]; -+ -+ if (num == 1) { -+ pmsg = &msgs[0]; -+ } else { -+ pmsg = &msgs[1]; -+ } -+ -+ if ((offset + pmsg->len) > 0x200) -+ return -EINVAL; -+ -+ if (pmsg->flags & I2C_M_RD) { -+ if (num != 2) { -+ dev_warn(i2c->m_dev, "Expecting 2 i2c messages. Got %d\n", num); -+ return -EINVAL; -+ } -+ -+ if (msgs[0].len != 1) { -+ dev_warn(i2c->m_dev, "Expecting mgs[0].len == 1. Got %d\n", -+ msgs[0].len); -+ return -EINVAL; -+ } -+ -+ ret = cel_cpld_i2c_read(i2c, pmsg->addr, offset, pmsg->buf, pmsg->len); -+ } else { -+ ret = cel_cpld_i2c_write(i2c, pmsg->addr, offset, &(pmsg->buf[1]), (pmsg->len - 1)); -+ } -+ -+ return (ret < 0) ? ret : num; -+} -+ -+static u32 cel_cpld_functionality(struct i2c_adapter *adap) -+{ -+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -+} -+ -+static const struct i2c_algorithm cel_cpld_algo = { -+ .master_xfer = cel_cpld_xfer, -+ .functionality = cel_cpld_functionality, -+}; -+ -+static struct i2c_adapter cel_cpld_ops = { -+ .owner = THIS_MODULE, -+ .name = "CEL_CPLD adapter", -+ .algo = &cel_cpld_algo, -+ .timeout = HZ, -+}; -+ -+static void __devinit cel_cpld_i2c_bus_setup(struct device_node *node, -+ struct cel_cpld_i2c *i2c, -+ u32 clock) -+{ -+ u8 clk_freq = CEL_CPLD_I2C_CLK_50KHZ; -+ -+ if (clock == 100000) -+ clk_freq = CEL_CPLD_I2C_CLK_100KHZ; -+ -+ i2c->m_clk_freq = clk_freq; -+ writeb(clk_freq, i2c->m_base + CEL_CPLD_I2C_PORT_ID); -+ -+ /* Reset the I2C master logic */ -+ writeb(~CSR_MASTER_RESET_L, i2c->m_base + CEL_CPLD_I2C_CSR); -+ udelay(3000); -+ writeb(CSR_MASTER_RESET_L, i2c->m_base + CEL_CPLD_I2C_CSR); -+ -+} -+ -+static const struct of_device_id cel_cpld_i2c_bus_of_match[]; -+static int __devinit cel_cpld_i2c_bus_probe(struct platform_device *op) -+{ -+ const struct of_device_id *match; -+ struct cel_cpld_i2c *i2c; -+ const u32 *prop; -+ u32 clock = 100000; -+ int result = 0; -+ int plen; -+ -+ match = of_match_device(cel_cpld_i2c_bus_of_match, &op->dev); -+ if (!match) -+ return -EINVAL; -+ -+ i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); -+ if (!i2c) -+ return -ENOMEM; -+ -+ i2c->m_dev = &op->dev; /* for debug and error output */ -+ -+ i2c->m_base = of_iomap(op->dev.of_node, 0); -+ if (!i2c->m_base) { -+ dev_err(i2c->m_dev, "failed to map controller\n"); -+ result = -ENOMEM; -+ goto fail_map; -+ } -+ -+ prop = of_get_property(op->dev.of_node, "clock-frequency", &plen); -+ if (prop && plen == sizeof(u32)) { -+ /* -+ * The hardware only supports two clock frequencies: -+ * 50kHz and 100kHz. -+ * -+ */ -+ if ((*prop != 50000) && (*prop != 100000)) { -+ dev_err(i2c->m_dev, "clock-frequency %u is not valid.\n", -+ *prop); -+ result = -EINVAL; -+ goto fail_property; -+ } else { -+ clock = *prop; -+ dev_info(i2c->m_dev, "clock-frequency %u\n", clock); -+ } -+ } -+ -+ cel_cpld_i2c_bus_setup(op->dev.of_node, i2c, clock); -+ -+ prop = of_get_property(op->dev.of_node, "cel_cpld,timeout", &plen); -+ if (prop && plen == sizeof(u32)) { -+ cel_cpld_ops.timeout = *prop * HZ / 1000000; -+ if (cel_cpld_ops.timeout < 5) -+ cel_cpld_ops.timeout = 5; -+ } -+ dev_info(i2c->m_dev, "timeout %u us\n", cel_cpld_ops.timeout * 1000000 / HZ); -+ -+ dev_set_drvdata(&op->dev, i2c); -+ -+ i2c->m_adap = cel_cpld_ops; -+ i2c_set_adapdata(&i2c->m_adap, i2c); -+ i2c->m_adap.dev.parent = &op->dev; -+ i2c->m_adap.dev.of_node = of_node_get(op->dev.of_node); -+ -+ result = i2c_add_adapter(&i2c->m_adap); -+ if (result < 0) { -+ dev_err(i2c->m_dev, "failed to add adapter\n"); -+ goto fail_add; -+ } -+ of_i2c_register_devices(&i2c->m_adap); -+ -+ return result; -+ -+ fail_add: -+ dev_set_drvdata(&op->dev, NULL); -+ fail_property: -+ iounmap(i2c->m_base); -+ fail_map: -+ kfree(i2c); -+ return result; -+}; -+ -+static int __devexit cel_cpld_i2c_bus_remove(struct platform_device *op) -+{ -+ struct cel_cpld_i2c *i2c = dev_get_drvdata(&op->dev); -+ -+ i2c_del_adapter(&i2c->m_adap); -+ dev_set_drvdata(&op->dev, NULL); -+ -+ iounmap(i2c->m_base); -+ kfree(i2c); -+ return 0; -+}; -+ -+static const struct of_device_id cel_cpld_i2c_bus_of_match[] = { -+ {.compatible = "cel,cpld-i2c-bus", }, -+ { /* end of list */ }, -+}; -+MODULE_DEVICE_TABLE(of, cel_cpld_i2c_bus_of_match); -+ -+/* Structure for a device driver */ -+static struct platform_driver cel_cpld_i2c_bus_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = BUS_DRV_NAME, -+ .of_match_table = cel_cpld_i2c_bus_of_match, -+ }, -+ .probe = cel_cpld_i2c_bus_probe, -+ .remove = __devexit_p(cel_cpld_i2c_bus_remove), -+}; -+ -+/* -+ * MUX Driver starts here -+ */ -+ -+#define MUX_DRV_NAME "cel-cpld-i2c-mux" -+ -+#define INVALID_CHANNEL (0xFF) -+ -+struct cel_cpld_vadapter { -+ struct i2c_adapter *m_adapter; /* virtual i2c adapter struct */ -+ u32 m_channel; /* MUX channel */ -+ struct llist_node m_llnode; -+}; -+ -+struct cel_cpld_i2c_mux { -+ struct device *m_dev; /* for debug and error output */ -+ struct llist_head m_vadapter_list; /* list of virtual i2c adapters */ -+ struct cel_cpld_i2c *m_i2c_bus; /* parent I2C master device */ -+ u8 m_last_channel; /* last channel selected */ -+ u32 m_mux_id; /* mux ID */ -+}; -+ -+static int cel_cpld_i2c_mux_select_chan(struct i2c_adapter *adap, -+ void *client, u32 channel) -+{ -+ struct cel_cpld_i2c_mux *mux = i2c_get_clientdata(client); -+ -+ if (channel != mux->m_last_channel) { -+ cel_cpld_set_mux_reg(mux->m_i2c_bus, channel); -+ mux->m_last_channel = channel; -+ } -+ -+ return 0; -+} -+ -+/* -+ * I2C init/probing/exit functions -+ */ -+ -+static int __devinit cel_cpld_i2c_mux_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); -+ struct cel_cpld_i2c *i2c = i2c_get_adapdata(adap); -+ struct cel_cpld_i2c_mux *mux; -+ const void* prop; -+ struct device_node *mux_of_child; -+ struct cel_cpld_vadapter *entry; -+ struct llist_node *llnode; -+ int plen = 0; -+ u32 mux_id, cnt = 0; -+ int rc = -ENODEV; -+ -+ /* -+ * Use the parent adapter for our register access. -+ */ -+ if (i2c->m_base == NULL) { -+ dev_err(&client->dev, -+ "Cannot find valid register iomap for CPLD mux.\n"); -+ rc = -ENODEV; -+ goto err; -+ } -+ -+ prop = of_get_property(client->dev.of_node, "reg", &plen); -+ if (prop && plen == sizeof(u32)) { -+ mux_id = *((u32*)prop); -+ } else { -+ dev_err(&client->dev, -+ "Cannot find valid mux_id for CPLD mux.\n"); -+ rc = -ENODEV; -+ goto err; -+ } -+ -+ mux = kmalloc(sizeof(struct cel_cpld_i2c_mux), GFP_KERNEL); -+ if (!mux) { -+ rc = -ENOMEM; -+ goto err; -+ } -+ -+ i2c_set_clientdata(client, mux); -+ -+ mux->m_dev = &client->dev; /* for debug and error output */ -+ mux->m_i2c_bus = i2c; -+ mux->m_mux_id = mux_id; -+ mux->m_last_channel = INVALID_CHANNEL; -+ init_llist_head(&mux->m_vadapter_list); -+ -+ /* Create a virtual adapter for each child channel of this mux */ -+ for_each_child_of_node(client->dev.of_node, mux_of_child) { -+ u32 channel; -+ -+ prop = of_get_property(mux_of_child, "reg", &plen); -+ if (prop && plen == sizeof(u32)) { -+ channel = *((u32*)prop); -+ } else { -+ dev_err(&client->dev, -+ "Cannot find channel for CPLD mux.\n"); -+ rc = -EINVAL; -+ of_node_put(mux_of_child); -+ goto virt_reg_failed; -+ } -+ of_node_put(mux_of_child); -+ -+ /* Check for duplicates */ -+ llist_for_each_entry(entry, -+ mux->m_vadapter_list.first, -+ m_llnode) { -+ if (entry->m_channel == channel) { -+ dev_err(&client->dev, -+ "Duplicate MUX channel: %u\n", channel); -+ rc = -EINVAL; -+ goto virt_reg_failed; -+ } -+ } -+ -+ entry = kmalloc(sizeof(struct cel_cpld_vadapter), GFP_KERNEL); -+ if (!entry) { -+ rc = -ENOMEM; -+ goto virt_reg_failed; -+ } -+ -+ entry->m_channel = channel; -+ entry->m_adapter = -+ i2c_add_mux_adapter(adap, &client->dev, client, -+ 0, channel, -+ cel_cpld_i2c_mux_select_chan, -+ NULL); -+ -+ if (entry->m_adapter == NULL) { -+ rc = -ENODEV; -+ dev_err(&client->dev, -+ "failed to register multiplexed adapter %u\n", -+ channel); -+ kfree(entry); -+ goto virt_reg_failed; -+ } -+ -+ llist_add(&entry->m_llnode, &mux->m_vadapter_list); -+ cnt++; -+ } -+ -+ dev_info(&client->dev, -+ "registered %u multiplexed buses for mux_id %u\n", -+ cnt, mux_id); -+ -+ return 0; -+ -+virt_reg_failed: -+ while ((llnode = llist_del_first(&mux->m_vadapter_list)) != NULL) { -+ entry = llist_entry(llnode, struct cel_cpld_vadapter, m_llnode); -+ if (entry->m_adapter) -+ (void)i2c_del_mux_adapter(entry->m_adapter); -+ kfree(entry); -+ } -+ -+ kfree(mux); -+err: -+ return rc; -+} -+ -+static int __devexit cel_cpld_i2c_mux_remove(struct i2c_client *client) -+{ -+ struct cel_cpld_i2c_mux *mux = i2c_get_clientdata(client); -+ struct llist_node *llnode; -+ struct cel_cpld_vadapter *entry; -+ -+ while ((llnode = llist_del_first(&mux->m_vadapter_list)) != NULL) { -+ entry = llist_entry(llnode, struct cel_cpld_vadapter, m_llnode); -+ if (entry->m_adapter) -+ (void)i2c_del_mux_adapter(entry->m_adapter); -+ kfree(entry); -+ } -+ -+ kfree(mux); -+ return 0; -+} -+ -+static const struct i2c_device_id cel_cpld_i2c_mux_ids[] = { -+ { "cpld-i2c-mux", 0 }, -+ { /* end of list */ }, -+}; -+MODULE_DEVICE_TABLE(i2c, cel_cpld_i2c_mux_ids); -+ -+static struct i2c_driver cel_cpld_i2c_mux_driver = { -+ .driver = { -+ .name = MUX_DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+ .probe = cel_cpld_i2c_mux_probe, -+ .remove = __devexit_p(cel_cpld_i2c_mux_remove), -+ .id_table = cel_cpld_i2c_mux_ids, -+}; -+ -+/* -+ * Module init/exit methods begin here. The init and exit methods -+ * register/de-register two devices: -+ * -+ * - The i2c bus adapter device -+ * - The i2c mux device -+ * -+ */ -+static int __init cel_cpld_i2c_init(void) -+{ -+ int rc; -+ -+ /* First register the i2c adapter */ -+ rc = platform_driver_register(&cel_cpld_i2c_bus_driver); -+ if (rc) { -+ printk(KERN_ERR"%s(): platform_driver_register() failed: %d\n", -+ __func__, rc); -+ return rc; -+ } -+ -+ /* Next register the i2c mux */ -+ rc = i2c_add_driver(&cel_cpld_i2c_mux_driver); -+ if (rc) { -+ printk(KERN_ERR"%s(): i2c_add_driver() failed: %d\n", -+ __func__, rc); -+ platform_driver_unregister(&cel_cpld_i2c_bus_driver); -+ } -+ -+ return rc; -+} -+ -+static void __exit cel_cpld_i2c_exit(void) -+{ -+ /* First remove the i2c mux driver */ -+ i2c_del_driver( &cel_cpld_i2c_mux_driver); -+ -+ /* Next remove the i2c adapter */ -+ platform_driver_unregister(&cel_cpld_i2c_bus_driver); -+} -+ -+module_init(cel_cpld_i2c_init); -+module_exit(cel_cpld_i2c_exit); -+ -+MODULE_AUTHOR("Curt Brune "); -+MODULE_DESCRIPTION("I2C Adapter/Mux Driver for Celestica CPLD"); -+MODULE_LICENSE("GPL v2"); -+MODULE_VERSION(BUS_MUX_DRV_VERSION); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-cumulus-p2020.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-cumulus-p2020.patch deleted file mode 100644 index 6390c060..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-cumulus-p2020.patch +++ /dev/null @@ -1,469 +0,0 @@ -Cumulus P2020 Support - -diff --git a/arch/powerpc/boot/dts/cumulus_p2020.dts b/arch/powerpc/boot/dts/cumulus_p2020.dts -new file mode 100644 -index 0000000..398b11b ---- /dev/null -+++ b/arch/powerpc/boot/dts/cumulus_p2020.dts -@@ -0,0 +1,214 @@ -+/* -+ * Cumulus P2020 Device Tree Source -+ * -+ * Copyright 2012 Cumulus Networks, 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/ "p2020si.dtsi" -+ -+/ { -+ model = "cumulus,cumulus_p2020"; -+ compatible = "cumulus,cumulus_p2020"; -+ -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ -+ mass_storage { -+ device = "mmcblk0"; -+ }; -+ -+ localbus@ffe05000 { -+ compatible = "fsl,elbc", "simple-bus"; -+ /* -+ ** Note: We are purposefully cutting the size of the -+ ** NOR flash in half, down to 128MB. Linux vmalloc() -+ ** on ppc32 has some issues trying to vmalloc more than -+ ** 256MB. -+ ** -+ ** The 256MB region should go from 0xe0000000 to -+ ** 0xf0000000, but we are skipping the first 128MB and -+ ** starting at 0xe8000000. -+ */ -+ ranges = <0x0 0x0 0x0 0xe8000000 0x08000000>; -+ -+ nor@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x08000000>; -+ bank-width = <2>; -+ partition@0 { -+ /* Entire flash minus (u-boot + onie) */ -+ reg = <0x00000000 0x07b60000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x07b60000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x07f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ /* 512KB u-boot */ -+ reg = <0x07f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ }; -+ -+ soc@ffe00000 { -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ rtc@68 { -+ compatible = "stm,m41st85"; -+ reg = <0x68>; -+ }; -+ eeprom@50 { -+ compatible = "at,24c08"; -+ reg = <0x50>; -+ }; -+ temp@4c { -+ compatible = "adi,adt7461"; -+ reg = <0x4c>; -+ }; -+ }; -+ -+ usb@22000 { -+ status = "disabled"; -+ }; -+ -+ mdio@24520 { -+ phy0: ethernet-phy@1 { -+ interrupt-parent = <&mpic>; -+ interrupts = <3 1>; -+ reg = <0x1>; -+ }; -+ phy1: ethernet-phy@2 { -+ interrupt-parent = <&mpic>; -+ interrupts = <3 1>; -+ reg = <0x2>; -+ }; -+ }; -+ -+ ptp_clock@24E00 { -+ compatible = "fsl,etsec-ptp"; -+ reg = <0x24E00 0xB0>; -+ interrupts = <68 2 69 2 70 2>; -+ interrupt-parent = < &mpic >; -+ fsl,tclk-period = <5>; -+ fsl,tmr-prsc = <200>; -+ fsl,tmr-add = <0xCCCCCCCD>; -+ fsl,tmr-fiper1 = <0x3B9AC9FB>; -+ fsl,tmr-fiper2 = <0x0001869B>; -+ fsl,max-adj = <249999999>; -+ }; -+ -+ enet0: ethernet@24000 { -+ phy-handle = <&phy0>; -+ phy-connection-type = "rgmii-id"; -+ }; -+ -+ enet1: ethernet@25000 { -+ phy-handle = <&phy1>; -+ phy-connection-type = "rgmii-id"; -+ }; -+ -+ enet2: ethernet@26000 { -+ status = "disabled"; -+ }; -+ -+ irq8@50100 { -+ reg = <0x50100 0x10>; -+ interrupt-parent = <&mpic>; -+ interrupts = <8 1>; -+ }; -+ }; -+ -+ pci0: pcie@ffe08000 { -+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x8 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x9 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0xa 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0xb 0x1 -+ >; -+ -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0x80000000 -+ 0x2000000 0x0 0x80000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x10000>; -+ }; -+ }; -+ -+ pci1: pcie@ffe09000 { -+ status = "disabled"; -+ }; -+ -+ pci2: pcie@ffe0a000 { -+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 -+ >; -+ -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xa0000000 -+ 0x2000000 0x0 0xa0000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/p2020si.dtsi b/arch/powerpc/boot/dts/p2020si.dtsi -index 6def17f..7fcc6f4 100644 ---- a/arch/powerpc/boot/dts/p2020si.dtsi -+++ b/arch/powerpc/boot/dts/p2020si.dtsi -@@ -295,6 +295,8 @@ - interrupt-parent = <&mpic>; - /* Filled in by U-Boot */ - clock-frequency = <0>; -+ // P2020 requires auto-cmd12 -+ sdhci,auto-cmd12; - }; - - crypto@30000 { -diff --git a/arch/powerpc/platforms/85xx/cumulus_p2020.c b/arch/powerpc/platforms/85xx/cumulus_p2020.c -new file mode 100644 -index 0000000..c2e8bf7 ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/cumulus_p2020.c -@@ -0,0 +1,228 @@ -+/* -+ * Copyright 2011 Cumulus Networks, Inc. -+ * -+ * P2020 setup and early boot code plus other random bits. -+ * -+ * 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 -+#include -+#include -+ -+#include -+#include -+ -+#undef DEBUG -+ -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+/******************************************************************************* -+ * -+ * Platform initialization functions -+ * -+ ******************************************************************************* -+*/ -+ -+/* -+ * Initialize the interrupt controller -+ */ -+static void __init cumulus_p2020_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np; -+ -+ np = of_find_node_by_type(NULL, "open-pic"); -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | -+ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | -+ MPIC_SINGLE_DEST_CPU, -+ 0, 256, " OpenPIC "); -+ -+ BUG_ON(mpic == NULL); -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+#ifdef CONFIG_SMP -+extern void __init mpc85xx_smp_init(void); -+#endif -+ -+static void __init cumulus_p2020_setup_arch(void) -+{ -+ struct device_node *cpu; -+ const unsigned int *fp; -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ -+ if (ppc_md.progress) -+ ppc_md.progress("cumulus_p2020_setup_arch()", 0); -+ -+ cpu = of_find_node_by_type(NULL, "cpu"); -+ if (cpu != 0) { -+ fp = of_get_property(cpu, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(cpu); -+ } -+ -+#ifdef CONFIG_PCI -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8548-pcie")) -+ fsl_add_bridge(np, 0); -+ } -+#endif -+ -+#ifdef CONFIG_SMP -+ mpc85xx_smp_init(); -+#endif -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+ -+ printk(KERN_INFO "Cumulus P2020 board from Cumulus Networks, Inc.\n"); -+} -+ -+ -+ -+static struct of_device_id __initdata cumulus_p2020_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ { .compatible = "gianfar", }, -+ {}, -+}; -+ -+ -+ -+static int __init cumulus_p2020_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, cumulus_p2020_ids, NULL); -+} -+machine_device_initcall(cumulus_p2020, cumulus_p2020_publish_devices); -+ -+ -+ -+static void cumulus_p2020_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu PLL setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init cumulus_p2020_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "cumulus,cumulus_p2020")) -+ return 1; -+ -+ return 0; -+} -+ -+void cumulus_p2020_restart(char *cmd) -+{ -+ struct device_node *np; -+ struct i2c_client *client; -+ -+ np = of_find_compatible_node(NULL, NULL, "stm,m41st85"); -+ if (np == NULL) { -+ printk(KERN_ERR __FILE__ ": Can't find stm,m41st85\n"); -+ goto newreset; -+ } -+ -+ client = of_find_i2c_device_by_node(np); -+ if (client == NULL) { -+ of_node_put(np); -+ printk(KERN_ERR __FILE__ ": Can't find device by node\n"); -+ goto newreset; -+ } -+ -+ printk(KERN_INFO "Watchdog Reset\n"); -+ // set watchdog for 1/16 of a second -+ i2c_smbus_write_byte_data(client, 0x09, 0x84); -+ // make sure the clock is running -+ i2c_smbus_write_byte_data(client, 0x01, 0x00); -+ -+newreset: -+ // asserts HRESET_REQ which will work on new hardware -+ printk(KERN_INFO "HRESET_REQ\n"); -+ fsl_rstcr_restart(cmd); -+} -+ -+define_machine(cumulus_p2020) { -+ .name = "Cumulus Networks P2020", -+ .probe = cumulus_p2020_probe, -+ .setup_arch = cumulus_p2020_setup_arch, -+ .init_IRQ = cumulus_p2020_pic_init, -+ .show_cpuinfo = cumulus_p2020_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = cumulus_p2020_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-6448-i2c-mux.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-6448-i2c-mux.patch deleted file mode 100644 index c6cc49a5..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-6448-i2c-mux.patch +++ /dev/null @@ -1,349 +0,0 @@ -The DNI 6448 uses it's CPLD to mux the I2C buses into multiple buses. - -This kernel module provides an I2C mux device usable by the I2C -infrastructure. - -diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig -index 90b7a01..2ee0386 100644 ---- a/drivers/i2c/muxes/Kconfig -+++ b/drivers/i2c/muxes/Kconfig -@@ -37,4 +37,10 @@ config I2C_MUX_PCA954x - This driver can also be built as a module. If so, the module - will be called pca954x. - -+config I2C_MUX_DNI_6448 -+ tristate "Delta Networks 6448 I2C Mux" -+ depends on EXPERIMENTAL -+ help -+ If you say yes here you get support for the DNI 6448 I2C Mux devices -+ - endmenu -diff --git a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile -index 4640436..e5bb944 100644 ---- a/drivers/i2c/muxes/Makefile -+++ b/drivers/i2c/muxes/Makefile -@@ -4,5 +4,6 @@ - obj-$(CONFIG_I2C_MUX_GPIO) += gpio-i2cmux.o - obj-$(CONFIG_I2C_MUX_PCA9541) += pca9541.o - obj-$(CONFIG_I2C_MUX_PCA954x) += pca954x.o -+obj-$(CONFIG_I2C_MUX_DNI_6448) += dni_6448_i2c_mux.o - - ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG -diff --git a/drivers/i2c/muxes/dni_6448_i2c_mux.c b/drivers/i2c/muxes/dni_6448_i2c_mux.c -new file mode 100644 -index 0000000..ecbbd1d ---- /dev/null -+++ b/drivers/i2c/muxes/dni_6448_i2c_mux.c -@@ -0,0 +1,312 @@ -+/* -+ * DNI 6448 CPLD I2C multiplexer -+ * -+ * Copyright (C) 2012 Cumulus Networks, Inc. -+ * Author: Curt Brune -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ * The DNI 6448 CPLD resides on the MPC8536 local bus and controls a a -+ * dual 1-of-4 high-speed FET multiplexer/demultiplexer. The details -+ * of the multiplexer are shielded from us as we only touch CPLD -+ * registers. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define CPLD_REG_PRODUCT_ID (0x07000) -+ -+#define CPLD_REG_I2C_1_CTRL (0x0e000) -+# define CPLD_I2C_1_EN_L (4) -+# define CPLD_I2C_1_SELECT_MSK (0x3) -+ -+#define CPLD_REG_I2C_2_CTRL (0x0f000) -+# define CPLD_I2C_2_SELECT_MSK (0x7) -+ -+// Expected product ID -+#define DNI_6448_PRODUCT_ID1 (0xa0) // single fixed power supply -+#define DNI_6448_PRODUCT_ID2 (0x80) // dual hot-swap power supplies -+#define DNI_6448_PRODUCT_ID3 (0xc0) // dual hot-swap power supplies ?? -+#define DNI_6448_PRODUCT_ID4 (0x20) // POE -+ -+static const char driver_name[] = "dni_6448_i2c_mux"; -+#define DRIVER_VERSION "1.1" -+ -+#undef DEBUG -+// #define DEBUG -+ -+#ifdef DEBUG -+#define LOG_DBG(fmt, args...) \ -+ do { \ -+ printk(KERN_ERR "%s:%s(): " fmt, \ -+ driver_name, __func__, ## args); \ -+ } while (0) -+#else -+#define LOG_DBG(fmt, args...) -+#endif -+ -+#define LOG_INFO(fmt, args...) \ -+ do { \ -+ printk(KERN_INFO "%s: " fmt, \ -+ driver_name, ## args); \ -+ } while (0) -+ -+#define LOG_ERR(fmt, args...) \ -+ do { \ -+ printk(KERN_ERR "%s:%s():ERROR: " fmt, \ -+ driver_name, __func__, ## args); \ -+ } while (0) -+ -+#define DNI_6448_MUX_NCHANS (8) -+ -+struct dni_6448_mux { -+ struct i2c_adapter* m_virt_adaps[DNI_6448_MUX_NCHANS]; -+ u8 __iomem* m_cpld_regs; /* Mem mapped CPLD */ -+ u8 m_last_chan; /* last register value */ -+ u32 m_mux_id; /* mux ID */ -+}; -+ -+static u16 dni_6448_num_channels[] = { -+ 0, -+ 4, // mux_id 1 has 4 channels -+ 8, // mux_id 2 has 8 channels -+}; -+ -+static int dni_6448_mux_select_chan(struct i2c_adapter *adap, -+ void *client, u32 chan) -+{ -+ struct dni_6448_mux* dev = i2c_get_clientdata(client); -+ u32 ctrl_reg; -+ u8 val, chan_mask; -+ -+ LOG_DBG("Setting mux %d to channel %d", dev->m_mux_id, chan); -+ -+ if (dev->m_mux_id == 1) { -+ ctrl_reg = CPLD_REG_I2C_1_CTRL; -+ chan_mask = CPLD_I2C_1_SELECT_MSK; -+ } -+ else { -+ ctrl_reg = CPLD_REG_I2C_2_CTRL; -+ chan_mask = CPLD_I2C_2_SELECT_MSK; -+ } -+ -+ if (chan & ~chan_mask) { -+ // bad channel -+ LOG_ERR("mux_id: %d -- trying to set non-existent channel %d", -+ dev->m_mux_id, chan); -+ return -EINVAL; -+ } -+ -+ if ( dev->m_last_chan != chan) { -+ -+ val = readb( dev->m_cpld_regs + ctrl_reg); -+ val &= ~chan_mask; -+ val |= chan; -+ writeb( val, dev->m_cpld_regs + ctrl_reg); -+ -+ dev->m_last_chan = chan; -+ } -+ -+ return 0; -+ -+} -+ -+/* -+ * I2C init/probing/exit functions -+ */ -+static int dni_6448_mux_probe(struct i2c_client* client, -+ const struct i2c_device_id* id) -+{ -+ struct i2c_adapter* adap = to_i2c_adapter(client->dev.parent); -+ int num; -+ struct dni_6448_mux* dev; -+ struct device_node* cpld; -+ u8 __iomem* cpld_regs; -+ u8 val; -+ int prop_len; -+ const void* prop; -+ u32 mux_id; -+ -+ int ret = -ENODEV; -+ -+ LOG_DBG("Entry"); -+ -+ if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) -+ goto err; -+ -+ cpld = of_find_compatible_node(NULL, NULL, "dni,6448-cpld"); -+ if (!cpld) { -+ LOG_ERR("Can not find 6448-cpld node in device tree\n"); -+ ret = -ENODEV; -+ goto err; -+ } -+ else { -+ cpld_regs = of_iomap(cpld, 0); -+ of_node_put(cpld); -+ } -+ -+ prop_len = 0; -+ prop = of_get_property( client->dev.of_node, "reg", &prop_len); -+ if ( (prop == NULL) || (prop_len != 4)) { -+ LOG_ERR("Can not find property for mux in device tree\n"); -+ LOG_ERR("prop is %sNULL. prop_len: %d\n", -+ (prop == NULL) ? "" : "not ", -+ prop_len); -+ ret = -ENODEV; -+ goto err; -+ } -+ else { -+ mux_id = *((u32*)prop); -+ LOG_DBG("mux_id: %d", mux_id); -+ } -+ -+ // Try to read a register and make sure we're good -+ val = readb( cpld_regs + CPLD_REG_PRODUCT_ID); -+ if ( (val != DNI_6448_PRODUCT_ID1) && -+ (val != DNI_6448_PRODUCT_ID2) && -+ (val != DNI_6448_PRODUCT_ID3) && -+ (val != DNI_6448_PRODUCT_ID4)) { -+ LOG_ERR("Can not verify dni-6448 product ID 0x%02x\n",val); -+ ret = -ENODEV; -+ goto err; -+ } -+ -+ dev = kzalloc(sizeof(struct dni_6448_mux), GFP_KERNEL); -+ if (!dev) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ i2c_set_clientdata(client, dev); -+ -+ dev->m_cpld_regs = cpld_regs; -+ dev->m_mux_id = mux_id; -+ -+ // Default to channel-0 and enable controller -+ if (mux_id == 1) { -+ val = readb( dev->m_cpld_regs + CPLD_REG_I2C_1_CTRL); -+ val &= ~CPLD_I2C_1_SELECT_MSK; -+ // also clear output enable, active low -+ val &= ~(1 << CPLD_I2C_1_EN_L); -+ writeb( val, dev->m_cpld_regs + CPLD_REG_I2C_1_CTRL); -+ } -+ else { -+ val = readb( dev->m_cpld_regs + CPLD_REG_I2C_2_CTRL); -+ val &= ~CPLD_I2C_2_SELECT_MSK; -+ writeb( val, dev->m_cpld_regs + CPLD_REG_I2C_2_CTRL); -+ } -+ dev->m_last_chan = 0; -+ -+ /* Now create an adapter for each channel */ -+ for (num = 0; num < dni_6448_num_channels[dev->m_mux_id]; num++) { -+ dev->m_virt_adaps[num] = -+ i2c_add_mux_adapter(adap, &client->dev, client, -+ 0, num, -+ dni_6448_mux_select_chan, -+ NULL); -+ -+ if (dev->m_virt_adaps[num] == NULL) { -+ ret = -ENODEV; -+ dev_err(&client->dev, -+ "failed to register multiplexed adapter %d\n", -+ num); -+ goto virt_reg_failed; -+ } -+ } -+ -+ dev_info(&client->dev, -+ "registered %d multiplexed buses for %s, mux_id %d\n", -+ num, driver_name, mux_id); -+ -+ LOG_DBG("Exit"); -+ return 0; -+ -+virt_reg_failed: -+ for (num--; num >= 0; num--) -+ i2c_del_mux_adapter(dev->m_virt_adaps[num]); -+ -+ kfree(dev); -+err: -+ LOG_DBG("Error Exit"); -+ return ret; -+} -+ -+static int dni_6448_mux_remove(struct i2c_client* client) -+{ -+ struct dni_6448_mux* dev = i2c_get_clientdata(client); -+ int i, err; -+ -+ LOG_DBG("Entry"); -+ for (i = 0; i < dni_6448_num_channels[dev->m_mux_id]; ++i) -+ if (dev->m_virt_adaps[i]) { -+ err = i2c_del_mux_adapter(dev->m_virt_adaps[i]); -+ if (err) -+ return err; -+ dev->m_virt_adaps[i] = NULL; -+ } -+ -+ kfree(dev); -+ LOG_DBG("Exit"); -+ return 0; -+} -+ -+static const struct i2c_device_id dni_6448_mux_ids[] = { -+ { "6448-i2c-mux", 0 }, -+ { /* end of list */ }, -+}; -+ -+static struct i2c_driver dni_6448_mux_driver = { -+ .driver = { -+ .name = driver_name, -+ .owner = THIS_MODULE, -+ }, -+ .probe = dni_6448_mux_probe, -+ .remove = dni_6448_mux_remove, -+ .id_table = dni_6448_mux_ids, -+}; -+ -+static int __init dni_6448_mux_init(void) -+{ -+ int rc; -+ -+ LOG_DBG("Loading %s", driver_name); -+ rc = i2c_add_driver( &dni_6448_mux_driver); -+ if ( rc) { -+ LOG_ERR("i2c_add_driver() failed"); -+ } -+ return rc; -+} -+ -+static void __exit dni_6448_mux_exit(void) -+{ -+ LOG_DBG("Entry"); -+ i2c_del_driver( &dni_6448_mux_driver); -+ LOG_DBG("Exit"); -+} -+ -+module_init(dni_6448_mux_init); -+module_exit(dni_6448_mux_exit); -+ -+MODULE_AUTHOR("Curt Brune "); -+MODULE_DESCRIPTION("I2C Mux Driver for Delta Networks Inc. ET6448"); -+MODULE_LICENSE("GPL v2"); -+MODULE_VERSION(DRIVER_VERSION); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-6448.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-6448.patch deleted file mode 100644 index a8a1b649..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-6448.patch +++ /dev/null @@ -1,672 +0,0 @@ -Add support for DNI-6448 board. - -diff --git a/arch/powerpc/boot/dts/dni_6448.dts b/arch/powerpc/boot/dts/dni_6448.dts -new file mode 100644 -index 0000000..749d1d9 ---- /dev/null -+++ b/arch/powerpc/boot/dts/dni_6448.dts -@@ -0,0 +1,433 @@ -+/* -+ * Delta Networks, Inc. ET-6448R Device Tree Source -+ * -+ * Copyright 2012, Cumulus Networks, 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/; -+ -+/ { -+ model = "dni,et-6448r"; -+ compatible = "dni,dni_6448"; -+ #address-cells = <0x2>; -+ #size-cells = <0x2>; -+ interrupt-parent = <&MPIC>; -+ aliases { -+ ethernet0 = &ENET0; -+ serial0 = &SERIAL0; -+ serial1 = &SERIAL1; -+ pci3 = &pci3; -+ }; -+ cpus { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ PowerPC,8536@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ d-cache-line-size = <32>; // 32 bytes -+ i-cache-line-size = <32>; // 32 bytes -+ d-cache-size = <0x8000>; // L1, 32K -+ i-cache-size = <0x8000>; // L1, 32K -+ timebase-frequency = <0>; // From uboot -+ bus-frequency = <0>; // From uboot -+ clock-frequency = <0>; // From uboot -+ next-level-cache = <&L2>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ -+ localbus@e0005000 { -+ #address-cells = <0x2>; -+ #size-cells = <0x1>; -+ compatible = "fsl,8536-elbc", "fsl,elbc", "simple-bus"; -+ reg = <0x0 0xe0005000 0x0 0x00001000>; -+ interrupts = <0x13 0x2>; -+ ranges = < -+ 0x0 0x0 0x0 0xfc000000 0x04000000 -+ 0x1 0x0 0x0 0xfa000000 0x00040000 -+ >; -+ flash@0,0 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x04000000>; -+ bank-width = <0x4>; -+ device-width = <0x2>; -+ byteswap; -+ partition@0 { -+ /* Entire flash minus (u-boot + info + onie) */ -+ reg = <0x00000000 0x03b00000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x03b00000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ /* 256KB, 1 sector */ -+ reg = <0x03f00000 0x00040000>; -+ label = "board_eeprom"; -+ }; -+ partition@3 { -+ /* 256KB, 1 sector */ -+ reg = <0x03f40000 0x00040000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@4 { -+ /* 512KB u-boot */ -+ reg = <0x03f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ cpld@1,0 { -+ compatible = "dni,6448-cpld"; -+ reg = <0x1 0x0 0x00040000>; -+ }; -+ }; -+ -+ soc@e0000000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ device_type = "soc"; -+ compatible = "fsl,8536-immr", "simple-bus"; -+ ranges = <0x0 0x0 0xe0000000 0x100000>; -+ bus-frequency = <0x0>; // From uboot -+ -+ memory-controller@2000 { -+ compatible = "fsl,mpc8536-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupts = <0x12 0x2>; -+ }; -+ -+ I2C0: i2c@3000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ cell-index = <0x0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <0x2b 0x2>; -+ dfsrr; -+ clock-frequency = <400000>; -+ fsl,timeout = <10000>; -+ mux@1 { -+ compatible = "dni,6448-i2c-mux"; -+ reg = <0x1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ // front panel port 45 -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port45"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ // front panel port 46 -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port46"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ // front panel port 47 -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port47"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ // front panel port 48 -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port48"; -+ }; -+ }; -+ }; -+ spd@52 { -+ read-only; -+ compatible = "at,spd"; -+ reg = <0x53>; -+ }; -+ }; -+ -+ I2C1: i2c@3100 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ cell-index = <0x1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <0x2b 0x2>; -+ dfsrr; -+ clock-frequency = <400000>; -+ fsl,timeout = <10000>; -+ mux@2 { -+ compatible = "dni,6448-i2c-mux"; -+ reg = <0x2>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ tmon@48 { -+ compatible = "ti,tmp75"; -+ reg = <0x48>; -+ }; -+ tmon@49 { -+ compatible = "ti,tmp75"; -+ reg = <0x49>; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ -+ hwmon@40 { -+ compatible = "lt,ltc4215"; -+ reg = <0x40>; -+ }; -+ psu_eeprom@54 { -+ compatible = "at,24c08"; -+ reg = <0x54>; -+ label = "psu1_eeprom"; -+ read-only; -+ }; -+ psu_eeprom@50 { -+ compatible = "at,24c08"; -+ reg = <0x50>; -+ label = "psu2_eeprom"; -+ read-only; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ -+ fan@48 { -+ compatible = "maxim,max6651"; -+ reg = <0x48>; -+ }; -+ rtc@68 { -+ compatible = "stm,m41st85"; -+ reg = <0x68>; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ // 10G module A.1 -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port49"; -+ }; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ // 10G module A.2 -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port50"; -+ }; -+ }; -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ // 10G module B.1 -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port51"; -+ }; -+ }; -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ // 10G module B.2 -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port52"; -+ }; -+ }; -+ }; -+ }; -+ -+ SERIAL0: serial@4500 { -+ cell-index = <0x0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0x0>; -+ interrupts = <0x2a 0x2>; -+ }; -+ -+ SERIAL1: serial@4600 { -+ cell-index = <1>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4600 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 0x2>; -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,mpc8536-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <0x20>; -+ cache-size = <0x80000>; -+ interrupts = <0x10 0x2>; -+ }; -+ -+ USB: usb@22000 { -+ compatible = "fsl-usb2-dr"; -+ reg = <0x22000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = <28 0x2>; -+ phy_type = "ulpi"; -+ dr_mode = "host"; -+ }; -+ -+ MDIO1: mdio@24520 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ PHY0: ethernet-phy@4 { -+ reg = <0x4>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ -+ ENET0: ethernet@24000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ cell-index = <0x1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x24000 0x1000>; -+ ranges = <0x0 0x24000 0x1000>; -+ interrupts = < -+ 0x1d 0x2 -+ 0x1e 0x2 -+ 0x22 0x2>; -+ phy-handle = <&PHY0>; -+ phy-connection-type = "rgmii"; -+ }; -+ -+ MPIC: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0x0>; -+ #interrupt-cells = <0x2>; -+ reg = <0x40000 0x40000>; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ }; -+ msi@41600 { -+ compatible = "fsl,mpc8536-msi", "fsl,mpic-msi"; -+ reg = <0x41600 0x80>; -+ msi-available-ranges = <0x0 0x100>; -+ interrupts = < -+ 0xe0 0x0 -+ 0xe1 0x0 -+ 0xe2 0x0 -+ 0xe3 0x0 -+ 0xe4 0x0 -+ 0xe5 0x0 -+ 0xe6 0x0 -+ 0xe7 0x0>; -+ }; -+ global-utilities@e0000 { -+ compatible = "fsl,mpc8548-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ }; -+ -+ pci3: pcie@e000b000 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0 0xe000b000 0 0x1000>; -+ bus-range = <0 0xff>; -+ ranges = <0x02000000 0 0xa0000000 0 0xa0000000 0 0x20000000 -+ 0x01000000 0 0x00000000 0 0xe3000000 0 0x01000000>; -+ clock-frequency = <33333333>; -+ interrupts = <27 0x2>; -+ interrupt-map-mask = <0xf800 0 0 7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0 0 1 &MPIC 8 1 -+ 0000 0 0 2 &MPIC 9 1 -+ 0000 0 0 3 &MPIC 10 1 -+ 0000 0 0 4 &MPIC 11 1 -+ >; -+ -+ // not sure what this seciton does, but cribbed from mpc8536ds.dts -+ pcie@0 { -+ reg = <0 0 0 0 0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x02000000 0 0xa0000000 -+ 0x02000000 0 0xa0000000 -+ 0 0x20000000 -+ -+ 0x01000000 0 0x00000000 -+ 0x01000000 0 0x00000000 -+ 0 0x01000000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/dni_6448.c b/arch/powerpc/platforms/85xx/dni_6448.c -new file mode 100644 -index 0000000..9c99bd9 ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/dni_6448.c -@@ -0,0 +1,225 @@ -+/* -+ * DNI 6448 - MPC8536 setup and early boot code plus other random bits. -+ * -+ * Copyright 2012 Cumulus Networks, 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 -+ -+#include -+#include -+ -+#undef DEBUG -+// #define DEBUG -+ -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_ERR "dni-6448:%s: " fmt, __func__, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+/* -+ * Enough of the CPLD to reset the system... full driver loads as a module -+*/ -+static uint8_t __iomem* cpld_regs; -+static uint32_t CPLD_REG_RESET = 0x02000; -+ -+/******************************************************************************* -+ * -+ * Platform initialization functions -+ * -+ ******************************************************************************* -+*/ -+ -+/* -+ * Initialize the interrupt controller -+ */ -+static void __init dni_6448_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np; -+ -+ np = of_find_node_by_type(NULL, "open-pic"); -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | -+ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | -+ MPIC_SINGLE_DEST_CPU, -+ 0, 256, " OpenPIC "); -+ -+ BUG_ON(mpic == NULL); -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+#ifdef CONFIG_SMP -+extern void __init mpc85xx_smp_init(void); -+#endif -+ -+static void __init dni_6448_setup_arch(void) -+{ -+ struct device_node *cpu; -+ const unsigned int *fp; -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ struct device_node *cpld; -+ -+ if (ppc_md.progress) -+ ppc_md.progress("dni_6448_setup_arch()", 0); -+ -+ cpu = of_find_node_by_type(NULL, "cpu"); -+ if (cpu != 0) { -+ fp = of_get_property(cpu, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(cpu); -+ } -+ -+#ifdef CONFIG_PCI -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8548-pcie")) -+ fsl_add_bridge(np, 0); -+ } -+#endif -+ -+ cpld = of_find_compatible_node(NULL, NULL, "dni,6448-cpld"); -+ if (!cpld) { -+ printk(KERN_ERR "Can not find 6448-cpld node in device tree\n"); -+ cpld_regs = NULL; -+ } else { -+ cpld_regs = of_iomap(cpld, 0); -+ of_node_put(cpld); -+ } -+ -+ powersave_nap = 0; -+ -+#ifdef CONFIG_SMP -+ mpc85xx_smp_init(); -+#endif -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+} -+ -+ -+ -+static struct of_device_id __initdata dni_6448_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ { .compatible = "gianfar", }, -+ {}, -+}; -+ -+ -+ -+static int __init dni_6448_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, dni_6448_ids, NULL); -+} -+machine_device_initcall(dni_6448, dni_6448_publish_devices); -+ -+ -+ -+static void dni_6448_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu Pll setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+ -+/* -+ * Platform specific restart... need to use the CPLD -+ */ -+static void dni_6448_restart(char *cmd) -+{ -+ printk (KERN_EMERG "Reset via the platform CPLD\n"); -+ -+ local_irq_disable(); -+ writeb(0, (cpld_regs + CPLD_REG_RESET)); -+ while (1); -+} -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init dni_6448_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "dni,dni_6448")) -+ return 1; -+ -+ return 0; -+} -+ -+define_machine(dni_6448) { -+ .name = "Delta Networks, Inc ET-6448", -+ .probe = dni_6448_probe, -+ .setup_arch = dni_6448_setup_arch, -+ .init_IRQ = dni_6448_pic_init, -+ .show_cpuinfo = dni_6448_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = dni_6448_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-7448.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-7448.patch deleted file mode 100644 index 0bf9ccc4..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-7448.patch +++ /dev/null @@ -1,608 +0,0 @@ -#Copyright 2012 Cumulus Networks, Inc. All rights reserved. - -Platform support for the DNI ET-7448 48x10+4x40 TOR platform - -diff --git a/arch/powerpc/boot/dts/dni_7448.dts b/arch/powerpc/boot/dts/dni_7448.dts -new file mode 100644 -index 0000000..f7a2563 ---- /dev/null -+++ b/arch/powerpc/boot/dts/dni_7448.dts -@@ -0,0 +1,331 @@ -+/* -+ * Delta Networks, Inc. ET-7448BF Device Tree Source -+ * -+ * Copyright 2012, Cumulus Networks, 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/; -+ -+/ { -+ model = "dni,et-7448bf"; -+ compatible = "dni,dni_7448"; -+ #address-cells = <0x2>; -+ #size-cells = <0x2>; -+ aliases { -+ ethernet0 = &ENET2; -+ serial0 = &SERIAL0; -+ serial1 = &SERIAL1; -+ pci2 = &PCI2; -+ }; -+ cpus { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ PowerPC,P2020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <0x1>; -+ }; -+ PowerPC,P2020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <0x1>; -+ }; -+ }; -+ memory { -+ device_type = "memory"; -+ }; -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ mass_storage { -+ device = "mmcblk0"; -+ }; -+ localbus@ffe05000 { -+ #address-cells = <0x2>; -+ #size-cells = <0x1>; -+ compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus"; -+ reg = <0x0 0xffe05000 0x0 0x00001000>; -+ interrupts = <19 0x2>; -+ interrupt-parent = <&MPIC>; -+ ranges = <0x0 0x0 0x0 0xe8000000 0x8000000 -+ 0x1 0x0 0x0 0xffdf0000 0x0000100>; -+ nor@0,0 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x8000000>; -+ bank-width = <0x2>; -+ device-width = <0x2>; -+ byteswap; -+ partition@0 { -+ /* Entire flash minus (u-boot + onie) */ -+ reg = <0x00000000 0x07b60000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x07b60000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x07f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ /* 512KB u-boot */ -+ reg = <0x07f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ cpld@1,0 { -+ compatible = "dni,7448-cpld"; -+ reg = <0x1 0x0 0x0000100>; -+ }; -+ }; -+ soc@ffe00000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ device_type = "soc"; -+ compatible = "fsl,p2020-immr", "simple-bus"; -+ ranges = <0x0 0x0 0xffe00000 0x100000>; -+ bus-frequency = <0x0>; -+ memory-controller@2000 { -+ compatible = "fsl,p2020-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupt-parent = <&MPIC>; -+ interrupts = <0x12 0x2>; -+ }; -+ I2C0: i2c@3000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ cell-index = <0x0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <0x2b 0x2>; -+ interrupt-parent = <&MPIC>; -+ dfsrr; -+ rtc@68 { -+ compatible = "stm,m41st85"; -+ reg = <0x68>; -+ }; -+ board_eeprom@54 { -+ compatible = "at,24c08"; -+ reg = <0x54>; -+ label = "board_eeprom"; -+ }; -+ spd@52 { -+ read-only; -+ compatible = "at,spd"; -+ reg = <0x52>; -+ }; -+ }; -+ I2C1: i2c@3100 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ cell-index = <0x1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <0x2b 0x2>; -+ interrupt-parent = <&MPIC>; -+ dfsrr; -+ fan@1b { -+ compatible = "maxim,max6650"; -+ reg = <0x1b>; -+ }; -+ fan@1f { -+ compatible = "maxim,max6650"; -+ reg = <0x1f>; -+ }; -+ fan@48 { -+ compatible = "maxim,max6650"; -+ reg = <0x48>; -+ }; -+ fan@4b { -+ compatible = "maxim,max6650"; -+ reg = <0x4b>; -+ }; -+ hotswap@40 { -+ compatible = "lt,ltc4215"; -+ reg = <0x40>; -+ }; -+ hotswap@42 { -+ compatible = "lt,ltc4215"; -+ reg = <0x42>; -+ }; -+ tmon@49 { -+ compatible = "ti,tmp75"; -+ reg = <0x49>; -+ }; -+ tmon@4a { -+ compatible = "ti,tmp75"; -+ reg = <0x4a>; -+ }; -+ tmon@4c { -+ compatible = "ti,tmp75"; -+ reg = <0x4c>; -+ }; -+ tmon@4d { -+ compatible = "ti,tmp75"; -+ reg = <0x4d>; -+ }; -+ psu_eeprom@50 { -+ read-only; -+ label = "psu2_eeprom"; -+ compatible = "at,24c08"; -+ reg = <0x50>; -+ }; -+ psu_eeprom@54 { -+ read-only; -+ label = "psu1_eeprom"; -+ compatible = "at,24c08"; -+ reg = <0x54>; -+ }; -+ }; -+ SERIAL0: serial@4500 { -+ cell-index = <0x0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0x0>; -+ interrupts = <0x2a 0x2>; -+ interrupt-parent = <&MPIC>; -+ }; -+ SERIAL1: serial@4600 { -+ cell-index = <0x1>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4600 0x100>; -+ clock-frequency = <0x0>; -+ interrupts = <0x2a 0x2>; -+ interrupt-parent = <&MPIC>; -+ }; -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,p2020-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <0x20>; -+ cache-size = <0x80000>; -+ interrupt-parent = <&MPIC>; -+ interrupts = <0x10 0x2>; -+ }; -+ MDIO1: mdio@24520 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ PHY1: ethernet-phy@1 { -+ reg = <0x1>; -+ device_type = "ethernet-phy"; -+ }; -+ TBI1: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ ENET2: ethernet@26000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ cell-index = <0x1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x26000 0x1000>; -+ ranges = <0x0 0x26000 0x1000>; -+ interrupts = < -+ 0x1f 0x2 -+ 0x20 0x2 -+ 0x21 0x2>; -+ interrupt-parent = <&MPIC>; -+ tbi-handle = <&TBI2>; -+ phy-handle = <&PHY1>; -+ phy-connection-type = "sgmii"; -+ }; -+ MDIO2: mdio@26520 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ compatible = "fsl,gianfar-tbi"; -+ reg = <0x520 0x20>; -+ TBI2: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ SDHCI: sdhci@2e000 { -+ compatible = "fsl,p2020-esdhc", "fsl,esdhc"; -+ reg = <0x2e000 0x1000>; -+ interrupts = <0x48 0x2>; -+ interrupt-parent = <&MPIC>; -+ clock-frequency = <0x0>; -+ // P2020 requires auto-cmd12 -+ sdhci,auto-cmd12; -+ }; -+ MPIC: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0x0>; -+ #interrupt-cells = <0x2>; -+ reg = <0x40000 0x40000>; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ }; -+ msi@41600 { -+ compatible = "fsl,mpic-msi"; -+ reg = <0x41600 0x80>; -+ msi-available-ranges = <0x0 0x100>; -+ interrupts = < -+ 0xe0 0x0 -+ 0xe1 0x0 -+ 0xe2 0x0 -+ 0xe3 0x0 -+ 0xe4 0x0 -+ 0xe5 0x0 -+ 0xe6 0x0 -+ 0xe7 0x0>; -+ interrupt-parent = <&MPIC>; -+ }; -+ global-utilities@e0000 { -+ compatible = "fsl,p2020-guts", "fsl,mpc8548-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ }; -+ PCI2: pcie@ffe0a000 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #interrupt-cells = <0x1>; -+ #size-cells = <0x2>; -+ #address-cells = <0x3>; -+ reg = <0x0 0xffe0a000 0x0 0x1000>; -+ bus-range = <0x0 0xff>; -+ ranges = <0x2000000 0x0 0xc0000000 0x0 0xc0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0x0 0xffc20000 0x0 0x00010000>; -+ clock-frequency = <0x5f5e100>; -+ interrupt-parent = <&MPIC>; -+ interrupts = <0x1a 0x2>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0x0 0x0 0x0 0x1 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x2 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x3 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x4 &MPIC 0x0 0x1>; -+ -+ -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <0x2>; -+ #address-cells = <0x3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xc0000000 0x2000000 0x0 0xc0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0x1000000 0x0 0x00000000 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/dni_7448.c b/arch/powerpc/platforms/85xx/dni_7448.c -new file mode 100644 -index 0000000..4618bef ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/dni_7448.c -@@ -0,0 +1,261 @@ -+/* -+ * DNI 7448 - P2020 setup and early boot code plus other random bits. -+ * -+ * Copyright 2012 Cumulus Networks, 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 -+ -+#include -+#include -+ -+#undef DEBUG -+ -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+/* -+ * Enough of the CPLD to reset the system... full driver loads as a module -+*/ -+static uint8_t __iomem * cpld_regs; -+static uint32_t CPLD_RESET_REG = 0x20; -+ -+/******************************************************************************* -+ * -+ * Platform initialization functions -+ * -+ ******************************************************************************* -+*/ -+ -+/* -+ * Initialize the interrupt controller -+ */ -+static void __init dni_7448_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np; -+ -+ np = of_find_node_by_type(NULL, "open-pic"); -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | -+ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | -+ MPIC_SINGLE_DEST_CPU, -+ 0, 256, " OpenPIC "); -+ -+ BUG_ON(mpic == NULL); -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+#ifdef CONFIG_SMP -+extern void __init mpc85xx_smp_init(void); -+#endif -+ -+static void __init dni_7448_setup_arch(void) -+{ -+ struct device_node *cpu; -+ const unsigned int *fp; -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ struct device_node *cpld; -+#ifdef CONFIG_MMC_SDHCI_OF_ESDHC -+ struct device_node *esdhc; -+ struct property *clk_prop; -+ unsigned int *clk; -+#endif -+ -+ if (ppc_md.progress) -+ ppc_md.progress("dni_7448_setup_arch()", 0); -+ -+ cpu = of_find_node_by_type(NULL, "cpu"); -+ if (cpu != 0) { -+ fp = of_get_property(cpu, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(cpu); -+ } -+ -+#ifdef CONFIG_PCI -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8548-pcie")) -+ fsl_add_bridge(np, 0); -+ } -+#endif -+ -+ cpld = of_find_compatible_node(NULL, NULL, "dni,7448-cpld"); -+ if (!cpld) { -+ printk(KERN_ERR "Can not find 7448-cpld node in device tree\n"); -+ cpld_regs = NULL; -+ } else { -+ cpld_regs = of_iomap(cpld, 0); -+ of_node_put(cpld); -+ } -+ -+#ifdef CONFIG_MMC_SDHCI_OF_ESDHC -+ esdhc = of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc"); -+ if (esdhc != NULL) { -+ clk_prop = of_find_property(esdhc, "clock-frequency", NULL); -+ if (clk_prop != NULL) { -+ /* -+ ** Increase reported SDHC clock-frequency by 2x. -+ ** This will cause the actual hardware bus speed -+ ** to be 2x slower (calculated by driver). -+ ** -+ ** The 2x number is imperical. One box I had -+ ** required a 1.1x increase, while another one -+ ** required a 1.4x increase. Using 2x to -+ ** hopefully never revisit. -+ ** -+ ** The slower hardware bus speed gives the part -+ ** more margin for safe operation. Without this -+ ** fix-up the SDHC will sometimes report CRC -+ ** errors on bus transactions and never recover. -+ */ -+ clk = clk_prop->value; -+ *clk = *clk * 2; -+ } -+ else { -+ printk(KERN_ERR "dni_7448: Can not find SDHC clock-frequency\n"); -+ } -+ of_node_put(esdhc); -+ } -+ else { -+ printk(KERN_ERR "dni_7448: Can not find p2020-esdhc in device tree\n"); -+ } -+#endif -+ powersave_nap = 0; -+ -+#ifdef CONFIG_SMP -+ mpc85xx_smp_init(); -+#endif -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+} -+ -+ -+ -+static struct of_device_id __initdata dni_7448_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ { .compatible = "gianfar", }, -+ {}, -+}; -+ -+ -+ -+static int __init dni_7448_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, dni_7448_ids, NULL); -+} -+machine_device_initcall(dni_7448, dni_7448_publish_devices); -+ -+ -+ -+static void dni_7448_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu Pll setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+ -+/* -+ * Platform specific restart... need to use the CPLD -+ */ -+static void dni_7448_restart(char *cmd) -+{ -+ printk (KERN_EMERG "Reset via the platform CPLD\n"); -+ -+ local_irq_disable(); -+ writeb(0, (cpld_regs + CPLD_RESET_REG)); -+ while (1); -+} -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init dni_7448_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "dni,dni_7448")) -+ return 1; -+ -+ return 0; -+} -+ -+define_machine(dni_7448) { -+ .name = "Delta Networks, Inc ET-7448", -+ .probe = dni_7448_probe, -+ .setup_arch = dni_7448_setup_arch, -+ .init_IRQ = dni_7448_pic_init, -+ .show_cpuinfo = dni_7448_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = dni_7448_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-c7448n.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-c7448n.patch deleted file mode 100644 index e1fb7054..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-dni-c7448n.patch +++ /dev/null @@ -1,607 +0,0 @@ -#Copyright 2012 Cumulus Networks, Inc. All rights reserved. - -Platform support for the DNI C7448N 48x10+4x40 TOR platform - -diff --git a/arch/powerpc/boot/dts/dni_c7448n.dts b/arch/powerpc/boot/dts/dni_c7448n.dts -new file mode 100644 -index 0000000..f33b3b6 ---- /dev/null -+++ b/arch/powerpc/boot/dts/dni_c7448n.dts -@@ -0,0 +1,327 @@ -+/* -+ * Delta Networks, Inc. C7448N Device Tree Source -+ * -+ * Copyright 2014, Cumulus Networks, 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/; -+ -+/ { -+ model = "dni,c7448n"; -+ compatible = "dni,c7448n"; -+ #address-cells = <0x2>; -+ #size-cells = <0x2>; -+ aliases { -+ ethernet0 = &ENET2; -+ serial0 = &SERIAL0; -+ serial1 = &SERIAL1; -+ pci2 = &PCI2; -+ }; -+ cpus { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ PowerPC,P2020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <0x1>; -+ }; -+ PowerPC,P2020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <0x1>; -+ }; -+ }; -+ memory { -+ device_type = "memory"; -+ }; -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ mass_storage { -+ device = "mmcblk0"; -+ }; -+ localbus@ffe05000 { -+ #address-cells = <0x2>; -+ #size-cells = <0x1>; -+ compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus"; -+ reg = <0x0 0xffe05000 0x0 0x00001000>; -+ interrupts = <19 0x2>; -+ interrupt-parent = <&MPIC>; -+ ranges = <0x0 0x0 0x0 0xe8000000 0x8000000 -+ 0x1 0x0 0x0 0xffdf0000 0x0000100>; -+ nor@0,0 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x8000000>; -+ bank-width = <0x2>; -+ device-width = <0x2>; -+ byteswap; -+ partition@0 { -+ /* Entire flash minus (u-boot + onie) */ -+ reg = <0x00000000 0x07b60000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x07b60000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x07f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ /* 512KB u-boot */ -+ reg = <0x07f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ cpld@1,0 { -+ compatible = "dni,c7448n-cpld"; -+ reg = <0x1 0x0 0x0000100>; -+ }; -+ }; -+ soc@ffe00000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ device_type = "soc"; -+ compatible = "fsl,p2020-immr", "simple-bus"; -+ ranges = <0x0 0x0 0xffe00000 0x100000>; -+ bus-frequency = <0x0>; -+ memory-controller@2000 { -+ compatible = "fsl,p2020-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupt-parent = <&MPIC>; -+ interrupts = <0x12 0x2>; -+ }; -+ I2C0: i2c@3000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ cell-index = <0x0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <0x2b 0x2>; -+ interrupt-parent = <&MPIC>; -+ dfsrr; -+ rtc@68 { -+ compatible = "stm,m41st85"; -+ reg = <0x68>; -+ }; -+ board_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "board_eeprom"; -+ }; -+ spd@52 { -+ read-only; -+ compatible = "at,spd"; -+ reg = <0x52>; -+ }; -+ }; -+ I2C1: i2c@3100 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ cell-index = <0x1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <0x2b 0x2>; -+ interrupt-parent = <&MPIC>; -+ dfsrr; -+ fan@29 { -+ compatible = "maxim,max6620"; -+ reg = <0x29>; -+ }; -+ hotswap@40 { -+ compatible = "lt,ltc4215"; -+ reg = <0x40>; -+ }; -+ hotswap@42 { -+ compatible = "lt,ltc4215"; -+ reg = <0x42>; -+ }; -+ tmon@49 { -+ compatible = "ti,tmp75"; -+ reg = <0x49>; -+ }; -+ tmon@4a { -+ compatible = "ti,tmp75"; -+ reg = <0x4a>; -+ }; -+ tmon@4b { -+ compatible = "ti,tmp75"; -+ reg = <0x4b>; -+ }; -+ tmon@4c { -+ compatible = "ti,tmp75"; -+ reg = <0x4c>; -+ }; -+ psu2_eeprom@50 { -+ read-only; -+ label = "psu2_eeprom"; -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ }; -+ psu1_eeprom@51 { -+ read-only; -+ label = "psu1_eeprom"; -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ }; -+ psu2_fan@59 { -+ compatible = "dni_dps460"; -+ reg = <0x59>; -+ }; -+ psu1_fan@58 { -+ compatible = "dni_dps460"; -+ reg = <0x58>; -+ }; -+ }; -+ SERIAL0: serial@4500 { -+ cell-index = <0x0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0x0>; -+ interrupts = <0x2a 0x2>; -+ interrupt-parent = <&MPIC>; -+ }; -+ SERIAL1: serial@4600 { -+ cell-index = <0x1>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4600 0x100>; -+ clock-frequency = <0x0>; -+ interrupts = <0x2a 0x2>; -+ interrupt-parent = <&MPIC>; -+ }; -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,p2020-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <0x20>; -+ cache-size = <0x80000>; -+ interrupt-parent = <&MPIC>; -+ interrupts = <0x10 0x2>; -+ }; -+ MDIO1: mdio@24520 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ PHY1: ethernet-phy@1 { -+ reg = <0x1>; -+ device_type = "ethernet-phy"; -+ }; -+ TBI1: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ ENET2: ethernet@26000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ cell-index = <0x1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x26000 0x1000>; -+ ranges = <0x0 0x26000 0x1000>; -+ interrupts = < -+ 0x1f 0x2 -+ 0x20 0x2 -+ 0x21 0x2>; -+ interrupt-parent = <&MPIC>; -+ tbi-handle = <&TBI2>; -+ phy-handle = <&PHY1>; -+ phy-connection-type = "sgmii"; -+ }; -+ MDIO2: mdio@26520 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ compatible = "fsl,gianfar-tbi"; -+ reg = <0x520 0x20>; -+ TBI2: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ SDHCI: sdhci@2e000 { -+ compatible = "fsl,p2020-esdhc", "fsl,esdhc"; -+ reg = <0x2e000 0x1000>; -+ interrupts = <0x48 0x2>; -+ interrupt-parent = <&MPIC>; -+ clock-frequency = <0x0>; -+ // P2020 requires auto-cmd12 -+ sdhci,auto-cmd12; -+ }; -+ MPIC: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0x0>; -+ #interrupt-cells = <0x2>; -+ reg = <0x40000 0x40000>; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ }; -+ msi@41600 { -+ compatible = "fsl,mpic-msi"; -+ reg = <0x41600 0x80>; -+ msi-available-ranges = <0x0 0x100>; -+ interrupts = < -+ 0xe0 0x0 -+ 0xe1 0x0 -+ 0xe2 0x0 -+ 0xe3 0x0 -+ 0xe4 0x0 -+ 0xe5 0x0 -+ 0xe6 0x0 -+ 0xe7 0x0>; -+ interrupt-parent = <&MPIC>; -+ }; -+ global-utilities@e0000 { -+ compatible = "fsl,p2020-guts", "fsl,mpc8548-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ }; -+ PCI2: pcie@ffe0a000 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #interrupt-cells = <0x1>; -+ #size-cells = <0x2>; -+ #address-cells = <0x3>; -+ reg = <0x0 0xffe0a000 0x0 0x1000>; -+ bus-range = <0x0 0xff>; -+ ranges = <0x2000000 0x0 0xc0000000 0x0 0xc0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0x0 0xffc20000 0x0 0x00010000>; -+ clock-frequency = <0x5f5e100>; -+ interrupt-parent = <&MPIC>; -+ interrupts = <0x1a 0x2>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0x0 0x0 0x0 0x1 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x2 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x3 &MPIC 0x0 0x1 -+ 0x0 0x0 0x0 0x4 &MPIC 0x0 0x1>; -+ -+ -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <0x2>; -+ #address-cells = <0x3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xc0000000 0x2000000 0x0 0xc0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0x1000000 0x0 0x00000000 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/dni_c7448n.c b/arch/powerpc/platforms/85xx/dni_c7448n.c -new file mode 100644 -index 0000000..d4a5d7a ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/dni_c7448n.c -@@ -0,0 +1,264 @@ -+/* -+ * DNI 7448 - P2020 setup and early boot code plus other random bits. -+ * -+ * Copyright 2014 Cumulus Networks, 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 -+ -+#include -+#include -+ -+#undef DEBUG -+ -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+/* -+ * Enough of the CPLD to reset the system... full driver loads as a module -+*/ -+static uint8_t __iomem * cpld_regs; -+static uint32_t CPLD_RESET_REG = 0x20; -+ -+/******************************************************************************* -+ * -+ * Platform initialization functions -+ * -+ ******************************************************************************* -+*/ -+ -+/* -+ * Initialize the interrupt controller -+ */ -+static void __init dni_c7448n_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np; -+ -+ np = of_find_node_by_type(NULL, "open-pic"); -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | -+ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | -+ MPIC_SINGLE_DEST_CPU, -+ 0, 256, " OpenPIC "); -+ -+ BUG_ON(mpic == NULL); -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+#ifdef CONFIG_SMP -+extern void __init mpc85xx_smp_init(void); -+#endif -+ -+static void __init dni_c7448n_setup_arch(void) -+{ -+ struct device_node *cpu; -+ const unsigned int *fp; -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ struct device_node *cpld; -+#ifdef CONFIG_MMC_SDHCI_OF_ESDHC -+ struct device_node *esdhc; -+ struct property *clk_prop; -+ unsigned int *clk; -+#endif -+ -+ if (ppc_md.progress) -+ ppc_md.progress("dni_c7448n_setup_arch()", 0); -+ -+ cpu = of_find_node_by_type(NULL, "cpu"); -+ if (cpu != 0) { -+ fp = of_get_property(cpu, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(cpu); -+ } -+ -+#ifdef CONFIG_PCI -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8548-pcie")) -+ fsl_add_bridge(np, 0); -+ } -+#endif -+ -+ cpld = of_find_compatible_node(NULL, NULL, "dni,c7448n-cpld"); -+ if (!cpld) { -+ printk(KERN_ERR "Can not find c7448n-cpld node in device tree\n"); -+ cpld_regs = NULL; -+ } else { -+ cpld_regs = of_iomap(cpld, 0); -+ of_node_put(cpld); -+ } -+ -+#ifdef CONFIG_MMC_SDHCI_OF_ESDHC -+ esdhc = of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc"); -+ if (esdhc != NULL) { -+ clk_prop = of_find_property(esdhc, "clock-frequency", NULL); -+ if (clk_prop != NULL) { -+ /* -+ ** Increase reported SDHC clock-frequency by 2x. -+ ** This will cause the actual hardware bus speed -+ ** to be 2x slower (calculated by driver). -+ ** -+ ** The 2x number is imperical. One box I had -+ ** required a 1.1x increase, while another one -+ ** required a 1.4x increase. Using 2x to -+ ** hopefully never revisit. -+ ** -+ ** The slower hardware bus speed gives the part -+ ** more margin for safe operation. Without this -+ ** fix-up the SDHC will sometimes report CRC -+ ** errors on bus transactions and never recover. -+ */ -+ clk = clk_prop->value; -+ *clk = *clk * 2; -+ } -+ else { -+ printk(KERN_ERR "dni_c7448n: Can not find SDHC clock-frequency\n"); -+ } -+ of_node_put(esdhc); -+ } -+ else { -+ printk(KERN_ERR "dni_c7448n: Can not find p2020-esdhc in device tree\n"); -+ } -+#endif -+ powersave_nap = 0; -+ -+#ifdef CONFIG_SMP -+ mpc85xx_smp_init(); -+#endif -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+} -+ -+ -+ -+static struct of_device_id __initdata dni_c7448n_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ { .compatible = "gianfar", }, -+ {}, -+}; -+ -+ -+ -+static int __init dni_c7448n_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, dni_c7448n_ids, NULL); -+} -+/*machine_device_initcall(dni_c7448n, dni_c7448n_publish_devices); */ -+machine_device_initcall(c7448n, dni_c7448n_publish_devices); -+ -+ -+ -+static void dni_c7448n_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu Pll setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+ -+/* -+ * Platform specific restart... need to use the CPLD -+ */ -+static void dni_c7448n_restart(char *cmd) -+{ -+ printk (KERN_EMERG "Reset via the platform CPLD\n"); -+ -+ local_irq_disable(); -+ writeb(0, (cpld_regs + CPLD_RESET_REG)); -+ while (1); -+} -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init dni_c7448n_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ printk(KERN_WARNING "probing dni_c7448n...\n"); -+ if (of_flat_dt_is_compatible(root, "dni,c7448n")) -+ return 1; -+ -+ printk(KERN_WARNING "return zero\n"); -+ return 0; -+} -+ -+define_machine(c7448n) { -+ .name = "Delta Networks, Inc C7448N", -+ .probe = dni_c7448n_probe, -+ .setup_arch = dni_c7448n_setup_arch, -+ .init_IRQ = dni_c7448n_pic_init, -+ .show_cpuinfo = dni_c7448n_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = dni_c7448n_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-85xx-Makefile.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-85xx-Makefile.patch deleted file mode 100644 index b59ce52e..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-85xx-Makefile.patch +++ /dev/null @@ -1,132 +0,0 @@ -Changes to arch/powerpc/platforms/85xx/Makefile and Kconfig. - -Keep these separate from the individual platform patches because all -platforms need to touch these two files. By keeping these changes in -a separate patch allows the platform specific patchsets to sink/float -without conflicts in these two files. - -diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig -index b9a2559..2c1aa86 100644 ---- a/arch/powerpc/platforms/85xx/Kconfig -+++ b/arch/powerpc/platforms/85xx/Kconfig -@@ -227,6 +227,99 @@ config P4080_DS - help - This option enables support for the P4080 DS board - -+config ACCTON_AS4600_54T -+ bool "Accton Technology Corporation AS4600_54T" -+ select DEFAULT_UIMAGE -+ help -+ This option enables support for the ACCTON AS4600_54T networking platform -+ -+config ACCTON_AS5610_52X -+ bool "Accton Technology Corporation AS5610_52X" -+ select DEFAULT_UIMAGE -+ help -+ This option enables support for the ACCTON AS5610_52X networking platform -+ -+config ACCTON_AS6701_32X -+ bool "Accton Technology Corporation AS6701-32X" -+ select DEFAULT_UIMAGE -+ help -+ This option enables support for the Accton AS6701-32X networking platform -+ -+config ACCTON_5652 -+ bool "Accton Technology Corporation ES5652BT1" -+ select DEFAULT_UIMAGE -+ help -+ This option enables support for the ACCTON ES5652BT1 networking platform -+ -+config BCM98548XMC -+ bool "Broadcom BCM98548XMC" -+ select DEFAULT_UIMAGE -+ help -+ This option enables support for the Broadcom BCM98548XMC board used on reference platforms -+ -+config CUMULUS_P2020 -+ bool "Cumulus Networks P2020" -+ select DEFAULT_UIMAGE -+ help -+ This option enables support for the Cumulus P2020 networking platform -+ -+config DNI_6448 -+ bool "Delta Networks 6448" -+ select DEFAULT_UIMAGE -+ help -+ This option enables support for the DNI-6448 networking platform -+ -+config DNI_7448 -+ bool "Delta Networks 7448" -+ select DEFAULT_UIMAGE -+ help -+ This option enables support for the DNI-7448 networking platform -+ -+config DNI_C7448N -+ bool "Delta Networks C7448N" -+ select DEFAULT_UIMAGE -+ help -+ This option enables support for the DNI-C7448N networking platform -+ -+config QUANTA_LB8 -+ bool "Quanta Computer LB8" -+ select DEFAULT_UIMAGE -+ select SWIOTLB -+ help -+ Enable support for the Quanta Computer LB8 48x10GE networking platform -+ -+config QUANTA_LB9 -+ bool "Quanta Computer LB9" -+ select DEFAULT_UIMAGE -+ help -+ Enable support for the Quanta Computer LB9 48x1G networking platform -+ -+config QUANTA_LY2_LY2R -+ bool "Quanta Computer LY2 and LY2R" -+ select DEFAULT_UIMAGE -+ help -+ Enable support for the Quanta Computer LY2 based networking platforms -+ -+config QUANTA_LY2 -+ bool "Quanta Computer LY2" -+ select DEFAULT_UIMAGE -+ select QUANTA_LY2_LY2R -+ help -+ Enable support for the Quanta Computer LY2 48x10GE networking platform -+ -+config QUANTA_LY2R -+ bool "Quanta Computer LY2R" -+ select DEFAULT_UIMAGE -+ select QUANTA_LY2_LY2R -+ help -+ Enable support for the Quanta Computer LY2R 48x10GE networking platform -+ -+config QUANTA_LY6_P2020 -+ bool "Quanta Computer LY6, P2020" -+ select DEFAULT_UIMAGE -+ help -+ Enable support for the Quanta Computer LY6 32x40G networking platform -+ - endif # PPC32 - - config P5020_DS -diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile -index bc5acb9..d04e66c 100644 ---- a/arch/powerpc/platforms/85xx/Makefile -+++ b/arch/powerpc/platforms/85xx/Makefile -@@ -25,3 +25,16 @@ obj-$(CONFIG_SBC8548) += sbc8548.o - obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o - obj-$(CONFIG_KSI8560) += ksi8560.o - obj-$(CONFIG_XES_MPC85xx) += xes_mpc85xx.o -+obj-$(CONFIG_ACCTON_AS4600_54T) += accton_as4600_54t.o -+obj-$(CONFIG_ACCTON_AS5610_52X) += accton_as5610_52x.o -+obj-$(CONFIG_ACCTON_AS6701_32X) += accton_as6701_32x.o -+obj-$(CONFIG_ACCTON_5652) += accton_5652.o -+obj-$(CONFIG_BCM98548XMC) += bcm98548xmc.o -+obj-$(CONFIG_CUMULUS_P2020) += cumulus_p2020.o -+obj-$(CONFIG_DNI_6448) += dni_6448.o -+obj-$(CONFIG_DNI_7448) += dni_7448.o -+obj-$(CONFIG_DNI_C7448N) += dni_c7448n.o -+obj-$(CONFIG_QUANTA_LB8) += quanta_lb8.o -+obj-$(CONFIG_QUANTA_LB9) += quanta_lb9.o -+obj-$(CONFIG_QUANTA_LY2_LY2R) += quanta_ly2_ly2r.o -+obj-$(CONFIG_QUANTA_LY6_P2020) += quanta_ly6_p2020.o diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-accton-as4600-54t-r0.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-accton-as4600-54t-r0.patch deleted file mode 100644 index 42bf89d0..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-accton-as4600-54t-r0.patch +++ /dev/null @@ -1,483 +0,0 @@ -diff -rupN a/arch/powerpc/boot/dts/powerpc-accton-as4600-54t-r0.dts b/arch/powerpc/boot/dts/powerpc-accton-as4600-54t-r0.dts ---- a/arch/powerpc/boot/dts/powerpc-accton-as4600-54t-r0.dts 1969-12-31 16:00:00.000000000 -0800 -+++ b/arch/powerpc/boot/dts/powerpc-accton-as4600-54t-r0.dts 2015-05-26 18:24:31.872428138 -0700 -@@ -0,0 +1,479 @@ -+/* -+ * P2020 RDB Device Tree Source -+ * -+ * Copyright 2009-2010 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/; -+/ { -+ model = "powerpc-as4600-54t"; -+ compatible = "fsl,P2020RDB"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ -+ aliases { -+ ethernet0 = &enet1; -+ serial0 = &serial0; -+ pci1 = &pci1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,P2020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ }; -+ -+ PowerPC,P2020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ localbus@ff705000 { -+ ranges = <0x0 0x0 0x0 0xef800000 0x800000 0x1 0x0 0x0 0xea000000 0x100>; -+ interrupts = <0x13 0x2>; -+ reg = <0x0 0xff705000 0x0 0x1000>; -+ compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus"; -+ #size-cells = <0x1>; -+ #address-cells = <0x2>; -+ bus-frequency = <0x1dcd650>; -+ -+ cpld@1,0 { -+ reg = <0x1 0x0 0x100>; -+ compatible = "accton,4654-cpld"; -+ }; -+ -+ flash@0,0 { -+ device-width = <0x1>; -+ bank-width = <0x1>; -+ reg = <0x0 0x0 0x800000>; -+ compatible = "cfi-flash"; -+ #size-cells = <0x1>; -+ #address-cells = <0x1>; -+ -+ partition@0 { -+ label = "open"; -+ reg = <0x0 0x360000>; -+ }; -+ -+ partition@1 { -+ label = "onie"; -+ reg = <0x360000 0x400000>; -+ }; -+ -+ partition@2 { -+ env_size = <0x10000>; -+ label = "uboot-env"; -+ reg = <0x760000 0x10000>; -+ }; -+ -+ partition@3 { -+ label = "board_eeprom"; -+ reg = <0x770000 0x10000>; -+ }; -+ -+ partition@4 { -+ label = "uboot"; -+ reg = <0x780000 0x80000>; -+ }; -+ -+ }; -+ }; -+ -+ soc@ff700000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,p2020-immr", "simple-bus"; -+ ranges = <0x0 0x0 0xff700000 0x100000>; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,p2020-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,p2020-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <18 2>; -+ }; -+ -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ -+ rtc@68 { -+ compatible = "dallas,ds1672"; -+ reg = <0x68>; -+ }; -+ -+ }; -+ -+ serial0: serial@4500 { -+ cell-index = <0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ spi@7000 { -+ cell-index = <0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,espi"; -+ reg = <0x7000 0x1000>; -+ interrupts = <59 0x2>; -+ interrupt-parent = <&mpic>; -+ mode = "cpu"; -+ -+ fsl_m25p80@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,espi-flash"; -+ reg = <0>; -+ linux,modalias = "fsl_m25p80"; -+ modal = "s25sl128b"; -+ spi-max-frequency = <32000000>; -+ mode = <0>; -+ -+ partition@0 { -+ /* 512KB for u-boot Bootloader Image */ -+ reg = <0x0 0x00080000>; -+ label = "SPI (RO) U-Boot Image"; -+ read-only; -+ }; -+ -+ partition@80000 { -+ /* 512KB for DTB Image */ -+ reg = <0x00080000 0x00080000>; -+ label = "SPI (RO) DTB Image"; -+ read-only; -+ }; -+ -+ partition@100000 { -+ /* 4MB for Linux Kernel Image */ -+ reg = <0x00100000 0x00400000>; -+ label = "SPI (RO) Linux Kernel Image"; -+ read-only; -+ }; -+ -+ partition@500000 { -+ /* 4MB for Compressed RFS Image */ -+ reg = <0x00500000 0x00400000>; -+ label = "SPI (RO) Compressed RFS Image"; -+ read-only; -+ }; -+ -+ partition@900000 { -+ /* 7MB for JFFS2 based RFS */ -+ reg = <0x00900000 0x00700000>; -+ label = "SPI (RW) JFFS2 RFS"; -+ }; -+ }; -+ }; -+ -+ dma@c300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0xc300 0x4>; -+ ranges = <0x0 0xc100 0x200>; -+ cell-index = <1>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <76 2>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <77 2>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupt-parent = <&mpic>; -+ interrupts = <78 2>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupt-parent = <&mpic>; -+ interrupts = <79 2>; -+ }; -+ }; -+ -+ gpio: gpio-controller@f000 { -+ #gpio-cells = <2>; -+ compatible = "fsl,mpc8572-gpio"; -+ reg = <0xf000 0x100>; -+ interrupts = <47 0x2>; -+ interrupt-parent = <&mpic>; -+ gpio-controller; -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,p2020-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x80000>; // L2,512K -+ interrupt-parent = <&mpic>; -+ interrupts = <16 2>; -+ }; -+ -+ dma@21300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0x21300 0x4>; -+ ranges = <0x0 0x21100 0x200>; -+ cell-index = <0>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <20 2>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <21 2>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupt-parent = <&mpic>; -+ interrupts = <22 2>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupt-parent = <&mpic>; -+ interrupts = <23 2>; -+ }; -+ }; -+ -+ usb@22000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl-usb2-dr"; -+ reg = <0x22000 0x1000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <28 0x2>; -+ phy_type = "ulpi"; -+ }; -+ -+ mdio0: mdio@24520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ phy1: ethernet-phy@1 { -+ interrupt-parent = <&mpic>; -+ interrupts = <3 1>; -+ reg = <0x1>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ -+ enet1: ethernet@25000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ cell-index = <0x1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x25000 0x1000>; -+ ranges = <0x0 0x25000 0x1000>; -+ interrupts = < -+ 0x23 0x2 -+ 0x24 0x2 -+ 0x28 0x2>; -+ interrupt-parent = <&mpic>; -+ tbi-handle = <&tbi1>; -+ phy-handle = <&phy1>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ mdio1: mdio@25520 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ compatible = "fsl,gianfar-tbi"; -+ reg = <0x520 0x20>; -+ tbi1: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ -+ sdhci@2e000 { -+ compatible = "fsl,p2020-esdhc", "fsl,esdhc"; -+ reg = <0x2e000 0x1000>; -+ interrupts = <72 0x2>; -+ interrupt-parent = <&mpic>; -+ fsl,sdhci-adjust-timeout; -+ /* Filled in by U-Boot */ -+ clock-frequency = <0>; -+ }; -+ -+ crypto@30000 { -+ compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4", -+ "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0"; -+ reg = <0x30000 0x10000>; -+ interrupts = <45 2 58 2>; -+ interrupt-parent = <&mpic>; -+ fsl,num-channels = <4>; -+ fsl,channel-fifo-len = <24>; -+ fsl,exec-units-mask = <0xbfe>; -+ fsl,descriptor-types-mask = <0x3ab0ebf>; -+ fsl,multi-host-mode = "dual"; -+ fsl,channel-remap = <0x3>; -+ }; -+ -+ mpic: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ reg = <0x40000 0x40000>; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ }; -+ -+ message@41400 { -+ compatible = "fsl,p2020-msg", "fsl,mpic-msg"; -+ reg = <0x41400 0x200>; -+ interrupts = < -+ 0xb0 2 -+ 0xb1 2 -+ 0xb2 2 -+ 0xb3 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ message@42400 { -+ compatible = "fsl,p2020-msg", "fsl,mpic-msg"; -+ reg = <0x42400 0x200>; -+ interrupts = < -+ 0xb4 2 -+ 0xb5 2 -+ 0xb6 2 -+ 0xb7 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ msi@41600 { -+ compatible = "fsl,p2020-msi", "fsl,mpic-msi"; -+ reg = <0x41600 0x80>; -+ msi-available-ranges = <0 0x100>; -+ interrupts = < -+ 0xe0 0 -+ 0xe1 0 -+ 0xe2 0 -+ 0xe3 0 -+ 0xe4 0 -+ 0xe5 0 -+ 0xe6 0 -+ 0xe7 0>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ global-utilities@e0000 { //global utilities block -+ compatible = "fsl,p2020-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ }; -+ -+ pci1: pcie@ff70a000 { -+ cell-index = <2>; -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0 0xff70a000 0 0x1000>; -+ bus-range = <0 255>; -+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; -+ clock-frequency = <33333333>; -+ interrupt-parent = <&mpic>; -+ interrupts = <26 2>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 -+ >; -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xc0000000 -+ 0x2000000 0x0 0xc0000000 -+ 0x0 0x20000000 -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x100000>; -+ }; -+ }; -+ -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-accton-as5610-52x-r0.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-accton-as5610-52x-r0.patch deleted file mode 100644 index dba8ef19..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-accton-as5610-52x-r0.patch +++ /dev/null @@ -1,588 +0,0 @@ -diff -rupN a/arch/powerpc/boot/dts/powerpc-accton-as5610-52x-r0.dts b/arch/powerpc/boot/dts/powerpc-accton-as5610-52x-r0.dts ---- a/arch/powerpc/boot/dts/powerpc-accton-as5610-52x-r0.dts 1969-12-31 16:00:00.000000000 -0800 -+++ b/arch/powerpc/boot/dts/powerpc-accton-as5610-52x-r0.dts 2015-05-26 18:29:02.440439239 -0700 -@@ -0,0 +1,584 @@ -+/* -+ * P2020 RDB Device Tree Source -+ * -+ * Copyright 2009-2010 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/; -+/ { -+ model = "powerpc-as5610-52x"; -+ compatible = "fsl,P2020RDB"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ -+ aliases { -+ ethernet0 = &enet0; -+ /* ethernet1 = &enet1; -+ ethernet2 = &enet2; */ -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,P2020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&L2>; -+ }; -+ -+ PowerPC,P2020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ localbus@ff705000 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus"; -+ reg = <0 0xff705000 0 0x1000>; -+ interrupts = <19 2>; -+ interrupt-parent = <&mpic>; -+ -+ /* NOR and CPLD, nvram, FPGA */ -+ ranges = <0x0 0x0 0x0 0xefc00000 0x00400000>; -+ nor@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x400000>; -+ bank-width = <1>; /* 1 = 64KB on each erase block */ -+ device-width = <1>; -+ -+ partition@0 { -+ /* 3.3 MB for Linux Kernel Image */ -+ reg = <0x0 0x00360000>; -+ label = "onie"; -+ }; -+ -+ partition@360000 { -+ /* 64 KB for u-boot environment */ -+ reg = <0x360000 0x00010000>; -+ label = "u-boot environment"; -+ }; -+ -+ partition@370000 { -+ /* 64 KB for VPD */ -+ reg = <0x00370000 0x00010000>; -+ label = "board_eeprom"; -+ read-only; -+ }; -+ -+ partition@380000 { -+ /* 512 KB for bootloader */ -+ reg = <0x00380000 0x00080000>; -+ label = "uboot"; -+ read-only; -+ }; -+ }; -+ -+ -+ }; -+ -+ soc@ff700000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,p2020-immr", "simple-bus"; -+ ranges = <0x0 0x0 0xff700000 0x100000>; -+ bus-frequency = <0>; // Filled out by uboot. -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,p2020-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,p2020-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <18 2>; -+ }; -+ -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ -+ mux@70 { -+ compatible = "nxp,pca9548"; -+ reg = <0x70>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ rtc@51 { -+ compatible = "nxp,pcf8563"; -+ reg = <0x51>; -+ }; -+ }; -+ }; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ }; -+ -+ serial0: serial@4500 { -+ cell-index = <0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ serial1: serial@4600 { -+ cell-index = <1>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4600 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ spi@7000 { -+ cell-index = <0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,espi"; -+ reg = <0x7000 0x1000>; -+ interrupts = <59 0x2>; -+ interrupt-parent = <&mpic>; -+ mode = "cpu"; -+ -+ fsl_m25p80@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,espi-flash"; -+ reg = <0>; -+ linux,modalias = "fsl_m25p80"; -+ modal = "s25sl128b"; -+ spi-max-frequency = <32000000>; -+ mode = <0>; -+ -+ partition@0 { -+ /* 512KB for u-boot Bootloader Image */ -+ reg = <0x0 0x00080000>; -+ label = "SPI (RO) U-Boot Image"; -+ read-only; -+ }; -+ -+ partition@80000 { -+ /* 512KB for DTB Image */ -+ reg = <0x00080000 0x00080000>; -+ label = "SPI (RO) DTB Image"; -+ read-only; -+ }; -+ -+ partition@100000 { -+ /* 4MB for Linux Kernel Image */ -+ reg = <0x00100000 0x00400000>; -+ label = "SPI (RO) Linux Kernel Image"; -+ read-only; -+ }; -+ -+ partition@500000 { -+ /* 4MB for Compressed RFS Image */ -+ reg = <0x00500000 0x00400000>; -+ label = "SPI (RO) Compressed RFS Image"; -+ read-only; -+ }; -+ -+ partition@900000 { -+ /* 7MB for JFFS2 based RFS */ -+ reg = <0x00900000 0x00700000>; -+ label = "SPI (RW) JFFS2 RFS"; -+ }; -+ }; -+ }; -+ -+ dma@c300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0xc300 0x4>; -+ ranges = <0x0 0xc100 0x200>; -+ cell-index = <1>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <76 2>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <77 2>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupt-parent = <&mpic>; -+ interrupts = <78 2>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupt-parent = <&mpic>; -+ interrupts = <79 2>; -+ }; -+ }; -+ -+ gpio: gpio-controller@f000 { -+ #gpio-cells = <2>; -+ compatible = "fsl,mpc8572-gpio"; -+ reg = <0xf000 0x100>; -+ interrupts = <47 0x2>; -+ interrupt-parent = <&mpic>; -+ gpio-controller; -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,p2020-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x80000>; // L2,512K -+ interrupt-parent = <&mpic>; -+ interrupts = <16 2>; -+ }; -+ -+ dma@21300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0x21300 0x4>; -+ ranges = <0x0 0x21100 0x200>; -+ cell-index = <0>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <20 2>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <21 2>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupt-parent = <&mpic>; -+ interrupts = <22 2>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupt-parent = <&mpic>; -+ interrupts = <23 2>; -+ }; -+ }; -+ -+ usb@22000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl-usb2-dr"; -+ reg = <0x22000 0x1000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <28 0x2>; -+ phy_type = "ulpi"; -+ }; -+/* No ptp_timer -+ ptp_timer: ptimer@24e00 { -+ compatible = "fsl,gianfar-ptp-timer"; -+ reg = <0x24e00 0xb0>; -+ }; -+*/ -+ enet0: ethernet@24000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <0>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x24000 0x1000>; -+ ranges = <0x0 0x24000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <29 2 30 2 34 2>; -+ interrupt-parent = <&mpic>; -+ fixed-link = <1 1 1000 0 0>; -+ phy-handle = <&phy1>; -+ phy-connection-type = "rgmii-id"; -+ /* ptimer-handle = <&ptp_timer>; */ -+ -+ mdio@520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ device_type = "mdio"; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x520 0x20>; -+/* -+ phy0: ethernet-phy@0 { -+ interrupt-parent = <&mpic>; -+ interrupts = <3 1>; -+ reg = <0x0>; -+ }; -+*/ -+ phy1: ethernet-phy@1 { -+ reg = <0x1>; -+ device_type = "ethernet-phy"; -+ linux,phandle = <0x4>; -+ }; -+ }; -+ }; -+/* not used ! -+ enet1: ethernet@25000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x25000 0x1000>; -+ ranges = <0x0 0x25000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <35 2 36 2 40 2>; -+ interrupt-parent = <&mpic>; -+ tbi-handle = <&tbi0>; -+ phy-handle = <&phy0>; -+ phy-connection-type = "sgmii"; -+ ptimer-handle = <&ptp_timer>; -+ -+ mdio@520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-tbi"; -+ reg = <0x520 0x20>; -+ -+ tbi0: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ }; -+ -+ enet2: ethernet@26000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <2>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x26000 0x1000>; -+ ranges = <0x0 0x26000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <31 2 32 2 33 2>; -+ interrupt-parent = <&mpic>; -+ phy-handle = <&phy1>; -+ phy-connection-type = "rgmii-id"; -+ ptimer-handle = <&ptp_timer>; -+ }; -+*/ -+ -+ sdhci@2e000 { -+ compatible = "fsl,p2020-esdhc", "fsl,esdhc"; -+ reg = <0x2e000 0x1000>; -+ interrupts = <72 0x2>; -+ interrupt-parent = <&mpic>; -+ fsl,sdhci-adjust-timeout; -+ /* Filled in by U-Boot */ -+ clock-frequency = <0>; -+ }; -+ -+ crypto@30000 { -+ compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4", -+ "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0"; -+ reg = <0x30000 0x10000>; -+ interrupts = <45 2 58 2>; -+ interrupt-parent = <&mpic>; -+ fsl,num-channels = <4>; -+ fsl,channel-fifo-len = <24>; -+ fsl,exec-units-mask = <0xbfe>; -+ fsl,descriptor-types-mask = <0x3ab0ebf>; -+ fsl,multi-host-mode = "dual"; -+ fsl,channel-remap = <0x3>; -+ }; -+ -+ mpic: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ reg = <0x40000 0x40000>; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ }; -+ -+ message@41400 { -+ compatible = "fsl,p2020-msg", "fsl,mpic-msg"; -+ reg = <0x41400 0x200>; -+ interrupts = < -+ 0xb0 2 -+ 0xb1 2 -+ 0xb2 2 -+ 0xb3 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ message@42400 { -+ compatible = "fsl,p2020-msg", "fsl,mpic-msg"; -+ reg = <0x42400 0x200>; -+ interrupts = < -+ 0xb4 2 -+ 0xb5 2 -+ 0xb6 2 -+ 0xb7 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ msi@41600 { -+ compatible = "fsl,p2020-msi", "fsl,mpic-msi"; -+ reg = <0x41600 0x80>; -+ msi-available-ranges = <0 0x100>; -+ interrupts = < -+ 0xe0 0 -+ 0xe1 0 -+ 0xe2 0 -+ 0xe3 0 -+ 0xe4 0 -+ 0xe5 0 -+ 0xe6 0 -+ 0xe7 0>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ global-utilities@e0000 { //global utilities block -+ compatible = "fsl,p2020-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ }; -+ -+ pci0: pcie@ff709000 { -+ cell-index = <1>; -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0 0xff709000 0 0x1000>; -+ bus-range = <0 255>; -+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc30000 0x0 0x10000>; -+ clock-frequency = <33333333>; -+ interrupt-parent = <&mpic>; -+ interrupts = <25 2>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x4 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x5 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1 -+ >; -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xc0000000 -+ 0x2000000 0x0 0xc0000000 -+ 0x0 0x20000000 -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x100000>; -+ }; -+ }; -+ pci1: pcie@ff70a000 { -+ cell-index = <2>; -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0 0xff70a000 0 0x1000>; -+ bus-range = <0 255>; -+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; -+ clock-frequency = <33333333>; -+ interrupt-parent = <&mpic>; -+ interrupts = <26 2>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 -+ >; -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xc0000000 -+ 0x2000000 0x0 0xc0000000 -+ 0x0 0x20000000 -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x100000>; -+ }; -+ }; -+ -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-dell-s4810-p2020-r0.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-dell-s4810-p2020-r0.patch deleted file mode 100644 index ba8fd87f..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-dell-s4810-p2020-r0.patch +++ /dev/null @@ -1,496 +0,0 @@ -diff -rupN a/arch/powerpc/boot/dts/powerpc-dell-s4810-p2020-r0.dts b/arch/powerpc/boot/dts/powerpc-dell-s4810-p2020-r0.dts ---- a/arch/powerpc/boot/dts/powerpc-dell-s4810-p2020-r0.dts 1969-12-31 16:00:00.000000000 -0800 -+++ b/arch/powerpc/boot/dts/powerpc-dell-s4810-p2020-r0.dts 2015-06-04 10:58:02.180863653 -0700 -@@ -0,0 +1,492 @@ -+/* -+ * Dell S4810 device tree source -+ * -+ * Copyright 2013 Big Switch Networks, 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/; -+ -+/ { -+ model = "powerpc-dell-s4810-p2020-r0"; -+ compatible = "dni,dni_7448"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ -+ aliases { -+ ethernet0 = &enet2; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci2 = &pci2; -+ mpic-msgr-block0 = &mpic_msgr_block0; -+ mpic-msgr-block1 = &mpic_msgr_block1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,P2020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&l2>; -+ }; -+ -+ PowerPC,P2020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <&l2>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ mass_storage { -+ device = "mmcblk0"; -+ }; -+ -+ localbus@ffe05000 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus"; -+ reg = <0 0xffe05000 0 0x1000>; -+ interrupts = <19 2>; -+ interrupt-parent = <&mpic>; -+ -+ ranges = <0x0 0x0 0x0 0xe8000000 0x8000000 -+ 0x1 0x0 0x0 0xffdf0000 0x0000100>; -+ -+ flash@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x8000000>; -+ bank-width = <2>; -+ device-width = <0x2>; -+ byteswap; -+ -+ flash@0 { -+ reg = <0x00000000 0x07b60000>; -+ label = "open"; -+ }; -+ flash@1 { -+ /* 4MB onie */ -+ reg = <0x07b60000 0x00400000>; -+ label = "onie"; -+ }; -+ flash@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x07f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ flash@3 { -+ /* 512KB u-boot */ -+ reg = <0x07f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ -+ cpld@1,0 { -+ compatible = "dni,7448-cpld"; -+ reg = <0x1 0x0 0x0000100>; -+ }; -+ }; -+ -+ soc@ffe00000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,p2020-immr", "simple-bus"; -+ ranges = <0x0 0x0 0xffe00000 0x100000>; -+ bus-frequency = <0>; -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,p2020-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,p2020-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <18 2>; -+ }; -+ -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ -+ dimm@52 { -+ compatible = "at,spd"; -+ reg = <0x52>; -+ read-only; -+ }; -+ -+ eeprom-mb@54 { -+ compatible = "at,24c08"; -+ reg = <0x54>; -+ read-only; -+ }; -+ -+ rtc@68 { -+ compatible = "stm,m41st85"; -+ reg = <0x68>; -+ }; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ -+ fan@1b { -+ compatible = "maxim,max6650"; -+ reg = <0x1b>; -+ }; -+ -+ fan@1f { -+ compatible = "maxim,max6650"; -+ reg = <0x1f>; -+ }; -+ -+ hotswap@40 { -+ compatible = "lt,ltc4215"; -+ reg = <0x40>; -+ }; -+ -+ hotswap@42 { -+ compatible = "lt,ltc4215"; -+ reg = <0x42>; -+ }; -+ -+ fan@48 { -+ compatible = "maxim,max6650"; -+ reg = <0x48>; -+ }; -+ -+ temp@49 { -+ compatible = "ti,tmp75"; -+ reg = <0x49>; -+ }; -+ -+ temp@4a { -+ compatible = "ti,tmp75"; -+ reg = <0x4a>; -+ }; -+ -+ fan@4b { -+ compatible = "maxim,max6650"; -+ reg = <0x4b>; -+ }; -+ -+ temp@4c { -+ compatible = "ti,tmp75"; -+ reg = <0x4c>; -+ }; -+ -+ temp@4d { -+ compatible = "ti,tmp75"; -+ reg = <0x4d>; -+ }; -+ -+ eeprom-psu-1@50 { -+ read-only; -+ compatible = "at,24c08"; -+ reg = <0x50>; -+ }; -+ -+ eeprom-psu-2@54 { -+ read-only; -+ compatible = "at,24c08"; -+ reg = <0x54>; -+ }; -+ }; -+ -+ serial0: serial@4500 { -+ cell-index = <0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ serial1: serial@4600 { -+ cell-index = <1>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4600 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ dma@c300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0xc300 0x4>; -+ ranges = <0x0 0xc100 0x200>; -+ cell-index = <1>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <76 2>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <77 2>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupt-parent = <&mpic>; -+ interrupts = <78 2>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupt-parent = <&mpic>; -+ interrupts = <79 2>; -+ }; -+ }; -+ -+ gpio: gpio-controller@f000 { -+ #gpio-cells = <2>; -+ compatible = "fsl,mpc8572-gpio"; -+ reg = <0xf000 0x100>; -+ interrupts = <47 0x2>; -+ interrupt-parent = <&mpic>; -+ gpio-controller; -+ }; -+ -+ l2: l2-cache-controller@20000 { -+ compatible = "fsl,p2020-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; -+ cache-size = <0x80000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <16 2>; -+ }; -+ -+ dma@21300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0x21300 0x4>; -+ ranges = <0x0 0x21100 0x200>; -+ cell-index = <0>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <20 2>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <21 2>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupt-parent = <&mpic>; -+ interrupts = <22 2>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupt-parent = <&mpic>; -+ interrupts = <23 2>; -+ }; -+ }; -+ -+ ptp_timer: ptimer@24e00 { -+ compatible = "fsl,gianfar-ptp-timer"; -+ reg = <0x24e00 0xb0>; -+ }; -+ -+ enet2: ethernet@26000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x26000 0x1000>; -+ ranges = <0x0 0x26000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <31 2 32 2 33 2>; -+ interrupt-parent = <&mpic>; -+ phy-connection-type = "sgmii"; -+ phy-handle = <&phy0>; -+ tbi-handle = <&tbi0>; -+ }; -+ -+ mdio@24520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ -+ phy0: ethernet-phy@0 { -+ reg = <0x1>; -+ device_type = "ethernet-phy"; -+ }; -+ tbi0: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ sdhci@2e000 { -+ compatible = "fsl,p2020-esdhc", "fsl,esdhc"; -+ reg = <0x2e000 0x1000>; -+ interrupts = <72 0x2>; -+ interrupt-parent = <&mpic>; -+ clock-frequency = <0>; -+ sdhci,auto-cmd12; -+ }; -+ -+ crypto@30000 { -+ compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4", -+ "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0"; -+ reg = <0x30000 0x10000>; -+ interrupts = <45 2 58 2>; -+ interrupt-parent = <&mpic>; -+ fsl,num-channels = <4>; -+ fsl,channel-fifo-len = <24>; -+ fsl,exec-units-mask = <0xbfe>; -+ fsl,descriptor-types-mask = <0x3ab0ebf>; -+ fsl,multi-host-mode = "dual"; -+ fsl,channel-remap = <0x3>; -+ }; -+ -+ mpic: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ reg = <0x40000 0x40000>; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ }; -+ -+ mpic_msgr_block0: message@41400 { -+ compatible = "fsl,mpic-v3.1-msgr"; -+ reg = <0x41400 0x200>; -+ interrupts = < -+ 0xb0 2 -+ 0xb1 2 -+ 0xb2 2 -+ 0xb3 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ mpic_msgr_block1: message@42400 { -+ compatible = "fsl,mpic-v3.1-msgr"; -+ reg = <0x42400 0x200>; -+ interrupts = < -+ 0xb4 2 -+ 0xb5 2 -+ 0xb6 2 -+ 0xb7 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ msi@41600 { -+ compatible = "fsl,p2020-msi", "fsl,mpic-msi"; -+ reg = <0x41600 0x80>; -+ msi-available-ranges = <0 0x100>; -+ interrupts = < -+ 0xe0 0 -+ 0xe1 0 -+ 0xe2 0 -+ 0xe3 0 -+ 0xe4 0 -+ 0xe5 0 -+ 0xe6 0 -+ 0xe7 0>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ global-utilities@e0000 { -+ compatible = "fsl,p2020-guts"; -+ reg = <0xe0000 0x1000>; -+ }; -+ }; -+ -+ pci2: pcie@ffe0a000 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0 0xffe0a000 0 0x1000>; -+ bus-range = <0 255>; -+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; -+ clock-frequency = <100000000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <26 2>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x0 0x1 -+ >; -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xc0000000 -+ 0x2000000 0x0 0xc0000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x10000>; -+ }; -+ }; -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-dni-7448-r0.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-dni-7448-r0.patch deleted file mode 100644 index 70806757..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-dni-7448-r0.patch +++ /dev/null @@ -1,496 +0,0 @@ -diff -rupN a/arch/powerpc/boot/dts/powerpc-dni-7448-r0.dts b/arch/powerpc/boot/dts/powerpc-dni-7448-r0.dts ---- a/arch/powerpc/boot/dts/powerpc-dni-7448-r0.dts 1969-12-31 16:00:00.000000000 -0800 -+++ b/arch/powerpc/boot/dts/powerpc-dni-7448-r0.dts 2015-06-04 10:40:17.736835830 -0700 -@@ -0,0 +1,492 @@ -+/* -+ * Delta ET-7448BF device tree source -+ * -+ * Copyright 2013 Big Switch Networks, 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/; -+ -+/ { -+ model = "powerpc-dni-7448-r0"; -+ compatible = "dni,dni_7448"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ -+ aliases { -+ ethernet0 = &enet2; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci2 = &pci2; -+ mpic-msgr-block0 = &mpic_msgr_block0; -+ mpic-msgr-block1 = &mpic_msgr_block1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,P2020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&l2>; -+ }; -+ -+ PowerPC,P2020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <&l2>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ mass_storage { -+ device = "mmcblk0"; -+ }; -+ -+ localbus@ffe05000 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus"; -+ reg = <0 0xffe05000 0 0x1000>; -+ interrupts = <19 2>; -+ interrupt-parent = <&mpic>; -+ -+ ranges = <0x0 0x0 0x0 0xe8000000 0x8000000 -+ 0x1 0x0 0x0 0xffdf0000 0x0000100>; -+ -+ flash@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x8000000>; -+ bank-width = <2>; -+ device-width = <0x2>; -+ byteswap; -+ -+ flash@0 { -+ reg = <0x00000000 0x07b60000>; -+ label = "open"; -+ }; -+ flash@1 { -+ /* 4MB onie */ -+ reg = <0x07b60000 0x00400000>; -+ label = "onie"; -+ }; -+ flash@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x07f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ flash@3 { -+ /* 512KB u-boot */ -+ reg = <0x07f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ -+ cpld@1,0 { -+ compatible = "dni,7448-cpld"; -+ reg = <0x1 0x0 0x0000100>; -+ }; -+ }; -+ -+ soc@ffe00000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,p2020-immr", "simple-bus"; -+ ranges = <0x0 0x0 0xffe00000 0x100000>; -+ bus-frequency = <0>; -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,p2020-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,p2020-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <18 2>; -+ }; -+ -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ -+ dimm@52 { -+ compatible = "at,spd"; -+ reg = <0x52>; -+ read-only; -+ }; -+ -+ eeprom-mb@54 { -+ compatible = "at,24c08"; -+ reg = <0x54>; -+ read-only; -+ }; -+ -+ rtc@68 { -+ compatible = "stm,m41st85"; -+ reg = <0x68>; -+ }; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ -+ fan@1b { -+ compatible = "maxim,max6650"; -+ reg = <0x1b>; -+ }; -+ -+ fan@1f { -+ compatible = "maxim,max6650"; -+ reg = <0x1f>; -+ }; -+ -+ hotswap@40 { -+ compatible = "lt,ltc4215"; -+ reg = <0x40>; -+ }; -+ -+ hotswap@42 { -+ compatible = "lt,ltc4215"; -+ reg = <0x42>; -+ }; -+ -+ fan@48 { -+ compatible = "maxim,max6650"; -+ reg = <0x48>; -+ }; -+ -+ temp@49 { -+ compatible = "ti,tmp75"; -+ reg = <0x49>; -+ }; -+ -+ temp@4a { -+ compatible = "ti,tmp75"; -+ reg = <0x4a>; -+ }; -+ -+ fan@4b { -+ compatible = "maxim,max6650"; -+ reg = <0x4b>; -+ }; -+ -+ temp@4c { -+ compatible = "ti,tmp75"; -+ reg = <0x4c>; -+ }; -+ -+ temp@4d { -+ compatible = "ti,tmp75"; -+ reg = <0x4d>; -+ }; -+ -+ eeprom-psu-1@50 { -+ read-only; -+ compatible = "at,24c08"; -+ reg = <0x50>; -+ }; -+ -+ eeprom-psu-2@54 { -+ read-only; -+ compatible = "at,24c08"; -+ reg = <0x54>; -+ }; -+ }; -+ -+ serial0: serial@4500 { -+ cell-index = <0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ serial1: serial@4600 { -+ cell-index = <1>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4600 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ dma@c300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0xc300 0x4>; -+ ranges = <0x0 0xc100 0x200>; -+ cell-index = <1>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <76 2>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <77 2>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupt-parent = <&mpic>; -+ interrupts = <78 2>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupt-parent = <&mpic>; -+ interrupts = <79 2>; -+ }; -+ }; -+ -+ gpio: gpio-controller@f000 { -+ #gpio-cells = <2>; -+ compatible = "fsl,mpc8572-gpio"; -+ reg = <0xf000 0x100>; -+ interrupts = <47 0x2>; -+ interrupt-parent = <&mpic>; -+ gpio-controller; -+ }; -+ -+ l2: l2-cache-controller@20000 { -+ compatible = "fsl,p2020-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; -+ cache-size = <0x80000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <16 2>; -+ }; -+ -+ dma@21300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0x21300 0x4>; -+ ranges = <0x0 0x21100 0x200>; -+ cell-index = <0>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <20 2>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <21 2>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupt-parent = <&mpic>; -+ interrupts = <22 2>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupt-parent = <&mpic>; -+ interrupts = <23 2>; -+ }; -+ }; -+ -+ ptp_timer: ptimer@24e00 { -+ compatible = "fsl,gianfar-ptp-timer"; -+ reg = <0x24e00 0xb0>; -+ }; -+ -+ enet2: ethernet@26000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x26000 0x1000>; -+ ranges = <0x0 0x26000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <31 2 32 2 33 2>; -+ interrupt-parent = <&mpic>; -+ phy-connection-type = "sgmii"; -+ phy-handle = <&phy0>; -+ tbi-handle = <&tbi0>; -+ }; -+ -+ mdio@24520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ -+ phy0: ethernet-phy@0 { -+ reg = <0x1>; -+ device_type = "ethernet-phy"; -+ }; -+ tbi0: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ sdhci@2e000 { -+ compatible = "fsl,p2020-esdhc", "fsl,esdhc"; -+ reg = <0x2e000 0x1000>; -+ interrupts = <72 0x2>; -+ interrupt-parent = <&mpic>; -+ clock-frequency = <0>; -+ sdhci,auto-cmd12; -+ }; -+ -+ crypto@30000 { -+ compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4", -+ "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0"; -+ reg = <0x30000 0x10000>; -+ interrupts = <45 2 58 2>; -+ interrupt-parent = <&mpic>; -+ fsl,num-channels = <4>; -+ fsl,channel-fifo-len = <24>; -+ fsl,exec-units-mask = <0xbfe>; -+ fsl,descriptor-types-mask = <0x3ab0ebf>; -+ fsl,multi-host-mode = "dual"; -+ fsl,channel-remap = <0x3>; -+ }; -+ -+ mpic: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ reg = <0x40000 0x40000>; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ }; -+ -+ mpic_msgr_block0: message@41400 { -+ compatible = "fsl,mpic-v3.1-msgr"; -+ reg = <0x41400 0x200>; -+ interrupts = < -+ 0xb0 2 -+ 0xb1 2 -+ 0xb2 2 -+ 0xb3 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ mpic_msgr_block1: message@42400 { -+ compatible = "fsl,mpic-v3.1-msgr"; -+ reg = <0x42400 0x200>; -+ interrupts = < -+ 0xb4 2 -+ 0xb5 2 -+ 0xb6 2 -+ 0xb7 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ msi@41600 { -+ compatible = "fsl,p2020-msi", "fsl,mpic-msi"; -+ reg = <0x41600 0x80>; -+ msi-available-ranges = <0 0x100>; -+ interrupts = < -+ 0xe0 0 -+ 0xe1 0 -+ 0xe2 0 -+ 0xe3 0 -+ 0xe4 0 -+ 0xe5 0 -+ 0xe6 0 -+ 0xe7 0>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ global-utilities@e0000 { -+ compatible = "fsl,p2020-guts"; -+ reg = <0xe0000 0x1000>; -+ }; -+ }; -+ -+ pci2: pcie@ffe0a000 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0 0xffe0a000 0 0x1000>; -+ bus-range = <0 255>; -+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; -+ clock-frequency = <100000000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <26 2>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x0 0x1 -+ >; -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xc0000000 -+ 0x2000000 0x0 0xc0000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x10000>; -+ }; -+ }; -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-quanta-lb9-r0.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-quanta-lb9-r0.patch deleted file mode 100644 index 23e739e9..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-quanta-lb9-r0.patch +++ /dev/null @@ -1,722 +0,0 @@ -diff -rupN a/arch/powerpc/boot/dts/powerpc-quanta-lb9-r0.dts b/arch/powerpc/boot/dts/powerpc-quanta-lb9-r0.dts ---- a/arch/powerpc/boot/dts/powerpc-quanta-lb9-r0.dts 1969-12-31 16:00:00.000000000 -0800 -+++ b/arch/powerpc/boot/dts/powerpc-quanta-lb9-r0.dts 2015-06-02 12:53:56.475579023 -0700 -@@ -0,0 +1,509 @@ -+/* -+ * -+ * -+ * Copyright 2013, 2014 BigSwitch Networks, Inc. -+ * -+ * This program is free software; you can redistribute it -+ * and/or modify it under the terms ofthe GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the License, -+ * or (at your option) any later version. -+ * -+ * -+ * -+ * -+ * -+ * Device tree for the Quanta LB9 -+ * -+ */ -+ -+ -+/dts-v1/; -+ -+/ { -+ model = "powerpc-quanta-lb9-r0"; -+ compatible = "quanta,lb9"; -+ reset-gpio = <&cpm_pio_a 24 1>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ aliases { -+ ethernet0 = &enet0; -+ serial0 = &serial0; -+ pci0 = &pci0; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8541@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ d-cache-line-size = <32>; // 32 bytes -+ i-cache-line-size = <32>; // 32 bytes -+ d-cache-size = <0x8000>; // L1, 32K -+ i-cache-size = <0x8000>; // L1, 32K -+ timebase-frequency = <0>; // 33 MHz -+ bus-frequency = <0>; // 166 MHz -+ clock-frequency = <0>; // 825 MHz -+ next-level-cache = <&L2>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x0 0x20000000>; // 512M at 0x0 -+ }; -+ -+ soc8541@e0000000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "simple-bus"; -+ ranges = <0x0 0xe0000000 0x100000>; -+ reg = <0xe0000000 0x1000>; // CCSRBAR 1M -+ bus-frequency = <0>; -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <8>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,mpc8541-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,8541-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <18 2>; -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,8541-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x40000>; // L2, 256K -+ interrupt-parent = <&mpic>; -+ interrupts = <16 2>; -+ }; -+ -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ -+ gpio-phy@20 { -+ compatible = "nxp,pca9555"; -+ reg = <0x20>; -+ #gpio-cells = <2>; -+ gpio-controller; -+ }; -+ -+ gpio-psu-1@24 { -+ compatible = "nxp,pca9555"; -+ reg = <0x24>; -+ #gpio-cells = <2>; -+ gpio-controller; -+ }; -+ -+ gpio-psu-2@25 { -+ compatible = "nxp,pca9555"; -+ reg = <0x25>; -+ #gpio-cells = <2>; -+ gpio-controller; -+ }; -+ -+ eeprom-mb@53 { -+ compatible = "at,24c02"; -+ reg = <0x53>; -+ read-only; -+ }; -+ -+ dimm@57 { -+ compatible = "at,spd"; -+ reg = <0x57>; -+ read-only; -+ }; -+ -+ rtc@68 { -+ compatible = "dallas,ds1338"; -+ reg = <0x68>; -+ }; -+ -+ mux@70 { -+ compatible = "nxp,pca9548"; -+ reg = <0x70>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ eeprom-sfp-1@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-1@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ -+ eeprom-sfp-2@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-2@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ -+ eeprom-sfp-3@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-3@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ -+ eeprom-sfp-4@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-4@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ -+ temp-fan-1@2c { -+ compatible = "adi,adt7470"; -+ reg = <0x2c>; -+ }; -+ }; -+ -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ -+ temp-fan-2@2f { -+ compatible = "adi,adt7470"; -+ reg = <0x2f>; -+ }; -+ }; -+ -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ -+ psu-1@58 { -+ compatible = "pmbus"; -+ reg = <0x58>; -+ }; -+ }; -+ -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ -+ psu-2@59 { -+ compatible = "pmbus"; -+ reg = <0x59>; -+ }; -+ }; -+ }; -+ }; -+ -+ dma@21300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8541-dma", "fsl,eloplus-dma"; -+ reg = <0x21300 0x4>; -+ ranges = <0x0 0x21100 0x200>; -+ cell-index = <0>; -+ dma-channel@0 { -+ compatible = "fsl,mpc8541-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <20 2>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,mpc8541-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <21 2>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,mpc8541-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupt-parent = <&mpic>; -+ interrupts = <22 2>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,mpc8541-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupt-parent = <&mpic>; -+ interrupts = <23 2>; -+ }; -+ }; -+ -+ enet0: ethernet@24000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <0>; -+ device_type = "network"; -+ model = "TSEC"; -+ compatible = "gianfar"; -+ reg = <0x24000 0x1000>; -+ ranges = <0x0 0x24000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <29 2 30 2 34 2>; -+ interrupt-parent = <&mpic>; -+ phy-handle = <&phy0>; -+ -+ mdio@520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x520 0x20>; -+ -+ phy0: ethernet-phy@0 { -+ interrupt-parent = <&mpic>; -+ reg = <0x0>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ }; -+ -+ serial0: serial@4500 { -+ cell-index = <0>; -+ device_type = "serial"; -+ compatible = "fsl,ns16550", "ns16550"; -+ reg = <0x4500 0x100>; // reg base, size -+ clock-frequency = <0>; -+ interrupts = <42 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ mpic: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ reg = <0x40000 0x40000>; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ }; -+ -+ cpm@919c0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8541-cpm", "fsl,cpm2"; -+ reg = <0x919c0 0x30>; -+ ranges; -+ -+ muram@80000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x0 0x80000 0x10000>; -+ -+ data@0 { -+ compatible = "fsl,cpm-muram-data"; -+ reg = <0x0 0x2000 0x9000 0x1000>; -+ }; -+ }; -+ -+ brg@919f0 { -+ compatible = "fsl,mpc8541-brg", -+ "fsl,cpm2-brg", -+ "fsl,cpm-brg"; -+ reg = <0x919f0 0x10 0x915f0 0x10>; -+ }; -+ -+ cpmpic: pic@90c00 { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <46 2>; -+ interrupt-parent = <&mpic>; -+ reg = <0x90c00 0x80>; -+ compatible = "fsl,mpc8541-cpm-pic", "fsl,cpm2-pic"; -+ }; -+ }; -+ -+ cpm_pio_a: gpio-controller@90d00 { -+ #gpio-cells = <2>; -+ compatible = "fsl,cpm2-pario-bank"; -+ reg = <0x90d00 0x14>; -+ gpio-controller; -+ }; -+ -+ cpm_pio_b: gpio-controller@90d20 { -+ #gpio-cells = <2>; -+ compatible = "fsl,cpm2-pario-bank"; -+ reg = <0x90d20 0x14>; -+ gpio-controller; -+ }; -+ -+ cpm_pio_c: gpio-controller@90d40 { -+ #gpio-cells = <2>; -+ compatible = "fsl,cpm2-pario-bank"; -+ reg = <0x90d40 0x14>; -+ gpio-controller; -+ }; -+ -+ cpm_pio_d: gpio-controller@90d60 { -+ #gpio-cells = <2>; -+ compatible = "fsl,cpm2-pario-bank"; -+ reg = <0x90d60 0x14>; -+ gpio-controller; -+ }; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ system-status { -+ gpios = <&cpm_pio_a 22 1>; -+ linux,default-trigger = "default-on"; -+ }; -+ }; -+ -+ pci0: pci@e0008000 { -+ cell-index = <0>; -+ interrupt-map-mask = <0x1f800 0x0 0x0 0x7>; -+ interrupt-map = < -+ -+ /* IDSEL 0x12 (Slot 1) */ -+ 0x9000 0x0 0x0 0x1 &mpic 0x3 0x1 -+ >; -+ -+ interrupt-parent = <&mpic>; -+ interrupts = <24 2>; -+ bus-range = <0 0>; -+ ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000 -+ 0x1000000 0x0 0x0 0xe2000000 0x0 0x100000>; -+ clock-frequency = <66666666>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0xe0008000 0x1000>; -+ compatible = "fsl,mpc8540-pci"; -+ device_type = "pci"; -+ -+ }; -+ -+ localbus@f0010100 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8541-localbus", -+ "fsl,pq2-localbus", -+ "simple-bus"; -+ reg = <0xf0010100 0x40>; -+ interrupt-parent = <&mpic>; -+ interrupts = <19 2>; -+ ranges = <0x0 0x0 0xfe000000 0x2000000 -+ 0x1 0x0 0xf0000000 0x10000 -+ 0x2 0x0 0xf0010000 0x10000>; -+ -+ flash@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x2000000>; -+ bank-width = <2>; -+ device-width = <1>; -+ -+ /* partition names must be sorted alphanumerically */ -+ /* otherwise kexec/Linux may reorder mtd devices */ -+ -+ flash-00@00000000 { -+ label = "onl-loader"; -+ reg = <0x00000000 0x00800000>; -+ }; -+ -+ flash-01@00800000 { -+ label = "mnt-flash"; -+ reg = <0x00800000 0x01360000>; -+ }; -+ -+ flash-02@01b60000 { -+ label = "onie"; -+ reg = <0x01b60000 0x00400000>; -+ read-only; -+ }; -+ -+ flash-03@01f60000 { -+ label = "uboot-env"; -+ reg = <0x01f60000 0x00020000>; -+ }; -+ -+ flash-04@01f80000 { -+ label = "uboot"; -+ reg = <0x01f80000 0x00080000>; -+ read-only; -+ }; -+ }; -+ -+ pata@3,0 { -+ compatible = "quanta-lb-ata"; -+ reg = <0x1 0x0 0x10000 0x2 0x0 0x10000>; -+ #interrupt-cells = <1>; -+ interrupts = <2 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ }; -+}; -diff -rupN a/drivers/ata/Kconfig b/drivers/ata/Kconfig ---- a/drivers/ata/Kconfig 2014-12-14 08:24:02.000000000 -0800 -+++ b/drivers/ata/Kconfig 2015-05-20 17:39:45.202136101 -0700 -@@ -870,6 +870,13 @@ config PATA_WINBOND_VLB - Support for the Winbond W83759A controller on Vesa Local Bus - systems. - -+config PATA_QUANTA_LB -+ bool "Quanta LB platform ATA support" -+ depends on PATA_PLATFORM && OF -+ help -+ This driver adds support for IDE/ATA drives on the Quanta LB -+ platform. -+ - comment "Generic fallback / legacy drivers" - - config PATA_ACPI -diff -rupN a/drivers/ata/Makefile b/drivers/ata/Makefile ---- a/drivers/ata/Makefile 2014-12-14 08:24:02.000000000 -0800 -+++ b/drivers/ata/Makefile 2015-05-20 17:39:13.602132473 -0700 -@@ -91,6 +91,7 @@ obj-$(CONFIG_PATA_OF_PLATFORM) += pata_o - obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o - obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o - obj-$(CONFIG_PATA_SAMSUNG_CF) += pata_samsung_cf.o -+obj-$(CONFIG_PATA_QUANTA_LB) += pata_quanta_lb.o - - obj-$(CONFIG_PATA_PXA) += pata_pxa.o - -diff -rupN a/drivers/ata/pata_quanta_lb.c b/drivers/ata/pata_quanta_lb.c ---- a/drivers/ata/pata_quanta_lb.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/drivers/ata/pata_quanta_lb.c 2015-05-20 17:40:21.562121047 -0700 -@@ -0,0 +1,177 @@ -+/* -+ * -+ * -+ * Copyright 2013, 2014 BigSwitch Networks, Inc. -+ * -+ * This program is free software; you can redistribute it -+ * and/or modify it under the terms ofthe GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the License, -+ * or (at your option) any later version. -+ * -+ * -+ * -+ * -+ * -+ * Quanta LBx platform PATA driver -+ */ -+#include -+#include -+#include -+ -+#define DRV_NAME "quanta-lb-ata" -+ -+static unsigned int -+quanta_lb_ata_data_xfer(struct ata_device *dev, unsigned char *buf, -+ unsigned int buflen, int rw) -+{ -+ unsigned long irq_flags; -+ void __iomem *data_addr = dev->link->ap->ioaddr.data_addr; -+ unsigned short *ptr = (unsigned short *) buf; -+ unsigned int count = (buflen + 1) / 2; -+ -+ local_irq_save(irq_flags); -+ -+ if (rw == READ) { -+ while (count--) { -+ *ptr++ = cpu_to_le16(__raw_readw(data_addr)); -+ } -+ } -+ else { -+ while (count--) { -+ __raw_writew(le16_to_cpu(*ptr), data_addr); -+ ptr++; -+ } -+ } -+ -+ local_irq_restore(irq_flags); -+ -+ return buflen; -+} -+ -+static int -+quanta_lb_ata_set_mode(struct ata_link *link, struct ata_device **unused) -+{ -+ struct ata_device *dev; -+ -+ ata_for_each_dev(dev, link, ENABLED) { -+ /* We don't really care */ -+ dev->pio_mode = dev->xfer_mode = XFER_PIO_0; -+ dev->xfer_shift = ATA_SHIFT_PIO; -+ dev->flags |= ATA_DFLAG_PIO; -+ ata_dev_info(dev, "configured for PIO\n"); -+ } -+ return 0; -+} -+ -+static struct scsi_host_template quanta_lb_ata_sht = { -+ ATA_PIO_SHT(DRV_NAME), -+}; -+ -+static struct ata_port_operations quanta_lb_ata_port_ops = { -+ .inherits = &ata_sff_port_ops, -+ .sff_data_xfer = quanta_lb_ata_data_xfer, -+ .cable_detect = ata_cable_unknown, -+ .set_mode = quanta_lb_ata_set_mode, -+}; -+ -+static int -+quanta_lb_ata_probe(struct platform_device *op) -+{ -+ int rv; -+ struct resource io_res, ctl_res, *irq_res; -+ int irq = 0; -+ void __iomem *io_mem, *ctl_mem; -+ struct ata_host *host; -+ struct ata_port *ap; -+ -+ rv = of_address_to_resource(op->dev.of_node, 0, &io_res); -+ if (rv) { -+ dev_err(&op->dev, "could not determine io base\n"); -+ return rv; -+ } -+ io_mem = devm_ioremap(&op->dev, io_res.start, resource_size(&io_res)); -+ if (!io_mem) { -+ dev_err(&op->dev, "could not map io base\n"); -+ return -ENOMEM; -+ } -+ -+ rv = of_address_to_resource(op->dev.of_node, 1, &ctl_res); -+ if (rv) { -+ dev_err(&op->dev, "could not determine ctl base\n"); -+ return rv; -+ } -+ ctl_mem = devm_ioremap(&op->dev, ctl_res.start, resource_size(&ctl_res)); -+ if (!ctl_mem) { -+ dev_err(&op->dev, "could not map ctl base\n"); -+ return -ENOMEM; -+ } -+ -+ irq_res = platform_get_resource(op, IORESOURCE_IRQ, 0); -+ if (irq_res) -+ irq = irq_res->start; -+ -+ host = ata_host_alloc(&op->dev, 1); -+ if (!host) -+ return -ENOMEM; -+ ap = host->ports[0]; -+ -+ ap->ops = &quanta_lb_ata_port_ops; -+ ap->pio_mask = ATA_PIO6; -+ ap->flags |= ATA_FLAG_SLAVE_POSS; -+ -+ if (!irq) { -+ ap->flags |= ATA_FLAG_PIO_POLLING; -+ ata_port_desc(ap, "no IRQ, using PIO polling"); -+ } -+ -+ ap->ioaddr.cmd_addr = io_mem; -+ ap->ioaddr.data_addr = io_mem + 0x02; -+ ap->ioaddr.error_addr = io_mem + 0x07; -+ ap->ioaddr.feature_addr = io_mem + 0x07; -+ ap->ioaddr.nsect_addr = io_mem + 0x0b; -+ ap->ioaddr.lbal_addr = io_mem + 0x0f; -+ ap->ioaddr.lbam_addr = io_mem + 0x13; -+ ap->ioaddr.lbah_addr = io_mem + 0x17; -+ ap->ioaddr.device_addr = io_mem + 0x1b; -+ ap->ioaddr.status_addr = io_mem + 0x1f; -+ ap->ioaddr.command_addr = io_mem + 0x1f; -+ ap->ioaddr.altstatus_addr = ctl_mem + 0x1b; -+ ap->ioaddr.ctl_addr = ctl_mem + 0x1b; -+ -+ ata_port_desc(ap, "mmio cmd 0x%llx ctl 0x%llx", -+ (unsigned long long) io_res.start, -+ (unsigned long long) ctl_res.start); -+ -+ return ata_host_activate(host, irq, irq ? ata_sff_interrupt : NULL, -+ 0, &quanta_lb_ata_sht); -+} -+ -+static int __exit -+quanta_lb_ata_remove(struct platform_device *op) -+{ -+ struct ata_host *host = dev_get_drvdata(&op->dev); -+ ata_host_detach(host); -+ return 0; -+} -+ -+static struct of_device_id quanta_lb_ata_of_match[] = { -+ { .compatible = "quanta-lb-ata", }, -+ {}, -+}; -+ -+static struct platform_driver quanta_lb_ata_of_platform_driver = { -+ .probe = quanta_lb_ata_probe, -+ .remove = __exit_p(quanta_lb_ata_remove), -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = quanta_lb_ata_of_match, -+ }, -+}; -+ -+module_platform_driver(quanta_lb_ata_of_platform_driver); -+ -+MODULE_AUTHOR("Big Switch Networks "); -+MODULE_DESCRIPTION("Quanta LBx platform PATA driver"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(of, quanta_lb_ata_of_match); diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-quanta-ly2-r0.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-quanta-ly2-r0.patch deleted file mode 100644 index 9776fb29..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-powerpc-quanta-ly2-r0.patch +++ /dev/null @@ -1,2491 +0,0 @@ -diff -rupN a/arch/powerpc/boot/dts/powerpc-quanta-ly2-r0.dts b/arch/powerpc/boot/dts/powerpc-quanta-ly2-r0.dts ---- a/arch/powerpc/boot/dts/powerpc-quanta-ly2-r0.dts 1969-12-31 16:00:00.000000000 -0800 -+++ b/arch/powerpc/boot/dts/powerpc-quanta-ly2-r0.dts 2015-05-18 13:39:01.764648504 -0700 -@@ -0,0 +1,1464 @@ -+/* -+ * -+ * -+ * Copyright 2013, 2014 BigSwitch Networks, Inc. -+ * -+ * This program is free software; you can redistribute it -+ * and/or modify it under the terms ofthe GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the License, -+ * or (at your option) any later version. -+ * -+ * -+ * -+ * -+ * -+ * Device tree for the Quanta LY2. -+ * -+ */ -+ -+ -+/dts-v1/; -+ -+/ { -+ model = "powerpc-quanta-ly2-r0"; -+ compatible = "fsl,P2020RDB"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ -+ aliases { -+ ethernet0 = &enet0; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci2 = &pci2; -+ mpic-msgr-block0 = &mpic_msgr_block0; -+ mpic-msgr-block1 = &mpic_msgr_block1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,P2020@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ next-level-cache = <&l2>; -+ }; -+ -+ PowerPC,P2020@1 { -+ device_type = "cpu"; -+ reg = <0x1>; -+ next-level-cache = <&l2>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ localbus@ffe05000 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus"; -+ reg = <0 0xffe05000 0 0x1000>; -+ interrupts = <19 2>; -+ interrupt-parent = <&mpic>; -+ -+ ranges = <0x0 0x0 0x0 0xee000000 0x2000000 -+ 0x1 0x0 0x0 0xec000000 0x2000000>; -+ -+ flash@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x2000000>; -+ bank-width = <2>; -+ -+ /* -+ * ONIE flash layout (reverse-engineered: -+ * - one ~27MiB loader partition -+ * - 4 MiB onie partition -+ * - uboot-env and uboot -+ * - 32MiB leftover space for jffs2 -+ * -+ */ -+ -+ flash@0 { -+ label = "onl-loader"; -+ reg = <0x00000000 0x01b60000>; -+ }; -+ -+ flash@1 { -+ label = "onie"; -+ reg = <0x01b60000 0x00400000>; -+ read-only; -+ }; -+ -+ flash@2 { -+ label = "uboot-env"; -+ reg = <0x01f60000 0x00020000>; -+ }; -+ -+ flash@3 { -+ label = "uboot"; -+ reg = <0x01f80000 0x00080000>; -+ read-only; -+ }; -+ -+ }; -+ -+ flash@1,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x1 0x0 0x2000000>; -+ bank-width = <2>; -+ -+ flash@4 { -+ label = "mnt-flash"; -+ reg = <0x00000000 0x02000000>; -+ }; -+ }; -+ }; -+ -+ soc@ffe00000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,p2020-immr", "simple-bus"; -+ ranges = <0x0 0x0 0xffe00000 0x100000>; -+ bus-frequency = <0>; -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <12>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,p2020-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,p2020-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <18 2>; -+ }; -+ -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ -+ dimm@51 { -+ compatible = "at,spd"; -+ reg = <0x51>; -+ read-only; -+ }; -+ -+ rtc@68 { -+ compatible = "dallas,ds1338"; -+ reg = <0x68>; -+ }; -+ -+ mux@71 { -+ compatible = "nxp,pca9546"; -+ reg = <0x71>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ eeprom-mb@54 { -+ compatible = "at,24c02"; -+ reg = <0x54>; -+ read-only; -+ }; -+ }; -+ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ }; -+ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ -+ temp-fan@2e { -+ compatible = "quanta_ly_hwmon"; -+ reg = <0x2e>; -+ }; -+ }; -+ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ }; -+ }; -+ -+ mux@75 { -+ compatible = "nxp,pca9546"; -+ reg = <0x75>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ psu-1@58 { -+ compatible = "pmbus"; -+ reg = <0x58>; -+ }; -+ }; -+ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ -+ psu-2@59 { -+ compatible = "pmbus"; -+ reg = <0x59>; -+ }; -+ }; -+ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ -+ gpio-psu-1@24 { -+ compatible = "nxp,pca9555"; -+ reg = <0x24>; -+ #gpio-cells = <2>; -+ gpio-controller; -+ }; -+ }; -+ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ -+ gpio-psu-2@25 { -+ compatible = "nxp,pca9555"; -+ reg = <0x25>; -+ #gpio-cells = <2>; -+ gpio-controller; -+ }; -+ }; -+ }; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ -+ mux@25 { -+ compatible = "quanta_ly2_i2c_mux"; -+ reg = <0x25>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ eeprom-sfp-2@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-2@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ -+ eeprom-sfp-1@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-1@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ -+ eeprom-sfp-4@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-4@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ -+ eeprom-sfp-3@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-3@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ -+ eeprom-sfp-6@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-6@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ -+ eeprom-sfp-5@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-5@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ -+ eeprom-sfp-8@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-8@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ -+ eeprom-sfp-7@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-7@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@8 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ -+ eeprom-sfp-10@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-10@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@9 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ -+ eeprom-sfp-9@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-9@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ -+ eeprom-sfp-12@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-12@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@11 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ -+ eeprom-sfp-11@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-11@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@12 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ -+ eeprom-sfp-14@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-14@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@13 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ -+ eeprom-sfp-13@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-13@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@14 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ -+ eeprom-sfp-16@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-16@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@15 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ -+ eeprom-sfp-15@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-15@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ }; -+ -+ mux@26 { -+ compatible = "quanta_ly2_i2c_mux"; -+ reg = <0x26>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ eeprom-sfp-18@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-18@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ -+ eeprom-sfp-17@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-17@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ -+ eeprom-sfp-20@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-20@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ -+ eeprom-sfp-19@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-19@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ -+ eeprom-sfp-22@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-22@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ -+ eeprom-sfp-21@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-21@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ -+ eeprom-sfp-24@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-24@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ -+ eeprom-sfp-23@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-23@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@8 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ -+ eeprom-sfp-26@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-26@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@9 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ -+ eeprom-sfp-25@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-25@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ -+ eeprom-sfp-28@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-28@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@11 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ -+ eeprom-sfp-27@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-27@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@12 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ -+ eeprom-sfp-30@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-30@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@13 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ -+ eeprom-sfp-29@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-29@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@14 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ -+ eeprom-sfp-32@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-32@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@15 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ -+ eeprom-sfp-31@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-31@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ }; -+ -+ mux@27 { -+ compatible = "quanta_ly2_i2c_mux"; -+ reg = <0x27>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ eeprom-sfp-34@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-34@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ -+ eeprom-sfp-33@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-33@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ -+ eeprom-sfp-36@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-36@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ -+ eeprom-sfp-35@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-35@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ -+ eeprom-sfp-38@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-38@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ -+ eeprom-sfp-37@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-37@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ -+ eeprom-sfp-40@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-40@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ -+ eeprom-sfp-39@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-39@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@8 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ -+ eeprom-sfp-42@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-42@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@9 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ -+ eeprom-sfp-41@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-41@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ -+ eeprom-sfp-44@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-44@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@11 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ -+ eeprom-sfp-43@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-43@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@12 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ -+ eeprom-sfp-46@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-46@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@13 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ -+ eeprom-sfp-45@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-45@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@14 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ -+ eeprom-sfp-48@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-48@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@15 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ -+ eeprom-sfp-47@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-sfp-47@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ }; -+ -+ mux@73 { -+ compatible = "nxp,pca9546"; -+ reg = <0x73>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ eeprom-qsfp-1@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-qsfp-1@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ -+ eeprom-qsfp-2@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-qsfp-2@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ -+ eeprom-qsfp-3@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-qsfp-3@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ -+ eeprom-qsfp-4@50 { -+ compatible = "at,24c02"; -+ reg = <0x50>; -+ read-only; -+ }; -+ eeprom-qsfp-4@51 { -+ compatible = "at,24c02"; -+ reg = <0x51>; -+ read-only; -+ }; -+ }; -+ }; -+ }; -+ -+ serial0: serial@4500 { -+ cell-index = <0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ serial1: serial@4600 { -+ cell-index = <1>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4600 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ dma@c300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0xc300 0x4>; -+ ranges = <0x0 0xc100 0x200>; -+ cell-index = <1>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <76 2>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <77 2>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupt-parent = <&mpic>; -+ interrupts = <78 2>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupt-parent = <&mpic>; -+ interrupts = <79 2>; -+ }; -+ }; -+ -+ gpio: gpio-controller@f000 { -+ #gpio-cells = <2>; -+ compatible = "fsl,mpc8572-gpio"; -+ reg = <0xf000 0x100>; -+ interrupts = <47 0x2>; -+ interrupt-parent = <&mpic>; -+ gpio-controller; -+ }; -+ -+ l2: l2-cache-controller@20000 { -+ compatible = "fsl,p2020-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x80000>; // L2,512K -+ interrupt-parent = <&mpic>; -+ interrupts = <16 2>; -+ }; -+ -+ dma@21300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,eloplus-dma"; -+ reg = <0x21300 0x4>; -+ ranges = <0x0 0x21100 0x200>; -+ cell-index = <0>; -+ dma-channel@0 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <20 2>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <21 2>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupt-parent = <&mpic>; -+ interrupts = <22 2>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupt-parent = <&mpic>; -+ interrupts = <23 2>; -+ }; -+ }; -+ -+/* usb@22000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl-usb2-dr"; -+ reg = <0x22000 0x1000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <28 0x2>; -+ phy_type = "ulpi"; -+ }; -+*/ -+ ptp_timer: ptimer@24e00 { -+ compatible = "fsl,gianfar-ptp-timer"; -+ reg = <0x24e00 0xb0>; -+ }; -+ -+ enet0: ethernet@24000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <0>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x24000 0x1000>; -+ ranges = <0x0 0x24000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <29 2 30 2 34 2>; -+ interrupt-parent = <&mpic>; -+ phy-connection-type = "sgmii"; -+ phy-handle = <&phy0>; -+ tbi-handle = <&tbi0>; -+ }; -+ -+ mdio@24520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ -+ phy0: ethernet-phy@0 { -+ reg = <0x1>; -+ device_type = "ethernet-phy"; -+ }; -+ tbi0: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ sdhci@2e000 { -+ compatible = "fsl,p2020-esdhc", "fsl,esdhc"; -+ reg = <0x2e000 0x1000>; -+ interrupts = <72 0x2>; -+ interrupt-parent = <&mpic>; -+ clock-frequency = <0>; -+ }; -+ -+ crypto@30000 { -+ compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4", -+ "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0"; -+ reg = <0x30000 0x10000>; -+ interrupts = <45 2 58 2>; -+ interrupt-parent = <&mpic>; -+ fsl,num-channels = <4>; -+ fsl,channel-fifo-len = <24>; -+ fsl,exec-units-mask = <0xbfe>; -+ fsl,descriptor-types-mask = <0x3ab0ebf>; -+ fsl,multi-host-mode = "dual"; -+ fsl,channel-remap = <0x3>; -+ }; -+ -+ mpic: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ reg = <0x40000 0x40000>; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ }; -+ -+ mpic_msgr_block0: message@41400 { -+ compatible = "fsl,mpic-v3.1-msgr"; -+ reg = <0x41400 0x200>; -+ interrupts = < -+ 0xb0 2 -+ 0xb1 2 -+ 0xb2 2 -+ 0xb3 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ mpic_msgr_block1: message@42400 { -+ compatible = "fsl,mpic-v3.1-msgr"; -+ reg = <0x42400 0x200>; -+ interrupts = < -+ 0xb4 2 -+ 0xb5 2 -+ 0xb6 2 -+ 0xb7 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ msi@41600 { -+ compatible = "fsl,p2020-msi", "fsl,mpic-msi"; -+ reg = <0x41600 0x80>; -+ msi-available-ranges = <0 0x100>; -+ interrupts = < -+ 0xe0 0 -+ 0xe1 0 -+ 0xe2 0 -+ 0xe3 0 -+ 0xe4 0 -+ 0xe5 0 -+ 0xe6 0 -+ 0xe7 0>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ global-utilities@e0000 { -+ compatible = "fsl,p2020-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+ }; -+ -+ pci2: pcie@ffe0a000 { -+ compatible = "fsl,mpc8548-pcie"; -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0 0xffe0a000 0 0x1000>; -+ bus-range = <0 255>; -+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; -+ clock-frequency = <100000000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <26 2>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 -+ >; -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xc0000000 -+ 0x2000000 0x0 0xc0000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x10000>; -+ }; -+ }; -+}; -diff -rupN a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig ---- a/drivers/hwmon/Kconfig 2015-05-18 14:01:39.048702767 -0700 -+++ b/drivers/hwmon/Kconfig 2015-05-18 13:51:58.972677584 -0700 -@@ -1412,6 +1412,13 @@ config SENSORS_MC13783_ADC - help - Support for the A/D converter on MC13783 PMIC. - -+config SENSORS_QUANTA_LY_HWMON -+ tristate "Quanta LYx hardware monitor" -+ depends on I2C -+ help -+ If you say yes here you get support for the Quanta LYx hardware -+ monitor. -+ - if ACPI - - comment "ACPI drivers" -diff -rupN a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile ---- a/drivers/hwmon/Makefile 2015-05-18 14:01:39.048702767 -0700 -+++ b/drivers/hwmon/Makefile 2015-05-18 13:48:34.908668001 -0700 -@@ -130,6 +130,7 @@ obj-$(CONFIG_SENSORS_W83L785TS) += w83l7 - obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o - obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o - obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o -+obj-$(CONFIG_SENSORS_QUANTA_LY_HWMON) += quanta-ly-hwmon.o - - obj-$(CONFIG_PMBUS) += pmbus/ - -diff -rupN a/drivers/hwmon/quanta-ly-hwmon.c b/drivers/hwmon/quanta-ly-hwmon.c ---- a/drivers/hwmon/quanta-ly-hwmon.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/drivers/hwmon/quanta-ly-hwmon.c 2015-05-18 13:53:49.548681131 -0700 -@@ -0,0 +1,297 @@ -+/* -+ * -+ * -+ * Copyright 2013, 2014 BigSwitch Networks, Inc. -+ * -+ * This program is free software; you can redistribute it -+ * and/or modify it under the terms ofthe GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the License, -+ * or (at your option) any later version. -+ * -+ * -+ * -+ * -+ * A hwmon driver for the Quanta LYx -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; -+ -+#define QUANTA_LY_HWMON_REG_TEMP_INPUT_BASE 0x30 -+#define QUANTA_LY_HWMON_REG_FAN_MODE 0x55 -+#define QUANTA_LY_HWMON_REG_FAN_DIR 0x56 -+#define QUANTA_LY_HWMON_REG_FAN_PWM_BASE 0x60 -+#define QUANTA_LY_HWMON_REG_FAN_INPUT_BASE 0x80 -+ -+#define QUANTA_LY_HWMON_FAN_MANUAL_MODE 1 -+#define QUANTA_LY_HWMON_FAN_AUTO_MODE 2 -+ -+#define QUANTA_LY_HWMON_NUM_FANS 8 -+ -+struct quanta_ly_hwmon_data { -+ struct device *hwmon_dev; -+ struct attribute_group attrs; -+ struct mutex lock; -+}; -+ -+static int quanta_ly_hwmon_probe(struct i2c_client *client, -+ const struct i2c_device_id *id); -+static int quanta_ly_hwmon_remove(struct i2c_client *client); -+ -+static const struct i2c_device_id quanta_ly_hwmon_id[] = { -+ { "quanta_ly_hwmon", 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, quanta_ly_hwmon_id); -+ -+static struct i2c_driver quanta_ly_hwmon_driver = { -+ .class = I2C_CLASS_HWMON, -+ .driver = { -+ .name = "quanta_ly_hwmon", -+ }, -+ .probe = quanta_ly_hwmon_probe, -+ .remove = quanta_ly_hwmon_remove, -+ .id_table = quanta_ly_hwmon_id, -+ .address_list = normal_i2c, -+}; -+ -+static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct quanta_ly_hwmon_data *data = i2c_get_clientdata(client); -+ int temp; -+ -+ mutex_lock(&data->lock); -+ temp = i2c_smbus_read_byte_data(client, -+ QUANTA_LY_HWMON_REG_TEMP_INPUT_BASE -+ + attr->index); -+ mutex_unlock(&data->lock); -+ return sprintf(buf, "%d\n", 1000 * temp); -+} -+ -+static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct quanta_ly_hwmon_data *data = i2c_get_clientdata(client); -+ int fan; -+ -+ mutex_lock(&data->lock); -+ fan = i2c_smbus_read_word_swapped(client, -+ QUANTA_LY_HWMON_REG_FAN_INPUT_BASE -+ + 2 * attr->index); -+ mutex_unlock(&data->lock); -+ return sprintf(buf, "%d\n", fan); -+} -+ -+static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct quanta_ly_hwmon_data *data = i2c_get_clientdata(client); -+ int pwm; -+ -+ mutex_lock(&data->lock); -+ pwm = i2c_smbus_read_word_swapped(client, -+ QUANTA_LY_HWMON_REG_FAN_PWM_BASE -+ + 2 * attr->index); -+ mutex_unlock(&data->lock); -+ return sprintf(buf, "%d\n", pwm * 255 / 10000); -+} -+ -+static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, -+ const char *buf, size_t count) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct quanta_ly_hwmon_data *data = i2c_get_clientdata(client); -+ long val; -+ int ret; -+ -+ ret = kstrtol(buf, 10, &val); -+ if (ret) -+ return ret; -+ mutex_lock(&data->lock); -+ i2c_smbus_write_word_swapped(client, -+ QUANTA_LY_HWMON_REG_FAN_PWM_BASE -+ + 2 * attr->index, val * 10000 / 255); -+ mutex_unlock(&data->lock); -+ return count; -+} -+ -+static ssize_t show_fan_dir(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct quanta_ly_hwmon_data *data = i2c_get_clientdata(client); -+ -+ int f2b = 0; -+ int b2f = 0; -+ int i; -+ -+ mutex_lock(&data->lock); -+ for(i = 0; i < 4; i++) { -+ f2b += i2c_smbus_read_word_swapped(client, -+ QUANTA_LY_HWMON_REG_FAN_INPUT_BASE -+ + 2 * i); -+ } -+ for(i = 4; i < 8; i++) { -+ b2f += i2c_smbus_read_word_swapped(client, -+ QUANTA_LY_HWMON_REG_FAN_INPUT_BASE -+ + 2 * i); -+ } -+ -+ mutex_unlock(&data->lock); -+ if(f2b) { -+ return sprintf(buf, "front-to-back"); -+ } -+ if(b2f) { -+ return sprintf(buf, "back-to-front"); -+ } -+ return sprintf(buf, "unknown"); -+} -+ -+static ssize_t set_fan_dir(struct device *dev, -+ struct device_attribute *devattr, const char *buf, -+ size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct quanta_ly_hwmon_data *data = i2c_get_clientdata(client); -+ int dir; -+ -+ if (!strncmp(buf, "normal", 6)) -+ dir = 0; -+ else if (!strncmp(buf, "reverse", 7)) -+ dir = 1; -+ else -+ return -EINVAL; -+ -+ mutex_lock(&data->lock); -+ i2c_smbus_write_byte_data(client, -+ QUANTA_LY_HWMON_REG_FAN_DIR, dir); -+ mutex_unlock(&data->lock); -+ return count; -+} -+ -+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); -+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); -+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); -+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); -+static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp, NULL, 4); -+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); -+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); -+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); -+static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); -+static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4); -+static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5); -+static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6); -+static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7); -+static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); -+static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); -+static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); -+static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); -+static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 4); -+static SENSOR_DEVICE_ATTR(pwm6, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 5); -+static SENSOR_DEVICE_ATTR(pwm7, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 6); -+static SENSOR_DEVICE_ATTR(pwm8, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 7); -+static SENSOR_DEVICE_ATTR(fan_dir, S_IWUSR | S_IRUGO, show_fan_dir, -+ set_fan_dir, 0); -+ -+static struct attribute *quanta_ly_hwmon_attr[] = { -+ &sensor_dev_attr_temp1_input.dev_attr.attr, -+ &sensor_dev_attr_temp2_input.dev_attr.attr, -+ &sensor_dev_attr_temp3_input.dev_attr.attr, -+ &sensor_dev_attr_temp4_input.dev_attr.attr, -+ &sensor_dev_attr_temp5_input.dev_attr.attr, -+ &sensor_dev_attr_fan1_input.dev_attr.attr, -+ &sensor_dev_attr_fan2_input.dev_attr.attr, -+ &sensor_dev_attr_fan3_input.dev_attr.attr, -+ &sensor_dev_attr_fan4_input.dev_attr.attr, -+ &sensor_dev_attr_fan5_input.dev_attr.attr, -+ &sensor_dev_attr_fan6_input.dev_attr.attr, -+ &sensor_dev_attr_fan7_input.dev_attr.attr, -+ &sensor_dev_attr_fan8_input.dev_attr.attr, -+ &sensor_dev_attr_pwm1.dev_attr.attr, -+ &sensor_dev_attr_pwm2.dev_attr.attr, -+ &sensor_dev_attr_pwm3.dev_attr.attr, -+ &sensor_dev_attr_pwm4.dev_attr.attr, -+ &sensor_dev_attr_pwm5.dev_attr.attr, -+ &sensor_dev_attr_pwm6.dev_attr.attr, -+ &sensor_dev_attr_pwm7.dev_attr.attr, -+ &sensor_dev_attr_pwm8.dev_attr.attr, -+ &sensor_dev_attr_fan_dir.dev_attr.attr, -+ NULL -+}; -+ -+static int quanta_ly_hwmon_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct quanta_ly_hwmon_data *data; -+ int err; -+ int i; -+ -+ data = devm_kzalloc(&client->dev, sizeof(struct quanta_ly_hwmon_data), -+ GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ i2c_set_clientdata(client, data); -+ mutex_init(&data->lock); -+ -+ dev_info(&client->dev, "%s chip found\n", client->name); -+ -+ data->attrs.attrs = quanta_ly_hwmon_attr; -+ err = sysfs_create_group(&client->dev.kobj, &data->attrs); -+ if (err) -+ return err; -+ -+ data->hwmon_dev = hwmon_device_register(&client->dev); -+ if (IS_ERR(data->hwmon_dev)) { -+ err = PTR_ERR(data->hwmon_dev); -+ goto exit_remove; -+ } -+ -+ i2c_smbus_write_byte_data(client, -+ QUANTA_LY_HWMON_REG_FAN_MODE, -+ QUANTA_LY_HWMON_FAN_MANUAL_MODE); -+ for (i = 0; i < QUANTA_LY_HWMON_NUM_FANS; i++) { -+ u8 cmd = QUANTA_LY_HWMON_REG_FAN_PWM_BASE + i * 2; -+ i2c_smbus_write_word_swapped(client, cmd, 10000); -+ } -+ -+ return 0; -+ -+exit_remove: -+ sysfs_remove_group(&client->dev.kobj, &data->attrs); -+ return err; -+} -+ -+static int quanta_ly_hwmon_remove(struct i2c_client *client) -+{ -+ struct quanta_ly_hwmon_data *data = i2c_get_clientdata(client); -+ -+ hwmon_device_unregister(data->hwmon_dev); -+ sysfs_remove_group(&client->dev.kobj, &data->attrs); -+ return 0; -+} -+ -+module_i2c_driver(quanta_ly_hwmon_driver); -+ -+MODULE_AUTHOR("Big Switch Networks "); -+MODULE_DESCRIPTION("Quanta LYx hardware monitor driver"); -+MODULE_LICENSE("GPL"); -diff -rupN a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c ---- a/drivers/i2c/muxes/i2c-mux-pca954x.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c 2015-05-18 13:55:04.600672335 -0700 -@@ -0,0 +1,295 @@ -+/* -+ * I2C multiplexer -+ * -+ * Copyright (c) 2008-2009 Rodolfo Giometti -+ * Copyright (c) 2008-2009 Eurotech S.p.A. -+ * -+ * This module supports the PCA954x series of I2C multiplexer/switch chips -+ * made by Philips Semiconductors. -+ * This includes the: -+ * PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547 -+ * and PCA9548. -+ * -+ * These chips are all controlled via the I2C bus itself, and all have a -+ * single 8-bit register. The upstream "parent" bus fans out to two, -+ * four, or eight downstream busses or channels; which of these -+ * are selected is determined by the chip type and register contents. A -+ * mux can select only one sub-bus at a time; a switch can select any -+ * combination simultaneously. -+ * -+ * Based on: -+ * pca954x.c from Kumar Gala -+ * Copyright (C) 2006 -+ * -+ * Based on: -+ * pca954x.c from Ken Harrenstien -+ * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) -+ * -+ * Based on: -+ * i2c-virtual_cb.c from Brian Kuschak -+ * and -+ * pca9540.c from Jean Delvare . -+ * -+ * 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 -+ -+#define PCA954X_MAX_NCHANS 8 -+ -+enum pca_type { -+ pca_9540, -+ pca_9542, -+ pca_9543, -+ pca_9544, -+ pca_9545, -+ pca_9546, -+ pca_9547, -+ pca_9548, -+}; -+ -+struct pca954x { -+ enum pca_type type; -+ struct i2c_adapter *virt_adaps[PCA954X_MAX_NCHANS]; -+ -+ u8 last_chan; /* last register value */ -+}; -+ -+struct chip_desc { -+ u8 nchans; -+ u8 enable; /* used for muxes only */ -+ enum muxtype { -+ pca954x_ismux = 0, -+ pca954x_isswi -+ } muxtype; -+}; -+ -+/* Provide specs for the PCA954x types we know about */ -+static const struct chip_desc chips[] = { -+ [pca_9540] = { -+ .nchans = 2, -+ .enable = 0x4, -+ .muxtype = pca954x_ismux, -+ }, -+ [pca_9543] = { -+ .nchans = 2, -+ .muxtype = pca954x_isswi, -+ }, -+ [pca_9544] = { -+ .nchans = 4, -+ .enable = 0x4, -+ .muxtype = pca954x_ismux, -+ }, -+ [pca_9545] = { -+ .nchans = 4, -+ .muxtype = pca954x_isswi, -+ }, -+ [pca_9547] = { -+ .nchans = 8, -+ .enable = 0x8, -+ .muxtype = pca954x_ismux, -+ }, -+ [pca_9548] = { -+ .nchans = 8, -+ .muxtype = pca954x_isswi, -+ }, -+}; -+ -+static const struct i2c_device_id pca954x_id[] = { -+ { "pca9540", pca_9540 }, -+ { "pca9542", pca_9540 }, -+ { "pca9543", pca_9543 }, -+ { "pca9544", pca_9544 }, -+ { "pca9545", pca_9545 }, -+ { "pca9546", pca_9545 }, -+ { "pca9547", pca_9547 }, -+ { "pca9548", pca_9548 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, pca954x_id); -+ -+/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer() -+ for this as they will try to lock adapter a second time */ -+static int pca954x_reg_write(struct i2c_adapter *adap, -+ struct i2c_client *client, u8 val) -+{ -+ int ret = -ENODEV; -+ -+ if (adap->algo->master_xfer) { -+ struct i2c_msg msg; -+ char buf[1]; -+ -+ msg.addr = client->addr; -+ msg.flags = 0; -+ msg.len = 1; -+ buf[0] = val; -+ msg.buf = buf; -+ ret = adap->algo->master_xfer(adap, &msg, 1); -+ } else { -+ union i2c_smbus_data data; -+ ret = adap->algo->smbus_xfer(adap, client->addr, -+ client->flags, -+ I2C_SMBUS_WRITE, -+ val, I2C_SMBUS_BYTE, &data); -+ } -+ -+ return ret; -+} -+ -+#define CONFIG_ALWAYS_SELECT_CHANNEL 1 -+ -+static int pca954x_select_chan(struct i2c_adapter *adap, -+ void *client, u32 chan) -+{ -+ struct pca954x *data = i2c_get_clientdata(client); -+ const struct chip_desc *chip = &chips[data->type]; -+ -+ u8 regval; -+ int ret = 0; -+ -+ /* we make switches look like muxes, not sure how to be smarter */ -+ if (chip->muxtype == pca954x_ismux) -+ regval = chan | chip->enable; -+ else -+ regval = 1 << chan; -+ -+ /* Only select the channel if its different from the last channel */ -+ if (CONFIG_ALWAYS_SELECT_CHANNEL || data->last_chan != regval) { -+ ret = pca954x_reg_write(adap, client, regval); -+ data->last_chan = regval; -+ } -+ -+ return ret; -+} -+ -+static int pca954x_deselect_mux(struct i2c_adapter *adap, -+ void *client, u32 chan) -+{ -+ struct pca954x *data = i2c_get_clientdata(client); -+ -+ /* Deselect active channel */ -+ data->last_chan = 0; -+ return pca954x_reg_write(adap, client, data->last_chan); -+} -+ -+/* -+ * I2C init/probing/exit functions -+ */ -+static int pca954x_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); -+ struct pca954x_platform_data *pdata = client->dev.platform_data; -+ int num, force, class; -+ struct pca954x *data; -+ int ret = -ENODEV; -+ -+ if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) -+ goto err; -+ -+ data = kzalloc(sizeof(struct pca954x), GFP_KERNEL); -+ if (!data) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ i2c_set_clientdata(client, data); -+ -+ /* Write the mux register at addr to verify -+ * that the mux is in fact present. This also -+ * initializes the mux to disconnected state. -+ */ -+ if (i2c_smbus_write_byte(client, 0) < 0) { -+ dev_warn(&client->dev, "probe failed\n"); -+ goto exit_free; -+ } -+ -+ data->type = id->driver_data; -+ data->last_chan = 0; /* force the first selection */ -+ -+ /* Now create an adapter for each channel */ -+ for (num = 0; num < chips[data->type].nchans; num++) { -+ force = 0; /* dynamic adap number */ -+ class = 0; /* no class by default */ -+ if (pdata) { -+ if (num < pdata->num_modes) { -+ /* force static number */ -+ force = pdata->modes[num].adap_id; -+ class = pdata->modes[num].class; -+ } else -+ /* discard unconfigured channels */ -+ break; -+ } -+ -+ data->virt_adaps[num] = -+ i2c_add_mux_adapter(adap, &client->dev, client, -+ force, num, class, pca954x_select_chan, -+ pca954x_deselect_mux); -+ -+ if (data->virt_adaps[num] == NULL) { -+ ret = -ENODEV; -+ dev_err(&client->dev, -+ "failed to register multiplexed adapter" -+ " %d as bus %d\n", num, force); -+ goto virt_reg_failed; -+ } -+ } -+ -+ dev_info(&client->dev, -+ "registered %d multiplexed busses for I2C %s %s\n", -+ num, chips[data->type].muxtype == pca954x_ismux -+ ? "mux" : "switch", client->name); -+ -+ return 0; -+ -+virt_reg_failed: -+ for (num--; num >= 0; num--) -+ i2c_del_mux_adapter(data->virt_adaps[num]); -+exit_free: -+ kfree(data); -+err: -+ return ret; -+} -+ -+static int pca954x_remove(struct i2c_client *client) -+{ -+ struct pca954x *data = i2c_get_clientdata(client); -+ const struct chip_desc *chip = &chips[data->type]; -+ int i, err; -+ -+ for (i = 0; i < chip->nchans; ++i) -+ if (data->virt_adaps[i]) { -+ err = i2c_del_mux_adapter(data->virt_adaps[i]); -+ if (err) -+ return err; -+ data->virt_adaps[i] = NULL; -+ } -+ -+ kfree(data); -+ return 0; -+} -+ -+static struct i2c_driver pca954x_driver = { -+ .driver = { -+ .name = "pca954x", -+ .owner = THIS_MODULE, -+ }, -+ .probe = pca954x_probe, -+ .remove = pca954x_remove, -+ .id_table = pca954x_id, -+}; -+ -+module_i2c_driver(pca954x_driver); -+ -+MODULE_AUTHOR("Rodolfo Giometti "); -+MODULE_DESCRIPTION("PCA954x I2C mux/switch driver"); -+MODULE_LICENSE("GPL v2"); -diff -rupN a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig ---- a/drivers/i2c/muxes/Kconfig 2015-05-18 14:01:39.076702769 -0700 -+++ b/drivers/i2c/muxes/Kconfig 2015-05-18 13:56:18.272692152 -0700 -@@ -49,4 +49,9 @@ config I2C_MUX_QUANTA - help - If you say yes here you get support for the QUANTA I2C Mux devices - -+config I2C_MUX_QUANTA_LY2 -+ tristate "Quanta LY2 I2C multiplexer" -+ help -+ If you say yes here you get support for the Quanta LY2 I2C/GPIO -+ multiplexer. - endmenu -diff -rupN a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile ---- a/drivers/i2c/muxes/Makefile 2015-05-18 14:01:39.080702769 -0700 -+++ b/drivers/i2c/muxes/Makefile 2015-05-18 13:57:01.776693234 -0700 -@@ -6,5 +6,6 @@ obj-$(CONFIG_I2C_MUX_PCA9541) += pca9541 - obj-$(CONFIG_I2C_MUX_PCA954x) += pca954x.o - obj-$(CONFIG_I2C_MUX_DNI_6448) += dni_6448_i2c_mux.o - obj-$(CONFIG_I2C_MUX_QUANTA) += quanta-i2cmux.o -+obj-$(CONFIG_I2C_MUX_QUANTA_LY2) += quanta-ly2-i2c-mux.o - - ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG -diff -rupN a/drivers/i2c/muxes/quanta-ly2-i2c-mux.c b/drivers/i2c/muxes/quanta-ly2-i2c-mux.c ---- a/drivers/i2c/muxes/quanta-ly2-i2c-mux.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/drivers/i2c/muxes/quanta-ly2-i2c-mux.c 2015-05-18 13:57:57.152691359 -0700 -@@ -0,0 +1,357 @@ -+/* -+ * -+ * -+ * Copyright 2013, 2014 BigSwitch Networks, Inc. -+ * -+ * This program is free software; you can redistribute it -+ * and/or modify it under the terms ofthe GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the License, -+ * or (at your option) any later version. -+ * -+ * -+ * -+ * -+ * An I2C multiplexer driver for the Quanta LY2 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define QUANTA_LY2_I2C_MUX_CHANNEL_FIRST 1 -+ -+#define QUANTA_LY2_I2C_MUX_NUM_CHANNELS 16 -+ -+/* -+ * 16 read GPIOs, 8 write GPIOs, -+ * treat them as a single GPIO chip, -+ * with the read GPIOs occurring first -+ */ -+#define QUANTA_LY2_I2C_MUX_NUM_READ_GPIOS 16 -+#define QUANTA_LY2_I2C_MUX_NUM_WRITE_GPIOS 8 -+ -+#define QUANTA_LY2_I2C_MUX_CMD_GET_GPIO 0 -+#define QUANTA_LY2_I2C_MUX_CMD_SET_GPIO 1 -+#define QUANTA_LY2_I2C_MUX_CMD_SET_CHANNEL 2 -+ -+struct quanta_ly2_i2c_mux { -+ struct i2c_client *client; -+ struct i2c_adapter *chan_adap[QUANTA_LY2_I2C_MUX_NUM_CHANNELS]; -+ struct gpio_chip gpio_chip; -+ u8 last_chan; -+ u8 gpio_write_val; -+}; -+ -+static const struct i2c_device_id quanta_ly2_i2c_mux_id[] = { -+ {"quanta_ly_i2c_mux", 0}, -+ {"quanta_ly2_i2c_mux", 0}, -+ {} -+}; -+ -+MODULE_DEVICE_TABLE(i2c, quanta_ly2_i2c_mux_id); -+ -+/* -+ * pld.c does 3-byte transactions, but none of the GPIO -+ * definitions require more than 16 bits -+ */ -+static int quanta_ly2_i2c_mux_reg_read(struct i2c_adapter *adap, -+ struct i2c_client *client, -+ u8 command, u16 *val) -+{ -+ int ret = -ENODEV; -+ -+ if (adap->algo->master_xfer) { -+ struct i2c_msg msg[2]; -+ char buf[4]; -+ -+ msg[0].addr = client->addr; -+ msg[0].flags = 0; -+ msg[0].len = 1; -+ buf[0] = command; -+ msg[0].buf = &buf[0]; -+ -+ /* always receive 3 bytes, else the PLD freaks out */ -+ msg[1].addr = client->addr; -+ msg[1].flags = I2C_M_RD; -+ msg[1].len = 3; -+ msg[1].buf = &buf[1]; -+ -+ ret = adap->algo->master_xfer(adap, msg, 2); -+ if (val != NULL && ret > -1) -+ *val = ((buf[2] << 8) | buf[1]); -+ } else { -+ union i2c_smbus_data data; -+ data.block[0] = 3; /* block transfer length */ -+ ret = adap->algo->smbus_xfer(adap, client->addr, -+ client->flags, -+ I2C_SMBUS_READ, -+ command, -+ I2C_SMBUS_I2C_BLOCK_DATA, &data); -+ if (val != NULL) -+ *val = ((data.block[2] << 8) | data.block[1]); -+ } -+ -+ return ret; -+} -+ -+/* -+ * pld.c shows 3-byte output transactions; -+ * in our case we only need 8 bits to -+ * (1) select one of the 16 muxed i2c devices, -+ * (2) drive one of the 8 defined GPIO outputs -+ */ -+static int quanta_ly2_i2c_mux_reg_write(struct i2c_adapter *adap, -+ struct i2c_client *client, -+ u8 command, u8 val) -+{ -+ int ret = -ENODEV; -+ -+ if (adap->algo->master_xfer) { -+ struct i2c_msg msg; -+ char buf[4]; -+ -+ msg.addr = client->addr; -+ msg.flags = 0; -+ msg.len = 3; -+ buf[0] = command; -+ buf[1] = val; -+ buf[2] = 0; -+ buf[3] = 0; -+ msg.buf = buf; -+ ret = adap->algo->master_xfer(adap, &msg, 1); -+ } else { -+ union i2c_smbus_data data; -+ -+ data.block[0] = 3; -+ data.block[1] = val; -+ data.block[2] = 0; -+ data.block[3] = 0; -+ -+ ret = adap->algo->smbus_xfer(adap, client->addr, -+ client->flags, -+ I2C_SMBUS_WRITE, -+ command, -+ I2C_SMBUS_I2C_BLOCK_DATA, &data); -+ } -+ -+ return ret; -+} -+ -+static void quanta_ly2_i2c_mux_gpio_set(struct gpio_chip *gc, unsigned offset, -+ int val) -+{ -+ struct quanta_ly2_i2c_mux *data = container_of( -+ gc, struct quanta_ly2_i2c_mux, gpio_chip); -+ -+ /* ignore write attempts to input GPIOs */ -+ if (offset < QUANTA_LY2_I2C_MUX_NUM_READ_GPIOS) { -+ dev_warn(&data->client->dev, -+ "ignoring GPIO write for input for pin %d\n", -+ offset); -+ return; -+ } -+ offset -= QUANTA_LY2_I2C_MUX_NUM_READ_GPIOS; -+ -+ if (val) -+ data->gpio_write_val |= (1 << offset); -+ else -+ data->gpio_write_val &= ~(1 << offset); -+ -+ quanta_ly2_i2c_mux_reg_write( -+ data->client->adapter, data->client, -+ QUANTA_LY2_I2C_MUX_CMD_SET_GPIO, -+ data->gpio_write_val); -+} -+ -+/* -+ * "read" one of the GPIOs. -+ * The first 16 (QUANTA_LY2_I2C_MUX_NUM_READ_GPIOS) -+ * are actual input GPIOs. -+ * the last 8 (QUANTA_LY2_I2C_MUX_NUM_WRITE_GPIOS) -+ * are output GPIOs, so readback just returns the cached value. -+ */ -+static int quanta_ly2_i2c_mux_gpio_get(struct gpio_chip *gc, unsigned offset) -+{ -+ int ret; -+ u16 buf; -+ struct quanta_ly2_i2c_mux *data = container_of( -+ gc, struct quanta_ly2_i2c_mux, gpio_chip); -+ -+ if (offset >= QUANTA_LY2_I2C_MUX_NUM_READ_GPIOS) { -+ offset -= QUANTA_LY2_I2C_MUX_NUM_READ_GPIOS; -+ return (data->gpio_write_val & (1 << offset)) ? 1 : 0; -+ } -+ -+ /* else, do a proper gpio read */ -+ buf = 0; -+ ret = quanta_ly2_i2c_mux_reg_read(data->client->adapter, -+ data->client, -+ QUANTA_LY2_I2C_MUX_CMD_GET_GPIO, -+ &buf); -+ if (ret < 0) { -+ dev_err(&data->client->dev, -+ "quanta_ly2_i2c_mux_reg_read failed\n"); -+ return 0; -+ } -+ return (buf & (1 << offset)) ? 1 : 0; -+} -+ -+static int quanta_ly2_i2c_mux_select_chan(struct i2c_adapter *adap, -+ void *client, u32 chan) -+{ -+ struct quanta_ly2_i2c_mux *data = i2c_get_clientdata(client); -+ int ret = 0; -+ u32 c = QUANTA_LY2_I2C_MUX_CHANNEL_FIRST + chan; -+ -+ if (data->last_chan != c) { -+ ret = quanta_ly2_i2c_mux_reg_write( -+ adap, client, -+ QUANTA_LY2_I2C_MUX_CMD_SET_CHANNEL, c); -+ data->last_chan = c; -+ } -+ -+ return ret; -+} -+ -+static int quanta_ly2_i2c_mux_release_chan(struct i2c_adapter *adap, -+ void *client, u32 chan) -+{ -+ struct quanta_ly2_i2c_mux *data = i2c_get_clientdata(client); -+ int ret = 0; -+ -+ ret = quanta_ly2_i2c_mux_reg_write( -+ adap, client, -+ QUANTA_LY2_I2C_MUX_CMD_SET_CHANNEL, 0); -+ data->last_chan = 0; -+ -+ return ret; -+} -+ -+static struct gpio_chip quanta_ly2_i2c_mux_gpio_chip = { -+ .label = "quanta_ly2_i2c_mux_gpio_chip", -+ .owner = THIS_MODULE, -+ .ngpio = QUANTA_LY2_I2C_MUX_NUM_READ_GPIOS + QUANTA_LY2_I2C_MUX_NUM_WRITE_GPIOS, -+ .base = -1, -+ .set = quanta_ly2_i2c_mux_gpio_set, -+ .get = quanta_ly2_i2c_mux_gpio_get, -+}; -+ -+static int quanta_ly2_i2c_mux_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct i2c_adapter *adap = client->adapter; -+ int chan; -+ struct quanta_ly2_i2c_mux *data; -+ int ret = -ENODEV; -+ -+ if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA)) -+ goto err; -+ -+ data = kzalloc(sizeof(struct quanta_ly2_i2c_mux), GFP_KERNEL); -+ if (!data) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ i2c_set_clientdata(client, data); -+ data->client = client; -+ -+ if (i2c_smbus_write_byte(client, 0) < 0) { -+ dev_warn(&client->dev, "probe failed\n"); -+ goto exit_free; -+ } -+ -+ i2c_lock_adapter(adap); -+ quanta_ly2_i2c_mux_release_chan(adap, client, 0); -+ i2c_unlock_adapter(adap); -+ -+ for (chan = 0; chan < QUANTA_LY2_I2C_MUX_NUM_CHANNELS; chan++) { -+ data->chan_adap[chan] = -+ i2c_add_mux_adapter(adap, &client->dev, client, -+ 0, chan, -+ quanta_ly2_i2c_mux_select_chan, -+ quanta_ly2_i2c_mux_release_chan); -+ -+ if (data->chan_adap[chan] == NULL) { -+ ret = -ENODEV; -+ dev_err(&client->dev, -+ "failed to register multiplexed adapter %d\n", -+ chan); -+ goto adap_reg_failed; -+ } -+ } -+ -+ dev_info(&client->dev, -+ "registered %d multiplexed buses for I2C mux %s\n", -+ chan, client->name); -+ -+ data->gpio_chip = quanta_ly2_i2c_mux_gpio_chip; -+ data->gpio_chip.dev = &client->dev; -+ data->gpio_write_val = 0xff; -+ -+ ret = gpiochip_add(&data->gpio_chip); -+ if (ret) { -+ dev_err(&client->dev, "failed to register GPIOs\n"); -+ goto adap_reg_failed; -+ } -+ -+ dev_info(&client->dev, -+ "registered GPIOs for I2C mux %s (%d read, %d write)\n", -+ client->name, -+ QUANTA_LY2_I2C_MUX_NUM_READ_GPIOS, -+ QUANTA_LY2_I2C_MUX_NUM_WRITE_GPIOS); -+ -+ return 0; -+ -+adap_reg_failed: -+ for (chan--; chan >= 0; chan--) -+ i2c_del_mux_adapter(data->chan_adap[chan]); -+ -+exit_free: -+ kfree(data); -+err: -+ return ret; -+} -+ -+static int quanta_ly2_i2c_mux_remove(struct i2c_client *client) -+{ -+ struct quanta_ly2_i2c_mux *data = i2c_get_clientdata(client); -+ int chan, ret; -+ -+ for (chan = 0; chan < QUANTA_LY2_I2C_MUX_NUM_CHANNELS; chan++) -+ if (data->chan_adap[chan]) { -+ ret = i2c_del_mux_adapter(data->chan_adap[chan]); -+ if (ret) -+ return ret; -+ data->chan_adap[chan] = NULL; -+ } -+ -+ ret = gpiochip_remove(&data->gpio_chip); -+ if (ret) -+ return ret; -+ -+ kfree(data); -+ return 0; -+} -+ -+static struct i2c_driver quanta_ly2_i2c_mux_driver = { -+ .driver = { -+ .name = "quanta_ly2_i2c_mux", -+ .owner = THIS_MODULE, -+ }, -+ .probe = quanta_ly2_i2c_mux_probe, -+ .remove = quanta_ly2_i2c_mux_remove, -+ .id_table = quanta_ly2_i2c_mux_id, -+}; -+ -+module_i2c_driver(quanta_ly2_i2c_mux_driver); -+ -+MODULE_AUTHOR("Big Switch Networks "); -+MODULE_DESCRIPTION("Quanta LY2 I2C multiplexer driver"); -+MODULE_LICENSE("GPL"); -diff -rupN a/drivers/net/tun.c b/drivers/net/tun.c ---- a/drivers/net/tun.c 2015-02-19 18:57:03.000000000 -0800 -+++ b/drivers/net/tun.c 2015-05-20 09:41:10.210631541 -0700 -@@ -74,7 +74,7 @@ - - #include - #include -- -+#include - /* Uncomment to enable debugging */ - /* #define TUN_DEBUG 1 */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-i2c-mux.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-i2c-mux.patch deleted file mode 100644 index a8141b8d..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-i2c-mux.patch +++ /dev/null @@ -1,303 +0,0 @@ -quanta-i2cmux: Driver for Quanta i2c mux - - drivers/i2c/muxes/Kconfig | 6 + - drivers/i2c/muxes/Makefile | 1 - drivers/i2c/muxes/quanta-i2cmux.c | 216 ++++++++++++++++++++++++++++++++++++++++ - include/linux/i2c/quanta-i2cmux.h | 17 +++ - 4 files changed, 240 insertions(+), 0 deletions(-) - create mode 100644 drivers/i2c/muxes/quanta-i2cmux.c - create mode 100644 include/linux/i2c/quanta-i2cmux.h - -diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig -index 2ee0386..73ed997 100644 ---- a/drivers/i2c/muxes/Kconfig -+++ b/drivers/i2c/muxes/Kconfig -@@ -43,4 +43,10 @@ config I2C_MUX_DNI_6448 - help - If you say yes here you get support for the DNI 6448 I2C Mux devices - -+config I2C_MUX_QUANTA -+ tristate "CumulusNetworks QUANTA I2C Mux" -+ depends on EXPERIMENTAL -+ help -+ If you say yes here you get support for the QUANTA I2C Mux devices -+ - endmenu -diff --git a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile -index e5bb944..7fbdd2f 100644 ---- a/drivers/i2c/muxes/Makefile -+++ b/drivers/i2c/muxes/Makefile -@@ -5,5 +5,6 @@ obj-$(CONFIG_I2C_MUX_GPIO) += gpio-i2cmux.o - obj-$(CONFIG_I2C_MUX_PCA9541) += pca9541.o - obj-$(CONFIG_I2C_MUX_PCA954x) += pca954x.o - obj-$(CONFIG_I2C_MUX_DNI_6448) += dni_6448_i2c_mux.o -+obj-$(CONFIG_I2C_MUX_QUANTA) += quanta-i2cmux.o - - ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG -diff --git a/drivers/i2c/muxes/quanta-i2cmux.c b/drivers/i2c/muxes/quanta-i2cmux.c -new file mode 100644 -index 0000000..498f6e7 ---- /dev/null -+++ b/drivers/i2c/muxes/quanta-i2cmux.c -@@ -0,0 +1,238 @@ -+/* -+ * I2C multiplexer for the quanta CPLD chips -+ * -+ * -+ * Copyright 2014 Cumulus Networks, inc all rights reserved -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define QUANTA_I2CMUX_MAX_NCHANS 32 -+ -+static const unsigned short quanta_sfp_address_list[] = { -+ 0x50, 0x51, I2C_CLIENT_END }; -+ -+enum quanta_i2cmux_type { -+ quanta_i2cmux_16, -+ quanta_i2cmux_32, -+}; -+ -+struct quanta_i2cmux { -+ enum quanta_i2cmux_type type; -+ struct i2c_adapter *virt_adaps[QUANTA_I2CMUX_MAX_NCHANS]; -+ u8 last_chan; /* last register value */ -+}; -+ -+/* Struct to hold private data for muxes */ -+struct chip_desc { -+ u8 nchans; -+}; -+ -+static const struct chip_desc chips[] = { -+ [quanta_i2cmux_16] = { -+ .nchans = 16, -+ }, -+ [quanta_i2cmux_32] = { -+ .nchans = 32, -+ }, -+}; -+ -+static const struct i2c_device_id quanta_i2cmux_id[] = { -+ { "quanta-i2cmux-16", quanta_i2cmux_16 }, -+ { "quanta-i2cmux-32", quanta_i2cmux_32 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, quanta_i2cmux_id); -+ -+static int quanta_i2cmux_reg_write(struct i2c_adapter *adap, -+ struct i2c_client *client, u8 command, u8 val) -+{ -+ int ret = -ENODEV; -+ -+ if (adap->algo->master_xfer) { -+ struct i2c_msg msg; -+ char buf[2]; -+ -+ msg.addr = client->addr; -+ msg.flags = 0; -+ msg.len = 2; -+ buf[0] = command; -+ buf[1] = val; -+ msg.buf = buf; -+ ret = adap->algo->master_xfer(adap, &msg, 1); -+ -+ } else { -+ union i2c_smbus_data data; -+ -+ data.byte = val; -+ ret = adap->algo->smbus_xfer(adap, client->addr, -+ client->flags, -+ I2C_SMBUS_WRITE, -+ command, I2C_SMBUS_BYTE_DATA, &data); -+ } -+ -+ return ret; -+} -+ -+static int quanta_i2cmux_select_chan(struct i2c_adapter *adap, -+ void *client, u32 chan) -+{ -+ struct quanta_i2cmux *data = i2c_get_clientdata(client); -+ const struct chip_desc *chip = &chips[data->type]; -+ u8 regval; -+ int ret = 0; -+ -+ /** -+ * The channel select register is 1-based, but our API to the -+ * world is 0-based. -+ */ -+ regval = chan + 1; -+ -+ /* Only select the channel if its different from the last channel */ -+ if (data->last_chan != regval) { -+ ret = quanta_i2cmux_reg_write(adap, client, -+ QUANTA_I2CMUX_CHANNEL_SELECT, regval); -+ data->last_chan = regval; -+ } -+ -+ return ret; -+} -+ -+static int quanta_i2cmux_deselect_mux(struct i2c_adapter *adap, -+ void *client, u32 chan) -+{ -+ struct quanta_i2cmux *data = i2c_get_clientdata(client); -+ -+ /* Deselect active channel */ -+ data->last_chan = 0; -+ return quanta_i2cmux_reg_write(adap, client, QUANTA_I2CMUX_CHANNEL_SELECT, -+ data->last_chan); -+} -+ -+static int quanta_i2cmux_client_detect(struct i2c_client *client, -+ struct i2c_board_info *info) -+{ -+ struct i2c_adapter *adap = client->adapter; -+ struct i2c_board_info tmp_info = { -+ I2C_BOARD_INFO("24c08", 0x50), -+ }; -+ union i2c_smbus_data dummy; -+ int err; -+ -+ err = i2c_smbus_xfer(adap, client->addr, 0, I2C_SMBUS_READ, 0, -+ I2C_SMBUS_BYTE, &dummy); -+ -+ memcpy(info->type, tmp_info.type, I2C_NAME_SIZE); -+ -+ return err; -+} -+ -+static int quanta_i2cmux_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); -+ struct quanta_i2cmux *data; -+ int num; -+ int ret = -ENODEV; -+ -+ if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) -+ goto err; -+ -+ data = kzalloc(sizeof(struct quanta_i2cmux), GFP_KERNEL); -+ if (!data) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ i2c_set_clientdata(client, data); -+ -+ if (i2c_smbus_write_byte(client, 0) < 0) { -+ dev_warn(&client->dev, "probe failed\n"); -+ goto exit_free; -+ } -+ -+ data->type = id->driver_data; -+ data->last_chan = 0; /* force the first selection */ -+ -+ /* Now create an adapter for each channel */ -+ for (num = 0; num < chips[data->type].nchans; num++) { -+ data->virt_adaps[num] = -+ i2c_add_mux_adapter(adap, &client->dev, client, -+ 0, num, -+ quanta_i2cmux_select_chan, -+ quanta_i2cmux_deselect_mux); -+ -+ if (data->virt_adaps[num] == NULL) { -+ ret = -ENODEV; -+ dev_err(&client->dev, -+ "failed to register multiplexed adapter" -+ " %d\n", num); -+ goto virt_reg_failed; -+ } -+ } -+ -+ dev_info(&client->dev, -+ "registered %d multiplexed busses for I2C mux %s\n", -+ num, client->name); -+ -+ return 0; -+ -+virt_reg_failed: -+ for (num--; num >= 0; num--) -+ i2c_del_mux_adapter(data->virt_adaps[num]); -+exit_free: -+ kfree(data); -+err: -+ return ret; -+} -+ -+static int quanta_i2cmux_remove(struct i2c_client *client) -+{ -+ struct quanta_i2cmux *data = i2c_get_clientdata(client); -+ int i, err; -+ -+ for (i = 0; i < chips[data->type].nchans; ++i) -+ if (data->virt_adaps[i]) { -+ err = i2c_del_mux_adapter(data->virt_adaps[i]); -+ if (err) -+ return err; -+ data->virt_adaps[i] = NULL; -+ } -+ -+ kfree(data); -+ return 0; -+} -+ -+static struct i2c_driver quanta_i2cmux_driver = { -+ .driver = { -+ .name = "quanta-i2cmux", -+ .owner = THIS_MODULE, -+ }, -+ .probe = quanta_i2cmux_probe, -+ .remove = quanta_i2cmux_remove, -+ .id_table = quanta_i2cmux_id, -+ .address_list = quanta_sfp_address_list, -+ .detect = quanta_i2cmux_client_detect, -+}; -+ -+static int __init quanta_i2cmux_init(void) -+{ -+ return i2c_add_driver(&quanta_i2cmux_driver); -+} -+ -+static void __exit quanta_i2cmux_exit(void) -+{ -+ i2c_del_driver(&quanta_i2cmux_driver); -+} -+ -+module_init(quanta_i2cmux_init); -+module_exit(quanta_i2cmux_exit); -+ -+MODULE_AUTHOR("Roopa Prabhu "); -+MODULE_DESCRIPTION("quanta I2C mux driver"); -+MODULE_LICENSE("GPL v2"); -diff --git a/include/linux/i2c/quanta-i2cmux.h b/include/linux/i2c/quanta-i2cmux.h -new file mode 100644 -index 0000000..042dcd2 ---- /dev/null -+++ b/include/linux/i2c/quanta-i2cmux.h -@@ -0,0 +1,17 @@ -+/* -+ * -+ * quanta-i2cmux.h - I2C multiplexer support -+ * -+ */ -+ -+ -+#ifndef _LINUX_QUANTA_I2CMUX_H -+#define _LINUX_QUANTA_I2CMUX_H -+ -+ -+/* Registers */ -+#define QUANTA_I2CMUX_INPUT_PRESENT 0x00 -+#define QUANTA_I2CMUX_OUTPUT_RESET 0x01 -+#define QUANTA_I2CMUX_CHANNEL_SELECT 0x02 -+ -+#endif /* _LINUX_QUANTA_I2CMUX_H */ diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-lb8.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-lb8.patch deleted file mode 100644 index b2b92d94..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-lb8.patch +++ /dev/null @@ -1,789 +0,0 @@ -#Copyright 2012 Cumulus Networks, Inc. All rights reserved. - -Add platform support for the Quanta LB8 48x10GE networking systems - -diff --git a/arch/powerpc/boot/dts/quanta_lb8.dts b/arch/powerpc/boot/dts/quanta_lb8.dts -new file mode 100644 -index 0000000..44f76fc ---- /dev/null -+++ b/arch/powerpc/boot/dts/quanta_lb8.dts -@@ -0,0 +1,446 @@ -+/* -+ * Quanta Computer LB8 Device Tree Source -+ * -+ * Copyright 2011, Cumulus Networks, LLC -+ * -+ * 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. -+ * -+ * IMPORTANT - This file contains the "desired" device-tree as well as a -+ * device-tree the mimics the one embedded in the FASTPATH -+ * u-boot. The desired device-tree is uncommented... mainly -+ * to facilitate memory for when we build a uboot that will -+ * accept an input DTB. The desired device tree is delimited -+ * by QUANTA_FASTPATH_HACK. -+ */ -+ -+/dts-v1/; -+/ { -+ model = "quanta,lb8"; -+ compatible = "quanta,lb8"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ aliases { -+ ethernet0 = &enet0; -+ serial0 = &serial0; -+ pcie0 = &pcie0; -+ fancontrol = &fancontrol; -+ }; -+ -+ chosen { -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x0 0x0>; // Filled by U-Boot -+ }; -+ -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ PowerPC,8548@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ d-cache-line-size = <32>; // 32 bytes -+ i-cache-line-size = <32>; // 32 bytes -+ d-cache-size = <0x8000>; // L1, 32K -+ i-cache-size = <0x8000>; // L1, 32K -+ timebase-frequency = <0>; -+ bus-frequency = <0>; -+ clock-frequency = <0>; -+ next-level-cache = <&L2>; -+ }; -+ }; -+ -+ soc8548@e0000000 { -+ device_type = "soc"; -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ bus-frequency = <0>; // Filled out by uboot. -+ ranges = <0x0000000 0xe0000000 0x00100000>; -+ reg = <0xe0000000 0x00100000>; // CCSRBAR -+ -+ memory-controller@2000 { -+ compatible = "fsl,mpc8548-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <18 2>; -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,mpc8548-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x80000>; // L2, 512K -+ interrupt-parent = <&mpic>; -+ interrupts = <16 2>; -+ }; -+ -+ mpic: pic@40000 { -+ interrupt-controller; -+ device_type = "open-pic"; -+ compatible = "chrp,open-pic"; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ built-in; -+ big-endian; -+ clock-frequency = <0>; -+ reg = <0x40000 0x40000>; -+ }; -+ -+ i2c@3000 { -+ device_type = "i2c"; -+ compatible = "fsl-i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x3000 0x100>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <43 2>; -+ dfsrr; -+/* power supply status pins, need to determine */ -+ pca9555@24 { -+ compatible = "nxp,pca9555"; -+ reg = <0x24>; -+ }; -+/* power supply status pins, need to determine */ -+ pca9555@25 { -+ compatible = "nxp,pca9555"; -+ reg = <0x25>; -+ }; -+ fancontrol: fan@2-cd { -+ compatible = "on,adt7463"; -+ reg = <0x2c>; -+ }; -+/* unused (on the board, but not connected) -+ fan@2e { -+ compatible = "on,adt7463"; -+ reg = <0x2e>; -+ }; -+*/ -+ config@52 { -+ compatible = "at,24c02"; -+ reg = <0x52>; -+ }; -+ spd@53 { -+ compatible = "at,spd"; -+ reg = <0x53>; -+ }; -+ eeprom@54 { -+ compatible = "at,24c02"; -+ reg = <0x54>; -+ label = "board_eeprom"; -+ read-only; -+ }; -+/* unknown (redundant power supply, likely an at24 type eeprom) -+ unknown@58 { -+ compatible = "cumulus,unknown"; -+ reg = <0x58>; -+ }; -+*/ -+/* unknown (redundant power supply, likely an at24 type eeprom) -+ unknown@59 { -+ compatible = "cumulus,unknown"; -+ reg = <0x59>; -+ }; -+*/ -+ rtc@68 { -+ compatible = "dallas,ds1338"; -+ reg = <0x68>; -+ }; -+ }; -+ -+ i2c@3100 { -+ device_type = "i2c"; -+ compatible = "fsl-i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x3100 0x100>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <43 2>; -+ dfsrr; -+/* quanta I2C mux CPLD for SFP+ on ports 1-16 */ -+ quanta-i2cmux@25 { -+ compatible = "cumulus,quanta-i2cmux-16"; -+ reg = <0x25>; -+ }; -+/* quanta I2C mux CPLD for SFP+ on ports 17-32 */ -+ quanta-i2cmux@26 { -+ compatible = "cumulus,quanta-i2cmux-16"; -+ reg = <0x26>; -+ }; -+/* quanta I2C mux CPLD for SFP+ on ports 33-48 */ -+ quanta-i2cmux@27 { -+ compatible = "cumulus,quanta-i2cmux-16"; -+ reg = <0x27>; -+ }; -+ }; -+ -+ serial0: serial@4500 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ cell-index = <0>; -+ clock-frequency = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <42 2>; -+ reg = <0x4500 0x100>; -+ }; -+ -+ enet0: ethernet@24000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ interrupt-parent = <&mpic>; -+ interrupts = <29 2 30 2 34 2>; -+ reg = <0x00024000 0x00001000>; -+ phy-handle = <&phy1>; -+ }; -+ -+ mdio@24520 { -+ device_type = "mdio"; -+ compatible = "fsl,gianfar-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x00024520 0x00000020>; -+ phy1: ethernet-phy@1 { -+ device_type = "ethernet-phy"; -+ reg = <1>; -+ }; -+ tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ global-utilities@e0000 { //global utilities block -+ compatible = "fsl,mpc8548-guts"; -+ reg = <0xe0000 0x1000>; -+ fsl,has-rstcr; -+ }; -+/* -+ crypto@30000 { -+ device_type = "cruypto"; -+ compatible = "fsl,sec2.1, talitos", "fsl,sec2.0, talitos"; -+ model = "SEC3"; -+ reg = <0x30000 0x10000>; -+ interrupts = <45 2>; -+ interrupt-parent = <&mpic>; -+ fsl,num-channels = <4>; -+ fsl,channel-fifo-len = <24>; -+ fsl,exec-units-mask = <0xfe>; -+ fsl,descriptor-types-mask = <0x12b0ebf>; -+ }; -+*/ -+/* Trident does not work with MSI -+ msi@41600 { -+ compatible = "fsl,mpic-msi"; -+ reg = <0x41600 0x80>; -+ msi-available-ranges = <0 0x100>; -+ interrupts = < -+ 0xe0 0 -+ 0xe1 0 -+ 0xe2 0 -+ 0xe3 0 -+ 0xe4 0 -+ 0xe5 0 -+ 0xe6 0 -+ 0xe7 0>; -+ interrupt-parent = <&mpic>; -+ }; -+*/ -+/* -+ dma@21300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8548-dma", "fsl,eloplus-dma"; -+ reg = <0x21300 0x4>; -+ ranges = <0x0 0x21100 0x200>; -+ cell-index = <0>; -+ dma-channel@0 { -+ compatible = "fsl,mpc8548-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <20 2>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,mpc8548-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <21 2>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,mpc8548-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupt-parent = <&mpic>; -+ interrupts = <22 2>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,mpc8548-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupt-parent = <&mpic>; -+ interrupts = <23 2>; -+ }; -+ }; -+*/ -+/* NOT USED -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <10>; -+ }; -+*/ -+/* -+ ecm@1000 { -+ compatible = "fsl,mpc8544-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2>; -+ interrupt-parent = <&mpic>; -+ }; -+*/ -+ }; -+/* -+ pci0: pci@e0008000 { -+ device_type = "pci"; -+ compatible = "fsl,mpc8540-pci"; -+ clock-frequency = <66666666>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ reg = <0xe0008000 0x1000>; -+ bus-range = <0 0>; -+ ranges = < -+ 0x2000000 0x0 0x80000000 0x80000000 0x0 0x10000000 -+ 0x1000000 0x0 0x00000000 0xe2000000 0x0 0x00800000 -+ >; -+ interrupt-parent = <&mpic>; -+ #interrupt-cells = <1>; -+ interrupts = <24 2>; -+ interrupt-map-mask = < -+ 0x0000f800 0x00000000 0x00000000 0x00000007 -+ >; -+ interrupt-map = < -+ // IDSEL 0x12 Slot 1 -+ 0x00009000 0x00000000 0x00000000 0x00000001 &mpic 0 1 -+ >; -+ }; -+*/ -+ pcie0: pcie@e000a000 { -+ device_type = "pci"; -+ compatible = "fsl,mpc8548-pcie"; -+ clock-frequency = <33333333>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ reg = <0xe000a000 0x00001000>; -+ bus-range = <0 255>; -+ ranges = < -+ 0x02000000 0x00000000 0xa0000000 0xa0000000 0x00000000 0x20000000 -+ 0x01000000 0x00000000 0x00000000 0xe3000000 0x00000000 0x00100000 -+ >; -+ interrupt-parent = <&mpic>; -+ #interrupt-cells = <1>; -+ interrupts = <10 2>; -+ interrupt-map-mask = < -+ 0x0000f800 0x00000000 0x00000000 0x00000007 -+ >; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0x00000000 0x00000000 0x00000000 0x00000001 &mpic 0 1 -+ 0x00000000 0x00000000 0x00000000 0x00000002 &mpic 1 1 -+ 0x00000000 0x00000000 0x00000000 0x00000003 &mpic 2 1 -+ 0x00000000 0x00000000 0x00000000 0x00000004 &mpic 3 1 -+ >; -+ }; -+ -+ localbus@0xe0005000 { -+ compatible = "fsl,pq3-localbus", "simple-bus"; -+ interrupt-parent = <&mpic>; -+ interrupts = <19 2>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ reg = <0xe0005000 0x1000>; -+ ranges = < -+ 0 0 0xfe000000 0x02000000 -+ 1 0 0xfc000000 0x02000000 -+ 2 0 0xf0000000 0x00020000 -+ 3 0 0xf0010000 0x00010000 -+ 4 0 0xf2000000 0x00100000 -+ 5 0 0xe0000000 0x00000002 -+ >; -+ -+ flash@0,0 { -+ compatible = "cfi-flash"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0 0 0x02000000>; -+ bank-width = <2>; -+ device-width = <2>; -+ partition@0 { -+ label = "system image"; -+ reg = <0x00000000 0x01f80000>; -+ }; -+ partition@2 { -+ label = "uboot-env"; -+ reg = <0x01f80000 0x00020000>; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ label = "uboot"; -+ reg = <0x01fa0000 0x00060000>; -+ }; -+ }; -+ -+ flash@1,0 { -+ compatible = "cfi-flash"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <1 0 0x02000000>; -+ bank-width = <2>; -+ device-width = <2>; -+ partition@0 { -+ label = "/var"; -+ reg = <0x00000000 0x01c00000>; -+ }; -+ partition@1 { -+ label = "/mnt/persist"; -+ reg = <0x01c00000 0x00400000>; -+ }; -+ }; -+/* -+ cfcard@2 { -+ compatible = "qci-ide"; -+ device_type = "ide"; -+ reg = < -+ 2 0 0x00020000 -+ 4 0 0x00100000 -+ >; -+ ioport_shift = <1>; -+ reg-shift = <1>; -+ #interrupt-cells = <1>; -+ interrupts = <2 2>; -+ interrupt-parent = <&mpic>; -+ }; -+*/ -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/quanta_lb8.c b/arch/powerpc/platforms/85xx/quanta_lb8.c -new file mode 100644 -index 0000000..329cf75 ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/quanta_lb8.c -@@ -0,0 +1,260 @@ -+/* -+ * quanta_lb8 setup and early boot code plus other random bits. -+ * -+ * Copyright 2012 Cumulus Networks, inc. -+ * -+ * Derived from mpc8548cds.c -+ * -+ * 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 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include "quanta_lb8.h" -+ -+/*------------------------------------------------------------------------------ -+ * -+ * General-Purpose IO -+ * -+ * Output Pins : PCI2_AD[15:8], GPOUT[24:31] -+ * Input Pins : PCI2_AD[7:0] -+ * -+ *------------------------------------------------------------------------------ -+ */ -+ -+enum quanta_lb8_gpio { -+ -+ GPIOCR_EN = 0x00030200, /* PCIout, PCIin, GPout */ -+ -+ GPOUTDR_DMA_RST_N = 0x00400000, /* PCI2_AD[14] - cpld reset */ -+ GPOUTDR_CF_RST_N = 0x00200000, /* PCI2_AD[13] - reset compact flash */ -+ GPOUTDR_CF_PWR_EN_N = 0x00100000, /* PCI2_AD[12] - compact flash power */ -+ GPOUTDR_LED_RST_N = 0x00080000, /* PCI2_AD[11] - led board reset */ -+ GPOUTDR_SYS_LED_N = 0x00040000, /* PCI2_AD[10] - system led */ -+ GPOUTDR_HW_RST_N = 0x00020000, /* PCI2_AD[9] - hard reset */ -+ GPOUTDR_CF_BUS_EN_N = 0x00010000, /* PCI2_AD[8] - compact flash enable */ -+ GPOUTDR_SW_RST_N = 0x00000080, /* GPOUT[24] - software reset */ -+ GPOUTDR_PLD1_RST_N = 0x00000040, /* GPOUT[25] - pld1 reset */ -+ GPOUTDR_PLD2_RST_N = 0x00000020, /* GPOUT[26] - pld2 reset */ -+ GPOUTDR_PLD3_RST_N = 0x00000010, /* GPOUT[27] - pld3 reset */ -+ GPOUTDR_PHY_RST = 0x00000002, /* GPOUT[30] - mgmt port phy reset */ -+ -+ GPINDR_CF_DET_0_N = 0x00040000, /* PCI2_AD[2] - compact flash present 0*/ -+ GPINDR_CF_DET_1_N = 0x00020000, /* PCI2_AD[1] - compact flash present 1*/ -+ GPINDR_CF_OC_DET_N = 0x00010000 /* PCI2_AD[0] - compact flash overcurrent */ -+}; -+ -+/*------------------------------------------------------------------------------ -+ * -+ * Platform specific functions -+ * -+ *------------------------------------------------------------------------------ -+ */ -+ -+static struct ccsr_guts_85xx __iomem *quanta_lb8_guts; -+ -+static void quanta_lb8_restart(char *cmd) -+{ -+ /* from MPC8548 spec */ -+ __be32 HRESET = 0x00000002; -+ -+ local_irq_disable(); -+ /* assert HW reset via internal register */ -+ setbits32(&quanta_lb8_guts->rstcr, HRESET); -+ /* assert HW reset via GPIO */ -+ clrbits32(&quanta_lb8_guts->gpoutdr, GPOUTDR_HW_RST_N); -+ while(1); -+} -+ -+static void __init quanta_lb8_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np = NULL; -+ -+ np = of_find_node_by_type(np, "open-pic"); -+ -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, -+ 0, 256, " OpenPIC "); -+ BUG_ON(mpic == NULL); -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+static void __init quanta_lb8_setup_arch(void) -+{ -+ struct device_node *np; -+ -+ if (ppc_md.progress) -+ ppc_md.progress("quanta_lb8_setup_arch()", 0); -+ -+ /* set the clock frequency */ -+ np = of_find_node_by_type(NULL, "cpu"); -+ if (np != 0) { -+ const unsigned int *fp; -+ -+ fp = of_get_property(np, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(np); -+ } -+ -+#ifdef CONFIG_PCI -+ /* setup PCI */ -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8540-pci") || -+ of_device_is_compatible(np, "85xx") || -+ of_device_is_compatible(np, "fsl,mpc8548-pcie")) { -+ struct resource rsrc; -+ of_address_to_resource(np, 0, &rsrc); -+ if ((rsrc.start & 0xfffff) == 0x8000) -+ fsl_add_bridge(np, 1); -+ else -+ fsl_add_bridge(np, 0); -+ } -+ } -+ -+ -+#endif -+ -+ /* map the global utilities register */ -+ printk(KERN_INFO "map MPC8548 global utilities register\n"); -+ np = of_find_compatible_node(NULL, NULL, "fsl,mpc8548-guts"); -+ if (!np) { -+ pr_err("%s: missing mpc8548 GUTs device node\n", -+ __func__); -+ return; -+ } -+ quanta_lb8_guts = of_iomap(np, 0); -+ -+ if (!quanta_lb8_guts) { -+ pr_err("%s: could not map mpc8548 GUTs register space\n", -+ __func__); -+ return; -+ } -+ -+ /* initialize powersave idle to be disabled */ -+ powersave_nap = 0; -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+ -+} -+ -+static void quanta_lb8_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu Pll setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init quanta_lb8_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "quanta,lb8")) { -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static struct of_device_id __initdata quanta_lb8_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ {}, -+}; -+ -+static int __init quanta_lb8_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, quanta_lb8_ids, NULL); -+} -+machine_device_initcall(quanta_lb8, quanta_lb8_publish_devices); -+ -+define_machine(quanta_lb8) { -+ .name = "Quanta Computer LB8", -+ .probe = quanta_lb8_probe, -+ .setup_arch = quanta_lb8_setup_arch, -+ .init_IRQ = quanta_lb8_pic_init, -+ .show_cpuinfo = quanta_lb8_show_cpuinfo, -+ .get_irq = mpic_get_irq, -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+ .power_save = e500_idle, -+ .restart = quanta_lb8_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; -diff --git a/arch/powerpc/platforms/85xx/quanta_lb8.h b/arch/powerpc/platforms/85xx/quanta_lb8.h -new file mode 100644 -index 0000000..6ba745a ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/quanta_lb8.h -@@ -0,0 +1,61 @@ -+/* -+ * Copyright 2012, Cumulus Networks, 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 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., 59 Temple Place, Suite 330, Boston, -+ * MA 02111-1307 USA -+ */ -+ -+/* -+ * General-Purpose Output Data Register (GPOUTDR) -+ * -+ * For GPOUTDR, need: -+ * GPOUT (GPOUTDR[0:7] corresponds to TSEC2_TXD[7:0]) : GPOUTDR[0:7] = 00000000 -+ * GPOUT (GPOUTDR[8:15] corresponds to PCI2_AD[15:8]) : GPOUTDR[8:15] = 11111111 -+ * Reserved : GPOUTDR[16:23] = 00000000 -+ * GPOUT : GPOUTDR[24:31] = 1000000 -+ * -+ * 0 4 8 12 16 20 24 28 -+ * 0000 0000 1111 1111 0000 0000 1000 0000 = 0x00FF0080 -+ * -+ * LB8 GPIO Signal : -+ * -+ * output : -+ * 0 GPOUTDR[8] <--> PCI2_AD[15] : N/A -+ * 1 GPOUTDR[9] <--> PCI2_AD[14] : DMA_RST_N (Reset CPLD, active low) -+ * 1 GPOUTDR[10] <--> PCI2_AD[13] : CF_RST_N (Reset Compact Flash card, active low) -+ * 0 GPOUTDR[11] <--> PCI2_AD[12] : CF_PWR_EN_N (Power enable for Compact Flash card, active low) -+ * 0 GPOUTDR[12] <--> PCI2_AD[11] : LED_RST_N (Reset LED board, active high) -+ * 0 GPOUTDR[13] <--> PCI2_AD[10] : LED_STATUS (The LED indicate system status, active low) -+ * 1 GPOUTDR[14] <--> PCI2_AD[9] : HW_RST_N (Hardware reset, active low) -+ * 0 GPOUTDR[15] <--> PCI2_AD[8] : CF_BUS_EN_N (Bus enable for Compact Flash card, active low) -+ * -+ * input : -+ * GPINDR[8] <--> PCI2_AD[7] : N/A -+ * GPINDR[9] <--> PCI2_AD[6] : N/A -+ * GPINDR[10] <--> PCI2_AD[5] : N/A -+ * GPINDR[11] <--> PCI2_AD[4] : N/A -+ * GPINDR[12] <--> PCI2_AD[3] : N/A -+ * GPINDR[13] <--> PCI2_AD[2] : CF_DET0 (Compact Flash card present 0, active low) -+ * GPINDR[14] <--> PCI2_AD[1] : CF_DET1 (Compact Flash card present 1, active low) -+ * GPINDR[15] <--> PCI2_AD[0] : CF_OC_N (Compact Flash card over-current detect active low) -+ * -+ * output : -+ * 1 GPOUTDR[24] <--> GPOUT[24] : SW_RST_N (Software reset, active low) -+ * 1 GPOUTDR[25] <--> GPOUT[25] : PLD1_RST_N (PLD1 reset signal, active low) -+ * 1 GPOUTDR[26] <--> GPOUT[26] : PLD2_RST_N (PLD2 reset signal, active low) -+ * 1 GPOUTDR[27] <--> GPOUT[27] : PLD3_RST_N (PLD3 reset signal, active low) -+ */ -+ -+#define QUANTA_LBX_GPIORST_N 0x00020000 diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-lb9.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-lb9.patch deleted file mode 100644 index 224334cc..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-lb9.patch +++ /dev/null @@ -1,762 +0,0 @@ -Quanta LB9 - -diff --git a/arch/powerpc/boot/dts/quanta_lb9.dts b/arch/powerpc/boot/dts/quanta_lb9.dts -new file mode 100644 -index 0000000..e92eb9c ---- /dev/null -+++ b/arch/powerpc/boot/dts/quanta_lb9.dts -@@ -0,0 +1,489 @@ -+/* -+ * Quanta LB9 Device Tree Source -+ * -+ * Copyright 2013 Cumulus Networks, Inc. -+ * Copyright 2006, 2008 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/; -+ -+/ { -+ model = "quanta,lb9"; -+ compatible = "quanta,lb9"; -+ reset-gpio = <&cpm_pio_a 24 1>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8541@0 { -+ device_type = "cpu"; -+ reg = <0x0>; -+ d-cache-line-size = <32>; // 32 bytes -+ i-cache-line-size = <32>; // 32 bytes -+ d-cache-size = <0x8000>; // L1, 32K -+ i-cache-size = <0x8000>; // L1, 32K -+ timebase-frequency = <0>; // 33 MHz, from uboot -+ bus-frequency = <0>; // 166 MHz -+ clock-frequency = <0>; // 825 MHz, from uboot -+ next-level-cache = <&L2>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ -+ mass_storage { -+ device = "sda"; -+ }; -+ -+ soc8541@e0000000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "simple-bus"; -+ ranges = <0x0 0xe0000000 0x100000>; -+ bus-frequency = <0>; -+ -+ ecm-law@0 { -+ compatible = "fsl,ecm-law"; -+ reg = <0x0 0x1000>; -+ fsl,num-laws = <8>; -+ }; -+ -+ ecm@1000 { -+ compatible = "fsl,mpc8541-ecm", "fsl,ecm"; -+ reg = <0x1000 0x1000>; -+ interrupts = <17 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ memory-controller@2000 { -+ compatible = "fsl,mpc8541-memory-controller"; -+ reg = <0x2000 0x1000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <18 2>; -+ }; -+ -+ L2: l2-cache-controller@20000 { -+ compatible = "fsl,mpc8541-l2-cache-controller"; -+ reg = <0x20000 0x1000>; -+ cache-line-size = <32>; // 32 bytes -+ cache-size = <0x40000>; // L2, 256K -+ interrupt-parent = <&mpic>; -+ interrupts = <16 2>; -+ }; -+ -+ I2C0: i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ fsl,preserve-clocking; -+ -+ rtc@68 { -+ compatible = "dallas,ds1339"; -+ reg = <0x68>; -+ }; -+ -+ board_eeprom@53 { -+ compatible = "at,24c02"; -+ reg = <0x53>; -+ label = "board_eeprom"; -+ }; -+ -+ spd@57 { -+ compatible = "at,spd"; -+ reg = <0x57>; -+ }; -+ -+ mux@70 { -+ compatible = "ti,pca9548"; -+ reg = <0x70>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ // 10G SFP+ 0 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port49"; -+ }; -+ }; -+ // 10G SFP+ 1 -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port50"; -+ }; -+ }; -+ // 10G SFP+ 2 -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port51"; -+ }; -+ }; -+ // 10G SFP+ 3 -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port52"; -+ }; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ fancontrol-fb@2C { -+ compatible = "on,adt7470"; -+ reg = <0x2C>; -+ label = "temp fan 1"; -+ disable-smbus-timeout; -+ }; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ fancontrol-fb@2F { -+ compatible = "on,adt7470"; -+ reg = <0x2F>; -+ label = "temp fan 2"; -+ disable-smbus-timeout; -+ }; -+ }; -+ }; -+ -+ pca9555@24 { -+ compatible = "nxp,pca9555"; -+ reg = <0x24>; -+ label = "PSU Status 1"; -+ }; -+ pca9555@25 { -+ compatible = "nxp,pca9555"; -+ reg = <0x25>; -+ label = "PSU Status 2"; -+ }; -+ pca9555@20 { -+ compatible = "nxp,pca9555"; -+ reg = <0x20>; -+ label = "8727"; -+ }; -+ }; -+ -+ dma@21300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8541-dma", "fsl,eloplus-dma"; -+ reg = <0x21300 0x4>; -+ ranges = <0x0 0x21100 0x200>; -+ cell-index = <0>; -+ dma-channel@0 { -+ compatible = "fsl,mpc8541-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ reg = <0x0 0x80>; -+ cell-index = <0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <20 2>; -+ }; -+ dma-channel@80 { -+ compatible = "fsl,mpc8541-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ reg = <0x80 0x80>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <21 2>; -+ }; -+ dma-channel@100 { -+ compatible = "fsl,mpc8541-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ reg = <0x100 0x80>; -+ cell-index = <2>; -+ interrupt-parent = <&mpic>; -+ interrupts = <22 2>; -+ }; -+ dma-channel@180 { -+ compatible = "fsl,mpc8541-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ reg = <0x180 0x80>; -+ cell-index = <3>; -+ interrupt-parent = <&mpic>; -+ interrupts = <23 2>; -+ }; -+ }; -+ -+ enet0: ethernet@24000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ cell-index = <0>; -+ device_type = "network"; -+ model = "TSEC"; -+ compatible = "gianfar"; -+ reg = <0x24000 0x1000>; -+ ranges = <0x0 0x24000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <29 2 30 2 34 2>; -+ interrupt-parent = <&mpic>; -+ phy-handle = <&phy0>; -+ -+ mdio@520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x520 0x20>; -+ -+ phy0: ethernet-phy@0 { -+ reg = <0x0>; -+ interrupt-parent = <&mpic>; -+ interrupts = <9 1>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ }; -+ -+ enet1: ethernet@25000 { -+ status = "disabled"; -+ }; -+ -+ serial0: serial@4500 { -+ cell-index = <0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ serial1: serial@4600 { -+ status = "disabled"; -+ cell-index = <1>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4600 0x100>; -+ clock-frequency = <0>; -+ interrupts = <42 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ crypto@30000 { -+ compatible = "fsl,sec2.0"; -+ reg = <0x30000 0x10000>; -+ interrupts = <45 2>; -+ interrupt-parent = <&mpic>; -+ fsl,num-channels = <4>; -+ fsl,channel-fifo-len = <24>; -+ fsl,exec-units-mask = <0x7e>; -+ fsl,descriptor-types-mask = <0x01010ebf>; -+ }; -+ -+ mpic: pic@40000 { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ reg = <0x40000 0x40000>; -+ compatible = "chrp,open-pic"; -+ device_type = "open-pic"; -+ }; -+ -+ cpm@919c0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8541-cpm", "fsl,cpm2"; -+ reg = <0x919c0 0x30>; -+ ranges; -+ -+ muram@80000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x0 0x80000 0x10000>; -+ -+ data@0 { -+ compatible = "fsl,cpm-muram-data"; -+ reg = <0x0 0x2000 0x9000 0x1000>; -+ }; -+ }; -+ -+ brg@919f0 { -+ compatible = "fsl,mpc8541-brg", -+ "fsl,cpm2-brg", -+ "fsl,cpm-brg"; -+ reg = <0x919f0 0x10 0x915f0 0x10>; -+ }; -+ -+ cpmpic: pic@90c00 { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <46 2>; -+ interrupt-parent = <&mpic>; -+ reg = <0x90c00 0x80>; -+ compatible = "fsl,mpc8541-cpm-pic", "fsl,cpm2-pic"; -+ }; -+ }; -+ -+ cpm_pio_a: gpio-controller@90d00 { -+ #gpio-cells = <2>; -+ compatible = "fsl,cpm2-pario-bank"; -+ reg = <0x90d00 0x14>; -+ gpio-controller; -+ }; -+ -+ cpm_pio_b: gpio-controller@90d20 { -+ #gpio-cells = <2>; -+ compatible = "fsl,cpm2-pario-bank"; -+ reg = <0x90d20 0x14>; -+ gpio-controller; -+ }; -+ -+ cpm_pio_c: gpio-controller@90d40 { -+ #gpio-cells = <2>; -+ compatible = "fsl,cpm2-pario-bank"; -+ reg = <0x90d40 0x14>; -+ gpio-controller; -+ }; -+ -+ cpm_pio_d: gpio-controller@90d60 { -+ #gpio-cells = <2>; -+ compatible = "fsl,cpm2-pario-bank"; -+ reg = <0x90d60 0x14>; -+ gpio-controller; -+ }; -+ }; -+ -+ pci0: pci@e0008000 { -+ interrupt-map-mask = <0x1f800 0x0 0x0 0x7>; -+ interrupt-map = <0x9000 0x0 0x0 0x1 &mpic 0x3 0x1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <24 2>; -+ bus-range = <0 0>; -+ ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000 -+ 0x1000000 0x0 0x0 0xe2000000 0x0 0x100000>; -+ clock-frequency = <66666666>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0xe0008000 0x1000>; -+ compatible = "fsl,mpc8540-pci"; -+ device_type = "pci"; -+ }; -+ -+ pci1: pci@e0009000 { -+ status = "disabled"; -+ }; -+ -+ localbus@e0005000 { -+ #address-cells = <0x2>; -+ #size-cells = <0x1>; -+ compatible = "fsl,mpc8541-localbus", "fsl,pq2-localbus", "simple-bus"; -+ reg = <0xe0005000 0x1000>; -+ ranges = <0x0 0x0 0xfe000000 0x2000000 -+ 0x1 0x0 0xfc000000 0x2000000 -+ 0x2 0x0 0xf0010000 0x10000 -+ 0x4 0x0 0xf2000000 0x100000 -+ 0x5 0x0 0xf0000000 0x10000>; -+ interrupt-parent = <&mpic>; -+ interrupts = <19 2>; -+ -+ nor@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x02000000>; -+ bank-width = <2>; -+ partition@0 { -+ /* Entire flash minus (u-boot + onie) */ -+ reg = <0x00000000 0x01b60000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x01b60000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x01f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ /* 512KB u-boot */ -+ reg = <0x01f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ -+ nor@1 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x1 0x0 0x02000000>; -+ bank-width = <2>; -+ partition@0 { -+ /* Entire 32MB */ -+ reg = <0x00000000 0x02000000>; -+ label = "open2"; -+ }; -+ }; -+ -+ cfcard@1 { -+ compatible = "ata-generic"; -+ device_type = "ide"; -+ reg = <0x5 0x0 0x10000 -+ 0x2 0x0 0x10000>; -+ port-width = <4>; -+ port-bswap; -+ /* XXX - broken at the moment, use poll mode -+ #interrupt-cells = <0x1>; -+ interrupts = <20 2>; -+ interrupt-parent = <&mpic>; -+ */ -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/quanta_lb9.c b/arch/powerpc/platforms/85xx/quanta_lb9.c -new file mode 100644 -index 0000000..9660990 ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/quanta_lb9.c -@@ -0,0 +1,259 @@ -+/* -+ * Quanta LB9 setup and early boot code plus other random bits. -+ * -+ * Copyright 2013 Cumulus Networks, Inc. -+ * Copyright 2005 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 -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+static unsigned int gpio_reset_handle; -+static bool gpio_reset_valid; -+ -+static int quanta_lb9_find_reset_gpio(unsigned int *handle) -+{ -+ struct device_node *gpio = NULL; -+ struct gpio_chip *gpiochip = NULL; -+ unsigned int gpio_handle = 0; -+ struct device_node *root; -+ enum of_gpio_flags flags; -+ const void *gpio_spec; -+ int rv; -+ -+ root = of_find_node_by_path("/"); -+ rv = of_parse_phandles_with_args(root, "reset-gpio", -+ "#gpio-cells", 0, &gpio, &gpio_spec); -+ if (rv < 0) { -+ printk(KERN_ERR "can't determine reset GPIO from device tree (/reset-gpio)\n"); -+ goto done; -+ } -+ -+ gpiochip = of_node_to_gpiochip(gpio); -+ if (!gpiochip) { -+ printk(KERN_ERR "gpio controller %s isn't registered\n", -+ gpio->full_name); -+ rv = -ENODEV; -+ goto done; -+ } -+ -+ gpio_handle = of_gpio_simple_xlate(gpiochip, root, gpio_spec, &flags); -+ if (gpio_handle < 0) { -+ rv = -ENODEV; -+ goto done; -+ } -+ -+ gpio_handle += gpiochip->base; -+ -+done: -+ if (gpio) { -+ of_node_put(gpio); -+ } -+ if (rv >= 0) { -+ *handle = gpio_handle; -+ } -+ return rv; -+} -+ -+static int __init quanta_lb9_reset_probe(void) -+{ -+ int rv; -+ -+ if (gpio_reset_valid) { -+ return 0; -+ } -+ -+ rv = quanta_lb9_find_reset_gpio(&gpio_reset_handle); -+ if (rv < 0) { -+ printk(KERN_ERR "GPIO reset unavailable\n"); -+ goto done; -+ } -+ -+ -+ rv = gpio_request(gpio_reset_handle, "reset"); -+ if (rv < 0) { -+ printk(KERN_ERR "GPIO reset pin unavailable\n"); -+ goto done; -+ } -+ -+ rv = gpio_direction_output(gpio_reset_handle, 1); -+ if (rv < 0) { -+ printk(KERN_ERR "Unable to set GPIO reset pin direction\n"); -+ goto done; -+ } -+ -+ printk(KERN_INFO "RESET: registered GPIO device: %d\n", gpio_reset_handle); -+ gpio_reset_valid = true; -+ -+done: -+ if (rv < 0) { -+ gpio_free(gpio_reset_handle); -+ gpio_reset_handle = 0; -+ } -+ return rv; -+} -+machine_device_initcall(quanta_lb9, quanta_lb9_reset_probe); -+ -+static void quanta_lb9_restart(char *cmd) -+{ -+ quanta_lb9_reset_probe(); -+ if (gpio_reset_handle) { -+ gpio_set_value(gpio_reset_handle, 0); -+ } else { -+ printk(KERN_ERR "RESET: GPIO not available, power off now.\n"); -+ } -+} -+ -+static void __init quanta_lb9_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np = NULL; -+ -+ np = of_find_node_by_type(np, "open-pic"); -+ -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, -+ 0, 256, " OpenPIC "); -+ BUG_ON(mpic == NULL); -+ -+ /* Return the mpic node */ -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+static void __init quanta_lb9_setup_arch(void) -+{ -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ -+ if (ppc_md.progress) -+ ppc_md.progress("quanta_lb9_setup_arch()", 0); -+ -+#ifdef CONFIG_PCI -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8540-pci") || -+ of_device_is_compatible(np, "fsl,mpc8548-pcie")) { -+ struct resource rsrc; -+ of_address_to_resource(np, 0, &rsrc); -+ if ((rsrc.start & 0xfffff) == 0x8000) -+ fsl_add_bridge(np, 1); -+ else -+ fsl_add_bridge(np, 0); -+ } -+ } -+#endif -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+} -+ -+static void quanta_lb9_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "Machine\t\t: Quanta LB9\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu Pll setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+} -+ -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init quanta_lb9_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ return of_flat_dt_is_compatible(root, "quanta,lb9"); -+} -+ -+static struct of_device_id __initdata of_bus_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ { .compatible = "gianfar", }, -+ {}, -+}; -+ -+static int __init declare_of_platform_devices(void) -+{ -+ return of_platform_bus_probe(NULL, of_bus_ids, NULL); -+} -+machine_device_initcall(quanta_lb9, declare_of_platform_devices); -+ -+define_machine(quanta_lb9) { -+ .name = "Quanta LB9", -+ .probe = quanta_lb9_probe, -+ .setup_arch = quanta_lb9_setup_arch, -+ .init_IRQ = quanta_lb9_pic_init, -+ .show_cpuinfo = quanta_lb9_show_cpuinfo, -+ .get_irq = mpic_get_irq, -+ .restart = quanta_lb9_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-ly2-ly2r.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-ly2-ly2r.patch deleted file mode 100644 index 1a54c44d..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-ly2-ly2r.patch +++ /dev/null @@ -1,1917 +0,0 @@ -Quanta LY2 Support - -diff --git a/arch/powerpc/boot/dts/quanta_ly2.dts b/arch/powerpc/boot/dts/quanta_ly2.dts -new file mode 100644 -index 0000000..dd6cd8e ---- /dev/null -+++ b/arch/powerpc/boot/dts/quanta_ly2.dts -@@ -0,0 +1,859 @@ -+/* -+ * Cumulus P2020 Device Tree Source -+ * -+ * Copyright 2012 Cumulus Networks, 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/ "p2020si.dtsi" -+ -+/ { -+ model = "quanta,ly2"; -+ compatible = "quanta,ly2"; -+ -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ -+ mass_storage { -+ device = "mmcblk0"; -+ }; -+ -+ localbus@ffe05000 { -+ compatible = "fsl,elbc", "simple-bus"; -+ ranges = <0x0 0x0 0x0 0xee000000 0x02000000 -+ 0x1 0x0 0x0 0xec000000 0x02000000>; -+ -+ nor@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x02000000>; -+ bank-width = <2>; -+ partition@0 { -+ /* Entire flash minus (u-boot + onie) */ -+ reg = <0x00000000 0x01b60000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x01b60000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x01f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ /* 512KB u-boot */ -+ reg = <0x01f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ -+ nor@1,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x1 0x0 0x02000000>; -+ bank-width = <2>; -+ partition@0 { -+ reg = <0x00000000 0x02000000>; -+ label = "not-used"; -+ }; -+ }; -+ }; -+ -+ soc@ffe00000 { -+ I2C0: i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ fsl,preserve-clocking; -+ rtc@68 { -+ compatible = "dallas,ds1339"; -+ reg = <0x68>; -+ }; -+ -+ mux@71 { -+ compatible = "ti,pca9546"; -+ reg = <0x71>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ /* -+ ** The eeprom utilities look for a label that -+ ** ends with "_eeprom". -+ */ -+ board_eeprom@54 { -+ compatible = "at,24c02"; -+ reg = <0x54>; -+ label = "board_eeprom"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ /* Cypress PSOC fan and temp controller */ -+ cypsoc: psoc@2e { -+ compatible = "CY8C3245"; -+ reg = <0x2e>; -+ label = "Cypress PSOC"; -+ }; -+ }; -+ }; -+ -+ mux@75 { -+ compatible = "ti,pca9546"; -+ reg = <0x75>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ psu1: psu@58 { -+ compatible = "at,24c02"; -+ reg = <0x58>; -+ label = "Redundant PSU 1"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ psu2: psu@59 { -+ compatible = "at,24c02"; -+ reg = <0x59>; -+ label = "Redundant PSU 2"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ pca9555@24 { -+ compatible = "nxp,pca9555"; -+ reg = <0x24>; -+ label = "PSU Status 1"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ pca9555@25 { -+ compatible = "nxp,pca9555"; -+ reg = <0x25>; -+ label = "PSU Status 2"; -+ }; -+ }; -+ }; -+ }; -+ -+ I2C1: i2c@3100 { -+ device_type = "i2c"; -+ compatible = "fsl-i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x3100 0x100>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <43 2>; -+ fsl,preserve-clocking; -+/* quanta I2C mux CPLD for SFP+ on ports 1-16 */ -+ mux@25 { -+ compatible = "cumulus,quanta-i2cmux-16"; -+ reg = <0x25>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ // SFP+ 1 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port1"; -+ }; -+ }; -+ // SFP+ 2 -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port2"; -+ }; -+ }; -+ // SFP+ 3 -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port3"; -+ }; -+ }; -+ // SFP+ 4 -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port4"; -+ }; -+ }; -+ // SFP+ 5 -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port5"; -+ }; -+ }; -+ // SFP+ 6 -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port6"; -+ }; -+ }; -+ // SFP+ 7 -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port7"; -+ }; -+ }; -+ // SFP+ 8 -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port8"; -+ }; -+ }; -+ // SFP+ 9 -+ i2c@8 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port9"; -+ }; -+ }; -+ // SFP+ 10 -+ i2c@9 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port10"; -+ }; -+ }; -+ // SFP+ 11 -+ i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port11"; -+ }; -+ }; -+ // SFP+ 12 -+ i2c@11 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port12"; -+ }; -+ }; -+ // SFP+ 13 -+ i2c@12 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port13"; -+ }; -+ }; -+ // SFP+ 14 -+ i2c@13 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port14"; -+ }; -+ }; -+ // SFP+ 15 -+ i2c@14 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port15"; -+ }; -+ }; -+ // SFP+ 16 -+ i2c@15 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port16"; -+ }; -+ }; -+ }; -+/* quanta I2C mux CPLD for SFP+ on ports 17-32 */ -+ mux@26 { -+ compatible = "cumulus,quanta-i2cmux-16"; -+ reg = <0x26>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ // SFP+ 17 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port17"; -+ }; -+ }; -+ // SFP+ 18 -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port18"; -+ }; -+ }; -+ // SFP+ 19 -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port19"; -+ }; -+ }; -+ // SFP+ 20 -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port20"; -+ }; -+ }; -+ // SFP+ 21 -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port21"; -+ }; -+ }; -+ // SFP+ 22 -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port22"; -+ }; -+ }; -+ // SFP+ 23 -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port23"; -+ }; -+ }; -+ // SFP+ 24 -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port24"; -+ }; -+ }; -+ // SFP+ 25 -+ i2c@8 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port25"; -+ }; -+ }; -+ // SFP+ 26 -+ i2c@9 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port26"; -+ }; -+ }; -+ // SFP+ 27 -+ i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port27"; -+ }; -+ }; -+ // SFP+ 28 -+ i2c@11 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port28"; -+ }; -+ }; -+ // SFP+ 29 -+ i2c@12 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port29"; -+ }; -+ }; -+ // SFP+ 30 -+ i2c@13 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port30"; -+ }; -+ }; -+ // SFP+ 31 -+ i2c@14 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port31"; -+ }; -+ }; -+ // SFP+ 32 -+ i2c@15 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port32"; -+ }; -+ }; -+ }; -+/* quanta I2C mux CPLD for SFP+ on ports 33-48 */ -+ mux@27 { -+ compatible = "cumulus,quanta-i2cmux-16"; -+ reg = <0x27>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ // SFP+ 33 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port33"; -+ }; -+ }; -+ // SFP+ 34 -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port34"; -+ }; -+ }; -+ // SFP+ 35 -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port35"; -+ }; -+ }; -+ // SFP+ 36 -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port36"; -+ }; -+ }; -+ // SFP+ 37 -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port37"; -+ }; -+ }; -+ // SFP+ 38 -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port38"; -+ }; -+ }; -+ // SFP+ 39 -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port39"; -+ }; -+ }; -+ // SFP+ 40 -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port40"; -+ }; -+ }; -+ // SFP+ 41 -+ i2c@8 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port41"; -+ }; -+ }; -+ // SFP+ 42 -+ i2c@9 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port42"; -+ }; -+ }; -+ // SFP+ 43 -+ i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port43"; -+ }; -+ }; -+ // SFP+ 44 -+ i2c@11 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port44"; -+ }; -+ }; -+ // SFP+ 45 -+ i2c@12 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port45"; -+ }; -+ }; -+ // SFP+ 46 -+ i2c@13 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port46"; -+ }; -+ }; -+ // SFP+ 47 -+ i2c@14 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port47"; -+ }; -+ }; -+ // SFP+ 48 -+ i2c@15 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port48"; -+ }; -+ }; -+ }; -+ -+ mux@73 { -+ compatible = "ti,pca9546"; -+ reg = <0x73>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ // QSFP+ 1 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port49"; -+ }; -+ }; -+ // QSFP+ 2 -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port50"; -+ }; -+ }; -+ // QSFP+ 3 -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port51"; -+ }; -+ }; -+ // QSFP+ 4 -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port52"; -+ }; -+ }; -+ }; -+ }; -+ -+ usb@22000 { -+ status = "disabled"; -+ }; -+ -+ mdio@24520 { -+ phy0: ethernet-phy@1 { -+ interrupt-parent = <&mpic>; -+ interrupts = <3 1>; -+ reg = <0x1>; -+ }; -+ }; -+ -+ enet0: ethernet@24000 { -+ phy-handle = <&phy0>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ enet1: ethernet@25000 { -+ status = "disabled"; -+ }; -+ -+ enet2: ethernet@26000 { -+ status = "disabled"; -+ }; -+ }; -+ -+ pci0: pcie@ffe08000 { -+ status = "disabled"; -+ }; -+ -+ pci1: pcie@ffe09000 { -+ status = "disabled"; -+ }; -+ -+ pci2: pcie@ffe0a000 { -+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 -+ >; -+ -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xc0000000 -+ 0x2000000 0x0 0xc0000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/quanta_ly2r.dts b/arch/powerpc/boot/dts/quanta_ly2r.dts -new file mode 100644 -index 0000000..9cc1040 ---- /dev/null -+++ b/arch/powerpc/boot/dts/quanta_ly2r.dts -@@ -0,0 +1,805 @@ -+/* -+ * Quanta LY2R Device Tree Source -+ * -+ * Copyright 2014 Cumulus Networks, 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/ "p2020si.dtsi" -+ -+/ { -+ model = "quanta,ly2r"; -+ compatible = "quanta,ly2r"; -+ -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ -+ mass_storage { -+ device = "mmcblk0"; -+ }; -+ -+ localbus@ffe05000 { -+ compatible = "fsl,elbc", "simple-bus"; -+ ranges = <0x0 0x0 0x0 0xec000000 0x04000000 -+ 0x1 0x0 0x0 0xe8000000 0x04000000>; -+ -+ nor@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x04000000>; -+ bank-width = <2>; -+ partition@0 { -+ /* Entire flash minus (u-boot + onie) */ -+ reg = <0x00000000 0x03b60000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x03b60000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x03f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ /* 512KB u-boot */ -+ reg = <0x03f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ -+ nor@1,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x1 0x0 0x04000000>; -+ bank-width = <2>; -+ partition@0 { -+ reg = <0x00000000 0x04000000>; -+ label = "open2"; -+ }; -+ }; -+ }; -+ -+ soc@ffe00000 { -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ fsl,preserve-clocking; -+ -+ rtc@68 { -+ compatible = "dallas,ds1338"; -+ reg = <0x68>; -+ }; -+ board_eeprom@54 { -+ compatible = "at,24c02"; -+ reg = <0x54>; -+ label = "board_eeprom"; -+ }; -+ /* Cypress PSOC fan and temp controller */ -+ cypsoc: psoc@2e { -+ compatible = "CY8C3245"; -+ reg = <0x2e>; -+ label = "Cypress PSOC"; -+ }; -+ pca9555@26 { -+ compatible = "nxp,pca9555"; -+ reg = <0x26>; -+ label = "Fan Status and CPLD"; -+ }; -+ mux@75 { -+ compatible = "ti,pca9546"; -+ reg = <0x75>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ psu1: psu@58 { -+ compatible = "at,24c02"; -+ reg = <0x58>; -+ label = "Redundant PSU 1"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ psu2: psu@59 { -+ compatible = "at,24c02"; -+ reg = <0x59>; -+ label = "Redundant PSU 2"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ pca9555@24 { -+ compatible = "nxp,pca9555"; -+ reg = <0x24>; -+ label = "PSU Control 1"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ pca9555@25 { -+ compatible = "nxp,pca9555"; -+ reg = <0x25>; -+ label = "PSU Control 2"; -+ }; -+ }; -+ }; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ fsl,preserve-clocking; -+ pca9698@21 { -+ compatible = "nxp,pca9698"; -+ reg = <0x21>; -+ label = "QSFP+ I/O Expander"; -+ }; -+ mux@72 { -+ compatible = "ti,pca9546"; -+ reg = <0x72>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ mux@38 { -+ compatible = "cumulus,quanta-i2cmux-32"; -+ reg = <0x38>; -+ label = "CPLD 1, I2C expander SFP+ 1-32"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ // SFP+ 1 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port1"; -+ }; -+ }; -+ i2c@1{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port2"; -+ }; -+ }; -+ i2c@2{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port3"; -+ }; -+ }; -+ i2c@3{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port4"; -+ }; -+ }; -+ i2c@4{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port5"; -+ }; -+ }; -+ i2c@5{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port6"; -+ }; -+ }; -+ i2c@6{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port7"; -+ }; -+ }; -+ i2c@7{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port8"; -+ }; -+ }; -+ i2c@8{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port9"; -+ }; -+ }; -+ i2c@9{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port10"; -+ }; -+ }; -+ i2c@10{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port11"; -+ }; -+ }; -+ i2c@11{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port12"; -+ }; -+ }; -+ i2c@12{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port13"; -+ }; -+ }; -+ i2c@13{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port14"; -+ }; -+ }; -+ i2c@14{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port15"; -+ }; -+ }; -+ i2c@15{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port16"; -+ }; -+ }; -+ i2c@16{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <16>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port17"; -+ }; -+ }; -+ i2c@17{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <17>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port18"; -+ }; -+ }; -+ i2c@18{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <18>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port19"; -+ }; -+ }; -+ i2c@19{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <19>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port20"; -+ }; -+ }; -+ i2c@20{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <20>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port21"; -+ }; -+ }; -+ i2c@21{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <21>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port22"; -+ }; -+ }; -+ i2c@22{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <22>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port23"; -+ }; -+ }; -+ i2c@23{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <23>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port24"; -+ }; -+ }; -+ i2c@24{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <24>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port25"; -+ }; -+ }; -+ i2c@25{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <25>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port26"; -+ }; -+ }; -+ i2c@26{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <26>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port27"; -+ }; -+ }; -+ i2c@27{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <27>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port28"; -+ }; -+ }; -+ i2c@28{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <28>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port29"; -+ }; -+ }; -+ i2c@29{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <29>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port30"; -+ }; -+ }; -+ i2c@30{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <30>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port31"; -+ }; -+ }; -+ i2c@31{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <31>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port32"; -+ }; -+ }; -+ }; -+ mux@39 { -+ compatible = "cumulus,quanta-i2cmux-32"; -+ reg = <0x39>; -+ label = "CPLD 2, I2C expander SFP+ 33-48"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ // SFP+ 33 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port33"; -+ }; -+ }; -+ i2c@1{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port34"; -+ }; -+ }; -+ i2c@2{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port35"; -+ }; -+ }; -+ i2c@3{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port36"; -+ }; -+ }; -+ i2c@4{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port37"; -+ }; -+ }; -+ i2c@5{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port38"; -+ }; -+ }; -+ i2c@6{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port39"; -+ }; -+ }; -+ i2c@7{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port40"; -+ }; -+ }; -+ i2c@8{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port41"; -+ }; -+ }; -+ i2c@9{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port42"; -+ }; -+ }; -+ i2c@10{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port43"; -+ }; -+ }; -+ i2c@11{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port44"; -+ }; -+ }; -+ i2c@12{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port45"; -+ }; -+ }; -+ i2c@13{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port46"; -+ }; -+ }; -+ i2c@14{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port47"; -+ }; -+ }; -+ i2c@15{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port48"; -+ }; -+ }; -+ i2c@16{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <16>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port49"; -+ }; -+ }; -+ i2c@17{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <17>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port50"; -+ }; -+ }; -+ i2c@18{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <18>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port51"; -+ }; -+ }; -+ i2c@19{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <19>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port52"; -+ }; -+ }; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ }; -+ }; -+ }; -+ -+ usb@22000 { -+ dr_mode = "host"; -+ phy_type = "ulpi"; -+ }; -+ -+ serial1: serial@4600 { -+ status = "disabled"; -+ }; -+ -+ mdio@24520 { -+ phy0: ethernet-phy@1 { -+ reg = <0x1>; -+ }; -+ }; -+ -+ enet0: ethernet@24000 { -+ phy-handle = <&phy0>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ enet1: ethernet@25000 { -+ status = "disabled"; -+ }; -+ -+ enet2: ethernet@26000 { -+ status = "disabled"; -+ }; -+ }; -+ -+ pci0: pcie@ffe08000 { -+ status = "disabled"; -+ }; -+ -+ pci1: pcie@ffe09000 { -+ status = "disabled"; -+ }; -+ -+ pci2: pcie@ffe0a000 { -+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 -+ >; -+ -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xc0000000 -+ 0x2000000 0x0 0xc0000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/quanta_ly2_ly2r.c b/arch/powerpc/platforms/85xx/quanta_ly2_ly2r.c -new file mode 100644 -index 0000000..aa24951 ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/quanta_ly2_ly2r.c -@@ -0,0 +1,233 @@ -+/* -+ * Copyright 2014 Cumulus Networks, Inc. -+ * -+ * LY2 setup and early boot code plus other random bits. -+ * -+ * 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 -+#include -+#include -+ -+#include -+#include -+ -+#undef DEBUG -+ -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+/******************************************************************************* -+ * -+ * Platform initialization functions -+ * -+ ******************************************************************************* -+*/ -+ -+/* -+ * Initialize the interrupt controller -+ */ -+static void __init quanta_ly2_ly2r_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np; -+ -+ np = of_find_node_by_type(NULL, "open-pic"); -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | -+ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | -+ MPIC_SINGLE_DEST_CPU, -+ 0, 256, " OpenPIC "); -+ -+ BUG_ON(mpic == NULL); -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+#ifdef CONFIG_SMP -+extern void __init mpc85xx_smp_init(void); -+#endif -+ -+static void __init quanta_ly2_ly2r_setup_arch(void) -+{ -+ struct device_node *cpu; -+ const unsigned int *fp; -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ -+ if (ppc_md.progress) -+ ppc_md.progress("quanta_ly2_ly2r_setup_arch()", 0); -+ -+ cpu = of_find_node_by_type(NULL, "cpu"); -+ if (cpu != 0) { -+ fp = of_get_property(cpu, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(cpu); -+ } -+ -+#ifdef CONFIG_PCI -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8548-pcie")) -+ fsl_add_bridge(np, 0); -+ } -+#endif -+ -+#ifdef CONFIG_SMP -+ mpc85xx_smp_init(); -+#endif -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+ -+ printk(KERN_INFO "Quanta LY2 & LY2R from Quanta Computer, Inc.\n"); -+} -+ -+ -+ -+static struct of_device_id __initdata quanta_ly2_ly2r_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ { .compatible = "gianfar", }, -+ {}, -+}; -+ -+ -+ -+static int __init quanta_ly2_ly2r_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, quanta_ly2_ly2r_ids, NULL); -+} -+machine_device_initcall(quanta_ly2, quanta_ly2_ly2r_publish_devices); -+machine_device_initcall(quanta_ly2r, quanta_ly2_ly2r_publish_devices); -+ -+static void quanta_ly2_ly2r_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu PLL setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init quanta_ly2_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "quanta,ly2")) -+ return 1; -+ -+ return 0; -+} -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init quanta_ly2r_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "quanta,ly2r")) -+ return 1; -+ -+ return 0; -+} -+ -+void quanta_ly2_ly2r_restart(char *cmd) -+{ -+ // asserts HRESET_REQ which will work on new hardware -+ printk(KERN_INFO "HRESET_REQ\n"); -+ fsl_rstcr_restart(cmd); -+} -+ -+define_machine(quanta_ly2) { -+ .name = "Quanta Computer, Inc. LY2", -+ .probe = quanta_ly2_probe, -+ .setup_arch = quanta_ly2_ly2r_setup_arch, -+ .init_IRQ = quanta_ly2_ly2r_pic_init, -+ .show_cpuinfo = quanta_ly2_ly2r_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = quanta_ly2_ly2r_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; -+ -+define_machine(quanta_ly2r) { -+ .name = "Quanta Computer, Inc. LY2R", -+ .probe = quanta_ly2r_probe, -+ .setup_arch = quanta_ly2_ly2r_setup_arch, -+ .init_IRQ = quanta_ly2_ly2r_pic_init, -+ .show_cpuinfo = quanta_ly2_ly2r_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = quanta_ly2_ly2r_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-ly2.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-ly2.patch deleted file mode 100644 index fbc25269..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-ly2.patch +++ /dev/null @@ -1,1768 +0,0 @@ -Quanta LY2 Support - -diff --git a/arch/powerpc/boot/dts/quanta_ly2.dts b/arch/powerpc/boot/dts/quanta_ly2.dts -new file mode 100644 -index 0000000..80fd639 ---- /dev/null -+++ b/arch/powerpc/boot/dts/quanta_ly2.dts -@@ -0,0 +1,859 @@ -+/* -+ * Cumulus P2020 Device Tree Source -+ * -+ * Copyright 2012 Cumulus Networks, 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/ "p2020si.dtsi" -+ -+/ { -+ model = "quanta,ly2"; -+ compatible = "quanta,ly2"; -+ -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ -+ mass_storage { -+ device = "mmcblk0"; -+ }; -+ -+ localbus@ffe05000 { -+ compatible = "fsl,elbc", "simple-bus"; -+ ranges = <0x0 0x0 0x0 0xee000000 0x02000000 -+ 0x1 0x0 0x0 0xec000000 0x02000000>; -+ -+ nor@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x02000000>; -+ bank-width = <2>; -+ partition@0 { -+ /* Entire flash minus (u-boot + onie) */ -+ reg = <0x00000000 0x01b60000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x01b60000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x01f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ /* 512KB u-boot */ -+ reg = <0x01f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ -+ nor@1,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x1 0x0 0x02000000>; -+ bank-width = <2>; -+ partition@0 { -+ reg = <0x00000000 0x02000000>; -+ label = "not-used"; -+ }; -+ }; -+ }; -+ -+ soc@ffe00000 { -+ I2C0: i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ fsl,preserve-clocking; -+ rtc@68 { -+ compatible = "dallas,ds1339"; -+ reg = <0x68>; -+ }; -+ -+ mux@71 { -+ compatible = "ti,pca9546"; -+ reg = <0x71>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ /* -+ ** The eeprom utilities look for a label that -+ ** ends with "_eeprom". -+ */ -+ board_eeprom@54 { -+ compatible = "at,24c02"; -+ reg = <0x54>; -+ label = "board_eeprom"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ /* Cypress PSOC fan and temp controller */ -+ cypsoc: psoc@2e { -+ compatible = "CY8C3245"; -+ reg = <0x2e>; -+ label = "Cypress PSOC"; -+ }; -+ }; -+ }; -+ -+ mux@75 { -+ compatible = "ti,pca9546"; -+ reg = <0x75>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ psu1: psu@58 { -+ compatible = "at,24c02"; -+ reg = <0x58>; -+ label = "Redundant PSU 1"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ psu2: psu@59 { -+ compatible = "at,24c02"; -+ reg = <0x59>; -+ label = "Redundant PSU 2"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ pca9555@24 { -+ compatible = "nxp,pca9555"; -+ reg = <0x24>; -+ label = "PSU Status 1"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ pca9555@25 { -+ compatible = "nxp,pca9555"; -+ reg = <0x25>; -+ label = "PSU Status 2"; -+ }; -+ }; -+ }; -+ }; -+ -+ I2C1: i2c@3100 { -+ device_type = "i2c"; -+ compatible = "fsl-i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x3100 0x100>; -+ cell-index = <1>; -+ interrupt-parent = <&mpic>; -+ interrupts = <43 2>; -+ fsl,preserve-clocking; -+/* quanta I2C mux CPLD for SFP+ on ports 1-16 */ -+ mux@25 { -+ compatible = "cumulus,quanta-i2cmux"; -+ reg = <0x25>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ // SFP+ 1 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port1"; -+ }; -+ }; -+ // SFP+ 2 -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port2"; -+ }; -+ }; -+ // SFP+ 3 -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port3"; -+ }; -+ }; -+ // SFP+ 4 -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port4"; -+ }; -+ }; -+ // SFP+ 5 -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port5"; -+ }; -+ }; -+ // SFP+ 6 -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port6"; -+ }; -+ }; -+ // SFP+ 7 -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port7"; -+ }; -+ }; -+ // SFP+ 8 -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port8"; -+ }; -+ }; -+ // SFP+ 9 -+ i2c@8 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port9"; -+ }; -+ }; -+ // SFP+ 10 -+ i2c@9 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port10"; -+ }; -+ }; -+ // SFP+ 11 -+ i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port11"; -+ }; -+ }; -+ // SFP+ 12 -+ i2c@11 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port12"; -+ }; -+ }; -+ // SFP+ 13 -+ i2c@12 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port13"; -+ }; -+ }; -+ // SFP+ 14 -+ i2c@13 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port14"; -+ }; -+ }; -+ // SFP+ 15 -+ i2c@14 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port15"; -+ }; -+ }; -+ // SFP+ 16 -+ i2c@15 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port16"; -+ }; -+ }; -+ }; -+/* quanta I2C mux CPLD for SFP+ on ports 17-32 */ -+ mux@26 { -+ compatible = "cumulus,quanta-i2cmux"; -+ reg = <0x26>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ // SFP+ 17 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port17"; -+ }; -+ }; -+ // SFP+ 18 -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port18"; -+ }; -+ }; -+ // SFP+ 19 -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port19"; -+ }; -+ }; -+ // SFP+ 20 -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port20"; -+ }; -+ }; -+ // SFP+ 21 -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port21"; -+ }; -+ }; -+ // SFP+ 22 -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port22"; -+ }; -+ }; -+ // SFP+ 23 -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port23"; -+ }; -+ }; -+ // SFP+ 24 -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port24"; -+ }; -+ }; -+ // SFP+ 25 -+ i2c@8 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port25"; -+ }; -+ }; -+ // SFP+ 26 -+ i2c@9 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port26"; -+ }; -+ }; -+ // SFP+ 27 -+ i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port27"; -+ }; -+ }; -+ // SFP+ 28 -+ i2c@11 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port28"; -+ }; -+ }; -+ // SFP+ 29 -+ i2c@12 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port29"; -+ }; -+ }; -+ // SFP+ 30 -+ i2c@13 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port30"; -+ }; -+ }; -+ // SFP+ 31 -+ i2c@14 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port31"; -+ }; -+ }; -+ // SFP+ 32 -+ i2c@15 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port32"; -+ }; -+ }; -+ }; -+/* quanta I2C mux CPLD for SFP+ on ports 33-48 */ -+ mux@27 { -+ compatible = "cumulus,quanta-i2cmux"; -+ reg = <0x27>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ // SFP+ 33 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port33"; -+ }; -+ }; -+ // SFP+ 34 -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port34"; -+ }; -+ }; -+ // SFP+ 35 -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port35"; -+ }; -+ }; -+ // SFP+ 36 -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port36"; -+ }; -+ }; -+ // SFP+ 37 -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port37"; -+ }; -+ }; -+ // SFP+ 38 -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port38"; -+ }; -+ }; -+ // SFP+ 39 -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port39"; -+ }; -+ }; -+ // SFP+ 40 -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port40"; -+ }; -+ }; -+ // SFP+ 41 -+ i2c@8 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port41"; -+ }; -+ }; -+ // SFP+ 42 -+ i2c@9 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port42"; -+ }; -+ }; -+ // SFP+ 43 -+ i2c@10 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port43"; -+ }; -+ }; -+ // SFP+ 44 -+ i2c@11 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port44"; -+ }; -+ }; -+ // SFP+ 45 -+ i2c@12 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port45"; -+ }; -+ }; -+ // SFP+ 46 -+ i2c@13 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port46"; -+ }; -+ }; -+ // SFP+ 47 -+ i2c@14 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port47"; -+ }; -+ }; -+ // SFP+ 48 -+ i2c@15 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port48"; -+ }; -+ }; -+ }; -+ -+ mux@73 { -+ compatible = "ti,pca9546"; -+ reg = <0x73>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ // QSFP+ 1 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port49"; -+ }; -+ }; -+ // QSFP+ 2 -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port50"; -+ }; -+ }; -+ // QSFP+ 3 -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port51"; -+ }; -+ }; -+ // QSFP+ 4 -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port52"; -+ }; -+ }; -+ }; -+ }; -+ -+ usb@22000 { -+ status = "disabled"; -+ }; -+ -+ mdio@24520 { -+ phy0: ethernet-phy@1 { -+ interrupt-parent = <&mpic>; -+ interrupts = <3 1>; -+ reg = <0x1>; -+ }; -+ }; -+ -+ enet0: ethernet@24000 { -+ phy-handle = <&phy0>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ enet1: ethernet@25000 { -+ status = "disabled"; -+ }; -+ -+ enet2: ethernet@26000 { -+ status = "disabled"; -+ }; -+ }; -+ -+ pci0: pcie@ffe08000 { -+ status = "disabled"; -+ }; -+ -+ pci1: pcie@ffe09000 { -+ status = "disabled"; -+ }; -+ -+ pci2: pcie@ffe0a000 { -+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 -+ >; -+ -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xc0000000 -+ 0x2000000 0x0 0xc0000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/boot/dts/quanta_ly2r.dts b/arch/powerpc/boot/dts/quanta_ly2r.dts -new file mode 100644 -index 0000000..1bb78ec ---- /dev/null -+++ b/arch/powerpc/boot/dts/quanta_ly2r.dts -@@ -0,0 +1,656 @@ -+/* -+ * Quanta LY2R Device Tree Source -+ * -+ * Copyright 2014 Cumulus Networks, 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/ "p2020si.dtsi" -+ -+/ { -+ model = "quanta,ly2r"; -+ compatible = "quanta,ly2r"; -+ -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ -+ mass_storage { -+ device = "mmcblk0"; -+ }; -+ -+ localbus@ffe05000 { -+ compatible = "fsl,elbc", "simple-bus"; -+ ranges = <0x0 0x0 0x0 0xec000000 0x04000000 -+ 0x1 0x0 0x0 0xe8000000 0x04000000>; -+ -+ nor@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x04000000>; -+ bank-width = <2>; -+ partition@0 { -+ /* Entire flash minus (u-boot + onie) */ -+ reg = <0x00000000 0x03b60000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x03b60000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x03f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ /* 512KB u-boot */ -+ reg = <0x03f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ -+ nor@1,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x1 0x0 0x04000000>; -+ bank-width = <2>; -+ partition@0 { -+ reg = <0x00000000 0x04000000>; -+ label = "open2"; -+ }; -+ }; -+ }; -+ -+ soc@ffe00000 { -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ fsl,preserve-clocking; -+ -+ rtc@68 { -+ compatible = "dallas,ds1338"; -+ reg = <0x68>; -+ }; -+ board_eeprom@54 { -+ compatible = "at,24c02"; -+ reg = <0x54>; -+ label = "board_eeprom"; -+ }; -+ /* Cypress PSOC fan and temp controller */ -+ cypsoc: psoc@2e { -+ compatible = "CY8C3245"; -+ reg = <0x2e>; -+ label = "Cypress PSOC"; -+ }; -+ pca9555@26 { -+ compatible = "nxp,pca9555"; -+ reg = <0x26>; -+ label = "Fan Status and CPLD"; -+ }; -+ mux@75 { -+ compatible = "ti,pca9546"; -+ reg = <0x75>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ psu1: psu@58 { -+ compatible = "at,24c02"; -+ reg = <0x58>; -+ label = "Redundant PSU 1"; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ psu2: psu@59 { -+ compatible = "at,24c02"; -+ reg = <0x59>; -+ label = "Redundant PSU 2"; -+ }; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ pca9555@24 { -+ compatible = "nxp,pca9555"; -+ reg = <0x24>; -+ label = "PSU Control 1"; -+ }; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ pca9555@25 { -+ compatible = "nxp,pca9555"; -+ reg = <0x25>; -+ label = "PSU Control 2"; -+ }; -+ }; -+ }; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ fsl,preserve-clocking; -+ pca9698@21 { -+ compatible = "nxp,pca9698"; -+ reg = <0x21>; -+ label = "QSFP+ I/O Expander"; -+ }; -+ mux@72 { -+ compatible = "ti,pca9546"; -+ reg = <0x72>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ mux@38 { -+ compatible = "cumulus,quanta-i2cmux"; -+ reg = <0x38>; -+ label = "CPLD 1, I2C expander SFP+ 1-32"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@16{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <16>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port17"; -+ }; -+ }; -+ i2c@17{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <17>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port18"; -+ }; -+ }; -+ i2c@18{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <18>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port19"; -+ }; -+ }; -+ i2c@19{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <19>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port20"; -+ }; -+ }; -+ i2c@20{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <20>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port21"; -+ }; -+ }; -+ i2c@21{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <21>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port22"; -+ }; -+ }; -+ i2c@22{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <22>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port23"; -+ }; -+ }; -+ i2c@23{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <23>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port24"; -+ }; -+ }; -+ i2c@24{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <24>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port25"; -+ }; -+ }; -+ i2c@25{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <25>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port26"; -+ }; -+ }; -+ i2c@26{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <26>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port27"; -+ }; -+ }; -+ i2c@27{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <27>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port28"; -+ }; -+ }; -+ i2c@28{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <28>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port29"; -+ }; -+ }; -+ i2c@29{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <29>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port30"; -+ }; -+ }; -+ i2c@30{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <30>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port31"; -+ }; -+ }; -+ i2c@31{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <31>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port32"; -+ }; -+ }; -+ }; -+ mux@39 { -+ compatible = "cumulus,quanta-i2cmux"; -+ reg = <0x39>; -+ label = "CPLD 2, I2C expander SFP+ 33-48"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ // SFP+ 33 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port33"; -+ }; -+ }; -+ }; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ mux@3A { -+ compatible = "cumulus,quanta-i2cmux"; -+ reg = <0x3A>; -+ label = "CPLD 3, IO expander SFP+ 1-16"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ // SFP+ 1 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port1"; -+ }; -+ }; -+ i2c@1{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port2"; -+ }; -+ }; -+ i2c@2{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port3"; -+ }; -+ }; -+ i2c@3{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port4"; -+ }; -+ }; -+ i2c@4{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port5"; -+ }; -+ }; -+ i2c@5{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port6"; -+ }; -+ }; -+ i2c@6{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port7"; -+ }; -+ }; -+ i2c@7{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port8"; -+ }; -+ }; -+ i2c@8{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <8>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port9"; -+ }; -+ }; -+ i2c@9{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <9>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port10"; -+ }; -+ }; -+ i2c@10{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <10>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port11"; -+ }; -+ }; -+ i2c@11{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <11>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port12"; -+ }; -+ }; -+ i2c@12{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <12>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port13"; -+ }; -+ }; -+ i2c@13{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <13>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port14"; -+ }; -+ }; -+ i2c@14{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <14>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port15"; -+ }; -+ }; -+ i2c@15{ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <15>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ label = "port16"; -+ }; -+ }; -+ }; -+ mux@3B { -+ compatible = "cumulus,quanta-i2cmux"; -+ reg = <0x3B>; -+ label = "CPLD 4, IO expander SFP+ 17-32"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ // SFP+ 1 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ }; -+ }; -+ }; -+ mux@3C { -+ compatible = "cumulus,quanta-i2cmux"; -+ reg = <0x3C>; -+ label = "CPLD 5, IO expander SFP+ 33-48"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ // SFP+ 1 -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "at,24c04"; -+ reg = <0x50>; -+ }; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ usb@22000 { -+ dr_mode = "host"; -+ phy_type = "ulpi"; -+ }; -+ -+ serial1: serial@4600 { -+ status = "disabled"; -+ }; -+ -+ mdio@24520 { -+ phy0: ethernet-phy@1 { -+ reg = <0x1>; -+ }; -+ }; -+ -+ enet0: ethernet@24000 { -+ phy-handle = <&phy0>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ enet1: ethernet@25000 { -+ status = "disabled"; -+ }; -+ -+ enet2: ethernet@26000 { -+ status = "disabled"; -+ }; -+ }; -+ -+ pci0: pcie@ffe08000 { -+ status = "disabled"; -+ }; -+ -+ pci1: pcie@ffe09000 { -+ status = "disabled"; -+ }; -+ -+ pci2: pcie@ffe0a000 { -+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 -+ >; -+ -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xc0000000 -+ 0x2000000 0x0 0xc0000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/quanta_ly2_ly2r.c b/arch/powerpc/platforms/85xx/quanta_ly2_ly2r.c -new file mode 100644 -index 0000000..aa24951 ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/quanta_ly2_ly2r.c -@@ -0,0 +1,233 @@ -+/* -+ * Copyright 2014 Cumulus Networks, Inc. -+ * -+ * LY2 setup and early boot code plus other random bits. -+ * -+ * 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 -+#include -+#include -+ -+#include -+#include -+ -+#undef DEBUG -+ -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+/******************************************************************************* -+ * -+ * Platform initialization functions -+ * -+ ******************************************************************************* -+*/ -+ -+/* -+ * Initialize the interrupt controller -+ */ -+static void __init quanta_ly2_ly2r_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np; -+ -+ np = of_find_node_by_type(NULL, "open-pic"); -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | -+ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | -+ MPIC_SINGLE_DEST_CPU, -+ 0, 256, " OpenPIC "); -+ -+ BUG_ON(mpic == NULL); -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+#ifdef CONFIG_SMP -+extern void __init mpc85xx_smp_init(void); -+#endif -+ -+static void __init quanta_ly2_ly2r_setup_arch(void) -+{ -+ struct device_node *cpu; -+ const unsigned int *fp; -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ -+ if (ppc_md.progress) -+ ppc_md.progress("quanta_ly2_ly2r_setup_arch()", 0); -+ -+ cpu = of_find_node_by_type(NULL, "cpu"); -+ if (cpu != 0) { -+ fp = of_get_property(cpu, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(cpu); -+ } -+ -+#ifdef CONFIG_PCI -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8548-pcie")) -+ fsl_add_bridge(np, 0); -+ } -+#endif -+ -+#ifdef CONFIG_SMP -+ mpc85xx_smp_init(); -+#endif -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+ -+ printk(KERN_INFO "Quanta LY2 & LY2R from Quanta Computer, Inc.\n"); -+} -+ -+ -+ -+static struct of_device_id __initdata quanta_ly2_ly2r_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ { .compatible = "gianfar", }, -+ {}, -+}; -+ -+ -+ -+static int __init quanta_ly2_ly2r_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, quanta_ly2_ly2r_ids, NULL); -+} -+machine_device_initcall(quanta_ly2, quanta_ly2_ly2r_publish_devices); -+machine_device_initcall(quanta_ly2r, quanta_ly2_ly2r_publish_devices); -+ -+static void quanta_ly2_ly2r_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu PLL setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init quanta_ly2_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "quanta,ly2")) -+ return 1; -+ -+ return 0; -+} -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init quanta_ly2r_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "quanta,ly2r")) -+ return 1; -+ -+ return 0; -+} -+ -+void quanta_ly2_ly2r_restart(char *cmd) -+{ -+ // asserts HRESET_REQ which will work on new hardware -+ printk(KERN_INFO "HRESET_REQ\n"); -+ fsl_rstcr_restart(cmd); -+} -+ -+define_machine(quanta_ly2) { -+ .name = "Quanta Computer, Inc. LY2", -+ .probe = quanta_ly2_probe, -+ .setup_arch = quanta_ly2_ly2r_setup_arch, -+ .init_IRQ = quanta_ly2_ly2r_pic_init, -+ .show_cpuinfo = quanta_ly2_ly2r_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = quanta_ly2_ly2r_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; -+ -+define_machine(quanta_ly2r) { -+ .name = "Quanta Computer, Inc. LY2R", -+ .probe = quanta_ly2r_probe, -+ .setup_arch = quanta_ly2_ly2r_setup_arch, -+ .init_IRQ = quanta_ly2_ly2r_pic_init, -+ .show_cpuinfo = quanta_ly2_ly2r_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = quanta_ly2_ly2r_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-ly6-p2020.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-ly6-p2020.patch deleted file mode 100644 index 87b5d6d5..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-quanta-ly6-p2020.patch +++ /dev/null @@ -1,1024 +0,0 @@ -Quanta LY6 Support - -diff --git a/arch/powerpc/boot/dts/quanta_ly6_p2020.dts b/arch/powerpc/boot/dts/quanta_ly6_p2020.dts -new file mode 100644 -index 0000000..c82cec0 ---- /dev/null -+++ b/arch/powerpc/boot/dts/quanta_ly6_p2020.dts -@@ -0,0 +1,804 @@ -+/* -+ * Cumulus P2020 Device Tree Source -+ * -+ * Copyright 2012 Cumulus Networks, 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/ "p2020si.dtsi" -+ -+/ { -+ model = "quanta,ly6_p2020"; -+ compatible = "quanta,ly6_p2020"; -+ -+ aliases { -+ ethernet0 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ bcm_dma { -+ compatible = "early-dma-alloc"; -+ // 64MB DMA region, aligned to 1MB -+ region_size = <0x04000000>; -+ alignment = <0x00100000>; -+ }; -+ -+ mass_storage { -+ device = "mmcblk0"; -+ }; -+ -+ localbus@ffe05000 { -+ compatible = "fsl,elbc", "simple-bus"; -+ ranges = <0x0 0x0 0x0 0xec000000 0x04000000 -+ 0x1 0x0 0x0 0xe8000000 0x04000000>; -+ -+ nor@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x0 0x0 0x04000000>; -+ bank-width = <2>; -+ partition@0 { -+ /* Entire flash minus (u-boot + onie) */ -+ reg = <0x00000000 0x03b60000>; -+ label = "open"; -+ }; -+ partition@1 { -+ /* 4MB onie */ -+ reg = <0x03b60000 0x00400000>; -+ label = "onie"; -+ }; -+ partition@2 { -+ /* 128KB, 1 sector */ -+ reg = <0x03f60000 0x00020000>; -+ label = "uboot-env"; -+ env_size = <0x2000>; -+ }; -+ partition@3 { -+ /* 512KB u-boot */ -+ reg = <0x03f80000 0x00080000>; -+ label = "uboot"; -+ }; -+ }; -+ -+ nor@1,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0x1 0x0 0x04000000>; -+ bank-width = <2>; -+ partition@0 { -+ reg = <0x00000000 0x04000000>; -+ label = "open2"; -+ }; -+ }; -+ }; -+ -+ soc@ffe00000 { -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ fsl,preserve-clocking; -+ -+ /* Cypress PSOC fan and temp controller */ -+ cypsoc: psoc@4e { -+ compatible = "CY8C3245R1"; -+ reg = <0x4e>; -+ label = "Cypress PSOC"; -+ }; -+ rtc@68 { -+ compatible = "dallas,ds1339"; -+ reg = <0x68>; -+ }; -+ mux@71 { -+ compatible = "ti,pca9546"; -+ reg = <0x71>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ pca9555@20 { -+ compatible = "nxp,pca9555"; -+ reg = <0x20>; -+ label = "PCA9555_1"; -+ }; -+ }; -+ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ board_eeprom@53 { -+ compatible = "at,24c02"; -+ reg = <0x53>; -+ label = "board_eeprom"; -+ }; -+ }; -+ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ pca9554@21 { -+ compatible = "nxp,pca9554"; -+ reg = <0x21>; -+ label = "PCA9554_1"; -+ }; -+ }; -+ }; -+ -+ mux@72 { -+ compatible = "ti,pca9546"; -+ reg = <0x72>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ psu_eeprom@58 { -+ compatible = "at,24c02"; -+ reg = <0x58>; -+ label = "psu1_eeprom"; -+ }; -+ }; -+ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ psu_eeprom@59 { -+ compatible = "at,24c02"; -+ reg = <0x59>; -+ label = "psu2_eeprom"; -+ }; -+ }; -+ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ pca9555@26 { -+ compatible = "nxp,pca9555"; -+ reg = <0x26>; -+ label = "PCA9555_PSU"; -+ }; -+ }; -+ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ board_eeprom@54 { -+ compatible = "at,24c02"; -+ reg = <0x54>; -+ label = "board_eeprom"; -+ }; -+ }; -+ }; -+ -+ mux@77 { -+ compatible = "ti,pca9548"; -+ reg = <0x77>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ mux@73 { -+ compatible = "nxp,pca9548"; -+ reg = <0x73>; -+ label = "QSFP 1-8 eeprom"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ /* QSFP 1 */ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port1"; -+ }; -+ }; -+ -+ /* QSFP 2 */ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port2"; -+ }; -+ }; -+ -+ /* QSFP 3 */ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port3"; -+ }; -+ }; -+ -+ -+ /* QSFP 4 */ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port4"; -+ }; -+ }; -+ -+ -+ /* QSFP 5 */ -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port5"; -+ }; -+ }; -+ -+ /* QSFP 6 */ -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port6"; -+ }; -+ }; -+ -+ /* QSFP 7 */ -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port7"; -+ }; -+ }; -+ -+ /* QSFP 8 */ -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port8"; -+ }; -+ }; -+ -+ }; -+ }; -+ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ mux@74 { -+ compatible = "nxp,pca9548"; -+ reg = <0x74>; -+ label = "QSFP 9-16 eeprom"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ /* QSFP 9 */ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port9"; -+ }; -+ }; -+ -+ /* QSFP 10 */ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port10"; -+ }; -+ }; -+ -+ /* QSFP 11 */ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port11"; -+ }; -+ }; -+ -+ /* QSFP 12 */ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port12"; -+ }; -+ }; -+ -+ /* QSFP 13 */ -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port13"; -+ }; -+ }; -+ -+ /* QSFP 14 */ -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port14"; -+ }; -+ }; -+ -+ /* QSFP 15 */ -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port15"; -+ }; -+ }; -+ -+ /* QSFP 16 */ -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port16"; -+ }; -+ }; -+ -+ }; -+ }; -+ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ mux@75 { -+ compatible = "nxp,pca9548"; -+ reg = <0x75>; -+ label = "QSFP 17-24 eeprom"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ /* QSFP 17 */ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port17"; -+ }; -+ }; -+ -+ /* QSFP 18 */ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port18"; -+ }; -+ }; -+ -+ /* QSFP 19 */ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port19"; -+ }; -+ }; -+ -+ /* QSFP 20 */ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port20"; -+ }; -+ }; -+ -+ /* QSFP 21 */ -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port21"; -+ }; -+ }; -+ -+ /* QSFP 22 */ -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port22"; -+ }; -+ }; -+ -+ /* QSFP 23 */ -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port23"; -+ }; -+ }; -+ -+ /* QSFP 24 */ -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port24"; -+ }; -+ }; -+ -+ }; -+ }; -+ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ mux@76 { -+ compatible = "nxp,pca9548"; -+ reg = <0x76>; -+ label = "QSFP 25-32 eeprom"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ deselect-on-exit; -+ -+ /* QSFP 25 */ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port25"; -+ }; -+ }; -+ -+ /* QSFP 26 */ -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port26"; -+ }; -+ }; -+ -+ /* QSFP 27 */ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port27"; -+ }; -+ }; -+ -+ /* QSFP 28 */ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port28"; -+ }; -+ }; -+ -+ /* QSFP 29 */ -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port29"; -+ }; -+ }; -+ -+ /* QSFP 30 */ -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port30"; -+ }; -+ }; -+ -+ /* QSFP 31 */ -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port31"; -+ }; -+ }; -+ -+ /* QSFP 32 */ -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ sfp_eeprom@50 { -+ compatible = "sff8436"; -+ reg = <0x50>; -+ label = "port32"; -+ }; -+ }; -+ -+ }; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ cpld_i2c@3A { -+ compatible = "quanta,ly6_p2020_cpld"; -+ reg = <0x3A>; -+ label = "cpld_1_16"; -+ }; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ cpld_i2c@3B { -+ compatible = "quanta,ly6_p2020_cpld"; -+ reg = <0x3B>; -+ label = "cpld_17_32"; -+ }; -+ }; -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ pca9555@24 { -+ compatible = "nxp,pca9555"; -+ reg = <0x24>; -+ label = "pca9555_3"; -+ }; -+ }; -+ -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ pca9555@23 { -+ compatible = "nxp,pca9555"; -+ reg = <0x23>; -+ label = "pca9555_4"; -+ }; -+ }; -+ }; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <43 2>; -+ interrupt-parent = <&mpic>; -+ fsl,preserve-clocking; -+ }; -+ -+ usb@22000 { -+ dr_mode = "host"; -+ phy_type = "ulpi"; -+ }; -+ -+ serial1: serial@4600 { -+ status = "disabled"; -+ }; -+ -+ mdio@24520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ phy0: ethernet-phy@5 { -+ reg = <0x5>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ -+ mdio1: mdio@25520 { -+ #address-cells = <0x1>; -+ #size-cells = <0x0>; -+ compatible = "fsl,gianfar-tbi"; -+ reg = <0x25520 0x20>; -+ tbi0: tbi-phy@11 { -+ reg = <0x11>; -+ device_type = "tbi-phy"; -+ }; -+ }; -+ -+ enet0: ethernet@24000 { -+ status = "disabled"; -+ }; -+ -+ enet1: ethernet@25000 { -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ cell-index = <0x1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x25000 0x1000>; -+ ranges = <0x0 0x25000 0x1000>; -+ interrupts = < -+ 0x23 0x2 -+ 0x24 0x2 -+ 0x28 0x2>; -+ interrupt-parent = <&mpic>; -+ tbi-handle = <&tbi0>; -+ phy-handle = <&phy0>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ enet2: ethernet@26000 { -+ status = "disabled"; -+ }; -+ }; -+ -+ pci0: pcie@ffe08000 { -+ status = "disabled"; -+ }; -+ -+ pci1: pcie@ffe09000 { -+ status = "disabled"; -+ }; -+ -+ pci2: pcie@ffe0a000 { -+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ /* IDSEL 0x0 */ -+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1 -+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1 -+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1 -+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1 -+ >; -+ -+ pcie@0 { -+ reg = <0x0 0x0 0x0 0x0 0x0>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ ranges = <0x2000000 0x0 0xc0000000 -+ 0x2000000 0x0 0xc0000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x10000>; -+ }; -+ }; -+}; -diff --git a/arch/powerpc/platforms/85xx/quanta_ly6_p2020.c b/arch/powerpc/platforms/85xx/quanta_ly6_p2020.c -new file mode 100644 -index 0000000..d90e06c ---- /dev/null -+++ b/arch/powerpc/platforms/85xx/quanta_ly6_p2020.c -@@ -0,0 +1,206 @@ -+/* -+ * Copyright 2013 Cumulus Networks, Inc. -+ * -+ * LY6 setup and early boot code. -+ * -+ * 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 -+#include -+#include -+ -+#include -+#include -+ -+#undef DEBUG -+ -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+/******************************************************************************* -+ * -+ * Platform initialization functions -+ * -+ ******************************************************************************* -+*/ -+ -+/* -+ * Initialize the interrupt controller -+ */ -+static void __init quanta_ly6_pic_init(void) -+{ -+ struct mpic *mpic; -+ struct resource r; -+ struct device_node *np; -+ -+ np = of_find_node_by_type(NULL, "open-pic"); -+ if (np == NULL) { -+ printk(KERN_ERR "Could not find open-pic node\n"); -+ return; -+ } -+ -+ if (of_address_to_resource(np, 0, &r)) { -+ printk(KERN_ERR "Failed to map mpic register space\n"); -+ of_node_put(np); -+ return; -+ } -+ -+ mpic = mpic_alloc(np, r.start, -+ MPIC_PRIMARY | MPIC_WANTS_RESET | -+ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | -+ MPIC_SINGLE_DEST_CPU, -+ 0, 256, " OpenPIC "); -+ -+ BUG_ON(mpic == NULL); -+ of_node_put(np); -+ -+ mpic_init(mpic); -+} -+ -+/* -+ * Setup the architecture -+ */ -+#ifdef CONFIG_SMP -+extern void __init mpc85xx_smp_init(void); -+#endif -+ -+static void __init quanta_ly6_setup_arch(void) -+{ -+ struct device_node *cpu; -+ const unsigned int *fp; -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ -+ if (ppc_md.progress) -+ ppc_md.progress("quanta_ly6_setup_arch()", 0); -+ -+ cpu = of_find_node_by_type(NULL, "cpu"); -+ if (cpu != 0) { -+ fp = of_get_property(cpu, "clock-frequency", NULL); -+ if (fp != 0) -+ loops_per_jiffy = *fp / HZ; -+ else -+ loops_per_jiffy = 500000000 / HZ; -+ of_node_put(cpu); -+ } -+ -+#ifdef CONFIG_PCI -+ for_each_node_by_type(np, "pci") { -+ if (of_device_is_compatible(np, "fsl,mpc8548-pcie")) -+ fsl_add_bridge(np, 0); -+ } -+#endif -+ -+#ifdef CONFIG_SMP -+ mpc85xx_smp_init(); -+#endif -+ -+#ifdef CONFIG_EARLY_DMA_ALLOC -+ eda_init(); -+#endif -+ -+ printk(KERN_INFO "Quanta LY6 from Quanta Computer, Inc.\n"); -+} -+ -+ -+ -+static struct of_device_id __initdata quanta_ly6_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ { .compatible = "simple-bus", }, -+ { .compatible = "gianfar", }, -+ {}, -+}; -+ -+ -+ -+static int __init quanta_ly6_publish_devices(void) -+{ -+ return of_platform_bus_probe(NULL, quanta_ly6_ids, NULL); -+} -+machine_device_initcall(quanta_ly6, quanta_ly6_publish_devices); -+ -+ -+ -+static void quanta_ly6_show_cpuinfo(struct seq_file *m) -+{ -+ uint pvid, svid, phid1; -+ uint memsize = total_memory; -+ -+ pvid = mfspr(SPRN_PVR); -+ svid = mfspr(SPRN_SVR); -+ -+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); -+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid); -+ seq_printf(m, "SVR\t\t: 0x%x\n", svid); -+ -+ /* Display cpu PLL setting */ -+ phid1 = mfspr(SPRN_HID1); -+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); -+ -+ /* Display the amount of memory */ -+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -+} -+ -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init quanta_ly6_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "quanta,ly6_p2020")) -+ return 1; -+ -+ return 0; -+} -+ -+void quanta_ly6_restart(char *cmd) -+{ -+ // asserts HRESET_REQ which will work on new hardware -+ printk(KERN_INFO "HRESET_REQ\n"); -+ fsl_rstcr_restart(cmd); -+} -+ -+ -+define_machine(quanta_ly6) { -+ .name = "Quanta Computer, Inc. LY6, P2020", -+ .probe = quanta_ly6_probe, -+ .setup_arch = quanta_ly6_setup_arch, -+ .init_IRQ = quanta_ly6_pic_init, -+ .show_cpuinfo = quanta_ly6_show_cpuinfo, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .power_save = e500_idle, -+ .restart = quanta_ly6_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/replace-fallback-with-bypass.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/replace-fallback-with-bypass.patch deleted file mode 100644 index bb2a9565..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/replace-fallback-with-bypass.patch +++ /dev/null @@ -1,833 +0,0 @@ -replace fallback with bypass - -diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c -index 25edb23..74d00e9 100644 ---- a/drivers/net/bonding/bond_3ad.c -+++ b/drivers/net/bonding/bond_3ad.c -@@ -70,7 +70,7 @@ - #define AD_PORT_STANDBY 0x80 - #define AD_PORT_SELECTED 0x100 - #define AD_PORT_MOVED 0x200 --#define AD_PORT_FALLBACK 0x400 -+#define AD_PORT_BYPASS 0x400 - - // Port Key definitions - // key is determined according to the link speed, duplex and -@@ -394,26 +394,26 @@ static u8 __get_duplex(struct port *port) - } - - /** -- * is_lacp_fallback_eligible - is bond eligible to go into lacp fallback mode -+ * is_lacp_bypass_eligible - is bond eligible to go into lacp bypass mode - * @bond: the bond we're looking at - * - * Return true if it is, false otherwise - */ --static bool is_lacp_fallback_eligible(struct bonding *bond) -+static bool is_lacp_bypass_eligible(struct bonding *bond) - { -- return (bond->params.lacp_fallback_allow && -- bond->params.lacp_fallback_active); -+ return (bond->params.lacp_bypass_allow && -+ bond->params.lacp_bypass_active); - } - - /** -- * is_better_fallback_slave - compare between two slaves of the same bond -- * and see which one is better for lacp fall back -+ * is_better_bypass_slave - compare between two slaves of the same bond -+ * and see which one is better for lacp bypass - * @slave1 - * @slave2 - * - * Return: true if slave1 is better, false otherwise - */ --static bool is_better_fallback_slave(struct slave *slave1, struct slave *slave2) -+static bool is_better_bypass_slave(struct slave *slave1, struct slave *slave2) - { - if (!slave1) - return false; -@@ -424,45 +424,45 @@ static bool is_better_fallback_slave(struct slave *slave1, struct slave *slave2) - if (slave1->bond != slave2->bond) - return false; - -- if (slave1->lacp_fallback_priority > slave2->lacp_fallback_priority) -+ if (slave1->lacp_bypass_priority > slave2->lacp_bypass_priority) - return true; - -- if (slave2->lacp_fallback_priority > slave1->lacp_fallback_priority) -+ if (slave2->lacp_bypass_priority > slave1->lacp_bypass_priority) - return false; - - return (strcmp(slave1->dev->name, slave2->dev->name) <= 0); - } - - /** -- * __get_best_fallback_slave_in_bond - get the best slave when bond is in fallback mode -+ * __get_best_bypass_slave_in_bond - get the best slave when bond is in bypass mode - * @bond: the bond we're looking at -- * Return the slave in the bond which is best for lacp fall back -+ * Return the slave in the bond which is best for lacp bypass - */ --static struct slave *__get_best_fallback_slave_in_bond(struct bonding *bond) -+static struct slave *__get_best_bypass_slave_in_bond(struct bonding *bond) - { - struct slave *slave, *best_slave = NULL; - int i; - -- if (!is_lacp_fallback_eligible(bond)) -+ if (!is_lacp_bypass_eligible(bond)) - return NULL; - - bond_for_each_slave(bond, slave, i) { - if (IS_UP(slave->dev)) { - if (!best_slave) - best_slave = slave; -- else if (is_better_fallback_slave(slave, best_slave)) -+ else if (is_better_bypass_slave(slave, best_slave)) - best_slave = slave; - } - } - return best_slave; - } - --static struct slave *__get_best_fallback_slave_in_agg(struct aggregator *agg) -+static struct slave *__get_best_bypass_slave_in_agg(struct aggregator *agg) - { - struct slave *best_slave = NULL; - struct port *port; - -- if (!is_lacp_fallback_eligible(agg->slave->bond)) -+ if (!is_lacp_bypass_eligible(agg->slave->bond)) - return NULL; - - for (port = agg->lag_ports; -@@ -472,7 +472,7 @@ static struct slave *__get_best_fallback_slave_in_agg(struct aggregator *agg) - if (IS_UP(port->slave->dev)) { - if (!best_slave) - best_slave = port->slave; -- else if (is_better_fallback_slave(port->slave, best_slave)) -+ else if (is_better_bypass_slave(port->slave, best_slave)) - best_slave = port->slave; - } - } -@@ -480,24 +480,24 @@ static struct slave *__get_best_fallback_slave_in_agg(struct aggregator *agg) - } - - /** -- * is_best_fallback_slave - is the given slave the best for lacp fallback -+ * is_best_bypass_slave - is the given slave the best for lacp bypass - * @slave: the slave we're looking at - * Return true if it is, false otherwise - */ --static bool is_best_fallback_slave(struct slave *slave) -+static bool is_best_bypass_slave(struct slave *slave) - { -- return (slave == __get_best_fallback_slave_in_bond(slave->bond)); -+ return (slave == __get_best_bypass_slave_in_bond(slave->bond)); - } - --static bool is_agg_in_fallback(struct aggregator *agg) -+static bool is_agg_in_bypass(struct aggregator *agg) - { - struct slave *slave; - - if (!agg) - return false; - -- slave = __get_best_fallback_slave_in_agg(agg); -- return (slave && (SLAVE_AD_INFO(slave).port.sm_vars & AD_PORT_FALLBACK)); -+ slave = __get_best_bypass_slave_in_agg(agg); -+ return (slave && (SLAVE_AD_INFO(slave).port.sm_vars & AD_PORT_BYPASS)); - } - - /** -@@ -1150,34 +1150,34 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - /* next state */ - port->sm_rx_state = AD_RX_PORT_DISABLED; - // check if new lacpdu arrived -- else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT) || (port->sm_rx_state == AD_RX_FALLBACK_EXPIRED))) { -+ else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT) || (port->sm_rx_state == AD_RX_BYPASS_EXPIRED))) { - port->sm_rx_timer_counter = 0; // zero timer - port->sm_rx_state = AD_RX_CURRENT; -- } else if (port->sm_rx_state == AD_RX_FALLBACK) { -+ } else if (port->sm_rx_state == AD_RX_BYPASS) { - if (lacpdu) { -- pr_debug("Fallback (%s): lacpdu received, disabling fallback\n", -+ pr_debug("Bypass (%s): lacpdu received, disabling bypass\n", - port->slave->dev->name); - -- port->sm_rx_fb_timer_counter = 0; -+ port->sm_rx_bypass_timer_counter = 0; - port->sm_rx_state = AD_RX_CURRENT; - __disable_port(port); // bring down the bond, let lacp runs its course -- } else if (!is_best_fallback_slave(port->slave) || -- !(port->sm_vars & AD_PORT_FALLBACK)) { -- pr_debug("(%s) fallback allow %d active %d or no longer best\n", -+ } else if (!is_best_bypass_slave(port->slave) || -+ !(port->sm_vars & AD_PORT_BYPASS)) { -+ pr_debug("(%s) bypass allow %d active %d or no longer best\n", - port->slave->dev->name, -- port->slave->bond->params.lacp_fallback_allow, -- port->slave->bond->params.lacp_fallback_active); -- port->sm_rx_fb_timer_counter = 0; -- if (is_lacp_fallback_eligible(port->slave->bond)) -- port->sm_rx_state = AD_RX_FALLBACK_EXPIRED; -+ port->slave->bond->params.lacp_bypass_allow, -+ port->slave->bond->params.lacp_bypass_active); -+ port->sm_rx_bypass_timer_counter = 0; -+ if (is_lacp_bypass_eligible(port->slave->bond)) -+ port->sm_rx_state = AD_RX_BYPASS_EXPIRED; - else - port->sm_rx_state = AD_RX_DEFAULTED; - __disable_port(port); -- } else if (port->sm_rx_fb_timer_counter && !(--port->sm_rx_fb_timer_counter)) { -- pr_debug("(%s) Fallback grace period expired (%d)\n", port->slave->dev->name, -+ } else if (port->sm_rx_bypass_timer_counter && !(--port->sm_rx_bypass_timer_counter)) { -+ pr_debug("(%s) Bypass grace period expired (%d)\n", port->slave->dev->name, - port->slave->inactive); - -- port->sm_rx_state = AD_RX_FALLBACK_EXPIRED; // next state -+ port->sm_rx_state = AD_RX_BYPASS_EXPIRED; // next state - __disable_port(port); - } - } else { -@@ -1185,8 +1185,8 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - if (port->sm_rx_timer_counter && !(--port->sm_rx_timer_counter)) { - switch (port->sm_rx_state) { - case AD_RX_EXPIRED: -- if (is_best_fallback_slave(port->slave)) -- port->sm_rx_state = AD_RX_FALLBACK; // next state -+ if (is_best_bypass_slave(port->slave)) -+ port->sm_rx_state = AD_RX_BYPASS; // next state - else - port->sm_rx_state = AD_RX_DEFAULTED; // next state - break; -@@ -1213,8 +1213,8 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - port->sm_rx_state = AD_RX_LACP_DISABLED; // next state - break; - case AD_RX_DEFAULTED: -- if (is_best_fallback_slave(port->slave)) -- port->sm_rx_state = AD_RX_FALLBACK; // next state -+ if (is_best_bypass_slave(port->slave)) -+ port->sm_rx_state = AD_RX_BYPASS; // next state - break; - default: //to silence the compiler - break; -@@ -1244,13 +1244,13 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - - case AD_RX_PORT_DISABLED: - port->sm_vars &= ~AD_PORT_MATCHED; -- port->sm_vars &= ~AD_PORT_FALLBACK; -- port->sm_rx_fb_timer_counter = 0; -+ port->sm_vars &= ~AD_PORT_BYPASS; -+ port->sm_rx_bypass_timer_counter = 0; - break; - case AD_RX_LACP_DISABLED: - port->sm_vars &= ~AD_PORT_SELECTED; -- port->sm_vars &= ~AD_PORT_FALLBACK; -- port->sm_rx_fb_timer_counter = 0; -+ port->sm_vars &= ~AD_PORT_BYPASS; -+ port->sm_rx_bypass_timer_counter = 0; - __record_default(port); - port->partner_oper.port_state &= ~AD_STATE_AGGREGATION; - port->sm_vars |= AD_PORT_MATCHED; -@@ -1262,8 +1262,8 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - //mux machine in case of EXPIRED even if LINK_DOWN didn't arrive for the port. - port->partner_oper.port_state &= ~AD_STATE_SYNCHRONIZATION; - port->sm_vars &= ~AD_PORT_MATCHED; -- port->sm_vars &= ~AD_PORT_FALLBACK; -- port->sm_rx_fb_timer_counter = 0; -+ port->sm_vars &= ~AD_PORT_BYPASS; -+ port->sm_rx_bypass_timer_counter = 0; - port->partner_oper.port_state |= - AD_STATE_LACP_ACTIVITY; - port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(AD_SHORT_TIMEOUT)); -@@ -1273,8 +1273,8 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - __update_default_selected(port); - __record_default(port); - port->sm_vars |= AD_PORT_MATCHED; -- port->sm_vars &= ~AD_PORT_FALLBACK; -- port->sm_rx_fb_timer_counter = 0; -+ port->sm_vars &= ~AD_PORT_BYPASS; -+ port->sm_rx_bypass_timer_counter = 0; - port->actor_oper_port_state &= ~AD_STATE_EXPIRED; - break; - case AD_RX_CURRENT: -@@ -1291,21 +1291,21 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) - __record_pdu(lacpdu, port); - port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)); - port->actor_oper_port_state &= ~AD_STATE_EXPIRED; -- port->sm_vars &= ~AD_PORT_FALLBACK; -+ port->sm_vars &= ~AD_PORT_BYPASS; - break; -- case AD_RX_FALLBACK: -- pr_debug("rx_machine: %s in fallback state (%d)\n", -- port->slave->dev->name, port->sm_rx_fb_timer_counter); -+ case AD_RX_BYPASS: -+ pr_debug("rx_machine: %s in bypass state (%d)\n", -+ port->slave->dev->name, port->sm_rx_bypass_timer_counter); - -- port->sm_rx_fb_timer_counter = -- port->slave->bond->params.lacp_fallback_period * -+ port->sm_rx_bypass_timer_counter = -+ port->slave->bond->params.lacp_bypass_period * - ad_ticks_per_sec; - port->sm_vars &= ~AD_PORT_SELECTED; -- port->sm_vars |= AD_PORT_FALLBACK; -+ port->sm_vars |= AD_PORT_BYPASS; - break; -- case AD_RX_FALLBACK_EXPIRED: -- port->sm_vars &= ~AD_PORT_FALLBACK; -- port->sm_rx_fb_timer_counter = 0; -+ case AD_RX_BYPASS_EXPIRED: -+ port->sm_vars &= ~AD_PORT_BYPASS; -+ port->sm_rx_bypass_timer_counter = 0; - break; - default: //to silence the compiler - break; -@@ -1601,14 +1601,14 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, - * 4. Therefore, current and best both have partner replies or - * both do not, so: - * -- * 4a. If both have no partner and bond is fallback eligible and if -- * current agg is a better fallback slave, select current. -+ * 4a. If both have no partner and bond is bypass eligible and if -+ * current agg is a better bypass slave, select current. - * -- * 4b. If both have no partner and bond is fallback eligible and if -- * best agg is a better fallback, keep best. -+ * 4b. If both have no partner and bond is bypass eligible and if -+ * best agg is a better bypass, keep best. - * - * 5. Therefore, current and best both have partner replies or -- * both do not and bond is not fallback eligible, perform -+ * both do not and bond is not bypass eligible, perform - * selection policy: - * - * BOND_AD_COUNT: Select by count of ports. If count is equal, -@@ -1633,16 +1633,16 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, - if (!__agg_has_partner(curr) && __agg_has_partner(best)) - return best; - -- if (is_lacp_fallback_eligible(curr->slave->bond) && -+ if (is_lacp_bypass_eligible(curr->slave->bond) && - !__agg_has_partner(curr) && !__agg_has_partner(best)) { - -- s1 = __get_best_fallback_slave_in_agg(curr); -- s2 = __get_best_fallback_slave_in_agg(best); -+ s1 = __get_best_bypass_slave_in_agg(curr); -+ s2 = __get_best_bypass_slave_in_agg(best); - -- if (is_better_fallback_slave(s1, s2)) -+ if (is_better_bypass_slave(s1, s2)) - return curr; - -- if (is_better_fallback_slave(s2, s1)) -+ if (is_better_bypass_slave(s2, s1)) - return best; - } - -@@ -1710,7 +1710,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) - { - struct aggregator *best, *active, *origin; - struct port *port; -- bool best_is_in_fallback = false; -+ bool best_is_in_bypass = false; - - origin = agg; - active = __get_active_agg(agg); -@@ -1724,9 +1724,9 @@ static void ad_agg_selection_logic(struct aggregator *agg) - - } while ((agg = __get_next_agg(agg))); - -- best_is_in_fallback = is_agg_in_fallback(best); -+ best_is_in_bypass = is_agg_in_bypass(best); - -- if (best && !best_is_in_fallback && -+ if (best && !best_is_in_bypass && - __get_agg_selection_mode(best->lag_ports) == BOND_AD_STABLE) { - /* - * For the STABLE policy, don't replace the old active -@@ -1792,7 +1792,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) - for (port = active->lag_ports; port; - port = port->next_port_in_aggregator) { - __disable_port(port); -- port->sm_vars &= ~AD_PORT_FALLBACK; -+ port->sm_vars &= ~AD_PORT_BYPASS; - } - } - } -@@ -1805,11 +1805,11 @@ static void ad_agg_selection_logic(struct aggregator *agg) - - if (active) { - if (!__agg_has_partner(active)) { -- bool is_fallback_eligible = is_lacp_fallback_eligible(active->slave->bond); -+ bool is_bypass_eligible = is_lacp_bypass_eligible(active->slave->bond); - for (port = active->lag_ports; port; - port = port->next_port_in_aggregator) { -- if (!is_fallback_eligible || -- (is_best_fallback_slave(port->slave))) { -+ if (!is_bypass_eligible || -+ (is_best_bypass_slave(port->slave))) { - pr_debug("(%s) agg active and no partner\n", port->slave->dev->name); - __enable_port(port); - } -@@ -1927,8 +1927,8 @@ static void ad_initialize_port(struct port *port, int lacp_fast) - port->next_port_in_aggregator = NULL; - port->transaction_id = 0; - -- // fallback -- port->sm_rx_fb_timer_counter = 0; -+ // bypass -+ port->sm_rx_bypass_timer_counter = 0; - - memcpy(&port->lacpdu, &lacpdu, sizeof(lacpdu)); - } -@@ -2560,18 +2560,18 @@ int bond_3ad_set_carrier(struct bonding *bond) - struct aggregator *active; - struct slave *slave; - int active_slaves = 0, i; -- bool fallback = false; -+ bool bypass = false; - - bond_for_each_slave(bond, slave, i) - if (bond_is_active_slave(slave)) - active_slaves++; - - active = __get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator)); -- fallback = is_agg_in_fallback(active); -- pr_debug("%s %s active id: %d #actives: %d fallback: %d\n", __FUNCTION__, -+ bypass = is_agg_in_bypass(active); -+ pr_debug("%s %s active id: %d #actives: %d bypass: %d\n", __FUNCTION__, - bond->dev->name, active ? active->aggregator_identifier : 0, -- active_slaves, fallback); -- if (active && (fallback || __agg_has_partner(active))) { -+ active_slaves, bypass); -+ if (active && (bypass || __agg_has_partner(active))) { - /* are enough slaves available to consider link up? */ - if (active_slaves < bond->params.min_links) { - if (netif_carrier_ok(bond->dev)) { -diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h -index bd844cc..5b9bad5 100644 ---- a/drivers/net/bonding/bond_3ad.h -+++ b/drivers/net/bonding/bond_3ad.h -@@ -56,8 +56,8 @@ typedef enum { - AD_RX_EXPIRED, // rx Machine - AD_RX_DEFAULTED, // rx Machine - AD_RX_CURRENT, // rx Machine -- AD_RX_FALLBACK, // rx Machine -- AD_RX_FALLBACK_EXPIRED // rx Machine -+ AD_RX_BYPASS, // rx Machine -+ AD_RX_BYPASS_EXPIRED // rx Machine - } rx_states_t; - - // periodic machine states(43.4.12 in the 802.3ad standard) -@@ -103,7 +103,7 @@ typedef enum { - AD_PERIODIC_TIMER, - AD_PARTNER_CHURN_TIMER, - AD_WAIT_WHILE_TIMER, -- AD_FALLBACK_TIMER, -+ AD_BYPASS_TIMER, - } ad_timers_t; - - #pragma pack(1) -@@ -226,7 +226,7 @@ typedef struct port { - u16 sm_vars; // all state machines variables for this port - rx_states_t sm_rx_state; // state machine rx state - u16 sm_rx_timer_counter; // state machine rx timer counter -- u16 sm_rx_fb_timer_counter; // state machine rx fallback timer counter -+ u16 sm_rx_bypass_timer_counter; // state machine rx bypass timer counter - periodic_states_t sm_periodic_state;// state machine periodic state - u16 sm_periodic_timer_counter; // state machine periodic timer counter - mux_states_t sm_mux_state; // state machine mux state -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index 536d298..70c865b 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -89,8 +89,8 @@ - /* monitor all links that often (in milliseconds). <=0 disables monitoring */ - #define BOND_LINK_MON_INTERV 0 - #define BOND_LINK_ARP_INTERV 0 --#define BOND_LACP_FALLBACK_PERIOD 0 --#define BOND_LACP_FALLBACK_ACTIVE_DEFAULT 1 -+#define BOND_LACP_BYPASS_PERIOD 0 -+#define BOND_LACP_BYPASS_ACTIVE_DEFAULT 1 - - static int max_bonds = BOND_DEFAULT_MAX_BONDS; - static int tx_queues = BOND_DEFAULT_TX_QUEUES; -@@ -4950,8 +4950,8 @@ static int bond_check_params(struct bond_params *params) - params->all_slaves_active = all_slaves_active; - params->resend_igmp = resend_igmp; - params->min_links = min_links; -- params->lacp_fallback_period = BOND_LACP_FALLBACK_PERIOD; -- params->lacp_fallback_active = BOND_LACP_FALLBACK_ACTIVE_DEFAULT; -+ params->lacp_bypass_period = BOND_LACP_BYPASS_PERIOD; -+ params->lacp_bypass_active = BOND_LACP_BYPASS_ACTIVE_DEFAULT; - - if (primary) { - strncpy(params->primary, primary, IFNAMSIZ); -@@ -5068,9 +5068,9 @@ static size_t bond_get_size(const struct net_device *bond_dev) - nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_INFO_ACTOR_KEY */ - nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_INFO_PARTNER_KEY*/ - nla_total_size(ETH_ALEN) + /* IFLA_BOND_AD_INFO_PARTNER_MAC*/ -- nla_total_size(sizeof(u8)) + /* IFLA_BOND_CL_LACP_FB_ALLOW */ -- nla_total_size(sizeof(u8)) + /* IFLA_BOND_CL_LACP_FB_ACTIVE */ -- nla_total_size(sizeof(u32)) + /* IFLA_BOND_CL_LACP_FB_PERIOD */ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_CL_LACP_BYPASS_ALLOW */ -+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_CL_LACP_BYPASS_ACTIVE */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_CL_LACP_BYPASS_PERIOD */ - 0; - } - -@@ -5218,16 +5218,16 @@ static int bond_fill_info(struct sk_buff *skb, - nla_nest_end(skb, nest); - } - -- if (nla_put_u8(skb, IFLA_BOND_CL_LACP_FB_ALLOW, -- bond->params.lacp_fallback_allow)) -+ if (nla_put_u8(skb, IFLA_BOND_CL_LACP_BYPASS_ALLOW, -+ bond->params.lacp_bypass_allow)) - goto nla_put_failure; - -- if (nla_put_u8(skb, IFLA_BOND_CL_LACP_FB_ACTIVE, -- bond->params.lacp_fallback_active)) -+ if (nla_put_u8(skb, IFLA_BOND_CL_LACP_BYPASS_ACTIVE, -+ bond->params.lacp_bypass_active)) - goto nla_put_failure; - -- if (nla_put_u32(skb, IFLA_BOND_CL_LACP_FB_PERIOD, -- bond->params.lacp_fallback_period)) -+ if (nla_put_u32(skb, IFLA_BOND_CL_LACP_BYPASS_PERIOD, -+ bond->params.lacp_bypass_period)) - goto nla_put_failure; - } - -@@ -5246,7 +5246,7 @@ static size_t bond_get_slave_size(const struct net_device *bond_dev, - nla_total_size(MAX_ADDR_LEN) + /* IFLA_BOND_SLAVE_PERM_HWADDR */ - nla_total_size(sizeof(u16)) + /* IFLA_BOND_SLAVE_QUEUE_ID */ - nla_total_size(sizeof(u16)) + /* IFLA_BOND_SLAVE_AD_AGGREGATOR_ID */ -- nla_total_size(sizeof(u32)) + /* IFLA_BOND_SLAVE_CL_LACP_FB_PRIO */ -+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_SLAVE_CL_LACP_BYPASS_PRIO */ - 0; - } - -@@ -5285,8 +5285,8 @@ static int bond_fill_slave_info(struct sk_buff *skb, - agg->aggregator_identifier)) - goto nla_put_failure; - -- if (nla_put_u32(skb, IFLA_BOND_SLAVE_CL_LACP_FB_PRIO, -- slave->lacp_fallback_priority)) -+ if (nla_put_u32(skb, IFLA_BOND_SLAVE_CL_LACP_BYPASS_PRIO, -+ slave->lacp_bypass_priority)) - goto nla_put_failure; - } - -diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c -index 13217bf..83544fb 100644 ---- a/drivers/net/bonding/bond_procfs.c -+++ b/drivers/net/bonding/bond_procfs.c -@@ -151,11 +151,11 @@ static void bond_info_show_master(struct seq_file *seq) - ad_info.partner_system); - } - -- seq_printf(seq, "Fall back Info:\n"); -+ seq_printf(seq, "LACP Bypass Info:\n"); - seq_printf(seq, "\tAllowed: %d\n", -- bond->params.lacp_fallback_allow); -+ bond->params.lacp_bypass_allow); - seq_printf(seq, "\tTimeout: %d\n", -- bond->params.lacp_fallback_period); -+ bond->params.lacp_bypass_period); - } - } - -@@ -191,12 +191,12 @@ static void bond_info_show_slave(struct seq_file *seq, - agg->aggregator_identifier); - else - seq_puts(seq, "Aggregator ID: N/A\n"); -- seq_printf(seq, "Lacp fall back priority: %d\n", -- slave->lacp_fallback_priority); -- if (SLAVE_AD_INFO(slave).port.sm_rx_state == AD_RX_FALLBACK) -- seq_printf(seq, "LACP fall back: on\n"); -- if (SLAVE_AD_INFO(slave).port.sm_rx_state == AD_RX_FALLBACK_EXPIRED) -- seq_printf(seq, "LACP fall back: expired\n"); -+ seq_printf(seq, "LACP bypass priority: %d\n", -+ slave->lacp_bypass_priority); -+ if (SLAVE_AD_INFO(slave).port.sm_rx_state == AD_RX_BYPASS) -+ seq_printf(seq, "LACP bypass: on\n"); -+ if (SLAVE_AD_INFO(slave).port.sm_rx_state == AD_RX_BYPASS_EXPIRED) -+ seq_printf(seq, "LACP bypass: expired\n"); - } - seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id); - } -diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c -index 4abf593..4e377e0 100644 ---- a/drivers/net/bonding/bond_sysfs.c -+++ b/drivers/net/bonding/bond_sysfs.c -@@ -53,28 +53,28 @@ struct slave_attribute { - int (*store)(struct slave *, unsigned long); - }; - --static ssize_t show_lacp_fallback_priority(struct slave *slave, char *buf) -+static ssize_t show_lacp_bypass_priority(struct slave *slave, char *buf) - { -- return sprintf(buf, "%d\n", slave->lacp_fallback_priority); -+ return sprintf(buf, "%d\n", slave->lacp_bypass_priority); - } - --static int store_lacp_fallback_priority(struct slave *slave, unsigned long val) -+static int store_lacp_bypass_priority(struct slave *slave, unsigned long val) - { -- slave->lacp_fallback_priority = val; -+ slave->lacp_bypass_priority = val; - return 0; - } - --static const struct slave_attribute slave_lacp_fallback_priority = { -+static const struct slave_attribute slave_lacp_bypass_priority = { - .attr = { -- .name = "lacp_fallback_priority", -+ .name = "lacp_bypass_priority", - .mode = S_IWUSR | S_IRUGO, - }, -- .show = show_lacp_fallback_priority, -- .store = store_lacp_fallback_priority, -+ .show = show_lacp_bypass_priority, -+ .store = store_lacp_bypass_priority, - }; - - static const struct slave_attribute *slave_attrs[] = { -- &slave_lacp_fallback_priority, -+ &slave_lacp_bypass_priority, - NULL - }; - -@@ -984,16 +984,16 @@ static ssize_t bonding_store_min_links(struct device *d, - static DEVICE_ATTR(min_links, S_IRUGO | S_IWUSR, - bonding_show_min_links, bonding_store_min_links); - --static ssize_t bonding_show_lacp_fallback_allow(struct device *d, -+static ssize_t bonding_show_lacp_bypass_allow(struct device *d, - struct device_attribute *attr, - char *buf) - { - struct bonding *bond = to_bond(d); - -- return sprintf(buf, "%d\n", bond->params.lacp_fallback_allow); -+ return sprintf(buf, "%d\n", bond->params.lacp_bypass_allow); - } - --static ssize_t bonding_store_lacp_fallback_allow(struct device *d, -+static ssize_t bonding_store_lacp_bypass_allow(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) - { -@@ -1002,7 +1002,7 @@ static ssize_t bonding_store_lacp_fallback_allow(struct device *d, - unsigned int new_value; - - if (bond->params.mode != BOND_MODE_8023AD) { -- pr_err("%s: Unable to update lacp_fallback_allow because bond is not " -+ pr_err("%s: Unable to update lacp_bypass_allow because bond is not " - "in 802.3ad mode.\n", bond->dev->name); - ret = -EPERM; - return ret; -@@ -1010,33 +1010,33 @@ static ssize_t bonding_store_lacp_fallback_allow(struct device *d, - - ret = kstrtouint(buf, 0, &new_value); - if (ret < 0) { -- pr_err("%s: Ignoring invalid lacp_fallback_allow value %s.\n", -+ pr_err("%s: Ignoring invalid lacp_bypass_allow value %s.\n", - bond->dev->name, buf); - return ret; - } - - if (!rtnl_trylock()) - return restart_syscall(); -- pr_debug("%s: Setting lacp_fallback_allow to %u\n", -+ pr_debug("%s: Setting lacp_bypass_allow to %u\n", - bond->dev->name, new_value); -- bond->params.lacp_fallback_allow = new_value; -+ bond->params.lacp_bypass_allow = new_value; - call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - rtnl_unlock(); - return count; - } --static DEVICE_ATTR(lacp_fallback_allow, S_IRUGO | S_IWUSR, -- bonding_show_lacp_fallback_allow, bonding_store_lacp_fallback_allow); -+static DEVICE_ATTR(lacp_bypass_allow, S_IRUGO | S_IWUSR, -+ bonding_show_lacp_bypass_allow, bonding_store_lacp_bypass_allow); - --static ssize_t bonding_show_lacp_fallback_period(struct device *d, -+static ssize_t bonding_show_lacp_bypass_period(struct device *d, - struct device_attribute *attr, - char *buf) - { - struct bonding *bond = to_bond(d); - -- return sprintf(buf, "%d\n", bond->params.lacp_fallback_period); -+ return sprintf(buf, "%d\n", bond->params.lacp_bypass_period); - } - --static ssize_t bonding_store_lacp_fallback_period(struct device *d, -+static ssize_t bonding_store_lacp_bypass_period(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) - { -@@ -1045,7 +1045,7 @@ static ssize_t bonding_store_lacp_fallback_period(struct device *d, - unsigned int new_value; - - if (bond->params.mode != BOND_MODE_8023AD) { -- pr_err("%s: Unable to update lacp_fallback_period because bond is not " -+ pr_err("%s: Unable to update lacp_bypass_period because bond is not " - "in 802.3ad mode.\n", bond->dev->name); - ret = -EPERM; - return ret; -@@ -1053,34 +1053,34 @@ static ssize_t bonding_store_lacp_fallback_period(struct device *d, - - ret = kstrtouint(buf, 0, &new_value); - if (ret < 0) { -- pr_err("%s: Ignoring invalid lacp_fallback_period value %s.\n", -+ pr_err("%s: Ignoring invalid lacp_bypass_period value %s.\n", - bond->dev->name, buf); - return ret; - } - - if (!rtnl_trylock()) - return restart_syscall(); -- pr_debug("%s: Setting lacp_fallback period to %u\n", -+ pr_debug("%s: Setting lacp_bypass period to %u\n", - bond->dev->name, new_value); -- bond->params.lacp_fallback_period = new_value; -+ bond->params.lacp_bypass_period = new_value; - call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - rtnl_unlock(); - return count; - } --static DEVICE_ATTR(lacp_fallback_period, S_IRUGO | S_IWUSR, -- bonding_show_lacp_fallback_period, -- bonding_store_lacp_fallback_period); -+static DEVICE_ATTR(lacp_bypass_period, S_IRUGO | S_IWUSR, -+ bonding_show_lacp_bypass_period, -+ bonding_store_lacp_bypass_period); - --static ssize_t bonding_show_lacp_fallback_active(struct device *d, -+static ssize_t bonding_show_lacp_bypass_active(struct device *d, - struct device_attribute *attr, - char *buf) - { - struct bonding *bond = to_bond(d); - -- return sprintf(buf, "%d\n", bond->params.lacp_fallback_active); -+ return sprintf(buf, "%d\n", bond->params.lacp_bypass_active); - } - --static ssize_t bonding_store_lacp_fallback_active(struct device *d, -+static ssize_t bonding_store_lacp_bypass_active(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) - { -@@ -1089,7 +1089,7 @@ static ssize_t bonding_store_lacp_fallback_active(struct device *d, - unsigned int new_value; - - if (bond->params.mode != BOND_MODE_8023AD) { -- pr_err("%s: Unable to update lacp_fallback_active because bond is not " -+ pr_err("%s: Unable to update lacp_bypass_active because bond is not " - "in 802.3ad mode.\n", bond->dev->name); - ret = -EPERM; - return ret; -@@ -1097,23 +1097,23 @@ static ssize_t bonding_store_lacp_fallback_active(struct device *d, - - ret = kstrtouint(buf, 0, &new_value); - if (ret < 0) { -- pr_err("%s: Ignoring invalid lacp_fallback_active value %s.\n", -+ pr_err("%s: Ignoring invalid lacp_bypass_active value %s.\n", - bond->dev->name, buf); - return ret; - } - - if (!rtnl_trylock()) - return restart_syscall(); -- pr_debug("%s: Setting lacp_fallback active to %u\n", -+ pr_debug("%s: Setting lacp_bypass active to %u\n", - bond->dev->name, new_value); -- bond->params.lacp_fallback_active = new_value; -+ bond->params.lacp_bypass_active = new_value; - call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); - rtnl_unlock(); - return count; - } --static DEVICE_ATTR(lacp_fallback_active, S_IRUGO | S_IWUSR, -- bonding_show_lacp_fallback_active, -- bonding_store_lacp_fallback_active); -+static DEVICE_ATTR(lacp_bypass_active, S_IRUGO | S_IWUSR, -+ bonding_show_lacp_bypass_active, -+ bonding_store_lacp_bypass_active); - - static ssize_t bonding_show_ad_select(struct device *d, - struct device_attribute *attr, -@@ -2092,9 +2092,9 @@ static struct attribute *per_bond_attrs[] = { - &dev_attr_all_slaves_active.attr, - &dev_attr_resend_igmp.attr, - &dev_attr_min_links.attr, -- &dev_attr_lacp_fallback_allow.attr, -- &dev_attr_lacp_fallback_active.attr, -- &dev_attr_lacp_fallback_period.attr, -+ &dev_attr_lacp_bypass_allow.attr, -+ &dev_attr_lacp_bypass_active.attr, -+ &dev_attr_lacp_bypass_period.attr, - NULL, - }; - -diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h -index af93ed4..b3594f7 100644 ---- a/drivers/net/bonding/bonding.h -+++ b/drivers/net/bonding/bonding.h -@@ -160,9 +160,9 @@ struct bond_params { - int tx_queues; - int all_slaves_active; - int resend_igmp; -- int lacp_fallback_allow; -- int lacp_fallback_active; -- u32 lacp_fallback_period; -+ int lacp_bypass_allow; -+ int lacp_bypass_active; -+ u32 lacp_bypass_period; - }; - - struct bond_parm_tbl { -@@ -197,7 +197,7 @@ struct slave { - u32 speed; - u16 queue_id; - u8 perm_hwaddr[ETH_ALEN]; -- int lacp_fallback_priority; -+ int lacp_bypass_priority; - struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */ - struct tlb_slave_info tlb_info; - #ifdef CONFIG_NET_POLL_CONTROLLER -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index ee99f97..086e2ad 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -354,9 +354,9 @@ enum { - IFLA_BOND_AD_INFO, - - IFLA_BOND_CL_START = 100, -- IFLA_BOND_CL_LACP_FB_ALLOW = IFLA_BOND_CL_START, -- IFLA_BOND_CL_LACP_FB_ACTIVE, -- IFLA_BOND_CL_LACP_FB_PERIOD, -+ IFLA_BOND_CL_LACP_BYPASS_ALLOW = IFLA_BOND_CL_START, -+ IFLA_BOND_CL_LACP_BYPASS_ACTIVE, -+ IFLA_BOND_CL_LACP_BYPASS_PERIOD, - __IFLA_BOND_MAX, - }; - -@@ -384,7 +384,7 @@ enum { - IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, - - IFLA_BOND_SLAVE_CL_START = 50, -- IFLA_BOND_SLAVE_CL_LACP_FB_PRIO = IFLA_BOND_SLAVE_CL_START, -+ IFLA_BOND_SLAVE_CL_LACP_BYPASS_PRIO = IFLA_BOND_SLAVE_CL_START, - __IFLA_BOND_SLAVE_MAX, - }; - diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/series b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/series deleted file mode 100644 index 40e11a5f..00000000 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/series +++ /dev/null @@ -1,246 +0,0 @@ -git-ignore.patch -arch-powerpc-emulated-lwsync.patch -arch-powerpc-jtag.patch -arch-powerpc-warn-unmapped-irq.patch -arch-powerpc-os-driven-pci-maxpayload-readreq-setup.patch -arch-powerpc-topology-info.patch -arch-intel-centerton-pci-id.patch -arch-intel-centerton-reboot-cf9.patch -arch-intel-os-driven-pci-maxpayload-readreq-setup.patch -arch-nr-gpio.patch -kernel-overlayfs-v11.patch -kernel-fs-overlayfs-inode.patch -kernel-oom-proc-file-warning.patch -kernel-nowarn-sysctl.patch -kernel-generic-access-phys-null-check.patch -kernel-ubifs-xattr-symlinks-bugs.patch -kernel-fs-make-dumpable-2-require-fully-qualified-path.patch -kernel-coredump-warn-about-unsafe-suid_dumpable-core_patter.patch -kernel-enable-compiling-firmware-into-kernel-binary.patch -driver-run-time-cfi-byte-swapping.patch -driver-rtc-hw-clock-fix-up.patch -driver-i2c-mux-device-tree.patch -driver-pca954x-i2c-mux-deselect-on-exit-dtb-property.patch -driver-esdhc-p2020-broken-timeout.patch -driver-early-dma-allocator.patch -driver-pata-port-width.patch -driver-cy8c3245-hwmon.patch -driver-cy8c3245r1-hwmon.patch -driver-adt7470-knob-to-disable-smbus-timeout.patch -driver-gpio-mpc8xxx-do-not-set.patch -driver-smsc-emc2305-hwmon.patch -driver-at24-fix-odd-length-two-byte-access.patch -driver-eeprom-class.patch -driver-at24-eeprom-class.patch -driver-at24-byte-word-write-access.patch -driver-at24-smbus-addr16.patch -driver-at24-add-i2cblock-disable-flag.patch -driver-mtd-micron-spiroms.patch -driver-fsl-dpaa_eth.patch -driver-ds100df410-retimer.patch -driver-pca9505-i2c-gpio.patch -driver-hwmon-max6697.patch -driver-i2c-bus-intel-ismt.patch -driver-i2c-bus-intel-ismt-add-delay-param.patch -driver-i2c-bus-intel-ismt-header.patch -driver-i2c-bus-intel-avoton.patch -driver-i2c-bus-intel-i801-update.patch -driver-gpio-intel-sch.patch -driver-mfd-intel-centerton-lpc-sch.patch -driver-hwmon-max6620.patch -driver-hwmon-max6620-fix-rpm-calc.patch -driver-hwmon-pmbus-dni_dps460.patch -driver-support-intel-igb-bcm54616-phy.patch -driver-support-intel-igb-bcm5461s-phy.patch -driver-support-sff-8436-eeprom.patch -driver-s6000-i2c-gpio-mux.patch -platform-powerpc-85xx-Makefile.patch -platform-accton-as4600_54t.patch -platform-accton-as5610_52x.patch -platform-accton-as6700_32x.patch -platform-accton-as6701-32x.patch -platform-accton-5652.patch -platform-bcm98548xmc.patch -platform-cel-p2020.patch -platform-celestica-cpld-i2c.patch -platform-cumulus-p2020.patch -platform-dni-6448.patch -platform-dni-6448-i2c-mux.patch -platform-dni-7448.patch -platform-dni-c7448n.patch -platform-quanta-lb8.patch -platform-quanta-i2c-mux.patch -platform-quanta-lb9.patch -platform-quanta-ly2-ly2r.patch -platform-quanta-ly6-p2020.patch -platform-powerpc-accton-as4600-54t-r0.patch -platform-powerpc-accton-as5610-52x-r0.patch -platform-powerpc-quanta-lb9-r0.patch -platform-powerpc-quanta-ly2-r0.patch -platform-powerpc-dell-s4810-p2020-r0.patch -platform-powerpc-dni-7448-r0.patch -network-increase-max-igmp-groups.patch -network-bridge-rearrange-fdb-notifications.patch -network-bridge-fix-fdb-update-notify.patch -network-bridge-disable-sw-bridging.patch -network-bridge-make-path-cost-setting-persistent.patch -network-bridge-make-master-index-partof-rtmneigh-msh.patch -network-ipv6-add-knob-to-send-unsolicited-ND-on-link-layer-address-change.patch -network-ipv6-blackhole-route-support.patch -network-ipv4-fib-flush-dead-routes-notify.patch -network-ipv6-use-addrconf-get-prefix-route-for-prefix-route-lookup.patch -debian-cumulus-config-abi-ref.patch -debian-cumulus-controlfiles.patch -network-ipv6-add-ecmp-support.patch -network-bridge-stp-changes.patch -network-neigh-fix-neigh-update-notify.patch -network-bonding-no-initial-bond0.patch -network-virtio-net-speed-duplex.patch -network-add-xtables-match-and-target-extensions.patch -network-disable-hw-aclstats.patch -network-stp-sysctl.patch -network-bonding-advertise-slave-activity.patch -network-bonding-advertise-speed-duplex.patch -network-bonding-fix-min-links.patch -network-bridge-ipoptions-fix.patch -network-ipv4-include-append-flag-in-notification.patch -network-vxlan-support.patch -network-rtnl-fdb-add-del-remove-redundant-notification.patch -network-bridge-stp-carrier-check.patch -network-bridge-export-multicast-database-via-netlink.patch -network-bridge-fix-seq-check-in-br_mdb_dump.patch -network-bridge-notify-mdb-changes-via-netlink.patch -network-bridge-add-support-of-adding-and-deleting-mdb-entrie.patch -network-bridge-add-flags-to-distinguish-permanent-mdb-entire.patch -network-bridge-Do-not-unregister-all-PF_BRIDGE-rtnl-operatio.patch -network-bridge-Correctly-encode-addresses-when-dumping-mdb-e.patch -network-bridge-allow-unprivileged-users-add-delete-mdb.patch -network-bridge-mdb-notify.patch -network-bridge-Correctly-unregister-MDB-rtnetlink-handlers.patch -network-bridge-Add-br_multicast_start_querier.patch -network-bridge-Restart-queries-when-last-querier-expires.patch -network-bridge-Add-multicast_querier-toggle-and-disable-quer.patch -network-bridge-Fix-fatal-typo-in-setup-of-multicast_querier_.patch -network-bridge-fix-endian.patch -network-bridge-implement-multicast-fast-leave.patch -network-bridge-fix-icmpv6-endian-bug-and-other-sparse-warnin.patch -network-bridge-use-ipv4_is_local_multicast-helper.patch -network-bridge-use-the-bridge-IP-addr-as-source-addr-for-que.patch -network-bridge-send-query-as-soon-as-leave-is-received.patch -network-bridge-mld-get-rid-of-MLDV2_MRC-and-simplify-calcu.patch -network-bridge-igmp-ifupdown-fixes.patch -network-bridge-disable-snooping-if-there-is-no-querier.patch -network-bridge-don-t-try-to-update-timers-in-case-of-broken-.patch -network-bridge-mrouter-fix.patch -network-bridge-static-mcgrp-fix.patch -network-bridge-pvst.patch -network-bridge-mdb-hash.patch -network-mcast-maxvifs.patch -network-bridge-igmp-fast-leave.patch -network-bridge-querier-ifaddr.patch -network-bridge-igmpv3.patch -network-bridge-cdp-process.patch -network-add-port-genl.patch -network-ipv6-route-fix-multipath-duplicate-nexthops.patch -network-core-move-RTM_DELLINK-to-until-after-ndo-uninit.patch -network-tcp-md5sig-pseudoheader-calc-workaround.patch -network-ethtool-sfp-gang-support.patch -network-bonding-set-sys-mac-priority.patch -network-bridge-porting-new-driver.patch -network-bridge-vlan-range-support.patch -network-bridge-fdb-mdb-vlan-fix.patch -network-bridge-initial-mac.patch -network-bridge-static-addr.patch -network-bridge-stp-disabled-bpdu-forward.patch -network-neighbour-update-neighbour-h-to-latest-upstream.patch -network-vxlan-fix-fdb-update.patch -network-bonding-lacp-no-tx-full-duplex.patch -network-bridge-add-per-vlan-igmp-querier-support.patch -network-bridge-revert-v6-link-local-snoop.patch -network-bridge-mdb-unspecified-vlan.patch -network-bridge-mdb-static-del.patch -network-bridge-lacp-fallback.patch -network-bridge-mdb-timer.patch -network-bridge-mdb-replace.patch -network-bridge-fdb-del-fix.patch -network-bridge-mdb-leave-dually-connected.patch -network-bridge-move-logging-to-pr-debug.patch -network-vxlan-self-replication.patch -network-bridge-fdb-show-filter.patch -network-bridge-fdb-netlink-dump-interface-in-par-with-brctl.patch -network-bridge-fdb-add-check-port-status.patch -network-vxlan-ip-select-ident-parameter-iph-to-skb.patch -network-bridge-fix-fdb-show-filter.patch -network-bridge-address-from-brport -network-bridge-mdb-dump-vlan.patch -network-virt-ethtool.patch -network-mdb-top-change.patch -network-bridge-mac-move-notify-vm.patch -network-bridge-fix-link-local-rx-drop-count.patch -network-port-genl-add-ethtool-settings-pull.patch -network-bridge-disable-mixed-vlans.patch -network-bonding-fix-inconsistent-stats.patch -network-bridge-local-fdb-delete-check.patch -network-bridge-prevent-fdb-insert-in-disallowed-vlan.patch -network-bridge-default-pvid.patch -network-bridge-get-default-pvid.patch -network-bridge-filtering-support-for-default-pvid.patch -network-bridge-fix-pvid-delete.patch -network-bridge-vlan-filter-auto-enable.patch -network-bridge-fdb-add-self.patch -network-rtnetlink-provide-api-for-getting-and-setting-slave-info.patch -network-bonding-cumulus-add-support-for-RTM_GETLINK.patch -network-bonding-create-netlink-event-when-bonding-option-changes.patch -network-bonding-rtnl-dump-lacp-fallback-support.patch -network-bonding-fix-bond-open-slave-state.patch -arch-powerpc-remove-arch-specific-overrides-of-panic_timeout.patch -kernel-panic-Make-panic_timeout-configurable.patch -network-arp-allow-per-if-arp_accept.patch -ethtool-stats-fix-kzalloc-flags.patch -network-bonding-lacp-fallback-check-bonding-mode.patch -debian-postinstall-call-depmod.patch -network-bridge-fdb-show-fix-filter-by-bridge.patch -network-link-routes-and-carrier.patch -network-virtio-net-ethtool-set-settings.patch -network-bonding-fix-race-between-sysfs-and-bond_enslave.patch -network-fix-dead-route-issues.patch -network-bridge-allow-fdb-replace-in-block-state.patch -network-fixup-ipv6-route-link-issues.patch -network-port-ethtool-rtnl-lock-handling-fixes.patch -network-bridge-dont-install-local-mac.patch -driver-hwmon-adt7475-clear-pwm-invert-bit.patch -network-core-fix-notify-for-move-RTM_DELLINK-to-until-after-ndo-uninit.patch -replace-fallback-with-bypass.patch -network-bonding-lacp-fix-incorrect-mux-state.patch -network-bonding-clag.patch -network-bridge-remove-vid-end-check.patch -network-ipv6-dont-disable-interface-with-no-addrs.patch -network-bridge-solicited-node-forward.patch -network-ipv6-fib-fix-fib-dump-restart.patch -network-ipv6-fib-fix-fib-dump-restart-next-node.patch -network-dev-net-call-notifiers-for-mtu-change-even-if-iface-is-not-up.patch -network-fix-route-lookup-failures-when-link-down.patch -network-bonding-fix-scheduling-while-atomic.patch -network-bridge-report-supression.patch -platform-bcm98548xmc-fix-reset-init.patch -network-port-ethtool-get-return-success-on-enodata.patch -arch-powerpc-cacheinfo.patch -network-port-ethtool-handle-errors.patch -network-vxlan-fdb-update-used.patch -network-vxlan-fdb-update-hardware-forwarding.patch -network-bridge-mlag-peer-dual-link.patch -network-bridge-fix-crash-when-set-mac-address-of-br-interfac.patch -network-core-proto-down.patch -network-bonding-clag-proto-down.patch -network-bridge-disable-multiple-sub-intfs-on-same-port.patch -network-virtio-proto-down.patch -overlayfs_notify.patch -driver-pca954x-i2c-mux-deselect-on-exit-config-option.patch -driver-mfd-lpc-ich.patch -driver-watchdog-itco-wd.patch -driver-broadcom-tigon3.patch -arch-intel-reboot-cf9-cold.patch -drivers-hwmon-adm1021-detect.patch -drivers-i2c-busses-i2c-isch-timeout.patch -CVE-2016-5195.patch -drivers-net-ethernet-broadcom-tg3-preamble-reset.patch