mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	MN10300: ASB2364: Add support for SMSC911X and SMC911X
Add support for SMSC911X and SMC911X for the ASB2364 unit. Signed-off-by: Akira Takeuchi <takeuchi.akr@jp.panasonic.com> Signed-off-by: Kiyoshi Owada <owada.kiyoshi@jp.panasonic.com> Signed-off-by: David Howells <dhowells@redhat.com> cc: steve.glendinning@smsc.com cc: netdev@vger.kernel.org
This commit is contained in:
		
							parent
							
								
									6044cf1d94
								
							
						
					
					
						commit
						62747cd27e
					
				
					 8 changed files with 256 additions and 3 deletions
				
			
		|  | @ -117,6 +117,7 @@ config MN10300_UNIT_ASB2305 | |||
| 
 | ||||
| config MN10300_UNIT_ASB2364 | ||||
| 	bool "ASB2364" | ||||
| 	select SMSC911X_ARCH_HOOKS if SMSC911X | ||||
| 
 | ||||
| endchoice | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										1
									
								
								arch/mn10300/include/asm/smsc911x.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								arch/mn10300/include/asm/smsc911x.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| #include <unit/smsc911x.h> | ||||
|  | @ -8,3 +8,5 @@ | |||
| # Note 2! The CFLAGS definitions are now in the main makefile...
 | ||||
| 
 | ||||
| obj-y   := unit-init.o leds.o irq-fpga.o | ||||
| 
 | ||||
| obj-$(CONFIG_SMSC911X) += smsc911x.o | ||||
|  |  | |||
							
								
								
									
										171
									
								
								arch/mn10300/unit-asb2364/include/unit/smsc911x.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								arch/mn10300/unit-asb2364/include/unit/smsc911x.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,171 @@ | |||
| /* Support for the SMSC911x NIC
 | ||||
|  * | ||||
|  * Copyright (C) 2006 Matsushita Electric Industrial Co., Ltd. | ||||
|  * All Rights Reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * as published by the Free Software Foundation; either version | ||||
|  * 2 of the License, or (at your option) any later version. | ||||
|  */ | ||||
| #ifndef _ASM_UNIT_SMSC911X_H | ||||
| #define _ASM_UNIT_SMSC911X_H | ||||
| 
 | ||||
| #include <linux/netdevice.h> | ||||
| #include <proc/irq.h> | ||||
| #include <unit/fpga-regs.h> | ||||
| 
 | ||||
| #define MN10300_USE_EXT_EEPROM | ||||
| 
 | ||||
| 
 | ||||
| #define SMSC911X_BASE		0xA8000000UL | ||||
| #define SMSC911X_BASE_END	0xA8000100UL | ||||
| #define SMSC911X_IRQ		FPGA_LAN_IRQ | ||||
| 
 | ||||
| /*
 | ||||
|  * Allow the FPGA to be initialised by the SMSC911x driver | ||||
|  */ | ||||
| #undef SMSC_INITIALIZE | ||||
| #define SMSC_INITIALIZE()					\ | ||||
| do {								\ | ||||
| 	/* release reset */					\ | ||||
| 	ASB2364_FPGA_REG_RESET_LAN = 0x0001;			\ | ||||
| 	SyncExBus();						\ | ||||
| } while (0) | ||||
| 
 | ||||
| #ifdef MN10300_USE_EXT_EEPROM | ||||
| #include <linux/delay.h> | ||||
| #include <unit/clock.h> | ||||
| 
 | ||||
| #define EEPROM_ADDRESS	0xA0 | ||||
| #define MAC_OFFSET	0x0008 | ||||
| #define USE_IIC_CH	0	/* 0 or 1 */ | ||||
| #define IIC_OFFSET	(0x80000 * USE_IIC_CH) | ||||
| #define IIC_DTRM	__SYSREG(0xd8400000 + IIC_OFFSET, u32) | ||||
| #define IIC_DREC	__SYSREG(0xd8400004 + IIC_OFFSET, u32) | ||||
| #define IIC_MYADD	__SYSREG(0xd8400008 + IIC_OFFSET, u32) | ||||
| #define IIC_CLK		__SYSREG(0xd840000c + IIC_OFFSET, u32) | ||||
| #define IIC_BRST	__SYSREG(0xd8400010 + IIC_OFFSET, u32) | ||||
| #define IIC_HOLD	__SYSREG(0xd8400014 + IIC_OFFSET, u32) | ||||
| #define IIC_BSTS	__SYSREG(0xd8400018 + IIC_OFFSET, u32) | ||||
| #define IIC_ICR		__SYSREG(0xd4000080 + 4 * USE_IIC_CH, u16) | ||||
| 
 | ||||
| #define IIC_CLK_PLS	((unsigned short)(MN10300_IOCLK / 100000 - 1)) | ||||
| #define IIC_CLK_LOW	((unsigned short)(IIC_CLK_PLS / 2)) | ||||
| 
 | ||||
| #define SYS_IIC_DTRM_Bit_STA	((unsigned short)0x0400) | ||||
| #define SYS_IIC_DTRM_Bit_STO	((unsigned short)0x0200) | ||||
| #define SYS_IIC_DTRM_Bit_ACK	((unsigned short)0x0100) | ||||
| #define SYS_IIC_DTRM_Bit_DATA	((unsigned short)0x00FF) | ||||
| 
 | ||||
| static inline void POLL_INT_REQ(volatile u16 *icr) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 	u16 tmp; | ||||
| 
 | ||||
| 	while (!(*icr & GxICR_REQUEST)) | ||||
| 		; | ||||
| 	flags = arch_local_cli_save(); | ||||
| 	tmp = *icr; | ||||
| 	*icr = (tmp & GxICR_LEVEL) | GxICR_DETECT; | ||||
| 	tmp = *icr; | ||||
| 	arch_local_irq_restore(flags); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Implement the SMSC911x hook for MAC address retrieval | ||||
|  */ | ||||
| #undef smsc_get_mac | ||||
| static inline int smsc_get_mac(struct net_device *dev) | ||||
| { | ||||
| 	unsigned char *mac_buf = dev->dev_addr; | ||||
| 	int i; | ||||
| 	unsigned short value; | ||||
| 	unsigned int data; | ||||
| 	int mac_length = 6; | ||||
| 	int check; | ||||
| 	u16 orig_gicr, tmp; | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	/* save original GnICR and clear GnICR.IE */ | ||||
| 	flags = arch_local_cli_save(); | ||||
| 	orig_gicr = IIC_ICR; | ||||
| 	IIC_ICR = orig_gicr & GxICR_LEVEL; | ||||
| 	tmp = IIC_ICR; | ||||
| 	arch_local_irq_restore(flags); | ||||
| 
 | ||||
| 	IIC_MYADD = 0x00000008; | ||||
| 	IIC_CLK = (IIC_CLK_LOW << 16) + (IIC_CLK_PLS); | ||||
| 	/* bus hung recovery */ | ||||
| 
 | ||||
| 	while (1) { | ||||
| 		check = 0; | ||||
| 		for (i = 0; i < 3; i++) { | ||||
| 			if ((IIC_BSTS & 0x00000003) == 0x00000003) | ||||
| 				check++; | ||||
| 			udelay(3); | ||||
| 		} | ||||
| 
 | ||||
| 		if (check == 3) { | ||||
| 			IIC_BRST = 0x00000003; | ||||
| 			break; | ||||
| 		} else { | ||||
| 			for (i = 0; i < 3; i++) { | ||||
| 				IIC_BRST = 0x00000002; | ||||
| 				udelay(8); | ||||
| 				IIC_BRST = 0x00000003; | ||||
| 				udelay(8); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	IIC_BRST = 0x00000002; | ||||
| 	IIC_BRST = 0x00000003; | ||||
| 
 | ||||
| 	value	=  SYS_IIC_DTRM_Bit_STA | SYS_IIC_DTRM_Bit_ACK; | ||||
| 	value	|= (((unsigned short)EEPROM_ADDRESS & SYS_IIC_DTRM_Bit_DATA) | | ||||
| 		    (unsigned short)0x0000); | ||||
| 	IIC_DTRM = value; | ||||
| 	POLL_INT_REQ(&IIC_ICR); | ||||
| 
 | ||||
| 	/** send offset of MAC address in EEPROM **/ | ||||
| 	IIC_DTRM = (unsigned char)((MAC_OFFSET & 0xFF00) >> 8); | ||||
| 	POLL_INT_REQ(&IIC_ICR); | ||||
| 
 | ||||
| 	IIC_DTRM = (unsigned char)(MAC_OFFSET & 0x00FF); | ||||
| 	POLL_INT_REQ(&IIC_ICR); | ||||
| 
 | ||||
| 	udelay(1000); | ||||
| 
 | ||||
| 	value	=  SYS_IIC_DTRM_Bit_STA; | ||||
| 	value	|= (((unsigned short)EEPROM_ADDRESS & SYS_IIC_DTRM_Bit_DATA) | | ||||
| 		    (unsigned short)0x0001); | ||||
| 	IIC_DTRM = value; | ||||
| 	POLL_INT_REQ(&IIC_ICR); | ||||
| 
 | ||||
| 	IIC_DTRM = 0x00000000; | ||||
| 	while (mac_length > 0) { | ||||
| 		POLL_INT_REQ(&IIC_ICR); | ||||
| 
 | ||||
| 		data = IIC_DREC; | ||||
| 		mac_length--; | ||||
| 		if (mac_length == 0) | ||||
| 			value = 0x00000300;	/* stop IIC bus */ | ||||
| 		else if (mac_length == 1) | ||||
| 			value = 0x00000100;	/* no ack */ | ||||
| 		else | ||||
| 			value = 0x00000000;	/* ack */ | ||||
| 		IIC_DTRM = value; | ||||
| 		*mac_buf++ = (unsigned char)(data & 0xff); | ||||
| 	} | ||||
| 
 | ||||
| 	/* restore GnICR.LV and GnICR.IE */ | ||||
| 	flags = arch_local_cli_save(); | ||||
| 	IIC_ICR = (orig_gicr & (GxICR_LEVEL | GxICR_ENABLE)); | ||||
| 	tmp = IIC_ICR; | ||||
| 	arch_local_irq_restore(flags); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| #endif /* MN10300_USE_EXT_EEPROM */ | ||||
| #endif /* _ASM_UNIT_SMSC911X_H */ | ||||
							
								
								
									
										58
									
								
								arch/mn10300/unit-asb2364/smsc911x.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								arch/mn10300/unit-asb2364/smsc911x.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,58 @@ | |||
| /* Specification for the SMSC911x NIC
 | ||||
|  * | ||||
|  * Copyright (C) 2006 Matsushita Electric Industrial Co., Ltd. | ||||
|  * All Rights Reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * as published by the Free Software Foundation; either version | ||||
|  * 2 of the License, or (at your option) any later version. | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/ioport.h> | ||||
| #include <linux/smsc911x.h> | ||||
| #include <unit/smsc911x.h> | ||||
| 
 | ||||
| static struct smsc911x_platform_config smsc911x_config = { | ||||
| 	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | ||||
| 	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN, | ||||
| 	.flags		= SMSC911X_USE_32BIT, | ||||
| }; | ||||
| 
 | ||||
| static struct resource smsc911x_resources[] = { | ||||
| 	[0] = { | ||||
| 		.start	= SMSC911X_BASE, | ||||
| 		.end	= SMSC911X_BASE_END, | ||||
| 		.flags	= IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	[1] = { | ||||
| 		.start	= SMSC911X_IRQ, | ||||
| 		.end	= SMSC911X_IRQ, | ||||
| 		.flags	= IORESOURCE_IRQ, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static struct platform_device smsc911x_device = { | ||||
| 	.name		= "smsc911x", | ||||
| 	.id		= 0, | ||||
| 	.num_resources	= ARRAY_SIZE(smsc911x_resources), | ||||
| 	.resource	= smsc911x_resources, | ||||
| 	.dev		= { | ||||
| 		.platform_data = &smsc911x_config, | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * add platform devices | ||||
|  */ | ||||
| static int __init unit_device_init(void) | ||||
| { | ||||
| 	platform_device_register(&smsc911x_device); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| device_initcall(unit_device_init); | ||||
|  | @ -1041,7 +1041,7 @@ config SMC911X | |||
| 	tristate "SMSC LAN911[5678] support" | ||||
| 	select CRC32 | ||||
| 	select MII | ||||
| 	depends on ARM || SUPERH | ||||
| 	depends on ARM || SUPERH || MN10300 | ||||
| 	help | ||||
| 	  This is a driver for SMSC's LAN911x series of Ethernet chipsets | ||||
| 	  including the new LAN9115, LAN9116, LAN9117, and LAN9118. | ||||
|  | @ -1055,7 +1055,7 @@ config SMC911X | |||
| 
 | ||||
| config SMSC911X | ||||
| 	tristate "SMSC LAN911x/LAN921x families embedded ethernet support" | ||||
| 	depends on ARM || SUPERH || BLACKFIN || MIPS | ||||
| 	depends on ARM || SUPERH || BLACKFIN || MIPS || MN10300 | ||||
| 	select CRC32 | ||||
| 	select MII | ||||
| 	select PHYLIB | ||||
|  | @ -1067,6 +1067,14 @@ config SMSC911X | |||
| 	  <file:Documentation/networking/net-modules.txt>. The module | ||||
| 	  will be called smsc911x. | ||||
| 
 | ||||
| config SMSC911X_ARCH_HOOKS | ||||
| 	def_bool n | ||||
| 	depends on SMSC911X | ||||
| 	help | ||||
| 	  If the arch enables this, it allows the arch to implement various | ||||
| 	  hooks for more comprehensive interrupt control and also to override | ||||
| 	  the source of the MAC address. | ||||
| 
 | ||||
| config NET_VENDOR_RACAL | ||||
| 	bool "Racal-Interlan (Micom) NI cards" | ||||
| 	depends on ISA | ||||
|  |  | |||
|  | @ -2075,7 +2075,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) | |||
| 	} else { | ||||
| 		/* Try reading mac address from device. if EEPROM is present
 | ||||
| 		 * it will already have been set */ | ||||
| 		smsc911x_read_mac_address(dev); | ||||
| 		smsc_get_mac(dev); | ||||
| 
 | ||||
| 		if (is_valid_ether_addr(dev->dev_addr)) { | ||||
| 			/* eeprom values are valid  so use them */ | ||||
|  | @ -2176,6 +2176,7 @@ static struct platform_driver smsc911x_driver = { | |||
| /* Entry point for loading the module */ | ||||
| static int __init smsc911x_init_module(void) | ||||
| { | ||||
| 	SMSC_INITIALIZE(); | ||||
| 	return platform_driver_register(&smsc911x_driver); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -394,4 +394,15 @@ | |||
| #define LPA_PAUSE_ALL			(LPA_PAUSE_CAP | \ | ||||
| 					 LPA_PAUSE_ASYM) | ||||
| 
 | ||||
| /*
 | ||||
|  * Provide hooks to let the arch add to the initialisation procedure | ||||
|  * and to override the source of the MAC address. | ||||
|  */ | ||||
| #define SMSC_INITIALIZE()		do {} while (0) | ||||
| #define smsc_get_mac(dev)		smsc911x_read_mac_address((dev)) | ||||
| 
 | ||||
| #ifdef CONFIG_SMSC911X_ARCH_HOOKS | ||||
| #include <asm/smsc911x.h> | ||||
| #endif | ||||
| 
 | ||||
| #endif				/* __SMSC911X_H__ */ | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Akira Takeuchi
						Akira Takeuchi