ray_cs.c

来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 1,911 行 · 第 1/5 页

C
1,911
字号
      local->wstats.qual.noise = local->spy_data.spy_stat[0].noise;      local->wstats.qual.updated = local->spy_data.spy_stat[0].updated;    }#endif /* WIRELESS_SPY */  if(pcmcia_dev_present(link)) {    local->wstats.qual.noise = readb(&p->rxnoise);    local->wstats.qual.updated |= 4;  }  return &local->wstats;} /* end ray_get_wireless_stats *//*------------------------------------------------------------------*//* * Structures to export the Wireless Handlers */static const iw_handler	ray_handler[] = {	[SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) ray_commit,	[SIOCGIWNAME  -SIOCIWFIRST] = (iw_handler) ray_get_name,	[SIOCSIWFREQ  -SIOCIWFIRST] = (iw_handler) ray_set_freq,	[SIOCGIWFREQ  -SIOCIWFIRST] = (iw_handler) ray_get_freq,	[SIOCSIWMODE  -SIOCIWFIRST] = (iw_handler) ray_set_mode,	[SIOCGIWMODE  -SIOCIWFIRST] = (iw_handler) ray_get_mode,	[SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) ray_get_range,#ifdef WIRELESS_SPY 	[SIOCSIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,	[SIOCGIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,	[SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,	[SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,#endif	/* WIRELESS_SPY */	[SIOCGIWAP    -SIOCIWFIRST] = (iw_handler) ray_get_wap,	[SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) ray_set_essid,	[SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) ray_get_essid,	[SIOCSIWRATE  -SIOCIWFIRST] = (iw_handler) ray_set_rate,	[SIOCGIWRATE  -SIOCIWFIRST] = (iw_handler) ray_get_rate,	[SIOCSIWRTS   -SIOCIWFIRST] = (iw_handler) ray_set_rts,	[SIOCGIWRTS   -SIOCIWFIRST] = (iw_handler) ray_get_rts,	[SIOCSIWFRAG  -SIOCIWFIRST] = (iw_handler) ray_set_frag,	[SIOCGIWFRAG  -SIOCIWFIRST] = (iw_handler) ray_get_frag,};#define SIOCSIPFRAMING	SIOCIWFIRSTPRIV		/* Set framing mode */#define SIOCGIPFRAMING	SIOCIWFIRSTPRIV + 1	/* Get framing mode */#define SIOCGIPCOUNTRY	SIOCIWFIRSTPRIV + 3	/* Get country code */static const iw_handler	ray_private_handler[] = {	[0] = (iw_handler) ray_set_framing,	[1] = (iw_handler) ray_get_framing,	[3] = (iw_handler) ray_get_country,};static const struct iw_priv_args	ray_private_args[] = {/* cmd,		set_args,	get_args,	name */{ SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" },{ SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" },{ SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" },};static const struct iw_handler_def	ray_handler_def ={	.num_standard	= sizeof(ray_handler)/sizeof(iw_handler),	.num_private	= sizeof(ray_private_handler)/sizeof(iw_handler),	.num_private_args = sizeof(ray_private_args)/sizeof(struct iw_priv_args),	.standard	= ray_handler,	.private	= ray_private_handler,	.private_args	= ray_private_args,	.get_wireless_stats = ray_get_wireless_stats,};/*===========================================================================*/static int ray_open(struct net_device *dev){    ray_dev_t *local = (ray_dev_t *)dev->priv;    struct pcmcia_device *link;    link = local->finder;        DEBUG(1, "ray_open('%s')\n", dev->name);    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){    ray_dev_t *local = (ray_dev_t *)dev->priv;    struct pcmcia_device *link;    link = local->finder;    DEBUG(1, "ray_dev_close('%s')\n", dev->name);    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;    struct pcmcia_device *link = local->finder;    if (!(pcmcia_dev_present(link))) {        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);    struct pcmcia_device *link = local->finder;    if (!(pcmcia_dev_present(link))) {        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);    struct pcmcia_device *link = local->finder;    if (!(pcmcia_dev_present(link))) {        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;    struct pcmcia_device *link = local->finder;    struct status __iomem *p = local->sram + STATUS_BASE;    if (!(pcmcia_dev_present(link))) {        DEBUG(2,"ray_cs net_device_stats - device not present\n");        return &local->stats;    }    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))    {        local->stats.rx_frame_errors += ntohs(readb(&p->rx_hec_error));        writeb(0,&p->rx_hec_error);        writeb(0,&p->rx_hec_error_for_host);    }    return &local->stats;}/*===========================================================================*/static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len){    ray_dev_t *local = (ray_dev_t *)dev->priv;    struct pcmcia_device *link = local->finder;    int ccsindex;    int i;    struct ccs __iomem *pccs;    if (!(pcmcia_dev_present(link))) {        DEBUG(2,"ray_update_parm - device not present\n");        return;    }    if ((ccsindex = get_free_ccs(local)) < 0)    {        DEBUG(0,"ray_update_parm - No free ccs\n");        return;    }    pccs = ccs_base(local) + ccsindex;    writeb(CCS_UPDATE_PARAMS, &pccs->cmd);    writeb(objid, &pccs->var.update_param.object_id);    writeb(1, &pccs->var.update_param.number_objects);    writeb(0, &pccs->var.update_param.failure_cause);    for (i=0; i<len; i++) {        writeb(value[i], local->sram + HOST_TO_ECF_BASE);    }    /* Interrupt the firmware to process the command */    if (interrupt_ecf(local, ccsindex)) {        DEBUG(0,"ray_cs associate failed - ECF not ready for intr\n");        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);    }}/*===========================================================================*/static void ray_update_multi_list(struct net_device *dev, int all){    struct dev_mc_list *dmi, **dmip;    int ccsindex;    struct ccs __iomem *pccs;    int i = 0;    ray_dev_t *local = (ray_dev_t *)dev->priv;    struct pcmcia_device *link = local->finder;    void __iomem *p = local->sram + HOST_TO_ECF_BASE;    if (!(pcmcia_dev_present(link))) {        DEBUG(2,"ray_update_multi_list - device not present\n");        return;    }    else         DEBUG(2,"ray_update_multi_list(%p)\n",dev);    if ((ccsindex = get_free_ccs(local)) < 0)    {        DEBUG(1,"ray_update_multi - No free ccs\n");        return;    }    pccs = ccs_base(local) + ccsindex;    writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);    if (all) {        writeb(0xff, &pccs->var);        local->num_multi = 0xff;    }    else {        /* Copy the kernel's list of MC addresses to card */        for (dmip=&dev->mc_list; (dmi=*dmip)!=NULL; dmip=&dmi->next) {            memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);            DEBUG(1,"ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",dmi->dmi_addr[0],dmi->dmi_addr[1],dmi->dmi_addr[2],dmi->dmi_addr[3],dmi->dmi_addr[4],dmi->dmi_addr[5]);            p += ETH_ALEN;            i++;        }        if (i > 256/ADDRLEN) i = 256/ADDRLEN;        writeb((UCHAR)i, &pccs->var);        DEBUG(1,"ray_cs update_multi %d addresses in list\n", i);        /* Interrupt the firmware to process the command */        local->num_multi = i;    }    if (interrupt_ecf(local, ccsindex)) {        DEBUG(1,"ray_cs update_multi failed - ECF not ready for intr\n");        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);    }} /* end ray_update_multi_list *//*===========================================================================*/static void set_multicast_list(struct net_device *dev){    ray_dev_t *local = 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?