Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/atm/nicstarmac.c
26278 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* this file included by nicstar.c
4
*/
5
6
/*
7
* nicstarmac.c
8
* Read this ForeRunner's MAC address from eprom/eeprom
9
*/
10
11
#include <linux/kernel.h>
12
13
typedef void __iomem *virt_addr_t;
14
15
#define CYCLE_DELAY 5
16
17
#define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
18
udelay((useconds));}
19
/*
20
* The following tables represent the timing diagrams found in
21
* the Data Sheet for the Xicor X25020 EEProm. The #defines below
22
* represent the bits in the NICStAR's General Purpose register
23
* that must be toggled for the corresponding actions on the EEProm
24
* to occur.
25
*/
26
27
/* Write Data To EEProm from SI line on rising edge of CLK */
28
/* Read Data From EEProm on falling edge of CLK */
29
30
#define CS_HIGH 0x0002 /* Chip select high */
31
#define CS_LOW 0x0000 /* Chip select low (active low) */
32
#define CLK_HIGH 0x0004 /* Clock high */
33
#define CLK_LOW 0x0000 /* Clock low */
34
#define SI_HIGH 0x0001 /* Serial input data high */
35
#define SI_LOW 0x0000 /* Serial input data low */
36
37
/* Read Status Register = 0000 0101b */
38
#if 0
39
static u_int32_t rdsrtab[] = {
40
CS_HIGH | CLK_HIGH,
41
CS_LOW | CLK_LOW,
42
CLK_HIGH, /* 0 */
43
CLK_LOW,
44
CLK_HIGH, /* 0 */
45
CLK_LOW,
46
CLK_HIGH, /* 0 */
47
CLK_LOW,
48
CLK_HIGH, /* 0 */
49
CLK_LOW,
50
CLK_HIGH, /* 0 */
51
CLK_LOW | SI_HIGH,
52
CLK_HIGH | SI_HIGH, /* 1 */
53
CLK_LOW | SI_LOW,
54
CLK_HIGH, /* 0 */
55
CLK_LOW | SI_HIGH,
56
CLK_HIGH | SI_HIGH /* 1 */
57
};
58
#endif /* 0 */
59
60
/* Read from EEPROM = 0000 0011b */
61
static u_int32_t readtab[] = {
62
/*
63
CS_HIGH | CLK_HIGH,
64
*/
65
CS_LOW | CLK_LOW,
66
CLK_HIGH, /* 0 */
67
CLK_LOW,
68
CLK_HIGH, /* 0 */
69
CLK_LOW,
70
CLK_HIGH, /* 0 */
71
CLK_LOW,
72
CLK_HIGH, /* 0 */
73
CLK_LOW,
74
CLK_HIGH, /* 0 */
75
CLK_LOW,
76
CLK_HIGH, /* 0 */
77
CLK_LOW | SI_HIGH,
78
CLK_HIGH | SI_HIGH, /* 1 */
79
CLK_LOW | SI_HIGH,
80
CLK_HIGH | SI_HIGH /* 1 */
81
};
82
83
/* Clock to read from/write to the eeprom */
84
static u_int32_t clocktab[] = {
85
CLK_LOW,
86
CLK_HIGH,
87
CLK_LOW,
88
CLK_HIGH,
89
CLK_LOW,
90
CLK_HIGH,
91
CLK_LOW,
92
CLK_HIGH,
93
CLK_LOW,
94
CLK_HIGH,
95
CLK_LOW,
96
CLK_HIGH,
97
CLK_LOW,
98
CLK_HIGH,
99
CLK_LOW,
100
CLK_HIGH,
101
CLK_LOW
102
};
103
104
#define NICSTAR_REG_WRITE(bs, reg, val) \
105
while ( readl(bs + STAT) & 0x0200 ) ; \
106
writel((val),(base)+(reg))
107
#define NICSTAR_REG_READ(bs, reg) \
108
readl((base)+(reg))
109
#define NICSTAR_REG_GENERAL_PURPOSE GP
110
111
/*
112
* This routine will clock the Read_Status_reg function into the X2520
113
* eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose
114
* register.
115
*/
116
#if 0
117
u_int32_t nicstar_read_eprom_status(virt_addr_t base)
118
{
119
u_int32_t val;
120
u_int32_t rbyte;
121
int32_t i, j;
122
123
/* Send read instruction */
124
val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
125
126
for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) {
127
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
128
(val | rdsrtab[i]));
129
osp_MicroDelay(CYCLE_DELAY);
130
}
131
132
/* Done sending instruction - now pull data off of bit 16, MSB first */
133
/* Data clocked out of eeprom on falling edge of clock */
134
135
rbyte = 0;
136
for (i = 7, j = 0; i >= 0; i--) {
137
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
138
(val | clocktab[j++]));
139
rbyte |= (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
140
& 0x00010000) >> 16) << i);
141
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
142
(val | clocktab[j++]));
143
osp_MicroDelay(CYCLE_DELAY);
144
}
145
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
146
osp_MicroDelay(CYCLE_DELAY);
147
return rbyte;
148
}
149
#endif /* 0 */
150
151
/*
152
* This routine will clock the Read_data function into the X2520
153
* eeprom, followed by the address to read from, through the NicSTaR's General
154
* Purpose register.
155
*/
156
157
static u_int8_t read_eprom_byte(virt_addr_t base, u_int8_t offset)
158
{
159
u_int32_t val = 0;
160
int i, j = 0;
161
u_int8_t tempread = 0;
162
163
val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
164
165
/* Send READ instruction */
166
for (i = 0; i < ARRAY_SIZE(readtab); i++) {
167
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
168
(val | readtab[i]));
169
osp_MicroDelay(CYCLE_DELAY);
170
}
171
172
/* Next, we need to send the byte address to read from */
173
for (i = 7; i >= 0; i--) {
174
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
175
(val | clocktab[j++] | ((offset >> i) & 1)));
176
osp_MicroDelay(CYCLE_DELAY);
177
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
178
(val | clocktab[j++] | ((offset >> i) & 1)));
179
osp_MicroDelay(CYCLE_DELAY);
180
}
181
182
j = 0;
183
184
/* Now, we can read data from the eeprom by clocking it in */
185
for (i = 7; i >= 0; i--) {
186
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
187
(val | clocktab[j++]));
188
osp_MicroDelay(CYCLE_DELAY);
189
tempread |=
190
(((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
191
& 0x00010000) >> 16) << i);
192
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
193
(val | clocktab[j++]));
194
osp_MicroDelay(CYCLE_DELAY);
195
}
196
197
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
198
osp_MicroDelay(CYCLE_DELAY);
199
return tempread;
200
}
201
202
static void nicstar_init_eprom(virt_addr_t base)
203
{
204
u_int32_t val;
205
206
/*
207
* turn chip select off
208
*/
209
val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
210
211
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
212
(val | CS_HIGH | CLK_HIGH));
213
osp_MicroDelay(CYCLE_DELAY);
214
215
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
216
(val | CS_HIGH | CLK_LOW));
217
osp_MicroDelay(CYCLE_DELAY);
218
219
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
220
(val | CS_HIGH | CLK_HIGH));
221
osp_MicroDelay(CYCLE_DELAY);
222
223
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
224
(val | CS_HIGH | CLK_LOW));
225
osp_MicroDelay(CYCLE_DELAY);
226
}
227
228
/*
229
* This routine will be the interface to the ReadPromByte function
230
* above.
231
*/
232
233
static void
234
nicstar_read_eprom(virt_addr_t base,
235
u_int8_t prom_offset, u_int8_t * buffer, u_int32_t nbytes)
236
{
237
u_int i;
238
239
for (i = 0; i < nbytes; i++) {
240
buffer[i] = read_eprom_byte(base, prom_offset);
241
++prom_offset;
242
osp_MicroDelay(CYCLE_DELAY);
243
}
244
}
245
246