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

📄 rt2500pci.h

📁 硬实时linux补丁rtai下的网络协议栈 最新
💻 H
📖 第 1 页 / 共 4 页
字号:
					const u16 max_entries,					const u16 entry_size,					const u16 desc_size) {    struct _rt2x00_pci	*rt2x00pci = rt2x00_priv(core);    rt2x00_init_ring(core, ring, ring_type, max_entries, entry_size, desc_size);    ring->data_addr = dma_alloc_coherent(&rt2x00pci->pci_dev->dev, ring->mem_size, &ring->data_dma, GFP_KERNEL);    if(!ring->data_addr)        return -ENOMEM;    memset(ring->data_addr, 0x00, ring->mem_size);    return 0;}static intrt2x00_pci_alloc_rings(struct _rt2x00_core *core) {    struct _rt2x00_pci	*rt2x00pci = rt2x00_priv(core);      if(rt2x00_pci_alloc_ring(core, &rt2x00pci->rx, RING_RX, RX_ENTRIES, DATA_FRAME_SIZE, SIZE_DESCRIPTOR)       || rt2x00_pci_alloc_ring(core, &rt2x00pci->tx, RING_TX, TX_ENTRIES, DATA_FRAME_SIZE, SIZE_DESCRIPTOR)) {        ERROR("DMA allocation failed.\n");        return -ENOMEM;    }    return 0;}static inline voidrt2x00_pci_free_ring(struct _data_ring *ring) {    struct _rt2x00_pci	*rt2x00pci = rt2x00_priv(ring->core);    if(ring->data_addr)        dma_free_coherent(&rt2x00pci->pci_dev->dev, ring->mem_size, ring->data_addr, ring->data_dma);    ring->data_addr = NULL;    rt2x00_deinit_ring(ring);}static voidrt2x00_pci_free_rings(struct _rt2x00_core *core) {    struct _rt2x00_pci	*rt2x00pci = rt2x00_priv(core);    rt2x00_pci_free_ring(&rt2x00pci->rx);    rt2x00_pci_free_ring(&rt2x00pci->tx);}/* * Macro's for calculating exact position in data ring. */#define DESC_BASE(__ring)		( (void*)((__ring)->data_addr) )#define DATA_BASE(__ring)		( (void*)(DESC_BASE(__ring) + ((__ring)->max_entries * (__ring)->desc_size)) )#define __DESC_ADDR(__ring, __index)	( (void*)(DESC_BASE(__ring) + ((__index) * (__ring)->desc_size)) )#define __DATA_ADDR(__ring, __index)	( (void*)(DATA_BASE(__ring) + ((__index) * (__ring)->entry_size)) )#define DESC_ADDR(__ring)		( __DESC_ADDR(__ring, (__ring)->index) )#define DESC_ADDR_DONE(__ring)		( __DESC_ADDR(__ring, (__ring)->index_done) )#define DATA_ADDR(__ring)		( __DATA_ADDR(__ring, (__ring)->index) )#define DATA_ADDR_DONE(__ring)		( __DATA_ADDR(__ring, (__ring)->index_done) )/* * Register access. * All access to the registers will go through rt2x00_register_read and rt2x00_register_write. * BBP and RF register require indirect register access through the register BBPCSR and RFCSR. * The indirect register access work with busy bits, and a read or write function call can fail. * Specific fields within a register can be accessed using the set and get field routines, * these function will handle the requirement of little_endian and big_endian conversions. */#define REGISTER_BUSY_COUNT	10	/* Number of retries before failing access BBP & RF indirect register */#define REGISTER_BUSY_DELAY	100	/* Delay between each register access retry. (us) */static voidrt2x00_register_read(const struct _rt2x00_pci *rt2x00pci, const unsigned long offset, u32 *value) {    *value = readl((void*)(rt2x00pci->csr_addr + offset));}static voidrt2x00_register_multiread(const struct _rt2x00_pci *rt2x00pci, const unsigned long offset, u32 *value, const u16 length) {    memcpy_fromio((void*)value, (void*)(rt2x00pci->csr_addr + offset), length);}static voidrt2x00_register_write(const struct _rt2x00_pci *rt2x00pci, const unsigned long offset, const u32 value) {    writel(value, (void*)(rt2x00pci->csr_addr + offset));}static voidrt2x00_register_multiwrite(const struct _rt2x00_pci *rt2x00pci, const unsigned long offset, u32 *value, const u16 length) {    memcpy_toio((void*)(rt2x00pci->csr_addr + offset), (void*)value, length);}static void rt2x00_bbp_regwrite(const struct _rt2x00_pci *rt2x00pci, const u8 reg_id, const u8 value) {    u32		reg = 0x00000000;    u8		counter = 0x00;    for(counter = 0x00; counter < REGISTER_BUSY_COUNT; counter++){        rt2x00_register_read(rt2x00pci, BBPCSR, &reg);        if(!rt2x00_get_field32(reg, BBPCSR_BUSY))            goto bbp_write;        udelay(REGISTER_BUSY_DELAY);    }    ERROR("BBPCSR register busy. Write failed\n");    return;  bbp_write:    reg = 0x00000000;    rt2x00_set_field32(&reg, BBPCSR_VALUE, value);    rt2x00_set_field32(&reg, BBPCSR_REGNUM, reg_id);    rt2x00_set_field32(&reg, BBPCSR_BUSY, 1);    rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1);    rt2x00_register_write(rt2x00pci, BBPCSR, reg);}static voidrt2x00_bbp_regread(const struct _rt2x00_pci *rt2x00pci, const u8 reg_id, u8 *value) {    u32		reg = 0x00000000;    u8		counter = 0x00;    /*     * We first have to acquire the requested BBP register,     * so we write the register id into the BBP register first.     */    rt2x00_set_field32(&reg, BBPCSR_REGNUM, reg_id);    rt2x00_set_field32(&reg, BBPCSR_BUSY, 1);    rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 0);    rt2x00_register_write(rt2x00pci, BBPCSR, reg);    for(counter = 0x00; counter < REGISTER_BUSY_COUNT; counter++){        rt2x00_register_read(rt2x00pci, BBPCSR, &reg);        if(!rt2x00_get_field32(reg, BBPCSR_BUSY)){            *value = rt2x00_get_field32(reg, BBPCSR_VALUE);            return;        }        udelay(REGISTER_BUSY_DELAY);    }    ERROR("BBPCSR register busy. Read failed\n");    *value = 0xff;}static void rt2x00_rf_regwrite(const struct _rt2x00_pci *rt2x00pci, const u32 value) {    u32		reg = 0x00000000;    u8		counter = 0x00;    for(counter = 0x00; counter < REGISTER_BUSY_COUNT; counter++){        rt2x00_register_read(rt2x00pci, RFCSR, &reg);        if(!rt2x00_get_field32(reg, RFCSR_BUSY))            goto rf_write;        udelay(REGISTER_BUSY_DELAY);    }    ERROR("RFCSR register busy. Write failed\n");    return;  rf_write:    reg = value;    rt2x00_set_field32(&reg, RFCSR_NUMBER_OF_BITS, 20);    rt2x00_set_field32(&reg, RFCSR_IF_SELECT, 0);    rt2x00_set_field32(&reg, RFCSR_BUSY, 1);    //  printk(KERN_INFO "DEBUG: %s:%d: reg=%x\n", __FILE__, __LINE__, reg);    rt2x00_register_write(rt2x00pci, RFCSR, reg);}/* * EEPROM access. * The EEPROM is being accessed by word index. * rt2x00_eeprom_read_word is the main access function that can be called by * the rest of the module. It will take the index number of the eeprom word * and the bus width. */static inline voidrt2x00_eeprom_pulse_high(const struct _rt2x00_pci *rt2x00pci, u32 *flags) {    rt2x00_set_field32(flags, CSR21_EEPROM_DATA_CLOCK, 1);    rt2x00_register_write(rt2x00pci, CSR21, *flags);    udelay(1);}static inline voidrt2x00_eeprom_pulse_low(const struct _rt2x00_pci *rt2x00pci, u32 *flags) {    rt2x00_set_field32(flags, CSR21_EEPROM_DATA_CLOCK, 0);    rt2x00_register_write(rt2x00pci, CSR21, *flags);    udelay(1);}static voidrt2x00_eeprom_shift_out_bits(const struct _rt2x00_pci *rt2x00pci, const u16 data, const u16 count) {    u32	flags = 0x00000000;    u32	mask =  0x0001 << (count - 1);    rt2x00_register_read(rt2x00pci, CSR21, &flags);    /*     * Clear data flags.     */    rt2x00_set_field32(&flags, CSR21_EEPROM_DATA_IN, 0);    rt2x00_set_field32(&flags, CSR21_EEPROM_DATA_OUT, 0);    /*     * Start writing all bits.      */    do{        /*         * Only set the data_in flag when we are at the correct bit.         */        rt2x00_set_field32(&flags, CSR21_EEPROM_DATA_IN, (data & mask) ? 1 : 0);        rt2x00_register_write(rt2x00pci, CSR21, flags);        rt2x00_eeprom_pulse_high(rt2x00pci, &flags);        rt2x00_eeprom_pulse_low(rt2x00pci, &flags);        /*         * Shift to next bit.         */        mask >>= 1;    } while(mask);    rt2x00_set_field32(&flags, CSR21_EEPROM_DATA_IN, 0);    rt2x00_register_write(rt2x00pci, CSR21, flags);}static voidrt2x00_eeprom_shift_in_bits(const struct _rt2x00_pci *rt2x00pci, u16 *data) {    u32	flags = 0x00000000;    u8	counter = 0x00;    rt2x00_register_read(rt2x00pci, CSR21, &flags);    /*     * Clear data flags.     */    rt2x00_set_field32(&flags, CSR21_EEPROM_DATA_IN, 0);    rt2x00_set_field32(&flags, CSR21_EEPROM_DATA_OUT, 0);    /*     * Start reading all 16 bits.     */    for(counter = 0; counter < 16; counter++){        /*         * Shift to the next bit.         */        *data <<= 1;        rt2x00_eeprom_pulse_high(rt2x00pci, &flags);        rt2x00_register_read(rt2x00pci, CSR21, &flags);        /*         * Clear data_in flag and set the data bit to 1 when the data_out flag is set.         */        rt2x00_set_field32(&flags, CSR21_EEPROM_DATA_IN, 0);        if(rt2x00_get_field32(flags, CSR21_EEPROM_DATA_OUT))            *data |= 1;	        rt2x00_eeprom_pulse_low(rt2x00pci, &flags);    }}static u16rt2x00_eeprom_read_word(const struct _rt2x00_pci *rt2x00pci, const u8 word) {    u32	flags = 0x00000000;    u16	data = 0x0000;    /*     * Clear all flags, and enable chip select.     */    rt2x00_register_read(rt2x00pci, CSR21, &flags);    rt2x00_set_field32(&flags, CSR21_EEPROM_DATA_IN, 0);    rt2x00_set_field32(&flags, CSR21_EEPROM_DATA_OUT, 0);    rt2x00_set_field32(&flags, CSR21_EEPROM_DATA_CLOCK, 0);    rt2x00_set_field32(&flags, CSR21_EEPROM_CHIP_SELECT, 1);    rt2x00_register_write(rt2x00pci, CSR21, flags);    /*     * kick a pulse.     */    rt2x00_eeprom_pulse_high(rt2x00pci, &flags);    rt2x00_eeprom_pulse_low(rt2x00pci, &flags);    /*     * Select the read opcode and bus_width.     */    rt2x00_eeprom_shift_out_bits(rt2x00pci, EEPROM_READ_OPCODE, 3);    rt2x00_eeprom_shift_out_bits(rt2x00pci, word, rt2x00pci->eeprom_width);    rt2x00_eeprom_shift_in_bits(rt2x00pci, &data);    /*     * Clear chip_select and data_in flags.     */    rt2x00_register_read(rt2x00pci, CSR21, &flags);    rt2x00_set_field32(&flags, CSR21_EEPROM_DATA_IN, 0);    rt2x00_set_field32(&flags, CSR21_EEPROM_CHIP_SELECT, 0);    rt2x00_register_write(rt2x00pci, CSR21, flags);    /*     * kick a pulse.     */    rt2x00_eeprom_pulse_high(rt2x00pci, &flags);    rt2x00_eeprom_pulse_low(rt2x00pci, &flags);    return data;}#endif /* RT2500PCI_H */

⌨️ 快捷键说明

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