wanpipe/patches/kdrivers/src/wan_aften/wan_aften.c

855 lines
21 KiB
C

#if defined(__LINUX__)
# include <linux/wanpipe_includes.h>
# include <linux/wanpipe.h>
# include <linux/wanpipe_cfg.h>
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
# include <wanpipe_includes.h>
# include <wanpipe.h>
# include <wanpipe_cfg.h>
#else
# error "This Operating System is not supported!"
#endif
#include "wan_aften.h"
#if 0
# define DEBUG_REG
#endif
static char *wan_drvname = "wan_aften";
static char wan_fullname[] = "WANPIPE(tm) Sangoma AFT (lite) Driver";
static char wan_copyright[] = "(c) 1995-2005 Sangoma Technologies Inc.";
static int ncards;
static sdla_t* card_list = NULL; /* adapter data space */
extern wan_iface_t wan_iface;
static int wan_aften_init(void*);
static int wan_aften_exit(void*);
#if 0
static int wan_aften_shutdown(void*);
static int wan_aften_ready_unload(void*);
#endif
static int wan_aften_setup(sdla_t *card, netdevice_t *dev);
static int wan_aften_release(sdla_t *card);
static int wan_aften_update_ports(void);
static int wan_aften_open(netdevice_t*);
static int wan_aften_close(netdevice_t*);
static int wan_aften_ioctl (netdevice_t*, struct ifreq*, wan_ioctl_cmd_t);
#if defined(__OpenBSD__)
struct cdevsw wan_aften_devsw = {
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
WAN_MODULE_DEFINE(
wan_aften,"wan_aften",
"Alex Feldman <al.feldman@sangoma.com>",
"WAN AFT Enable",
"GPL",
wan_aften_init, wan_aften_exit,/* wan_aften_shutdown, wan_aften_ready_unload,*/
&wan_aften_devsw);
#else
WAN_MODULE_DEFINE(
wan_aften,"wan_aften",
"Alex Feldman <al.feldman@sangoma.com>",
"WAN AFT Enable",
"GPL",
wan_aften_init, wan_aften_exit,/*wan_aften_shutdown, wan_aften_ready_unload,*/
NULL);
#endif
WAN_MODULE_DEPEND(wan_aften, sdladrv, 1, SDLADRV_MAJOR_VER, SDLADRV_MAJOR_VER);
WAN_MODULE_VERSION(wan_aften, WAN_AFTEN_VER);
static int wan_aften_init(void *arg)
{
struct wan_aften_priv *priv = NULL;
struct wan_dev_le *devle;
sdla_t *card, *tmp;
static int if_index = 0;
int err = 0, i;
#if defined(__OpenBSD__) || defined(__NetBSD__)
sdladrv_init();
#endif
DEBUG_EVENT("%s v%d %s\n",
wan_fullname,
WAN_AFTEN_VER,
wan_copyright);
ncards = sdla_hw_probe();
if (!ncards){
DEBUG_EVENT("No Sangoma cards found, unloading modules!\n");
return -ENODEV;
}
for (i=0;i<ncards;i++){
wan_device_t* wandev;
netdevice_t* dev;
card=wan_malloc(sizeof(sdla_t));
if (!card){
DEBUG_EVENT("%s: Failed allocate new card!\n",
wan_drvname);
goto wanpipe_init_done;
}
memset(card, 0, sizeof(sdla_t));
/* Allocate HDLC device */
if (!wan_iface.alloc || (dev = wan_iface.alloc(1,WAN_IFT_OTHER)) == NULL){
wan_free(card);
goto wanpipe_init_done;
}
devle = wan_malloc(sizeof(struct wan_dev_le));
if (devle == NULL){
DEBUG_EVENT("%s: Failed allocate memory!\n",
wan_drvname);
wan_free(card);
goto wanpipe_init_done;
}
if ((priv = wan_malloc(sizeof(struct wan_aften_priv))) == NULL){
DEBUG_EVENT("%s: Failed to allocate priv structure!\n",
wan_drvname);
wan_free(card);
wan_free(devle);
goto wanpipe_init_done;
}
priv->common.is_netdev = 1;
priv->common.iface.open = &wan_aften_open;
priv->common.iface.close = &wan_aften_close;
priv->common.iface.ioctl = &wan_aften_ioctl;
priv->common.card = card;
wan_netif_set_priv(dev, priv);
#if defined(__LINUX__)
/*sprintf(card->devname, "hdlc%d", if_index++);*/
sprintf(card->devname, "w%dg1", ++if_index);
#else
sprintf(card->devname, "w%cg1",
'a' + if_index++);
#endif
/* Register in HDLC device */
if (!wan_iface.attach || wan_iface.attach(dev, card->devname, 1)){
wan_free(devle);
if (wan_iface.free) wan_iface.free(dev);
goto wanpipe_init_done;
}
wandev = &card->wandev;
wandev->magic = ROUTER_MAGIC;
wandev->name = card->devname;
wandev->priv = card;
devle->dev = dev;
/* Set device pointer */
WAN_LIST_INIT(&wandev->dev_head);
WAN_LIST_INSERT_HEAD(&wandev->dev_head, devle, dev_link);
card->list = NULL;
if (card_list){
for(tmp = card_list;tmp->list;tmp = tmp->list);
tmp->list = card;
}else{
card_list = card;
}
#if 0
card->list = card_list;
card_list = card;
#endif
if (wan_aften_setup(card, dev)){
DEBUG_EVENT("%s: Failed setup new device!\n",
card->devname);
WAN_LIST_REMOVE(devle, dev_link);
wan_free(devle);
if (wan_iface.detach) wan_iface.detach(dev, 1);
if (wan_iface.free) wan_iface.free(dev);
if (card_list == card){
card_list = NULL;
}else{
for(tmp = card_list;
tmp->list != card; tmp = tmp->list);
tmp->list = card->list;
card->list = NULL;
}
wan_free(card);
}
}
wan_aften_update_ports();
wanpipe_init_done:
if (err) wan_aften_exit(arg);
return err;
}
static int wan_aften_exit(void *arg)
{
struct wan_dev_le *devle;
sdla_t *card;
int err = 0;
for (card=card_list;card_list;){
DEBUG_EVENT("%s: Unregistering device\n", card->devname);
devle = WAN_LIST_FIRST(&card->wandev.dev_head);
if (devle && devle->dev){
struct wan_aften_priv *priv = wan_netif_priv(devle->dev);
DEBUG_EVENT("%s: Unregistering interface...\n",
wan_netif_name(devle->dev));
if (wan_iface.detach) wan_iface.detach(devle->dev, 1);
wan_free(priv);
if (wan_iface.free) wan_iface.free(devle->dev);
WAN_LIST_REMOVE(devle, dev_link);
wan_free(devle);
}
DEBUG_EVENT("%s: Release device\n", card->devname);
wan_aften_release(card);
card_list = card->list;
wan_free(card);
card = card_list;
}
card_list=NULL;
#if defined(__OpenBSD__) || defined(__NetBSD__)
sdladrv_exit();
#endif
DEBUG_EVENT("\n");
DEBUG_EVENT("%s Unloaded.\n", wan_fullname);
return err;
}
#if 0
int wan_aften_shutdown(void *arg)
{
DEBUG_EVENT("Shutting down WAN_AFTEN module ...\n");
return 0;
}
int wan_aften_ready_unload(void *arg)
{
DEBUG_EVENT("Is WAN_AFTEN module ready to unload...\n");
return 0;
}
#endif
static int wan_aften_setup(sdla_t *card, netdevice_t *dev)
{
struct wan_aften_priv *priv = wan_netif_priv(dev);
int err;
card->hw = sdla_register(&card->hw_iface, NULL, card->devname);
if (card->hw == NULL){
DEBUG_EVENT("%s: Failed to register hw device\n",
card->devname);
goto wan_aften_setup_error;
}
err = card->hw_iface.setup(card->hw, NULL);
if (err){
DEBUG_EVENT("%s: Hardware setup Failed %d\n",
card->devname,err);
sdla_unregister(&card->hw, card->devname);
goto wan_aften_setup_error;
}
WAN_HWCALL(getcfg, (card->hw, SDLA_BUS, &priv->bus));
WAN_HWCALL(getcfg, (card->hw, SDLA_SLOT, &priv->slot));
WAN_HWCALL(getcfg, (card->hw, SDLA_IRQ, &priv->irq));
WAN_HWCALL(pci_read_config_dword,
(card->hw, 0x04, &priv->base_class));
WAN_HWCALL(pci_read_config_dword,
(card->hw, PCI_IO_BASE_DWORD, &priv->base_addr0));
WAN_HWCALL(pci_read_config_dword,
(card->hw, PCI_MEM_BASE0_DWORD, &priv->base_addr1));
DEBUG_EVENT("%s: BaseClass %X BaseAddr %X:%X IRQ %d\n",
wan_netif_name(dev),
priv->base_class,
priv->base_addr0,
priv->base_addr1,
priv->irq);
/* Save pci bridge config (if needed) */
WAN_HWCALL(getcfg, (card->hw, SDLA_PCIEXPRESS, &priv->pci_express_bridge));
if (priv->pci_express_bridge){
int off = 0;
WAN_HWCALL(pci_bridge_read_config_dword,
(card->hw, 0x04, &priv->pci_bridge_base_class));
WAN_HWCALL(pci_bridge_read_config_dword,
(card->hw, PCI_IO_BASE_DWORD, &priv->pci_bridge_base_addr0));
WAN_HWCALL(pci_bridge_read_config_dword,
(card->hw, PCI_MEM_BASE0_DWORD, &priv->pci_bridge_base_addr1));
WAN_HWCALL(pci_bridge_read_config_byte,
(card->hw, PCI_INT_LINE_BYTE, &priv->pci_bridge_irq));
for(off=0;off<=15;off++){
WAN_HWCALL(pci_bridge_read_config_dword,
(card->hw, off*4, &priv->pci_bridge_cfg[off]));
}
DEBUG_EVENT("%s: PCI_ExpressBridge: BaseClass %X BaseAddr %X:%X IRQ %d\n",
wan_netif_name(dev),
priv->pci_bridge_base_class,
priv->pci_bridge_base_addr0,
priv->pci_bridge_base_addr1,
priv->pci_bridge_irq);
}
#if defined(ENABLED_IRQ)
if(request_irq(irq, wan_aften_isr, SA_SHIRQ, card->devname, card)){
DEBUG_EVENT("%s: Can't reserve IRQ %d!\n",
card->devname, irq);
sdla_unregister(&card->hw, card->devname);
goto wan_aften_setup_error;
}
#endif
return 0;
wan_aften_setup_error:
return -EINVAL;
}
static int wan_aften_release(sdla_t *card)
{
#if defined(ENABLED_IRQ)
struct wan_aften_priv *priv = wan_netif_priv(dev);
free_irq(priv->irq, card);
#endif
if (card->hw_iface.hw_down){
card->hw_iface.hw_down(card->hw);
}
sdla_unregister(&card->hw, card->devname);
return 0;
}
static int wan_aften_update_ports(void)
{
sdla_t *card, *prev = NULL;
#if 0
unsigned char *hwprobe;
int err;
#endif
DEBUG_TEST("\n\nList of available Sangoma devices:\n");
for (card=card_list; card; card = card->list){
netdevice_t *dev;
dev = WAN_DEVLE2DEV(WAN_LIST_FIRST(&card->wandev.dev_head));
if (dev){
if (prev && prev->hw == card->hw){
card->wandev.comm_port =
prev->wandev.comm_port + 1;
}
#if 0
err = card->hw_iface.get_hwprobe(
card->hw,
card->wandev.comm_port,
(void**)&hwprobe);
if (!err){
hwprobe[strlen(hwprobe)] = '\0';
DEBUG_EVENT("%s: %s\n",
wan_netif_name(dev),
hwprobe);
}
#endif
}
prev = card;
}
return 0;
}
static int wan_aften_read_reg(sdla_t *card, wan_cmd_api_t *api_cmd, int idata)
{
if (api_cmd->len == 1){
if (api_cmd->offset <= 0x3C){
card->hw_iface.pci_read_config_byte(
card->hw,
api_cmd->offset,
(unsigned char*)&api_cmd->data[idata]);
}else{
card->hw_iface.bus_read_1(
card->hw,
api_cmd->offset,
(unsigned char*)&api_cmd->data[idata]);
}
#if defined(WAN_DEBUG_REG)
DEBUG_EVENT("%s: Reading Off=0x%08X Len=%i Data=0x%02X\n",
card->devname,
api_cmd->offset,
api_cmd->len,
*(unsigned char*)&api_cmd->data[idata]);
#endif
}else if (api_cmd->len == 2){
if (api_cmd->offset <= 0x3C){
card->hw_iface.pci_read_config_word(
card->hw,
api_cmd->offset,
(unsigned short*)&api_cmd->data[idata]);
}else{
card->hw_iface.bus_read_2(
card->hw,
api_cmd->offset,
(unsigned short*)&api_cmd->data[idata]);
}
#if defined(WAN_DEBUG_REG)
DEBUG_EVENT("%s: Reading Off=0x%08X Len=%i Data=0x%04X\n",
card->devname,
api_cmd->offset,
api_cmd->len,
*(unsigned short*)&api_cmd->data[idata]);
#endif
}else if (api_cmd->len == 4){
if (api_cmd->offset <= 0x3C){
card->hw_iface.pci_read_config_dword(
card->hw,
api_cmd->offset,
(unsigned int*)&api_cmd->data[idata]);
}else{
card->hw_iface.bus_read_4(
card->hw,
api_cmd->offset,
(unsigned int*)&api_cmd->data[idata]);
}
#if defined(WAN_DEBUG_REG)
DEBUG_EVENT("ADEBUG: %s: Reading Off=0x%08X Len=%i Data=0x%04X (idata=%d)\n",
card->devname,
api_cmd->offset,
api_cmd->len,
*(unsigned int*)&api_cmd->data[idata],
idata);
#endif
}else{
card->hw_iface.peek(
card->hw,
api_cmd->offset,
(unsigned char*)&api_cmd->data[idata],
api_cmd->len);
#if 0
memcpy_fromio((unsigned char*)&api_cmd.data[0],
(unsigned char*)vector, api_cmd.len);
#endif
#if defined(WAN_DEBUG_REG)
DEBUG_EVENT("%s: Reading Off=0x%08X Len=%i\n",
card->devname,
api_cmd->offset,
api_cmd->len);
#endif
}
return 0;
}
static int wan_aften_all_read_reg(sdla_t *card_head, wan_cmd_api_t *api_cmd)
{
sdla_t *card, *prev = NULL;
int idata = 0;
for (card=card_list; card; card = card->list){
#if 0
if (prev == NULL || prev->hw != card->hw){
#endif
if (prev == NULL||!card->hw_iface.hw_same(prev->hw, card->hw)){
wan_aften_read_reg(card, api_cmd, idata);
idata += api_cmd->len;
}
prev = card;
}
return 0;
}
static int wan_aften_write_reg(sdla_t *card, wan_cmd_api_t *api_cmd)
{
if (api_cmd->len == 1){
card->hw_iface.bus_write_1(
card->hw,
api_cmd->offset,
*(unsigned char*)&api_cmd->data[0]);
#if defined(WAN_DEBUG_REG)
DEBUG_EVENT("%s: Write Offset=0x%08X Data=0x%02X\n",
card->devname,api_cmd->offset,
*(unsigned char*)&api_cmd->data[0]);
#endif
}else if (api_cmd->len == 2){
card->hw_iface.bus_write_2(
card->hw,
api_cmd->offset,
*(unsigned short*)&api_cmd->data[0]);
#if defined(WAN_DEBUG_REG)
DEBUG_EVENT("%s: Write Offset=0x%08X Data=0x%04X\n",
card->devname,api_cmd->offset,
*(unsigned short*)&api_cmd->data[0]);
#endif
}else if (api_cmd->len == 4){
card->hw_iface.bus_write_4(
card->hw,
api_cmd->offset,
*(unsigned int*)&api_cmd->data[0]);
#if defined(WAN_DEBUG_REG)
DEBUG_EVENT("ADEBUG: %s: Write Offset=0x%08X Data=0x%08X\n",
card->devname,api_cmd->offset,
*(unsigned int*)&api_cmd->data[0]);
#endif
}else{
card->hw_iface.poke(
card->hw,
api_cmd->offset,
(unsigned char*)&api_cmd->data[0],
api_cmd->len);
#if 0
memcpy_toio((unsigned char*)vector,
(unsigned char*)&api_cmd->data[0], api_cmd->len);
#endif
}
return 0;
}
static int wan_aften_all_write_reg(sdla_t *card_head, wan_cmd_api_t *api_cmd)
{
sdla_t *card, *prev = NULL;
for (card=card_list; card; card = card->list){
#if 0
if (prev == NULL || prev->hw != card->hw){
#endif
if (prev == NULL||!card->hw_iface.hw_same(prev->hw, card->hw)){
wan_aften_write_reg(card, api_cmd);
}
prev = card;
}
return 0;
}
static int wan_aften_set_pci_bios(sdla_t *card)
{
netdevice_t *dev = NULL;
struct wan_aften_priv *priv;
dev = WAN_DEVLE2DEV(WAN_LIST_FIRST(&card->wandev.dev_head));
if (dev == NULL){
return -EINVAL;
}
priv= wan_netif_priv(dev);
DEBUG_TEST("%s: Set PCI BaseClass %X BaseAddr0 %X BaseAddr1 %X IRQ %d\n",
wan_netif_name(dev),
priv->base_class,
priv->base_addr0,
priv->base_addr1,
priv->irq);
if (priv->pci_express_bridge){
int off = 0;
WAN_HWCALL(pci_bridge_write_config_dword,
(card->hw, 0x04, priv->pci_bridge_base_class));
WAN_HWCALL(pci_bridge_write_config_dword,
(card->hw, PCI_IO_BASE_DWORD, priv->pci_bridge_base_addr0));
WAN_HWCALL(pci_bridge_write_config_dword,
(card->hw, PCI_MEM_BASE0_DWORD, priv->pci_bridge_base_addr1));
WAN_HWCALL(pci_bridge_write_config_byte,
(card->hw, PCI_INT_LINE_BYTE, priv->pci_bridge_irq));
for(off=0;off<=15;off++){
WAN_HWCALL(pci_bridge_write_config_dword,
(card->hw, off*4, priv->pci_bridge_cfg[off]));
}
}
WP_DELAY(200);
card->hw_iface.pci_write_config_dword(
card->hw, 0x04, priv->base_class);
card->hw_iface.pci_write_config_dword(
card->hw, PCI_IO_BASE_DWORD, priv->base_addr0);
card->hw_iface.pci_write_config_dword(
card->hw, PCI_MEM_BASE0_DWORD, priv->base_addr1);
card->hw_iface.pci_write_config_byte(
card->hw, PCI_INT_LINE_BYTE, priv->irq);
return 0;
}
static int wan_aften_all_set_pci_bios(sdla_t *card_head)
{
sdla_t *card, *prev = NULL;
for (card=card_list; card; card = card->list){
#if 0
if (prev == NULL || prev->hw != card->hw){
#endif
if (prev == NULL||!card->hw_iface.hw_same(prev->hw, card->hw)){
if (wan_aften_set_pci_bios(card)){
return -EINVAL;
}
}
prev = card;
}
return 0;
}
static int wan_aften_hwprobe(sdla_t *card, wan_cmd_api_t *api_cmd)
{
netdevice_t *dev;
unsigned char *str;
int err;
dev = WAN_DEVLE2DEV(WAN_LIST_FIRST(&card->wandev.dev_head));
if (dev && card->hw_iface.get_hwprobe && card->hw_iface.getcfg){
char ver;
memcpy(&api_cmd->data[api_cmd->len],
wan_netif_name(dev),
strlen(wan_netif_name(dev)));
api_cmd->len += strlen(wan_netif_name(dev));
api_cmd->data[api_cmd->len++] = ':';
api_cmd->data[api_cmd->len++] = ' ';
err = card->hw_iface.get_hwprobe(
card->hw, card->wandev.comm_port, (void**)&str);
if (err){
return err;
}
str[strlen(str)] = '\0';
memcpy(&api_cmd->data[api_cmd->len], str, strlen(str));
api_cmd->len += strlen(str); /* set to number of cards */
api_cmd->data[api_cmd->len++] = ' ';
api_cmd->data[api_cmd->len++] = '(';
api_cmd->data[api_cmd->len++] = 'V';
api_cmd->data[api_cmd->len++] = 'e';
api_cmd->data[api_cmd->len++] = 'r';
api_cmd->data[api_cmd->len++] = '.';
err = card->hw_iface.getcfg(
card->hw, SDLA_COREREV, &ver);
if (err){
return err;
}
sprintf(&api_cmd->data[api_cmd->len], "%02X", ver);
api_cmd->len += 2;
api_cmd->data[api_cmd->len++] = ')';
api_cmd->data[api_cmd->len++] = '\n';
DEBUG_TEST("%s: Read card hwprobe (%s)!\n",
wan_netif_name(dev),
api_cmd->data);
}else{
return -EINVAL;
}
return 0;
}
static int wan_aften_all_hwprobe(sdla_t *card_head, wan_cmd_api_t *api_cmd)
{
sdla_t *card, *prev=NULL;
#if 0
int bus = -1, slot = -1;
#endif
int err = 0;
for (card=card_list; card; card = card->list){
if (prev == NULL||!card->hw_iface.hw_same(prev->hw, card->hw)){
if ((err = wan_aften_hwprobe(card, api_cmd))){
return err;
}
}
prev = card;
#if 0
netdevice_t *dev = WAN_DEVLE2DEV(WAN_LIST_FIRST(&card->wandev.dev_head));
struct wan_aften_priv *priv = wan_netif_priv(dev);
if (bus == -1 ||
!(bus == priv->bus && slot == priv->slot)){
if ((err = wan_aften_hwprobe(card, api_cmd))){
return err;
}
}
bus = priv->bus;
slot = priv->slot;
#endif
}
return 0;
}
static int
wan_aften_read_pcibridge_reg(sdla_t *card, wan_cmd_api_t *api_cmd, int idata)
{
if (card->hw_iface.pci_bridge_read_config_dword == NULL){
return -EINVAL;
}
card->hw_iface.pci_bridge_read_config_dword(
card->hw,
api_cmd->offset,
(u32*)&api_cmd->data[idata]);
DEBUG_TEST("%s: Reading value from %X: %X\n",
card->devname,
api_cmd->offset,
api_cmd->data[idata]);
return 0;
}
static int
wan_aften_all_read_pcibridge_reg(sdla_t *card_head, wan_cmd_api_t *api_cmd)
{
sdla_t *card, *prev = NULL;
int idata = 0;
for (card=card_list; card; card = card->list){
if (prev == NULL||!card->hw_iface.hw_same(prev->hw, card->hw)){
wan_aften_read_pcibridge_reg(card, api_cmd, idata);
idata += api_cmd->len;
}
prev = card;
}
return 0;
}
static int wan_aften_write_pcibridge_reg(sdla_t *card, wan_cmd_api_t *api_cmd)
{
if (card->hw_iface.pci_bridge_write_config_dword == NULL){
return -EINVAL;
}
card->hw_iface.pci_bridge_write_config_dword(
card->hw,
api_cmd->offset,
*(unsigned int*)&api_cmd->data[0]);
DEBUG_TEST("%s: Writing value %X to %X\n",
card->devname,
*(unsigned int*)&api_cmd->data[0],
api_cmd->offset);
return 0;
}
static int wan_aften_all_write_pcibridge_reg(sdla_t *card_head, wan_cmd_api_t *api_cmd)
{
sdla_t *card, *prev = NULL;
for (card=card_list; card; card = card->list){
if (prev == NULL||!card->hw_iface.hw_same(prev->hw, card->hw)){
wan_aften_write_pcibridge_reg(card, api_cmd);
}
prev = card;
}
return 0;
}
static int wan_aften_open(netdevice_t *dev)
{
WAN_NETIF_START_QUEUE(dev);
return 0;
}
static int wan_aften_close(netdevice_t *dev)
{
WAN_NETIF_STOP_QUEUE(dev);
return 0;
}
static int
wan_aften_ioctl (netdevice_t *dev, struct ifreq *ifr, wan_ioctl_cmd_t cmd)
{
sdla_t *card;
struct wan_aften_priv *priv= wan_netif_priv(dev);
wan_cmd_api_t api_cmd;
int err=-EINVAL;
if (!priv || !priv->common.card){
DEBUG_EVENT("%s: Invalid structures!\n", wan_netif_name(dev));
return -ENODEV;
}
DEBUG_TEST("%s: CMD=0x%X\n",__FUNCTION__,cmd);
if (cmd != SIOC_WAN_DEVEL_IOCTL){
DEBUG_IOCTL("%s: Unsupported IOCTL call!\n",
wan_netif_name(dev));
return -EINVAL;
}
if (!ifr->ifr_data){
DEBUG_EVENT("%s: No API data!\n", wan_netif_name(dev));
return -EINVAL;
}
card = priv->common.card;
if (WAN_COPY_FROM_USER(&api_cmd,ifr->ifr_data,sizeof(wan_cmd_api_t))){
return -EFAULT;
}
/* Hardcode bar access FELD */
switch (api_cmd.cmd){
case SIOC_WAN_READ_REG:
err = wan_aften_read_reg(card, &api_cmd, 0);
break;
case SIOC_WAN_ALL_READ_REG:
err = wan_aften_all_read_reg(card_list, &api_cmd);
break;
case SIOC_WAN_WRITE_REG:
err = wan_aften_write_reg(card, &api_cmd);
break;
case SIOC_WAN_ALL_WRITE_REG:
err = wan_aften_all_write_reg(card_list, &api_cmd);
break;
case SIOC_WAN_SET_PCI_BIOS:
err = wan_aften_set_pci_bios(card);
break;
case SIOC_WAN_ALL_SET_PCI_BIOS:
err = wan_aften_all_set_pci_bios(card_list);
break;
case SIOC_WAN_HWPROBE:
DEBUG_TEST("%s: Read Sangoma device hwprobe!\n",
wan_netif_name(dev));
memset(&api_cmd.data[0], 0, WAN_MAX_DATA_SIZE);
api_cmd.len = 0;
err = wan_aften_hwprobe(card, &api_cmd);
break;
case SIOC_WAN_ALL_HWPROBE:
DEBUG_TEST("%s: Read list of Sangoma devices!\n",
wan_netif_name(dev));
memset(&api_cmd.data[0], 0, WAN_MAX_DATA_SIZE);
api_cmd.len = 0;
err = wan_aften_all_hwprobe(card, &api_cmd);
break;
case SIOC_WAN_COREREV:
if (card->hw_iface.getcfg){
err = card->hw_iface.getcfg(
card->hw,
SDLA_COREREV,
&api_cmd.data[0]);
api_cmd.len = 1;
}
DEBUG_TEST("%s: Get core revision (rev %X)!\n",
wan_netif_name(dev), api_cmd.data[0]);
break;
case SIOC_WAN_READ_PCIBRIDGE_REG:
err = wan_aften_read_pcibridge_reg(card, &api_cmd, 0);
break;
case SIOC_WAN_ALL_READ_PCIBRIDGE_REG:
err = wan_aften_all_read_pcibridge_reg(card, &api_cmd);
break;
case SIOC_WAN_WRITE_PCIBRIDGE_REG:
err = wan_aften_write_pcibridge_reg(card, &api_cmd);
break;
case SIOC_WAN_ALL_WRITE_PCIBRIDGE_REG:
err = wan_aften_all_write_pcibridge_reg(card, &api_cmd);
break;
}
if (WAN_COPY_TO_USER(ifr->ifr_data,&api_cmd,sizeof(wan_cmd_api_t))){
return -EFAULT;
}
return err;
}