This source file includes following definitions.
- hp_plus_probe
- hpp_probe1
- hpp_open
- hpp_close
- hpp_reset_8390
- hpp_io_block_input
- hpp_mem_block_input
- hpp_io_block_output
- hpp_mem_block_output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 static char *version =
22 "hp-plus.c:v1.10 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
23
24 #include <linux/string.h>
25 #include <linux/kernel.h>
26 #include <linux/sched.h>
27 #include <linux/errno.h>
28 #include <linux/ioport.h>
29 #include <linux/netdevice.h>
30 #include <linux/etherdevice.h>
31
32 #include <asm/system.h>
33 #include <asm/io.h>
34
35
36 #include "8390.h"
37 extern struct device *init_etherdev(struct device *dev, int sizeof_private,
38 unsigned long *mem_startp);
39
40
41 static unsigned int hpplus_portlist[] =
42 {0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 #define HP_ID 0x00
70 #define HP_PAGING 0x02
71 #define HPP_OPTION 0x04
72 #define HPP_OUT_ADDR 0x08
73 #define HPP_IN_ADDR 0x0A
74 #define HP_DATAPORT 0x0c
75 #define NIC_OFFSET 0x10
76 #define HP_IO_EXTENT 32
77
78 #define HP_START_PG 0x00
79 #define HP_STOP_PG 0x80
80
81
82 enum PageName {
83 Perf_Page = 0,
84 MAC_Page = 1,
85 HW_Page = 2,
86 LAN_Page = 4,
87 ID_Page = 6 };
88
89
90 enum HP_Option {
91 NICReset = 1, ChipReset = 2,
92 EnableIRQ = 4, FakeIntr = 8, BootROMEnb = 0x10, IOEnb = 0x20,
93 MemEnable = 0x40, ZeroWait = 0x80, MemDisable = 0x1000, };
94
95 int hpplus_probe(struct device *dev);
96 int hpp_probe1(struct device *dev, int ioaddr);
97
98 static void hpp_reset_8390(struct device *dev);
99 static int hpp_open(struct device *dev);
100 static int hpp_close(struct device *dev);
101 static int hpp_mem_block_input(struct device *dev, int count,
102 char *buf, int ring_offset);
103 static void hpp_mem_block_output(struct device *dev, int count,
104 const unsigned char *buf, const start_page);
105 static int hpp_io_block_input(struct device *dev, int count,
106 char *buf, int ring_offset);
107 static void hpp_io_block_output(struct device *dev, int count,
108 const unsigned char *buf, const start_page);
109
110
111
112
113 #ifdef HAVE_DEVLIST
114
115
116 struct netdev_entry hpplus_drv =
117 {"hpplus", hpp_probe1, HP_IO_EXTENT, hpplus_portlist};
118 #else
119
120 int hp_plus_probe(struct device *dev)
121 {
122 int i;
123 int base_addr = dev ? dev->base_addr : 0;
124
125 if (base_addr > 0x1ff)
126 return hpp_probe1(dev, base_addr);
127 else if (base_addr != 0)
128 return ENXIO;
129
130 for (i = 0; hpplus_portlist[i]; i++) {
131 int ioaddr = hpplus_portlist[i];
132 if (check_region(ioaddr, HP_IO_EXTENT))
133 continue;
134 if (hpp_probe1(dev, ioaddr) == 0)
135 return 0;
136 }
137
138 return ENODEV;
139 }
140 #endif
141
142
143 int hpp_probe1(struct device *dev, int ioaddr)
144 {
145 int i;
146 unsigned char checksum = 0;
147 char *name = "HP-PC-LAN+";
148 int mem_start;
149
150
151 if (inw(ioaddr + HP_ID) != 0x4850
152 || (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300)
153 return ENODEV;
154
155 if (dev == NULL)
156 dev = init_etherdev(0, sizeof(struct ei_device), 0);
157
158 printk("%s: %s at %#3x,", dev->name, name, ioaddr);
159
160
161 outw(MAC_Page, ioaddr + HP_PAGING);
162
163 for(i = 0; i < ETHER_ADDR_LEN; i++) {
164 unsigned char inval = inb(ioaddr + 8 + i);
165 dev->dev_addr[i] = inval;
166 checksum += inval;
167 printk(" %2.2x", inval);
168 }
169 checksum += inb(ioaddr + 14);
170
171 if (checksum != 0xff) {
172 printk(" bad checksum %2.2x.\n", checksum);
173 return ENODEV;
174 } else {
175
176 outw(ID_Page, ioaddr + HP_PAGING);
177 printk(" ID %4.4x", inw(ioaddr + 12));
178 }
179
180
181 request_region(ioaddr, HP_IO_EXTENT,"hp-plus");
182
183
184 outw(HW_Page, ioaddr + HP_PAGING);
185 {
186 int irq = inb(ioaddr + 13) & 0x0f;
187 int option = inw(ioaddr + HPP_OPTION);
188
189 dev->irq = irq;
190 if (option & MemEnable) {
191 mem_start = inw(ioaddr + 9) << 8;
192 printk(", IRQ %d, memory address %#x.\n", irq, mem_start);
193 } else {
194 mem_start = 0;
195 printk(", IRQ %d, programmed-I/O mode.\n", irq);
196 }
197 }
198
199 printk( "%s%s", KERN_INFO, version);
200
201
202 outw((HP_START_PG + TX_2X_PAGES) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
203
204
205 dev->base_addr = ioaddr + NIC_OFFSET;
206
207 ethdev_init(dev);
208
209 dev->open = &hpp_open;
210 dev->stop = &hpp_close;
211
212 ei_status.name = name;
213 ei_status.word16 = 0;
214 ei_status.tx_start_page = HP_START_PG;
215 ei_status.rx_start_page = HP_START_PG + TX_2X_PAGES;
216 ei_status.stop_page = HP_STOP_PG;
217
218 ei_status.reset_8390 = &hpp_reset_8390;
219 ei_status.block_input = &hpp_io_block_input;
220 ei_status.block_output = &hpp_io_block_output;
221
222
223 if (mem_start) {
224 ei_status.block_input = &hpp_mem_block_input;
225 ei_status.block_output = &hpp_mem_block_output;
226 dev->mem_start = mem_start;
227 dev->rmem_start = dev->mem_start + TX_2X_PAGES*256;
228 dev->mem_end = dev->rmem_end
229 = dev->mem_start + (HP_STOP_PG - HP_START_PG)*256;
230 }
231
232 outw(Perf_Page, ioaddr + HP_PAGING);
233 NS8390_init(dev, 0);
234
235 outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION);
236
237 return 0;
238 }
239
240 static int
241 hpp_open(struct device *dev)
242 {
243 int ioaddr = dev->base_addr - NIC_OFFSET;
244 int option_reg;
245
246 if (request_irq(dev->irq, &ei_interrupt, 0, "hp-plus")) {
247 return -EAGAIN;
248 }
249
250
251 option_reg = inw(ioaddr + HPP_OPTION);
252 outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
253 SLOW_DOWN_IO; SLOW_DOWN_IO;
254
255 outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
256
257
258 outw(HW_Page, ioaddr + HP_PAGING);
259 outw((HP_START_PG + TX_2X_PAGES) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
260
261
262 outw(Perf_Page, ioaddr + HP_PAGING);
263
264 return ei_open(dev);
265 }
266
267 static int
268 hpp_close(struct device *dev)
269 {
270 int ioaddr = dev->base_addr - NIC_OFFSET;
271 int option_reg = inw(ioaddr + HPP_OPTION);
272
273 free_irq(dev->irq);
274 irq2dev_map[dev->irq] = NULL;
275 NS8390_init(dev, 0);
276 outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset,
277 ioaddr + HPP_OPTION);
278
279 return 0;
280 }
281
282 static void
283 hpp_reset_8390(struct device *dev)
284 {
285 int ioaddr = dev->base_addr - NIC_OFFSET;
286 int option_reg = inw(ioaddr + HPP_OPTION);
287
288 if (ei_debug > 1) printk("resetting the 8390 time=%ld...", jiffies);
289
290 outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
291
292 SLOW_DOWN_IO;
293 SLOW_DOWN_IO;
294 ei_status.txing = 0;
295 outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
296
297 SLOW_DOWN_IO; SLOW_DOWN_IO;
298
299
300 if ((inb_p(ioaddr+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0)
301 printk("%s: hp_reset_8390() did not complete.\n", dev->name);
302
303 if (ei_debug > 1) printk("8390 reset done (%ld).", jiffies);
304 return;
305 }
306
307
308
309
310 static int
311 hpp_io_block_input(struct device *dev, int count, char *buf, int ring_offset)
312 {
313 int ioaddr = dev->base_addr - NIC_OFFSET;
314
315 outw(ring_offset, ioaddr + HPP_IN_ADDR);
316 insw(ioaddr + HP_DATAPORT, buf, count>>1);
317 if (count & 0x01)
318 buf[count-1] = inw(ioaddr + HP_DATAPORT);
319 return ring_offset + count;
320 }
321
322 static int
323 hpp_mem_block_input(struct device *dev, int count, char *buf, int ring_offset)
324 {
325 int ioaddr = dev->base_addr - NIC_OFFSET;
326 int option_reg = inw(ioaddr + HPP_OPTION);
327
328 outw(ring_offset, ioaddr + HPP_IN_ADDR);
329
330 outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
331
332 memcpy(buf, (char*)dev->mem_start, (count + 3) & ~3);
333 outw(option_reg, ioaddr + HPP_OPTION);
334
335 return ring_offset + count;
336 }
337
338
339
340 static void
341 hpp_io_block_output(struct device *dev, int count,
342 const unsigned char *buf, const start_page)
343 {
344 int ioaddr = dev->base_addr - NIC_OFFSET;
345 outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
346 outsl(ioaddr + HP_DATAPORT, buf, (count+3)>>2);
347 return;
348 }
349
350 static void
351 hpp_mem_block_output(struct device *dev, int count,
352 const unsigned char *buf, const start_page)
353 {
354 int ioaddr = dev->base_addr - NIC_OFFSET;
355 int option_reg = inw(ioaddr + HPP_OPTION);
356
357 outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
358 outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
359 memcpy((char *)dev->mem_start, buf, (count + 3) & ~3);
360 outw(option_reg, ioaddr + HPP_OPTION);
361
362 return;
363 }
364
365
366
367
368
369
370
371
372
373
374