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

rt_rtl8139.c

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

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