1/* Support for the SMSC911x NIC 2 * 3 * Copyright (C) 2006 Matsushita Electric Industrial Co., Ltd. 4 * All Rights Reserved. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11#ifndef _ASM_UNIT_SMSC911X_H 12#define _ASM_UNIT_SMSC911X_H 13 14#include <linux/netdevice.h> 15#include <proc/irq.h> 16#include <unit/fpga-regs.h> 17 18#define MN10300_USE_EXT_EEPROM 19 20 21#define SMSC911X_BASE 0xA8000000UL 22#define SMSC911X_BASE_END 0xA8000100UL 23#define SMSC911X_IRQ FPGA_LAN_IRQ 24 25/* 26 * Allow the FPGA to be initialised by the SMSC911x driver 27 */ 28#undef SMSC_INITIALIZE 29#define SMSC_INITIALIZE() \ 30do { \ 31 /* release reset */ \ 32 ASB2364_FPGA_REG_RESET_LAN = 0x0001; \ 33 SyncExBus(); \ 34} while (0) 35 36#ifdef MN10300_USE_EXT_EEPROM 37#include <linux/delay.h> 38#include <unit/clock.h> 39 40#define EEPROM_ADDRESS 0xA0 41#define MAC_OFFSET 0x0008 42#define USE_IIC_CH 0 /* 0 or 1 */ 43#define IIC_OFFSET (0x80000 * USE_IIC_CH) 44#define IIC_DTRM __SYSREG(0xd8400000 + IIC_OFFSET, u32) 45#define IIC_DREC __SYSREG(0xd8400004 + IIC_OFFSET, u32) 46#define IIC_MYADD __SYSREG(0xd8400008 + IIC_OFFSET, u32) 47#define IIC_CLK __SYSREG(0xd840000c + IIC_OFFSET, u32) 48#define IIC_BRST __SYSREG(0xd8400010 + IIC_OFFSET, u32) 49#define IIC_HOLD __SYSREG(0xd8400014 + IIC_OFFSET, u32) 50#define IIC_BSTS __SYSREG(0xd8400018 + IIC_OFFSET, u32) 51#define IIC_ICR __SYSREG(0xd4000080 + 4 * USE_IIC_CH, u16) 52 53#define IIC_CLK_PLS ((unsigned short)(MN10300_IOCLK / 100000 - 1)) 54#define IIC_CLK_LOW ((unsigned short)(IIC_CLK_PLS / 2)) 55 56#define SYS_IIC_DTRM_Bit_STA ((unsigned short)0x0400) 57#define SYS_IIC_DTRM_Bit_STO ((unsigned short)0x0200) 58#define SYS_IIC_DTRM_Bit_ACK ((unsigned short)0x0100) 59#define SYS_IIC_DTRM_Bit_DATA ((unsigned short)0x00FF) 60 61static inline void POLL_INT_REQ(volatile u16 *icr) 62{ 63 unsigned long flags; 64 u16 tmp; 65 66 while (!(*icr & GxICR_REQUEST)) 67 ; 68 flags = arch_local_cli_save(); 69 tmp = *icr; 70 *icr = (tmp & GxICR_LEVEL) | GxICR_DETECT; 71 tmp = *icr; 72 arch_local_irq_restore(flags); 73} 74 75/* 76 * Implement the SMSC911x hook for MAC address retrieval 77 */ 78#undef smsc_get_mac 79static inline int smsc_get_mac(struct net_device *dev) 80{ 81 unsigned char *mac_buf = dev->dev_addr; 82 int i; 83 unsigned short value; 84 unsigned int data; 85 int mac_length = 6; 86 int check; 87 u16 orig_gicr, tmp; 88 unsigned long flags; 89 90 /* save original GnICR and clear GnICR.IE */ 91 flags = arch_local_cli_save(); 92 orig_gicr = IIC_ICR; 93 IIC_ICR = orig_gicr & GxICR_LEVEL; 94 tmp = IIC_ICR; 95 arch_local_irq_restore(flags); 96 97 IIC_MYADD = 0x00000008; 98 IIC_CLK = (IIC_CLK_LOW << 16) + (IIC_CLK_PLS); 99 /* bus hung recovery */ 100 101 while (1) { 102 check = 0; 103 for (i = 0; i < 3; i++) { 104 if ((IIC_BSTS & 0x00000003) == 0x00000003) 105 check++; 106 udelay(3); 107 } 108 109 if (check == 3) { 110 IIC_BRST = 0x00000003; 111 break; 112 } else { 113 for (i = 0; i < 3; i++) { 114 IIC_BRST = 0x00000002; 115 udelay(8); 116 IIC_BRST = 0x00000003; 117 udelay(8); 118 } 119 } 120 } 121 122 IIC_BRST = 0x00000002; 123 IIC_BRST = 0x00000003; 124 125 value = SYS_IIC_DTRM_Bit_STA | SYS_IIC_DTRM_Bit_ACK; 126 value |= (((unsigned short)EEPROM_ADDRESS & SYS_IIC_DTRM_Bit_DATA) | 127 (unsigned short)0x0000); 128 IIC_DTRM = value; 129 POLL_INT_REQ(&IIC_ICR); 130 131 /** send offset of MAC address in EEPROM **/ 132 IIC_DTRM = (unsigned char)((MAC_OFFSET & 0xFF00) >> 8); 133 POLL_INT_REQ(&IIC_ICR); 134 135 IIC_DTRM = (unsigned char)(MAC_OFFSET & 0x00FF); 136 POLL_INT_REQ(&IIC_ICR); 137 138 udelay(1000); 139 140 value = SYS_IIC_DTRM_Bit_STA; 141 value |= (((unsigned short)EEPROM_ADDRESS & SYS_IIC_DTRM_Bit_DATA) | 142 (unsigned short)0x0001); 143 IIC_DTRM = value; 144 POLL_INT_REQ(&IIC_ICR); 145 146 IIC_DTRM = 0x00000000; 147 while (mac_length > 0) { 148 POLL_INT_REQ(&IIC_ICR); 149 150 data = IIC_DREC; 151 mac_length--; 152 if (mac_length == 0) 153 value = 0x00000300; /* stop IIC bus */ 154 else if (mac_length == 1) 155 value = 0x00000100; /* no ack */ 156 else 157 value = 0x00000000; /* ack */ 158 IIC_DTRM = value; 159 *mac_buf++ = (unsigned char)(data & 0xff); 160 } 161 162 /* restore GnICR.LV and GnICR.IE */ 163 flags = arch_local_cli_save(); 164 IIC_ICR = (orig_gicr & (GxICR_LEVEL | GxICR_ENABLE)); 165 tmp = IIC_ICR; 166 arch_local_irq_restore(flags); 167 168 return 0; 169} 170#endif /* MN10300_USE_EXT_EEPROM */ 171#endif /* _ASM_UNIT_SMSC911X_H */ 172