Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*=============================================================================
0003  *
0004  * A  PCMCIA client driver for the Raylink wireless LAN card.
0005  * The starting point for this module was the skeleton.c in the
0006  * PCMCIA 2.9.12 package written by David Hinds, dahinds@users.sourceforge.net
0007  *
0008  * Copyright (c) 1998  Corey Thomas (corey@world.std.com)
0009  *
0010  * Changes:
0011  * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/08/2000
0012  * - reorganize kmallocs in ray_attach, checking all for failure
0013  *   and releasing the previous allocations if one fails
0014  *
0015  * Daniele Bellucci <bellucda@tiscali.it> - 07/10/2003
0016  * - Audit copy_to_user in ioctl(SIOCGIWESSID)
0017  *
0018 =============================================================================*/
0019 
0020 #include <linux/module.h>
0021 #include <linux/kernel.h>
0022 #include <linux/proc_fs.h>
0023 #include <linux/ptrace.h>
0024 #include <linux/seq_file.h>
0025 #include <linux/string.h>
0026 #include <linux/timer.h>
0027 #include <linux/init.h>
0028 #include <linux/netdevice.h>
0029 #include <linux/etherdevice.h>
0030 #include <linux/if_arp.h>
0031 #include <linux/ioport.h>
0032 #include <linux/skbuff.h>
0033 #include <linux/ieee80211.h>
0034 
0035 #include <pcmcia/cistpl.h>
0036 #include <pcmcia/cisreg.h>
0037 #include <pcmcia/ds.h>
0038 
0039 #include <linux/wireless.h>
0040 #include <net/iw_handler.h>
0041 
0042 #include <asm/io.h>
0043 #include <asm/byteorder.h>
0044 #include <linux/uaccess.h>
0045 
0046 /* Warning : these stuff will slow down the driver... */
0047 #define WIRELESS_SPY        /* Enable spying addresses */
0048 /* Definitions we need for spy */
0049 typedef struct iw_statistics iw_stats;
0050 typedef u_char mac_addr[ETH_ALEN];  /* Hardware address */
0051 
0052 #include "rayctl.h"
0053 #include "ray_cs.h"
0054 
0055 
0056 /** Prototypes based on PCMCIA skeleton driver *******************************/
0057 static int ray_config(struct pcmcia_device *link);
0058 static void ray_release(struct pcmcia_device *link);
0059 static void ray_detach(struct pcmcia_device *p_dev);
0060 
0061 /***** Prototypes indicated by device structure ******************************/
0062 static int ray_dev_close(struct net_device *dev);
0063 static int ray_dev_config(struct net_device *dev, struct ifmap *map);
0064 static struct net_device_stats *ray_get_stats(struct net_device *dev);
0065 static int ray_dev_init(struct net_device *dev);
0066 
0067 static int ray_open(struct net_device *dev);
0068 static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb,
0069                         struct net_device *dev);
0070 static void set_multicast_list(struct net_device *dev);
0071 static void ray_update_multi_list(struct net_device *dev, int all);
0072 static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
0073                unsigned char *data, int len);
0074 static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx,
0075                  UCHAR msg_type, unsigned char *data);
0076 static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len);
0077 static iw_stats *ray_get_wireless_stats(struct net_device *dev);
0078 static const struct iw_handler_def ray_handler_def;
0079 
0080 /***** Prototypes for raylink functions **************************************/
0081 static void authenticate(ray_dev_t *local);
0082 static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type);
0083 static void authenticate_timeout(struct timer_list *t);
0084 static int get_free_ccs(ray_dev_t *local);
0085 static int get_free_tx_ccs(ray_dev_t *local);
0086 static void init_startup_params(ray_dev_t *local);
0087 static int parse_addr(char *in_str, UCHAR *out);
0088 static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev, UCHAR type);
0089 static int ray_init(struct net_device *dev);
0090 static int interrupt_ecf(ray_dev_t *local, int ccs);
0091 static void ray_reset(struct net_device *dev);
0092 static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len);
0093 static void verify_dl_startup(struct timer_list *t);
0094 
0095 /* Prototypes for interrpt time functions **********************************/
0096 static irqreturn_t ray_interrupt(int reg, void *dev_id);
0097 static void clear_interrupt(ray_dev_t *local);
0098 static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
0099                   unsigned int pkt_addr, int rx_len);
0100 static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len);
0101 static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs __iomem *prcs);
0102 static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs);
0103 static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
0104                 unsigned int pkt_addr, int rx_len);
0105 static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
0106             unsigned int pkt_addr, int rx_len);
0107 static void associate(ray_dev_t *local);
0108 
0109 /* Card command functions */
0110 static int dl_startup_params(struct net_device *dev);
0111 static void join_net(struct timer_list *t);
0112 static void start_net(struct timer_list *t);
0113 
0114 /*===========================================================================*/
0115 /* Parameters that can be set with 'insmod' */
0116 
0117 /* ADHOC=0, Infrastructure=1 */
0118 static int net_type = ADHOC;
0119 
0120 /* Hop dwell time in Kus (1024 us units defined by 802.11) */
0121 static int hop_dwell = 128;
0122 
0123 /* Beacon period in Kus */
0124 static int beacon_period = 256;
0125 
0126 /* power save mode (0 = off, 1 = save power) */
0127 static int psm;
0128 
0129 /* String for network's Extended Service Set ID. 32 Characters max */
0130 static char *essid;
0131 
0132 /* Default to encapsulation unless translation requested */
0133 static bool translate = true;
0134 
0135 static int country = USA;
0136 
0137 static int sniffer;
0138 
0139 static int bc;
0140 
0141 /* 48 bit physical card address if overriding card's real physical
0142  * address is required.  Since IEEE 802.11 addresses are 48 bits
0143  * like ethernet, an int can't be used, so a string is used. To
0144  * allow use of addresses starting with a decimal digit, the first
0145  * character must be a letter and will be ignored. This letter is
0146  * followed by up to 12 hex digits which are the address.  If less
0147  * than 12 digits are used, the address will be left filled with 0's.
0148  * Note that bit 0 of the first byte is the broadcast bit, and evil
0149  * things will happen if it is not 0 in a card address.
0150  */
0151 static char *phy_addr = NULL;
0152 
0153 static unsigned int ray_mem_speed = 500;
0154 
0155 /* WARNING: THIS DRIVER IS NOT CAPABLE OF HANDLING MULTIPLE DEVICES! */
0156 static struct pcmcia_device *this_device = NULL;
0157 
0158 MODULE_AUTHOR("Corey Thomas <corey@world.std.com>");
0159 MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
0160 MODULE_LICENSE("GPL");
0161 
0162 module_param(net_type, int, 0);
0163 module_param(hop_dwell, int, 0);
0164 module_param(beacon_period, int, 0);
0165 module_param(psm, int, 0);
0166 module_param(essid, charp, 0);
0167 module_param(translate, bool, 0);
0168 module_param(country, int, 0);
0169 module_param(sniffer, int, 0);
0170 module_param(bc, int, 0);
0171 module_param(phy_addr, charp, 0);
0172 module_param(ray_mem_speed, int, 0);
0173 
0174 static const UCHAR b5_default_startup_parms[] = {
0175     0, 0,           /* Adhoc station */
0176     'L', 'I', 'N', 'U', 'X', 0, 0, 0,   /* 32 char ESSID */
0177     0, 0, 0, 0, 0, 0, 0, 0,
0178     0, 0, 0, 0, 0, 0, 0, 0,
0179     0, 0, 0, 0, 0, 0, 0, 0,
0180     1, 0,           /* Active scan, CA Mode */
0181     0, 0, 0, 0, 0, 0,   /* No default MAC addr  */
0182     0x7f, 0xff,     /* Frag threshold */
0183     0x00, 0x80,     /* Hop time 128 Kus */
0184     0x01, 0x00,     /* Beacon period 256 Kus */
0185     0x01, 0x07, 0xa3,   /* DTIM, retries, ack timeout */
0186     0x1d, 0x82, 0x4e,   /* SIFS, DIFS, PIFS */
0187     0x7f, 0xff,     /* RTS threshold */
0188     0x04, 0xe2, 0x38, 0xA4, /* scan_dwell, max_scan_dwell */
0189     0x05,           /* assoc resp timeout thresh */
0190     0x08, 0x02, 0x08,   /* adhoc, infra, super cycle max */
0191     0,          /* Promiscuous mode */
0192     0x0c, 0x0bd,        /* Unique word */
0193     0x32,           /* Slot time */
0194     0xff, 0xff,     /* roam-low snr, low snr count */
0195     0x05, 0xff,     /* Infra, adhoc missed bcn thresh */
0196     0x01, 0x0b, 0x4f,   /* USA, hop pattern, hop pat length */
0197 /* b4 - b5 differences start here */
0198     0x00, 0x3f,     /* CW max */
0199     0x00, 0x0f,     /* CW min */
0200     0x04, 0x08,     /* Noise gain, limit offset */
0201     0x28, 0x28,     /* det rssi, med busy offsets */
0202     7,          /* det sync thresh */
0203     0, 2, 2,        /* test mode, min, max */
0204     0,          /* allow broadcast SSID probe resp */
0205     0, 0,           /* privacy must start, can join */
0206     2, 0, 0, 0, 0, 0, 0, 0  /* basic rate set */
0207 };
0208 
0209 static const UCHAR b4_default_startup_parms[] = {
0210     0, 0,           /* Adhoc station */
0211     'L', 'I', 'N', 'U', 'X', 0, 0, 0,   /* 32 char ESSID */
0212     0, 0, 0, 0, 0, 0, 0, 0,
0213     0, 0, 0, 0, 0, 0, 0, 0,
0214     0, 0, 0, 0, 0, 0, 0, 0,
0215     1, 0,           /* Active scan, CA Mode */
0216     0, 0, 0, 0, 0, 0,   /* No default MAC addr  */
0217     0x7f, 0xff,     /* Frag threshold */
0218     0x02, 0x00,     /* Hop time */
0219     0x00, 0x01,     /* Beacon period */
0220     0x01, 0x07, 0xa3,   /* DTIM, retries, ack timeout */
0221     0x1d, 0x82, 0xce,   /* SIFS, DIFS, PIFS */
0222     0x7f, 0xff,     /* RTS threshold */
0223     0xfb, 0x1e, 0xc7, 0x5c, /* scan_dwell, max_scan_dwell */
0224     0x05,           /* assoc resp timeout thresh */
0225     0x04, 0x02, 0x4,    /* adhoc, infra, super cycle max */
0226     0,          /* Promiscuous mode */
0227     0x0c, 0x0bd,        /* Unique word */
0228     0x4e,           /* Slot time (TBD seems wrong) */
0229     0xff, 0xff,     /* roam-low snr, low snr count */
0230     0x05, 0xff,     /* Infra, adhoc missed bcn thresh */
0231     0x01, 0x0b, 0x4e,   /* USA, hop pattern, hop pat length */
0232 /* b4 - b5 differences start here */
0233     0x3f, 0x0f,     /* CW max, min */
0234     0x04, 0x08,     /* Noise gain, limit offset */
0235     0x28, 0x28,     /* det rssi, med busy offsets */
0236     7,          /* det sync thresh */
0237     0, 2, 2,        /* test mode, min, max */
0238     0,          /* rx/tx delay */
0239     0, 0, 0, 0, 0, 0,   /* current BSS id */
0240     0           /* hop set */
0241 };
0242 
0243 /*===========================================================================*/
0244 static const u8 eth2_llc[] = { 0xaa, 0xaa, 3, 0, 0, 0 };
0245 
0246 static const char hop_pattern_length[] = { 1,
0247     USA_HOP_MOD, EUROPE_HOP_MOD,
0248     JAPAN_HOP_MOD, KOREA_HOP_MOD,
0249     SPAIN_HOP_MOD, FRANCE_HOP_MOD,
0250     ISRAEL_HOP_MOD, AUSTRALIA_HOP_MOD,
0251     JAPAN_TEST_HOP_MOD
0252 };
0253 
0254 static const char rcsid[] =
0255     "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
0256 
0257 static const struct net_device_ops ray_netdev_ops = {
0258     .ndo_init       = ray_dev_init,
0259     .ndo_open       = ray_open,
0260     .ndo_stop       = ray_dev_close,
0261     .ndo_start_xmit     = ray_dev_start_xmit,
0262     .ndo_set_config     = ray_dev_config,
0263     .ndo_get_stats      = ray_get_stats,
0264     .ndo_set_rx_mode    = set_multicast_list,
0265     .ndo_set_mac_address    = eth_mac_addr,
0266     .ndo_validate_addr  = eth_validate_addr,
0267 };
0268 
0269 static int ray_probe(struct pcmcia_device *p_dev)
0270 {
0271     ray_dev_t *local;
0272     struct net_device *dev;
0273 
0274     dev_dbg(&p_dev->dev, "ray_attach()\n");
0275 
0276     /* Allocate space for private device-specific data */
0277     dev = alloc_etherdev(sizeof(ray_dev_t));
0278     if (!dev)
0279         goto fail_alloc_dev;
0280 
0281     local = netdev_priv(dev);
0282     local->finder = p_dev;
0283 
0284     /* The io structure describes IO port mapping. None used here */
0285     p_dev->resource[0]->end = 0;
0286     p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
0287 
0288     /* General socket configuration */
0289     p_dev->config_flags |= CONF_ENABLE_IRQ;
0290     p_dev->config_index = 1;
0291 
0292     p_dev->priv = dev;
0293 
0294     local->finder = p_dev;
0295     local->card_status = CARD_INSERTED;
0296     local->authentication_state = UNAUTHENTICATED;
0297     local->num_multi = 0;
0298     dev_dbg(&p_dev->dev, "ray_attach p_dev = %p,  dev = %p,  local = %p, intr = %p\n",
0299           p_dev, dev, local, &ray_interrupt);
0300 
0301     /* Raylink entries in the device structure */
0302     dev->netdev_ops = &ray_netdev_ops;
0303     dev->wireless_handlers = &ray_handler_def;
0304 #ifdef WIRELESS_SPY
0305     local->wireless_data.spy_data = &local->spy_data;
0306     dev->wireless_data = &local->wireless_data;
0307 #endif /* WIRELESS_SPY */
0308 
0309 
0310     dev_dbg(&p_dev->dev, "ray_cs ray_attach calling ether_setup.)\n");
0311     netif_stop_queue(dev);
0312 
0313     timer_setup(&local->timer, NULL, 0);
0314 
0315     this_device = p_dev;
0316     return ray_config(p_dev);
0317 
0318 fail_alloc_dev:
0319     return -ENOMEM;
0320 } /* ray_attach */
0321 
0322 static void ray_detach(struct pcmcia_device *link)
0323 {
0324     struct net_device *dev;
0325     ray_dev_t *local;
0326 
0327     dev_dbg(&link->dev, "ray_detach\n");
0328 
0329     this_device = NULL;
0330     dev = link->priv;
0331 
0332     ray_release(link);
0333 
0334     local = netdev_priv(dev);
0335     del_timer_sync(&local->timer);
0336 
0337     if (link->priv) {
0338         unregister_netdev(dev);
0339         free_netdev(dev);
0340     }
0341     dev_dbg(&link->dev, "ray_cs ray_detach ending\n");
0342 } /* ray_detach */
0343 
0344 #define MAX_TUPLE_SIZE 128
0345 static int ray_config(struct pcmcia_device *link)
0346 {
0347     int ret = 0;
0348     int i;
0349     struct net_device *dev = (struct net_device *)link->priv;
0350     ray_dev_t *local = netdev_priv(dev);
0351 
0352     dev_dbg(&link->dev, "ray_config\n");
0353 
0354     /* Determine card type and firmware version */
0355     printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n",
0356            link->prod_id[0] ? link->prod_id[0] : " ",
0357            link->prod_id[1] ? link->prod_id[1] : " ",
0358            link->prod_id[2] ? link->prod_id[2] : " ",
0359            link->prod_id[3] ? link->prod_id[3] : " ");
0360 
0361     /* Now allocate an interrupt line.  Note that this does not
0362        actually assign a handler to the interrupt.
0363      */
0364     ret = pcmcia_request_irq(link, ray_interrupt);
0365     if (ret)
0366         goto failed;
0367     dev->irq = link->irq;
0368 
0369     ret = pcmcia_enable_device(link);
0370     if (ret)
0371         goto failed;
0372 
0373 /*** Set up 32k window for shared memory (transmit and control) ************/
0374     link->resource[2]->flags |= WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
0375     link->resource[2]->start = 0;
0376     link->resource[2]->end = 0x8000;
0377     ret = pcmcia_request_window(link, link->resource[2], ray_mem_speed);
0378     if (ret)
0379         goto failed;
0380     ret = pcmcia_map_mem_page(link, link->resource[2], 0);
0381     if (ret)
0382         goto failed;
0383     local->sram = ioremap(link->resource[2]->start,
0384             resource_size(link->resource[2]));
0385     if (!local->sram)
0386         goto failed;
0387 
0388 /*** Set up 16k window for shared memory (receive buffer) ***************/
0389     link->resource[3]->flags |=
0390         WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
0391     link->resource[3]->start = 0;
0392     link->resource[3]->end = 0x4000;
0393     ret = pcmcia_request_window(link, link->resource[3], ray_mem_speed);
0394     if (ret)
0395         goto failed;
0396     ret = pcmcia_map_mem_page(link, link->resource[3], 0x8000);
0397     if (ret)
0398         goto failed;
0399     local->rmem = ioremap(link->resource[3]->start,
0400             resource_size(link->resource[3]));
0401     if (!local->rmem)
0402         goto failed;
0403 
0404 /*** Set up window for attribute memory ***********************************/
0405     link->resource[4]->flags |=
0406         WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT;
0407     link->resource[4]->start = 0;
0408     link->resource[4]->end = 0x1000;
0409     ret = pcmcia_request_window(link, link->resource[4], ray_mem_speed);
0410     if (ret)
0411         goto failed;
0412     ret = pcmcia_map_mem_page(link, link->resource[4], 0);
0413     if (ret)
0414         goto failed;
0415     local->amem = ioremap(link->resource[4]->start,
0416             resource_size(link->resource[4]));
0417     if (!local->amem)
0418         goto failed;
0419 
0420     dev_dbg(&link->dev, "ray_config sram=%p\n", local->sram);
0421     dev_dbg(&link->dev, "ray_config rmem=%p\n", local->rmem);
0422     dev_dbg(&link->dev, "ray_config amem=%p\n", local->amem);
0423     if (ray_init(dev) < 0) {
0424         ray_release(link);
0425         return -ENODEV;
0426     }
0427 
0428     SET_NETDEV_DEV(dev, &link->dev);
0429     i = register_netdev(dev);
0430     if (i != 0) {
0431         printk("ray_config register_netdev() failed\n");
0432         ray_release(link);
0433         return i;
0434     }
0435 
0436     printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %pM\n",
0437            dev->name, dev->irq, dev->dev_addr);
0438 
0439     return 0;
0440 
0441 failed:
0442     ray_release(link);
0443     return -ENODEV;
0444 } /* ray_config */
0445 
0446 static inline struct ccs __iomem *ccs_base(ray_dev_t *dev)
0447 {
0448     return dev->sram + CCS_BASE;
0449 }
0450 
0451 static inline struct rcs __iomem *rcs_base(ray_dev_t *dev)
0452 {
0453     /*
0454      * This looks nonsensical, since there is a separate
0455      * RCS_BASE. But the difference between a "struct rcs"
0456      * and a "struct ccs" ends up being in the _index_ off
0457      * the base, so the base pointer is the same for both
0458      * ccs/rcs.
0459      */
0460     return dev->sram + CCS_BASE;
0461 }
0462 
0463 /*===========================================================================*/
0464 static int ray_init(struct net_device *dev)
0465 {
0466     int i;
0467     struct ccs __iomem *pccs;
0468     ray_dev_t *local = netdev_priv(dev);
0469     struct pcmcia_device *link = local->finder;
0470     dev_dbg(&link->dev, "ray_init(0x%p)\n", dev);
0471     if (!(pcmcia_dev_present(link))) {
0472         dev_dbg(&link->dev, "ray_init - device not present\n");
0473         return -1;
0474     }
0475 
0476     local->net_type = net_type;
0477     local->sta_type = TYPE_STA;
0478 
0479     /* Copy the startup results to local memory */
0480     memcpy_fromio(&local->startup_res, local->sram + ECF_TO_HOST_BASE,
0481               sizeof(struct startup_res_6));
0482 
0483     /* Check Power up test status and get mac address from card */
0484     if (local->startup_res.startup_word != 0x80) {
0485         printk(KERN_INFO "ray_init ERROR card status = %2x\n",
0486                local->startup_res.startup_word);
0487         local->card_status = CARD_INIT_ERROR;
0488         return -1;
0489     }
0490 
0491     local->fw_ver = local->startup_res.firmware_version[0];
0492     local->fw_bld = local->startup_res.firmware_version[1];
0493     local->fw_var = local->startup_res.firmware_version[2];
0494     dev_dbg(&link->dev, "ray_init firmware version %d.%d\n", local->fw_ver,
0495           local->fw_bld);
0496 
0497     local->tib_length = 0x20;
0498     if ((local->fw_ver == 5) && (local->fw_bld >= 30))
0499         local->tib_length = local->startup_res.tib_length;
0500     dev_dbg(&link->dev, "ray_init tib_length = 0x%02x\n", local->tib_length);
0501     /* Initialize CCS's to buffer free state */
0502     pccs = ccs_base(local);
0503     for (i = 0; i < NUMBER_OF_CCS; i++) {
0504         writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
0505     }
0506     init_startup_params(local);
0507 
0508     /* copy mac address to startup parameters */
0509     if (!parse_addr(phy_addr, local->sparm.b4.a_mac_addr)) {
0510         memcpy(&local->sparm.b4.a_mac_addr,
0511                &local->startup_res.station_addr, ADDRLEN);
0512     }
0513 
0514     clear_interrupt(local); /* Clear any interrupt from the card */
0515     local->card_status = CARD_AWAITING_PARAM;
0516     dev_dbg(&link->dev, "ray_init ending\n");
0517     return 0;
0518 } /* ray_init */
0519 
0520 /*===========================================================================*/
0521 /* Download startup parameters to the card and command it to read them       */
0522 static int dl_startup_params(struct net_device *dev)
0523 {
0524     int ccsindex;
0525     ray_dev_t *local = netdev_priv(dev);
0526     struct ccs __iomem *pccs;
0527     struct pcmcia_device *link = local->finder;
0528 
0529     dev_dbg(&link->dev, "dl_startup_params entered\n");
0530     if (!(pcmcia_dev_present(link))) {
0531         dev_dbg(&link->dev, "ray_cs dl_startup_params - device not present\n");
0532         return -1;
0533     }
0534 
0535     /* Copy parameters to host to ECF area */
0536     if (local->fw_ver == 0x55)
0537         memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b4,
0538                 sizeof(struct b4_startup_params));
0539     else
0540         memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b5,
0541                 sizeof(struct b5_startup_params));
0542 
0543     /* Fill in the CCS fields for the ECF */
0544     if ((ccsindex = get_free_ccs(local)) < 0)
0545         return -1;
0546     local->dl_param_ccs = ccsindex;
0547     pccs = ccs_base(local) + ccsindex;
0548     writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd);
0549     dev_dbg(&link->dev, "dl_startup_params start ccsindex = %d\n",
0550           local->dl_param_ccs);
0551     /* Interrupt the firmware to process the command */
0552     if (interrupt_ecf(local, ccsindex)) {
0553         printk(KERN_INFO "ray dl_startup_params failed - "
0554                "ECF not ready for intr\n");
0555         local->card_status = CARD_DL_PARAM_ERROR;
0556         writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
0557         return -2;
0558     }
0559     local->card_status = CARD_DL_PARAM;
0560     /* Start kernel timer to wait for dl startup to complete. */
0561     local->timer.expires = jiffies + HZ / 2;
0562     local->timer.function = verify_dl_startup;
0563     add_timer(&local->timer);
0564     dev_dbg(&link->dev,
0565           "ray_cs dl_startup_params started timer for verify_dl_startup\n");
0566     return 0;
0567 } /* dl_startup_params */
0568 
0569 /*===========================================================================*/
0570 static void init_startup_params(ray_dev_t *local)
0571 {
0572     int i;
0573 
0574     if (country > JAPAN_TEST)
0575         country = USA;
0576     else if (country < USA)
0577         country = USA;
0578     /* structure for hop time and beacon period is defined here using
0579      * New 802.11D6.1 format.  Card firmware is still using old format
0580      * until version 6.
0581      *    Before                    After
0582      *    a_hop_time ms byte        a_hop_time ms byte
0583      *    a_hop_time 2s byte        a_hop_time ls byte
0584      *    a_hop_time ls byte        a_beacon_period ms byte
0585      *    a_beacon_period           a_beacon_period ls byte
0586      *
0587      *    a_hop_time = uS           a_hop_time = KuS
0588      *    a_beacon_period = hops    a_beacon_period = KuS
0589      *//* 64ms = 010000 */
0590     if (local->fw_ver == 0x55) {
0591         memcpy(&local->sparm.b4, b4_default_startup_parms,
0592                sizeof(struct b4_startup_params));
0593         /* Translate sane kus input values to old build 4/5 format */
0594         /* i = hop time in uS truncated to 3 bytes */
0595         i = (hop_dwell * 1024) & 0xffffff;
0596         local->sparm.b4.a_hop_time[0] = (i >> 16) & 0xff;
0597         local->sparm.b4.a_hop_time[1] = (i >> 8) & 0xff;
0598         local->sparm.b4.a_beacon_period[0] = 0;
0599         local->sparm.b4.a_beacon_period[1] =
0600             ((beacon_period / hop_dwell) - 1) & 0xff;
0601         local->sparm.b4.a_curr_country_code = country;
0602         local->sparm.b4.a_hop_pattern_length =
0603             hop_pattern_length[(int)country] - 1;
0604         if (bc) {
0605             local->sparm.b4.a_ack_timeout = 0x50;
0606             local->sparm.b4.a_sifs = 0x3f;
0607         }
0608     } else { /* Version 5 uses real kus values */
0609         memcpy((UCHAR *) &local->sparm.b5, b5_default_startup_parms,
0610                sizeof(struct b5_startup_params));
0611 
0612         local->sparm.b5.a_hop_time[0] = (hop_dwell >> 8) & 0xff;
0613         local->sparm.b5.a_hop_time[1] = hop_dwell & 0xff;
0614         local->sparm.b5.a_beacon_period[0] =
0615             (beacon_period >> 8) & 0xff;
0616         local->sparm.b5.a_beacon_period[1] = beacon_period & 0xff;
0617         if (psm)
0618             local->sparm.b5.a_power_mgt_state = 1;
0619         local->sparm.b5.a_curr_country_code = country;
0620         local->sparm.b5.a_hop_pattern_length =
0621             hop_pattern_length[(int)country];
0622     }
0623 
0624     local->sparm.b4.a_network_type = net_type & 0x01;
0625     local->sparm.b4.a_acting_as_ap_status = TYPE_STA;
0626 
0627     if (essid != NULL)
0628         strncpy(local->sparm.b4.a_current_ess_id, essid, ESSID_SIZE);
0629 } /* init_startup_params */
0630 
0631 /*===========================================================================*/
0632 static void verify_dl_startup(struct timer_list *t)
0633 {
0634     ray_dev_t *local = from_timer(local, t, timer);
0635     struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
0636     UCHAR status;
0637     struct pcmcia_device *link = local->finder;
0638 
0639     if (!(pcmcia_dev_present(link))) {
0640         dev_dbg(&link->dev, "ray_cs verify_dl_startup - device not present\n");
0641         return;
0642     }
0643 #if 0
0644     {
0645         int i;
0646         printk(KERN_DEBUG
0647                "verify_dl_startup parameters sent via ccs %d:\n",
0648                local->dl_param_ccs);
0649         for (i = 0; i < sizeof(struct b5_startup_params); i++) {
0650             printk(" %2x",
0651                    (unsigned int)readb(local->sram +
0652                            HOST_TO_ECF_BASE + i));
0653         }
0654         printk("\n");
0655     }
0656 #endif
0657 
0658     status = readb(&pccs->buffer_status);
0659     if (status != CCS_BUFFER_FREE) {
0660         printk(KERN_INFO
0661                "Download startup params failed.  Status = %d\n",
0662                status);
0663         local->card_status = CARD_DL_PARAM_ERROR;
0664         return;
0665     }
0666     if (local->sparm.b4.a_network_type == ADHOC)
0667         start_net(&local->timer);
0668     else
0669         join_net(&local->timer);
0670 } /* end verify_dl_startup */
0671 
0672 /*===========================================================================*/
0673 /* Command card to start a network */
0674 static void start_net(struct timer_list *t)
0675 {
0676     ray_dev_t *local = from_timer(local, t, timer);
0677     struct ccs __iomem *pccs;
0678     int ccsindex;
0679     struct pcmcia_device *link = local->finder;
0680     if (!(pcmcia_dev_present(link))) {
0681         dev_dbg(&link->dev, "ray_cs start_net - device not present\n");
0682         return;
0683     }
0684     /* Fill in the CCS fields for the ECF */
0685     if ((ccsindex = get_free_ccs(local)) < 0)
0686         return;
0687     pccs = ccs_base(local) + ccsindex;
0688     writeb(CCS_START_NETWORK, &pccs->cmd);
0689     writeb(0, &pccs->var.start_network.update_param);
0690     /* Interrupt the firmware to process the command */
0691     if (interrupt_ecf(local, ccsindex)) {
0692         dev_dbg(&link->dev, "ray start net failed - card not ready for intr\n");
0693         writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
0694         return;
0695     }
0696     local->card_status = CARD_DOING_ACQ;
0697 } /* end start_net */
0698 
0699 /*===========================================================================*/
0700 /* Command card to join a network */
0701 static void join_net(struct timer_list *t)
0702 {
0703     ray_dev_t *local = from_timer(local, t, timer);
0704 
0705     struct ccs __iomem *pccs;
0706     int ccsindex;
0707     struct pcmcia_device *link = local->finder;
0708 
0709     if (!(pcmcia_dev_present(link))) {
0710         dev_dbg(&link->dev, "ray_cs join_net - device not present\n");
0711         return;
0712     }
0713     /* Fill in the CCS fields for the ECF */
0714     if ((ccsindex = get_free_ccs(local)) < 0)
0715         return;
0716     pccs = ccs_base(local) + ccsindex;
0717     writeb(CCS_JOIN_NETWORK, &pccs->cmd);
0718     writeb(0, &pccs->var.join_network.update_param);
0719     writeb(0, &pccs->var.join_network.net_initiated);
0720     /* Interrupt the firmware to process the command */
0721     if (interrupt_ecf(local, ccsindex)) {
0722         dev_dbg(&link->dev, "ray join net failed - card not ready for intr\n");
0723         writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
0724         return;
0725     }
0726     local->card_status = CARD_DOING_ACQ;
0727 }
0728 
0729 
0730 static void ray_release(struct pcmcia_device *link)
0731 {
0732     struct net_device *dev = link->priv;
0733     ray_dev_t *local = netdev_priv(dev);
0734 
0735     dev_dbg(&link->dev, "ray_release\n");
0736 
0737     del_timer(&local->timer);
0738 
0739     iounmap(local->sram);
0740     iounmap(local->rmem);
0741     iounmap(local->amem);
0742     pcmcia_disable_device(link);
0743 
0744     dev_dbg(&link->dev, "ray_release ending\n");
0745 }
0746 
0747 static int ray_suspend(struct pcmcia_device *link)
0748 {
0749     struct net_device *dev = link->priv;
0750 
0751     if (link->open)
0752         netif_device_detach(dev);
0753 
0754     return 0;
0755 }
0756 
0757 static int ray_resume(struct pcmcia_device *link)
0758 {
0759     struct net_device *dev = link->priv;
0760 
0761     if (link->open) {
0762         ray_reset(dev);
0763         netif_device_attach(dev);
0764     }
0765 
0766     return 0;
0767 }
0768 
0769 /*===========================================================================*/
0770 static int ray_dev_init(struct net_device *dev)
0771 {
0772 #ifdef RAY_IMMEDIATE_INIT
0773     int i;
0774 #endif /* RAY_IMMEDIATE_INIT */
0775     ray_dev_t *local = netdev_priv(dev);
0776     struct pcmcia_device *link = local->finder;
0777 
0778     dev_dbg(&link->dev, "ray_dev_init(dev=%p)\n", dev);
0779     if (!(pcmcia_dev_present(link))) {
0780         dev_dbg(&link->dev, "ray_dev_init - device not present\n");
0781         return -1;
0782     }
0783 #ifdef RAY_IMMEDIATE_INIT
0784     /* Download startup parameters */
0785     if ((i = dl_startup_params(dev)) < 0) {
0786         printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
0787                "returns 0x%x\n", i);
0788         return -1;
0789     }
0790 #else /* RAY_IMMEDIATE_INIT */
0791     /* Postpone the card init so that we can still configure the card,
0792      * for example using the Wireless Extensions. The init will happen
0793      * in ray_open() - Jean II */
0794     dev_dbg(&link->dev,
0795           "ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
0796           local->card_status);
0797 #endif /* RAY_IMMEDIATE_INIT */
0798 
0799     /* copy mac and broadcast addresses to linux device */
0800     eth_hw_addr_set(dev, local->sparm.b4.a_mac_addr);
0801     eth_broadcast_addr(dev->broadcast);
0802 
0803     dev_dbg(&link->dev, "ray_dev_init ending\n");
0804     return 0;
0805 }
0806 
0807 /*===========================================================================*/
0808 static int ray_dev_config(struct net_device *dev, struct ifmap *map)
0809 {
0810     ray_dev_t *local = netdev_priv(dev);
0811     struct pcmcia_device *link = local->finder;
0812     /* Dummy routine to satisfy device structure */
0813     dev_dbg(&link->dev, "ray_dev_config(dev=%p,ifmap=%p)\n", dev, map);
0814     if (!(pcmcia_dev_present(link))) {
0815         dev_dbg(&link->dev, "ray_dev_config - device not present\n");
0816         return -1;
0817     }
0818 
0819     return 0;
0820 }
0821 
0822 /*===========================================================================*/
0823 static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb,
0824                         struct net_device *dev)
0825 {
0826     ray_dev_t *local = netdev_priv(dev);
0827     struct pcmcia_device *link = local->finder;
0828     short length = skb->len;
0829 
0830     if (!pcmcia_dev_present(link)) {
0831         dev_dbg(&link->dev, "ray_dev_start_xmit - device not present\n");
0832         dev_kfree_skb(skb);
0833         return NETDEV_TX_OK;
0834     }
0835 
0836     dev_dbg(&link->dev, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev);
0837     if (local->authentication_state == NEED_TO_AUTH) {
0838         dev_dbg(&link->dev, "ray_cs Sending authentication request.\n");
0839         if (!build_auth_frame(local, local->auth_id, OPEN_AUTH_REQUEST)) {
0840             local->authentication_state = AUTHENTICATED;
0841             netif_stop_queue(dev);
0842             return NETDEV_TX_BUSY;
0843         }
0844     }
0845 
0846     if (length < ETH_ZLEN) {
0847         if (skb_padto(skb, ETH_ZLEN))
0848             return NETDEV_TX_OK;
0849         length = ETH_ZLEN;
0850     }
0851     switch (ray_hw_xmit(skb->data, length, dev, DATA_TYPE)) {
0852     case XMIT_NO_CCS:
0853     case XMIT_NEED_AUTH:
0854         netif_stop_queue(dev);
0855         return NETDEV_TX_BUSY;
0856     case XMIT_NO_INTR:
0857     case XMIT_MSG_BAD:
0858     case XMIT_OK:
0859     default:
0860         dev_kfree_skb(skb);
0861     }
0862 
0863     return NETDEV_TX_OK;
0864 } /* ray_dev_start_xmit */
0865 
0866 /*===========================================================================*/
0867 static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev,
0868                UCHAR msg_type)
0869 {
0870     ray_dev_t *local = netdev_priv(dev);
0871     struct ccs __iomem *pccs;
0872     int ccsindex;
0873     int offset;
0874     struct tx_msg __iomem *ptx; /* Address of xmit buffer in PC space */
0875     short int addr;     /* Address of xmit buffer in card space */
0876 
0877     pr_debug("ray_hw_xmit(data=%p, len=%d, dev=%p)\n", data, len, dev);
0878     if (len + TX_HEADER_LENGTH > TX_BUF_SIZE) {
0879         printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",
0880                len);
0881         return XMIT_MSG_BAD;
0882     }
0883     switch (ccsindex = get_free_tx_ccs(local)) {
0884     case ECCSBUSY:
0885         pr_debug("ray_hw_xmit tx_ccs table busy\n");
0886         fallthrough;
0887     case ECCSFULL:
0888         pr_debug("ray_hw_xmit No free tx ccs\n");
0889         fallthrough;
0890     case ECARDGONE:
0891         netif_stop_queue(dev);
0892         return XMIT_NO_CCS;
0893     default:
0894         break;
0895     }
0896     addr = TX_BUF_BASE + (ccsindex << 11);
0897 
0898     if (msg_type == DATA_TYPE) {
0899         local->stats.tx_bytes += len;
0900         local->stats.tx_packets++;
0901     }
0902 
0903     ptx = local->sram + addr;
0904 
0905     ray_build_header(local, ptx, msg_type, data);
0906     if (translate) {
0907         offset = translate_frame(local, ptx, data, len);
0908     } else { /* Encapsulate frame */
0909         /* TBD TIB length will move address of ptx->var */
0910         memcpy_toio(&ptx->var, data, len);
0911         offset = 0;
0912     }
0913 
0914     /* fill in the CCS */
0915     pccs = ccs_base(local) + ccsindex;
0916     len += TX_HEADER_LENGTH + offset;
0917     writeb(CCS_TX_REQUEST, &pccs->cmd);
0918     writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]);
0919     writeb(local->tib_length, &pccs->var.tx_request.tx_data_ptr[1]);
0920     writeb(len >> 8, &pccs->var.tx_request.tx_data_length[0]);
0921     writeb(len & 0xff, &pccs->var.tx_request.tx_data_length[1]);
0922 /* TBD still need psm_cam? */
0923     writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode);
0924     writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate);
0925     writeb(0, &pccs->var.tx_request.antenna);
0926     pr_debug("ray_hw_xmit default_tx_rate = 0x%x\n",
0927           local->net_default_tx_rate);
0928 
0929     /* Interrupt the firmware to process the command */
0930     if (interrupt_ecf(local, ccsindex)) {
0931         pr_debug("ray_hw_xmit failed - ECF not ready for intr\n");
0932 /* TBD very inefficient to copy packet to buffer, and then not
0933    send it, but the alternative is to queue the messages and that
0934    won't be done for a while.  Maybe set tbusy until a CCS is free?
0935 */
0936         writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
0937         return XMIT_NO_INTR;
0938     }
0939     return XMIT_OK;
0940 } /* end ray_hw_xmit */
0941 
0942 /*===========================================================================*/
0943 static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
0944                unsigned char *data, int len)
0945 {
0946     __be16 proto = ((struct ethhdr *)data)->h_proto;
0947     if (ntohs(proto) >= ETH_P_802_3_MIN) { /* DIX II ethernet frame */
0948         pr_debug("ray_cs translate_frame DIX II\n");
0949         /* Copy LLC header to card buffer */
0950         memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc));
0951         memcpy_toio(((void __iomem *)&ptx->var) + sizeof(eth2_llc),
0952                 (UCHAR *) &proto, 2);
0953         if (proto == htons(ETH_P_AARP) || proto == htons(ETH_P_IPX)) {
0954             /* This is the selective translation table, only 2 entries */
0955             writeb(0xf8,
0956                    &((struct snaphdr_t __iomem *)ptx->var)->org[2]);
0957         }
0958         /* Copy body of ethernet packet without ethernet header */
0959         memcpy_toio((void __iomem *)&ptx->var +
0960                 sizeof(struct snaphdr_t), data + ETH_HLEN,
0961                 len - ETH_HLEN);
0962         return (int)sizeof(struct snaphdr_t) - ETH_HLEN;
0963     } else { /* already  802 type, and proto is length */
0964         pr_debug("ray_cs translate_frame 802\n");
0965         if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */
0966             pr_debug("ray_cs translate_frame evil IPX\n");
0967             memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
0968             return 0 - ETH_HLEN;
0969         }
0970         memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
0971         return 0 - ETH_HLEN;
0972     }
0973     /* TBD do other frame types */
0974 } /* end translate_frame */
0975 
0976 /*===========================================================================*/
0977 static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx,
0978                  UCHAR msg_type, unsigned char *data)
0979 {
0980     writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1);
0981 /*** IEEE 802.11 Address field assignments *************
0982         TODS    FROMDS  addr_1      addr_2      addr_3  addr_4
0983 Adhoc       0   0   dest        src (terminal)  BSSID   N/A
0984 AP to Terminal  0   1   dest        AP(BSSID)   source  N/A
0985 Terminal to AP  1   0   AP(BSSID)   src (terminal)  dest    N/A
0986 AP to AP    1   1   dest AP     src AP      dest    source
0987 *******************************************************/
0988     if (local->net_type == ADHOC) {
0989         writeb(0, &ptx->mac.frame_ctl_2);
0990         memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest,
0991                 ADDRLEN);
0992         memcpy_toio(ptx->mac.addr_2, ((struct ethhdr *)data)->h_source,
0993                 ADDRLEN);
0994         memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
0995     } else { /* infrastructure */
0996 
0997         if (local->sparm.b4.a_acting_as_ap_status) {
0998             writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);
0999             memcpy_toio(ptx->mac.addr_1,
1000                     ((struct ethhdr *)data)->h_dest, ADDRLEN);
1001             memcpy_toio(ptx->mac.addr_2, local->bss_id, 6);
1002             memcpy_toio(ptx->mac.addr_3,
1003                     ((struct ethhdr *)data)->h_source, ADDRLEN);
1004         } else { /* Terminal */
1005 
1006             writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2);
1007             memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN);
1008             memcpy_toio(ptx->mac.addr_2,
1009                     ((struct ethhdr *)data)->h_source, ADDRLEN);
1010             memcpy_toio(ptx->mac.addr_3,
1011                     ((struct ethhdr *)data)->h_dest, ADDRLEN);
1012         }
1013     }
1014 } /* end encapsulate_frame */
1015 
1016 /*====================================================================*/
1017 
1018 /*------------------------------------------------------------------*/
1019 /*
1020  * Wireless Handler : get protocol name
1021  */
1022 static int ray_get_name(struct net_device *dev, struct iw_request_info *info,
1023             union iwreq_data *wrqu, char *extra)
1024 {
1025     strcpy(wrqu->name, "IEEE 802.11-FH");
1026     return 0;
1027 }
1028 
1029 /*------------------------------------------------------------------*/
1030 /*
1031  * Wireless Handler : set frequency
1032  */
1033 static int ray_set_freq(struct net_device *dev, struct iw_request_info *info,
1034             union iwreq_data *wrqu, char *extra)
1035 {
1036     ray_dev_t *local = netdev_priv(dev);
1037     int err = -EINPROGRESS; /* Call commit handler */
1038 
1039     /* Reject if card is already initialised */
1040     if (local->card_status != CARD_AWAITING_PARAM)
1041         return -EBUSY;
1042 
1043     /* Setting by channel number */
1044     if ((wrqu->freq.m > USA_HOP_MOD) || (wrqu->freq.e > 0))
1045         err = -EOPNOTSUPP;
1046     else
1047         local->sparm.b5.a_hop_pattern = wrqu->freq.m;
1048 
1049     return err;
1050 }
1051 
1052 /*------------------------------------------------------------------*/
1053 /*
1054  * Wireless Handler : get frequency
1055  */
1056 static int ray_get_freq(struct net_device *dev, struct iw_request_info *info,
1057             union iwreq_data *wrqu, char *extra)
1058 {
1059     ray_dev_t *local = netdev_priv(dev);
1060 
1061     wrqu->freq.m = local->sparm.b5.a_hop_pattern;
1062     wrqu->freq.e = 0;
1063     return 0;
1064 }
1065 
1066 /*------------------------------------------------------------------*/
1067 /*
1068  * Wireless Handler : set ESSID
1069  */
1070 static int ray_set_essid(struct net_device *dev, struct iw_request_info *info,
1071              union iwreq_data *wrqu, char *extra)
1072 {
1073     ray_dev_t *local = netdev_priv(dev);
1074 
1075     /* Reject if card is already initialised */
1076     if (local->card_status != CARD_AWAITING_PARAM)
1077         return -EBUSY;
1078 
1079     /* Check if we asked for `any' */
1080     if (wrqu->essid.flags == 0)
1081         /* Corey : can you do that ? */
1082         return -EOPNOTSUPP;
1083 
1084     /* Check the size of the string */
1085     if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1086         return -E2BIG;
1087 
1088     /* Set the ESSID in the card */
1089     memset(local->sparm.b5.a_current_ess_id, 0, IW_ESSID_MAX_SIZE);
1090     memcpy(local->sparm.b5.a_current_ess_id, extra, wrqu->essid.length);
1091 
1092     return -EINPROGRESS;    /* Call commit handler */
1093 }
1094 
1095 /*------------------------------------------------------------------*/
1096 /*
1097  * Wireless Handler : get ESSID
1098  */
1099 static int ray_get_essid(struct net_device *dev, struct iw_request_info *info,
1100              union iwreq_data *wrqu, char *extra)
1101 {
1102     ray_dev_t *local = netdev_priv(dev);
1103     UCHAR tmp[IW_ESSID_MAX_SIZE + 1];
1104 
1105     /* Get the essid that was set */
1106     memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
1107     memcpy(tmp, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
1108     tmp[IW_ESSID_MAX_SIZE] = '\0';
1109 
1110     /* Push it out ! */
1111     wrqu->essid.length = strlen(tmp);
1112     wrqu->essid.flags = 1;  /* active */
1113 
1114     return 0;
1115 }
1116 
1117 /*------------------------------------------------------------------*/
1118 /*
1119  * Wireless Handler : get AP address
1120  */
1121 static int ray_get_wap(struct net_device *dev, struct iw_request_info *info,
1122                union iwreq_data *wrqu, char *extra)
1123 {
1124     ray_dev_t *local = netdev_priv(dev);
1125 
1126     memcpy(wrqu->ap_addr.sa_data, local->bss_id, ETH_ALEN);
1127     wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1128 
1129     return 0;
1130 }
1131 
1132 /*------------------------------------------------------------------*/
1133 /*
1134  * Wireless Handler : set Bit-Rate
1135  */
1136 static int ray_set_rate(struct net_device *dev, struct iw_request_info *info,
1137             union iwreq_data *wrqu, char *extra)
1138 {
1139     ray_dev_t *local = netdev_priv(dev);
1140 
1141     /* Reject if card is already initialised */
1142     if (local->card_status != CARD_AWAITING_PARAM)
1143         return -EBUSY;
1144 
1145     /* Check if rate is in range */
1146     if ((wrqu->bitrate.value != 1000000) && (wrqu->bitrate.value != 2000000))
1147         return -EINVAL;
1148 
1149     /* Hack for 1.5 Mb/s instead of 2 Mb/s */
1150     if ((local->fw_ver == 0x55) &&  /* Please check */
1151         (wrqu->bitrate.value == 2000000))
1152         local->net_default_tx_rate = 3;
1153     else
1154         local->net_default_tx_rate = wrqu->bitrate.value / 500000;
1155 
1156     return 0;
1157 }
1158 
1159 /*------------------------------------------------------------------*/
1160 /*
1161  * Wireless Handler : get Bit-Rate
1162  */
1163 static int ray_get_rate(struct net_device *dev, struct iw_request_info *info,
1164             union iwreq_data *wrqu, char *extra)
1165 {
1166     ray_dev_t *local = netdev_priv(dev);
1167 
1168     if (local->net_default_tx_rate == 3)
1169         wrqu->bitrate.value = 2000000;  /* Hum... */
1170     else
1171         wrqu->bitrate.value = local->net_default_tx_rate * 500000;
1172     wrqu->bitrate.fixed = 0;    /* We are in auto mode */
1173 
1174     return 0;
1175 }
1176 
1177 /*------------------------------------------------------------------*/
1178 /*
1179  * Wireless Handler : set RTS threshold
1180  */
1181 static int ray_set_rts(struct net_device *dev, struct iw_request_info *info,
1182                union iwreq_data *wrqu, char *extra)
1183 {
1184     ray_dev_t *local = netdev_priv(dev);
1185     int rthr = wrqu->rts.value;
1186 
1187     /* Reject if card is already initialised */
1188     if (local->card_status != CARD_AWAITING_PARAM)
1189         return -EBUSY;
1190 
1191     /* if(wrq->u.rts.fixed == 0) we should complain */
1192     if (wrqu->rts.disabled)
1193         rthr = 32767;
1194     else {
1195         if ((rthr < 0) || (rthr > 2347))   /* What's the max packet size ??? */
1196             return -EINVAL;
1197     }
1198     local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF;
1199     local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF;
1200 
1201     return -EINPROGRESS;    /* Call commit handler */
1202 }
1203 
1204 /*------------------------------------------------------------------*/
1205 /*
1206  * Wireless Handler : get RTS threshold
1207  */
1208 static int ray_get_rts(struct net_device *dev, struct iw_request_info *info,
1209                union iwreq_data *wrqu, char *extra)
1210 {
1211     ray_dev_t *local = netdev_priv(dev);
1212 
1213     wrqu->rts.value = (local->sparm.b5.a_rts_threshold[0] << 8)
1214         + local->sparm.b5.a_rts_threshold[1];
1215     wrqu->rts.disabled = (wrqu->rts.value == 32767);
1216     wrqu->rts.fixed = 1;
1217 
1218     return 0;
1219 }
1220 
1221 /*------------------------------------------------------------------*/
1222 /*
1223  * Wireless Handler : set Fragmentation threshold
1224  */
1225 static int ray_set_frag(struct net_device *dev, struct iw_request_info *info,
1226             union iwreq_data *wrqu, char *extra)
1227 {
1228     ray_dev_t *local = netdev_priv(dev);
1229     int fthr = wrqu->frag.value;
1230 
1231     /* Reject if card is already initialised */
1232     if (local->card_status != CARD_AWAITING_PARAM)
1233         return -EBUSY;
1234 
1235     /* if(wrq->u.frag.fixed == 0) should complain */
1236     if (wrqu->frag.disabled)
1237         fthr = 32767;
1238     else {
1239         if ((fthr < 256) || (fthr > 2347))  /* To check out ! */
1240             return -EINVAL;
1241     }
1242     local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF;
1243     local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF;
1244 
1245     return -EINPROGRESS;    /* Call commit handler */
1246 }
1247 
1248 /*------------------------------------------------------------------*/
1249 /*
1250  * Wireless Handler : get Fragmentation threshold
1251  */
1252 static int ray_get_frag(struct net_device *dev, struct iw_request_info *info,
1253             union iwreq_data *wrqu, char *extra)
1254 {
1255     ray_dev_t *local = netdev_priv(dev);
1256 
1257     wrqu->frag.value = (local->sparm.b5.a_frag_threshold[0] << 8)
1258         + local->sparm.b5.a_frag_threshold[1];
1259     wrqu->frag.disabled = (wrqu->frag.value == 32767);
1260     wrqu->frag.fixed = 1;
1261 
1262     return 0;
1263 }
1264 
1265 /*------------------------------------------------------------------*/
1266 /*
1267  * Wireless Handler : set Mode of Operation
1268  */
1269 static int ray_set_mode(struct net_device *dev, struct iw_request_info *info,
1270             union iwreq_data *wrqu, char *extra)
1271 {
1272     ray_dev_t *local = netdev_priv(dev);
1273     int err = -EINPROGRESS; /* Call commit handler */
1274     char card_mode = 1;
1275 
1276     /* Reject if card is already initialised */
1277     if (local->card_status != CARD_AWAITING_PARAM)
1278         return -EBUSY;
1279 
1280     switch (wrqu->mode) {
1281     case IW_MODE_ADHOC:
1282         card_mode = 0;
1283         fallthrough;
1284     case IW_MODE_INFRA:
1285         local->sparm.b5.a_network_type = card_mode;
1286         break;
1287     default:
1288         err = -EINVAL;
1289     }
1290 
1291     return err;
1292 }
1293 
1294 /*------------------------------------------------------------------*/
1295 /*
1296  * Wireless Handler : get Mode of Operation
1297  */
1298 static int ray_get_mode(struct net_device *dev, struct iw_request_info *info,
1299             union iwreq_data *wrqu, char *extra)
1300 {
1301     ray_dev_t *local = netdev_priv(dev);
1302 
1303     if (local->sparm.b5.a_network_type)
1304         wrqu->mode = IW_MODE_INFRA;
1305     else
1306         wrqu->mode = IW_MODE_ADHOC;
1307 
1308     return 0;
1309 }
1310 
1311 /*------------------------------------------------------------------*/
1312 /*
1313  * Wireless Handler : get range info
1314  */
1315 static int ray_get_range(struct net_device *dev, struct iw_request_info *info,
1316              union iwreq_data *wrqu, char *extra)
1317 {
1318     struct iw_range *range = (struct iw_range *)extra;
1319 
1320     memset(range, 0, sizeof(struct iw_range));
1321 
1322     /* Set the length (very important for backward compatibility) */
1323     wrqu->data.length = sizeof(struct iw_range);
1324 
1325     /* Set the Wireless Extension versions */
1326     range->we_version_compiled = WIRELESS_EXT;
1327     range->we_version_source = 9;
1328 
1329     /* Set information in the range struct */
1330     range->throughput = 1.1 * 1000 * 1000;  /* Put the right number here */
1331     range->num_channels = hop_pattern_length[(int)country];
1332     range->num_frequency = 0;
1333     range->max_qual.qual = 0;
1334     range->max_qual.level = 255;    /* What's the correct value ? */
1335     range->max_qual.noise = 255;    /* Idem */
1336     range->num_bitrates = 2;
1337     range->bitrate[0] = 1000000;    /* 1 Mb/s */
1338     range->bitrate[1] = 2000000;    /* 2 Mb/s */
1339     return 0;
1340 }
1341 
1342 /*------------------------------------------------------------------*/
1343 /*
1344  * Wireless Private Handler : set framing mode
1345  */
1346 static int ray_set_framing(struct net_device *dev, struct iw_request_info *info,
1347                union iwreq_data *wrqu, char *extra)
1348 {
1349     translate = !!*(extra); /* Set framing mode */
1350 
1351     return 0;
1352 }
1353 
1354 /*------------------------------------------------------------------*/
1355 /*
1356  * Wireless Private Handler : get framing mode
1357  */
1358 static int ray_get_framing(struct net_device *dev, struct iw_request_info *info,
1359                union iwreq_data *wrqu, char *extra)
1360 {
1361     *(extra) = translate;
1362 
1363     return 0;
1364 }
1365 
1366 /*------------------------------------------------------------------*/
1367 /*
1368  * Wireless Private Handler : get country
1369  */
1370 static int ray_get_country(struct net_device *dev, struct iw_request_info *info,
1371                union iwreq_data *wrqu, char *extra)
1372 {
1373     *(extra) = country;
1374 
1375     return 0;
1376 }
1377 
1378 /*------------------------------------------------------------------*/
1379 /*
1380  * Commit handler : called after a bunch of SET operations
1381  */
1382 static int ray_commit(struct net_device *dev, struct iw_request_info *info,
1383               union iwreq_data *wrqu, char *extra)
1384 {
1385     return 0;
1386 }
1387 
1388 /*------------------------------------------------------------------*/
1389 /*
1390  * Stats handler : return Wireless Stats
1391  */
1392 static iw_stats *ray_get_wireless_stats(struct net_device *dev)
1393 {
1394     ray_dev_t *local = netdev_priv(dev);
1395     struct pcmcia_device *link = local->finder;
1396     struct status __iomem *p = local->sram + STATUS_BASE;
1397 
1398     local->wstats.status = local->card_status;
1399 #ifdef WIRELESS_SPY
1400     if ((local->spy_data.spy_number > 0)
1401         && (local->sparm.b5.a_network_type == 0)) {
1402         /* Get it from the first node in spy list */
1403         local->wstats.qual.qual = local->spy_data.spy_stat[0].qual;
1404         local->wstats.qual.level = local->spy_data.spy_stat[0].level;
1405         local->wstats.qual.noise = local->spy_data.spy_stat[0].noise;
1406         local->wstats.qual.updated =
1407             local->spy_data.spy_stat[0].updated;
1408     }
1409 #endif /* WIRELESS_SPY */
1410 
1411     if (pcmcia_dev_present(link)) {
1412         local->wstats.qual.noise = readb(&p->rxnoise);
1413         local->wstats.qual.updated |= 4;
1414     }
1415 
1416     return &local->wstats;
1417 } /* end ray_get_wireless_stats */
1418 
1419 /*------------------------------------------------------------------*/
1420 /*
1421  * Structures to export the Wireless Handlers
1422  */
1423 
1424 static const iw_handler ray_handler[] = {
1425     IW_HANDLER(SIOCSIWCOMMIT, ray_commit),
1426     IW_HANDLER(SIOCGIWNAME, ray_get_name),
1427     IW_HANDLER(SIOCSIWFREQ, ray_set_freq),
1428     IW_HANDLER(SIOCGIWFREQ, ray_get_freq),
1429     IW_HANDLER(SIOCSIWMODE, ray_set_mode),
1430     IW_HANDLER(SIOCGIWMODE, ray_get_mode),
1431     IW_HANDLER(SIOCGIWRANGE, ray_get_range),
1432 #ifdef WIRELESS_SPY
1433     IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1434     IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1435     IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1436     IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1437 #endif /* WIRELESS_SPY */
1438     IW_HANDLER(SIOCGIWAP, ray_get_wap),
1439     IW_HANDLER(SIOCSIWESSID, ray_set_essid),
1440     IW_HANDLER(SIOCGIWESSID, ray_get_essid),
1441     IW_HANDLER(SIOCSIWRATE, ray_set_rate),
1442     IW_HANDLER(SIOCGIWRATE, ray_get_rate),
1443     IW_HANDLER(SIOCSIWRTS, ray_set_rts),
1444     IW_HANDLER(SIOCGIWRTS, ray_get_rts),
1445     IW_HANDLER(SIOCSIWFRAG, ray_set_frag),
1446     IW_HANDLER(SIOCGIWFRAG, ray_get_frag),
1447 };
1448 
1449 #define SIOCSIPFRAMING  SIOCIWFIRSTPRIV /* Set framing mode */
1450 #define SIOCGIPFRAMING  SIOCIWFIRSTPRIV + 1 /* Get framing mode */
1451 #define SIOCGIPCOUNTRY  SIOCIWFIRSTPRIV + 3 /* Get country code */
1452 
1453 static const iw_handler ray_private_handler[] = {
1454     [0] = ray_set_framing,
1455     [1] = ray_get_framing,
1456     [3] = ray_get_country,
1457 };
1458 
1459 static const struct iw_priv_args ray_private_args[] = {
1460 /* cmd,     set_args,   get_args,   name */
1461     {SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0,
1462      "set_framing"},
1463     {SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
1464      "get_framing"},
1465     {SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
1466      "get_country"},
1467 };
1468 
1469 static const struct iw_handler_def ray_handler_def = {
1470     .num_standard = ARRAY_SIZE(ray_handler),
1471     .num_private = ARRAY_SIZE(ray_private_handler),
1472     .num_private_args = ARRAY_SIZE(ray_private_args),
1473     .standard = ray_handler,
1474     .private = ray_private_handler,
1475     .private_args = ray_private_args,
1476     .get_wireless_stats = ray_get_wireless_stats,
1477 };
1478 
1479 /*===========================================================================*/
1480 static int ray_open(struct net_device *dev)
1481 {
1482     ray_dev_t *local = netdev_priv(dev);
1483     struct pcmcia_device *link;
1484     link = local->finder;
1485 
1486     dev_dbg(&link->dev, "ray_open('%s')\n", dev->name);
1487 
1488     if (link->open == 0)
1489         local->num_multi = 0;
1490     link->open++;
1491 
1492     /* If the card is not started, time to start it ! - Jean II */
1493     if (local->card_status == CARD_AWAITING_PARAM) {
1494         int i;
1495 
1496         dev_dbg(&link->dev, "ray_open: doing init now !\n");
1497 
1498         /* Download startup parameters */
1499         if ((i = dl_startup_params(dev)) < 0) {
1500             printk(KERN_INFO
1501                    "ray_dev_init dl_startup_params failed - "
1502                    "returns 0x%x\n", i);
1503             return -1;
1504         }
1505     }
1506 
1507     if (sniffer)
1508         netif_stop_queue(dev);
1509     else
1510         netif_start_queue(dev);
1511 
1512     dev_dbg(&link->dev, "ray_open ending\n");
1513     return 0;
1514 } /* end ray_open */
1515 
1516 /*===========================================================================*/
1517 static int ray_dev_close(struct net_device *dev)
1518 {
1519     ray_dev_t *local = netdev_priv(dev);
1520     struct pcmcia_device *link;
1521     link = local->finder;
1522 
1523     dev_dbg(&link->dev, "ray_dev_close('%s')\n", dev->name);
1524 
1525     link->open--;
1526     netif_stop_queue(dev);
1527 
1528     /* In here, we should stop the hardware (stop card from beeing active)
1529      * and set local->card_status to CARD_AWAITING_PARAM, so that while the
1530      * card is closed we can chage its configuration.
1531      * Probably also need a COR reset to get sane state - Jean II */
1532 
1533     return 0;
1534 } /* end ray_dev_close */
1535 
1536 /*===========================================================================*/
1537 static void ray_reset(struct net_device *dev)
1538 {
1539     pr_debug("ray_reset entered\n");
1540 }
1541 
1542 /*===========================================================================*/
1543 /* Cause a firmware interrupt if it is ready for one                         */
1544 /* Return nonzero if not ready                                               */
1545 static int interrupt_ecf(ray_dev_t *local, int ccs)
1546 {
1547     int i = 50;
1548     struct pcmcia_device *link = local->finder;
1549 
1550     if (!(pcmcia_dev_present(link))) {
1551         dev_dbg(&link->dev, "ray_cs interrupt_ecf - device not present\n");
1552         return -1;
1553     }
1554     dev_dbg(&link->dev, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs);
1555 
1556     while (i &&
1557            (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) &
1558         ECF_INTR_SET))
1559         i--;
1560     if (i == 0) {
1561         dev_dbg(&link->dev, "ray_cs interrupt_ecf card not ready for interrupt\n");
1562         return -1;
1563     }
1564     /* Fill the mailbox, then kick the card */
1565     writeb(ccs, local->sram + SCB_BASE);
1566     writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET);
1567     return 0;
1568 } /* interrupt_ecf */
1569 
1570 /*===========================================================================*/
1571 /* Get next free transmit CCS                                                */
1572 /* Return - index of current tx ccs                                          */
1573 static int get_free_tx_ccs(ray_dev_t *local)
1574 {
1575     int i;
1576     struct ccs __iomem *pccs = ccs_base(local);
1577     struct pcmcia_device *link = local->finder;
1578 
1579     if (!(pcmcia_dev_present(link))) {
1580         dev_dbg(&link->dev, "ray_cs get_free_tx_ccs - device not present\n");
1581         return ECARDGONE;
1582     }
1583 
1584     if (test_and_set_bit(0, &local->tx_ccs_lock)) {
1585         dev_dbg(&link->dev, "ray_cs tx_ccs_lock busy\n");
1586         return ECCSBUSY;
1587     }
1588 
1589     for (i = 0; i < NUMBER_OF_TX_CCS; i++) {
1590         if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
1591             writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
1592             writeb(CCS_END_LIST, &(pccs + i)->link);
1593             local->tx_ccs_lock = 0;
1594             return i;
1595         }
1596     }
1597     local->tx_ccs_lock = 0;
1598     dev_dbg(&link->dev, "ray_cs ERROR no free tx CCS for raylink card\n");
1599     return ECCSFULL;
1600 } /* get_free_tx_ccs */
1601 
1602 /*===========================================================================*/
1603 /* Get next free CCS                                                         */
1604 /* Return - index of current ccs                                             */
1605 static int get_free_ccs(ray_dev_t *local)
1606 {
1607     int i;
1608     struct ccs __iomem *pccs = ccs_base(local);
1609     struct pcmcia_device *link = local->finder;
1610 
1611     if (!(pcmcia_dev_present(link))) {
1612         dev_dbg(&link->dev, "ray_cs get_free_ccs - device not present\n");
1613         return ECARDGONE;
1614     }
1615     if (test_and_set_bit(0, &local->ccs_lock)) {
1616         dev_dbg(&link->dev, "ray_cs ccs_lock busy\n");
1617         return ECCSBUSY;
1618     }
1619 
1620     for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) {
1621         if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
1622             writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
1623             writeb(CCS_END_LIST, &(pccs + i)->link);
1624             local->ccs_lock = 0;
1625             return i;
1626         }
1627     }
1628     local->ccs_lock = 0;
1629     dev_dbg(&link->dev, "ray_cs ERROR no free CCS for raylink card\n");
1630     return ECCSFULL;
1631 } /* get_free_ccs */
1632 
1633 /*===========================================================================*/
1634 static void authenticate_timeout(struct timer_list *t)
1635 {
1636     ray_dev_t *local = from_timer(local, t, timer);
1637     del_timer(&local->timer);
1638     printk(KERN_INFO "ray_cs Authentication with access point failed"
1639            " - timeout\n");
1640     join_net(&local->timer);
1641 }
1642 
1643 /*===========================================================================*/
1644 static int parse_addr(char *in_str, UCHAR *out)
1645 {
1646     int i, k;
1647     int len;
1648 
1649     if (in_str == NULL)
1650         return 0;
1651     len = strnlen(in_str, ADDRLEN * 2 + 1) - 1;
1652     if (len < 1)
1653         return 0;
1654     memset(out, 0, ADDRLEN);
1655 
1656     i = 5;
1657 
1658     while (len > 0) {
1659         if ((k = hex_to_bin(in_str[len--])) != -1)
1660             out[i] = k;
1661         else
1662             return 0;
1663 
1664         if (len == 0)
1665             break;
1666         if ((k = hex_to_bin(in_str[len--])) != -1)
1667             out[i] += k << 4;
1668         else
1669             return 0;
1670         if (!i--)
1671             break;
1672     }
1673     return 1;
1674 }
1675 
1676 /*===========================================================================*/
1677 static struct net_device_stats *ray_get_stats(struct net_device *dev)
1678 {
1679     ray_dev_t *local = netdev_priv(dev);
1680     struct pcmcia_device *link = local->finder;
1681     struct status __iomem *p = local->sram + STATUS_BASE;
1682     if (!(pcmcia_dev_present(link))) {
1683         dev_dbg(&link->dev, "ray_cs net_device_stats - device not present\n");
1684         return &local->stats;
1685     }
1686     if (readb(&p->mrx_overflow_for_host)) {
1687         local->stats.rx_over_errors += swab16(readw(&p->mrx_overflow));
1688         writeb(0, &p->mrx_overflow);
1689         writeb(0, &p->mrx_overflow_for_host);
1690     }
1691     if (readb(&p->mrx_checksum_error_for_host)) {
1692         local->stats.rx_crc_errors +=
1693             swab16(readw(&p->mrx_checksum_error));
1694         writeb(0, &p->mrx_checksum_error);
1695         writeb(0, &p->mrx_checksum_error_for_host);
1696     }
1697     if (readb(&p->rx_hec_error_for_host)) {
1698         local->stats.rx_frame_errors += swab16(readw(&p->rx_hec_error));
1699         writeb(0, &p->rx_hec_error);
1700         writeb(0, &p->rx_hec_error_for_host);
1701     }
1702     return &local->stats;
1703 }
1704 
1705 /*===========================================================================*/
1706 static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value,
1707                 int len)
1708 {
1709     ray_dev_t *local = netdev_priv(dev);
1710     struct pcmcia_device *link = local->finder;
1711     int ccsindex;
1712     int i;
1713     struct ccs __iomem *pccs;
1714 
1715     if (!(pcmcia_dev_present(link))) {
1716         dev_dbg(&link->dev, "ray_update_parm - device not present\n");
1717         return;
1718     }
1719 
1720     if ((ccsindex = get_free_ccs(local)) < 0) {
1721         dev_dbg(&link->dev, "ray_update_parm - No free ccs\n");
1722         return;
1723     }
1724     pccs = ccs_base(local) + ccsindex;
1725     writeb(CCS_UPDATE_PARAMS, &pccs->cmd);
1726     writeb(objid, &pccs->var.update_param.object_id);
1727     writeb(1, &pccs->var.update_param.number_objects);
1728     writeb(0, &pccs->var.update_param.failure_cause);
1729     for (i = 0; i < len; i++) {
1730         writeb(value[i], local->sram + HOST_TO_ECF_BASE);
1731     }
1732     /* Interrupt the firmware to process the command */
1733     if (interrupt_ecf(local, ccsindex)) {
1734         dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n");
1735         writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
1736     }
1737 }
1738 
1739 /*===========================================================================*/
1740 static void ray_update_multi_list(struct net_device *dev, int all)
1741 {
1742     int ccsindex;
1743     struct ccs __iomem *pccs;
1744     ray_dev_t *local = netdev_priv(dev);
1745     struct pcmcia_device *link = local->finder;
1746     void __iomem *p = local->sram + HOST_TO_ECF_BASE;
1747 
1748     if (!(pcmcia_dev_present(link))) {
1749         dev_dbg(&link->dev, "ray_update_multi_list - device not present\n");
1750         return;
1751     } else
1752         dev_dbg(&link->dev, "ray_update_multi_list(%p)\n", dev);
1753     if ((ccsindex = get_free_ccs(local)) < 0) {
1754         dev_dbg(&link->dev, "ray_update_multi - No free ccs\n");
1755         return;
1756     }
1757     pccs = ccs_base(local) + ccsindex;
1758     writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);
1759 
1760     if (all) {
1761         writeb(0xff, &pccs->var);
1762         local->num_multi = 0xff;
1763     } else {
1764         struct netdev_hw_addr *ha;
1765         int i = 0;
1766 
1767         /* Copy the kernel's list of MC addresses to card */
1768         netdev_for_each_mc_addr(ha, dev) {
1769             memcpy_toio(p, ha->addr, ETH_ALEN);
1770             dev_dbg(&link->dev, "ray_update_multi add addr %pm\n",
1771                 ha->addr);
1772             p += ETH_ALEN;
1773             i++;
1774         }
1775         if (i > 256 / ADDRLEN)
1776             i = 256 / ADDRLEN;
1777         writeb((UCHAR) i, &pccs->var);
1778         dev_dbg(&link->dev, "ray_cs update_multi %d addresses in list\n", i);
1779         /* Interrupt the firmware to process the command */
1780         local->num_multi = i;
1781     }
1782     if (interrupt_ecf(local, ccsindex)) {
1783         dev_dbg(&link->dev,
1784               "ray_cs update_multi failed - ECF not ready for intr\n");
1785         writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
1786     }
1787 } /* end ray_update_multi_list */
1788 
1789 /*===========================================================================*/
1790 static void set_multicast_list(struct net_device *dev)
1791 {
1792     ray_dev_t *local = netdev_priv(dev);
1793     UCHAR promisc;
1794 
1795     pr_debug("ray_cs set_multicast_list(%p)\n", dev);
1796 
1797     if (dev->flags & IFF_PROMISC) {
1798         if (local->sparm.b5.a_promiscuous_mode == 0) {
1799             pr_debug("ray_cs set_multicast_list promisc on\n");
1800             local->sparm.b5.a_promiscuous_mode = 1;
1801             promisc = 1;
1802             ray_update_parm(dev, OBJID_promiscuous_mode,
1803                     &promisc, sizeof(promisc));
1804         }
1805     } else {
1806         if (local->sparm.b5.a_promiscuous_mode == 1) {
1807             pr_debug("ray_cs set_multicast_list promisc off\n");
1808             local->sparm.b5.a_promiscuous_mode = 0;
1809             promisc = 0;
1810             ray_update_parm(dev, OBJID_promiscuous_mode,
1811                     &promisc, sizeof(promisc));
1812         }
1813     }
1814 
1815     if (dev->flags & IFF_ALLMULTI)
1816         ray_update_multi_list(dev, 1);
1817     else {
1818         if (local->num_multi != netdev_mc_count(dev))
1819             ray_update_multi_list(dev, 0);
1820     }
1821 } /* end set_multicast_list */
1822 
1823 /*=============================================================================
1824  * All routines below here are run at interrupt time.
1825 =============================================================================*/
1826 static irqreturn_t ray_interrupt(int irq, void *dev_id)
1827 {
1828     struct net_device *dev = (struct net_device *)dev_id;
1829     struct pcmcia_device *link;
1830     ray_dev_t *local;
1831     struct ccs __iomem *pccs;
1832     struct rcs __iomem *prcs;
1833     UCHAR rcsindex;
1834     UCHAR tmp;
1835     UCHAR cmd;
1836     UCHAR status;
1837     UCHAR memtmp[ESSID_SIZE + 1];
1838 
1839 
1840     if (dev == NULL)    /* Note that we want interrupts with dev->start == 0 */
1841         return IRQ_NONE;
1842 
1843     pr_debug("ray_cs: interrupt for *dev=%p\n", dev);
1844 
1845     local = netdev_priv(dev);
1846     link = local->finder;
1847     if (!pcmcia_dev_present(link)) {
1848         pr_debug(
1849             "ray_cs interrupt from device not present or suspended.\n");
1850         return IRQ_NONE;
1851     }
1852     rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index);
1853 
1854     if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
1855         dev_dbg(&link->dev, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex);
1856         clear_interrupt(local);
1857         return IRQ_HANDLED;
1858     }
1859     if (rcsindex < NUMBER_OF_CCS) { /* If it's a returned CCS */
1860         pccs = ccs_base(local) + rcsindex;
1861         cmd = readb(&pccs->cmd);
1862         status = readb(&pccs->buffer_status);
1863         switch (cmd) {
1864         case CCS_DOWNLOAD_STARTUP_PARAMS:   /* Happens in firmware someday */
1865             del_timer(&local->timer);
1866             if (status == CCS_COMMAND_COMPLETE) {
1867                 dev_dbg(&link->dev,
1868                       "ray_cs interrupt download_startup_parameters OK\n");
1869             } else {
1870                 dev_dbg(&link->dev,
1871                       "ray_cs interrupt download_startup_parameters fail\n");
1872             }
1873             break;
1874         case CCS_UPDATE_PARAMS:
1875             dev_dbg(&link->dev, "ray_cs interrupt update params done\n");
1876             if (status != CCS_COMMAND_COMPLETE) {
1877                 tmp =
1878                     readb(&pccs->var.update_param.
1879                       failure_cause);
1880                 dev_dbg(&link->dev,
1881                       "ray_cs interrupt update params failed - reason %d\n",
1882                       tmp);
1883             }
1884             break;
1885         case CCS_REPORT_PARAMS:
1886             dev_dbg(&link->dev, "ray_cs interrupt report params done\n");
1887             break;
1888         case CCS_UPDATE_MULTICAST_LIST: /* Note that this CCS isn't returned */
1889             dev_dbg(&link->dev,
1890                   "ray_cs interrupt CCS Update Multicast List done\n");
1891             break;
1892         case CCS_UPDATE_POWER_SAVINGS_MODE:
1893             dev_dbg(&link->dev,
1894                   "ray_cs interrupt update power save mode done\n");
1895             break;
1896         case CCS_START_NETWORK:
1897         case CCS_JOIN_NETWORK:
1898             memcpy(memtmp, local->sparm.b4.a_current_ess_id,
1899                                 ESSID_SIZE);
1900             memtmp[ESSID_SIZE] = '\0';
1901 
1902             if (status == CCS_COMMAND_COMPLETE) {
1903                 if (readb
1904                     (&pccs->var.start_network.net_initiated) ==
1905                     1) {
1906                     dev_dbg(&link->dev,
1907                           "ray_cs interrupt network \"%s\" started\n",
1908                           memtmp);
1909                 } else {
1910                     dev_dbg(&link->dev,
1911                           "ray_cs interrupt network \"%s\" joined\n",
1912                           memtmp);
1913                 }
1914                 memcpy_fromio(&local->bss_id,
1915                           pccs->var.start_network.bssid,
1916                           ADDRLEN);
1917 
1918                 if (local->fw_ver == 0x55)
1919                     local->net_default_tx_rate = 3;
1920                 else
1921                     local->net_default_tx_rate =
1922                         readb(&pccs->var.start_network.
1923                           net_default_tx_rate);
1924                 local->encryption =
1925                     readb(&pccs->var.start_network.encryption);
1926                 if (!sniffer && (local->net_type == INFRA)
1927                     && !(local->sparm.b4.a_acting_as_ap_status)) {
1928                     authenticate(local);
1929                 }
1930                 local->card_status = CARD_ACQ_COMPLETE;
1931             } else {
1932                 local->card_status = CARD_ACQ_FAILED;
1933 
1934                 del_timer(&local->timer);
1935                 local->timer.expires = jiffies + HZ * 5;
1936                 if (status == CCS_START_NETWORK) {
1937                     dev_dbg(&link->dev,
1938                           "ray_cs interrupt network \"%s\" start failed\n",
1939                           memtmp);
1940                     local->timer.function = start_net;
1941                 } else {
1942                     dev_dbg(&link->dev,
1943                           "ray_cs interrupt network \"%s\" join failed\n",
1944                           memtmp);
1945                     local->timer.function = join_net;
1946                 }
1947                 add_timer(&local->timer);
1948             }
1949             break;
1950         case CCS_START_ASSOCIATION:
1951             if (status == CCS_COMMAND_COMPLETE) {
1952                 local->card_status = CARD_ASSOC_COMPLETE;
1953                 dev_dbg(&link->dev, "ray_cs association successful\n");
1954             } else {
1955                 dev_dbg(&link->dev, "ray_cs association failed,\n");
1956                 local->card_status = CARD_ASSOC_FAILED;
1957                 join_net(&local->timer);
1958             }
1959             break;
1960         case CCS_TX_REQUEST:
1961             if (status == CCS_COMMAND_COMPLETE) {
1962                 dev_dbg(&link->dev,
1963                       "ray_cs interrupt tx request complete\n");
1964             } else {
1965                 dev_dbg(&link->dev,
1966                       "ray_cs interrupt tx request failed\n");
1967             }
1968             if (!sniffer)
1969                 netif_start_queue(dev);
1970             netif_wake_queue(dev);
1971             break;
1972         case CCS_TEST_MEMORY:
1973             dev_dbg(&link->dev, "ray_cs interrupt mem test done\n");
1974             break;
1975         case CCS_SHUTDOWN:
1976             dev_dbg(&link->dev,
1977                   "ray_cs interrupt Unexpected CCS returned - Shutdown\n");
1978             break;
1979         case CCS_DUMP_MEMORY:
1980             dev_dbg(&link->dev, "ray_cs interrupt dump memory done\n");
1981             break;
1982         case CCS_START_TIMER:
1983             dev_dbg(&link->dev,
1984                   "ray_cs interrupt DING - raylink timer expired\n");
1985             break;
1986         default:
1987             dev_dbg(&link->dev,
1988                   "ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",
1989                   rcsindex, cmd);
1990         }
1991         writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
1992     } else { /* It's an RCS */
1993 
1994         prcs = rcs_base(local) + rcsindex;
1995 
1996         switch (readb(&prcs->interrupt_id)) {
1997         case PROCESS_RX_PACKET:
1998             ray_rx(dev, local, prcs);
1999             break;
2000         case REJOIN_NET_COMPLETE:
2001             dev_dbg(&link->dev, "ray_cs interrupt rejoin net complete\n");
2002             local->card_status = CARD_ACQ_COMPLETE;
2003             /* do we need to clear tx buffers CCS's? */
2004             if (local->sparm.b4.a_network_type == ADHOC) {
2005                 if (!sniffer)
2006                     netif_start_queue(dev);
2007             } else {
2008                 memcpy_fromio(&local->bss_id,
2009                           prcs->var.rejoin_net_complete.
2010                           bssid, ADDRLEN);
2011                 dev_dbg(&link->dev, "ray_cs new BSSID = %pm\n",
2012                     local->bss_id);
2013                 if (!sniffer)
2014                     authenticate(local);
2015             }
2016             break;
2017         case ROAMING_INITIATED:
2018             dev_dbg(&link->dev, "ray_cs interrupt roaming initiated\n");
2019             netif_stop_queue(dev);
2020             local->card_status = CARD_DOING_ACQ;
2021             break;
2022         case JAPAN_CALL_SIGN_RXD:
2023             dev_dbg(&link->dev, "ray_cs interrupt japan call sign rx\n");
2024             break;
2025         default:
2026             dev_dbg(&link->dev,
2027                   "ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",
2028                   rcsindex,
2029                   (unsigned int)readb(&prcs->interrupt_id));
2030             break;
2031         }
2032         writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
2033     }
2034     clear_interrupt(local);
2035     return IRQ_HANDLED;
2036 } /* ray_interrupt */
2037 
2038 /*===========================================================================*/
2039 static void ray_rx(struct net_device *dev, ray_dev_t *local,
2040            struct rcs __iomem *prcs)
2041 {
2042     int rx_len;
2043     unsigned int pkt_addr;
2044     void __iomem *pmsg;
2045     pr_debug("ray_rx process rx packet\n");
2046 
2047     /* Calculate address of packet within Rx buffer */
2048     pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
2049             + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END;
2050     /* Length of first packet fragment */
2051     rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8)
2052         + readb(&prcs->var.rx_packet.rx_data_length[1]);
2053 
2054     local->last_rsl = readb(&prcs->var.rx_packet.rx_sig_lev);
2055     pmsg = local->rmem + pkt_addr;
2056     switch (readb(pmsg)) {
2057     case DATA_TYPE:
2058         pr_debug("ray_rx data type\n");
2059         rx_data(dev, prcs, pkt_addr, rx_len);
2060         break;
2061     case AUTHENTIC_TYPE:
2062         pr_debug("ray_rx authentic type\n");
2063         if (sniffer)
2064             rx_data(dev, prcs, pkt_addr, rx_len);
2065         else
2066             rx_authenticate(local, prcs, pkt_addr, rx_len);
2067         break;
2068     case DEAUTHENTIC_TYPE:
2069         pr_debug("ray_rx deauth type\n");
2070         if (sniffer)
2071             rx_data(dev, prcs, pkt_addr, rx_len);
2072         else
2073             rx_deauthenticate(local, prcs, pkt_addr, rx_len);
2074         break;
2075     case NULL_MSG_TYPE:
2076         pr_debug("ray_cs rx NULL msg\n");
2077         break;
2078     case BEACON_TYPE:
2079         pr_debug("ray_rx beacon type\n");
2080         if (sniffer)
2081             rx_data(dev, prcs, pkt_addr, rx_len);
2082 
2083         copy_from_rx_buff(local, (UCHAR *) &local->last_bcn, pkt_addr,
2084                   rx_len < sizeof(struct beacon_rx) ?
2085                   rx_len : sizeof(struct beacon_rx));
2086 
2087         local->beacon_rxed = 1;
2088         /* Get the statistics so the card counters never overflow */
2089         ray_get_stats(dev);
2090         break;
2091     default:
2092         pr_debug("ray_cs unknown pkt type %2x\n",
2093               (unsigned int)readb(pmsg));
2094         break;
2095     }
2096 
2097 } /* end ray_rx */
2098 
2099 /*===========================================================================*/
2100 static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
2101             unsigned int pkt_addr, int rx_len)
2102 {
2103     struct sk_buff *skb = NULL;
2104     struct rcs __iomem *prcslink = prcs;
2105     ray_dev_t *local = netdev_priv(dev);
2106     UCHAR *rx_ptr;
2107     int total_len;
2108     int tmp;
2109 #ifdef WIRELESS_SPY
2110     int siglev = local->last_rsl;
2111     u_char linksrcaddr[ETH_ALEN];   /* Other end of the wireless link */
2112 #endif
2113 
2114     if (!sniffer) {
2115         if (translate) {
2116 /* TBD length needs fixing for translated header */
2117             if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
2118                 rx_len >
2119                 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
2120                  FCS_LEN)) {
2121                 pr_debug(
2122                       "ray_cs invalid packet length %d received\n",
2123                       rx_len);
2124                 return;
2125             }
2126         } else { /* encapsulated ethernet */
2127 
2128             if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
2129                 rx_len >
2130                 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
2131                  FCS_LEN)) {
2132                 pr_debug(
2133                       "ray_cs invalid packet length %d received\n",
2134                       rx_len);
2135                 return;
2136             }
2137         }
2138     }
2139     pr_debug("ray_cs rx_data packet\n");
2140     /* If fragmented packet, verify sizes of fragments add up */
2141     if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
2142         pr_debug("ray_cs rx'ed fragment\n");
2143         tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
2144             + readb(&prcs->var.rx_packet.totalpacketlength[1]);
2145         total_len = tmp;
2146         prcslink = prcs;
2147         do {
2148             tmp -=
2149                 (readb(&prcslink->var.rx_packet.rx_data_length[0])
2150                  << 8)
2151                 + readb(&prcslink->var.rx_packet.rx_data_length[1]);
2152             if (readb(&prcslink->var.rx_packet.next_frag_rcs_index)
2153                 == 0xFF || tmp < 0)
2154                 break;
2155             prcslink = rcs_base(local)
2156                 + readb(&prcslink->link_field);
2157         } while (1);
2158 
2159         if (tmp < 0) {
2160             pr_debug(
2161                   "ray_cs rx_data fragment lengths don't add up\n");
2162             local->stats.rx_dropped++;
2163             release_frag_chain(local, prcs);
2164             return;
2165         }
2166     } else { /* Single unfragmented packet */
2167         total_len = rx_len;
2168     }
2169 
2170     skb = dev_alloc_skb(total_len + 5);
2171     if (skb == NULL) {
2172         pr_debug("ray_cs rx_data could not allocate skb\n");
2173         local->stats.rx_dropped++;
2174         if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
2175             release_frag_chain(local, prcs);
2176         return;
2177     }
2178     skb_reserve(skb, 2);    /* Align IP on 16 byte (TBD check this) */
2179 
2180     pr_debug("ray_cs rx_data total_len = %x, rx_len = %x\n", total_len,
2181           rx_len);
2182 
2183 /************************/
2184     /* Reserve enough room for the whole damn packet. */
2185     rx_ptr = skb_put(skb, total_len);
2186     /* Copy the whole packet to sk_buff */
2187     rx_ptr +=
2188         copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
2189     /* Get source address */
2190 #ifdef WIRELESS_SPY
2191     skb_copy_from_linear_data_offset(skb,
2192                      offsetof(struct mac_header, addr_2),
2193                      linksrcaddr, ETH_ALEN);
2194 #endif
2195     /* Now, deal with encapsulation/translation/sniffer */
2196     if (!sniffer) {
2197         if (!translate) {
2198             /* Encapsulated ethernet, so just lop off 802.11 MAC header */
2199 /* TBD reserve            skb_reserve( skb, RX_MAC_HEADER_LENGTH); */
2200             skb_pull(skb, RX_MAC_HEADER_LENGTH);
2201         } else {
2202             /* Do translation */
2203             untranslate(local, skb, total_len);
2204         }
2205     } else { /* sniffer mode, so just pass whole packet */
2206     }
2207 
2208 /************************/
2209     /* Now pick up the rest of the fragments if any */
2210     tmp = 17;
2211     if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
2212         prcslink = prcs;
2213         pr_debug("ray_cs rx_data in fragment loop\n");
2214         do {
2215             prcslink = rcs_base(local)
2216                 +
2217                 readb(&prcslink->var.rx_packet.next_frag_rcs_index);
2218             rx_len =
2219                 ((readb(&prcslink->var.rx_packet.rx_data_length[0])
2220                   << 8)
2221                  +
2222                  readb(&prcslink->var.rx_packet.rx_data_length[1]))
2223                 & RX_BUFF_END;
2224             pkt_addr =
2225                 ((readb(&prcslink->var.rx_packet.rx_data_ptr[0]) <<
2226                   8)
2227                  + readb(&prcslink->var.rx_packet.rx_data_ptr[1]))
2228                 & RX_BUFF_END;
2229 
2230             rx_ptr +=
2231                 copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len);
2232 
2233         } while (tmp-- &&
2234              readb(&prcslink->var.rx_packet.next_frag_rcs_index) !=
2235              0xFF);
2236         release_frag_chain(local, prcs);
2237     }
2238 
2239     skb->protocol = eth_type_trans(skb, dev);
2240     netif_rx(skb);
2241     local->stats.rx_packets++;
2242     local->stats.rx_bytes += total_len;
2243 
2244     /* Gather signal strength per address */
2245 #ifdef WIRELESS_SPY
2246     /* For the Access Point or the node having started the ad-hoc net
2247      * note : ad-hoc work only in some specific configurations, but we
2248      * kludge in ray_get_wireless_stats... */
2249     if (!memcmp(linksrcaddr, local->bss_id, ETH_ALEN)) {
2250         /* Update statistics */
2251         /*local->wstats.qual.qual = none ? */
2252         local->wstats.qual.level = siglev;
2253         /*local->wstats.qual.noise = none ? */
2254         local->wstats.qual.updated = 0x2;
2255     }
2256     /* Now, update the spy stuff */
2257     {
2258         struct iw_quality wstats;
2259         wstats.level = siglev;
2260         /* wstats.noise = none ? */
2261         /* wstats.qual = none ? */
2262         wstats.updated = 0x2;
2263         /* Update spy records */
2264         wireless_spy_update(dev, linksrcaddr, &wstats);
2265     }
2266 #endif /* WIRELESS_SPY */
2267 } /* end rx_data */
2268 
2269 /*===========================================================================*/
2270 static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
2271 {
2272     snaphdr_t *psnap = (snaphdr_t *) (skb->data + RX_MAC_HEADER_LENGTH);
2273     struct ieee80211_hdr *pmac = (struct ieee80211_hdr *)skb->data;
2274     __be16 type = *(__be16 *) psnap->ethertype;
2275     int delta;
2276     struct ethhdr *peth;
2277     UCHAR srcaddr[ADDRLEN];
2278     UCHAR destaddr[ADDRLEN];
2279     static const UCHAR org_bridge[3] = { 0, 0, 0xf8 };
2280     static const UCHAR org_1042[3] = { 0, 0, 0 };
2281 
2282     memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
2283     memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
2284 
2285 #if 0
2286     if {
2287         print_hex_dump(KERN_DEBUG, "skb->data before untranslate: ",
2288                    DUMP_PREFIX_NONE, 16, 1,
2289                    skb->data, 64, true);
2290         printk(KERN_DEBUG
2291                "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
2292                ntohs(type), psnap->dsap, psnap->ssap, psnap->ctrl,
2293                psnap->org[0], psnap->org[1], psnap->org[2]);
2294         printk(KERN_DEBUG "untranslate skb->data = %p\n", skb->data);
2295     }
2296 #endif
2297 
2298     if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
2299         /* not a snap type so leave it alone */
2300         pr_debug("ray_cs untranslate NOT SNAP %02x %02x %02x\n",
2301               psnap->dsap, psnap->ssap, psnap->ctrl);
2302 
2303         delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2304         peth = (struct ethhdr *)(skb->data + delta);
2305         peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
2306     } else { /* Its a SNAP */
2307         if (memcmp(psnap->org, org_bridge, 3) == 0) {
2308         /* EtherII and nuke the LLC */
2309             pr_debug("ray_cs untranslate Bridge encap\n");
2310             delta = RX_MAC_HEADER_LENGTH
2311                 + sizeof(struct snaphdr_t) - ETH_HLEN;
2312             peth = (struct ethhdr *)(skb->data + delta);
2313             peth->h_proto = type;
2314         } else if (memcmp(psnap->org, org_1042, 3) == 0) {
2315             switch (ntohs(type)) {
2316             case ETH_P_IPX:
2317             case ETH_P_AARP:
2318                 pr_debug("ray_cs untranslate RFC IPX/AARP\n");
2319                 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2320                 peth = (struct ethhdr *)(skb->data + delta);
2321                 peth->h_proto =
2322                     htons(len - RX_MAC_HEADER_LENGTH);
2323                 break;
2324             default:
2325                 pr_debug("ray_cs untranslate RFC default\n");
2326                 delta = RX_MAC_HEADER_LENGTH +
2327                     sizeof(struct snaphdr_t) - ETH_HLEN;
2328                 peth = (struct ethhdr *)(skb->data + delta);
2329                 peth->h_proto = type;
2330                 break;
2331             }
2332         } else {
2333             printk("ray_cs untranslate very confused by packet\n");
2334             delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2335             peth = (struct ethhdr *)(skb->data + delta);
2336             peth->h_proto = type;
2337         }
2338     }
2339 /* TBD reserve  skb_reserve(skb, delta); */
2340     skb_pull(skb, delta);
2341     pr_debug("untranslate after skb_pull(%d), skb->data = %p\n", delta,
2342           skb->data);
2343     memcpy(peth->h_dest, destaddr, ADDRLEN);
2344     memcpy(peth->h_source, srcaddr, ADDRLEN);
2345 #if 0
2346     {
2347         int i;
2348         printk(KERN_DEBUG "skb->data after untranslate:");
2349         for (i = 0; i < 64; i++)
2350             printk("%02x ", skb->data[i]);
2351         printk("\n");
2352     }
2353 #endif
2354 } /* end untranslate */
2355 
2356 /*===========================================================================*/
2357 /* Copy data from circular receive buffer to PC memory.
2358  * dest     = destination address in PC memory
2359  * pkt_addr = source address in receive buffer
2360  * len      = length of packet to copy
2361  */
2362 static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr,
2363                  int length)
2364 {
2365     int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1);
2366     if (wrap_bytes <= 0) {
2367         memcpy_fromio(dest, local->rmem + pkt_addr, length);
2368     } else { /* Packet wrapped in circular buffer */
2369 
2370         memcpy_fromio(dest, local->rmem + pkt_addr,
2371                   length - wrap_bytes);
2372         memcpy_fromio(dest + length - wrap_bytes, local->rmem,
2373                   wrap_bytes);
2374     }
2375     return length;
2376 }
2377 
2378 /*===========================================================================*/
2379 static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs)
2380 {
2381     struct rcs __iomem *prcslink = prcs;
2382     int tmp = 17;
2383     unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index);
2384 
2385     while (tmp--) {
2386         writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2387         if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
2388             pr_debug("ray_cs interrupt bad rcsindex = 0x%x\n",
2389                   rcsindex);
2390             break;
2391         }
2392         prcslink = rcs_base(local) + rcsindex;
2393         rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index);
2394     }
2395     writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2396 }
2397 
2398 /*===========================================================================*/
2399 static void authenticate(ray_dev_t *local)
2400 {
2401     struct pcmcia_device *link = local->finder;
2402     dev_dbg(&link->dev, "ray_cs Starting authentication.\n");
2403     if (!(pcmcia_dev_present(link))) {
2404         dev_dbg(&link->dev, "ray_cs authenticate - device not present\n");
2405         return;
2406     }
2407 
2408     del_timer(&local->timer);
2409     if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
2410         local->timer.function = join_net;
2411     } else {
2412         local->timer.function = authenticate_timeout;
2413     }
2414     local->timer.expires = jiffies + HZ * 2;
2415     add_timer(&local->timer);
2416     local->authentication_state = AWAITING_RESPONSE;
2417 } /* end authenticate */
2418 
2419 /*===========================================================================*/
2420 static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
2421                 unsigned int pkt_addr, int rx_len)
2422 {
2423     UCHAR buff[256];
2424     struct ray_rx_msg *msg = (struct ray_rx_msg *) buff;
2425 
2426     del_timer(&local->timer);
2427 
2428     copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
2429     /* if we are trying to get authenticated */
2430     if (local->sparm.b4.a_network_type == ADHOC) {
2431         pr_debug("ray_cs rx_auth var= %6ph\n", msg->var);
2432         if (msg->var[2] == 1) {
2433             pr_debug("ray_cs Sending authentication response.\n");
2434             if (!build_auth_frame
2435                 (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
2436                 local->authentication_state = NEED_TO_AUTH;
2437                 memcpy(local->auth_id, msg->mac.addr_2,
2438                        ADDRLEN);
2439             }
2440         }
2441     } else { /* Infrastructure network */
2442 
2443         if (local->authentication_state == AWAITING_RESPONSE) {
2444             /* Verify authentication sequence #2 and success */
2445             if (msg->var[2] == 2) {
2446                 if ((msg->var[3] | msg->var[4]) == 0) {
2447                     pr_debug("Authentication successful\n");
2448                     local->card_status = CARD_AUTH_COMPLETE;
2449                     associate(local);
2450                     local->authentication_state =
2451                         AUTHENTICATED;
2452                 } else {
2453                     pr_debug("Authentication refused\n");
2454                     local->card_status = CARD_AUTH_REFUSED;
2455                     join_net(&local->timer);
2456                     local->authentication_state =
2457                         UNAUTHENTICATED;
2458                 }
2459             }
2460         }
2461     }
2462 
2463 } /* end rx_authenticate */
2464 
2465 /*===========================================================================*/
2466 static void associate(ray_dev_t *local)
2467 {
2468     struct ccs __iomem *pccs;
2469     struct pcmcia_device *link = local->finder;
2470     struct net_device *dev = link->priv;
2471     int ccsindex;
2472     if (!(pcmcia_dev_present(link))) {
2473         dev_dbg(&link->dev, "ray_cs associate - device not present\n");
2474         return;
2475     }
2476     /* If no tx buffers available, return */
2477     if ((ccsindex = get_free_ccs(local)) < 0) {
2478 /* TBD should never be here but... what if we are? */
2479         dev_dbg(&link->dev, "ray_cs associate - No free ccs\n");
2480         return;
2481     }
2482     dev_dbg(&link->dev, "ray_cs Starting association with access point\n");
2483     pccs = ccs_base(local) + ccsindex;
2484     /* fill in the CCS */
2485     writeb(CCS_START_ASSOCIATION, &pccs->cmd);
2486     /* Interrupt the firmware to process the command */
2487     if (interrupt_ecf(local, ccsindex)) {
2488         dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n");
2489         writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
2490 
2491         del_timer(&local->timer);
2492         local->timer.expires = jiffies + HZ * 2;
2493         local->timer.function = join_net;
2494         add_timer(&local->timer);
2495         local->card_status = CARD_ASSOC_FAILED;
2496         return;
2497     }
2498     if (!sniffer)
2499         netif_start_queue(dev);
2500 
2501 } /* end associate */
2502 
2503 /*===========================================================================*/
2504 static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
2505                   unsigned int pkt_addr, int rx_len)
2506 {
2507 /*  UCHAR buff[256];
2508     struct ray_rx_msg *msg = (struct ray_rx_msg *) buff;
2509 */
2510     pr_debug("Deauthentication frame received\n");
2511     local->authentication_state = UNAUTHENTICATED;
2512     /* Need to reauthenticate or rejoin depending on reason code */
2513 /*  copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
2514  */
2515 }
2516 
2517 /*===========================================================================*/
2518 static void clear_interrupt(ray_dev_t *local)
2519 {
2520     writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET);
2521 }
2522 
2523 /*===========================================================================*/
2524 #ifdef CONFIG_PROC_FS
2525 #define MAXDATA (PAGE_SIZE - 80)
2526 
2527 static const char *card_status[] = {
2528     "Card inserted - uninitialized",    /* 0 */
2529     "Card not downloaded",          /* 1 */
2530     "Waiting for download parameters",  /* 2 */
2531     "Card doing acquisition",       /* 3 */
2532     "Acquisition complete",         /* 4 */
2533     "Authentication complete",      /* 5 */
2534     "Association complete",         /* 6 */
2535     "???", "???", "???", "???",     /* 7 8 9 10 undefined */
2536     "Card init error",          /* 11 */
2537     "Download parameters error",        /* 12 */
2538     "???",                  /* 13 */
2539     "Acquisition failed",           /* 14 */
2540     "Authentication refused",       /* 15 */
2541     "Association failed"            /* 16 */
2542 };
2543 
2544 static const char *nettype[] = { "Adhoc", "Infra " };
2545 static const char *framing[] = { "Encapsulation", "Translation" }
2546 
2547 ;
2548 /*===========================================================================*/
2549 static int ray_cs_proc_show(struct seq_file *m, void *v)
2550 {
2551 /* Print current values which are not available via other means
2552  * eg ifconfig
2553  */
2554     int i;
2555     struct pcmcia_device *link;
2556     struct net_device *dev;
2557     ray_dev_t *local;
2558     UCHAR *p;
2559     struct freq_hop_element *pfh;
2560     UCHAR c[33];
2561 
2562     link = this_device;
2563     if (!link)
2564         return 0;
2565     dev = (struct net_device *)link->priv;
2566     if (!dev)
2567         return 0;
2568     local = netdev_priv(dev);
2569     if (!local)
2570         return 0;
2571 
2572     seq_puts(m, "Raylink Wireless LAN driver status\n");
2573     seq_printf(m, "%s\n", rcsid);
2574     /* build 4 does not report version, and field is 0x55 after memtest */
2575     seq_puts(m, "Firmware version     = ");
2576     if (local->fw_ver == 0x55)
2577         seq_puts(m, "4 - Use dump_cis for more details\n");
2578     else
2579         seq_printf(m, "%2d.%02d.%02d\n",
2580                local->fw_ver, local->fw_bld, local->fw_var);
2581 
2582     for (i = 0; i < 32; i++)
2583         c[i] = local->sparm.b5.a_current_ess_id[i];
2584     c[32] = 0;
2585     seq_printf(m, "%s network ESSID = \"%s\"\n",
2586            nettype[local->sparm.b5.a_network_type], c);
2587 
2588     p = local->bss_id;
2589     seq_printf(m, "BSSID                = %pM\n", p);
2590 
2591     seq_printf(m, "Country code         = %d\n",
2592            local->sparm.b5.a_curr_country_code);
2593 
2594     i = local->card_status;
2595     if (i < 0)
2596         i = 10;
2597     if (i > 16)
2598         i = 10;
2599     seq_printf(m, "Card status          = %s\n", card_status[i]);
2600 
2601     seq_printf(m, "Framing mode         = %s\n", framing[translate]);
2602 
2603     seq_printf(m, "Last pkt signal lvl  = %d\n", local->last_rsl);
2604 
2605     if (local->beacon_rxed) {
2606         /* Pull some fields out of last beacon received */
2607         seq_printf(m, "Beacon Interval      = %d Kus\n",
2608                local->last_bcn.beacon_intvl[0]
2609                + 256 * local->last_bcn.beacon_intvl[1]);
2610 
2611         p = local->last_bcn.elements;
2612         if (p[0] == C_ESSID_ELEMENT_ID)
2613             p += p[1] + 2;
2614         else {
2615             seq_printf(m,
2616                    "Parse beacon failed at essid element id = %d\n",
2617                    p[0]);
2618             return 0;
2619         }
2620 
2621         if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
2622             seq_puts(m, "Supported rate codes = ");
2623             for (i = 2; i < p[1] + 2; i++)
2624                 seq_printf(m, "0x%02x ", p[i]);
2625             seq_putc(m, '\n');
2626             p += p[1] + 2;
2627         } else {
2628             seq_puts(m, "Parse beacon failed at rates element\n");
2629             return 0;
2630         }
2631 
2632         if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
2633             pfh = (struct freq_hop_element *)p;
2634             seq_printf(m, "Hop dwell            = %d Kus\n",
2635                    pfh->dwell_time[0] +
2636                    256 * pfh->dwell_time[1]);
2637             seq_printf(m, "Hop set              = %d\n",
2638                    pfh->hop_set);
2639             seq_printf(m, "Hop pattern          = %d\n",
2640                    pfh->hop_pattern);
2641             seq_printf(m, "Hop index            = %d\n",
2642                    pfh->hop_index);
2643             p += p[1] + 2;
2644         } else {
2645             seq_puts(m,
2646                  "Parse beacon failed at FH param element\n");
2647             return 0;
2648         }
2649     } else {
2650         seq_puts(m, "No beacons received\n");
2651     }
2652     return 0;
2653 }
2654 #endif
2655 /*===========================================================================*/
2656 static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
2657 {
2658     int addr;
2659     struct ccs __iomem *pccs;
2660     struct tx_msg __iomem *ptx;
2661     int ccsindex;
2662 
2663     /* If no tx buffers available, return */
2664     if ((ccsindex = get_free_tx_ccs(local)) < 0) {
2665         pr_debug("ray_cs send authenticate - No free tx ccs\n");
2666         return -1;
2667     }
2668 
2669     pccs = ccs_base(local) + ccsindex;
2670 
2671     /* Address in card space */
2672     addr = TX_BUF_BASE + (ccsindex << 11);
2673     /* fill in the CCS */
2674     writeb(CCS_TX_REQUEST, &pccs->cmd);
2675     writeb(addr >> 8, pccs->var.tx_request.tx_data_ptr);
2676     writeb(0x20, pccs->var.tx_request.tx_data_ptr + 1);
2677     writeb(TX_AUTHENTICATE_LENGTH_MSB, pccs->var.tx_request.tx_data_length);
2678     writeb(TX_AUTHENTICATE_LENGTH_LSB,
2679            pccs->var.tx_request.tx_data_length + 1);
2680     writeb(0, &pccs->var.tx_request.pow_sav_mode);
2681 
2682     ptx = local->sram + addr;
2683     /* fill in the mac header */
2684     writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1);
2685     writeb(0, &ptx->mac.frame_ctl_2);
2686 
2687     memcpy_toio(ptx->mac.addr_1, dest, ADDRLEN);
2688     memcpy_toio(ptx->mac.addr_2, local->sparm.b4.a_mac_addr, ADDRLEN);
2689     memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
2690 
2691     /* Fill in msg body with protocol 00 00, sequence 01 00 ,status 00 00 */
2692     memset_io(ptx->var, 0, 6);
2693     writeb(auth_type & 0xff, ptx->var + 2);
2694 
2695     /* Interrupt the firmware to process the command */
2696     if (interrupt_ecf(local, ccsindex)) {
2697         pr_debug(
2698               "ray_cs send authentication request failed - ECF not ready for intr\n");
2699         writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
2700         return -1;
2701     }
2702     return 0;
2703 } /* End build_auth_frame */
2704 
2705 /*===========================================================================*/
2706 #ifdef CONFIG_PROC_FS
2707 static ssize_t ray_cs_essid_proc_write(struct file *file,
2708         const char __user *buffer, size_t count, loff_t *pos)
2709 {
2710     static char proc_essid[33];
2711     unsigned int len = count;
2712 
2713     if (len > 32)
2714         len = 32;
2715     memset(proc_essid, 0, 33);
2716     if (copy_from_user(proc_essid, buffer, len))
2717         return -EFAULT;
2718     essid = proc_essid;
2719     return count;
2720 }
2721 
2722 static const struct proc_ops ray_cs_essid_proc_ops = {
2723     .proc_write = ray_cs_essid_proc_write,
2724     .proc_lseek = noop_llseek,
2725 };
2726 
2727 static ssize_t int_proc_write(struct file *file, const char __user *buffer,
2728                   size_t count, loff_t *pos)
2729 {
2730     static char proc_number[10];
2731     char *p;
2732     int nr, len;
2733 
2734     if (!count)
2735         return 0;
2736 
2737     if (count > 9)
2738         return -EINVAL;
2739     if (copy_from_user(proc_number, buffer, count))
2740         return -EFAULT;
2741     p = proc_number;
2742     nr = 0;
2743     len = count;
2744     do {
2745         unsigned int c = *p - '0';
2746         if (c > 9)
2747             return -EINVAL;
2748         nr = nr * 10 + c;
2749         p++;
2750     } while (--len);
2751     *(int *)pde_data(file_inode(file)) = nr;
2752     return count;
2753 }
2754 
2755 static const struct proc_ops int_proc_ops = {
2756     .proc_write = int_proc_write,
2757     .proc_lseek = noop_llseek,
2758 };
2759 #endif
2760 
2761 static const struct pcmcia_device_id ray_ids[] = {
2762     PCMCIA_DEVICE_MANF_CARD(0x01a6, 0x0000),
2763     PCMCIA_DEVICE_NULL,
2764 };
2765 
2766 MODULE_DEVICE_TABLE(pcmcia, ray_ids);
2767 
2768 static struct pcmcia_driver ray_driver = {
2769     .owner = THIS_MODULE,
2770     .name = "ray_cs",
2771     .probe = ray_probe,
2772     .remove = ray_detach,
2773     .id_table = ray_ids,
2774     .suspend = ray_suspend,
2775     .resume = ray_resume,
2776 };
2777 
2778 static int __init init_ray_cs(void)
2779 {
2780     int rc;
2781 
2782     pr_debug("%s\n", rcsid);
2783     rc = pcmcia_register_driver(&ray_driver);
2784     pr_debug("raylink init_module register_pcmcia_driver returns 0x%x\n",
2785           rc);
2786     if (rc)
2787         return rc;
2788 
2789 #ifdef CONFIG_PROC_FS
2790     proc_mkdir("driver/ray_cs", NULL);
2791 
2792     proc_create_single("driver/ray_cs/ray_cs", 0, NULL, ray_cs_proc_show);
2793     proc_create("driver/ray_cs/essid", 0200, NULL, &ray_cs_essid_proc_ops);
2794     proc_create_data("driver/ray_cs/net_type", 0200, NULL, &int_proc_ops,
2795              &net_type);
2796     proc_create_data("driver/ray_cs/translate", 0200, NULL, &int_proc_ops,
2797              &translate);
2798 #endif
2799     translate = !!translate;
2800     return 0;
2801 } /* init_ray_cs */
2802 
2803 /*===========================================================================*/
2804 
2805 static void __exit exit_ray_cs(void)
2806 {
2807     pr_debug("ray_cs: cleanup_module\n");
2808 
2809 #ifdef CONFIG_PROC_FS
2810     remove_proc_subtree("driver/ray_cs", NULL);
2811 #endif
2812 
2813     pcmcia_unregister_driver(&ray_driver);
2814 } /* exit_ray_cs */
2815 
2816 module_init(init_ray_cs);
2817 module_exit(exit_ray_cs);
2818 
2819 /*===========================================================================*/