Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
smsc911x.h
Go to the documentation of this file.
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() \
30 do { \
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 
61 static 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;
73 }
74 
75 /*
76  * Implement the SMSC911x hook for MAC address retrieval
77  */
78 #undef smsc_get_mac
79 static 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;
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 
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 
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 */