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 + -
显示快捷键?