Added activate_isapnp_device() line
[people/xl0/gpxe.git] / src / drivers / net / skel.c
1 /**************************************************************************
2 Etherboot -  BOOTP/TFTP Bootstrap Program
3 Skeleton NIC driver for Etherboot
4 ***************************************************************************/
5
6 /*
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2, or (at
10  * your option) any later version.
11  */
12
13 /* to get some global routines like printf */
14 #include "etherboot.h"
15 /* to get the interface to the body of the program */
16 #include "nic.h"
17 /* Drag in support for whichever bus(es) we want for this NIC */
18 #include "pci.h"
19 #include "isa.h"
20 #include "eisa.h"
21 #include "isapnp.h"
22 #include "mca.h"
23
24 /* NIC specific static variables go here.  Try to avoid using static
25  * variables wherever possible.  In particular, the I/O address can
26  * always be accessed via nic->ioaddr.
27  */
28
29 /*
30  * Don't forget to remove "__unused" from all the function parameters!
31  *
32  */
33
34 /**************************************************************************
35  * CONNECT - Connect to the network
36  **************************************************************************
37 */
38 static int skel_connect ( struct nic *nic __unused ) {
39         /*
40          * Connect to the network.  For most NICs, this will probably
41          * be a no-op.  For wireless NICs, this should be the point at
42          * which you attempt to join to an access point.
43          *
44          * Return 0 if the connection failed (e.g. no cable plugged
45          * in), 1 for success.
46          *
47          */
48         return 1;
49 }
50
51 /**************************************************************************
52  * POLL - Wait for a frame
53  **************************************************************************
54 */
55 static int skel_poll ( struct nic *nic __unused, int retrieve __unused ) {
56         /* Work out whether or not there's an ethernet packet ready to
57          * read.  Return 0 if not.
58          */
59         /* 
60            if ( ! <packet_ready> ) return 0;
61         */
62
63         /* retrieve==0 indicates that we are just checking for the
64          * presence of a packet but don't want to read it just yet.
65          */
66         /*
67            if ( ! retrieve ) return 1;
68         */
69
70         /* Copy data to nic->packet.  Data should include the
71          * link-layer header (dest MAC, source MAC, type).
72          * Store length of data in nic->packetlen.
73          * Return true to indicate a packet has been read.
74          */
75         /* 
76            nic->packetlen = <packet_length>;
77            memcpy ( nic->packet, <packet_data>, <packet_length> );
78            return 1;
79         */
80
81         return 0;       /* Remove this line once this method is implemented */
82 }
83
84 /**************************************************************************
85  * TRANSMIT - Transmit a frame
86  **************************************************************************
87 */
88 static void skel_transmit ( struct nic *nic __unused,
89                             const char *dest __unused,
90                             unsigned int type __unused,
91                             unsigned int size __unused,
92                             const char *packet __unused ) {
93         /* Transmit packet to dest MAC address.  You will need to
94          * construct the link-layer header (dest MAC, source MAC,
95          * type).
96          */
97         /*
98            unsigned int nstype = htons ( type );
99            memcpy ( <tx_buffer>, dest, ETH_ALEN );
100            memcpy ( <tx_buffer> + ETH_ALEN, nic->node_addr, ETH_ALEN );
101            memcpy ( <tx_buffer> + 2 * ETH_ALEN, &nstype, 2 );
102            memcpy ( <tx_buffer> + ETH_HLEN, data, size );
103            <transmit_data> ( <tx_buffer>, size + ETH_HLEN );
104          */
105 }
106
107 /**************************************************************************
108  * DISABLE - Turn off ethernet interface
109  **************************************************************************
110  */
111 static void skel_disable ( struct nic *nic __unused ) {
112         /* put the card in its initial state */
113         /* This function serves 3 purposes.
114          * This disables DMA and interrupts so we don't receive
115          *  unexpected packets or interrupts from the card after
116          *  etherboot has finished. 
117          * This frees resources so etherboot may use
118          *  this driver on another interface
119          * This allows etherboot to reinitialize the interface
120          *  if something is something goes wrong.
121          */
122 }
123
124 /**************************************************************************
125  * IRQ - handle interrupts
126  **************************************************************************
127 */
128 static void skel_irq ( struct nic *nic __unused, irq_action_t action ) {
129         /* This routine is somewhat optional.  Etherboot itself
130          * doesn't use interrupts, but they are required under some
131          * circumstances when we're acting as a PXE stack.
132          *
133          * If you don't implement this routine, the only effect will
134          * be that your driver cannot be used via Etherboot's UNDI
135          * API.  This won't affect programs that use only the UDP
136          * portion of the PXE API, such as pxelinux.
137          */
138        
139         switch ( action ) {
140         case DISABLE :
141         case ENABLE :
142                 /* Set receive interrupt enabled/disabled state */
143                 /*
144                   outb ( action == ENABLE ? IntrMaskEnabled : IntrMaskDisabled,
145                          nic->ioaddr + IntrMaskRegister );
146                  */
147                 break;
148         case FORCE :
149                 /* Force NIC to generate a receive interrupt */
150                 /*
151                   outb ( ForceInterrupt, nic->ioaddr + IntrForceRegister );
152                  */
153                 break;
154         }
155 }
156
157 /**************************************************************************
158  * OPERATIONS TABLE - Pointers to all the above methods
159  **************************************************************************
160  */
161 static struct nic_operations skel_operations = {
162         .connect        = skel_connect,
163         .poll           = skel_poll,
164         .transmit       = skel_transmit,
165         .irq            = skel_irq,
166         .disable        = skel_disable,
167 };
168
169 /**************************************************************************
170  * PROBE - Look for an adapter
171  *
172  * You need to define a probe routine for each bus type that your
173  * driver supports, together with tables that enable Etherboot to
174  * identify that your driver should be used for a particular device.
175  *
176  * Delete whichever of the following sections you don't need.  For
177  * example, most PCI devices will only need the PCI probing section;
178  * ISAPnP, EISA, etc. can all be deleted.
179  *
180  * Some devices will need custom bus logic.  The ISA 3c509 is a good
181  * example of this; it has a contention-resolution mechanism that is
182  * similar to ISAPnP, but not close enough to use the generic ISAPnP
183  * code.  Look at 3c509.c to see how it works.
184  *
185  **************************************************************************
186  */
187
188 /**************************************************************************
189  * PCI PROBE - Look for an adapter
190  **************************************************************************
191  */
192 static int skel_pci_probe ( struct dev *dev, struct pci_device *pci ) {
193         struct nic *nic = nic_device ( dev );
194
195         nic->ioaddr = pci->ioaddr;
196         nic->irqno = pci->irq;
197
198         /* Test for physical presence of NIC */
199         /*
200            if ( ! my_tests ) {
201                 DBG ( "Could not find NIC: my explanation\n" );
202                 return 0;
203            }
204         */
205
206         /* point to NIC specific routines */
207         nic->nic_op = &skel_operations;
208         return 1;
209 }
210
211 static struct pci_id skel_pci_nics[] = {
212 PCI_ROM ( 0x0000, 0x0000, "skel-pci", "Skeleton PCI Adapter" ),
213 };
214
215 static struct pci_driver skel_pci_driver =
216         PCI_DRIVER ( "SKEL/PCI", skel_pci_nics, PCI_NO_CLASS );
217
218 BOOT_DRIVER ( "SKEL/PCI", find_pci_boot_device,
219               skel_pci_driver, skel_pci_probe );
220
221 /**************************************************************************
222  * EISA PROBE - Look for an adapter
223  **************************************************************************
224  */
225 static int skel_eisa_probe ( struct dev *dev, struct eisa_device *eisa ) {
226         struct nic *nic = nic_device ( dev );
227
228         enable_eisa_device ( eisa );
229         nic->ioaddr = eisa->ioaddr;
230         nic->irqno = 0;
231
232         /* Test for physical presence of NIC */
233         /*
234            if ( ! my_tests ) {
235                 DBG ( "Could not find NIC: my explanation\n" );
236                 return 0;
237            }
238         */
239
240         /* point to NIC specific routines */
241         nic->nic_op = &skel_operations;
242         return 1;
243 }
244
245 static struct eisa_id skel_eisa_nics[] = {
246         { "Skeleton EISA Adapter", EISA_VENDOR('S','K','L'), 0x0000 },
247 };
248
249 static struct eisa_driver skel_eisa_driver =
250         EISA_DRIVER ( "SKEL/EISA", skel_eisa_nics );
251
252 BOOT_DRIVER ( "SKEL/EISA", find_eisa_boot_device,
253               skel_eisa_driver, skel_eisa_probe );
254
255 ISA_ROM ( "skel-eisa", "Skeleton EISA Adapter" );
256
257 /**************************************************************************
258  * ISAPnP PROBE - Look for an adapter
259  **************************************************************************
260  */
261 static int skel_isapnp_probe ( struct dev *dev,
262                                struct isapnp_device *isapnp ) {
263         struct nic *nic = nic_device ( dev );
264
265         nic->ioaddr = isapnp->ioaddr;
266         nic->irqno = isapnp->irqno;
267         activate_isapnp_device ( isapnp );
268
269         /* Test for physical presence of NIC */
270         /*
271            if ( ! my_tests ) {
272                 DBG ( "Could not find NIC: my explanation\n" );
273                 return 0;
274            }
275         */
276
277         /* point to NIC specific routines */
278         nic->nic_op = &skel_operations;
279         return 1;
280 }
281
282 static struct isapnp_id skel_isapnp_nics[] = {
283         { "Skeleton ISAPnP Adapter", ISAPNP_VENDOR('S','K','L'), 0x0000 },
284 };
285
286 static struct isapnp_driver skel_isapnp_driver =
287         ISAPNP_DRIVER ( "SKEL/ISAPnP", skel_isapnp_nics );
288
289 BOOT_DRIVER ( "SKEL/ISAPnP", find_isapnp_boot_device,
290               skel_isapnp_driver, skel_isapnp_probe );
291
292 ISA_ROM ( "skel-isapnp", "Skeleton ISAPnP Adapter" );
293
294 /**************************************************************************
295  * MCA PROBE - Look for an adapter
296  **************************************************************************
297  */
298 static int skel_mca_probe ( struct dev *dev,
299                             struct mca_device *mca __unused ) {
300         struct nic *nic = nic_device ( dev );
301
302         /* MCA parameters are available in the mca->pos[] array */
303         /*
304            nic->ioaddr = ( mca->pos[xxx] << 8 ) + mca->pos[yyy];
305            nic->irqno = mca->pos[zzz] & 0x0f;
306         */
307
308         /* Test for physical presence of NIC */
309         /*
310            if ( ! my_tests ) {
311                 DBG ( "Could not find NIC: my explanation\n" );
312                 return 0;
313            }
314         */
315
316         /* point to NIC specific routines */
317         nic->nic_op = &skel_operations;
318         return 1;
319 }
320
321 static struct mca_id skel_mca_nics[] = {
322         { "Skeleton MCA Adapter", 0x0000 },
323 };
324
325 static struct mca_driver skel_mca_driver =
326         MCA_DRIVER ( "SKEL/MCA", skel_mca_nics );
327
328 BOOT_DRIVER ( "SKEL/MCA", find_mca_boot_device,
329               skel_mca_driver, skel_mca_probe );
330
331 ISA_ROM ( "skel-mca", "Skeleton MCA Adapter" );
332
333 /**************************************************************************
334  * ISA PROBE - Look for an adapter
335  *
336  * The "classical" ISA probe is split into two stages: trying a list
337  * of I/O addresses to see if there's anything listening, and then
338  * using that I/O address to fill in the information in the nic
339  * structure.
340  *
341  * The list of probe addresses defined in skel_isa_probe_addrs[] will
342  * be passed to skel_isa_probe_addr().  If skel_isa_probe_addr()
343  * returns true, a struct isa_device will be created with isa->ioaddr
344  * set to the working I/O address, and skel_isa_probe() will be
345  * called.
346  *
347  * There is a standard mechanism for overriding the probe address list
348  * using ISA_PROBE_ADDRS.  Do not implement any custom code to
349  * override the probe address list.
350  *
351  **************************************************************************
352  */
353 static int skel_isa_probe_addr ( isa_probe_addr_t ioaddr __unused ) {
354         return 0;
355 }
356
357 static int skel_isa_probe ( struct dev *dev, struct isa_device *isa ) {
358         struct nic *nic = nic_device ( dev );
359
360         nic->ioaddr = isa->ioaddr;
361         nic->irqno = 0;
362
363         /* Test for physical presence of NIC */
364         /*
365            if ( ! my_tests ) {
366                 DBG ( "Could not find NIC: my explanation\n" );
367                 return 0;
368            }
369         */
370
371         /* point to NIC specific routines */
372         nic->nic_op = &skel_operations;
373         return 1;
374 }
375
376 static isa_probe_addr_t skel_isa_probe_addrs[] = {
377         /*
378            0x200, 0x240,
379         */
380 };
381
382 static struct isa_driver skel_isa_driver =
383         ISA_DRIVER ( "SKEL/ISA", skel_isa_probe_addrs, skel_isa_probe_addr,
384                      ISA_VENDOR('S','K','L'), 0x0000 );
385
386 BOOT_DRIVER ( "SKEL/ISA", find_isa_boot_device,
387               skel_isa_driver, skel_isa_probe );
388
389 ISA_ROM ( "skel-isa", "Skeleton ISA Adapter" );
390