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