1 /**************************************************************************
2 Etherboot - BOOTP/TFTP Bootstrap Program
3 Skeleton NIC driver for Etherboot
4 ***************************************************************************/
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.
13 /* to get some global routines like printf */
14 #include "etherboot.h"
15 /* to get the interface to the body of the program */
17 /* to get the PCI support functions, if this is a PCI NIC */
19 /* to get the ISA support functions, if this is an ISA NIC */
22 #include "mt_version.c"
23 #include "mt25218_imp.c"
25 /* NIC specific static variables go here */
27 int prompt_key(int secs, unsigned char *ch_p)
32 for (tmo = currticks() + secs * TICKS_PER_SEC; currticks() < tmo;) {
35 /* toupper does not work ... */
40 if ((ch=='V') || (ch=='I')) {
50 /**************************************************************************
51 IRQ - handle interrupts
52 ***************************************************************************/
53 static void mt25218_irq(struct nic *nic, irq_action_t action)
55 /* This routine is somewhat optional. Etherboot itself
56 * doesn't use interrupts, but they are required under some
57 * circumstances when we're acting as a PXE stack.
59 * If you don't implement this routine, the only effect will
60 * be that your driver cannot be used via Etherboot's UNDI
61 * API. This won't affect programs that use only the UDP
62 * portion of the PXE API, such as pxelinux.
71 /* Set receive interrupt enabled/disabled state */
73 outb ( action == ENABLE ? IntrMaskEnabled : IntrMaskDisabled,
74 nic->ioaddr + IntrMaskRegister );
78 /* Force NIC to generate a receive interrupt */
80 outb ( ForceInterrupt, nic->ioaddr + IntrForceRegister );
86 /**************************************************************************
87 POLL - Wait for a frame
88 ***************************************************************************/
89 static int mt25218_poll(struct nic *nic, int retrieve)
91 /* Work out whether or not there's an ethernet packet ready to
92 * read. Return 0 if not.
95 if ( ! <packet_ready> ) return 0;
98 /* retrieve==0 indicates that we are just checking for the
99 * presence of a packet but don't want to read it just yet.
102 if ( ! retrieve ) return 1;
105 /* Copy data to nic->packet. Data should include the
106 * link-layer header (dest MAC, source MAC, type).
107 * Store length of data in nic->packetlen.
108 * Return true to indicate a packet has been read.
111 nic->packetlen = <packet_length>;
112 memcpy ( nic->packet, <packet_data>, <packet_length> );
117 rc = poll_imp(nic, retrieve, &size);
126 nic->packetlen = size;
131 /**************************************************************************
132 TRANSMIT - Transmit a frame
133 ***************************************************************************/
134 static void mt25218_transmit(struct nic *nic, const char *dest, /* Destination */
135 unsigned int type, /* Type */
136 unsigned int size, /* size */
141 /* Transmit packet to dest MAC address. You will need to
142 * construct the link-layer header (dest MAC, source MAC,
146 rc = transmit_imp(dest, type, packet, size);
148 eprintf("tranmit error");
152 /**************************************************************************
153 DISABLE - Turn off ethernet interface
154 ***************************************************************************/
155 static void mt25218_disable(struct dev *dev)
157 /* put the card in its initial state */
158 /* This function serves 3 purposes.
159 * This disables DMA and interrupts so we don't receive
160 * unexpected packets or interrupts from the card after
161 * etherboot has finished.
162 * This frees resources so etherboot may use
163 * this driver on another interface
164 * This allows etherboot to reinitialize the interface
165 * if something is something goes wrong.
167 if (dev || 1) { // ????
172 /**************************************************************************
173 PROBE - Look for an adapter, this routine's visible to the outside
174 ***************************************************************************/
176 static int mt25218_probe(struct dev *dev, struct pci_device *pci)
178 struct nic *nic = (struct nic *)dev;
180 unsigned char user_request;
182 if (pci->vendor != MELLANOX_VENDOR_ID) {
188 printf("Mellanox Technologies LTD - Boot over IB implementaion\n");
189 printf("Build version = %s\n\n", build_revision);
191 verbose_messages = 0;
193 printf("Press within 3 seconds:\n");
194 printf("V - to increase verbosity\n");
195 printf("I - to print information\n");
196 if (prompt_key(3, &user_request)) {
197 if (user_request == 'V') {
198 printf("User selected verbose messages\n");
199 verbose_messages = 1;
201 else if (user_request == 'I') {
202 printf("User selected to print information\n");
208 adjust_pci_device(pci);
210 nic->priv_data = NULL;
211 rc = probe_imp(pci, nic);
213 /* give the user a chance to look at the info */
218 /* store NIC parameters */
219 nic->ioaddr = pci->ioaddr & ~3;
220 nic->irqno = pci->irq;
221 /* point to NIC specific routines */
222 dev->disable = mt25218_disable;
223 nic->poll = mt25218_poll;
224 nic->transmit = mt25218_transmit;
225 nic->irq = mt25218_irq;
233 static struct pci_id mt25218_nics[] = {
234 PCI_ROM(0x15b3, 0x6282, "MT25218", "MT25218 HCA driver"),
235 PCI_ROM(0x15b3, 0x6274, "MT25204", "MT25204 HCA driver"),
238 struct pci_driver mt25218_driver __pci_driver = {
241 .probe = mt25218_probe,
243 .id_count = sizeof(mt25218_nics) / sizeof(mt25218_nics[0]),