1 /*---------------------------------------------------------------------------
2 FT1000 driver for Flarion Flash OFDM NIC Device
4 Copyright (C) 2002 Flarion Technologies, All rights reserved.
5 Copyright (C) 2006 Patrik Ostrihon, All rights reserved.
6 Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved.
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2 of the License, or (at your option) any
11 later version. This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 more details. You should have received a copy of the GNU General Public
15 License along with this program; if not, write to the
16 Free Software Foundation, Inc., 59 Temple Place -
17 Suite 330, Boston, MA 02111-1307, USA.
18 -------------------------------------------------------------------------*/
20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/sched.h>
25 #include <linux/ptrace.h>
26 #include <linux/slab.h>
27 #include <linux/string.h>
28 #include <linux/timer.h>
29 #include <linux/interrupt.h>
32 #include <asm/bitops.h>
34 #include <linux/netdevice.h>
35 #include <linux/etherdevice.h>
36 #include <linux/skbuff.h>
37 #include <linux/if_arp.h>
38 #include <linux/ioport.h>
39 #include <linux/wait.h>
40 #include <linux/vmalloc.h>
42 #include <linux/firmware.h>
43 #include <linux/ethtool.h>
45 #include <pcmcia/cistpl.h>
46 #include <pcmcia/cisreg.h>
47 #include <pcmcia/ds.h>
49 #include <linux/delay.h>
52 static const struct firmware *fw_entry;
54 static void ft1000_hbchk(u_long data);
55 static struct timer_list poll_timer = {
56 .function = ft1000_hbchk
59 static u16 cmdbuffer[1024];
60 static u8 tempbuffer[1600];
61 static u8 ft1000_card_present;
62 static u8 flarion_ft1000_cnt;
64 static irqreturn_t ft1000_interrupt(int irq, void *dev_id);
65 static void ft1000_enable_interrupts(struct net_device *dev);
66 static void ft1000_disable_interrupts(struct net_device *dev);
71 ("Support for Flarion Flash OFDM NIC Device. Support for PCMCIA when used with ft1000_cs.");
72 MODULE_LICENSE("GPL");
73 MODULE_SUPPORTED_DEVICE("FT1000");
75 #define MAX_RCV_LOOP 100
77 /*---------------------------------------------------------------------------
79 Function: ft1000_read_fifo_len
80 Description: This function will read the ASIC Uplink FIFO status register
81 which will return the number of bytes remaining in the Uplink FIFO.
82 Sixteen bytes are subtracted to make sure that the ASIC does not
85 dev - network device structure
87 value - number of bytes available in the ASIC Uplink FIFO.
89 -------------------------------------------------------------------------*/
90 static inline u16 ft1000_read_fifo_len(struct net_device *dev)
92 struct ft1000_info *info = netdev_priv(dev);
94 if (info->AsicID == ELECTRABUZZ_ID)
95 return (ft1000_read_reg(dev, FT1000_REG_UFIFO_STAT) - 16);
97 return (ft1000_read_reg(dev, FT1000_REG_MAG_UFSR) - 16);
100 /*---------------------------------------------------------------------------
102 Function: ft1000_read_dpram
103 Description: This function will read the specific area of dpram
104 (Electrabuzz ASIC only)
106 dev - device structure
107 offset - index of dpram
109 value - value of dpram
111 -------------------------------------------------------------------------*/
112 u16 ft1000_read_dpram(struct net_device *dev, int offset)
114 struct ft1000_info *info = netdev_priv(dev);
118 /* Provide mutual exclusive access while reading ASIC registers. */
119 spin_lock_irqsave(&info->dpram_lock, flags);
120 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
121 data = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
122 spin_unlock_irqrestore(&info->dpram_lock, flags);
127 /*---------------------------------------------------------------------------
129 Function: ft1000_write_dpram
130 Description: This function will write to a specific area of dpram
131 (Electrabuzz ASIC only)
133 dev - device structure
134 offset - index of dpram
135 value - value to write
139 -------------------------------------------------------------------------*/
140 static inline void ft1000_write_dpram(struct net_device *dev,
141 int offset, u16 value)
143 struct ft1000_info *info = netdev_priv(dev);
146 /* Provide mutual exclusive access while reading ASIC registers. */
147 spin_lock_irqsave(&info->dpram_lock, flags);
148 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
149 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, value);
150 spin_unlock_irqrestore(&info->dpram_lock, flags);
153 /*---------------------------------------------------------------------------
155 Function: ft1000_read_dpram_mag_16
156 Description: This function will read the specific area of dpram
157 (Magnemite ASIC only)
159 dev - device structure
160 offset - index of dpram
162 value - value of dpram
164 -------------------------------------------------------------------------*/
165 u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index)
167 struct ft1000_info *info = netdev_priv(dev);
171 /* Provide mutual exclusive access while reading ASIC registers. */
172 spin_lock_irqsave(&info->dpram_lock, flags);
173 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
174 /* check if we want to read upper or lower 32-bit word */
176 data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAL);
178 data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAH);
180 spin_unlock_irqrestore(&info->dpram_lock, flags);
185 /*---------------------------------------------------------------------------
187 Function: ft1000_write_dpram_mag_16
188 Description: This function will write to a specific area of dpram
189 (Magnemite ASIC only)
191 dev - device structure
192 offset - index of dpram
193 value - value to write
197 -------------------------------------------------------------------------*/
198 static inline void ft1000_write_dpram_mag_16(struct net_device *dev,
199 int offset, u16 value, int Index)
201 struct ft1000_info *info = netdev_priv(dev);
204 /* Provide mutual exclusive access while reading ASIC registers. */
205 spin_lock_irqsave(&info->dpram_lock, flags);
206 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
208 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAL, value);
210 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, value);
212 spin_unlock_irqrestore(&info->dpram_lock, flags);
215 /*---------------------------------------------------------------------------
217 Function: ft1000_read_dpram_mag_32
218 Description: This function will read the specific area of dpram
219 (Magnemite ASIC only)
221 dev - device structure
222 offset - index of dpram
224 value - value of dpram
226 -------------------------------------------------------------------------*/
227 u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset)
229 struct ft1000_info *info = netdev_priv(dev);
233 /* Provide mutual exclusive access while reading ASIC registers. */
234 spin_lock_irqsave(&info->dpram_lock, flags);
235 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
236 data = inl(dev->base_addr + FT1000_REG_MAG_DPDATAL);
237 spin_unlock_irqrestore(&info->dpram_lock, flags);
242 /*---------------------------------------------------------------------------
244 Function: ft1000_write_dpram_mag_32
245 Description: This function will write to a specific area of dpram
246 (Magnemite ASIC only)
248 dev - device structure
249 offset - index of dpram
250 value - value to write
254 -------------------------------------------------------------------------*/
255 void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value)
257 struct ft1000_info *info = netdev_priv(dev);
260 /* Provide mutual exclusive access while reading ASIC registers. */
261 spin_lock_irqsave(&info->dpram_lock, flags);
262 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
263 outl(value, dev->base_addr + FT1000_REG_MAG_DPDATAL);
264 spin_unlock_irqrestore(&info->dpram_lock, flags);
267 /*---------------------------------------------------------------------------
269 Function: ft1000_enable_interrupts
270 Description: This function will enable interrupts base on the current interrupt mask.
272 dev - device structure
276 -------------------------------------------------------------------------*/
277 static void ft1000_enable_interrupts(struct net_device *dev)
281 ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_DEFAULT_MASK);
282 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
283 pr_debug("current interrupt enable mask = 0x%x\n", tempword);
286 /*---------------------------------------------------------------------------
288 Function: ft1000_disable_interrupts
289 Description: This function will disable all interrupts.
291 dev - device structure
295 -------------------------------------------------------------------------*/
296 static void ft1000_disable_interrupts(struct net_device *dev)
300 ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_MASK_ALL);
301 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
302 pr_debug("current interrupt enable mask = 0x%x\n", tempword);
305 /*---------------------------------------------------------------------------
307 Function: ft1000_reset_asic
308 Description: This function will call the Card Service function to reset the
311 dev - device structure
315 -------------------------------------------------------------------------*/
316 static void ft1000_reset_asic(struct net_device *dev)
318 struct ft1000_info *info = netdev_priv(dev);
319 struct ft1000_pcmcia *pcmcia = info->priv;
322 (*info->ft1000_reset) (pcmcia->link);
325 * Let's use the register provided by the Magnemite ASIC to reset the
328 if (info->AsicID == MAGNEMITE_ID) {
329 ft1000_write_reg(dev, FT1000_REG_RESET,
330 (DSP_RESET_BIT | ASIC_RESET_BIT));
333 if (info->AsicID == ELECTRABUZZ_ID) {
334 /* set watermark to -1 in order to not generate an interrupt */
335 ft1000_write_reg(dev, FT1000_REG_WATERMARK, 0xffff);
337 /* set watermark to -1 in order to not generate an interrupt */
338 ft1000_write_reg(dev, FT1000_REG_MAG_WATERMARK, 0xffff);
340 /* clear interrupts */
341 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
342 pr_debug("interrupt status register = 0x%x\n", tempword);
343 ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword);
344 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
345 pr_debug("interrupt status register = 0x%x\n", tempword);
349 /*---------------------------------------------------------------------------
351 Function: ft1000_reset_card
352 Description: This function will reset the card
354 dev - device structure
356 status - false (card reset fail)
357 true (card reset successful)
359 -------------------------------------------------------------------------*/
360 static int ft1000_reset_card(struct net_device *dev)
362 struct ft1000_info *info = netdev_priv(dev);
366 struct prov_record *ptr;
369 info->ProgConStat = 0;
370 info->squeseqnum = 0;
371 ft1000_disable_interrupts(dev);
373 /* del_timer(&poll_timer); */
375 /* Make sure we free any memory reserve for provisioning */
376 while (list_empty(&info->prov_list) == 0) {
377 pr_debug("deleting provisioning record\n");
378 ptr = list_entry(info->prov_list.next, struct prov_record, list);
379 list_del(&ptr->list);
380 kfree(ptr->pprov_data);
384 if (info->AsicID == ELECTRABUZZ_ID) {
385 pr_debug("resetting DSP\n");
386 ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
388 pr_debug("resetting ASIC and DSP\n");
389 ft1000_write_reg(dev, FT1000_REG_RESET,
390 (DSP_RESET_BIT | ASIC_RESET_BIT));
393 /* Copy DSP session record into info block if this is not a coldstart */
394 if (ft1000_card_present == 1) {
395 spin_lock_irqsave(&info->dpram_lock, flags);
396 if (info->AsicID == ELECTRABUZZ_ID) {
397 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
398 FT1000_DPRAM_RX_BASE);
399 for (i = 0; i < MAX_DSP_SESS_REC; i++) {
400 info->DSPSess.Rec[i] =
402 FT1000_REG_DPRAM_DATA);
405 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
406 FT1000_DPRAM_MAG_RX_BASE);
407 for (i = 0; i < MAX_DSP_SESS_REC / 2; i++) {
408 info->DSPSess.MagRec[i] =
409 inl(dev->base_addr + FT1000_REG_MAG_DPDATA);
412 spin_unlock_irqrestore(&info->dpram_lock, flags);
415 pr_debug("resetting ASIC\n");
418 ft1000_reset_asic(dev);
420 pr_debug("downloading dsp image\n");
422 if (info->AsicID == MAGNEMITE_ID) {
423 /* Put dsp in reset and take ASIC out of reset */
424 pr_debug("Put DSP in reset and take ASIC out of reset\n");
425 ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
427 /* Setting MAGNEMITE ASIC to big endian mode */
428 ft1000_write_reg(dev, FT1000_REG_SUP_CTRL, HOST_INTF_BE);
429 /* Download bootloader */
432 /* Take DSP out of reset */
433 ft1000_write_reg(dev, FT1000_REG_RESET, 0);
434 /* FLARION_DSP_ACTIVE; */
436 pr_debug("Take DSP out of reset\n");
438 /* Wait for 0xfefe indicating dsp ready before starting download */
439 for (i = 0; i < 50; i++) {
441 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DPRAM_FEFE,
442 FT1000_MAG_DPRAM_FEFE_INDX);
443 if (tempword == 0xfefe) {
450 pr_debug("No FEFE detected from DSP\n");
455 /* Take DSP out of reset */
456 ft1000_write_reg(dev, FT1000_REG_RESET, ~DSP_RESET_BIT);
460 if (card_download(dev, fw_entry->data, fw_entry->size)) {
461 pr_debug("card download unsuccessful\n");
464 pr_debug("card download successful\n");
469 if (info->AsicID == ELECTRABUZZ_ID) {
471 * Need to initialize the FIFO length counter to zero in order to sync up
475 ft1000_write_dpram(dev, FT1000_FIFO_LEN, info->fifo_cnt);
476 /* Initialize DSP heartbeat area to ho */
477 ft1000_write_dpram(dev, FT1000_HI_HO, ho);
478 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
479 pr_debug("hi_ho value = 0x%x\n", tempword);
481 /* Initialize DSP heartbeat area to ho */
482 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, ho_mag,
483 FT1000_MAG_HI_HO_INDX);
485 ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO,
486 FT1000_MAG_HI_HO_INDX);
487 pr_debug("hi_ho value = 0x%x\n", tempword);
491 ft1000_enable_interrupts(dev);
493 /* Schedule heartbeat process to run every 2 seconds */
494 /* poll_timer.expires = jiffies + (2*HZ); */
495 /* poll_timer.data = (u_long)dev; */
496 /* add_timer(&poll_timer); */
502 /*---------------------------------------------------------------------------
504 Function: ft1000_chkcard
505 Description: This function will check if the device is presently available on
508 dev - device structure
510 status - false (device is not present)
511 true (device is present)
513 -------------------------------------------------------------------------*/
514 static int ft1000_chkcard(struct net_device *dev)
519 * Mask register is used to check for device presence since it is never
522 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
524 pr_debug("IMASK = 0 Card not detected\n");
528 * The system will return the value of 0xffff for the version register
529 * if the device is not present.
531 tempword = ft1000_read_reg(dev, FT1000_REG_ASIC_ID);
532 if (tempword == 0xffff) {
533 pr_debug("Version = 0xffff Card not detected\n");
540 /*---------------------------------------------------------------------------
542 Function: ft1000_hbchk
543 Description: This function will perform the heart beat check of the DSP as
546 dev - device structure
550 -------------------------------------------------------------------------*/
551 static void ft1000_hbchk(u_long data)
553 struct net_device *dev = (struct net_device *)data;
555 struct ft1000_info *info;
558 info = netdev_priv(dev);
560 if (info->CardReady == 1) {
561 /* Perform dsp heartbeat check */
562 if (info->AsicID == ELECTRABUZZ_ID) {
563 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
566 ntohs(ft1000_read_dpram_mag_16
567 (dev, FT1000_MAG_HI_HO,
568 FT1000_MAG_HI_HO_INDX));
570 pr_debug("hi_ho value = 0x%x\n", tempword);
571 /* Let's perform another check if ho is not detected */
572 if (tempword != ho) {
573 if (info->AsicID == ELECTRABUZZ_ID) {
574 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
577 tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX));
580 if (tempword != ho) {
581 pr_info("heartbeat failed - no ho detected\n");
582 if (info->AsicID == ELECTRABUZZ_ID) {
584 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
586 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
588 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
590 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
593 ft1000_read_dpram_mag_16(dev,
594 FT1000_MAG_DSP_TIMER0,
595 FT1000_MAG_DSP_TIMER0_INDX);
597 ft1000_read_dpram_mag_16(dev,
598 FT1000_MAG_DSP_TIMER1,
599 FT1000_MAG_DSP_TIMER1_INDX);
601 ft1000_read_dpram_mag_16(dev,
602 FT1000_MAG_DSP_TIMER2,
603 FT1000_MAG_DSP_TIMER2_INDX);
605 ft1000_read_dpram_mag_16(dev,
606 FT1000_MAG_DSP_TIMER3,
607 FT1000_MAG_DSP_TIMER3_INDX);
609 info->DrvErrNum = DSP_HB_INFO;
610 if (ft1000_reset_card(dev) == 0) {
611 pr_info("Hardware Failure Detected - PC Card disabled\n");
612 info->ProgConStat = 0xff;
615 /* Schedule this module to run every 2 seconds */
616 poll_timer.expires = jiffies + (2*HZ);
617 poll_timer.data = (u_long)dev;
618 add_timer(&poll_timer);
622 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
623 /* Let's check doorbell again if fail */
624 if (tempword & FT1000_DB_HB) {
625 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
627 if (tempword & FT1000_DB_HB) {
628 pr_info("heartbeat doorbell not clear by firmware\n");
629 if (info->AsicID == ELECTRABUZZ_ID) {
631 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
633 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
635 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
637 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
640 ft1000_read_dpram_mag_16(dev,
641 FT1000_MAG_DSP_TIMER0,
642 FT1000_MAG_DSP_TIMER0_INDX);
644 ft1000_read_dpram_mag_16(dev,
645 FT1000_MAG_DSP_TIMER1,
646 FT1000_MAG_DSP_TIMER1_INDX);
648 ft1000_read_dpram_mag_16(dev,
649 FT1000_MAG_DSP_TIMER2,
650 FT1000_MAG_DSP_TIMER2_INDX);
652 ft1000_read_dpram_mag_16(dev,
653 FT1000_MAG_DSP_TIMER3,
654 FT1000_MAG_DSP_TIMER3_INDX);
656 info->DrvErrNum = DSP_HB_INFO;
657 if (ft1000_reset_card(dev) == 0) {
658 pr_info("Hardware Failure Detected - PC Card disabled\n");
659 info->ProgConStat = 0xff;
662 /* Schedule this module to run every 2 seconds */
663 poll_timer.expires = jiffies + (2*HZ);
664 poll_timer.data = (u_long)dev;
665 add_timer(&poll_timer);
669 * Set dedicated area to hi and ring appropriate doorbell according
670 * to hi/ho heartbeat protocol
672 if (info->AsicID == ELECTRABUZZ_ID) {
673 ft1000_write_dpram(dev, FT1000_HI_HO, hi);
675 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag,
676 FT1000_MAG_HI_HO_INDX);
679 if (info->AsicID == ELECTRABUZZ_ID) {
680 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
683 ntohs(ft1000_read_dpram_mag_16
684 (dev, FT1000_MAG_HI_HO,
685 FT1000_MAG_HI_HO_INDX));
687 /* Let's write hi again if fail */
688 if (tempword != hi) {
689 if (info->AsicID == ELECTRABUZZ_ID) {
690 ft1000_write_dpram(dev, FT1000_HI_HO, hi);
693 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag, FT1000_MAG_HI_HO_INDX);
696 if (info->AsicID == ELECTRABUZZ_ID) {
697 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
700 tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX));
705 if (tempword != hi) {
706 pr_info("heartbeat failed - cannot write hi into DPRAM\n");
707 if (info->AsicID == ELECTRABUZZ_ID) {
709 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
711 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
713 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
715 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
718 ft1000_read_dpram_mag_16(dev,
719 FT1000_MAG_DSP_TIMER0,
720 FT1000_MAG_DSP_TIMER0_INDX);
722 ft1000_read_dpram_mag_16(dev,
723 FT1000_MAG_DSP_TIMER1,
724 FT1000_MAG_DSP_TIMER1_INDX);
726 ft1000_read_dpram_mag_16(dev,
727 FT1000_MAG_DSP_TIMER2,
728 FT1000_MAG_DSP_TIMER2_INDX);
730 ft1000_read_dpram_mag_16(dev,
731 FT1000_MAG_DSP_TIMER3,
732 FT1000_MAG_DSP_TIMER3_INDX);
734 info->DrvErrNum = DSP_HB_INFO;
735 if (ft1000_reset_card(dev) == 0) {
736 pr_info("Hardware Failure Detected - PC Card disabled\n");
737 info->ProgConStat = 0xff;
740 /* Schedule this module to run every 2 seconds */
741 poll_timer.expires = jiffies + (2*HZ);
742 poll_timer.data = (u_long)dev;
743 add_timer(&poll_timer);
746 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_HB);
750 /* Schedule this module to run every 2 seconds */
751 poll_timer.expires = jiffies + (2 * HZ);
752 poll_timer.data = (u_long)dev;
753 add_timer(&poll_timer);
756 /*---------------------------------------------------------------------------
758 Function: ft1000_send_cmd
763 -------------------------------------------------------------------------*/
764 static void ft1000_send_cmd(struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype)
766 struct ft1000_info *info = netdev_priv(dev);
771 size += sizeof(struct pseudo_hdr);
772 /* check for odd byte and increment to 16-bit word align value */
773 if ((size & 0x0001)) {
776 pr_debug("total length = %d\n", size);
777 pr_debug("length = %d\n", ntohs(*ptempbuffer));
779 * put message into slow queue area
780 * All messages are in the form total_len + pseudo header + message body
782 spin_lock_irqsave(&info->dpram_lock, flags);
784 /* Make sure SLOWQ doorbell is clear */
785 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
787 while (tempword & FT1000_DB_DPRAM_TX) {
791 spin_unlock_irqrestore(&info->dpram_lock, flags);
794 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
797 if (info->AsicID == ELECTRABUZZ_ID) {
798 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
799 FT1000_DPRAM_TX_BASE);
800 /* Write total length to dpram */
801 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, size);
802 /* Write pseudo header and messgae body */
803 for (i = 0; i < (size >> 1); i++) {
804 pr_debug("data %d = 0x%x\n", i, *ptempbuffer);
805 tempword = htons(*ptempbuffer++);
806 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, tempword);
809 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
810 FT1000_DPRAM_MAG_TX_BASE);
811 /* Write total length to dpram */
812 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, htons(size));
813 /* Write pseudo header and messgae body */
814 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
815 FT1000_DPRAM_MAG_TX_BASE + 1);
816 for (i = 0; i < (size >> 2); i++) {
817 pr_debug("data = 0x%x\n", *ptempbuffer);
819 dev->base_addr + FT1000_REG_MAG_DPDATAL);
820 pr_debug("data = 0x%x\n", *ptempbuffer);
822 dev->base_addr + FT1000_REG_MAG_DPDATAH);
824 pr_debug("data = 0x%x\n", *ptempbuffer);
825 outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAL);
826 pr_debug("data = 0x%x\n", *ptempbuffer);
827 outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAH);
829 spin_unlock_irqrestore(&info->dpram_lock, flags);
831 /* ring doorbell to notify DSP that we have a message ready */
832 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_TX);
835 /*---------------------------------------------------------------------------
837 Function: ft1000_receive_cmd
838 Description: This function will read a message from the dpram area.
840 dev - network device structure
841 pbuffer - caller supply address to buffer
842 pnxtph - pointer to next pseudo header
844 Status = 0 (unsuccessful)
847 -------------------------------------------------------------------------*/
848 static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer,
849 int maxsz, u16 *pnxtph)
851 struct ft1000_info *info = netdev_priv(dev);
858 if (info->AsicID == ELECTRABUZZ_ID) {
859 size = (ft1000_read_dpram(dev, *pnxtph)) + sizeof(struct pseudo_hdr);
862 ntohs(ft1000_read_dpram_mag_16
863 (dev, FT1000_MAG_PH_LEN,
864 FT1000_MAG_PH_LEN_INDX)) + sizeof(struct pseudo_hdr);
867 pr_debug("Invalid command length = %d\n", size);
870 ppseudohdr = (u16 *)pbuffer;
871 spin_lock_irqsave(&info->dpram_lock, flags);
872 if (info->AsicID == ELECTRABUZZ_ID) {
873 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
874 FT1000_DPRAM_RX_BASE + 2);
875 for (i = 0; i <= (size >> 1); i++) {
877 ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
878 *pbuffer++ = ntohs(tempword);
881 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
882 FT1000_DPRAM_MAG_RX_BASE);
883 *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH);
884 pr_debug("received data = 0x%x\n", *pbuffer);
886 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
887 FT1000_DPRAM_MAG_RX_BASE + 1);
888 for (i = 0; i <= (size >> 2); i++) {
891 FT1000_REG_MAG_DPDATAL);
895 FT1000_REG_MAG_DPDATAH);
898 /* copy odd aligned word */
899 *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAL);
900 pr_debug("received data = 0x%x\n", *pbuffer);
902 *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH);
903 pr_debug("received data = 0x%x\n", *pbuffer);
907 /* copy odd byte from fifo */
908 tempword = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
909 *pbuffer = ntohs(tempword);
911 spin_unlock_irqrestore(&info->dpram_lock, flags);
914 * Check if pseudo header checksum is good
915 * Calculate pseudo header checksum
917 tempword = *ppseudohdr++;
918 for (i = 1; i < 7; i++) {
919 tempword ^= *ppseudohdr++;
921 if ((tempword != *ppseudohdr)) {
922 pr_debug("Pseudo header checksum mismatch\n");
923 /* Drop this message */
930 /*---------------------------------------------------------------------------
932 Function: ft1000_proc_drvmsg
933 Description: This function will process the various driver messages.
935 dev - device structure
936 pnxtph - pointer to next pseudo header
940 -------------------------------------------------------------------------*/
941 static void ft1000_proc_drvmsg(struct net_device *dev)
943 struct ft1000_info *info = netdev_priv(dev);
946 struct media_msg *pmediamsg;
947 struct dsp_init_msg *pdspinitmsg;
948 struct drv_msg *pdrvmsg;
951 struct prov_record *ptr;
952 struct pseudo_hdr *ppseudo_hdr;
960 if (info->AsicID == ELECTRABUZZ_ID) {
961 tempword = FT1000_DPRAM_RX_BASE+2;
964 tempword = FT1000_DPRAM_MAG_RX_BASE;
966 if (ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword)) {
968 /* Get the message type which is total_len + PSEUDO header + msgtype + message body */
969 pdrvmsg = (struct drv_msg *)&cmdbuffer[0];
970 msgtype = ntohs(pdrvmsg->type);
971 pr_debug("Command message type = 0x%x\n", msgtype);
974 pr_debug("Got a provisioning request message from DSP\n");
976 while (list_empty(&info->prov_list) == 0) {
977 pr_debug("Sending a provisioning message\n");
978 /* Make sure SLOWQ doorbell is clear */
980 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
982 while (tempword & FT1000_DB_DPRAM_TX) {
990 list_entry(info->prov_list.next,
991 struct prov_record, list);
992 len = *(u16 *)ptr->pprov_data;
995 pmsg = (u16 *)ptr->pprov_data;
996 ppseudo_hdr = (struct pseudo_hdr *)pmsg;
997 /* Insert slow queue sequence number */
998 ppseudo_hdr->seq_num = info->squeseqnum++;
999 ppseudo_hdr->portsrc = 0;
1000 /* Calculate new checksum */
1001 ppseudo_hdr->checksum = *pmsg++;
1002 pr_debug("checksum = 0x%x\n",
1003 ppseudo_hdr->checksum);
1004 for (i = 1; i < 7; i++) {
1005 ppseudo_hdr->checksum ^= *pmsg++;
1006 pr_debug("checksum = 0x%x\n",
1007 ppseudo_hdr->checksum);
1010 ft1000_send_cmd(dev, (u16 *)ptr->pprov_data, len, SLOWQ_TYPE);
1011 list_del(&ptr->list);
1012 kfree(ptr->pprov_data);
1016 * Indicate adapter is ready to take application messages after all
1017 * provisioning messages are sent
1019 info->CardReady = 1;
1022 pmediamsg = (struct media_msg *)&cmdbuffer[0];
1023 if (info->ProgConStat != 0xFF) {
1024 if (pmediamsg->state) {
1025 pr_debug("Media is up\n");
1026 if (info->mediastate == 0) {
1027 netif_carrier_on(dev);
1028 netif_wake_queue(dev);
1029 info->mediastate = 1;
1030 do_gettimeofday(&tv);
1031 info->ConTm = tv.tv_sec;
1034 pr_debug("Media is down\n");
1035 if (info->mediastate == 1) {
1036 info->mediastate = 0;
1037 netif_carrier_off(dev);
1038 netif_stop_queue(dev);
1044 pr_debug("Media is down\n");
1045 if (info->mediastate == 1) {
1046 info->mediastate = 0;
1047 netif_carrier_off(dev);
1048 netif_stop_queue(dev);
1054 pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[0];
1055 memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ);
1056 pr_debug("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n",
1057 info->DspVer[0], info->DspVer[1],
1058 info->DspVer[2], info->DspVer[3]);
1059 memcpy(info->HwSerNum, pdspinitmsg->HwSerNum,
1061 memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ);
1062 memcpy(info->eui64, pdspinitmsg->eui64, EUISZ);
1063 dev->dev_addr[0] = info->eui64[0];
1064 dev->dev_addr[1] = info->eui64[1];
1065 dev->dev_addr[2] = info->eui64[2];
1066 dev->dev_addr[3] = info->eui64[5];
1067 dev->dev_addr[4] = info->eui64[6];
1068 dev->dev_addr[5] = info->eui64[7];
1070 if (ntohs(pdspinitmsg->length) ==
1071 (sizeof(struct dsp_init_msg) - 20)) {
1072 memcpy(info->ProductMode,
1073 pdspinitmsg->ProductMode, MODESZ);
1074 memcpy(info->RfCalVer, pdspinitmsg->RfCalVer,
1076 memcpy(info->RfCalDate, pdspinitmsg->RfCalDate,
1078 pr_debug("RFCalVer = 0x%2x 0x%2x\n",
1079 info->RfCalVer[0], info->RfCalVer[1]);
1083 case DSP_STORE_INFO:
1084 pr_debug("Got DSP_STORE_INFO\n");
1085 tempword = ntohs(pdrvmsg->length);
1086 info->DSPInfoBlklen = tempword;
1087 if (tempword < (MAX_DSP_SESS_REC - 4)) {
1088 pmsg = (u16 *)&pdrvmsg->data[0];
1089 for (i = 0; i < ((tempword + 1) / 2); i++) {
1090 pr_debug("dsp info data = 0x%x\n",
1092 info->DSPInfoBlk[i + 10] = *pmsg++;
1097 pr_debug("Got DSP_GET_INFO\n");
1099 * copy dsp info block to dsp
1100 * allow any outstanding ioctl to finish
1103 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1104 if (tempword & FT1000_DB_DPRAM_TX) {
1107 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1108 if (tempword & FT1000_DB_DPRAM_TX) {
1113 if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
1115 * Put message into Slow Queue
1116 * Form Pseudo header
1118 pmsg = (u16 *)info->DSPInfoBlk;
1119 ppseudo_hdr = (struct pseudo_hdr *)pmsg;
1120 ppseudo_hdr->length =
1121 htons(info->DSPInfoBlklen + 4);
1122 ppseudo_hdr->source = 0x10;
1123 ppseudo_hdr->destination = 0x20;
1124 ppseudo_hdr->portdest = 0;
1125 ppseudo_hdr->portsrc = 0;
1126 ppseudo_hdr->sh_str_id = 0;
1127 ppseudo_hdr->control = 0;
1128 ppseudo_hdr->rsvd1 = 0;
1129 ppseudo_hdr->rsvd2 = 0;
1130 ppseudo_hdr->qos_class = 0;
1131 /* Insert slow queue sequence number */
1132 ppseudo_hdr->seq_num = info->squeseqnum++;
1133 /* Insert application id */
1134 ppseudo_hdr->portsrc = 0;
1135 /* Calculate new checksum */
1136 ppseudo_hdr->checksum = *pmsg++;
1137 for (i = 1; i < 7; i++) {
1138 ppseudo_hdr->checksum ^= *pmsg++;
1140 info->DSPInfoBlk[8] = 0x7200;
1141 info->DSPInfoBlk[9] =
1142 htons(info->DSPInfoBlklen);
1143 ft1000_send_cmd(dev, (u16 *)info->DSPInfoBlk, (u16)(info->DSPInfoBlklen+4), 0);
1147 case GET_DRV_ERR_RPT_MSG:
1148 pr_debug("Got GET_DRV_ERR_RPT_MSG\n");
1150 * copy driver error message to dsp
1151 * allow any outstanding ioctl to finish
1154 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1155 if (tempword & FT1000_DB_DPRAM_TX) {
1158 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1159 if (tempword & FT1000_DB_DPRAM_TX) {
1164 if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
1166 * Put message into Slow Queue
1167 * Form Pseudo header
1169 pmsg = (u16 *)&tempbuffer[0];
1170 ppseudo_hdr = (struct pseudo_hdr *)pmsg;
1171 ppseudo_hdr->length = htons(0x0012);
1172 ppseudo_hdr->source = 0x10;
1173 ppseudo_hdr->destination = 0x20;
1174 ppseudo_hdr->portdest = 0;
1175 ppseudo_hdr->portsrc = 0;
1176 ppseudo_hdr->sh_str_id = 0;
1177 ppseudo_hdr->control = 0;
1178 ppseudo_hdr->rsvd1 = 0;
1179 ppseudo_hdr->rsvd2 = 0;
1180 ppseudo_hdr->qos_class = 0;
1181 /* Insert slow queue sequence number */
1182 ppseudo_hdr->seq_num = info->squeseqnum++;
1183 /* Insert application id */
1184 ppseudo_hdr->portsrc = 0;
1185 /* Calculate new checksum */
1186 ppseudo_hdr->checksum = *pmsg++;
1187 for (i = 1; i < 7; i++) {
1188 ppseudo_hdr->checksum ^= *pmsg++;
1190 pmsg = (u16 *)&tempbuffer[16];
1191 *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG);
1192 *pmsg++ = htons(0x000e);
1193 *pmsg++ = htons(info->DSP_TIME[0]);
1194 *pmsg++ = htons(info->DSP_TIME[1]);
1195 *pmsg++ = htons(info->DSP_TIME[2]);
1196 *pmsg++ = htons(info->DSP_TIME[3]);
1197 convert.byte[0] = info->DspVer[0];
1198 convert.byte[1] = info->DspVer[1];
1199 *pmsg++ = convert.wrd;
1200 convert.byte[0] = info->DspVer[2];
1201 convert.byte[1] = info->DspVer[3];
1202 *pmsg++ = convert.wrd;
1203 *pmsg++ = htons(info->DrvErrNum);
1205 ft1000_send_cmd(dev, (u16 *)&tempbuffer[0], (u16)(0x0012), 0);
1206 info->DrvErrNum = 0;
1216 /*---------------------------------------------------------------------------
1218 Function: ft1000_parse_dpram_msg
1219 Description: This function will parse the message received from the DSP
1220 via the DPRAM interface.
1222 dev - device structure
1227 -------------------------------------------------------------------------*/
1228 static int ft1000_parse_dpram_msg(struct net_device *dev)
1230 struct ft1000_info *info = netdev_priv(dev);
1236 unsigned long flags;
1238 doorbell = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1239 pr_debug("Doorbell = 0x%x\n", doorbell);
1241 if (doorbell & FT1000_ASIC_RESET_REQ) {
1242 /* Copy DSP session record from info block */
1243 spin_lock_irqsave(&info->dpram_lock, flags);
1244 if (info->AsicID == ELECTRABUZZ_ID) {
1245 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
1246 FT1000_DPRAM_RX_BASE);
1247 for (i = 0; i < MAX_DSP_SESS_REC; i++) {
1248 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA,
1249 info->DSPSess.Rec[i]);
1252 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
1253 FT1000_DPRAM_MAG_RX_BASE);
1254 for (i = 0; i < MAX_DSP_SESS_REC / 2; i++) {
1255 outl(info->DSPSess.MagRec[i],
1256 dev->base_addr + FT1000_REG_MAG_DPDATA);
1259 spin_unlock_irqrestore(&info->dpram_lock, flags);
1261 /* clear ASIC RESET request */
1262 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1263 FT1000_ASIC_RESET_REQ);
1264 pr_debug("Got an ASIC RESET Request\n");
1265 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1266 FT1000_ASIC_RESET_DSP);
1268 if (info->AsicID == MAGNEMITE_ID) {
1269 /* Setting MAGNEMITE ASIC to big endian mode */
1270 ft1000_write_reg(dev, FT1000_REG_SUP_CTRL,
1275 if (doorbell & FT1000_DSP_ASIC_RESET) {
1276 pr_debug("Got a dsp ASIC reset message\n");
1277 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1278 FT1000_DSP_ASIC_RESET);
1283 if (doorbell & FT1000_DB_DPRAM_RX) {
1284 pr_debug("Got a slow queue message\n");
1285 nxtph = FT1000_DPRAM_RX_BASE + 2;
1286 if (info->AsicID == ELECTRABUZZ_ID) {
1288 ft1000_read_dpram(dev, FT1000_DPRAM_RX_BASE);
1291 ntohs(ft1000_read_dpram_mag_16
1292 (dev, FT1000_MAG_TOTAL_LEN,
1293 FT1000_MAG_TOTAL_LEN_INDX));
1295 pr_debug("total length = %d\n", total_len);
1296 if ((total_len < MAX_CMD_SQSIZE) && (total_len > sizeof(struct pseudo_hdr))) {
1299 * ft1000_read_reg will return a value that needs to be byteswap
1300 * in order to get DSP_QID_OFFSET.
1302 if (info->AsicID == ELECTRABUZZ_ID) {
1306 DSP_QID_OFFSET + FT1000_DPRAM_RX_BASE +
1310 (ft1000_read_dpram_mag_16
1311 (dev, FT1000_MAG_PORT_ID,
1312 FT1000_MAG_PORT_ID_INDX) & 0xff);
1314 pr_debug("DSP_QID = 0x%x\n", portid);
1316 if (portid == DRIVERID) {
1317 /* We are assumming one driver message from the DSP at a time. */
1318 ft1000_proc_drvmsg(dev);
1321 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_RX);
1324 if (doorbell & FT1000_DB_COND_RESET) {
1325 /* Reset ASIC and DSP */
1326 if (info->AsicID == ELECTRABUZZ_ID) {
1328 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
1330 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
1332 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
1334 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
1337 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER0,
1338 FT1000_MAG_DSP_TIMER0_INDX);
1340 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER1,
1341 FT1000_MAG_DSP_TIMER1_INDX);
1343 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER2,
1344 FT1000_MAG_DSP_TIMER2_INDX);
1346 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER3,
1347 FT1000_MAG_DSP_TIMER3_INDX);
1349 info->DrvErrNum = DSP_CONDRESET_INFO;
1350 pr_debug("DSP conditional reset requested\n");
1351 ft1000_reset_card(dev);
1352 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1353 FT1000_DB_COND_RESET);
1355 /* let's clear any unexpected doorbells from DSP */
1357 doorbell & ~(FT1000_DB_DPRAM_RX | FT1000_ASIC_RESET_REQ |
1358 FT1000_DB_COND_RESET | 0xff00);
1360 pr_debug("Clearing unexpected doorbell = 0x%x\n", doorbell);
1361 ft1000_write_reg(dev, FT1000_REG_DOORBELL, doorbell);
1368 /*---------------------------------------------------------------------------
1370 Function: ft1000_flush_fifo
1371 Description: This function will flush one packet from the downlink
1374 dev - device structure
1375 drv_err - driver error causing the flush fifo
1379 -------------------------------------------------------------------------*/
1380 static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum)
1382 struct ft1000_info *info = netdev_priv(dev);
1383 struct ft1000_pcmcia *pcmcia = info->priv;
1388 if (pcmcia->PktIntfErr > MAX_PH_ERR) {
1389 if (info->AsicID == ELECTRABUZZ_ID) {
1391 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
1393 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
1395 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
1397 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
1400 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER0,
1401 FT1000_MAG_DSP_TIMER0_INDX);
1403 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER1,
1404 FT1000_MAG_DSP_TIMER1_INDX);
1406 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER2,
1407 FT1000_MAG_DSP_TIMER2_INDX);
1409 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER3,
1410 FT1000_MAG_DSP_TIMER3_INDX);
1412 info->DrvErrNum = DrvErrNum;
1413 ft1000_reset_card(dev);
1416 /* Flush corrupted pkt from FIFO */
1419 if (info->AsicID == ELECTRABUZZ_ID) {
1421 ft1000_read_reg(dev, FT1000_REG_DFIFO);
1423 ft1000_read_reg(dev, FT1000_REG_DFIFO_STAT);
1426 inl(dev->base_addr + FT1000_REG_MAG_DFR);
1428 inw(dev->base_addr + FT1000_REG_MAG_DFSR);
1432 * This should never happen unless the ASIC is broken.
1433 * We must reset to recover.
1435 if ((i > 2048) || (tempword == 0)) {
1436 if (info->AsicID == ELECTRABUZZ_ID) {
1438 ft1000_read_dpram(dev,
1441 ft1000_read_dpram(dev,
1444 ft1000_read_dpram(dev,
1447 ft1000_read_dpram(dev,
1451 ft1000_read_dpram_mag_16(dev,
1452 FT1000_MAG_DSP_TIMER0,
1453 FT1000_MAG_DSP_TIMER0_INDX);
1455 ft1000_read_dpram_mag_16(dev,
1456 FT1000_MAG_DSP_TIMER1,
1457 FT1000_MAG_DSP_TIMER1_INDX);
1459 ft1000_read_dpram_mag_16(dev,
1460 FT1000_MAG_DSP_TIMER2,
1461 FT1000_MAG_DSP_TIMER2_INDX);
1463 ft1000_read_dpram_mag_16(dev,
1464 FT1000_MAG_DSP_TIMER3,
1465 FT1000_MAG_DSP_TIMER3_INDX);
1467 if (tempword == 0) {
1469 * Let's check if ASIC reads are still ok by reading the Mask register
1470 * which is never zero at this point of the code.
1473 inw(dev->base_addr +
1474 FT1000_REG_SUP_IMASK);
1475 if (tempword == 0) {
1476 /* This indicates that we can not communicate with the ASIC */
1480 /* Let's assume that we really flush the FIFO */
1481 pcmcia->PktIntfErr++;
1485 info->DrvErrNum = FIFO_FLUSH_MAXLIMIT;
1489 tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT);
1490 } while ((tempword & 0x03) != 0x03);
1491 if (info->AsicID == ELECTRABUZZ_ID) {
1493 pr_debug("Flushing FIFO complete = %x\n", tempword);
1494 /* Flush last word in FIFO. */
1495 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1496 /* Update FIFO counter for DSP */
1498 pr_debug("Flush Data byte count to dsp = %d\n", i);
1499 info->fifo_cnt += i;
1500 ft1000_write_dpram(dev, FT1000_FIFO_LEN,
1503 pr_debug("Flushing FIFO complete = %x\n", tempword);
1504 /* Flush last word in FIFO */
1505 templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1506 tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT);
1507 pr_debug("FT1000_REG_SUP_STAT = 0x%x\n", tempword);
1508 tempword = inw(dev->base_addr + FT1000_REG_MAG_DFSR);
1509 pr_debug("FT1000_REG_MAG_DFSR = 0x%x\n", tempword);
1512 pcmcia->PktIntfErr++;
1517 /*---------------------------------------------------------------------------
1519 Function: ft1000_copy_up_pkt
1520 Description: This function will pull Flarion packets out of the Downlink
1521 FIFO and convert it to an ethernet packet. The ethernet packet will
1522 then be deliver to the TCP/IP stack.
1524 dev - device structure
1529 -------------------------------------------------------------------------*/
1530 static int ft1000_copy_up_pkt(struct net_device *dev)
1533 struct ft1000_info *info = netdev_priv(dev);
1535 struct sk_buff *skb;
1544 if (info->AsicID == ELECTRABUZZ_ID) {
1545 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1548 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1549 len = ntohs(tempword);
1552 pr_debug("Number of Bytes in FIFO = %d\n", len);
1554 if (len > ENET_MAX_SIZE) {
1555 pr_debug("size of ethernet packet invalid\n");
1556 if (info->AsicID == MAGNEMITE_ID) {
1557 /* Read High word to complete 32 bit access */
1558 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1560 ft1000_flush_fifo(dev, DSP_PKTLEN_INFO);
1561 info->stats.rx_errors++;
1565 skb = dev_alloc_skb(len + 12 + 2);
1568 pr_debug("No Network buffers available\n");
1569 /* Read High word to complete 32 bit access */
1570 if (info->AsicID == MAGNEMITE_ID) {
1571 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1573 ft1000_flush_fifo(dev, 0);
1574 info->stats.rx_errors++;
1577 pbuffer = (u8 *)skb_put(skb, len + 12);
1580 if (info->AsicID == ELECTRABUZZ_ID) {
1581 for (i = 1; i < 7; i++) {
1582 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1585 /* read checksum value */
1586 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1588 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1589 pr_debug("Pseudo = 0x%x\n", tempword);
1592 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1593 pr_debug("Pseudo = 0x%x\n", tempword);
1596 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1597 pr_debug("Pseudo = 0x%x\n", tempword);
1600 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1601 pr_debug("Pseudo = 0x%x\n", tempword);
1604 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1605 pr_debug("Pseudo = 0x%x\n", tempword);
1608 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1609 pr_debug("Pseudo = 0x%x\n", tempword);
1612 /* read checksum value */
1613 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1614 pr_debug("Pseudo = 0x%x\n", tempword);
1617 if (chksum != tempword) {
1618 pr_debug("Packet checksum mismatch 0x%x 0x%x\n",
1620 ft1000_flush_fifo(dev, DSP_PKTPHCKSUM_INFO);
1621 info->stats.rx_errors++;
1625 /* subtract the number of bytes read already */
1628 /* fake MAC address */
1629 *pbuffer++ = dev->dev_addr[0];
1630 *pbuffer++ = dev->dev_addr[1];
1631 *pbuffer++ = dev->dev_addr[2];
1632 *pbuffer++ = dev->dev_addr[3];
1633 *pbuffer++ = dev->dev_addr[4];
1634 *pbuffer++ = dev->dev_addr[5];
1642 if (info->AsicID == ELECTRABUZZ_ID) {
1643 for (i = 0; i < len / 2; i++) {
1644 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1645 *pbuffer++ = (u8) (tempword >> 8);
1646 *pbuffer++ = (u8)tempword;
1647 if (ft1000_chkcard(dev) == false) {
1653 /* Need to read one more word if odd byte */
1655 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1656 *pbuffer++ = (u8) (tempword >> 8);
1659 ptemplong = (u32 *)pbuffer;
1660 for (i = 0; i < len / 4; i++) {
1661 templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1662 pr_debug("Data = 0x%8x\n", templong);
1663 *ptemplong++ = templong;
1666 /* Need to read one more word if odd align. */
1668 templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1669 pr_debug("Data = 0x%8x\n", templong);
1670 *ptemplong++ = templong;
1675 pr_debug("Data passed to Protocol layer:\n");
1676 for (i = 0; i < len + 12; i++) {
1677 pr_debug("Protocol Data: 0x%x\n", *ptemp++);
1681 skb->protocol = eth_type_trans(skb, dev);
1682 skb->ip_summed = CHECKSUM_UNNECESSARY;
1685 info->stats.rx_packets++;
1686 /* Add on 12 bytes for MAC address which was removed */
1687 info->stats.rx_bytes += (len + 12);
1689 if (info->AsicID == ELECTRABUZZ_ID) {
1690 /* track how many bytes have been read from FIFO - round up to 16 bit word */
1691 tempword = len + 16;
1692 if (tempword & 0x01)
1694 info->fifo_cnt += tempword;
1695 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_FIFO_LEN);
1696 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, info->fifo_cnt);
1702 /*---------------------------------------------------------------------------
1704 Function: ft1000_copy_down_pkt
1705 Description: This function will take an ethernet packet and convert it to
1706 a Flarion packet prior to sending it to the ASIC Downlink
1709 dev - device structure
1710 packet - address of ethernet packet
1711 len - length of IP packet
1716 -------------------------------------------------------------------------*/
1717 static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len)
1719 struct ft1000_info *info = netdev_priv(dev);
1720 struct ft1000_pcmcia *pcmcia = info->priv;
1722 struct pseudo_hdr blk;
1723 u16 buff[sizeof(struct pseudo_hdr) >> 1];
1724 u8 buffc[sizeof(struct pseudo_hdr)];
1729 /* Check if there is room on the FIFO */
1730 if (len > ft1000_read_fifo_len(dev)) {
1732 if (len > ft1000_read_fifo_len(dev)) {
1735 if (len > ft1000_read_fifo_len(dev)) {
1738 if (len > ft1000_read_fifo_len(dev)) {
1741 if (len > ft1000_read_fifo_len(dev)) {
1744 if (len > ft1000_read_fifo_len(dev)) {
1747 if (len > ft1000_read_fifo_len(dev)) {
1748 pr_debug("Transmit FIFO is full - pkt drop\n");
1749 info->stats.tx_errors++;
1753 /* Create pseudo header and send pseudo/ip to hardware */
1754 if (info->AsicID == ELECTRABUZZ_ID) {
1755 pseudo.blk.length = len;
1757 pseudo.blk.length = ntohs(len);
1759 pseudo.blk.source = DSPID; /* Need to swap to get in correct order */
1760 pseudo.blk.destination = HOSTID;
1761 pseudo.blk.portdest = NETWORKID; /* Need to swap to get in correct order */
1762 pseudo.blk.portsrc = DSPAIRID;
1763 pseudo.blk.sh_str_id = 0;
1764 pseudo.blk.control = 0;
1765 pseudo.blk.rsvd1 = 0;
1766 pseudo.blk.seq_num = 0;
1767 pseudo.blk.rsvd2 = pcmcia->packetseqnum++;
1768 pseudo.blk.qos_class = 0;
1769 /* Calculate pseudo header checksum */
1770 pseudo.blk.checksum = pseudo.buff[0];
1771 for (i = 1; i < 7; i++) {
1772 pseudo.blk.checksum ^= pseudo.buff[i];
1775 /* Production Mode */
1776 if (info->AsicID == ELECTRABUZZ_ID) {
1777 /* copy first word to UFIFO_BEG reg */
1778 ft1000_write_reg(dev, FT1000_REG_UFIFO_BEG, pseudo.buff[0]);
1779 pr_debug("data 0 BEG = 0x%04x\n", pseudo.buff[0]);
1781 /* copy subsequent words to UFIFO_MID reg */
1782 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[1]);
1783 pr_debug("data 1 MID = 0x%04x\n", pseudo.buff[1]);
1784 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[2]);
1785 pr_debug("data 2 MID = 0x%04x\n", pseudo.buff[2]);
1786 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[3]);
1787 pr_debug("data 3 MID = 0x%04x\n", pseudo.buff[3]);
1788 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[4]);
1789 pr_debug("data 4 MID = 0x%04x\n", pseudo.buff[4]);
1790 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[5]);
1791 pr_debug("data 5 MID = 0x%04x\n", pseudo.buff[5]);
1792 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[6]);
1793 pr_debug("data 6 MID = 0x%04x\n", pseudo.buff[6]);
1794 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[7]);
1795 pr_debug("data 7 MID = 0x%04x\n", pseudo.buff[7]);
1797 /* Write PPP type + IP Packet into Downlink FIFO */
1798 for (i = 0; i < (len >> 1) - 1; i++) {
1799 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID,
1801 pr_debug("data %d MID = 0x%04x\n",
1802 i + 8, htons(*packet));
1806 /* Check for odd byte */
1808 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID,
1810 pr_debug("data MID = 0x%04x\n", htons(*packet));
1812 ft1000_write_reg(dev, FT1000_REG_UFIFO_END,
1814 pr_debug("data %d MID = 0x%04x\n",
1815 i + 8, htons(*packet));
1817 ft1000_write_reg(dev, FT1000_REG_UFIFO_END,
1819 pr_debug("data %d MID = 0x%04x\n",
1820 i + 8, htons(*packet));
1823 outl(*(u32 *)&pseudo.buff[0],
1824 dev->base_addr + FT1000_REG_MAG_UFDR);
1825 pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[0]);
1826 outl(*(u32 *)&pseudo.buff[2],
1827 dev->base_addr + FT1000_REG_MAG_UFDR);
1828 pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[2]);
1829 outl(*(u32 *)&pseudo.buff[4],
1830 dev->base_addr + FT1000_REG_MAG_UFDR);
1831 pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[4]);
1832 outl(*(u32 *)&pseudo.buff[6],
1833 dev->base_addr + FT1000_REG_MAG_UFDR);
1834 pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[6]);
1836 plong = (u32 *)packet;
1837 /* Write PPP type + IP Packet into Downlink FIFO */
1838 for (i = 0; i < (len >> 2); i++) {
1839 outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
1842 /* Check for odd alignment */
1844 pr_debug("data = 0x%8x\n", *plong);
1845 outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
1847 outl(1, dev->base_addr + FT1000_REG_MAG_UFER);
1850 info->stats.tx_packets++;
1851 /* Add 14 bytes for MAC address plus ethernet type */
1852 info->stats.tx_bytes += (len + 14);
1856 static struct net_device_stats *ft1000_stats(struct net_device *dev)
1858 struct ft1000_info *info = netdev_priv(dev);
1860 return &info->stats;
1863 static int ft1000_open(struct net_device *dev)
1865 ft1000_reset_card(dev);
1867 /* schedule ft1000_hbchk to perform periodic heartbeat checks on DSP and ASIC */
1868 init_timer(&poll_timer);
1869 poll_timer.expires = jiffies + (2 * HZ);
1870 poll_timer.data = (u_long)dev;
1871 add_timer(&poll_timer);
1876 static int ft1000_close(struct net_device *dev)
1878 struct ft1000_info *info = netdev_priv(dev);
1880 info->CardReady = 0;
1881 del_timer(&poll_timer);
1883 if (ft1000_card_present == 1) {
1884 pr_debug("Media is down\n");
1885 netif_stop_queue(dev);
1887 ft1000_disable_interrupts(dev);
1888 ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
1891 ft1000_reset_asic(dev);
1896 static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
1898 struct ft1000_info *info = netdev_priv(dev);
1902 pr_debug("skb == NULL!!!\n");
1906 pr_debug("length of packet = %d\n", skb->len);
1908 pdata = (u8 *)skb->data;
1910 if (info->mediastate == 0) {
1911 /* Drop packet is mediastate is down */
1912 pr_debug("mediastate is down\n");
1916 if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) {
1917 /* Drop packet which has invalid size */
1918 pr_debug("invalid ethernet length\n");
1921 ft1000_copy_down_pkt(dev, (u16 *) (pdata + ENET_HEADER_SIZE - 2),
1922 skb->len - ENET_HEADER_SIZE + 2);
1929 static irqreturn_t ft1000_interrupt(int irq, void *dev_id)
1931 struct net_device *dev = dev_id;
1932 struct ft1000_info *info = netdev_priv(dev);
1937 if (info->CardReady == 0) {
1938 ft1000_disable_interrupts(dev);
1942 if (ft1000_chkcard(dev) == false) {
1943 ft1000_disable_interrupts(dev);
1947 ft1000_disable_interrupts(dev);
1949 /* Read interrupt type */
1950 inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
1952 /* Make sure we process all interrupt before leaving the ISR due to the edge trigger interrupt type */
1954 if (inttype & ISR_DOORBELL_PEND)
1955 ft1000_parse_dpram_msg(dev);
1957 if (inttype & ISR_RCV) {
1958 pr_debug("Data in FIFO\n");
1962 /* Check if we have packets in the Downlink FIFO */
1963 if (info->AsicID == ELECTRABUZZ_ID) {
1965 ft1000_read_reg(dev,
1966 FT1000_REG_DFIFO_STAT);
1969 ft1000_read_reg(dev,
1970 FT1000_REG_MAG_DFSR);
1972 if (tempword & 0x1f) {
1973 ft1000_copy_up_pkt(dev);
1978 } while (cnt < MAX_RCV_LOOP);
1981 /* clear interrupts */
1982 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
1983 pr_debug("interrupt status register = 0x%x\n", tempword);
1984 ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword);
1986 /* Read interrupt type */
1987 inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
1988 pr_debug("interrupt status register after clear = 0x%x\n",
1991 ft1000_enable_interrupts(dev);
1995 void stop_ft1000_card(struct net_device *dev)
1997 struct ft1000_info *info = netdev_priv(dev);
1998 struct prov_record *ptr;
2001 info->CardReady = 0;
2002 ft1000_card_present = 0;
2003 netif_stop_queue(dev);
2004 ft1000_disable_interrupts(dev);
2006 /* Make sure we free any memory reserve for provisioning */
2007 while (list_empty(&info->prov_list) == 0) {
2008 ptr = list_entry(info->prov_list.next, struct prov_record, list);
2009 list_del(&ptr->list);
2010 kfree(ptr->pprov_data);
2016 if (info->registered) {
2017 unregister_netdev(dev);
2018 info->registered = 0;
2021 free_irq(dev->irq, dev);
2022 release_region(dev->base_addr, 256);
2023 release_firmware(fw_entry);
2024 flarion_ft1000_cnt--;
2028 static void ft1000_get_drvinfo(struct net_device *dev,
2029 struct ethtool_drvinfo *info)
2031 struct ft1000_info *ft_info;
2032 ft_info = netdev_priv(dev);
2034 strlcpy(info->driver, "ft1000", sizeof(info->driver));
2035 snprintf(info->bus_info, sizeof(info->bus_info), "PCMCIA 0x%lx",
2037 snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d.%d",
2038 ft_info->DspVer[0], ft_info->DspVer[1], ft_info->DspVer[2],
2039 ft_info->DspVer[3]);
2042 static u32 ft1000_get_link(struct net_device *dev)
2044 struct ft1000_info *info;
2046 info = netdev_priv(dev);
2047 return info->mediastate;
2050 static const struct ethtool_ops ops = {
2051 .get_drvinfo = ft1000_get_drvinfo,
2052 .get_link = ft1000_get_link
2055 struct net_device *init_ft1000_card(struct pcmcia_device *link,
2058 struct ft1000_info *info;
2059 struct ft1000_pcmcia *pcmcia;
2060 struct net_device *dev;
2062 static const struct net_device_ops ft1000ops = /* Slavius 21.10.2009 due to kernel changes */
2064 .ndo_open = &ft1000_open,
2065 .ndo_stop = &ft1000_close,
2066 .ndo_start_xmit = &ft1000_start_xmit,
2067 .ndo_get_stats = &ft1000_stats,
2070 pr_debug("irq = %d, port = 0x%04llx\n",
2071 link->irq, (unsigned long long)link->resource[0]->start);
2073 flarion_ft1000_cnt++;
2075 if (flarion_ft1000_cnt > 1) {
2076 flarion_ft1000_cnt--;
2078 dev_info(&link->dev,
2079 "This driver can not support more than one instance\n");
2083 dev = alloc_etherdev(sizeof(struct ft1000_info));
2085 dev_err(&link->dev, "Failed to allocate etherdev\n");
2089 SET_NETDEV_DEV(dev, &link->dev);
2090 info = netdev_priv(dev);
2092 memset(info, 0, sizeof(struct ft1000_info));
2094 pr_debug("address of dev = 0x%p\n", dev);
2095 pr_debug("address of dev info = 0x%p\n", info);
2096 pr_debug("device name = %s\n", dev->name);
2098 memset(&info->stats, 0, sizeof(struct net_device_stats));
2100 info->priv = kzalloc(sizeof(struct ft1000_pcmcia), GFP_KERNEL);
2101 pcmcia = info->priv;
2102 pcmcia->link = link;
2104 spin_lock_init(&info->dpram_lock);
2105 info->DrvErrNum = 0;
2106 info->registered = 1;
2107 info->ft1000_reset = ft1000_reset;
2108 info->mediastate = 0;
2110 info->CardReady = 0;
2111 info->DSP_TIME[0] = 0;
2112 info->DSP_TIME[1] = 0;
2113 info->DSP_TIME[2] = 0;
2114 info->DSP_TIME[3] = 0;
2115 flarion_ft1000_cnt = 0;
2117 INIT_LIST_HEAD(&info->prov_list);
2119 info->squeseqnum = 0;
2121 /* dev->hard_start_xmit = &ft1000_start_xmit; */
2122 /* dev->get_stats = &ft1000_stats; */
2123 /* dev->open = &ft1000_open; */
2124 /* dev->stop = &ft1000_close; */
2126 dev->netdev_ops = &ft1000ops; /* Slavius 21.10.2009 due to kernel changes */
2128 pr_debug("device name = %s\n", dev->name);
2130 dev->irq = link->irq;
2131 dev->base_addr = link->resource[0]->start;
2132 if (pcmcia_get_mac_from_cis(link, dev)) {
2133 netdev_err(dev, "Could not read mac address\n");
2137 if (request_irq(dev->irq, ft1000_interrupt, IRQF_SHARED, dev->name, dev)) {
2138 netdev_err(dev, "Could not request_irq\n");
2142 if (request_region(dev->base_addr, 256, dev->name) == NULL) {
2143 netdev_err(dev, "Could not request_region\n");
2147 if (register_netdev(dev) != 0) {
2148 pr_debug("Could not register netdev\n");
2152 info->AsicID = ft1000_read_reg(dev, FT1000_REG_ASIC_ID);
2153 if (info->AsicID == ELECTRABUZZ_ID) {
2154 pr_debug("ELECTRABUZZ ASIC\n");
2155 if (request_firmware(&fw_entry, "ft1000.img", &link->dev) != 0) {
2156 pr_info("Could not open ft1000.img\n");
2160 pr_debug("MAGNEMITE ASIC\n");
2161 if (request_firmware(&fw_entry, "ft2000.img", &link->dev) != 0) {
2162 pr_info("Could not open ft2000.img\n");
2167 ft1000_enable_interrupts(dev);
2169 ft1000_card_present = 1;
2170 dev->ethtool_ops = &ops;
2171 pr_info("%s: addr 0x%04lx irq %d, MAC addr %pM\n",
2172 dev->name, dev->base_addr, dev->irq, dev->dev_addr);
2176 unregister_netdev(dev);
2178 release_region(dev->base_addr, 256);
2180 free_irq(dev->irq, dev);