mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-30 21:44:27 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			491 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			491 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *  Atheros AR71xx built-in ethernet mac driver
 | |
|  *
 | |
|  *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
 | |
|  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
 | |
|  *
 | |
|  *  Based on Atheros' AG7100 driver
 | |
|  *
 | |
|  *  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 __AG71XX_H
 | |
| #define __AG71XX_H
 | |
| 
 | |
| #include <linux/kernel.h>
 | |
| #include <linux/version.h>
 | |
| #include <linux/module.h>
 | |
| #include <linux/init.h>
 | |
| #include <linux/types.h>
 | |
| #include <linux/random.h>
 | |
| #include <linux/spinlock.h>
 | |
| #include <linux/interrupt.h>
 | |
| #include <linux/platform_device.h>
 | |
| #include <linux/ethtool.h>
 | |
| #include <linux/etherdevice.h>
 | |
| #include <linux/phy.h>
 | |
| #include <linux/skbuff.h>
 | |
| #include <linux/dma-mapping.h>
 | |
| #include <linux/workqueue.h>
 | |
| 
 | |
| #include <linux/bitops.h>
 | |
| 
 | |
| #include <asm/mach-ar71xx/ar71xx.h>
 | |
| #include <asm/mach-ar71xx/platform.h>
 | |
| 
 | |
| #define ETH_FCS_LEN	4
 | |
| 
 | |
| #define AG71XX_DRV_NAME		"ag71xx"
 | |
| #define AG71XX_DRV_VERSION	"0.5.31"
 | |
| 
 | |
| #define AG71XX_NAPI_WEIGHT	64
 | |
| #define AG71XX_OOM_REFILL	(1 + HZ/10)
 | |
| 
 | |
| #define AG71XX_INT_ERR	(AG71XX_INT_RX_BE | AG71XX_INT_TX_BE)
 | |
| #define AG71XX_INT_TX	(AG71XX_INT_TX_PS)
 | |
| #define AG71XX_INT_RX	(AG71XX_INT_RX_PR | AG71XX_INT_RX_OF)
 | |
| 
 | |
| #define AG71XX_INT_POLL	(AG71XX_INT_RX | AG71XX_INT_TX)
 | |
| #define AG71XX_INT_INIT	(AG71XX_INT_ERR | AG71XX_INT_POLL)
 | |
| 
 | |
| #define AG71XX_TX_FIFO_LEN	2048
 | |
| #define AG71XX_TX_MTU_LEN	1536
 | |
| #define AG71XX_RX_PKT_RESERVE	64
 | |
| #define AG71XX_RX_PKT_SIZE	\
 | |
| 	(AG71XX_RX_PKT_RESERVE + ETH_HLEN + ETH_FRAME_LEN + ETH_FCS_LEN)
 | |
| 
 | |
| #define AG71XX_TX_RING_SIZE	64
 | |
| #define AG71XX_TX_THRES_STOP	(AG71XX_TX_RING_SIZE - 4)
 | |
| #define AG71XX_TX_THRES_WAKEUP	\
 | |
| 		(AG71XX_TX_RING_SIZE - (AG71XX_TX_RING_SIZE / 4))
 | |
| 
 | |
| #define AG71XX_RX_RING_SIZE	128
 | |
| 
 | |
| #ifdef CONFIG_AG71XX_DEBUG
 | |
| #define DBG(fmt, args...)	printk(KERN_DEBUG fmt, ## args)
 | |
| #else
 | |
| #define DBG(fmt, args...)	do {} while (0)
 | |
| #endif
 | |
| 
 | |
| #define ag71xx_assert(_cond)						\
 | |
| do {									\
 | |
| 	if (_cond)							\
 | |
| 		break;							\
 | |
| 	printk("%s,%d: assertion failed\n", __FILE__, __LINE__);	\
 | |
| 	BUG();								\
 | |
| } while (0)
 | |
| 
 | |
| struct ag71xx_desc {
 | |
| 	u32	data;
 | |
| 	u32	ctrl;
 | |
| #define DESC_EMPTY	BIT(31)
 | |
| #define DESC_MORE	BIT(24)
 | |
| #define DESC_PKTLEN_M	0xfff
 | |
| 	u32	next;
 | |
| 	u32	pad;
 | |
| } __attribute__((aligned(4)));
 | |
| 
 | |
| struct ag71xx_buf {
 | |
| 	struct sk_buff		*skb;
 | |
| 	struct ag71xx_desc 	*desc;
 | |
| 	dma_addr_t		dma_addr;
 | |
| 	u32			pad;
 | |
| };
 | |
| 
 | |
| struct ag71xx_ring {
 | |
| 	struct ag71xx_buf	*buf;
 | |
| 	u8			*descs_cpu;
 | |
| 	dma_addr_t		descs_dma;
 | |
| 	unsigned int		desc_size;
 | |
| 	unsigned int		curr;
 | |
| 	unsigned int		dirty;
 | |
| 	unsigned int		size;
 | |
| };
 | |
| 
 | |
| struct ag71xx_mdio {
 | |
| 	struct mii_bus		*mii_bus;
 | |
| 	int			mii_irq[PHY_MAX_ADDR];
 | |
| 	void __iomem		*mdio_base;
 | |
| 	struct ag71xx_mdio_platform_data *pdata;
 | |
| };
 | |
| 
 | |
| struct ag71xx_int_stats {
 | |
| 	unsigned long		rx_pr;
 | |
| 	unsigned long		rx_be;
 | |
| 	unsigned long		rx_of;
 | |
| 	unsigned long		tx_ps;
 | |
| 	unsigned long		tx_be;
 | |
| 	unsigned long		tx_ur;
 | |
| 	unsigned long		total;
 | |
| };
 | |
| 
 | |
| struct ag71xx_napi_stats {
 | |
| 	unsigned long		napi_calls;
 | |
| 	unsigned long		rx_count;
 | |
| 	unsigned long		rx_packets;
 | |
| 	unsigned long		rx_packets_max;
 | |
| 	unsigned long		tx_count;
 | |
| 	unsigned long		tx_packets;
 | |
| 	unsigned long		tx_packets_max;
 | |
| 
 | |
| 	unsigned long		rx[AG71XX_NAPI_WEIGHT + 1];
 | |
| 	unsigned long		tx[AG71XX_NAPI_WEIGHT + 1];
 | |
| };
 | |
| 
 | |
| struct ag71xx_debug {
 | |
| 	struct dentry		*debugfs_dir;
 | |
| 	struct dentry		*debugfs_int_stats;
 | |
| 	struct dentry		*debugfs_napi_stats;
 | |
| 
 | |
| 	struct ag71xx_int_stats int_stats;
 | |
| 	struct ag71xx_napi_stats napi_stats;
 | |
| };
 | |
| 
 | |
| struct ag71xx {
 | |
| 	void __iomem		*mac_base;
 | |
| 	void __iomem		*mii_ctrl;
 | |
| 
 | |
| 	spinlock_t		lock;
 | |
| 	struct platform_device	*pdev;
 | |
| 	struct net_device	*dev;
 | |
| 	struct napi_struct	napi;
 | |
| 	u32			msg_enable;
 | |
| 
 | |
| 	struct ag71xx_ring	rx_ring;
 | |
| 	struct ag71xx_ring	tx_ring;
 | |
| 
 | |
| 	struct mii_bus		*mii_bus;
 | |
| 	struct phy_device	*phy_dev;
 | |
| 
 | |
| 	unsigned int		link;
 | |
| 	unsigned int		speed;
 | |
| 	int 			duplex;
 | |
| 
 | |
| 	struct work_struct	restart_work;
 | |
| 	struct timer_list	oom_timer;
 | |
| 
 | |
| #ifdef CONFIG_AG71XX_DEBUG_FS
 | |
| 	struct ag71xx_debug	debug;
 | |
| #endif
 | |
| };
 | |
| 
 | |
| extern struct ethtool_ops ag71xx_ethtool_ops;
 | |
| void ag71xx_link_adjust(struct ag71xx *ag);
 | |
| 
 | |
| int ag71xx_mdio_driver_init(void) __init;
 | |
| void ag71xx_mdio_driver_exit(void);
 | |
| 
 | |
| int ag71xx_phy_connect(struct ag71xx *ag);
 | |
| void ag71xx_phy_disconnect(struct ag71xx *ag);
 | |
| void ag71xx_phy_start(struct ag71xx *ag);
 | |
| void ag71xx_phy_stop(struct ag71xx *ag);
 | |
| 
 | |
| static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag)
 | |
| {
 | |
| 	return ag->pdev->dev.platform_data;
 | |
| }
 | |
| 
 | |
| static inline int ag71xx_desc_empty(struct ag71xx_desc *desc)
 | |
| {
 | |
| 	return ((desc->ctrl & DESC_EMPTY) != 0);
 | |
| }
 | |
| 
 | |
| static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc)
 | |
| {
 | |
| 	return (desc->ctrl & DESC_PKTLEN_M);
 | |
| }
 | |
| 
 | |
| /* Register offsets */
 | |
| #define AG71XX_REG_MAC_CFG1	0x0000
 | |
| #define AG71XX_REG_MAC_CFG2	0x0004
 | |
| #define AG71XX_REG_MAC_IPG	0x0008
 | |
| #define AG71XX_REG_MAC_HDX	0x000c
 | |
| #define AG71XX_REG_MAC_MFL	0x0010
 | |
| #define AG71XX_REG_MII_CFG	0x0020
 | |
| #define AG71XX_REG_MII_CMD	0x0024
 | |
| #define AG71XX_REG_MII_ADDR	0x0028
 | |
| #define AG71XX_REG_MII_CTRL	0x002c
 | |
| #define AG71XX_REG_MII_STATUS	0x0030
 | |
| #define AG71XX_REG_MII_IND	0x0034
 | |
| #define AG71XX_REG_MAC_IFCTL	0x0038
 | |
| #define AG71XX_REG_MAC_ADDR1	0x0040
 | |
| #define AG71XX_REG_MAC_ADDR2	0x0044
 | |
| #define AG71XX_REG_FIFO_CFG0	0x0048
 | |
| #define AG71XX_REG_FIFO_CFG1	0x004c
 | |
| #define AG71XX_REG_FIFO_CFG2	0x0050
 | |
| #define AG71XX_REG_FIFO_CFG3	0x0054
 | |
| #define AG71XX_REG_FIFO_CFG4	0x0058
 | |
| #define AG71XX_REG_FIFO_CFG5	0x005c
 | |
| #define AG71XX_REG_FIFO_RAM0	0x0060
 | |
| #define AG71XX_REG_FIFO_RAM1	0x0064
 | |
| #define AG71XX_REG_FIFO_RAM2	0x0068
 | |
| #define AG71XX_REG_FIFO_RAM3	0x006c
 | |
| #define AG71XX_REG_FIFO_RAM4	0x0070
 | |
| #define AG71XX_REG_FIFO_RAM5	0x0074
 | |
| #define AG71XX_REG_FIFO_RAM6	0x0078
 | |
| #define AG71XX_REG_FIFO_RAM7	0x007c
 | |
| 
 | |
| #define AG71XX_REG_TX_CTRL	0x0180
 | |
| #define AG71XX_REG_TX_DESC	0x0184
 | |
| #define AG71XX_REG_TX_STATUS	0x0188
 | |
| #define AG71XX_REG_RX_CTRL	0x018c
 | |
| #define AG71XX_REG_RX_DESC	0x0190
 | |
| #define AG71XX_REG_RX_STATUS	0x0194
 | |
| #define AG71XX_REG_INT_ENABLE	0x0198
 | |
| #define AG71XX_REG_INT_STATUS	0x019c
 | |
| 
 | |
| #define MAC_CFG1_TXE		BIT(0)	/* Tx Enable */
 | |
| #define MAC_CFG1_STX		BIT(1)	/* Synchronize Tx Enable */
 | |
| #define MAC_CFG1_RXE		BIT(2)	/* Rx Enable */
 | |
| #define MAC_CFG1_SRX		BIT(3)	/* Synchronize Rx Enable */
 | |
| #define MAC_CFG1_TFC		BIT(4)	/* Tx Flow Control Enable */
 | |
| #define MAC_CFG1_RFC		BIT(5)	/* Rx Flow Control Enable */
 | |
| #define MAC_CFG1_LB		BIT(8)	/* Loopback mode */
 | |
| #define MAC_CFG1_SR		BIT(31)	/* Soft Reset */
 | |
| 
 | |
| #define MAC_CFG2_FDX		BIT(0)
 | |
| #define MAC_CFG2_CRC_EN		BIT(1)
 | |
| #define MAC_CFG2_PAD_CRC_EN	BIT(2)
 | |
| #define MAC_CFG2_LEN_CHECK	BIT(4)
 | |
| #define MAC_CFG2_HUGE_FRAME_EN	BIT(5)
 | |
| #define MAC_CFG2_IF_1000	BIT(9)
 | |
| #define MAC_CFG2_IF_10_100	BIT(8)
 | |
| 
 | |
| #define FIFO_CFG0_WTM		BIT(0)	/* Watermark Module */
 | |
| #define FIFO_CFG0_RXS		BIT(1)	/* Rx System Module */
 | |
| #define FIFO_CFG0_RXF		BIT(2)	/* Rx Fabric Module */
 | |
| #define FIFO_CFG0_TXS		BIT(3)	/* Tx System Module */
 | |
| #define FIFO_CFG0_TXF		BIT(4)	/* Tx Fabric Module */
 | |
| #define FIFO_CFG0_ALL	(FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \
 | |
| 			| FIFO_CFG0_TXS | FIFO_CFG0_TXF)
 | |
| 
 | |
| #define FIFO_CFG0_ENABLE_SHIFT	8
 | |
| 
 | |
| #define FIFO_CFG4_DE		BIT(0)	/* Drop Event */
 | |
| #define FIFO_CFG4_DV		BIT(1)	/* RX_DV Event */
 | |
| #define FIFO_CFG4_FC		BIT(2)	/* False Carrier */
 | |
| #define FIFO_CFG4_CE		BIT(3)	/* Code Error */
 | |
| #define FIFO_CFG4_CR		BIT(4)	/* CRC error */
 | |
| #define FIFO_CFG4_LM		BIT(5)	/* Length Mismatch */
 | |
| #define FIFO_CFG4_LO		BIT(6)	/* Length out of range */
 | |
| #define FIFO_CFG4_OK		BIT(7)	/* Packet is OK */
 | |
| #define FIFO_CFG4_MC		BIT(8)	/* Multicast Packet */
 | |
| #define FIFO_CFG4_BC		BIT(9)	/* Broadcast Packet */
 | |
| #define FIFO_CFG4_DR		BIT(10)	/* Dribble */
 | |
| #define FIFO_CFG4_LE		BIT(11)	/* Long Event */
 | |
| #define FIFO_CFG4_CF		BIT(12)	/* Control Frame */
 | |
| #define FIFO_CFG4_PF		BIT(13)	/* Pause Frame */
 | |
| #define FIFO_CFG4_UO		BIT(14)	/* Unsupported Opcode */
 | |
| #define FIFO_CFG4_VT		BIT(15)	/* VLAN tag detected */
 | |
| #define FIFO_CFG4_FT		BIT(16)	/* Frame Truncated */
 | |
| #define FIFO_CFG4_UC		BIT(17)	/* Unicast Packet */
 | |
| 
 | |
| #define FIFO_CFG5_DE		BIT(0)	/* Drop Event */
 | |
| #define FIFO_CFG5_DV		BIT(1)	/* RX_DV Event */
 | |
| #define FIFO_CFG5_FC		BIT(2)	/* False Carrier */
 | |
| #define FIFO_CFG5_CE		BIT(3)	/* Code Error */
 | |
| #define FIFO_CFG5_LM		BIT(4)	/* Length Mismatch */
 | |
| #define FIFO_CFG5_LO		BIT(5)	/* Length Out of Range */
 | |
| #define FIFO_CFG5_OK		BIT(6)	/* Packet is OK */
 | |
| #define FIFO_CFG5_MC		BIT(7)	/* Multicast Packet */
 | |
| #define FIFO_CFG5_BC		BIT(8)	/* Broadcast Packet */
 | |
| #define FIFO_CFG5_DR		BIT(9)	/* Dribble */
 | |
| #define FIFO_CFG5_CF		BIT(10)	/* Control Frame */
 | |
| #define FIFO_CFG5_PF		BIT(11)	/* Pause Frame */
 | |
| #define FIFO_CFG5_UO		BIT(12)	/* Unsupported Opcode */
 | |
| #define FIFO_CFG5_VT		BIT(13)	/* VLAN tag detected */
 | |
| #define FIFO_CFG5_LE		BIT(14)	/* Long Event */
 | |
| #define FIFO_CFG5_FT		BIT(15)	/* Frame Truncated */
 | |
| #define FIFO_CFG5_16		BIT(16)	/* unknown */
 | |
| #define FIFO_CFG5_17		BIT(17)	/* unknown */
 | |
| #define FIFO_CFG5_SF		BIT(18)	/* Short Frame */
 | |
| #define FIFO_CFG5_BM		BIT(19)	/* Byte Mode */
 | |
| 
 | |
| #define AG71XX_INT_TX_PS	BIT(0)
 | |
| #define AG71XX_INT_TX_UR	BIT(1)
 | |
| #define AG71XX_INT_TX_BE	BIT(3)
 | |
| #define AG71XX_INT_RX_PR	BIT(4)
 | |
| #define AG71XX_INT_RX_OF	BIT(6)
 | |
| #define AG71XX_INT_RX_BE	BIT(7)
 | |
| 
 | |
| #define MAC_IFCTL_SPEED		BIT(16)
 | |
| 
 | |
| #define MII_CFG_CLK_DIV_4	0
 | |
| #define MII_CFG_CLK_DIV_6	2
 | |
| #define MII_CFG_CLK_DIV_8	3
 | |
| #define MII_CFG_CLK_DIV_10	4
 | |
| #define MII_CFG_CLK_DIV_14	5
 | |
| #define MII_CFG_CLK_DIV_20	6
 | |
| #define MII_CFG_CLK_DIV_28	7
 | |
| #define MII_CFG_RESET		BIT(31)
 | |
| 
 | |
| #define MII_CMD_WRITE		0x0
 | |
| #define MII_CMD_READ		0x1
 | |
| #define MII_ADDR_SHIFT		8
 | |
| #define MII_IND_BUSY		BIT(0)
 | |
| #define MII_IND_INVALID		BIT(2)
 | |
| 
 | |
| #define TX_CTRL_TXE		BIT(0)	/* Tx Enable */
 | |
| 
 | |
| #define TX_STATUS_PS		BIT(0)	/* Packet Sent */
 | |
| #define TX_STATUS_UR		BIT(1)	/* Tx Underrun */
 | |
| #define TX_STATUS_BE		BIT(3)	/* Bus Error */
 | |
| 
 | |
| #define RX_CTRL_RXE		BIT(0)	/* Rx Enable */
 | |
| 
 | |
| #define RX_STATUS_PR		BIT(0)	/* Packet Received */
 | |
| #define RX_STATUS_OF		BIT(2)	/* Rx Overflow */
 | |
| #define RX_STATUS_BE		BIT(3)	/* Bus Error */
 | |
| 
 | |
| #define MII_CTRL_IF_MASK	3
 | |
| #define MII_CTRL_SPEED_SHIFT	4
 | |
| #define MII_CTRL_SPEED_MASK	3
 | |
| #define MII_CTRL_SPEED_10	0
 | |
| #define MII_CTRL_SPEED_100	1
 | |
| #define MII_CTRL_SPEED_1000	2
 | |
| 
 | |
| static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg)
 | |
| {
 | |
| 	switch (reg) {
 | |
| 	case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL:
 | |
| 	case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS:
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		BUG();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value)
 | |
| {
 | |
| 	ag71xx_check_reg_offset(ag, reg);
 | |
| 
 | |
| 	__raw_writel(value, ag->mac_base + reg);
 | |
| 	/* flush write */
 | |
| 	(void) __raw_readl(ag->mac_base + reg);
 | |
| }
 | |
| 
 | |
| static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg)
 | |
| {
 | |
| 	ag71xx_check_reg_offset(ag, reg);
 | |
| 
 | |
| 	return __raw_readl(ag->mac_base + reg);
 | |
| }
 | |
| 
 | |
| static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask)
 | |
| {
 | |
| 	void __iomem *r;
 | |
| 
 | |
| 	ag71xx_check_reg_offset(ag, reg);
 | |
| 
 | |
| 	r = ag->mac_base + reg;
 | |
| 	__raw_writel(__raw_readl(r) | mask, r);
 | |
| 	/* flush write */
 | |
| 	(void)__raw_readl(r);
 | |
| }
 | |
| 
 | |
| static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask)
 | |
| {
 | |
| 	void __iomem *r;
 | |
| 
 | |
| 	ag71xx_check_reg_offset(ag, reg);
 | |
| 
 | |
| 	r = ag->mac_base + reg;
 | |
| 	__raw_writel(__raw_readl(r) & ~mask, r);
 | |
| 	/* flush write */
 | |
| 	(void) __raw_readl(r);
 | |
| }
 | |
| 
 | |
| static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints)
 | |
| {
 | |
| 	ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints);
 | |
| }
 | |
| 
 | |
| static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints)
 | |
| {
 | |
| 	ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints);
 | |
| }
 | |
| 
 | |
| static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value)
 | |
| {
 | |
| 	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
 | |
| 
 | |
| 	if (pdata->is_ar724x)
 | |
| 		return;
 | |
| 
 | |
| 	__raw_writel(value, ag->mii_ctrl);
 | |
| 
 | |
| 	/* flush write */
 | |
| 	__raw_readl(ag->mii_ctrl);
 | |
| }
 | |
| 
 | |
| static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag)
 | |
| {
 | |
| 	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
 | |
| 
 | |
| 	if (pdata->is_ar724x)
 | |
| 		return 0xffffffff;
 | |
| 
 | |
| 	return __raw_readl(ag->mii_ctrl);
 | |
| }
 | |
| 
 | |
| static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag,
 | |
| 					  unsigned int mii_if)
 | |
| {
 | |
| 	u32 t;
 | |
| 
 | |
| 	t = ag71xx_mii_ctrl_rr(ag);
 | |
| 	t &= ~(MII_CTRL_IF_MASK);
 | |
| 	t |= (mii_if & MII_CTRL_IF_MASK);
 | |
| 	ag71xx_mii_ctrl_wr(ag, t);
 | |
| }
 | |
| 
 | |
| static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag,
 | |
| 					     unsigned int speed)
 | |
| {
 | |
| 	u32 t;
 | |
| 
 | |
| 	t = ag71xx_mii_ctrl_rr(ag);
 | |
| 	t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT);
 | |
| 	t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT;
 | |
| 	ag71xx_mii_ctrl_wr(ag, t);
 | |
| }
 | |
| 
 | |
| #ifdef CONFIG_AG71XX_AR8216_SUPPORT
 | |
| void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb);
 | |
| int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb);
 | |
| #else
 | |
| static inline void ag71xx_add_ar8216_header(struct ag71xx *ag,
 | |
| 					   struct sk_buff *skb)
 | |
| {
 | |
| }
 | |
| 
 | |
| static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag,
 | |
| 					      struct sk_buff *skb)
 | |
| {
 | |
| 	return 0;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #ifdef CONFIG_AG71XX_DEBUG_FS
 | |
| int ag71xx_debugfs_root_init(void);
 | |
| void ag71xx_debugfs_root_exit(void);
 | |
| int ag71xx_debugfs_init(struct ag71xx *ag);
 | |
| void ag71xx_debugfs_exit(struct ag71xx *ag);
 | |
| void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status);
 | |
| void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx);
 | |
| #else
 | |
| static inline int ag71xx_debugfs_root_init(void) { return 0; }
 | |
| static inline void ag71xx_debugfs_root_exit(void) {}
 | |
| static inline int ag71xx_debugfs_init(struct ag71xx *ag) { return 0; }
 | |
| static inline void ag71xx_debugfs_exit(struct ag71xx *ag) {}
 | |
| static inline void ag71xx_debugfs_update_int_stats(struct ag71xx *ag,
 | |
| 						   u32 status) {}
 | |
| static inline void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag,
 | |
| 						    int rx, int tx) {}
 | |
| #endif /* CONFIG_AG71XX_DEBUG_FS */
 | |
| 
 | |
| #endif /* _AG71XX_H */
 |