#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/ptrace.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/ioport.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
+#include <linux/ieee80211.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
dev->set_multicast_list = &set_multicast_list;
DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");
- SET_MODULE_OWNER(dev);
dev->init = &ray_dev_init;
dev->open = &ray_open;
dev->stop = &ray_dev_close;
memreq_t mem;
struct net_device *dev = (struct net_device *)link->priv;
ray_dev_t *local = netdev_priv(dev);
+ DECLARE_MAC_BUF(mac);
DEBUG(1, "ray_config(0x%p)\n", link);
strcpy(local->node.dev_name, dev->name);
link->dev_node = &local->node;
- printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",
- dev->name, dev->irq);
- for (i = 0; i < 6; i++)
- printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
+ printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %s\n",
+ dev->name, dev->irq, print_mac(mac, dev->dev_addr));
return 0;
static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, unsigned char *data,
int len)
{
- unsigned short int proto = ((struct ethhdr *)data)->h_proto;
+ __be16 proto = ((struct ethhdr *)data)->h_proto;
if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
DEBUG(3,"ray_cs translate_frame DIX II\n");
/* Copy LLC header to card buffer */
memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc));
memcpy_toio( ((void __iomem *)&ptx->var) + sizeof(eth2_llc), (UCHAR *)&proto, 2);
- if ((proto == 0xf380) || (proto == 0x3781)) {
+ if (proto == htons(ETH_P_AARP) || proto == htons(ETH_P_IPX)) {
/* This is the selective translation table, only 2 entries */
writeb(0xf8, &((struct snaphdr_t __iomem *)ptx->var)->org[3]);
}
}
else { /* already 802 type, and proto is length */
DEBUG(3,"ray_cs translate_frame 802\n");
- if (proto == 0xffff) { /* evil netware IPX 802.3 without LLC */
+ if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */
DEBUG(3,"ray_cs translate_frame evil IPX\n");
memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
return 0 - ETH_HLEN;
static const struct iw_handler_def ray_handler_def =
{
- .num_standard = sizeof(ray_handler)/sizeof(iw_handler),
- .num_private = sizeof(ray_private_handler)/sizeof(iw_handler),
- .num_private_args = sizeof(ray_private_args)/sizeof(struct iw_priv_args),
+ .num_standard = ARRAY_SIZE(ray_handler),
+ .num_private = ARRAY_SIZE(ray_private_handler),
+ .num_private_args = ARRAY_SIZE(ray_private_args),
.standard = ray_handler,
.private = ray_private_handler,
.private_args = ray_private_args,
}
if (readb(&p->mrx_overflow_for_host))
{
- local->stats.rx_over_errors += ntohs(readb(&p->mrx_overflow));
+ local->stats.rx_over_errors += swab16(readw(&p->mrx_overflow));
writeb(0,&p->mrx_overflow);
writeb(0,&p->mrx_overflow_for_host);
}
if (readb(&p->mrx_checksum_error_for_host))
{
- local->stats.rx_crc_errors += ntohs(readb(&p->mrx_checksum_error));
+ local->stats.rx_crc_errors += swab16(readw(&p->mrx_checksum_error));
writeb(0,&p->mrx_checksum_error);
writeb(0,&p->mrx_checksum_error_for_host);
}
if (readb(&p->rx_hec_error_for_host))
{
- local->stats.rx_frame_errors += ntohs(readb(&p->rx_hec_error));
+ local->stats.rx_frame_errors += swab16(readw(&p->rx_hec_error));
writeb(0,&p->rx_hec_error);
writeb(0,&p->rx_hec_error_for_host);
}
static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
{
snaphdr_t *psnap = (snaphdr_t *)(skb->data + RX_MAC_HEADER_LENGTH);
- struct mac_header *pmac = (struct mac_header *)skb->data;
- unsigned short type = *(unsigned short *)psnap->ethertype;
- unsigned int xsap = *(unsigned int *)psnap & 0x00ffffff;
- unsigned int org = (*(unsigned int *)psnap->org) & 0x00ffffff;
+ struct ieee80211_hdr *pmac = (struct ieee80211_hdr *)skb->data;
+ __be16 type = *(__be16 *)psnap->ethertype;
int delta;
struct ethhdr *peth;
UCHAR srcaddr[ADDRLEN];
UCHAR destaddr[ADDRLEN];
+ static UCHAR org_bridge[3] = {0, 0, 0xf8};
+ static UCHAR org_1042[3] = {0, 0, 0};
- if (pmac->frame_ctl_2 & FC2_FROM_DS) {
- if (pmac->frame_ctl_2 & FC2_TO_DS) { /* AP to AP */
- memcpy(destaddr, pmac->addr_3, ADDRLEN);
- memcpy(srcaddr, ((unsigned char *)pmac->addr_3) + ADDRLEN, ADDRLEN);
- } else { /* AP to terminal */
- memcpy(destaddr, pmac->addr_1, ADDRLEN);
- memcpy(srcaddr, pmac->addr_3, ADDRLEN);
- }
- } else { /* Terminal to AP */
- if (pmac->frame_ctl_2 & FC2_TO_DS) {
- memcpy(destaddr, pmac->addr_3, ADDRLEN);
- memcpy(srcaddr, pmac->addr_2, ADDRLEN);
- } else { /* Adhoc */
- memcpy(destaddr, pmac->addr_1, ADDRLEN);
- memcpy(srcaddr, pmac->addr_2, ADDRLEN);
- }
- }
+ memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
+ memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
#ifdef PCMCIA_DEBUG
if (pc_debug > 3) {
printk(KERN_DEBUG "skb->data before untranslate");
for (i=0;i<64;i++)
printk("%02x ",skb->data[i]);
- printk("\n" KERN_DEBUG "type = %08x, xsap = %08x, org = %08x\n",
- type,xsap,org);
+ printk("\n" KERN_DEBUG "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
+ ntohs(type),
+ psnap->dsap, psnap->ssap, psnap->ctrl,
+ psnap->org[0], psnap->org[1], psnap->org[2]);
printk(KERN_DEBUG "untranslate skb->data = %p\n",skb->data);
}
#endif
- if ( xsap != SNAP_ID) {
+ if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
/* not a snap type so leave it alone */
- DEBUG(3,"ray_cs untranslate NOT SNAP %x\n", *(unsigned int *)psnap & 0x00ffffff);
+ DEBUG(3,"ray_cs untranslate NOT SNAP %02x %02x %02x\n",
+ psnap->dsap, psnap->ssap, psnap->ctrl);
delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
peth = (struct ethhdr *)(skb->data + delta);
peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
}
else { /* Its a SNAP */
- if (org == BRIDGE_ENCAP) { /* EtherII and nuke the LLC */
+ if (memcmp(psnap->org, org_bridge, 3) == 0) { /* EtherII and nuke the LLC */
DEBUG(3,"ray_cs untranslate Bridge encap\n");
delta = RX_MAC_HEADER_LENGTH
+ sizeof(struct snaphdr_t) - ETH_HLEN;
peth = (struct ethhdr *)(skb->data + delta);
peth->h_proto = type;
- }
- else {
- if (org == RFC1042_ENCAP) {
- switch (type) {
- case RAY_IPX_TYPE:
- case APPLEARP_TYPE:
+ } else if (memcmp(psnap->org, org_1042, 3) == 0) {
+ switch (ntohs(type)) {
+ case ETH_P_IPX:
+ case ETH_P_AARP:
DEBUG(3,"ray_cs untranslate RFC IPX/AARP\n");
delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
peth = (struct ethhdr *)(skb->data + delta);
peth->h_proto = type;
break;
}
- }
- else {
+ } else {
printk("ray_cs untranslate very confused by packet\n");
delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
peth = (struct ethhdr *)(skb->data + delta);
peth->h_proto = type;
- }
- }
+ }
}
/* TBD reserve skb_reserve(skb, delta); */
skb_pull(skb, delta);
static char *framing[] = {"Encapsulation", "Translation"}
;
/*===========================================================================*/
-static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len)
+static int ray_cs_proc_show(struct seq_file *m, void *v)
{
/* Print current values which are not available via other means
* eg ifconfig
UCHAR *p;
struct freq_hop_element *pfh;
UCHAR c[33];
+ DECLARE_MAC_BUF(mac);
link = this_device;
if (!link)
if (!local)
return 0;
- len = 0;
-
- len += sprintf(buf + len, "Raylink Wireless LAN driver status\n");
- len += sprintf(buf + len, "%s\n", rcsid);
+ seq_puts(m, "Raylink Wireless LAN driver status\n");
+ seq_printf(m, "%s\n", rcsid);
/* build 4 does not report version, and field is 0x55 after memtest */
- len += sprintf(buf + len, "Firmware version = ");
+ seq_puts(m, "Firmware version = ");
if (local->fw_ver == 0x55)
- len += sprintf(buf + len, "4 - Use dump_cis for more details\n");
+ seq_puts(m, "4 - Use dump_cis for more details\n");
else
- len += sprintf(buf + len, "%2d.%02d.%02d\n",
+ seq_printf(m, "%2d.%02d.%02d\n",
local->fw_ver, local->fw_bld, local->fw_var);
for (i=0; i<32; i++) c[i] = local->sparm.b5.a_current_ess_id[i];
c[32] = 0;
- len += sprintf(buf + len, "%s network ESSID = \"%s\"\n",
+ seq_printf(m, "%s network ESSID = \"%s\"\n",
nettype[local->sparm.b5.a_network_type], c);
p = local->bss_id;
- len += sprintf(buf + len,
- "BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
- p[0],p[1],p[2],p[3],p[4],p[5]);
+ seq_printf(m, "BSSID = %s\n",
+ print_mac(mac, p));
- len += sprintf(buf + len, "Country code = %d\n",
+ seq_printf(m, "Country code = %d\n",
local->sparm.b5.a_curr_country_code);
i = local->card_status;
if (i < 0) i = 10;
if (i > 16) i = 10;
- len += sprintf(buf + len, "Card status = %s\n", card_status[i]);
+ seq_printf(m, "Card status = %s\n", card_status[i]);
- len += sprintf(buf + len, "Framing mode = %s\n",framing[translate]);
+ seq_printf(m, "Framing mode = %s\n",framing[translate]);
- len += sprintf(buf + len, "Last pkt signal lvl = %d\n", local->last_rsl);
+ seq_printf(m, "Last pkt signal lvl = %d\n", local->last_rsl);
if (local->beacon_rxed) {
/* Pull some fields out of last beacon received */
- len += sprintf(buf + len, "Beacon Interval = %d Kus\n",
+ seq_printf(m, "Beacon Interval = %d Kus\n",
local->last_bcn.beacon_intvl[0]
+ 256 * local->last_bcn.beacon_intvl[1]);
p = local->last_bcn.elements;
if (p[0] == C_ESSID_ELEMENT_ID) p += p[1] + 2;
else {
- len += sprintf(buf + len, "Parse beacon failed at essid element id = %d\n",p[0]);
- return len;
+ seq_printf(m, "Parse beacon failed at essid element id = %d\n",p[0]);
+ return 0;
}
if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
- len += sprintf(buf + len, "Supported rate codes = ");
+ seq_puts(m, "Supported rate codes = ");
for (i=2; i<p[1] + 2; i++)
- len += sprintf(buf + len, "0x%02x ", p[i]);
- len += sprintf(buf + len, "\n");
+ seq_printf(m, "0x%02x ", p[i]);
+ seq_putc(m, '\n');
p += p[1] + 2;
}
else {
- len += sprintf(buf + len, "Parse beacon failed at rates element\n");
- return len;
+ seq_puts(m, "Parse beacon failed at rates element\n");
+ return 0;
}
if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
pfh = (struct freq_hop_element *)p;
- len += sprintf(buf + len, "Hop dwell = %d Kus\n",
+ seq_printf(m, "Hop dwell = %d Kus\n",
pfh->dwell_time[0] + 256 * pfh->dwell_time[1]);
- len += sprintf(buf + len, "Hop set = %d \n", pfh->hop_set);
- len += sprintf(buf + len, "Hop pattern = %d \n", pfh->hop_pattern);
- len += sprintf(buf + len, "Hop index = %d \n", pfh->hop_index);
+ seq_printf(m, "Hop set = %d \n", pfh->hop_set);
+ seq_printf(m, "Hop pattern = %d \n", pfh->hop_pattern);
+ seq_printf(m, "Hop index = %d \n", pfh->hop_index);
p += p[1] + 2;
}
else {
- len += sprintf(buf + len, "Parse beacon failed at FH param element\n");
- return len;
+ seq_puts(m, "Parse beacon failed at FH param element\n");
+ return 0;
}
} else {
- len += sprintf(buf + len, "No beacons received\n");
+ seq_puts(m, "No beacons received\n");
}
- return len;
+ return 0;
}
+static int ray_cs_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ray_cs_proc_show, NULL);
+}
+
+static const struct file_operations ray_cs_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ray_cs_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
#endif
/*===========================================================================*/
static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
#ifdef CONFIG_PROC_FS
proc_mkdir("driver/ray_cs", NULL);
- create_proc_info_entry("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_read);
+ proc_create("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_fops);
raycs_write("driver/ray_cs/essid", write_essid, NULL);
raycs_write("driver/ray_cs/net_type", write_int, &net_type);
raycs_write("driver/ray_cs/translate", write_int, &translate);