staging: ft1000: remove obsolete driver

Remove support for Qleadtek Flash-OFDM modems. Telecom carrier is
discontinuing service for the radio technology.
See http://www.gtigroup.org/news/ind/2015-08-18/6996.html.

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Deepa Dinamani 2015-10-21 18:42:37 -07:00 committed by Greg Kroah-Hartman
parent eb96c7fc24
commit 6512edec48
21 changed files with 0 additions and 7578 deletions

View File

@ -62,8 +62,6 @@ source "drivers/staging/xgifb/Kconfig"
source "drivers/staging/emxx_udc/Kconfig"
source "drivers/staging/ft1000/Kconfig"
source "drivers/staging/speakup/Kconfig"
source "drivers/staging/ste_rmi4/Kconfig"

View File

@ -25,7 +25,6 @@ obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_FB_SM750) += sm750fb/
obj-$(CONFIG_FB_XGI) += xgifb/
obj-$(CONFIG_USB_EMXX) += emxx_udc/
obj-$(CONFIG_FT1000) += ft1000/
obj-$(CONFIG_SPEAKUP) += speakup/
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/
obj-$(CONFIG_MFD_NVEC) += nvec/

View File

@ -1,22 +0,0 @@
config FT1000
tristate "Drivers for Flarion ft1000 devices"
if FT1000
config FT1000_USB
tristate "Driver for ft1000 usb devices."
depends on USB
depends on NET
help
Say Y if you want to have support for Qleadtek FLASH-OFDM USB Modem [LR7F04],
Qleadtek Express Card or Leadtek Multi-band modem HSDPA.
config FT1000_PCMCIA
tristate "Driver for ft1000 pcmcia device."
depends on PCMCIA
depends on NET
help
Say Y if you want to have support for Flarion card also called
Multimedia Net Card.
endif

View File

@ -1,3 +0,0 @@
obj-$(CONFIG_FT1000_USB) += ft1000-usb/
obj-$(CONFIG_FT1000_PCMCIA) += ft1000-pcmcia/

View File

@ -1,9 +0,0 @@
TODO:
- checkpatch.pl cleanups
- coding style
- sparse fixes
- adapt to latest usb and pcmcia api changes
- change firmware loading for usb driver to proper kernel method (request_firmware)
Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
Cc: Marek Belisko <marek.belisko@gmail.com>

View File

@ -1,2 +0,0 @@
obj-$(CONFIG_FT1000_PCMCIA) = ft1000_pcmcia.o
ft1000_pcmcia-y := ft1000_hw.o ft1000_dnld.o ft1000_cs.o

View File

@ -1,158 +0,0 @@
/*---------------------------------------------------------------------------
FT1000 driver for Flarion Flash OFDM NIC Device
Copyright (C) 2002 Flarion Technologies, All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option) any
later version. This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License along with this program; if not, write to the
Free Software Foundation, Inc., 59 Temple Place -
Suite 330, Boston, MA 02111-1307, USA.
---------------------------------------------------------------------------
File: boot.h
Description: boatloader
History:
1/11/05 Whc Ported to Linux.
---------------------------------------------------------------------------*/
#ifndef _BOOTH_
#define _BOOTH_
/* Official bootloader */
static unsigned char bootimage[] = {
0x00, 0x00, 0x01, 0x5E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0xD7,
0x00, 0x00, 0x01, 0x5E, 0x46, 0xB3,
0xE6, 0x02, 0x00, 0x98, 0xE6, 0x8C,
0x00, 0x98, 0xFB, 0x92, 0xFF, 0xFF,
0x98, 0xFB, 0x94, 0xFF, 0xFF, 0x98,
0xFB, 0x06, 0x08, 0x00, 0x98, 0xFB,
0x96, 0x84, 0x00, 0x98, 0xFB, 0x08,
0x1C, 0x00, 0x98, 0xFB, 0x51, 0x25,
0x10, 0x1C, 0x00, 0xE6, 0x51, 0x01,
0x07, 0xFD, 0x4C, 0xFF, 0x20, 0xF5,
0x51, 0x02, 0x20, 0x08, 0x00, 0x4C,
0xFF, 0x20, 0x3C, 0x00, 0xC0, 0x64,
0x98, 0xC0, 0x66, 0x98, 0xC0, 0x68,
0x98, 0xC0, 0x6A, 0x98, 0xC0, 0x6C,
0x98, 0x90, 0x08, 0x90, 0x09, 0x90,
0x0A, 0x90, 0x0B, 0x90, 0x0C, 0x90,
0x0D, 0x90, 0x0E, 0x90, 0x0F, 0x90,
0x04, 0x90, 0x06, 0xFB, 0x51, 0x22,
0x16, 0x08, 0x03, 0xFB, 0x51, 0x52,
0x16, 0x08, 0x04, 0xFB, 0x51, 0x24,
0x2B, 0x08, 0x06, 0xFB, 0x51, 0x54,
0x2B, 0x08, 0x07, 0xFB, 0x51, 0x24,
0x2B, 0x08, 0x09, 0xFB, 0x51, 0x54,
0x2B, 0x08, 0x0A, 0xFB, 0x51, 0x12,
0x16, 0x08, 0x0C, 0xFB, 0x51, 0x52,
0x16, 0x08, 0x0D, 0x78, 0x00, 0x00,
0x00, 0x16, 0x00, 0x00, 0xEC, 0x31,
0xAE, 0x00, 0x00, 0x81, 0x4C, 0x0F,
0xE6, 0x43, 0xFF, 0xEC, 0x31, 0x4E,
0x00, 0x00, 0x91, 0xEC, 0x31, 0xAE,
0x00, 0x00, 0x91, 0x4C, 0x0F, 0xE6,
0x43, 0xFF, 0xEC, 0x31, 0x5E, 0x00,
0x00, 0xA1, 0xEB, 0x31, 0x08, 0x00,
0x00, 0xA6, 0xEB, 0x31, 0x08, 0x00,
0x00, 0xAC, 0x3C, 0x00, 0xEB, 0x31,
0x08, 0x00, 0x00, 0xA8, 0x76, 0xFE,
0xFE, 0x08, 0xEB, 0x31, 0x08, 0x20,
0x00, 0x00, 0x76, 0xFF, 0xFF, 0x18,
0xED, 0x31, 0x08, 0x20, 0x00, 0x00,
0x26, 0x10, 0x04, 0x10, 0xF5, 0x3C,
0x01, 0x3C, 0x00, 0x08, 0x01, 0x12,
0x3C, 0x11, 0x3C, 0x00, 0x08, 0x01,
0x0B, 0x08, 0x00, 0x6D, 0xEC, 0x31,
0xAE, 0x20, 0x00, 0x06, 0xED, 0x4D,
0x08, 0x00, 0x00, 0x67, 0x80, 0x6F,
0x00, 0x01, 0x0B, 0x6F, 0x00, 0x02,
0x2E, 0x76, 0xEE, 0x01, 0x48, 0x06,
0x01, 0x39, 0xED, 0x4D, 0x18, 0x00,
0x02, 0xED, 0x4D, 0x08, 0x00, 0x04,
0x14, 0x06, 0xA4, 0xED, 0x31, 0x22,
0x00, 0x00, 0xAC, 0x76, 0xEE, 0x07,
0x48, 0x6D, 0x22, 0x01, 0x1E, 0x08,
0x01, 0x58, 0xEB, 0x31, 0x08, 0x00,
0x00, 0xAC, 0x06, 0xFF, 0xBA, 0x3C,
0x00, 0xEB, 0x31, 0x08, 0x20, 0x00,
0x04, 0x3C, 0x30, 0xEB, 0x31, 0x08,
0x20, 0x00, 0x02, 0x3C, 0x10, 0xEB,
0x31, 0x08, 0x20, 0x00, 0x00, 0xED,
0x31, 0x08, 0x20, 0x00, 0x00, 0x04,
0x10, 0xF7, 0xED, 0x31, 0x08, 0x00,
0x00, 0xA2, 0x91, 0x00, 0x9C, 0x3C,
0x80, 0xEB, 0x31, 0x08, 0x20, 0x00,
0x04, 0x3C, 0x20, 0xEB, 0x31, 0x08,
0x20, 0x00, 0x02, 0x3C, 0x10, 0xEB,
0x31, 0x08, 0x20, 0x00, 0x00, 0xED,
0x31, 0x08, 0x20, 0x00, 0x00, 0x04,
0x10, 0xF7, 0xED, 0x31, 0x08, 0x20,
0x00, 0x04, 0x42, 0x10, 0x90, 0x08,
0xEC, 0x31, 0xAE, 0x20, 0x00, 0x06,
0xA4, 0x41, 0x08, 0x00, 0xB6, 0xED,
0x41, 0x28, 0x7D, 0xFF, 0xFF, 0x22,
0xB3, 0x40, 0x98, 0x2A, 0x32, 0xEB,
0x41, 0x28, 0xB4, 0x43, 0xFC, 0x05,
0xFF, 0xE6, 0xA0, 0x31, 0x20, 0x00,
0x06, 0xEB, 0x31, 0x08, 0x20, 0x00,
0x04, 0x3C, 0x20, 0xEB, 0x31, 0x08,
0x20, 0x00, 0x02, 0x3C, 0x10, 0xEB,
0x31, 0x08, 0x20, 0x00, 0x00, 0xED,
0x31, 0x08, 0x20, 0x00, 0x00, 0x04,
0x10, 0xF7, 0xED, 0x31, 0x08, 0x20,
0x00, 0x04, 0x42, 0x10, 0x90, 0x08,
0xEC, 0x31, 0xAE, 0x20, 0x00, 0x06,
0xA4, 0x41, 0x08, 0x00, 0x68, 0xED,
0x41, 0x28, 0x7D, 0xFF, 0xFF, 0x22,
0xB3, 0x40, 0x98, 0x2A, 0x32, 0xEB,
0x41, 0x28, 0xB4, 0x43, 0xFC, 0x05,
0xFF, 0xE6, 0x48, 0x04, 0xEB, 0x31,
0x08, 0x20, 0x00, 0x04, 0xEB, 0x31,
0x18, 0x20, 0x00, 0x02, 0x3C, 0x11,
0xEB, 0x31, 0x18, 0x20, 0x00, 0x00,
0xED, 0x31, 0x08, 0x20, 0x00, 0x00,
0x04, 0x10, 0xF7, 0xED, 0x31, 0x08,
0x20, 0x00, 0x02, 0x66, 0x00, 0x6F,
0x00, 0x01, 0x16, 0x76, 0xEE, 0x06,
0x48, 0x4A, 0x1E, 0x48, 0x04, 0xED,
0x31, 0x08, 0x20, 0x00, 0x04, 0xEB,
0x31, 0x08, 0x00, 0x00, 0xA4, 0x48,
0x04, 0xED, 0x31, 0x08, 0x20, 0x00,
0x04, 0xEB, 0x31, 0x08, 0x00, 0x00,
0xA2, 0x48, 0x04, 0x20, 0x20, 0x4A,
0x7C, 0x46, 0x82, 0x50, 0x05, 0x50,
0x15, 0xB5, 0x1E, 0x98, 0xED, 0x31,
0x08, 0x00, 0x00, 0xA8, 0x10, 0x47,
0x3B, 0x2C, 0x01, 0xDB, 0x40, 0x11,
0x98, 0xC1, 0x1E, 0x98, 0x10, 0x07,
0x30, 0xF9, 0x40, 0x07, 0x18, 0x98,
0x2A, 0x10, 0xEB, 0x31, 0x08, 0x00,
0x00, 0xA8, 0xA4, 0x1E, 0x98, 0xBB,
0x1E, 0x98, 0x50, 0x14, 0x50, 0x04,
0x46, 0x83, 0x48, 0x04, 0x02, 0x01,
0x00, 0x50, 0x05, 0x50, 0x15, 0x10,
0x87, 0x3F, 0x90, 0x2B, 0x18, 0x01,
0x00, 0xC0, 0x31, 0x00, 0x00, 0xAE,
0xDF, 0x41, 0x00, 0x08, 0x00, 0x1A,
0x42, 0x11, 0x67, 0x01, 0xDF, 0x41,
0x02, 0x08, 0x00, 0x10, 0x42, 0x11,
0x62, 0x01, 0xB4, 0x43, 0x4A, 0x68,
0x50, 0x14, 0x50, 0x04, 0x24, 0x10,
0x48, 0x04, 0xF2, 0x31, 0x00, 0x01,
0x00, 0x00, 0xAE, 0xF6, 0x31, 0x00,
0x01, 0x00, 0x00, 0xAE, 0x62, 0xE4,
0xE5, 0x61, 0x04, 0x48, 0x04, 0xE5,
0x63, 0x05, 0x48, 0x04, 0x20, 0x20,
0x00, 0x00, 0x00, 0x00
};
#endif

View File

@ -1,70 +0,0 @@
/*---------------------------------------------------------------------------
FT1000 driver for Flarion Flash OFDM NIC Device
Copyright (C) 2002 Flarion Technologies, All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option) any
later version. This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License along with this program; if not, write to the
Free Software Foundation, Inc., 59 Temple Place -
Suite 330, Boston, MA 02111-1307, USA.
---------------------------------------------------------------------------
Description: Common structures and defines
---------------------------------------------------------------------------*/
#ifndef _FT1000H_
#define _FT1000H_
#include "../ft1000.h"
#define FT1000_DRV_VER 0x01010300
#define FT1000_DPRAM_BASE 0x0000 /* Dual Port RAM starting offset */
/*
* Maximum number of occurrence of pseudo header errors before resetting PC
* Card.
*/
#define MAX_PH_ERR 300
#define SUCCESS 0x00
#define FAILURE 0x01
struct ft1000_pcmcia {
int PktIntfErr;
u16 packetseqnum;
void *link;
};
struct pcmcia_device;
struct net_device;
struct net_device *init_ft1000_card(struct pcmcia_device *link,
void *ft1000_reset);
void stop_ft1000_card(struct net_device *dev);
int card_download(struct net_device *dev, const u8 *pFileStart,
size_t FileLength);
u16 ft1000_read_dpram(struct net_device *dev, int offset);
void card_bootload(struct net_device *dev);
u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index);
u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset);
void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value);
/* Read the value of a given ASIC register. */
static inline u16 ft1000_read_reg(struct net_device *dev, u16 offset)
{
return inw(dev->base_addr + offset);
}
/* Set the value of a given ASIC register. */
static inline void ft1000_write_reg(struct net_device *dev, u16 offset,
u16 value)
{
outw(value, dev->base_addr + offset);
}
#endif

View File

@ -1,158 +0,0 @@
/*---------------------------------------------------------------------------
FT1000 driver for Flarion Flash OFDM NIC Device
Copyright (C) 1999 David A. Hinds. All Rights Reserved.
Copyright (C) 2002 Flarion Technologies, All rights reserved.
Copyright (C) 2006 Patrik Ostrihon, All rights reserved.
Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved.
The initial developer of the original code is David A. Hinds
<dahinds@users.sourceforge.net>. Portions created by David A. Hinds.
This file was modified to support the Flarion Flash OFDM NIC Device
by Wai Chan (w.chan@flarion.com).
Port for kernel 2.6 created by Patrik Ostrihon (patrik.ostrihon@pwc.sk)
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option) any
later version. This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License along with this program; if not, write to the
Free Software Foundation, Inc., 59 Temple Place -
Suite 330, Boston, MA 02111-1307, USA.
-----------------------------------------------------------------------------*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
/*====================================================================*/
MODULE_AUTHOR("Wai Chan");
MODULE_DESCRIPTION("FT1000 PCMCIA driver");
MODULE_LICENSE("GPL");
/*====================================================================*/
static int ft1000_config(struct pcmcia_device *link);
static void ft1000_detach(struct pcmcia_device *link);
static int ft1000_attach(struct pcmcia_device *link);
#include "ft1000.h"
/*====================================================================*/
static void ft1000_reset(struct pcmcia_device *link)
{
pcmcia_reset_card(link->socket);
}
static int ft1000_attach(struct pcmcia_device *link)
{
link->priv = NULL;
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
return ft1000_config(link);
}
static void ft1000_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
if (dev)
stop_ft1000_card(dev);
pcmcia_disable_device(link);
free_netdev(dev);
}
static int ft1000_confcheck(struct pcmcia_device *link, void *priv_data)
{
return pcmcia_request_io(link);
}
/*======================================================================
ft1000_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
======================================================================*/
static int ft1000_config(struct pcmcia_device *link)
{
int ret;
dev_dbg(&link->dev, "ft1000_cs: ft1000_config(0x%p)\n", link);
/* setup IO window */
ret = pcmcia_loop_config(link, ft1000_confcheck, NULL);
if (ret) {
dev_err(&link->dev, "Could not configure pcmcia\n");
return -ENODEV;
}
/* configure device */
ret = pcmcia_enable_device(link);
if (ret) {
dev_err(&link->dev, "Could not enable pcmcia\n");
goto failed;
}
link->priv = init_ft1000_card(link, &ft1000_reset);
if (!link->priv) {
dev_err(&link->dev, "Could not register as network device\n");
goto failed;
}
/* Finally, report what we've done */
return 0;
failed:
pcmcia_disable_device(link);
return -ENODEV;
}
static int ft1000_suspend(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
if (link->open)
netif_device_detach(dev);
return 0;
}
static int ft1000_resume(struct pcmcia_device *link)
{
return 0;
}
/*====================================================================*/
static const struct pcmcia_device_id ft1000_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x0100),
PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x1000),
PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x1300),
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, ft1000_ids);
static struct pcmcia_driver ft1000_cs_driver = {
.owner = THIS_MODULE,
.name = "ft1000_cs",
.probe = ft1000_attach,
.remove = ft1000_detach,
.id_table = ft1000_ids,
.suspend = ft1000_suspend,
.resume = ft1000_resume,
};
module_pcmcia_driver(ft1000_cs_driver);

View File

@ -1,762 +0,0 @@
/*---------------------------------------------------------------------------
FT1000 driver for Flarion Flash OFDM NIC Device
Copyright (C) 2002 Flarion Technologies, All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option) any
later version. This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License along with this program; if not, write to the
Free Software Foundation, Inc., 59 Temple Place -
Suite 330, Boston, MA 02111-1307, USA.
--------------------------------------------------------------------------
Description: This module will handshake with the DSP bootloader to
download the DSP runtime image.
---------------------------------------------------------------------------*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#define __KERNEL_SYSCALLS__
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/unistd.h>
#include <linux/netdevice.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include "ft1000.h"
#include "boot.h"
#define MAX_DSP_WAIT_LOOPS 100
#define DSP_WAIT_SLEEP_TIME 1 /* 1 millisecond */
#define MAX_LENGTH 0x7f0
#define DWNLD_MAG_HANDSHAKE_LOC 0x00
#define DWNLD_MAG_TYPE_LOC 0x01
#define DWNLD_MAG_SIZE_LOC 0x02
#define DWNLD_MAG_PS_HDR_LOC 0x03
#define DWNLD_HANDSHAKE_LOC 0x02
#define DWNLD_TYPE_LOC 0x04
#define DWNLD_SIZE_MSW_LOC 0x06
#define DWNLD_SIZE_LSW_LOC 0x08
#define DWNLD_PS_HDR_LOC 0x0A
#define HANDSHAKE_TIMEOUT_VALUE 0xF1F1
#define HANDSHAKE_RESET_VALUE 0xFEFE /* When DSP requests startover */
#define HANDSHAKE_DSP_BL_READY 0xFEFE /* At start DSP writes this when bootloader ready */
#define HANDSHAKE_DRIVER_READY 0xFFFF /* Driver writes after receiving 0xFEFE */
#define HANDSHAKE_SEND_DATA 0x0000 /* DSP writes this when ready for more data */
#define HANDSHAKE_REQUEST 0x0001 /* Request from DSP */
#define HANDSHAKE_RESPONSE 0x0000 /* Satisfied DSP request */
#define REQUEST_CODE_LENGTH 0x0000
#define REQUEST_RUN_ADDRESS 0x0001
#define REQUEST_CODE_SEGMENT 0x0002 /* In WORD count */
#define REQUEST_DONE_BL 0x0003
#define REQUEST_DONE_CL 0x0004
#define REQUEST_VERSION_INFO 0x0005
#define REQUEST_CODE_BY_VERSION 0x0006
#define REQUEST_MAILBOX_DATA 0x0007
#define REQUEST_FILE_CHECKSUM 0x0008
#define STATE_START_DWNLD 0x01
#define STATE_BOOT_DWNLD 0x02
#define STATE_CODE_DWNLD 0x03
#define STATE_DONE_DWNLD 0x04
#define STATE_SECTION_PROV 0x05
#define STATE_DONE_PROV 0x06
#define STATE_DONE_FILE 0x07
struct dsp_file_hdr {
u32 version_id; /* Version ID of this image format. */
u32 package_id; /* Package ID of code release. */
u32 build_date; /* Date/time stamp when file was built. */
u32 commands_offset; /* Offset to attached commands in Pseudo Hdr format. */
u32 loader_offset; /* Offset to bootloader code. */
u32 loader_code_address; /* Start address of bootloader. */
u32 loader_code_end; /* Where bootloader code ends. */
u32 loader_code_size;
u32 version_data_offset; /* Offset were scrambled version data begins. */
u32 version_data_size; /* Size, in words, of scrambled version data. */
u32 nDspImages; /* Number of DSP images in file. */
} __packed;
struct dsp_image_info {
u32 coff_date; /* Date/time when DSP Coff image was built. */
u32 begin_offset; /* Offset in file where image begins. */
u32 end_offset; /* Offset in file where image begins. */
u32 run_address; /* On chip Start address of DSP code. */
u32 image_size; /* Size of image. */
u32 version; /* Embedded version # of DSP code. */
unsigned short checksum; /* Dsp File checksum */
unsigned short pad1;
} __packed;
void card_bootload(struct net_device *dev)
{
struct ft1000_info *info = netdev_priv(dev);
unsigned long flags;
u32 *pdata;
u32 size;
u32 i;
u32 templong;
netdev_dbg(dev, "card_bootload is called\n");
pdata = (u32 *)bootimage;
size = sizeof(bootimage);
/* check for odd word */
if (size & 0x0003)
size += 4;
/* Provide mutual exclusive access while reading ASIC registers. */
spin_lock_irqsave(&info->dpram_lock, flags);
/* need to set i/o base address initially and hardware will autoincrement */
ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_BASE);
/* write bytes */
for (i = 0; i < (size >> 2); i++) {
templong = *pdata++;
outl(templong, dev->base_addr + FT1000_REG_MAG_DPDATA);
}
spin_unlock_irqrestore(&info->dpram_lock, flags);
}
static u16 get_handshake(struct net_device *dev, u16 expected_value)
{
struct ft1000_info *info = netdev_priv(dev);
u16 handshake;
u32 tempx;
int loopcnt;
loopcnt = 0;
while (loopcnt < MAX_DSP_WAIT_LOOPS) {
if (info->AsicID == ELECTRABUZZ_ID) {
ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
DWNLD_HANDSHAKE_LOC);
handshake = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
} else {
tempx =
ntohl(ft1000_read_dpram_mag_32
(dev, DWNLD_MAG_HANDSHAKE_LOC));
handshake = (u16)tempx;
}
if ((handshake == expected_value)
|| (handshake == HANDSHAKE_RESET_VALUE)) {
return handshake;
}
loopcnt++;
mdelay(DSP_WAIT_SLEEP_TIME);
}
return HANDSHAKE_TIMEOUT_VALUE;
}
static void put_handshake(struct net_device *dev, u16 handshake_value)
{
struct ft1000_info *info = netdev_priv(dev);
u32 tempx;
if (info->AsicID == ELECTRABUZZ_ID) {
ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
DWNLD_HANDSHAKE_LOC);
ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, handshake_value); /* Handshake */
} else {
tempx = (u32)handshake_value;
tempx = ntohl(tempx);
ft1000_write_dpram_mag_32(dev, DWNLD_MAG_HANDSHAKE_LOC, tempx); /* Handshake */
}
}
static u16 get_request_type(struct net_device *dev)
{
struct ft1000_info *info = netdev_priv(dev);
u16 request_type;
u32 tempx;
if (info->AsicID == ELECTRABUZZ_ID) {
ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, DWNLD_TYPE_LOC);
request_type = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
} else {
tempx = ft1000_read_dpram_mag_32(dev, DWNLD_MAG_TYPE_LOC);
tempx = ntohl(tempx);
request_type = (u16)tempx;
}
return request_type;
}
static long get_request_value(struct net_device *dev)
{
struct ft1000_info *info = netdev_priv(dev);
long value;
u16 w_val;
if (info->AsicID == ELECTRABUZZ_ID) {
ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
DWNLD_SIZE_MSW_LOC);
w_val = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
value = (long)(w_val << 16);
ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
DWNLD_SIZE_LSW_LOC);
w_val = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
value = (long)(value | w_val);
} else {
value = ft1000_read_dpram_mag_32(dev, DWNLD_MAG_SIZE_LOC);
value = ntohl(value);
}
return value;
}
static void put_request_value(struct net_device *dev, long lvalue)
{
struct ft1000_info *info = netdev_priv(dev);
u16 size;
u32 tempx;
if (info->AsicID == ELECTRABUZZ_ID) {
size = (u16) (lvalue >> 16);
ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
DWNLD_SIZE_MSW_LOC);
ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, size);
size = (u16) (lvalue);
ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
DWNLD_SIZE_LSW_LOC);
ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, size);
} else {
tempx = ntohl(lvalue);
ft1000_write_dpram_mag_32(dev, DWNLD_MAG_SIZE_LOC, tempx); /* Handshake */
}
}
static u16 hdr_checksum(struct pseudo_hdr *pHdr)
{
u16 *usPtr = (u16 *)pHdr;
u16 chksum;
chksum = (((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^
usPtr[4]) ^ usPtr[5]) ^ usPtr[6];
return chksum;
}
int card_download(struct net_device *dev, const u8 *pFileStart,
size_t FileLength)
{
struct ft1000_info *info = netdev_priv(dev);
int Status = SUCCESS;
u32 uiState;
u16 handshake;
struct pseudo_hdr *pHdr;
u16 usHdrLength;
long word_length;
u16 request;
u16 temp;
struct prov_record *pprov_record;
u8 *pbuffer;
struct dsp_file_hdr *pFileHdr5;
struct dsp_image_info *pDspImageInfoV6 = NULL;
long requested_version;
bool bGoodVersion = false;
struct drv_msg *pMailBoxData;
u16 *pUsData = NULL;
u16 *pUsFile = NULL;
u8 *pUcFile = NULL;
u8 *pBootEnd = NULL;
u8 *pCodeEnd = NULL;
int imageN;
long file_version;
long loader_code_address = 0;
long loader_code_size = 0;
long run_address = 0;
long run_size = 0;
unsigned long flags;
unsigned long templong;
unsigned long image_chksum = 0;
file_version = *(long *)pFileStart;
if (file_version != 6) {
pr_err("unsupported firmware version %ld\n", file_version);
Status = FAILURE;
}
uiState = STATE_START_DWNLD;
pFileHdr5 = (struct dsp_file_hdr *)pFileStart;
pUsFile = (u16 *) ((long)pFileStart + pFileHdr5->loader_offset);
pUcFile = (u8 *) ((long)pFileStart + pFileHdr5->loader_offset);
pBootEnd = (u8 *) ((long)pFileStart + pFileHdr5->loader_code_end);
loader_code_address = pFileHdr5->loader_code_address;
loader_code_size = pFileHdr5->loader_code_size;
bGoodVersion = false;
while ((Status == SUCCESS) && (uiState != STATE_DONE_FILE)) {
switch (uiState) {
case STATE_START_DWNLD:
handshake = get_handshake(dev, HANDSHAKE_DSP_BL_READY);
if (handshake == HANDSHAKE_DSP_BL_READY)
put_handshake(dev, HANDSHAKE_DRIVER_READY);
else
Status = FAILURE;
uiState = STATE_BOOT_DWNLD;
break;
case STATE_BOOT_DWNLD:
handshake = get_handshake(dev, HANDSHAKE_REQUEST);
if (handshake == HANDSHAKE_REQUEST) {
/*
* Get type associated with the request.
*/
request = get_request_type(dev);
switch (request) {
case REQUEST_RUN_ADDRESS:
put_request_value(dev,
loader_code_address);
break;
case REQUEST_CODE_LENGTH:
put_request_value(dev,
loader_code_size);
break;
case REQUEST_DONE_BL:
/* Reposition ptrs to beginning of code section */
pUsFile = (u16 *) ((long)pBootEnd);
pUcFile = (u8 *) ((long)pBootEnd);
uiState = STATE_CODE_DWNLD;
break;
case REQUEST_CODE_SEGMENT:
word_length = get_request_value(dev);
if (word_length > MAX_LENGTH) {
Status = FAILURE;
break;
}
if ((word_length * 2 + (long)pUcFile) >
(long)pBootEnd) {
/*
* Error, beyond boot code range.
*/
Status = FAILURE;
break;
}
/* Provide mutual exclusive access while reading ASIC registers. */
spin_lock_irqsave(&info->dpram_lock,
flags);
/*
* Position ASIC DPRAM auto-increment pointer.
*/
outw(DWNLD_MAG_PS_HDR_LOC,
dev->base_addr +
FT1000_REG_DPRAM_ADDR);
if (word_length & 0x01)
word_length++;
word_length = word_length / 2;
for (; word_length > 0; word_length--) { /* In words */
templong = *pUsFile++;
templong |=
(*pUsFile++ << 16);
pUcFile += 4;
outl(templong,
dev->base_addr +
FT1000_REG_MAG_DPDATAL);
}
spin_unlock_irqrestore(&info->
dpram_lock,
flags);
break;
default:
Status = FAILURE;
break;
}
put_handshake(dev, HANDSHAKE_RESPONSE);
} else {
Status = FAILURE;
}
break;
case STATE_CODE_DWNLD:
handshake = get_handshake(dev, HANDSHAKE_REQUEST);
if (handshake == HANDSHAKE_REQUEST) {
/*
* Get type associated with the request.
*/
request = get_request_type(dev);
switch (request) {
case REQUEST_FILE_CHECKSUM:
netdev_dbg(dev,
"ft1000_dnld: REQUEST_FOR_CHECKSUM\n");
put_request_value(dev, image_chksum);
break;
case REQUEST_RUN_ADDRESS:
if (bGoodVersion) {
put_request_value(dev,
run_address);
} else {
Status = FAILURE;
break;
}
break;
case REQUEST_CODE_LENGTH:
if (bGoodVersion) {
put_request_value(dev,
run_size);
} else {
Status = FAILURE;
break;
}
break;
case REQUEST_DONE_CL:
/* Reposition ptrs to beginning of provisioning section */
pUsFile = (u16 *) ((long)pFileStart + pFileHdr5->commands_offset);
pUcFile = (u8 *) ((long)pFileStart + pFileHdr5->commands_offset);
uiState = STATE_DONE_DWNLD;
break;
case REQUEST_CODE_SEGMENT:
if (!bGoodVersion) {
Status = FAILURE;
break;
}
word_length = get_request_value(dev);
if (word_length > MAX_LENGTH) {
Status = FAILURE;
break;
}
if ((word_length * 2 + (long)pUcFile) >
(long)pCodeEnd) {
/*
* Error, beyond boot code range.
*/
Status = FAILURE;
break;
}
/*
* Position ASIC DPRAM auto-increment pointer.
*/
outw(DWNLD_MAG_PS_HDR_LOC,
dev->base_addr +
FT1000_REG_DPRAM_ADDR);
if (word_length & 0x01)
word_length++;
word_length = word_length / 2;
for (; word_length > 0; word_length--) { /* In words */
templong = *pUsFile++;
templong |=
(*pUsFile++ << 16);
pUcFile += 4;
outl(templong,
dev->base_addr +
FT1000_REG_MAG_DPDATAL);
}
break;
case REQUEST_MAILBOX_DATA:
/* Convert length from byte count to word count. Make sure we round up. */
word_length =
(long)(info->DSPInfoBlklen + 1) / 2;
put_request_value(dev, word_length);
pMailBoxData =
(struct drv_msg *)&info->DSPInfoBlk[0];
pUsData =
(u16 *)&pMailBoxData->data[0];
/* Provide mutual exclusive access while reading ASIC registers. */
spin_lock_irqsave(&info->dpram_lock,
flags);
if (file_version == 5) {
/*
* Position ASIC DPRAM auto-increment pointer.
*/
ft1000_write_reg(dev,
FT1000_REG_DPRAM_ADDR,
DWNLD_PS_HDR_LOC);
for (; word_length > 0; word_length--) { /* In words */
temp = ntohs(*pUsData);
ft1000_write_reg(dev,
FT1000_REG_DPRAM_DATA,
temp);
pUsData++;
}
} else {
/*
* Position ASIC DPRAM auto-increment pointer.
*/
outw(DWNLD_MAG_PS_HDR_LOC,
dev->base_addr +
FT1000_REG_DPRAM_ADDR);
if (word_length & 0x01)
word_length++;
word_length = word_length / 2;
for (; word_length > 0; word_length--) { /* In words */
templong = *pUsData++;
templong |=
(*pUsData++ << 16);
outl(templong,
dev->base_addr +
FT1000_REG_MAG_DPDATAL);
}
}
spin_unlock_irqrestore(&info->
dpram_lock,
flags);
break;
case REQUEST_VERSION_INFO:
word_length =
pFileHdr5->version_data_size;
put_request_value(dev, word_length);
pUsFile =
(u16 *) ((long)pFileStart +
pFileHdr5->
version_data_offset);
/* Provide mutual exclusive access while reading ASIC registers. */
spin_lock_irqsave(&info->dpram_lock,
flags);
/*
* Position ASIC DPRAM auto-increment pointer.
*/
outw(DWNLD_MAG_PS_HDR_LOC,
dev->base_addr +
FT1000_REG_DPRAM_ADDR);
if (word_length & 0x01)
word_length++;
word_length = word_length / 2;
for (; word_length > 0; word_length--) { /* In words */
templong =
ntohs(*pUsFile++);
temp =
ntohs(*pUsFile++);
templong |=
(temp << 16);
outl(templong,
dev->base_addr +
FT1000_REG_MAG_DPDATAL);
}
spin_unlock_irqrestore(&info->
dpram_lock,
flags);
break;
case REQUEST_CODE_BY_VERSION:
bGoodVersion = false;
requested_version =
get_request_value(dev);
pDspImageInfoV6 =
(struct dsp_image_info *) ((long)
pFileStart
+
sizeof
(struct dsp_file_hdr));
for (imageN = 0;
imageN <
pFileHdr5->nDspImages;
imageN++) {
temp = (u16)
(pDspImageInfoV6->
version);
templong = temp;
temp = (u16)
(pDspImageInfoV6->
version >> 16);
templong |=
(temp << 16);
if (templong ==
requested_version) {
bGoodVersion =
true;
pUsFile =
(u16
*) ((long)
pFileStart
+
pDspImageInfoV6->
begin_offset);
pUcFile =
(u8
*) ((long)
pFileStart
+
pDspImageInfoV6->
begin_offset);
pCodeEnd =
(u8
*) ((long)
pFileStart
+
pDspImageInfoV6->
end_offset);
run_address =
pDspImageInfoV6->
run_address;
run_size =
pDspImageInfoV6->
image_size;
image_chksum =
(u32)
pDspImageInfoV6->
checksum;
netdev_dbg(dev,
"ft1000_dnld: image_chksum = 0x%8x\n",
(unsigned
int)
image_chksum);
break;
}
pDspImageInfoV6++;
}
if (!bGoodVersion) {
/*
* Error, beyond boot code range.
*/
Status = FAILURE;
break;
}
break;
default:
Status = FAILURE;
break;
}
put_handshake(dev, HANDSHAKE_RESPONSE);
} else {
Status = FAILURE;
}
break;
case STATE_DONE_DWNLD:
if (((unsigned long)(pUcFile) - (unsigned long) pFileStart) >=
(unsigned long)FileLength) {
uiState = STATE_DONE_FILE;
break;
}
pHdr = (struct pseudo_hdr *)pUsFile;
if (pHdr->portdest == 0x80 /* DspOAM */
&& (pHdr->portsrc == 0x00 /* Driver */
|| pHdr->portsrc == 0x10 /* FMM */)) {
uiState = STATE_SECTION_PROV;
} else {
netdev_dbg(dev,
"Download error: Bad Port IDs in Pseudo Record\n");
netdev_dbg(dev, "\t Port Source = 0x%2.2x\n",
pHdr->portsrc);
netdev_dbg(dev, "\t Port Destination = 0x%2.2x\n",
pHdr->portdest);
Status = FAILURE;
}
break;
case STATE_SECTION_PROV:
pHdr = (struct pseudo_hdr *)pUcFile;
if (pHdr->checksum == hdr_checksum(pHdr)) {
if (pHdr->portdest != 0x80 /* Dsp OAM */) {
uiState = STATE_DONE_PROV;
break;
}
usHdrLength = ntohs(pHdr->length); /* Byte length for PROV records */
/* Get buffer for provisioning data */
pbuffer =
kmalloc(usHdrLength + sizeof(struct pseudo_hdr),
GFP_ATOMIC);
if (pbuffer) {
memcpy(pbuffer, pUcFile,
(u32) (usHdrLength +
sizeof(struct pseudo_hdr)));
/* link provisioning data */
pprov_record =
kmalloc(sizeof(struct prov_record),
GFP_ATOMIC);
if (pprov_record) {
pprov_record->pprov_data =
pbuffer;
list_add_tail(&pprov_record->
list,
&info->prov_list);
/* Move to next entry if available */
pUcFile =
(u8 *)((unsigned long) pUcFile +
(unsigned long) ((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr));
if ((unsigned long) (pUcFile) -
(unsigned long) (pFileStart) >=
(unsigned long)FileLength) {
uiState =
STATE_DONE_FILE;
}
} else {
kfree(pbuffer);
Status = FAILURE;
}
} else {
Status = FAILURE;
}
} else {
/* Checksum did not compute */
Status = FAILURE;
}
break;
case STATE_DONE_PROV:
uiState = STATE_DONE_FILE;
break;
default:
Status = FAILURE;
break;
} /* End Switch */
} /* End while */
return Status;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
obj-$(CONFIG_FT1000_USB) += ft1000.o
ft1000-y := ft1000_debug.o ft1000_download.o ft1000_hw.o ft1000_usb.o

View File

@ -1,789 +0,0 @@
/*
*---------------------------------------------------------------------------
* FT1000 driver for Flarion Flash OFDM NIC Device
*
* Copyright (C) 2006 Flarion Technologies, All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option) any
* later version. This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details. You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place -
* Suite 330, Boston, MA 02111-1307, USA.
*---------------------------------------------------------------------------
*
* File: ft1000_chdev.c
*
* Description: Custom character device dispatch routines.
*
* History:
* 8/29/02 Whc Ported to Linux.
* 6/05/06 Whc Porting to Linux 2.6.9
*
*---------------------------------------------------------------------------
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/poll.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
#include <linux/ioctl.h>
#include <linux/debugfs.h>
#include "ft1000_usb.h"
static int ft1000_flarion_cnt;
static int ft1000_open(struct inode *inode, struct file *file);
static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait);
static long ft1000_ioctl(struct file *file, unsigned int command,
unsigned long argument);
static int ft1000_release(struct inode *inode, struct file *file);
/* List to free receive command buffer pool */
struct list_head freercvpool;
/* lock to arbitrate free buffer list for receive command data */
spinlock_t free_buff_lock;
int numofmsgbuf;
/*
* Table of entry-point routines for char device
*/
static const struct file_operations ft1000fops = {
.unlocked_ioctl = ft1000_ioctl,
.poll = ft1000_poll_dev,
.open = ft1000_open,
.release = ft1000_release,
.llseek = no_llseek,
};
/*
---------------------------------------------------------------------------
* Function: ft1000_get_buffer
*
* Parameters:
*
* Returns:
*
* Description:
*
* Notes:
*
*---------------------------------------------------------------------------
*/
struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist)
{
unsigned long flags;
struct dpram_blk *ptr;
spin_lock_irqsave(&free_buff_lock, flags);
/* Check if buffer is available */
if (list_empty(bufflist)) {
pr_debug("No more buffer - %d\n", numofmsgbuf);
ptr = NULL;
} else {
numofmsgbuf--;
ptr = list_entry(bufflist->next, struct dpram_blk, list);
list_del(&ptr->list);
/* pr_debug("number of free msg buffers = %d\n", numofmsgbuf); */
}
spin_unlock_irqrestore(&free_buff_lock, flags);
return ptr;
}
/*
*---------------------------------------------------------------------------
* Function: ft1000_free_buffer
*
* Parameters:
*
* Returns:
*
* Description:
*
* Notes:
*
*---------------------------------------------------------------------------
*/
void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist)
{
unsigned long flags;
spin_lock_irqsave(&free_buff_lock, flags);
/* Put memory back to list */
list_add_tail(&pdpram_blk->list, plist);
numofmsgbuf++;
/*pr_debug("number of free msg buffers = %d\n", numofmsgbuf); */
spin_unlock_irqrestore(&free_buff_lock, flags);
}
/*
*---------------------------------------------------------------------------
* Function: ft1000_CreateDevice
*
* Parameters: dev - pointer to adapter object
*
* Returns: 0 if successful
*
* Description: Creates a private char device.
*
* Notes: Only called by init_module().
*
*---------------------------------------------------------------------------
*/
int ft1000_create_dev(struct ft1000_usb *dev)
{
int result;
int i;
struct dentry *dir, *file;
struct ft1000_debug_dirs *tmp;
/* make a new device name */
sprintf(dev->DeviceName, "%s%d", "FT1000_", dev->CardNumber);
pr_debug("number of instance = %d\n", ft1000_flarion_cnt);
pr_debug("DeviceCreated = %x\n", dev->DeviceCreated);
if (dev->DeviceCreated) {
pr_debug("\"%s\" already registered\n", dev->DeviceName);
return -EIO;
}
/* register the device */
pr_debug("\"%s\" debugfs device registration\n", dev->DeviceName);
tmp = kmalloc(sizeof(struct ft1000_debug_dirs), GFP_KERNEL);
if (tmp == NULL) {
result = -1;
goto fail;
}
dir = debugfs_create_dir(dev->DeviceName, NULL);
if (IS_ERR(dir)) {
result = PTR_ERR(dir);
goto debug_dir_fail;
}
file = debugfs_create_file("device", S_IRUGO | S_IWUSR, dir,
dev, &ft1000fops);
if (IS_ERR(file)) {
result = PTR_ERR(file);
goto debug_file_fail;
}
tmp->dent = dir;
tmp->file = file;
tmp->int_number = dev->CardNumber;
list_add(&tmp->list, &dev->nodes.list);
pr_debug("registered debugfs directory \"%s\"\n", dev->DeviceName);
/* initialize application information */
dev->appcnt = 0;
for (i = 0; i < MAX_NUM_APP; i++) {
dev->app_info[i].nTxMsg = 0;
dev->app_info[i].nRxMsg = 0;
dev->app_info[i].nTxMsgReject = 0;
dev->app_info[i].nRxMsgMiss = 0;
dev->app_info[i].fileobject = NULL;
dev->app_info[i].app_id = i+1;
dev->app_info[i].DspBCMsgFlag = 0;
dev->app_info[i].NumOfMsg = 0;
init_waitqueue_head(&dev->app_info[i].wait_dpram_msg);
INIT_LIST_HEAD(&dev->app_info[i].app_sqlist);
}
dev->DeviceCreated = TRUE;
ft1000_flarion_cnt++;
return 0;
debug_file_fail:
debugfs_remove(dir);
debug_dir_fail:
kfree(tmp);
fail:
return result;
}
/*
*---------------------------------------------------------------------------
* Function: ft1000_DestroyDeviceDEBUG
*
* Parameters: dev - pointer to adapter object
*
* Description: Destroys a private char device.
*
* Notes: Only called by cleanup_module().
*
*---------------------------------------------------------------------------
*/
void ft1000_destroy_dev(struct net_device *netdev)
{
struct ft1000_info *info = netdev_priv(netdev);
struct ft1000_usb *dev = info->priv;
int i;
struct dpram_blk *pdpram_blk;
struct dpram_blk *ptr;
struct list_head *pos, *q;
struct ft1000_debug_dirs *dir;
if (dev->DeviceCreated) {
ft1000_flarion_cnt--;
list_for_each_safe(pos, q, &dev->nodes.list) {
dir = list_entry(pos, struct ft1000_debug_dirs, list);
if (dir->int_number == dev->CardNumber) {
debugfs_remove(dir->file);
debugfs_remove(dir->dent);
list_del(pos);
kfree(dir);
}
}
pr_debug("unregistered device \"%s\"\n", dev->DeviceName);
/* Make sure we free any memory reserve for slow Queue */
for (i = 0; i < MAX_NUM_APP; i++) {
while (list_empty(&dev->app_info[i].app_sqlist) == 0) {
pdpram_blk = list_entry(dev->app_info[i].app_sqlist.next,
struct dpram_blk, list);
list_del(&pdpram_blk->list);
ft1000_free_buffer(pdpram_blk, &freercvpool);
}
wake_up_interruptible(&dev->app_info[i].wait_dpram_msg);
}
/* Remove buffer allocated for receive command data */
if (ft1000_flarion_cnt == 0) {
while (list_empty(&freercvpool) == 0) {
ptr = list_entry(freercvpool.next, struct dpram_blk, list);
list_del(&ptr->list);
kfree(ptr->pbuffer);
kfree(ptr);
}
}
dev->DeviceCreated = FALSE;
}
}
/*
*---------------------------------------------------------------------------
* Function: ft1000_open
*
* Parameters:
*
* Description:
*
* Notes:
*
*---------------------------------------------------------------------------
*/
static int ft1000_open(struct inode *inode, struct file *file)
{
struct ft1000_info *info;
struct ft1000_usb *dev = (struct ft1000_usb *)inode->i_private;
int i, num;
num = MINOR(inode->i_rdev) & 0xf;
pr_debug("minor number=%d\n", num);
info = file->private_data = netdev_priv(dev->net);
pr_debug("f_owner = %p number of application = %d\n",
&file->f_owner, dev->appcnt);
/* Check if maximum number of application exceeded */
if (dev->appcnt > MAX_NUM_APP) {
pr_debug("Maximum number of application exceeded\n");
return -EACCES;
}
/* Search for available application info block */
for (i = 0; i < MAX_NUM_APP; i++) {
if (dev->app_info[i].fileobject == NULL)
break;
}
/* Fail due to lack of application info block */
if (i == MAX_NUM_APP) {
pr_debug("Could not find an application info block\n");
return -EACCES;
}
dev->appcnt++;
dev->app_info[i].fileobject = &file->f_owner;
dev->app_info[i].nTxMsg = 0;
dev->app_info[i].nRxMsg = 0;
dev->app_info[i].nTxMsgReject = 0;
dev->app_info[i].nRxMsgMiss = 0;
nonseekable_open(inode, file);
return 0;
}
/*
*---------------------------------------------------------------------------
* Function: ft1000_poll_dev
*
* Parameters:
*
* Description:
*
* Notes:
*
*---------------------------------------------------------------------------
*/
static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait)
{
struct net_device *netdev = file->private_data;
struct ft1000_info *info = netdev_priv(netdev);
struct ft1000_usb *dev = info->priv;
int i;
if (ft1000_flarion_cnt == 0) {
pr_debug("called with ft1000_flarion_cnt value zero\n");
return -EBADF;
}
/* Search for matching file object */
for (i = 0; i < MAX_NUM_APP; i++) {
if (dev->app_info[i].fileobject == &file->f_owner) {
/* pr_debug("Message is for AppId = %d\n", dev->app_info[i].app_id); */
break;
}
}
/* Could not find application info block */
if (i == MAX_NUM_APP) {
pr_debug("Could not find application info block\n");
return -EACCES;
}
if (list_empty(&dev->app_info[i].app_sqlist) == 0) {
pr_debug("Message detected in slow queue\n");
return(POLLIN | POLLRDNORM | POLLPRI);
}
poll_wait(file, &dev->app_info[i].wait_dpram_msg, wait);
/* pr_debug("Polling for data from DSP\n"); */
return 0;
}
/*
*---------------------------------------------------------------------------
* Function: ft1000_ioctl
*
* Parameters:
*
* Description:
*
* Notes:
*
*---------------------------------------------------------------------------
*/
static long ft1000_ioctl(struct file *file, unsigned int command,
unsigned long argument)
{
void __user *argp = (void __user *)argument;
struct ft1000_info *info;
struct ft1000_usb *ft1000dev;
int result = 0;
int cmd;
int i;
u16 tempword;
unsigned long flags;
struct timeval tv;
struct IOCTL_GET_VER get_ver_data;
struct IOCTL_GET_DSP_STAT get_stat_data;
u8 ConnectionMsg[] = {
0x00, 0x44, 0x10, 0x20, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x93, 0x64,
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0a,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x37, 0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7f, 0x00,
0x00, 0x01, 0x00, 0x00
};
unsigned short ledStat = 0;
unsigned short conStat = 0;
if (ft1000_flarion_cnt == 0) {
pr_debug("called with ft1000_flarion_cnt of zero\n");
return -EBADF;
}
/* pr_debug("command = 0x%x argument = 0x%8x\n", command, (u32)argument); */
info = file->private_data;
ft1000dev = info->priv;
cmd = _IOC_NR(command);
/* pr_debug("cmd = 0x%x\n", cmd); */
/* process the command */
switch (cmd) {
case IOCTL_REGISTER_CMD:
pr_debug("IOCTL_FT1000_REGISTER called\n");
result = get_user(tempword, (__u16 __user *)argp);
if (result) {
pr_debug("result = %d failed to get_user\n", result);
break;
}
if (tempword == DSPBCMSGID) {
/* Search for matching file object */
for (i = 0; i < MAX_NUM_APP; i++) {
if (ft1000dev->app_info[i].fileobject == &file->f_owner) {
ft1000dev->app_info[i].DspBCMsgFlag = 1;
pr_debug("Registered for broadcast messages\n");
break;
}
}
}
break;
case IOCTL_GET_VER_CMD:
pr_debug("IOCTL_FT1000_GET_VER called\n");
get_ver_data.drv_ver = FT1000_DRV_VER;
if (copy_to_user(argp, &get_ver_data, sizeof(get_ver_data))) {
pr_debug("copy fault occurred\n");
result = -EFAULT;
break;
}
pr_debug("driver version = 0x%x\n",
(unsigned int)get_ver_data.drv_ver);
break;
case IOCTL_CONNECT:
/* Connect Message */
pr_debug("IOCTL_FT1000_CONNECT\n");
ConnectionMsg[79] = 0xfc;
result = card_send_command(ft1000dev, ConnectionMsg, 0x4c);
break;
case IOCTL_DISCONNECT:
/* Disconnect Message */
pr_debug("IOCTL_FT1000_DISCONNECT\n");
ConnectionMsg[79] = 0xfd;
result = card_send_command(ft1000dev, ConnectionMsg, 0x4c);
break;
case IOCTL_GET_DSP_STAT_CMD:
/* pr_debug("IOCTL_FT1000_GET_DSP_STAT\n"); */
memset(&get_stat_data, 0, sizeof(get_stat_data));
memcpy(get_stat_data.DspVer, info->DspVer, DSPVERSZ);
memcpy(get_stat_data.HwSerNum, info->HwSerNum, HWSERNUMSZ);
memcpy(get_stat_data.Sku, info->Sku, SKUSZ);
memcpy(get_stat_data.eui64, info->eui64, EUISZ);
if (info->ProgConStat != 0xFF) {
ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_LED,
(u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX);
get_stat_data.LedStat = ntohs(ledStat);
pr_debug("LedStat = 0x%x\n", get_stat_data.LedStat);
ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE,
(u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX);
get_stat_data.ConStat = ntohs(conStat);
pr_debug("ConStat = 0x%x\n", get_stat_data.ConStat);
} else {
get_stat_data.ConStat = 0x0f;
}
get_stat_data.nTxPkts = info->stats.tx_packets;
get_stat_data.nRxPkts = info->stats.rx_packets;
get_stat_data.nTxBytes = info->stats.tx_bytes;
get_stat_data.nRxBytes = info->stats.rx_bytes;
do_gettimeofday(&tv);
get_stat_data.ConTm = (u32)(tv.tv_sec - info->ConTm);
pr_debug("Connection Time = %d\n", (int)get_stat_data.ConTm);
if (copy_to_user(argp, &get_stat_data, sizeof(get_stat_data))) {
pr_debug("copy fault occurred\n");
result = -EFAULT;
break;
}
pr_debug("GET_DSP_STAT succeed\n");
break;
case IOCTL_SET_DPRAM_CMD:
{
struct IOCTL_DPRAM_BLK *dpram_data = NULL;
/* struct IOCTL_DPRAM_COMMAND dpram_command; */
u16 qtype;
u16 msgsz;
struct pseudo_hdr *ppseudo_hdr;
u16 *pmsg;
u16 total_len;
u16 app_index;
u16 status;
/* pr_debug("IOCTL_FT1000_SET_DPRAM called\n");*/
if (ft1000_flarion_cnt == 0)
return -EBADF;
if (ft1000dev->DrvMsgPend)
return -ENOTTY;
if (ft1000dev->fProvComplete == 0)
return -EACCES;
ft1000dev->fAppMsgPend = true;
if (info->CardReady) {
/* pr_debug("try to SET_DPRAM\n"); */
/* Get the length field to see how many bytes to copy */
result = get_user(msgsz, (__u16 __user *)argp);
if (result)
break;
msgsz = ntohs(msgsz);
/* pr_debug("length of message = %d\n", msgsz); */
if (msgsz > MAX_CMD_SQSIZE) {
pr_debug("bad message length = %d\n", msgsz);
result = -EINVAL;
break;
}
result = -ENOMEM;
dpram_data = kmalloc(msgsz + 2, GFP_KERNEL);
if (!dpram_data)
break;
if (copy_from_user(dpram_data, argp, msgsz+2)) {
pr_debug("copy fault occurred\n");
result = -EFAULT;
} else {
/* Check if this message came from a registered application */
for (i = 0; i < MAX_NUM_APP; i++) {
if (ft1000dev->app_info[i].fileobject == &file->f_owner)
break;
}
if (i == MAX_NUM_APP) {
pr_debug("No matching application fileobject\n");
result = -EINVAL;
kfree(dpram_data);
break;
}
app_index = i;
/* Check message qtype type which is the lower byte within qos_class */
qtype = ntohs(dpram_data->pseudohdr.qos_class) & 0xff;
/* pr_debug("qtype = %d\n", qtype); */
if (!qtype) {
/* Put message into Slow Queue */
/* Only put a message into the DPRAM if msg doorbell is available */
status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL);
/* pr_debug("READ REGISTER tempword=%x\n", tempword); */
if (tempword & FT1000_DB_DPRAM_TX) {
/* Suspend for 2ms and try again due to DSP doorbell busy */
mdelay(2);
status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL);
if (tempword & FT1000_DB_DPRAM_TX) {
/* Suspend for 1ms and try again due to DSP doorbell busy */
mdelay(1);
status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL);
if (tempword & FT1000_DB_DPRAM_TX) {
status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL);
if (tempword & FT1000_DB_DPRAM_TX) {
/* Suspend for 3ms and try again due to DSP doorbell busy */
mdelay(3);
status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL);
if (tempword & FT1000_DB_DPRAM_TX) {
pr_debug("Doorbell not available\n");
result = -ENOTTY;
kfree(dpram_data);
break;
}
}
}
}
}
/*pr_debug("finished reading register\n"); */
/* Make sure we are within the limits of the slow queue memory limitation */
if ((msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ)) {
/* Need to put sequence number plus new checksum for message */
pmsg = (u16 *)&dpram_data->pseudohdr;
ppseudo_hdr = (struct pseudo_hdr *)pmsg;
total_len = msgsz+2;
if (total_len & 0x1)
total_len++;
/* Insert slow queue sequence number */
ppseudo_hdr->seq_num = info->squeseqnum++;
ppseudo_hdr->portsrc = ft1000dev->app_info[app_index].app_id;
/* Calculate new checksum */
ppseudo_hdr->checksum = *pmsg++;
/* pr_debug("checksum = 0x%x\n", ppseudo_hdr->checksum); */
for (i = 1; i < 7; i++) {
ppseudo_hdr->checksum ^= *pmsg++;
/* pr_debug("checksum = 0x%x\n", ppseudo_hdr->checksum); */
}
pmsg++;
ppseudo_hdr = (struct pseudo_hdr *)pmsg;
result = card_send_command(ft1000dev, dpram_data, total_len+2);
ft1000dev->app_info[app_index].nTxMsg++;
} else {
result = -EINVAL;
}
}
}
} else {
pr_debug("Card not ready take messages\n");
result = -EACCES;
}
kfree(dpram_data);
}
break;
case IOCTL_GET_DPRAM_CMD:
{
struct dpram_blk *pdpram_blk;
struct IOCTL_DPRAM_BLK __user *pioctl_dpram;
int msglen;
/* pr_debug("IOCTL_FT1000_GET_DPRAM called\n"); */
if (ft1000_flarion_cnt == 0)
return -EBADF;
/* Search for matching file object */
for (i = 0; i < MAX_NUM_APP; i++) {
if (ft1000dev->app_info[i].fileobject == &file->f_owner) {
/*pr_debug("Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */
break;
}
}
/* Could not find application info block */
if (i == MAX_NUM_APP) {
pr_debug("Could not find application info block\n");
result = -EBADF;
break;
}
result = 0;
pioctl_dpram = argp;
if (list_empty(&ft1000dev->app_info[i].app_sqlist) == 0) {
/* pr_debug("Message detected in slow queue\n"); */
spin_lock_irqsave(&free_buff_lock, flags);
pdpram_blk = list_entry(ft1000dev->app_info[i].app_sqlist.next,
struct dpram_blk, list);
list_del(&pdpram_blk->list);
ft1000dev->app_info[i].NumOfMsg--;
/* pr_debug("NumOfMsg for app %d = %d\n", i, ft1000dev->app_info[i].NumOfMsg); */
spin_unlock_irqrestore(&free_buff_lock, flags);
msglen = ntohs(*(u16 *)pdpram_blk->pbuffer) + PSEUDOSZ;
result = get_user(msglen, &pioctl_dpram->total_len);
if (result)
break;
msglen = htons(msglen);
/* pr_debug("msg length = %x\n", msglen); */
if (copy_to_user(&pioctl_dpram->pseudohdr, pdpram_blk->pbuffer, msglen)) {
pr_debug("copy fault occurred\n");
result = -EFAULT;
break;
}
ft1000_free_buffer(pdpram_blk, &freercvpool);
result = msglen;
}
/* pr_debug("IOCTL_FT1000_GET_DPRAM no message\n"); */
}
break;
default:
pr_debug("unknown command: 0x%x\n", command);
result = -ENOTTY;
break;
}
ft1000dev->fAppMsgPend = false;
return result;
}
/*
*---------------------------------------------------------------------------
* Function: ft1000_release
*
* Parameters:
*
* Description:
*
* Notes:
*
*---------------------------------------------------------------------------
*/
static int ft1000_release(struct inode *inode, struct file *file)
{
struct ft1000_info *info;
struct net_device *dev;
struct ft1000_usb *ft1000dev;
int i;
struct dpram_blk *pdpram_blk;
struct dpram_blk *tmp;
dev = file->private_data;
info = netdev_priv(dev);
ft1000dev = info->priv;
if (ft1000_flarion_cnt == 0) {
ft1000dev->appcnt--;
return -EBADF;
}
/* Search for matching file object */
for (i = 0; i < MAX_NUM_APP; i++) {
if (ft1000dev->app_info[i].fileobject == &file->f_owner) {
/* pr_debug("Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */
break;
}
}
if (i == MAX_NUM_APP)
return 0;
list_for_each_entry_safe(pdpram_blk, tmp, &ft1000dev->app_info[i].app_sqlist, list) {
pr_debug("Remove and free memory queue up on slow queue\n");
list_del(&pdpram_blk->list);
ft1000_free_buffer(pdpram_blk, &freercvpool);
}
/* initialize application information */
ft1000dev->appcnt--;
pr_debug("appcnt = %d\n", ft1000dev->appcnt);
ft1000dev->app_info[i].fileobject = NULL;
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,123 +0,0 @@
/*
*---------------------------------------------------------------------------
* FT1000 driver for Flarion Flash OFDM NIC Device
*
* Copyright (C) 2002 Flarion Technologies, All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option) any
* later version. This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details. You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place -
* Suite 330, Boston, MA 02111-1307, USA.
*---------------------------------------------------------------------------
*
* File: ft1000_ioctl.h
*
* Description: Common structures and defines relating to IOCTL
*
* History:
* 11/5/02 Whc Created.
*
*---------------------------------------------------------------------------
*/
#ifndef _FT1000IOCTLH_
#define _FT1000IOCTLH_
struct IOCTL_GET_VER {
unsigned long drv_ver;
} __packed;
/* Data structure for Dsp statistics */
struct IOCTL_GET_DSP_STAT {
unsigned char DspVer[DSPVERSZ]; /* DSP version number */
unsigned char HwSerNum[HWSERNUMSZ]; /* Hardware Serial Number */
unsigned char Sku[SKUSZ]; /* SKU */
unsigned char eui64[EUISZ]; /* EUI64 */
unsigned short ConStat; /* Connection Status */
/* Bits 0-3 = Connection Status Field */
/* 0000=Idle (Disconnect) */
/* 0001=Searching */
/* 0010=Active (Connected) */
/* 0011=Waiting for L2 down */
/* 0100=Sleep */
unsigned short LedStat; /* Led Status */
/* Bits 0-3 = Signal Strength Field */
/* 0000 = -105dBm to -92dBm */
/* 0001 = -92dBm to -85dBm */
/* 0011 = -85dBm to -75dBm */
/* 0111 = -75dBm to -50dBm */
/* 1111 = -50dBm to 0dBm */
/* Bits 4-7 = Reserved */
/* Bits 8-11 = SNR Field */
/* 0000 = <2dB */
/* 0001 = 2dB to 8dB */
/* 0011 = 8dB to 15dB */
/* 0111 = 15dB to 22dB */
/* 1111 = >22dB */
/* Bits 12-15 = Reserved */
unsigned long nTxPkts; /* Number of packets transmitted
* from host to dsp
*/
unsigned long nRxPkts; /* Number of packets received from
* dsp to host
*/
unsigned long nTxBytes; /* Number of bytes transmitted
* from host to dsp
*/
unsigned long nRxBytes; /* Number of bytes received from
* dsp to host
*/
unsigned long ConTm; /* Current session connection time
* in seconds
*/
unsigned char CalVer[CALVERSZ]; /* Proprietary Calibration
* Version
*/
unsigned char CalDate[CALDATESZ]; /* Proprietary Calibration Date */
} __packed;
/* Data structure for Dual Ported RAM messaging between Host and Dsp */
struct IOCTL_DPRAM_BLK {
unsigned short total_len;
struct pseudo_hdr pseudohdr;
unsigned char buffer[1780];
} __packed;
struct IOCTL_DPRAM_COMMAND {
unsigned short extra;
struct IOCTL_DPRAM_BLK dpram_blk;
} __packed;
/*
* Custom IOCTL command codes
*/
#define FT1000_MAGIC_CODE 'F'
#define IOCTL_REGISTER_CMD 0
#define IOCTL_SET_DPRAM_CMD 3
#define IOCTL_GET_DPRAM_CMD 4
#define IOCTL_GET_DSP_STAT_CMD 6
#define IOCTL_GET_VER_CMD 7
#define IOCTL_CONNECT 10
#define IOCTL_DISCONNECT 11
#define IOCTL_FT1000_GET_DSP_STAT _IOR(FT1000_MAGIC_CODE, \
IOCTL_GET_DSP_STAT_CMD, \
struct IOCTL_GET_DSP_STAT)
#define IOCTL_FT1000_GET_VER _IOR(FT1000_MAGIC_CODE, IOCTL_GET_VER_CMD, \
struct IOCTL_GET_VER)
#define IOCTL_FT1000_CONNECT _IO(FT1000_MAGIC_CODE, IOCTL_CONNECT)
#define IOCTL_FT1000_DISCONNECT _IO(FT1000_MAGIC_CODE, IOCTL_DISCONNECT)
#define IOCTL_FT1000_SET_DPRAM _IOW(FT1000_MAGIC_CODE, IOCTL_SET_DPRAM_CMD, \
struct IOCTL_DPRAM_BLK)
#define IOCTL_FT1000_GET_DPRAM _IOR(FT1000_MAGIC_CODE, IOCTL_GET_DPRAM_CMD, \
struct IOCTL_DPRAM_BLK)
#define IOCTL_FT1000_REGISTER _IOW(FT1000_MAGIC_CODE, IOCTL_REGISTER_CMD, \
unsigned short *)
#endif /* _FT1000IOCTLH_ */

View File

@ -1,248 +0,0 @@
/*=====================================================
* CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
*
*
* This file is part of Express Card USB Driver
*====================================================
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include "ft1000_usb.h"
#include <linux/kthread.h>
MODULE_DESCRIPTION("FT1000 EXPRESS CARD DRIVER");
MODULE_LICENSE("Dual MPL/GPL");
MODULE_SUPPORTED_DEVICE("QFT FT1000 Express Cards");
void *pFileStart;
size_t FileLength;
#define VENDOR_ID 0x1291 /* Qualcomm vendor id */
#define PRODUCT_ID 0x11 /* fake product id */
/* table of devices that work with this driver */
static struct usb_device_id id_table[] = {
{USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
{},
};
MODULE_DEVICE_TABLE(usb, id_table);
static bool gPollingfailed;
static int ft1000_poll_thread(void *arg)
{
int ret;
while (!kthread_should_stop()) {
usleep_range(10000, 11000);
if (!gPollingfailed) {
ret = ft1000_poll(arg);
if (ret != 0) {
pr_debug("polling failed\n");
gPollingfailed = true;
}
}
}
return 0;
}
static int ft1000_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
struct usb_device *dev;
unsigned numaltsetting;
int i, ret = 0, size;
struct ft1000_usb *ft1000dev;
struct ft1000_info *pft1000info = NULL;
const struct firmware *dsp_fw;
ft1000dev = kzalloc(sizeof(struct ft1000_usb), GFP_KERNEL);
if (!ft1000dev)
return -ENOMEM;
dev = interface_to_usbdev(interface);
pr_debug("usb device descriptor info - number of configuration is %d\n",
dev->descriptor.bNumConfigurations);
ft1000dev->dev = dev;
ft1000dev->status = 0;
ft1000dev->net = NULL;
ft1000dev->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
ft1000dev->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!ft1000dev->tx_urb || !ft1000dev->rx_urb) {
ret = -ENOMEM;
goto err_fw;
}
numaltsetting = interface->num_altsetting;
pr_debug("number of alt settings is: %d\n", numaltsetting);
iface_desc = interface->cur_altsetting;
pr_debug("number of endpoints is: %d\n",
iface_desc->desc.bNumEndpoints);
pr_debug("descriptor type is: %d\n", iface_desc->desc.bDescriptorType);
pr_debug("interface number is: %d\n",
iface_desc->desc.bInterfaceNumber);
pr_debug("alternatesetting is: %d\n",
iface_desc->desc.bAlternateSetting);
pr_debug("interface class is: %d\n", iface_desc->desc.bInterfaceClass);
pr_debug("control endpoint info:\n");
pr_debug("descriptor0 type -- %d\n",
iface_desc->endpoint[0].desc.bmAttributes);
pr_debug("descriptor1 type -- %d\n",
iface_desc->endpoint[1].desc.bmAttributes);
pr_debug("descriptor2 type -- %d\n",
iface_desc->endpoint[2].desc.bmAttributes);
for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
endpoint =
(struct usb_endpoint_descriptor *)&iface_desc->
endpoint[i].desc;
pr_debug("endpoint %d\n", i);
pr_debug("bEndpointAddress=%x, bmAttributes=%x\n",
endpoint->bEndpointAddress, endpoint->bmAttributes);
if (usb_endpoint_is_bulk_in(endpoint)) {
ft1000dev->bulk_in_endpointAddr =
endpoint->bEndpointAddress;
pr_debug("in: %d\n", endpoint->bEndpointAddress);
}
if (usb_endpoint_is_bulk_in(endpoint)) {
ft1000dev->bulk_out_endpointAddr =
endpoint->bEndpointAddress;
pr_debug("out: %d\n", endpoint->bEndpointAddress);
}
}
pr_debug("bulk_in=%d, bulk_out=%d\n",
ft1000dev->bulk_in_endpointAddr,
ft1000dev->bulk_out_endpointAddr);
ret = request_firmware(&dsp_fw, "ft3000.img", &dev->dev);
if (ret < 0) {
dev_err(interface->usb_dev, "Error request_firmware()\n");
goto err_fw;
}
size = max_t(uint, dsp_fw->size, 4096);
pFileStart = kmalloc(size, GFP_KERNEL);
if (!pFileStart) {
release_firmware(dsp_fw);
ret = -ENOMEM;
goto err_fw;
}
memcpy(pFileStart, dsp_fw->data, dsp_fw->size);
FileLength = dsp_fw->size;
release_firmware(dsp_fw);
pr_debug("start downloading dsp image...\n");
ret = init_ft1000_netdev(ft1000dev);
if (ret)
goto err_load;
pft1000info = netdev_priv(ft1000dev->net);
pr_debug("pft1000info=%p\n", pft1000info);
ret = dsp_reload(ft1000dev);
if (ret) {
dev_err(interface->usb_dev,
"Problem with DSP image loading\n");
goto err_load;
}
gPollingfailed = false;
ft1000dev->pPollThread =
kthread_run(ft1000_poll_thread, ft1000dev, "ft1000_poll");
if (IS_ERR(ft1000dev->pPollThread)) {
ret = PTR_ERR(ft1000dev->pPollThread);
goto err_load;
}
msleep(500);
while (!pft1000info->CardReady) {
if (gPollingfailed) {
ret = -EIO;
goto err_thread;
}
msleep(100);
pr_debug("Waiting for Card Ready\n");
}
pr_debug("Card Ready!!!! Registering network device\n");
ret = reg_ft1000_netdev(ft1000dev, interface);
if (ret)
goto err_thread;
ft1000dev->NetDevRegDone = 1;
return 0;
err_thread:
kthread_stop(ft1000dev->pPollThread);
err_load:
kfree(pFileStart);
err_fw:
usb_free_urb(ft1000dev->rx_urb);
usb_free_urb(ft1000dev->tx_urb);
kfree(ft1000dev);
return ret;
}
static void ft1000_disconnect(struct usb_interface *interface)
{
struct ft1000_info *pft1000info;
struct ft1000_usb *ft1000dev;
pft1000info = (struct ft1000_info *)usb_get_intfdata(interface);
pr_debug("In disconnect pft1000info=%p\n", pft1000info);
if (pft1000info) {
ft1000dev = pft1000info->priv;
if (ft1000dev->pPollThread)
kthread_stop(ft1000dev->pPollThread);
pr_debug("threads are terminated\n");
if (ft1000dev->net) {
pr_debug("destroy char driver\n");
ft1000_destroy_dev(ft1000dev->net);
unregister_netdev(ft1000dev->net);
pr_debug("network device unregistered\n");
free_netdev(ft1000dev->net);
}
usb_free_urb(ft1000dev->rx_urb);
usb_free_urb(ft1000dev->tx_urb);
pr_debug("urb freed\n");
kfree(ft1000dev);
}
kfree(pFileStart);
}
static struct usb_driver ft1000_usb_driver = {
.name = "ft1000usb",
.probe = ft1000_probe,
.disconnect = ft1000_disconnect,
.id_table = id_table,
};
module_usb_driver(ft1000_usb_driver);

View File

@ -1,150 +0,0 @@
#ifndef _FT1000_USB_H_
#define _FT1000_USB_H_
#include "../ft1000.h"
#include "ft1000_ioctl.h"
#define FT1000_DRV_VER 0x01010403
#define MAX_NUM_APP 6
#define MAX_MSG_LIMIT 200
#define NUM_OF_FREE_BUFFERS 1500
#define PSEUDOSZ 16
struct app_info_block {
u32 nTxMsg; /* DPRAM msg sent to DSP with app_id */
u32 nRxMsg; /* DPRAM msg rcv from dsp with app_id */
u32 nTxMsgReject; /* DPRAM msg rejected due to DSP doorbell
* set
*/
u32 nRxMsgMiss; /* DPRAM msg dropped due to overflow */
struct fown_struct *fileobject;/* Application's file object */
u16 app_id; /* Application id */
int DspBCMsgFlag;
int NumOfMsg; /* number of messages queued up */
wait_queue_head_t wait_dpram_msg;
struct list_head app_sqlist; /* link list of msgs for applicaton on
* slow queue
*/
} __packed;
#define FALSE 0
#define TRUE 1
#define FT1000_STATUS_CLOSING 0x01
#define DSPBCMSGID 0x10
/* Electrabuzz specific DPRAM mapping */
/* this is used by ft1000_usb driver - isn't that a bug? */
#undef FT1000_DPRAM_RX_BASE
#define FT1000_DPRAM_RX_BASE 0x1800 /* RX AREA (SlowQ) */
/* MEMORY MAP FOR MAGNEMITE */
/* the indexes are swapped comparing to PCMCIA - is it OK or a bug? */
#undef FT1000_MAG_DSP_LED_INDX
#define FT1000_MAG_DSP_LED_INDX 0x1 /* dsp led status for PAD
* device
*/
#undef FT1000_MAG_DSP_CON_STATE_INDX
#define FT1000_MAG_DSP_CON_STATE_INDX 0x0 /* DSP Connection Status Info */
/* Maximum times trying to get ASIC out of reset */
#define MAX_ASIC_RESET_CNT 20
#define MAX_BUF_SIZE 4096
struct ft1000_debug_dirs {
struct list_head list;
struct dentry *dent;
struct dentry *file;
int int_number;
};
struct ft1000_usb {
struct usb_device *dev;
struct net_device *net;
u32 status;
struct urb *rx_urb;
struct urb *tx_urb;
u8 tx_buf[MAX_BUF_SIZE];
u8 rx_buf[MAX_BUF_SIZE];
u8 bulk_in_endpointAddr;
u8 bulk_out_endpointAddr;
struct task_struct *pPollThread;
unsigned char fcodeldr;
unsigned char bootmode;
unsigned char usbboot;
unsigned short dspalive;
bool fProvComplete;
bool fCondResetPend;
bool fAppMsgPend;
int DeviceCreated;
int NetDevRegDone;
u8 CardNumber;
u8 DeviceName[15];
struct ft1000_debug_dirs nodes;
spinlock_t fifo_lock;
int appcnt;
struct app_info_block app_info[MAX_NUM_APP];
u16 DrvMsgPend;
unsigned short tempbuf[32];
} __packed;
struct dpram_blk {
struct list_head list;
u16 *pbuffer;
} __packed;
int ft1000_read_register(struct ft1000_usb *ft1000dev,
u16 *Data, u16 nRegIndx);
int ft1000_write_register(struct ft1000_usb *ft1000dev,
u16 value, u16 nRegIndx);
int ft1000_read_dpram32(struct ft1000_usb *ft1000dev,
u16 indx, u8 *buffer, u16 cnt);
int ft1000_write_dpram32(struct ft1000_usb *ft1000dev,
u16 indx, u8 *buffer, u16 cnt);
int ft1000_read_dpram16(struct ft1000_usb *ft1000dev,
u16 indx, u8 *buffer, u8 highlow);
int ft1000_write_dpram16(struct ft1000_usb *ft1000dev,
u16 indx, u16 value, u8 highlow);
int fix_ft1000_read_dpram32(struct ft1000_usb *ft1000dev,
u16 indx, u8 *buffer);
int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev,
u16 indx, u8 *buffer);
extern void *pFileStart;
extern size_t FileLength;
extern int numofmsgbuf;
int ft1000_close(struct net_device *dev);
int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
u32 FileLength);
extern struct list_head freercvpool;
/* lock to arbitrate free buffer list for receive command data */
extern spinlock_t free_buff_lock;
int ft1000_create_dev(struct ft1000_usb *dev);
void ft1000_destroy_dev(struct net_device *dev);
int card_send_command(struct ft1000_usb *ft1000dev,
void *ptempbuffer, int size);
struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist);
void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist);
int dsp_reload(struct ft1000_usb *ft1000dev);
int init_ft1000_netdev(struct ft1000_usb *ft1000dev);
struct usb_interface;
int reg_ft1000_netdev(struct ft1000_usb *ft1000dev,
struct usb_interface *intf);
int ft1000_poll(void *dev_id);
#endif /* _FT1000_USB_H_ */

View File

@ -1,366 +0,0 @@
/*
* Common structures and definitions for FT1000 Flarion Flash OFDM PCMCIA and
* USB devices.
*
* Originally copyright (c) 2002 Flarion Technologies
*
*/
#define DSPVERSZ 4
#define HWSERNUMSZ 16
#define SKUSZ 20
#define EUISZ 8
#define MODESZ 2
#define CALVERSZ 2
#define CALDATESZ 6
#define ELECTRABUZZ_ID 0 /* ASIC ID for Electrabuzz */
#define MAGNEMITE_ID 0x1a01 /* ASIC ID for Magnemite */
/* MEMORY MAP common to both ELECTRABUZZ and MAGNEMITE */
#define FT1000_REG_DPRAM_ADDR 0x000E /* DPADR - Dual Port Ram Indirect
* Address Register
*/
#define FT1000_REG_SUP_CTRL 0x0020 /* HCTR - Host Control Register */
#define FT1000_REG_SUP_STAT 0x0022 /* HSTAT - Host Status Register */
#define FT1000_REG_RESET 0x0024 /* HCTR - Host Control Register */
#define FT1000_REG_SUP_ISR 0x0026 /* HISR - Host Interrupt Status
* Register
*/
#define FT1000_REG_SUP_IMASK 0x0028 /* HIMASK - Host Interrupt Mask */
#define FT1000_REG_DOORBELL 0x002a /* DBELL - Door Bell Register */
#define FT1000_REG_ASIC_ID 0x002e /* ASICID - ASIC Identification
* Number
*/
/* MEMORY MAP FOR ELECTRABUZZ ASIC */
#define FT1000_REG_UFIFO_STAT 0x0000 /* UFSR - Uplink FIFO status register */
#define FT1000_REG_UFIFO_BEG 0x0002 /* UFBR - Uplink FIFO beginning
* register
*/
#define FT1000_REG_UFIFO_MID 0x0004 /* UFMR - Uplink FIFO middle register */
#define FT1000_REG_UFIFO_END 0x0006 /* UFER - Uplink FIFO end register */
#define FT1000_REG_DFIFO_STAT 0x0008 /* DFSR - Downlink FIFO status
* register
*/
#define FT1000_REG_DFIFO 0x000A /* DFR - Downlink FIFO Register */
#define FT1000_REG_DPRAM_DATA 0x000C /* DPRAM - Dual Port Indirect
* Data Register
*/
#define FT1000_REG_WATERMARK 0x0010 /* WMARK - Watermark Register */
/* MEMORY MAP FOR MAGNEMITE */
#define FT1000_REG_MAG_UFDR 0x0000 /* UFDR - Uplink FIFO Data
* Register (32-bits)
*/
#define FT1000_REG_MAG_UFDRL 0x0000 /* UFDRL - Uplink FIFO Data
* Register low-word (16-bits)
*/
#define FT1000_REG_MAG_UFDRH 0x0002 /* UFDRH - Uplink FIFO Data Register
* high-word (16-bits)
*/
#define FT1000_REG_MAG_UFER 0x0004 /* UFER - Uplink FIFO End Register */
#define FT1000_REG_MAG_UFSR 0x0006 /* UFSR - Uplink FIFO Status Register */
#define FT1000_REG_MAG_DFR 0x0008 /* DFR - Downlink FIFO Register
* (32-bits)
*/
#define FT1000_REG_MAG_DFRL 0x0008 /* DFRL - Downlink FIFO Register
* low-word (16-bits)
*/
#define FT1000_REG_MAG_DFRH 0x000a /* DFRH - Downlink FIFO Register
* high-word (16-bits)
*/
#define FT1000_REG_MAG_DFSR 0x000c /* DFSR - Downlink FIFO Status
* Register
*/
#define FT1000_REG_MAG_DPDATA 0x0010 /* DPDATA - Dual Port RAM Indirect
* Data Register (32-bits)
*/
#define FT1000_REG_MAG_DPDATAL 0x0010 /* DPDATAL - Dual Port RAM Indirect
* Data Register low-word (16-bits)
*/
#define FT1000_REG_MAG_DPDATAH 0x0012 /* DPDATAH - Dual Port RAM Indirect Data
* Register high-word (16-bits)
*/
#define FT1000_REG_MAG_WATERMARK 0x002c /* WMARK - Watermark Register */
#define FT1000_REG_MAG_VERSION 0x0030 /* LLC Version */
/* Reserved Dual Port RAM offsets for Electrabuzz */
#define FT1000_DPRAM_TX_BASE 0x0002 /* Host to PC Card Messaging Area */
#define FT1000_DPRAM_RX_BASE 0x0800 /* PC Card to Host Messaging Area */
#define FT1000_FIFO_LEN 0x07FC /* total length for DSP FIFO tracking */
#define FT1000_HI_HO 0x07FE /* heartbeat with HI/HO */
#define FT1000_DSP_STATUS 0x0FFE /* dsp status - non-zero is a request
* to reset dsp
*/
#define FT1000_DSP_LED 0x0FFA /* dsp led status for PAD device */
#define FT1000_DSP_CON_STATE 0x0FF8 /* DSP Connection Status Info */
#define FT1000_DPRAM_FEFE 0x0002 /* location for dsp ready indicator */
#define FT1000_DSP_TIMER0 0x1FF0 /* Timer Field from Basestation */
#define FT1000_DSP_TIMER1 0x1FF2 /* Timer Field from Basestation */
#define FT1000_DSP_TIMER2 0x1FF4 /* Timer Field from Basestation */
#define FT1000_DSP_TIMER3 0x1FF6 /* Timer Field from Basestation */
/* Reserved Dual Port RAM offsets for Magnemite */
#define FT1000_DPRAM_MAG_TX_BASE 0x0000 /* Host to PC Card
* Messaging Area
*/
#define FT1000_DPRAM_MAG_RX_BASE 0x0200 /* PC Card to Host
* Messaging Area
*/
#define FT1000_MAG_FIFO_LEN 0x1FF /* total length for DSP
* FIFO tracking
*/
#define FT1000_MAG_FIFO_LEN_INDX 0x1 /* low-word index */
#define FT1000_MAG_HI_HO 0x1FF /* heartbeat with HI/HO */
#define FT1000_MAG_HI_HO_INDX 0x0 /* high-word index */
#define FT1000_MAG_DSP_LED 0x3FE /* dsp led status for
* PAD device
*/
#define FT1000_MAG_DSP_LED_INDX 0x0 /* dsp led status for
* PAD device
*/
#define FT1000_MAG_DSP_CON_STATE 0x3FE /* DSP Connection Status Info */
#define FT1000_MAG_DSP_CON_STATE_INDX 0x1 /* DSP Connection Status Info */
#define FT1000_MAG_DPRAM_FEFE 0x000 /* location for dsp ready
* indicator
*/
#define FT1000_MAG_DPRAM_FEFE_INDX 0x0 /* location for dsp ready
* indicator
*/
#define FT1000_MAG_DSP_TIMER0 0x3FC /* Timer Field from
* Basestation
*/
#define FT1000_MAG_DSP_TIMER0_INDX 0x1
#define FT1000_MAG_DSP_TIMER1 0x3FC /* Timer Field from
* Basestation
*/
#define FT1000_MAG_DSP_TIMER1_INDX 0x0
#define FT1000_MAG_DSP_TIMER2 0x3FD /* Timer Field from
* Basestation
*/
#define FT1000_MAG_DSP_TIMER2_INDX 0x1
#define FT1000_MAG_DSP_TIMER3 0x3FD /* Timer Field from
* Basestation
*/
#define FT1000_MAG_DSP_TIMER3_INDX 0x0
#define FT1000_MAG_TOTAL_LEN 0x200
#define FT1000_MAG_TOTAL_LEN_INDX 0x1
#define FT1000_MAG_PH_LEN 0x200
#define FT1000_MAG_PH_LEN_INDX 0x0
#define FT1000_MAG_PORT_ID 0x201
#define FT1000_MAG_PORT_ID_INDX 0x0
#define HOST_INTF_LE 0x0 /* Host interface little endian mode */
#define HOST_INTF_BE 0x1 /* Host interface big endian mode */
/* FT1000 to Host Doorbell assignments */
#define FT1000_DB_DPRAM_RX 0x0001 /* this value indicates that DSP
* has data for host in DPRAM
*/
#define FT1000_DB_DNLD_RX 0x0002 /* Downloader handshake doorbell */
#define FT1000_ASIC_RESET_REQ 0x0004 /* DSP requesting host to
* reset the ASIC
*/
#define FT1000_DSP_ASIC_RESET 0x0008 /* DSP indicating host that
* it will reset the ASIC
*/
#define FT1000_DB_COND_RESET 0x0010 /* DSP request for a card reset. */
/* Host to FT1000 Doorbell assignments */
#define FT1000_DB_DPRAM_TX 0x0100 /* this value indicates that host
* has data for DSP in DPRAM.
*/
#define FT1000_DB_DNLD_TX 0x0200 /* Downloader handshake doorbell */
#define FT1000_ASIC_RESET_DSP 0x0400 /* Responds to FT1000_ASIC_RESET_REQ */
#define FT1000_DB_HB 0x1000 /* Indicates that supervisor has a
* heartbeat message for DSP.
*/
#define hi 0x6869 /* PC Card heartbeat values */
#define ho 0x686f /* PC Card heartbeat values */
/* Magnemite specific defines */
#define hi_mag 0x6968 /* Byte swap hi to avoid
* additional system call
*/
#define ho_mag 0x6f68 /* Byte swap ho to avoid
* additional system call
*/
/* Bit field definitions for Host Interrupt Status Register */
/* Indicate the cause of an interrupt. */
#define ISR_EMPTY 0x00 /* no bits set */
#define ISR_DOORBELL_ACK 0x01 /* Doorbell acknowledge from DSP */
#define ISR_DOORBELL_PEND 0x02 /* Doorbell pending from DSP */
#define ISR_RCV 0x04 /* Packet available in Downlink FIFO */
#define ISR_WATERMARK 0x08 /* Watermark requirements satisfied */
/* Bit field definition for Host Interrupt Mask */
#define ISR_MASK_NONE 0x0000 /* no bits set */
#define ISR_MASK_DOORBELL_ACK 0x0001 /* Doorbell acknowledge mask */
#define ISR_MASK_DOORBELL_PEND 0x0002 /* Doorbell pending mask */
#define ISR_MASK_RCV 0x0004 /* Downlink Packet available mask */
#define ISR_MASK_WATERMARK 0x0008 /* Watermark interrupt mask */
#define ISR_MASK_ALL 0xffff /* Mask all interrupts */
/* Default interrupt mask
* (Enable Doorbell pending and Packet available interrupts)
*/
#define ISR_DEFAULT_MASK 0x7ff9
/* Bit field definition for Host Control Register */
#define DSP_RESET_BIT 0x0001 /* Bit field to control
* dsp reset state
*/
/* (0 = out of reset 1 = reset) */
#define ASIC_RESET_BIT 0x0002 /* Bit field to control
* ASIC reset state
*/
/* (0 = out of reset 1 = reset) */
#define DSP_UNENCRYPTED 0x0004
#define DSP_ENCRYPTED 0x0008
#define EFUSE_MEM_DISABLE 0x0040
/* Application specific IDs */
#define DSPID 0x20
#define HOSTID 0x10
#define DSPAIRID 0x90
#define DRIVERID 0x00
#define NETWORKID 0x20
/* Size of DPRAM Message */
#define MAX_CMD_SQSIZE 1780
#define ENET_MAX_SIZE 1514
#define ENET_HEADER_SIZE 14
#define SLOWQ_TYPE 0
#define FASTQ_TYPE 1
#define MAX_DSP_SESS_REC 1024
#define DSP_QID_OFFSET 4
/* Driver message types */
#define MEDIA_STATE 0x0010
#define TIME_UPDATE 0x0020
#define DSP_PROVISION 0x0030
#define DSP_INIT_MSG 0x0050
#define DSP_HIBERNATE 0x0060
#define DSP_STORE_INFO 0x0070
#define DSP_GET_INFO 0x0071
#define GET_DRV_ERR_RPT_MSG 0x0073
#define RSP_DRV_ERR_RPT_MSG 0x0074
/* Driver Error Messages for DSP */
#define DSP_HB_INFO 0x7ef0
#define DSP_FIFO_INFO 0x7ef1
#define DSP_CONDRESET_INFO 0x7ef2
#define DSP_CMDLEN_INFO 0x7ef3
#define DSP_CMDPHCKSUM_INFO 0x7ef4
#define DSP_PKTPHCKSUM_INFO 0x7ef5
#define DSP_PKTLEN_INFO 0x7ef6
#define DSP_USER_RESET 0x7ef7
#define FIFO_FLUSH_MAXLIMIT 0x7ef8
#define FIFO_FLUSH_BADCNT 0x7ef9
#define FIFO_ZERO_LEN 0x7efa
/* Pseudo Header structure */
struct pseudo_hdr {
unsigned short length; /* length of msg body */
unsigned char source; /* hardware source id */
/* Host = 0x10 */
/* Dsp = 0x20 */
unsigned char destination; /* hardware destination id
* (refer to source)
*/
unsigned char portdest; /* software destination port id */
/* Host = 0x00 */
/* Applicaton Broadcast = 0x10 */
/* Network Stack = 0x20 */
/* Dsp OAM = 0x80 */
/* Dsp Airlink = 0x90 */
/* Dsp Loader = 0xa0 */
/* Dsp MIP = 0xb0 */
unsigned char portsrc; /* software source port id
* (refer to portdest)
*/
unsigned short sh_str_id; /* not used */
unsigned char control; /* not used */
unsigned char rsvd1;
unsigned char seq_num; /* message sequence number */
unsigned char rsvd2;
unsigned short qos_class; /* not used */
unsigned short checksum; /* pseudo header checksum */
} __packed;
struct drv_msg {
struct pseudo_hdr pseudo;
u16 type;
u16 length;
u8 data[0];
} __packed;
struct media_msg {
struct pseudo_hdr pseudo;
u16 type;
u16 length;
u16 state;
u32 ip_addr;
u32 net_mask;
u32 gateway;
u32 dns_1;
u32 dns_2;
} __packed;
struct dsp_init_msg {
struct pseudo_hdr pseudo;
u16 type;
u16 length;
u8 DspVer[DSPVERSZ]; /* DSP version number */
u8 HwSerNum[HWSERNUMSZ]; /* Hardware Serial Number */
u8 Sku[SKUSZ]; /* SKU */
u8 eui64[EUISZ]; /* EUI64 */
u8 ProductMode[MODESZ]; /* Product Mode (Market/Production) */
u8 RfCalVer[CALVERSZ]; /* Rf Calibration version */
u8 RfCalDate[CALDATESZ]; /* Rf Calibration date */
} __packed;
struct prov_record {
struct list_head list;
u8 *pprov_data;
};
struct ft1000_info {
void *priv;
struct net_device_stats stats;
u16 DrvErrNum;
u16 AsicID;
int CardReady;
int registered;
int mediastate;
u8 squeseqnum; /* sequence number on slow queue */
spinlock_t dpram_lock;
u16 fifo_cnt;
u8 DspVer[DSPVERSZ]; /* DSP version number */
u8 HwSerNum[HWSERNUMSZ]; /* Hardware Serial Number */
u8 Sku[SKUSZ]; /* SKU */
u8 eui64[EUISZ]; /* EUI64 */
time_t ConTm; /* Connection Time */
u8 ProductMode[MODESZ];
u8 RfCalVer[CALVERSZ];
u8 RfCalDate[CALDATESZ];
u16 DSP_TIME[4];
u16 LedStat;
u16 ConStat;
u16 ProgConStat;
struct list_head prov_list;
u16 DSPInfoBlklen;
int (*ft1000_reset)(void *);
u16 DSPInfoBlk[MAX_DSP_SESS_REC];
union {
u16 Rec[MAX_DSP_SESS_REC];
u32 MagRec[MAX_DSP_SESS_REC/2];
} DSPSess;
};