diff options
| author | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-01-22 22:38:11 +0000 | 
|---|---|---|
| committer | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-01-22 22:38:11 +0000 | 
| commit | 22b99f32a13348502bc0f33b93b70565e941d99c (patch) | |
| tree | f60488ea3f321808d90711807b8a352e1f476b03 /target/linux/ar71xx/files/drivers | |
| parent | b66dee35c331cdcfc0ac2e61699abe1e9191e8d0 (diff) | |
ar71xx: move arch specific files to files-2.6.39
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@29867 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/ar71xx/files/drivers')
17 files changed, 0 insertions, 6213 deletions
diff --git a/target/linux/ar71xx/files/drivers/mtd/maps/ar91xx_flash.c b/target/linux/ar71xx/files/drivers/mtd/maps/ar91xx_flash.c deleted file mode 100644 index 51ba7f578..000000000 --- a/target/linux/ar71xx/files/drivers/mtd/maps/ar91xx_flash.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Parallel flash driver for the Atheros AR91xx SoC - * - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - * - * 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. - * - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/device.h> -#include <linux/platform_device.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/map.h> -#include <linux/mtd/partitions.h> -#include <linux/io.h> - -#include <asm/mach-ar71xx/ar71xx.h> -#include <asm/mach-ar71xx/ar91xx_flash.h> - -#define DRV_NAME	"ar91xx-flash" - -struct ar91xx_flash_info { -	struct mtd_info		*mtd; -	struct map_info		map; -#ifdef CONFIG_MTD_PARTITIONS -	int			nr_parts; -	struct mtd_partition	*parts; -#endif -}; - -static map_word ar91xx_flash_read(struct map_info *map, unsigned long ofs) -{ -	map_word val; - -	if (map_bankwidth_is_1(map)) -		val.x[0] = __raw_readb(map->virt + (ofs ^ 3)); -	else if (map_bankwidth_is_2(map)) -		val.x[0] = __raw_readw(map->virt + (ofs ^ 2)); -	else -		val = map_word_ff(map); - -	return val; -} - -static void ar91xx_flash_write(struct map_info *map, map_word d, -			       unsigned long ofs) -{ -	if (map_bankwidth_is_1(map)) -		__raw_writeb(d.x[0], map->virt + (ofs ^ 3)); -	else if (map_bankwidth_is_2(map)) -		__raw_writew(d.x[0], map->virt + (ofs ^ 2)); - -	mb(); -} - -static map_word ar91xx_flash_read_lock(struct map_info *map, unsigned long ofs) -{ -	map_word ret; - -	ar71xx_flash_acquire(); -	ret = ar91xx_flash_read(map, ofs); -	ar71xx_flash_release(); - -	return ret; -} - -static void ar91xx_flash_write_lock(struct map_info *map, map_word d, -			       unsigned long ofs) -{ -	ar71xx_flash_acquire(); -	ar91xx_flash_write(map, d, ofs); -	ar71xx_flash_release(); -} - -static void ar91xx_flash_copy_from_lock(struct map_info *map, void *to, -					unsigned long from, ssize_t len) -{ -	ar71xx_flash_acquire(); -	inline_map_copy_from(map, to, from, len); -	ar71xx_flash_release(); -} - -static void ar91xx_flash_copy_to_lock(struct map_info *map, unsigned long to, -				      const void *from, ssize_t len) -{ -	ar71xx_flash_acquire(); -	inline_map_copy_to(map, to, from, len); -	ar71xx_flash_release(); -} - -static int ar91xx_flash_remove(struct platform_device *pdev) -{ -	struct ar91xx_flash_platform_data *pdata; -	struct ar91xx_flash_info *info; - -	info = platform_get_drvdata(pdev); -	if (info == NULL) -		return 0; - -	platform_set_drvdata(pdev, NULL); - -	if (info->mtd == NULL) -		return 0; - -	pdata = pdev->dev.platform_data; -#ifdef CONFIG_MTD_PARTITIONS -	if (info->nr_parts) { -		del_mtd_partitions(info->mtd); -		kfree(info->parts); -	} else if (pdata->nr_parts) { -		del_mtd_partitions(info->mtd); -	} else { -		del_mtd_device(info->mtd); -	} -#else -	del_mtd_device(info->mtd); -#endif -	map_destroy(info->mtd); - -	return 0; -} - -static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; -#ifdef CONFIG_MTD_PARTITIONS -static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; -#endif - -static int ar91xx_flash_probe(struct platform_device *pdev) -{ -	struct ar91xx_flash_platform_data *pdata; -	struct ar91xx_flash_info *info; -	struct resource *res; -	struct resource *region; -	const char **probe_type; -	int err = 0; - -	pdata = pdev->dev.platform_data; -	if (pdata == NULL) -		return -EINVAL; - -	info = devm_kzalloc(&pdev->dev, sizeof(struct ar91xx_flash_info), -			    GFP_KERNEL); -	if (info == NULL) { -		err = -ENOMEM; -		goto err_out; -	} - -	platform_set_drvdata(pdev, info); - -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (res == NULL) { -		err = -ENOENT; -		goto err_out; -	} - -	dev_info(&pdev->dev, "%.8llx at %.8llx\n", -		 (unsigned long long)(res->end - res->start + 1), -		 (unsigned long long)res->start); - -	region = devm_request_mem_region(&pdev->dev, -					 res->start, res->end - res->start + 1, -					 dev_name(&pdev->dev)); -	if (region == NULL) { -		dev_err(&pdev->dev, "could not reserve memory region\n"); -		err = -ENOMEM; -		goto err_out; -	} - -	info->map.name = dev_name(&pdev->dev); -	info->map.phys = res->start; -	info->map.size = res->end - res->start + 1; -	info->map.bankwidth = pdata->width; - -	info->map.virt = devm_ioremap(&pdev->dev, info->map.phys, -				      info->map.size); -	if (info->map.virt == NULL) { -		dev_err(&pdev->dev, "failed to ioremap flash region\n"); -		err = -EIO; -		goto err_out; -	} - -	simple_map_init(&info->map); -	if (pdata->is_shared) { -		info->map.read = ar91xx_flash_read_lock; -		info->map.write = ar91xx_flash_write_lock; -		info->map.copy_from = ar91xx_flash_copy_from_lock; -		info->map.copy_to = ar91xx_flash_copy_to_lock; -	} else { -		info->map.read = ar91xx_flash_read; -		info->map.write = ar91xx_flash_write; -	} - -	probe_type = rom_probe_types; -	for (; info->mtd == NULL && *probe_type != NULL; probe_type++) -		info->mtd = do_map_probe(*probe_type, &info->map); - -	if (info->mtd == NULL) { -		dev_err(&pdev->dev, "map_probe failed\n"); -		err = -ENXIO; -		goto err_out; -	} - -	info->mtd->owner = THIS_MODULE; - -#ifdef CONFIG_MTD_PARTITIONS -	if (pdata->nr_parts) { -		dev_info(&pdev->dev, "using static partition mapping\n"); -		add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); -		return 0; -	} - -	err = parse_mtd_partitions(info->mtd, part_probe_types, -				   &info->parts, 0); -	if (err > 0) { -		add_mtd_partitions(info->mtd, info->parts, err); -		return 0; -	} -#endif - -	add_mtd_device(info->mtd); -	return 0; - -err_out: -	ar91xx_flash_remove(pdev); -	return err; -} - -#ifdef CONFIG_PM -static int ar91xx_flash_suspend(struct platform_device *dev, pm_message_t state) -{ -	struct ar91xx_flash_info *info = platform_get_drvdata(dev); -	int ret = 0; - -	if (info->mtd->suspend) -		ret = info->mtd->suspend(info->mtd); - -	if (ret) -		goto fail; - -	return 0; - -fail: -	if (info->mtd->suspend) { -		BUG_ON(!info->mtd->resume); -		info->mtd->resume(info->mtd); -	} - -	return ret; -} - -static int ar91xx_flash_resume(struct platform_device *pdev) -{ -	struct ar91xx_flash_info *info = platform_get_drvdata(pdev); - -	if (info->mtd->resume) -		info->mtd->resume(info->mtd); - -	return 0; -} - -static void ar91xx_flash_shutdown(struct platform_device *pdev) -{ -	struct ar91xx_flash_info *info = platform_get_drvdata(pdev); - -	if (info->mtd->suspend && info->mtd->resume) -		if (info->mtd->suspend(info->mtd) == 0) -			info->mtd->resume(info->mtd); -} -#else -#define ar91xx_flash_suspend	NULL -#define ar91xx_flash_resume	NULL -#define ar91xx_flash_shutdown	NULL -#endif - -static struct platform_driver ar91xx_flash_driver = { -	.probe		= ar91xx_flash_probe, -	.remove		= ar91xx_flash_remove, -	.suspend	= ar91xx_flash_suspend, -	.resume		= ar91xx_flash_resume, -	.shutdown	= ar91xx_flash_shutdown, -	.driver		= { -		.name	= DRV_NAME, -		.owner	= THIS_MODULE, -	}, -}; - -static int __init ar91xx_flash_init(void) -{ -	return platform_driver_register(&ar91xx_flash_driver); -} - -static void __exit ar91xx_flash_exit(void) -{ -	platform_driver_unregister(&ar91xx_flash_driver); -} - -module_init(ar91xx_flash_init); -module_exit(ar91xx_flash_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); -MODULE_DESCRIPTION("Parallel flash driver for the Atheros AR91xx SoC"); -MODULE_ALIAS("platform:" DRV_NAME); diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/Kconfig b/target/linux/ar71xx/files/drivers/net/ag71xx/Kconfig deleted file mode 100644 index 7db779e38..000000000 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/Kconfig +++ /dev/null @@ -1,33 +0,0 @@ -config AG71XX -	tristate "Atheros AR71xx built-in ethernet mac support" -	depends on ATHEROS_AR71XX -	select PHYLIB -	help -	  If you wish to compile a kernel for AR71xx/91xx and enable -	  ethernet support, then you should always answer Y to this. - -if AG71XX - -config AG71XX_DEBUG -	bool "Atheros AR71xx built-in ethernet driver debugging" -	default n -	help -	  Atheros AR71xx built-in ethernet driver debugging messages. - -config AG71XX_DEBUG_FS -	bool "Atheros AR71xx built-in ethernet driver debugfs support" -	depends on DEBUG_FS -	default n -	help -	  Say Y, if you need access to various statistics provided by -	  the ag71xx driver. - -config AG71XX_AR8216_SUPPORT -	bool "special support for the Atheros AR8216 switch" -	default n -	default y if AR71XX_MACH_WNR2000 || AR71XX_MACH_MZK_W04NU -	help -	  Say 'y' here if you want to enable special support for the -	  Atheros AR8216 switch found on some boards. - -endif diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/Makefile b/target/linux/ar71xx/files/drivers/net/ag71xx/Makefile deleted file mode 100644 index b3ec4084c..000000000 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# Makefile for the Atheros AR71xx built-in ethernet macs -# - -ag71xx-y	+= ag71xx_main.o -ag71xx-y	+= ag71xx_ethtool.o -ag71xx-y	+= ag71xx_phy.o -ag71xx-y	+= ag71xx_mdio.o -ag71xx-y	+= ag71xx_ar7240.o - -ag71xx-$(CONFIG_AG71XX_DEBUG_FS)	+= ag71xx_debugfs.o -ag71xx-$(CONFIG_AG71XX_AR8216_SUPPORT)	+= ag71xx_ar8216.o - -obj-$(CONFIG_AG71XX)	+= ag71xx.o - diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h deleted file mode 100644 index 97e5fb284..000000000 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h +++ /dev/null @@ -1,465 +0,0 @@ -/* - *  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/if_vlan.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 AG71XX_DRV_NAME		"ag71xx" -#define AG71XX_DRV_VERSION	"0.5.35" - -#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_MTU_LEN	1540 -#define AG71XX_RX_PKT_RESERVE	64 -#define AG71XX_RX_PKT_SIZE	\ -	(AG71XX_RX_PKT_RESERVE + ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) - -#define AG71XX_TX_RING_SIZE_DEFAULT	64 -#define AG71XX_RX_RING_SIZE_DEFAULT	128 - -#define AG71XX_TX_RING_SIZE_MAX		256 -#define AG71XX_RX_RING_SIZE_MAX		256 - -#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; -	unsigned long		timestamp; -}; - -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 ag71xx_int_stats int_stats; -	struct ag71xx_napi_stats napi_stats; -}; - -struct ag71xx { -	void __iomem		*mac_base; - -	spinlock_t		lock; -	struct platform_device	*pdev; -	struct net_device	*dev; -	struct napi_struct	napi; -	u32			msg_enable; - -	struct ag71xx_desc	*stop_desc; -	dma_addr_t		stop_desc_dma; - -	struct ag71xx_ring	rx_ring; -	struct ag71xx_ring	tx_ring; - -	struct mii_bus		*mii_bus; -	struct phy_device	*phy_dev; -	void			*phy_priv; - -	unsigned int		link; -	unsigned int		speed; -	int			duplex; - -	struct work_struct	restart_work; -	struct delayed_work	link_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 AG71XX_REG_FIFO_DEPTH	0x01a8 -#define AG71XX_REG_RX_SM	0x01b0 -#define AG71XX_REG_TX_SM	0x01b4 - -#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 */ - -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_TX_SM: -	case AG71XX_REG_MII_CFG: -		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); -} - -#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, -				int pktlen); -static inline int ag71xx_has_ar8216(struct ag71xx *ag) -{ -	return ag71xx_get_pdata(ag)->has_ar8216; -} -#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, -					      int pktlen) -{ -	return 0; -} -static inline int ag71xx_has_ar8216(struct ag71xx *ag) -{ -	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 */ - -void ag71xx_ar7240_start(struct ag71xx *ag); -void ag71xx_ar7240_stop(struct ag71xx *ag); -int ag71xx_ar7240_init(struct ag71xx *ag); -void ag71xx_ar7240_cleanup(struct ag71xx *ag); - -int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg); -void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val); - -u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr, -		      unsigned reg_addr); -int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr, -		       unsigned reg_addr, u16 reg_val); - -#endif /* _AG71XX_H */ diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ar7240.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ar7240.c deleted file mode 100644 index ab7abd9e5..000000000 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ar7240.c +++ /dev/null @@ -1,1194 +0,0 @@ -/* - *  Driver for the built-in ethernet switch of the Atheros AR7240 SoC - *  Copyright (c) 2010 Gabor Juhos <juhosg@openwrt.org> - *  Copyright (c) 2010 Felix Fietkau <nbd@openwrt.org> - * - *  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. - * - */ - -#include <linux/etherdevice.h> -#include <linux/list.h> -#include <linux/netdevice.h> -#include <linux/phy.h> -#include <linux/mii.h> -#include <linux/bitops.h> -#include <linux/switch.h> -#include "ag71xx.h" - -#define BITM(_count)	(BIT(_count) - 1) -#define BITS(_shift, _count)	(BITM(_count) << _shift) - -#define AR7240_REG_MASK_CTRL		0x00 -#define AR7240_MASK_CTRL_REVISION_M	BITM(8) -#define AR7240_MASK_CTRL_VERSION_M	BITM(8) -#define AR7240_MASK_CTRL_VERSION_S	8 -#define   AR7240_MASK_CTRL_VERSION_AR7240 0x01 -#define   AR7240_MASK_CTRL_VERSION_AR934X 0x02 -#define AR7240_MASK_CTRL_SOFT_RESET	BIT(31) - -#define AR7240_REG_MAC_ADDR0		0x20 -#define AR7240_REG_MAC_ADDR1		0x24 - -#define AR7240_REG_FLOOD_MASK		0x2c -#define AR7240_FLOOD_MASK_BROAD_TO_CPU	BIT(26) - -#define AR7240_REG_GLOBAL_CTRL		0x30 -#define AR7240_GLOBAL_CTRL_MTU_M	BITM(12) - -#define AR7240_REG_VTU			0x0040 -#define   AR7240_VTU_OP			BITM(3) -#define   AR7240_VTU_OP_NOOP		0x0 -#define   AR7240_VTU_OP_FLUSH		0x1 -#define   AR7240_VTU_OP_LOAD		0x2 -#define   AR7240_VTU_OP_PURGE		0x3 -#define   AR7240_VTU_OP_REMOVE_PORT	0x4 -#define   AR7240_VTU_ACTIVE		BIT(3) -#define   AR7240_VTU_FULL		BIT(4) -#define   AR7240_VTU_PORT		BITS(8, 4) -#define   AR7240_VTU_PORT_S		8 -#define   AR7240_VTU_VID		BITS(16, 12) -#define   AR7240_VTU_VID_S		16 -#define   AR7240_VTU_PRIO		BITS(28, 3) -#define   AR7240_VTU_PRIO_S		28 -#define   AR7240_VTU_PRIO_EN		BIT(31) - -#define AR7240_REG_VTU_DATA		0x0044 -#define   AR7240_VTUDATA_MEMBER		BITS(0, 10) -#define   AR7240_VTUDATA_VALID		BIT(11) - -#define AR7240_REG_ATU			0x50 -#define AR7240_ATU_FLUSH_ALL		0x1 - -#define AR7240_REG_AT_CTRL		0x5c -#define AR7240_AT_CTRL_AGE_TIME		BITS(0, 15) -#define AR7240_AT_CTRL_AGE_EN		BIT(17) -#define AR7240_AT_CTRL_LEARN_CHANGE	BIT(18) -#define AR7240_AT_CTRL_RESERVED		BIT(19) -#define AR7240_AT_CTRL_ARP_EN		BIT(20) - -#define AR7240_REG_TAG_PRIORITY		0x70 - -#define AR7240_REG_SERVICE_TAG		0x74 -#define AR7240_SERVICE_TAG_M		BITM(16) - -#define AR7240_REG_CPU_PORT		0x78 -#define AR7240_MIRROR_PORT_S		4 -#define AR7240_CPU_PORT_EN		BIT(8) - -#define AR7240_REG_MIB_FUNCTION0	0x80 -#define AR7240_MIB_TIMER_M		BITM(16) -#define AR7240_MIB_AT_HALF_EN		BIT(16) -#define AR7240_MIB_BUSY			BIT(17) -#define AR7240_MIB_FUNC_S		24 -#define AR7240_MIB_FUNC_NO_OP		0x0 -#define AR7240_MIB_FUNC_FLUSH		0x1 -#define AR7240_MIB_FUNC_CAPTURE		0x3 - -#define AR7240_REG_MDIO_CTRL		0x98 -#define AR7240_MDIO_CTRL_DATA_M		BITM(16) -#define AR7240_MDIO_CTRL_REG_ADDR_S	16 -#define AR7240_MDIO_CTRL_PHY_ADDR_S	21 -#define AR7240_MDIO_CTRL_CMD_WRITE	0 -#define AR7240_MDIO_CTRL_CMD_READ	BIT(27) -#define AR7240_MDIO_CTRL_MASTER_EN	BIT(30) -#define AR7240_MDIO_CTRL_BUSY		BIT(31) - -#define AR7240_REG_PORT_BASE(_port)	(0x100 + (_port) * 0x100) - -#define AR7240_REG_PORT_STATUS(_port)	(AR7240_REG_PORT_BASE((_port)) + 0x00) -#define AR7240_PORT_STATUS_SPEED_S	0 -#define AR7240_PORT_STATUS_SPEED_M	BITM(2) -#define AR7240_PORT_STATUS_SPEED_10	0 -#define AR7240_PORT_STATUS_SPEED_100	1 -#define AR7240_PORT_STATUS_SPEED_1000	2 -#define AR7240_PORT_STATUS_TXMAC	BIT(2) -#define AR7240_PORT_STATUS_RXMAC	BIT(3) -#define AR7240_PORT_STATUS_TXFLOW	BIT(4) -#define AR7240_PORT_STATUS_RXFLOW	BIT(5) -#define AR7240_PORT_STATUS_DUPLEX	BIT(6) -#define AR7240_PORT_STATUS_LINK_UP	BIT(8) -#define AR7240_PORT_STATUS_LINK_AUTO	BIT(9) -#define AR7240_PORT_STATUS_LINK_PAUSE	BIT(10) - -#define AR7240_REG_PORT_CTRL(_port)	(AR7240_REG_PORT_BASE((_port)) + 0x04) -#define AR7240_PORT_CTRL_STATE_M	BITM(3) -#define	AR7240_PORT_CTRL_STATE_DISABLED	0 -#define AR7240_PORT_CTRL_STATE_BLOCK	1 -#define AR7240_PORT_CTRL_STATE_LISTEN	2 -#define AR7240_PORT_CTRL_STATE_LEARN	3 -#define AR7240_PORT_CTRL_STATE_FORWARD	4 -#define AR7240_PORT_CTRL_LEARN_LOCK	BIT(7) -#define AR7240_PORT_CTRL_VLAN_MODE_S	8 -#define AR7240_PORT_CTRL_VLAN_MODE_KEEP	0 -#define AR7240_PORT_CTRL_VLAN_MODE_STRIP 1 -#define AR7240_PORT_CTRL_VLAN_MODE_ADD	2 -#define AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG 3 -#define AR7240_PORT_CTRL_IGMP_SNOOP	BIT(10) -#define AR7240_PORT_CTRL_HEADER		BIT(11) -#define AR7240_PORT_CTRL_MAC_LOOP	BIT(12) -#define AR7240_PORT_CTRL_SINGLE_VLAN	BIT(13) -#define AR7240_PORT_CTRL_LEARN		BIT(14) -#define AR7240_PORT_CTRL_DOUBLE_TAG	BIT(15) -#define AR7240_PORT_CTRL_MIRROR_TX	BIT(16) -#define AR7240_PORT_CTRL_MIRROR_RX	BIT(17) - -#define AR7240_REG_PORT_VLAN(_port)	(AR7240_REG_PORT_BASE((_port)) + 0x08) - -#define AR7240_PORT_VLAN_DEFAULT_ID_S	0 -#define AR7240_PORT_VLAN_DEST_PORTS_S	16 -#define AR7240_PORT_VLAN_MODE_S		30 -#define AR7240_PORT_VLAN_MODE_PORT_ONLY	0 -#define AR7240_PORT_VLAN_MODE_PORT_FALLBACK	1 -#define AR7240_PORT_VLAN_MODE_VLAN_ONLY	2 -#define AR7240_PORT_VLAN_MODE_SECURE	3 - - -#define AR7240_REG_STATS_BASE(_port)	(0x20000 + (_port) * 0x100) - -#define AR7240_STATS_RXBROAD		0x00 -#define AR7240_STATS_RXPAUSE		0x04 -#define AR7240_STATS_RXMULTI		0x08 -#define AR7240_STATS_RXFCSERR		0x0c -#define AR7240_STATS_RXALIGNERR		0x10 -#define AR7240_STATS_RXRUNT		0x14 -#define AR7240_STATS_RXFRAGMENT		0x18 -#define AR7240_STATS_RX64BYTE		0x1c -#define AR7240_STATS_RX128BYTE		0x20 -#define AR7240_STATS_RX256BYTE		0x24 -#define AR7240_STATS_RX512BYTE		0x28 -#define AR7240_STATS_RX1024BYTE		0x2c -#define AR7240_STATS_RX1518BYTE		0x30 -#define AR7240_STATS_RXMAXBYTE		0x34 -#define AR7240_STATS_RXTOOLONG		0x38 -#define AR7240_STATS_RXGOODBYTE		0x3c -#define AR7240_STATS_RXBADBYTE		0x44 -#define AR7240_STATS_RXOVERFLOW		0x4c -#define AR7240_STATS_FILTERED		0x50 -#define AR7240_STATS_TXBROAD		0x54 -#define AR7240_STATS_TXPAUSE		0x58 -#define AR7240_STATS_TXMULTI		0x5c -#define AR7240_STATS_TXUNDERRUN		0x60 -#define AR7240_STATS_TX64BYTE		0x64 -#define AR7240_STATS_TX128BYTE		0x68 -#define AR7240_STATS_TX256BYTE		0x6c -#define AR7240_STATS_TX512BYTE		0x70 -#define AR7240_STATS_TX1024BYTE		0x74 -#define AR7240_STATS_TX1518BYTE		0x78 -#define AR7240_STATS_TXMAXBYTE		0x7c -#define AR7240_STATS_TXOVERSIZE		0x80 -#define AR7240_STATS_TXBYTE		0x84 -#define AR7240_STATS_TXCOLLISION	0x8c -#define AR7240_STATS_TXABORTCOL		0x90 -#define AR7240_STATS_TXMULTICOL		0x94 -#define AR7240_STATS_TXSINGLECOL	0x98 -#define AR7240_STATS_TXEXCDEFER		0x9c -#define AR7240_STATS_TXDEFER		0xa0 -#define AR7240_STATS_TXLATECOL		0xa4 - -#define AR7240_PORT_CPU		0 -#define AR7240_NUM_PORTS	6 -#define AR7240_NUM_PHYS		5 - -#define AR7240_PHY_ID1		0x004d -#define AR7240_PHY_ID2		0xd041 - -#define AR934X_PHY_ID1		0x004d -#define AR934X_PHY_ID2		0xd042 - -#define AR7240_MAX_VLANS	16 - -#define AR934X_REG_OPER_MODE0		0x04 -#define   AR934X_OPER_MODE0_MAC_GMII_EN	BIT(6) -#define   AR934X_OPER_MODE0_PHY_MII_EN	BIT(10) - -#define AR934X_REG_OPER_MODE1		0x08 -#define   AR934X_REG_OPER_MODE1_PHY4_MII_EN	BIT(28) - -#define AR934X_REG_PORT_BASE(_port)	(0x100 + (_port) * 0x100) - -#define AR934X_REG_PORT_VLAN1(_port)	(AR934X_REG_PORT_BASE((_port)) + 0x08) -#define   AR934X_PORT_VLAN1_DEFAULT_SVID_S		0 -#define   AR934X_PORT_VLAN1_FORCE_DEFAULT_VID_EN 	BIT(12) -#define   AR934X_PORT_VLAN1_PORT_TLS_MODE		BIT(13) -#define   AR934X_PORT_VLAN1_PORT_VLAN_PROP_EN		BIT(14) -#define   AR934X_PORT_VLAN1_PORT_CLONE_EN		BIT(15) -#define   AR934X_PORT_VLAN1_DEFAULT_CVID_S		16 -#define   AR934X_PORT_VLAN1_FORCE_PORT_VLAN_EN		BIT(28) -#define   AR934X_PORT_VLAN1_ING_PORT_PRI_S		29 - -#define AR934X_REG_PORT_VLAN2(_port)	(AR934X_REG_PORT_BASE((_port)) + 0x0c) -#define   AR934X_PORT_VLAN2_PORT_VID_MEM_S		16 -#define   AR934X_PORT_VLAN2_8021Q_MODE_S		30 -#define   AR934X_PORT_VLAN2_8021Q_MODE_PORT_ONLY	0 -#define   AR934X_PORT_VLAN2_8021Q_MODE_PORT_FALLBACK	1 -#define   AR934X_PORT_VLAN2_8021Q_MODE_VLAN_ONLY	2 -#define   AR934X_PORT_VLAN2_8021Q_MODE_SECURE		3 - -#define sw_to_ar7240(_dev) container_of(_dev, struct ar7240sw, swdev) - -struct ar7240sw_port_stat { -	unsigned long rx_broadcast; -	unsigned long rx_pause; -	unsigned long rx_multicast; -	unsigned long rx_fcs_error; -	unsigned long rx_align_error; -	unsigned long rx_runt; -	unsigned long rx_fragments; -	unsigned long rx_64byte; -	unsigned long rx_128byte; -	unsigned long rx_256byte; -	unsigned long rx_512byte; -	unsigned long rx_1024byte; -	unsigned long rx_1518byte; -	unsigned long rx_maxbyte; -	unsigned long rx_toolong; -	unsigned long rx_good_byte; -	unsigned long rx_bad_byte; -	unsigned long rx_overflow; -	unsigned long filtered; - -	unsigned long tx_broadcast; -	unsigned long tx_pause; -	unsigned long tx_multicast; -	unsigned long tx_underrun; -	unsigned long tx_64byte; -	unsigned long tx_128byte; -	unsigned long tx_256byte; -	unsigned long tx_512byte; -	unsigned long tx_1024byte; -	unsigned long tx_1518byte; -	unsigned long tx_maxbyte; -	unsigned long tx_oversize; -	unsigned long tx_byte; -	unsigned long tx_collision; -	unsigned long tx_abortcol; -	unsigned long tx_multicol; -	unsigned long tx_singlecol; -	unsigned long tx_excdefer; -	unsigned long tx_defer; -	unsigned long tx_xlatecol; -}; - -struct ar7240sw { -	struct mii_bus	*mii_bus; -	struct ag71xx_switch_platform_data *swdata; -	struct switch_dev swdev; -	int num_ports; -	u8 ver; -	bool vlan; -	u16 vlan_id[AR7240_MAX_VLANS]; -	u8 vlan_table[AR7240_MAX_VLANS]; -	u8 vlan_tagged; -	u16 pvid[AR7240_NUM_PORTS]; -	char buf[80]; - -	rwlock_t stats_lock; -	struct ar7240sw_port_stat port_stats[AR7240_NUM_PORTS]; -}; - -struct ar7240sw_hw_stat { -	char string[ETH_GSTRING_LEN]; -	int sizeof_stat; -	int reg; -}; - -static DEFINE_MUTEX(reg_mutex); - -static inline int sw_is_ar7240(struct ar7240sw *as) -{ -	return as->ver == AR7240_MASK_CTRL_VERSION_AR7240; -} - -static inline int sw_is_ar934x(struct ar7240sw *as) -{ -	return as->ver == AR7240_MASK_CTRL_VERSION_AR934X; -} - -static inline u32 ar7240sw_port_mask(struct ar7240sw *as, int port) -{ -	return BIT(port); -} - -static inline u32 ar7240sw_port_mask_all(struct ar7240sw *as) -{ -	return BIT(as->swdev.ports) - 1; -} - -static inline u32 ar7240sw_port_mask_but(struct ar7240sw *as, int port) -{ -	return ar7240sw_port_mask_all(as) & ~BIT(port); -} - -static inline u16 mk_phy_addr(u32 reg) -{ -	return 0x17 & ((reg >> 4) | 0x10); -} - -static inline u16 mk_phy_reg(u32 reg) -{ -	return (reg << 1) & 0x1e; -} - -static inline u16 mk_high_addr(u32 reg) -{ -	return (reg >> 7) & 0x1ff; -} - -static u32 __ar7240sw_reg_read(struct mii_bus *mii, u32 reg) -{ -	unsigned long flags; -	u16 phy_addr; -	u16 phy_reg; -	u32 hi, lo; - -	reg = (reg & 0xfffffffc) >> 2; -	phy_addr = mk_phy_addr(reg); -	phy_reg = mk_phy_reg(reg); - -	local_irq_save(flags); -	ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); -	lo = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg); -	hi = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg + 1); -	local_irq_restore(flags); - -	return (hi << 16) | lo; -} - -static void __ar7240sw_reg_write(struct mii_bus *mii, u32 reg, u32 val) -{ -	unsigned long flags; -	u16 phy_addr; -	u16 phy_reg; - -	reg = (reg & 0xfffffffc) >> 2; -	phy_addr = mk_phy_addr(reg); -	phy_reg = mk_phy_reg(reg); - -	local_irq_save(flags); -	ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); -	ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg + 1, (val >> 16)); -	ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg, (val & 0xffff)); -	local_irq_restore(flags); -} - -static u32 ar7240sw_reg_read(struct mii_bus *mii, u32 reg_addr) -{ -	u32 ret; - -	mutex_lock(®_mutex); -	ret = __ar7240sw_reg_read(mii, reg_addr); -	mutex_unlock(®_mutex); - -	return ret; -} - -static void ar7240sw_reg_write(struct mii_bus *mii, u32 reg_addr, u32 reg_val) -{ -	mutex_lock(®_mutex); -	__ar7240sw_reg_write(mii, reg_addr, reg_val); -	mutex_unlock(®_mutex); -} - -static u32 ar7240sw_reg_rmw(struct mii_bus *mii, u32 reg, u32 mask, u32 val) -{ -	u32 t; - -	mutex_lock(®_mutex); -	t = __ar7240sw_reg_read(mii, reg); -	t &= ~mask; -	t |= val; -	__ar7240sw_reg_write(mii, reg, t); -	mutex_unlock(®_mutex); - -	return t; -} - -static void ar7240sw_reg_set(struct mii_bus *mii, u32 reg, u32 val) -{ -	u32 t; - -	mutex_lock(®_mutex); -	t = __ar7240sw_reg_read(mii, reg); -	t |= val; -	__ar7240sw_reg_write(mii, reg, t); -	mutex_unlock(®_mutex); -} - -static int __ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val, -			       unsigned timeout) -{ -	int i; - -	for (i = 0; i < timeout; i++) { -		u32 t; - -		t = __ar7240sw_reg_read(mii, reg); -		if ((t & mask) == val) -			return 0; - -		msleep(1); -	} - -	return -ETIMEDOUT; -} - -static int ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val, -			     unsigned timeout) -{ -	int ret; - -	mutex_lock(®_mutex); -	ret = __ar7240sw_reg_wait(mii, reg, mask, val, timeout); -	mutex_unlock(®_mutex); -	return ret; -} - -u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr, -		      unsigned reg_addr) -{ -	u32 t, val = 0xffff; -	int err; - -	if (phy_addr >= AR7240_NUM_PHYS) -		return 0xffff; - -	mutex_lock(®_mutex); -	t = (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | -	    (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | -	    AR7240_MDIO_CTRL_MASTER_EN | -	    AR7240_MDIO_CTRL_BUSY | -	    AR7240_MDIO_CTRL_CMD_READ; - -	__ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t); -	err = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL, -				  AR7240_MDIO_CTRL_BUSY, 0, 5); -	if (!err) -		val = __ar7240sw_reg_read(mii, AR7240_REG_MDIO_CTRL); -	mutex_unlock(®_mutex); - -	return val & AR7240_MDIO_CTRL_DATA_M; -} - -int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr, -		       unsigned reg_addr, u16 reg_val) -{ -	u32 t; -	int ret; - -	if (phy_addr >= AR7240_NUM_PHYS) -		return -EINVAL; - -	mutex_lock(®_mutex); -	t = (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | -	    (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | -	    AR7240_MDIO_CTRL_MASTER_EN | -	    AR7240_MDIO_CTRL_BUSY | -	    AR7240_MDIO_CTRL_CMD_WRITE | -	    reg_val; - -	__ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t); -	ret = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL, -				  AR7240_MDIO_CTRL_BUSY, 0, 5); -	mutex_unlock(®_mutex); - -	return ret; -} - -static int ar7240sw_capture_stats(struct ar7240sw *as) -{ -	struct mii_bus *mii = as->mii_bus; -	int port; -	int ret; - -	write_lock(&as->stats_lock); - -	/* Capture the hardware statistics for all ports */ -	ar7240sw_reg_write(mii, AR7240_REG_MIB_FUNCTION0, -			   (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S)); - -	/* Wait for the capturing to complete. */ -	ret = ar7240sw_reg_wait(mii, AR7240_REG_MIB_FUNCTION0, -				AR7240_MIB_BUSY, 0, 10); - -	if (ret) -		goto unlock; - -	for (port = 0; port < AR7240_NUM_PORTS; port++) { -		unsigned int base; -		struct ar7240sw_port_stat *stats; - -		base = AR7240_REG_STATS_BASE(port); -		stats = &as->port_stats[port]; - -#define READ_STAT(_r) ar7240sw_reg_read(mii, base + AR7240_STATS_ ## _r) - -		stats->rx_good_byte += READ_STAT(RXGOODBYTE); -		stats->tx_byte += READ_STAT(TXBYTE); - -#undef READ_STAT -	} - -	ret = 0; - -unlock: -	write_unlock(&as->stats_lock); -	return ret; -} - -static void ar7240sw_disable_port(struct ar7240sw *as, unsigned port) -{ -	ar7240sw_reg_write(as->mii_bus, AR7240_REG_PORT_CTRL(port), -			   AR7240_PORT_CTRL_STATE_DISABLED); -} - -static void ar7240sw_setup(struct ar7240sw *as) -{ -	struct mii_bus *mii = as->mii_bus; - -	/* Enable CPU port, and disable mirror port */ -	ar7240sw_reg_write(mii, AR7240_REG_CPU_PORT, -			   AR7240_CPU_PORT_EN | -			   (15 << AR7240_MIRROR_PORT_S)); - -	/* Setup TAG priority mapping */ -	ar7240sw_reg_write(mii, AR7240_REG_TAG_PRIORITY, 0xfa50); - -	/* Enable ARP frame acknowledge, aging, MAC replacing */ -	ar7240sw_reg_write(mii, AR7240_REG_AT_CTRL, -		AR7240_AT_CTRL_RESERVED | -		0x2b /* 5 min age time */ | -		AR7240_AT_CTRL_AGE_EN | -		AR7240_AT_CTRL_ARP_EN | -		AR7240_AT_CTRL_LEARN_CHANGE); - -	/* Enable Broadcast frames transmitted to the CPU */ -	ar7240sw_reg_set(mii, AR7240_REG_FLOOD_MASK, -			 AR7240_FLOOD_MASK_BROAD_TO_CPU); - -	/* setup MTU */ -	ar7240sw_reg_rmw(mii, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M, -			 1536); - -	/* setup Service TAG */ -	ar7240sw_reg_rmw(mii, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M, 0); -} - -static int ar7240sw_reset(struct ar7240sw *as) -{ -	struct mii_bus *mii = as->mii_bus; -	int ret; -	int i; - -	/* Set all ports to disabled state. */ -	for (i = 0; i < AR7240_NUM_PORTS; i++) -		ar7240sw_disable_port(as, i); - -	/* Wait for transmit queues to drain. */ -	msleep(2); - -	/* Reset the switch. */ -	ar7240sw_reg_write(mii, AR7240_REG_MASK_CTRL, -			   AR7240_MASK_CTRL_SOFT_RESET); - -	ret = ar7240sw_reg_wait(mii, AR7240_REG_MASK_CTRL, -				AR7240_MASK_CTRL_SOFT_RESET, 0, 1000); - -	ar7240sw_setup(as); -	return ret; -} - -static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port, u8 portmask) -{ -	struct mii_bus *mii = as->mii_bus; -	u32 ctrl; -	u32 vid, mode; - -	ctrl = AR7240_PORT_CTRL_STATE_FORWARD | AR7240_PORT_CTRL_LEARN | -		AR7240_PORT_CTRL_SINGLE_VLAN; - -	if (port == AR7240_PORT_CPU) { -		ar7240sw_reg_write(mii, AR7240_REG_PORT_STATUS(port), -				   AR7240_PORT_STATUS_SPEED_1000 | -				   AR7240_PORT_STATUS_TXFLOW | -				   AR7240_PORT_STATUS_RXFLOW | -				   AR7240_PORT_STATUS_TXMAC | -				   AR7240_PORT_STATUS_RXMAC | -				   AR7240_PORT_STATUS_DUPLEX); -	} else { -		ar7240sw_reg_write(mii, AR7240_REG_PORT_STATUS(port), -				   AR7240_PORT_STATUS_LINK_AUTO); -	} - -	/* Set the default VID for this port */ -	if (as->vlan) { -		vid = as->vlan_id[as->pvid[port]]; -		mode = AR7240_PORT_VLAN_MODE_SECURE; -	} else { -		vid = port; -		mode = AR7240_PORT_VLAN_MODE_PORT_ONLY; -	} - -	if (as->vlan && (as->vlan_tagged & BIT(port))) { -		ctrl |= AR7240_PORT_CTRL_VLAN_MODE_ADD << -			AR7240_PORT_CTRL_VLAN_MODE_S; -	} else { -		ctrl |= AR7240_PORT_CTRL_VLAN_MODE_STRIP << -			AR7240_PORT_CTRL_VLAN_MODE_S; -	} - -	if (!portmask) { -		if (port == AR7240_PORT_CPU) -			portmask = ar7240sw_port_mask_but(as, AR7240_PORT_CPU); -		else -			portmask = ar7240sw_port_mask(as, AR7240_PORT_CPU); -	} - -	/* allow the port to talk to all other ports, but exclude its -	 * own ID to prevent frames from being reflected back to the -	 * port that they came from */ -	portmask &= ar7240sw_port_mask_but(as, port); - -	ar7240sw_reg_write(mii, AR7240_REG_PORT_CTRL(port), ctrl); -	if (sw_is_ar934x(as)) { -		u32 vlan1, vlan2; - -		vlan1 = (vid << AR934X_PORT_VLAN1_DEFAULT_CVID_S); -		vlan2 = (portmask << AR934X_PORT_VLAN2_PORT_VID_MEM_S) | -			(mode << AR934X_PORT_VLAN2_8021Q_MODE_S); -		ar7240sw_reg_write(mii, AR934X_REG_PORT_VLAN1(port), vlan1); -		ar7240sw_reg_write(mii, AR934X_REG_PORT_VLAN2(port), vlan2); -	} else { -		u32 vlan; - -		vlan = vid | (mode << AR7240_PORT_VLAN_MODE_S) | -		       (portmask << AR7240_PORT_VLAN_DEST_PORTS_S); - -		ar7240sw_reg_write(mii, AR7240_REG_PORT_VLAN(port), vlan); -	} -} - -static int ar7240_set_addr(struct ar7240sw *as, u8 *addr) -{ -	struct mii_bus *mii = as->mii_bus; -	u32 t; - -	t = (addr[4] << 8) | addr[5]; -	ar7240sw_reg_write(mii, AR7240_REG_MAC_ADDR0, t); - -	t = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3]; -	ar7240sw_reg_write(mii, AR7240_REG_MAC_ADDR1, t); - -	return 0; -} - -static int -ar7240_set_vid(struct switch_dev *dev, const struct switch_attr *attr, -		struct switch_val *val) -{ -	struct ar7240sw *as = sw_to_ar7240(dev); -	as->vlan_id[val->port_vlan] = val->value.i; -	return 0; -} - -static int -ar7240_get_vid(struct switch_dev *dev, const struct switch_attr *attr, -		struct switch_val *val) -{ -	struct ar7240sw *as = sw_to_ar7240(dev); -	val->value.i = as->vlan_id[val->port_vlan]; -	return 0; -} - -static int -ar7240_set_pvid(struct switch_dev *dev, int port, int vlan) -{ -	struct ar7240sw *as = sw_to_ar7240(dev); - -	/* make sure no invalid PVIDs get set */ - -	if (vlan >= dev->vlans) -		return -EINVAL; - -	as->pvid[port] = vlan; -	return 0; -} - -static int -ar7240_get_pvid(struct switch_dev *dev, int port, int *vlan) -{ -	struct ar7240sw *as = sw_to_ar7240(dev); -	*vlan = as->pvid[port]; -	return 0; -} - -static int -ar7240_get_ports(struct switch_dev *dev, struct switch_val *val) -{ -	struct ar7240sw *as = sw_to_ar7240(dev); -	u8 ports = as->vlan_table[val->port_vlan]; -	int i; - -	val->len = 0; -	for (i = 0; i < as->swdev.ports; i++) { -		struct switch_port *p; - -		if (!(ports & (1 << i))) -			continue; - -		p = &val->value.ports[val->len++]; -		p->id = i; -		if (as->vlan_tagged & (1 << i)) -			p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); -		else -			p->flags = 0; -	} -	return 0; -} - -static int -ar7240_set_ports(struct switch_dev *dev, struct switch_val *val) -{ -	struct ar7240sw *as = sw_to_ar7240(dev); -	u8 *vt = &as->vlan_table[val->port_vlan]; -	int i, j; - -	*vt = 0; -	for (i = 0; i < val->len; i++) { -		struct switch_port *p = &val->value.ports[i]; - -		if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) -			as->vlan_tagged |= (1 << p->id); -		else { -			as->vlan_tagged &= ~(1 << p->id); -			as->pvid[p->id] = val->port_vlan; - -			/* make sure that an untagged port does not -			 * appear in other vlans */ -			for (j = 0; j < AR7240_MAX_VLANS; j++) { -				if (j == val->port_vlan) -					continue; -				as->vlan_table[j] &= ~(1 << p->id); -			} -		} - -		*vt |= 1 << p->id; -	} -	return 0; -} - -static int -ar7240_set_vlan(struct switch_dev *dev, const struct switch_attr *attr, -		struct switch_val *val) -{ -	struct ar7240sw *as = sw_to_ar7240(dev); -	as->vlan = !!val->value.i; -	return 0; -} - -static int -ar7240_get_vlan(struct switch_dev *dev, const struct switch_attr *attr, -		struct switch_val *val) -{ -	struct ar7240sw *as = sw_to_ar7240(dev); -	val->value.i = as->vlan; -	return 0; -} - -static const char * -ar7240_speed_str(u32 status) -{ -	u32 speed; - -	speed = (status >> AR7240_PORT_STATUS_SPEED_S) & -					AR7240_PORT_STATUS_SPEED_M; -	switch (speed) { -	case AR7240_PORT_STATUS_SPEED_10: -		return "10baseT"; -	case AR7240_PORT_STATUS_SPEED_100: -		return "100baseT"; -	case AR7240_PORT_STATUS_SPEED_1000: -		return "1000baseT"; -	} - -	return "unknown"; -} - -static int -ar7240_port_get_link(struct switch_dev *dev, const struct switch_attr *attr, -		     struct switch_val *val) -{ -	struct ar7240sw *as = sw_to_ar7240(dev); -	struct mii_bus *mii = as->mii_bus; -	u32 len; -	u32 status; -	int port; - -	port = val->port_vlan; - -	memset(as->buf, '\0', sizeof(as->buf)); -	status = ar7240sw_reg_read(mii, AR7240_REG_PORT_STATUS(port)); - -	if (status & AR7240_PORT_STATUS_LINK_UP) { -		len = snprintf(as->buf, sizeof(as->buf), -				"port:%d link:up speed:%s %s-duplex %s%s%s", -				port, -				ar7240_speed_str(status), -				(status & AR7240_PORT_STATUS_DUPLEX) ? -					"full" : "half", -				(status & AR7240_PORT_STATUS_TXFLOW) ? -					"txflow ": "", -				(status & AR7240_PORT_STATUS_RXFLOW) ? -					"rxflow " : "", -				(status & AR7240_PORT_STATUS_LINK_AUTO) ? -					"auto ": ""); -	} else { -		len = snprintf(as->buf, sizeof(as->buf), -			       "port:%d link:down", port); -	} - -	val->value.s = as->buf; -	val->len = len; - -	return 0; -} - -static void -ar7240_vtu_op(struct ar7240sw *as, u32 op, u32 val) -{ -	struct mii_bus *mii = as->mii_bus; - -	if (ar7240sw_reg_wait(mii, AR7240_REG_VTU, AR7240_VTU_ACTIVE, 0, 5)) -		return; - -	if ((op & AR7240_VTU_OP) == AR7240_VTU_OP_LOAD) { -		val &= AR7240_VTUDATA_MEMBER; -		val |= AR7240_VTUDATA_VALID; -		ar7240sw_reg_write(mii, AR7240_REG_VTU_DATA, val); -	} -	op |= AR7240_VTU_ACTIVE; -	ar7240sw_reg_write(mii, AR7240_REG_VTU, op); -} - -static int -ar7240_hw_apply(struct switch_dev *dev) -{ -	struct ar7240sw *as = sw_to_ar7240(dev); -	u8 portmask[AR7240_NUM_PORTS]; -	int i, j; - -	/* flush all vlan translation unit entries */ -	ar7240_vtu_op(as, AR7240_VTU_OP_FLUSH, 0); - -	memset(portmask, 0, sizeof(portmask)); -	if (as->vlan) { -		/* calculate the port destination masks and load vlans -		 * into the vlan translation unit */ -		for (j = 0; j < AR7240_MAX_VLANS; j++) { -			u8 vp = as->vlan_table[j]; - -			if (!vp) -				continue; - -			for (i = 0; i < as->swdev.ports; i++) { -				u8 mask = (1 << i); -				if (vp & mask) -					portmask[i] |= vp & ~mask; -			} - -			ar7240_vtu_op(as, -				AR7240_VTU_OP_LOAD | -				(as->vlan_id[j] << AR7240_VTU_VID_S), -				as->vlan_table[j]); -		} -	} else { -		/* vlan disabled: -		 * isolate all ports, but connect them to the cpu port */ -		for (i = 0; i < as->swdev.ports; i++) { -			if (i == AR7240_PORT_CPU) -				continue; - -			portmask[i] = 1 << AR7240_PORT_CPU; -			portmask[AR7240_PORT_CPU] |= (1 << i); -		} -	} - -	/* update the port destination mask registers and tag settings */ -	for (i = 0; i < as->swdev.ports; i++) -		ar7240sw_setup_port(as, i, portmask[i]); - -	return 0; -} - -static int -ar7240_reset_switch(struct switch_dev *dev) -{ -	struct ar7240sw *as = sw_to_ar7240(dev); -	ar7240sw_reset(as); -	return 0; -} - -static int -ar7240_get_port_link(struct switch_dev *dev, int port, -		     struct switch_port_link *link) -{ -	struct ar7240sw *as = sw_to_ar7240(dev); -	struct mii_bus *mii = as->mii_bus; -	u32 status; - -	if (port > AR7240_NUM_PORTS) -		return -EINVAL; - -	status = ar7240sw_reg_read(mii, AR7240_REG_PORT_STATUS(port)); - -	link->link = !!(status & AR7240_PORT_STATUS_LINK_UP); -	link->aneg = !!(status & AR7240_PORT_STATUS_LINK_AUTO); -	link->duplex = !!(status & AR7240_PORT_STATUS_DUPLEX); -	link->tx_flow = !!(status & AR7240_PORT_STATUS_TXFLOW); -	link->rx_flow = !!(status & AR7240_PORT_STATUS_RXFLOW); -	switch (status & AR7240_PORT_STATUS_SPEED_M) { -	case AR7240_PORT_STATUS_SPEED_10: -		link->speed = SWITCH_PORT_SPEED_10; -		break; -	case AR7240_PORT_STATUS_SPEED_100: -		link->speed = SWITCH_PORT_SPEED_100; -		break; -	case AR7240_PORT_STATUS_SPEED_1000: -		link->speed = SWITCH_PORT_SPEED_1000; -		break; -	} - -	return 0; -} - -static int -ar7240_get_port_stats(struct switch_dev *dev, int port, -		      struct switch_port_stats *stats) -{ -	struct ar7240sw *as = sw_to_ar7240(dev); - -	if (port > AR7240_NUM_PORTS) -		return -EINVAL; - -	ar7240sw_capture_stats(as); - -	read_lock(&as->stats_lock); -	stats->rx_bytes = as->port_stats[port].rx_good_byte; -	stats->tx_bytes = as->port_stats[port].tx_byte; -	read_unlock(&as->stats_lock); - -	return 0; -} - -static struct switch_attr ar7240_globals[] = { -	{ -		.type = SWITCH_TYPE_INT, -		.name = "enable_vlan", -		.description = "Enable VLAN mode", -		.set = ar7240_set_vlan, -		.get = ar7240_get_vlan, -		.max = 1 -	}, -}; - -static struct switch_attr ar7240_port[] = { -	{ -		.type = SWITCH_TYPE_STRING, -		.name = "link", -		.description = "Get port link information", -		.max = 1, -		.set = NULL, -		.get = ar7240_port_get_link, -	}, -}; - -static struct switch_attr ar7240_vlan[] = { -	{ -		.type = SWITCH_TYPE_INT, -		.name = "vid", -		.description = "VLAN ID", -		.set = ar7240_set_vid, -		.get = ar7240_get_vid, -		.max = 4094, -	}, -}; - -static const struct switch_dev_ops ar7240_ops = { -	.attr_global = { -		.attr = ar7240_globals, -		.n_attr = ARRAY_SIZE(ar7240_globals), -	}, -	.attr_port = { -		.attr = ar7240_port, -		.n_attr = ARRAY_SIZE(ar7240_port), -	}, -	.attr_vlan = { -		.attr = ar7240_vlan, -		.n_attr = ARRAY_SIZE(ar7240_vlan), -	}, -	.get_port_pvid = ar7240_get_pvid, -	.set_port_pvid = ar7240_set_pvid, -	.get_vlan_ports = ar7240_get_ports, -	.set_vlan_ports = ar7240_set_ports, -	.apply_config = ar7240_hw_apply, -	.reset_switch = ar7240_reset_switch, -	.get_port_link = ar7240_get_port_link, -	.get_port_stats = ar7240_get_port_stats, -}; - -static struct ar7240sw *ar7240_probe(struct ag71xx *ag) -{ -	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -	struct mii_bus *mii = ag->mii_bus; -	struct ar7240sw *as; -	struct switch_dev *swdev; -	u32 ctrl; -	u16 phy_id1; -	u16 phy_id2; -	int i; - -	phy_id1 = ar7240sw_phy_read(mii, 0, MII_PHYSID1); -	phy_id2 = ar7240sw_phy_read(mii, 0, MII_PHYSID2); -	if ((phy_id1 != AR7240_PHY_ID1 || phy_id2 != AR7240_PHY_ID2) && -	    (phy_id1 != AR934X_PHY_ID1 || phy_id2 != AR934X_PHY_ID2)) { -		pr_err("%s: unknown phy id '%04x:%04x'\n", -		       ag->dev->name, phy_id1, phy_id2); -		return NULL; -	} - -	as = kzalloc(sizeof(*as), GFP_KERNEL); -	if (!as) -		return NULL; - -	as->mii_bus = mii; -	as->swdata = pdata->switch_data; - -	swdev = &as->swdev; - -	ctrl = ar7240sw_reg_read(mii, AR7240_REG_MASK_CTRL); -	as->ver = (ctrl >> AR7240_MASK_CTRL_VERSION_S) & -		  AR7240_MASK_CTRL_VERSION_M; - -	if (sw_is_ar7240(as)) { -		swdev->name = "AR7240/AR9330 built-in switch"; -	} else if (sw_is_ar934x(as)) { -		swdev->name = "AR934X built-in switch"; - -		if (pdata->phy_if_mode == PHY_INTERFACE_MODE_GMII) { -			ar7240sw_reg_set(mii, AR934X_REG_OPER_MODE0, -					 AR934X_OPER_MODE0_MAC_GMII_EN); -		} else if (pdata->phy_if_mode == PHY_INTERFACE_MODE_MII) { -			ar7240sw_reg_set(mii, AR934X_REG_OPER_MODE0, -					 AR934X_OPER_MODE0_PHY_MII_EN); -		} else { -			pr_err("%s: invalid PHY interface mode\n", -			       ag->dev->name); -			goto err_free; -		} - -		if (as->swdata->phy4_mii_en) -			ar7240sw_reg_set(mii, AR934X_REG_OPER_MODE1, -					 AR934X_REG_OPER_MODE1_PHY4_MII_EN); -	} else { -		pr_err("%s: unsupported chip, ctrl=%08x\n", -			ag->dev->name, ctrl); -		goto err_free; -	} - -	swdev->ports = AR7240_NUM_PORTS - 1; -	swdev->cpu_port = AR7240_PORT_CPU; -	swdev->vlans = AR7240_MAX_VLANS; -	swdev->ops = &ar7240_ops; - -	if (register_switch(&as->swdev, ag->dev) < 0) -		goto err_free; - -	pr_info("%s: Found an %s\n", ag->dev->name, swdev->name); - -	/* initialize defaults */ -	for (i = 0; i < AR7240_MAX_VLANS; i++) -		as->vlan_id[i] = i; - -	as->vlan_table[0] = ar7240sw_port_mask_all(as); - -	return as; - -err_free: -	kfree(as); -	return NULL; -} - -static void link_function(struct work_struct *work) { -	struct ag71xx *ag = container_of(work, struct ag71xx, link_work.work); -	unsigned long flags; -	int i; -	int status = 0; - -	for (i = 0; i < 4; i++) { -		int link = ar7240sw_phy_read(ag->mii_bus, i, MII_BMSR); -		if(link & BMSR_LSTATUS) { -			status = 1; -			break; -		} -	} - -	spin_lock_irqsave(&ag->lock, flags); -	if(status != ag->link) { -		ag->link = status; -		ag71xx_link_adjust(ag); -	} -	spin_unlock_irqrestore(&ag->lock, flags); - -	schedule_delayed_work(&ag->link_work, HZ / 2); -} - -void ag71xx_ar7240_start(struct ag71xx *ag) -{ -	struct ar7240sw *as = ag->phy_priv; - -	ar7240sw_reset(as); - -	ag->speed = SPEED_1000; -	ag->duplex = 1; - -	ar7240_set_addr(as, ag->dev->dev_addr); -	ar7240_hw_apply(&as->swdev); - -	schedule_delayed_work(&ag->link_work, HZ / 10); -} - -void ag71xx_ar7240_stop(struct ag71xx *ag) -{ -	cancel_delayed_work_sync(&ag->link_work); -} - -int __devinit ag71xx_ar7240_init(struct ag71xx *ag) -{ -	struct ar7240sw *as; - -	as = ar7240_probe(ag); -	if (!as) -		return -ENODEV; - -	ag->phy_priv = as; -	ar7240sw_reset(as); - -	rwlock_init(&as->stats_lock); -	INIT_DELAYED_WORK(&ag->link_work, link_function); - -	return 0; -} - -void ag71xx_ar7240_cleanup(struct ag71xx *ag) -{ -	struct ar7240sw *as = ag->phy_priv; - -	if (!as) -		return; - -	unregister_switch(&as->swdev); -	kfree(as); -	ag->phy_priv = NULL; -} diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ar8216.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ar8216.c deleted file mode 100644 index 7ec43b722..000000000 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ar8216.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - *  Atheros AR71xx built-in ethernet mac driver - *  Special support for the Atheros ar8216 switch chip - * - *  Copyright (C) 2009-2010 Gabor Juhos <juhosg@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. - */ - -#include "ag71xx.h" - -#define AR8216_PACKET_TYPE_MASK		0xf -#define AR8216_PACKET_TYPE_NORMAL	0 - -#define AR8216_HEADER_LEN	2 - -void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb) -{ -	skb_push(skb, AR8216_HEADER_LEN); -	skb->data[0] = 0x10; -	skb->data[1] = 0x80; -} - -int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, -				int pktlen) -{ -	u8 type; - -	type = skb->data[1] & AR8216_PACKET_TYPE_MASK; -	switch (type) { -	case AR8216_PACKET_TYPE_NORMAL: -		break; - -	default: -		return -EINVAL; -	} - -	skb_pull(skb, AR8216_HEADER_LEN); -	return 0; -} diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_debugfs.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_debugfs.c deleted file mode 100644 index 65f2be198..000000000 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_debugfs.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - *  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. - */ - -#include <linux/debugfs.h> - -#include "ag71xx.h" - -static struct dentry *ag71xx_debugfs_root; - -static int ag71xx_debugfs_generic_open(struct inode *inode, struct file *file) -{ -	file->private_data = inode->i_private; -	return 0; -} - -void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status) -{ -	if (status) -		ag->debug.int_stats.total++; -	if (status & AG71XX_INT_TX_PS) -		ag->debug.int_stats.tx_ps++; -	if (status & AG71XX_INT_TX_UR) -		ag->debug.int_stats.tx_ur++; -	if (status & AG71XX_INT_TX_BE) -		ag->debug.int_stats.tx_be++; -	if (status & AG71XX_INT_RX_PR) -		ag->debug.int_stats.rx_pr++; -	if (status & AG71XX_INT_RX_OF) -		ag->debug.int_stats.rx_of++; -	if (status & AG71XX_INT_RX_BE) -		ag->debug.int_stats.rx_be++; -} - -static ssize_t read_file_int_stats(struct file *file, char __user *user_buf, -				   size_t count, loff_t *ppos) -{ -#define PR_INT_STAT(_label, _field)					\ -	len += snprintf(buf + len, sizeof(buf) - len,			\ -		"%20s: %10lu\n", _label, ag->debug.int_stats._field); - -	struct ag71xx *ag = file->private_data; -	char buf[256]; -	unsigned int len = 0; - -	PR_INT_STAT("TX Packet Sent", tx_ps); -	PR_INT_STAT("TX Underrun", tx_ur); -	PR_INT_STAT("TX Bus Error", tx_be); -	PR_INT_STAT("RX Packet Received", rx_pr); -	PR_INT_STAT("RX Overflow", rx_of); -	PR_INT_STAT("RX Bus Error", rx_be); -	len += snprintf(buf + len, sizeof(buf) - len, "\n"); -	PR_INT_STAT("Total", total); - -	return simple_read_from_buffer(user_buf, count, ppos, buf, len); -#undef PR_INT_STAT -} - -static const struct file_operations ag71xx_fops_int_stats = { -	.open	= ag71xx_debugfs_generic_open, -	.read	= read_file_int_stats, -	.owner	= THIS_MODULE -}; - -void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx) -{ -	struct ag71xx_napi_stats *stats = &ag->debug.napi_stats; - -	if (rx) { -		stats->rx_count++; -		stats->rx_packets += rx; -		if (rx <= AG71XX_NAPI_WEIGHT) -			stats->rx[rx]++; -		if (rx > stats->rx_packets_max) -			stats->rx_packets_max = rx; -	} - -	if (tx) { -		stats->tx_count++; -		stats->tx_packets += tx; -		if (tx <= AG71XX_NAPI_WEIGHT) -			stats->tx[tx]++; -		if (tx > stats->tx_packets_max) -			stats->tx_packets_max = tx; -	} -} - -static ssize_t read_file_napi_stats(struct file *file, char __user *user_buf, -				    size_t count, loff_t *ppos) -{ -	struct ag71xx *ag = file->private_data; -	struct ag71xx_napi_stats *stats = &ag->debug.napi_stats; -	char *buf; -	unsigned int buflen; -	unsigned int len = 0; -	unsigned long rx_avg = 0; -	unsigned long tx_avg = 0; -	int ret; -	int i; - -	buflen = 2048; -	buf = kmalloc(buflen, GFP_KERNEL); -	if (!buf) -		return -ENOMEM; - -	if (stats->rx_count) -		rx_avg = stats->rx_packets / stats->rx_count; - -	if (stats->tx_count) -		tx_avg = stats->tx_packets / stats->tx_count; - -	len += snprintf(buf + len, buflen - len, "%3s  %10s %10s\n", -			"len", "rx", "tx"); - -	for (i = 1; i <= AG71XX_NAPI_WEIGHT; i++) -		len += snprintf(buf + len, buflen - len, -				"%3d: %10lu %10lu\n", -				i, stats->rx[i], stats->tx[i]); - -	len += snprintf(buf + len, buflen - len, "\n"); - -	len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", -			"sum", stats->rx_count, stats->tx_count); -	len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", -			"avg", rx_avg, tx_avg); -	len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", -			"max", stats->rx_packets_max, stats->tx_packets_max); -	len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", -			"pkt", stats->rx_packets, stats->tx_packets); - -	ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); -	kfree(buf); - -	return ret; -} - -static const struct file_operations ag71xx_fops_napi_stats = { -	.open	= ag71xx_debugfs_generic_open, -	.read	= read_file_napi_stats, -	.owner	= THIS_MODULE -}; - -#define DESC_PRINT_LEN	64 - -static ssize_t read_file_ring(struct file *file, char __user *user_buf, -			      size_t count, loff_t *ppos, -			      struct ag71xx *ag, -			      struct ag71xx_ring *ring, -			      unsigned desc_reg) -{ -	char *buf; -	unsigned int buflen; -	unsigned int len = 0; -	unsigned long flags; -	ssize_t ret; -	int curr; -	int dirty; -	u32 desc_hw; -	int i; - -	buflen = (ring->size * DESC_PRINT_LEN); -	buf = kmalloc(buflen, GFP_KERNEL); -	if (!buf) -		return -ENOMEM; - -	len += snprintf(buf + len, buflen - len, -			"Idx ... %-8s %-8s %-8s %-8s . %-10s\n", -			"desc", "next", "data", "ctrl", "timestamp"); - -	spin_lock_irqsave(&ag->lock, flags); - -	curr = (ring->curr % ring->size); -	dirty = (ring->dirty % ring->size); -	desc_hw = ag71xx_rr(ag, desc_reg); -	for (i = 0; i < ring->size; i++) { -		struct ag71xx_buf *ab = &ring->buf[i]; -		u32 desc_dma = ((u32) ring->descs_dma) + i * ring->desc_size; - -		len += snprintf(buf + len, buflen - len, -			"%3d %c%c%c %08x %08x %08x %08x %c %10lu\n", -			i, -			(i == curr) ? 'C' : ' ', -			(i == dirty) ? 'D' : ' ', -			(desc_hw == desc_dma) ? 'H' : ' ', -			desc_dma, -			ab->desc->next, -			ab->desc->data, -			ab->desc->ctrl, -			(ab->desc->ctrl & DESC_EMPTY) ? 'E' : '*', -			ab->timestamp); -	} - -	spin_unlock_irqrestore(&ag->lock, flags); - -	ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); -	kfree(buf); - -	return ret; -} - -static ssize_t read_file_tx_ring(struct file *file, char __user *user_buf, -				 size_t count, loff_t *ppos) -{ -	struct ag71xx *ag = file->private_data; - -	return read_file_ring(file, user_buf, count, ppos, ag, &ag->tx_ring, -			      AG71XX_REG_TX_DESC); -} - -static const struct file_operations ag71xx_fops_tx_ring = { -	.open	= ag71xx_debugfs_generic_open, -	.read	= read_file_tx_ring, -	.owner	= THIS_MODULE -}; - -static ssize_t read_file_rx_ring(struct file *file, char __user *user_buf, -				 size_t count, loff_t *ppos) -{ -	struct ag71xx *ag = file->private_data; - -	return read_file_ring(file, user_buf, count, ppos, ag, &ag->rx_ring, -			      AG71XX_REG_RX_DESC); -} - -static const struct file_operations ag71xx_fops_rx_ring = { -	.open	= ag71xx_debugfs_generic_open, -	.read	= read_file_rx_ring, -	.owner	= THIS_MODULE -}; - -void ag71xx_debugfs_exit(struct ag71xx *ag) -{ -	debugfs_remove_recursive(ag->debug.debugfs_dir); -} - -int ag71xx_debugfs_init(struct ag71xx *ag) -{ -	ag->debug.debugfs_dir = debugfs_create_dir(ag->dev->name, -						   ag71xx_debugfs_root); -	if (!ag->debug.debugfs_dir) -		return -ENOMEM; - -	debugfs_create_file("int_stats", S_IRUGO, ag->debug.debugfs_dir, -			    ag, &ag71xx_fops_int_stats); -	debugfs_create_file("napi_stats", S_IRUGO, ag->debug.debugfs_dir, -			    ag, &ag71xx_fops_napi_stats); -	debugfs_create_file("tx_ring", S_IRUGO, ag->debug.debugfs_dir, -			    ag, &ag71xx_fops_tx_ring); -	debugfs_create_file("rx_ring", S_IRUGO, ag->debug.debugfs_dir, -			    ag, &ag71xx_fops_rx_ring); - -	return 0; -} - -int ag71xx_debugfs_root_init(void) -{ -	if (ag71xx_debugfs_root) -		return -EBUSY; - -	ag71xx_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); -	if (!ag71xx_debugfs_root) -		return -ENOENT; - -	return 0; -} - -void ag71xx_debugfs_root_exit(void) -{ -	debugfs_remove(ag71xx_debugfs_root); -	ag71xx_debugfs_root = NULL; -} diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ethtool.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ethtool.c deleted file mode 100644 index 498fbed1f..000000000 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ethtool.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - *  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. - */ - -#include "ag71xx.h" - -static int ag71xx_ethtool_get_settings(struct net_device *dev, -				       struct ethtool_cmd *cmd) -{ -	struct ag71xx *ag = netdev_priv(dev); -	struct phy_device *phydev = ag->phy_dev; - -	if (!phydev) -		return -ENODEV; - -	return phy_ethtool_gset(phydev, cmd); -} - -static int ag71xx_ethtool_set_settings(struct net_device *dev, -				       struct ethtool_cmd *cmd) -{ -	struct ag71xx *ag = netdev_priv(dev); -	struct phy_device *phydev = ag->phy_dev; - -	if (!phydev) -		return -ENODEV; - -	return phy_ethtool_sset(phydev, cmd); -} - -static void ag71xx_ethtool_get_drvinfo(struct net_device *dev, -				       struct ethtool_drvinfo *info) -{ -	struct ag71xx *ag = netdev_priv(dev); - -	strcpy(info->driver, ag->pdev->dev.driver->name); -	strcpy(info->version, AG71XX_DRV_VERSION); -	strcpy(info->bus_info, dev_name(&ag->pdev->dev)); -} - -static u32 ag71xx_ethtool_get_msglevel(struct net_device *dev) -{ -	struct ag71xx *ag = netdev_priv(dev); - -	return ag->msg_enable; -} - -static void ag71xx_ethtool_set_msglevel(struct net_device *dev, u32 msg_level) -{ -	struct ag71xx *ag = netdev_priv(dev); - -	ag->msg_enable = msg_level; -} - -static void ag71xx_ethtool_get_ringparam(struct net_device *dev, -					 struct ethtool_ringparam *er) -{ -	struct ag71xx *ag = netdev_priv(dev); - -	er->tx_max_pending = AG71XX_TX_RING_SIZE_MAX; -	er->rx_max_pending = AG71XX_RX_RING_SIZE_MAX; -	er->rx_mini_max_pending = 0; -	er->rx_jumbo_max_pending = 0; - -	er->tx_pending = ag->tx_ring.size; -	er->rx_pending = ag->rx_ring.size; -	er->rx_mini_pending = 0; -	er->rx_jumbo_pending = 0; -} - -static int ag71xx_ethtool_set_ringparam(struct net_device *dev, -					struct ethtool_ringparam *er) -{ -	struct ag71xx *ag = netdev_priv(dev); -	unsigned tx_size; -	unsigned rx_size; -	int err; - -	if (er->rx_mini_pending != 0|| -	    er->rx_jumbo_pending != 0 || -	    er->rx_pending == 0 || -	    er->tx_pending == 0) -		return -EINVAL; - -	tx_size = er->tx_pending < AG71XX_TX_RING_SIZE_MAX ? -		  er->tx_pending : AG71XX_TX_RING_SIZE_MAX; - -	rx_size = er->rx_pending < AG71XX_RX_RING_SIZE_MAX ? -		  er->rx_pending : AG71XX_RX_RING_SIZE_MAX; - -	if (netif_running(dev)) { -		err = dev->netdev_ops->ndo_stop(dev); -		if (err) -			return err; -	} - -	ag->tx_ring.size = tx_size; -	ag->rx_ring.size = rx_size; - -	if (netif_running(dev)) -		err = dev->netdev_ops->ndo_open(dev); - -	return err; -} - -struct ethtool_ops ag71xx_ethtool_ops = { -	.set_settings	= ag71xx_ethtool_set_settings, -	.get_settings	= ag71xx_ethtool_get_settings, -	.get_drvinfo	= ag71xx_ethtool_get_drvinfo, -	.get_msglevel	= ag71xx_ethtool_get_msglevel, -	.set_msglevel	= ag71xx_ethtool_set_msglevel, -	.get_ringparam	= ag71xx_ethtool_get_ringparam, -	.set_ringparam	= ag71xx_ethtool_set_ringparam, -	.get_link	= ethtool_op_get_link, -}; diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c deleted file mode 100644 index 3ebf4b171..000000000 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c +++ /dev/null @@ -1,1265 +0,0 @@ -/* - *  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. - */ - -#include "ag71xx.h" - -#define AG71XX_DEFAULT_MSG_ENABLE	\ -	(NETIF_MSG_DRV			\ -	| NETIF_MSG_PROBE		\ -	| NETIF_MSG_LINK		\ -	| NETIF_MSG_TIMER		\ -	| NETIF_MSG_IFDOWN		\ -	| NETIF_MSG_IFUP		\ -	| NETIF_MSG_RX_ERR		\ -	| NETIF_MSG_TX_ERR) - -static int ag71xx_msg_level = -1; - -module_param_named(msg_level, ag71xx_msg_level, int, 0); -MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)"); - -static void ag71xx_dump_dma_regs(struct ag71xx *ag) -{ -	DBG("%s: dma_tx_ctrl=%08x, dma_tx_desc=%08x, dma_tx_status=%08x\n", -		ag->dev->name, -		ag71xx_rr(ag, AG71XX_REG_TX_CTRL), -		ag71xx_rr(ag, AG71XX_REG_TX_DESC), -		ag71xx_rr(ag, AG71XX_REG_TX_STATUS)); - -	DBG("%s: dma_rx_ctrl=%08x, dma_rx_desc=%08x, dma_rx_status=%08x\n", -		ag->dev->name, -		ag71xx_rr(ag, AG71XX_REG_RX_CTRL), -		ag71xx_rr(ag, AG71XX_REG_RX_DESC), -		ag71xx_rr(ag, AG71XX_REG_RX_STATUS)); -} - -static void ag71xx_dump_regs(struct ag71xx *ag) -{ -	DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n", -		ag->dev->name, -		ag71xx_rr(ag, AG71XX_REG_MAC_CFG1), -		ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), -		ag71xx_rr(ag, AG71XX_REG_MAC_IPG), -		ag71xx_rr(ag, AG71XX_REG_MAC_HDX), -		ag71xx_rr(ag, AG71XX_REG_MAC_MFL)); -	DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n", -		ag->dev->name, -		ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), -		ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1), -		ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2)); -	DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n", -		ag->dev->name, -		ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), -		ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), -		ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); -	DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n", -		ag->dev->name, -		ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), -		ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), -		ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); -} - -static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr) -{ -	DBG("%s: %s intr=%08x %s%s%s%s%s%s\n", -		ag->dev->name, label, intr, -		(intr & AG71XX_INT_TX_PS) ? "TXPS " : "", -		(intr & AG71XX_INT_TX_UR) ? "TXUR " : "", -		(intr & AG71XX_INT_TX_BE) ? "TXBE " : "", -		(intr & AG71XX_INT_RX_PR) ? "RXPR " : "", -		(intr & AG71XX_INT_RX_OF) ? "RXOF " : "", -		(intr & AG71XX_INT_RX_BE) ? "RXBE " : ""); -} - -static void ag71xx_ring_free(struct ag71xx_ring *ring) -{ -	kfree(ring->buf); - -	if (ring->descs_cpu) -		dma_free_coherent(NULL, ring->size * ring->desc_size, -				  ring->descs_cpu, ring->descs_dma); -} - -static int ag71xx_ring_alloc(struct ag71xx_ring *ring) -{ -	int err; -	int i; - -	ring->desc_size = sizeof(struct ag71xx_desc); -	if (ring->desc_size % cache_line_size()) { -		DBG("ag71xx: ring %p, desc size %u rounded to %u\n", -			ring, ring->desc_size, -			roundup(ring->desc_size, cache_line_size())); -		ring->desc_size = roundup(ring->desc_size, cache_line_size()); -	} - -	ring->descs_cpu = dma_alloc_coherent(NULL, ring->size * ring->desc_size, -					     &ring->descs_dma, GFP_ATOMIC); -	if (!ring->descs_cpu) { -		err = -ENOMEM; -		goto err; -	} - - -	ring->buf = kzalloc(ring->size * sizeof(*ring->buf), GFP_KERNEL); -	if (!ring->buf) { -		err = -ENOMEM; -		goto err; -	} - -	for (i = 0; i < ring->size; i++) { -		int idx = i * ring->desc_size; -		ring->buf[i].desc = (struct ag71xx_desc *)&ring->descs_cpu[idx]; -		DBG("ag71xx: ring %p, desc %d at %p\n", -			ring, i, ring->buf[i].desc); -	} - -	return 0; - -err: -	return err; -} - -static void ag71xx_ring_tx_clean(struct ag71xx *ag) -{ -	struct ag71xx_ring *ring = &ag->tx_ring; -	struct net_device *dev = ag->dev; - -	while (ring->curr != ring->dirty) { -		u32 i = ring->dirty % ring->size; - -		if (!ag71xx_desc_empty(ring->buf[i].desc)) { -			ring->buf[i].desc->ctrl = 0; -			dev->stats.tx_errors++; -		} - -		if (ring->buf[i].skb) -			dev_kfree_skb_any(ring->buf[i].skb); - -		ring->buf[i].skb = NULL; - -		ring->dirty++; -	} - -	/* flush descriptors */ -	wmb(); - -} - -static void ag71xx_ring_tx_init(struct ag71xx *ag) -{ -	struct ag71xx_ring *ring = &ag->tx_ring; -	int i; - -	for (i = 0; i < ring->size; i++) { -		ring->buf[i].desc->next = (u32) (ring->descs_dma + -			ring->desc_size * ((i + 1) % ring->size)); - -		ring->buf[i].desc->ctrl = DESC_EMPTY; -		ring->buf[i].skb = NULL; -	} - -	/* flush descriptors */ -	wmb(); - -	ring->curr = 0; -	ring->dirty = 0; -} - -static void ag71xx_ring_rx_clean(struct ag71xx *ag) -{ -	struct ag71xx_ring *ring = &ag->rx_ring; -	int i; - -	if (!ring->buf) -		return; - -	for (i = 0; i < ring->size; i++) -		if (ring->buf[i].skb) { -			dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr, -					 AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); -			kfree_skb(ring->buf[i].skb); -		} -} - -static int ag71xx_rx_reserve(struct ag71xx *ag) -{ -	int reserve = 0; - -	if (ag71xx_get_pdata(ag)->is_ar724x) { -		if (!ag71xx_has_ar8216(ag)) -			reserve = 2; - -		if (ag->phy_dev) -			reserve += 4 - (ag->phy_dev->pkt_align % 4); - -		reserve %= 4; -	} - -	return reserve + AG71XX_RX_PKT_RESERVE; -} - - -static int ag71xx_ring_rx_init(struct ag71xx *ag) -{ -	struct ag71xx_ring *ring = &ag->rx_ring; -	unsigned int reserve = ag71xx_rx_reserve(ag); -	unsigned int i; -	int ret; - -	ret = 0; -	for (i = 0; i < ring->size; i++) { -		ring->buf[i].desc->next = (u32) (ring->descs_dma + -			ring->desc_size * ((i + 1) % ring->size)); - -		DBG("ag71xx: RX desc at %p, next is %08x\n", -			ring->buf[i].desc, -			ring->buf[i].desc->next); -	} - -	for (i = 0; i < ring->size; i++) { -		struct sk_buff *skb; -		dma_addr_t dma_addr; - -		skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); -		if (!skb) { -			ret = -ENOMEM; -			break; -		} - -		skb->dev = ag->dev; -		skb_reserve(skb, reserve); - -		dma_addr = dma_map_single(&ag->dev->dev, skb->data, -					  AG71XX_RX_PKT_SIZE, -					  DMA_FROM_DEVICE); -		ring->buf[i].skb = skb; -		ring->buf[i].dma_addr = dma_addr; -		ring->buf[i].desc->data = (u32) dma_addr; -		ring->buf[i].desc->ctrl = DESC_EMPTY; -	} - -	/* flush descriptors */ -	wmb(); - -	ring->curr = 0; -	ring->dirty = 0; - -	return ret; -} - -static int ag71xx_ring_rx_refill(struct ag71xx *ag) -{ -	struct ag71xx_ring *ring = &ag->rx_ring; -	unsigned int reserve = ag71xx_rx_reserve(ag); -	unsigned int count; - -	count = 0; -	for (; ring->curr - ring->dirty > 0; ring->dirty++) { -		unsigned int i; - -		i = ring->dirty % ring->size; - -		if (ring->buf[i].skb == NULL) { -			dma_addr_t dma_addr; -			struct sk_buff *skb; - -			skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); -			if (skb == NULL) -				break; - -			skb_reserve(skb, reserve); -			skb->dev = ag->dev; - -			dma_addr = dma_map_single(&ag->dev->dev, skb->data, -						  AG71XX_RX_PKT_SIZE, -						  DMA_FROM_DEVICE); - -			ring->buf[i].skb = skb; -			ring->buf[i].dma_addr = dma_addr; -			ring->buf[i].desc->data = (u32) dma_addr; -		} - -		ring->buf[i].desc->ctrl = DESC_EMPTY; -		count++; -	} - -	/* flush descriptors */ -	wmb(); - -	DBG("%s: %u rx descriptors refilled\n", ag->dev->name, count); - -	return count; -} - -static int ag71xx_rings_init(struct ag71xx *ag) -{ -	int ret; - -	ret = ag71xx_ring_alloc(&ag->tx_ring); -	if (ret) -		return ret; - -	ag71xx_ring_tx_init(ag); - -	ret = ag71xx_ring_alloc(&ag->rx_ring); -	if (ret) -		return ret; - -	ret = ag71xx_ring_rx_init(ag); -	return ret; -} - -static void ag71xx_rings_cleanup(struct ag71xx *ag) -{ -	ag71xx_ring_rx_clean(ag); -	ag71xx_ring_free(&ag->rx_ring); - -	ag71xx_ring_tx_clean(ag); -	ag71xx_ring_free(&ag->tx_ring); -} - -static unsigned char *ag71xx_speed_str(struct ag71xx *ag) -{ -	switch (ag->speed) { -	case SPEED_1000: -		return "1000"; -	case SPEED_100: -		return "100"; -	case SPEED_10: -		return "10"; -	} - -	return "?"; -} - -static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) -{ -	u32 t; - -	t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16) -	  | (((u32) mac[3]) << 8) | ((u32) mac[2]); - -	ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t); - -	t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16); -	ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t); -} - -static void ag71xx_dma_reset(struct ag71xx *ag) -{ -	u32 val; -	int i; - -	ag71xx_dump_dma_regs(ag); - -	/* stop RX and TX */ -	ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); -	ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); - -	/* -	 * give the hardware some time to really stop all rx/tx activity -	 * clearing the descriptors too early causes random memory corruption -	 */ -	mdelay(1); - -	/* clear descriptor addresses */ -	ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->stop_desc_dma); -	ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->stop_desc_dma); - -	/* clear pending RX/TX interrupts */ -	for (i = 0; i < 256; i++) { -		ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); -		ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); -	} - -	/* clear pending errors */ -	ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF); -	ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR); - -	val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); -	if (val) -		printk(KERN_ALERT "%s: unable to clear DMA Rx status: %08x\n", -			ag->dev->name, val); - -	val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); - -	/* mask out reserved bits */ -	val &= ~0xff000000; - -	if (val) -		printk(KERN_ALERT "%s: unable to clear DMA Tx status: %08x\n", -			ag->dev->name, val); - -	ag71xx_dump_dma_regs(ag); -} - -#define MAC_CFG1_INIT	(MAC_CFG1_RXE | MAC_CFG1_TXE | \ -			 MAC_CFG1_SRX | MAC_CFG1_STX) - -#define FIFO_CFG0_INIT	(FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT) - -#define FIFO_CFG4_INIT	(FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \ -			 FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \ -			 FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \ -			 FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \ -			 FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \ -			 FIFO_CFG4_VT) - -#define FIFO_CFG5_INIT	(FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \ -			 FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \ -			 FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \ -			 FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \ -			 FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \ -			 FIFO_CFG5_17 | FIFO_CFG5_SF) - -static void ag71xx_hw_stop(struct ag71xx *ag) -{ -	/* disable all interrupts and stop the rx/tx engine */ -	ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0); -	ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); -	ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); -} - -static void ag71xx_hw_setup(struct ag71xx *ag) -{ -	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); - -	/* setup MAC configuration registers */ -	ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_INIT); - -	ag71xx_sb(ag, AG71XX_REG_MAC_CFG2, -		  MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK); - -	/* setup max frame length */ -	ag71xx_wr(ag, AG71XX_REG_MAC_MFL, AG71XX_TX_MTU_LEN); - -	/* setup FIFO configuration registers */ -	ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT); -	if (pdata->is_ar724x) { -		ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, pdata->fifo_cfg1); -		ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, pdata->fifo_cfg2); -	} else { -		ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000); -		ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff); -	} -	ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT); -	ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT); -} - -static void ag71xx_hw_init(struct ag71xx *ag) -{ -	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -	u32 reset_mask = pdata->reset_bit; - -	ag71xx_hw_stop(ag); - -	if (pdata->is_ar724x) { -		u32 reset_phy = reset_mask; - -		reset_phy &= RESET_MODULE_GE0_PHY | RESET_MODULE_GE1_PHY; -		reset_mask &= ~(RESET_MODULE_GE0_PHY | RESET_MODULE_GE1_PHY); - -		ar71xx_device_stop(reset_phy); -		mdelay(50); -		ar71xx_device_start(reset_phy); -		mdelay(200); -	} - -	ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR); -	udelay(20); - -	ar71xx_device_stop(reset_mask); -	mdelay(100); -	ar71xx_device_start(reset_mask); -	mdelay(200); - -	ag71xx_hw_setup(ag); - -	ag71xx_dma_reset(ag); -} - -static void ag71xx_fast_reset(struct ag71xx *ag) -{ -	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -	struct net_device *dev = ag->dev; -	u32 reset_mask = pdata->reset_bit; -	u32 rx_ds, tx_ds; -	u32 mii_reg; - -	reset_mask &= RESET_MODULE_GE0_MAC | RESET_MODULE_GE1_MAC; - -	mii_reg = ag71xx_rr(ag, AG71XX_REG_MII_CFG); -	rx_ds = ag71xx_rr(ag, AG71XX_REG_RX_DESC); -	tx_ds = ag71xx_rr(ag, AG71XX_REG_TX_DESC); - -	ar71xx_device_stop(reset_mask); -	udelay(10); -	ar71xx_device_start(reset_mask); -	udelay(10); - -	ag71xx_dma_reset(ag); -	ag71xx_hw_setup(ag); - -	ag71xx_wr(ag, AG71XX_REG_RX_DESC, rx_ds); -	ag71xx_wr(ag, AG71XX_REG_TX_DESC, tx_ds); -	ag71xx_wr(ag, AG71XX_REG_MII_CFG, mii_reg); - -	ag71xx_hw_set_macaddr(ag, dev->dev_addr); -} - -static void ag71xx_hw_start(struct ag71xx *ag) -{ -	/* start RX engine */ -	ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); - -	/* enable interrupts */ -	ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT); -} - -void ag71xx_link_adjust(struct ag71xx *ag) -{ -	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -	u32 cfg2; -	u32 ifctl; -	u32 fifo5; - -	if (!ag->link) { -		ag71xx_hw_stop(ag); -		netif_carrier_off(ag->dev); -		if (netif_msg_link(ag)) -			printk(KERN_INFO "%s: link down\n", ag->dev->name); -		return; -	} - -	if (pdata->is_ar724x) -		ag71xx_fast_reset(ag); - -	cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); -	cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); -	cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; - -	ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); -	ifctl &= ~(MAC_IFCTL_SPEED); - -	fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); -	fifo5 &= ~FIFO_CFG5_BM; - -	switch (ag->speed) { -	case SPEED_1000: -		cfg2 |= MAC_CFG2_IF_1000; -		fifo5 |= FIFO_CFG5_BM; -		break; -	case SPEED_100: -		cfg2 |= MAC_CFG2_IF_10_100; -		ifctl |= MAC_IFCTL_SPEED; -		break; -	case SPEED_10: -		cfg2 |= MAC_CFG2_IF_10_100; -		break; -	default: -		BUG(); -		return; -	} - -	if (pdata->is_ar91xx) -		ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff); -	else if (pdata->is_ar724x) -		ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3); -	else -		ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff); - -	if (pdata->set_speed) -		pdata->set_speed(ag->speed); - -	ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); -	ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); -	ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); -	ag71xx_hw_start(ag); - -	netif_carrier_on(ag->dev); -	if (netif_msg_link(ag)) -		printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n", -			ag->dev->name, -			ag71xx_speed_str(ag), -			(DUPLEX_FULL == ag->duplex) ? "Full" : "Half"); - -	DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", -		ag->dev->name, -		ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), -		ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), -		ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); - -	DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", -		ag->dev->name, -		ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), -		ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), -		ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); - -	DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n", -		ag->dev->name, -		ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), -		ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), -		ag71xx_mii_ctrl_rr(ag)); -} - -static int ag71xx_open(struct net_device *dev) -{ -	struct ag71xx *ag = netdev_priv(dev); -	int ret; - -	ret = ag71xx_rings_init(ag); -	if (ret) -		goto err; - -	napi_enable(&ag->napi); - -	netif_carrier_off(dev); -	ag71xx_phy_start(ag); - -	ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma); -	ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->rx_ring.descs_dma); - -	ag71xx_hw_set_macaddr(ag, dev->dev_addr); - -	netif_start_queue(dev); - -	return 0; - -err: -	ag71xx_rings_cleanup(ag); -	return ret; -} - -static int ag71xx_stop(struct net_device *dev) -{ -	struct ag71xx *ag = netdev_priv(dev); -	unsigned long flags; - -	netif_carrier_off(dev); -	ag71xx_phy_stop(ag); - -	spin_lock_irqsave(&ag->lock, flags); - -	netif_stop_queue(dev); - -	ag71xx_hw_stop(ag); -	ag71xx_dma_reset(ag); - -	napi_disable(&ag->napi); -	del_timer_sync(&ag->oom_timer); - -	spin_unlock_irqrestore(&ag->lock, flags); - -	ag71xx_rings_cleanup(ag); - -	return 0; -} - -static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb, -					  struct net_device *dev) -{ -	struct ag71xx *ag = netdev_priv(dev); -	struct ag71xx_ring *ring = &ag->tx_ring; -	struct ag71xx_desc *desc; -	dma_addr_t dma_addr; -	int i; - -	i = ring->curr % ring->size; -	desc = ring->buf[i].desc; - -	if (!ag71xx_desc_empty(desc)) -		goto err_drop; - -	if (ag71xx_has_ar8216(ag)) -		ag71xx_add_ar8216_header(ag, skb); - -	if (skb->len <= 0) { -		DBG("%s: packet len is too small\n", ag->dev->name); -		goto err_drop; -	} - -	dma_addr = dma_map_single(&dev->dev, skb->data, skb->len, -				  DMA_TO_DEVICE); - -	ring->buf[i].skb = skb; -	ring->buf[i].timestamp = jiffies; - -	/* setup descriptor fields */ -	desc->data = (u32) dma_addr; -	desc->ctrl = (skb->len & DESC_PKTLEN_M); - -	/* flush descriptor */ -	wmb(); - -	ring->curr++; -	if (ring->curr == (ring->dirty + ring->size)) { -		DBG("%s: tx queue full\n", ag->dev->name); -		netif_stop_queue(dev); -	} - -	DBG("%s: packet injected into TX queue\n", ag->dev->name); - -	/* enable TX engine */ -	ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE); - -	return NETDEV_TX_OK; - -err_drop: -	dev->stats.tx_dropped++; - -	dev_kfree_skb(skb); -	return NETDEV_TX_OK; -} - -static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ -	struct ag71xx *ag = netdev_priv(dev); -	int ret; - -	switch (cmd) { -	case SIOCETHTOOL: -		if (ag->phy_dev == NULL) -			break; - -		spin_lock_irq(&ag->lock); -		ret = phy_ethtool_ioctl(ag->phy_dev, (void *) ifr->ifr_data); -		spin_unlock_irq(&ag->lock); -		return ret; - -	case SIOCSIFHWADDR: -		if (copy_from_user -			(dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr))) -			return -EFAULT; -		return 0; - -	case SIOCGIFHWADDR: -		if (copy_to_user -			(ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr))) -			return -EFAULT; -		return 0; - -	case SIOCGMIIPHY: -	case SIOCGMIIREG: -	case SIOCSMIIREG: -		if (ag->phy_dev == NULL) -			break; - -		return phy_mii_ioctl(ag->phy_dev, ifr, cmd); - -	default: -		break; -	} - -	return -EOPNOTSUPP; -} - -static void ag71xx_oom_timer_handler(unsigned long data) -{ -	struct net_device *dev = (struct net_device *) data; -	struct ag71xx *ag = netdev_priv(dev); - -	napi_schedule(&ag->napi); -} - -static void ag71xx_tx_timeout(struct net_device *dev) -{ -	struct ag71xx *ag = netdev_priv(dev); - -	if (netif_msg_tx_err(ag)) -		printk(KERN_DEBUG "%s: tx timeout\n", ag->dev->name); - -	schedule_work(&ag->restart_work); -} - -static void ag71xx_restart_work_func(struct work_struct *work) -{ -	struct ag71xx *ag = container_of(work, struct ag71xx, restart_work); - -	if (ag71xx_get_pdata(ag)->is_ar724x) { -		ag->link = 0; -		ag71xx_link_adjust(ag); -		return; -	} - -	ag71xx_stop(ag->dev); -	ag71xx_open(ag->dev); -} - -static bool ag71xx_check_dma_stuck(struct ag71xx *ag, unsigned long timestamp) -{ -	u32 rx_sm, tx_sm, rx_fd; - -	if (likely(time_before(jiffies, timestamp + HZ/10))) -		return false; - -	if (!netif_carrier_ok(ag->dev)) -		return false; - -	rx_sm = ag71xx_rr(ag, AG71XX_REG_RX_SM); -	if ((rx_sm & 0x7) == 0x3 && ((rx_sm >> 4) & 0x7) == 0x6) -		return true; - -	tx_sm = ag71xx_rr(ag, AG71XX_REG_TX_SM); -	rx_fd = ag71xx_rr(ag, AG71XX_REG_FIFO_DEPTH); -	if (((tx_sm >> 4) & 0x7) == 0 && ((rx_sm & 0x7) == 0) && -	    ((rx_sm >> 4) & 0x7) == 0 && rx_fd == 0) -		return true; - -	return false; -} - -static int ag71xx_tx_packets(struct ag71xx *ag) -{ -	struct ag71xx_ring *ring = &ag->tx_ring; -	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -	int sent; - -	DBG("%s: processing TX ring\n", ag->dev->name); - -	sent = 0; -	while (ring->dirty != ring->curr) { -		unsigned int i = ring->dirty % ring->size; -		struct ag71xx_desc *desc = ring->buf[i].desc; -		struct sk_buff *skb = ring->buf[i].skb; - -		if (!ag71xx_desc_empty(desc)) { -			if (pdata->is_ar7240 && -			    ag71xx_check_dma_stuck(ag, ring->buf[i].timestamp)) -				schedule_work(&ag->restart_work); -			break; -		} - -		ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); - -		ag->dev->stats.tx_bytes += skb->len; -		ag->dev->stats.tx_packets++; - -		dev_kfree_skb_any(skb); -		ring->buf[i].skb = NULL; - -		ring->dirty++; -		sent++; -	} - -	DBG("%s: %d packets sent out\n", ag->dev->name, sent); - -	if ((ring->curr - ring->dirty) < (ring->size * 3) / 4) -		netif_wake_queue(ag->dev); - -	return sent; -} - -static int ag71xx_rx_packets(struct ag71xx *ag, int limit) -{ -	struct net_device *dev = ag->dev; -	struct ag71xx_ring *ring = &ag->rx_ring; -	int done = 0; - -	DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n", -			dev->name, limit, ring->curr, ring->dirty); - -	while (done < limit) { -		unsigned int i = ring->curr % ring->size; -		struct ag71xx_desc *desc = ring->buf[i].desc; -		struct sk_buff *skb; -		int pktlen; -		int err = 0; - -		if (ag71xx_desc_empty(desc)) -			break; - -		if ((ring->dirty + ring->size) == ring->curr) { -			ag71xx_assert(0); -			break; -		} - -		ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); - -		skb = ring->buf[i].skb; -		pktlen = ag71xx_desc_pktlen(desc); -		pktlen -= ETH_FCS_LEN; - -		dma_unmap_single(&dev->dev, ring->buf[i].dma_addr, -				 AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); - -		dev->last_rx = jiffies; -		dev->stats.rx_packets++; -		dev->stats.rx_bytes += pktlen; - -		skb_put(skb, pktlen); -		if (ag71xx_has_ar8216(ag)) -			err = ag71xx_remove_ar8216_header(ag, skb, pktlen); - -		if (err) { -			dev->stats.rx_dropped++; -			kfree_skb(skb); -		} else { -			skb->dev = dev; -			skb->ip_summed = CHECKSUM_NONE; -			if (ag->phy_dev) { -				ag->phy_dev->netif_receive_skb(skb); -			} else { -				skb->protocol = eth_type_trans(skb, dev); -				netif_receive_skb(skb); -			} -		} - -		ring->buf[i].skb = NULL; -		done++; - -		ring->curr++; -	} - -	ag71xx_ring_rx_refill(ag); - -	DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n", -		dev->name, ring->curr, ring->dirty, done); - -	return done; -} - -static int ag71xx_poll(struct napi_struct *napi, int limit) -{ -	struct ag71xx *ag = container_of(napi, struct ag71xx, napi); -	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -	struct net_device *dev = ag->dev; -	struct ag71xx_ring *rx_ring; -	unsigned long flags; -	u32 status; -	int tx_done; -	int rx_done; - -	pdata->ddr_flush(); -	tx_done = ag71xx_tx_packets(ag); - -	DBG("%s: processing RX ring\n", dev->name); -	rx_done = ag71xx_rx_packets(ag, limit); - -	ag71xx_debugfs_update_napi_stats(ag, rx_done, tx_done); - -	rx_ring = &ag->rx_ring; -	if (rx_ring->buf[rx_ring->dirty % rx_ring->size].skb == NULL) -		goto oom; - -	status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); -	if (unlikely(status & RX_STATUS_OF)) { -		ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF); -		dev->stats.rx_fifo_errors++; - -		/* restart RX */ -		ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); -	} - -	if (rx_done < limit) { -		if (status & RX_STATUS_PR) -			goto more; - -		status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); -		if (status & TX_STATUS_PS) -			goto more; - -		DBG("%s: disable polling mode, rx=%d, tx=%d,limit=%d\n", -			dev->name, rx_done, tx_done, limit); - -		napi_complete(napi); - -		/* enable interrupts */ -		spin_lock_irqsave(&ag->lock, flags); -		ag71xx_int_enable(ag, AG71XX_INT_POLL); -		spin_unlock_irqrestore(&ag->lock, flags); -		return rx_done; -	} - -more: -	DBG("%s: stay in polling mode, rx=%d, tx=%d, limit=%d\n", -			dev->name, rx_done, tx_done, limit); -	return rx_done; - -oom: -	if (netif_msg_rx_err(ag)) -		printk(KERN_DEBUG "%s: out of memory\n", dev->name); - -	mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL); -	napi_complete(napi); -	return 0; -} - -static irqreturn_t ag71xx_interrupt(int irq, void *dev_id) -{ -	struct net_device *dev = dev_id; -	struct ag71xx *ag = netdev_priv(dev); -	u32 status; - -	status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS); -	ag71xx_dump_intr(ag, "raw", status); - -	if (unlikely(!status)) -		return IRQ_NONE; - -	if (unlikely(status & AG71XX_INT_ERR)) { -		if (status & AG71XX_INT_TX_BE) { -			ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE); -			dev_err(&dev->dev, "TX BUS error\n"); -		} -		if (status & AG71XX_INT_RX_BE) { -			ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE); -			dev_err(&dev->dev, "RX BUS error\n"); -		} -	} - -	if (likely(status & AG71XX_INT_POLL)) { -		ag71xx_int_disable(ag, AG71XX_INT_POLL); -		DBG("%s: enable polling mode\n", dev->name); -		napi_schedule(&ag->napi); -	} - -	ag71xx_debugfs_update_int_stats(ag, status); - -	return IRQ_HANDLED; -} - -static void ag71xx_set_multicast_list(struct net_device *dev) -{ -	/* TODO */ -} - -#ifdef CONFIG_NET_POLL_CONTROLLER -/* - * Polling 'interrupt' - used by things like netconsole to send skbs - * without having to re-enable interrupts. It's not called while - * the interrupt routine is executing. - */ -static void ag71xx_netpoll(struct net_device *dev) -{ -	disable_irq(dev->irq); -	ag71xx_interrupt(dev->irq, dev); -	enable_irq(dev->irq); -} -#endif - -static const struct net_device_ops ag71xx_netdev_ops = { -	.ndo_open		= ag71xx_open, -	.ndo_stop		= ag71xx_stop, -	.ndo_start_xmit		= ag71xx_hard_start_xmit, -	.ndo_set_multicast_list	= ag71xx_set_multicast_list, -	.ndo_do_ioctl		= ag71xx_do_ioctl, -	.ndo_tx_timeout		= ag71xx_tx_timeout, -	.ndo_change_mtu		= eth_change_mtu, -	.ndo_set_mac_address	= eth_mac_addr, -	.ndo_validate_addr	= eth_validate_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER -	.ndo_poll_controller	= ag71xx_netpoll, -#endif -}; - -static int __devinit ag71xx_probe(struct platform_device *pdev) -{ -	struct net_device *dev; -	struct resource *res; -	struct ag71xx *ag; -	struct ag71xx_platform_data *pdata; -	int err; - -	pdata = pdev->dev.platform_data; -	if (!pdata) { -		dev_err(&pdev->dev, "no platform data specified\n"); -		err = -ENXIO; -		goto err_out; -	} - -	if (pdata->mii_bus_dev == NULL) { -		dev_err(&pdev->dev, "no MII bus device specified\n"); -		err = -EINVAL; -		goto err_out; -	} - -	dev = alloc_etherdev(sizeof(*ag)); -	if (!dev) { -		dev_err(&pdev->dev, "alloc_etherdev failed\n"); -		err = -ENOMEM; -		goto err_out; -	} - -	SET_NETDEV_DEV(dev, &pdev->dev); - -	ag = netdev_priv(dev); -	ag->pdev = pdev; -	ag->dev = dev; -	ag->msg_enable = netif_msg_init(ag71xx_msg_level, -					AG71XX_DEFAULT_MSG_ENABLE); -	spin_lock_init(&ag->lock); - -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base"); -	if (!res) { -		dev_err(&pdev->dev, "no mac_base resource found\n"); -		err = -ENXIO; -		goto err_out; -	} - -	ag->mac_base = ioremap_nocache(res->start, res->end - res->start + 1); -	if (!ag->mac_base) { -		dev_err(&pdev->dev, "unable to ioremap mac_base\n"); -		err = -ENOMEM; -		goto err_free_dev; -	} - -	dev->irq = platform_get_irq(pdev, 0); -	err = request_irq(dev->irq, ag71xx_interrupt, -			  IRQF_DISABLED, -			  dev->name, dev); -	if (err) { -		dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq); -		goto err_unmap_base; -	} - -	dev->base_addr = (unsigned long)ag->mac_base; -	dev->netdev_ops = &ag71xx_netdev_ops; -	dev->ethtool_ops = &ag71xx_ethtool_ops; - -	INIT_WORK(&ag->restart_work, ag71xx_restart_work_func); - -	init_timer(&ag->oom_timer); -	ag->oom_timer.data = (unsigned long) dev; -	ag->oom_timer.function = ag71xx_oom_timer_handler; - -	ag->tx_ring.size = AG71XX_TX_RING_SIZE_DEFAULT; -	ag->rx_ring.size = AG71XX_RX_RING_SIZE_DEFAULT; - -	ag->stop_desc = dma_alloc_coherent(NULL, -		sizeof(struct ag71xx_desc), &ag->stop_desc_dma, GFP_KERNEL); - -	if (!ag->stop_desc) -		goto err_free_irq; - -	ag->stop_desc->data = 0; -	ag->stop_desc->ctrl = 0; -	ag->stop_desc->next = (u32) ag->stop_desc_dma; - -	memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN); - -	netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT); - -	err = register_netdev(dev); -	if (err) { -		dev_err(&pdev->dev, "unable to register net device\n"); -		goto err_free_desc; -	} - -	printk(KERN_INFO "%s: Atheros AG71xx at 0x%08lx, irq %d\n", -	       dev->name, dev->base_addr, dev->irq); - -	ag71xx_dump_regs(ag); - -	ag71xx_hw_init(ag); - -	ag71xx_dump_regs(ag); - -	err = ag71xx_phy_connect(ag); -	if (err) -		goto err_unregister_netdev; - -	err = ag71xx_debugfs_init(ag); -	if (err) -		goto err_phy_disconnect; - -	platform_set_drvdata(pdev, dev); - -	return 0; - -err_phy_disconnect: -	ag71xx_phy_disconnect(ag); -err_unregister_netdev: -	unregister_netdev(dev); -err_free_desc: -	dma_free_coherent(NULL, sizeof(struct ag71xx_desc), ag->stop_desc, -			  ag->stop_desc_dma); -err_free_irq: -	free_irq(dev->irq, dev); -err_unmap_base: -	iounmap(ag->mac_base); -err_free_dev: -	kfree(dev); -err_out: -	platform_set_drvdata(pdev, NULL); -	return err; -} - -static int __devexit ag71xx_remove(struct platform_device *pdev) -{ -	struct net_device *dev = platform_get_drvdata(pdev); - -	if (dev) { -		struct ag71xx *ag = netdev_priv(dev); - -		ag71xx_debugfs_exit(ag); -		ag71xx_phy_disconnect(ag); -		unregister_netdev(dev); -		free_irq(dev->irq, dev); -		iounmap(ag->mac_base); -		kfree(dev); -		platform_set_drvdata(pdev, NULL); -	} - -	return 0; -} - -static struct platform_driver ag71xx_driver = { -	.probe		= ag71xx_probe, -	.remove		= __exit_p(ag71xx_remove), -	.driver = { -		.name	= AG71XX_DRV_NAME, -	} -}; - -static int __init ag71xx_module_init(void) -{ -	int ret; - -	ret = ag71xx_debugfs_root_init(); -	if (ret) -		goto err_out; - -	ret = ag71xx_mdio_driver_init(); -	if (ret) -		goto err_debugfs_exit; - -	ret = platform_driver_register(&ag71xx_driver); -	if (ret) -		goto err_mdio_exit; - -	return 0; - -err_mdio_exit: -	ag71xx_mdio_driver_exit(); -err_debugfs_exit: -	ag71xx_debugfs_root_exit(); -err_out: -	return ret; -} - -static void __exit ag71xx_module_exit(void) -{ -	platform_driver_unregister(&ag71xx_driver); -	ag71xx_mdio_driver_exit(); -	ag71xx_debugfs_root_exit(); -} - -module_init(ag71xx_module_init); -module_exit(ag71xx_module_exit); - -MODULE_VERSION(AG71XX_DRV_VERSION); -MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); -MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:" AG71XX_DRV_NAME); diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_mdio.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_mdio.c deleted file mode 100644 index b2460d726..000000000 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_mdio.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - *  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. - */ - -#include "ag71xx.h" - -#define AG71XX_MDIO_RETRY	1000 -#define AG71XX_MDIO_DELAY	5 - -static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg, -				  u32 value) -{ -	void __iomem *r; - -	r = am->mdio_base + reg; -	__raw_writel(value, r); - -	/* flush write */ -	(void) __raw_readl(r); -} - -static inline u32 ag71xx_mdio_rr(struct ag71xx_mdio *am, unsigned reg) -{ -	return __raw_readl(am->mdio_base + reg); -} - -static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am) -{ -	DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n", -		am->mii_bus->name, -		ag71xx_mdio_rr(am, AG71XX_REG_MII_CFG), -		ag71xx_mdio_rr(am, AG71XX_REG_MII_CMD), -		ag71xx_mdio_rr(am, AG71XX_REG_MII_ADDR)); -	DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n", -		am->mii_bus->name, -		ag71xx_mdio_rr(am, AG71XX_REG_MII_CTRL), -		ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS), -		ag71xx_mdio_rr(am, AG71XX_REG_MII_IND)); -} - -int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg) -{ -	int ret; -	int i; - -	ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); -	ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, -			((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); -	ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_READ); - -	i = AG71XX_MDIO_RETRY; -	while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) { -		if (i-- == 0) { -			printk(KERN_ERR "%s: mii_read timed out\n", -				am->mii_bus->name); -			ret = 0xffff; -			goto out; -		} -		udelay(AG71XX_MDIO_DELAY); -	} - -	ret = ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS) & 0xffff; -	ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); - -	DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret); - -out: -	return ret; -} - -void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val) -{ -	int i; - -	DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val); - -	ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, -			((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); -	ag71xx_mdio_wr(am, AG71XX_REG_MII_CTRL, val); - -	i = AG71XX_MDIO_RETRY; -	while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) { -		if (i-- == 0) { -			printk(KERN_ERR "%s: mii_write timed out\n", -				am->mii_bus->name); -			break; -		} -		udelay(AG71XX_MDIO_DELAY); -	} -} - -static int ag71xx_mdio_reset(struct mii_bus *bus) -{ -	struct ag71xx_mdio *am = bus->priv; -	u32 t; - -	if (am->pdata->is_ar7240) -		t = MII_CFG_CLK_DIV_6; -	else -		t = MII_CFG_CLK_DIV_28; - -	ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t | MII_CFG_RESET); -	udelay(100); - -	ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t); -	udelay(100); - -	return 0; -} - -static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg) -{ -	struct ag71xx_mdio *am = bus->priv; - -	if (am->pdata->is_ar7240) -		return ar7240sw_phy_read(bus, addr, reg); -	else -		return ag71xx_mdio_mii_read(am, addr, reg); -} - -static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val) -{ -	struct ag71xx_mdio *am = bus->priv; - -	if (am->pdata->is_ar7240) -		ar7240sw_phy_write(bus, addr, reg, val); -	else -		ag71xx_mdio_mii_write(am, addr, reg, val); -	return 0; -} - -static int __devinit ag71xx_mdio_probe(struct platform_device *pdev) -{ -	struct ag71xx_mdio_platform_data *pdata; -	struct ag71xx_mdio *am; -	struct resource *res; -	int i; -	int err; - -	pdata = pdev->dev.platform_data; -	if (!pdata) { -		dev_err(&pdev->dev, "no platform data specified\n"); -		return -EINVAL; -	} - -	am = kzalloc(sizeof(*am), GFP_KERNEL); -	if (!am) { -		err = -ENOMEM; -		goto err_out; -	} - -	am->pdata = pdata; - -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_err(&pdev->dev, "no iomem resource found\n"); -		err = -ENXIO; -		goto err_out; -	} - -	am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1); -	if (!am->mdio_base) { -		dev_err(&pdev->dev, "unable to ioremap registers\n"); -		err = -ENOMEM; -		goto err_free_mdio; -	} - -	am->mii_bus = mdiobus_alloc(); -	if (am->mii_bus == NULL) { -		err = -ENOMEM; -		goto err_iounmap; -	} - -	am->mii_bus->name = "ag71xx_mdio"; -	am->mii_bus->read = ag71xx_mdio_read; -	am->mii_bus->write = ag71xx_mdio_write; -	am->mii_bus->reset = ag71xx_mdio_reset; -	am->mii_bus->irq = am->mii_irq; -	am->mii_bus->priv = am; -	am->mii_bus->parent = &pdev->dev; -	snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev)); -	am->mii_bus->phy_mask = pdata->phy_mask; - -	for (i = 0; i < PHY_MAX_ADDR; i++) -		am->mii_irq[i] = PHY_POLL; - -	ag71xx_mdio_wr(am, AG71XX_REG_MAC_CFG1, 0); - -	err = mdiobus_register(am->mii_bus); -	if (err) -		goto err_free_bus; - -	ag71xx_mdio_dump_regs(am); - -	platform_set_drvdata(pdev, am); -	return 0; - -err_free_bus: -	mdiobus_free(am->mii_bus); -err_iounmap: -	iounmap(am->mdio_base); -err_free_mdio: -	kfree(am); -err_out: -	return err; -} - -static int __devexit ag71xx_mdio_remove(struct platform_device *pdev) -{ -	struct ag71xx_mdio *am = platform_get_drvdata(pdev); - -	if (am) { -		mdiobus_unregister(am->mii_bus); -		mdiobus_free(am->mii_bus); -		iounmap(am->mdio_base); -		kfree(am); -		platform_set_drvdata(pdev, NULL); -	} - -	return 0; -} - -static struct platform_driver ag71xx_mdio_driver = { -	.probe		= ag71xx_mdio_probe, -	.remove		= __exit_p(ag71xx_mdio_remove), -	.driver = { -		.name	= "ag71xx-mdio", -	} -}; - -int __init ag71xx_mdio_driver_init(void) -{ -	return platform_driver_register(&ag71xx_mdio_driver); -} - -void ag71xx_mdio_driver_exit(void) -{ -	platform_driver_unregister(&ag71xx_mdio_driver); -} diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_phy.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_phy.c deleted file mode 100644 index b10dd4917..000000000 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_phy.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - *  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. - */ - -#include "ag71xx.h" - -static void ag71xx_phy_link_adjust(struct net_device *dev) -{ -	struct ag71xx *ag = netdev_priv(dev); -	struct phy_device *phydev = ag->phy_dev; -	unsigned long flags; -	int status_change = 0; - -	spin_lock_irqsave(&ag->lock, flags); - -	if (phydev->link) { -		if (ag->duplex != phydev->duplex -		    || ag->speed != phydev->speed) { -			status_change = 1; -		} -	} - -	if (phydev->link != ag->link) -		status_change = 1; - -	ag->link = phydev->link; -	ag->duplex = phydev->duplex; -	ag->speed = phydev->speed; - -	if (status_change) -		ag71xx_link_adjust(ag); - -	spin_unlock_irqrestore(&ag->lock, flags); -} - -void ag71xx_phy_start(struct ag71xx *ag) -{ -	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); - -	if (ag->phy_dev) { -		phy_start(ag->phy_dev); -	} else if (pdata->switch_data) { -		ag71xx_ar7240_start(ag); -	} else { -		ag->link = 1; -		ag71xx_link_adjust(ag); -	} -} - -void ag71xx_phy_stop(struct ag71xx *ag) -{ -	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -	unsigned long flags; - -	if (ag->phy_dev) -		phy_stop(ag->phy_dev); -	else if (pdata->switch_data) -		ag71xx_ar7240_stop(ag); - -	spin_lock_irqsave(&ag->lock, flags); -	if (ag->link) { -		ag->link = 0; -		ag71xx_link_adjust(ag); -	} -	spin_unlock_irqrestore(&ag->lock, flags); -} - -static int ag71xx_phy_connect_fixed(struct ag71xx *ag) -{ -	struct net_device *dev = ag->dev; -	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -	int ret = 0; - -	/* use fixed settings */ -	switch (pdata->speed) { -	case SPEED_10: -	case SPEED_100: -	case SPEED_1000: -		break; -	default: -		printk(KERN_ERR "%s: invalid speed specified\n", dev->name); -		ret = -EINVAL; -		break; -	} - -	printk(KERN_DEBUG "%s: using fixed link parameters\n", dev->name); - -	ag->duplex = pdata->duplex; -	ag->speed = pdata->speed; - -	return ret; -} - -static int ag71xx_phy_connect_multi(struct ag71xx *ag) -{ -	struct net_device *dev = ag->dev; -	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -	struct phy_device *phydev = NULL; -	int phy_addr; -	int ret = 0; - -	for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { -		if (!(pdata->phy_mask & (1 << phy_addr))) -			continue; - -		if (ag->mii_bus->phy_map[phy_addr] == NULL) -			continue; - -		DBG("%s: PHY found at %s, uid=%08x\n", -			dev->name, -			dev_name(&ag->mii_bus->phy_map[phy_addr]->dev), -			ag->mii_bus->phy_map[phy_addr]->phy_id); - -		if (phydev == NULL) -			phydev = ag->mii_bus->phy_map[phy_addr]; -	} - -	if (!phydev) { -		printk(KERN_ERR "%s: no PHY found with phy_mask=%08x\n", -			dev->name, pdata->phy_mask); -		return -ENODEV; -	} - -	ag->phy_dev = phy_connect(dev, dev_name(&phydev->dev), -				  &ag71xx_phy_link_adjust, 0, -				  pdata->phy_if_mode); - -	if (IS_ERR(ag->phy_dev)) { -		printk(KERN_ERR "%s: could not connect to PHY at %s\n", -			dev->name, dev_name(&phydev->dev)); -		return PTR_ERR(ag->phy_dev); -	} - -	/* mask with MAC supported features */ -	if (pdata->has_gbit) -		phydev->supported &= PHY_GBIT_FEATURES; -	else -		phydev->supported &= PHY_BASIC_FEATURES; - -	phydev->advertising = phydev->supported; - -	printk(KERN_DEBUG "%s: connected to PHY at %s [uid=%08x, driver=%s]\n", -		dev->name, dev_name(&phydev->dev), -		phydev->phy_id, phydev->drv->name); - -	ag->link = 0; -	ag->speed = 0; -	ag->duplex = -1; - -	return ret; -} - -static int dev_is_class(struct device *dev, void *class) -{ -	if (dev->class != NULL && !strcmp(dev->class->name, class)) -		return 1; - -	return 0; -} - -static struct device *dev_find_class(struct device *parent, char *class) -{ -	if (dev_is_class(parent, class)) { -		get_device(parent); -		return parent; -	} - -	return device_find_child(parent, class, dev_is_class); -} - -static struct mii_bus *dev_to_mii_bus(struct device *dev) -{ -	struct device *d; - -	d = dev_find_class(dev, "mdio_bus"); -	if (d != NULL) { -		struct mii_bus *bus; - -		bus = to_mii_bus(d); -		put_device(d); - -		return bus; -	} - -	return NULL; -} - -int __devinit ag71xx_phy_connect(struct ag71xx *ag) -{ -	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); - -	if (pdata->mii_bus_dev == NULL || -	    pdata->mii_bus_dev->bus == NULL ) -		return ag71xx_phy_connect_fixed(ag); - -	ag->mii_bus = dev_to_mii_bus(pdata->mii_bus_dev); -	if (ag->mii_bus == NULL) { -		printk(KERN_ERR "%s: unable to find MII bus on device '%s'\n", -			ag->dev->name, dev_name(pdata->mii_bus_dev)); -		return -ENODEV; -	} - -	/* Reset the mdio bus explicitly */ -	if (ag->mii_bus->reset) { -		mutex_lock(&ag->mii_bus->mdio_lock); -		ag->mii_bus->reset(ag->mii_bus); -		mutex_unlock(&ag->mii_bus->mdio_lock); -	} - -	if (pdata->switch_data) -		return ag71xx_ar7240_init(ag); - -	if (pdata->phy_mask) -		return ag71xx_phy_connect_multi(ag); - -	return ag71xx_phy_connect_fixed(ag); -} - -void ag71xx_phy_disconnect(struct ag71xx *ag) -{ -	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); - -	if (pdata->switch_data) -		ag71xx_ar7240_cleanup(ag); -	else if (ag->phy_dev) -		phy_disconnect(ag->phy_dev); -} diff --git a/target/linux/ar71xx/files/drivers/spi/ar71xx_spi.c b/target/linux/ar71xx/files/drivers/spi/ar71xx_spi.c deleted file mode 100644 index d1ed731c1..000000000 --- a/target/linux/ar71xx/files/drivers/spi/ar71xx_spi.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Atheros AR71xx SPI Controller driver - * - * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> - * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> - * - * 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. - * - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/spinlock.h> -#include <linux/workqueue.h> -#include <linux/platform_device.h> -#include <linux/io.h> -#include <linux/spi/spi.h> -#include <linux/spi/spi_bitbang.h> -#include <linux/bitops.h> - -#include <asm/mach-ar71xx/ar71xx.h> -#include <asm/mach-ar71xx/platform.h> - -#define DRV_DESC	"Atheros AR71xx SPI Controller driver" -#define DRV_VERSION	"0.2.4" -#define DRV_NAME	"ar71xx-spi" - -#undef PER_BIT_READ - -struct ar71xx_spi { -	struct	spi_bitbang	bitbang; -	u32			ioc_base; -	u32			reg_ctrl; - -	void __iomem		*base; - -	struct platform_device	*pdev; -	u32			(*get_ioc_base)(u8 chip_select, int cs_high, -						int is_on); -}; - -static inline u32 ar71xx_spi_rr(struct ar71xx_spi *sp, unsigned reg) -{ -	return __raw_readl(sp->base + reg); -} - -static inline void ar71xx_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val) -{ -	__raw_writel(val, sp->base + reg); -} - -static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi) -{ -	return spi_master_get_devdata(spi->master); -} - -static u32 ar71xx_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on) -{ -	u32 ret; - -	if (is_on == AR71XX_SPI_CS_INACTIVE) -		ret = SPI_IOC_CS_ALL; -	else -		ret = SPI_IOC_CS_ALL & ~SPI_IOC_CS(chip_select); - -	return ret; -} - -static void ar71xx_spi_chipselect(struct spi_device *spi, int value) -{ -	struct ar71xx_spi *sp = spidev_to_sp(spi); -	void __iomem *base = sp->base; -	u32 ioc_base; - -	switch (value) { -	case BITBANG_CS_INACTIVE: -		ioc_base = sp->get_ioc_base(spi->chip_select, -					(spi->mode & SPI_CS_HIGH) != 0, -					AR71XX_SPI_CS_INACTIVE); -		__raw_writel(ioc_base, base + SPI_REG_IOC); -		break; - -	case BITBANG_CS_ACTIVE: -		ioc_base = sp->get_ioc_base(spi->chip_select, -					(spi->mode & SPI_CS_HIGH) != 0, -					AR71XX_SPI_CS_ACTIVE); - -		__raw_writel(ioc_base, base + SPI_REG_IOC); -		sp->ioc_base = ioc_base; -		break; -	} -} - -static void ar71xx_spi_setup_regs(struct ar71xx_spi *sp) -{ -	/* enable GPIO mode */ -	ar71xx_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO); - -	/* save CTRL register */ -	sp->reg_ctrl = ar71xx_spi_rr(sp, SPI_REG_CTRL); - -	/* TODO: setup speed? */ -	ar71xx_spi_wr(sp, SPI_REG_CTRL, 0x43); -} - -static void ar71xx_spi_restore_regs(struct ar71xx_spi *sp) -{ -	/* restore CTRL register */ -	ar71xx_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl); -	/* disable GPIO mode */ -	ar71xx_spi_wr(sp, SPI_REG_FS, 0); -} - -static int ar71xx_spi_setup(struct spi_device *spi) -{ -	if (spi->bits_per_word > 32) -		return -EINVAL; - -	return spi_bitbang_setup(spi); -} - -static void ar71xx_spi_cleanup(struct spi_device *spi) -{ -	spi_bitbang_cleanup(spi); -} - -static u32 ar71xx_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs, -					u32 word, u8 bits) -{ -	struct ar71xx_spi *sp = spidev_to_sp(spi); -	void __iomem *base = sp->base; -	u32 ioc = sp->ioc_base; -	u32 ret; - -	/* clock starts at inactive polarity */ -	for (word <<= (32 - bits); likely(bits); bits--) { -		u32 out; - -		if (word & (1 << 31)) -			out = ioc | SPI_IOC_DO; -		else -			out = ioc & ~SPI_IOC_DO; - -		/* setup MSB (to slave) on trailing edge */ -		__raw_writel(out, base + SPI_REG_IOC); - -		__raw_writel(out | SPI_IOC_CLK, base + SPI_REG_IOC); - -		word <<= 1; - -#ifdef PER_BIT_READ -		/* sample MSB (from slave) on leading edge */ -		ret = __raw_readl(base + SPI_REG_RDS); -		__raw_writel(out, base + SPI_REG_IOC); -#endif - -	} - -#ifndef PER_BIT_READ -	ret = __raw_readl(base + SPI_REG_RDS); -#endif -	return ret; -} - -static int ar71xx_spi_probe(struct platform_device *pdev) -{ -	struct spi_master *master; -	struct ar71xx_spi *sp; -	struct ar71xx_spi_platform_data *pdata; -	struct resource	*r; -	int ret; - -	master = spi_alloc_master(&pdev->dev, sizeof(*sp)); -	if (master == NULL) { -		dev_err(&pdev->dev, "failed to allocate spi master\n"); -		return -ENOMEM; -	} - -	sp = spi_master_get_devdata(master); -	platform_set_drvdata(pdev, sp); - -	pdata = pdev->dev.platform_data; - -	master->setup = ar71xx_spi_setup; -	master->cleanup = ar71xx_spi_cleanup; - -	sp->bitbang.master = spi_master_get(master); -	sp->bitbang.chipselect = ar71xx_spi_chipselect; -	sp->bitbang.txrx_word[SPI_MODE_0] = ar71xx_spi_txrx_mode0; -	sp->bitbang.setup_transfer = spi_bitbang_setup_transfer; - -	sp->get_ioc_base = ar71xx_spi_get_ioc_base; -	if (pdata) { -		sp->bitbang.master->bus_num = pdata->bus_num; -		sp->bitbang.master->num_chipselect = pdata->num_chipselect; -		if (pdata->get_ioc_base) -			sp->get_ioc_base = pdata->get_ioc_base; -	} else { -		sp->bitbang.master->bus_num = 0; -		sp->bitbang.master->num_chipselect = 3; -	} - -	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (r == NULL) { -		ret = -ENOENT; -		goto err1; -	} - -	sp->base = ioremap_nocache(r->start, r->end - r->start + 1); -	if (!sp->base) { -		ret = -ENXIO; -		goto err1; -	} - -	ar71xx_spi_setup_regs(sp); - -	ret = spi_bitbang_start(&sp->bitbang); -	if (!ret) -		return 0; - -	ar71xx_spi_restore_regs(sp); -	iounmap(sp->base); -err1: -	platform_set_drvdata(pdev, NULL); -	spi_master_put(sp->bitbang.master); - -	return ret; -} - -static int ar71xx_spi_remove(struct platform_device *pdev) -{ -	struct ar71xx_spi *sp = platform_get_drvdata(pdev); - -	spi_bitbang_stop(&sp->bitbang); -	ar71xx_spi_restore_regs(sp); -	iounmap(sp->base); -	platform_set_drvdata(pdev, NULL); -	spi_master_put(sp->bitbang.master); - -	return 0; -} - -static void ar71xx_spi_shutdown(struct platform_device *pdev) -{ -	int ret; - -	ret = ar71xx_spi_remove(pdev); -	if (ret) -		dev_err(&pdev->dev, "shutdown failed with %d\n", ret); -} - -static struct platform_driver ar71xx_spi_drv = { -	.probe		= ar71xx_spi_probe, -	.remove		= ar71xx_spi_remove, -	.shutdown	= ar71xx_spi_shutdown, -	.driver		= { -		.name	= DRV_NAME, -		.owner	= THIS_MODULE, -	}, -}; - -static int __init ar71xx_spi_init(void) -{ -	printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); -	return platform_driver_register(&ar71xx_spi_drv); -} -module_init(ar71xx_spi_init); - -static void __exit ar71xx_spi_exit(void) -{ -	platform_driver_unregister(&ar71xx_spi_drv); -} -module_exit(ar71xx_spi_exit); - -MODULE_ALIAS("platform:" DRV_NAME); -MODULE_DESCRIPTION(DRV_DESC); -MODULE_VERSION(DRV_VERSION); -MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); -MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>"); -MODULE_LICENSE("GPL v2"); diff --git a/target/linux/ar71xx/files/drivers/spi/pb44_spi.c b/target/linux/ar71xx/files/drivers/spi/pb44_spi.c deleted file mode 100644 index 556c7717c..000000000 --- a/target/linux/ar71xx/files/drivers/spi/pb44_spi.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Atheros PB44 board SPI controller driver - * - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - * - * 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. - * - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/spinlock.h> -#include <linux/workqueue.h> -#include <linux/platform_device.h> -#include <linux/io.h> -#include <linux/spi/spi.h> -#include <linux/spi/spi_bitbang.h> -#include <linux/bitops.h> -#include <linux/gpio.h> - -#include <asm/mach-ar71xx/ar71xx.h> -#include <asm/mach-ar71xx/platform.h> - -#define DRV_DESC	"Atheros PB44 SPI Controller driver" -#define DRV_VERSION	"0.1.0" -#define DRV_NAME	"pb44-spi" - -#undef PER_BIT_READ - -struct ar71xx_spi { -	struct	spi_bitbang	bitbang; -	u32			ioc_base; -	u32			reg_ctrl; - -	void __iomem		*base; - -	struct platform_device	*pdev; -}; - -static inline u32 pb44_spi_rr(struct ar71xx_spi *sp, unsigned reg) -{ -	return __raw_readl(sp->base + reg); -} - -static inline void pb44_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val) -{ -	__raw_writel(val, sp->base + reg); -} - -static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi) -{ -	return spi_master_get_devdata(spi->master); -} - -static void pb44_spi_chipselect(struct spi_device *spi, int is_active) -{ -	struct ar71xx_spi *sp = spidev_to_sp(spi); -	int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active; - -	if (is_active) { -		/* set initial clock polarity */ -		if (spi->mode & SPI_CPOL) -			sp->ioc_base |= SPI_IOC_CLK; -		else -			sp->ioc_base &= ~SPI_IOC_CLK; - -		pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base); -	} - -	if (spi->chip_select) { -		unsigned long gpio = (unsigned long) spi->controller_data; - -		/* SPI is normally active-low */ -		gpio_set_value(gpio, cs_high); -	} else { -		if (cs_high) -			sp->ioc_base |= SPI_IOC_CS0; -		else -			sp->ioc_base &= ~SPI_IOC_CS0; - -		pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base); -	} - -} - -static void pb44_spi_enable(struct ar71xx_spi *sp) -{ -	/* enable GPIO mode */ -	pb44_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO); - -	/* save CTRL register */ -	sp->reg_ctrl = pb44_spi_rr(sp, SPI_REG_CTRL); -	sp->ioc_base = pb44_spi_rr(sp, SPI_REG_IOC); - -	pb44_spi_wr(sp, SPI_REG_CTRL, 0x43); -} - -static void pb44_spi_disable(struct ar71xx_spi *sp) -{ -	/* restore CTRL register */ -	pb44_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl); -	/* disable GPIO mode */ -	pb44_spi_wr(sp, SPI_REG_FS, 0); -} - -static int pb44_spi_setup_cs(struct spi_device *spi) -{ -	struct ar71xx_spi *sp = spidev_to_sp(spi); - -	if (spi->chip_select) { -		unsigned long gpio = (unsigned long) spi->controller_data; -		int status = 0; - -		status = gpio_request(gpio, dev_name(&spi->dev)); -		if (status) -			return status; - -		status = gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH); -		if (status) { -			gpio_free(gpio); -			return status; -		} -	} else { -		if (spi->mode & SPI_CS_HIGH) -			sp->ioc_base |= SPI_IOC_CS0; -		else -			sp->ioc_base &= ~SPI_IOC_CS0; -		pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base); -	} - -	return 0; -} - -static void pb44_spi_cleanup_cs(struct spi_device *spi) -{ -	if (spi->chip_select) { -		unsigned long gpio = (unsigned long) spi->controller_data; -		gpio_free(gpio); -	} -} - -static int pb44_spi_setup(struct spi_device *spi) -{ -	int status = 0; - -	if (spi->bits_per_word > 32) -		return -EINVAL; - -	if (!spi->controller_state) { -		status = pb44_spi_setup_cs(spi); -		if (status) -			return status; -	} - -	status = spi_bitbang_setup(spi); -	if (status && !spi->controller_state) -		pb44_spi_cleanup_cs(spi); - -	return status; -} - -static void pb44_spi_cleanup(struct spi_device *spi) -{ -	pb44_spi_cleanup_cs(spi); -	spi_bitbang_cleanup(spi); -} - -static u32 pb44_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs, -			       u32 word, u8 bits) -{ -	struct ar71xx_spi *sp = spidev_to_sp(spi); -	u32 ioc = sp->ioc_base; -	u32 ret; - -	/* clock starts at inactive polarity */ -	for (word <<= (32 - bits); likely(bits); bits--) { -		u32 out; - -		if (word & (1 << 31)) -			out = ioc | SPI_IOC_DO; -		else -			out = ioc & ~SPI_IOC_DO; - -		/* setup MSB (to slave) on trailing edge */ -		pb44_spi_wr(sp, SPI_REG_IOC, out); -		pb44_spi_wr(sp, SPI_REG_IOC, out | SPI_IOC_CLK); - -		word <<= 1; - -#ifdef PER_BIT_READ -		/* sample MSB (from slave) on leading edge */ -		ret = pb44_spi_rr(sp, SPI_REG_RDS); -		pb44_spi_wr(sp, SPI_REG_IOC, out); -#endif -	} - -#ifndef PER_BIT_READ -	ret = pb44_spi_rr(sp, SPI_REG_RDS); -#endif -	return ret; -} - -static int pb44_spi_probe(struct platform_device *pdev) -{ -	struct spi_master *master; -	struct ar71xx_spi *sp; -	struct ar71xx_spi_platform_data *pdata; -	struct resource	*r; -	int ret; - -	master = spi_alloc_master(&pdev->dev, sizeof(*sp)); -	if (master == NULL) { -		dev_err(&pdev->dev, "failed to allocate spi master\n"); -		return -ENOMEM; -	} - -	sp = spi_master_get_devdata(master); -	platform_set_drvdata(pdev, sp); - -	pdata = pdev->dev.platform_data; - -	master->setup = pb44_spi_setup; -	master->cleanup = pb44_spi_cleanup; -	if (pdata) { -		master->bus_num = pdata->bus_num; -		master->num_chipselect = pdata->num_chipselect; -	} else { -		master->bus_num = 0; -		master->num_chipselect = 1; -	} - -	sp->bitbang.master = spi_master_get(master); -	sp->bitbang.chipselect = pb44_spi_chipselect; -	sp->bitbang.txrx_word[SPI_MODE_0] = pb44_spi_txrx_mode0; -	sp->bitbang.setup_transfer = spi_bitbang_setup_transfer; -	sp->bitbang.flags = SPI_CS_HIGH; - -	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (r == NULL) { -		ret = -ENOENT; -		goto err1; -	} - -	sp->base = ioremap_nocache(r->start, r->end - r->start + 1); -	if (!sp->base) { -		ret = -ENXIO; -		goto err1; -	} - -	pb44_spi_enable(sp); - -	ret = spi_bitbang_start(&sp->bitbang); -	if (!ret) -		return 0; - -	pb44_spi_disable(sp); -	iounmap(sp->base); -err1: -	platform_set_drvdata(pdev, NULL); -	spi_master_put(sp->bitbang.master); - -	return ret; -} - -static int pb44_spi_remove(struct platform_device *pdev) -{ -	struct ar71xx_spi *sp = platform_get_drvdata(pdev); - -	spi_bitbang_stop(&sp->bitbang); -	pb44_spi_disable(sp); -	iounmap(sp->base); -	platform_set_drvdata(pdev, NULL); -	spi_master_put(sp->bitbang.master); - -	return 0; -} - -static void pb44_spi_shutdown(struct platform_device *pdev) -{ -	int ret; - -	ret = pb44_spi_remove(pdev); -	if (ret) -		dev_err(&pdev->dev, "shutdown failed with %d\n", ret); -} - -static struct platform_driver pb44_spi_drv = { -	.probe		= pb44_spi_probe, -	.remove		= pb44_spi_remove, -	.shutdown	= pb44_spi_shutdown, -	.driver		= { -		.name	= DRV_NAME, -		.owner	= THIS_MODULE, -	}, -}; - -static int __init pb44_spi_init(void) -{ -	return platform_driver_register(&pb44_spi_drv); -} -module_init(pb44_spi_init); - -static void __exit pb44_spi_exit(void) -{ -	platform_driver_unregister(&pb44_spi_drv); -} -module_exit(pb44_spi_exit); - -MODULE_ALIAS("platform:" DRV_NAME); -MODULE_DESCRIPTION(DRV_DESC); -MODULE_VERSION(DRV_VERSION); -MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); -MODULE_LICENSE("GPL v2"); diff --git a/target/linux/ar71xx/files/drivers/tty/serial/ar933x_uart.c b/target/linux/ar71xx/files/drivers/tty/serial/ar933x_uart.c deleted file mode 100644 index 6aca24f36..000000000 --- a/target/linux/ar71xx/files/drivers/tty/serial/ar933x_uart.c +++ /dev/null @@ -1,688 +0,0 @@ -/* - *  Atheros AR933X SoC built-in UART driver - * - *  Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> - * - *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. - * - *  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. - */ - -#include <linux/module.h> -#include <linux/ioport.h> -#include <linux/init.h> -#include <linux/console.h> -#include <linux/sysrq.h> -#include <linux/delay.h> -#include <linux/platform_device.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/serial_core.h> -#include <linux/serial.h> -#include <linux/slab.h> -#include <linux/io.h> -#include <linux/irq.h> - -#include <asm/mach-ar71xx/ar933x_uart.h> -#include <asm/mach-ar71xx/ar933x_uart_platform.h> - -#define DRIVER_NAME "ar933x-uart" - -#define AR933X_DUMMY_STATUS_RD	0x01 - -static struct uart_driver ar933x_uart_driver; - -struct ar933x_uart_port { -	struct uart_port	port; -	unsigned int		ier;	/* shadow Interrupt Enable Register */ -}; - -static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, -					    int offset) -{ -	return readl(up->port.membase + offset); -} - -static inline void ar933x_uart_write(struct ar933x_uart_port *up, -				     int offset, unsigned int value) -{ -	writel(value, up->port.membase + offset); -} - -static inline void ar933x_uart_rmw(struct ar933x_uart_port *up, -				  unsigned int offset, -				  unsigned int mask, -				  unsigned int val) -{ -	unsigned int t; - -	t = ar933x_uart_read(up, offset); -	t &= ~mask; -	t |= val; -	ar933x_uart_write(up, offset, t); -} - -static inline void ar933x_uart_rmw_set(struct ar933x_uart_port *up, -				       unsigned int offset, -				       unsigned int val) -{ -	ar933x_uart_rmw(up, offset, 0, val); -} - -static inline void ar933x_uart_rmw_clear(struct ar933x_uart_port *up, -					 unsigned int offset, -					 unsigned int val) -{ -	ar933x_uart_rmw(up, offset, val, 0); -} - -static inline void ar933x_uart_start_tx_interrupt(struct ar933x_uart_port *up) -{ -	up->ier |= AR933X_UART_INT_TX_EMPTY; -	ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); -} - -static inline void ar933x_uart_stop_tx_interrupt(struct ar933x_uart_port *up) -{ -	up->ier &= ~AR933X_UART_INT_TX_EMPTY; -	ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); -} - -static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch) -{ -	unsigned int rdata; - -	rdata = ch & AR933X_UART_DATA_TX_RX_MASK; -	rdata |= AR933X_UART_DATA_TX_CSR; -	ar933x_uart_write(up, AR933X_UART_DATA_REG, rdata); -} - -static unsigned int ar933x_uart_tx_empty(struct uart_port *port) -{ -	struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; -	unsigned long flags; -	unsigned int rdata; - -	spin_lock_irqsave(&up->port.lock, flags); -	rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG); -	spin_unlock_irqrestore(&up->port.lock, flags); - -	return (rdata & AR933X_UART_DATA_TX_CSR) ? 0 : TIOCSER_TEMT; -} - -static unsigned int ar933x_uart_get_mctrl(struct uart_port *port) -{ -	return TIOCM_CAR; -} - -static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ -} - -static void ar933x_uart_start_tx(struct uart_port *port) -{ -	struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; - -	ar933x_uart_start_tx_interrupt(up); -} - -static void ar933x_uart_stop_tx(struct uart_port *port) -{ -	struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; - -	ar933x_uart_stop_tx_interrupt(up); -} - -static void ar933x_uart_stop_rx(struct uart_port *port) -{ -	struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; - -	up->ier &= ~AR933X_UART_INT_RX_VALID; -	ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); -} - -static void ar933x_uart_break_ctl(struct uart_port *port, int break_state) -{ -	struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; -	unsigned long flags; - -	spin_lock_irqsave(&up->port.lock, flags); -	if (break_state == -1) -		ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, -				    AR933X_UART_CS_TX_BREAK); -	else -		ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG, -				      AR933X_UART_CS_TX_BREAK); -	spin_unlock_irqrestore(&up->port.lock, flags); -} - -static void ar933x_uart_enable_ms(struct uart_port *port) -{ -} - -static void ar933x_uart_set_termios(struct uart_port *port, -				    struct ktermios *new, -				    struct ktermios *old) -{ -	struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; -	unsigned int cs; -	unsigned long flags; -	unsigned int baud, scale; - -	/* Only CS8 is supported */ -	new->c_cflag &= ~CSIZE; -	new->c_cflag |= CS8; - -	/* Only one stop bit is supported */ -	new->c_cflag &= ~CSTOPB; - -	cs = 0; -	if (new->c_cflag & PARENB) { -		if (!(new->c_cflag & PARODD)) -			cs |= AR933X_UART_CS_PARITY_EVEN; -		else -			cs |= AR933X_UART_CS_PARITY_ODD; -	} else { -		cs |= AR933X_UART_CS_PARITY_NONE; -	} - -	/* Mark/space parity is not supported */ -	new->c_cflag &= ~CMSPAR; - -	baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); -	scale = (port->uartclk / (16 * baud)) - 1; - -	/* -	 * Ok, we're now changing the port state. Do it with -	 * interrupts disabled. -	 */ -	spin_lock_irqsave(&up->port.lock, flags); - -	/* Update the per-port timeout. */ -	uart_update_timeout(port, new->c_cflag, baud); - -	up->port.ignore_status_mask = 0; - -	/* ignore all characters if CREAD is not set */ -	if ((new->c_cflag & CREAD) == 0) -		up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD; - -	ar933x_uart_write(up, AR933X_UART_CLOCK_REG, -			  scale << AR933X_UART_CLOCK_SCALE_S | 8192); - -	/* setup configuration register */ -	ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs); - -	/* enable host interrupt */ -	ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, -			    AR933X_UART_CS_HOST_INT_EN); - -	spin_unlock_irqrestore(&up->port.lock, flags); - -	if (tty_termios_baud_rate(new)) -		tty_termios_encode_baud_rate(new, baud, baud); -} - -static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) -{ -	struct tty_struct *tty; -	int max_count = 256; - -	tty = tty_port_tty_get(&up->port.state->port); -	do { -		unsigned int rdata; -		unsigned char ch; - -		rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG); -		if ((rdata & AR933X_UART_DATA_RX_CSR) == 0) -			break; - -		/* remove the character from the FIFO */ -		ar933x_uart_write(up, AR933X_UART_DATA_REG, -				  AR933X_UART_DATA_RX_CSR); - -		if (!tty) { -			/* discard the data if no tty available */ -			continue; -		} - -		up->port.icount.rx++; -		ch = rdata & AR933X_UART_DATA_TX_RX_MASK; - -		if (uart_handle_sysrq_char(&up->port, ch)) -			continue; - -		if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0) -			tty_insert_flip_char(tty, ch, TTY_NORMAL); -	} while (max_count-- > 0); - -	if (tty) { -		tty_flip_buffer_push(tty); -		tty_kref_put(tty); -	} -} - -static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) -{ -	struct circ_buf *xmit = &up->port.state->xmit; -	int count; - -	if (uart_tx_stopped(&up->port)) -		return; - -	count = up->port.fifosize; -	do { -		unsigned int rdata; - -		rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG); -		if ((rdata & AR933X_UART_DATA_TX_CSR) == 0) -			break; - -		if (up->port.x_char) { -			ar933x_uart_putc(up, up->port.x_char); -			up->port.icount.tx++; -			up->port.x_char = 0; -			continue; -		} - -		if (uart_circ_empty(xmit)) -			break; - -		ar933x_uart_putc(up, xmit->buf[xmit->tail]); - -		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); -		up->port.icount.tx++; -	} while (--count > 0); - -	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) -		uart_write_wakeup(&up->port); - -	if (!uart_circ_empty(xmit)) -		ar933x_uart_start_tx_interrupt(up); -} - -static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id) -{ -	struct ar933x_uart_port *up = dev_id; -	unsigned int status; - -	status = ar933x_uart_read(up, AR933X_UART_CS_REG); -	if ((status & AR933X_UART_CS_HOST_INT) == 0) -		return IRQ_NONE; - -	spin_lock(&up->port.lock); - -	status = ar933x_uart_read(up, AR933X_UART_INT_REG); -	status &= ar933x_uart_read(up, AR933X_UART_INT_EN_REG); - -	if (status & AR933X_UART_INT_RX_VALID) { -		ar933x_uart_write(up, AR933X_UART_INT_REG, -				  AR933X_UART_INT_RX_VALID); -		ar933x_uart_rx_chars(up); -	} - -	if (status & AR933X_UART_INT_TX_EMPTY) { -		ar933x_uart_write(up, AR933X_UART_INT_REG, -				  AR933X_UART_INT_TX_EMPTY); -		ar933x_uart_stop_tx_interrupt(up); -		ar933x_uart_tx_chars(up); -	} - -	spin_unlock(&up->port.lock); - -	return IRQ_HANDLED; -} - -static int ar933x_uart_startup(struct uart_port *port) -{ -	struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; -	unsigned long flags; -	int ret; - -	ret = request_irq(up->port.irq, ar933x_uart_interrupt, -			  up->port.irqflags, dev_name(up->port.dev), up); -	if (ret) -		return ret; - -	spin_lock_irqsave(&up->port.lock, flags); - -	/* Enable HOST interrupts */ -	ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, -			    AR933X_UART_CS_HOST_INT_EN); - -	/* Enable RX interrupts */ -	up->ier = AR933X_UART_INT_RX_VALID; -	ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); - -	spin_unlock_irqrestore(&up->port.lock, flags); - -	return 0; -} - -static void ar933x_uart_shutdown(struct uart_port *port) -{ -	struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; - -	/* Disable all interrupts */ -	up->ier = 0; -	ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); - -	/* Disable break condition */ -	ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG, -			      AR933X_UART_CS_TX_BREAK); - -	free_irq(up->port.irq, up); -} - -static const char *ar933x_uart_type(struct uart_port *port) -{ -	return (port->type == PORT_AR933X) ? "AR933X UART" : NULL; -} - -static void ar933x_uart_release_port(struct uart_port *port) -{ -	/* Nothing to release ... */ -} - -static int ar933x_uart_request_port(struct uart_port *port) -{ -	/* UARTs always present */ -	return 0; -} - -static void ar933x_uart_config_port(struct uart_port *port, int flags) -{ -	if (flags & UART_CONFIG_TYPE) -		port->type = PORT_AR933X; -} - -static int ar933x_uart_verify_port(struct uart_port *port, -				   struct serial_struct *ser) -{ -	if (ser->type != PORT_UNKNOWN && -	    ser->type != PORT_AR933X) -		return -EINVAL; - -	if (ser->irq < 0 || ser->irq >= NR_IRQS) -		return -EINVAL; - -	if (ser->baud_base < 28800) -		return -EINVAL; - -	return 0; -} - -static struct uart_ops ar933x_uart_ops = { -	.tx_empty	= ar933x_uart_tx_empty, -	.set_mctrl	= ar933x_uart_set_mctrl, -	.get_mctrl	= ar933x_uart_get_mctrl, -	.stop_tx	= ar933x_uart_stop_tx, -	.start_tx	= ar933x_uart_start_tx, -	.stop_rx	= ar933x_uart_stop_rx, -	.enable_ms	= ar933x_uart_enable_ms, -	.break_ctl	= ar933x_uart_break_ctl, -	.startup	= ar933x_uart_startup, -	.shutdown	= ar933x_uart_shutdown, -	.set_termios	= ar933x_uart_set_termios, -	.type		= ar933x_uart_type, -	.release_port	= ar933x_uart_release_port, -	.request_port	= ar933x_uart_request_port, -	.config_port	= ar933x_uart_config_port, -	.verify_port	= ar933x_uart_verify_port, -}; - -#ifdef CONFIG_SERIAL_AR933X_CONSOLE - -static struct ar933x_uart_port * -ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS]; - -static void ar933x_uart_wait_xmitr(struct ar933x_uart_port *up) -{ -	unsigned int status; -	unsigned int timeout = 60000; - -	/* Wait up to 60ms for the character(s) to be sent. */ -	do { -		status = ar933x_uart_read(up, AR933X_UART_DATA_REG); -		if (--timeout == 0) -			break; -		udelay(1); -	} while ((status & AR933X_UART_DATA_TX_CSR) == 0); -} - -static void ar933x_uart_console_putchar(struct uart_port *port, int ch) -{ -	struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; - -	ar933x_uart_wait_xmitr(up); -	ar933x_uart_putc(up, ch); -} - -static void ar933x_uart_console_write(struct console *co, const char *s, -				      unsigned int count) -{ -	struct ar933x_uart_port *up = ar933x_console_ports[co->index]; -	unsigned long flags; -	unsigned int int_en; -	int locked = 1; - -	local_irq_save(flags); - -	if (up->port.sysrq) -		locked = 0; -	else if (oops_in_progress) -		locked = spin_trylock(&up->port.lock); -	else -		spin_lock(&up->port.lock); - -	/* -	 * First save the IER then disable the interrupts -	 */ -	int_en = ar933x_uart_read(up, AR933X_UART_INT_EN_REG); -	ar933x_uart_write(up, AR933X_UART_INT_EN_REG, 0); - -	uart_console_write(&up->port, s, count, ar933x_uart_console_putchar); - -	/* -	 * Finally, wait for transmitter to become empty -	 * and restore the IER -	 */ -	ar933x_uart_wait_xmitr(up); -	ar933x_uart_write(up, AR933X_UART_INT_EN_REG, int_en); - -	ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_ALLINTS); - -	if (locked) -		spin_unlock(&up->port.lock); - -	local_irq_restore(flags); -} - -static int ar933x_uart_console_setup(struct console *co, char *options) -{ -	struct ar933x_uart_port *up; -	int baud = 115200; -	int bits = 8; -	int parity = 'n'; -	int flow = 'n'; - -	if (co->index < 0 || co->index >= CONFIG_SERIAL_AR933X_NR_UARTS) -		return -EINVAL; - -	up = ar933x_console_ports[co->index]; -	if (!up) -		return -ENODEV; - -	if (options) -		uart_parse_options(options, &baud, &parity, &bits, &flow); - -	return uart_set_options(&up->port, co, baud, parity, bits, flow); -} - -static struct console ar933x_uart_console = { -	.name		= "ttyATH", -	.write		= ar933x_uart_console_write, -	.device		= uart_console_device, -	.setup		= ar933x_uart_console_setup, -	.flags		= CON_PRINTBUFFER, -	.index		= -1, -	.data		= &ar933x_uart_driver, -}; - -static void ar933x_uart_add_console_port(struct ar933x_uart_port *up) -{ -	ar933x_console_ports[up->port.line] = up; -} - -#define AR933X_SERIAL_CONSOLE	(&ar933x_uart_console) - -#else - -static inline void ar933x_uart_add_console_port(struct ar933x_uart_port *up) {} - -#define AR933X_SERIAL_CONSOLE	NULL - -#endif /* CONFIG_SERIAL_AR933X_CONSOLE */ - -static struct uart_driver ar933x_uart_driver = { -	.owner		= THIS_MODULE, -	.driver_name	= DRIVER_NAME, -	.dev_name	= "ttyATH", -	.nr		= CONFIG_SERIAL_AR933X_NR_UARTS, -	.cons		= AR933X_SERIAL_CONSOLE, -}; - -static int __devinit ar933x_uart_probe(struct platform_device *pdev) -{ -	struct ar933x_uart_platform_data *pdata; -	struct ar933x_uart_port *up; -	struct uart_port *port; -	struct resource *mem_res; -	struct resource *irq_res; -	int id; -	int ret; - -	pdata = pdev->dev.platform_data; -	if (!pdata) -		return -EINVAL; - -	id = pdev->id; -	if (id == -1) -		id = 0; - -	if (id > CONFIG_SERIAL_AR933X_NR_UARTS) -		return -EINVAL; - -	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!mem_res) { -		dev_err(&pdev->dev, "no MEM resource\n"); -		return -EINVAL; -	} - -	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -	if (!irq_res) { -		dev_err(&pdev->dev, "no IRQ resource\n"); -		return -EINVAL; -	} - -	up = kzalloc(sizeof(struct ar933x_uart_port), GFP_KERNEL); -	if (!up) -		return -ENOMEM; - -	port = &up->port; -	port->mapbase = mem_res->start; - -	port->membase = ioremap(mem_res->start, AR933X_UART_REGS_SIZE); -	if (!port->membase) { -		ret = -ENOMEM; -		goto err_free_up; -	} - -	port->line = id; -	port->irq = irq_res->start; -	port->dev = &pdev->dev; -	port->type = PORT_AR933X; -	port->iotype = UPIO_MEM32; -	port->uartclk = pdata->uartclk; - -	port->regshift = 2; -	port->fifosize = AR933X_UART_FIFO_SIZE; -	port->ops = &ar933x_uart_ops; - -	ar933x_uart_add_console_port(up); - -	ret = uart_add_one_port(&ar933x_uart_driver, &up->port); -	if (ret) -		goto err_unmap; - -	platform_set_drvdata(pdev, up); -	return 0; - -err_unmap: -	iounmap(up->port.membase); -err_free_up: -	kfree(up); -	return ret; -} - -static int __devexit ar933x_uart_remove(struct platform_device *pdev) -{ -	struct ar933x_uart_port *up; - -	up = platform_get_drvdata(pdev); -	platform_set_drvdata(pdev, NULL); - -	if (up) { -		uart_remove_one_port(&ar933x_uart_driver, &up->port); -		iounmap(up->port.membase); -		kfree(up); -	} - -	return 0; -} - -static struct platform_driver ar933x_uart_platform_driver = { -	.probe		= ar933x_uart_probe, -	.remove		= __devexit_p(ar933x_uart_remove), -	.driver		= { -		.name		= DRIVER_NAME, -		.owner		= THIS_MODULE, -	}, -}; - -static int __init ar933x_uart_init(void) -{ -	int ret; - -	ar933x_uart_driver.nr = CONFIG_SERIAL_AR933X_NR_UARTS; -	ret = uart_register_driver(&ar933x_uart_driver); -	if (ret) -		goto err_out; - -	ret = platform_driver_register(&ar933x_uart_platform_driver); -	if (ret) -		goto err_unregister_uart_driver; - -	return 0; - -err_unregister_uart_driver: -	uart_unregister_driver(&ar933x_uart_driver); -err_out: -	return ret; -} - -static void __exit ar933x_uart_exit(void) -{ -	platform_driver_unregister(&ar933x_uart_platform_driver); -	uart_unregister_driver(&ar933x_uart_driver); -} - -module_init(ar933x_uart_init); -module_exit(ar933x_uart_exit); - -MODULE_DESCRIPTION("Atheros AR933X UART driver"); -MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/target/linux/ar71xx/files/drivers/usb/host/ehci-ar71xx.c b/target/linux/ar71xx/files/drivers/usb/host/ehci-ar71xx.c deleted file mode 100644 index b08db5baf..000000000 --- a/target/linux/ar71xx/files/drivers/usb/host/ehci-ar71xx.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - *  Bus Glue for Atheros AR71xx built-in EHCI controller. - * - *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> - * - *  Parts of this file are based on Atheros' 2.6.15 BSP - *	Copyright (C) 2007 Atheros Communications, Inc. - * - *  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. - */ - -#include <linux/platform_device.h> -#include <linux/delay.h> - -#include <asm/mach-ar71xx/platform.h> - -extern int usb_disabled(void); - -static int ehci_ar71xx_init(struct usb_hcd *hcd) -{ -	struct ehci_hcd *ehci = hcd_to_ehci(hcd); -	int ret; - -	ehci->caps = hcd->regs; -	ehci->regs = hcd->regs + -			HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); -	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); - -	ehci->sbrn = 0x20; -	ehci->has_synopsys_hc_bug = 1; - -	ehci_reset(ehci); - -	ret = ehci_init(hcd); -	if (ret) -		return ret; - -	ehci_port_power(ehci, 0); - -	return 0; -} - -static int ehci_ar91xx_init(struct usb_hcd *hcd) -{ -	struct ehci_hcd *ehci = hcd_to_ehci(hcd); -	int ret; - -	ehci->caps = hcd->regs + 0x100; -	ehci->regs = hcd->regs + 0x100 + -			HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); -	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); - -	hcd->has_tt = 1; -	ehci->sbrn = 0x20; - -	ehci_reset(ehci); - -	ret = ehci_init(hcd); -	if (ret) -		return ret; - -	ehci_port_power(ehci, 0); - -	return 0; -} - -static int ehci_ar71xx_probe(const struct hc_driver *driver, -			     struct usb_hcd **hcd_out, -			     struct platform_device *pdev) -{ -	struct usb_hcd *hcd; -	struct resource *res; -	int irq; -	int ret; - -	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -	if (!res) { -		dev_dbg(&pdev->dev, "no IRQ specified for %s\n", -			dev_name(&pdev->dev)); -		return -ENODEV; -	} -	irq = res->start; - -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_dbg(&pdev->dev, "no base address specified for %s\n", -			dev_name(&pdev->dev)); -		return -ENODEV; -	} - -	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); -	if (!hcd) -		return -ENOMEM; - -	hcd->rsrc_start	= res->start; -	hcd->rsrc_len	= res->end - res->start + 1; - -	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { -		dev_dbg(&pdev->dev, "controller already in use\n"); -		ret = -EBUSY; -		goto err_put_hcd; -	} - -	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); -	if (!hcd->regs) { -		dev_dbg(&pdev->dev, "error mapping memory\n"); -		ret = -EFAULT; -		goto err_release_region; -	} - -	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); -	if (ret) -		goto err_iounmap; - -	return 0; - -err_iounmap: -	iounmap(hcd->regs); - -err_release_region: -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err_put_hcd: -	usb_put_hcd(hcd); -	return ret; -} - -static void ehci_ar71xx_remove(struct usb_hcd *hcd, -			       struct platform_device *pdev) -{ -	usb_remove_hcd(hcd); -	iounmap(hcd->regs); -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -	usb_put_hcd(hcd); -} - -static const struct hc_driver ehci_ar71xx_hc_driver = { -	.description		= hcd_name, -	.product_desc		= "Atheros AR71xx built-in EHCI controller", -	.hcd_priv_size		= sizeof(struct ehci_hcd), - -	.irq			= ehci_irq, -	.flags			= HCD_MEMORY | HCD_USB2, - -	.reset			= ehci_ar71xx_init, -	.start			= ehci_run, -	.stop			= ehci_stop, -	.shutdown		= ehci_shutdown, - -	.urb_enqueue		= ehci_urb_enqueue, -	.urb_dequeue		= ehci_urb_dequeue, -	.endpoint_disable	= ehci_endpoint_disable, -	.endpoint_reset		= ehci_endpoint_reset, - -	.get_frame_number	= ehci_get_frame, - -	.hub_status_data	= ehci_hub_status_data, -	.hub_control		= ehci_hub_control, -#ifdef CONFIG_PM -	.hub_suspend		= ehci_hub_suspend, -	.hub_resume		= ehci_hub_resume, -#endif -	.relinquish_port	= ehci_relinquish_port, -	.port_handed_over	= ehci_port_handed_over, - -	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static const struct hc_driver ehci_ar91xx_hc_driver = { -	.description		= hcd_name, -	.product_desc		= "Atheros AR91xx built-in EHCI controller", -	.hcd_priv_size		= sizeof(struct ehci_hcd), -	.irq			= ehci_irq, -	.flags			= HCD_MEMORY | HCD_USB2, - -	.reset			= ehci_ar91xx_init, -	.start			= ehci_run, -	.stop			= ehci_stop, -	.shutdown		= ehci_shutdown, - -	.urb_enqueue		= ehci_urb_enqueue, -	.urb_dequeue		= ehci_urb_dequeue, -	.endpoint_disable	= ehci_endpoint_disable, -	.endpoint_reset		= ehci_endpoint_reset, - -	.get_frame_number	= ehci_get_frame, - -	.hub_status_data	= ehci_hub_status_data, -	.hub_control		= ehci_hub_control, -#ifdef CONFIG_PM -	.hub_suspend		= ehci_hub_suspend, -	.hub_resume		= ehci_hub_resume, -#endif -	.relinquish_port	= ehci_relinquish_port, -	.port_handed_over	= ehci_port_handed_over, - -	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static int ehci_ar71xx_driver_probe(struct platform_device *pdev) -{ -	struct ar71xx_ehci_platform_data *pdata; -	struct usb_hcd *hcd = NULL; -	int ret; - -	if (usb_disabled()) -		return -ENODEV; - -	pdata = pdev->dev.platform_data; -	if (!pdata) { -		dev_err(&pdev->dev, "no platform data specified for %s\n", -			dev_name(&pdev->dev)); -		return -ENODEV; -	} - -	if (pdata->is_ar91xx) -		ret = ehci_ar71xx_probe(&ehci_ar91xx_hc_driver, &hcd, pdev); -	else -		ret = ehci_ar71xx_probe(&ehci_ar71xx_hc_driver, &hcd, pdev); - -	return ret; -} - -static int ehci_ar71xx_driver_remove(struct platform_device *pdev) -{ -	struct usb_hcd *hcd = platform_get_drvdata(pdev); - -	ehci_ar71xx_remove(hcd, pdev); -	return 0; -} - -MODULE_ALIAS("platform:ar71xx-ehci"); - -static struct platform_driver ehci_ar71xx_driver = { -	.probe		= ehci_ar71xx_driver_probe, -	.remove		= ehci_ar71xx_driver_remove, -	.driver = { -		.name	= "ar71xx-ehci", -	} -}; diff --git a/target/linux/ar71xx/files/drivers/usb/host/ohci-ar71xx.c b/target/linux/ar71xx/files/drivers/usb/host/ohci-ar71xx.c deleted file mode 100644 index 1ab33f3bf..000000000 --- a/target/linux/ar71xx/files/drivers/usb/host/ohci-ar71xx.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - *  OHCI HCD (Host Controller Driver) for USB. - * - *  Bus Glue for Atheros AR71xx built-in OHCI controller. - * - *  Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org> - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> - * - *  Parts of this file are based on Atheros' 2.6.15 BSP - *	Copyright (C) 2007 Atheros Communications, Inc. - * - *  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. - */ - -#include <linux/platform_device.h> -#include <linux/delay.h> - -extern int usb_disabled(void); - -static int usb_hcd_ar71xx_probe(const struct hc_driver *driver, -				struct platform_device *pdev) -{ -	struct usb_hcd *hcd; -	struct resource *res; -	int irq; -	int ret; - -	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -	if (!res) { -		dev_dbg(&pdev->dev, "no IRQ specified for %s\n", -			dev_name(&pdev->dev)); -		return -ENODEV; -	} -	irq = res->start; - -	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); -	if (!hcd) -		return -ENOMEM; - -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_dbg(&pdev->dev, "no base address specified for %s\n", -			dev_name(&pdev->dev)); -		ret = -ENODEV; -		goto err_put_hcd; -	} -	hcd->rsrc_start	= res->start; -	hcd->rsrc_len	= res->end - res->start + 1; - -	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { -		dev_dbg(&pdev->dev, "controller already in use\n"); -		ret = -EBUSY; -		goto err_put_hcd; -	} - -	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); -	if (!hcd->regs) { -		dev_dbg(&pdev->dev, "error mapping memory\n"); -		ret = -EFAULT; -		goto err_release_region; -	} - -	ohci_hcd_init(hcd_to_ohci(hcd)); - -	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); -	if (ret) -		goto err_stop_hcd; - -	return 0; - -err_stop_hcd: -	iounmap(hcd->regs); -err_release_region: -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err_put_hcd: -	usb_put_hcd(hcd); -	return ret; -} - -void usb_hcd_ar71xx_remove(struct usb_hcd *hcd, struct platform_device *pdev) -{ -	usb_remove_hcd(hcd); -	iounmap(hcd->regs); -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -	usb_put_hcd(hcd); -} - -static int __devinit ohci_ar71xx_start(struct usb_hcd *hcd) -{ -	struct ohci_hcd	*ohci = hcd_to_ohci(hcd); -	int ret; - -	ret = ohci_init(ohci); -	if (ret < 0) -		return ret; - -	ret = ohci_run(ohci); -	if (ret < 0) -		goto err; - -	return 0; - -err: -	ohci_stop(hcd); -	return ret; -} - -static const struct hc_driver ohci_ar71xx_hc_driver = { -	.description		= hcd_name, -	.product_desc		= "Atheros AR71xx built-in OHCI controller", -	.hcd_priv_size		= sizeof(struct ohci_hcd), - -	.irq			= ohci_irq, -	.flags			= HCD_USB11 | HCD_MEMORY, - -	.start			= ohci_ar71xx_start, -	.stop			= ohci_stop, -	.shutdown		= ohci_shutdown, - -	.urb_enqueue		= ohci_urb_enqueue, -	.urb_dequeue		= ohci_urb_dequeue, -	.endpoint_disable	= ohci_endpoint_disable, - -	/* -	 * scheduling support -	 */ -	.get_frame_number	= ohci_get_frame, - -	/* -	 * root hub support -	 */ -	.hub_status_data	= ohci_hub_status_data, -	.hub_control		= ohci_hub_control, -	.start_port_reset	= ohci_start_port_reset, -}; - -static int ohci_hcd_ar71xx_drv_probe(struct platform_device *pdev) -{ -	if (usb_disabled()) -		return -ENODEV; - -	return usb_hcd_ar71xx_probe(&ohci_ar71xx_hc_driver, pdev); -} - -static int ohci_hcd_ar71xx_drv_remove(struct platform_device *pdev) -{ -	struct usb_hcd *hcd = platform_get_drvdata(pdev); - -	usb_hcd_ar71xx_remove(hcd, pdev); -	return 0; -} - -MODULE_ALIAS("platform:ar71xx-ohci"); - -static struct platform_driver ohci_hcd_ar71xx_driver = { -	.probe		= ohci_hcd_ar71xx_drv_probe, -	.remove		= ohci_hcd_ar71xx_drv_remove, -	.shutdown	= usb_hcd_platform_shutdown, -	.driver		= { -		.name	= "ar71xx-ohci", -		.owner	= THIS_MODULE, -	}, -}; diff --git a/target/linux/ar71xx/files/drivers/watchdog/ar71xx_wdt.c b/target/linux/ar71xx/files/drivers/watchdog/ar71xx_wdt.c deleted file mode 100644 index d5e1f8a3c..000000000 --- a/target/linux/ar71xx/files/drivers/watchdog/ar71xx_wdt.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Driver for the Atheros AR71xx SoC's built-in hardware watchdog timer. - * - * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> - * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org> - * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> - * - * Parts of this file are based on Atheros 2.6.31 BSP - * - * This driver was based on: drivers/watchdog/ixp4xx_wdt.c - *	Author: Deepak Saxena <dsaxena@plexity.net> - *	Copyright 2004 (c) MontaVista, Software, Inc. - * - * which again was based on sa1100 driver, - *	Copyright (C) 2000 Oleg Drokin <green@crimea.edu> - * - * 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. - * - */ - -#include <linux/bitops.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/miscdevice.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/platform_device.h> -#include <linux/types.h> -#include <linux/watchdog.h> -#include <linux/delay.h> - -#include <asm/mach-ar71xx/ar71xx.h> - -#define DRV_NAME	"ar71xx-wdt" -#define DRV_DESC	"Atheros AR71xx hardware watchdog driver" -#define DRV_VERSION	"0.1.0" - -#define WDT_TIMEOUT	15	/* seconds */ - -static int nowayout = WATCHDOG_NOWAYOUT; - -#ifdef CONFIG_WATCHDOG_NOWAYOUT -module_param(nowayout, int, 0); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " -			   "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -#endif - -static unsigned long wdt_flags; - -#define WDT_FLAGS_BUSY		0 -#define WDT_FLAGS_EXPECT_CLOSE	1 - -static int wdt_timeout = WDT_TIMEOUT; -static int boot_status; -static int max_timeout; -static u32 wdt_clk_freq; - -static inline void ar71xx_wdt_keepalive(void) -{ -	ar71xx_reset_wr(AR71XX_RESET_REG_WDOG, wdt_clk_freq * wdt_timeout); -} - -static inline void ar71xx_wdt_enable(void) -{ -	printk(KERN_DEBUG DRV_NAME ": enabling watchdog timer\n"); -	ar71xx_wdt_keepalive(); -	udelay(2); -	ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR); -} - -static inline void ar71xx_wdt_disable(void) -{ -	printk(KERN_DEBUG DRV_NAME ": disabling watchdog timer\n"); -	ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE); -} - -static int ar71xx_wdt_set_timeout(int val) -{ -	if (val < 1 || val > max_timeout) -		return -EINVAL; - -	wdt_timeout = val; -	ar71xx_wdt_keepalive(); - -	printk(KERN_DEBUG DRV_NAME ": timeout=%d secs\n", wdt_timeout); - -	return 0; -} - -static int ar71xx_wdt_open(struct inode *inode, struct file *file) -{ -	if (test_and_set_bit(WDT_FLAGS_BUSY, &wdt_flags)) -		return -EBUSY; - -	clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags); - -	ar71xx_wdt_enable(); - -	return nonseekable_open(inode, file); -} - -static int ar71xx_wdt_release(struct inode *inode, struct file *file) -{ -	if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags)) { -		ar71xx_wdt_disable(); -	} else { -		printk(KERN_CRIT DRV_NAME ": device closed unexpectedly, " -					"watchdog timer will not stop!\n"); -	} - -	clear_bit(WDT_FLAGS_BUSY, &wdt_flags); -	clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags); - -	return 0; -} - -static ssize_t ar71xx_wdt_write(struct file *file, const char *data, -				size_t len, loff_t *ppos) -{ -	if (len) { -		if (!nowayout) { -			size_t i; - -			clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags); - -			for (i = 0; i != len; i++) { -				char c; - -				if (get_user(c, data + i)) -					return -EFAULT; - -				if (c == 'V') -					set_bit(WDT_FLAGS_EXPECT_CLOSE, -						&wdt_flags); -			} -		} - -		ar71xx_wdt_keepalive(); -	} - -	return len; -} - -static struct watchdog_info ar71xx_wdt_info = { -	.options		= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | -				  WDIOF_MAGICCLOSE | WDIOF_CARDRESET, -	.firmware_version	= 0, -	.identity		= "AR71XX watchdog", -}; - -static long ar71xx_wdt_ioctl(struct file *file, -			    unsigned int cmd, unsigned long arg) -{ -	int t; -	int ret; - -	switch (cmd) { -	case WDIOC_GETSUPPORT: -		ret = copy_to_user((struct watchdog_info *)arg, -				   &ar71xx_wdt_info, -				   sizeof(ar71xx_wdt_info)) ? -EFAULT : 0; -		break; - -	case WDIOC_GETSTATUS: -		ret = put_user(0, (int *)arg) ? -EFAULT : 0; -		break; - -	case WDIOC_GETBOOTSTATUS: -		ret = put_user(boot_status, (int *)arg) ? -EFAULT : 0; -		break; - -	case WDIOC_KEEPALIVE: -		ar71xx_wdt_keepalive(); -		ret = 0; -		break; - -	case WDIOC_SETTIMEOUT: -		ret = get_user(t, (int *)arg) ? -EFAULT : 0; -		if (ret) -			break; - -		ret = ar71xx_wdt_set_timeout(t); -		if (ret) -			break; - -		/* fallthrough */ -	case WDIOC_GETTIMEOUT: -		ret = put_user(wdt_timeout, (int *)arg) ? -EFAULT : 0; -		break; - -	default: -		ret = -ENOTTY; -		break; -	} - -	return ret; -} - -static const struct file_operations ar71xx_wdt_fops = { -	.owner		= THIS_MODULE, -	.write		= ar71xx_wdt_write, -	.unlocked_ioctl	= ar71xx_wdt_ioctl, -	.open		= ar71xx_wdt_open, -	.release	= ar71xx_wdt_release, -}; - -static struct miscdevice ar71xx_wdt_miscdev = { -	.minor = WATCHDOG_MINOR, -	.name = "watchdog", -	.fops = &ar71xx_wdt_fops, -}; - -static int __devinit ar71xx_wdt_probe(struct platform_device *pdev) -{ -	int ret; - -	switch (ar71xx_soc) { -	case AR71XX_SOC_AR7130: -	case AR71XX_SOC_AR7141: -	case AR71XX_SOC_AR7161: -	case AR71XX_SOC_AR7240: -	case AR71XX_SOC_AR7241: -	case AR71XX_SOC_AR7242: -	case AR71XX_SOC_AR9130: -	case AR71XX_SOC_AR9132: -		wdt_clk_freq = ar71xx_ahb_freq; -		break; - -	case AR71XX_SOC_AR9330: -	case AR71XX_SOC_AR9331: -	case AR71XX_SOC_AR9341: -	case AR71XX_SOC_AR9342: -	case AR71XX_SOC_AR9344: -		wdt_clk_freq = ar71xx_ref_freq; -		break; - -	default: -		BUG(); -	} - -	max_timeout = (0xfffffffful / wdt_clk_freq); -	wdt_timeout = (max_timeout < WDT_TIMEOUT) ? max_timeout : WDT_TIMEOUT; - -	if (ar71xx_reset_rr(AR71XX_RESET_REG_WDOG_CTRL) & WDOG_CTRL_LAST_RESET) -		boot_status = WDIOF_CARDRESET; - -	ret = misc_register(&ar71xx_wdt_miscdev); -	if (ret) -		goto err_out; - -	printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); - -	printk(KERN_DEBUG DRV_NAME ": timeout=%d secs (max=%d)\n", -					wdt_timeout, max_timeout); - -	return 0; - -err_out: -	return ret; -} - -static int __devexit ar71xx_wdt_remove(struct platform_device *pdev) -{ -	misc_deregister(&ar71xx_wdt_miscdev); -	return 0; -} - -static void ar71xx_wdt_shutdown(struct platform_device *pdev) -{ -	ar71xx_wdt_disable(); -} - -static struct platform_driver ar71xx_wdt_driver = { -	.probe		= ar71xx_wdt_probe, -	.remove		= __devexit_p(ar71xx_wdt_remove), -	.shutdown	= ar71xx_wdt_shutdown, -	.driver		= { -		.name	= DRV_NAME, -		.owner	= THIS_MODULE, -	}, -}; - -static int __init ar71xx_wdt_init(void) -{ -	return platform_driver_register(&ar71xx_wdt_driver); -} -module_init(ar71xx_wdt_init); - -static void __exit ar71xx_wdt_exit(void) -{ -	platform_driver_unregister(&ar71xx_wdt_driver); -} -module_exit(ar71xx_wdt_exit); - -MODULE_DESCRIPTION(DRV_DESC); -MODULE_VERSION(DRV_VERSION); -MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org"); -MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:" DRV_NAME); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);  | 
