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

📄 rt_rt2500pci.c

📁 硬实时linux补丁rtai下的网络协议栈 最新
💻 C
📖 第 1 页 / 共 3 页
字号:
    u8			reg_rx;    u8			reg_tx;    rt2x00_register_read(rt2x00pci, BBPCSR1, &reg);    rt2x00_bbp_regread(rt2x00pci, 14, &reg_rx);    rt2x00_bbp_regread(rt2x00pci, 2, &reg_tx);    /* TX antenna select */    if(config->antenna_tx == 1) {         /* Antenna A */        reg_tx = (reg_tx & 0xfc) | 0x00;        reg    = (reg    & 0xfffcfffc) | 0x00;    }    else if(config->antenna_tx == 2) {         /* Antenna B */        reg_tx = (reg_tx & 0xfc) | 0x02;        reg    = (reg    & 0xfffcfffc) | 0x00020002;    }    else {        /* Diversity */        reg_tx = (reg_tx & 0xfc) | 0x02;        reg    = (reg    & 0xfffcfffc) | 0x00020002;    }            /* RX antenna select */    if(config->antenna_rx == 1)        reg_rx = (reg_rx & 0xfc) | 0x00;    else if(config->antenna_rx == 2)        reg_rx = (reg_rx & 0xfc) | 0x02;    else        reg_rx = (reg_rx & 0xfc) | 0x02;    /*     * RT2525E and RT5222 need to flip I/Q     */    if(rt2x00_rf(&rt2x00pci->chip, RF5222)){                reg |=  0x00040004;        reg_tx |= 0x04;    }    else if(rt2x00_rf(&rt2x00pci->chip, RF2525E)) {                reg |=  0x00040004;        reg_tx |= 0x04;        reg_rx |= 0xfb;    }    rt2x00_register_write(rt2x00pci, BBPCSR1, reg);    rt2x00_bbp_regwrite(rt2x00pci, 14, reg_rx);    rt2x00_bbp_regwrite(rt2x00pci, 2, reg_tx);}static voidrt2x00_dev_update_duration(struct _rt2x00_pci *rt2x00pci, struct _rt2x00_config *config) {    u32			reg = 0x00000000;    DEBUG("Start.\n");    rt2x00_register_read(rt2x00pci, CSR11, &reg);    rt2x00_set_field32(&reg, CSR11_CWMIN, 5);		/* 2^5 = 32. */    rt2x00_set_field32(&reg, CSR11_CWMAX, 10);		/* 2^10 = 1024. */    rt2x00_set_field32(&reg, CSR11_SLOT_TIME, config->slot_time);    rt2x00_set_field32(&reg, CSR11_CW_SELECT, 1);    rt2x00_register_write(rt2x00pci, CSR11, reg);    rt2x00_register_read(rt2x00pci, CSR18, &reg);    rt2x00_set_field32(&reg, CSR18_SIFS, config->sifs);    rt2x00_set_field32(&reg, CSR18_PIFS, config->sifs + config->slot_time);    rt2x00_register_write(rt2x00pci, CSR18, reg);    rt2x00_register_read(rt2x00pci, CSR19, &reg);    rt2x00_set_field32(&reg, CSR19_DIFS, config->sifs + (2 * config->slot_time));    rt2x00_set_field32(&reg, CSR19_EIFS, config->sifs + get_duration((IEEE80211_HEADER + ACK_SIZE), capabilities.bitrate[0]));    rt2x00_register_write(rt2x00pci, CSR19, reg);}static voidrt2x00_dev_update_retry(struct _rt2x00_pci * rt2x00pci, struct _rt2x00_config * config) {    u32			reg = 0x00000000;    rt2x00_register_read(rt2x00pci, CSR11, &reg);    rt2x00_set_field32(&reg, CSR11_LONG_RETRY, config->long_retry);    rt2x00_set_field32(&reg, CSR11_SHORT_RETRY, config->short_retry);    rt2x00_register_write(rt2x00pci, CSR11, reg);}static voidrt2x00_dev_update_preamble(struct _rt2x00_pci *rt2x00pci, struct _rt2x00_config *config) {    u32			reg[4];    u32			preamble = 0x00000000;    memset(&reg, 0x00, sizeof(reg));    reg[0] = cpu_to_le32(0x00700400 | preamble);	/* ARCSR2 */    reg[1] = cpu_to_le32(0x00380401 | preamble);	/* ARCSR3 */    reg[2] = cpu_to_le32(0x00150402 | preamble);	/* ARCSR4 */    reg[3] = cpu_to_le32(0x000b8403 | preamble);	/* ARCSR5 */    rt2x00_register_multiwrite(rt2x00pci, ARCSR2, &reg[0], sizeof(reg));}static voidrt2x00_dev_update_led(struct _rt2x00_pci *rt2x00pci, struct _rt2x00_config *config) {    u32			reg = 0x00000000;    rt2x00_register_read(rt2x00pci, LEDCSR, &reg);    rt2x00_set_field32(&reg, LEDCSR_LINK, config->led_status ? 1 : 0);    rt2x00_register_write(rt2x00pci, LEDCSR, reg);}static intrt2x00_dev_update_config(struct _rt2x00_core *core, u16 update_flags) {    struct _rt2x00_pci 	*rt2x00pci = rt2x00_priv(core);    DEBUG("Start.\n");    if(update_flags & UPDATE_BSSID)        rt2x00_dev_update_bssid(rt2x00pci, &core->config);    if(update_flags & UPDATE_PACKET_FILTER)        rt2x00_dev_update_packet_filter(rt2x00pci, &core->config);    if(update_flags & UPDATE_CHANNEL)        rt2x00_dev_update_channel(rt2x00pci, &core->config);    if(update_flags & UPDATE_BITRATE)        rt2x00_dev_update_rate(rt2x00pci, &core->config);    if(update_flags & UPDATE_TXPOWER)        rt2x00_dev_update_txpower(rt2x00pci, &core->config);    if(update_flags & UPDATE_ANTENNA)        rt2x00_dev_update_antenna(rt2x00pci, &core->config);    if(update_flags & UPDATE_DURATION)        rt2x00_dev_update_duration(rt2x00pci, &core->config);    if(update_flags & UPDATE_RETRY)         rt2x00_dev_update_retry(rt2x00pci, &core->config);    if(update_flags & UPDATE_PREAMBLE)        rt2x00_dev_update_preamble(rt2x00pci, &core->config);    if(update_flags & UPDATE_LED_STATUS)        rt2x00_dev_update_led(rt2x00pci, &core->config);    if(update_flags & UPDATE_AUTORESP)        rt2x00_dev_update_autoresp(rt2x00pci, &core->config);    if(update_flags & UPDATE_BBPSENS)        rt2x00_dev_update_bbpsens(rt2x00pci, &core->config);    DEBUG("Exit.\n");    return 0;}/* * Transmission routines. * rt2x00_write_tx_desc will write the txd descriptor. * rt2x00_dev_xmit_packet will copy the packets to the appropriate DMA ring. *//* * PLCP_SIGNAL, PLCP_SERVICE, PLCP_LENGTH_LOW and PLCP_LENGTH_HIGH are BBP registers. * For RT2460 devices we need, besides the value we want to write, * also set the busy bit (0x8000) and the register number (0x0f00). * The value we want to write is stored in 0x00ff. * For PLCP_SIGNAL we can optionally enable SHORT_PREAMBLE. * For PLCP_SERVICE we can set the length extension bit according to * 802.11b standard 18.2.3.5. */static void rt2x00_write_tx_desc(struct _rt2x00_pci *rt2x00pci, struct _txd *txd, u32 packet_size, u16 rate, u16 xmit_flags) {    u32		residual = 0x00000000;    u32         duration = 0x00000000;    u16		signal = 0x0000;    u16		service = 0x0000;    u16		length_low = 0x0000;    u16		length_high = 0x0000;    rt2x00_set_field32(&txd->word0, TXD_W0_VALID, 1);    rt2x00_set_field32(&txd->word0, TXD_W0_DATABYTE_COUNT, packet_size);    rt2x00_set_field32(&txd->word0, TXD_W0_ACK, (xmit_flags & XMIT_ACK) ? 1 : 0);    rt2x00_set_field32(&txd->word0, TXD_W0_RETRY_MODE, (xmit_flags & XMIT_LONG_RETRY) ? 1 : 0);    rt2x00_set_field32(&txd->word0, TXD_W0_TIMESTAMP, (xmit_flags & XMIT_TIMESTAMP) ? 1 : 0);    rt2x00_set_field32(&txd->word0, TXD_W0_MORE_FRAG, (xmit_flags & XMIT_MORE_FRAGS) ? 1 : 0);    rt2x00_set_field32(&txd->word0, TXD_W0_MORE_FRAG, (xmit_flags & XMIT_RTS) ? 1 : 0);    rt2x00_set_field32(&txd->word10, TXD_W10_RTS, (xmit_flags & XMIT_RTS) ? 1 : 0);    rt2x00_set_field32(&txd->word0, TXD_W0_OFDM, (xmit_flags & XMIT_OFDM) ? 1 : 0);    packet_size += 4;    if(xmit_flags & XMIT_OFDM) {        /*         * convert length to microseconds.         */        length_high = (packet_size >> 6) & 0x3f;        length_low = (packet_size & 0x3f);    } else {        residual = get_duration_res(packet_size, rate);        duration = get_duration(packet_size, rate);        if(residual != 0)            duration++;        length_high = duration >> 8;        length_low = duration & 0xff;    }      signal |= 0x8500 | rt2x00_get_plcp(rate);    if(xmit_flags & XMIT_SHORT_PREAMBLE)        signal |= 0x0008;    service |= 0x0600 | 0x0004;    if(residual <= (8 % 11))        service |= 0x0080;    rt2x00_set_field32(&txd->word3, TXD_W3_PLCP_SIGNAL, signal);    rt2x00_set_field32(&txd->word3, TXD_W3_PLCP_SERVICE, service);    rt2x00_set_field32(&txd->word3, TXD_W3_PLCP_LENGTH_LOW, length_low);    rt2x00_set_field32(&txd->word3, TXD_W3_PLCP_LENGTH_HIGH, length_high);    /* set XMIT_IFS to XMIT_IFS_NONE */    rt2x00_set_field32(&txd->word0, TXD_W0_IFS, XMIT_IFS_NONE);    /* highest priority */    rt2x00_set_field32(&txd->word2, TXD_W2_CWMIN, 1);    rt2x00_set_field32(&txd->word2, TXD_W2_CWMAX, 2);    rt2x00_set_field32(&txd->word2, TXD_W2_AIFS, 1);      /*     * set this last, after this the device can start transmitting the packet.     */    rt2x00_set_field32(&txd->word0, TXD_W0_OWNER_NIC, 1);}static int rt2x00_dev_xmit_packet(struct _rt2x00_core * core, 				  struct rtskb *rtskb, 				  u16 rate,				  u16 xmit_flags) {    struct _rt2x00_pci	*rt2x00pci = rt2x00_priv(core);    struct _data_ring	*ring = NULL;    struct _txd		*txd = NULL;    void		*data = NULL;    u32			reg = 0x00000000;    rtdm_lockctx_t context;    rtdm_lock_get_irqsave(&rt2x00pci->lock, context);    /* load tx-control register */    rt2x00_register_read(rt2x00pci, TXCSR0, &reg);    /* select tx-descriptor ring and prepare xmit */    ring = &rt2x00pci->tx;    rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);    txd = DESC_ADDR(ring);    data = DATA_ADDR(ring);    if(rt2x00_get_field32(txd->word0, TXD_W0_OWNER_NIC)       || rt2x00_get_field32(txd->word0, TXD_W0_VALID)) {        rtdm_lock_put_irqrestore(&rt2x00pci->lock, context);        return -ENOMEM;    }    /* get and patch time stamp just before the transmission */    if (rtskb->xmit_stamp)        *rtskb->xmit_stamp = cpu_to_be64(rtdm_clock_read() + *rtskb->xmit_stamp);    /* copy rtskb to dma */    memcpy(data, rtskb->data, rtskb->len);    rt2x00_write_tx_desc(rt2x00pci, txd, rtskb->len, rate, xmit_flags);    rt2x00_ring_index_inc(ring);        /* let the device do the rest ... */    rt2x00_register_write(rt2x00pci, TXCSR0, reg);    rtdm_lock_put_irqrestore(&rt2x00pci->lock, context);    return 0;}/* * PCI device handlers for usage by core module. */static struct _rt2x00_dev_handler rt2x00_pci_handler = {    .dev_module		 = THIS_MODULE,    .dev_probe		 = rt2x00_dev_probe,    .dev_remove		 = rt2x00_dev_remove,    .dev_radio_on	 = rt2x00_dev_radio_on,    .dev_radio_off	 = rt2x00_dev_radio_off,    .dev_update_config   = rt2x00_dev_update_config,    .dev_register_access = rt2x00_dev_register_access,    .dev_xmit_packet     = rt2x00_dev_xmit_packet,};int rt2x00_pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) {      struct rtnet_device	*rtnet_dev = NULL;    int			status = 0x00000000;    DEBUG("start.\n");    if(id->driver_data != RT2560){        ERROR("detected device not supported.\n");        status = -ENODEV;        goto exit;    }    if(pci_enable_device(pci_dev)){        ERROR("enable device failed.\n");        status = -EIO;        goto exit;    }    pci_set_master(pci_dev);    if(pci_set_dma_mask(pci_dev, DMA_64BIT_MASK)       && pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)){        ERROR("PCI DMA not supported\n");        status = -EIO;        goto exit_disable_device;    }    if(pci_request_regions(pci_dev, pci_name(pci_dev))){        ERROR("PCI request regions failed.\n");        status = -EBUSY;        goto exit_disable_device;    }    INFO("pci_dev->irq=%d\n", pci_dev->irq);        rtnet_dev = rt2x00_core_probe(&rt2x00_pci_handler, pci_dev, sizeof(struct _rt2x00_pci));    if(!rtnet_dev){        ERROR("rtnet_device allocation failed.\n");        status = -ENOMEM;        goto exit_release_regions;    }        rtnet_dev->irq = pci_dev->irq;        pci_set_drvdata(pci_dev, rtnet_dev);        return 0;      exit_release_regions:    pci_release_regions(pci_dev);      exit_disable_device:    if(status != -EBUSY)        pci_disable_device(pci_dev);      exit:    return status;}static void rt2x00_pci_remove(struct pci_dev *pci_dev) {    struct rtnet_device	*rtnet_dev = pci_get_drvdata(pci_dev);    rt2x00_core_remove(rtnet_dev);    pci_set_drvdata(pci_dev, NULL);    pci_release_regions(pci_dev);    pci_disable_device(pci_dev);}/* * RT2500 PCI module information. */char version[] = DRV_NAME " - " DRV_VERSION;struct pci_device_id rt2x00_device_pci_tbl[] = {    { PCI_DEVICE(0x1814, 0x0201), .driver_data = RT2560},	/* Ralink 802.11g */    {0,}};MODULE_AUTHOR(DRV_AUTHOR);MODULE_DESCRIPTION("RTnet rt2500 PCI WLAN driver (PCI Module)");MODULE_LICENSE("GPL");struct pci_driver rt2x00_pci_driver ={    .name	= DRV_NAME,    .id_table	= rt2x00_device_pci_tbl,    .probe	= rt2x00_pci_probe,    .remove	= __devexit_p(rt2x00_pci_remove),};static int __init rt2x00_pci_init(void) {    rtdm_printk(KERN_INFO "Loading module: %s\n", version);    return pci_register_driver(&rt2x00_pci_driver);}static void __exit rt2x00_pci_exit(void) {    rtdm_printk(KERN_INFO "Unloading module: %s\n", version);    pci_unregister_driver(&rt2x00_pci_driver);}module_init(rt2x00_pci_init);module_exit(rt2x00_pci_exit);

⌨️ 快捷键说明

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