:x
[people/sha0/gpxe.git] / src / drivers / net / natsemi.c
1 /* natsemi.c - gPXE driver for the NatSemi DP8381x series. */
2
3 /*
4
5  
6    natsemi.c: An Etherboot driver for the NatSemi DP8381x series.
7
8    Copyright (C) 2001 Entity Cyber, Inc.
9    
10    This development of this Etherboot driver was funded by 
11    
12       Sicom Systems: http://www.sicompos.com/
13    
14    Author: Marty Connor (mdc@thinguin.org)         
15    Adapted from a Linux driver which was written by Donald Becker
16    
17    This software may be used and distributed according to the terms
18    of the GNU Public License (GPL), incorporated herein by reference.
19    
20    Original Copyright Notice:
21    
22    Written/copyright 1999-2001 by Donald Becker.
23    
24    This software may be used and distributed according to the terms of
25    the GNU General Public License (GPL), incorporated herein by reference.
26    Drivers based on or derived from this code fall under the GPL and must
27    retain the authorship, copyright and license notice.  This file is not
28    a complete program and may only be used when the entire operating
29    system is licensed under the GPL.  License for under other terms may be
30    available.  Contact the original author for details.
31    
32    The original author may be reached as becker@scyld.com, or at
33    Scyld Computing Corporation
34    410 Severn Ave., Suite 210
35    Annapolis MD 21403
36    
37    Support information and updates available at
38    http://www.scyld.com/network/netsemi.html
39    
40    References:
41    
42    http://www.scyld.com/expert/100mbps.html
43    http://www.scyld.com/expert/NWay.html
44    Datasheet is available from:
45    http://www.national.com/pf/DP/DP83815.html
46
47 */
48
49 /* Revision History */
50
51 /*
52   02 JUL 2007 Udayan Kumar       1.2 ported the driver from etherboot to gPXE API.
53                                      Fully rewritten,adapting the old driver.
54                                      Added a circular buffer for transmit and receive.
55                                      transmit routine will not wait for transmission to finish.
56                                      poll routine deals with it.
57
58   13 Dec 2003 timlegge           1.1 Enabled Multicast Support
59   29 May 2001  mdc               1.0
60      Initial Release.            Tested with Netgear FA311 and FA312 boards
61 */
62  
63
64
65
66 #include <stdint.h>
67 #include <pic8259.h>
68 #include <stdlib.h>
69 #include <stdio.h>
70 #include <io.h>
71 #include <errno.h>
72 #include <timer.h>
73 #include <byteswap.h>
74 #include <gpxe/pci.h>
75 #include <gpxe/if_ether.h>
76 #include <gpxe/ethernet.h>
77 #include <gpxe/iobuf.h>
78 #include <gpxe/netdevice.h>
79 #include <gpxe/spi_bit.h>
80 #include <gpxe/threewire.h>
81 #include <gpxe/nvo.h>
82
83 #define TX_RING_SIZE 4
84 #define NUM_RX_DESC  4
85 #define RX_BUF_SIZE 1536
86 #define OWN       0x80000000
87 #define DSIZE     0x00000FFF
88 #define CRC_SIZE  4
89
90 struct natsemi_tx {
91         uint32_t link;
92         uint32_t cmdsts;
93         uint32_t bufptr;
94 };
95
96 struct natsemi_rx {
97         uint32_t link;
98         uint32_t cmdsts;
99         uint32_t bufptr;
100 };
101
102 struct natsemi_nic {
103         unsigned short ioaddr;
104         unsigned short tx_cur;
105         unsigned short tx_dirty;
106         unsigned short rx_cur;
107         struct natsemi_tx tx[TX_RING_SIZE];
108         struct natsemi_rx rx[NUM_RX_DESC];
109         /* need to add iobuf as we cannot free iobuf->data in close without this 
110          * alternatively substracting sizeof(head) and sizeof(list_head) can also 
111          * give the same.
112          */
113         struct io_buffer *iobuf[NUM_RX_DESC];
114         /* netdev_tx_complete needs pointer to the iobuf of the data so as to free 
115          * it from the memory.
116          */
117         struct io_buffer *tx_iobuf[TX_RING_SIZE];
118         struct spi_bit_basher spibit;
119         struct spi_device eeprom;
120         struct nvo_block nvo;
121 };
122
123 /* NATSEMI: Offsets to the device registers.
124  * Unlike software-only systems, device drivers interact with complex hardware.
125  * It's not useful to define symbolic names for every register bit in the
126  * device.
127  */
128 enum register_offsets {
129     ChipCmd      = 0x00, 
130     ChipConfig   = 0x04, 
131     EECtrl       = 0x08, 
132     PCIBusCfg    = 0x0C,
133     IntrStatus   = 0x10, 
134     IntrMask     = 0x14, 
135     IntrEnable   = 0x18,
136     TxRingPtr    = 0x20, 
137     TxConfig     = 0x24,
138     RxRingPtr    = 0x30,
139     RxConfig     = 0x34, 
140     ClkRun       = 0x3C,
141     WOLCmd       = 0x40, 
142     PauseCmd     = 0x44,
143     RxFilterAddr = 0x48, 
144     RxFilterData = 0x4C,
145     BootRomAddr  = 0x50, 
146     BootRomData  = 0x54, 
147     SiliconRev   = 0x58, 
148     StatsCtrl    = 0x5C,
149     StatsData    = 0x60, 
150     RxPktErrs    = 0x60, 
151     RxMissed     = 0x68, 
152     RxCRCErrs    = 0x64,
153     PCIPM        = 0x44,
154     PhyStatus    = 0xC0, 
155     MIntrCtrl    = 0xC4, 
156     MIntrStatus  = 0xC8,
157     /* These are from the spec, around page 78... on a separate table. 
158      */
159     PGSEL        = 0xCC, 
160     PMDCSR       = 0xE4, 
161     TSTDAT       = 0xFC, 
162     DSPCFG       = 0xF4, 
163     SDCFG        = 0x8C,
164     BasicControl = 0x80,        
165     BasicStatus  = 0x84
166             
167 };
168
169 /* Bit in ChipCmd.
170  */
171 enum ChipCmdBits {
172     ChipReset = 0x100, 
173     RxReset   = 0x20, 
174     TxReset   = 0x10, 
175     RxOff     = 0x08, 
176     RxOn      = 0x04,
177     TxOff     = 0x02, 
178     TxOn      = 0x01
179 };
180
181 /* Bits in the RxMode register.
182  */
183 enum rx_mode_bits {
184     AcceptErr          = 0x20,
185     AcceptRunt         = 0x10,
186     AcceptBroadcast    = 0xC0000000,
187     AcceptMulticast    = 0x00200000, 
188     AcceptAllMulticast = 0x20000000,
189     AcceptAllPhys      = 0x10000000, 
190     AcceptMyPhys       = 0x08000000,
191     RxFilterEnable     = 0x80000000
192 };
193
194 /* Bits in network_desc.status
195  */
196 enum desc_status_bits {
197     DescOwn   = 0x80000000, 
198     DescMore  = 0x40000000, 
199     DescIntr  = 0x20000000,
200     DescNoCRC = 0x10000000,
201     DescPktOK = 0x08000000, 
202     RxTooLong = 0x00400000
203 };
204
205 /*Bits in Interrupt Mask register
206  */
207 enum Intr_mask_register_bits {
208     RxOk       = 0x001,
209     RxErr      = 0x004,
210     TxOk       = 0x040,
211     TxErr      = 0x100 
212 };      
213
214 /*  EEPROM access , values are devices specific
215  */
216 #define EE_CS           0x08    /* EEPROM chip select */
217 #define EE_SK           0x04    /* EEPROM shift clock */
218 #define EE_DI           0x01    /* Data in */
219 #define EE_DO           0x02    /* Data out */
220
221 /* Offsets within EEPROM (these are word offsets)
222  */
223 #define EE_MAC 7
224 #define EE_REG  EECtrl
225 static uint32_t SavedClkRun;    
226
227 static const uint8_t nat_ee_bits[] = {
228         [SPI_BIT_SCLK]  = EE_SK,
229         [SPI_BIT_MOSI]  = EE_DI,
230         [SPI_BIT_MISO]  = EE_DO,
231         [SPI_BIT_SS(0)] = EE_CS,
232 };
233
234 static int nat_spi_read_bit ( struct bit_basher *basher,
235                               unsigned int bit_id ) {
236         struct natsemi_nic *nat = container_of ( basher, struct natsemi_nic,
237                                                  spibit.basher );
238         uint8_t mask = nat_ee_bits[bit_id];
239         uint8_t eereg;
240
241         eereg = inb ( nat->ioaddr + EE_REG);
242         return ( eereg & mask );
243 }
244
245 static void nat_spi_write_bit ( struct bit_basher *basher,
246                                 unsigned int bit_id, unsigned long data ) {
247         struct natsemi_nic *nat = container_of ( basher, struct natsemi_nic,
248                                                  spibit.basher );
249         uint8_t mask = nat_ee_bits[bit_id];
250         uint8_t eereg;
251
252         eereg = inb ( nat->ioaddr + EE_REG );
253         eereg &= ~mask;
254         eereg |= ( data & mask );
255         outb ( eereg, nat->ioaddr + EE_REG);
256 }
257
258 static struct bit_basher_operations nat_basher_ops = {
259         .read = nat_spi_read_bit,
260         .write = nat_spi_write_bit,
261 };
262
263 /* It looks that this portion of EEPROM can be used for 
264  * non-volatile stored options. Data sheet does not talk about this region.
265  * Currently it is not working. But with some efforts it can.
266  */
267 static struct nvo_fragment nat_nvo_fragments[] = {
268         { 0x0c, 0x68 },
269         { 0, 0 }
270 };
271
272 /*
273  * Set up for EEPROM access
274  *
275  * @v NAT               NATSEMI NIC
276  */
277  void nat_init_eeprom ( struct natsemi_nic *nat ) {
278
279         /* Initialise three-wire bus 
280          */
281         nat->spibit.basher.op = &nat_basher_ops;
282         nat->spibit.bus.mode = SPI_MODE_THREEWIRE;
283         nat->spibit.endianness = SPI_BIT_LITTLE_ENDIAN;
284         init_spi_bit_basher ( &nat->spibit );
285
286         /*natsemi DP 83815 only supports at93c46
287          */
288         init_at93c46 ( &nat->eeprom, 16 );
289         nat->eeprom.bus = &nat->spibit.bus;
290
291         nat->nvo.nvs = &nat->eeprom.nvs;
292         nat->nvo.fragments = nat_nvo_fragments;
293 }
294
295 /*
296  * Reset NIC
297  *
298  * @v           NATSEMI NIC
299  *
300  * Issues a hardware reset and waits for the reset to complete.
301  */
302 static void nat_reset ( struct natsemi_nic *nat ) {
303
304         int i;
305         /* Reset chip
306          */
307         outl ( ChipReset, nat->ioaddr + ChipCmd );
308         mdelay ( 10 );
309         nat->tx_dirty=0;
310         nat->tx_cur=0;
311         for(i=0;i<TX_RING_SIZE;i++) {
312                 nat->tx[i].link=0;
313                 nat->tx[i].cmdsts=0;
314                 nat->tx[i].bufptr=0;
315         }
316         nat->rx_cur = 0;
317         outl(virt_to_bus(&nat->tx[0]),nat->ioaddr+TxRingPtr);
318         outl(virt_to_bus(&nat->rx[0]), nat->ioaddr + RxRingPtr);
319
320         outl(TxOff|RxOff, nat->ioaddr + ChipCmd);
321
322         /* Restore PME enable bit
323          */
324         outl(SavedClkRun, nat->ioaddr + ClkRun);
325 }
326
327 /*
328  * Open NIC
329  *
330  * @v netdev            Net device
331  * @ret rc              Return status code
332  */
333 static int nat_open ( struct net_device *netdev ) {
334         struct natsemi_nic *nat = netdev->priv;
335         int i;
336         uint32_t tx_config,rx_config;
337         
338         /* Disable PME:
339          * The PME bit is initialized from the EEPROM contents.
340          * PCI cards probably have PME disabled, but motherboard
341          * implementations may have PME set to enable WakeOnLan. 
342          * With PME set the chip will scan incoming packets but
343          * nothing will be written to memory. 
344          */
345         SavedClkRun = inl(nat->ioaddr + ClkRun);
346         outl(SavedClkRun & ~0x100, nat->ioaddr + ClkRun);
347
348         /* Setting up Mac address in the NIC
349          */
350         for ( i = 0 ; i < ETH_ALEN ; i+=2 ) {
351                 outl(i,nat->ioaddr+RxFilterAddr);
352                 outw ( netdev->ll_addr[i] + (netdev->ll_addr[i+1]<<8),
353                          nat->ioaddr +RxFilterData);
354         }
355
356         /*Set up the Tx Ring
357          */
358         nat->tx_cur=0;
359         nat->tx_dirty=0;
360         for (i=0;i<TX_RING_SIZE;i++) {
361                 nat->tx[i].link   = virt_to_bus((i+1 < TX_RING_SIZE) ? &nat->tx[i+1] : &nat->tx[0]);
362                 nat->tx[i].cmdsts = 0;
363                 nat->tx[i].bufptr = 0;
364         }
365
366         /* Set up RX ring
367          */
368         nat->rx_cur=0;
369         for (i=0;i<NUM_RX_DESC;i++) {
370                 nat->iobuf[i] = alloc_iob ( RX_BUF_SIZE );
371                 if (!nat->iobuf[i])
372                         goto memory_alloc_err;
373                 nat->rx[i].link   = virt_to_bus((i+1 < NUM_RX_DESC) ? &nat->rx[i+1] : &nat->rx[0]);
374                 nat->rx[i].cmdsts = RX_BUF_SIZE;
375                 nat->rx[i].bufptr = virt_to_bus(nat->iobuf[i]->data);
376         }
377
378         /* load Receive Descriptor Register
379          */
380         outl(virt_to_bus(&nat->rx[0]), nat->ioaddr + RxRingPtr);
381         DBG("Natsemi Rx descriptor loaded with: %X\n",
382                 (unsigned int)inl(nat->ioaddr+RxRingPtr));              
383
384         /* setup Tx ring
385          */
386         outl(virt_to_bus(&nat->tx[0]),nat->ioaddr+TxRingPtr);
387         DBG("Natsemi Tx descriptor loaded with: %X\n",
388                 (unsigned int)inl(nat->ioaddr+TxRingPtr));
389
390         /* Enables RX
391          */
392         outl(RxFilterEnable|AcceptBroadcast|AcceptAllMulticast|AcceptMyPhys,
393                  nat->ioaddr+RxFilterAddr);
394
395         /* Initialize other registers. 
396          * Configure the PCI bus bursts and FIFO thresholds. 
397          * Configure for standard, in-spec Ethernet. 
398          */
399         if (inl(nat->ioaddr + ChipConfig) & 0x20000000) {       /* Full duplex */
400                 tx_config = 0xD0801002;
401                 rx_config = 0x10000020;
402         } else {
403                 tx_config = 0x10801002;
404                 rx_config = 0x0020;
405         }
406         outl(tx_config, nat->ioaddr + TxConfig);
407         outl(rx_config, nat->ioaddr + RxConfig);
408
409         /*start the receiver 
410          */
411         outl(RxOn, nat->ioaddr + ChipCmd);
412
413         /* mask the interrupts. note interrupt is not enabled here
414          */
415         return 0;
416                        
417 memory_alloc_err:
418         /* this block frees the previously allocated buffers
419          * if memory for all the buffers is not available
420          */
421         i=0;
422         while(nat->rx[i].cmdsts == RX_BUF_SIZE) {
423                 free_iob(nat->iobuf[i]);
424                 i++;
425         }
426         return -ENOMEM; 
427 }
428
429 /**
430  * Close NIC
431  *
432  * @v netdev            Net device
433  */
434 static void nat_close ( struct net_device *netdev ) {
435         struct natsemi_nic *nat = netdev->priv;
436         int i;
437         /* Reset the hardware to disable everything in one go
438          */
439         nat_reset ( nat );
440
441         /* Free RX ring
442          */
443         for (i=0;i<NUM_RX_DESC;i++) {
444                 
445                 free_iob( nat->iobuf[i] );
446         }
447 }
448
449 /** 
450  * Transmit packet
451  *
452  * @v netdev    Network device
453  * @v iobuf     I/O buffer
454  * @ret rc      Return status code
455  */
456 static int nat_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
457         struct natsemi_nic *nat = netdev->priv;
458
459         /* check for space in TX ring
460          */
461         if (nat->tx[nat->tx_cur].cmdsts !=0) {
462                 DBG( "TX overflow\n" );
463                 return -ENOBUFS;
464         }
465
466         /* to be used in netdev_tx_complete
467          */
468         nat->tx_iobuf[nat->tx_cur]=iobuf;
469
470         /* Pad and align packet has not been used because its not required here
471          * iob_pad ( iobuf, ETH_ZLEN ); can be used to achieve it
472          */
473
474         /* Add to TX ring
475          */
476         DBG ( "TX id %d at %lx+%x\n", nat->tx_cur,
477               virt_to_bus ( &iobuf->data ), iob_len ( iobuf ) );
478
479         nat->tx[nat->tx_cur].bufptr = virt_to_bus(iobuf->data);
480         nat->tx[nat->tx_cur].cmdsts= iob_len(iobuf)|OWN;
481         /* increment the circular buffer pointer to the next buffer location
482          */
483         nat->tx_cur=(nat->tx_cur+1) % TX_RING_SIZE;
484
485         /*start the transmitter 
486          */
487         outl(TxOn, nat->ioaddr + ChipCmd);
488
489         return 0;
490 }
491
492 /** 
493  * Poll for received packets
494  *
495  * @v netdev    Network device
496  * @v rx_quota  Maximum number of packets to receive
497  */
498 static void nat_poll ( struct net_device *netdev) {
499         struct natsemi_nic *nat = netdev->priv;
500         unsigned int status;
501         unsigned int rx_status;
502         unsigned int intr_status;
503         unsigned int rx_len;
504         struct io_buffer *rx_iob;
505         int i;
506         
507         /* read the interrupt register
508          */
509         intr_status=inl(nat->ioaddr+IntrStatus);
510         if(!intr_status)
511         goto end;
512
513         /* check the status of packets given to card for transmission
514          */     
515         DBG("Intr status %X\n",intr_status);
516
517         i=nat->tx_dirty;
518         while(i!=nat->tx_cur) {
519                 status=nat->tx[nat->tx_dirty].cmdsts;
520                 DBG("value of tx_dirty = %d tx_cur=%d status=%X\n",
521                         nat->tx_dirty,nat->tx_cur,status);
522                 
523                 /* check if current packet has been transmitted or not
524                  */
525                 if(status & OWN) 
526                         break;
527                 /* Check if any errors in transmission
528                  */
529                 if (! (status & DescPktOK)) {
530                         DBG("Error in sending Packet status:%X\n",
531                                         (unsigned int)status);
532                         netdev_tx_complete_err(netdev,nat->tx_iobuf[nat->tx_dirty],-EINVAL);
533                 } else {
534                         DBG("Success in transmitting Packet\n");
535                         netdev_tx_complete(netdev,nat->tx_iobuf[nat->tx_dirty]);
536                 }
537                 /* setting cmdsts zero, indicating that it can be reused 
538                  */
539                 nat->tx[nat->tx_dirty].cmdsts=0;
540                 nat->tx_dirty=(nat->tx_dirty +1) % TX_RING_SIZE;
541                 i=(i+1) % TX_RING_SIZE;
542         }
543         
544         /* Handle received packets 
545          */
546         rx_status=(unsigned int)nat->rx[nat->rx_cur].cmdsts; 
547         while ((rx_status & OWN)) {
548                 rx_len= (rx_status & DSIZE) - CRC_SIZE;
549                 /*check for the corrupt packet 
550                  */
551                 if((rx_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK) {
552                          DBG("natsemi_poll: Corrupted packet received, "
553                                         "buffer status = %X ^ %X \n",rx_status,
554                                         (unsigned int) nat->rx[nat->rx_cur].cmdsts);
555                          netdev_rx_err(netdev,NULL,-EINVAL);
556                 } else  {
557                         rx_iob = alloc_iob(rx_len);
558                         if(!rx_iob) 
559                                 /* leave packet for next call to poll
560                                  */
561                                 goto end;
562                         memcpy(iob_put(rx_iob,rx_len),
563                                         nat->iobuf[nat->rx_cur]->data,rx_len);
564                         DBG("received packet\n");
565                         /* add to the receive queue. 
566                          */
567                         netdev_rx(netdev,rx_iob);
568                 }
569                 nat->rx[nat->rx_cur].cmdsts = RX_BUF_SIZE;
570                 nat->rx_cur=(nat->rx_cur+1) % NUM_RX_DESC;
571                 rx_status=nat->rx[nat->rx_cur].cmdsts; 
572         }
573 end:
574         /* re-enable the potentially idle receive state machine 
575          */
576         outl(RxOn, nat->ioaddr + ChipCmd);      
577 }                               
578
579 /**
580  * Enable/disable interrupts
581  *
582  * @v netdev    Network device
583  * @v enable    Interrupts should be enabled
584  */
585 static void nat_irq ( struct net_device *netdev, int enable ) {
586         struct natsemi_nic *nat= netdev->priv;
587
588         outl((enable?(RxOk|RxErr|TxOk|TxErr):0),
589                 nat->ioaddr + IntrMask); 
590         outl((enable ? 1:0),nat->ioaddr +IntrEnable);
591 }
592
593
594
595
596
597 /** natsemi net device operations */
598 static struct net_device_operations nat_operations = {
599         .open           = nat_open,
600         .close          = nat_close,
601         .transmit       = nat_transmit,
602         .poll           = nat_poll,
603         .irq            = nat_irq,
604 };
605
606 /*
607  * Probe PCI device
608  *
609  * @v pci       PCI device
610  * @v id        PCI ID
611  * @ret rc      Return status code
612  */
613 static int nat_probe ( struct pci_device *pci,
614                        const struct pci_device_id *id __unused ) {
615         struct net_device *netdev;
616         struct natsemi_nic *nat = NULL;
617         int rc;
618         int i;
619         uint8_t ll_addr_encoded[MAX_LL_ADDR_LEN];
620         uint8_t last=0;
621         uint8_t last1=0;
622         uint8_t prev_bytes[2];
623
624         /* Allocate net device 
625          */
626         netdev = alloc_etherdev ( sizeof ( *nat ) );
627         if ( ! netdev ) 
628                 return -ENOMEM;
629         netdev_init(netdev,&nat_operations);
630         nat = netdev->priv;
631         pci_set_drvdata ( pci, netdev );
632         netdev->dev = &pci->dev;
633         memset ( nat, 0, sizeof ( *nat ) );
634         nat->ioaddr = pci->ioaddr;
635
636         /* Fix up PCI device
637          */
638         adjust_pci_device ( pci );
639
640         /* Reset the NIC, set up EEPROM access and read MAC address
641          */
642         nat_reset ( nat );
643         nat_init_eeprom ( nat );
644         nvs_read ( &nat->eeprom.nvs, EE_MAC-1, prev_bytes, 1);
645         nvs_read ( &nat->eeprom.nvs, EE_MAC, ll_addr_encoded, ETH_ALEN );
646         /* decoding the MAC address read from NVS 
647          * and save it in netdev->ll_addr
648          */
649         last=prev_bytes[1]>>7;
650         for ( i = 0 ; i < ETH_ALEN ; i++) {
651                 last1=ll_addr_encoded[i]>>7;
652                 netdev->ll_addr[i]=ll_addr_encoded[i]<<1|last;
653                 last=last1;
654         }
655
656         /* Register network device
657          */
658         if ( ( rc = register_netdev ( netdev ) ) != 0 )
659                 goto err_register_netdev;
660
661         return 0;
662
663 err_register_netdev:
664         /* Disable NIC
665          */
666         nat_reset ( nat );
667         /* Free net device
668          */
669         netdev_put ( netdev );
670         return rc;
671 }
672
673 /**
674  * Remove PCI device
675  *
676  * @v pci       PCI device
677  */
678 static void nat_remove ( struct pci_device *pci ) {
679         struct net_device *netdev = pci_get_drvdata ( pci );
680         struct natsemi_nic *nat = netdev->priv;
681  
682         if ( nat->nvo.nvs )
683                 nvo_unregister ( &nat->nvo );
684                 
685         unregister_netdev ( netdev );
686         nat_reset ( nat );
687         netdev_put ( netdev );
688 }
689
690 static struct pci_device_id natsemi_nics[] = {
691         PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815"),
692 };
693
694 struct pci_driver natsemi_driver __pci_driver = {
695         .ids = natsemi_nics,
696         .id_count = ( sizeof ( natsemi_nics ) / sizeof ( natsemi_nics[0] ) ),
697         .probe = nat_probe,
698         .remove = nat_remove,
699 };