331 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			331 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*******************************************************************************
 | |
|   STMMAC Common Header File
 | |
| 
 | |
|   Copyright (C) 2007-2009  STMicroelectronics Ltd
 | |
| 
 | |
|   This program is free software; you can redistribute it and/or modify it
 | |
|   under the terms and conditions of the GNU General Public License,
 | |
|   version 2, as published by the Free Software Foundation.
 | |
| 
 | |
|   This program is distributed in the hope 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 "COPYING".
 | |
| 
 | |
|   Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
 | |
| *******************************************************************************/
 | |
| 
 | |
| #include "descs.h"
 | |
| #include <linux/io.h>
 | |
| 
 | |
| /* *********************************************
 | |
|    DMA CRS Control and Status Register Mapping
 | |
|  * *********************************************/
 | |
| #define DMA_BUS_MODE		0x00001000	/* Bus Mode */
 | |
| #define DMA_XMT_POLL_DEMAND	0x00001004	/* Transmit Poll Demand */
 | |
| #define DMA_RCV_POLL_DEMAND	0x00001008	/* Received Poll Demand */
 | |
| #define DMA_RCV_BASE_ADDR	0x0000100c	/* Receive List Base */
 | |
| #define DMA_TX_BASE_ADDR	0x00001010	/* Transmit List Base */
 | |
| #define DMA_STATUS		0x00001014	/* Status Register */
 | |
| #define DMA_CONTROL		0x00001018	/* Ctrl (Operational Mode) */
 | |
| #define DMA_INTR_ENA		0x0000101c	/* Interrupt Enable */
 | |
| #define DMA_MISSED_FRAME_CTR	0x00001020	/* Missed Frame Counter */
 | |
| #define DMA_CUR_TX_BUF_ADDR	0x00001050	/* Current Host Tx Buffer */
 | |
| #define DMA_CUR_RX_BUF_ADDR	0x00001054	/* Current Host Rx Buffer */
 | |
| 
 | |
| /* ********************************
 | |
|    DMA Control register defines
 | |
|  * ********************************/
 | |
| #define DMA_CONTROL_ST		0x00002000	/* Start/Stop Transmission */
 | |
| #define DMA_CONTROL_SR		0x00000002	/* Start/Stop Receive */
 | |
| 
 | |
| /* **************************************
 | |
|    DMA Interrupt Enable register defines
 | |
|  * **************************************/
 | |
| /**** NORMAL INTERRUPT ****/
 | |
| #define DMA_INTR_ENA_NIE 0x00010000	/* Normal Summary */
 | |
| #define DMA_INTR_ENA_TIE 0x00000001	/* Transmit Interrupt */
 | |
| #define DMA_INTR_ENA_TUE 0x00000004	/* Transmit Buffer Unavailable */
 | |
| #define DMA_INTR_ENA_RIE 0x00000040	/* Receive Interrupt */
 | |
| #define DMA_INTR_ENA_ERE 0x00004000	/* Early Receive */
 | |
| 
 | |
| #define DMA_INTR_NORMAL	(DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \
 | |
| 			DMA_INTR_ENA_TIE)
 | |
| 
 | |
| /**** ABNORMAL INTERRUPT ****/
 | |
| #define DMA_INTR_ENA_AIE 0x00008000	/* Abnormal Summary */
 | |
| #define DMA_INTR_ENA_FBE 0x00002000	/* Fatal Bus Error */
 | |
| #define DMA_INTR_ENA_ETE 0x00000400	/* Early Transmit */
 | |
| #define DMA_INTR_ENA_RWE 0x00000200	/* Receive Watchdog */
 | |
| #define DMA_INTR_ENA_RSE 0x00000100	/* Receive Stopped */
 | |
| #define DMA_INTR_ENA_RUE 0x00000080	/* Receive Buffer Unavailable */
 | |
| #define DMA_INTR_ENA_UNE 0x00000020	/* Tx Underflow */
 | |
| #define DMA_INTR_ENA_OVE 0x00000010	/* Receive Overflow */
 | |
| #define DMA_INTR_ENA_TJE 0x00000008	/* Transmit Jabber */
 | |
| #define DMA_INTR_ENA_TSE 0x00000002	/* Transmit Stopped */
 | |
| 
 | |
| #define DMA_INTR_ABNORMAL	(DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \
 | |
| 				DMA_INTR_ENA_UNE)
 | |
| 
 | |
| /* DMA default interrupt mask */
 | |
| #define DMA_INTR_DEFAULT_MASK	(DMA_INTR_NORMAL | DMA_INTR_ABNORMAL)
 | |
| 
 | |
| /* ****************************
 | |
|  *  DMA Status register defines
 | |
|  * ****************************/
 | |
| #define DMA_STATUS_GPI		0x10000000	/* PMT interrupt */
 | |
| #define DMA_STATUS_GMI		0x08000000	/* MMC interrupt */
 | |
| #define DMA_STATUS_GLI		0x04000000	/* GMAC Line interface int. */
 | |
| #define DMA_STATUS_GMI		0x08000000
 | |
| #define DMA_STATUS_GLI		0x04000000
 | |
| #define DMA_STATUS_EB_MASK	0x00380000	/* Error Bits Mask */
 | |
| #define DMA_STATUS_EB_TX_ABORT	0x00080000	/* Error Bits - TX Abort */
 | |
| #define DMA_STATUS_EB_RX_ABORT	0x00100000	/* Error Bits - RX Abort */
 | |
| #define DMA_STATUS_TS_MASK	0x00700000	/* Transmit Process State */
 | |
| #define DMA_STATUS_TS_SHIFT	20
 | |
| #define DMA_STATUS_RS_MASK	0x000e0000	/* Receive Process State */
 | |
| #define DMA_STATUS_RS_SHIFT	17
 | |
| #define DMA_STATUS_NIS	0x00010000	/* Normal Interrupt Summary */
 | |
| #define DMA_STATUS_AIS	0x00008000	/* Abnormal Interrupt Summary */
 | |
| #define DMA_STATUS_ERI	0x00004000	/* Early Receive Interrupt */
 | |
| #define DMA_STATUS_FBI	0x00002000	/* Fatal Bus Error Interrupt */
 | |
| #define DMA_STATUS_ETI	0x00000400	/* Early Transmit Interrupt */
 | |
| #define DMA_STATUS_RWT	0x00000200	/* Receive Watchdog Timeout */
 | |
| #define DMA_STATUS_RPS	0x00000100	/* Receive Process Stopped */
 | |
| #define DMA_STATUS_RU	0x00000080	/* Receive Buffer Unavailable */
 | |
| #define DMA_STATUS_RI	0x00000040	/* Receive Interrupt */
 | |
| #define DMA_STATUS_UNF	0x00000020	/* Transmit Underflow */
 | |
| #define DMA_STATUS_OVF	0x00000010	/* Receive Overflow */
 | |
| #define DMA_STATUS_TJT	0x00000008	/* Transmit Jabber Timeout */
 | |
| #define DMA_STATUS_TU	0x00000004	/* Transmit Buffer Unavailable */
 | |
| #define DMA_STATUS_TPS	0x00000002	/* Transmit Process Stopped */
 | |
| #define DMA_STATUS_TI	0x00000001	/* Transmit Interrupt */
 | |
| 
 | |
| /* Other defines */
 | |
| #define HASH_TABLE_SIZE 64
 | |
| #define PAUSE_TIME 0x200
 | |
| 
 | |
| /* Flow Control defines */
 | |
| #define FLOW_OFF	0
 | |
| #define FLOW_RX		1
 | |
| #define FLOW_TX		2
 | |
| #define FLOW_AUTO	(FLOW_TX | FLOW_RX)
 | |
| 
 | |
| /* DMA STORE-AND-FORWARD Operation Mode */
 | |
| #define SF_DMA_MODE 1
 | |
| 
 | |
| #define HW_CSUM 1
 | |
| #define NO_HW_CSUM 0
 | |
| 
 | |
| /* GMAC TX FIFO is 8K, Rx FIFO is 16K */
 | |
| #define BUF_SIZE_16KiB 16384
 | |
| #define BUF_SIZE_8KiB 8192
 | |
| #define BUF_SIZE_4KiB 4096
 | |
| #define BUF_SIZE_2KiB 2048
 | |
| 
 | |
| /* Power Down and WOL */
 | |
| #define PMT_NOT_SUPPORTED 0
 | |
| #define PMT_SUPPORTED 1
 | |
| 
 | |
| /* Common MAC defines */
 | |
| #define MAC_CTRL_REG		0x00000000	/* MAC Control */
 | |
| #define MAC_ENABLE_TX		0x00000008	/* Transmitter Enable */
 | |
| #define MAC_RNABLE_RX		0x00000004	/* Receiver Enable */
 | |
| 
 | |
| /* MAC Management Counters register */
 | |
| #define MMC_CONTROL		0x00000100	/* MMC Control */
 | |
| #define MMC_HIGH_INTR		0x00000104	/* MMC High Interrupt */
 | |
| #define MMC_LOW_INTR		0x00000108	/* MMC Low Interrupt */
 | |
| #define MMC_HIGH_INTR_MASK	0x0000010c	/* MMC High Interrupt Mask */
 | |
| #define MMC_LOW_INTR_MASK	0x00000110	/* MMC Low Interrupt Mask */
 | |
| 
 | |
| #define MMC_CONTROL_MAX_FRM_MASK	0x0003ff8	/* Maximum Frame Size */
 | |
| #define MMC_CONTROL_MAX_FRM_SHIFT	3
 | |
| #define MMC_CONTROL_MAX_FRAME		0x7FF
 | |
| 
 | |
| struct stmmac_extra_stats {
 | |
| 	/* Transmit errors */
 | |
| 	unsigned long tx_underflow ____cacheline_aligned;
 | |
| 	unsigned long tx_carrier;
 | |
| 	unsigned long tx_losscarrier;
 | |
| 	unsigned long tx_heartbeat;
 | |
| 	unsigned long tx_deferred;
 | |
| 	unsigned long tx_vlan;
 | |
| 	unsigned long tx_jabber;
 | |
| 	unsigned long tx_frame_flushed;
 | |
| 	unsigned long tx_payload_error;
 | |
| 	unsigned long tx_ip_header_error;
 | |
| 	/* Receive errors */
 | |
| 	unsigned long rx_desc;
 | |
| 	unsigned long rx_partial;
 | |
| 	unsigned long rx_runt;
 | |
| 	unsigned long rx_toolong;
 | |
| 	unsigned long rx_collision;
 | |
| 	unsigned long rx_crc;
 | |
| 	unsigned long rx_lenght;
 | |
| 	unsigned long rx_mii;
 | |
| 	unsigned long rx_multicast;
 | |
| 	unsigned long rx_gmac_overflow;
 | |
| 	unsigned long rx_watchdog;
 | |
| 	unsigned long da_rx_filter_fail;
 | |
| 	unsigned long sa_rx_filter_fail;
 | |
| 	unsigned long rx_missed_cntr;
 | |
| 	unsigned long rx_overflow_cntr;
 | |
| 	unsigned long rx_vlan;
 | |
| 	/* Tx/Rx IRQ errors */
 | |
| 	unsigned long tx_undeflow_irq;
 | |
| 	unsigned long tx_process_stopped_irq;
 | |
| 	unsigned long tx_jabber_irq;
 | |
| 	unsigned long rx_overflow_irq;
 | |
| 	unsigned long rx_buf_unav_irq;
 | |
| 	unsigned long rx_process_stopped_irq;
 | |
| 	unsigned long rx_watchdog_irq;
 | |
| 	unsigned long tx_early_irq;
 | |
| 	unsigned long fatal_bus_error_irq;
 | |
| 	/* Extra info */
 | |
| 	unsigned long threshold;
 | |
| 	unsigned long tx_pkt_n;
 | |
| 	unsigned long rx_pkt_n;
 | |
| 	unsigned long poll_n;
 | |
| 	unsigned long sched_timer_n;
 | |
| 	unsigned long normal_irq_n;
 | |
| };
 | |
| 
 | |
| /* GMAC core can compute the checksums in HW. */
 | |
| enum rx_frame_status {
 | |
| 	good_frame = 0,
 | |
| 	discard_frame = 1,
 | |
| 	csum_none = 2,
 | |
| };
 | |
| 
 | |
| static inline void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
 | |
| 			 unsigned int high, unsigned int low)
 | |
| {
 | |
| 	unsigned long data;
 | |
| 
 | |
| 	data = (addr[5] << 8) | addr[4];
 | |
| 	writel(data, ioaddr + high);
 | |
| 	data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
 | |
| 	writel(data, ioaddr + low);
 | |
| 
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| static inline void stmmac_get_mac_addr(unsigned long ioaddr,
 | |
| 				unsigned char *addr, unsigned int high,
 | |
| 				unsigned int low)
 | |
| {
 | |
| 	unsigned int hi_addr, lo_addr;
 | |
| 
 | |
| 	/* Read the MAC address from the hardware */
 | |
| 	hi_addr = readl(ioaddr + high);
 | |
| 	lo_addr = readl(ioaddr + low);
 | |
| 
 | |
| 	/* Extract the MAC address from the high and low words */
 | |
| 	addr[0] = lo_addr & 0xff;
 | |
| 	addr[1] = (lo_addr >> 8) & 0xff;
 | |
| 	addr[2] = (lo_addr >> 16) & 0xff;
 | |
| 	addr[3] = (lo_addr >> 24) & 0xff;
 | |
| 	addr[4] = hi_addr & 0xff;
 | |
| 	addr[5] = (hi_addr >> 8) & 0xff;
 | |
| 
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| struct stmmac_ops {
 | |
| 	/* MAC core initialization */
 | |
| 	void (*core_init) (unsigned long ioaddr) ____cacheline_aligned;
 | |
| 	/* DMA core initialization */
 | |
| 	int (*dma_init) (unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
 | |
| 	/* Dump MAC registers */
 | |
| 	void (*dump_mac_regs) (unsigned long ioaddr);
 | |
| 	/* Dump DMA registers */
 | |
| 	void (*dump_dma_regs) (unsigned long ioaddr);
 | |
| 	/* Set tx/rx threshold in the csr6 register
 | |
| 	 * An invalid value enables the store-and-forward mode */
 | |
| 	void (*dma_mode) (unsigned long ioaddr, int txmode, int rxmode);
 | |
| 	/* To track extra statistic (if supported) */
 | |
| 	void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
 | |
| 				   unsigned long ioaddr);
 | |
| 	/* RX descriptor ring initialization */
 | |
| 	void (*init_rx_desc) (struct dma_desc *p, unsigned int ring_size,
 | |
| 				int disable_rx_ic);
 | |
| 	/* TX descriptor ring initialization */
 | |
| 	void (*init_tx_desc) (struct dma_desc *p, unsigned int ring_size);
 | |
| 
 | |
| 	/* Invoked by the xmit function to prepare the tx descriptor */
 | |
| 	void (*prepare_tx_desc) (struct dma_desc *p, int is_fs, int len,
 | |
| 				 int csum_flag);
 | |
| 	/* Set/get the owner of the descriptor */
 | |
| 	void (*set_tx_owner) (struct dma_desc *p);
 | |
| 	int (*get_tx_owner) (struct dma_desc *p);
 | |
| 	/* Invoked by the xmit function to close the tx descriptor */
 | |
| 	void (*close_tx_desc) (struct dma_desc *p);
 | |
| 	/* Clean the tx descriptor as soon as the tx irq is received */
 | |
| 	void (*release_tx_desc) (struct dma_desc *p);
 | |
| 	/* Clear interrupt on tx frame completion. When this bit is
 | |
| 	 * set an interrupt happens as soon as the frame is transmitted */
 | |
| 	void (*clear_tx_ic) (struct dma_desc *p);
 | |
| 	/* Last tx segment reports the transmit status */
 | |
| 	int (*get_tx_ls) (struct dma_desc *p);
 | |
| 	/* Return the transmit status looking at the TDES1 */
 | |
| 	int (*tx_status) (void *data, struct stmmac_extra_stats *x,
 | |
| 			  struct dma_desc *p, unsigned long ioaddr);
 | |
| 	/* Get the buffer size from the descriptor */
 | |
| 	int (*get_tx_len) (struct dma_desc *p);
 | |
| 	/* Handle extra events on specific interrupts hw dependent */
 | |
| 	void (*host_irq_status) (unsigned long ioaddr);
 | |
| 	int (*get_rx_owner) (struct dma_desc *p);
 | |
| 	void (*set_rx_owner) (struct dma_desc *p);
 | |
| 	/* Get the receive frame size */
 | |
| 	int (*get_rx_frame_len) (struct dma_desc *p);
 | |
| 	/* Return the reception status looking at the RDES1 */
 | |
| 	int (*rx_status) (void *data, struct stmmac_extra_stats *x,
 | |
| 			  struct dma_desc *p);
 | |
| 	/* Multicast filter setting */
 | |
| 	void (*set_filter) (struct net_device *dev);
 | |
| 	/* Flow control setting */
 | |
| 	void (*flow_ctrl) (unsigned long ioaddr, unsigned int duplex,
 | |
| 			   unsigned int fc, unsigned int pause_time);
 | |
| 	/* Set power management mode (e.g. magic frame) */
 | |
| 	void (*pmt) (unsigned long ioaddr, unsigned long mode);
 | |
| 	/* Set/Get Unicast MAC addresses */
 | |
| 	void (*set_umac_addr) (unsigned long ioaddr, unsigned char *addr,
 | |
| 			     unsigned int reg_n);
 | |
| 	void (*get_umac_addr) (unsigned long ioaddr, unsigned char *addr,
 | |
| 			     unsigned int reg_n);
 | |
| };
 | |
| 
 | |
| struct mac_link {
 | |
| 	int port;
 | |
| 	int duplex;
 | |
| 	int speed;
 | |
| };
 | |
| 
 | |
| struct mii_regs {
 | |
| 	unsigned int addr;	/* MII Address */
 | |
| 	unsigned int data;	/* MII Data */
 | |
| };
 | |
| 
 | |
| struct hw_cap {
 | |
| 	unsigned int version;	/* Core Version register (GMAC) */
 | |
| 	unsigned int pmt;	/* Power-Down mode (GMAC) */
 | |
| 	struct mac_link link;
 | |
| 	struct mii_regs mii;
 | |
| };
 | |
| 
 | |
| struct mac_device_info {
 | |
| 	struct hw_cap hw;
 | |
| 	struct stmmac_ops *ops;
 | |
| };
 | |
| 
 | |
| struct mac_device_info *gmac_setup(unsigned long addr);
 | |
| struct mac_device_info *mac100_setup(unsigned long addr);
 |