📄 ray_cs.c
字号:
/* Copy addresses to the driver */ if(copy_from_user(address, wrq->u.data.pointer, sizeof(struct sockaddr) * local->spy_number)) { err = -EFAULT; break; } /* Copy addresses to the lp structure */ for(i = 0; i < local->spy_number; i++) memcpy(local->spy_address[i], address[i].sa_data, ETH_ALEN); /* Reset structure... */ memset(local->spy_stat, 0x00, sizeof(iw_qual) * IW_MAX_SPY);#ifdef DEBUG_IOCTL_INFO printk(KERN_DEBUG "SetSpy - Set of new addresses is :\n"); for(i = 0; i < local->spy_number; i++) printk(KERN_DEBUG "%02X:%02X:%02X:%02X:%02X:%02X\n", local->spy_address[i][0], local->spy_address[i][1], local->spy_address[i][2], local->spy_address[i][3], local->spy_address[i][4], local->spy_address[i][5]);#endif /* DEBUG_IOCTL_INFO */ } break; /* Get the spy list and spy stats */ case SIOCGIWSPY: /* Set the number of addresses */ wrq->u.data.length = local->spy_number; /* If the user want to have the addresses back... */ if((local->spy_number > 0) && (wrq->u.data.pointer != (caddr_t) 0)) { struct sockaddr address[IW_MAX_SPY]; int i; /* Copy addresses from the lp structure */ for(i = 0; i < local->spy_number; i++) { memcpy(address[i].sa_data, local->spy_address[i], ETH_ALEN); address[i].sa_family = ARPHRD_ETHER; } /* Copy addresses to the user buffer */ if(copy_to_user(wrq->u.data.pointer, address, sizeof(struct sockaddr) * local->spy_number)) { err = -EFAULT; break; } /* Copy stats to the user buffer (just after) */ if(copy_to_user(wrq->u.data.pointer + (sizeof(struct sockaddr) * local->spy_number), local->spy_stat, sizeof(iw_qual) * local->spy_number)) { err = -EFAULT; break; } /* Reset updated flags */ for(i = 0; i < local->spy_number; i++) local->spy_stat[i].updated = 0x0; } /* if(pointer != NULL) */ break;#endif /* WIRELESS_SPY */ /* ------------------ PRIVATE IOCTL ------------------ */#ifndef SIOCIWFIRSTPRIV#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE#endif /* SIOCIWFIRSTPRIV */#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1 /* Get framing mode */#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */ case SIOCSIPFRAMING: if(!capable(CAP_NET_ADMIN)) /* For private IOCTLs, we need to check permissions */ { err = -EPERM; break; } translate = *(wrq->u.name); /* Set framing mode */ break; case SIOCGIPFRAMING: *(wrq->u.name) = translate; break; case SIOCGIPCOUNTRY: *(wrq->u.name) = country; break; case SIOCGIWPRIV: /* Export our "private" intercace */ if(wrq->u.data.pointer != (caddr_t) 0) { struct iw_priv_args priv[] = { /* cmd, set_args, get_args, name */ { SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" }, { SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" }, { SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" }, }; /* Set the number of ioctl available */ wrq->u.data.length = 3; /* Copy structure to the user buffer */ if(copy_to_user(wrq->u.data.pointer, (u_char *) priv, sizeof(priv))) err = -EFAULT; } break;#endif /* WIRELESS_EXT > 7 */ default: DEBUG(0,"ray_dev_ioctl cmd = 0x%x\n", cmd); err = -EOPNOTSUPP; } return err;} /* end ray_dev_ioctl *//*===========================================================================*/#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */static iw_stats * ray_get_wireless_stats(struct net_device * dev){ ray_dev_t * local = (ray_dev_t *) dev->priv; dev_link_t *link = local->finder; struct status __iomem *p = local->sram + STATUS_BASE; if(local == (ray_dev_t *) NULL) return (iw_stats *) NULL; local->wstats.status = local->card_status;#ifdef WIRELESS_SPY if((local->spy_number > 0) && (local->sparm.b5.a_network_type == 0)) { /* Get it from the first node in spy list */ local->wstats.qual.qual = local->spy_stat[0].qual; local->wstats.qual.level = local->spy_stat[0].level; local->wstats.qual.noise = local->spy_stat[0].noise; local->wstats.qual.updated = local->spy_stat[0].updated; }#endif /* WIRELESS_SPY */ if((link->state & DEV_PRESENT)) { local->wstats.qual.noise = readb(&p->rxnoise); local->wstats.qual.updated |= 4; } return &local->wstats;} /* end ray_get_wireless_stats */#endif /* WIRELESS_EXT > 7 *//*===========================================================================*/static int ray_open(struct net_device *dev){ dev_link_t *link; ray_dev_t *local = (ray_dev_t *)dev->priv; DEBUG(1, "ray_open('%s')\n", dev->name); for (link = dev_list; link; link = link->next) if (link->priv == dev) break; if (!DEV_OK(link)) { return -ENODEV; } if (link->open == 0) local->num_multi = 0; link->open++; /* If the card is not started, time to start it ! - Jean II */ if(local->card_status == CARD_AWAITING_PARAM) { int i; DEBUG(1,"ray_open: doing init now !\n"); /* Download startup parameters */ if ( (i = dl_startup_params(dev)) < 0) { printk(KERN_INFO "ray_dev_init dl_startup_params failed - " "returns 0x%x\n",i); return -1; } } if (sniffer) netif_stop_queue(dev); else netif_start_queue(dev); DEBUG(2,"ray_open ending\n"); return 0;} /* end ray_open *//*===========================================================================*/static int ray_dev_close(struct net_device *dev){ dev_link_t *link; DEBUG(1, "ray_dev_close('%s')\n", dev->name); for (link = dev_list; link; link = link->next) if (link->priv == dev) break; if (link == NULL) return -ENODEV; link->open--; netif_stop_queue(dev); /* In here, we should stop the hardware (stop card from beeing active) * and set local->card_status to CARD_AWAITING_PARAM, so that while the * card is closed we can chage its configuration. * Probably also need a COR reset to get sane state - Jean II */ return 0;} /* end ray_dev_close *//*===========================================================================*/static void ray_reset(struct net_device *dev) { DEBUG(1,"ray_reset entered\n"); return;}/*===========================================================================*//* Cause a firmware interrupt if it is ready for one *//* Return nonzero if not ready */static int interrupt_ecf(ray_dev_t *local, int ccs){ int i = 50; dev_link_t *link = local->finder; if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs interrupt_ecf - device not present\n"); return -1; } DEBUG(2,"interrupt_ecf(local=%p, ccs = 0x%x\n",local,ccs); while ( i && (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) & ECF_INTR_SET)) i--; if (i == 0) { DEBUG(2,"ray_cs interrupt_ecf card not ready for interrupt\n"); return -1; } /* Fill the mailbox, then kick the card */ writeb(ccs, local->sram + SCB_BASE); writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET); return 0;} /* interrupt_ecf *//*===========================================================================*//* Get next free transmit CCS *//* Return - index of current tx ccs */static int get_free_tx_ccs(ray_dev_t *local){ int i; struct ccs __iomem *pccs = ccs_base(local); dev_link_t *link = local->finder; if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n"); return ECARDGONE; } if (test_and_set_bit(0,&local->tx_ccs_lock)) { DEBUG(1,"ray_cs tx_ccs_lock busy\n"); return ECCSBUSY; } for (i=0; i < NUMBER_OF_TX_CCS; i++) { if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) { writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status); writeb(CCS_END_LIST, &(pccs+i)->link); local->tx_ccs_lock = 0; return i; } } local->tx_ccs_lock = 0; DEBUG(2,"ray_cs ERROR no free tx CCS for raylink card\n"); return ECCSFULL;} /* get_free_tx_ccs *//*===========================================================================*//* Get next free CCS *//* Return - index of current ccs */static int get_free_ccs(ray_dev_t *local){ int i; struct ccs __iomem *pccs = ccs_base(local); dev_link_t *link = local->finder; if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs get_free_ccs - device not present\n"); return ECARDGONE; } if (test_and_set_bit(0,&local->ccs_lock)) { DEBUG(1,"ray_cs ccs_lock busy\n"); return ECCSBUSY; } for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) { if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) { writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status); writeb(CCS_END_LIST, &(pccs+i)->link); local->ccs_lock = 0; return i; } } local->ccs_lock = 0; DEBUG(1,"ray_cs ERROR no free CCS for raylink card\n"); return ECCSFULL;} /* get_free_ccs *//*===========================================================================*/static void authenticate_timeout(u_long data){ ray_dev_t *local = (ray_dev_t *)data; del_timer(&local->timer); printk(KERN_INFO "ray_cs Authentication with access point failed" " - timeout\n"); join_net((u_long)local);}/*===========================================================================*/static int asc_to_int(char a){ if (a < '0') return -1; if (a <= '9') return (a - '0'); if (a < 'A') return -1; if (a <= 'F') return (10 + a - 'A'); if (a < 'a') return -1; if (a <= 'f') return (10 + a - 'a'); return -1;}/*===========================================================================*/static int parse_addr(char *in_str, UCHAR *out){ int len; int i,j,k; int status; if (in_str == NULL) return 0; if ((len = strlen(in_str)) < 2) return 0; memset(out, 0, ADDRLEN); status = 1; j = len - 1; if (j > 12) j = 12; i = 5; while (j > 0) { if ((k = asc_to_int(in_str[j--])) != -1) out[i] = k; else return 0; if (j == 0) break; if ((k = asc_to_int(in_str[j--])) != -1) out[i] += k << 4; else return 0; if (!i--) break; } return status;}/*===========================================================================*/static struct net_device_stats *ray_get_stats(struct net_device *dev){ ray_dev_t *local = (ray_dev_t *)dev->priv; dev_link_t *link = local->finder; struct status __iomem *p = local->sram + STATUS_BASE; if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs net_device_stats - device not present\n"); return &local->stats; } if (readb(&p->mrx_overflow_for_host)) { local->stats.rx_over_errors += ntohs(readb(&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)); writeb(0,&p->mrx_checksum_error); writeb(0,&p->mrx_checksum_error_for_host); } if (readb(&p->rx_hec_error_for_host)) { loc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -