staging: ft1000: Fix identation in ftnet_ops struct.
[deliverable/linux.git] / drivers / staging / ft1000 / ft1000-usb / ft1000_hw.c
CommitLineData
f7c1be0c
MB
1//=====================================================
2// CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
3//
4//
5// This file is part of Express Card USB Driver
6//
7// $Id:
8//====================================================
9// 20090926; aelias; removed compiler warnings & errors; ubuntu 9.04; 2.6.28-15-generic
10
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/netdevice.h>
15#include <linux/etherdevice.h>
16#include <linux/usb.h>
17#include "ft1000_usb.h"
18#include <linux/types.h>
f7c1be0c
MB
19
20#define HARLEY_READ_REGISTER 0x0
21#define HARLEY_WRITE_REGISTER 0x01
22#define HARLEY_READ_DPRAM_32 0x02
23#define HARLEY_READ_DPRAM_LOW 0x03
24#define HARLEY_READ_DPRAM_HIGH 0x04
25#define HARLEY_WRITE_DPRAM_32 0x05
26#define HARLEY_WRITE_DPRAM_LOW 0x06
27#define HARLEY_WRITE_DPRAM_HIGH 0x07
28
29#define HARLEY_READ_OPERATION 0xc1
30#define HARLEY_WRITE_OPERATION 0x41
31
32//#define JDEBUG
33
2a953cfd 34static int ft1000_reset(struct net_device *ft1000dev);
1a88a068 35static int ft1000_submit_rx_urb(struct ft1000_info *info);
f7c1be0c
MB
36static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev);
37static int ft1000_open (struct net_device *dev);
f7c1be0c 38static struct net_device_stats *ft1000_netdev_stats(struct net_device *dev);
f7c1be0c 39static int ft1000_chkcard (struct ft1000_device *dev);
f7c1be0c
MB
40
41//Jim
42
43static u8 tempbuffer[1600];
f7c1be0c
MB
44
45#define MAX_RCV_LOOP 100
46
f7c1be0c
MB
47//---------------------------------------------------------------------------
48// Function: ft1000_control
49//
50// Parameters: ft1000_device - device structure
51// pipe - usb control message pipe
52// request - control request
53// requesttype - control message request type
54// value - value to be written or 0
55// index - register index
56// data - data buffer to hold the read/write values
57// size - data size
58// timeout - control message time out value
bf3146c8 59//
f7c1be0c
MB
60// Returns: STATUS_SUCCESS - success
61// STATUS_FAILURE - failure
62//
63// Description: This function sends a control message via USB interface synchronously
64//
65// Notes:
66//
67//---------------------------------------------------------------------------
537a20ab
MB
68static int ft1000_control(struct ft1000_device *ft1000dev, unsigned int pipe,
69 u8 request, u8 requesttype, u16 value, u16 index,
70 void *data, u16 size, int timeout)
f7c1be0c
MB
71{
72 u16 ret;
bf3146c8 73
537a20ab
MB
74 if ((ft1000dev == NULL) || (ft1000dev->dev == NULL)) {
75 DEBUG("ft1000dev or ft1000dev->dev == NULL, failure\n");
76 return -ENODEV;
77 }
78
79 ret = usb_control_msg(ft1000dev->dev, pipe, request, requesttype,
80 value, index, data, size, LARGE_TIMEOUT);
bf3146c8 81
310bad04
MB
82 if (ret > 0)
83 ret = 0;
bf3146c8 84
537a20ab 85 return ret;
f7c1be0c 86}
537a20ab 87
f7c1be0c
MB
88//---------------------------------------------------------------------------
89// Function: ft1000_read_register
90//
91// Parameters: ft1000_device - device structure
92// Data - data buffer to hold the value read
93// nRegIndex - register index
bf3146c8 94//
f7c1be0c
MB
95// Returns: STATUS_SUCCESS - success
96// STATUS_FAILURE - failure
97//
98// Description: This function returns the value in a register
99//
100// Notes:
101//
102//---------------------------------------------------------------------------
103
31da7c09
MB
104int ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data,
105 u16 nRegIndx)
f7c1be0c 106{
31da7c09
MB
107 int ret = STATUS_SUCCESS;
108
109 ret = ft1000_control(ft1000dev,
110 usb_rcvctrlpipe(ft1000dev->dev, 0),
111 HARLEY_READ_REGISTER,
112 HARLEY_READ_OPERATION,
113 0,
114 nRegIndx,
115 Data,
116 2,
117 LARGE_TIMEOUT);
f7c1be0c 118
31da7c09 119 return ret;
bf3146c8 120}
f7c1be0c
MB
121
122//---------------------------------------------------------------------------
123// Function: ft1000_write_register
124//
125// Parameters: ft1000_device - device structure
126// value - value to write into a register
127// nRegIndex - register index
bf3146c8 128//
f7c1be0c
MB
129// Returns: STATUS_SUCCESS - success
130// STATUS_FAILURE - failure
131//
132// Description: This function writes the value in a register
133//
134// Notes:
135//
136//---------------------------------------------------------------------------
31da7c09
MB
137int ft1000_write_register(struct ft1000_device *ft1000dev, u16 value,
138 u16 nRegIndx)
f7c1be0c 139{
31da7c09
MB
140 int ret = STATUS_SUCCESS;
141
142 ret = ft1000_control(ft1000dev,
143 usb_sndctrlpipe(ft1000dev->dev, 0),
144 HARLEY_WRITE_REGISTER,
145 HARLEY_WRITE_OPERATION,
146 value,
147 nRegIndx,
148 NULL,
149 0,
150 LARGE_TIMEOUT);
bf3146c8 151
31da7c09 152 return ret;
f7c1be0c
MB
153}
154
155//---------------------------------------------------------------------------
156// Function: ft1000_read_dpram32
157//
158// Parameters: ft1000_device - device structure
159// indx - starting address to read
160// buffer - data buffer to hold the data read
161// cnt - number of byte read from DPRAM
bf3146c8 162//
f7c1be0c
MB
163// Returns: STATUS_SUCCESS - success
164// STATUS_FAILURE - failure
165//
166// Description: This function read a number of bytes from DPRAM
167//
168// Notes:
169//
170//---------------------------------------------------------------------------
171
e3fc923d
MB
172int ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer,
173 u16 cnt)
f7c1be0c 174{
e3fc923d 175 int ret = STATUS_SUCCESS;
f7c1be0c 176
e3fc923d
MB
177 ret = ft1000_control(ft1000dev,
178 usb_rcvctrlpipe(ft1000dev->dev, 0),
179 HARLEY_READ_DPRAM_32,
180 HARLEY_READ_OPERATION,
181 0,
182 indx,
183 buffer,
184 cnt,
185 LARGE_TIMEOUT);
f7c1be0c 186
e3fc923d 187 return ret;
bf3146c8 188}
f7c1be0c
MB
189
190//---------------------------------------------------------------------------
191// Function: ft1000_write_dpram32
192//
193// Parameters: ft1000_device - device structure
194// indx - starting address to write the data
195// buffer - data buffer to write into DPRAM
196// cnt - number of bytes to write
bf3146c8 197//
f7c1be0c
MB
198// Returns: STATUS_SUCCESS - success
199// STATUS_FAILURE - failure
200//
201// Description: This function writes into DPRAM a number of bytes
202//
203// Notes:
204//
205//---------------------------------------------------------------------------
e3fc923d
MB
206int ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer,
207 u16 cnt)
f7c1be0c 208{
e3fc923d
MB
209 int ret = STATUS_SUCCESS;
210
211 if (cnt % 4)
212 cnt += cnt - (cnt % 4);
213
214 ret = ft1000_control(ft1000dev,
215 usb_sndctrlpipe(ft1000dev->dev, 0),
216 HARLEY_WRITE_DPRAM_32,
217 HARLEY_WRITE_OPERATION,
218 0,
219 indx,
220 buffer,
221 cnt,
222 LARGE_TIMEOUT);
223
224 return ret;
f7c1be0c
MB
225}
226
227//---------------------------------------------------------------------------
228// Function: ft1000_read_dpram16
229//
230// Parameters: ft1000_device - device structure
231// indx - starting address to read
232// buffer - data buffer to hold the data read
233// hightlow - high or low 16 bit word
bf3146c8 234//
f7c1be0c
MB
235// Returns: STATUS_SUCCESS - success
236// STATUS_FAILURE - failure
237//
238// Description: This function read 16 bits from DPRAM
239//
240// Notes:
241//
242//---------------------------------------------------------------------------
460bd5dd
MB
243int ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer,
244 u8 highlow)
f7c1be0c 245{
460bd5dd
MB
246 int ret = STATUS_SUCCESS;
247 u8 request;
bf3146c8 248
460bd5dd
MB
249 if (highlow == 0)
250 request = HARLEY_READ_DPRAM_LOW;
251 else
252 request = HARLEY_READ_DPRAM_HIGH;
f7c1be0c 253
460bd5dd
MB
254 ret = ft1000_control(ft1000dev,
255 usb_rcvctrlpipe(ft1000dev->dev, 0),
256 request,
257 HARLEY_READ_OPERATION,
258 0,
259 indx,
260 buffer,
261 2,
262 LARGE_TIMEOUT);
f7c1be0c 263
460bd5dd 264 return ret;
bf3146c8 265}
f7c1be0c
MB
266
267//---------------------------------------------------------------------------
268// Function: ft1000_write_dpram16
269//
270// Parameters: ft1000_device - device structure
271// indx - starting address to write the data
272// value - 16bits value to write
273// hightlow - high or low 16 bit word
bf3146c8 274//
f7c1be0c
MB
275// Returns: STATUS_SUCCESS - success
276// STATUS_FAILURE - failure
277//
278// Description: This function writes into DPRAM a number of bytes
279//
280// Notes:
281//
282//---------------------------------------------------------------------------
4a526fca 283int ft1000_write_dpram16(struct ft1000_device *ft1000dev, u16 indx, u16 value, u8 highlow)
f7c1be0c 284{
460bd5dd
MB
285 int ret = STATUS_SUCCESS;
286 u8 request;
bf3146c8 287
460bd5dd
MB
288 if (highlow == 0)
289 request = HARLEY_WRITE_DPRAM_LOW;
290 else
291 request = HARLEY_WRITE_DPRAM_HIGH;
f7c1be0c 292
460bd5dd
MB
293 ret = ft1000_control(ft1000dev,
294 usb_sndctrlpipe(ft1000dev->dev, 0),
295 request,
296 HARLEY_WRITE_OPERATION,
297 value,
298 indx,
299 NULL,
300 0,
301 LARGE_TIMEOUT);
bf3146c8 302
460bd5dd 303 return ret;
f7c1be0c
MB
304}
305
306//---------------------------------------------------------------------------
307// Function: fix_ft1000_read_dpram32
308//
309// Parameters: ft1000_device - device structure
310// indx - starting address to read
311// buffer - data buffer to hold the data read
bf3146c8
GKH
312//
313//
f7c1be0c
MB
314// Returns: STATUS_SUCCESS - success
315// STATUS_FAILURE - failure
316//
317// Description: This function read DPRAM 4 words at a time
318//
319// Notes:
320//
321//---------------------------------------------------------------------------
71e3335d
MB
322int fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx,
323 u8 *buffer)
f7c1be0c 324{
71e3335d
MB
325 u8 buf[16];
326 u16 pos;
327 int ret = STATUS_SUCCESS;
f7c1be0c 328
71e3335d
MB
329 pos = (indx / 4) * 4;
330 ret = ft1000_read_dpram32(ft1000dev, pos, buf, 16);
331
332 if (ret == STATUS_SUCCESS) {
333 pos = (indx % 4) * 4;
334 *buffer++ = buf[pos++];
335 *buffer++ = buf[pos++];
336 *buffer++ = buf[pos++];
337 *buffer++ = buf[pos++];
338 } else {
339 DEBUG("fix_ft1000_read_dpram32: DPRAM32 Read failed\n");
340 *buffer++ = 0;
341 *buffer++ = 0;
342 *buffer++ = 0;
343 *buffer++ = 0;
344 }
f7c1be0c 345
71e3335d 346 return ret;
bf3146c8 347}
f7c1be0c
MB
348
349
350//---------------------------------------------------------------------------
351// Function: fix_ft1000_write_dpram32
352//
353// Parameters: ft1000_device - device structure
354// indx - starting address to write
355// buffer - data buffer to write
bf3146c8
GKH
356//
357//
f7c1be0c
MB
358// Returns: STATUS_SUCCESS - success
359// STATUS_FAILURE - failure
360//
361// Description: This function write to DPRAM 4 words at a time
362//
363// Notes:
364//
365//---------------------------------------------------------------------------
4a526fca 366int fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer)
f7c1be0c 367{
8bfef502
MB
368 u16 pos1;
369 u16 pos2;
370 u16 i;
371 u8 buf[32];
372 u8 resultbuffer[32];
373 u8 *pdata;
374 int ret = STATUS_SUCCESS;
375
376 pos1 = (indx / 4) * 4;
377 pdata = buffer;
378 ret = ft1000_read_dpram32(ft1000dev, pos1, buf, 16);
bf3146c8 379
8bfef502
MB
380 if (ret == STATUS_SUCCESS) {
381 pos2 = (indx % 4)*4;
382 buf[pos2++] = *buffer++;
383 buf[pos2++] = *buffer++;
384 buf[pos2++] = *buffer++;
385 buf[pos2++] = *buffer++;
386 ret = ft1000_write_dpram32(ft1000dev, pos1, buf, 16);
387 } else {
388 DEBUG("fix_ft1000_write_dpram32: DPRAM32 Read failed\n");
389 return ret;
390 }
f7c1be0c 391
8bfef502 392 ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16);
f7c1be0c 393
8bfef502
MB
394 if (ret == STATUS_SUCCESS) {
395 buffer = pdata;
396 for (i = 0; i < 16; i++) {
397 if (buf[i] != resultbuffer[i])
398 ret = STATUS_FAILURE;
399 }
400 }
bf3146c8 401
8bfef502
MB
402 if (ret == STATUS_FAILURE) {
403 ret = ft1000_write_dpram32(ft1000dev, pos1,
404 (u8 *)&tempbuffer[0], 16);
405 ret = ft1000_read_dpram32(ft1000dev, pos1,
406 (u8 *)&resultbuffer[0], 16);
407 if (ret == STATUS_SUCCESS) {
408 buffer = pdata;
409 for (i = 0; i < 16; i++) {
410 if (tempbuffer[i] != resultbuffer[i]) {
411 ret = STATUS_FAILURE;
412 DEBUG("%s Failed to write\n",
413 __func__);
414 }
415 }
416 }
417 }
f7c1be0c 418
8bfef502 419 return ret;
f7c1be0c
MB
420}
421
422
423//------------------------------------------------------------------------
424//
425// Function: card_reset_dsp
426//
427// Synopsis: This function is called to reset or activate the DSP
428//
429// Arguments: value - reset or activate
430//
431// Returns: None
432//-----------------------------------------------------------------------
677aaa43 433static void card_reset_dsp(struct ft1000_device *ft1000dev, bool value)
f7c1be0c 434{
677aaa43
MB
435 u16 status = STATUS_SUCCESS;
436 u16 tempword;
437
438 status = ft1000_write_register(ft1000dev, HOST_INTF_BE,
439 FT1000_REG_SUP_CTRL);
440 status = ft1000_read_register(ft1000dev, &tempword,
441 FT1000_REG_SUP_CTRL);
442
443 if (value) {
444 DEBUG("Reset DSP\n");
445 status = ft1000_read_register(ft1000dev, &tempword,
446 FT1000_REG_RESET);
447 tempword |= DSP_RESET_BIT;
448 status = ft1000_write_register(ft1000dev, tempword,
449 FT1000_REG_RESET);
450 } else {
451 DEBUG("Activate DSP\n");
452 status = ft1000_read_register(ft1000dev, &tempword,
453 FT1000_REG_RESET);
454 tempword |= DSP_ENCRYPTED;
455 tempword &= ~DSP_UNENCRYPTED;
456 status = ft1000_write_register(ft1000dev, tempword,
457 FT1000_REG_RESET);
458 status = ft1000_read_register(ft1000dev, &tempword,
459 FT1000_REG_RESET);
460 tempword &= ~EFUSE_MEM_DISABLE;
461 tempword &= ~DSP_RESET_BIT;
462 status = ft1000_write_register(ft1000dev, tempword,
463 FT1000_REG_RESET);
464 status = ft1000_read_register(ft1000dev, &tempword,
465 FT1000_REG_RESET);
466 }
f7c1be0c
MB
467}
468
469//---------------------------------------------------------------------------
a209efad 470// Function: card_send_command
f7c1be0c
MB
471//
472// Parameters: ft1000_device - device structure
473// ptempbuffer - command buffer
474// size - command buffer size
bf3146c8 475//
f7c1be0c
MB
476// Returns: STATUS_SUCCESS - success
477// STATUS_FAILURE - failure
478//
479// Description: This function sends a command to ASIC
480//
481// Notes:
482//
483//---------------------------------------------------------------------------
68e79bcc
MB
484void card_send_command(struct ft1000_device *ft1000dev, void *ptempbuffer,
485 int size)
f7c1be0c 486{
68e79bcc
MB
487 unsigned short temp;
488 unsigned char *commandbuf;
bf3146c8 489
68e79bcc 490 DEBUG("card_send_command: enter card_send_command... size=%d\n", size);
bf3146c8 491
68e79bcc
MB
492 commandbuf = (unsigned char *)kmalloc(size + 2, GFP_KERNEL);
493 memcpy((void *)commandbuf + 2, (void *)ptempbuffer, size);
bf3146c8 494
68e79bcc 495 //DEBUG("card_send_command: Command Send\n");
bf3146c8 496
68e79bcc 497 ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
bf3146c8 498
68e79bcc
MB
499 if (temp & 0x0100)
500 msleep(10);
bf3146c8 501
68e79bcc
MB
502 /* check for odd word */
503 size = size + 2;
f7c1be0c 504
68e79bcc
MB
505 /* Must force to be 32 bit aligned */
506 if (size % 4)
507 size += 4 - (size % 4);
bf3146c8 508
68e79bcc
MB
509 //DEBUG("card_send_command: write dpram ... size=%d\n", size);
510 ft1000_write_dpram32(ft1000dev, 0, commandbuf, size);
511 msleep(1);
512 //DEBUG("card_send_command: write into doorbell ...\n");
513 ft1000_write_register(ft1000dev, FT1000_DB_DPRAM_TX,
514 FT1000_REG_DOORBELL);
515 msleep(1);
bf3146c8 516
68e79bcc
MB
517 ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
518 //DEBUG("card_send_command: read doorbell ...temp=%x\n", temp);
519 if ((temp & 0x0100) == 0) {
520 //DEBUG("card_send_command: Message sent\n");
521 }
f7c1be0c
MB
522
523}
524
f7c1be0c
MB
525//--------------------------------------------------------------------------
526//
527// Function: dsp_reload
528//
529// Synopsis: This function is called to load or reload the DSP
530//
531// Arguments: ft1000dev - device structure
532//
533// Returns: None
534//-----------------------------------------------------------------------
5cb9954a 535int dsp_reload(struct ft1000_device *ft1000dev)
f7c1be0c 536{
3529bd41
MB
537 u16 status;
538 u16 tempword;
539 u32 templong;
bf3146c8 540
1a88a068 541 struct ft1000_info *pft1000info;
bf3146c8 542
3529bd41 543 pft1000info = netdev_priv(ft1000dev->net);
f7c1be0c 544
3529bd41 545 pft1000info->CardReady = 0;
f7c1be0c 546
3529bd41
MB
547 /* Program Interrupt Mask register */
548 status = ft1000_write_register(ft1000dev, 0xffff, FT1000_REG_SUP_IMASK);
f7c1be0c 549
3529bd41
MB
550 status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET);
551 tempword |= ASIC_RESET_BIT;
552 status = ft1000_write_register(ft1000dev, tempword, FT1000_REG_RESET);
553 msleep(1000);
554 status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET);
555 DEBUG("Reset Register = 0x%x\n", tempword);
f7c1be0c 556
3529bd41
MB
557 /* Toggle DSP reset */
558 card_reset_dsp(ft1000dev, 1);
559 msleep(1000);
560 card_reset_dsp(ft1000dev, 0);
561 msleep(1000);
f7c1be0c 562
3529bd41
MB
563 status =
564 ft1000_write_register(ft1000dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL);
f7c1be0c 565
3529bd41
MB
566 /* Let's check for FEFE */
567 status =
568 ft1000_read_dpram32(ft1000dev, FT1000_MAG_DPRAM_FEFE_INDX,
569 (u8 *) &templong, 4);
570 DEBUG("templong (fefe) = 0x%8x\n", templong);
f7c1be0c 571
3529bd41
MB
572 /* call codeloader */
573 status = scram_dnldr(ft1000dev, pFileStart, FileLength);
bf3146c8 574
5cb9954a
MB
575 if (status != STATUS_SUCCESS)
576 return -EIO;
f7c1be0c 577
3529bd41 578 msleep(1000);
f7c1be0c 579
3529bd41 580 DEBUG("dsp_reload returned\n");
f7c1be0c 581
3529bd41 582 return 0;
f7c1be0c
MB
583}
584
585//---------------------------------------------------------------------------
586//
587// Function: ft1000_reset_asic
588// Descripton: This function will call the Card Service function to reset the
589// ASIC.
590// Input:
591// dev - device structure
592// Output:
593// none
594//
595//---------------------------------------------------------------------------
84a60963 596static void ft1000_reset_asic(struct net_device *dev)
f7c1be0c 597{
1a88a068 598 struct ft1000_info *info = netdev_priv(dev);
84a60963
MB
599 struct ft1000_device *ft1000dev = info->pFt1000Dev;
600 u16 tempword;
bf3146c8 601
84a60963 602 DEBUG("ft1000_hw:ft1000_reset_asic called\n");
f7c1be0c 603
84a60963 604 info->ASICResetNum++;
bf3146c8 605
84a60963
MB
606 /* Let's use the register provided by the Magnemite ASIC to reset the
607 * ASIC and DSP.
608 */
609 ft1000_write_register(ft1000dev, (DSP_RESET_BIT | ASIC_RESET_BIT),
610 FT1000_REG_RESET);
f7c1be0c 611
84a60963 612 mdelay(1);
bf3146c8 613
84a60963
MB
614 /* set watermark to -1 in order to not generate an interrrupt */
615 ft1000_write_register(ft1000dev, 0xffff, FT1000_REG_MAG_WATERMARK);
bf3146c8 616
84a60963
MB
617 /* clear interrupts */
618 ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_ISR);
619 DEBUG("ft1000_hw: interrupt status register = 0x%x\n", tempword);
620 ft1000_write_register(ft1000dev, tempword, FT1000_REG_SUP_ISR);
621 ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_ISR);
622 DEBUG("ft1000_hw: interrupt status register = 0x%x\n", tempword);
f7c1be0c 623}
f7c1be0c 624
f7c1be0c
MB
625
626//---------------------------------------------------------------------------
627//
628// Function: ft1000_reset_card
629// Descripton: This function will reset the card
630// Input:
631// dev - device structure
632// Output:
633// status - FALSE (card reset fail)
bf3146c8 634// TRUE (card reset successful)
f7c1be0c
MB
635//
636//---------------------------------------------------------------------------
3071c12e 637static int ft1000_reset_card(struct net_device *dev)
f7c1be0c 638{
1a88a068 639 struct ft1000_info *info = netdev_priv(dev);
3071c12e
MB
640 struct ft1000_device *ft1000dev = info->pFt1000Dev;
641 u16 tempword;
e27d96dd 642 struct prov_record *ptr;
f7c1be0c 643
3071c12e 644 DEBUG("ft1000_hw:ft1000_reset_card called.....\n");
f7c1be0c 645
3071c12e
MB
646 info->fCondResetPend = 1;
647 info->CardReady = 0;
648 info->fProvComplete = 0;
bf3146c8 649
3071c12e
MB
650 /* Make sure we free any memory reserve for provisioning */
651 while (list_empty(&info->prov_list) == 0) {
652 DEBUG("ft1000_reset_card:deleting provisioning record\n");
653 ptr =
654 list_entry(info->prov_list.next, struct prov_record, list);
655 list_del(&ptr->list);
656 kfree(ptr->pprov_data);
657 kfree(ptr);
658 }
bf3146c8 659
3071c12e
MB
660 DEBUG("ft1000_hw:ft1000_reset_card: reset asic\n");
661 ft1000_reset_asic(dev);
bf3146c8 662
3071c12e 663 info->DSPResetNum++;
f7c1be0c 664
3071c12e
MB
665 DEBUG("ft1000_hw:ft1000_reset_card: call dsp_reload\n");
666 dsp_reload(ft1000dev);
bf3146c8 667
3071c12e 668 DEBUG("dsp reload successful\n");
f7c1be0c 669
3071c12e 670 mdelay(10);
bf3146c8 671
3071c12e
MB
672 /* Initialize DSP heartbeat area */
673 ft1000_write_dpram16(ft1000dev, FT1000_MAG_HI_HO, ho_mag,
674 FT1000_MAG_HI_HO_INDX);
675 ft1000_read_dpram16(ft1000dev, FT1000_MAG_HI_HO, (u8 *) &tempword,
676 FT1000_MAG_HI_HO_INDX);
677 DEBUG("ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n", tempword);
bf3146c8 678
3071c12e 679 info->CardReady = 1;
bf3146c8 680
3071c12e 681 info->fCondResetPend = 0;
f7c1be0c 682
3071c12e 683 return TRUE;
f7c1be0c
MB
684}
685
686
687//mbelian
688#ifdef HAVE_NET_DEVICE_OPS
689static const struct net_device_ops ftnet_ops =
690{
cb3aa5d5
MB
691 .ndo_open = &ft1000_open,
692 .ndo_stop = &ft1000_close,
693 .ndo_start_xmit = &ft1000_start_xmit,
694 .ndo_get_stats = &ft1000_netdev_stats,
f7c1be0c
MB
695};
696#endif
697
698
699//---------------------------------------------------------------------------
700// Function: init_ft1000_netdev
701//
702// Parameters: ft1000dev - device structure
703//
bf3146c8 704//
f7c1be0c
MB
705// Returns: STATUS_SUCCESS - success
706// STATUS_FAILURE - failure
707//
708// Description: This function initialize the network device
709//
710// Notes:
711//
712//---------------------------------------------------------------------------
713u16 init_ft1000_netdev(struct ft1000_device *ft1000dev)
714{
715 struct net_device *netdev;
1a88a068 716 struct ft1000_info *pInfo = NULL;
29437ab0 717 struct dpram_blk *pdpram_blk;
f9d17373 718 int i, ret_val;
b7378b9e 719 struct list_head *cur, *tmp;
f9d17373 720 char card_nr[2];
448d4014 721 unsigned long gCardIndex = 0;
f7c1be0c
MB
722
723 DEBUG("Enter init_ft1000_netdev...\n");
bf3146c8 724
f7c1be0c 725
1a88a068 726 netdev = alloc_etherdev(sizeof(struct ft1000_info));
f7c1be0c
MB
727 if (!netdev )
728 {
729 DEBUG("init_ft1000_netdev: can not allocate network device\n");
78890fdb 730 return -ENOMEM;
f7c1be0c
MB
731 }
732
e33196e1 733 pInfo = netdev_priv(netdev);
bf3146c8 734
f7c1be0c
MB
735 //DEBUG("init_ft1000_netdev: gFt1000Info=%x, netdev=%x, ft1000dev=%x\n", gFt1000Info, netdev, ft1000dev);
736
1a88a068 737 memset(pInfo, 0, sizeof(struct ft1000_info));
f7c1be0c
MB
738
739 dev_alloc_name(netdev, netdev->name);
740
f7c1be0c 741 DEBUG("init_ft1000_netdev: network device name is %s\n", netdev->name);
bf3146c8 742
f9d17373
MB
743 if ( strncmp(netdev->name,"eth", 3) == 0) {
744 card_nr[0] = netdev->name[3];
745 card_nr[1] = '\0';
746 ret_val = strict_strtoul(card_nr, 10, &gCardIndex);
747 if (ret_val) {
748 printk(KERN_ERR "Can't parse netdev\n");
78890fdb 749 goto err_net;
f9d17373
MB
750 }
751
f7c1be0c
MB
752 pInfo->CardNumber = gCardIndex;
753 DEBUG("card number = %d\n", pInfo->CardNumber);
754 }
755 else {
bf3146c8 756 printk(KERN_ERR "ft1000: Invalid device name\n");
78890fdb
MB
757 ret_val = -ENXIO;
758 goto err_net;
f7c1be0c 759 }
f7c1be0c
MB
760
761 memset(&pInfo->stats, 0, sizeof(struct net_device_stats) );
762
763 spin_lock_init(&pInfo->dpram_lock);
764 pInfo->pFt1000Dev = ft1000dev;
765 pInfo->DrvErrNum = 0;
766 pInfo->ASICResetNum = 0;
767 pInfo->registered = 1;
768 pInfo->ft1000_reset = ft1000_reset;
769 pInfo->mediastate = 0;
770 pInfo->fifo_cnt = 0;
771 pInfo->DeviceCreated = FALSE;
f7c1be0c
MB
772 pInfo->CurrentInterruptEnableMask = ISR_DEFAULT_MASK;
773 pInfo->InterruptsEnabled = FALSE;
774 pInfo->CardReady = 0;
f7c1be0c
MB
775 pInfo->DSP_TIME[0] = 0;
776 pInfo->DSP_TIME[1] = 0;
777 pInfo->DSP_TIME[2] = 0;
778 pInfo->DSP_TIME[3] = 0;
779 pInfo->fAppMsgPend = 0;
780 pInfo->fCondResetPend = 0;
781 pInfo->usbboot = 0;
782 pInfo->dspalive = 0;
eb21c158 783 memset(&pInfo->tempbuf[0], 0, sizeof(pInfo->tempbuf));
f7c1be0c
MB
784
785 INIT_LIST_HEAD(&pInfo->prov_list);
786
9119dee1 787 INIT_LIST_HEAD(&pInfo->nodes.list);
f7c1be0c
MB
788//mbelian
789#ifdef HAVE_NET_DEVICE_OPS
bf3146c8 790 netdev->netdev_ops = &ftnet_ops;
f7c1be0c 791#else
bf3146c8 792 netdev->hard_start_xmit = &ft1000_start_xmit;
f7c1be0c
MB
793 netdev->get_stats = &ft1000_netdev_stats;
794 netdev->open = &ft1000_open;
795 netdev->stop = &ft1000_close;
796#endif
797
f7c1be0c
MB
798 ft1000dev->net = netdev;
799
800
801
bf3146c8 802//init free_buff_lock, freercvpool, numofmsgbuf, pdpram_blk
f7c1be0c
MB
803//only init once per card
804//Jim
805 DEBUG("Initialize free_buff_lock and freercvpool\n");
806 spin_lock_init(&free_buff_lock);
807
808 // initialize a list of buffers to be use for queuing up receive command data
809 INIT_LIST_HEAD (&freercvpool);
810
811 // create list of free buffers
812 for (i=0; i<NUM_OF_FREE_BUFFERS; i++) {
813 // Get memory for DPRAM_DATA link list
29437ab0 814 pdpram_blk = kmalloc(sizeof(struct dpram_blk), GFP_KERNEL);
78890fdb
MB
815 if (pdpram_blk == NULL) {
816 ret_val = -ENOMEM;
817 goto err_free;
818 }
f7c1be0c 819 // Get a block of memory to store command data
bf3146c8 820 pdpram_blk->pbuffer = kmalloc ( MAX_CMD_SQSIZE, GFP_KERNEL );
78890fdb
MB
821 if (pdpram_blk->pbuffer == NULL) {
822 ret_val = -ENOMEM;
823 kfree(pdpram_blk);
824 goto err_free;
825 }
bf3146c8 826 // link provisioning data
f7c1be0c
MB
827 list_add_tail (&pdpram_blk->list, &freercvpool);
828 }
829 numofmsgbuf = NUM_OF_FREE_BUFFERS;
830
bf3146c8 831
78890fdb 832 return 0;
bf3146c8 833
b7378b9e
VK
834
835err_free:
1055cc99 836 list_for_each_safe(cur, tmp, &freercvpool) {
29437ab0 837 pdpram_blk = list_entry(cur, struct dpram_blk, list);
b7378b9e
VK
838 list_del(&pdpram_blk->list);
839 kfree(pdpram_blk->pbuffer);
840 kfree(pdpram_blk);
841 }
78890fdb
MB
842err_net:
843 free_netdev(netdev);
844 return ret_val;
f7c1be0c
MB
845}
846
847
848
849//---------------------------------------------------------------------------
850// Function: reg_ft1000_netdev
851//
852// Parameters: ft1000dev - device structure
853//
bf3146c8 854//
f7c1be0c
MB
855// Returns: STATUS_SUCCESS - success
856// STATUS_FAILURE - failure
857//
858// Description: This function register the network driver
859//
860// Notes:
861//
862//---------------------------------------------------------------------------
aaf0885c 863int reg_ft1000_netdev(struct ft1000_device *ft1000dev, struct usb_interface *intf)
f7c1be0c
MB
864{
865 struct net_device *netdev;
1a88a068 866 struct ft1000_info *pInfo;
7dc59115 867 int rc;
f7c1be0c
MB
868
869 netdev = ft1000dev->net;
870 pInfo = netdev_priv(ft1000dev->net);
871 DEBUG("Enter reg_ft1000_netdev...\n");
872
873
874 ft1000_read_register(ft1000dev, &pInfo->AsicID, FT1000_REG_ASIC_ID);
875
876 usb_set_intfdata(intf, pInfo);
877 SET_NETDEV_DEV(netdev, &intf->dev);
bf3146c8 878
f7c1be0c
MB
879 rc = register_netdev(netdev);
880 if (rc)
881 {
882 DEBUG("reg_ft1000_netdev: could not register network device\n");
883 free_netdev(netdev);
aaf0885c 884 return rc;
f7c1be0c
MB
885 }
886
887
888 //Create character device, implemented by Jim
4d791234 889 ft1000_create_dev(ft1000dev);
f7c1be0c 890
f7c1be0c
MB
891 DEBUG ("reg_ft1000_netdev returned\n");
892
893 pInfo->CardReady = 1;
894
895
aaf0885c 896 return 0;
f7c1be0c
MB
897}
898
2a953cfd 899static int ft1000_reset(struct net_device *dev)
f7c1be0c
MB
900{
901 ft1000_reset_card(dev);
902 return 0;
903}
904
905//---------------------------------------------------------------------------
906// Function: ft1000_usb_transmit_complete
907//
908// Parameters: urb - transmitted usb urb
909//
bf3146c8 910//
f7c1be0c
MB
911// Returns: none
912//
913// Description: This is the callback function when a urb is transmitted
914//
915// Notes:
916//
917//---------------------------------------------------------------------------
918static void ft1000_usb_transmit_complete(struct urb *urb)
919{
920
921 struct ft1000_device *ft1000dev = urb->context;
922
923 //DEBUG("ft1000_usb_transmit_complete entered\n");
f7c1be0c
MB
924
925 if (urb->status)
926 printk("%s: TX status %d\n", ft1000dev->net->name, urb->status);
927
928 netif_wake_queue(ft1000dev->net);
929
f7c1be0c
MB
930 //DEBUG("Return from ft1000_usb_transmit_complete\n");
931}
932
f7c1be0c
MB
933//---------------------------------------------------------------------------
934//
935// Function: ft1000_copy_down_pkt
bf3146c8
GKH
936// Descripton: This function will take an ethernet packet and convert it to
937// a Flarion packet prior to sending it to the ASIC Downlink
f7c1be0c
MB
938// FIFO.
939// Input:
940// dev - device structure
941// packet - address of ethernet packet
942// len - length of IP packet
943// Output:
bf3146c8
GKH
944// status - FAILURE
945// SUCCESS
f7c1be0c
MB
946//
947//---------------------------------------------------------------------------
2a953cfd 948static int ft1000_copy_down_pkt (struct net_device *netdev, u8 *packet, u16 len)
f7c1be0c 949{
1a88a068 950 struct ft1000_info *pInfo = netdev_priv(netdev);
f7c1be0c
MB
951 struct ft1000_device *pFt1000Dev = pInfo->pFt1000Dev;
952
953
d2b07455 954 int count, ret;
f7c1be0c 955 u8 *t;
d2b07455 956 struct pseudo_hdr hdr;
bf3146c8 957
f7c1be0c
MB
958 if (!pInfo->CardReady)
959 {
bf3146c8 960
f7c1be0c 961 DEBUG("ft1000_copy_down_pkt::Card Not Ready\n");
35e9403b 962 return -ENODEV;
bf3146c8 963
f7c1be0c 964 }
f7c1be0c 965
bf3146c8
GKH
966
967 //DEBUG("ft1000_copy_down_pkt() entered, len = %d\n", len);
968
b13e39b2 969 count = sizeof(struct pseudo_hdr) + len;
f7c1be0c
MB
970 if(count > MAX_BUF_SIZE)
971 {
972 DEBUG("Error:ft1000_copy_down_pkt:Message Size Overflow!\n");
973 DEBUG("size = %d\n", count);
35e9403b 974 return -EINVAL;
f7c1be0c 975 }
bf3146c8 976
f7c1be0c
MB
977 if ( count % 4)
978 count = count + (4- (count %4) );
bf3146c8 979
d2b07455
MB
980 memset(&hdr, 0, sizeof(struct pseudo_hdr));
981
982 hdr.length = ntohs(count);
983 hdr.source = 0x10;
984 hdr.destination = 0x20;
985 hdr.portdest = 0x20;
986 hdr.portsrc = 0x10;
987 hdr.sh_str_id = 0x91;
988 hdr.control = 0x00;
989
990 hdr.checksum = hdr.length ^ hdr.source ^ hdr.destination ^
991 hdr.portdest ^ hdr.portsrc ^ hdr.sh_str_id ^
992 hdr.control;
993
994 memcpy(&pFt1000Dev->tx_buf[0], &hdr, sizeof(hdr));
b13e39b2 995 memcpy(&(pFt1000Dev->tx_buf[sizeof(struct pseudo_hdr)]), packet, len);
f7c1be0c 996
f7c1be0c
MB
997 netif_stop_queue(netdev);
998
999 //DEBUG ("ft1000_copy_down_pkt: count = %d\n", count);
bf3146c8 1000
f7c1be0c
MB
1001 usb_fill_bulk_urb(pFt1000Dev->tx_urb,
1002 pFt1000Dev->dev,
1003 usb_sndbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_out_endpointAddr),
1004 pFt1000Dev->tx_buf,
1005 count,
1006 ft1000_usb_transmit_complete,
bf3146c8
GKH
1007 (void*)pFt1000Dev);
1008
f7c1be0c
MB
1009 t = (u8 *)pFt1000Dev->tx_urb->transfer_buffer;
1010 //DEBUG("transfer_length=%d\n", pFt1000Dev->tx_urb->transfer_buffer_length);
1011 /*for (i=0; i<count; i++ )
bf3146c8 1012 {
f7c1be0c 1013 DEBUG("%x ", *t++ );
bf3146c8
GKH
1014 }*/
1015
1016
35e9403b
MB
1017 ret = usb_submit_urb(pFt1000Dev->tx_urb, GFP_ATOMIC);
1018 if (ret) {
f7c1be0c 1019 DEBUG("ft1000 failed tx_urb %d\n", ret);
35e9403b
MB
1020 return ret;
1021 } else {
1022 pInfo->stats.tx_packets++;
1023 pInfo->stats.tx_bytes += (len+14);
1024 }
bf3146c8
GKH
1025
1026 //DEBUG("ft1000_copy_down_pkt() exit\n");
1027
35e9403b 1028 return 0;
f7c1be0c
MB
1029}
1030
1031//---------------------------------------------------------------------------
1032// Function: ft1000_start_xmit
1033//
1034// Parameters: skb - socket buffer to be sent
1035// dev - network device
1036//
bf3146c8 1037//
f7c1be0c
MB
1038// Returns: none
1039//
1040// Description: transmit a ethernet packet
1041//
1042// Notes:
1043//
1044//---------------------------------------------------------------------------
bf3146c8 1045static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
f7c1be0c 1046{
1a88a068 1047 struct ft1000_info *pInfo = netdev_priv(dev);
f7c1be0c
MB
1048 struct ft1000_device *pFt1000Dev= pInfo->pFt1000Dev;
1049 u8 *pdata;
1050 int maxlen, pipe;
bf3146c8
GKH
1051
1052
1053 //DEBUG(" ft1000_start_xmit() entered\n");
1054
1055 if ( skb == NULL )
f7c1be0c 1056 {
bf3146c8 1057 DEBUG ("ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n" );
3b3291e8 1058 return NETDEV_TX_OK;
f7c1be0c 1059 }
bf3146c8 1060
f7c1be0c
MB
1061 if ( pFt1000Dev->status & FT1000_STATUS_CLOSING)
1062 {
1063 DEBUG("network driver is closed, return\n");
3b3291e8 1064 goto err;
f7c1be0c
MB
1065 }
1066
1067 //DEBUG("ft1000_start_xmit 1:length of packet = %d\n", skb->len);
1068 pipe = usb_sndbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_out_endpointAddr);
1069 maxlen = usb_maxpacket(pFt1000Dev->dev, pipe, usb_pipeout(pipe));
1070 //DEBUG("ft1000_start_xmit 2: pipe=%d dev->maxpacket = %d\n", pipe, maxlen);
1071
1072 pdata = (u8 *)skb->data;
1073 /*for (i=0; i<skb->len; i++)
1074 DEBUG("skb->data[%d]=%x ", i, *(skb->data+i));
bf3146c8 1075
f7c1be0c 1076 DEBUG("\n");*/
bf3146c8
GKH
1077
1078
1079 if (pInfo->mediastate == 0)
f7c1be0c
MB
1080 {
1081 /* Drop packet is mediastate is down */
1082 DEBUG("ft1000_hw:ft1000_start_xmit:mediastate is down\n");
3b3291e8 1083 goto err;
f7c1be0c
MB
1084 }
1085
bf3146c8 1086 if ( (skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE) )
f7c1be0c
MB
1087 {
1088 /* Drop packet which has invalid size */
1089 DEBUG("ft1000_hw:ft1000_start_xmit:invalid ethernet length\n");
3b3291e8 1090 goto err;
f7c1be0c 1091 }
bf3146c8 1092//mbelian
3b3291e8
MB
1093 ft1000_copy_down_pkt(dev, (pdata+ENET_HEADER_SIZE-2),
1094 skb->len - ENET_HEADER_SIZE + 2);
bf3146c8 1095
3b3291e8
MB
1096err:
1097 dev_kfree_skb(skb);
f7c1be0c 1098 //DEBUG(" ft1000_start_xmit() exit\n");
bf3146c8 1099
3b3291e8 1100 return NETDEV_TX_OK;
f7c1be0c
MB
1101}
1102
1103//---------------------------------------------------------------------------
1104//
1105// Function: ft1000_copy_up_pkt
1106// Descripton: This function will take a packet from the FIFO up link and
1107// convert it into an ethernet packet and deliver it to the IP stack
1108// Input:
1109// urb - the receving usb urb
1110//
1111// Output:
bf3146c8
GKH
1112// status - FAILURE
1113// SUCCESS
f7c1be0c
MB
1114//
1115//---------------------------------------------------------------------------
2a953cfd 1116static int ft1000_copy_up_pkt (struct urb *urb)
f7c1be0c 1117{
1a88a068 1118 struct ft1000_info *info = urb->context;
f7c1be0c
MB
1119 struct ft1000_device *ft1000dev = info->pFt1000Dev;
1120 struct net_device *net = ft1000dev->net;
bf3146c8 1121
f7c1be0c
MB
1122 u16 tempword;
1123 u16 len;
1124 u16 lena; //mbelian
1125 struct sk_buff *skb;
1126 u16 i;
1127 u8 *pbuffer=NULL;
1128 u8 *ptemp=NULL;
1129 u16 *chksum;
1130
1131
1132 //DEBUG("ft1000_copy_up_pkt entered\n");
bf3146c8 1133
f7c1be0c
MB
1134 if ( ft1000dev->status & FT1000_STATUS_CLOSING)
1135 {
1136 DEBUG("network driver is closed, return\n");
1137 return STATUS_SUCCESS;
1138 }
bf3146c8 1139
f7c1be0c
MB
1140 // Read length
1141 len = urb->transfer_buffer_length;
1142 lena = urb->actual_length; //mbelian
1143 //DEBUG("ft1000_copy_up_pkt: transfer_buffer_length=%d, actual_buffer_len=%d\n",
1144 // urb->transfer_buffer_length, urb->actual_length);
1145
d1674983 1146 chksum = (u16 *)ft1000dev->rx_buf;
bf3146c8 1147
f7c1be0c
MB
1148 tempword = *chksum++;
1149 for (i=1; i<7; i++)
1150 {
1151 tempword ^= *chksum++;
1152 }
bf3146c8 1153
f7c1be0c 1154 if (tempword != *chksum)
bf3146c8 1155 {
f7c1be0c
MB
1156 info->stats.rx_errors ++;
1157 ft1000_submit_rx_urb(info);
1158 return STATUS_FAILURE;
1159 }
1160
1161
1162 //DEBUG("ft1000_copy_up_pkt: checksum is correct %x\n", *chksum);
bf3146c8 1163
f7c1be0c
MB
1164 skb = dev_alloc_skb(len+12+2);
1165
bf3146c8 1166 if (skb == NULL)
f7c1be0c
MB
1167 {
1168 DEBUG("ft1000_copy_up_pkt: No Network buffers available\n");
1169 info->stats.rx_errors++;
1170 ft1000_submit_rx_urb(info);
1171 return STATUS_FAILURE;
1172 }
bf3146c8 1173
f7c1be0c 1174 pbuffer = (u8 *)skb_put(skb, len+12);
bf3146c8 1175
f7c1be0c
MB
1176 //subtract the number of bytes read already
1177 ptemp = pbuffer;
1178
1179 // fake MAC address
1180 *pbuffer++ = net->dev_addr[0];
1181 *pbuffer++ = net->dev_addr[1];
1182 *pbuffer++ = net->dev_addr[2];
1183 *pbuffer++ = net->dev_addr[3];
1184 *pbuffer++ = net->dev_addr[4];
1185 *pbuffer++ = net->dev_addr[5];
1186 *pbuffer++ = 0x00;
1187 *pbuffer++ = 0x07;
1188 *pbuffer++ = 0x35;
1189 *pbuffer++ = 0xff;
1190 *pbuffer++ = 0xff;
1191 *pbuffer++ = 0xfe;
f7c1be0c 1192
bf3146c8
GKH
1193
1194
1195
b13e39b2 1196 memcpy(pbuffer, ft1000dev->rx_buf+sizeof(struct pseudo_hdr), len-sizeof(struct pseudo_hdr));
f7c1be0c
MB
1197
1198 //DEBUG("ft1000_copy_up_pkt: Data passed to Protocol layer\n");
bf3146c8 1199 /*for (i=0; i<len+12; i++)
f7c1be0c
MB
1200 {
1201 DEBUG("ft1000_copy_up_pkt: Protocol Data: 0x%x\n ", *ptemp++);
1202 }*/
1203
1204 skb->dev = net;
bf3146c8 1205
f7c1be0c
MB
1206 skb->protocol = eth_type_trans(skb, net);
1207 skb->ip_summed = CHECKSUM_UNNECESSARY;
1208 netif_rx(skb);
1209
1210 info->stats.rx_packets++;
1211 // Add on 12 bytes for MAC address which was removed
1212 info->stats.rx_bytes += (lena+12); //mbelian
1213
bf3146c8 1214 ft1000_submit_rx_urb(info);
f7c1be0c
MB
1215 //DEBUG("ft1000_copy_up_pkt exited\n");
1216 return SUCCESS;
1217}
1218
1219//---------------------------------------------------------------------------
1220//
1221// Function: ft1000_submit_rx_urb
1222// Descripton: the receiving function of the network driver
1223//
1224// Input:
1225// info - a private structure contains the device information
1226//
1227// Output:
bf3146c8
GKH
1228// status - FAILURE
1229// SUCCESS
f7c1be0c
MB
1230//
1231//---------------------------------------------------------------------------
1a88a068 1232static int ft1000_submit_rx_urb(struct ft1000_info *info)
f7c1be0c
MB
1233{
1234 int result;
1235 struct ft1000_device *pFt1000Dev = info->pFt1000Dev;
1236
bf3146c8 1237
f7c1be0c
MB
1238 //DEBUG ("ft1000_submit_rx_urb entered: sizeof rx_urb is %d\n", sizeof(*pFt1000Dev->rx_urb));
1239 if ( pFt1000Dev->status & FT1000_STATUS_CLOSING)
1240 {
1241 DEBUG("network driver is closed, return\n");
1242 //usb_kill_urb(pFt1000Dev->rx_urb); //mbelian
d7780865 1243 return -ENODEV;
f7c1be0c 1244 }
f7c1be0c
MB
1245
1246 usb_fill_bulk_urb(pFt1000Dev->rx_urb,
1247 pFt1000Dev->dev,
1248 usb_rcvbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_in_endpointAddr),
1249 pFt1000Dev->rx_buf,
1250 MAX_BUF_SIZE,
1251 (usb_complete_t)ft1000_copy_up_pkt,
1252 info);
1253
1254
1255 if((result = usb_submit_urb(pFt1000Dev->rx_urb, GFP_ATOMIC)))
1256 {
1257 printk("ft1000_submit_rx_urb: submitting rx_urb %d failed\n", result);
d7780865 1258 return result;
f7c1be0c 1259 }
bf3146c8 1260
f7c1be0c
MB
1261 //DEBUG("ft1000_submit_rx_urb exit: result=%d\n", result);
1262
d7780865 1263 return 0;
f7c1be0c
MB
1264}
1265
1266//---------------------------------------------------------------------------
1267// Function: ft1000_open
1268//
bf3146c8 1269// Parameters:
f7c1be0c
MB
1270// dev - network device
1271//
bf3146c8 1272//
f7c1be0c
MB
1273// Returns: none
1274//
1275// Description: open the network driver
1276//
1277// Notes:
1278//
1279//---------------------------------------------------------------------------
bf3146c8 1280static int ft1000_open (struct net_device *dev)
f7c1be0c 1281{
e33196e1 1282 struct ft1000_info *pInfo = netdev_priv(dev);
f7c1be0c 1283 struct timeval tv; //mbelian
95112cb4 1284 int ret;
f7c1be0c
MB
1285
1286 DEBUG("ft1000_open is called for card %d\n", pInfo->CardNumber);
1287 //DEBUG("ft1000_open: dev->addr=%x, dev->addr_len=%d\n", dev->addr, dev->addr_len);
1288
1289 pInfo->stats.rx_bytes = 0; //mbelian
1290 pInfo->stats.tx_bytes = 0; //mbelian
1291 pInfo->stats.rx_packets = 0; //mbelian
1292 pInfo->stats.tx_packets = 0; //mbelian
1293 do_gettimeofday(&tv);
1294 pInfo->ConTm = tv.tv_sec;
1295 pInfo->ProgConStat = 0; //mbelian
bf3146c8
GKH
1296
1297
f7c1be0c 1298 netif_start_queue(dev);
bf3146c8 1299
f7c1be0c 1300 netif_carrier_on(dev); //mbelian
bf3146c8 1301
95112cb4
MB
1302 ret = ft1000_submit_rx_urb(pInfo);
1303
1304 return ret;
f7c1be0c
MB
1305}
1306
1307//---------------------------------------------------------------------------
1308// Function: ft1000_close
1309//
bf3146c8 1310// Parameters:
f7c1be0c
MB
1311// net - network device
1312//
bf3146c8 1313//
f7c1be0c
MB
1314// Returns: none
1315//
1316// Description: close the network driver
1317//
1318// Notes:
1319//
1320//---------------------------------------------------------------------------
1321int ft1000_close(struct net_device *net)
1322{
e33196e1 1323 struct ft1000_info *pInfo = netdev_priv(net);
f7c1be0c
MB
1324 struct ft1000_device *ft1000dev = pInfo->pFt1000Dev;
1325
1326 //DEBUG ("ft1000_close: netdev->refcnt=%d\n", net->refcnt);
bf3146c8 1327
f7c1be0c 1328 ft1000dev->status |= FT1000_STATUS_CLOSING;
8e99c33d 1329
f7c1be0c 1330 //DEBUG("ft1000_close: calling usb_kill_urb \n");
f7c1be0c 1331
7cfd8a37 1332 DEBUG("ft1000_close: pInfo=%p, ft1000dev=%p\n", pInfo, ft1000dev);
f7c1be0c
MB
1333 netif_carrier_off(net);//mbelian
1334 netif_stop_queue(net);
1335 //DEBUG("ft1000_close: netif_stop_queue called\n");
1336 ft1000dev->status &= ~FT1000_STATUS_CLOSING;
1337
1338 pInfo->ProgConStat = 0xff; //mbelian
1339
1340
1341 return 0;
1342}
1343
1344static struct net_device_stats *ft1000_netdev_stats(struct net_device *dev)
1345{
e33196e1 1346 struct ft1000_info *info = netdev_priv(dev);
bf3146c8 1347
f7c1be0c
MB
1348 return &(info->stats); //mbelian
1349}
1350
1351
1352/*********************************************************************************
1353Jim
1354*/
1355
1356
1357//---------------------------------------------------------------------------
1358//
1359// Function: ft1000_chkcard
1360// Descripton: This function will check if the device is presently available on
1361// the system.
1362// Input:
1363// dev - device structure
1364// Output:
1365// status - FALSE (device is not present)
bf3146c8 1366// TRUE (device is present)
f7c1be0c
MB
1367//
1368//---------------------------------------------------------------------------
1369static int ft1000_chkcard (struct ft1000_device *dev) {
1370 u16 tempword;
1371 u16 status;
e33196e1 1372 struct ft1000_info *info = netdev_priv(dev->net);
bf3146c8 1373
f7c1be0c
MB
1374 if (info->fCondResetPend)
1375 {
1376 DEBUG("ft1000_hw:ft1000_chkcard:Card is being reset, return FALSE\n");
1377 return TRUE;
1378 }
bf3146c8 1379
f7c1be0c
MB
1380 // Mask register is used to check for device presence since it is never
1381 // set to zero.
1382 status = ft1000_read_register(dev, &tempword, FT1000_REG_SUP_IMASK);
1383 //DEBUG("ft1000_hw:ft1000_chkcard: read FT1000_REG_SUP_IMASK = %x\n", tempword);
1384 if (tempword == 0) {
1385 DEBUG("ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n");
1386 return FALSE;
1387 }
1388
1389 // The system will return the value of 0xffff for the version register
1390 // if the device is not present.
1391 status = ft1000_read_register(dev, &tempword, FT1000_REG_ASIC_ID);
1392 //DEBUG("ft1000_hw:ft1000_chkcard: read FT1000_REG_ASIC_ID = %x\n", tempword);
f7c1be0c
MB
1393 if (tempword != 0x1b01 ){
1394 dev->status |= FT1000_STATUS_CLOSING; //mbelian
1395 DEBUG("ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n");
1396 return FALSE;
1397 }
1398 return TRUE;
1399}
1400
f7c1be0c 1401
f7c1be0c
MB
1402
1403//---------------------------------------------------------------------------
1404//
1405// Function: ft1000_receive_cmd
bf3146c8 1406// Descripton: This function will read a message from the dpram area.
f7c1be0c
MB
1407// Input:
1408// dev - network device structure
1409// pbuffer - caller supply address to buffer
1410// pnxtph - pointer to next pseudo header
1411// Output:
1412// Status = 0 (unsuccessful)
1413// = 1 (successful)
1414//
1415//---------------------------------------------------------------------------
81584137 1416static bool ft1000_receive_cmd (struct ft1000_device *dev, u16 *pbuffer, int maxsz, u16 *pnxtph) {
f7c1be0c
MB
1417 u16 size, ret;
1418 u16 *ppseudohdr;
1419 int i;
1420 u16 tempword;
1421
e2cb7da1 1422 ret = ft1000_read_dpram16(dev, FT1000_MAG_PH_LEN, (u8 *)&size, FT1000_MAG_PH_LEN_INDX);
f7c1be0c
MB
1423 size = ntohs(size) + PSEUDOSZ;
1424 if (size > maxsz) {
1425 DEBUG("FT1000:ft1000_receive_cmd:Invalid command length = %d\n", size);
1426 return FALSE;
1427 }
1428 else {
1429 ppseudohdr = (u16 *)pbuffer;
f7c1be0c
MB
1430 ft1000_write_register(dev, FT1000_DPRAM_MAG_RX_BASE, FT1000_REG_DPRAM_ADDR);
1431 ret = ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH);
1432 //DEBUG("ft1000_hw:received data = 0x%x\n", *pbuffer);
bf3146c8 1433 pbuffer++;
f7c1be0c
MB
1434 ft1000_write_register(dev, FT1000_DPRAM_MAG_RX_BASE+1, FT1000_REG_DPRAM_ADDR);
1435 for (i=0; i<=(size>>2); i++) {
1436 ret = ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAL);
1437 pbuffer++;
1438 ret = ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH);
1439 pbuffer++;
1440 }
1441 //copy odd aligned word
1442 ret = ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAL);
1443 //DEBUG("ft1000_hw:received data = 0x%x\n", *pbuffer);
1444 pbuffer++;
1445 ret = ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH);
1446 //DEBUG("ft1000_hw:received data = 0x%x\n", *pbuffer);
1447 pbuffer++;
1448 if (size & 0x0001) {
1449 //copy odd byte from fifo
1450 ret = ft1000_read_register(dev, &tempword, FT1000_REG_DPRAM_DATA);
1451 *pbuffer = ntohs(tempword);
1452 }
f7c1be0c
MB
1453
1454 // Check if pseudo header checksum is good
1455 // Calculate pseudo header checksum
1456 tempword = *ppseudohdr++;
1457 for (i=1; i<7; i++) {
1458 tempword ^= *ppseudohdr++;
1459 }
1460 if ( (tempword != *ppseudohdr) ) {
1461 return FALSE;
1462 }
bf3146c8 1463
f7c1be0c
MB
1464 return TRUE;
1465 }
1466}
1467
1468
2a953cfd 1469static int ft1000_dsp_prov(void *arg)
f7c1be0c
MB
1470{
1471 struct ft1000_device *dev = (struct ft1000_device *)arg;
e33196e1 1472 struct ft1000_info *info = netdev_priv(dev->net);
f7c1be0c
MB
1473 u16 tempword;
1474 u16 len;
1475 u16 i=0;
e27d96dd 1476 struct prov_record *ptr;
b13e39b2 1477 struct pseudo_hdr *ppseudo_hdr;
d1674983 1478 u16 *pmsg;
f7c1be0c 1479 u16 status;
fc549a05 1480 u16 TempShortBuf [256];
f7c1be0c
MB
1481
1482 DEBUG("*** DspProv Entered\n");
1483
8e99c33d 1484 while (list_empty(&info->prov_list) == 0)
f7c1be0c
MB
1485 {
1486 DEBUG("DSP Provisioning List Entry\n");
1487
1488 // Check if doorbell is available
1489 DEBUG("check if doorbell is cleared\n");
1490 status = ft1000_read_register (dev, &tempword, FT1000_REG_DOORBELL);
1491 if (status)
1492 {
1493 DEBUG("ft1000_dsp_prov::ft1000_read_register error\n");
1494 break;
1495 }
1496
1497 while (tempword & FT1000_DB_DPRAM_TX) {
1498 mdelay(10);
1499 i++;
1500 if (i==10) {
1501 DEBUG("FT1000:ft1000_dsp_prov:message drop\n");
1502 return STATUS_FAILURE;
1503 }
1504 ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL);
1505 }
1506
1507 if ( !(tempword & FT1000_DB_DPRAM_TX) ) {
1508 DEBUG("*** Provision Data Sent to DSP\n");
bf3146c8 1509
f7c1be0c 1510 // Send provisioning data
e27d96dd 1511 ptr = list_entry(info->prov_list.next, struct prov_record, list);
f7c1be0c
MB
1512 len = *(u16 *)ptr->pprov_data;
1513 len = htons(len);
1514 len += PSEUDOSZ;
bf3146c8 1515
d1674983 1516 pmsg = (u16 *)ptr->pprov_data;
b13e39b2 1517 ppseudo_hdr = (struct pseudo_hdr *)pmsg;
f7c1be0c
MB
1518 // Insert slow queue sequence number
1519 ppseudo_hdr->seq_num = info->squeseqnum++;
1520 ppseudo_hdr->portsrc = 0;
1521 // Calculate new checksum
1522 ppseudo_hdr->checksum = *pmsg++;
1523 //DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum);
1524 for (i=1; i<7; i++) {
1525 ppseudo_hdr->checksum ^= *pmsg++;
1526 //DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum);
1527 }
bf3146c8 1528
f7c1be0c
MB
1529 TempShortBuf[0] = 0;
1530 TempShortBuf[1] = htons (len);
1531 memcpy(&TempShortBuf[2], ppseudo_hdr, len);
bf3146c8 1532
e2cb7da1 1533 status = ft1000_write_dpram32 (dev, 0, (u8 *)&TempShortBuf[0], (unsigned short)(len+2));
bf3146c8
GKH
1534 status = ft1000_write_register (dev, FT1000_DB_DPRAM_TX, FT1000_REG_DOORBELL);
1535
f7c1be0c
MB
1536 list_del(&ptr->list);
1537 kfree(ptr->pprov_data);
bf3146c8 1538 kfree(ptr);
f7c1be0c
MB
1539 }
1540 msleep(10);
1541 }
1542
1543 DEBUG("DSP Provisioning List Entry finished\n");
1544
1545 msleep(100);
bf3146c8 1546
f7c1be0c
MB
1547 info->fProvComplete = 1;
1548 info->CardReady = 1;
f7c1be0c 1549 return STATUS_SUCCESS;
bf3146c8 1550
f7c1be0c
MB
1551}
1552
bf3146c8 1553
2a953cfd 1554static int ft1000_proc_drvmsg (struct ft1000_device *dev, u16 size) {
e33196e1 1555 struct ft1000_info *info = netdev_priv(dev->net);
f7c1be0c
MB
1556 u16 msgtype;
1557 u16 tempword;
1b8a3012 1558 struct media_msg *pmediamsg;
369e857e 1559 struct dsp_init_msg *pdspinitmsg;
e09aee2a 1560 struct drv_msg *pdrvmsg;
f7c1be0c 1561 u16 i;
b13e39b2 1562 struct pseudo_hdr *ppseudo_hdr;
d1674983 1563 u16 *pmsg;
bf3146c8 1564 u16 status;
f7c1be0c
MB
1565 union {
1566 u8 byte[2];
1567 u16 wrd;
1568 } convert;
1569
bf3146c8 1570
2a953cfd
AB
1571 char *cmdbuffer = kmalloc(1600, GFP_KERNEL);
1572 if (!cmdbuffer)
1573 return STATUS_FAILURE;
bf3146c8 1574
2a953cfd 1575 status = ft1000_read_dpram32(dev, 0x200, cmdbuffer, size);
f7c1be0c 1576
bf3146c8 1577
bf3146c8
GKH
1578
1579#ifdef JDEBUG
f7c1be0c
MB
1580 DEBUG("ft1000_proc_drvmsg:cmdbuffer\n");
1581 for(i = 0; i < size; i+=5)
1582 {
bf3146c8
GKH
1583 if( (i + 5) < size )
1584 DEBUG("0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", cmdbuffer[i], cmdbuffer[i+1], cmdbuffer[i+2], cmdbuffer[i+3], cmdbuffer[i+4]);
f7c1be0c
MB
1585 else
1586 {
1587 for (j = i; j < size; j++)
bf3146c8
GKH
1588 DEBUG("0x%x ", cmdbuffer[j]);
1589 DEBUG("\n");
f7c1be0c
MB
1590 break;
1591 }
1592 }
bf3146c8 1593#endif
e09aee2a 1594 pdrvmsg = (struct drv_msg *)&cmdbuffer[2];
f7c1be0c
MB
1595 msgtype = ntohs(pdrvmsg->type);
1596 DEBUG("ft1000_proc_drvmsg:Command message type = 0x%x\n", msgtype);
1597 switch (msgtype) {
1598 case MEDIA_STATE: {
1599 DEBUG("ft1000_proc_drvmsg:Command message type = MEDIA_STATE");
bf3146c8 1600
1b8a3012 1601 pmediamsg = (struct media_msg *)&cmdbuffer[0];
f7c1be0c
MB
1602 if (info->ProgConStat != 0xFF) {
1603 if (pmediamsg->state) {
1604 DEBUG("Media is up\n");
1605 if (info->mediastate == 0) {
1606 if ( info->NetDevRegDone )
1607 {
1608 //netif_carrier_on(dev->net);//mbelian
bf3146c8 1609 netif_wake_queue(dev->net);
f7c1be0c 1610 }
bf3146c8 1611 info->mediastate = 1;
f7c1be0c
MB
1612 /*do_gettimeofday(&tv);
1613 info->ConTm = tv.tv_sec;*/ //mbelian
1614 }
1615 }
1616 else {
1617 DEBUG("Media is down\n");
1618 if (info->mediastate == 1) {
1619 info->mediastate = 0;
1620 if ( info->NetDevRegDone )
1621 {
1622 //netif_carrier_off(dev->net); mbelian
1623 //netif_stop_queue(dev->net);
1624 }
1625 info->ConTm = 0;
1626 }
1627 }
1628 }
1629 else {
1630 DEBUG("Media is down\n");
1631 if (info->mediastate == 1) {
1632 info->mediastate = 0;
bf3146c8 1633 if ( info->NetDevRegDone)
f7c1be0c
MB
1634 {
1635 //netif_carrier_off(dev->net); //mbelian
1636 //netif_stop_queue(dev->net);
1637 }
1638 info->ConTm = 0;
1639 }
1640 }
1641 break;
1642 }
1643 case DSP_INIT_MSG: {
1644 DEBUG("ft1000_proc_drvmsg:Command message type = DSP_INIT_MSG");
bf3146c8 1645
369e857e 1646 pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[2];
f7c1be0c
MB
1647 memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ);
1648 DEBUG("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", info->DspVer[0], info->DspVer[1], info->DspVer[2], info->DspVer[3]);
1649 memcpy(info->HwSerNum, pdspinitmsg->HwSerNum, HWSERNUMSZ);
1650 memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ);
1651 memcpy(info->eui64, pdspinitmsg->eui64, EUISZ);
1652 DEBUG("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n", info->eui64[0],info->eui64[1], info->eui64[2], info->eui64[3], info->eui64[4], info->eui64[5],info->eui64[6], info->eui64[7]);
1653 dev->net->dev_addr[0] = info->eui64[0];
1654 dev->net->dev_addr[1] = info->eui64[1];
1655 dev->net->dev_addr[2] = info->eui64[2];
1656 dev->net->dev_addr[3] = info->eui64[5];
1657 dev->net->dev_addr[4] = info->eui64[6];
1658 dev->net->dev_addr[5] = info->eui64[7];
bf3146c8 1659
369e857e 1660 if (ntohs(pdspinitmsg->length) == (sizeof(struct dsp_init_msg) - 20)) {
f7c1be0c
MB
1661 memcpy(info->ProductMode, pdspinitmsg->ProductMode, MODESZ);
1662 memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, CALVERSZ);
1663 memcpy(info->RfCalDate, pdspinitmsg->RfCalDate, CALDATESZ);
1664 DEBUG("RFCalVer = 0x%2x 0x%2x\n", info->RfCalVer[0], info->RfCalVer[1]);
1665 }
1666 break;
1667 }
1668 case DSP_PROVISION: {
1669 DEBUG("ft1000_proc_drvmsg:Command message type = DSP_PROVISION\n");
bf3146c8 1670
f7c1be0c
MB
1671 // kick off dspprov routine to start provisioning
1672 // Send provisioning data to DSP
bf3146c8 1673 if (list_empty(&info->prov_list) == 0)
f7c1be0c
MB
1674 {
1675 info->fProvComplete = 0;
1676 status = ft1000_dsp_prov(dev);
1677 if (status != STATUS_SUCCESS)
2a953cfd 1678 goto out;
f7c1be0c
MB
1679 }
1680 else {
1681 info->fProvComplete = 1;
1682 status = ft1000_write_register (dev, FT1000_DB_HB, FT1000_REG_DOORBELL);
1683 DEBUG("FT1000:drivermsg:No more DSP provisioning data in dsp image\n");
1684 }
1685 DEBUG("ft1000_proc_drvmsg:DSP PROVISION is done\n");
1686 break;
1687 }
1688 case DSP_STORE_INFO: {
1689 DEBUG("ft1000_proc_drvmsg:Command message type = DSP_STORE_INFO");
bf3146c8 1690
f7c1be0c
MB
1691 DEBUG("FT1000:drivermsg:Got DSP_STORE_INFO\n");
1692 tempword = ntohs(pdrvmsg->length);
1693 info->DSPInfoBlklen = tempword;
1694 if (tempword < (MAX_DSP_SESS_REC-4) ) {
d1674983 1695 pmsg = (u16 *)&pdrvmsg->data[0];
f7c1be0c
MB
1696 for (i=0; i<((tempword+1)/2); i++) {
1697 DEBUG("FT1000:drivermsg:dsp info data = 0x%x\n", *pmsg);
1698 info->DSPInfoBlk[i+10] = *pmsg++;
1699 }
1700 }
1701 else {
1702 info->DSPInfoBlklen = 0;
1703 }
1704 break;
1705 }
1706 case DSP_GET_INFO: {
1707 DEBUG("FT1000:drivermsg:Got DSP_GET_INFO\n");
1708 // copy dsp info block to dsp
1709 info->DrvMsgPend = 1;
1710 // allow any outstanding ioctl to finish
1711 mdelay(10);
1712 status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL);
1713 if (tempword & FT1000_DB_DPRAM_TX) {
1714 mdelay(10);
1715 status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL);
1716 if (tempword & FT1000_DB_DPRAM_TX) {
1717 mdelay(10);
1718 status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL);
1719 if (tempword & FT1000_DB_DPRAM_TX) {
1720 break;
1721 }
bf3146c8 1722 }
f7c1be0c 1723 }
bf3146c8 1724
f7c1be0c
MB
1725 // Put message into Slow Queue
1726 // Form Pseudo header
d1674983 1727 pmsg = (u16 *)info->DSPInfoBlk;
f7c1be0c 1728 *pmsg++ = 0;
bf3146c8 1729 *pmsg++ = htons(info->DSPInfoBlklen+20+info->DSPInfoBlklen);
d1674983 1730 ppseudo_hdr = (struct pseudo_hdr *)(u16 *)&info->DSPInfoBlk[2];
f7c1be0c 1731 ppseudo_hdr->length = htons(info->DSPInfoBlklen+4+info->DSPInfoBlklen);
bf3146c8 1732 ppseudo_hdr->source = 0x10;
f7c1be0c
MB
1733 ppseudo_hdr->destination = 0x20;
1734 ppseudo_hdr->portdest = 0;
1735 ppseudo_hdr->portsrc = 0;
1736 ppseudo_hdr->sh_str_id = 0;
1737 ppseudo_hdr->control = 0;
1738 ppseudo_hdr->rsvd1 = 0;
1739 ppseudo_hdr->rsvd2 = 0;
1740 ppseudo_hdr->qos_class = 0;
1741 // Insert slow queue sequence number
1742 ppseudo_hdr->seq_num = info->squeseqnum++;
bf3146c8 1743 // Insert application id
f7c1be0c
MB
1744 ppseudo_hdr->portsrc = 0;
1745 // Calculate new checksum
1746 ppseudo_hdr->checksum = *pmsg++;
1747 for (i=1; i<7; i++) {
1748 ppseudo_hdr->checksum ^= *pmsg++;
1749 }
1750 info->DSPInfoBlk[10] = 0x7200;
1751 info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen);
e2cb7da1 1752 status = ft1000_write_dpram32 (dev, 0, (u8 *)&info->DSPInfoBlk[0], (unsigned short)(info->DSPInfoBlklen+22));
bf3146c8 1753 status = ft1000_write_register (dev, FT1000_DB_DPRAM_TX, FT1000_REG_DOORBELL);
f7c1be0c 1754 info->DrvMsgPend = 0;
bf3146c8 1755
f7c1be0c
MB
1756 break;
1757 }
bf3146c8 1758
f7c1be0c
MB
1759 case GET_DRV_ERR_RPT_MSG: {
1760 DEBUG("FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n");
1761 // copy driver error message to dsp
1762 info->DrvMsgPend = 1;
1763 // allow any outstanding ioctl to finish
1764 mdelay(10);
1765 status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL);
1766 if (tempword & FT1000_DB_DPRAM_TX) {
1767 mdelay(10);
1768 status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL);
1769 if (tempword & FT1000_DB_DPRAM_TX) {
1770 mdelay(10);
bf3146c8 1771 }
f7c1be0c 1772 }
bf3146c8 1773
f7c1be0c
MB
1774 if ( (tempword & FT1000_DB_DPRAM_TX) == 0) {
1775 // Put message into Slow Queue
1776 // Form Pseudo header
d1674983 1777 pmsg = (u16 *)&tempbuffer[0];
b13e39b2 1778 ppseudo_hdr = (struct pseudo_hdr *)pmsg;
f7c1be0c 1779 ppseudo_hdr->length = htons(0x0012);
bf3146c8 1780 ppseudo_hdr->source = 0x10;
f7c1be0c
MB
1781 ppseudo_hdr->destination = 0x20;
1782 ppseudo_hdr->portdest = 0;
1783 ppseudo_hdr->portsrc = 0;
1784 ppseudo_hdr->sh_str_id = 0;
1785 ppseudo_hdr->control = 0;
1786 ppseudo_hdr->rsvd1 = 0;
1787 ppseudo_hdr->rsvd2 = 0;
1788 ppseudo_hdr->qos_class = 0;
1789 // Insert slow queue sequence number
1790 ppseudo_hdr->seq_num = info->squeseqnum++;
bf3146c8 1791 // Insert application id
f7c1be0c
MB
1792 ppseudo_hdr->portsrc = 0;
1793 // Calculate new checksum
1794 ppseudo_hdr->checksum = *pmsg++;
1795 for (i=1; i<7; i++) {
1796 ppseudo_hdr->checksum ^= *pmsg++;
1797 }
d1674983 1798 pmsg = (u16 *)&tempbuffer[16];
f7c1be0c
MB
1799 *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG);
1800 *pmsg++ = htons(0x000e);
1801 *pmsg++ = htons(info->DSP_TIME[0]);
1802 *pmsg++ = htons(info->DSP_TIME[1]);
1803 *pmsg++ = htons(info->DSP_TIME[2]);
1804 *pmsg++ = htons(info->DSP_TIME[3]);
1805 convert.byte[0] = info->DspVer[0];
1806 convert.byte[1] = info->DspVer[1];
1807 *pmsg++ = convert.wrd;
1808 convert.byte[0] = info->DspVer[2];
1809 convert.byte[1] = info->DspVer[3];
1810 *pmsg++ = convert.wrd;
1811 *pmsg++ = htons(info->DrvErrNum);
1812
a209efad 1813 card_send_command (dev, (unsigned char*)&tempbuffer[0], (u16)(0x0012 + PSEUDOSZ));
f7c1be0c
MB
1814 info->DrvErrNum = 0;
1815 }
1816 info->DrvMsgPend = 0;
bf3146c8
GKH
1817
1818 break;
f7c1be0c 1819 }
bf3146c8 1820
f7c1be0c 1821 default:
bf3146c8 1822 break;
f7c1be0c
MB
1823 }
1824
f7c1be0c 1825
2a953cfd
AB
1826 status = STATUS_SUCCESS;
1827out:
1828 kfree(cmdbuffer);
f7c1be0c 1829 DEBUG("return from ft1000_proc_drvmsg\n");
2a953cfd 1830 return status;
f7c1be0c
MB
1831}
1832
1833
1834
1835int ft1000_poll(void* dev_id) {
bf3146c8 1836
f7c1be0c 1837 struct ft1000_device *dev = (struct ft1000_device *)dev_id;
e33196e1 1838 struct ft1000_info *info = netdev_priv(dev->net);
bf3146c8 1839
f7c1be0c
MB
1840 u16 tempword;
1841 u16 status;
1842 u16 size;
1843 int i;
fc549a05
MB
1844 u16 data;
1845 u16 modulo;
1846 u16 portid;
f7c1be0c 1847 u16 nxtph;
29437ab0 1848 struct dpram_blk *pdpram_blk;
b13e39b2 1849 struct pseudo_hdr *ppseudo_hdr;
f7c1be0c 1850 unsigned long flags;
bf3146c8 1851
f7c1be0c
MB
1852 //DEBUG("Enter ft1000_poll...\n");
1853 if (ft1000_chkcard(dev) == FALSE) {
1854 DEBUG("ft1000_poll::ft1000_chkcard: failed\n");
1855 return STATUS_FAILURE;
1856 }
1857
1858 status = ft1000_read_register (dev, &tempword, FT1000_REG_DOORBELL);
1859 // DEBUG("ft1000_poll: read FT1000_REG_DOORBELL message 0x%x\n", tempword);
1860
bf3146c8
GKH
1861 if ( !status )
1862 {
1863
f7c1be0c
MB
1864 if (tempword & FT1000_DB_DPRAM_RX) {
1865 //DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX\n");
bf3146c8 1866
e2cb7da1 1867 status = ft1000_read_dpram16(dev, 0x200, (u8 *)&data, 0);
f7c1be0c
MB
1868 //DEBUG("ft1000_poll:FT1000_DB_DPRAM_RX:ft1000_read_dpram16:size = 0x%x\n", data);
1869 size = ntohs(data) + 16 + 2; //wai
1870 if (size % 4) {
1871 modulo = 4 - (size % 4);
1872 size = size + modulo;
bf3146c8 1873 }
e2cb7da1 1874 status = ft1000_read_dpram16(dev, 0x201, (u8 *)&portid, 1);
f7c1be0c
MB
1875 portid &= 0xff;
1876 //DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid 0x%x\n", portid);
bf3146c8 1877
f7c1be0c 1878 if (size < MAX_CMD_SQSIZE) {
bf3146c8 1879 switch (portid)
f7c1be0c
MB
1880 {
1881 case DRIVERID:
1882 DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DRIVERID\n");
bf3146c8 1883
f7c1be0c
MB
1884 status = ft1000_proc_drvmsg (dev, size);
1885 if (status != STATUS_SUCCESS )
1886 return status;
1887 break;
1888 case DSPBCMSGID:
1889 // This is a dsp broadcast message
bf3146c8 1890 // Check which application has registered for dsp broadcast messages
f7c1be0c 1891 //DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DSPBCMSGID\n");
bf3146c8 1892
f7c1be0c 1893 for (i=0; i<MAX_NUM_APP; i++) {
bf3146c8
GKH
1894 if ( (info->app_info[i].DspBCMsgFlag) && (info->app_info[i].fileobject) &&
1895 (info->app_info[i].NumOfMsg < MAX_MSG_LIMIT) )
f7c1be0c
MB
1896 {
1897 //DEBUG("Dsp broadcast message detected for app id %d\n", i);
1898 nxtph = FT1000_DPRAM_RX_BASE + 2;
1899 pdpram_blk = ft1000_get_buffer (&freercvpool);
1900 if (pdpram_blk != NULL) {
1901 if ( ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE, &nxtph) ) {
b13e39b2 1902 ppseudo_hdr = (struct pseudo_hdr *)pdpram_blk->pbuffer;
f7c1be0c
MB
1903 // Put message into the appropriate application block
1904 info->app_info[i].nRxMsg++;
1905 spin_lock_irqsave(&free_buff_lock, flags);
1906 list_add_tail(&pdpram_blk->list, &info->app_info[i].app_sqlist);
1907 info->app_info[i].NumOfMsg++;
1908 spin_unlock_irqrestore(&free_buff_lock, flags);
1909 wake_up_interruptible(&info->app_info[i].wait_dpram_msg);
1910 }
1911 else {
1912 info->app_info[i].nRxMsgMiss++;
1913 // Put memory back to free pool
1914 ft1000_free_buffer(pdpram_blk, &freercvpool);
1915 DEBUG("pdpram_blk::ft1000_get_buffer NULL\n");
1916 }
1917 }
1918 else {
1919 DEBUG("Out of memory in free receive command pool\n");
1920 info->app_info[i].nRxMsgMiss++;
1921 }//endof if (pdpram_blk != NULL)
bf3146c8 1922 }//endof if
f7c1be0c
MB
1923 //else
1924 // DEBUG("app_info mismatch\n");
1925 }// endof for
1926 break;
1927 default:
1928 pdpram_blk = ft1000_get_buffer (&freercvpool);
1929 //DEBUG("Memory allocated = 0x%8x\n", (u32)pdpram_blk);
1930 if (pdpram_blk != NULL) {
1931 if ( ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE, &nxtph) ) {
b13e39b2 1932 ppseudo_hdr = (struct pseudo_hdr *)pdpram_blk->pbuffer;
f7c1be0c
MB
1933 // Search for correct application block
1934 for (i=0; i<MAX_NUM_APP; i++) {
1935 if (info->app_info[i].app_id == ppseudo_hdr->portdest) {
1936 break;
1937 }
1938 }
1939
fcbf77bf 1940 if (i == MAX_NUM_APP) {
f7c1be0c
MB
1941 DEBUG("FT1000:ft1000_parse_dpram_msg: No application matching id = %d\n", ppseudo_hdr->portdest);
1942 // Put memory back to free pool
1943 ft1000_free_buffer(pdpram_blk, &freercvpool);
1944 }
1945 else {
1946 if (info->app_info[i].NumOfMsg > MAX_MSG_LIMIT) {
1947 // Put memory back to free pool
1948 ft1000_free_buffer(pdpram_blk, &freercvpool);
1949 }
1950 else {
1951 info->app_info[i].nRxMsg++;
1952 // Put message into the appropriate application block
1953 //pxu spin_lock_irqsave(&free_buff_lock, flags);
1954 list_add_tail(&pdpram_blk->list, &info->app_info[i].app_sqlist);
1955 info->app_info[i].NumOfMsg++;
1956 //pxu spin_unlock_irqrestore(&free_buff_lock, flags);
1957 //pxu wake_up_interruptible(&info->app_info[i].wait_dpram_msg);
1958 }
1959 }
1960 }
1961 else {
1962 // Put memory back to free pool
1963 ft1000_free_buffer(pdpram_blk, &freercvpool);
1964 }
1965 }
1966 else {
1967 DEBUG("Out of memory in free receive command pool\n");
1968 }
1969 break;
1970 } //end of switch
1971 } //endof if (size < MAX_CMD_SQSIZE)
1972 else {
1973 DEBUG("FT1000:dpc:Invalid total length for SlowQ = %d\n", size);
1974 }
bf3146c8 1975 status = ft1000_write_register (dev, FT1000_DB_DPRAM_RX, FT1000_REG_DOORBELL);
f7c1be0c
MB
1976 }
1977 else if (tempword & FT1000_DSP_ASIC_RESET) {
1978 //DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DSP_ASIC_RESET\n");
1979
1980 // Let's reset the ASIC from the Host side as well
1981 status = ft1000_write_register (dev, ASIC_RESET_BIT, FT1000_REG_RESET);
1982 status = ft1000_read_register (dev, &tempword, FT1000_REG_RESET);
1983 i = 0;
1984 while (tempword & ASIC_RESET_BIT) {
1985 status = ft1000_read_register (dev, &tempword, FT1000_REG_RESET);
1986 msleep(10);
1987 i++;
1988 if (i==100)
1989 break;
1990 }
1991 if (i==100) {
1992 DEBUG("Unable to reset ASIC\n");
1993 return STATUS_SUCCESS;
1994 }
1995 msleep(10);
1996 // Program WMARK register
1997 status = ft1000_write_register (dev, 0x600, FT1000_REG_MAG_WATERMARK);
1998 // clear ASIC reset doorbell
1999 status = ft1000_write_register (dev, FT1000_DSP_ASIC_RESET, FT1000_REG_DOORBELL);
2000 msleep(10);
2001 }
2002 else if (tempword & FT1000_ASIC_RESET_REQ) {
2003 DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_ASIC_RESET_REQ\n");
bf3146c8 2004
f7c1be0c
MB
2005 // clear ASIC reset request from DSP
2006 status = ft1000_write_register (dev, FT1000_ASIC_RESET_REQ, FT1000_REG_DOORBELL);
2007 status = ft1000_write_register (dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL);
2008 // copy dsp session record from Adapter block
e2cb7da1 2009 status = ft1000_write_dpram32 (dev, 0, (u8 *)&info->DSPSess.Rec[0], 1024);
f7c1be0c
MB
2010 // Program WMARK register
2011 status = ft1000_write_register (dev, 0x600, FT1000_REG_MAG_WATERMARK);
bf3146c8 2012 // ring doorbell to tell DSP that ASIC is out of reset
f7c1be0c 2013 status = ft1000_write_register (dev, FT1000_ASIC_RESET_DSP, FT1000_REG_DOORBELL);
bf3146c8 2014 }
f7c1be0c 2015 else if (tempword & FT1000_DB_COND_RESET) {
bf3146c8 2016 DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_COND_RESET\n");
f7c1be0c 2017//By Jim
bf3146c8 2018// Reset ASIC and DSP
f7c1be0c
MB
2019//MAG
2020 if (info->fAppMsgPend == 0) {
bf3146c8
GKH
2021 // Reset ASIC and DSP
2022
e2cb7da1
MB
2023 status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER0, (u8 *)&(info->DSP_TIME[0]), FT1000_MAG_DSP_TIMER0_INDX);
2024 status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER1, (u8 *)&(info->DSP_TIME[1]), FT1000_MAG_DSP_TIMER1_INDX);
2025 status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER2, (u8 *)&(info->DSP_TIME[2]), FT1000_MAG_DSP_TIMER2_INDX);
2026 status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER3, (u8 *)&(info->DSP_TIME[3]), FT1000_MAG_DSP_TIMER3_INDX);
bf3146c8 2027 info->CardReady = 0;
f7c1be0c
MB
2028 info->DrvErrNum = DSP_CONDRESET_INFO;
2029 DEBUG("ft1000_hw:DSP conditional reset requested\n");
2030 info->ft1000_reset(dev->net);
2031 }
2032 else {
2033 info->fProvComplete = 0;
2034 info->fCondResetPend = 1;
2035 }
bf3146c8
GKH
2036
2037 ft1000_write_register(dev, FT1000_DB_COND_RESET, FT1000_REG_DOORBELL);
f7c1be0c 2038 }
bf3146c8 2039
f7c1be0c
MB
2040 }//endof if ( !status )
2041
2042 //DEBUG("return from ft1000_poll.\n");
2043 return STATUS_SUCCESS;
2044
2045}
2046
2047/*end of Jim*/
This page took 0.170953 seconds and 5 git commands to generate.