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)
449 pr_debug("No FEFE detected from DSP\n");
454 /* Take DSP out of reset */
455 ft1000_write_reg(dev, FT1000_REG_RESET, ~DSP_RESET_BIT);
459 if (card_download(dev, fw_entry->data, fw_entry->size)) {
460 pr_debug("card download unsuccessful\n");
463 pr_debug("card download successful\n");
468 if (info->AsicID == ELECTRABUZZ_ID) {
470 * Need to initialize the FIFO length counter to zero in order to sync up
474 ft1000_write_dpram(dev, FT1000_FIFO_LEN, info->fifo_cnt);
475 /* Initialize DSP heartbeat area to ho */
476 ft1000_write_dpram(dev, FT1000_HI_HO, ho);
477 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
478 pr_debug("hi_ho value = 0x%x\n", tempword);
480 /* Initialize DSP heartbeat area to ho */
481 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, ho_mag,
482 FT1000_MAG_HI_HO_INDX);
484 ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO,
485 FT1000_MAG_HI_HO_INDX);
486 pr_debug("hi_ho value = 0x%x\n", tempword);
490 ft1000_enable_interrupts(dev);
492 /* Schedule heartbeat process to run every 2 seconds */
493 /* poll_timer.expires = jiffies + (2*HZ); */
494 /* poll_timer.data = (u_long)dev; */
495 /* add_timer(&poll_timer); */
501 /*---------------------------------------------------------------------------
503 Function: ft1000_chkcard
504 Description: This function will check if the device is presently available on
507 dev - device structure
509 status - false (device is not present)
510 true (device is present)
512 -------------------------------------------------------------------------*/
513 static int ft1000_chkcard(struct net_device *dev)
518 * Mask register is used to check for device presence since it is never
521 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
523 pr_debug("IMASK = 0 Card not detected\n");
527 * The system will return the value of 0xffff for the version register
528 * if the device is not present.
530 tempword = ft1000_read_reg(dev, FT1000_REG_ASIC_ID);
531 if (tempword == 0xffff) {
532 pr_debug("Version = 0xffff Card not detected\n");
539 /*---------------------------------------------------------------------------
541 Function: ft1000_hbchk
542 Description: This function will perform the heart beat check of the DSP as
545 dev - device structure
549 -------------------------------------------------------------------------*/
550 static void ft1000_hbchk(u_long data)
552 struct net_device *dev = (struct net_device *)data;
554 struct ft1000_info *info;
557 info = netdev_priv(dev);
559 if (info->CardReady == 1) {
560 /* Perform dsp heartbeat check */
561 if (info->AsicID == ELECTRABUZZ_ID) {
562 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
565 ntohs(ft1000_read_dpram_mag_16
566 (dev, FT1000_MAG_HI_HO,
567 FT1000_MAG_HI_HO_INDX));
569 pr_debug("hi_ho value = 0x%x\n", tempword);
570 /* Let's perform another check if ho is not detected */
571 if (tempword != ho) {
572 if (info->AsicID == ELECTRABUZZ_ID)
573 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
575 tempword = ntohs(ft1000_read_dpram_mag_16(dev,
577 FT1000_MAG_HI_HO_INDX));
579 if (tempword != ho) {
580 pr_info("heartbeat failed - no ho detected\n");
581 if (info->AsicID == ELECTRABUZZ_ID) {
583 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
585 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
587 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
589 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
592 ft1000_read_dpram_mag_16(dev,
593 FT1000_MAG_DSP_TIMER0,
594 FT1000_MAG_DSP_TIMER0_INDX);
596 ft1000_read_dpram_mag_16(dev,
597 FT1000_MAG_DSP_TIMER1,
598 FT1000_MAG_DSP_TIMER1_INDX);
600 ft1000_read_dpram_mag_16(dev,
601 FT1000_MAG_DSP_TIMER2,
602 FT1000_MAG_DSP_TIMER2_INDX);
604 ft1000_read_dpram_mag_16(dev,
605 FT1000_MAG_DSP_TIMER3,
606 FT1000_MAG_DSP_TIMER3_INDX);
608 info->DrvErrNum = DSP_HB_INFO;
609 if (ft1000_reset_card(dev) == 0) {
610 pr_info("Hardware Failure Detected - PC Card disabled\n");
611 info->ProgConStat = 0xff;
614 /* Schedule this module to run every 2 seconds */
615 poll_timer.expires = jiffies + (2*HZ);
616 poll_timer.data = (u_long)dev;
617 add_timer(&poll_timer);
621 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
622 /* Let's check doorbell again if fail */
623 if (tempword & FT1000_DB_HB)
624 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
626 if (tempword & FT1000_DB_HB) {
627 pr_info("heartbeat doorbell not clear by firmware\n");
628 if (info->AsicID == ELECTRABUZZ_ID) {
630 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
632 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
634 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
636 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
639 ft1000_read_dpram_mag_16(dev,
640 FT1000_MAG_DSP_TIMER0,
641 FT1000_MAG_DSP_TIMER0_INDX);
643 ft1000_read_dpram_mag_16(dev,
644 FT1000_MAG_DSP_TIMER1,
645 FT1000_MAG_DSP_TIMER1_INDX);
647 ft1000_read_dpram_mag_16(dev,
648 FT1000_MAG_DSP_TIMER2,
649 FT1000_MAG_DSP_TIMER2_INDX);
651 ft1000_read_dpram_mag_16(dev,
652 FT1000_MAG_DSP_TIMER3,
653 FT1000_MAG_DSP_TIMER3_INDX);
655 info->DrvErrNum = DSP_HB_INFO;
656 if (ft1000_reset_card(dev) == 0) {
657 pr_info("Hardware Failure Detected - PC Card disabled\n");
658 info->ProgConStat = 0xff;
661 /* Schedule this module to run every 2 seconds */
662 poll_timer.expires = jiffies + (2*HZ);
663 poll_timer.data = (u_long)dev;
664 add_timer(&poll_timer);
668 * Set dedicated area to hi and ring appropriate doorbell according
669 * to hi/ho heartbeat protocol
671 if (info->AsicID == ELECTRABUZZ_ID) {
672 ft1000_write_dpram(dev, FT1000_HI_HO, hi);
674 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag,
675 FT1000_MAG_HI_HO_INDX);
678 if (info->AsicID == ELECTRABUZZ_ID) {
679 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
682 ntohs(ft1000_read_dpram_mag_16
683 (dev, FT1000_MAG_HI_HO,
684 FT1000_MAG_HI_HO_INDX));
686 /* Let's write hi again if fail */
687 if (tempword != hi) {
688 if (info->AsicID == ELECTRABUZZ_ID)
689 ft1000_write_dpram(dev, FT1000_HI_HO, hi);
691 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag, FT1000_MAG_HI_HO_INDX);
693 if (info->AsicID == ELECTRABUZZ_ID)
694 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
696 tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX));
700 if (tempword != hi) {
701 pr_info("heartbeat failed - cannot write hi into DPRAM\n");
702 if (info->AsicID == ELECTRABUZZ_ID) {
704 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
706 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
708 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
710 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
713 ft1000_read_dpram_mag_16(dev,
714 FT1000_MAG_DSP_TIMER0,
715 FT1000_MAG_DSP_TIMER0_INDX);
717 ft1000_read_dpram_mag_16(dev,
718 FT1000_MAG_DSP_TIMER1,
719 FT1000_MAG_DSP_TIMER1_INDX);
721 ft1000_read_dpram_mag_16(dev,
722 FT1000_MAG_DSP_TIMER2,
723 FT1000_MAG_DSP_TIMER2_INDX);
725 ft1000_read_dpram_mag_16(dev,
726 FT1000_MAG_DSP_TIMER3,
727 FT1000_MAG_DSP_TIMER3_INDX);
729 info->DrvErrNum = DSP_HB_INFO;
730 if (ft1000_reset_card(dev) == 0) {
731 pr_info("Hardware Failure Detected - PC Card disabled\n");
732 info->ProgConStat = 0xff;
735 /* Schedule this module to run every 2 seconds */
736 poll_timer.expires = jiffies + (2*HZ);
737 poll_timer.data = (u_long)dev;
738 add_timer(&poll_timer);
741 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_HB);
745 /* Schedule this module to run every 2 seconds */
746 poll_timer.expires = jiffies + (2 * HZ);
747 poll_timer.data = (u_long)dev;
748 add_timer(&poll_timer);
751 /*---------------------------------------------------------------------------
753 Function: ft1000_send_cmd
758 -------------------------------------------------------------------------*/
759 static void ft1000_send_cmd(struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype)
761 struct ft1000_info *info = netdev_priv(dev);
766 size += sizeof(struct pseudo_hdr);
767 /* check for odd byte and increment to 16-bit word align value */
770 pr_debug("total length = %d\n", size);
771 pr_debug("length = %d\n", ntohs(*ptempbuffer));
773 * put message into slow queue area
774 * All messages are in the form total_len + pseudo header + message body
776 spin_lock_irqsave(&info->dpram_lock, flags);
778 /* Make sure SLOWQ doorbell is clear */
779 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
781 while (tempword & FT1000_DB_DPRAM_TX) {
785 spin_unlock_irqrestore(&info->dpram_lock, flags);
788 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
791 if (info->AsicID == ELECTRABUZZ_ID) {
792 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
793 FT1000_DPRAM_TX_BASE);
794 /* Write total length to dpram */
795 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, size);
796 /* Write pseudo header and messgae body */
797 for (i = 0; i < (size >> 1); i++) {
798 pr_debug("data %d = 0x%x\n", i, *ptempbuffer);
799 tempword = htons(*ptempbuffer++);
800 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, tempword);
803 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
804 FT1000_DPRAM_MAG_TX_BASE);
805 /* Write total length to dpram */
806 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, htons(size));
807 /* Write pseudo header and messgae body */
808 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
809 FT1000_DPRAM_MAG_TX_BASE + 1);
810 for (i = 0; i < (size >> 2); i++) {
811 pr_debug("data = 0x%x\n", *ptempbuffer);
813 dev->base_addr + FT1000_REG_MAG_DPDATAL);
814 pr_debug("data = 0x%x\n", *ptempbuffer);
816 dev->base_addr + FT1000_REG_MAG_DPDATAH);
818 pr_debug("data = 0x%x\n", *ptempbuffer);
819 outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAL);
820 pr_debug("data = 0x%x\n", *ptempbuffer);
821 outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAH);
823 spin_unlock_irqrestore(&info->dpram_lock, flags);
825 /* ring doorbell to notify DSP that we have a message ready */
826 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_TX);
829 /*---------------------------------------------------------------------------
831 Function: ft1000_receive_cmd
832 Description: This function will read a message from the dpram area.
834 dev - network device structure
835 pbuffer - caller supply address to buffer
836 pnxtph - pointer to next pseudo header
838 Status = 0 (unsuccessful)
841 -------------------------------------------------------------------------*/
842 static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer,
843 int maxsz, u16 *pnxtph)
845 struct ft1000_info *info = netdev_priv(dev);
852 if (info->AsicID == ELECTRABUZZ_ID) {
853 size = (ft1000_read_dpram(dev, *pnxtph)) + sizeof(struct pseudo_hdr);
856 ntohs(ft1000_read_dpram_mag_16
857 (dev, FT1000_MAG_PH_LEN,
858 FT1000_MAG_PH_LEN_INDX)) + sizeof(struct pseudo_hdr);
861 pr_debug("Invalid command length = %d\n", size);
864 ppseudohdr = (u16 *)pbuffer;
865 spin_lock_irqsave(&info->dpram_lock, flags);
866 if (info->AsicID == ELECTRABUZZ_ID) {
867 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
868 FT1000_DPRAM_RX_BASE + 2);
869 for (i = 0; i <= (size >> 1); i++) {
871 ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
872 *pbuffer++ = ntohs(tempword);
875 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
876 FT1000_DPRAM_MAG_RX_BASE);
877 *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH);
878 pr_debug("received data = 0x%x\n", *pbuffer);
880 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
881 FT1000_DPRAM_MAG_RX_BASE + 1);
882 for (i = 0; i <= (size >> 2); i++) {
885 FT1000_REG_MAG_DPDATAL);
889 FT1000_REG_MAG_DPDATAH);
892 /* copy odd aligned word */
893 *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAL);
894 pr_debug("received data = 0x%x\n", *pbuffer);
896 *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH);
897 pr_debug("received data = 0x%x\n", *pbuffer);
901 /* copy odd byte from fifo */
902 tempword = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
903 *pbuffer = ntohs(tempword);
905 spin_unlock_irqrestore(&info->dpram_lock, flags);
908 * Check if pseudo header checksum is good
909 * Calculate pseudo header checksum
911 tempword = *ppseudohdr++;
912 for (i = 1; i < 7; i++)
913 tempword ^= *ppseudohdr++;
914 if ((tempword != *ppseudohdr)) {
915 pr_debug("Pseudo header checksum mismatch\n");
916 /* Drop this message */
923 /*---------------------------------------------------------------------------
925 Function: ft1000_proc_drvmsg
926 Description: This function will process the various driver messages.
928 dev - device structure
929 pnxtph - pointer to next pseudo header
933 -------------------------------------------------------------------------*/
934 static void ft1000_proc_drvmsg(struct net_device *dev)
936 struct ft1000_info *info = netdev_priv(dev);
939 struct media_msg *pmediamsg;
940 struct dsp_init_msg *pdspinitmsg;
941 struct drv_msg *pdrvmsg;
944 struct prov_record *ptr;
945 struct pseudo_hdr *ppseudo_hdr;
953 if (info->AsicID == ELECTRABUZZ_ID)
954 tempword = FT1000_DPRAM_RX_BASE+2;
956 tempword = FT1000_DPRAM_MAG_RX_BASE;
958 if (ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword)) {
960 /* Get the message type which is total_len + PSEUDO header + msgtype + message body */
961 pdrvmsg = (struct drv_msg *)&cmdbuffer[0];
962 msgtype = ntohs(pdrvmsg->type);
963 pr_debug("Command message type = 0x%x\n", msgtype);
966 pr_debug("Got a provisioning request message from DSP\n");
968 while (list_empty(&info->prov_list) == 0) {
969 pr_debug("Sending a provisioning message\n");
970 /* Make sure SLOWQ doorbell is clear */
972 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
974 while (tempword & FT1000_DB_DPRAM_TX) {
981 list_entry(info->prov_list.next,
982 struct prov_record, list);
983 len = *(u16 *)ptr->pprov_data;
986 pmsg = (u16 *)ptr->pprov_data;
987 ppseudo_hdr = (struct pseudo_hdr *)pmsg;
988 /* Insert slow queue sequence number */
989 ppseudo_hdr->seq_num = info->squeseqnum++;
990 ppseudo_hdr->portsrc = 0;
991 /* Calculate new checksum */
992 ppseudo_hdr->checksum = *pmsg++;
993 pr_debug("checksum = 0x%x\n",
994 ppseudo_hdr->checksum);
995 for (i = 1; i < 7; i++) {
996 ppseudo_hdr->checksum ^= *pmsg++;
997 pr_debug("checksum = 0x%x\n",
998 ppseudo_hdr->checksum);
1001 ft1000_send_cmd(dev, (u16 *)ptr->pprov_data, len, SLOWQ_TYPE);
1002 list_del(&ptr->list);
1003 kfree(ptr->pprov_data);
1007 * Indicate adapter is ready to take application messages after all
1008 * provisioning messages are sent
1010 info->CardReady = 1;
1013 pmediamsg = (struct media_msg *)&cmdbuffer[0];
1014 if (info->ProgConStat != 0xFF) {
1015 if (pmediamsg->state) {
1016 pr_debug("Media is up\n");
1017 if (info->mediastate == 0) {
1018 netif_carrier_on(dev);
1019 netif_wake_queue(dev);
1020 info->mediastate = 1;
1021 do_gettimeofday(&tv);
1022 info->ConTm = tv.tv_sec;
1025 pr_debug("Media is down\n");
1026 if (info->mediastate == 1) {
1027 info->mediastate = 0;
1028 netif_carrier_off(dev);
1029 netif_stop_queue(dev);
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 pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[0];
1045 memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ);
1046 pr_debug("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n",
1047 info->DspVer[0], info->DspVer[1],
1048 info->DspVer[2], info->DspVer[3]);
1049 memcpy(info->HwSerNum, pdspinitmsg->HwSerNum,
1051 memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ);
1052 memcpy(info->eui64, pdspinitmsg->eui64, EUISZ);
1053 dev->dev_addr[0] = info->eui64[0];
1054 dev->dev_addr[1] = info->eui64[1];
1055 dev->dev_addr[2] = info->eui64[2];
1056 dev->dev_addr[3] = info->eui64[5];
1057 dev->dev_addr[4] = info->eui64[6];
1058 dev->dev_addr[5] = info->eui64[7];
1060 if (ntohs(pdspinitmsg->length) ==
1061 (sizeof(struct dsp_init_msg) - 20)) {
1062 memcpy(info->ProductMode,
1063 pdspinitmsg->ProductMode, MODESZ);
1064 memcpy(info->RfCalVer, pdspinitmsg->RfCalVer,
1066 memcpy(info->RfCalDate, pdspinitmsg->RfCalDate,
1068 pr_debug("RFCalVer = 0x%2x 0x%2x\n",
1069 info->RfCalVer[0], info->RfCalVer[1]);
1073 case DSP_STORE_INFO:
1074 pr_debug("Got DSP_STORE_INFO\n");
1075 tempword = ntohs(pdrvmsg->length);
1076 info->DSPInfoBlklen = tempword;
1077 if (tempword < (MAX_DSP_SESS_REC - 4)) {
1078 pmsg = (u16 *)&pdrvmsg->data[0];
1079 for (i = 0; i < ((tempword + 1) / 2); i++) {
1080 pr_debug("dsp info data = 0x%x\n",
1082 info->DSPInfoBlk[i + 10] = *pmsg++;
1087 pr_debug("Got DSP_GET_INFO\n");
1089 * copy dsp info block to dsp
1090 * allow any outstanding ioctl to finish
1093 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1094 if (tempword & FT1000_DB_DPRAM_TX) {
1097 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1098 if (tempword & FT1000_DB_DPRAM_TX)
1102 if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
1104 * Put message into Slow Queue
1105 * Form Pseudo header
1107 pmsg = (u16 *)info->DSPInfoBlk;
1108 ppseudo_hdr = (struct pseudo_hdr *)pmsg;
1109 ppseudo_hdr->length =
1110 htons(info->DSPInfoBlklen + 4);
1111 ppseudo_hdr->source = 0x10;
1112 ppseudo_hdr->destination = 0x20;
1113 ppseudo_hdr->portdest = 0;
1114 ppseudo_hdr->portsrc = 0;
1115 ppseudo_hdr->sh_str_id = 0;
1116 ppseudo_hdr->control = 0;
1117 ppseudo_hdr->rsvd1 = 0;
1118 ppseudo_hdr->rsvd2 = 0;
1119 ppseudo_hdr->qos_class = 0;
1120 /* Insert slow queue sequence number */
1121 ppseudo_hdr->seq_num = info->squeseqnum++;
1122 /* Insert application id */
1123 ppseudo_hdr->portsrc = 0;
1124 /* Calculate new checksum */
1125 ppseudo_hdr->checksum = *pmsg++;
1126 for (i = 1; i < 7; i++)
1127 ppseudo_hdr->checksum ^= *pmsg++;
1129 info->DSPInfoBlk[8] = 0x7200;
1130 info->DSPInfoBlk[9] =
1131 htons(info->DSPInfoBlklen);
1132 ft1000_send_cmd(dev, (u16 *)info->DSPInfoBlk, (u16)(info->DSPInfoBlklen+4), 0);
1136 case GET_DRV_ERR_RPT_MSG:
1137 pr_debug("Got GET_DRV_ERR_RPT_MSG\n");
1139 * copy driver error message to dsp
1140 * allow any outstanding ioctl to finish
1143 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1144 if (tempword & FT1000_DB_DPRAM_TX) {
1147 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1148 if (tempword & FT1000_DB_DPRAM_TX)
1152 if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
1154 * Put message into Slow Queue
1155 * Form Pseudo header
1157 pmsg = (u16 *)&tempbuffer[0];
1158 ppseudo_hdr = (struct pseudo_hdr *)pmsg;
1159 ppseudo_hdr->length = htons(0x0012);
1160 ppseudo_hdr->source = 0x10;
1161 ppseudo_hdr->destination = 0x20;
1162 ppseudo_hdr->portdest = 0;
1163 ppseudo_hdr->portsrc = 0;
1164 ppseudo_hdr->sh_str_id = 0;
1165 ppseudo_hdr->control = 0;
1166 ppseudo_hdr->rsvd1 = 0;
1167 ppseudo_hdr->rsvd2 = 0;
1168 ppseudo_hdr->qos_class = 0;
1169 /* Insert slow queue sequence number */
1170 ppseudo_hdr->seq_num = info->squeseqnum++;
1171 /* Insert application id */
1172 ppseudo_hdr->portsrc = 0;
1173 /* Calculate new checksum */
1174 ppseudo_hdr->checksum = *pmsg++;
1175 for (i = 1; i < 7; i++)
1176 ppseudo_hdr->checksum ^= *pmsg++;
1178 pmsg = (u16 *)&tempbuffer[16];
1179 *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG);
1180 *pmsg++ = htons(0x000e);
1181 *pmsg++ = htons(info->DSP_TIME[0]);
1182 *pmsg++ = htons(info->DSP_TIME[1]);
1183 *pmsg++ = htons(info->DSP_TIME[2]);
1184 *pmsg++ = htons(info->DSP_TIME[3]);
1185 convert.byte[0] = info->DspVer[0];
1186 convert.byte[1] = info->DspVer[1];
1187 *pmsg++ = convert.wrd;
1188 convert.byte[0] = info->DspVer[2];
1189 convert.byte[1] = info->DspVer[3];
1190 *pmsg++ = convert.wrd;
1191 *pmsg++ = htons(info->DrvErrNum);
1193 ft1000_send_cmd(dev, (u16 *)&tempbuffer[0], (u16)(0x0012), 0);
1194 info->DrvErrNum = 0;
1204 /*---------------------------------------------------------------------------
1206 Function: ft1000_parse_dpram_msg
1207 Description: This function will parse the message received from the DSP
1208 via the DPRAM interface.
1210 dev - device structure
1215 -------------------------------------------------------------------------*/
1216 static int ft1000_parse_dpram_msg(struct net_device *dev)
1218 struct ft1000_info *info = netdev_priv(dev);
1224 unsigned long flags;
1226 doorbell = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1227 pr_debug("Doorbell = 0x%x\n", doorbell);
1229 if (doorbell & FT1000_ASIC_RESET_REQ) {
1230 /* Copy DSP session record from info block */
1231 spin_lock_irqsave(&info->dpram_lock, flags);
1232 if (info->AsicID == ELECTRABUZZ_ID) {
1233 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
1234 FT1000_DPRAM_RX_BASE);
1235 for (i = 0; i < MAX_DSP_SESS_REC; i++) {
1236 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA,
1237 info->DSPSess.Rec[i]);
1240 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
1241 FT1000_DPRAM_MAG_RX_BASE);
1242 for (i = 0; i < MAX_DSP_SESS_REC / 2; i++) {
1243 outl(info->DSPSess.MagRec[i],
1244 dev->base_addr + FT1000_REG_MAG_DPDATA);
1247 spin_unlock_irqrestore(&info->dpram_lock, flags);
1249 /* clear ASIC RESET request */
1250 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1251 FT1000_ASIC_RESET_REQ);
1252 pr_debug("Got an ASIC RESET Request\n");
1253 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1254 FT1000_ASIC_RESET_DSP);
1256 if (info->AsicID == MAGNEMITE_ID) {
1257 /* Setting MAGNEMITE ASIC to big endian mode */
1258 ft1000_write_reg(dev, FT1000_REG_SUP_CTRL,
1263 if (doorbell & FT1000_DSP_ASIC_RESET) {
1264 pr_debug("Got a dsp ASIC reset message\n");
1265 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1266 FT1000_DSP_ASIC_RESET);
1271 if (doorbell & FT1000_DB_DPRAM_RX) {
1272 pr_debug("Got a slow queue message\n");
1273 nxtph = FT1000_DPRAM_RX_BASE + 2;
1274 if (info->AsicID == ELECTRABUZZ_ID) {
1276 ft1000_read_dpram(dev, FT1000_DPRAM_RX_BASE);
1279 ntohs(ft1000_read_dpram_mag_16
1280 (dev, FT1000_MAG_TOTAL_LEN,
1281 FT1000_MAG_TOTAL_LEN_INDX));
1283 pr_debug("total length = %d\n", total_len);
1284 if ((total_len < MAX_CMD_SQSIZE) && (total_len > sizeof(struct pseudo_hdr))) {
1287 * ft1000_read_reg will return a value that needs to be byteswap
1288 * in order to get DSP_QID_OFFSET.
1290 if (info->AsicID == ELECTRABUZZ_ID) {
1294 DSP_QID_OFFSET + FT1000_DPRAM_RX_BASE +
1298 (ft1000_read_dpram_mag_16
1299 (dev, FT1000_MAG_PORT_ID,
1300 FT1000_MAG_PORT_ID_INDX) & 0xff);
1302 pr_debug("DSP_QID = 0x%x\n", portid);
1304 if (portid == DRIVERID) {
1305 /* We are assumming one driver message from the DSP at a time. */
1306 ft1000_proc_drvmsg(dev);
1309 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_RX);
1312 if (doorbell & FT1000_DB_COND_RESET) {
1313 /* Reset ASIC and DSP */
1314 if (info->AsicID == ELECTRABUZZ_ID) {
1316 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
1318 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
1320 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
1322 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
1325 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER0,
1326 FT1000_MAG_DSP_TIMER0_INDX);
1328 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER1,
1329 FT1000_MAG_DSP_TIMER1_INDX);
1331 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER2,
1332 FT1000_MAG_DSP_TIMER2_INDX);
1334 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER3,
1335 FT1000_MAG_DSP_TIMER3_INDX);
1337 info->DrvErrNum = DSP_CONDRESET_INFO;
1338 pr_debug("DSP conditional reset requested\n");
1339 ft1000_reset_card(dev);
1340 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1341 FT1000_DB_COND_RESET);
1343 /* let's clear any unexpected doorbells from DSP */
1345 doorbell & ~(FT1000_DB_DPRAM_RX | FT1000_ASIC_RESET_REQ |
1346 FT1000_DB_COND_RESET | 0xff00);
1348 pr_debug("Clearing unexpected doorbell = 0x%x\n", doorbell);
1349 ft1000_write_reg(dev, FT1000_REG_DOORBELL, doorbell);
1356 /*---------------------------------------------------------------------------
1358 Function: ft1000_flush_fifo
1359 Description: This function will flush one packet from the downlink
1362 dev - device structure
1363 drv_err - driver error causing the flush fifo
1367 -------------------------------------------------------------------------*/
1368 static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum)
1370 struct ft1000_info *info = netdev_priv(dev);
1371 struct ft1000_pcmcia *pcmcia = info->priv;
1376 if (pcmcia->PktIntfErr > MAX_PH_ERR) {
1377 if (info->AsicID == ELECTRABUZZ_ID) {
1379 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
1381 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
1383 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
1385 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
1388 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER0,
1389 FT1000_MAG_DSP_TIMER0_INDX);
1391 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER1,
1392 FT1000_MAG_DSP_TIMER1_INDX);
1394 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER2,
1395 FT1000_MAG_DSP_TIMER2_INDX);
1397 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER3,
1398 FT1000_MAG_DSP_TIMER3_INDX);
1400 info->DrvErrNum = DrvErrNum;
1401 ft1000_reset_card(dev);
1404 /* Flush corrupted pkt from FIFO */
1407 if (info->AsicID == ELECTRABUZZ_ID) {
1409 ft1000_read_reg(dev, FT1000_REG_DFIFO);
1411 ft1000_read_reg(dev, FT1000_REG_DFIFO_STAT);
1414 inl(dev->base_addr + FT1000_REG_MAG_DFR);
1416 inw(dev->base_addr + FT1000_REG_MAG_DFSR);
1420 * This should never happen unless the ASIC is broken.
1421 * We must reset to recover.
1423 if ((i > 2048) || (tempword == 0)) {
1424 if (info->AsicID == ELECTRABUZZ_ID) {
1426 ft1000_read_dpram(dev,
1429 ft1000_read_dpram(dev,
1432 ft1000_read_dpram(dev,
1435 ft1000_read_dpram(dev,
1439 ft1000_read_dpram_mag_16(dev,
1440 FT1000_MAG_DSP_TIMER0,
1441 FT1000_MAG_DSP_TIMER0_INDX);
1443 ft1000_read_dpram_mag_16(dev,
1444 FT1000_MAG_DSP_TIMER1,
1445 FT1000_MAG_DSP_TIMER1_INDX);
1447 ft1000_read_dpram_mag_16(dev,
1448 FT1000_MAG_DSP_TIMER2,
1449 FT1000_MAG_DSP_TIMER2_INDX);
1451 ft1000_read_dpram_mag_16(dev,
1452 FT1000_MAG_DSP_TIMER3,
1453 FT1000_MAG_DSP_TIMER3_INDX);
1455 if (tempword == 0) {
1457 * Let's check if ASIC reads are still ok by reading the Mask register
1458 * which is never zero at this point of the code.
1461 inw(dev->base_addr +
1462 FT1000_REG_SUP_IMASK);
1463 if (tempword == 0) {
1464 /* This indicates that we can not communicate with the ASIC */
1468 /* Let's assume that we really flush the FIFO */
1469 pcmcia->PktIntfErr++;
1473 info->DrvErrNum = FIFO_FLUSH_MAXLIMIT;
1477 tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT);
1478 } while ((tempword & 0x03) != 0x03);
1479 if (info->AsicID == ELECTRABUZZ_ID) {
1481 pr_debug("Flushing FIFO complete = %x\n", tempword);
1482 /* Flush last word in FIFO. */
1483 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1484 /* Update FIFO counter for DSP */
1486 pr_debug("Flush Data byte count to dsp = %d\n", i);
1487 info->fifo_cnt += i;
1488 ft1000_write_dpram(dev, FT1000_FIFO_LEN,
1491 pr_debug("Flushing FIFO complete = %x\n", tempword);
1492 /* Flush last word in FIFO */
1493 templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1494 tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT);
1495 pr_debug("FT1000_REG_SUP_STAT = 0x%x\n", tempword);
1496 tempword = inw(dev->base_addr + FT1000_REG_MAG_DFSR);
1497 pr_debug("FT1000_REG_MAG_DFSR = 0x%x\n", tempword);
1500 pcmcia->PktIntfErr++;
1504 /*---------------------------------------------------------------------------
1506 Function: ft1000_copy_up_pkt
1507 Description: This function will pull Flarion packets out of the Downlink
1508 FIFO and convert it to an ethernet packet. The ethernet packet will
1509 then be deliver to the TCP/IP stack.
1511 dev - device structure
1516 -------------------------------------------------------------------------*/
1517 static int ft1000_copy_up_pkt(struct net_device *dev)
1520 struct ft1000_info *info = netdev_priv(dev);
1522 struct sk_buff *skb;
1531 if (info->AsicID == ELECTRABUZZ_ID) {
1532 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1535 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1536 len = ntohs(tempword);
1539 pr_debug("Number of Bytes in FIFO = %d\n", len);
1541 if (len > ENET_MAX_SIZE) {
1542 pr_debug("size of ethernet packet invalid\n");
1543 if (info->AsicID == MAGNEMITE_ID) {
1544 /* Read High word to complete 32 bit access */
1545 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1547 ft1000_flush_fifo(dev, DSP_PKTLEN_INFO);
1548 info->stats.rx_errors++;
1552 skb = dev_alloc_skb(len + 12 + 2);
1555 pr_debug("No Network buffers available\n");
1556 /* Read High word to complete 32 bit access */
1557 if (info->AsicID == MAGNEMITE_ID)
1558 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1560 ft1000_flush_fifo(dev, 0);
1561 info->stats.rx_errors++;
1564 pbuffer = (u8 *)skb_put(skb, len + 12);
1567 if (info->AsicID == ELECTRABUZZ_ID) {
1568 for (i = 1; i < 7; i++) {
1569 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1572 /* read checksum value */
1573 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1575 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1576 pr_debug("Pseudo = 0x%x\n", tempword);
1579 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1580 pr_debug("Pseudo = 0x%x\n", tempword);
1583 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1584 pr_debug("Pseudo = 0x%x\n", tempword);
1587 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1588 pr_debug("Pseudo = 0x%x\n", tempword);
1591 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1592 pr_debug("Pseudo = 0x%x\n", tempword);
1595 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1596 pr_debug("Pseudo = 0x%x\n", tempword);
1599 /* read checksum value */
1600 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1601 pr_debug("Pseudo = 0x%x\n", tempword);
1604 if (chksum != tempword) {
1605 pr_debug("Packet checksum mismatch 0x%x 0x%x\n",
1607 ft1000_flush_fifo(dev, DSP_PKTPHCKSUM_INFO);
1608 info->stats.rx_errors++;
1612 /* subtract the number of bytes read already */
1615 /* fake MAC address */
1616 *pbuffer++ = dev->dev_addr[0];
1617 *pbuffer++ = dev->dev_addr[1];
1618 *pbuffer++ = dev->dev_addr[2];
1619 *pbuffer++ = dev->dev_addr[3];
1620 *pbuffer++ = dev->dev_addr[4];
1621 *pbuffer++ = dev->dev_addr[5];
1629 if (info->AsicID == ELECTRABUZZ_ID) {
1630 for (i = 0; i < len / 2; i++) {
1631 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1632 *pbuffer++ = (u8) (tempword >> 8);
1633 *pbuffer++ = (u8)tempword;
1634 if (ft1000_chkcard(dev) == false) {
1640 /* Need to read one more word if odd byte */
1642 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1643 *pbuffer++ = (u8) (tempword >> 8);
1646 ptemplong = (u32 *)pbuffer;
1647 for (i = 0; i < len / 4; i++) {
1648 templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1649 pr_debug("Data = 0x%8x\n", templong);
1650 *ptemplong++ = templong;
1653 /* Need to read one more word if odd align. */
1655 templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1656 pr_debug("Data = 0x%8x\n", templong);
1657 *ptemplong++ = templong;
1662 pr_debug("Data passed to Protocol layer:\n");
1663 for (i = 0; i < len + 12; i++)
1664 pr_debug("Protocol Data: 0x%x\n", *ptemp++);
1667 skb->protocol = eth_type_trans(skb, dev);
1668 skb->ip_summed = CHECKSUM_UNNECESSARY;
1671 info->stats.rx_packets++;
1672 /* Add on 12 bytes for MAC address which was removed */
1673 info->stats.rx_bytes += (len + 12);
1675 if (info->AsicID == ELECTRABUZZ_ID) {
1676 /* track how many bytes have been read from FIFO - round up to 16 bit word */
1677 tempword = len + 16;
1678 if (tempword & 0x01)
1680 info->fifo_cnt += tempword;
1681 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_FIFO_LEN);
1682 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, info->fifo_cnt);
1688 /*---------------------------------------------------------------------------
1690 Function: ft1000_copy_down_pkt
1691 Description: This function will take an ethernet packet and convert it to
1692 a Flarion packet prior to sending it to the ASIC Downlink
1695 dev - device structure
1696 packet - address of ethernet packet
1697 len - length of IP packet
1702 -------------------------------------------------------------------------*/
1703 static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len)
1705 struct ft1000_info *info = netdev_priv(dev);
1706 struct ft1000_pcmcia *pcmcia = info->priv;
1708 struct pseudo_hdr blk;
1709 u16 buff[sizeof(struct pseudo_hdr) >> 1];
1710 u8 buffc[sizeof(struct pseudo_hdr)];
1715 /* Check if there is room on the FIFO */
1716 if (len > ft1000_read_fifo_len(dev)) {
1718 if (len > ft1000_read_fifo_len(dev))
1720 if (len > ft1000_read_fifo_len(dev))
1722 if (len > ft1000_read_fifo_len(dev))
1724 if (len > ft1000_read_fifo_len(dev))
1726 if (len > ft1000_read_fifo_len(dev))
1728 if (len > ft1000_read_fifo_len(dev)) {
1729 pr_debug("Transmit FIFO is full - pkt drop\n");
1730 info->stats.tx_errors++;
1734 /* Create pseudo header and send pseudo/ip to hardware */
1735 if (info->AsicID == ELECTRABUZZ_ID)
1736 pseudo.blk.length = len;
1738 pseudo.blk.length = ntohs(len);
1740 pseudo.blk.source = DSPID; /* Need to swap to get in correct order */
1741 pseudo.blk.destination = HOSTID;
1742 pseudo.blk.portdest = NETWORKID; /* Need to swap to get in correct order */
1743 pseudo.blk.portsrc = DSPAIRID;
1744 pseudo.blk.sh_str_id = 0;
1745 pseudo.blk.control = 0;
1746 pseudo.blk.rsvd1 = 0;
1747 pseudo.blk.seq_num = 0;
1748 pseudo.blk.rsvd2 = pcmcia->packetseqnum++;
1749 pseudo.blk.qos_class = 0;
1750 /* Calculate pseudo header checksum */
1751 pseudo.blk.checksum = pseudo.buff[0];
1752 for (i = 1; i < 7; i++)
1753 pseudo.blk.checksum ^= pseudo.buff[i];
1755 /* Production Mode */
1756 if (info->AsicID == ELECTRABUZZ_ID) {
1757 /* copy first word to UFIFO_BEG reg */
1758 ft1000_write_reg(dev, FT1000_REG_UFIFO_BEG, pseudo.buff[0]);
1759 pr_debug("data 0 BEG = 0x%04x\n", pseudo.buff[0]);
1761 /* copy subsequent words to UFIFO_MID reg */
1762 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[1]);
1763 pr_debug("data 1 MID = 0x%04x\n", pseudo.buff[1]);
1764 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[2]);
1765 pr_debug("data 2 MID = 0x%04x\n", pseudo.buff[2]);
1766 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[3]);
1767 pr_debug("data 3 MID = 0x%04x\n", pseudo.buff[3]);
1768 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[4]);
1769 pr_debug("data 4 MID = 0x%04x\n", pseudo.buff[4]);
1770 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[5]);
1771 pr_debug("data 5 MID = 0x%04x\n", pseudo.buff[5]);
1772 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[6]);
1773 pr_debug("data 6 MID = 0x%04x\n", pseudo.buff[6]);
1774 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[7]);
1775 pr_debug("data 7 MID = 0x%04x\n", pseudo.buff[7]);
1777 /* Write PPP type + IP Packet into Downlink FIFO */
1778 for (i = 0; i < (len >> 1) - 1; i++) {
1779 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID,
1781 pr_debug("data %d MID = 0x%04x\n",
1782 i + 8, htons(*packet));
1786 /* Check for odd byte */
1788 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID,
1790 pr_debug("data MID = 0x%04x\n", htons(*packet));
1792 ft1000_write_reg(dev, FT1000_REG_UFIFO_END,
1794 pr_debug("data %d MID = 0x%04x\n",
1795 i + 8, htons(*packet));
1797 ft1000_write_reg(dev, FT1000_REG_UFIFO_END,
1799 pr_debug("data %d MID = 0x%04x\n",
1800 i + 8, htons(*packet));
1803 outl(*(u32 *)&pseudo.buff[0],
1804 dev->base_addr + FT1000_REG_MAG_UFDR);
1805 pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[0]);
1806 outl(*(u32 *)&pseudo.buff[2],
1807 dev->base_addr + FT1000_REG_MAG_UFDR);
1808 pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[2]);
1809 outl(*(u32 *)&pseudo.buff[4],
1810 dev->base_addr + FT1000_REG_MAG_UFDR);
1811 pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[4]);
1812 outl(*(u32 *)&pseudo.buff[6],
1813 dev->base_addr + FT1000_REG_MAG_UFDR);
1814 pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[6]);
1816 plong = (u32 *)packet;
1817 /* Write PPP type + IP Packet into Downlink FIFO */
1818 for (i = 0; i < (len >> 2); i++)
1819 outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
1821 /* Check for odd alignment */
1823 pr_debug("data = 0x%8x\n", *plong);
1824 outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
1826 outl(1, dev->base_addr + FT1000_REG_MAG_UFER);
1829 info->stats.tx_packets++;
1830 /* Add 14 bytes for MAC address plus ethernet type */
1831 info->stats.tx_bytes += (len + 14);
1835 static struct net_device_stats *ft1000_stats(struct net_device *dev)
1837 struct ft1000_info *info = netdev_priv(dev);
1839 return &info->stats;
1842 static int ft1000_open(struct net_device *dev)
1844 ft1000_reset_card(dev);
1846 /* schedule ft1000_hbchk to perform periodic heartbeat checks on DSP and ASIC */
1847 init_timer(&poll_timer);
1848 poll_timer.expires = jiffies + (2 * HZ);
1849 poll_timer.data = (u_long)dev;
1850 add_timer(&poll_timer);
1855 static int ft1000_close(struct net_device *dev)
1857 struct ft1000_info *info = netdev_priv(dev);
1859 info->CardReady = 0;
1860 del_timer(&poll_timer);
1862 if (ft1000_card_present == 1) {
1863 pr_debug("Media is down\n");
1864 netif_stop_queue(dev);
1866 ft1000_disable_interrupts(dev);
1867 ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
1870 ft1000_reset_asic(dev);
1875 static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
1877 struct ft1000_info *info = netdev_priv(dev);
1881 pr_debug("skb == NULL!!!\n");
1885 pr_debug("length of packet = %d\n", skb->len);
1887 pdata = (u8 *)skb->data;
1889 if (info->mediastate == 0) {
1890 /* Drop packet is mediastate is down */
1891 pr_debug("mediastate is down\n");
1895 if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) {
1896 /* Drop packet which has invalid size */
1897 pr_debug("invalid ethernet length\n");
1900 ft1000_copy_down_pkt(dev, (u16 *) (pdata + ENET_HEADER_SIZE - 2),
1901 skb->len - ENET_HEADER_SIZE + 2);
1908 static irqreturn_t ft1000_interrupt(int irq, void *dev_id)
1910 struct net_device *dev = dev_id;
1911 struct ft1000_info *info = netdev_priv(dev);
1916 if (info->CardReady == 0) {
1917 ft1000_disable_interrupts(dev);
1921 if (ft1000_chkcard(dev) == false) {
1922 ft1000_disable_interrupts(dev);
1926 ft1000_disable_interrupts(dev);
1928 /* Read interrupt type */
1929 inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
1931 /* Make sure we process all interrupt before leaving the ISR due to the edge trigger interrupt type */
1933 if (inttype & ISR_DOORBELL_PEND)
1934 ft1000_parse_dpram_msg(dev);
1936 if (inttype & ISR_RCV) {
1937 pr_debug("Data in FIFO\n");
1941 /* Check if we have packets in the Downlink FIFO */
1942 if (info->AsicID == ELECTRABUZZ_ID) {
1944 ft1000_read_reg(dev,
1945 FT1000_REG_DFIFO_STAT);
1948 ft1000_read_reg(dev,
1949 FT1000_REG_MAG_DFSR);
1951 if (tempword & 0x1f) {
1952 ft1000_copy_up_pkt(dev);
1957 } while (cnt < MAX_RCV_LOOP);
1960 /* clear interrupts */
1961 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
1962 pr_debug("interrupt status register = 0x%x\n", tempword);
1963 ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword);
1965 /* Read interrupt type */
1966 inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
1967 pr_debug("interrupt status register after clear = 0x%x\n",
1970 ft1000_enable_interrupts(dev);
1974 void stop_ft1000_card(struct net_device *dev)
1976 struct ft1000_info *info = netdev_priv(dev);
1977 struct prov_record *ptr;
1980 info->CardReady = 0;
1981 ft1000_card_present = 0;
1982 netif_stop_queue(dev);
1983 ft1000_disable_interrupts(dev);
1985 /* Make sure we free any memory reserve for provisioning */
1986 while (list_empty(&info->prov_list) == 0) {
1987 ptr = list_entry(info->prov_list.next, struct prov_record, list);
1988 list_del(&ptr->list);
1989 kfree(ptr->pprov_data);
1995 if (info->registered) {
1996 unregister_netdev(dev);
1997 info->registered = 0;
2000 free_irq(dev->irq, dev);
2001 release_region(dev->base_addr, 256);
2002 release_firmware(fw_entry);
2003 flarion_ft1000_cnt--;
2007 static void ft1000_get_drvinfo(struct net_device *dev,
2008 struct ethtool_drvinfo *info)
2010 struct ft1000_info *ft_info;
2011 ft_info = netdev_priv(dev);
2013 strlcpy(info->driver, "ft1000", sizeof(info->driver));
2014 snprintf(info->bus_info, sizeof(info->bus_info), "PCMCIA 0x%lx",
2016 snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d.%d",
2017 ft_info->DspVer[0], ft_info->DspVer[1], ft_info->DspVer[2],
2018 ft_info->DspVer[3]);
2021 static u32 ft1000_get_link(struct net_device *dev)
2023 struct ft1000_info *info;
2025 info = netdev_priv(dev);
2026 return info->mediastate;
2029 static const struct ethtool_ops ops = {
2030 .get_drvinfo = ft1000_get_drvinfo,
2031 .get_link = ft1000_get_link
2034 struct net_device *init_ft1000_card(struct pcmcia_device *link,
2037 struct ft1000_info *info;
2038 struct ft1000_pcmcia *pcmcia;
2039 struct net_device *dev;
2041 static const struct net_device_ops ft1000ops = /* Slavius 21.10.2009 due to kernel changes */
2043 .ndo_open = &ft1000_open,
2044 .ndo_stop = &ft1000_close,
2045 .ndo_start_xmit = &ft1000_start_xmit,
2046 .ndo_get_stats = &ft1000_stats,
2049 pr_debug("irq = %d, port = 0x%04llx\n",
2050 link->irq, (unsigned long long)link->resource[0]->start);
2052 flarion_ft1000_cnt++;
2054 if (flarion_ft1000_cnt > 1) {
2055 flarion_ft1000_cnt--;
2057 dev_info(&link->dev,
2058 "This driver can not support more than one instance\n");
2062 dev = alloc_etherdev(sizeof(struct ft1000_info));
2064 dev_err(&link->dev, "Failed to allocate etherdev\n");
2068 SET_NETDEV_DEV(dev, &link->dev);
2069 info = netdev_priv(dev);
2071 memset(info, 0, sizeof(struct ft1000_info));
2073 pr_debug("address of dev = 0x%p\n", dev);
2074 pr_debug("address of dev info = 0x%p\n", info);
2075 pr_debug("device name = %s\n", dev->name);
2077 memset(&info->stats, 0, sizeof(struct net_device_stats));
2079 info->priv = kzalloc(sizeof(struct ft1000_pcmcia), GFP_KERNEL);
2080 pcmcia = info->priv;
2081 pcmcia->link = link;
2083 spin_lock_init(&info->dpram_lock);
2084 info->DrvErrNum = 0;
2085 info->registered = 1;
2086 info->ft1000_reset = ft1000_reset;
2087 info->mediastate = 0;
2089 info->CardReady = 0;
2090 info->DSP_TIME[0] = 0;
2091 info->DSP_TIME[1] = 0;
2092 info->DSP_TIME[2] = 0;
2093 info->DSP_TIME[3] = 0;
2094 flarion_ft1000_cnt = 0;
2096 INIT_LIST_HEAD(&info->prov_list);
2098 info->squeseqnum = 0;
2100 /* dev->hard_start_xmit = &ft1000_start_xmit; */
2101 /* dev->get_stats = &ft1000_stats; */
2102 /* dev->open = &ft1000_open; */
2103 /* dev->stop = &ft1000_close; */
2105 dev->netdev_ops = &ft1000ops; /* Slavius 21.10.2009 due to kernel changes */
2107 pr_debug("device name = %s\n", dev->name);
2109 dev->irq = link->irq;
2110 dev->base_addr = link->resource[0]->start;
2111 if (pcmcia_get_mac_from_cis(link, dev)) {
2112 netdev_err(dev, "Could not read mac address\n");
2116 if (request_irq(dev->irq, ft1000_interrupt, IRQF_SHARED, dev->name, dev)) {
2117 netdev_err(dev, "Could not request_irq\n");
2121 if (request_region(dev->base_addr, 256, dev->name) == NULL) {
2122 netdev_err(dev, "Could not request_region\n");
2126 if (register_netdev(dev) != 0) {
2127 pr_debug("Could not register netdev\n");
2131 info->AsicID = ft1000_read_reg(dev, FT1000_REG_ASIC_ID);
2132 if (info->AsicID == ELECTRABUZZ_ID) {
2133 pr_debug("ELECTRABUZZ ASIC\n");
2134 if (request_firmware(&fw_entry, "ft1000.img", &link->dev) != 0) {
2135 pr_info("Could not open ft1000.img\n");
2139 pr_debug("MAGNEMITE ASIC\n");
2140 if (request_firmware(&fw_entry, "ft2000.img", &link->dev) != 0) {
2141 pr_info("Could not open ft2000.img\n");
2146 ft1000_enable_interrupts(dev);
2148 ft1000_card_present = 1;
2149 dev->ethtool_ops = &ops;
2150 pr_info("%s: addr 0x%04lx irq %d, MAC addr %pM\n",
2151 dev->name, dev->base_addr, dev->irq, dev->dev_addr);
2155 unregister_netdev(dev);
2157 release_region(dev->base_addr, 256);
2159 free_irq(dev->irq, dev);