12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
21d3bb996SDavid Gibson /*
33396c782SPaul Gortmaker * drivers/net/ethernet/ibm/emac/core.h
41d3bb996SDavid Gibson *
51d3bb996SDavid Gibson * Driver for PowerPC 4xx on-chip ethernet controller.
61d3bb996SDavid Gibson *
717cf803aSBenjamin Herrenschmidt * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
817cf803aSBenjamin Herrenschmidt * <benh@kernel.crashing.org>
917cf803aSBenjamin Herrenschmidt *
1017cf803aSBenjamin Herrenschmidt * Based on the arch/ppc version of the driver:
1117cf803aSBenjamin Herrenschmidt *
121d3bb996SDavid Gibson * Copyright (c) 2004, 2005 Zultys Technologies.
131d3bb996SDavid Gibson * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
141d3bb996SDavid Gibson *
151d3bb996SDavid Gibson * Based on original work by
161d3bb996SDavid Gibson * Armin Kuster <akuster@mvista.com>
171d3bb996SDavid Gibson * Johnnie Peters <jpeters@mvista.com>
181d3bb996SDavid Gibson * Copyright 2000, 2001 MontaVista Softare Inc.
191d3bb996SDavid Gibson */
201d3bb996SDavid Gibson #ifndef __IBM_NEWEMAC_CORE_H
211d3bb996SDavid Gibson #define __IBM_NEWEMAC_CORE_H
221d3bb996SDavid Gibson
231d3bb996SDavid Gibson #include <linux/module.h>
241d3bb996SDavid Gibson #include <linux/list.h>
251d3bb996SDavid Gibson #include <linux/kernel.h>
261d3bb996SDavid Gibson #include <linux/interrupt.h>
271d3bb996SDavid Gibson #include <linux/netdevice.h>
281d3bb996SDavid Gibson #include <linux/dma-mapping.h>
291d3bb996SDavid Gibson #include <linux/spinlock.h>
305a0e3ad6STejun Heo #include <linux/slab.h>
311d3bb996SDavid Gibson
321d3bb996SDavid Gibson #include <asm/io.h>
331d3bb996SDavid Gibson #include <asm/dcr.h>
341d3bb996SDavid Gibson
351d3bb996SDavid Gibson #include "emac.h"
361d3bb996SDavid Gibson #include "phy.h"
371d3bb996SDavid Gibson #include "zmii.h"
381d3bb996SDavid Gibson #include "rgmii.h"
391d3bb996SDavid Gibson #include "mal.h"
401d3bb996SDavid Gibson #include "tah.h"
411d3bb996SDavid Gibson #include "debug.h"
421d3bb996SDavid Gibson
433b3bceefSTony Breeds #define NUM_TX_BUFF CONFIG_IBM_EMAC_TXB
443b3bceefSTony Breeds #define NUM_RX_BUFF CONFIG_IBM_EMAC_RXB
451d3bb996SDavid Gibson
461d3bb996SDavid Gibson /* Simple sanity check */
471d3bb996SDavid Gibson #if NUM_TX_BUFF > 256 || NUM_RX_BUFF > 256
481d3bb996SDavid Gibson #error Invalid number of buffer descriptors (greater than 256)
491d3bb996SDavid Gibson #endif
501d3bb996SDavid Gibson
511d3bb996SDavid Gibson #define EMAC_MIN_MTU 46
521d3bb996SDavid Gibson
531d3bb996SDavid Gibson /* Maximum L2 header length (VLAN tagged, no FCS) */
541d3bb996SDavid Gibson #define EMAC_MTU_OVERHEAD (6 * 2 + 2 + 4)
551d3bb996SDavid Gibson
561d3bb996SDavid Gibson /* RX BD size for the given MTU */
emac_rx_size(int mtu)571d3bb996SDavid Gibson static inline int emac_rx_size(int mtu)
581d3bb996SDavid Gibson {
591d3bb996SDavid Gibson if (mtu > ETH_DATA_LEN)
601d3bb996SDavid Gibson return MAL_MAX_RX_SIZE;
611d3bb996SDavid Gibson else
621d3bb996SDavid Gibson return mal_rx_size(ETH_DATA_LEN + EMAC_MTU_OVERHEAD);
631d3bb996SDavid Gibson }
641d3bb996SDavid Gibson
651d3bb996SDavid Gibson /* Size of RX skb for the given MTU */
emac_rx_skb_size(int mtu)661d3bb996SDavid Gibson static inline int emac_rx_skb_size(int mtu)
671d3bb996SDavid Gibson {
681d3bb996SDavid Gibson int size = max(mtu + EMAC_MTU_OVERHEAD, emac_rx_size(mtu));
6922087d65SChristian Lamparter
7022087d65SChristian Lamparter return SKB_DATA_ALIGN(size + NET_IP_ALIGN) + NET_SKB_PAD;
711d3bb996SDavid Gibson }
721d3bb996SDavid Gibson
731d3bb996SDavid Gibson /* RX DMA sync size */
emac_rx_sync_size(int mtu)741d3bb996SDavid Gibson static inline int emac_rx_sync_size(int mtu)
751d3bb996SDavid Gibson {
7622087d65SChristian Lamparter return SKB_DATA_ALIGN(emac_rx_size(mtu) + NET_IP_ALIGN);
771d3bb996SDavid Gibson }
781d3bb996SDavid Gibson
791d3bb996SDavid Gibson /* Driver statistcs is split into two parts to make it more cache friendly:
801d3bb996SDavid Gibson * - normal statistics (packet count, etc)
811d3bb996SDavid Gibson * - error statistics
821d3bb996SDavid Gibson *
831d3bb996SDavid Gibson * When statistics is requested by ethtool, these parts are concatenated,
841d3bb996SDavid Gibson * normal one goes first.
851d3bb996SDavid Gibson *
861d3bb996SDavid Gibson * Please, keep these structures in sync with emac_stats_keys.
871d3bb996SDavid Gibson */
881d3bb996SDavid Gibson
891d3bb996SDavid Gibson /* Normal TX/RX Statistics */
901d3bb996SDavid Gibson struct emac_stats {
911d3bb996SDavid Gibson u64 rx_packets;
921d3bb996SDavid Gibson u64 rx_bytes;
931d3bb996SDavid Gibson u64 tx_packets;
941d3bb996SDavid Gibson u64 tx_bytes;
951d3bb996SDavid Gibson u64 rx_packets_csum;
961d3bb996SDavid Gibson u64 tx_packets_csum;
971d3bb996SDavid Gibson };
981d3bb996SDavid Gibson
991d3bb996SDavid Gibson /* Error statistics */
1001d3bb996SDavid Gibson struct emac_error_stats {
1011d3bb996SDavid Gibson u64 tx_undo;
1021d3bb996SDavid Gibson
1031d3bb996SDavid Gibson /* Software RX Errors */
1041d3bb996SDavid Gibson u64 rx_dropped_stack;
1051d3bb996SDavid Gibson u64 rx_dropped_oom;
1061d3bb996SDavid Gibson u64 rx_dropped_error;
1071d3bb996SDavid Gibson u64 rx_dropped_resize;
1081d3bb996SDavid Gibson u64 rx_dropped_mtu;
1091d3bb996SDavid Gibson u64 rx_stopped;
1101d3bb996SDavid Gibson /* BD reported RX errors */
1111d3bb996SDavid Gibson u64 rx_bd_errors;
1121d3bb996SDavid Gibson u64 rx_bd_overrun;
1131d3bb996SDavid Gibson u64 rx_bd_bad_packet;
1141d3bb996SDavid Gibson u64 rx_bd_runt_packet;
1151d3bb996SDavid Gibson u64 rx_bd_short_event;
1161d3bb996SDavid Gibson u64 rx_bd_alignment_error;
1171d3bb996SDavid Gibson u64 rx_bd_bad_fcs;
1181d3bb996SDavid Gibson u64 rx_bd_packet_too_long;
1191d3bb996SDavid Gibson u64 rx_bd_out_of_range;
1201d3bb996SDavid Gibson u64 rx_bd_in_range;
1211d3bb996SDavid Gibson /* EMAC IRQ reported RX errors */
1221d3bb996SDavid Gibson u64 rx_parity;
1231d3bb996SDavid Gibson u64 rx_fifo_overrun;
1241d3bb996SDavid Gibson u64 rx_overrun;
1251d3bb996SDavid Gibson u64 rx_bad_packet;
1261d3bb996SDavid Gibson u64 rx_runt_packet;
1271d3bb996SDavid Gibson u64 rx_short_event;
1281d3bb996SDavid Gibson u64 rx_alignment_error;
1291d3bb996SDavid Gibson u64 rx_bad_fcs;
1301d3bb996SDavid Gibson u64 rx_packet_too_long;
1311d3bb996SDavid Gibson u64 rx_out_of_range;
1321d3bb996SDavid Gibson u64 rx_in_range;
1331d3bb996SDavid Gibson
1341d3bb996SDavid Gibson /* Software TX Errors */
1351d3bb996SDavid Gibson u64 tx_dropped;
1361d3bb996SDavid Gibson /* BD reported TX errors */
1371d3bb996SDavid Gibson u64 tx_bd_errors;
1381d3bb996SDavid Gibson u64 tx_bd_bad_fcs;
1391d3bb996SDavid Gibson u64 tx_bd_carrier_loss;
1401d3bb996SDavid Gibson u64 tx_bd_excessive_deferral;
1411d3bb996SDavid Gibson u64 tx_bd_excessive_collisions;
1421d3bb996SDavid Gibson u64 tx_bd_late_collision;
1431d3bb996SDavid Gibson u64 tx_bd_multple_collisions;
1441d3bb996SDavid Gibson u64 tx_bd_single_collision;
1451d3bb996SDavid Gibson u64 tx_bd_underrun;
1461d3bb996SDavid Gibson u64 tx_bd_sqe;
1471d3bb996SDavid Gibson /* EMAC IRQ reported TX errors */
1481d3bb996SDavid Gibson u64 tx_parity;
1491d3bb996SDavid Gibson u64 tx_underrun;
1501d3bb996SDavid Gibson u64 tx_sqe;
1511d3bb996SDavid Gibson u64 tx_errors;
1521d3bb996SDavid Gibson };
1531d3bb996SDavid Gibson
1541d3bb996SDavid Gibson #define EMAC_ETHTOOL_STATS_COUNT ((sizeof(struct emac_stats) + \
1551d3bb996SDavid Gibson sizeof(struct emac_error_stats)) \
1561d3bb996SDavid Gibson / sizeof(u64))
1571d3bb996SDavid Gibson
1581d3bb996SDavid Gibson struct emac_instance {
1591d3bb996SDavid Gibson struct net_device *ndev;
1601d3bb996SDavid Gibson struct emac_regs __iomem *emacp;
1612dc11581SGrant Likely struct platform_device *ofdev;
1621d3bb996SDavid Gibson struct device_node **blist; /* bootlist entry */
1631d3bb996SDavid Gibson
1641d3bb996SDavid Gibson /* MAL linkage */
1651d3bb996SDavid Gibson u32 mal_ph;
1662dc11581SGrant Likely struct platform_device *mal_dev;
1671d3bb996SDavid Gibson u32 mal_rx_chan;
1681d3bb996SDavid Gibson u32 mal_tx_chan;
1691d3bb996SDavid Gibson struct mal_instance *mal;
1701d3bb996SDavid Gibson struct mal_commac commac;
1711d3bb996SDavid Gibson
1721d3bb996SDavid Gibson /* PHY infos */
173f9218617SAndrew Lunn phy_interface_t phy_mode;
1741d3bb996SDavid Gibson u32 phy_map;
1751d3bb996SDavid Gibson u32 phy_address;
1761d3bb996SDavid Gibson u32 phy_feat_exc;
1771d3bb996SDavid Gibson struct mii_phy phy;
1781d3bb996SDavid Gibson struct mutex link_lock;
1791d3bb996SDavid Gibson struct delayed_work link_work;
1801d3bb996SDavid Gibson int link_polling;
1811d3bb996SDavid Gibson
1829e3cb294SVictor Gallardo /* GPCS PHY infos */
1839e3cb294SVictor Gallardo u32 gpcs_address;
1849e3cb294SVictor Gallardo
1851d3bb996SDavid Gibson /* Shared MDIO if any */
1861d3bb996SDavid Gibson u32 mdio_ph;
1872dc11581SGrant Likely struct platform_device *mdio_dev;
1881d3bb996SDavid Gibson struct emac_instance *mdio_instance;
1891d3bb996SDavid Gibson struct mutex mdio_lock;
1901d3bb996SDavid Gibson
1911d3bb996SDavid Gibson /* ZMII infos if any */
1921d3bb996SDavid Gibson u32 zmii_ph;
1931d3bb996SDavid Gibson u32 zmii_port;
1942dc11581SGrant Likely struct platform_device *zmii_dev;
1951d3bb996SDavid Gibson
1961d3bb996SDavid Gibson /* RGMII infos if any */
1971d3bb996SDavid Gibson u32 rgmii_ph;
1981d3bb996SDavid Gibson u32 rgmii_port;
1992dc11581SGrant Likely struct platform_device *rgmii_dev;
2001d3bb996SDavid Gibson
2011d3bb996SDavid Gibson /* TAH infos if any */
2021d3bb996SDavid Gibson u32 tah_ph;
2031d3bb996SDavid Gibson u32 tah_port;
2042dc11581SGrant Likely struct platform_device *tah_dev;
2051d3bb996SDavid Gibson
2061d3bb996SDavid Gibson /* IRQs */
2071d3bb996SDavid Gibson int wol_irq;
2081d3bb996SDavid Gibson int emac_irq;
2091d3bb996SDavid Gibson
2101d3bb996SDavid Gibson /* OPB bus frequency in Mhz */
2111d3bb996SDavid Gibson u32 opb_bus_freq;
2121d3bb996SDavid Gibson
2131d3bb996SDavid Gibson /* Cell index within an ASIC (for clk mgmnt) */
2141d3bb996SDavid Gibson u32 cell_index;
2151d3bb996SDavid Gibson
2161d3bb996SDavid Gibson /* Max supported MTU */
2171d3bb996SDavid Gibson u32 max_mtu;
2181d3bb996SDavid Gibson
2191d3bb996SDavid Gibson /* Feature bits (from probe table) */
2201d3bb996SDavid Gibson unsigned int features;
2211d3bb996SDavid Gibson
2221d3bb996SDavid Gibson /* Tx and Rx fifo sizes & other infos in bytes */
2231d3bb996SDavid Gibson u32 tx_fifo_size;
2241d3bb996SDavid Gibson u32 tx_fifo_size_gige;
2251d3bb996SDavid Gibson u32 rx_fifo_size;
2261d3bb996SDavid Gibson u32 rx_fifo_size_gige;
2271d3bb996SDavid Gibson u32 fifo_entry_size;
2281d3bb996SDavid Gibson u32 mal_burst_size; /* move to MAL ? */
2291d3bb996SDavid Gibson
23005781ccdSGrant Erickson /* IAHT and GAHT filter parameterization */
23105781ccdSGrant Erickson u32 xaht_slots_shift;
23205781ccdSGrant Erickson u32 xaht_width_shift;
23305781ccdSGrant Erickson
2341d3bb996SDavid Gibson /* Descriptor management
2351d3bb996SDavid Gibson */
2361d3bb996SDavid Gibson struct mal_descriptor *tx_desc;
2371d3bb996SDavid Gibson int tx_cnt;
2381d3bb996SDavid Gibson int tx_slot;
2391d3bb996SDavid Gibson int ack_slot;
2401d3bb996SDavid Gibson
2411d3bb996SDavid Gibson struct mal_descriptor *rx_desc;
2421d3bb996SDavid Gibson int rx_slot;
2431d3bb996SDavid Gibson struct sk_buff *rx_sg_skb; /* 1 */
2441d3bb996SDavid Gibson int rx_skb_size;
2451d3bb996SDavid Gibson int rx_sync_size;
2461d3bb996SDavid Gibson
2471d3bb996SDavid Gibson struct sk_buff *tx_skb[NUM_TX_BUFF];
2481d3bb996SDavid Gibson struct sk_buff *rx_skb[NUM_RX_BUFF];
2491d3bb996SDavid Gibson
2501d3bb996SDavid Gibson /* Stats
2511d3bb996SDavid Gibson */
2521d3bb996SDavid Gibson struct emac_error_stats estats;
2531d3bb996SDavid Gibson struct emac_stats stats;
2541d3bb996SDavid Gibson
2551d3bb996SDavid Gibson /* Misc
2561d3bb996SDavid Gibson */
2571d3bb996SDavid Gibson int reset_failed;
2581d3bb996SDavid Gibson int stop_timeout; /* in us */
2591d3bb996SDavid Gibson int no_mcast;
2601d3bb996SDavid Gibson int mcast_pending;
26161dbceceSBenjamin Herrenschmidt int opened;
2621d3bb996SDavid Gibson struct work_struct reset_work;
2631d3bb996SDavid Gibson spinlock_t lock;
2641d3bb996SDavid Gibson };
2651d3bb996SDavid Gibson
2661d3bb996SDavid Gibson /*
2671d3bb996SDavid Gibson * Features of various EMAC implementations
2681d3bb996SDavid Gibson */
2691d3bb996SDavid Gibson
2701d3bb996SDavid Gibson /*
2711d3bb996SDavid Gibson * No flow control on 40x according to the original driver
2721d3bb996SDavid Gibson */
2731d3bb996SDavid Gibson #define EMAC_FTR_NO_FLOW_CONTROL_40x 0x00000001
2741d3bb996SDavid Gibson /*
2751d3bb996SDavid Gibson * Cell is an EMAC4
2761d3bb996SDavid Gibson */
2771d3bb996SDavid Gibson #define EMAC_FTR_EMAC4 0x00000002
2781d3bb996SDavid Gibson /*
2791d3bb996SDavid Gibson * For the 440SPe, AMCC inexplicably changed the polarity of
2801d3bb996SDavid Gibson * the "operation complete" bit in the MII control register.
2811d3bb996SDavid Gibson */
2821d3bb996SDavid Gibson #define EMAC_FTR_STACR_OC_INVERT 0x00000004
2831d3bb996SDavid Gibson /*
2841d3bb996SDavid Gibson * Set if we have a TAH.
2851d3bb996SDavid Gibson */
2861d3bb996SDavid Gibson #define EMAC_FTR_HAS_TAH 0x00000008
2871d3bb996SDavid Gibson /*
2881d3bb996SDavid Gibson * Set if we have a ZMII.
2891d3bb996SDavid Gibson */
2901d3bb996SDavid Gibson #define EMAC_FTR_HAS_ZMII 0x00000010
2911d3bb996SDavid Gibson /*
2921d3bb996SDavid Gibson * Set if we have a RGMII.
2931d3bb996SDavid Gibson */
2941d3bb996SDavid Gibson #define EMAC_FTR_HAS_RGMII 0x00000020
2951d3bb996SDavid Gibson /*
296bff713b5SBenjamin Herrenschmidt * Set if we have new type STACR with STAOPC
2971d3bb996SDavid Gibson */
298bff713b5SBenjamin Herrenschmidt #define EMAC_FTR_HAS_NEW_STACR 0x00000040
2990925ab5dSValentine Barshak /*
3000925ab5dSValentine Barshak * Set if we need phy clock workaround for 440gx
3010925ab5dSValentine Barshak */
3020925ab5dSValentine Barshak #define EMAC_FTR_440GX_PHY_CLK_FIX 0x00000080
30311121e30SValentine Barshak /*
30411121e30SValentine Barshak * Set if we need phy clock workaround for 440ep or 440gr
30511121e30SValentine Barshak */
30611121e30SValentine Barshak #define EMAC_FTR_440EP_PHY_CLK_FIX 0x00000100
30705781ccdSGrant Erickson /*
30805781ccdSGrant Erickson * The 405EX and 460EX contain the EMAC4SYNC core
30905781ccdSGrant Erickson */
31005781ccdSGrant Erickson #define EMAC_FTR_EMAC4SYNC 0x00000200
3119e3cb294SVictor Gallardo /*
3129e3cb294SVictor Gallardo * Set if we need phy clock workaround for 460ex or 460gt
3139e3cb294SVictor Gallardo */
3149e3cb294SVictor Gallardo #define EMAC_FTR_460EX_PHY_CLK_FIX 0x00000400
315ae5d3372SDuc Dang /*
316ae5d3372SDuc Dang * APM821xx requires Jumbo frame size set explicitly
317ae5d3372SDuc Dang */
318ae5d3372SDuc Dang #define EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE 0x00000800
319ae5d3372SDuc Dang /*
320ae5d3372SDuc Dang * APM821xx does not support Half Duplex mode
321ae5d3372SDuc Dang */
322ae5d3372SDuc Dang #define EMAC_FTR_APM821XX_NO_HALF_DUPLEX 0x00001000
3231d3bb996SDavid Gibson
3241d3bb996SDavid Gibson /* Right now, we don't quite handle the always/possible masks on the
3251d3bb996SDavid Gibson * most optimal way as we don't have a way to say something like
3261d3bb996SDavid Gibson * always EMAC4. Patches welcome.
3271d3bb996SDavid Gibson */
3281d3bb996SDavid Gibson enum {
3291d3bb996SDavid Gibson EMAC_FTRS_ALWAYS = 0,
3301d3bb996SDavid Gibson
3311d3bb996SDavid Gibson EMAC_FTRS_POSSIBLE =
3323b3bceefSTony Breeds #ifdef CONFIG_IBM_EMAC_EMAC4
33305781ccdSGrant Erickson EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC |
33405781ccdSGrant Erickson EMAC_FTR_HAS_NEW_STACR |
3350925ab5dSValentine Barshak EMAC_FTR_STACR_OC_INVERT | EMAC_FTR_440GX_PHY_CLK_FIX |
3361d3bb996SDavid Gibson #endif
3373b3bceefSTony Breeds #ifdef CONFIG_IBM_EMAC_TAH
3381d3bb996SDavid Gibson EMAC_FTR_HAS_TAH |
3391d3bb996SDavid Gibson #endif
3403b3bceefSTony Breeds #ifdef CONFIG_IBM_EMAC_ZMII
3411d3bb996SDavid Gibson EMAC_FTR_HAS_ZMII |
3421d3bb996SDavid Gibson #endif
3433b3bceefSTony Breeds #ifdef CONFIG_IBM_EMAC_RGMII
3441d3bb996SDavid Gibson EMAC_FTR_HAS_RGMII |
3451d3bb996SDavid Gibson #endif
3463b3bceefSTony Breeds #ifdef CONFIG_IBM_EMAC_NO_FLOW_CTRL
347b68d185aSJosh Boyer EMAC_FTR_NO_FLOW_CONTROL_40x |
348b68d185aSJosh Boyer #endif
3499e3cb294SVictor Gallardo EMAC_FTR_460EX_PHY_CLK_FIX |
350ae5d3372SDuc Dang EMAC_FTR_440EP_PHY_CLK_FIX |
351ae5d3372SDuc Dang EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE |
352ae5d3372SDuc Dang EMAC_FTR_APM821XX_NO_HALF_DUPLEX,
3531d3bb996SDavid Gibson };
3541d3bb996SDavid Gibson
emac_has_feature(struct emac_instance * dev,unsigned long feature)3551d3bb996SDavid Gibson static inline int emac_has_feature(struct emac_instance *dev,
3561d3bb996SDavid Gibson unsigned long feature)
3571d3bb996SDavid Gibson {
3581d3bb996SDavid Gibson return (EMAC_FTRS_ALWAYS & feature) ||
3591d3bb996SDavid Gibson (EMAC_FTRS_POSSIBLE & dev->features & feature);
3601d3bb996SDavid Gibson }
3611d3bb996SDavid Gibson
36205781ccdSGrant Erickson /*
36305781ccdSGrant Erickson * Various instances of the EMAC core have varying 1) number of
36405781ccdSGrant Erickson * address match slots, 2) width of the registers for handling address
36505781ccdSGrant Erickson * match slots, 3) number of registers for handling address match
36605781ccdSGrant Erickson * slots and 4) base offset for those registers.
36705781ccdSGrant Erickson *
36805781ccdSGrant Erickson * These macros and inlines handle these differences based on
36905781ccdSGrant Erickson * parameters supplied by the device structure which are, in turn,
37005781ccdSGrant Erickson * initialized based on the "compatible" entry in the device tree.
37105781ccdSGrant Erickson */
37205781ccdSGrant Erickson
37305781ccdSGrant Erickson #define EMAC4_XAHT_SLOTS_SHIFT 6
37405781ccdSGrant Erickson #define EMAC4_XAHT_WIDTH_SHIFT 4
37505781ccdSGrant Erickson
37605781ccdSGrant Erickson #define EMAC4SYNC_XAHT_SLOTS_SHIFT 8
37705781ccdSGrant Erickson #define EMAC4SYNC_XAHT_WIDTH_SHIFT 5
37805781ccdSGrant Erickson
379ee4fccbeSKees Cook /* The largest span between slots and widths above is 3 */
380ee4fccbeSKees Cook #define EMAC_XAHT_MAX_REGS (1 << 3)
381ee4fccbeSKees Cook
38205781ccdSGrant Erickson #define EMAC_XAHT_SLOTS(dev) (1 << (dev)->xaht_slots_shift)
38305781ccdSGrant Erickson #define EMAC_XAHT_WIDTH(dev) (1 << (dev)->xaht_width_shift)
38405781ccdSGrant Erickson #define EMAC_XAHT_REGS(dev) (1 << ((dev)->xaht_slots_shift - \
38505781ccdSGrant Erickson (dev)->xaht_width_shift))
38605781ccdSGrant Erickson
38705781ccdSGrant Erickson #define EMAC_XAHT_CRC_TO_SLOT(dev, crc) \
38805781ccdSGrant Erickson ((EMAC_XAHT_SLOTS(dev) - 1) - \
38905781ccdSGrant Erickson ((crc) >> ((sizeof (u32) * BITS_PER_BYTE) - \
39005781ccdSGrant Erickson (dev)->xaht_slots_shift)))
39105781ccdSGrant Erickson
39205781ccdSGrant Erickson #define EMAC_XAHT_SLOT_TO_REG(dev, slot) \
39305781ccdSGrant Erickson ((slot) >> (dev)->xaht_width_shift)
39405781ccdSGrant Erickson
39505781ccdSGrant Erickson #define EMAC_XAHT_SLOT_TO_MASK(dev, slot) \
39605781ccdSGrant Erickson ((u32)(1 << (EMAC_XAHT_WIDTH(dev) - 1)) >> \
39705781ccdSGrant Erickson ((slot) & (u32)(EMAC_XAHT_WIDTH(dev) - 1)))
39805781ccdSGrant Erickson
emac_xaht_base(struct emac_instance * dev)3995aa3b55bSSimon Horman static inline u32 __iomem *emac_xaht_base(struct emac_instance *dev)
40005781ccdSGrant Erickson {
40105781ccdSGrant Erickson struct emac_regs __iomem *p = dev->emacp;
40205781ccdSGrant Erickson int offset;
40305781ccdSGrant Erickson
40405781ccdSGrant Erickson /* The first IAHT entry always is the base of the block of
40505781ccdSGrant Erickson * IAHT and GAHT registers.
40605781ccdSGrant Erickson */
40705781ccdSGrant Erickson if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC))
40805781ccdSGrant Erickson offset = offsetof(struct emac_regs, u1.emac4sync.iaht1);
40905781ccdSGrant Erickson else
41005781ccdSGrant Erickson offset = offsetof(struct emac_regs, u0.emac4.iaht1);
41105781ccdSGrant Erickson
4125aa3b55bSSimon Horman return (u32 __iomem *)((__force ptrdiff_t)p + offset);
41305781ccdSGrant Erickson }
41405781ccdSGrant Erickson
emac_gaht_base(struct emac_instance * dev)4155aa3b55bSSimon Horman static inline u32 __iomem *emac_gaht_base(struct emac_instance *dev)
41605781ccdSGrant Erickson {
41705781ccdSGrant Erickson /* GAHT registers always come after an identical number of
41805781ccdSGrant Erickson * IAHT registers.
41905781ccdSGrant Erickson */
420807540baSEric Dumazet return emac_xaht_base(dev) + EMAC_XAHT_REGS(dev);
42105781ccdSGrant Erickson }
42205781ccdSGrant Erickson
emac_iaht_base(struct emac_instance * dev)42305781ccdSGrant Erickson static inline u32 *emac_iaht_base(struct emac_instance *dev)
42405781ccdSGrant Erickson {
42505781ccdSGrant Erickson /* IAHT registers always come before an identical number of
42605781ccdSGrant Erickson * GAHT registers.
42705781ccdSGrant Erickson */
428807540baSEric Dumazet return emac_xaht_base(dev);
42905781ccdSGrant Erickson }
4301d3bb996SDavid Gibson
4311d3bb996SDavid Gibson /* Ethtool get_regs complex data.
4321d3bb996SDavid Gibson * We want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH
4331d3bb996SDavid Gibson * when available.
4341d3bb996SDavid Gibson *
4351d3bb996SDavid Gibson * Returned BLOB consists of the ibm_emac_ethtool_regs_hdr,
4361d3bb996SDavid Gibson * MAL registers, EMAC registers and optional ZMII, RGMII, TAH registers.
4371d3bb996SDavid Gibson * Each register component is preceded with emac_ethtool_regs_subhdr.
4381d3bb996SDavid Gibson * Order of the optional headers follows their relative bit posititions
4391d3bb996SDavid Gibson * in emac_ethtool_regs_hdr.components
4401d3bb996SDavid Gibson */
4411d3bb996SDavid Gibson #define EMAC_ETHTOOL_REGS_ZMII 0x00000001
4421d3bb996SDavid Gibson #define EMAC_ETHTOOL_REGS_RGMII 0x00000002
4431d3bb996SDavid Gibson #define EMAC_ETHTOOL_REGS_TAH 0x00000004
4441d3bb996SDavid Gibson
4451d3bb996SDavid Gibson struct emac_ethtool_regs_hdr {
4461d3bb996SDavid Gibson u32 components;
4471d3bb996SDavid Gibson };
4481d3bb996SDavid Gibson
4491d3bb996SDavid Gibson struct emac_ethtool_regs_subhdr {
4501d3bb996SDavid Gibson u32 version;
4511d3bb996SDavid Gibson u32 index;
4521d3bb996SDavid Gibson };
4531d3bb996SDavid Gibson
454661dfc65SIvan Mikhaylov #define EMAC_ETHTOOL_REGS_VER 3
455661dfc65SIvan Mikhaylov #define EMAC4_ETHTOOL_REGS_VER 4
456661dfc65SIvan Mikhaylov #define EMAC4SYNC_ETHTOOL_REGS_VER 5
45705781ccdSGrant Erickson
4581d3bb996SDavid Gibson #endif /* __IBM_NEWEMAC_CORE_H */
459