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