clean
[linux-2.4.21-pre4.git] / drivers / net / ptifddi.c
1 /* $Id: ptifddi.c,v 1.1.1.1 2005/04/11 02:50:27 jack Exp $
2  * ptifddi.c: Network driver for Performance Technologies single-attach
3  *            and dual-attach FDDI sbus cards.
4  *
5  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
6  */
7
8 static char *version =
9         "ptifddi.c:v1.0 10/Dec/96 David S. Miller (davem@caipfs.rutgers.edu)\n";
10
11 #include <linux/string.h>
12 #include <linux/init.h>
13
14 #include "ptifddi.h"
15
16 #include "ptifddi_asm.h"
17
18 #ifdef MODULE
19 static struct ptifddi *root_pti_dev;
20 #endif
21
22 static inline void pti_reset(struct ptifddi *pp)
23 {
24         pp->reset = 1;
25 }
26
27 static inline void pti_unreset(struct ptifddi *pp)
28 {
29         pp->unreset = 1;
30 }
31
32 static inline void pti_load_code_base(struct dfddi_ram *rp, unsigned short addr)
33 {
34         rp->loader_addr = ((addr << 8) & 0xff00) | ((addr >> 8) & 0x00ff);
35 }
36
37 static inline void pti_clear_dpram(struct ptifddi *pp)
38 {
39         memset(pp->dpram, 0, DPRAM_SIZE);
40 }
41
42 #define CARD_TEST_TIMEOUT       100000
43
44 static inline int pti_card_test(struct ptifddi *pp)
45 {
46         struct dfddi_ram *rp    = pp->dpram;
47         unsigned char *code     = &rp->loader;
48         unsigned char *status   = (unsigned char *) rp;
49         int clicks              = CARD_TEST_TIMEOUT;
50
51         /* Clear it out. */
52         pti_clear_dpram(pp);
53
54         /* Load test data. */
55         for(i = 0; i < test_firmware_size; i++)
56                 code[i] = test_firmware[i];
57
58         /* Tell card where to execute the code. */
59         pti_load_code_base(pp, test_firmware_dev_addr);
60
61         /* Clear test run status in dpram. */
62         *status = 0;
63
64         /* Reset single attach state machine before the test. */
65         rp->reset = 1;
66
67         /* Unreset, to get the test code running. */
68         pti_unreset(pp);
69
70         /* Wait for dpram status to become 5, else fail if we time out. */
71         while(--clicks) {
72                 if(*status == 5) {
73                         pti_reset(pp);
74                         return 0;
75                 }
76                 udelay(20);
77         }
78         return 1;
79 }
80
81 static inline void pti_init_firmware_loader(struct ptifddi *pp)
82 {
83         struct dfddi_ram *rp = pp->dpram;
84         int i;
85
86         for(i = 0; i < firmware_loader_size; i++)
87                 rp->loader.loader_firmware[i] = firmware_loader[i];
88 }
89
90 static inline void pti_load_main_firmware(struct ptifddi *pp)
91 {
92         struct dfddi_ram *rp            = pp->dpram;
93         struct dpram_loader *lp         = &rp.loader;
94         int i;
95
96
97 }
98
99 static void pti_init_rings(struct ptifddi *pp, int from_irq)
100 {
101 }
102
103 static int pti_init(struct ptifddi *pp, int from_irq)
104 {
105 }
106
107 static void pti_is_not_so_happy(struct ptifddi *pp)
108 {
109 }
110
111 static inline void pti_tx(struct ptifddi *pp, struct net_device *dev)
112 {
113 }
114
115 static inline void myri_rx(struct ptifddi *pp, struct net_device *dev)
116 {
117 }
118
119 static void pti_interrupt(int irq, void *dev_id, struct pt_regs *regs)
120 {
121         struct net_device *dev          = (struct net_device *) dev_id;
122         struct ptifddi *pp              = (struct ptifddi *) dev->priv;
123
124 }
125
126 static int pti_open(struct net_device *dev)
127 {
128         struct ptifddi *pp = (struct ptifddi *) dev->priv;
129
130         return pti_init(pp, in_interrupt());
131 }
132
133 static int pti_close(struct net_device *dev)
134 {
135         struct ptifddi *pp = (struct ptifddi *) dev->priv;
136
137         return 0;
138 }
139
140 static int pti_start_xmit(struct sk_buff *skb, struct net_device *dev)
141 {
142         struct ptifddi *pp = (struct ptifddi *) dev->priv;
143 }
144
145 static struct net_device_stats *pti_get_stats(struct net_device *dev)
146 { return &(((struct ptifddi *)dev->priv)->enet_stats); }
147
148 static void pti_set_multicast(struct net_device *dev)
149 {
150 }
151
152 static inline int pti_fddi_init(struct net_device *dev, struct sbus_dev *sdev, int num)
153 {
154         static unsigned version_printed;
155         struct ptifddi *pp;
156         int i;
157
158         dev = init_fddidev(0, sizeof(struct ptifddi));
159
160         if(version_printed++ == 0)
161                 printk(version);
162
163         /* Register 0 mapping contains DPRAM. */
164         pp->dpram = (struct dfddi_ram *) sbus_ioremap(
165             &sdep->resource[0], 0, sizeof(sturct dfddi_ram), "PTI FDDI DPRAM");
166         if(!pp->dpram) {
167                 printk("ptiFDDI: Cannot map DPRAM I/O area.\n");
168                 return -ENODEV;
169         }
170
171         /* Next, register 1 contains reset byte. */
172         pp->reset = (unsigned char *) sbus_ioremap(
173             &sdep->resource[1], 0, 1, "PTI FDDI RESET Byte");
174         if(!pp->reset) {
175                 printk("ptiFDDI: Cannot map RESET byte.\n");
176                 return -ENODEV;
177         }
178
179         /* Register 2 contains unreset byte. */
180         pp->unreset = (unsigned char *) sbus_ioremap(
181             &sdep->resource[2], 0, 1, "PTI FDDI UNRESET Byte");
182         if(!pp->unreset) {
183                 printk("ptiFDDI: Cannot map UNRESET byte.\n");
184                 return -ENODEV;
185         }
186
187         /* Reset the card. */
188         pti_reset(pp);
189
190         /* Run boot-up card tests. */
191         i = pti_card_test(pp);
192         if(i) {
193                 printk("ptiFDDI: Bootup card test fails.\n");
194                 return -ENODEV;
195         }
196
197         /* Clear DPRAM, start afresh. */
198         pti_clear_dpram(pp);
199
200         /* Init the firmware loader. */
201         pti_init_firmware_loader(pp);
202
203         /* Now load main card FDDI firmware, using the loader. */
204         pti_load_main_firmware(pp);
205 }
206
207 int __init ptifddi_sbus_probe(struct net_device *dev)
208 {
209         struct sbus_bus *bus;
210         struct sbus_dev *sdev = 0;
211         static int called;
212         int cards = 0, v;
213
214         if(called)
215                 return -ENODEV;
216         called++;
217
218         for_each_sbus(bus) {
219                 for_each_sbusdev(sdev, bus) {
220                         if(cards) dev = NULL;
221                         if(!strcmp(sdev->prom_name, "PTI,sbs600") ||
222                            !strcmp(sdev->prom_name, "DPV,fddid")) {
223                                 cards++;
224                                 DET(("Found PTI FDDI as %s\n", sdev->prom_name));
225                                 if((v = pti_fddi_init(dev, sdev, (cards - 1))))
226                                         return v;
227                         }
228                 }
229         }
230         if(!cards)
231                 return -ENODEV;
232         return 0;
233 }
234
235
236 #ifdef MODULE
237
238 int
239 init_module(void)
240 {
241         root_pti_dev = NULL;
242         return ptifddi_sbus_probe(NULL);
243 }
244
245 void
246 cleanup_module(void)
247 {
248         struct ptifddi *pp;
249
250         /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
251         while (root_pti_dev) {
252                 pp = root_pti_dev->next_module;
253
254                 unregister_netdev(root_pti_dev->dev);
255                 kfree(root_pti_dev->dev);
256                 root_pti_dev = mp;
257         }
258 }
259
260 #endif /* MODULE */