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 | /* to get the PCI support functions, if this is a PCI NIC */
|
---|
18 | #include "pci.h"
|
---|
19 | /* to get the ISA support functions, if this is an ISA NIC */
|
---|
20 | #include "isa.h"
|
---|
21 |
|
---|
22 | /* NIC specific static variables go here */
|
---|
23 |
|
---|
24 | /**************************************************************************
|
---|
25 | POLL - Wait for a frame
|
---|
26 | ***************************************************************************/
|
---|
27 | static int skel_poll(struct nic *nic, int retrieve)
|
---|
28 | {
|
---|
29 | /* Work out whether or not there's an ethernet packet ready to
|
---|
30 | * read. Return 0 if not.
|
---|
31 | */
|
---|
32 | /*
|
---|
33 | if ( ! <packet_ready> ) return 0;
|
---|
34 | */
|
---|
35 |
|
---|
36 | /* retrieve==0 indicates that we are just checking for the
|
---|
37 | * presence of a packet but don't want to read it just yet.
|
---|
38 | */
|
---|
39 | /*
|
---|
40 | if ( ! retrieve ) return 1;
|
---|
41 | */
|
---|
42 |
|
---|
43 | /* Copy data to nic->packet. Data should include the
|
---|
44 | * link-layer header (dest MAC, source MAC, type).
|
---|
45 | * Store length of data in nic->packetlen.
|
---|
46 | * Return true to indicate a packet has been read.
|
---|
47 | */
|
---|
48 | /*
|
---|
49 | nic->packetlen = <packet_length>;
|
---|
50 | memcpy ( nic->packet, <packet_data>, <packet_length> );
|
---|
51 | return 1;
|
---|
52 | */
|
---|
53 |
|
---|
54 | return 0; /* Remove this line once this method is implemented */
|
---|
55 | }
|
---|
56 |
|
---|
57 | /**************************************************************************
|
---|
58 | TRANSMIT - Transmit a frame
|
---|
59 | ***************************************************************************/
|
---|
60 | static void skel_transmit(
|
---|
61 | struct nic *nic,
|
---|
62 | const char *dest, /* Destination */
|
---|
63 | unsigned int type, /* Type */
|
---|
64 | unsigned int size, /* size */
|
---|
65 | const char *packet) /* Packet */
|
---|
66 | {
|
---|
67 | /* Transmit packet to dest MAC address. You will need to
|
---|
68 | * construct the link-layer header (dest MAC, source MAC,
|
---|
69 | * type).
|
---|
70 | */
|
---|
71 | /*
|
---|
72 | unsigned int nstype = htons ( type );
|
---|
73 | memcpy ( <tx_buffer>, dest, ETH_ALEN );
|
---|
74 | memcpy ( <tx_buffer> + ETH_ALEN, nic->node_addr, ETH_ALEN );
|
---|
75 | memcpy ( <tx_buffer> + 2 * ETH_ALEN, &nstype, 2 );
|
---|
76 | memcpy ( <tx_buffer> + ETH_HLEN, data, size );
|
---|
77 | <transmit_data> ( <tx_buffer>, size + ETH_HLEN );
|
---|
78 | */
|
---|
79 | }
|
---|
80 |
|
---|
81 | /**************************************************************************
|
---|
82 | DISABLE - Turn off ethernet interface
|
---|
83 | ***************************************************************************/
|
---|
84 | static void skel_disable(struct dev *dev)
|
---|
85 | {
|
---|
86 | /* put the card in its initial state */
|
---|
87 | /* This function serves 3 purposes.
|
---|
88 | * This disables DMA and interrupts so we don't receive
|
---|
89 | * unexpected packets or interrupts from the card after
|
---|
90 | * etherboot has finished.
|
---|
91 | * This frees resources so etherboot may use
|
---|
92 | * this driver on another interface
|
---|
93 | * This allows etherboot to reinitialize the interface
|
---|
94 | * if something is something goes wrong.
|
---|
95 | */
|
---|
96 | }
|
---|
97 |
|
---|
98 | /**************************************************************************
|
---|
99 | IRQ - handle interrupts
|
---|
100 | ***************************************************************************/
|
---|
101 | static void skel_irq(struct nic *nic, irq_action_t action)
|
---|
102 | {
|
---|
103 | /* This routine is somewhat optional. Etherboot itself
|
---|
104 | * doesn't use interrupts, but they are required under some
|
---|
105 | * circumstances when we're acting as a PXE stack.
|
---|
106 | *
|
---|
107 | * If you don't implement this routine, the only effect will
|
---|
108 | * be that your driver cannot be used via Etherboot's UNDI
|
---|
109 | * API. This won't affect programs that use only the UDP
|
---|
110 | * portion of the PXE API, such as pxelinux.
|
---|
111 | */
|
---|
112 |
|
---|
113 | switch ( action ) {
|
---|
114 | case DISABLE :
|
---|
115 | case ENABLE :
|
---|
116 | /* Set receive interrupt enabled/disabled state */
|
---|
117 | /*
|
---|
118 | outb ( action == ENABLE ? IntrMaskEnabled : IntrMaskDisabled,
|
---|
119 | nic->ioaddr + IntrMaskRegister );
|
---|
120 | */
|
---|
121 | break;
|
---|
122 | case FORCE :
|
---|
123 | /* Force NIC to generate a receive interrupt */
|
---|
124 | /*
|
---|
125 | outb ( ForceInterrupt, nic->ioaddr + IntrForceRegister );
|
---|
126 | */
|
---|
127 | break;
|
---|
128 | }
|
---|
129 | }
|
---|
130 |
|
---|
131 | /**************************************************************************
|
---|
132 | PROBE - Look for an adapter, this routine's visible to the outside
|
---|
133 | ***************************************************************************/
|
---|
134 |
|
---|
135 | #define board_found 1
|
---|
136 | #define valid_link 0
|
---|
137 | static int skel_probe(struct dev *dev, struct pci_device *pci)
|
---|
138 | {
|
---|
139 | struct nic *nic = (struct nic *)dev;
|
---|
140 |
|
---|
141 | if (board_found && valid_link)
|
---|
142 | {
|
---|
143 | /* store NIC parameters */
|
---|
144 | nic->ioaddr = pci->ioaddr & ~3;
|
---|
145 | nic->irqno = pci->irq;
|
---|
146 | /* point to NIC specific routines */
|
---|
147 | dev->disable = skel_disable;
|
---|
148 | nic->poll = skel_poll;
|
---|
149 | nic->transmit = skel_transmit;
|
---|
150 | nic->irq = skel_irq;
|
---|
151 | return 1;
|
---|
152 | }
|
---|
153 | /* else */
|
---|
154 | return 0;
|
---|
155 | }
|
---|
156 |
|
---|
157 | static struct pci_id skel_nics[] = {
|
---|
158 | PCI_ROM(0x0000, 0x0000, "skel-pci", "Skeleton PCI Adaptor"),
|
---|
159 | };
|
---|
160 |
|
---|
161 | static struct pci_driver skel_driver __pci_driver = {
|
---|
162 | .type = NIC_DRIVER,
|
---|
163 | .name = "SKELETON/PCI",
|
---|
164 | .probe = skel_probe,
|
---|
165 | .ids = skel_nics,
|
---|
166 | .id_count = sizeof(skel_nics)/sizeof(skel_nics[0]),
|
---|
167 | .class = 0,
|
---|
168 | };
|
---|
169 |
|
---|
170 | /**************************************************************************
|
---|
171 | PROBE - Look for an adapter, this routine's visible to the outside
|
---|
172 | ***************************************************************************/
|
---|
173 | static int skel_isa_probe(struct dev *dev, unsigned short *probe_addrs)
|
---|
174 | {
|
---|
175 | struct nic *nic = (struct nic *)dev;
|
---|
176 | /* if probe_addrs is 0, then routine can use a hardwired default */
|
---|
177 | if (board_found && valid_link)
|
---|
178 | {
|
---|
179 | /* point to NIC specific routines */
|
---|
180 | dev->disable = skel_disable;
|
---|
181 | nic->poll = skel_poll;
|
---|
182 | nic->transmit = skel_transmit;
|
---|
183 |
|
---|
184 | /* Report the ISA pnp id of the board */
|
---|
185 | dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
|
---|
186 | dev->devid.vendor_id = htons(0x1234);
|
---|
187 | return 1;
|
---|
188 | }
|
---|
189 | /* else */
|
---|
190 | return 0;
|
---|
191 | }
|
---|
192 |
|
---|
193 | ISA_ROM("skel-isa", "Skeleton ISA driver")
|
---|
194 | static struct isa_driver skel_isa_driver __isa_driver = {
|
---|
195 | .type = NIC_DRIVER,
|
---|
196 | .name = "SKELETON/ISA",
|
---|
197 | .probe = skel_isa_probe,
|
---|
198 | .ioaddrs = 0,
|
---|
199 | };
|
---|
200 |
|
---|