Merge branch 'master' into next
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / ft1000 / ft1000-pcmcia / ft1000_hw.c
CommitLineData
f7c1be0c
MB
1/*---------------------------------------------------------------------------
2 FT1000 driver for Flarion Flash OFDM NIC Device
bf3146c8 3
f7c1be0c
MB
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.
bf3146c8
GKH
7
8 This program is free software; you can redistribute it and/or modify it
f7c1be0c 9 under the terms of the GNU General Public License as published by the Free
bf3146c8
GKH
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.
f7c1be0c
MB
18-----------------------------------------------------------------------------*/
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/proc_fs.h>
23
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>
30#include <linux/in.h>
31#include <asm/io.h>
32#include <asm/system.h>
33#include <asm/bitops.h>
34
35#include <linux/netdevice.h>
36#include <linux/etherdevice.h>
37#include <linux/skbuff.h>
38#include <linux/if_arp.h>
39#include <linux/ioport.h>
40#include <linux/wait.h>
41#include <linux/vmalloc.h>
42
43#include <linux/firmware.h>
44#include <linux/ethtool.h>
45
c331e766
MB
46#include <pcmcia/cistpl.h>
47#include <pcmcia/cisreg.h>
48#include <pcmcia/ds.h>
49
f7c1be0c
MB
50#ifdef FT_DEBUG
51#define DEBUG(n, args...) printk(KERN_DEBUG args);
52#else
53#define DEBUG(n, args...)
54#endif
55
56#include <linux/delay.h>
57#include "ft1000_dev.h"
58#include "ft1000.h"
59
c331e766 60int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength);
f7c1be0c
MB
61
62void ft1000InitProc(struct net_device *dev);
63void ft1000CleanupProc(struct net_device *dev);
64
65const struct firmware *fw_entry;
66
67static void ft1000_hbchk(u_long data);
68static struct timer_list poll_timer = {
69 function:ft1000_hbchk
70};
71
72static u16 cmdbuffer[1024];
73static u8 tempbuffer[1600];
74static u8 ft1000_card_present = 0;
75static u8 flarion_ft1000_cnt = 0;
76
77static irqreturn_t ft1000_interrupt(int irq, void *dev_id);
78static void ft1000_enable_interrupts(struct net_device *dev);
79static void ft1000_disable_interrupts(struct net_device *dev);
80
81/* new kernel */
82MODULE_AUTHOR("");
83MODULE_DESCRIPTION
84 ("Support for Flarion Flash OFDM NIC Device. Support for PCMCIA when used with ft1000_cs.");
85MODULE_LICENSE("GPL");
86MODULE_SUPPORTED_DEVICE("FT1000");
87
88#define MAX_RCV_LOOP 100
89
90//---------------------------------------------------------------------------
91//
92// Function: ft1000_asic_read
25985edc 93// Description: This function will retrieve the value of a specific ASIC
f7c1be0c
MB
94// register.
95// Input:
96// dev - network device structure
97// offset - ASIC register to read
98// Output:
99// value - value of ASIC register
100//
101//---------------------------------------------------------------------------
102inline u16 ft1000_asic_read(struct net_device *dev, u16 offset)
103{
104 return (ft1000_read_reg(dev, offset));
105}
106
107//---------------------------------------------------------------------------
108//
109// Function: ft1000_asic_write
25985edc 110// Description: This function will set the value of a specific ASIC
f7c1be0c
MB
111// register.
112// Input:
113// dev - network device structure
114// value - value to set ASIC register
115// Output:
116// none
117//
118//---------------------------------------------------------------------------
119inline void ft1000_asic_write(struct net_device *dev, u16 offset, u16 value)
120{
121 ft1000_write_reg(dev, offset, value);
122}
123
124//---------------------------------------------------------------------------
125//
126// Function: ft1000_read_fifo_len
25985edc 127// Description: This function will read the ASIC Uplink FIFO status register
f7c1be0c
MB
128// which will return the number of bytes remaining in the Uplink FIFO.
129// Sixteen bytes are subtracted to make sure that the ASIC does not
130// reach its threshold.
131// Input:
132// dev - network device structure
133// Output:
134// value - number of bytes available in the ASIC Uplink FIFO.
135//
136//---------------------------------------------------------------------------
137static inline u16 ft1000_read_fifo_len(struct net_device *dev)
138{
e33196e1 139 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
140
141 if (info->AsicID == ELECTRABUZZ_ID) {
142 return (ft1000_read_reg(dev, FT1000_REG_UFIFO_STAT) - 16);
143 } else {
144 return (ft1000_read_reg(dev, FT1000_REG_MAG_UFSR) - 16);
145 }
146}
147
148//---------------------------------------------------------------------------
149//
150// Function: ft1000_read_dpram
25985edc 151// Description: This function will read the specific area of dpram
f7c1be0c
MB
152// (Electrabuzz ASIC only)
153// Input:
154// dev - device structure
155// offset - index of dpram
156// Output:
157// value - value of dpram
158//
159//---------------------------------------------------------------------------
160u16 ft1000_read_dpram(struct net_device * dev, int offset)
161{
e33196e1 162 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
163 unsigned long flags;
164 u16 data;
165
166 // Provide mutual exclusive access while reading ASIC registers.
167 spin_lock_irqsave(&info->dpram_lock, flags);
168 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
169 data = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
170 spin_unlock_irqrestore(&info->dpram_lock, flags);
171
172 return (data);
173}
174
175//---------------------------------------------------------------------------
176//
177// Function: ft1000_write_dpram
25985edc 178// Description: This function will write to a specific area of dpram
f7c1be0c
MB
179// (Electrabuzz ASIC only)
180// Input:
181// dev - device structure
182// offset - index of dpram
183// value - value to write
184// Output:
185// none.
186//
187//---------------------------------------------------------------------------
188static inline void ft1000_write_dpram(struct net_device *dev,
189 int offset, u16 value)
190{
e33196e1 191 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
192 unsigned long flags;
193
194 // Provide mutual exclusive access while reading ASIC registers.
195 spin_lock_irqsave(&info->dpram_lock, flags);
196 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
197 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, value);
198 spin_unlock_irqrestore(&info->dpram_lock, flags);
199}
200
201//---------------------------------------------------------------------------
202//
203// Function: ft1000_read_dpram_mag_16
25985edc 204// Description: This function will read the specific area of dpram
f7c1be0c
MB
205// (Magnemite ASIC only)
206// Input:
207// dev - device structure
208// offset - index of dpram
209// Output:
210// value - value of dpram
211//
212//---------------------------------------------------------------------------
213u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index)
214{
e33196e1 215 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
216 unsigned long flags;
217 u16 data;
218
219 // Provide mutual exclusive access while reading ASIC registers.
220 spin_lock_irqsave(&info->dpram_lock, flags);
221 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
222 // check if we want to read upper or lower 32-bit word
223 if (Index) {
224 data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAL);
225 } else {
226 data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAH);
227 }
228 spin_unlock_irqrestore(&info->dpram_lock, flags);
229
230 return (data);
231}
232
233//---------------------------------------------------------------------------
234//
235// Function: ft1000_write_dpram_mag_16
25985edc 236// Description: This function will write to a specific area of dpram
f7c1be0c
MB
237// (Magnemite ASIC only)
238// Input:
239// dev - device structure
240// offset - index of dpram
241// value - value to write
242// Output:
243// none.
244//
245//---------------------------------------------------------------------------
246static inline void ft1000_write_dpram_mag_16(struct net_device *dev,
247 int offset, u16 value, int Index)
248{
e33196e1 249 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
250 unsigned long flags;
251
252 // Provide mutual exclusive access while reading ASIC registers.
253 spin_lock_irqsave(&info->dpram_lock, flags);
254 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
255 if (Index) {
256 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAL, value);
257 } else {
258 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, value);
259 }
260 spin_unlock_irqrestore(&info->dpram_lock, flags);
261}
262
263//---------------------------------------------------------------------------
264//
265// Function: ft1000_read_dpram_mag_32
25985edc 266// Description: This function will read the specific area of dpram
f7c1be0c
MB
267// (Magnemite ASIC only)
268// Input:
269// dev - device structure
270// offset - index of dpram
271// Output:
272// value - value of dpram
273//
274//---------------------------------------------------------------------------
275u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset)
276{
e33196e1 277 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
278 unsigned long flags;
279 u32 data;
280
281 // Provide mutual exclusive access while reading ASIC registers.
282 spin_lock_irqsave(&info->dpram_lock, flags);
283 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
284 data = inl(dev->base_addr + FT1000_REG_MAG_DPDATAL);
285 spin_unlock_irqrestore(&info->dpram_lock, flags);
286
287 return (data);
288}
289
290//---------------------------------------------------------------------------
291//
292// Function: ft1000_write_dpram_mag_32
25985edc 293// Description: This function will write to a specific area of dpram
f7c1be0c
MB
294// (Magnemite ASIC only)
295// Input:
296// dev - device structure
297// offset - index of dpram
298// value - value to write
299// Output:
300// none.
301//
302//---------------------------------------------------------------------------
303void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value)
304{
e33196e1 305 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
306 unsigned long flags;
307
308 // Provide mutual exclusive access while reading ASIC registers.
309 spin_lock_irqsave(&info->dpram_lock, flags);
310 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
311 outl(value, dev->base_addr + FT1000_REG_MAG_DPDATAL);
312 spin_unlock_irqrestore(&info->dpram_lock, flags);
313}
314
315//---------------------------------------------------------------------------
316//
317// Function: ft1000_enable_interrupts
25985edc 318// Description: This function will enable interrupts base on the current interrupt mask.
f7c1be0c
MB
319// Input:
320// dev - device structure
321// Output:
322// None.
323//
324//---------------------------------------------------------------------------
325static void ft1000_enable_interrupts(struct net_device *dev)
326{
e33196e1 327 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
328 u16 tempword;
329
330 DEBUG(1, "ft1000_hw:ft1000_enable_interrupts()\n");
331 ft1000_write_reg(dev, FT1000_REG_SUP_IMASK,
332 info->CurrentInterruptEnableMask);
333 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
334 DEBUG(1,
335 "ft1000_hw:ft1000_enable_interrupts:current interrupt enable mask = 0x%x\n",
336 tempword);
337 info->InterruptsEnabled = TRUE;
338}
339
340//---------------------------------------------------------------------------
341//
342// Function: ft1000_disable_interrupts
25985edc 343// Description: This function will disable all interrupts.
f7c1be0c
MB
344// Input:
345// dev - device structure
346// Output:
347// None.
348//
349//---------------------------------------------------------------------------
350static void ft1000_disable_interrupts(struct net_device *dev)
351{
e33196e1 352 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
353 u16 tempword;
354
355 DEBUG(1, "ft1000_hw: ft1000_disable_interrupts()\n");
356 ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_MASK_ALL);
357 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
358 DEBUG(1,
359 "ft1000_hw:ft1000_disable_interrupts:current interrupt enable mask = 0x%x\n",
360 tempword);
361 info->InterruptsEnabled = FALSE;
362}
363
364//---------------------------------------------------------------------------
365//
366// Function: ft1000_reset_asic
25985edc 367// Description: This function will call the Card Service function to reset the
f7c1be0c
MB
368// ASIC.
369// Input:
370// dev - device structure
371// Output:
372// none
373//
374//---------------------------------------------------------------------------
375static void ft1000_reset_asic(struct net_device *dev)
376{
e33196e1 377 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
378 u16 tempword;
379
380 DEBUG(1, "ft1000_hw:ft1000_reset_asic called\n");
381
382 (*info->ft1000_reset) (info->link);
383 info->ASICResetNum++;
384
385 // Let's use the register provided by the Magnemite ASIC to reset the
386 // ASIC and DSP.
387 if (info->AsicID == MAGNEMITE_ID) {
388 ft1000_write_reg(dev, FT1000_REG_RESET,
389 (DSP_RESET_BIT | ASIC_RESET_BIT));
390 }
391 mdelay(1);
392 if (info->AsicID == ELECTRABUZZ_ID) {
393 // set watermark to -1 in order to not generate an interrrupt
394 ft1000_write_reg(dev, FT1000_REG_WATERMARK, 0xffff);
395 } else {
396 // set watermark to -1 in order to not generate an interrrupt
397 ft1000_write_reg(dev, FT1000_REG_MAG_WATERMARK, 0xffff);
398 }
399 // clear interrupts
400 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
401 DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword);
402 ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword);
403 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
404 DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword);
405
406}
407
408//---------------------------------------------------------------------------
409//
410// Function: ft1000_reset_card
25985edc 411// Description: This function will reset the card
f7c1be0c
MB
412// Input:
413// dev - device structure
414// Output:
415// status - FALSE (card reset fail)
bf3146c8 416// TRUE (card reset successful)
f7c1be0c
MB
417//
418//---------------------------------------------------------------------------
419static int ft1000_reset_card(struct net_device *dev)
420{
e33196e1 421 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
422 u16 tempword;
423 int i;
424 unsigned long flags;
425 PPROV_RECORD ptr;
426
427 DEBUG(1, "ft1000_hw:ft1000_reset_card called.....\n");
428
429 info->CardReady = 0;
430 info->ProgConStat = 0;
431 info->squeseqnum = 0;
432 ft1000_disable_interrupts(dev);
433
434// del_timer(&poll_timer);
435
436 // Make sure we free any memory reserve for provisioning
437 while (list_empty(&info->prov_list) == 0) {
438 DEBUG(0,
439 "ft1000_hw:ft1000_reset_card:deleting provisioning record\n");
440 ptr = list_entry(info->prov_list.next, PROV_RECORD, list);
441 list_del(&ptr->list);
442 kfree(ptr->pprov_data);
443 kfree(ptr);
444 }
445
446 if (info->AsicID == ELECTRABUZZ_ID) {
447 DEBUG(1, "ft1000_hw:ft1000_reset_card:resetting DSP\n");
448 ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
449 } else {
450 DEBUG(1,
451 "ft1000_hw:ft1000_reset_card:resetting ASIC and DSP\n");
452 ft1000_write_reg(dev, FT1000_REG_RESET,
453 (DSP_RESET_BIT | ASIC_RESET_BIT));
454 }
455
bf3146c8 456 // Copy DSP session record into info block if this is not a coldstart
f7c1be0c
MB
457 if (ft1000_card_present == 1) {
458 spin_lock_irqsave(&info->dpram_lock, flags);
459 if (info->AsicID == ELECTRABUZZ_ID) {
460 if (info->DspHibernateFlag == 0) {
461 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
462 FT1000_DPRAM_RX_BASE);
463 for (i = 0; i < MAX_DSP_SESS_REC; i++) {
464 info->DSPSess.Rec[i] =
465 ft1000_read_reg(dev,
466 FT1000_REG_DPRAM_DATA);
467 }
468 }
469 } else {
470 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
471 FT1000_DPRAM_MAG_RX_BASE);
472 for (i = 0; i < MAX_DSP_SESS_REC / 2; i++) {
473 info->DSPSess.MagRec[i] =
474 inl(dev->base_addr + FT1000_REG_MAG_DPDATA);
475 }
476 }
477 spin_unlock_irqrestore(&info->dpram_lock, flags);
478 }
479
480 DEBUG(1, "ft1000_hw:ft1000_reset_card:resetting ASIC\n");
481 mdelay(10);
482 //reset ASIC
483 ft1000_reset_asic(dev);
484
485 info->DSPResetNum++;
486
487 DEBUG(1, "ft1000_hw:ft1000_reset_card:downloading dsp image\n");
488
489 if (info->AsicID == MAGNEMITE_ID) {
490 // Put dsp in reset and take ASIC out of reset
491 DEBUG(0,
492 "ft1000_hw:ft1000_reset_card:Put DSP in reset and take ASIC out of reset\n");
493 ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
494
495 // Setting MAGNEMITE ASIC to big endian mode
496 ft1000_write_reg(dev, FT1000_REG_SUP_CTRL, HOST_INTF_BE);
497 // Download bootloader
498 card_bootload(dev);
499
500 // Take DSP out of reset
501 ft1000_write_reg(dev, FT1000_REG_RESET, 0);
502 // FLARION_DSP_ACTIVE;
503 mdelay(10);
504 DEBUG(0, "ft1000_hw:ft1000_reset_card:Take DSP out of reset\n");
505
506 // Wait for 0xfefe indicating dsp ready before starting download
507 for (i = 0; i < 50; i++) {
508 tempword =
509 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DPRAM_FEFE,
510 FT1000_MAG_DPRAM_FEFE_INDX);
511 if (tempword == 0xfefe) {
512 break;
513 }
514 mdelay(20);
515 }
516
517 if (i == 50) {
518 DEBUG(0,
519 "ft1000_hw:ft1000_reset_card:No FEFE detected from DSP\n");
520 return FALSE;
521 }
522
523 } else {
524 // Take DSP out of reset
525 ft1000_write_reg(dev, FT1000_REG_RESET, ~DSP_RESET_BIT);
526 mdelay(10);
527 }
528
529 if (card_download(dev, fw_entry->data, fw_entry->size)) {
530 DEBUG(1, "card download unsuccessful\n");
531 return FALSE;
532 } else {
533 DEBUG(1, "card download successful\n");
534 }
535
536 mdelay(10);
537
538 if (info->AsicID == ELECTRABUZZ_ID) {
539 // Need to initialize the FIFO length counter to zero in order to sync up
540 // with the DSP
541 info->fifo_cnt = 0;
542 ft1000_write_dpram(dev, FT1000_FIFO_LEN, info->fifo_cnt);
543 // Initialize DSP heartbeat area to ho
544 ft1000_write_dpram(dev, FT1000_HI_HO, ho);
545 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
546 DEBUG(1, "ft1000_hw:ft1000_reset_asic:hi_ho value = 0x%x\n",
547 tempword);
548 } else {
549 // Initialize DSP heartbeat area to ho
550 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, ho_mag,
551 FT1000_MAG_HI_HO_INDX);
552 tempword =
553 ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO,
554 FT1000_MAG_HI_HO_INDX);
555 DEBUG(1, "ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n",
556 tempword);
557 }
558
559 info->CardReady = 1;
560 ft1000_enable_interrupts(dev);
561
562 /* Schedule heartbeat process to run every 2 seconds */
563// poll_timer.expires = jiffies + (2*HZ);
564// poll_timer.data = (u_long)dev;
565// add_timer(&poll_timer);
566
567 return TRUE;
568
569}
570
571//---------------------------------------------------------------------------
572//
573// Function: ft1000_chkcard
25985edc 574// Description: This function will check if the device is presently available on
f7c1be0c
MB
575// the system.
576// Input:
577// dev - device structure
578// Output:
579// status - FALSE (device is not present)
bf3146c8 580// TRUE (device is present)
f7c1be0c
MB
581//
582//---------------------------------------------------------------------------
583static int ft1000_chkcard(struct net_device *dev)
584{
585 u16 tempword;
586
587 // Mask register is used to check for device presence since it is never
588 // set to zero.
589 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
590 if (tempword == 0) {
591 DEBUG(1,
592 "ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n");
593 return FALSE;
594 }
595 // The system will return the value of 0xffff for the version register
596 // if the device is not present.
597 tempword = ft1000_read_reg(dev, FT1000_REG_ASIC_ID);
598 if (tempword == 0xffff) {
599 DEBUG(1,
600 "ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n");
601 return FALSE;
602 }
603 return TRUE;
604}
605
606
607//---------------------------------------------------------------------------
608//
609// Function: ft1000_hbchk
25985edc 610// Description: This function will perform the heart beat check of the DSP as
f7c1be0c
MB
611// well as the ASIC.
612// Input:
613// dev - device structure
614// Output:
615// none
616//
617//---------------------------------------------------------------------------
618static void ft1000_hbchk(u_long data)
619{
620 struct net_device *dev = (struct net_device *)data;
621
622 FT1000_INFO *info;
623 USHORT tempword;
624
e33196e1 625 info = netdev_priv(dev);
f7c1be0c
MB
626
627 if (info->CardReady == 1) {
628 // Perform dsp heartbeat check
629 if (info->AsicID == ELECTRABUZZ_ID) {
630 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
631 } else {
632 tempword =
633 ntohs(ft1000_read_dpram_mag_16
634 (dev, FT1000_MAG_HI_HO,
635 FT1000_MAG_HI_HO_INDX));
636 }
637 DEBUG(1, "ft1000_hw:ft1000_hbchk:hi_ho value = 0x%x\n",
638 tempword);
639 // Let's perform another check if ho is not detected
640 if (tempword != ho) {
641 if (info->AsicID == ELECTRABUZZ_ID) {
642 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
643 }
644 else {
645 tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX));
646 }
bf3146c8 647 }
f7c1be0c
MB
648 if (tempword != ho) {
649 printk(KERN_INFO
650 "ft1000: heartbeat failed - no ho detected\n");
651 if (info->AsicID == ELECTRABUZZ_ID) {
652 info->DSP_TIME[0] =
653 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
654 info->DSP_TIME[1] =
655 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
656 info->DSP_TIME[2] =
657 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
658 info->DSP_TIME[3] =
659 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
660 } else {
661 info->DSP_TIME[0] =
662 ft1000_read_dpram_mag_16(dev,
663 FT1000_MAG_DSP_TIMER0,
664 FT1000_MAG_DSP_TIMER0_INDX);
665 info->DSP_TIME[1] =
666 ft1000_read_dpram_mag_16(dev,
667 FT1000_MAG_DSP_TIMER1,
668 FT1000_MAG_DSP_TIMER1_INDX);
669 info->DSP_TIME[2] =
670 ft1000_read_dpram_mag_16(dev,
671 FT1000_MAG_DSP_TIMER2,
672 FT1000_MAG_DSP_TIMER2_INDX);
673 info->DSP_TIME[3] =
674 ft1000_read_dpram_mag_16(dev,
675 FT1000_MAG_DSP_TIMER3,
676 FT1000_MAG_DSP_TIMER3_INDX);
677 }
678 info->DrvErrNum = DSP_HB_INFO;
679 if (ft1000_reset_card(dev) == 0) {
680 printk(KERN_INFO
681 "ft1000: Hardware Failure Detected - PC Card disabled\n");
682 info->ProgConStat = 0xff;
683 return;
684 }
685 /* Schedule this module to run every 2 seconds */
686 poll_timer.expires = jiffies + (2*HZ);
687 poll_timer.data = (u_long)dev;
688 add_timer(&poll_timer);
689 return;
690 }
691
692 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
693 // Let's check doorbell again if fail
694 if (tempword & FT1000_DB_HB) {
695 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
bf3146c8 696 }
f7c1be0c
MB
697 if (tempword & FT1000_DB_HB) {
698 printk(KERN_INFO
699 "ft1000: heartbeat doorbell not clear by firmware\n");
700 if (info->AsicID == ELECTRABUZZ_ID) {
701 info->DSP_TIME[0] =
702 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
703 info->DSP_TIME[1] =
704 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
705 info->DSP_TIME[2] =
706 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
707 info->DSP_TIME[3] =
708 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
709 } else {
710 info->DSP_TIME[0] =
711 ft1000_read_dpram_mag_16(dev,
712 FT1000_MAG_DSP_TIMER0,
713 FT1000_MAG_DSP_TIMER0_INDX);
714 info->DSP_TIME[1] =
715 ft1000_read_dpram_mag_16(dev,
716 FT1000_MAG_DSP_TIMER1,
717 FT1000_MAG_DSP_TIMER1_INDX);
718 info->DSP_TIME[2] =
719 ft1000_read_dpram_mag_16(dev,
720 FT1000_MAG_DSP_TIMER2,
721 FT1000_MAG_DSP_TIMER2_INDX);
722 info->DSP_TIME[3] =
723 ft1000_read_dpram_mag_16(dev,
724 FT1000_MAG_DSP_TIMER3,
725 FT1000_MAG_DSP_TIMER3_INDX);
726 }
727 info->DrvErrNum = DSP_HB_INFO;
728 if (ft1000_reset_card(dev) == 0) {
729 printk(KERN_INFO
730 "ft1000: Hardware Failure Detected - PC Card disabled\n");
731 info->ProgConStat = 0xff;
732 return;
733 }
734 /* Schedule this module to run every 2 seconds */
735 poll_timer.expires = jiffies + (2*HZ);
736 poll_timer.data = (u_long)dev;
737 add_timer(&poll_timer);
738 return;
739 }
bf3146c8 740 // Set dedicated area to hi and ring appropriate doorbell according
f7c1be0c
MB
741 // to hi/ho heartbeat protocol
742 if (info->AsicID == ELECTRABUZZ_ID) {
743 ft1000_write_dpram(dev, FT1000_HI_HO, hi);
744 } else {
745 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag,
746 FT1000_MAG_HI_HO_INDX);
747 }
748
749 if (info->AsicID == ELECTRABUZZ_ID) {
750 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
751 } else {
752 tempword =
753 ntohs(ft1000_read_dpram_mag_16
754 (dev, FT1000_MAG_HI_HO,
755 FT1000_MAG_HI_HO_INDX));
756 }
757 // Let's write hi again if fail
758 if (tempword != hi) {
759 if (info->AsicID == ELECTRABUZZ_ID) {
760 ft1000_write_dpram(dev, FT1000_HI_HO, hi);
761 }
762 else {
763 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag, FT1000_MAG_HI_HO_INDX);
764 }
765
766 if (info->AsicID == ELECTRABUZZ_ID) {
767 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
768 }
769 else {
770 tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX));
771 }
bf3146c8 772
f7c1be0c 773 }
bf3146c8 774
f7c1be0c
MB
775 if (tempword != hi) {
776 printk(KERN_INFO
777 "ft1000: heartbeat failed - cannot write hi into DPRAM\n");
778 if (info->AsicID == ELECTRABUZZ_ID) {
779 info->DSP_TIME[0] =
780 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
781 info->DSP_TIME[1] =
782 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
783 info->DSP_TIME[2] =
784 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
785 info->DSP_TIME[3] =
786 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
787 } else {
788 info->DSP_TIME[0] =
789 ft1000_read_dpram_mag_16(dev,
790 FT1000_MAG_DSP_TIMER0,
791 FT1000_MAG_DSP_TIMER0_INDX);
792 info->DSP_TIME[1] =
793 ft1000_read_dpram_mag_16(dev,
794 FT1000_MAG_DSP_TIMER1,
795 FT1000_MAG_DSP_TIMER1_INDX);
796 info->DSP_TIME[2] =
797 ft1000_read_dpram_mag_16(dev,
798 FT1000_MAG_DSP_TIMER2,
799 FT1000_MAG_DSP_TIMER2_INDX);
800 info->DSP_TIME[3] =
801 ft1000_read_dpram_mag_16(dev,
802 FT1000_MAG_DSP_TIMER3,
803 FT1000_MAG_DSP_TIMER3_INDX);
804 }
805 info->DrvErrNum = DSP_HB_INFO;
806 if (ft1000_reset_card(dev) == 0) {
807 printk(KERN_INFO
808 "ft1000: Hardware Failure Detected - PC Card disabled\n");
809 info->ProgConStat = 0xff;
810 return;
811 }
812 /* Schedule this module to run every 2 seconds */
813 poll_timer.expires = jiffies + (2*HZ);
814 poll_timer.data = (u_long)dev;
815 add_timer(&poll_timer);
816 return;
817 }
818 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_HB);
819
820 }
821
822 /* Schedule this module to run every 2 seconds */
823 poll_timer.expires = jiffies + (2 * HZ);
824 poll_timer.data = (u_long) dev;
825 add_timer(&poll_timer);
826}
827
828//---------------------------------------------------------------------------
829//
830// Function: ft1000_send_cmd
25985edc 831// Description:
f7c1be0c
MB
832// Input:
833// Output:
834//
835//---------------------------------------------------------------------------
836void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype)
837{
e33196e1 838 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
839 int i;
840 u16 tempword;
841 unsigned long flags;
842
843 size += PSEUDOSZ;
844 // check for odd byte and increment to 16-bit word align value
845 if ((size & 0x0001)) {
846 size++;
847 }
848 DEBUG(1, "FT1000:ft1000_send_cmd:total length = %d\n", size);
849 DEBUG(1, "FT1000:ft1000_send_cmd:length = %d\n", ntohs(*ptempbuffer));
850 // put message into slow queue area
851 // All messages are in the form total_len + pseudo header + message body
852 spin_lock_irqsave(&info->dpram_lock, flags);
853
854 // Make sure SLOWQ doorbell is clear
855 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
856 i=0;
857 while (tempword & FT1000_DB_DPRAM_TX) {
858 mdelay(10);
859 i++;
860 if (i==10) {
861 spin_unlock_irqrestore(&info->dpram_lock, flags);
862 return;
863 }
864 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
865 }
866
867 if (info->AsicID == ELECTRABUZZ_ID) {
868 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
869 FT1000_DPRAM_TX_BASE);
870 // Write total length to dpram
871 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, size);
872 // Write pseudo header and messgae body
873 for (i = 0; i < (size >> 1); i++) {
874 DEBUG(1, "FT1000:ft1000_send_cmd:data %d = 0x%x\n", i,
875 *ptempbuffer);
876 tempword = htons(*ptempbuffer++);
877 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, tempword);
878 }
879 } else {
880 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
881 FT1000_DPRAM_MAG_TX_BASE);
882 // Write total length to dpram
883 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, htons(size));
884 // Write pseudo header and messgae body
885 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
886 FT1000_DPRAM_MAG_TX_BASE + 1);
887 for (i = 0; i < (size >> 2); i++) {
888 DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n",
889 *ptempbuffer);
890 outw(*ptempbuffer++,
891 dev->base_addr + FT1000_REG_MAG_DPDATAL);
892 DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n",
893 *ptempbuffer);
894 outw(*ptempbuffer++,
895 dev->base_addr + FT1000_REG_MAG_DPDATAH);
896 }
897 DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", *ptempbuffer);
898 outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAL);
899 DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", *ptempbuffer);
900 outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAH);
901 }
902 spin_unlock_irqrestore(&info->dpram_lock, flags);
903
904 // ring doorbell to notify DSP that we have a message ready
905 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_TX);
906}
907
908//---------------------------------------------------------------------------
909//
910// Function: ft1000_receive_cmd
25985edc 911// Description: This function will read a message from the dpram area.
f7c1be0c
MB
912// Input:
913// dev - network device structure
914// pbuffer - caller supply address to buffer
915// pnxtph - pointer to next pseudo header
916// Output:
917// Status = 0 (unsuccessful)
918// = 1 (successful)
919//
920//---------------------------------------------------------------------------
921BOOLEAN ft1000_receive_cmd(struct net_device *dev, u16 * pbuffer, int maxsz, u16 *pnxtph)
922{
e33196e1 923 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
924 u16 size;
925 u16 *ppseudohdr;
926 int i;
927 u16 tempword;
928 unsigned long flags;
929
930 if (info->AsicID == ELECTRABUZZ_ID) {
931 size = ( ft1000_read_dpram(dev, *pnxtph) ) + PSEUDOSZ;
932 } else {
933 size =
934 ntohs(ft1000_read_dpram_mag_16
935 (dev, FT1000_MAG_PH_LEN,
936 FT1000_MAG_PH_LEN_INDX)) + PSEUDOSZ;
937 }
938 if (size > maxsz) {
939 DEBUG(1,
940 "FT1000:ft1000_receive_cmd:Invalid command length = %d\n",
941 size);
942 return FALSE;
943 } else {
944 ppseudohdr = (u16 *) pbuffer;
945 spin_lock_irqsave(&info->dpram_lock, flags);
946 if (info->AsicID == ELECTRABUZZ_ID) {
947 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
948 FT1000_DPRAM_RX_BASE + 2);
949 for (i = 0; i <= (size >> 1); i++) {
950 tempword =
951 ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
952 *pbuffer++ = ntohs(tempword);
953 }
954 } else {
955 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
956 FT1000_DPRAM_MAG_RX_BASE);
957 *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH);
958 DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer);
959 pbuffer++;
960 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
961 FT1000_DPRAM_MAG_RX_BASE + 1);
962 for (i = 0; i <= (size >> 2); i++) {
963 *pbuffer =
964 inw(dev->base_addr +
965 FT1000_REG_MAG_DPDATAL);
966 pbuffer++;
967 *pbuffer =
968 inw(dev->base_addr +
969 FT1000_REG_MAG_DPDATAH);
970 pbuffer++;
971 }
972 //copy odd aligned word
973 *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAL);
974 DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer);
975 pbuffer++;
976 *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH);
977 DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer);
978 pbuffer++;
979 }
980 if (size & 0x0001) {
981 //copy odd byte from fifo
982 tempword = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
983 *pbuffer = ntohs(tempword);
984 }
985 spin_unlock_irqrestore(&info->dpram_lock, flags);
986
987 // Check if pseudo header checksum is good
988 // Calculate pseudo header checksum
989 tempword = *ppseudohdr++;
990 for (i = 1; i < 7; i++) {
991 tempword ^= *ppseudohdr++;
992 }
993 if ((tempword != *ppseudohdr)) {
994 DEBUG(1,
995 "FT1000:ft1000_receive_cmd:Pseudo header checksum mismatch\n");
996 // Drop this message
997 return FALSE;
998 }
999 return TRUE;
1000 }
1001}
1002
1003//---------------------------------------------------------------------------
1004//
1005// Function: ft1000_proc_drvmsg
25985edc 1006// Description: This function will process the various driver messages.
f7c1be0c
MB
1007// Input:
1008// dev - device structure
1009// pnxtph - pointer to next pseudo header
1010// Output:
1011// none
1012//
1013//---------------------------------------------------------------------------
1014void ft1000_proc_drvmsg(struct net_device *dev)
1015{
e33196e1 1016 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
1017 u16 msgtype;
1018 u16 tempword;
1019 PMEDIAMSG pmediamsg;
1020 PDSPINITMSG pdspinitmsg;
1021 PDRVMSG pdrvmsg;
1022 u16 len;
1023 u16 i;
1024 PPROV_RECORD ptr;
1025 PPSEUDO_HDR ppseudo_hdr;
1026 PUSHORT pmsg;
1027 struct timeval tv;
1028 union {
1029 u8 byte[2];
1030 u16 wrd;
1031 } convert;
1032
1033 if (info->AsicID == ELECTRABUZZ_ID) {
1034 tempword = FT1000_DPRAM_RX_BASE+2;
1035 }
1036 else {
1037 tempword = FT1000_DPRAM_MAG_RX_BASE;
1038 }
1039 if ( ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword) ) {
1040
1041 // Get the message type which is total_len + PSEUDO header + msgtype + message body
1042 pdrvmsg = (PDRVMSG) & cmdbuffer[0];
1043 msgtype = ntohs(pdrvmsg->type);
1044 DEBUG(1, "Command message type = 0x%x\n", msgtype);
1045 switch (msgtype) {
1046 case DSP_PROVISION:
1047 DEBUG(0,
1048 "Got a provisioning request message from DSP\n");
1049 mdelay(25);
1050 while (list_empty(&info->prov_list) == 0) {
1051 DEBUG(0, "Sending a provisioning message\n");
1052 // Make sure SLOWQ doorbell is clear
1053 tempword =
1054 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1055 i = 0;
1056 while (tempword & FT1000_DB_DPRAM_TX) {
1057 mdelay(5);
1058 i++;
1059 if (i == 10) {
1060 break;
1061 }
1062 }
1063 ptr =
1064 list_entry(info->prov_list.next,
1065 PROV_RECORD, list);
1066 len = *(u16 *) ptr->pprov_data;
1067 len = htons(len);
1068
1069 pmsg = (PUSHORT) ptr->pprov_data;
1070 ppseudo_hdr = (PPSEUDO_HDR) pmsg;
1071 // Insert slow queue sequence number
1072 ppseudo_hdr->seq_num = info->squeseqnum++;
1073 ppseudo_hdr->portsrc = 0;
1074 // Calculate new checksum
1075 ppseudo_hdr->checksum = *pmsg++;
1076 DEBUG(1, "checksum = 0x%x\n",
1077 ppseudo_hdr->checksum);
1078 for (i = 1; i < 7; i++) {
1079 ppseudo_hdr->checksum ^= *pmsg++;
1080 DEBUG(1, "checksum = 0x%x\n",
1081 ppseudo_hdr->checksum);
1082 }
1083
1084 ft1000_send_cmd (dev, (u16 *)ptr->pprov_data, len, SLOWQ_TYPE);
1085 list_del(&ptr->list);
1086 kfree(ptr->pprov_data);
1087 kfree(ptr);
1088 }
1089 // Indicate adapter is ready to take application messages after all
1090 // provisioning messages are sent
1091 info->CardReady = 1;
1092 break;
1093 case MEDIA_STATE:
1094 pmediamsg = (PMEDIAMSG) & cmdbuffer[0];
1095 if (info->ProgConStat != 0xFF) {
1096 if (pmediamsg->state) {
1097 DEBUG(1, "Media is up\n");
1098 if (info->mediastate == 0) {
1099 netif_carrier_on(dev);
1100 netif_wake_queue(dev);
1101 info->mediastate = 1;
1102 do_gettimeofday(&tv);
1103 info->ConTm = tv.tv_sec;
1104 }
1105 } else {
1106 DEBUG(1, "Media is down\n");
1107 if (info->mediastate == 1) {
1108 info->mediastate = 0;
1109 netif_carrier_off(dev);
1110 netif_stop_queue(dev);
1111 info->ConTm = 0;
bf3146c8 1112 }
f7c1be0c
MB
1113 }
1114 }
1115 else {
1116 DEBUG(1,"Media is down\n");
1117 if (info->mediastate == 1) {
1118 info->mediastate = 0;
1119 netif_carrier_off(dev);
1120 netif_stop_queue(dev);
1121 info->ConTm = 0;
1122 }
1123 }
1124 break;
1125 case DSP_INIT_MSG:
1126 pdspinitmsg = (PDSPINITMSG) & cmdbuffer[0];
1127 memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ);
1128 DEBUG(1, "DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n",
1129 info->DspVer[0], info->DspVer[1], info->DspVer[2],
1130 info->DspVer[3]);
1131 memcpy(info->HwSerNum, pdspinitmsg->HwSerNum,
1132 HWSERNUMSZ);
1133 memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ);
1134 memcpy(info->eui64, pdspinitmsg->eui64, EUISZ);
1135 dev->dev_addr[0] = info->eui64[0];
1136 dev->dev_addr[1] = info->eui64[1];
1137 dev->dev_addr[2] = info->eui64[2];
1138 dev->dev_addr[3] = info->eui64[5];
1139 dev->dev_addr[4] = info->eui64[6];
1140 dev->dev_addr[5] = info->eui64[7];
1141
1142 if (ntohs(pdspinitmsg->length) ==
1143 (sizeof(DSPINITMSG) - 20)) {
1144 memcpy(info->ProductMode,
1145 pdspinitmsg->ProductMode, MODESZ);
1146 memcpy(info->RfCalVer, pdspinitmsg->RfCalVer,
1147 CALVERSZ);
1148 memcpy(info->RfCalDate, pdspinitmsg->RfCalDate,
1149 CALDATESZ);
1150 DEBUG(1, "RFCalVer = 0x%2x 0x%2x\n",
1151 info->RfCalVer[0], info->RfCalVer[1]);
1152 }
1153
1154 break ;
1155 case DSP_STORE_INFO:
1156 DEBUG(1, "FT1000:drivermsg:Got DSP_STORE_INFO\n");
1157 tempword = ntohs(pdrvmsg->length);
1158 info->DSPInfoBlklen = tempword;
1159 if (tempword < (MAX_DSP_SESS_REC - 4)) {
1160 pmsg = (PUSHORT) & pdrvmsg->data[0];
1161 for (i = 0; i < ((tempword + 1) / 2); i++) {
1162 DEBUG(1,
1163 "FT1000:drivermsg:dsp info data = 0x%x\n",
1164 *pmsg);
1165 info->DSPInfoBlk[i + 10] = *pmsg++;
1166 }
1167 }
1168 break;
1169 case DSP_GET_INFO:
1170 DEBUG(1, "FT1000:drivermsg:Got DSP_GET_INFO\n");
1171 // copy dsp info block to dsp
1172 info->DrvMsgPend = 1;
1173 // allow any outstanding ioctl to finish
1174 mdelay(10);
1175 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1176 if (tempword & FT1000_DB_DPRAM_TX) {
1177 mdelay(10);
1178 tempword =
1179 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1180 if (tempword & FT1000_DB_DPRAM_TX) {
1181 mdelay(10);
1182 }
1183 }
1184
1185 if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
1186 // Put message into Slow Queue
1187 // Form Pseudo header
1188 pmsg = (PUSHORT) info->DSPInfoBlk;
1189 ppseudo_hdr = (PPSEUDO_HDR) pmsg;
1190 ppseudo_hdr->length =
1191 htons(info->DSPInfoBlklen + 4);
1192 ppseudo_hdr->source = 0x10;
1193 ppseudo_hdr->destination = 0x20;
1194 ppseudo_hdr->portdest = 0;
1195 ppseudo_hdr->portsrc = 0;
1196 ppseudo_hdr->sh_str_id = 0;
1197 ppseudo_hdr->control = 0;
1198 ppseudo_hdr->rsvd1 = 0;
1199 ppseudo_hdr->rsvd2 = 0;
1200 ppseudo_hdr->qos_class = 0;
1201 // Insert slow queue sequence number
1202 ppseudo_hdr->seq_num = info->squeseqnum++;
bf3146c8 1203 // Insert application id
f7c1be0c
MB
1204 ppseudo_hdr->portsrc = 0;
1205 // Calculate new checksum
1206 ppseudo_hdr->checksum = *pmsg++;
1207 for (i = 1; i < 7; i++) {
1208 ppseudo_hdr->checksum ^= *pmsg++;
1209 }
1210 info->DSPInfoBlk[8] = 0x7200;
1211 info->DSPInfoBlk[9] =
1212 htons(info->DSPInfoBlklen);
1213 ft1000_send_cmd (dev, (PUSHORT)info->DSPInfoBlk, (USHORT)(info->DSPInfoBlklen+4), 0);
1214 }
1215 info->DrvMsgPend = 0;
1216
1217 break;
1218 case GET_DRV_ERR_RPT_MSG:
1219 DEBUG(1, "FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n");
1220 // copy driver error message to dsp
1221 info->DrvMsgPend = 1;
1222 // allow any outstanding ioctl to finish
1223 mdelay(10);
1224 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1225 if (tempword & FT1000_DB_DPRAM_TX) {
1226 mdelay(10);
1227 tempword =
1228 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1229 if (tempword & FT1000_DB_DPRAM_TX) {
1230 mdelay(10);
1231 }
1232 }
1233
1234 if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
1235 // Put message into Slow Queue
1236 // Form Pseudo header
1237 pmsg = (PUSHORT) & tempbuffer[0];
1238 ppseudo_hdr = (PPSEUDO_HDR) pmsg;
1239 ppseudo_hdr->length = htons(0x0012);
1240 ppseudo_hdr->source = 0x10;
1241 ppseudo_hdr->destination = 0x20;
1242 ppseudo_hdr->portdest = 0;
1243 ppseudo_hdr->portsrc = 0;
1244 ppseudo_hdr->sh_str_id = 0;
1245 ppseudo_hdr->control = 0;
1246 ppseudo_hdr->rsvd1 = 0;
1247 ppseudo_hdr->rsvd2 = 0;
1248 ppseudo_hdr->qos_class = 0;
1249 // Insert slow queue sequence number
1250 ppseudo_hdr->seq_num = info->squeseqnum++;
bf3146c8 1251 // Insert application id
f7c1be0c
MB
1252 ppseudo_hdr->portsrc = 0;
1253 // Calculate new checksum
1254 ppseudo_hdr->checksum = *pmsg++;
1255 for (i=1; i<7; i++) {
1256 ppseudo_hdr->checksum ^= *pmsg++;
1257 }
1258 pmsg = (PUSHORT) & tempbuffer[16];
1259 *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG);
1260 *pmsg++ = htons(0x000e);
1261 *pmsg++ = htons(info->DSP_TIME[0]);
1262 *pmsg++ = htons(info->DSP_TIME[1]);
1263 *pmsg++ = htons(info->DSP_TIME[2]);
1264 *pmsg++ = htons(info->DSP_TIME[3]);
1265 convert.byte[0] = info->DspVer[0];
1266 convert.byte[1] = info->DspVer[1];
1267 *pmsg++ = convert.wrd;
1268 convert.byte[0] = info->DspVer[2];
1269 convert.byte[1] = info->DspVer[3];
1270 *pmsg++ = convert.wrd;
1271 *pmsg++ = htons(info->DrvErrNum);
1272
1273 ft1000_send_cmd (dev, (PUSHORT)&tempbuffer[0], (USHORT)(0x0012), 0);
1274 info->DrvErrNum = 0;
1275 }
1276 info->DrvMsgPend = 0;
1277
1278 break;
1279 default:
1280 break;
1281 }
1282 }
1283}
1284
1285//---------------------------------------------------------------------------
1286//
1287// Function: ft1000_parse_dpram_msg
25985edc 1288// Description: This function will parse the message received from the DSP
f7c1be0c
MB
1289// via the DPRAM interface.
1290// Input:
1291// dev - device structure
1292// Output:
bf3146c8
GKH
1293// status - FAILURE
1294// SUCCESS
f7c1be0c
MB
1295//
1296//---------------------------------------------------------------------------
1297int ft1000_parse_dpram_msg(struct net_device *dev)
1298{
e33196e1 1299 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
1300 u16 doorbell;
1301 u16 portid;
1302 u16 nxtph;
1303 u16 total_len;
1304 int i = 0;
1305 int cnt;
1306 unsigned long flags;
1307
1308 doorbell = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1309 DEBUG(1, "Doorbell = 0x%x\n", doorbell);
1310
1311 if (doorbell & FT1000_ASIC_RESET_REQ) {
1312 // Copy DSP session record from info block
1313 spin_lock_irqsave(&info->dpram_lock, flags);
1314 if (info->AsicID == ELECTRABUZZ_ID) {
1315 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
1316 FT1000_DPRAM_RX_BASE);
1317 for (i = 0; i < MAX_DSP_SESS_REC; i++) {
1318 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA,
1319 info->DSPSess.Rec[i]);
1320 }
1321 } else {
1322 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
1323 FT1000_DPRAM_MAG_RX_BASE);
1324 for (i = 0; i < MAX_DSP_SESS_REC / 2; i++) {
1325 outl(info->DSPSess.MagRec[i],
1326 dev->base_addr + FT1000_REG_MAG_DPDATA);
1327 }
1328 }
1329 spin_unlock_irqrestore(&info->dpram_lock, flags);
1330
1331 // clear ASIC RESET request
1332 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1333 FT1000_ASIC_RESET_REQ);
1334 DEBUG(1, "Got an ASIC RESET Request\n");
1335 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1336 FT1000_ASIC_RESET_DSP);
1337
1338 if (info->AsicID == MAGNEMITE_ID) {
1339 // Setting MAGNEMITE ASIC to big endian mode
1340 ft1000_write_reg(dev, FT1000_REG_SUP_CTRL,
1341 HOST_INTF_BE);
1342 }
1343 info->DspAsicReset = 0;
1344 }
1345
1346 if (doorbell & FT1000_DSP_ASIC_RESET) {
1347 DEBUG(0,
1348 "FT1000:ft1000_parse_dpram_msg: Got a dsp ASIC reset message\n");
1349 info->DspAsicReset = 1;
1350 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1351 FT1000_DSP_ASIC_RESET);
1352 udelay(200);
1353 return SUCCESS;
1354 }
1355
1356 if (doorbell & FT1000_DB_DPRAM_RX) {
1357 DEBUG(1,
1358 "FT1000:ft1000_parse_dpram_msg: Got a slow queue message\n");
1359 nxtph = FT1000_DPRAM_RX_BASE + 2;
1360 if (info->AsicID == ELECTRABUZZ_ID) {
1361 total_len =
1362 ft1000_read_dpram(dev, FT1000_DPRAM_RX_BASE);
1363 } else {
1364 total_len =
1365 ntohs(ft1000_read_dpram_mag_16
1366 (dev, FT1000_MAG_TOTAL_LEN,
1367 FT1000_MAG_TOTAL_LEN_INDX));
1368 }
1369 DEBUG(1, "FT1000:ft1000_parse_dpram_msg:total length = %d\n",
1370 total_len);
1371 if ((total_len < MAX_CMD_SQSIZE) && (total_len > PSEUDOSZ)) {
1372 total_len += nxtph;
1373 cnt = 0;
1374 // ft1000_read_reg will return a value that needs to be byteswap
1375 // in order to get DSP_QID_OFFSET.
1376 if (info->AsicID == ELECTRABUZZ_ID) {
1377 portid =
1378 (ft1000_read_dpram
1379 (dev,
1380 DSP_QID_OFFSET + FT1000_DPRAM_RX_BASE +
1381 2) >> 8) & 0xff;
1382 } else {
1383 portid =
1384 (ft1000_read_dpram_mag_16
1385 (dev, FT1000_MAG_PORT_ID,
1386 FT1000_MAG_PORT_ID_INDX) & 0xff);
1387 }
1388 DEBUG(1, "DSP_QID = 0x%x\n", portid);
1389
1390 if (portid == DRIVERID) {
1391 // We are assumming one driver message from the DSP at a time.
1392 ft1000_proc_drvmsg(dev);
1393 }
1394 }
1395 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_RX);
1396 }
1397
1398 if (doorbell & FT1000_DB_COND_RESET) {
bf3146c8 1399 // Reset ASIC and DSP
f7c1be0c
MB
1400 if (info->AsicID == ELECTRABUZZ_ID) {
1401 info->DSP_TIME[0] =
1402 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
1403 info->DSP_TIME[1] =
1404 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
1405 info->DSP_TIME[2] =
1406 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
1407 info->DSP_TIME[3] =
1408 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
1409 } else {
1410 info->DSP_TIME[0] =
1411 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER0,
1412 FT1000_MAG_DSP_TIMER0_INDX);
1413 info->DSP_TIME[1] =
1414 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER1,
1415 FT1000_MAG_DSP_TIMER1_INDX);
1416 info->DSP_TIME[2] =
1417 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER2,
1418 FT1000_MAG_DSP_TIMER2_INDX);
1419 info->DSP_TIME[3] =
1420 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER3,
1421 FT1000_MAG_DSP_TIMER3_INDX);
1422 }
1423 info->DrvErrNum = DSP_CONDRESET_INFO;
1424 DEBUG(1, "ft1000_hw:DSP conditional reset requested\n");
1425 ft1000_reset_card(dev);
1426 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1427 FT1000_DB_COND_RESET);
1428 }
1429 // let's clear any unexpected doorbells from DSP
1430 doorbell =
1431 doorbell & ~(FT1000_DB_DPRAM_RX | FT1000_ASIC_RESET_REQ |
1432 FT1000_DB_COND_RESET | 0xff00);
1433 if (doorbell) {
1434 DEBUG(1, "Clearing unexpected doorbell = 0x%x\n", doorbell);
1435 ft1000_write_reg(dev, FT1000_REG_DOORBELL, doorbell);
1436 }
1437
1438 return SUCCESS;
1439
1440}
1441
1442//---------------------------------------------------------------------------
1443//
1444// Function: ft1000_flush_fifo
25985edc 1445// Description: This function will flush one packet from the downlink
f7c1be0c
MB
1446// FIFO.
1447// Input:
1448// dev - device structure
1449// drv_err - driver error causing the flush fifo
1450// Output:
1451// None.
1452//
1453//---------------------------------------------------------------------------
1454static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum)
1455{
e33196e1 1456 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
1457 u16 i;
1458 u32 templong;
1459 u16 tempword;
1460
1461 DEBUG(1, "ft1000:ft1000_hw:ft1000_flush_fifo called\n");
1462 if (info->PktIntfErr > MAX_PH_ERR) {
1463 if (info->AsicID == ELECTRABUZZ_ID) {
1464 info->DSP_TIME[0] =
1465 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
1466 info->DSP_TIME[1] =
1467 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
1468 info->DSP_TIME[2] =
1469 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
1470 info->DSP_TIME[3] =
1471 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
1472 } else {
1473 info->DSP_TIME[0] =
1474 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER0,
1475 FT1000_MAG_DSP_TIMER0_INDX);
1476 info->DSP_TIME[1] =
1477 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER1,
1478 FT1000_MAG_DSP_TIMER1_INDX);
1479 info->DSP_TIME[2] =
1480 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER2,
1481 FT1000_MAG_DSP_TIMER2_INDX);
1482 info->DSP_TIME[3] =
1483 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER3,
1484 FT1000_MAG_DSP_TIMER3_INDX);
1485 }
1486 info->DrvErrNum = DrvErrNum;
1487 ft1000_reset_card(dev);
1488 return;
1489 } else {
1490 // Flush corrupted pkt from FIFO
1491 i = 0;
1492 do {
1493 if (info->AsicID == ELECTRABUZZ_ID) {
1494 tempword =
1495 ft1000_read_reg(dev, FT1000_REG_DFIFO);
1496 tempword =
1497 ft1000_read_reg(dev, FT1000_REG_DFIFO_STAT);
1498 } else {
1499 templong =
1500 inl(dev->base_addr + FT1000_REG_MAG_DFR);
1501 tempword =
1502 inw(dev->base_addr + FT1000_REG_MAG_DFSR);
1503 }
1504 i++;
1505 // This should never happen unless the ASIC is broken.
1506 // We must reset to recover.
1507 if ((i > 2048) || (tempword == 0)) {
1508 if (info->AsicID == ELECTRABUZZ_ID) {
1509 info->DSP_TIME[0] =
1510 ft1000_read_dpram(dev,
1511 FT1000_DSP_TIMER0);
1512 info->DSP_TIME[1] =
1513 ft1000_read_dpram(dev,
1514 FT1000_DSP_TIMER1);
1515 info->DSP_TIME[2] =
1516 ft1000_read_dpram(dev,
1517 FT1000_DSP_TIMER2);
1518 info->DSP_TIME[3] =
1519 ft1000_read_dpram(dev,
1520 FT1000_DSP_TIMER3);
1521 } else {
1522 info->DSP_TIME[0] =
1523 ft1000_read_dpram_mag_16(dev,
1524 FT1000_MAG_DSP_TIMER0,
1525 FT1000_MAG_DSP_TIMER0_INDX);
1526 info->DSP_TIME[1] =
1527 ft1000_read_dpram_mag_16(dev,
1528 FT1000_MAG_DSP_TIMER1,
1529 FT1000_MAG_DSP_TIMER1_INDX);
1530 info->DSP_TIME[2] =
1531 ft1000_read_dpram_mag_16(dev,
1532 FT1000_MAG_DSP_TIMER2,
1533 FT1000_MAG_DSP_TIMER2_INDX);
1534 info->DSP_TIME[3] =
1535 ft1000_read_dpram_mag_16(dev,
1536 FT1000_MAG_DSP_TIMER3,
1537 FT1000_MAG_DSP_TIMER3_INDX);
1538 }
1539 if (tempword == 0) {
1540 // Let's check if ASIC reads are still ok by reading the Mask register
1541 // which is never zero at this point of the code.
1542 tempword =
1543 inw(dev->base_addr +
1544 FT1000_REG_SUP_IMASK);
1545 if (tempword == 0) {
1546 // This indicates that we can not communicate with the ASIC
1547 info->DrvErrNum =
1548 FIFO_FLUSH_BADCNT;
1549 } else {
1550 // Let's assume that we really flush the FIFO
1551 info->PktIntfErr++;
1552 return;
1553 }
1554 } else {
1555 info->DrvErrNum = FIFO_FLUSH_MAXLIMIT;
1556 }
1557 return;
1558 }
1559 tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT);
1560 } while ((tempword & 0x03) != 0x03);
1561 if (info->AsicID == ELECTRABUZZ_ID) {
1562 i++;
1563 DEBUG(0, "Flushing FIFO complete = %x\n", tempword);
1564 // Flush last word in FIFO.
1565 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1566 // Update FIFO counter for DSP
1567 i = i * 2;
1568 DEBUG(0, "Flush Data byte count to dsp = %d\n", i);
1569 info->fifo_cnt += i;
1570 ft1000_write_dpram(dev, FT1000_FIFO_LEN,
1571 info->fifo_cnt);
1572 } else {
1573 DEBUG(0, "Flushing FIFO complete = %x\n", tempword);
1574 // Flush last word in FIFO
1575 templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1576 tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT);
1577 DEBUG(0, "FT1000_REG_SUP_STAT = 0x%x\n", tempword);
1578 tempword = inw(dev->base_addr + FT1000_REG_MAG_DFSR);
1579 DEBUG(0, "FT1000_REG_MAG_DFSR = 0x%x\n", tempword);
1580 }
1581 if (DrvErrNum) {
1582 info->PktIntfErr++;
1583 }
1584 }
1585}
1586
1587//---------------------------------------------------------------------------
1588//
1589// Function: ft1000_copy_up_pkt
25985edc 1590// Description: This function will pull Flarion packets out of the Downlink
f7c1be0c
MB
1591// FIFO and convert it to an ethernet packet. The ethernet packet will
1592// then be deliver to the TCP/IP stack.
1593// Input:
1594// dev - device structure
1595// Output:
bf3146c8
GKH
1596// status - FAILURE
1597// SUCCESS
f7c1be0c
MB
1598//
1599//---------------------------------------------------------------------------
1600int ft1000_copy_up_pkt(struct net_device *dev)
1601{
1602 u16 tempword;
e33196e1 1603 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
1604 u16 len;
1605 struct sk_buff *skb;
1606 u16 i;
1607 u8 *pbuffer = NULL;
1608 u8 *ptemp = NULL;
1609 u16 chksum;
1610 u32 *ptemplong;
1611 u32 templong;
1612
1613 DEBUG(1, "ft1000_copy_up_pkt\n");
1614 // Read length
1615 if (info->AsicID == ELECTRABUZZ_ID) {
1616 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1617 len = tempword;
1618 } else {
1619 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1620 len = ntohs(tempword);
1621 }
1622 chksum = tempword;
1623 DEBUG(1, "Number of Bytes in FIFO = %d\n", len);
1624
1625 if (len > ENET_MAX_SIZE) {
1626 DEBUG(0, "size of ethernet packet invalid\n");
1627 if (info->AsicID == MAGNEMITE_ID) {
1628 // Read High word to complete 32 bit access
1629 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1630 }
1631 ft1000_flush_fifo(dev, DSP_PKTLEN_INFO);
1632 info->stats.rx_errors++;
1633 return FAILURE;
1634 }
1635
1636 skb = dev_alloc_skb(len + 12 + 2);
1637
1638 if (skb == NULL) {
1639 DEBUG(0, "No Network buffers available\n");
1640 // Read High word to complete 32 bit access
1641 if (info->AsicID == MAGNEMITE_ID) {
1642 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1643 }
1644 ft1000_flush_fifo(dev, 0);
1645 info->stats.rx_errors++;
1646 return FAILURE;
1647 }
1648 pbuffer = (u8 *) skb_put(skb, len + 12);
1649
1650 // Pseudo header
1651 if (info->AsicID == ELECTRABUZZ_ID) {
1652 for (i = 1; i < 7; i++) {
1653 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1654 chksum ^= tempword;
1655 }
1656 // read checksum value
1657 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1658 } else {
1659 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1660 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1661 chksum ^= tempword;
1662
1663 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1664 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1665 chksum ^= tempword;
1666
1667 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1668 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1669 chksum ^= tempword;
1670
1671 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1672 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1673 chksum ^= tempword;
1674
1675 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1676 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1677 chksum ^= tempword;
1678
1679 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1680 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1681 chksum ^= tempword;
1682
1683 // read checksum value
1684 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1685 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1686 }
1687
1688 if (chksum != tempword) {
1689 DEBUG(0, "Packet checksum mismatch 0x%x 0x%x\n", chksum,
1690 tempword);
1691 ft1000_flush_fifo(dev, DSP_PKTPHCKSUM_INFO);
1692 info->stats.rx_errors++;
c95aef41 1693 kfree_skb(skb);
f7c1be0c
MB
1694 return FAILURE;
1695 }
1696 //subtract the number of bytes read already
1697 ptemp = pbuffer;
1698
1699 // fake MAC address
1700 *pbuffer++ = dev->dev_addr[0];
1701 *pbuffer++ = dev->dev_addr[1];
1702 *pbuffer++ = dev->dev_addr[2];
1703 *pbuffer++ = dev->dev_addr[3];
1704 *pbuffer++ = dev->dev_addr[4];
1705 *pbuffer++ = dev->dev_addr[5];
1706 *pbuffer++ = 0x00;
1707 *pbuffer++ = 0x07;
1708 *pbuffer++ = 0x35;
1709 *pbuffer++ = 0xff;
1710 *pbuffer++ = 0xff;
1711 *pbuffer++ = 0xfe;
1712
1713 if (info->AsicID == ELECTRABUZZ_ID) {
1714 for (i = 0; i < len / 2; i++) {
1715 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1716 *pbuffer++ = (u8) (tempword >> 8);
1717 *pbuffer++ = (u8) tempword;
1718 if (ft1000_chkcard(dev) == FALSE) {
c95aef41 1719 kfree_skb(skb);
f7c1be0c
MB
1720 return FAILURE;
1721 }
1722 }
1723
1724 // Need to read one more word if odd byte
1725 if (len & 0x0001) {
1726 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1727 *pbuffer++ = (u8) (tempword >> 8);
1728 }
1729 } else {
1730 ptemplong = (u32 *) pbuffer;
1731 for (i = 0; i < len / 4; i++) {
1732 templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1733 DEBUG(1, "Data = 0x%8x\n", templong);
1734 *ptemplong++ = templong;
1735 }
1736
1737 // Need to read one more word if odd align.
1738 if (len & 0x0003) {
1739 templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1740 DEBUG(1, "Data = 0x%8x\n", templong);
1741 *ptemplong++ = templong;
1742 }
1743
1744 }
1745
1746 DEBUG(1, "Data passed to Protocol layer:\n");
1747 for (i = 0; i < len + 12; i++) {
1748 DEBUG(1, "Protocol Data: 0x%x\n ", *ptemp++);
1749 }
1750
1751 skb->dev = dev;
1752 skb->protocol = eth_type_trans(skb, dev);
1753 skb->ip_summed = CHECKSUM_UNNECESSARY;
1754 netif_rx(skb);
1755
1756 info->stats.rx_packets++;
1757 // Add on 12 bytes for MAC address which was removed
1758 info->stats.rx_bytes += (len + 12);
1759
1760 if (info->AsicID == ELECTRABUZZ_ID) {
1761 // track how many bytes have been read from FIFO - round up to 16 bit word
1762 tempword = len + 16;
1763 if (tempword & 0x01)
1764 tempword++;
1765 info->fifo_cnt += tempword;
1766 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_FIFO_LEN);
1767 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, info->fifo_cnt);
1768 }
1769
1770 return SUCCESS;
1771}
1772
1773//---------------------------------------------------------------------------
1774//
1775// Function: ft1000_copy_down_pkt
25985edc 1776// Description: This function will take an ethernet packet and convert it to
bf3146c8 1777// a Flarion packet prior to sending it to the ASIC Downlink
f7c1be0c
MB
1778// FIFO.
1779// Input:
1780// dev - device structure
1781// packet - address of ethernet packet
1782// len - length of IP packet
1783// Output:
bf3146c8
GKH
1784// status - FAILURE
1785// SUCCESS
f7c1be0c
MB
1786//
1787//---------------------------------------------------------------------------
1788int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len)
1789{
e33196e1 1790 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
1791 union {
1792 PSEUDO_HDR blk;
1793 u16 buff[sizeof(PSEUDO_HDR) >> 1];
1794 u8 buffc[sizeof(PSEUDO_HDR)];
1795 } pseudo;
1796 int i;
1797 u32 *plong;
1798
1799 DEBUG(1, "ft1000_hw: copy_down_pkt()\n");
1800
bf3146c8 1801 // Check if there is room on the FIFO
f7c1be0c
MB
1802 if (len > ft1000_read_fifo_len(dev)) {
1803 udelay(10);
1804 if (len > ft1000_read_fifo_len(dev)) {
1805 udelay(20);
1806 }
1807 if (len > ft1000_read_fifo_len(dev)) {
1808 udelay(20);
1809 }
1810 if (len > ft1000_read_fifo_len(dev)) {
1811 udelay(20);
1812 }
1813 if (len > ft1000_read_fifo_len(dev)) {
1814 udelay(20);
1815 }
1816 if (len > ft1000_read_fifo_len(dev)) {
1817 udelay(20);
1818 }
1819 if (len > ft1000_read_fifo_len(dev)) {
1820 DEBUG(1,
1821 "ft1000_hw:ft1000_copy_down_pkt:Transmit FIFO is fulli - pkt drop\n");
1822 info->stats.tx_errors++;
1823 return SUCCESS;
1824 }
1825 }
1826 // Create pseudo header and send pseudo/ip to hardware
1827 if (info->AsicID == ELECTRABUZZ_ID) {
1828 pseudo.blk.length = len;
1829 } else {
1830 pseudo.blk.length = ntohs(len);
1831 }
1832 pseudo.blk.source = DSPID; // Need to swap to get in correct order
1833 pseudo.blk.destination = HOSTID;
1834 pseudo.blk.portdest = NETWORKID; // Need to swap to get in correct order
1835 pseudo.blk.portsrc = DSPAIRID;
1836 pseudo.blk.sh_str_id = 0;
1837 pseudo.blk.control = 0;
1838 pseudo.blk.rsvd1 = 0;
1839 pseudo.blk.seq_num = 0;
1840 pseudo.blk.rsvd2 = info->packetseqnum++;
1841 pseudo.blk.qos_class = 0;
1842 /* Calculate pseudo header checksum */
1843 pseudo.blk.checksum = pseudo.buff[0];
1844 for (i = 1; i < 7; i++) {
1845 pseudo.blk.checksum ^= pseudo.buff[i];
1846 }
1847
1848 // Production Mode
1849 if (info->AsicID == ELECTRABUZZ_ID) {
bf3146c8 1850 // copy first word to UFIFO_BEG reg
f7c1be0c
MB
1851 ft1000_write_reg(dev, FT1000_REG_UFIFO_BEG, pseudo.buff[0]);
1852 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 0 BEG = 0x%04x\n",
1853 pseudo.buff[0]);
1854
bf3146c8 1855 // copy subsequent words to UFIFO_MID reg
f7c1be0c
MB
1856 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[1]);
1857 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 1 MID = 0x%04x\n",
1858 pseudo.buff[1]);
1859 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[2]);
1860 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 2 MID = 0x%04x\n",
1861 pseudo.buff[2]);
1862 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[3]);
1863 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 3 MID = 0x%04x\n",
1864 pseudo.buff[3]);
1865 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[4]);
1866 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 4 MID = 0x%04x\n",
1867 pseudo.buff[4]);
1868 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[5]);
1869 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 5 MID = 0x%04x\n",
1870 pseudo.buff[5]);
1871 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[6]);
1872 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 6 MID = 0x%04x\n",
1873 pseudo.buff[6]);
1874 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[7]);
1875 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 7 MID = 0x%04x\n",
1876 pseudo.buff[7]);
1877
1878 // Write PPP type + IP Packet into Downlink FIFO
1879 for (i = 0; i < (len >> 1) - 1; i++) {
1880 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID,
1881 htons(*packet));
1882 DEBUG(1,
1883 "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n",
1884 i + 8, htons(*packet));
1885 packet++;
1886 }
1887
bf3146c8 1888 // Check for odd byte
f7c1be0c
MB
1889 if (len & 0x0001) {
1890 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID,
1891 htons(*packet));
1892 DEBUG(1,
1893 "ft1000_hw:ft1000_copy_down_pkt:data MID = 0x%04x\n",
1894 htons(*packet));
1895 packet++;
1896 ft1000_write_reg(dev, FT1000_REG_UFIFO_END,
1897 htons(*packet));
1898 DEBUG(1,
1899 "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n",
1900 i + 8, htons(*packet));
1901 } else {
1902 ft1000_write_reg(dev, FT1000_REG_UFIFO_END,
1903 htons(*packet));
1904 DEBUG(1,
1905 "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n",
1906 i + 8, htons(*packet));
1907 }
1908 } else {
1909 outl(*(u32 *) & pseudo.buff[0],
1910 dev->base_addr + FT1000_REG_MAG_UFDR);
1911 DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n",
1912 *(u32 *) & pseudo.buff[0]);
1913 outl(*(u32 *) & pseudo.buff[2],
1914 dev->base_addr + FT1000_REG_MAG_UFDR);
1915 DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n",
1916 *(u32 *) & pseudo.buff[2]);
1917 outl(*(u32 *) & pseudo.buff[4],
1918 dev->base_addr + FT1000_REG_MAG_UFDR);
1919 DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n",
1920 *(u32 *) & pseudo.buff[4]);
1921 outl(*(u32 *) & pseudo.buff[6],
1922 dev->base_addr + FT1000_REG_MAG_UFDR);
1923 DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n",
1924 *(u32 *) & pseudo.buff[6]);
1925
1926 plong = (u32 *) packet;
1927 // Write PPP type + IP Packet into Downlink FIFO
1928 for (i = 0; i < (len >> 2); i++) {
1929 outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
1930 }
1931
bf3146c8 1932 // Check for odd alignment
f7c1be0c
MB
1933 if (len & 0x0003) {
1934 DEBUG(1,
1935 "ft1000_hw:ft1000_copy_down_pkt:data = 0x%8x\n",
1936 *plong);
1937 outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
1938 }
1939 outl(1, dev->base_addr + FT1000_REG_MAG_UFER);
1940 }
1941
1942 info->stats.tx_packets++;
aec563b4 1943 // Add 14 bytes for MAC address plus ethernet type
f7c1be0c
MB
1944 info->stats.tx_bytes += (len + 14);
1945 return SUCCESS;
1946}
1947
1948static struct net_device_stats *ft1000_stats(struct net_device *dev)
1949{
e33196e1 1950 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
1951 return (&info->stats);
1952}
1953
1954static int ft1000_open(struct net_device *dev)
1955{
1956
1957 DEBUG(0, "ft1000_hw: ft1000_open is called\n");
1958
1959 ft1000_reset_card(dev);
1960 DEBUG(0, "ft1000_hw: ft1000_open is ended\n");
1961
1962 /* schedule ft1000_hbchk to perform periodic heartbeat checks on DSP and ASIC */
1963 init_timer(&poll_timer);
1964 poll_timer.expires = jiffies + (2 * HZ);
1965 poll_timer.data = (u_long) dev;
1966 add_timer(&poll_timer);
1967
1968 DEBUG(0, "ft1000_hw: ft1000_open is ended2\n");
1969 return 0;
1970}
1971
1972static int ft1000_close(struct net_device *dev)
1973{
e33196e1 1974 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
1975
1976 DEBUG(0, "ft1000_hw: ft1000_close()\n");
1977
1978 info->CardReady = 0;
1979 del_timer(&poll_timer);
1980
1981 if (ft1000_card_present == 1) {
1982 DEBUG(0, "Media is down\n");
1983 netif_stop_queue(dev);
1984
1985 ft1000_disable_interrupts(dev);
1986 ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
1987
1988 //reset ASIC
1989 ft1000_reset_asic(dev);
1990 }
1991 return 0;
1992}
1993
1994static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
1995{
e33196e1 1996 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
1997 u8 *pdata;
1998
1999 DEBUG(1, "ft1000_hw: ft1000_start_xmit()\n");
2000 if (skb == NULL) {
2001 DEBUG(1, "ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n");
2002 return 0;
2003 }
2004
2005 DEBUG(1, "ft1000_hw: ft1000_start_xmit:length of packet = %d\n",
2006 skb->len);
2007
2008 pdata = (u8 *) skb->data;
2009
2010 if (info->mediastate == 0) {
2011 /* Drop packet is mediastate is down */
2012 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:mediastate is down\n");
2013 return SUCCESS;
2014 }
2015
2016 if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) {
2017 /* Drop packet which has invalid size */
2018 DEBUG(1,
2019 "ft1000_hw:ft1000_copy_down_pkt:invalid ethernet length\n");
2020 return SUCCESS;
2021 }
2022 ft1000_copy_down_pkt(dev, (u16 *) (pdata + ENET_HEADER_SIZE - 2),
2023 skb->len - ENET_HEADER_SIZE + 2);
2024
2025 dev_kfree_skb(skb);
2026
2027 return 0;
2028}
2029
2030static irqreturn_t ft1000_interrupt(int irq, void *dev_id)
2031{
2032 struct net_device *dev = (struct net_device *)dev_id;
e33196e1 2033 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
2034 u16 tempword;
2035 u16 inttype;
2036 int cnt;
2037
2038 DEBUG(1, "ft1000_hw: ft1000_interrupt()\n");
2039
2040 if (info->CardReady == 0) {
2041 ft1000_disable_interrupts(dev);
2042 return IRQ_HANDLED;
2043 }
2044
2045 if (ft1000_chkcard(dev) == FALSE) {
2046 ft1000_disable_interrupts(dev);
2047 return IRQ_HANDLED;
2048 }
2049
2050 ft1000_disable_interrupts(dev);
2051
2052 // Read interrupt type
2053 inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
2054
2055 // Make sure we process all interrupt before leaving the ISR due to the edge trigger interrupt type
2056 while (inttype) {
2057 if (inttype & ISR_DOORBELL_PEND) {
2058 ft1000_parse_dpram_msg(dev);
2059 }
2060
2061 if (inttype & ISR_RCV) {
2062 DEBUG(1, "Data in FIFO\n");
2063
2064 cnt = 0;
2065 do {
2066 // Check if we have packets in the Downlink FIFO
2067 if (info->AsicID == ELECTRABUZZ_ID) {
2068 tempword =
2069 ft1000_read_reg(dev, FT1000_REG_DFIFO_STAT);
2070 } else {
2071 tempword =
2072 ft1000_read_reg(dev, FT1000_REG_MAG_DFSR);
2073 }
2074 if (tempword & 0x1f) {
2075 ft1000_copy_up_pkt(dev);
2076 } else {
2077 break;
2078 }
2079 cnt++;
2080 } while (cnt < MAX_RCV_LOOP);
2081
2082 }
2083 // clear interrupts
2084 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
2085 DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword);
2086 ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword);
2087
2088 // Read interrupt type
2089 inttype = ft1000_read_reg (dev, FT1000_REG_SUP_ISR);
2090 DEBUG(1,"ft1000_hw: interrupt status register after clear = 0x%x\n",inttype);
2091 }
2092 ft1000_enable_interrupts(dev);
2093 return IRQ_HANDLED;
2094}
2095
2096void stop_ft1000_card(struct net_device *dev)
2097{
e33196e1 2098 FT1000_INFO *info = netdev_priv(dev);
f7c1be0c
MB
2099 PPROV_RECORD ptr;
2100// int cnt;
2101
2102 DEBUG(0, "ft1000_hw: stop_ft1000_card()\n");
2103
2104 info->CardReady = 0;
2105 ft1000_card_present = 0;
2106 netif_stop_queue(dev);
2107 ft1000_disable_interrupts(dev);
2108
2109 // Make sure we free any memory reserve for provisioning
2110 while (list_empty(&info->prov_list) == 0) {
2111 ptr = list_entry(info->prov_list.next, PROV_RECORD, list);
2112 list_del(&ptr->list);
2113 kfree(ptr->pprov_data);
2114 kfree(ptr);
2115 }
2116
2117 if (info->registered) {
2118 unregister_netdev(dev);
2119 info->registered = 0;
2120 }
2121
2122 free_irq(dev->irq, dev);
2123 release_region(dev->base_addr,256);
2124 release_firmware(fw_entry);
2125 flarion_ft1000_cnt--;
2126 ft1000CleanupProc(dev);
2127
2128}
2129
2130static void ft1000_get_drvinfo(struct net_device *dev,
2131 struct ethtool_drvinfo *info)
2132{
2133 FT1000_INFO *ft_info;
e33196e1 2134 ft_info = netdev_priv(dev);
f7c1be0c
MB
2135
2136 snprintf(info->driver, 32, "ft1000");
2137 snprintf(info->bus_info, ETHTOOL_BUSINFO_LEN, "PCMCIA 0x%lx",
2138 dev->base_addr);
2139 snprintf(info->fw_version, 32, "%d.%d.%d.%d", ft_info->DspVer[0],
2140 ft_info->DspVer[1], ft_info->DspVer[2], ft_info->DspVer[3]);
2141}
2142
2143static u32 ft1000_get_link(struct net_device *dev)
2144{
2145 FT1000_INFO *info;
e33196e1 2146 info = netdev_priv(dev);
f7c1be0c
MB
2147 return info->mediastate;
2148}
2149
2150static const struct ethtool_ops ops = {
2151 .get_drvinfo = ft1000_get_drvinfo,
2152 .get_link = ft1000_get_link
2153};
2154
c331e766
MB
2155struct net_device *init_ft1000_card(struct pcmcia_device *link,
2156 void *ft1000_reset)
f7c1be0c
MB
2157{
2158 FT1000_INFO *info;
2159 struct net_device *dev;
f7c1be0c
MB
2160
2161 static const struct net_device_ops ft1000ops = // Slavius 21.10.2009 due to kernel changes
2162 {
2163 .ndo_open = &ft1000_open,
2164 .ndo_stop = &ft1000_close,
2165 .ndo_start_xmit = &ft1000_start_xmit,
2166 .ndo_get_stats = &ft1000_stats,
2167 };
2168
2169 DEBUG(1, "ft1000_hw: init_ft1000_card()\n");
c331e766
MB
2170 DEBUG(1, "ft1000_hw: irq = %d\n", link->irq);
2171 DEBUG(1, "ft1000_hw: port = 0x%04x\n", link->resource[0]->start);
f7c1be0c
MB
2172
2173 flarion_ft1000_cnt++;
2174
2175 if (flarion_ft1000_cnt > 1) {
2176 flarion_ft1000_cnt--;
2177
2178 printk(KERN_INFO
2179 "ft1000: This driver can not support more than one instance\n");
2180 return NULL;
2181 }
2182
2183 dev = alloc_etherdev(sizeof(FT1000_INFO));
2184 if (!dev) {
2185 printk(KERN_ERR "ft1000: failed to allocate etherdev\n");
2186 return NULL;
2187 }
2188
c331e766 2189 SET_NETDEV_DEV(dev, &link->dev);
e33196e1 2190 info = netdev_priv(dev);
f7c1be0c
MB
2191
2192 memset(info, 0, sizeof(FT1000_INFO));
2193
2194 DEBUG(1, "address of dev = 0x%8x\n", (u32) dev);
2195 DEBUG(1, "address of dev info = 0x%8x\n", (u32) info);
2196 DEBUG(0, "device name = %s\n", dev->name);
2197
2198 memset(&info->stats, 0, sizeof(struct net_device_stats));
2199
2200 spin_lock_init(&info->dpram_lock);
2201 info->DrvErrNum = 0;
2202 info->ASICResetNum = 0;
2203 info->registered = 1;
2204 info->link = link;
2205 info->ft1000_reset = ft1000_reset;
2206 info->mediastate = 0;
2207 info->fifo_cnt = 0;
2208 info->DeviceCreated = FALSE;
2209 info->DeviceMajor = 0;
2210 info->CurrentInterruptEnableMask = ISR_DEFAULT_MASK;
2211 info->InterruptsEnabled = FALSE;
2212 info->CardReady = 0;
2213 info->DSP_TIME[0] = 0;
2214 info->DSP_TIME[1] = 0;
2215 info->DSP_TIME[2] = 0;
2216 info->DSP_TIME[3] = 0;
2217 flarion_ft1000_cnt = 0;
2218
2219 INIT_LIST_HEAD(&info->prov_list);
2220
2221 info->squeseqnum = 0;
2222
2223// dev->hard_start_xmit = &ft1000_start_xmit;
2224// dev->get_stats = &ft1000_stats;
2225// dev->open = &ft1000_open;
2226// dev->stop = &ft1000_close;
2227
2228 dev->netdev_ops = &ft1000ops; // Slavius 21.10.2009 due to kernel changes
2229
2230 DEBUG(0, "device name = %s\n", dev->name);
2231
c331e766
MB
2232 dev->irq = link->irq;
2233 dev->base_addr = link->resource[0]->start;
2234 if (pcmcia_get_mac_from_cis(link, dev)) {
2235 printk(KERN_ERR "ft1000: Could not read mac address\n");
2236 goto err_dev;
f7c1be0c
MB
2237 }
2238
f7c1be0c
MB
2239 if (request_irq(dev->irq, ft1000_interrupt, IRQF_SHARED, dev->name, dev)) {
2240 printk(KERN_ERR "ft1000: Could not request_irq\n");
c95aef41 2241 goto err_dev;
f7c1be0c
MB
2242 }
2243
c95aef41
VK
2244 if (request_region(dev->base_addr, 256, dev->name) == NULL) {
2245 printk(KERN_ERR "ft1000: Could not request_region\n");
2246 goto err_irq;
2247 }
f7c1be0c
MB
2248
2249 if (register_netdev(dev) != 0) {
2250 DEBUG(0, "ft1000: Could not register netdev");
c95aef41 2251 goto err_reg;
f7c1be0c
MB
2252 }
2253
2254 info->AsicID = ft1000_read_reg(dev, FT1000_REG_ASIC_ID);
2255 if (info->AsicID == ELECTRABUZZ_ID) {
2256 DEBUG(0, "ft1000_hw: ELECTRABUZZ ASIC\n");
c331e766 2257 if (request_firmware(&fw_entry, "ft1000.img", &link->dev) != 0) {
f7c1be0c 2258 printk(KERN_INFO "ft1000: Could not open ft1000.img\n");
c95aef41 2259 goto err_unreg;
f7c1be0c
MB
2260 }
2261 } else {
2262 DEBUG(0, "ft1000_hw: MAGNEMITE ASIC\n");
c331e766 2263 if (request_firmware(&fw_entry, "ft2000.img", &link->dev) != 0) {
f7c1be0c 2264 printk(KERN_INFO "ft1000: Could not open ft2000.img\n");
c95aef41 2265 goto err_unreg;
f7c1be0c
MB
2266 }
2267 }
2268
2269 ft1000_enable_interrupts(dev);
2270
2271 ft1000InitProc(dev);
2272 ft1000_card_present = 1;
2273 SET_ETHTOOL_OPS(dev, &ops);
2274 printk(KERN_INFO
2275 "ft1000: %s: addr 0x%04lx irq %d, MAC addr %02x:%02x:%02x:%02x:%02x:%02x\n",
2276 dev->name, dev->base_addr, dev->irq, dev->dev_addr[0],
2277 dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3],
2278 dev->dev_addr[4], dev->dev_addr[5]);
2279 return dev;
c95aef41
VK
2280
2281err_unreg:
2282 unregister_netdev(dev);
2283err_reg:
2284 release_region(dev->base_addr, 256);
2285err_irq:
2286 free_irq(dev->irq, dev);
2287err_dev:
2288 free_netdev(dev);
2289 return NULL;
f7c1be0c 2290}