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