Updated to new API.
[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  * IRQ - handle interrupts
109  **************************************************************************
110 */
111 static void skel_irq ( struct nic *nic __unused, irq_action_t action ) {
112         /* This routine is somewhat optional.  Etherboot itself
113          * doesn't use interrupts, but they are required under some
114          * circumstances when we're acting as a PXE stack.
115          *
116          * If you don't implement this routine, the only effect will
117          * be that your driver cannot be used via Etherboot's UNDI
118          * API.  This won't affect programs that use only the UDP
119          * portion of the PXE API, such as pxelinux.
120          */
121        
122         switch ( action ) {
123         case DISABLE :
124         case ENABLE :
125                 /* Set receive interrupt enabled/disabled state */
126                 /*
127                   outb ( action == ENABLE ? IntrMaskEnabled : IntrMaskDisabled,
128                          nic->ioaddr + IntrMaskRegister );
129                  */
130                 break;
131         case FORCE :
132                 /* Force NIC to generate a receive interrupt */
133                 /*
134                   outb ( ForceInterrupt, nic->ioaddr + IntrForceRegister );
135                  */
136                 break;
137         }
138 }
139
140 /**************************************************************************
141  * OPERATIONS TABLE - Pointers to all the above methods
142  **************************************************************************
143  */
144 static struct nic_operations skel_operations = {
145         .connect        = skel_connect,
146         .poll           = skel_poll,
147         .transmit       = skel_transmit,
148         .irq            = skel_irq,
149 };
150
151 /**************************************************************************
152  * PROBE - Look for an adapter
153  *
154  * You need to define a probe routine and a disable routine for each
155  * bus type that your driver supports, together with tables that
156  * enable Etherboot to identify that your driver should be used for a
157  * particular device.
158  *
159  * Delete whichever of the following sections you don't need.  For
160  * example, most PCI devices will only need the PCI probing section;
161  * ISAPnP, EISA, etc. can all be deleted.
162  *
163  * Some devices will need custom bus logic.  The ISA 3c509 is a good
164  * example of this; it has a contention-resolution mechanism that is
165  * similar to ISAPnP, but not close enough to use the generic ISAPnP
166  * code.  Look at 3c509.c to see how it works.
167  *
168  **************************************************************************
169  */
170
171 /**************************************************************************
172  * PCI PROBE and DISABLE
173  **************************************************************************
174  */
175 static int skel_pci_probe ( struct nic *nic, struct pci_device *pci ) {
176
177         pci_fill_nic ( nic, pci );
178
179         /* Test for physical presence of NIC */
180         /*
181            if ( ! my_tests ) {
182                 DBG ( "Could not find NIC: my explanation\n" );
183                 return 0;
184            }
185         */
186
187         /* point to NIC specific routines */
188         nic->nic_op = &skel_operations;
189         return 1;
190 }
191
192 static void skel_pci_disable ( struct nic *nic __unused,
193                                struct pci_device *pci __unused ) {
194         /* Reset the card to its initial state, disable DMA and
195          * interrupts
196          */
197 }
198
199 static struct pci_id skel_pci_nics[] = {
200 PCI_ROM ( 0x0000, 0x0000, "skel-pci", "Skeleton PCI Adapter" ),
201 };
202
203 static struct pci_driver skel_pci_driver =
204         PCI_DRIVER ( skel_pci_nics, PCI_NO_CLASS );
205
206 DRIVER ( "SKEL/PCI", nic_driver, pci_driver, skel_pci_driver,
207          skel_pci_probe, skel_pci_disable );
208
209 /**************************************************************************
210  * EISA PROBE and DISABLE
211  **************************************************************************
212  */
213 static int skel_eisa_probe ( struct nic *nic, struct eisa_device *eisa ) {
214
215         eisa_fill_nic ( nic, eisa );
216         enable_eisa_device ( eisa );
217         nic->irqno = 0; /* No standard way to get irq from EISA cards */
218
219         /* Test for physical presence of NIC */
220         /*
221            if ( ! my_tests ) {
222                 DBG ( "Could not find NIC: my explanation\n" );
223                 return 0;
224            }
225         */
226
227         /* point to NIC specific routines */
228         nic->nic_op = &skel_operations;
229         return 1;
230 }
231
232 static void skel_eisa_disable ( struct nic *nic __unused,
233                                 struct eisa_device *eisa ) {
234         /* Reset the card to its initial state, disable DMA and
235          * interrupts
236          */
237         disable_eisa_device ( eisa );
238 }
239
240 static struct eisa_id skel_eisa_nics[] = {
241         { "Skeleton EISA Adapter", EISA_VENDOR('S','K','L'), 0x0000 },
242 };
243
244 static struct eisa_driver skel_eisa_driver =
245         EISA_DRIVER ( skel_eisa_nics );
246
247 DRIVER ( "SKEL/EISA", nic_driver, eisa_driver, skel_eisa_driver,
248          skel_eisa_probe, skel_eisa_disable );
249
250 ISA_ROM ( "skel-eisa", "Skeleton EISA Adapter" );
251
252 /**************************************************************************
253  * ISAPnP PROBE and DISABLE
254  **************************************************************************
255  */
256 static int skel_isapnp_probe ( struct nic *nic,
257                                struct isapnp_device *isapnp ) {
258
259         isapnp_fill_nic ( nic, isapnp );
260         activate_isapnp_device ( isapnp );
261
262         /* Test for physical presence of NIC */
263         /*
264            if ( ! my_tests ) {
265                 DBG ( "Could not find NIC: my explanation\n" );
266                 return 0;
267            }
268         */
269
270         /* point to NIC specific routines */
271         nic->nic_op = &skel_operations;
272         return 1;
273 }
274
275 static void skel_isapnp_disable ( struct nic *nic __unused,
276                                   struct isapnp_device *isapnp ) {
277         /* Reset the card to its initial state, disable DMA and
278          * interrupts
279          */
280         deactivate_isapnp_device ( isapnp );
281 }
282
283 static struct isapnp_id skel_isapnp_nics[] = {
284         { "Skeleton ISAPnP Adapter", ISAPNP_VENDOR('S','K','L'), 0x0000 },
285 };
286
287 static struct isapnp_driver skel_isapnp_driver =
288         ISAPNP_DRIVER ( skel_isapnp_nics );
289
290 DRIVER ( "SKEL/ISAPnP", nic_driver, isapnp_driver, skel_isapnp_driver,
291          skel_isapnp_probe, skel_isapnp_disable );
292
293 ISA_ROM ( "skel-isapnp", "Skeleton ISAPnP Adapter" );
294
295 /**************************************************************************
296  * MCA PROBE and DISABLE
297  **************************************************************************
298  */
299 static int skel_mca_probe ( struct nic *nic,
300                             struct mca_device *mca ) {
301
302         mca_fill_nic ( nic, mca );
303
304         /* MCA parameters are available in the mca->pos[] array */
305         /*
306            nic->ioaddr = ( mca->pos[xxx] << 8 ) + mca->pos[yyy];
307            nic->irqno = mca->pos[zzz] & 0x0f;
308         */
309
310         /* Test for physical presence of NIC */
311         /*
312            if ( ! my_tests ) {
313                 DBG ( "Could not find NIC: my explanation\n" );
314                 return 0;
315            }
316         */
317
318         /* point to NIC specific routines */
319         nic->nic_op = &skel_operations;
320         return 1;
321 }
322
323 static void skel_mca_disable ( struct nic *nic __unused,
324                                struct mca_device *mca __unused ) {
325         /* Reset the card to its initial state, disable DMA and
326          * interrupts
327          */
328 }
329
330 static struct mca_id skel_mca_nics[] = {
331         { "Skeleton MCA Adapter", 0x0000 },
332 };
333
334 static struct mca_driver skel_mca_driver =
335         MCA_DRIVER ( skel_mca_nics );
336
337 DRIVER ( "SKEL/MCA", nic_driver, mca_driver, skel_mca_driver,
338          skel_mca_probe, skel_mca_disable );
339
340 ISA_ROM ( "skel-mca", "Skeleton MCA Adapter" );
341
342 /**************************************************************************
343  * ISA PROBE and DISABLE
344  *
345  * The "classical" ISA probe is split into two stages: trying a list
346  * of I/O addresses to see if there's anything listening, and then
347  * using that I/O address to fill in the information in the nic
348  * structure.
349  *
350  * The list of probe addresses defined in skel_isa_probe_addrs[] will
351  * be passed to skel_isa_probe_addr().  If skel_isa_probe_addr()
352  * returns true, a struct isa_device will be created with isa->ioaddr
353  * set to the working I/O address, and skel_isa_probe() will be
354  * called.
355  *
356  * There is a standard mechanism for overriding the probe address list
357  * using ISA_PROBE_ADDRS.  Do not implement any custom code to
358  * override the probe address list.
359  *
360  **************************************************************************
361  */
362 static int skel_isa_probe_addr ( isa_probe_addr_t ioaddr __unused ) {
363         return 0;
364 }
365
366 static int skel_isa_probe ( struct nic *nic, struct isa_device *isa ) {
367
368         isa_fill_nic ( nic, isa );
369         nic->irqno = 0; /* No standard way to get IRQ for ISA */
370
371         /* Test for physical presence of NIC */
372         /*
373            if ( ! my_tests ) {
374                 DBG ( "Could not find NIC: my explanation\n" );
375                 return 0;
376            }
377         */
378
379         /* point to NIC specific routines */
380         nic->nic_op = &skel_operations;
381         return 1;
382 }
383
384 static void skel_isa_disable ( struct nic *nic __unused,
385                               struct isa_device *isa __unused ) {
386         /* Reset the card to its initial state, disable DMA and
387          * interrupts
388          */
389 }
390
391 static isa_probe_addr_t skel_isa_probe_addrs[] = {
392         /*
393            0x200, 0x240,
394         */
395 };
396
397 static struct isa_driver skel_isa_driver =
398         ISA_DRIVER ( skel_isa_probe_addrs, skel_isa_probe_addr,
399                      ISA_VENDOR('S','K','L'), 0x0000 );
400
401 DRIVER ( "SKEL/ISA", nic_driver, isa_driver, skel_isa_driver,
402          skel_isa_probe, skel_isa_disable );
403
404 ISA_ROM ( "skel-isa", "Skeleton ISA Adapter" );
405