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

📄 nifce_driver.c

📁 lwip tcp/ip 协议栈 adsp BF533 DSP 移植 用 visual dsp++ 编译
💻 C
📖 第 1 页 / 共 2 页
字号:
  }

  // No need of data maipulation as we are directly getting from pbufs.
  if (Trace_Function) Trace_Function('T',p->tot_len,((unsigned char *)p->payload)+2);

  // see whether we've got a free transmit buffer
  old_level = sys_arch_protect();

  tx = (ADI_ETHER_BUFFER*)nip->x;
  if (tx == NULL)
  {
#ifdef LINK_STATS
    lwip_stats.link.memerr++;
#endif

    sys_arch_unprotect(old_level);
    return ERR_MEM;
  }

  // remove first free one from the list
  nip->x = tx->pNext;
  tx->pNext = NULL;

  // copy data from pbuf(s) into our buffer
  q = p;
  //data = (char*)tx->Data;
  
  //
  // first two bytes reserved for length
  data = (char*)tx->Data+2;

  // ... first pbuf: skip field unused1 in struct eth_hdr
  memcpy(data, ((u8_t*)q->payload) + 2, q->len - 2);
  data += (q->len - 2);
  len = q->len - 2;
  q = q->next;
  // copy any subsequent pbufs
  while (q) {
    memcpy(data, q->payload, q->len);
    data += q->len;
    len += q->len;
    q = q->next;
  }
  LWIP_ASSERT("low_level_output: data length correct", len == (p->tot_len - 2));
  //tx->ElementCount = p->tot_len - 2;
  tx->ElementCount = p->tot_len; // total element count including 2 byte header

 

  // see whether we need to shuffle etharp frame up to account for
  // the alignment fields unused2 and unused3
  //ethhdr  = (struct hw_eth_hdr*)tx->Data;
  //
  ethhdr  = (struct hw_eth_hdr*)((char*)tx->Data+2);//skip the header
  if (htons(ethhdr->type) == ETHTYPE_ARP)
  {
    u8_t* pdst = (u8_t*)tx->Data + 28 +2;
    u8_t* psrc = pdst + 2;  // skip unused2 field

    memmove(pdst, psrc, 10);
    pdst += 10;
    psrc += 12;             // skip unused3 field
    memmove(pdst, psrc, 4);

    //tx->num_elements -= 4;
    tx->ElementCount -= 4;
  }

   ps = (unsigned short*)tx->Data;
  *ps = tx->ElementCount-2; // only the frame size excluding 2 byte header
  tx->PayLoad =  0; // payload is part of the packet
  tx->StatusWord = 0; // changes from 0 to the status info 
  // give it to the physical driver
  adi_dev_Write(nip->handle,ADI_DEV_1D,(ADI_DEV_BUFFER*)tx);

#ifdef LINK_STATS
  lwip_stats.link.xmit++;
#endif

  sys_arch_unprotect(old_level);

  return ERR_OK;
}

/*##########################################################################
*
* Called by the TCP/IP stack when an IP packet should be sent.
* It calls the function called low_level_output() to actually transmit the
* packet.
*#########################################################################*/
static err_t
nifce_driver_output(struct netif* netif, struct pbuf* p, struct ip_addr* ipaddr)
{
  p = etharp_output(netif, ipaddr, p);
  if (p != NULL)
    low_level_output(netif, p);
  return ERR_OK;
}

/*##########################################################################
*
* Sends an incoming Ethernet frame up the stack to a function that will
* understand it (or just drops the frame).
*
*#########################################################################*/
static void
eth_input(struct pbuf* p, struct netif* netif)
{
  // Ethernet protocol layer
  struct eth_hdr* ethhdr;
  struct pbuf* q = NULL;

  ethhdr = p->payload;

  switch (htons(ethhdr->type))
  {
      case ETHTYPE_IP:
      //q = etharp_ip_input(netif, p);
      pbuf_header(p, -(s16_t)sizeof(struct eth_hdr));
      netif->input(p, netif);
      break;
      case ETHTYPE_ARP:
      q = etharp_arp_input(netif, (struct eth_addr*)&(netif->hwaddr[0]), p);
      break;
      default:
      pbuf_free(p);
      break;
  }

  if (q != NULL)
  {
    low_level_output(netif, q);
    pbuf_free(q);
  }
}

/*##########################################################################
 *
 * low_level_init
 *
 *#########################################################################*/
static void
low_level_init(struct netif *netif)
{
  ADI_ETHER_BUFFER* p;
  struct nifce_info* nip = (struct nifce_info*)netif->state;
  struct buffer_info* bip;
  int rx_len, tx_len, count;
  int i;
  ADI_ETHER_BUFFER* rx_head = NULL;
  ADI_ETHER_BUFFER* tx_head = NULL;
  unsigned int *mangle_ptr;

  LWIP_ASSERT("low_level_init: nfice info supply failed", nip != NULL);
  LWIP_ASSERT("low_level_init: buffer area supply failed",
              nip->buff_area != NULL && nip->buff_area_size > 0);

  // copy individual (MAC) address into netif struct
  for (i = 0; i < 6; i += 1)
    netif->hwaddr[i] = nip->ia[i];
  netif->hwaddr_len = 6;

  // calculate total requirement for each rx and tx buffer
  rx_len =  sizeof(ADI_ETHER_BUFFER) + sizeof(struct buffer_info);
  tx_len = rx_len;
  rx_len += nip->rx_buff_datalen + nip->buff_overhead;
  tx_len += nip->tx_buff_datalen + nip->buff_overhead;
  rx_len = ((rx_len + 3) / 4) * 4;
  tx_len = ((tx_len + 3) / 4) * 4;

  // allocate buffers in required ratio from supplied memory area
  while (nip->buff_area_size > rx_len || nip->buff_area_size > tx_len)
  {
    int n;
    for (n = 0; n < nip->rx_buffs; n += 1) {
      if (nip->buff_area_size < rx_len)
        break;
      p = (ADI_ETHER_BUFFER*)nip->buff_area;
      nip->buff_area += rx_len;
      nip->buff_area_size -= rx_len;
      p->pNext = rx_head;
      rx_head = p;
    }
    for (n = 0; n < nip->tx_buffs; n += 1) {
      if (nip->buff_area_size < tx_len)
        break;
      p = (ADI_ETHER_BUFFER*)nip->buff_area;
      nip->buff_area += tx_len;
      nip->buff_area_size -= tx_len;
      p->pNext = tx_head;
      tx_head = p;
    }
  }

  // initialise each buffer's ADI_ETHER_BUFFER descriptor
  p = rx_head;
  count = 0;
  while (p)
  {
    p->Data = (char*)p + sizeof(ADI_ETHER_BUFFER) + nip->buff_overhead;
    p->ElementCount = nip->rx_buff_datalen;
    p->ElementWidth = 1;
    p->CallbackParameter =p;
	p->ProcessedElementCount=0;
	p->ProcessedFlag =0;

	mangle_ptr = ((unsigned int*)&p->Reserved)+4;
	*((unsigned int*)mangle_ptr)= (unsigned int)((char*)p->Data + p->ElementCount);
    bip = (struct buffer_info*)(*(unsigned int*)mangle_ptr);
    bip->netif = netif;
    bip->max_buf_len = nip->rx_buff_datalen;
//    memset(p->data_start, 0x80 + netif->num, p->num_elements);
    memset(p->Data, 0x80 + netif->num, p->ElementCount);
    count += 1;
    p = p->pNext;
  }
  nip->rx_buffs = count;
  p = tx_head;
  count = 0;
  while (p)
  {
    p->Data = (char*)p + sizeof(ADI_ETHER_BUFFER) + nip->buff_overhead;
    p->ElementCount = nip->tx_buff_datalen;
    p->ElementWidth = 1;
    p->CallbackParameter =p;

	mangle_ptr = ((unsigned int*)&p->Reserved)+4;
	*((unsigned int*)mangle_ptr)= (unsigned int)((char*)p->Data + p->ElementCount);

    bip = (struct buffer_info*)(*(unsigned int*)mangle_ptr);
	
    bip->netif = netif;
    bip->max_buf_len = nip->tx_buff_datalen;
    //memset(p->data_start, 0x90 + netif->num, p->num_elements);
    memset(p->Data, 0x90 + netif->num, p->ElementCount);
    count += 1;
    p = p->pNext;
  }
  nip->tx_buffs = count;

  // give all the rx buffers to the IDataPort instance
	adi_dev_Read(nip->handle,ADI_DEV_1D,(ADI_DEV_BUFFER*)rx_head);

  // save the list of tx buffers until they are needed
  nip->x = tx_head;
}

/*##########################################################################
*
* nifce_driver_init(struct netif *netif):
*
* Should be called at the beginning of the program to set up a
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware. It expects the 'status' member of netif
* to be holding a pointer to a nifce_info struct.
*
*#########################################################################*/
err_t
nifce_driver_init(struct netif *netif)
{
  sys_sem_t sem;

  // set up base part of this interface's name
  netif->name[0] = IFNAME0;
  netif->name[1] = IFNAME1;
  // install function that TCP should call to output packets
  netif->output = nifce_driver_output;
  // install function that actually queues output for transmission
  netif->linkoutput = low_level_output;
  // set up this interface's maximum transfer unit and address length
  netif->mtu = MTU - 18;      // MTU without ethernet header and crc

  // carry out lowest level initialisation and enable the interface
  low_level_init(netif);

  return ERR_OK;
}

⌨️ 快捷键说明

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