259 lines
8.7 KiB
C
259 lines
8.7 KiB
C
/*
|
|
* linux/drivers/net/ethernet/allwinner/sunxi_gmac.h
|
|
*
|
|
* Copyright © 2016-2018, fuzhaoke
|
|
* Author: fuzhaoke <fuzhaoke@allwinnertech.com>
|
|
*
|
|
* This file is provided under a dual BSD/GPL license. When using or
|
|
* redistributing this file, you may do so under either 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.
|
|
*/
|
|
#ifndef __SUNXI_GETH_H__
|
|
#define __SUNXI_GETH_H__
|
|
|
|
#include <linux/etherdevice.h>
|
|
#include <linux/netdevice.h>
|
|
#include <linux/phy.h>
|
|
#include <linux/module.h>
|
|
#include <linux/init.h>
|
|
|
|
/* GETH_FRAME_FILTER register value */
|
|
#define GETH_FRAME_FILTER_PR 0x00000001 /* Promiscuous Mode */
|
|
#define GETH_FRAME_FILTER_HUC 0x00000002 /* Hash Unicast */
|
|
#define GETH_FRAME_FILTER_HMC 0x00000004 /* Hash Multicast */
|
|
#define GETH_FRAME_FILTER_DAIF 0x00000008 /* DA Inverse Filtering */
|
|
#define GETH_FRAME_FILTER_PM 0x00000010 /* Pass all multicast */
|
|
#define GETH_FRAME_FILTER_DBF 0x00000020 /* Disable Broadcast frames */
|
|
#define GETH_FRAME_FILTER_SAIF 0x00000100 /* Inverse Filtering */
|
|
#define GETH_FRAME_FILTER_SAF 0x00000200 /* Source Address Filter */
|
|
#define GETH_FRAME_FILTER_HPF 0x00000400 /* Hash or perfect Filter */
|
|
#define GETH_FRAME_FILTER_RA 0x80000000 /* Receive all mode */
|
|
|
|
/* Default tx descriptor */
|
|
#define TX_SINGLE_DESC0 0x80000000
|
|
#define TX_SINGLE_DESC1 0x63000000
|
|
|
|
/* Default rx descriptor */
|
|
#define RX_SINGLE_DESC0 0x80000000
|
|
#define RX_SINGLE_DESC1 0x83000000
|
|
|
|
typedef union {
|
|
struct {
|
|
/* TDES0 */
|
|
unsigned int deferred:1; /* Deferred bit (only half-duplex) */
|
|
unsigned int under_err:1; /* Underflow error */
|
|
unsigned int ex_deferral:1; /* Excessive deferral */
|
|
unsigned int coll_cnt:4; /* Collision count */
|
|
unsigned int vlan_tag:1; /* VLAN Frame */
|
|
unsigned int ex_coll:1; /* Excessive collision */
|
|
unsigned int late_coll:1; /* Late collision */
|
|
unsigned int no_carr:1; /* No carrier */
|
|
unsigned int loss_carr:1; /* Loss of collision */
|
|
unsigned int ipdat_err:1; /* IP payload error */
|
|
unsigned int frm_flu:1; /* Frame flushed */
|
|
unsigned int jab_timeout:1; /* Jabber timeout */
|
|
unsigned int err_sum:1; /* Error summary */
|
|
unsigned int iphead_err:1; /* IP header error */
|
|
unsigned int ttss:1; /* Transmit time stamp status */
|
|
unsigned int reserved0:13;
|
|
unsigned int own:1; /* Own bit. CPU:0, DMA:1 */
|
|
} tx;
|
|
|
|
/* bits 5 7 0 | Frame status
|
|
* ----------------------------------------------------------
|
|
* 0 0 0 | IEEE 802.3 Type frame (length < 1536 octects)
|
|
* 1 0 0 | IPv4/6 No CSUM errorS.
|
|
* 1 0 1 | IPv4/6 CSUM PAYLOAD error
|
|
* 1 1 0 | IPv4/6 CSUM IP HR error
|
|
* 1 1 1 | IPv4/6 IP PAYLOAD AND HEADER errorS
|
|
* 0 0 1 | IPv4/6 unsupported IP PAYLOAD
|
|
* 0 1 1 | COE bypassed.. no IPv4/6 frame
|
|
* 0 1 0 | Reserved.
|
|
*/
|
|
struct {
|
|
/* RDES0 */
|
|
unsigned int chsum_err:1; /* Payload checksum error */
|
|
unsigned int crc_err:1; /* CRC error */
|
|
unsigned int dribbling:1; /* Dribble bit error */
|
|
unsigned int mii_err:1; /* Received error (bit3) */
|
|
unsigned int recv_wt:1; /* Received watchdog timeout */
|
|
unsigned int frm_type:1; /* Frame type */
|
|
unsigned int late_coll:1; /* Late Collision */
|
|
unsigned int ipch_err:1; /* IPv header checksum error (bit7) */
|
|
unsigned int last_desc:1; /* Laset descriptor */
|
|
unsigned int first_desc:1; /* First descriptor */
|
|
unsigned int vlan_tag:1; /* VLAN Tag */
|
|
unsigned int over_err:1; /* Overflow error (bit11) */
|
|
unsigned int len_err:1; /* Length error */
|
|
unsigned int sou_filter:1; /* Source address filter fail */
|
|
unsigned int desc_err:1; /* Descriptor error */
|
|
unsigned int err_sum:1; /* Error summary (bit15) */
|
|
unsigned int frm_len:14; /* Frame length */
|
|
unsigned int des_filter:1; /* Destination address filter fail */
|
|
unsigned int own:1; /* Own bit. CPU:0, DMA:1 */
|
|
#define RX_PKT_OK 0x7FFFB77C
|
|
#define RX_LEN 0x3FFF0000
|
|
} rx;
|
|
|
|
unsigned int all;
|
|
} desc0_u;
|
|
|
|
typedef union {
|
|
struct {
|
|
/* TDES1 */
|
|
unsigned int buf1_size:11; /* Transmit buffer1 size */
|
|
unsigned int buf2_size:11; /* Transmit buffer2 size */
|
|
unsigned int ttse:1; /* Transmit time stamp enable */
|
|
unsigned int dis_pad:1; /* Disable pad (bit23) */
|
|
unsigned int adr_chain:1; /* Second address chained */
|
|
unsigned int end_ring:1; /* Transmit end of ring */
|
|
unsigned int crc_dis:1; /* Disable CRC */
|
|
unsigned int cic:2; /* Checksum insertion control (bit27:28) */
|
|
unsigned int first_sg:1; /* First Segment */
|
|
unsigned int last_seg:1; /* Last Segment */
|
|
unsigned int interrupt:1; /* Interrupt on completion */
|
|
} tx;
|
|
|
|
struct {
|
|
/* RDES1 */
|
|
unsigned int buf1_size:11; /* Received buffer1 size */
|
|
unsigned int buf2_size:11; /* Received buffer2 size */
|
|
unsigned int reserved1:2;
|
|
unsigned int adr_chain:1; /* Second address chained */
|
|
unsigned int end_ring:1; /* Received end of ring */
|
|
unsigned int reserved2:5;
|
|
unsigned int dis_ic:1; /* Disable interrupt on completion */
|
|
} rx;
|
|
|
|
unsigned int all;
|
|
} desc1_u;
|
|
|
|
typedef struct dma_desc {
|
|
desc0_u desc0;
|
|
desc1_u desc1;
|
|
/* The address of buffers */
|
|
unsigned int desc2;
|
|
/* Next desc's address */
|
|
unsigned int desc3;
|
|
} __attribute__((packed)) dma_desc_t;
|
|
|
|
enum rx_frame_status { /* IPC status */
|
|
good_frame = 0,
|
|
discard_frame = 1,
|
|
csum_none = 2,
|
|
llc_snap = 4,
|
|
};
|
|
|
|
enum tx_dma_irq_status {
|
|
tx_hard_error = 1,
|
|
tx_hard_error_bump_tc = 2,
|
|
handle_tx_rx = 3,
|
|
};
|
|
|
|
struct geth_extra_stats {
|
|
/* Transmit errors */
|
|
unsigned long tx_underflow;
|
|
unsigned long tx_carrier;
|
|
unsigned long tx_losscarrier;
|
|
unsigned long vlan_tag;
|
|
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 sa_filter_fail;
|
|
unsigned long overflow_error;
|
|
unsigned long ipc_csum_error;
|
|
unsigned long rx_collision;
|
|
unsigned long rx_crc;
|
|
unsigned long dribbling_bit;
|
|
unsigned long rx_length;
|
|
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;
|
|
};
|
|
|
|
int sunxi_mdio_read(void *, int, int);
|
|
int sunxi_mdio_write(void *, int, int, unsigned short);
|
|
int sunxi_mdio_reset(void *);
|
|
void sunxi_set_link_mode(void *iobase, int duplex, int speed);
|
|
void sunxi_int_disable(void *);
|
|
int sunxi_int_status(void *, struct geth_extra_stats *x);
|
|
int sunxi_mac_init(void *, int txmode, int rxmode);
|
|
void sunxi_set_umac(void *, unsigned char *, int);
|
|
void sunxi_mac_enable(void *);
|
|
void sunxi_mac_disable(void *);
|
|
void sunxi_tx_poll(void *);
|
|
void sunxi_int_enable(void *);
|
|
void sunxi_start_rx(void *, unsigned long);
|
|
void sunxi_start_tx(void *, unsigned long);
|
|
void sunxi_stop_tx(void *);
|
|
void sunxi_stop_rx(void *);
|
|
void sunxi_hash_filter(void *iobase, unsigned long low, unsigned long high);
|
|
void sunxi_set_filter(void *iobase, unsigned long flags);
|
|
void sunxi_flow_ctrl(void *iobase, int duplex, int fc, int pause);
|
|
void sunxi_mac_loopback(void *iobase, int enable);
|
|
|
|
void desc_buf_set(struct dma_desc *p, unsigned long paddr, int size);
|
|
void desc_set_own(struct dma_desc *p);
|
|
void desc_init_chain(struct dma_desc *p, unsigned long paddr, unsigned int size);
|
|
void desc_tx_close(struct dma_desc *first, struct dma_desc *end, int csum_insert);
|
|
void desc_init(struct dma_desc *p);
|
|
int desc_get_tx_status(struct dma_desc *desc, struct geth_extra_stats *x);
|
|
int desc_buf_get_len(struct dma_desc *desc);
|
|
int desc_buf_get_addr(struct dma_desc *desc);
|
|
int desc_get_rx_status(struct dma_desc *desc, struct geth_extra_stats *x);
|
|
int desc_get_own(struct dma_desc *desc);
|
|
int desc_get_tx_ls(struct dma_desc *desc);
|
|
int desc_rx_frame_len(struct dma_desc *desc);
|
|
|
|
int sunxi_mac_reset(void *iobase, void (*mdelay)(int), int n);
|
|
int sunxi_geth_register(void *iobase, int version, unsigned int div);
|
|
|
|
#if defined(CONFIG_SUNXI_EPHY)
|
|
extern int ephy_is_enable(void);
|
|
#endif
|
|
|
|
#if defined(CONFIG_ARCH_SUN8IW3) \
|
|
|| defined(CONFIG_ARCH_SUN9IW1) \
|
|
|| defined(CONFIG_ARCH_SUN7I)
|
|
#define HW_VERSION 0
|
|
#else
|
|
#define HW_VERSION 1
|
|
#endif
|
|
|
|
#endif
|