X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fray_cs.c;h=61b83a5e737a719719646d37a4ff76d03b9fd949;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=e39bcddc30a370b49b8e88120fb3cd6071d0c8e6;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index e39bcddc3..61b83a5e7 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -30,7 +30,6 @@ * =============================================================================*/ -#include #include #include #include @@ -46,7 +45,6 @@ #include #include -#include #include #include #include @@ -54,7 +52,7 @@ #include #include -#ifdef CONFIG_NET_PCMCIA_RADIO +#include #include #include @@ -66,9 +64,7 @@ #define WIRELESS_SPY /* Enable spying addresses */ /* Definitions we need for spy */ typedef struct iw_statistics iw_stats; -typedef struct iw_quality iw_qual; typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */ -#endif /* CONFIG_NET_PCMCIA_RADIO */ #include "rayctl.h" #include "ray_cs.h" @@ -86,25 +82,22 @@ typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */ #ifdef PCMCIA_DEBUG static int ray_debug; static int pc_debug = PCMCIA_DEBUG; -MODULE_PARM(pc_debug, "i"); +module_param(pc_debug, int, 0); /* #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); */ #define DEBUG(n, args...) if (pc_debug>(n)) printk(args); #else #define DEBUG(n, args...) #endif /** Prototypes based on PCMCIA skeleton driver *******************************/ -static void ray_config(dev_link_t *link); -static void ray_release(dev_link_t *link); -static int ray_event(event_t event, int priority, event_callback_args_t *args); -static dev_link_t *ray_attach(void); -static void ray_detach(dev_link_t *); +static int ray_config(struct pcmcia_device *link); +static void ray_release(struct pcmcia_device *link); +static void ray_detach(struct pcmcia_device *p_dev); /***** Prototypes indicated by device structure ******************************/ static int ray_dev_close(struct net_device *dev); static int ray_dev_config(struct net_device *dev, struct ifmap *map); static struct net_device_stats *ray_get_stats(struct net_device *dev); static int ray_dev_init(struct net_device *dev); -static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static struct ethtool_ops netdev_ethtool_ops; @@ -112,14 +105,13 @@ static int ray_open(struct net_device *dev); static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev); static void set_multicast_list(struct net_device *dev); static void ray_update_multi_list(struct net_device *dev, int all); -static int translate_frame(ray_dev_t *local, struct tx_msg *ptx, +static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, unsigned char *data, int len); -static void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type, +static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type, unsigned char *data); static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len); -#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ static iw_stats * ray_get_wireless_stats(struct net_device * dev); -#endif /* WIRELESS_EXT > 7 */ +static const struct iw_handler_def ray_handler_def; /***** Prototypes for raylink functions **************************************/ static int asc_to_int(char a); @@ -140,14 +132,14 @@ static void verify_dl_startup(u_long); /* Prototypes for interrpt time functions **********************************/ static irqreturn_t ray_interrupt (int reg, void *dev_id, struct pt_regs *regs); static void clear_interrupt(ray_dev_t *local); -static void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs, +static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs, unsigned int pkt_addr, int rx_len); static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len); -static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs); -static void release_frag_chain(ray_dev_t *local, struct rcs *prcs); -static void rx_authenticate(ray_dev_t *local, struct rcs *prcs, +static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs __iomem *prcs); +static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs); +static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs, unsigned int pkt_addr, int rx_len); -static void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr, +static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned int pkt_addr, int rx_len); static void associate(ray_dev_t *local); @@ -157,15 +149,8 @@ static void join_net(u_long local); static void start_net(u_long local); /* void start_net(ray_dev_t *local); */ -/* Create symbol table for registering with kernel in init_module */ -EXPORT_SYMBOL(ray_dev_ioctl); -EXPORT_SYMBOL(ray_rx); - /*===========================================================================*/ /* Parameters that can be set with 'insmod' */ -/* Bit map of interrupts to choose from */ -/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */ -static u_long irq_mask = 0xdeb8; /* ADHOC=0, Infrastructure=1 */ static int net_type = ADHOC; @@ -204,42 +189,32 @@ static int bc; static char *phy_addr = NULL; -/* The dev_info variable is the "key" that is used to match up this - device driver with appropriate cards, through the card configuration - database. -*/ -static dev_info_t dev_info = "ray_cs"; - -/* A linked list of "instances" of the ray device. Each actual - PCMCIA card corresponds to one device instance, and is described - by one dev_link_t structure (defined in ds.h). -*/ -static dev_link_t *dev_list = NULL; - -/* A dev_link_t structure has fields for most things that are needed +/* A struct pcmcia_device structure has fields for most things that are needed to keep track of a socket, but there will usually be some device specific information that also needs to be kept track of. The - 'priv' pointer in a dev_link_t structure can be used to point to + 'priv' pointer in a struct pcmcia_device structure can be used to point to a device-specific private data structure, like this. */ static unsigned int ray_mem_speed = 500; +/* WARNING: THIS DRIVER IS NOT CAPABLE OF HANDLING MULTIPLE DEVICES! */ +static struct pcmcia_device *this_device = NULL; + MODULE_AUTHOR("Corey Thomas "); MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver"); MODULE_LICENSE("GPL"); -MODULE_PARM(irq_mask,"i"); -MODULE_PARM(net_type,"i"); -MODULE_PARM(hop_dwell,"i"); -MODULE_PARM(beacon_period,"i"); -MODULE_PARM(psm,"i"); -MODULE_PARM(essid,"s"); -MODULE_PARM(translate,"i"); -MODULE_PARM(country,"i"); -MODULE_PARM(sniffer,"i"); -MODULE_PARM(bc,"i"); -MODULE_PARM(phy_addr,"s"); -MODULE_PARM(ray_mem_speed, "i"); +module_param(net_type, int, 0); +module_param(hop_dwell, int, 0); +module_param(beacon_period, int, 0); +module_param(psm, int, 0); +module_param(essid, charp, 0); +module_param(translate, int, 0); +module_param(country, int, 0); +module_param(sniffer, int, 0); +module_param(bc, int, 0); +module_param(phy_addr, charp, 0); +module_param(ray_mem_speed, int, 0); static UCHAR b5_default_startup_parms[] = { 0, 0, /* Adhoc station */ @@ -327,69 +302,57 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey priv; - - memset(link, 0, sizeof(struct dev_link_t)); + local->finder = p_dev; /* The io structure describes IO port mapping. None used here */ - link->io.NumPorts1 = 0; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = 5; + p_dev->io.NumPorts1 = 0; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = 5; /* Interrupt setup. For PCMCIA, driver takes what's given */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; - link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID; - link->irq.IRQInfo2 = irq_mask; - link->irq.Handler = &ray_interrupt; + p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; + p_dev->irq.Handler = &ray_interrupt; /* General socket configuration */ - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - link->conf.ConfigIndex = 1; - link->conf.Present = PRESENT_OPTION; - - link->priv = dev; - link->irq.Instance = dev; + p_dev->conf.Attributes = CONF_ENABLE_IRQ; + p_dev->conf.IntType = INT_MEMORY_AND_IO; + p_dev->conf.ConfigIndex = 1; + p_dev->conf.Present = PRESENT_OPTION; + + p_dev->priv = dev; + p_dev->irq.Instance = dev; - local->finder = link; + local->finder = p_dev; local->card_status = CARD_INSERTED; local->authentication_state = UNAUTHENTICATED; local->num_multi = 0; - DEBUG(2,"ray_attach link = %p, dev = %p, local = %p, intr = %p\n", - link,dev,local,&ray_interrupt); + DEBUG(2,"ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n", + p_dev,dev,local,&ray_interrupt); /* Raylink entries in the device structure */ dev->hard_start_xmit = &ray_dev_start_xmit; dev->set_config = &ray_dev_config; dev->get_stats = &ray_get_stats; - dev->do_ioctl = &ray_dev_ioctl; SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); -#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ - dev->get_wireless_stats = ray_get_wireless_stats; -#endif + dev->wireless_handlers = &ray_handler_def; +#ifdef WIRELESS_SPY + local->wireless_data.spy_data = &local->spy_data; + dev->wireless_data = &local->wireless_data; +#endif /* WIRELESS_SPY */ dev->set_multicast_list = &set_multicast_list; @@ -400,36 +363,13 @@ static dev_link_t *ray_attach(void) dev->stop = &ray_dev_close; netif_stop_queue(dev); - /* Register with Card Services */ - link->next = dev_list; - dev_list = link; - client_reg.dev_info = &dev_info; - client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; - client_reg.EventMask = - CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | - CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | - CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; - client_reg.event_handler = &ray_event; - client_reg.Version = 0x0210; - client_reg.event_callback_args.client_data = link; - - DEBUG(2,"ray_cs ray_attach calling pcmcia_register_client(...)\n"); - init_timer(&local->timer); - ret = pcmcia_register_client(&link->handle, &client_reg); - if (ret != 0) { - printk("ray_cs ray_attach RegisterClient unhappy - detaching\n"); - cs_error(link->handle, RegisterClient, ret); - ray_detach(link); - return NULL; - } - DEBUG(2,"ray_cs ray_attach ending\n"); - return link; + this_device = p_dev; + return ray_config(p_dev); fail_alloc_dev: - kfree(link); - return NULL; + return -ENOMEM; } /* ray_attach */ /*============================================================================= This deletes a driver "instance". The device is de-registered @@ -437,38 +377,25 @@ fail_alloc_dev: structures are freed. Otherwise, the structures will be freed when the device is released. =============================================================================*/ -static void ray_detach(dev_link_t *link) +static void ray_detach(struct pcmcia_device *link) { - dev_link_t **linkp; + struct net_device *dev; + ray_dev_t *local; DEBUG(1, "ray_detach(0x%p)\n", link); - - /* Locate device structure */ - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) break; - if (*linkp == NULL) - return; - /* If the device is currently configured and active, we won't - actually delete it yet. Instead, it is marked so that when - the release() function is called, that will trigger a proper - detach(). - */ - if (link->state & DEV_CONFIG) - ray_release(link); + this_device = NULL; + dev = link->priv; + + ray_release(link); + + local = (ray_dev_t *)dev->priv; + del_timer(&local->timer); - /* Break the link with Card Services */ - if (link->handle) - pcmcia_deregister_client(link->handle); - - /* Unlink device structure, free pieces */ - *linkp = link->next; if (link->priv) { - struct net_device *dev = link->priv; - if (link->dev) unregister_netdev(dev); + if (link->dev_node) unregister_netdev(dev); free_netdev(dev); } - kfree(link); DEBUG(2,"ray_cs ray_detach ending\n"); } /* ray_detach */ /*============================================================================= @@ -479,9 +406,8 @@ static void ray_detach(dev_link_t *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) #define MAX_TUPLE_SIZE 128 -static void ray_config(dev_link_t *link) +static int ray_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; tuple_t tuple; cisparse_t parse; int last_fn = 0, last_ret = 0; @@ -496,113 +422,129 @@ static void ray_config(dev_link_t *link) /* This reads the card's CONFIG tuple to find its configuration regs */ tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); tuple.TupleData = buf; tuple.TupleDataMax = MAX_TUPLE_SIZE; tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Determine card type and firmware version */ buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0; tuple.DesiredTuple = CISTPL_VERS_1; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); tuple.TupleData = buf; tuple.TupleDataMax = MAX_TUPLE_SIZE; tuple.TupleOffset = 2; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); for (i=0; istate |= DEV_CONFIG; - /* Now allocate an interrupt line. Note that this does not actually assign a handler to the interrupt. */ - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); dev->irq = link->irq.AssignedIRQ; /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /*** Set up 32k window for shared memory (transmit and control) ************/ req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT; req.Base = 0; req.Size = 0x8000; req.AccessSpeed = ray_mem_speed; - CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win)); mem.CardOffset = 0x0000; mem.Page = 0; CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem)); - local->sram = (UCHAR *)(ioremap(req.Base,req.Size)); + local->sram = ioremap(req.Base,req.Size); /*** Set up 16k window for shared memory (receive buffer) ***************/ req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT; req.Base = 0; req.Size = 0x4000; req.AccessSpeed = ray_mem_speed; - CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->rmem_handle)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->rmem_handle)); mem.CardOffset = 0x8000; mem.Page = 0; CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem)); - local->rmem = (UCHAR *)(ioremap(req.Base,req.Size)); + local->rmem = ioremap(req.Base,req.Size); /*** Set up window for attribute memory ***********************************/ req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT; req.Base = 0; req.Size = 0x1000; req.AccessSpeed = ray_mem_speed; - CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->amem_handle)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->amem_handle)); mem.CardOffset = 0x0000; mem.Page = 0; CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem)); - local->amem = (UCHAR *)(ioremap(req.Base,req.Size)); + local->amem = ioremap(req.Base,req.Size); DEBUG(3,"ray_config sram=%p\n",local->sram); DEBUG(3,"ray_config rmem=%p\n",local->rmem); DEBUG(3,"ray_config amem=%p\n",local->amem); if (ray_init(dev) < 0) { ray_release(link); - return; + return -ENODEV; } + SET_NETDEV_DEV(dev, &handle_to_dev(link)); i = register_netdev(dev); if (i != 0) { printk("ray_config register_netdev() failed\n"); ray_release(link); - return; + return i; } strcpy(local->node.dev_name, dev->name); - link->dev = &local->node; + link->dev_node = &local->node; - link->state &= ~DEV_CONFIG_PENDING; printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ", dev->name, dev->irq); for (i = 0; i < 6; i++) printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); ray_release(link); + return -ENODEV; } /* ray_config */ + +static inline struct ccs __iomem *ccs_base(ray_dev_t *dev) +{ + return dev->sram + CCS_BASE; +} + +static inline struct rcs __iomem *rcs_base(ray_dev_t *dev) +{ + /* + * This looks nonsensical, since there is a separate + * RCS_BASE. But the difference between a "struct rcs" + * and a "struct ccs" ends up being in the _index_ off + * the base, so the base pointer is the same for both + * ccs/rcs. + */ + return dev->sram + CCS_BASE; +} + /*===========================================================================*/ static int ray_init(struct net_device *dev) { int i; UCHAR *p; - struct ccs *pccs; + struct ccs __iomem *pccs; ray_dev_t *local = (ray_dev_t *)dev->priv; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; DEBUG(1, "ray_init(0x%p)\n", dev); - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(0,"ray_init - device not present\n"); return -1; } @@ -632,7 +574,7 @@ static int ray_init(struct net_device *dev) local->tib_length = local->startup_res.tib_length; DEBUG(2,"ray_init tib_length = 0x%02x\n", local->tib_length); /* Initialize CCS's to buffer free state */ - pccs = (struct ccs *)(local->sram + CCS_BASE); + pccs = ccs_base(local); for (i=0; ibuffer_status); } @@ -661,11 +603,11 @@ static int dl_startup_params(struct net_device *dev) { int ccsindex; ray_dev_t *local = (ray_dev_t *)dev->priv; - struct ccs *pccs; - dev_link_t *link = local->finder; + struct ccs __iomem *pccs; + struct pcmcia_device *link = local->finder; DEBUG(1,"dl_startup_params entered\n"); - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs dl_startup_params - device not present\n"); return -1; } @@ -682,7 +624,7 @@ static int dl_startup_params(struct net_device *dev) /* Fill in the CCS fields for the ECF */ if ((ccsindex = get_free_ccs(local)) < 0) return -1; local->dl_param_ccs = ccsindex; - pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + pccs = ccs_base(local) + ccsindex; writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd); DEBUG(2,"dl_startup_params start ccsindex = %d\n", local->dl_param_ccs); /* Interrupt the firmware to process the command */ @@ -767,11 +709,11 @@ static void init_startup_params(ray_dev_t *local) static void verify_dl_startup(u_long data) { ray_dev_t *local = (ray_dev_t *)data; - struct ccs *pccs = ((struct ccs *)(local->sram + CCS_BASE)) + local->dl_param_ccs; + struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs; UCHAR status; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs verify_dl_startup - device not present\n"); return; } @@ -807,16 +749,16 @@ static void verify_dl_startup(u_long data) static void start_net(u_long data) { ray_dev_t *local = (ray_dev_t *)data; - struct ccs *pccs; + struct ccs __iomem *pccs; int ccsindex; - dev_link_t *link = local->finder; - if (!(link->state & DEV_PRESENT)) { + struct pcmcia_device *link = local->finder; + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs start_net - device not present\n"); return; } /* Fill in the CCS fields for the ECF */ if ((ccsindex = get_free_ccs(local)) < 0) return; - pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + pccs = ccs_base(local) + ccsindex; writeb(CCS_START_NETWORK, &pccs->cmd); writeb(0, &pccs->var.start_network.update_param); /* Interrupt the firmware to process the command */ @@ -834,17 +776,17 @@ static void join_net(u_long data) { ray_dev_t *local = (ray_dev_t *)data; - struct ccs *pccs; + struct ccs __iomem *pccs; int ccsindex; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs join_net - device not present\n"); return; } /* Fill in the CCS fields for the ECF */ if ((ccsindex = get_free_ccs(local)) < 0) return; - pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + pccs = ccs_base(local) + ccsindex; writeb(CCS_JOIN_NETWORK, &pccs->cmd); writeb(0, &pccs->var.join_network.update_param); writeb(0, &pccs->var.join_network.net_initiated); @@ -862,7 +804,7 @@ static void join_net(u_long data) device, and release the PCMCIA configuration. If the device is still open, this will be postponed until it is closed. =============================================================================*/ -static void ray_release(dev_link_t *link) +static void ray_release(struct pcmcia_device *link) { struct net_device *dev = link->priv; ray_dev_t *local = dev->priv; @@ -871,85 +813,42 @@ static void ray_release(dev_link_t *link) DEBUG(1, "ray_release(0x%p)\n", link); del_timer(&local->timer); - link->state &= ~DEV_CONFIG; iounmap(local->sram); iounmap(local->rmem); iounmap(local->amem); /* Do bother checking to see if these succeed or not */ - i = pcmcia_release_window(link->win); - if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(link->win) ret = %x\n",i); i = pcmcia_release_window(local->amem_handle); if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i); i = pcmcia_release_window(local->rmem_handle); if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i); - i = pcmcia_release_configuration(link->handle); - if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseConfiguration ret = %x\n",i); - i = pcmcia_release_irq(link->handle, &link->irq); - if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i); + pcmcia_disable_device(link); DEBUG(2,"ray_release ending\n"); } -/*============================================================================= - The card status event handler. Mostly, this schedules other - stuff to run after an event is received. A CARD_REMOVAL event - also sets some flags to discourage the net drivers from trying - to talk to the card any more. - - When a CARD_REMOVAL event is received, we immediately set a flag - to block future accesses to this device. All the functions that - actually access the device should check this flag to make sure - the card is still present. -=============================================================================*/ -static int ray_event(event_t event, int priority, - event_callback_args_t *args) +static int ray_suspend(struct pcmcia_device *link) { - dev_link_t *link = args->client_data; - struct net_device *dev = link->priv; - ray_dev_t *local = (ray_dev_t *)dev->priv; - DEBUG(1, "ray_event(0x%06x)\n", event); - - switch (event) { - case CS_EVENT_CARD_REMOVAL: - link->state &= ~DEV_PRESENT; - netif_device_detach(dev); - if (link->state & DEV_CONFIG) { - ray_release(link); - del_timer(&local->timer); - } - break; - case CS_EVENT_CARD_INSERTION: - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - ray_config(link); - break; - case CS_EVENT_PM_SUSPEND: - link->state |= DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_RESET_PHYSICAL: - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - - pcmcia_release_configuration(link->handle); - } - break; - case CS_EVENT_PM_RESUME: - link->state &= ~DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_CARD_RESET: - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - ray_reset(dev); + struct net_device *dev = link->priv; + + if (link->open) + netif_device_detach(dev); + + return 0; +} + +static int ray_resume(struct pcmcia_device *link) +{ + struct net_device *dev = link->priv; + + if (link->open) { + ray_reset(dev); netif_device_attach(dev); - } - } - break; - } - return 0; - DEBUG(2,"ray_event ending\n"); -} /* ray_event */ + } + + return 0; +} + /*===========================================================================*/ int ray_dev_init(struct net_device *dev) { @@ -957,10 +856,10 @@ int ray_dev_init(struct net_device *dev) int i; #endif /* RAY_IMMEDIATE_INIT */ ray_dev_t *local = dev->priv; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; DEBUG(1,"ray_dev_init(dev=%p)\n",dev); - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_dev_init - device not present\n"); return -1; } @@ -991,10 +890,10 @@ int ray_dev_init(struct net_device *dev) static int ray_dev_config(struct net_device *dev, struct ifmap *map) { ray_dev_t *local = dev->priv; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; /* Dummy routine to satisfy device structure */ DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map); - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_dev_config - device not present\n"); return -1; } @@ -1005,10 +904,10 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map) static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev) { ray_dev_t *local = dev->priv; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; short length = skb->len; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_dev_start_xmit - device not present\n"); return -1; } @@ -1024,8 +923,7 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev) if (length < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; length = ETH_ZLEN; } @@ -1049,10 +947,10 @@ static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, UCHAR msg_type) { ray_dev_t *local = (ray_dev_t *)dev->priv; - struct ccs *pccs; + struct ccs __iomem *pccs; int ccsindex; int offset; - struct tx_msg *ptx; /* Address of xmit buffer in PC space */ + struct tx_msg __iomem *ptx; /* Address of xmit buffer in PC space */ short int addr; /* Address of xmit buffer in card space */ DEBUG(3,"ray_hw_xmit(data=%p, len=%d, dev=%p)\n",data,len,dev); @@ -1079,7 +977,7 @@ static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, local->stats.tx_packets++; } - ptx = (struct tx_msg *)(local->sram + addr); + ptx = local->sram + addr; ray_build_header(local, ptx, msg_type, data); if (translate) { @@ -1092,7 +990,7 @@ static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, } /* fill in the CCS */ - pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + pccs = ccs_base(local) + ccsindex; len += TX_HEADER_LENGTH + offset; writeb(CCS_TX_REQUEST, &pccs->cmd); writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]); @@ -1119,21 +1017,21 @@ static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, return XMIT_OK; } /* end ray_hw_xmit */ /*===========================================================================*/ -static int translate_frame(ray_dev_t *local, struct tx_msg *ptx, unsigned char *data, +static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, unsigned char *data, int len) { unsigned short int proto = ((struct ethhdr *)data)->h_proto; if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */ DEBUG(3,"ray_cs translate_frame DIX II\n"); /* Copy LLC header to card buffer */ - memcpy_toio((UCHAR *)&ptx->var, eth2_llc, sizeof(eth2_llc)); - memcpy_toio( ((UCHAR *)&ptx->var) + sizeof(eth2_llc), (UCHAR *)&proto, 2); + memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc)); + memcpy_toio( ((void __iomem *)&ptx->var) + sizeof(eth2_llc), (UCHAR *)&proto, 2); if ((proto == 0xf380) || (proto == 0x3781)) { /* This is the selective translation table, only 2 entries */ - writeb(0xf8, (UCHAR *) &((struct snaphdr_t *)ptx->var)->org[3]); + writeb(0xf8, &((struct snaphdr_t __iomem *)ptx->var)->org[3]); } /* Copy body of ethernet packet without ethernet header */ - memcpy_toio((UCHAR *)&ptx->var + sizeof(struct snaphdr_t), \ + memcpy_toio((void __iomem *)&ptx->var + sizeof(struct snaphdr_t), \ data + ETH_HLEN, len - ETH_HLEN); return (int) sizeof(struct snaphdr_t) - ETH_HLEN; } @@ -1141,16 +1039,16 @@ static int translate_frame(ray_dev_t *local, struct tx_msg *ptx, unsigned char * DEBUG(3,"ray_cs translate_frame 802\n"); if (proto == 0xffff) { /* evil netware IPX 802.3 without LLC */ DEBUG(3,"ray_cs translate_frame evil IPX\n"); - memcpy_toio((UCHAR *)&ptx->var, data + ETH_HLEN, len - ETH_HLEN); + memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN); return 0 - ETH_HLEN; } - memcpy_toio((UCHAR *)&ptx->var, data + ETH_HLEN, len - ETH_HLEN); + memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN); return 0 - ETH_HLEN; } /* TBD do other frame types */ } /* end translate_frame */ /*===========================================================================*/ -static void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type, +static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type, unsigned char *data) { writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1); @@ -1200,479 +1098,518 @@ static struct ethtool_ops netdev_ethtool_ops = { /*====================================================================*/ -static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get protocol name + */ +static int ray_get_name(struct net_device *dev, + struct iw_request_info *info, + char *cwrq, + char *extra) { - ray_dev_t *local = (ray_dev_t *)dev->priv; - dev_link_t *link = local->finder; - int err = 0; -#if WIRELESS_EXT > 7 - struct iwreq *wrq = (struct iwreq *) ifr; -#endif /* WIRELESS_EXT > 7 */ - - if (!(link->state & DEV_PRESENT)) { - DEBUG(2,"ray_dev_ioctl - device not present\n"); - return -1; - } - DEBUG(2,"ray_cs IOCTL dev=%p, ifr=%p, cmd = 0x%x\n",dev,ifr,cmd); - /* Validate the command */ - switch (cmd) - { -#if WIRELESS_EXT > 7 - /* --------------- WIRELESS EXTENSIONS --------------- */ - /* Get name */ - case SIOCGIWNAME: - strcpy(wrq->u.name, "IEEE 802.11-FH"); - break; - - /* Get frequency/channel */ - case SIOCGIWFREQ: - wrq->u.freq.m = local->sparm.b5.a_hop_pattern; - wrq->u.freq.e = 0; - break; - - /* Set frequency/channel */ - case SIOCSIWFREQ: - /* Reject if card is already initialised */ - if(local->card_status != CARD_AWAITING_PARAM) - { - err = -EBUSY; - break; - } + strcpy(cwrq, "IEEE 802.11-FH"); + return 0; +} - /* Setting by channel number */ - if ((wrq->u.freq.m > USA_HOP_MOD) || (wrq->u.freq.e > 0)) - err = -EOPNOTSUPP; - else - local->sparm.b5.a_hop_pattern = wrq->u.freq.m; - break; +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : set frequency + */ +static int ray_set_freq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *fwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + int err = -EINPROGRESS; /* Call commit handler */ - /* Get current network name (ESSID) */ - case SIOCGIWESSID: - if (wrq->u.data.pointer) - { - char essid[IW_ESSID_MAX_SIZE + 1]; - /* Get the essid that was set */ - memcpy(essid, local->sparm.b5.a_current_ess_id, - IW_ESSID_MAX_SIZE); - essid[IW_ESSID_MAX_SIZE] = '\0'; - - /* Push it out ! */ - wrq->u.data.length = strlen(essid) + 1; - wrq->u.data.flags = 1; /* active */ - if (copy_to_user(wrq->u.data.pointer, essid, sizeof(essid))) - err = -EFAULT; - } - break; + /* Reject if card is already initialised */ + if(local->card_status != CARD_AWAITING_PARAM) + return -EBUSY; - /* Set desired network name (ESSID) */ - case SIOCSIWESSID: - /* Reject if card is already initialised */ - if(local->card_status != CARD_AWAITING_PARAM) - { - err = -EBUSY; - break; - } + /* Setting by channel number */ + if ((fwrq->m > USA_HOP_MOD) || (fwrq->e > 0)) + err = -EOPNOTSUPP; + else + local->sparm.b5.a_hop_pattern = fwrq->m; - if (wrq->u.data.pointer) - { - char card_essid[IW_ESSID_MAX_SIZE + 1]; - - /* Check if we asked for `any' */ - if(wrq->u.data.flags == 0) - { + return err; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get frequency + */ +static int ray_get_freq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *fwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + + fwrq->m = local->sparm.b5.a_hop_pattern; + fwrq->e = 0; + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : set ESSID + */ +static int ray_set_essid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + + /* Reject if card is already initialised */ + if(local->card_status != CARD_AWAITING_PARAM) + return -EBUSY; + + /* Check if we asked for `any' */ + if(dwrq->flags == 0) { /* Corey : can you do that ? */ - err = -EOPNOTSUPP; - } - else - { + return -EOPNOTSUPP; + } else { /* Check the size of the string */ - if(wrq->u.data.length > - IW_ESSID_MAX_SIZE + 1) - { - err = -E2BIG; - break; - } - if (copy_from_user(card_essid, - wrq->u.data.pointer, - wrq->u.data.length)) { - err = -EFAULT; - break; + if(dwrq->length > IW_ESSID_MAX_SIZE + 1) { + return -E2BIG; } - card_essid[IW_ESSID_MAX_SIZE] = '\0'; /* Set the ESSID in the card */ - memcpy(local->sparm.b5.a_current_ess_id, card_essid, - IW_ESSID_MAX_SIZE); - } + memset(local->sparm.b5.a_current_ess_id, 0, IW_ESSID_MAX_SIZE); + memcpy(local->sparm.b5.a_current_ess_id, extra, dwrq->length); } - break; - - /* Get current Access Point (BSSID in our case) */ - case SIOCGIWAP: - memcpy(wrq->u.ap_addr.sa_data, local->bss_id, ETH_ALEN); - wrq->u.ap_addr.sa_family = ARPHRD_ETHER; - break; - - /* Get the current bit-rate */ - case SIOCGIWRATE: - if(local->net_default_tx_rate == 3) - wrq->u.bitrate.value = 2000000; /* Hum... */ - else - wrq->u.bitrate.value = local->net_default_tx_rate * 500000; - wrq->u.bitrate.fixed = 0; /* We are in auto mode */ - break; - - /* Set the desired bit-rate */ - case SIOCSIWRATE: - /* Check if rate is in range */ - if((wrq->u.bitrate.value != 1000000) && - (wrq->u.bitrate.value != 2000000)) - { - err = -EINVAL; - break; - } - /* Hack for 1.5 Mb/s instead of 2 Mb/s */ - if((local->fw_ver == 0x55) && /* Please check */ - (wrq->u.bitrate.value == 2000000)) - local->net_default_tx_rate = 3; - else - local->net_default_tx_rate = wrq->u.bitrate.value/500000; - break; - - /* Get the current RTS threshold */ - case SIOCGIWRTS: - wrq->u.rts.value = (local->sparm.b5.a_rts_threshold[0] << 8) - + local->sparm.b5.a_rts_threshold[1]; -#if WIRELESS_EXT > 8 - wrq->u.rts.disabled = (wrq->u.rts.value == 32767); -#endif /* WIRELESS_EXT > 8 */ - wrq->u.rts.fixed = 1; - break; - - /* Set the desired RTS threshold */ - case SIOCSIWRTS: - { - int rthr = wrq->u.rts.value; - /* Reject if card is already initialised */ - if(local->card_status != CARD_AWAITING_PARAM) - { - err = -EBUSY; - break; - } + return -EINPROGRESS; /* Call commit handler */ +} - /* if(wrq->u.rts.fixed == 0) we should complain */ -#if WIRELESS_EXT > 8 - if(wrq->u.rts.disabled) - rthr = 32767; +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get ESSID + */ +static int ray_get_essid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + + /* Get the essid that was set */ + memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); + extra[IW_ESSID_MAX_SIZE] = '\0'; + + /* Push it out ! */ + dwrq->length = strlen(extra); + dwrq->flags = 1; /* active */ + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get AP address + */ +static int ray_get_wap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *awrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + + memcpy(awrq->sa_data, local->bss_id, ETH_ALEN); + awrq->sa_family = ARPHRD_ETHER; + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : set Bit-Rate + */ +static int ray_set_rate(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + + /* Reject if card is already initialised */ + if(local->card_status != CARD_AWAITING_PARAM) + return -EBUSY; + + /* Check if rate is in range */ + if((vwrq->value != 1000000) && (vwrq->value != 2000000)) + return -EINVAL; + + /* Hack for 1.5 Mb/s instead of 2 Mb/s */ + if((local->fw_ver == 0x55) && /* Please check */ + (vwrq->value == 2000000)) + local->net_default_tx_rate = 3; else -#endif /* WIRELESS_EXT > 8 */ - if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */ - { - err = -EINVAL; - break; - } + local->net_default_tx_rate = vwrq->value/500000; + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get Bit-Rate + */ +static int ray_get_rate(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + + if(local->net_default_tx_rate == 3) + vwrq->value = 2000000; /* Hum... */ + else + vwrq->value = local->net_default_tx_rate * 500000; + vwrq->fixed = 0; /* We are in auto mode */ + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : set RTS threshold + */ +static int ray_set_rts(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + int rthr = vwrq->value; + + /* Reject if card is already initialised */ + if(local->card_status != CARD_AWAITING_PARAM) + return -EBUSY; + + /* if(wrq->u.rts.fixed == 0) we should complain */ + if(vwrq->disabled) + rthr = 32767; + else { + if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */ + return -EINVAL; + } local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF; local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF; - } - break; - /* Get the current fragmentation threshold */ - case SIOCGIWFRAG: - wrq->u.frag.value = (local->sparm.b5.a_frag_threshold[0] << 8) - + local->sparm.b5.a_frag_threshold[1]; -#if WIRELESS_EXT > 8 - wrq->u.frag.disabled = (wrq->u.frag.value == 32767); -#endif /* WIRELESS_EXT > 8 */ - wrq->u.frag.fixed = 1; - break; + return -EINPROGRESS; /* Call commit handler */ +} - /* Set the desired fragmentation threshold */ - case SIOCSIWFRAG: - { - int fthr = wrq->u.frag.value; - /* Reject if card is already initialised */ - if(local->card_status != CARD_AWAITING_PARAM) - { - err = -EBUSY; - break; - } +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get RTS threshold + */ +static int ray_get_rts(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + + vwrq->value = (local->sparm.b5.a_rts_threshold[0] << 8) + + local->sparm.b5.a_rts_threshold[1]; + vwrq->disabled = (vwrq->value == 32767); + vwrq->fixed = 1; + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : set Fragmentation threshold + */ +static int ray_set_frag(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + int fthr = vwrq->value; + + /* Reject if card is already initialised */ + if(local->card_status != CARD_AWAITING_PARAM) + return -EBUSY; /* if(wrq->u.frag.fixed == 0) should complain */ -#if WIRELESS_EXT > 8 - if(wrq->u.frag.disabled) - fthr = 32767; - else -#endif /* WIRELESS_EXT > 8 */ - if((fthr < 256) || (fthr > 2347)) /* To check out ! */ - { - err = -EINVAL; - break; - } + if(vwrq->disabled) + fthr = 32767; + else { + if((fthr < 256) || (fthr > 2347)) /* To check out ! */ + return -EINVAL; + } local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF; local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF; - } - break; -#endif /* WIRELESS_EXT > 7 */ -#if WIRELESS_EXT > 8 + return -EINPROGRESS; /* Call commit handler */ +} - /* Get the current mode of operation */ - case SIOCGIWMODE: - if(local->sparm.b5.a_network_type) - wrq->u.mode = IW_MODE_INFRA; - else - wrq->u.mode = IW_MODE_ADHOC; - break; +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get Fragmentation threshold + */ +static int ray_get_frag(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; - /* Set the current mode of operation */ - case SIOCSIWMODE: - { + vwrq->value = (local->sparm.b5.a_frag_threshold[0] << 8) + + local->sparm.b5.a_frag_threshold[1]; + vwrq->disabled = (vwrq->value == 32767); + vwrq->fixed = 1; + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : set Mode of Operation + */ +static int ray_set_mode(struct net_device *dev, + struct iw_request_info *info, + __u32 *uwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + int err = -EINPROGRESS; /* Call commit handler */ char card_mode = 1; - - /* Reject if card is already initialised */ - if(local->card_status != CARD_AWAITING_PARAM) - { - err = -EBUSY; - break; - } - switch (wrq->u.mode) + /* Reject if card is already initialised */ + if(local->card_status != CARD_AWAITING_PARAM) + return -EBUSY; + + switch (*uwrq) { case IW_MODE_ADHOC: - card_mode = 0; - // Fall through + card_mode = 0; + // Fall through case IW_MODE_INFRA: - local->sparm.b5.a_network_type = card_mode; - break; + local->sparm.b5.a_network_type = card_mode; + break; default: - err = -EINVAL; + err = -EINVAL; } - } - break; -#endif /* WIRELESS_EXT > 8 */ -#if WIRELESS_EXT > 7 - /* ------------------ IWSPY SUPPORT ------------------ */ - /* Define the range (variations) of above parameters */ - case SIOCGIWRANGE: - /* Basic checking... */ - if(wrq->u.data.pointer != (caddr_t) 0) - { - struct iw_range range; - memset((char *) &range, 0, sizeof(struct iw_range)); - - /* Set the length (very important for backward compatibility) */ - wrq->u.data.length = sizeof(struct iw_range); - -#if WIRELESS_EXT > 10 - /* Set the Wireless Extension versions */ - range.we_version_compiled = WIRELESS_EXT; - range.we_version_source = 9; -#endif /* WIRELESS_EXT > 10 */ - - /* Set information in the range struct */ - range.throughput = 1.1 * 1000 * 1000; /* Put the right number here */ - range.num_channels = hop_pattern_length[(int)country]; - range.num_frequency = 0; - range.max_qual.qual = 0; - range.max_qual.level = 255; /* What's the correct value ? */ - range.max_qual.noise = 255; /* Idem */ - range.num_bitrates = 2; - range.bitrate[0] = 1000000; /* 1 Mb/s */ - range.bitrate[1] = 2000000; /* 2 Mb/s */ - - /* Copy structure to the user buffer */ - if(copy_to_user(wrq->u.data.pointer, &range, - sizeof(struct iw_range))) - err = -EFAULT; - } - break; + return err; +} -#ifdef WIRELESS_SPY - /* Set addresses to spy */ - case SIOCSIWSPY: - /* Check the number of addresses */ - if(wrq->u.data.length > IW_MAX_SPY) - { - err = -E2BIG; - break; - } - local->spy_number = wrq->u.data.length; +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get Mode of Operation + */ +static int ray_get_mode(struct net_device *dev, + struct iw_request_info *info, + __u32 *uwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; - /* If there is some addresses to copy */ - if(local->spy_number > 0) - { - struct sockaddr address[IW_MAX_SPY]; - int i; - - /* Copy addresses to the driver */ - if(copy_from_user(address, wrq->u.data.pointer, - sizeof(struct sockaddr) * local->spy_number)) - { - err = -EFAULT; - break; - } - - /* Copy addresses to the lp structure */ - for(i = 0; i < local->spy_number; i++) - memcpy(local->spy_address[i], address[i].sa_data, ETH_ALEN); - - /* Reset structure... */ - memset(local->spy_stat, 0x00, sizeof(iw_qual) * IW_MAX_SPY); - -#ifdef DEBUG_IOCTL_INFO - printk(KERN_DEBUG "SetSpy - Set of new addresses is :\n"); - for(i = 0; i < local->spy_number; i++) - printk(KERN_DEBUG "%02X:%02X:%02X:%02X:%02X:%02X\n", - local->spy_address[i][0], - local->spy_address[i][1], - local->spy_address[i][2], - local->spy_address[i][3], - local->spy_address[i][4], - local->spy_address[i][5]); -#endif /* DEBUG_IOCTL_INFO */ - } - break; + if(local->sparm.b5.a_network_type) + *uwrq = IW_MODE_INFRA; + else + *uwrq = IW_MODE_ADHOC; - /* Get the spy list and spy stats */ - case SIOCGIWSPY: - /* Set the number of addresses */ - wrq->u.data.length = local->spy_number; + return 0; +} - /* If the user want to have the addresses back... */ - if((local->spy_number > 0) && (wrq->u.data.pointer != (caddr_t) 0)) - { - struct sockaddr address[IW_MAX_SPY]; - int i; - - /* Copy addresses from the lp structure */ - for(i = 0; i < local->spy_number; i++) - { - memcpy(address[i].sa_data, local->spy_address[i], ETH_ALEN); - address[i].sa_family = ARPHRD_ETHER; - } - - /* Copy addresses to the user buffer */ - if(copy_to_user(wrq->u.data.pointer, address, - sizeof(struct sockaddr) * local->spy_number)) - { - err = -EFAULT; - break; - } - - /* Copy stats to the user buffer (just after) */ - if(copy_to_user(wrq->u.data.pointer + - (sizeof(struct sockaddr) * local->spy_number), - local->spy_stat, sizeof(iw_qual) * local->spy_number)) - { - err = -EFAULT; - break; - } - - /* Reset updated flags */ - for(i = 0; i < local->spy_number; i++) - local->spy_stat[i].updated = 0x0; - } /* if(pointer != NULL) */ - - break; -#endif /* WIRELESS_SPY */ +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get range info + */ +static int ray_get_range(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra) +{ + struct iw_range *range = (struct iw_range *) extra; + + memset((char *) range, 0, sizeof(struct iw_range)); + + /* Set the length (very important for backward compatibility) */ + dwrq->length = sizeof(struct iw_range); + + /* Set the Wireless Extension versions */ + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 9; + + /* Set information in the range struct */ + range->throughput = 1.1 * 1000 * 1000; /* Put the right number here */ + range->num_channels = hop_pattern_length[(int)country]; + range->num_frequency = 0; + range->max_qual.qual = 0; + range->max_qual.level = 255; /* What's the correct value ? */ + range->max_qual.noise = 255; /* Idem */ + range->num_bitrates = 2; + range->bitrate[0] = 1000000; /* 1 Mb/s */ + range->bitrate[1] = 2000000; /* 2 Mb/s */ + return 0; +} - /* ------------------ PRIVATE IOCTL ------------------ */ -#ifndef SIOCIWFIRSTPRIV -#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE -#endif /* SIOCIWFIRSTPRIV */ -#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */ -#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1 /* Get framing mode */ -#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */ - case SIOCSIPFRAMING: - if(!capable(CAP_NET_ADMIN)) /* For private IOCTLs, we need to check permissions */ - { - err = -EPERM; - break; - } - translate = *(wrq->u.name); /* Set framing mode */ - break; - case SIOCGIPFRAMING: - *(wrq->u.name) = translate; - break; - case SIOCGIPCOUNTRY: - *(wrq->u.name) = country; - break; - case SIOCGIWPRIV: - /* Export our "private" intercace */ - if(wrq->u.data.pointer != (caddr_t) 0) - { - struct iw_priv_args priv[] = - { /* cmd, set_args, get_args, name */ - { SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" }, - { SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" }, - { SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" }, - }; - /* Set the number of ioctl available */ - wrq->u.data.length = 3; - /* Copy structure to the user buffer */ - if(copy_to_user(wrq->u.data.pointer, (u_char *) priv, - sizeof(priv))) - err = -EFAULT; - } - break; -#endif /* WIRELESS_EXT > 7 */ +/*------------------------------------------------------------------*/ +/* + * Wireless Private Handler : set framing mode + */ +static int ray_set_framing(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + translate = *(extra); /* Set framing mode */ + return 0; +} - default: - DEBUG(0,"ray_dev_ioctl cmd = 0x%x\n", cmd); - err = -EOPNOTSUPP; - } - return err; -} /* end ray_dev_ioctl */ -/*===========================================================================*/ -#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ +/*------------------------------------------------------------------*/ +/* + * Wireless Private Handler : get framing mode + */ +static int ray_get_framing(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + *(extra) = translate; + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Private Handler : get country + */ +static int ray_get_country(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + *(extra) = country; + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Commit handler : called after a bunch of SET operations + */ +static int ray_commit(struct net_device *dev, + struct iw_request_info *info, /* NULL */ + void *zwrq, /* NULL */ + char *extra) /* NULL */ +{ + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Stats handler : return Wireless Stats + */ static iw_stats * ray_get_wireless_stats(struct net_device * dev) { ray_dev_t * local = (ray_dev_t *) dev->priv; - dev_link_t *link = local->finder; - struct status *p = (struct status *)(local->sram + STATUS_BASE); + struct pcmcia_device *link = local->finder; + struct status __iomem *p = local->sram + STATUS_BASE; if(local == (ray_dev_t *) NULL) return (iw_stats *) NULL; local->wstats.status = local->card_status; #ifdef WIRELESS_SPY - if((local->spy_number > 0) && (local->sparm.b5.a_network_type == 0)) + if((local->spy_data.spy_number > 0) && (local->sparm.b5.a_network_type == 0)) { /* Get it from the first node in spy list */ - local->wstats.qual.qual = local->spy_stat[0].qual; - local->wstats.qual.level = local->spy_stat[0].level; - local->wstats.qual.noise = local->spy_stat[0].noise; - local->wstats.qual.updated = local->spy_stat[0].updated; + local->wstats.qual.qual = local->spy_data.spy_stat[0].qual; + local->wstats.qual.level = local->spy_data.spy_stat[0].level; + local->wstats.qual.noise = local->spy_data.spy_stat[0].noise; + local->wstats.qual.updated = local->spy_data.spy_stat[0].updated; } #endif /* WIRELESS_SPY */ - if((link->state & DEV_PRESENT)) { + if(pcmcia_dev_present(link)) { local->wstats.qual.noise = readb(&p->rxnoise); local->wstats.qual.updated |= 4; } return &local->wstats; } /* end ray_get_wireless_stats */ -#endif /* WIRELESS_EXT > 7 */ + +/*------------------------------------------------------------------*/ +/* + * Structures to export the Wireless Handlers + */ + +static const iw_handler ray_handler[] = { + [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) ray_commit, + [SIOCGIWNAME -SIOCIWFIRST] = (iw_handler) ray_get_name, + [SIOCSIWFREQ -SIOCIWFIRST] = (iw_handler) ray_set_freq, + [SIOCGIWFREQ -SIOCIWFIRST] = (iw_handler) ray_get_freq, + [SIOCSIWMODE -SIOCIWFIRST] = (iw_handler) ray_set_mode, + [SIOCGIWMODE -SIOCIWFIRST] = (iw_handler) ray_get_mode, + [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) ray_get_range, +#ifdef WIRELESS_SPY + [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy, + [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy, + [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy, + [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy, +#endif /* WIRELESS_SPY */ + [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) ray_get_wap, + [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) ray_set_essid, + [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) ray_get_essid, + [SIOCSIWRATE -SIOCIWFIRST] = (iw_handler) ray_set_rate, + [SIOCGIWRATE -SIOCIWFIRST] = (iw_handler) ray_get_rate, + [SIOCSIWRTS -SIOCIWFIRST] = (iw_handler) ray_set_rts, + [SIOCGIWRTS -SIOCIWFIRST] = (iw_handler) ray_get_rts, + [SIOCSIWFRAG -SIOCIWFIRST] = (iw_handler) ray_set_frag, + [SIOCGIWFRAG -SIOCIWFIRST] = (iw_handler) ray_get_frag, +}; + +#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */ +#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1 /* Get framing mode */ +#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */ + +static const iw_handler ray_private_handler[] = { + [0] = (iw_handler) ray_set_framing, + [1] = (iw_handler) ray_get_framing, + [3] = (iw_handler) ray_get_country, +}; + +static const struct iw_priv_args ray_private_args[] = { +/* cmd, set_args, get_args, name */ +{ SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" }, +{ SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" }, +{ SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" }, +}; + +static const struct iw_handler_def ray_handler_def = +{ + .num_standard = sizeof(ray_handler)/sizeof(iw_handler), + .num_private = sizeof(ray_private_handler)/sizeof(iw_handler), + .num_private_args = sizeof(ray_private_args)/sizeof(struct iw_priv_args), + .standard = ray_handler, + .private = ray_private_handler, + .private_args = ray_private_args, + .get_wireless_stats = ray_get_wireless_stats, +}; + /*===========================================================================*/ static int ray_open(struct net_device *dev) { - dev_link_t *link; ray_dev_t *local = (ray_dev_t *)dev->priv; + struct pcmcia_device *link; + link = local->finder; DEBUG(1, "ray_open('%s')\n", dev->name); - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - if (!DEV_OK(link)) { - return -ENODEV; - } - - if (link->open == 0) local->num_multi = 0; + if (link->open == 0) + local->num_multi = 0; link->open++; /* If the card is not started, time to start it ! - Jean II */ @@ -1699,15 +1636,12 @@ static int ray_open(struct net_device *dev) /*===========================================================================*/ static int ray_dev_close(struct net_device *dev) { - dev_link_t *link; + ray_dev_t *local = (ray_dev_t *)dev->priv; + struct pcmcia_device *link; + link = local->finder; DEBUG(1, "ray_dev_close('%s')\n", dev->name); - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - if (link == NULL) - return -ENODEV; - link->open--; netif_stop_queue(dev); @@ -1729,9 +1663,9 @@ static void ray_reset(struct net_device *dev) { static int interrupt_ecf(ray_dev_t *local, int ccs) { int i = 50; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs interrupt_ecf - device not present\n"); return -1; } @@ -1755,10 +1689,10 @@ static int interrupt_ecf(ray_dev_t *local, int ccs) static int get_free_tx_ccs(ray_dev_t *local) { int i; - struct ccs *pccs = (struct ccs *)(local->sram + CCS_BASE); - dev_link_t *link = local->finder; + struct ccs __iomem *pccs = ccs_base(local); + struct pcmcia_device *link = local->finder; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n"); return ECARDGONE; } @@ -1786,10 +1720,10 @@ static int get_free_tx_ccs(ray_dev_t *local) static int get_free_ccs(ray_dev_t *local) { int i; - struct ccs *pccs = (struct ccs *)(local->sram + CCS_BASE); - dev_link_t *link = local->finder; + struct ccs __iomem *pccs = ccs_base(local); + struct pcmcia_device *link = local->finder; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs get_free_ccs - device not present\n"); return ECARDGONE; } @@ -1862,9 +1796,9 @@ static int parse_addr(char *in_str, UCHAR *out) static struct net_device_stats *ray_get_stats(struct net_device *dev) { ray_dev_t *local = (ray_dev_t *)dev->priv; - dev_link_t *link = local->finder; - struct status *p = (struct status *)(local->sram + STATUS_BASE); - if (!(link->state & DEV_PRESENT)) { + struct pcmcia_device *link = local->finder; + struct status __iomem *p = local->sram + STATUS_BASE; + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs net_device_stats - device not present\n"); return &local->stats; } @@ -1892,12 +1826,12 @@ static struct net_device_stats *ray_get_stats(struct net_device *dev) static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len) { ray_dev_t *local = (ray_dev_t *)dev->priv; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; int ccsindex; int i; - struct ccs *pccs; + struct ccs __iomem *pccs; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_update_parm - device not present\n"); return; } @@ -1907,7 +1841,7 @@ static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, i DEBUG(0,"ray_update_parm - No free ccs\n"); return; } - pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + pccs = ccs_base(local) + ccsindex; writeb(CCS_UPDATE_PARAMS, &pccs->cmd); writeb(objid, &pccs->var.update_param.object_id); writeb(1, &pccs->var.update_param.number_objects); @@ -1926,13 +1860,13 @@ static void ray_update_multi_list(struct net_device *dev, int all) { struct dev_mc_list *dmi, **dmip; int ccsindex; - struct ccs *pccs; + struct ccs __iomem *pccs; int i = 0; ray_dev_t *local = (ray_dev_t *)dev->priv; - dev_link_t *link = local->finder; - UCHAR *p = local->sram + HOST_TO_ECF_BASE; + struct pcmcia_device *link = local->finder; + void __iomem *p = local->sram + HOST_TO_ECF_BASE; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_update_multi_list - device not present\n"); return; } @@ -1943,7 +1877,7 @@ static void ray_update_multi_list(struct net_device *dev, int all) DEBUG(1,"ray_update_multi - No free ccs\n"); return; } - pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + pccs = ccs_base(local) + ccsindex; writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd); if (all) { @@ -2009,10 +1943,10 @@ static void set_multicast_list(struct net_device *dev) static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = (struct net_device *)dev_id; - dev_link_t *link; + struct pcmcia_device *link; ray_dev_t *local; - struct ccs *pccs; - struct rcs *prcs; + struct ccs __iomem *pccs; + struct rcs __iomem *prcs; UCHAR rcsindex; UCHAR tmp; UCHAR cmd; @@ -2024,12 +1958,12 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev); local = (ray_dev_t *)dev->priv; - link = (dev_link_t *)local->finder; - if ( ! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND ) { + link = (struct pcmcia_device *)local->finder; + if (!pcmcia_dev_present(link)) { DEBUG(2,"ray_cs interrupt from device not present or suspended.\n"); return IRQ_NONE; } - rcsindex = readb(&((struct scb *)(local->sram))->rcs_index); + rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index); if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) { @@ -2039,7 +1973,7 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) } if (rcsindex < NUMBER_OF_CCS) /* If it's a returned CCS */ { - pccs = ((struct ccs *) (local->sram + CCS_BASE)) + rcsindex; + pccs = ccs_base(local) + rcsindex; cmd = readb(&pccs->cmd); status = readb(&pccs->buffer_status); switch (cmd) @@ -2153,7 +2087,7 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) } else /* It's an RCS */ { - prcs = ((struct rcs *)(local->sram + CCS_BASE)) + rcsindex; + prcs = rcs_base(local) + rcsindex; switch (readb(&prcs->interrupt_id)) { @@ -2194,11 +2128,11 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) return IRQ_HANDLED; } /* ray_interrupt */ /*===========================================================================*/ -static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs) +static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs __iomem *prcs) { int rx_len; unsigned int pkt_addr; - UCHAR *pmsg; + void __iomem *pmsg; DEBUG(4,"ray_rx process rx packet\n"); /* Calculate address of packet within Rx buffer */ @@ -2248,11 +2182,11 @@ static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs) } /* end ray_rx */ /*===========================================================================*/ -static void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr, +static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned int pkt_addr, int rx_len) { struct sk_buff *skb = NULL; - struct rcs *prcslink = prcs; + struct rcs __iomem *prcslink = prcs; ray_dev_t *local = dev->priv; UCHAR *rx_ptr; int total_len; @@ -2294,7 +2228,7 @@ static void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_a + readb(&prcslink->var.rx_packet.rx_data_length[1]); if (readb(&prcslink->var.rx_packet.next_frag_rcs_index) == 0xFF || tmp < 0) break; - prcslink = ((struct rcs *)(local->sram + CCS_BASE)) + prcslink = rcs_base(local) + readb(&prcslink->link_field); } while (1); @@ -2355,7 +2289,7 @@ static void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_a prcslink = prcs; DEBUG(1,"ray_cs rx_data in fragment loop\n"); do { - prcslink = ((struct rcs *)(local->sram + CCS_BASE)) + prcslink = rcs_base(local) + readb(&prcslink->var.rx_packet.next_frag_rcs_index); rx_len = (( readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8) + readb(&prcslink->var.rx_packet.rx_data_length[1])) @@ -2390,20 +2324,15 @@ static void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_a /*local->wstats.qual.noise = none ? */ local->wstats.qual.updated = 0x2; } - /* Now, for the addresses in the spy list */ + /* Now, update the spy stuff */ { - int i; - /* Look all addresses */ - for(i = 0; i < local->spy_number; i++) - /* If match */ - if(!memcmp(linksrcaddr, local->spy_address[i], ETH_ALEN)) - { - /* Update statistics */ - /*local->spy_stat[i].qual = none ? */ - local->spy_stat[i].level = siglev; - /*local->spy_stat[i].noise = none ? */ - local->spy_stat[i].updated = 0x2; - } + struct iw_quality wstats; + wstats.level = siglev; + /* wstats.noise = none ? */ + /* wstats.qual = none ? */ + wstats.updated = 0x2; + /* Update spy records */ + wireless_spy_update(dev, linksrcaddr, &wstats); } #endif /* WIRELESS_SPY */ } /* end rx_data */ @@ -2529,9 +2458,9 @@ static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int le return length; } /*===========================================================================*/ -static void release_frag_chain(ray_dev_t *local, struct rcs* prcs) +static void release_frag_chain(ray_dev_t *local, struct rcs __iomem * prcs) { - struct rcs *prcslink = prcs; + struct rcs __iomem *prcslink = prcs; int tmp = 17; unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index); @@ -2541,7 +2470,7 @@ static void release_frag_chain(ray_dev_t *local, struct rcs* prcs) DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex); break; } - prcslink = ((struct rcs *)(local->sram + CCS_BASE)) + rcsindex; + prcslink = rcs_base(local) + rcsindex; rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index); } writeb(CCS_BUFFER_FREE, &prcslink->buffer_status); @@ -2549,9 +2478,9 @@ static void release_frag_chain(ray_dev_t *local, struct rcs* prcs) /*===========================================================================*/ static void authenticate(ray_dev_t *local) { - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; DEBUG(0,"ray_cs Starting authentication.\n"); - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs authenticate - device not present\n"); return; } @@ -2569,7 +2498,7 @@ static void authenticate(ray_dev_t *local) local->authentication_state = AWAITING_RESPONSE; } /* end authenticate */ /*===========================================================================*/ -static void rx_authenticate(ray_dev_t *local, struct rcs *prcs, +static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs, unsigned int pkt_addr, int rx_len) { UCHAR buff[256]; @@ -2614,11 +2543,11 @@ static void rx_authenticate(ray_dev_t *local, struct rcs *prcs, /*===========================================================================*/ static void associate(ray_dev_t *local) { - struct ccs *pccs; - dev_link_t *link = local->finder; + struct ccs __iomem *pccs; + struct pcmcia_device *link = local->finder; struct net_device *dev = link->priv; int ccsindex; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs associate - device not present\n"); return; } @@ -2630,7 +2559,7 @@ static void associate(ray_dev_t *local) return; } DEBUG(1,"ray_cs Starting association with access point\n"); - pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + pccs = ccs_base(local) + ccsindex; /* fill in the CCS */ writeb(CCS_START_ASSOCIATION, &pccs->cmd); /* Interrupt the firmware to process the command */ @@ -2650,7 +2579,7 @@ static void associate(ray_dev_t *local) } /* end associate */ /*===========================================================================*/ -static void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs, +static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs, unsigned int pkt_addr, int rx_len) { /* UCHAR buff[256]; @@ -2698,14 +2627,14 @@ static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len) * eg ifconfig */ int i; - dev_link_t *link; + struct pcmcia_device *link; struct net_device *dev; ray_dev_t *local; UCHAR *p; struct freq_hop_element *pfh; UCHAR c[33]; - link = dev_list; + link = this_device; if (!link) return 0; dev = (struct net_device *)link->priv; @@ -2798,8 +2727,8 @@ static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len) static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type) { int addr; - struct ccs *pccs; - struct tx_msg *ptx; + struct ccs __iomem *pccs; + struct tx_msg __iomem *ptx; int ccsindex; /* If no tx buffers available, return */ @@ -2809,7 +2738,7 @@ static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type) return -1; } - pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + pccs = ccs_base(local) + ccsindex; /* Address in card space */ addr = TX_BUF_BASE + (ccsindex << 11); @@ -2821,7 +2750,7 @@ static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type) writeb(TX_AUTHENTICATE_LENGTH_LSB,pccs->var.tx_request.tx_data_length + 1); writeb(0, &pccs->var.tx_request.pow_sav_mode); - ptx = (struct tx_msg *)(local->sram + addr); + ptx = local->sram + addr; /* fill in the mac header */ writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1); writeb(0, &ptx->mac.frame_ctl_2); @@ -2896,13 +2825,22 @@ static int write_int(struct file *file, const char __user *buffer, unsigned long } #endif +static struct pcmcia_device_id ray_ids[] = { + PCMCIA_DEVICE_MANF_CARD(0x01a6, 0x0000), + PCMCIA_DEVICE_NULL, +}; +MODULE_DEVICE_TABLE(pcmcia, ray_ids); + static struct pcmcia_driver ray_driver = { .owner = THIS_MODULE, .drv = { .name = "ray_cs", }, - .attach = ray_attach, - .detach = ray_detach, + .probe = ray_probe, + .remove = ray_detach, + .id_table = ray_ids, + .suspend = ray_suspend, + .resume = ray_resume, }; static int __init init_ray_cs(void) @@ -2931,15 +2869,6 @@ static void __exit exit_ray_cs(void) { DEBUG(0, "ray_cs: cleanup_module\n"); - -#ifdef CONFIG_PROC_FS - remove_proc_entry("ray_cs", proc_root_driver); -#endif - - pcmcia_unregister_driver(&ray_driver); - while (dev_list != NULL) - ray_detach(dev_list); - #ifdef CONFIG_PROC_FS remove_proc_entry("driver/ray_cs/ray_cs", NULL); remove_proc_entry("driver/ray_cs/essid", NULL); @@ -2947,6 +2876,8 @@ static void __exit exit_ray_cs(void) remove_proc_entry("driver/ray_cs/translate", NULL); remove_proc_entry("driver/ray_cs", NULL); #endif + + pcmcia_unregister_driver(&ray_driver); } /* exit_ray_cs */ module_init(init_ray_cs);