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

📄 at_test.c

📁 Linux* Base Driver for the Attansic(R) L1 Gigabit Ethernet Adapter
💻 C
📖 第 1 页 / 共 2 页
字号:
static int at_priv_drv_tpd(struct at_adapter* adapter, at_drv_tpd* drvtpd, void* usraddr)
{
    struct at_tpd_ring* tpd_ring = &adapter->tpd_ring;
    uint16_t i, index;
    uint8_t* buffer;
    tx_packet_desc_t * tpd; 
    uint32_t size;
    at_drv_tpd* p;
    
    if (drvtpd->length > tpd_ring->count || 
        drvtpd->idx_start >= tpd_ring->count) {
        return -EINVAL;
    }
    index = drvtpd->idx_start;
    size = drvtpd->length*sizeof(tx_packet_desc_t)+sizeof(*drvtpd);
    p = kmalloc(size, GFP_KERNEL);
    if (!p) {
        return -ENOMEM;
    }
    buffer = (uint8_t*) p->data;
    memcpy(p, drvtpd, sizeof(*p));
    
    for (i=0; i<drvtpd->length; i++) {
        tpd = AT_TPD_DESC(tpd_ring, index);
        memcpy(buffer+i*sizeof(tx_packet_desc_t), tpd, sizeof(tx_packet_desc_t));
        index++;
        index = index % tpd_ring->count;
    }
    if (copy_to_user(usraddr, p, size)) {
        kfree(p);
        return -EFAULT;
    }
    kfree(p);
    return 0;
}

// read rfd from driver allocated memory

static int at_priv_drv_rfd(struct at_adapter* adapter, at_drv_rfd* drvrfd, void* usraddr)
{
    struct at_rfd_ring* rfd_ring = &adapter->rfd_ring;
    uint16_t i, index = drvrfd->idx_start % rfd_ring->count;
    uint8_t* buffer;
    rx_free_desc_t* rfd;
    uint32_t size;
    at_drv_rfd* p;
    
    if (drvrfd->length > rfd_ring->count) {
        return -EINVAL;
    }
    size = drvrfd->length*sizeof(rx_free_desc_t) + sizeof(*drvrfd);
    p = kmalloc(size, GFP_KERNEL);
    if (!p) {
        return -ENOMEM;
    }
    buffer = (uint8_t*) p->data;
    memcpy(p, drvrfd, sizeof(*p));
    
    for (i=0; i<drvrfd->length; i++) {
        rfd = AT_RFD_DESC(rfd_ring, index); 
        memcpy(buffer+i*sizeof(rx_free_desc_t), rfd, sizeof(rx_free_desc_t));
        index++;
        index = index % rfd_ring->count;
    }
    if (copy_to_user(usraddr, p, size)) {
        kfree(p);
        return -EFAULT;
    }
    kfree(p);
    return 0;
}

// read rrd from driver allocated memory

static int at_priv_drv_rrd(struct at_adapter* adapter, at_drv_rrd* drvrrd, void* usraddr)
{
    struct at_rrd_ring* rrd_ring = &adapter->rrd_ring;
    uint16_t i, index = drvrrd->idx_start % rrd_ring->count;
    uint8_t* buffer;
    rx_return_desc_t* rrd;
    uint32_t size;
    at_drv_rrd* p;
    
    if (drvrrd->length > rrd_ring->count) {
        return -EINVAL;
    }
    
    size = drvrrd->length * sizeof(rx_return_desc_t) + sizeof(*drvrrd);
    p = kmalloc(size, GFP_KERNEL);
    if (!p) {
        return -ENOMEM;
    }
    buffer = (uint8_t*) p->data;
    memcpy(p, drvrrd, sizeof(*p));
    
    for (i=0; i<drvrrd->length; i++) {
        rrd = AT_RRD_DESC(rrd_ring, index);
        memcpy(buffer+i*sizeof(rx_return_desc_t), rrd, sizeof(rx_return_desc_t));
        index++;
        index = index % rrd_ring->count;
    }
    if (copy_to_user(usraddr, p, size)) {
        kfree(p);
        return -EFAULT;
    }
    kfree(p);
    return 0;
}

static int
at_priv_dump_regs(struct at_adapter* adapter, at_dump_regs* regs, void* usraddr)
{
    at_dump_regs* new_regs;
    uint32_t i;
    
    
    new_regs = kmalloc(sizeof(*regs)+regs->length*4, GFP_KERNEL);
    if (!new_regs) {
        return -ENOMEM;
    }
    new_regs->length = regs->length;
    new_regs->start = regs->start;
    new_regs->cmd = LNX_CMD_DUMP_REGS;
    
    for (i =0; i < regs->length; i++) {
        ((uint32_t*)new_regs->data)[i] = 
            AT_READ_REG(&adapter->hw, (4*i+regs->start));
    }
    
    if (copy_to_user(usraddr, new_regs, sizeof(*new_regs)+regs->length*4)) {
        kfree(new_regs);
        return -EFAULT;
    }
    kfree(new_regs);
    return 0;
}

static int
at_priv_dump_dregs(struct at_adapter* adapter, at_dump_dregs* regs, void* usraddr)
{
    at_dump_dregs* new_regs;
    uint32_t i;
    
    
    new_regs = kmalloc(sizeof(*regs)+regs->length*4, GFP_KERNEL);
    if (!new_regs) {
        return -ENOMEM;
    }
    new_regs->length = regs->length;
    new_regs->start = regs->start;
    new_regs->cmd = LNX_CMD_DUMP_DREGS;
    
    for (i =0; i < regs->length; i++) {
        AT_WRITE_REG(&adapter->hw, 0x1900, i+regs->start);
        ((uint32_t*)new_regs->data)[i] = 
            AT_READ_REG(&adapter->hw, 0x1904);
    }
    
    if (copy_to_user(usraddr, new_regs, sizeof(*new_regs)+regs->length*4)) {
        kfree(new_regs);
        return -EFAULT;
    }
    kfree(new_regs);
    return 0;
}

int 
at_priv_ioctl(struct net_device* netdev, struct ifreq * ifr)
{
    struct  at_adapter *adapter = netdev->priv;
    void *      addr = ifr->ifr_data;
    uint16_t    cmd;
	
    if(get_user(cmd, (uint16_t *) addr))
	return -EFAULT;
	
    switch (cmd) {
    case LNX_CMD_RBS: 
    {
        at_rbs rbs;
	if(copy_from_user(&rbs, addr, sizeof(rbs))) 
	    return -EFAULT;
	return at_priv_rbs(adapter, &rbs);
    }
    case LNX_CMD_RBC:
    {
        at_rbc rbc;
        if(copy_from_user(&rbc, addr, sizeof(rbc)))
            return  -EFAULT;
        return at_priv_rbc(adapter, &rbc);
    }
    case LNX_CMD_TBC:
    {
        at_tbc tbc;
        if(copy_from_user(&tbc, addr, sizeof(tbc)))
            return -EFAULT;
        return at_priv_tbc(adapter, &tbc);
    }
    case LNX_CMD_DRV_TPD:
    {
        at_drv_tpd tpd;
        if (copy_from_user(&tpd, addr, sizeof(tpd)))
            return -EFAULT;
	return at_priv_drv_tpd(adapter, &tpd, addr);
    }
    case LNX_CMD_DRV_RFD:
    {
        at_drv_rfd rfd;
        if(copy_from_user(&rfd, addr, sizeof(rfd)))
            return -EFAULT;
        return at_priv_drv_rfd(adapter, &rfd, addr);
    }
    case LNX_CMD_DRV_RRD:
    {
        at_drv_rrd rrd;
        if(copy_from_user(&rrd, addr, sizeof(rrd)))
            return -EFAULT;
        return at_priv_drv_rrd(adapter, &rrd, addr);
    }
    case LNX_CMD_SRAM_TPD:
    {
        at_sram_tpd tpd;
        if(copy_from_user(&tpd, addr, sizeof(tpd)))
            return -EFAULT;
        return at_priv_sram_tpd(adapter, &tpd, addr);
    }
    case LNX_CMD_SRAM_RFD:
    {
        at_sram_rfd rfd;
        if(copy_from_user(&rfd, addr, sizeof(rfd)))
            return -EFAULT;
        return at_priv_sram_rfd(adapter, &rfd, addr);
    }
    case LNX_CMD_SRAM_RRD:
    {
        at_sram_rrd rrd;
        if(copy_from_user(&rrd, addr, sizeof(rrd)))
            return -EFAULT;
        return at_priv_sram_rrd(adapter, &rrd, addr);
    }
    case LNX_CMD_SRAM_TRD:
    {
        at_sram_trd trd;
        if(copy_from_user(&trd, addr, sizeof(trd)))
            return -EFAULT;
        return at_priv_sram_trd(adapter, &trd, addr);
    }
    case LNX_CMD_SRAM_TXF:
    {
        at_sram_txf txf;
        if (copy_from_user(&txf, addr, sizeof(txf)))
            return -EFAULT;
        if (txf.length == 0) {
	    txf.length = (uint16_t)AT_READ_REG(&adapter->hw, REG_SRAM_TXF_LEN);
            txf.length *= 2; // DWORDs
	    if (copy_to_user(addr, &txf, sizeof(txf))) {
	        return -EFAULT;
	    }
	    return 0;
	}
	return at_priv_sram_txf(adapter, &txf, addr);
    }
    case LNX_CMD_SRAM_RXF:
    {
        at_sram_rxf rxf;
	if (copy_from_user(&rxf, addr, sizeof(rxf)))
	    return -EFAULT;
        if (rxf.length == 0) {
            rxf.length = (uint16_t)AT_READ_REG(&adapter->hw, REG_SRAM_RXF_LEN);
            rxf.length *= 2; // DWORDs
            if (copy_to_user(addr, &rxf, sizeof(rxf))) {
                return -EFAULT;
            }
            return 0;
        }
        return at_priv_sram_rxf(adapter, &rxf, addr);
    }
    case LNX_CMD_DRV_SMB:
    {
        at_drv_smb drvsmb;
        if (copy_from_user(&drvsmb, addr, sizeof(drvsmb)))
            return -EFAULT;  
        return at_priv_drv_smb(adapter, &drvsmb, addr);
    }
    case LNX_CMD_DRV_CMB:
    {
        at_drv_cmb cmb;
        if(copy_from_user(&cmb, addr, sizeof(cmb)))
            return -EFAULT;
	        
        cmb.data[0] = adapter->cmb.cmb->int_stats;
        cmb.data[1] = adapter->cmb.cmb->rrd_prod_idx;
        cmb.data[2] = adapter->cmb.cmb->rfd_cons_idx;
        cmb.data[3] = adapter->cmb.cmb->tpd_cons_idx;
        if (copy_to_user(addr, &cmb, sizeof(cmb)))
            return -EFAULT;
        return 0;
    }
    case LNX_CMD_NIC_CMB:
    {
        at_sram_cmb cmb;
	if(copy_from_user(&cmb, addr, sizeof(cmb)))
	    return -EFAULT;
	cmb.data[0] = AT_READ_REG(&adapter->hw, REG_RFD_RRD_IDX);
	cmb.data[1] = AT_READ_REG(&adapter->hw, REG_TPD_IDX);
	if(copy_to_user(addr, &cmb, sizeof(cmb)))
	    return -EFAULT;
	return 0;
    }
    case LNX_CMD_DUMP_REGS:
    {
	at_dump_regs regs;
	if(copy_from_user(&regs, addr, sizeof(regs)))
	    return -EFAULT;
	return at_priv_dump_regs(adapter, &regs, addr);
    }
    case LNX_CMD_WRITE_REG:
    {
        at_write_reg wreg;
        uint32_t    data;
        if (copy_from_user(&wreg, addr, sizeof(wreg))) {
            return -EFAULT;
        }
        if (0xffffffff != wreg.mask) {
            data = AT_READ_REG(&adapter->hw, wreg.reg);
            data = (wreg.data&wreg.mask) | (data&~wreg.mask);
        } else {
            data = wreg.data;
        }
        AT_WRITE_REG(&adapter->hw, wreg.reg, data);
        return 0;
    }
    //////////////////////////////////// added at 05-06-25
    case LNX_CMD_READ_BYTE:
    {
    	at_read_breg breg;
    	if(copy_from_user(&breg, addr, sizeof(breg)))
    		return -EFAULT;
    	breg.data = AT_READ_REGB(&adapter->hw, breg.reg);
    	if (copy_to_user(addr, &breg, sizeof(breg)))
    		return -EFAULT;
    	return 0;    	
    }
    case LNX_CMD_WRITE_BYTE:
    {
    	at_write_breg wbreg;
    	
    	if (copy_from_user(&wbreg, addr, sizeof(wbreg))) {
    		return -EFAULT;
    	}
    	AT_WRITE_REGB(&adapter->hw, wbreg.reg, wbreg.data);
    	return 0;
    }
    case LNX_CMD_READ_PHY:
    {
    	at_read_preg preg;
    	if(copy_from_user(&preg, addr, sizeof(preg)))
    		return -EFAULT;
    		
    	if (at_read_phy_reg(&adapter->hw,
            				preg.reg,
            				&preg.data))
            return -EFAULT;
    	if (copy_to_user(addr, &preg, sizeof(preg)))
    		return -EFAULT;
    	return 0;    	
    }
    case LNX_CMD_WRITE_PHY:
    {
    	at_write_preg preg;
    	
    	if (copy_from_user(&preg, addr, sizeof(preg))) {
    		return -EFAULT;
    	}
    	if (at_write_phy_reg(&adapter->hw,
							 preg.reg,
        					 preg.data))
        	return -EFAULT;
    	return 0;
    }   
    ///////////////////////////////////

    case LNX_CMD_DUMP_DREGS:
    {
        at_dump_dregs regs;
        if(copy_from_user(&regs, addr, sizeof(regs)))
            return -EFAULT;
        return at_priv_dump_dregs(adapter, &regs, addr);
    }
    case LNX_CMD_READ_CFG_REG:
    {
        at_read_cfg_reg reg;
        if(copy_from_user(&reg, addr, sizeof(reg)))
            return -EFAULT;
          
        pci_read_config_dword(
  			adapter->pdev,
			reg.reg,
			&reg.data);
        if(copy_to_user(addr, &reg, sizeof(reg)))
            return -EFAULT;
        return 0;
    }
    case LNX_CMD_WRITE_CFG_REG:
    {
        at_write_cfg_reg reg;
        uint32_t data;
        if(copy_from_user(&reg, addr, sizeof(reg)))
            return  -EFAULT;
        if (reg.mask == 0xffffffff) {
            data = reg.data;
        } else {
            pci_read_config_dword(
                adapter->pdev,
                reg.reg,
                &data);
            data = (data&~reg.mask) | (reg.data&reg.mask);
        }
	pci_write_config_dword(
	       adapter->pdev,
	       reg.reg,
	       data);
	return 0;
    }
    default:
        return -EFAULT;
    }
}

#endif//SIOCDEVPRIVATE

⌨️ 快捷键说明

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