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