Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

rt_3c905x.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001, Swedish Institute of Computer Science.
00003  * All rights reserved. 
00004  *
00005  * Redistribution and use in source and binary forms, with or without 
00006  * modification, are permitted provided that the following conditions 
00007  * are met: 
00008  * 1. Redistributions of source code must retain the above copyright 
00009  *    notice, this list of conditions and the following disclaimer. 
00010  * 2. Redistributions in binary form must reproduce the above copyright 
00011  *    notice, this list of conditions and the following disclaimer in the 
00012  *    documentation and/or other materials provided with the distribution. 
00013  * 3. Neither the name of the Institute nor the names of its contributors 
00014  *    may be used to endorse or promote products derived from this software 
00015  *    without specific prior written permission. 
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
00027  * SUCH DAMAGE. 
00028  *
00029  */
00030 
00031 /*********************************************************************************/
00032 /* This file is based in one file part of the lwIP TCP/IP stack. The file is:    */
00033 /* ethernetif.c                                                                  */
00034 /* which author is: Adam Dunkels <adam@sics.se>                                  */
00035 /*                                                                               */
00036 /* This file has been modified by Sergio Perez Alcañiz <serpeal@disca.upv.es>    */
00037 /*            Departamento de Informática de Sistemas y Computadores             */
00038 /*            Universidad Politécnica de Valencia                                */
00039 /*            Valencia (Spain)                                                   */
00040 /*                                                                               */
00041 /* The RTL-lwIP project has been supported by the Spanish Government Research    */
00042 /* Office (CICYT) under grant TIC2002-04123-C03-03                               */
00043 /*                                                                               */
00044 /* Copyright (c) March, 2003 SISTEMAS DE TIEMPO REAL EMPOTRADOS, FIABLES Y       */
00045 /* DISTRIBUIDOS BASADOS EN COMPONENTES                                           */
00046 /*                                                                               */
00047 /*  This program is free software; you can redistribute it and/or modify         */
00048 /*  it under the terms of the GNU General Public License as published by         */
00049 /*  the Free Software Foundation; either version 2 of the License, or            */
00050 /*  (at your option) any later version.                                          */
00051 /*                                                                               */
00052 /*  This program is distributed in the hope that it will be useful,              */
00053 /*  but WITHOUT ANY WARRANTY; without even the implied warrabnty of              */
00054 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                */
00055 /*  GNU General Public License for more details.                                 */
00056 /*                                                                               */
00057 /*  You should have received a copy of the GNU General Public License            */
00058 /*  along with this program; if not, write to the Free Software                  */
00059 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    */
00060 /*                                                                               */
00061 /*  Linking RTL-lwIP statically or dynamically with other modules is making a    */
00062 /*  combined work based on RTL-lwIP.  Thus, the terms and conditions of the GNU  */
00063 /*  General Public License cover the whole combination.                          */
00064 /*                                                                               */
00065 /*  As a special exception, the copyright holders of RTL-lwIP give you           */
00066 /*  permission to link RTL-lwIP with independent modules that communicate with   */
00067 /*  RTL-lwIP solely through the interfaces, regardless of the license terms of   */
00068 /*  these independent modules, and to copy and distribute the resulting combined */
00069 /*  work under terms of your choice, provided that every copy of the combined    */
00070 /*  work is accompanied by a complete copy of the source code of RTL-lwIP (the   */
00071 /*  version of RTL-lwIP used to produce the combined work), being distributed    */
00072 /*  under the terms of the GNU General Public License plus this exception.  An   */
00073 /*  independent module is a module which is not derived from or based on         */
00074 /*  RTL-lwIP.                                                                    */
00075 /*                                                                               */
00076 /*  Note that people who make modified versions of RTL-lwIP are not obligated to */
00077 /*  grant this special exception for their modified versions; it is their choice */
00078 /*  whether to do so.  The GNU General Public License gives permission to        */
00079 /*  release a modified version without this exception; this exception also makes */
00080 /*  it possible to release a modified version which carries forward this         */
00081 /*  exception.                                                                   */
00082 /*********************************************************************************/
00083 
00084 #include "lwip/opt.h"
00085 #include "lwip/def.h"
00086 #include "lwip/mem.h"
00087 #include "lwip/pbuf.h"
00088 #include "lwip/sys.h"
00089 #include "netif/etharp.h"
00090 #include "netif/rt_3c905x_exports.h"
00091 #include "netif/ethernetif.h"
00092 #include <unistd.h>
00093 #include "bcopy.h"
00094 #include <signal.h>
00095 #include <rtl_sema.h>
00096 
00097 #define IFNAME0 'e'
00098 #define IFNAME1 't'
00099 #define COM3_SIGNAL RTL_SIGUSR2
00100 
00101 ethernetif_thread_t com3_thread;
00102 
00103 struct rt_3c905cif {
00104   struct eth_addr *ethaddr;
00105 };
00106 
00107 static const struct eth_addr rt_3c905cif_ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
00108 static int rt_3c905cif_fd;
00109 static struct netif *rt_3c905cif_netif;
00110 
00111 /* Forward declarations. */
00112 static void rt_3c905cif_input(struct pbuf *p, struct netif *netif);
00113 static err_t rt_3c905cif_output(struct netif *netif, struct pbuf *p,
00114                                struct ip_addr *ipaddr);
00115 static void rt_3c905cif_ethernetif_thread(void *arg);
00116 
00117 /*-----------------------------------------------------------------------------------*/
00118 static void
00119 rt_3com905cif_low_level_init(struct netif *netif)
00120 {
00121   struct rt_3c905cif *rt_3c905cif;
00122   char dev_name[]={"/dev/eth0"};
00123   
00124   rt_3c905cif = netif->state;
00125   
00126   /* Do whatever else is needed to initialize interface. */  
00127   if((rt_3c905cif_fd=open(dev_name,0)) == -1)
00128     rtl_printf("ERROR OPENING /dev/%s0\n",COM3_905C_NAME);
00129 
00130   /* Obtain MAC address from network interface. */
00131   ioctl(rt_3c905cif_fd, 2, (unsigned long) rt_3c905cif->ethaddr->addr);
00132 
00133   /* We set an IP filter to the ethernet card */
00134   ioctl(rt_3c905cif_fd, 1, (unsigned long) netif->ip_addr.addr);
00135 
00136 //  rtl_printf("ADRESS: %x:%x:%x:%x:%x:%x \n",rt_3c905cif->ethaddr->addr[0],rt_3c905cif->ethaddr->addr[1],rt_3c905cif->ethaddr->addr[2],rt_3c905cif->ethaddr->addr[3],rt_3c905cif->ethaddr->addr[4],rt_3c905cif->ethaddr->addr[5]);
00137 
00138   sys_thread_new(rt_3c905cif_ethernetif_thread, netif, 0);
00139 
00140   return ;
00141 }
00142 
00143 /*-----------------------------------------------------------------------------------*/
00144 static void rt_3c905cif_ethernetif_thread(void *arg){
00145   struct sched_param p;
00146 
00147   p . sched_priority = 100000;
00148   pthread_setschedparam (pthread_self(), SCHED_FIFO, &p);
00149 
00150   do{
00151     rt_3c905cif_input(NULL, rt_3c905cif_netif);  
00152   }while(1);
00153 
00154 }
00155 
00156 /*-----------------------------------------------------------------------------------*/
00157 /*
00158  * rt_3com905cif_low_level_output():
00159  *
00160  * Should do the actual transmission of the packet. The packet is
00161  * contained in the pbuf that is passed to the function. This pbuf
00162  * might be chained.
00163  *
00164  */
00165 /*-----------------------------------------------------------------------------------*/
00166 
00167 err_t
00168 rt_3com905cif_low_level_output(struct netif *rt_3c905cif, struct pbuf *p)
00169 {
00170 
00171   struct pbuf *q;
00172   unsigned char buf[1536];
00173   unsigned char *bufptr;  
00174 
00175   //initiate transfer;
00176   bufptr = buf;  
00177   
00178   for(q = p; q != NULL; q = q->next) {
00179     /* Send the data from the pbuf to the interface, one pbuf at a
00180        time. The size of the data in each pbuf is kept in the ->len
00181        variable. */
00182     bcopy(q->payload, bufptr, q->len);
00183     bufptr += q->len;
00184   }
00185 
00186   //signal that packet should be sent;
00187   {
00188     int tmp;
00189     int counter=0;
00190  
00191     while((tmp = write(rt_3c905cif_fd,buf,p->tot_len)) == -1){
00192       counter++;
00193       usleep(1);  
00194     }
00195   }
00196   
00197   return ERR_OK;
00198 }
00199 /*-----------------------------------------------------------------------------------*/
00200 /*
00201  * rt_3com905cif_low_level_input():
00202  *
00203  * Should allocate a pbuf and transfer the bytes of the incoming
00204  * packet from the interface into the pbuf.
00205  *
00206  */
00207 /*-----------------------------------------------------------------------------------*/
00208 static struct pbuf *
00209 rt_3com905cif_low_level_input(struct rt_3c905cif *rt_3c905cif)
00210 {
00211   struct pbuf *p, *q;
00212   struct memory receive_buffer;
00213   unsigned char *bufptr;
00214   u16_t len;
00215   
00216   /* Obtain the size of the packet and put it into the "len"
00217      variable. */
00218   len = read(rt_3c905cif_fd,(void *) &receive_buffer,1536);
00219   
00220   /* We allocate a pbuf chain of pbufs from the pool. */
00221   p = pbuf_alloc(PBUF_LINK, len, PBUF_POOL);
00222   
00223   if(p != NULL) {
00224     /* We iterate over the pbuf chain until we have read the entire
00225        packet into the pbuf. */
00226     bufptr = receive_buffer.mem;
00227     for(q = p; q != NULL; q = q->next) {
00228       /* Read enough bytes to fill this pbuf in the chain. The
00229          avaliable data in the pbuf is given by the q->len
00230          variable. */
00231       bcopy(bufptr, q->payload, q->len);
00232       bufptr += q->len;
00233     }
00234   } else {
00235     rtl_printf("ERROR:Not enough memory!!!\n");
00236     sys_arch_close();
00237   }
00238 
00239   return p;  
00240 }
00241 /*-----------------------------------------------------------------------------------*/
00242 /*
00243  * rt_3c905cif_output():
00244  *
00245  * This function is called by the TCP/IP stack when an IP packet
00246  * should be sent. It calls the function called rt_3com905cif_low_level_output() to
00247  * do the actuall transmission of the packet.
00248  *
00249  */
00250 /*-----------------------------------------------------------------------------------*/
00251 static err_t
00252 rt_3c905cif_output(struct netif *netif, struct pbuf *p,
00253                   struct ip_addr *ipaddr)
00254 {
00255   
00256   p = etharp_output(netif, ipaddr, p);
00257   if(p != NULL) {
00258     rt_3com905cif_low_level_output(netif, p);
00259   }
00260   return ERR_OK;
00261 }
00262 
00263 /*-----------------------------------------------------------------------------------*/
00264 /*
00265  * rt_3c905cif_input():
00266  *
00267  * This function should be called when a packet is ready to be read
00268  * from the interface. It uses the function rt_3com905cif_low_level_input() that
00269  * should handle the actual reception of bytes from the network
00270  * interface.
00271  *
00272  */
00273 /*-----------------------------------------------------------------------------------*/
00274 static void
00275 
00276 rt_3c905cif_input(struct pbuf *o, struct netif *netif)//(struct netif *netif)
00277 {
00278 
00279   /* Ethernet protocol layer */
00280   struct eth_hdr *ethhdr;
00281   struct rt_3c905cif *rt_3c905cif = netif->state;
00282   struct pbuf *q = NULL , *p = NULL;
00283   
00284   p = rt_3com905cif_low_level_input(rt_3c905cif);
00285 
00286   ethhdr = p->payload;
00287   
00288   switch(htons(ethhdr->type)) {
00289   case ETHTYPE_IP:
00290     q = etharp_ip_input(netif, p);
00291     pbuf_header(p, -14);
00292     netif->input(p, netif);
00293     break;
00294   case ETHTYPE_ARP:
00295     q = etharp_arp_input(netif, rt_3c905cif->ethaddr, p);
00296     break;
00297   default:
00298     pbuf_free(p);
00299     break;
00300   }
00301   if(q != NULL) {
00302     rt_3com905cif_low_level_output(netif, q);
00303     pbuf_free(q);
00304   }
00305 }
00306 
00307 /*-----------------------------------------------------------------------------------*/
00308 void rt_3com905cif_etharp_timer(int signo)
00309 {
00310   etharp_tmr();
00311   sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)rt_3com905cif_etharp_timer, NULL);
00312 }
00313 
00314 /*-----------------------------------------------------------------------------------*/
00315 /*
00316  * rt_3c905cif_init():
00317  *
00318  * Should be called at the beginning of the program to set up the
00319  * network interface. It calls the function rt_3com905cif_low_level_init() to do the
00320  * actual setup of the hardware.
00321  *
00322  */
00323 /*-----------------------------------------------------------------------------------*/
00324 err_t
00325 rt_3c905cif_init(struct netif *netif)
00326 {
00327   struct rt_3c905cif *rt_3c905cif;
00328     
00329   rt_3c905cif = mem_malloc(sizeof(struct rt_3c905cif));
00330   netif->state = rt_3c905cif;
00331   netif->name[0] = IFNAME0;
00332   netif->name[1] = IFNAME1;
00333   netif->output = rt_3c905cif_output;
00334   netif->linkoutput = rt_3com905cif_low_level_output;
00335   
00336   rt_3c905cif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
00337   netif->hwaddr_len = 6;
00338 
00339   rt_3c905cif_netif = netif; 
00340 
00341   rt_3com905cif_low_level_init(netif);
00342   etharp_init();
00343 
00344   sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)rt_3com905cif_etharp_timer, NULL);
00345 
00346   return ERR_OK;
00347 }
00348 
00349 
00350 /*-----------------------------------------------------------------------------------*/
00351 void rt_3c905cif_close(void){
00352   /* Unregistering the thread */
00353   ioctl(rt_3c905cif_fd, 4, (unsigned long) &com3_thread);
00354   /* Closing the 3Com905C-X card */
00355   close(rt_3c905cif_fd);
00356 }
00357 

Generated on Wed Jan 14 12:58:56 2004 for RTL-lwIP-0.4 by doxygen 1.3.4