1/* $Id: ptifddi.c,v 1.1.1.1 2008/10/15 03:26:38 james26_jang 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
8static 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
19static struct ptifddi *root_pti_dev;
20#endif
21
22static inline void pti_reset(struct ptifddi *pp)
23{
24	pp->reset = 1;
25}
26
27static inline void pti_unreset(struct ptifddi *pp)
28{
29	pp->unreset = 1;
30}
31
32static 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
37static 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
44static 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
81static 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
90static 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
99static void pti_init_rings(struct ptifddi *pp, int from_irq)
100{
101}
102
103static int pti_init(struct ptifddi *pp, int from_irq)
104{
105}
106
107static void pti_is_not_so_happy(struct ptifddi *pp)
108{
109}
110
111static inline void pti_tx(struct ptifddi *pp, struct net_device *dev)
112{
113}
114
115static inline void myri_rx(struct ptifddi *pp, struct net_device *dev)
116{
117}
118
119static 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
126static 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
133static int pti_close(struct net_device *dev)
134{
135	struct ptifddi *pp = (struct ptifddi *) dev->priv;
136
137	return 0;
138}
139
140static int pti_start_xmit(struct sk_buff *skb, struct net_device *dev)
141{
142	struct ptifddi *pp = (struct ptifddi *) dev->priv;
143}
144
145static struct net_device_stats *pti_get_stats(struct net_device *dev)
146{ return &(((struct ptifddi *)dev->priv)->enet_stats); }
147
148static void pti_set_multicast(struct net_device *dev)
149{
150}
151
152static 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
207int __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
238int
239init_module(void)
240{
241	root_pti_dev = NULL;
242	return ptifddi_sbus_probe(NULL);
243}
244
245void
246cleanup_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 */
261