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

📄 ray_cs.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
} /* init_startup_params */ /*===========================================================================*/static void verify_dl_startup(u_long data){    ray_dev_t *local = (ray_dev_t *)data;    struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;    UCHAR status;    dev_link_t *link = local->finder;    if (!(link->state & DEV_PRESENT)) {        DEBUG(2,"ray_cs verify_dl_startup - device not present\n");        return;    }#ifdef PCMCIA_DEBUG    if (pc_debug > 2) {    int i;    printk(KERN_DEBUG "verify_dl_startup parameters sent via ccs %d:\n",           local->dl_param_ccs);        for (i=0; i<sizeof(struct b5_startup_params); i++) {            printk(" %2x", (unsigned int) readb(local->sram + HOST_TO_ECF_BASE + i));        }    printk("\n");    }#endif    status = readb(&pccs->buffer_status);    if (status!= CCS_BUFFER_FREE)    {        printk(KERN_INFO "Download startup params failed.  Status = %d\n",           status);        local->card_status = CARD_DL_PARAM_ERROR;        return;    }    if (local->sparm.b4.a_network_type == ADHOC)        start_net((u_long)local);    else        join_net((u_long)local);    return;} /* end verify_dl_startup *//*===========================================================================*//* Command card to start a network */static void start_net(u_long data){    ray_dev_t *local = (ray_dev_t *)data;    struct ccs __iomem *pccs;    int ccsindex;    dev_link_t *link = local->finder;    if (!(link->state & DEV_PRESENT)) {        DEBUG(2,"ray_cs start_net - device not present\n");        return;    }    /* Fill in the CCS fields for the ECF */    if ((ccsindex = get_free_ccs(local)) < 0) return;    pccs = ccs_base(local) + ccsindex;    writeb(CCS_START_NETWORK, &pccs->cmd);    writeb(0, &pccs->var.start_network.update_param);    /* Interrupt the firmware to process the command */    if (interrupt_ecf(local, ccsindex)) {        DEBUG(1,"ray start net failed - card not ready for intr\n");        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);        return;    }    local->card_status = CARD_DOING_ACQ;    return;} /* end start_net *//*===========================================================================*//* Command card to join a network */static void join_net(u_long data){    ray_dev_t *local = (ray_dev_t *)data;    struct ccs __iomem *pccs;    int ccsindex;    dev_link_t *link = local->finder;        if (!(link->state & DEV_PRESENT)) {        DEBUG(2,"ray_cs join_net - device not present\n");        return;    }    /* Fill in the CCS fields for the ECF */    if ((ccsindex = get_free_ccs(local)) < 0) return;    pccs = ccs_base(local) + ccsindex;    writeb(CCS_JOIN_NETWORK, &pccs->cmd);    writeb(0, &pccs->var.join_network.update_param);    writeb(0, &pccs->var.join_network.net_initiated);    /* Interrupt the firmware to process the command */    if (interrupt_ecf(local, ccsindex)) {        DEBUG(1,"ray join net failed - card not ready for intr\n");        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);        return;    }    local->card_status = CARD_DOING_ACQ;    return;}/*============================================================================    After a card is removed, ray_release() will unregister the net    device, and release the PCMCIA configuration.  If the device is    still open, this will be postponed until it is closed.=============================================================================*/static void ray_release(dev_link_t *link){    struct net_device *dev = link->priv;     ray_dev_t *local = dev->priv;    int i;        DEBUG(1, "ray_release(0x%p)\n", link);    del_timer(&local->timer);    link->state &= ~DEV_CONFIG;    iounmap(local->sram);    iounmap(local->rmem);    iounmap(local->amem);    /* Do bother checking to see if these succeed or not */    i = pcmcia_release_window(link->win);    if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(link->win) ret = %x\n",i);    i = pcmcia_release_window(local->amem_handle);    if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);    i = pcmcia_release_window(local->rmem_handle);    if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);    i = pcmcia_release_configuration(link->handle);    if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseConfiguration ret = %x\n",i);    i = pcmcia_release_irq(link->handle, &link->irq);    if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i);    DEBUG(2,"ray_release ending\n");}/*=============================================================================    The card status event handler.  Mostly, this schedules other    stuff to run after an event is received.  A CARD_REMOVAL event    also sets some flags to discourage the net drivers from trying    to talk to the card any more.    When a CARD_REMOVAL event is received, we immediately set a flag    to block future accesses to this device.  All the functions that    actually access the device should check this flag to make sure    the card is still present.=============================================================================*/static int ray_event(event_t event, int priority,                     event_callback_args_t *args){    dev_link_t *link = args->client_data;    struct net_device *dev = link->priv;    ray_dev_t *local = (ray_dev_t *)dev->priv;    DEBUG(1, "ray_event(0x%06x)\n", event);        switch (event) {    case CS_EVENT_CARD_REMOVAL:        link->state &= ~DEV_PRESENT;        netif_device_detach(dev);        if (link->state & DEV_CONFIG) {	    ray_release(link);            del_timer(&local->timer);        }        break;    case CS_EVENT_CARD_INSERTION:        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;        ray_config(link);        break;    case CS_EVENT_PM_SUSPEND:        link->state |= DEV_SUSPEND;        /* Fall through... */    case CS_EVENT_RESET_PHYSICAL:        if (link->state & DEV_CONFIG) {            if (link->open)            	netif_device_detach(dev);            pcmcia_release_configuration(link->handle);        }        break;    case CS_EVENT_PM_RESUME:        link->state &= ~DEV_SUSPEND;        /* Fall through... */    case CS_EVENT_CARD_RESET:        if (link->state & DEV_CONFIG) {            pcmcia_request_configuration(link->handle, &link->conf);            if (link->open) {                ray_reset(dev);		netif_device_attach(dev);            }        }        break;    }    return 0;    DEBUG(2,"ray_event ending\n");} /* ray_event *//*===========================================================================*/int ray_dev_init(struct net_device *dev){#ifdef RAY_IMMEDIATE_INIT    int i;#endif	/* RAY_IMMEDIATE_INIT */    ray_dev_t *local = dev->priv;    dev_link_t *link = local->finder;    DEBUG(1,"ray_dev_init(dev=%p)\n",dev);    if (!(link->state & DEV_PRESENT)) {        DEBUG(2,"ray_dev_init - device not present\n");        return -1;    }#ifdef RAY_IMMEDIATE_INIT    /* 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;    }#else	/* RAY_IMMEDIATE_INIT */    /* Postpone the card init so that we can still configure the card,     * for example using the Wireless Extensions. The init will happen     * in ray_open() - Jean II */    DEBUG(1,"ray_dev_init: postponing card init to ray_open() ; Status = %d\n",	  local->card_status);#endif	/* RAY_IMMEDIATE_INIT */    /* copy mac and broadcast addresses to linux device */    memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);    memset(dev->broadcast, 0xff, ETH_ALEN);    DEBUG(2,"ray_dev_init ending\n");    return 0;}/*===========================================================================*/static int ray_dev_config(struct net_device *dev, struct ifmap *map){    ray_dev_t *local = dev->priv;    dev_link_t *link = local->finder;    /* Dummy routine to satisfy device structure */    DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map);    if (!(link->state & DEV_PRESENT)) {        DEBUG(2,"ray_dev_config - device not present\n");        return -1;    }    return 0;}/*===========================================================================*/static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev){    ray_dev_t *local = dev->priv;    dev_link_t *link = local->finder;    short length = skb->len;    if (!(link->state & DEV_PRESENT)) {        DEBUG(2,"ray_dev_start_xmit - device not present\n");        return -1;    }    DEBUG(3,"ray_dev_start_xmit(skb=%p, dev=%p)\n",skb,dev);    if (local->authentication_state == NEED_TO_AUTH) {        DEBUG(0,"ray_cs Sending authentication request.\n");        if (!build_auth_frame (local, local->auth_id, OPEN_AUTH_REQUEST)) {            local->authentication_state = AUTHENTICATED;            netif_stop_queue(dev);            return 1;        }    }    if (length < ETH_ZLEN)    {    	skb = skb_padto(skb, ETH_ZLEN);    	if (skb == NULL)    		return 0;    	length = ETH_ZLEN;    }    switch (ray_hw_xmit( skb->data, length, dev, DATA_TYPE)) {        case XMIT_NO_CCS:        case XMIT_NEED_AUTH:	    netif_stop_queue(dev);            return 1;        case XMIT_NO_INTR:        case XMIT_MSG_BAD:        case XMIT_OK:        default:            dev->trans_start = jiffies;            dev_kfree_skb(skb);            return 0;    }    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 __iomem *pccs;    int ccsindex;    int offset;    struct tx_msg __iomem *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) {        local->stats.tx_bytes += len;        local->stats.tx_packets++;    }    ptx = 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 = ccs_base(local) + 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 set tbusy 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 __iomem *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(&ptx->var, eth2_llc, sizeof(eth2_llc));        memcpy_toio( ((void __iomem *)&ptx->var) + sizeof(eth2_llc), (UCHAR *)&proto, 2);        if ((proto == 0xf380) || (proto == 0x3781)) {            /* This is the selective translation table, only 2 entries */            writeb(0xf8, &((struct snaphdr_t __iomem *)ptx->var)->org[3]);        }        /* Copy body of ethernet packet without ethernet header */        memcpy_toio((void __iomem *)&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");        if (proto == 0xffff) { /* evil netware IPX 802.3 without LLC */        DEBUG(3,"ray_cs translate_frame evil IPX\n");            memcpy_toio(&ptx->var, data + ETH_HLEN,  len - ETH_HLEN);            return 0 - ETH_HLEN;        }

⌨️ 快捷键说明

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