📄 ray_cs.c
字号:
} 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 *p = (struct status *)(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; MOD_INC_USE_COUNT; 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)) { MOD_DEC_USE_COUNT; return -ENODEV; } if (link->open == 0) local->num_multi = 0; link->open++; 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); if (link->state & DEV_STALE_CONFIG) mod_timer(&link->release, jiffies + HZ/20); MOD_DEC_USE_COUNT; 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 *pccs = (struct ccs *)(local->sram + CCS_BASE); 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 *pccs = (struct ccs *)(local->sram + CCS_BASE); 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 *p = (struct status *)(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)) { 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; dev_link_t *link = local->finder; int ccsindex; int i; struct ccs *pccs; if (!(link->state & DEV_PRESENT)) { 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 = ((struct ccs *)(local->sram + CCS_BASE)) + 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 *pccs; int i = 0; ray_dev_t *local = (ray_dev_t *)dev->priv; dev_link_t *link = local->finder; UCHAR *p = local->sram + HOST_TO_ECF_BASE; if (!(link->state & DEV_PRESENT)) { 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 = ((struct ccs *)(local->sram + CCS_BASE)) + 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -