00001 /*############################################################################## 00002 00003 nIP - nano IP stack 00004 00005 File : net_if.c 00006 00007 Description : Network interface control 00008 00009 Copyright notice: 00010 00011 Copyright (C) 2005 - 00012 Andreas Dittrich, dittrich@informatik.hu-berlin.de 00013 Jon Kowal, kowal@informatik.hu-berlin.de 00014 00015 This program is free software; you can redistribute it and/or 00016 modify it under the terms of the GNU General Public License 00017 as published by the Free Software Foundation; either version 2 00018 of the License, or (at your option) any later version. 00019 00020 This program is distributed in the hope that it will be useful, 00021 but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 GNU General Public License for more details. 00024 00025 You should have received a copy of the GNU General Public License 00026 along with this program; if not, write to the Free Software 00027 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00028 00029 ##############################################################################*/ 00030 00031 #include "nip_init.h" 00032 #include "net/net_if.h" 00033 #include "net/ethernet.h" 00034 #include "net/ip.h" 00035 00036 #if (NIP_NET_ENABLE == 1) 00037 00038 /** network interface list */ 00039 nip_net_if_t nip_net_if_list[NIP_NET_IF_COUNT]; 00040 00041 /** network transmissions */ 00042 nip_net_if_trans_t nip_net_trans_list[NIP_NET_MAX_TRANSMISSIONS]; 00043 00044 00045 /** Reset transmission. (Free data pointers, clear status,...). The given 00046 * pointer will not actually be freed from memory. 00047 */ 00048 void nip_reset_trans( nip_net_if_trans_t *trans ) 00049 { 00050 nip_mem_free( trans->header ); 00051 if ( trans->flags.free_payload == 1 ) 00052 nip_mem_free( trans->payload ); 00053 00054 nip_memset( &trans->params, 0, sizeof( nip_net_if_trans_params_t) ); 00055 00056 trans->header = NIP_MEM_NULL; 00057 trans->payload = NIP_MEM_NULL; 00058 trans->header_size = 0; 00059 trans->payload_size = 0; 00060 trans->retrans_cnt = 0; 00061 00062 if ( trans->flags.reset_status == 1 ) 00063 trans->status = NIP_NET_IF_IDLE; 00064 00065 trans->flags.reset_status = 0; 00066 trans->flags.free_payload = 0; 00067 00068 } 00069 00070 /** Create item in network interface list. The item configuration will be 00071 * initialized depending on the given type 00072 * 00073 * @return ID of network interface or NIP_NET_IF_ID_UNEFINED 00074 */ 00075 nip_net_if_id_t nip_net_if_create( nip_phy_if_type_t type ) 00076 { 00077 nip_net_if_id_t id; 00078 00079 // search for free item in network interface list 00080 id = 0; 00081 #if NIP_NET_IF_COUNT>1 00082 do 00083 { 00084 #endif 00085 // found free item? 00086 if ( nip_net_if_list[id].id == NIP_NET_NO_IF ) 00087 { 00088 // set item id and type 00089 nip_net_if_list[id].id = id; 00090 nip_net_if_list[id].phy_conf.type = type; 00091 00092 #if NIP_NET_IF_COUNT>1 00093 // stop searching 00094 break; 00095 #endif 00096 } 00097 #if NIP_NET_IF_COUNT>1 00098 } while ( ++id < NIP_NET_IF_COUNT ); 00099 #endif 00100 00101 // no free item found? 00102 if ( id >= NIP_NET_IF_COUNT ) 00103 return NIP_NET_NO_IF; 00104 00105 // reset interface statistics 00106 nip_net_if_list[id].phy_conf.stats.cnt_discarded = 0; 00107 00108 // configure item depending on type 00109 switch ( type ) 00110 { 00111 // default configuration for ethernet interface 00112 #if (NIP_ETH_ENABLE==1) 00113 case NIP_PHY_IF_ETH: 00114 nip_eth_configure_if_defaults( id ); 00115 break; 00116 #endif 00117 00118 default: 00119 nip_net_if_list[id].phy_conf.flags = NIP_PHY_IFF_NOARP; 00120 nip_net_if_list[id].phy_conf.open = NULL; 00121 nip_net_if_list[id].phy_conf.close = NULL; 00122 nip_net_if_list[id].phy_conf.hard_send_init = NULL; 00123 nip_net_if_list[id].phy_conf.hard_send = NULL; 00124 nip_net_if_list[id].phy_conf.hard_read_init = NULL; 00125 nip_net_if_list[id].phy_conf.hard_read = NULL; 00126 break; 00127 } 00128 00129 return id; 00130 } 00131 00132 /** free network interface 00133 * 00134 * The network interface will be brought down and freed. 00135 */ 00136 void nip_net_if_free ( nip_net_if_id_t id ) 00137 { 00138 // bring down network interface 00139 if ( nip_net_if_list[id].phy_conf.flags & NIP_PHY_IFF_UP ) 00140 { 00141 nip_net_if_down( id ); 00142 } 00143 // unset list item 00144 nip_net_if_list[id].id = NIP_NET_IF_COUNT; 00145 } 00146 00147 /** set network interface flags 00148 * @note The network interface has to be closed (down) when calling this function. 00149 */ 00150 nip_success_t nip_set_if_flags ( nip_net_if_id_t id, nip_phy_if_flags_t flags) 00151 { 00152 if ( nip_net_if_list[id].phy_conf.flags & NIP_PHY_IFF_UP ) 00153 { 00154 // error if interface is up 00155 return NIP_ERROR; 00156 } 00157 else 00158 { 00159 // update flags if interface is down 00160 nip_net_if_list[id].phy_conf.flags = flags; 00161 } 00162 00163 // if UP flag was set, try to open interface 00164 if ( nip_net_if_list[id].phy_conf.flags & NIP_PHY_IFF_UP ) 00165 { 00166 return nip_net_if_up( id ); 00167 } 00168 else 00169 { 00170 // flags have been set successfully 00171 return NIP_SUCCESS; 00172 } 00173 } 00174 00175 00176 /** return pointer to network interface configuration struct. */ 00177 nip_net_if_t *nip_net_if_ptr ( nip_net_if_id_t id) 00178 { 00179 return &nip_net_if_list[id]; 00180 } 00181 00182 /** Bring up network interface. */ 00183 nip_success_t nip_net_if_up ( nip_net_if_id_t id ) 00184 { 00185 nip_net_if_t *net_if = &nip_net_if_list[id]; 00186 00187 // check if interface's open method has been configured 00188 if ( net_if->phy_conf.open != NULL ) 00189 { 00190 // call open method and update IFF_UP-flag 00191 if ( net_if->phy_conf.open( id ) == NIP_SUCCESS ) 00192 net_if->phy_conf.flags |= NIP_PHY_IFF_UP; 00193 } 00194 00195 // return success if interface is up 00196 if ( net_if->phy_conf.flags & NIP_PHY_IFF_UP ) 00197 { 00198 // no IP address configured? -> start autoconfiguration of IP address 00199 #if (NIP_IP_ENABLE==1) 00200 if ( net_if->ip_conf.state != NIP_IP_CONF_STAT_CONFIGURED ) 00201 nip_ip_addr_autoconf( id ); 00202 else 00203 nip_ip_up( id ); 00204 #endif 00205 00206 return NIP_SUCCESS; 00207 } else 00208 return NIP_ERROR; 00209 } 00210 00211 /** Bring down network interface. */ 00212 nip_success_t nip_net_if_down ( nip_net_if_id_t id) 00213 { 00214 nip_net_if_t *net_if = &nip_net_if_list[id]; 00215 00216 // check if interface's close method has been configured 00217 if ( net_if->phy_conf.open != NULL ) 00218 { 00219 // call close method and update IFF_UP-flag 00220 if ( net_if->phy_conf.close( id ) == NIP_SUCCESS ) 00221 net_if->phy_conf.flags &= ~NIP_PHY_IFF_UP; 00222 } 00223 00224 // return error if interface is not down 00225 if ( net_if->phy_conf.flags & NIP_PHY_IFF_UP ) 00226 return NIP_ERROR; 00227 else 00228 return NIP_SUCCESS; 00229 } 00230 00231 #endif /* NIP_NET_ENABLE==1 */