コード例 #1
0
ファイル: nicdrv.c プロジェクト: strongly-typed/SOEM
/** Basic setup to connect NIC to socket.
 * @param[in] ifname      = Name of NIC device, f.e. "eth0"
 * @param[in] secondary   = if >0 then use secondary stack instead of primary
 * @return >0 if succeeded
 */
int ecx_setupnic(ecx_portt *port, const char *ifname, int secondary) 
{
   HPESTATUS status;
   HPEMEDIASTATUS mstat;
   time_t now, t;
   unsigned char mac[6];
   int i;
   int dontWaitForLink = 0;
   int result = 1;
   HPE_CONFIG_OPTIONS conf = { 0, 0, NULL};

   status = hpeOpen(ifname, phy_settings, interrupt_mode, &(port->handle));
   if (status != E_OK) 
   {
      ECAT_PRINT_ERROR("hpeOpen failed with status %04x ", status);
	  if(status == E_EXIST) ECAT_PRINT_ERROR("E_EXIST\n"); 
	  else if(status == E_STATE) ECAT_PRINT_ERROR("E_STATE\n");
      else if(status == E_PARAM) ECAT_PRINT_ERROR("E_PARAM\n");
	  else if(status == E_INVALID_ADDR) ECAT_PRINT_ERROR("E_INVALID_ADDR\n");
	  else if(status == E_IO) ECAT_PRINT_ERROR("E_IO\n");
	  else if(status == E_TIME) ECAT_PRINT_ERROR("E_TIME\n");
	  else ECAT_PRINT_ERROR("UNKNOWN\n");
      result = 0;
      goto end;
   }
   
   conf.option_flags |= OPT_PROMISC;

   status = hpeConfigOptions(port->handle, &conf, sizeof(conf));
   if (status != E_OK) 
   {
      ECAT_PRINT_ERROR("hpeConfigOptions failed with status %04x\n", status);
      // NOTE: HPE driver for Intel 10/100 Mbps device currently doesn't support multicast.
      result = 0;
      goto end;
   }
   
   time(&now);
   do 
   {
	   status = hpeGetMediaStatus(port->handle, &mstat);
       if (status != E_OK) 
       {
           ECAT_PRINT_ERROR("hpeGetMediaStatus failed with status %04x\n", status);
           result = 0;
           goto end;
       }
       if (mstat.media_speed == SPEED_NONE) 
       {
           RtSleepEx(1000);
           time(&t);
       }
   } while (mstat.media_speed == SPEED_NONE && t < (now+10));

   if (((mstat.media_speed & phy_settings) == 0) || ((mstat.media_duplex & phy_settings) == 0)) {
      ECAT_PRINT_ERROR("Media not connected as requested: speed=%u, duplex=%u\n", 
              mstat.media_speed, mstat.media_duplex);
      result = 0;
      goto end;
   }

   status= hpeGetMacAddress(port->handle, mac);
   if (status != E_OK) 
   {
      ECAT_PRINT_ERROR("hpeGetMacAddress failed with status %04x\n", status);
      result = 0;
      goto end;
   }

   /* allocate 2 receive buffers and attach them */
   status  = hpeAllocateReceiveBufferSet(port->handle, &(port->rx_buffers), EC_MAXBUF, EC_BUFSIZE);
   if (status != E_OK) 
   {
      ECAT_PRINT_ERROR("hpeAllocateReceiveBufferSet failed with status %04x\n", status);
      result = 0;
      goto end;
   }

   status = hpeAttachReceiveBufferSet(port->handle, port->rx_buffers);
   if (status != E_OK) 
   {
      ECAT_PRINT_ERROR("hpeAttachReceiveBufferSet failed with status %04x\n", status);
      result = 0;
      goto end;
   }

   if (secondary)
   {
      /* secondary port struct available? */
      if (port->redport)
      {
         /* when using secondary socket it is automatically a redundant setup */
         port->redstate = ECT_RED_DOUBLE;
      }
   }
   else
   {
      port->redstate = ECT_RED_NONE;
      /* Init regions */
      port->getindex_region = CreateRtRegion (PRIORITY_QUEUING);
      port->rx_region = CreateRtRegion (PRIORITY_QUEUING);
      port->tx_region = CreateRtRegion (PRIORITY_QUEUING);
      port->lastidx = 0;
      port->stack.txbuf       = &(port->txbuf);
      port->stack.txbuflength = &(port->txbuflength);
      port->stack.tempbuf     = &(port->tempinbuf);
      port->stack.rxbuf       = &(port->rxbuf);
      port->stack.rxbufstat   = &(port->rxbufstat);
      port->stack.rxsa        = &(port->rxsa);
   }  
   
   /* setup ethernet headers in tx buffers so we don't have to repeat it */
   for (i = 0; i < EC_MAXBUF; i++)
   {
      ec_setupheader(&(port->txbuf[i]));
      port->rxbufstat[i] = EC_BUF_EMPTY;
      // allocate 1 transmit buffer of two fragments and 500 bytes and attach it
      port->tx_buffers[i] = (HPETXBUFFERSET *)AllocateRtMemory(sizeof(HPETXBUFFER) + sizeof(HPETXBUFFERSET));
      port->tx_buffers[i]->buffer_count = 1;
      port->tx_buffers[i]->buffers[0].fragment_count = 1;
      // first fragment is the fixed header, second is dynamic data
      port->tx_buffers[i]->buffers[0].fragments[0].ptr = port->txbuf[i];
      port->tx_buffers[i]->buffers[0].fragments[0].size = EC_BUFSIZE;
      port->tx_buffers[i]->buffers[0].fragments[0].paddr = 0;
   }
   ec_setupheader(&(port->txbuf2));

end:
   return result;
}
コード例 #2
0
ファイル: nicdrv.c プロジェクト: LoyVanBeek/SOEM
/** Basic setup to connect NIC to socket.
 * @param[in] port        = port context struct
 * @param[in] ifname      = Name of NIC device, f.e. "eth0"
 * @param[in] secondary   = if >0 then use secondary stack instead of primary
 * @return >0 if succeeded
 */
int ecx_setupnic(ecx_portt *port, const char *ifname, int secondary)
{
   int i;
   int rVal;
   int *psock;

   port->getindex_mutex = mtx_create();
   port->tx_mutex = mtx_create();
   port->rx_mutex = mtx_create();

   rVal = bfin_EMAC_init((uint8_t *)priMAC);
   if (rVal != 0)
      return 0;

   if (secondary)
   {
      /* secondary port struct available? */
      if (port->redport)
      {
         /* when using secondary socket it is automatically a redundant setup */
         psock = &(port->redport->sockhandle);
         *psock = -1;
         port->redstate                   = ECT_RED_DOUBLE;
         port->redport->stack.sock        = &(port->redport->sockhandle);
         port->redport->stack.txbuf       = &(port->txbuf);
         port->redport->stack.txbuflength = &(port->txbuflength);
         port->redport->stack.tempbuf     = &(port->redport->tempinbuf);
         port->redport->stack.rxbuf       = &(port->redport->rxbuf);
         port->redport->stack.rxbufstat   = &(port->redport->rxbufstat);
         port->redport->stack.rxsa        = &(port->redport->rxsa);
         ecx_clear_rxbufstat(&(port->redport->rxbufstat[0]));
      }
      else
      {
         /* fail */
         return 0;
      }
   }
   else
   {
      port->getindex_mutex = mtx_create();
      port->tx_mutex = mtx_create();
      port->rx_mutex = mtx_create();
      port->sockhandle        = -1;
      port->lastidx           = 0;
      port->redstate          = ECT_RED_NONE;
      port->stack.sock        = &(port->sockhandle);
      port->stack.txbuf       = &(port->txbuf);
      port->stack.txbuflength = &(port->txbuflength);
      port->stack.tempbuf     = &(port->tempinbuf);
      port->stack.rxbuf       = &(port->rxbuf);
      port->stack.rxbufstat   = &(port->rxbufstat);
      port->stack.rxsa        = &(port->rxsa);
      ecx_clear_rxbufstat(&(port->rxbufstat[0]));
      psock = &(port->sockhandle);
   }

   /* setup ethernet headers in tx buffers so we don't have to repeat it */
   for (i = 0; i < EC_MAXBUF; i++)
   {
      ec_setupheader(&(port->txbuf[i]));
      port->rxbufstat[i] = EC_BUF_EMPTY;
   }
   ec_setupheader(&(port->txbuf2));

   return 1;
}
コード例 #3
0
ファイル: nicdrv.c プロジェクト: nswdc/soem-rosbuild
/** Basic setup to connect NIC to socket.
 * @param[in] port        = port context struct
 * @param[in] ifname      = Name of NIC device, f.e. "eth0"
 * @param[in] secondary   = if >0 then use secondary stack instead of primary
 * @return >0 if succeeded
 */
int ecx_setupnic(ecx_portt *port, const char *ifname, int secondary) 
{
   int i;
   int r, rval, ifindex;
   struct timeval timeout;
   struct ifreq ifr;
   struct sockaddr_ll sll;
   int *psock;

   rval = 0;
   if (secondary)
   {
      /* secondary port stuct available? */
      if (port->redport)
      {
         /* when using secondary socket it is automatically a redundant setup */
         psock = &(port->redport->sockhandle);
         *psock = -1;
         port->redstate                   = ECT_RED_DOUBLE;
         port->redport->stack.sock        = &(port->redport->sockhandle);
         port->redport->stack.txbuf       = &(port->txbuf);
         port->redport->stack.txbuflength = &(port->txbuflength);
         port->redport->stack.tempbuf     = &(port->redport->tempinbuf);
         port->redport->stack.rxbuf       = &(port->redport->rxbuf);
         port->redport->stack.rxbufstat   = &(port->redport->rxbufstat);
         port->redport->stack.rxsa        = &(port->redport->rxsa);
      }
      else
      {
         /* fail */
         return 0;
      }
   }
   else
   {	  
      rt_mutex_create(&port->getindex_mutex, "getindex_mutex");
      rt_mutex_create(&port->tx_mutex, "tx_mutex");
      rt_mutex_create(&port->rx_mutex, "rx_mutex");
     
      port->sockhandle        = -1;
      port->lastidx           = 0;
      port->redstate          = ECT_RED_NONE;
      port->stack.sock        = &(port->sockhandle);
      port->stack.txbuf       = &(port->txbuf);
      port->stack.txbuflength = &(port->txbuflength);
      port->stack.tempbuf     = &(port->tempinbuf);
      port->stack.rxbuf       = &(port->rxbuf);
      port->stack.rxbufstat   = &(port->rxbufstat);
      port->stack.rxsa        = &(port->rxsa);
      psock = &(port->sockhandle);
   }   
   /* we use RAW packet socket, with packet type ETH_P_ECAT */
   *psock = SOCKET(PF_PACKET, SOCK_RAW, htons(ETH_P_ECAT));
   
   timeout.tv_sec =  0;
   timeout.tv_usec = 1; 
   
   r = SETSOCKOPT(*psock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
   r = SETSOCKOPT(*psock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
   i = 1;
   r = SETSOCKOPT(*psock, SOL_SOCKET, SO_DONTROUTE, &i, sizeof(i));
   /* connect socket to NIC by name */
   strcpy(ifr.ifr_name, ifname);
   r = IOCTL(*psock, SIOCGIFINDEX, &ifr);
   ifindex = ifr.ifr_ifindex;
   strcpy(ifr.ifr_name, ifname);
   ifr.ifr_flags = 0;
   /* reset flags of NIC interface */
   r = IOCTL(*psock, SIOCGIFFLAGS, &ifr); 
   /* set flags of NIC interface, here promiscuous and broadcast */
   ifr.ifr_flags = ifr.ifr_flags || IFF_PROMISC || IFF_BROADCAST;
   r = IOCTL(*psock, SIOCGIFFLAGS, &ifr);
   /* bind socket to protocol, in this case RAW EtherCAT */
   sll.sll_family = AF_PACKET;
   sll.sll_ifindex = ifindex;
   sll.sll_protocol = htons(ETH_P_ECAT);
   r = BIND(*psock, (struct sockaddr *)&sll, sizeof(sll));
   /* setup ethernet headers in tx buffers so we don't have to repeat it */
   for (i = 0; i < EC_MAXBUF; i++) 
   {
      ec_setupheader(&(port->txbuf[i]));
      port->rxbufstat[i] = EC_BUF_EMPTY;
   }
   ec_setupheader(&(port->txbuf2));
   if (r == 0) rval = 1;
   
   return rval;
}