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:
parent
eb96c7fc24
commit
6512edec48
|
@ -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"
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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
|
|
@ -1,3 +0,0 @@
|
|||
obj-$(CONFIG_FT1000_USB) += ft1000-usb/
|
||||
obj-$(CONFIG_FT1000_PCMCIA) += ft1000-pcmcia/
|
||||
|
|
@ -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>
|
|
@ -1,2 +0,0 @@
|
|||
obj-$(CONFIG_FT1000_PCMCIA) = ft1000_pcmcia.o
|
||||
ft1000_pcmcia-y := ft1000_hw.o ft1000_dnld.o ft1000_cs.o
|
|
@ -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
|
|
@ -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
|
Binary file not shown.
|
@ -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);
|
|
@ -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
|
@ -1,3 +0,0 @@
|
|||
obj-$(CONFIG_FT1000_USB) += ft1000.o
|
||||
|
||||
ft1000-y := ft1000_debug.o ft1000_download.o ft1000_hw.o ft1000_usb.o
|
|
@ -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
|
@ -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_ */
|
|
@ -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);
|
|
@ -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_ */
|
Binary file not shown.
|
@ -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;
|
||||
};
|
Loading…
Reference in New Issue