⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ray_cs.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 5 页
字号:
            return 1;        }    }    length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;    switch (ray_hw_xmit( skb->data, length, dev, DATA_TYPE)) {        case XMIT_NO_CCS:        case XMIT_NEED_AUTH:	    netif_stop_queue(dev);            spin_unlock(&local->ray_lock);#ifdef __SMP__            enable_irq(dev->irq);#endif            return 1;        case XMIT_NO_INTR:        case XMIT_MSG_BAD:        case XMIT_OK:        default:            dev->trans_start = jiffies;            spin_unlock(&local->ray_lock);#ifdef __SMP__            enable_irq(dev->irq);#endif            DEV_KFREE_SKB(skb);            return 0;    }    /* Never get here.  All returns from above switch */    return 0;} /* ray_dev_start_xmit *//*===========================================================================*/static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev,                 UCHAR msg_type){    ray_dev_t *local = (ray_dev_t *)dev->priv;    struct ccs *pccs;    int ccsindex;    int offset;    struct tx_msg *ptx; /* Address of xmit buffer in PC space */    short int addr;     /* Address of xmit buffer in card space */        DEBUG(3,"ray_hw_xmit(data=%p, len=%d, dev=%p)\n",data,len,dev);    if (len + TX_HEADER_LENGTH > TX_BUF_SIZE)    {        printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",len);        return XMIT_MSG_BAD;    }    switch (ccsindex = get_free_tx_ccs(local)) {    case ECCSBUSY:	DEBUG(2,"ray_hw_xmit tx_ccs table busy\n");    case ECCSFULL:        DEBUG(2,"ray_hw_xmit No free tx ccs\n");    case ECARDGONE:	netif_stop_queue(dev);        return XMIT_NO_CCS;    default:	break;    }    addr = TX_BUF_BASE + (ccsindex << 11);    if (msg_type == DATA_TYPE) {	add_tx_bytes(&local->stats, len);        local->stats.tx_packets++;    }    ptx = (struct tx_msg *)(local->sram + addr);    ray_build_header(local, ptx, msg_type, data);    if (translate) {        offset = translate_frame(local, ptx, data, len);    }    else { /* Encapsulate frame */        /* TBD TIB length will move address of ptx->var */        memcpy_toio(&ptx->var, data, len);        offset = 0;    }    /* fill in the CCS */    pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;    len += TX_HEADER_LENGTH + offset;    writeb(CCS_TX_REQUEST, &pccs->cmd);    writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]);    writeb(local->tib_length, &pccs->var.tx_request.tx_data_ptr[1]);    writeb(len >> 8, &pccs->var.tx_request.tx_data_length[0]);    writeb(len & 0xff, &pccs->var.tx_request.tx_data_length[1]);/* TBD still need psm_cam? */    writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode);    writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate);    writeb(0, &pccs->var.tx_request.antenna);    DEBUG(3,"ray_hw_xmit default_tx_rate = 0x%x\n",\          local->net_default_tx_rate);    /* Interrupt the firmware to process the command */    if (interrupt_ecf(local, ccsindex)) {        DEBUG(2,"ray_hw_xmit failed - ECF not ready for intr\n");/* TBD very inefficient to copy packet to buffer, and then not   send it, but the alternative is to queue the messages and that   won't be done for a while.  Maybe stop the tx queue until a CCS is   free?*/        writeb(CCS_BUFFER_FREE, &pccs->buffer_status);        return XMIT_NO_INTR;    }    return XMIT_OK;} /* end ray_hw_xmit *//*===========================================================================*/static int translate_frame(ray_dev_t *local, struct tx_msg *ptx, unsigned char *data,                    int len){    unsigned short int 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((UCHAR *)&ptx->var, eth2_llc, sizeof(eth2_llc));        memcpy_toio( ((UCHAR *)&ptx->var) + sizeof(eth2_llc), (UCHAR *)&proto, 2);	if ((proto == APPLEARP_TYPE) || (proto == RAY_IPX_TYPE)) {            /* This is the selective translation table, only 2 entries */            writeb(0xf8, (UCHAR *) &((struct snaphdr_t *)ptx->var)->org[2]);        }        /* Copy body of ethernet packet without ethernet header */        memcpy_toio((UCHAR *)&ptx->var + sizeof(struct snaphdr_t), \                    data + ETH_HLEN,  len - ETH_HLEN);        return (int) sizeof(struct snaphdr_t) - ETH_HLEN;    }    else { /* already  802 type, and proto is length */        DEBUG(3,"ray_cs translate_frame 802\n");            memcpy_toio((UCHAR *)&ptx->var, data + ETH_HLEN,  len - ETH_HLEN);            return 0 - ETH_HLEN;    }    /* TBD do other frame types */} /* end translate_frame *//*===========================================================================*/static void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type,                unsigned char *data){    writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1);/*** IEEE 802.11 Address field assignments *************                TODS FROMDS   addr_1     addr_2          addr_3   addr_4Adhoc           0    0        dest       src (terminal)  BSSID    N/AAP to Terminal  0    1        dest       AP(BSSID)       source   N/ATerminal to AP  1    0        AP(BSSID)  src (terminal)  dest     N/AAP to AP        1    1        dest AP    src AP          dest     source      *******************************************************/    if (local->net_type == ADHOC) {           writeb(0, &ptx->mac.frame_ctl_2);        memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, 2 * ADDRLEN);        memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);    }    else /* infrastructure */    {        if (local->sparm.b4.a_acting_as_ap_status)        {            writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);;            memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, ADDRLEN);            memcpy_toio(ptx->mac.addr_2, local->bss_id, 6);            memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_source, ADDRLEN);        }        else /* Terminal */        {            writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2);            memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN);            memcpy_toio(ptx->mac.addr_2, ((struct ethhdr *)data)->h_source, ADDRLEN);            memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_dest, ADDRLEN);        }    }} /* end encapsulate_frame *//*===========================================================================*/static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd){    ray_dev_t *local = (ray_dev_t *)dev->priv;    dev_link_t *link = local->finder;    int err = 0;#if WIRELESS_EXT > 8    struct iwreq *wrq = (struct iwreq *) ifr;#endif	/* WIRELESS_EXT > 8 */    if (!DEV_OK(link)) {        DEBUG(2,"ray_dev_ioctl - device not present\n");        return -1;    }    DEBUG(2,"ray_cs IOCTL dev=%p, ifr=%p, cmd = 0x%x\n",dev,ifr,cmd);#ifdef __SMP__    disable_irq(dev->irq);#endif    spin_lock(&local->ray_lock);    /* Validate the command */    switch (cmd)    {#if WIRELESS_EXT > 8      /* --------------- WIRELESS EXTENSIONS --------------- */      /* The Wireless Extension support was written by Jean Tourrilhes,       * so blame me for the bugs, not Corey... */      /* Get name */    case SIOCGIWNAME:      strcpy(wrq->u.name, "IEEE 802.11-FH");      break;      /* Get frequency/channel */    case SIOCGIWFREQ:      wrq->u.freq.m = local->sparm.b5.a_hop_pattern;      wrq->u.freq.e = 0;      break;      /* Set frequency/channel */    case SIOCSIWFREQ:      /* Reject if card is already initialised */      if(local->card_status != CARD_AWAITING_PARAM)	{	  err = -EBUSY;	  break;	}      /* Setting by channel number */      if ((wrq->u.freq.m > USA_HOP_MOD) || (wrq->u.freq.e > 0))	err = -EOPNOTSUPP;      else	local->sparm.b5.a_hop_pattern = wrq->u.freq.m;      break;      /* Get current network name (ESSID) */    case SIOCGIWESSID:      if (wrq->u.data.pointer)	{	  char card_essid[IW_ESSID_MAX_SIZE + 1];	  /* Get the essid that was set */          memcpy(card_essid, local->sparm.b5.a_current_ess_id,		 IW_ESSID_MAX_SIZE);	  essid[IW_ESSID_MAX_SIZE] = '\0';	  /* Push it out ! */          wrq->u.data.length = strlen(card_essid) + 1;	  wrq->u.data.flags = 1; /* active */	  copy_to_user(wrq->u.data.pointer, card_essid, sizeof(card_essid));	}      break;      /* Set desired network name (ESSID) */    case SIOCSIWESSID:      /* Reject if card is already initialised */      if(local->card_status != CARD_AWAITING_PARAM)	{	  err = -EBUSY;	  break;	}	if (wrq->u.data.pointer)	{	    char	card_essid[IW_ESSID_MAX_SIZE + 1];	    	    /* Check if we asked for `any' */	    if(wrq->u.data.flags == 0)	    {		/* Corey : can you do that ? */		err = -EOPNOTSUPP;	    }	    else	    {		/* Check the size of the string */		if(wrq->u.data.length >		   IW_ESSID_MAX_SIZE + 1)		{		    err = -E2BIG;		    break;		}		copy_from_user(card_essid,			       wrq->u.data.pointer,			       wrq->u.data.length);		card_essid[IW_ESSID_MAX_SIZE] = '\0';		/* Set the ESSID in the card */		memcpy(local->sparm.b5.a_current_ess_id, card_essid,		       IW_ESSID_MAX_SIZE);	    }	}	break;	/* Get current Access Point (BSSID in our case) */    case SIOCGIWAP:	memcpy(wrq->u.ap_addr.sa_data, local->bss_id, ETH_ALEN);	wrq->u.ap_addr.sa_family = ARPHRD_ETHER;	break;	/* Get the current bit-rate */    case SIOCGIWRATE:	if(local->net_default_tx_rate == 3)	    wrq->u.bitrate.value = 2000000;	/* Hum... */	else	    wrq->u.bitrate.value = local->net_default_tx_rate * 500000;	wrq->u.bitrate.fixed = 0;		/* We are in auto mode */	break;	/* Set the desired bit-rate */    case SIOCSIWRATE:    {	int card_rate = wrq->u.bitrate.value;	/* Auto ? */	if(wrq->u.bitrate.fixed == 0)	    card_rate = 2000000;	/* Check if rate is in range */	if((card_rate != 1000000) &&	   (card_rate != 2000000))	{	    err = -EINVAL;	    break;	}	/* Hack for 1.5 Mb/s instead of 2 Mb/s */	if((local->fw_ver == 0x55) &&		/* Please check */	   (card_rate == 2000000))	    local->net_default_tx_rate = 3;	else	    local->net_default_tx_rate = card_rate/500000;    }      break;      /* Get the current RTS threshold */    case SIOCGIWRTS:      wrq->u.rts.value = (local->sparm.b5.a_rts_threshold[0] << 8)	+ local->sparm.b5.a_rts_threshold[1];      wrq->u.rts.disabled = (wrq->u.rts.value == 32767);      wrq->u.rts.fixed = 1;      break;      /* Set the desired RTS threshold */    case SIOCSIWRTS:    {	int rthr = wrq->u.rts.value;      /* Reject if card is already initialised */      if(local->card_status != CARD_AWAITING_PARAM)	{	  err = -EBUSY;	  break;	}	/* if(wrq->u.rts.fixed == 0) we should complain */	if(wrq->u.rts.disabled)	    rthr = 32767;	else	    if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */	    {		err = -EINVAL;		break;	    }	local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF;	local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF;    }    break;      /* Get the current fragmentation threshold */    case SIOCGIWFRAG:      wrq->u.frag.value = (local->sparm.b5.a_frag_threshold[0] << 8)	+ local->sparm.b5.a_frag_threshold[1];      wrq->u.frag.disabled = (wrq->u.frag.value == 32767);      wrq->u.frag.fixed = 1;      break;      /* Set the desired fragmentation threshold */    case SIOCSIWFRAG:    {	int fthr = wrq->u.frag.value;      /* Reject if card is already initialised */      if(local->card_status != CARD_AWAITING_PARAM)	{	  err = -EBUSY;	  break;	}	/* if(wrq->u.frag.fixed == 0) should complain */	if(wrq->u.frag.disabled)	    fthr = 32767;	else	    if((fthr < 256) || (fthr > 2347)) /* To check out ! */	    {

⌨️ 快捷键说明

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