1/********************************************************************* 2 * 3 * Filename: irlan_eth.c 4 * Version: 5 * Description: 6 * Status: Experimental. 7 * Author: Dag Brattli <dagb@cs.uit.no> 8 * Created at: Thu Oct 15 08:37:58 1998 9 * Modified at: Tue Mar 21 09:06:41 2000 10 * Modified by: Dag Brattli <dagb@cs.uit.no> 11 * Sources: skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov> 12 * slip.c by Laurence Culhane, <loz@holmes.demon.co.uk> 13 * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> 14 * 15 * Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved. 16 * 17 * This program is free software; you can redistribute it and/or 18 * modify it under the terms of the GNU General Public License as 19 * published by the Free Software Foundation; either version 2 of 20 * the License, or (at your option) any later version. 21 * 22 * Neither Dag Brattli nor University of Troms� admit liability nor 23 * provide warranty for any of this software. This material is 24 * provided "AS-IS" and at no charge. 25 * 26 ********************************************************************/ 27 28#include <linux/config.h> 29#include <linux/netdevice.h> 30#include <linux/etherdevice.h> 31#include <linux/inetdevice.h> 32#include <linux/if_arp.h> 33#include <linux/random.h> 34#include <net/arp.h> 35 36#include <net/irda/irda.h> 37#include <net/irda/irmod.h> 38#include <net/irda/irlan_common.h> 39#include <net/irda/irlan_client.h> 40#include <net/irda/irlan_event.h> 41#include <net/irda/irlan_eth.h> 42 43/* 44 * Function irlan_eth_init (dev) 45 * 46 * The network device initialization function. 47 * 48 */ 49int irlan_eth_init(struct net_device *dev) 50{ 51 struct irlan_cb *self; 52 53 IRDA_DEBUG(2, __FUNCTION__"()\n"); 54 55 ASSERT(dev != NULL, return -1;); 56 57 self = (struct irlan_cb *) dev->priv; 58 59 dev->open = irlan_eth_open; 60 dev->stop = irlan_eth_close; 61 dev->hard_start_xmit = irlan_eth_xmit; 62 dev->get_stats = irlan_eth_get_stats; 63 dev->set_multicast_list = irlan_eth_set_multicast_list; 64 65 /* NETIF_F_DYNALLOC feature was set by irlan_eth_init() and would 66 * cause the unregister_netdev() to do asynch completion _and_ 67 * kfree self->dev afterwards. Which is really bad because the 68 * netdevice was not allocated separately but is embedded in 69 * our control block and therefore gets freed with *self. 70 * The only reason why this would have been enabled is to hide 71 * some netdev refcount issues. If unregister_netdev() blocks 72 * forever, tell us about it... */ 73 //dev->features |= NETIF_F_DYNALLOC; 74 75 ether_setup(dev); 76 77 /* 78 * Lets do all queueing in IrTTP instead of this device driver. 79 * Queueing here as well can introduce some strange latency 80 * problems, which we will avoid by setting the queue size to 0. 81 */ 82 dev->tx_queue_len = 0; 83 84 if (self->provider.access_type == ACCESS_DIRECT) { 85 /* 86 * Since we are emulating an IrLAN sever we will have to 87 * give ourself an ethernet address! 88 */ 89 dev->dev_addr[0] = 0x40; 90 dev->dev_addr[1] = 0x00; 91 dev->dev_addr[2] = 0x00; 92 dev->dev_addr[3] = 0x00; 93 get_random_bytes(dev->dev_addr+4, 1); 94 get_random_bytes(dev->dev_addr+5, 1); 95 } 96 97 return 0; 98} 99 100/* 101 * Function irlan_eth_open (dev) 102 * 103 * Network device has been opened by user 104 * 105 */ 106int irlan_eth_open(struct net_device *dev) 107{ 108 struct irlan_cb *self; 109 110 IRDA_DEBUG(2, __FUNCTION__ "()\n"); 111 112 ASSERT(dev != NULL, return -1;); 113 114 self = (struct irlan_cb *) dev->priv; 115 116 ASSERT(self != NULL, return -1;); 117 118 /* Ready to play! */ 119 netif_stop_queue(dev); /* Wait until data link is ready */ 120 121 /* We are now open, so time to do some work */ 122 self->disconnect_reason = 0; 123 irlan_client_wakeup(self, self->saddr, self->daddr); 124 125 irlan_mod_inc_use_count(); 126 127 /* Make sure we have a hardware address before we return, so DHCP clients gets happy */ 128 interruptible_sleep_on(&self->open_wait); 129 130 return 0; 131} 132 133/* 134 * Function irlan_eth_close (dev) 135 * 136 * Stop the ether network device, his function will usually be called by 137 * ifconfig down. We should now disconnect the link, We start the 138 * close timer, so that the instance will be removed if we are unable 139 * to discover the remote device after the disconnect. 140 */ 141int irlan_eth_close(struct net_device *dev) 142{ 143 struct irlan_cb *self = (struct irlan_cb *) dev->priv; 144 struct sk_buff *skb; 145 146 IRDA_DEBUG(2, __FUNCTION__ "()\n"); 147 148 /* Stop device */ 149 netif_stop_queue(dev); 150 151 irlan_mod_dec_use_count(); 152 153 irlan_close_data_channel(self); 154 irlan_close_tsaps(self); 155 156 irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL); 157 irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL); 158 159 /* Remove frames queued on the control channel */ 160 while ((skb = skb_dequeue(&self->client.txq))) 161 dev_kfree_skb(skb); 162 163 self->client.tx_busy = 0; 164 165 return 0; 166} 167 168/* 169 * Function irlan_eth_tx (skb) 170 * 171 * Transmits ethernet frames over IrDA link. 172 * 173 */ 174int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev) 175{ 176 struct irlan_cb *self; 177 int ret; 178 179 self = (struct irlan_cb *) dev->priv; 180 181 ASSERT(self != NULL, return 0;); 182 ASSERT(self->magic == IRLAN_MAGIC, return 0;); 183 184 /* skb headroom large enough to contain all IrDA-headers? */ 185 if ((skb_headroom(skb) < self->max_header_size) || (skb_shared(skb))) { 186 struct sk_buff *new_skb = 187 skb_realloc_headroom(skb, self->max_header_size); 188 189 /* We have to free the original skb anyway */ 190 dev_kfree_skb(skb); 191 192 /* Did the realloc succeed? */ 193 if (new_skb == NULL) 194 return 0; 195 196 /* Use the new skb instead */ 197 skb = new_skb; 198 } 199 200 dev->trans_start = jiffies; 201 202 /* Now queue the packet in the transport layer */ 203 if (self->use_udata) 204 ret = irttp_udata_request(self->tsap_data, skb); 205 else 206 ret = irttp_data_request(self->tsap_data, skb); 207 208 if (ret < 0) { 209 /* 210 * IrTTPs tx queue is full, so we just have to 211 * drop the frame! You might think that we should 212 * just return -1 and don't deallocate the frame, 213 * but that is dangerous since it's possible that 214 * we have replaced the original skb with a new 215 * one with larger headroom, and that would really 216 * confuse do_dev_queue_xmit() in dev.c! I have 217 * tried :-) DB 218 */ 219 dev_kfree_skb(skb); 220 self->stats.tx_dropped++; 221 } else { 222 self->stats.tx_packets++; 223 self->stats.tx_bytes += skb->len; 224 } 225 226 return 0; 227} 228 229/* 230 * Function irlan_eth_receive (handle, skb) 231 * 232 * This function gets the data that is received on the data channel 233 * 234 */ 235int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb) 236{ 237 struct irlan_cb *self; 238 239 self = (struct irlan_cb *) instance; 240 241 if (skb == NULL) { 242 ++self->stats.rx_dropped; 243 return 0; 244 } 245 ASSERT(skb->len > 1, return 0;); 246 247 /* 248 * Adopt this frame! Important to set all these fields since they 249 * might have been previously set by the low level IrDA network 250 * device driver 251 */ 252 skb->dev = &self->dev; 253 skb->protocol=eth_type_trans(skb, skb->dev); /* Remove eth header */ 254 255 self->stats.rx_packets++; 256 self->stats.rx_bytes += skb->len; 257 258 netif_rx(skb); /* Eat it! */ 259 260 return 0; 261} 262 263/* 264 * Function irlan_eth_flow (status) 265 * 266 * Do flow control between IP/Ethernet and IrLAN/IrTTP. This is done by 267 * controlling the queue stop/start. 268 */ 269void irlan_eth_flow_indication(void *instance, void *sap, LOCAL_FLOW flow) 270{ 271 struct irlan_cb *self; 272 struct net_device *dev; 273 274 self = (struct irlan_cb *) instance; 275 276 ASSERT(self != NULL, return;); 277 ASSERT(self->magic == IRLAN_MAGIC, return;); 278 279 dev = &self->dev; 280 281 ASSERT(dev != NULL, return;); 282 283 switch (flow) { 284 case FLOW_STOP: 285 netif_stop_queue(dev); 286 break; 287 case FLOW_START: 288 default: 289 /* Tell upper layers that its time to transmit frames again */ 290 /* Schedule network layer */ 291 netif_start_queue(dev); 292 break; 293 } 294} 295 296/* 297 * Function irlan_eth_rebuild_header (buff, dev, dest, skb) 298 * 299 * If we don't want to use ARP. Currently not used!! 300 * 301 */ 302void irlan_eth_rebuild_header(void *buff, struct net_device *dev, 303 unsigned long dest, struct sk_buff *skb) 304{ 305 struct ethhdr *eth = (struct ethhdr *) buff; 306 307 memcpy(eth->h_source, dev->dev_addr, dev->addr_len); 308 memcpy(eth->h_dest, dev->dev_addr, dev->addr_len); 309 310 /* return 0; */ 311} 312 313/* 314 * Function irlan_etc_send_gratuitous_arp (dev) 315 * 316 * Send gratuitous ARP to announce that we have changed 317 * hardware address, so that all peers updates their ARP tables 318 */ 319void irlan_eth_send_gratuitous_arp(struct net_device *dev) 320{ 321 struct in_device *in_dev; 322 323 /* 324 * When we get a new MAC address do a gratuitous ARP. This 325 * is useful if we have changed access points on the same 326 * subnet. 327 */ 328#ifdef CONFIG_INET 329 IRDA_DEBUG(4, "IrLAN: Sending gratuitous ARP\n"); 330 in_dev = in_dev_get(dev); 331 if (in_dev == NULL) 332 return; 333 read_lock(&in_dev->lock); 334 if (in_dev->ifa_list) 335 336 arp_send(ARPOP_REQUEST, ETH_P_ARP, 337 in_dev->ifa_list->ifa_address, 338 dev, 339 in_dev->ifa_list->ifa_address, 340 NULL, dev->dev_addr, NULL); 341 read_unlock(&in_dev->lock); 342 in_dev_put(in_dev); 343#endif /* CONFIG_INET */ 344} 345 346/* 347 * Function set_multicast_list (dev) 348 * 349 * Configure the filtering of the device 350 * 351 */ 352#define HW_MAX_ADDRS 4 /* Must query to get it! */ 353void irlan_eth_set_multicast_list(struct net_device *dev) 354{ 355 struct irlan_cb *self; 356 357 self = dev->priv; 358 359 IRDA_DEBUG(2, __FUNCTION__ "()\n"); 360 361 ASSERT(self != NULL, return;); 362 ASSERT(self->magic == IRLAN_MAGIC, return;); 363 364 /* Check if data channel has been connected yet */ 365 if (self->client.state != IRLAN_DATA) { 366 IRDA_DEBUG(1, __FUNCTION__ "(), delaying!\n"); 367 return; 368 } 369 370 if (dev->flags & IFF_PROMISC) { 371 /* Enable promiscuous mode */ 372 WARNING("Promiscous mode not implemented by IrLAN!\n"); 373 } 374 else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS) { 375 /* Disable promiscuous mode, use normal mode. */ 376 IRDA_DEBUG(4, __FUNCTION__ "(), Setting multicast filter\n"); 377 /* hardware_set_filter(NULL); */ 378 379 irlan_set_multicast_filter(self, TRUE); 380 } 381 else if (dev->mc_count) { 382 IRDA_DEBUG(4, __FUNCTION__ "(), Setting multicast filter\n"); 383 /* Walk the address list, and load the filter */ 384 /* hardware_set_filter(dev->mc_list); */ 385 386 irlan_set_multicast_filter(self, TRUE); 387 } 388 else { 389 IRDA_DEBUG(4, __FUNCTION__ "(), Clearing multicast filter\n"); 390 irlan_set_multicast_filter(self, FALSE); 391 } 392 393 if (dev->flags & IFF_BROADCAST) 394 irlan_set_broadcast_filter(self, TRUE); 395 else 396 irlan_set_broadcast_filter(self, FALSE); 397} 398 399/* 400 * Function irlan_get_stats (dev) 401 * 402 * Get the current statistics for this device 403 * 404 */ 405struct net_device_stats *irlan_eth_get_stats(struct net_device *dev) 406{ 407 struct irlan_cb *self = (struct irlan_cb *) dev->priv; 408 409 ASSERT(self != NULL, return NULL;); 410 ASSERT(self->magic == IRLAN_MAGIC, return NULL;); 411 412 return &self->stats; 413} 414