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

📄 at_test.c

📁 Linux* Base Driver for the Attansic(R) L1 Gigabit Ethernet Adapter
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "at.h"
#ifdef SIOCDEVPRIVATE
#include "drv_ioctl.h"
#include <asm/uaccess.h>
extern int32_t at_up(struct at_adapter* adapter);
extern void at_down(struct at_adapter* adapter);
extern void at_reset(struct at_adapter* adapter);
extern int32_t at_setup_ring_resources(struct at_adapter* adapter);
extern void at_free_ring_resources(struct at_adapter* adapter);


// set rfd buffer size. do not support !

int at_priv_rbs(struct at_adapter* adapter, at_rbs* rbs)
{
   	int err;
        if (rbs->size == adapter->rx_buffer_len) 
            return 0;

	if(netif_running(adapter->netdev)){
		at_down(adapter);
                adapter->rx_buffer_len = rbs->size;
                if ((err = at_up(adapter)))
                    return err;
        }
        adapter->rx_buffer_len = rbs->size;
        return 0;
}

// set rfd(rrd) ring size
int at_priv_tbc(struct at_adapter* adapter, at_tbc* tbc)
{
   	int err;
	struct at_tpd_ring *tpdr = &adapter->tpd_ring;
	struct at_rrd_ring *rrdr = &adapter->rrd_ring;
	struct at_rfd_ring *rfdr = &adapter->rfd_ring;
	
	struct at_tpd_ring tpd_old, tpd_new;
	struct at_rfd_ring rfd_old, rfd_new;
	struct at_rrd_ring rrd_old , rrd_new;


	tpd_old = adapter->tpd_ring;
	rfd_old = adapter->rfd_ring;
	rrd_old = adapter->rrd_ring;
	
	if(netif_running(adapter->netdev))
		at_down(adapter);

	rfdr->count = rfd_old.count;
	rrdr->count = rrd_old.count;
	tpdr->count = tbc->size;

	if(netif_running(adapter->netdev)) {
	    /* try to get new resources before deleting old */
	    if ((err = at_setup_ring_resources(adapter)))
	        goto err_tbc;	
	
		
		/* save the new, restore the old in order to free it,
		 * then restore the new back again */	
	
		rfd_new = adapter->rfd_ring;
		rrd_new = adapter->rrd_ring;
		tpd_new = adapter->tpd_ring;
		adapter->rfd_ring = rfd_old;
		adapter->rrd_ring = rrd_old;
		adapter->tpd_ring = tpd_old;
		at_free_ring_resources(adapter);
        adapter->rfd_ring = rfd_new;
		adapter->rrd_ring = rrd_new;
		adapter->tpd_ring = tpd_new;

		if((err = at_up(adapter)))
			return err;
	}
	return 0;

err_tbc:
	adapter->rfd_ring = rfd_old;
	adapter->rrd_ring = rrd_old;
	adapter->tpd_ring = tpd_old;
	at_up(adapter);
	return err;
}

// set rfd(rrd)  ring size
int at_priv_rbc(struct at_adapter* adapter, at_rbc* rbc)
{
   	int err;
	struct at_tpd_ring *tpdr = &adapter->tpd_ring;
	struct at_rrd_ring *rrdr = &adapter->rrd_ring;
	struct at_rfd_ring *rfdr = &adapter->rfd_ring;
	
	struct at_tpd_ring tpd_old, tpd_new;
	struct at_rfd_ring rfd_old, rfd_new;
	struct at_rrd_ring rrd_old , rrd_new;
	tpd_old = adapter->tpd_ring;
	rfd_old = adapter->rfd_ring;
	rrd_old = adapter->rrd_ring;
	
	if(netif_running(adapter->netdev))
		at_down(adapter);

	rfdr->count = rbc->size;
	rrdr->count = rfdr->count;
	tpdr->count = tpd_old.count;

	if(netif_running(adapter->netdev)) {
		/* try to get new resources before deleting old */
	    if ((err = at_setup_ring_resources(adapter)))
	        goto err_rbc;	
	
		
		/* save the new, restore the old in order to free it,
		 * then restore the new back again */	
	
		rfd_new = adapter->rfd_ring;
		rrd_new = adapter->rrd_ring;
		tpd_new = adapter->tpd_ring;
		adapter->rfd_ring = rfd_old;
		adapter->rrd_ring = rrd_old;
		adapter->tpd_ring = tpd_old;
		at_free_ring_resources(adapter);
        adapter->rfd_ring = rfd_new;
		adapter->rrd_ring = rrd_new;
		adapter->tpd_ring = tpd_new;

		if((err = at_up(adapter)))
			return err;
	}
	return 0;

err_rbc:
	adapter->rfd_ring = rfd_old;
	adapter->rrd_ring = rrd_old;
	adapter->tpd_ring = tpd_old;
	at_up(adapter);
	return err;
}

static int 
at_priv_sram_tpd(struct at_adapter* adapter, at_sram_tpd* drvtpd, void* usraddr)
{
    uint32_t    src, header, len;
    uint32_t    i,size;
    uint32_t*   buffer;
    at_sram_tpd* p;
    
    header = AT_READ_REG(&adapter->hw, REG_SRAM_TPD_ADDR);
    if (header == 0xffffffff) {
        return -EFAULT;
    }
    header &= 0xffff;
    len = AT_READ_REG(&adapter->hw, REG_SRAM_TPD_LEN);
    len = (len*8) / sizeof(tx_packet_desc_t); // number of TPD
    
    if ((drvtpd->idx_start > len)||
        (drvtpd->length > len)) {
        return -EINVAL;
    }
    size = drvtpd->length*sizeof(tx_packet_desc_t) + sizeof(*drvtpd);
    
    p = kmalloc(size, GFP_KERNEL);
    if (!p) {
        return -ENOMEM;
    }
    buffer = (uint32_t*) p->data;
    memcpy(p, drvtpd, sizeof(*p));
    
    src = 0x8000 + (header*8 + drvtpd->idx_start*sizeof(tx_packet_desc_t));
    
    for (i = 0; i < (drvtpd->length*sizeof(tx_packet_desc_t))/4; i++) {
        *(buffer+i) = AT_READ_REG(&adapter->hw, src);
        src += 4;
    }
    if (copy_to_user(usraddr, p, size))
    {
        kfree(p);
        return -EFAULT;
    }
    kfree(p);
    return 0;    
}


static int 
at_priv_sram_rfd(struct at_adapter* adapter, at_sram_rfd* drvrfd, void* usraddr)
{
    uint32_t    src, header, len;
    uint32_t    i,size;
    uint32_t*   buffer;
    at_sram_rfd* p;
    
    header = AT_READ_REG(&adapter->hw, REG_SRAM_RFD_ADDR);
    if (header == 0xffffffff) {
        return -EFAULT;
    }
    header &= 0xffff;
    len = AT_READ_REG(&adapter->hw, REG_SRAM_RFD_LEN);
    len = (len*8) / sizeof(rx_free_desc_t); // number of RFD
    
    if ((drvrfd->idx_start > len)||
        (drvrfd->length > len)) {
        return -EFAULT;
    }
    size = drvrfd->length*sizeof(rx_free_desc_t) + sizeof(*drvrfd);
    p = kmalloc(size, GFP_KERNEL);
    if (!p) {
        return -ENOMEM;
    }
    buffer = (uint32_t*) p->data;
    memcpy(p, drvrfd, sizeof(*p));
    
    src = 0x8000 + (header*8 + drvrfd->idx_start*sizeof(rx_free_desc_t));
    
    for (i = 0; i < (drvrfd->length*sizeof(rx_free_desc_t))/4; i++) {
        *(buffer+i) = AT_READ_REG(&adapter->hw, src);
        src += 4;
    }
    if (copy_to_user(usraddr, p, size))
    {
        kfree(p);
        return -EFAULT;
    }
    kfree(p);
    return 0;    
}

static int 
at_priv_sram_rrd(struct at_adapter* adapter, at_sram_rrd* drvrrd, void* usraddr)
{
    uint32_t    src, header, len;
    uint32_t    i;
    uint32_t*   buffer;
    uint32_t    size;
    at_sram_rrd* p;
    
    header = AT_READ_REG(&adapter->hw, REG_SRAM_RRD_ADDR);
    if (header == 0xffffffff) {
        return -EFAULT;
    }
    header &= 0xffff;
    len = AT_READ_REG(&adapter->hw, REG_SRAM_RRD_LEN);
    len = (len*8) / sizeof(rx_return_desc_t); // number of TPD
    
    if ((drvrrd->idx_start > len)||
        (drvrrd->length > len)) {
        return -EINVAL;
    }
    size = drvrrd->length*sizeof(rx_return_desc_t)+sizeof(*drvrrd);
    p = kmalloc(size, GFP_KERNEL);
    if (!p) {
        return -ENOMEM;
    }
    buffer = (uint32_t*)p->data;
    memcpy(p, drvrrd,sizeof(*p));
    
    src = 0x8000 + (header*8 + drvrrd->idx_start*sizeof(rx_return_desc_t));
    
    for (i = 0; i < (drvrrd->length*sizeof(rx_return_desc_t))/4; i++) {
        *(buffer+i) = AT_READ_REG(&adapter->hw, src);
        src += 4;
    }
    if (copy_to_user(usraddr, p, size))
    {
        kfree(p);
        return -EFAULT;
    }
    kfree(p);
    return 0;    
}

static int 
at_priv_sram_trd(struct at_adapter* adapter, at_sram_trd* drvtrd, void* usraddr)
{
    uint32_t    src, header, len;
    uint32_t    i,size;
    uint32_t*   buffer;
    at_sram_trd* p;
    
    header = AT_READ_REG(&adapter->hw, REG_SRAM_TRD_ADDR);
    if (header == 0xffffffff) {
        return -EFAULT;
    }
    header &= 0xffff;
    len = AT_READ_REG(&adapter->hw, REG_SRAM_TRD_LEN);
    len = (len*8) / 8; // number of TRD
    
    if ((drvtrd->idx_start > len)||
        (drvtrd->length > len)) {
        return -EINVAL;
    }
    size = drvtrd->length*8 + sizeof(*drvtrd);
    p = kmalloc(size, GFP_KERNEL);
    if (!p) {
        return -ENOMEM;
    }
    buffer = (uint32_t*) p->data;
    memcpy(p, drvtrd, sizeof(*p));
    
    src = 0x8000 + (header*8 + drvtrd->idx_start*8);
    
    for (i = 0; i < (drvtrd->length*8)/4; i++) {
        *(buffer+i) = AT_READ_REG(&adapter->hw, src);
        src += 4;
    }
    if (copy_to_user(usraddr, p, size))
    {
        kfree(p);
        return -EFAULT;
    }
    kfree(p);
    return 0;    
}

static int 
at_priv_sram_txf(struct at_adapter* adapter, at_sram_txf* drvtxf, void* usraddr)
{
    uint32_t    src, header, len;
    uint32_t    i;
    uint32_t*   buffer;
    at_sram_txf*   p;

    header = AT_READ_REG(&adapter->hw, REG_SRAM_TXF_ADDR);
    if (header == 0xffffffff) {
        return -EFAULT;
    }
    header &= 0xffff;
    len = AT_READ_REG(&adapter->hw, REG_SRAM_TXF_LEN);
    len *= 2; // number of DWORDs
    
    if (drvtxf->length > len) {
        return -EINVAL;
    }
    
    p = kmalloc(sizeof(*drvtxf) + drvtxf->length*4, GFP_KERNEL);
    if (!p) {
        return -ENOMEM;
    }
    buffer = (uint32_t*)&(p->data);
    memcpy(p, drvtxf, sizeof(*p));

    src = 0x8000 + header*8;
    
    for (i = 0; i < drvtxf->length; i++) {
        *(buffer+i) = AT_READ_REG(&adapter->hw, src);
        src += 4;
    }
    if (copy_to_user(usraddr, p, sizeof(*drvtxf)+drvtxf->length*4))
    {
        kfree(p);
        return -EFAULT;
    }
    kfree(p);
    return 0;    
}

static int
at_priv_drv_smb(struct at_adapter* adapter, at_drv_smb* drvsmb, void* usraddr)
{
     at_drv_smb* newsmb;

     newsmb = kmalloc(sizeof(*drvsmb)+drvsmb->length, GFP_KERNEL);
     if (!newsmb)
     {
         return -ENOMEM;
     } 
     memcpy(newsmb, drvsmb, sizeof(*drvsmb));
     if (newsmb->length > 0)
     {
         int length = newsmb->length;
         if (length > sizeof(adapter->smb))
         {
              length = sizeof(adapter->smb);
         }
         memcpy(newsmb->data, &adapter->smb, length);
         if(copy_to_user(usraddr, newsmb, sizeof(*newsmb)+newsmb->length))
         {
             kfree(newsmb);
             return -EFAULT;
         }
      }
      kfree(newsmb);
      return 0;
}

static int 
at_priv_sram_rxf(struct at_adapter* adapter, at_sram_rxf* drvrxf, void* usraddr)
{
    uint32_t    src, header, len;
    uint32_t    i;
    uint32_t*   buffer;
    at_sram_rxf* p;
    
    header = AT_READ_REG(&adapter->hw, REG_SRAM_RXF_ADDR);
    if (header == 0xffffffff) {
        return -EFAULT;
    }
    header &= 0xffff;
    len = AT_READ_REG(&adapter->hw, REG_SRAM_RXF_LEN);
    len *= 2;// number of DWORDs
    
    if (drvrxf->length > len) {
        return -EINVAL;
    }
    
    p = kmalloc(sizeof(*drvrxf)+drvrxf->length*4, GFP_KERNEL);
    if (!p) {
        return -ENOMEM;
    }
    memcpy(p, drvrxf, sizeof(*p));
    buffer = (uint32_t*)(p->data);
    
    src = 0x8000 + header*8;
    
    for (i = 0; i < drvrxf->length; i++) {
        *(buffer+i) = AT_READ_REG(&adapter->hw, src);
        src += 4;
    }
    if (copy_to_user(usraddr, p, sizeof(*p)+drvrxf->length*4))
    {
        kfree(p);
        return -EFAULT;
    }
    kfree(p);
    return 0;    
}


// read tpd from driver allocated memory

⌨️ 快捷键说明

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