Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 833716e0 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'stmmac-GMAC4.x'



Alexandre TORGUE says:

====================
Enhance stmmac driver to support GMAC4.x IP

This is a subset of patch to enhance current stmmac driver to support
new GMAC4.x chips. New set of callbacks is defined to support this new
family: descriptors, dma, core.

One of main changes of GMAC 4.xx IP is descriptors management.
 -descriptors are only used in ring mode.
 -A descriptor is composed of 4 32bits registers (no more extended
  descriptors)
 -descriptor mechanism (Tx for example, but it is exactly the same for RX):
 -useful registers:
  -DMA_CH#_TxDesc_Ring_Len: length of transmit descriptor ring
  -DMA_CH#_TxDesc_List_Address: start address of the ring
  -DMA_CH#_TxDesc_Tail_Pointer: address of the last descriptor to send + 1.
  -DMA_CH#_TxDesc_Current_App_TxDesc: address of the current descriptor

 -The descriptor Tail Pointer register contains the pointer to the
  descriptor address (N). The base address and the current
  descriptor decide the address of the current descriptor that the
  DMA can process. The descriptors up to one location less than the
  one indicated by the descriptor tail pointer (N-1) are owned by
  the DMA. The DMA continues to process the descriptors until the
  following condition occurs:
  "current descriptor pointer == Descriptor Tail pointer"

  Then the DMA goes into suspend mode. The application must perform
  a write to descriptor tail pointer register and update the tail
  pointer to have the following condition and to start a new transfer:
  "current descriptor pointer < Descriptor tail pointer"

  The DMA automatically wraps around the base address when the end
  of ring is reached.

New features are available on IP:
 -TSO (TCP Segmentation Offload) for TX only
 -Split header: to have header and payload in 2 different buffers (not yet implemented)

Below some throughput figures obtained on some boxes:

                        iperf (mbps)
--------------------------------------
                       tcp     udp
                    tx   rx   tx  rx
                     -----------------
    GMAC4.x         935  930  750 800

Note: There is a change in 4.10a databook on bitfield mapping of DMA_CHANx_INTR_ENA register.
This requires to have é diffrent set of callbacks between IP 4.00a and 4.10a.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5ada37b5 91979b9d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ Optional properties:
	- snps,fb: fixed-burst
	- snps,mb: mixed-burst
	- snps,rb: rebuild INCRx Burst
	- snps,tso: this enables the TSO feature otherwise it will be managed by
	    MAC HW capability register.
- mdio: with compatible = "snps,dwmac-mdio", create and register mdio bus.

Examples:
+38 −6
Original line number Diff line number Diff line
       STMicroelectronics 10/100/1000 Synopsys Ethernet driver

Copyright (C) 2007-2014  STMicroelectronics Ltd
Copyright (C) 2007-2015  STMicroelectronics Ltd
Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>

This is the driver for the MAC 10/100/1000 on-chip Ethernet controllers
@@ -138,6 +138,8 @@ struct plat_stmmacenet_data {
	int (*init)(struct platform_device *pdev, void *priv);
	void (*exit)(struct platform_device *pdev, void *priv);
	void *bsp_priv;
	int has_gmac4;
	bool tso_en;
};

Where:
@@ -181,6 +183,8 @@ Where:
	     registers.  init/exit callbacks should not use or modify
	     platform data.
 o bsp_priv: another private pointer.
 o has_gmac4: uses GMAC4 core.
 o tso_en: Enables TSO (TCP Segmentation Offload) feature.

For MDIO bus The we have:

@@ -278,6 +282,13 @@ Please see the following document:
 o stmmac_ethtool.c: to implement the ethtool support;
 o stmmac.h: private driver structure;
 o common.h: common definitions and VFTs;
 o mmc_core.c/mmc.h: Management MAC Counters;
 o stmmac_hwtstamp.c: HW timestamp support for PTP;
 o stmmac_ptp.c: PTP 1588 clock;
 o dwmac-<XXX>.c: these are for the platform glue-logic file; e.g. dwmac-sti.c
   for STMicroelectronics SoCs.

- GMAC 3.x
 o descs.h: descriptor structure definitions;
 o dwmac1000_core.c: dwmac GiGa core functions;
 o dwmac1000_dma.c: dma functions for the GMAC chip;
@@ -289,11 +300,32 @@ Please see the following document:
 o enh_desc.c: functions for handling enhanced descriptors;
 o norm_desc.c: functions for handling normal descriptors;
 o chain_mode.c/ring_mode.c:: functions to manage RING/CHAINED modes;
 o mmc_core.c/mmc.h: Management MAC Counters;
 o stmmac_hwtstamp.c: HW timestamp support for PTP;
 o stmmac_ptp.c: PTP 1588 clock;
 o dwmac-<XXX>.c: these are for the platform glue-logic file; e.g. dwmac-sti.c
   for STMicroelectronics SoCs.

- GMAC4.x generation
 o dwmac4_core.c: dwmac GMAC4.x core functions;
 o dwmac4_desc.c: functions for handling GMAC4.x descriptors;
 o dwmac4_descs.h: descriptor definitions;
 o dwmac4_dma.c: dma functions for the GMAC4.x chip;
 o dwmac4_dma.h: dma definitions for the GMAC4.x chip;
 o dwmac4.h: core definitions for the GMAC4.x chip;
 o dwmac4_lib.c: generic GMAC4.x functions;

4.12) TSO support (GMAC4.x)

TSO (Tcp Segmentation Offload) feature is supported by GMAC 4.x chip family.
When a packet is sent through TCP protocol, the TCP stack ensures that
the SKB provided to the low level driver (stmmac in our case) matches with
the maximum frame len (IP header + TCP header + payload <= 1500 bytes (for
MTU set to 1500)). It means that if an application using TCP want to send a
packet which will have a length (after adding headers) > 1514 the packet
will be split in several TCP packets: The data payload is split and headers
(TCP/IP ..) are added. It is done by software.

When TSO is enabled, the TCP stack doesn't care about the maximum frame
length and provide SKB packet to stmmac as it is. The GMAC IP will have to
perform the segmentation by it self to match with maximum frame length.

This feature can be enabled in device tree through "snps,tso" entry.

5) Debug Information

+1 −0
Original line number Diff line number Diff line
@@ -3348,6 +3348,7 @@ F: Documentation/powerpc/cxlflash.txt

STMMAC ETHERNET DRIVER
M:	Giuseppe Cavallaro <peppe.cavallaro@st.com>
M:	Alexandre Torgue <alexandre.torgue@st.com>
L:	netdev@vger.kernel.org
W:	http://www.stlinux.com
S:	Supported
+2 −1
Original line number Diff line number Diff line
@@ -2,7 +2,8 @@ obj-$(CONFIG_STMMAC_ETH) += stmmac.o
stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o	\
	      chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o	\
	      dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o	\
	      mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o $(stmmac-y)
	      mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o	\
	      dwmac4_dma.o dwmac4_lib.o dwmac4_core.o $(stmmac-y)

# Ordering matters. Generic driver must be last.
obj-$(CONFIG_STMMAC_PLATFORM)	+= stmmac-platform.o
+58 −6
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@
/* Synopsys Core versions */
#define	DWMAC_CORE_3_40	0x34
#define	DWMAC_CORE_3_50	0x35
#define	DWMAC_CORE_4_00	0x40
#define STMMAC_CHAN0	0	/* Always supported and default for all chips */

#define DMA_TX_SIZE 512
#define DMA_RX_SIZE 512
@@ -167,6 +169,9 @@ struct stmmac_extra_stats {
	unsigned long mtl_rx_fifo_ctrl_active;
	unsigned long mac_rx_frame_ctrl_fifo;
	unsigned long mac_gmii_rx_proto_engine;
	/* TSO */
	unsigned long tx_tso_frames;
	unsigned long tx_tso_nfrags;
};

/* CSR Frequency Access Defines*/
@@ -243,6 +248,7 @@ enum rx_frame_status {
	csum_none = 0x2,
	llc_snap = 0x4,
	dma_own = 0x8,
	rx_not_ls = 0x10,
};

/* Tx status */
@@ -269,6 +275,7 @@ enum dma_irq_status {
#define	CORE_PCS_ANE_COMPLETE		(1 << 5)
#define	CORE_PCS_LINK_STATUS		(1 << 6)
#define	CORE_RGMII_IRQ			(1 << 7)
#define CORE_IRQ_MTL_RX_OVERFLOW	BIT(8)

/* Physical Coding Sublayer */
struct rgmii_adv {
@@ -300,8 +307,10 @@ struct dma_features {
	/* 802.3az - Energy-Efficient Ethernet (EEE) */
	unsigned int eee;
	unsigned int av;
	unsigned int tsoen;
	/* TX and RX csum */
	unsigned int tx_coe;
	unsigned int rx_coe;
	unsigned int rx_coe_type1;
	unsigned int rx_coe_type2;
	unsigned int rxfifo_over_2048;
@@ -348,6 +357,10 @@ struct stmmac_desc_ops {
	void (*prepare_tx_desc) (struct dma_desc *p, int is_fs, int len,
				 bool csum_flag, int mode, bool tx_own,
				 bool ls);
	void (*prepare_tso_tx_desc)(struct dma_desc *p, int is_fs, int len1,
				    int len2, bool tx_own, bool ls,
				    unsigned int tcphdrlen,
				    unsigned int tcppayloadlen);
	/* Set/get the owner of the descriptor */
	void (*set_tx_owner) (struct dma_desc *p);
	int (*get_tx_owner) (struct dma_desc *p);
@@ -380,6 +393,10 @@ struct stmmac_desc_ops {
	 u64(*get_timestamp) (void *desc, u32 ats);
	/* get rx timestamp status */
	int (*get_rx_timestamp_status) (void *desc, u32 ats);
	/* Display ring */
	void (*display_ring)(void *head, unsigned int size, bool rx);
	/* set MSS via context descriptor */
	void (*set_mss)(struct dma_desc *p, unsigned int mss);
};

extern const struct stmmac_desc_ops enh_desc_ops;
@@ -412,9 +429,15 @@ struct stmmac_dma_ops {
	int (*dma_interrupt) (void __iomem *ioaddr,
			      struct stmmac_extra_stats *x);
	/* If supported then get the optional core features */
	unsigned int (*get_hw_feature) (void __iomem *ioaddr);
	void (*get_hw_feature)(void __iomem *ioaddr,
			       struct dma_features *dma_cap);
	/* Program the HW RX Watchdog */
	void (*rx_watchdog) (void __iomem *ioaddr, u32 riwt);
	void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len);
	void (*set_rx_ring_len)(void __iomem *ioaddr, u32 len);
	void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
	void (*set_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
	void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan);
};

struct mac_device_info;
@@ -463,6 +486,7 @@ struct stmmac_hwtimestamp {
};

extern const struct stmmac_hwtimestamp stmmac_ptp;
extern const struct stmmac_mode_ops dwmac4_ring_mode_ops;

struct mac_link {
	int port;
@@ -495,7 +519,6 @@ struct mac_device_info {
	const struct stmmac_hwtimestamp *ptp;
	struct mii_regs mii;	/* MII register Addresses */
	struct mac_link link;
	unsigned int synopsys_uid;
	void __iomem *pcsr;     /* vpointer to device CSRs */
	int multicast_filter_bins;
	int unicast_filter_entries;
@@ -504,18 +527,47 @@ struct mac_device_info {
};

struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
					int perfect_uc_entries);
struct mac_device_info *dwmac100_setup(void __iomem *ioaddr);
					int perfect_uc_entries,
					int *synopsys_id);
struct mac_device_info *dwmac100_setup(void __iomem *ioaddr, int *synopsys_id);
struct mac_device_info *dwmac4_setup(void __iomem *ioaddr, int mcbins,
				     int perfect_uc_entries, int *synopsys_id);

void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
			 unsigned int high, unsigned int low);
void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
			 unsigned int high, unsigned int low);

void stmmac_set_mac(void __iomem *ioaddr, bool enable);

void stmmac_dwmac4_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
				unsigned int high, unsigned int low);
void stmmac_dwmac4_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
				unsigned int high, unsigned int low);
void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable);

void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
extern const struct stmmac_mode_ops ring_mode_ops;
extern const struct stmmac_mode_ops chain_mode_ops;

extern const struct stmmac_desc_ops dwmac4_desc_ops;

/**
 * stmmac_get_synopsys_id - return the SYINID.
 * @priv: driver private structure
 * Description: this simple function is to decode and return the SYINID
 * starting from the HW core register.
 */
static inline u32 stmmac_get_synopsys_id(u32 hwid)
{
	/* Check Synopsys Id (not available on old chips) */
	if (likely(hwid)) {
		u32 uid = ((hwid & 0x0000ff00) >> 8);
		u32 synid = (hwid & 0x000000ff);

		pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n",
			uid, synid);

		return synid;
	}
	return 0;
}
#endif /* __COMMON_H__ */
Loading