root/net/tcp/dev.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. min
  2. dev_add_pack
  3. dev_remove_pack
  4. get_dev
  5. dev_queue_xmit
  6. dev_rint
  7. dev_tint

   1 /* dev.c */
   2 /*
   3     Copyright (C) 1992  Ross Biro
   4 
   5     This program is free software; you can redistribute it and/or modify
   6     it under the terms of the GNU General Public License as published by
   7     the Free Software Foundation; either version 2, or (at your option)
   8     any later version.
   9 
  10     This program is distributed in the hope that it will be useful,
  11     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13     GNU General Public License for more details.
  14 
  15     You should have received a copy of the GNU General Public License
  16     along with this program; if not, write to the Free Software
  17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  18 
  19     The Author may be reached as bir7@leland.stanford.edu or
  20     C/O Department of Mathematics; Stanford University; Stanford, CA 94305
  21 */
  22 /* $Id: dev.c,v 0.8.4.4 1992/11/18 15:38:03 bir7 Exp $ */
  23 /* $Log: dev.c,v $
  24  * Revision 0.8.4.4  1992/11/18  15:38:03  bir7
  25  * Fixed bug in copying packets and changed some printk's
  26  *
  27  * Revision 0.8.4.3  1992/11/15  14:55:30  bir7
  28  * More sanity checks.
  29  *
  30  * Revision 0.8.4.2  1992/11/10  10:38:48  bir7
  31  * Change free_s to kfree_s and accidently changed free_skb to kfree_skb.
  32  *
  33  * Revision 0.8.4.1  1992/11/10  00:17:18  bir7
  34  * version change only.
  35  *
  36  * Revision 0.8.3.5  1992/11/10  00:14:47  bir7
  37  * Changed malloc to kmalloc and added $iId$ 
  38  *
  39  */
  40 
  41 #include <asm/segment.h>
  42 #include <asm/system.h>
  43 #include <linux/types.h>
  44 #include <linux/kernel.h>
  45 #include <linux/sched.h>
  46 #include <linux/string.h>
  47 #include <linux/mm.h>
  48 #include <linux/socket.h>
  49 #include <netinet/in.h>
  50 #include "dev.h"
  51 #include "eth.h"
  52 #include "timer.h"
  53 #include "ip.h"
  54 #include "tcp.h"
  55 #include "sock.h"
  56 #include <linux/errno.h>
  57 #include "arp.h"
  58 
  59 #undef DEV_DEBUG
  60 #ifdef DEV_DEBUG
  61 #define PRINTK printk
  62 #else
  63 #define PRINTK dummy_routine
  64 #endif
  65 
  66 
  67 static  unsigned long
  68 min(unsigned long a, unsigned long b)
     /* [previous][next][first][last][top][bottom][index][help] */
  69 {
  70    if (a < b) return (a);
  71    return (b);
  72 }
  73 
  74 void
  75 dev_add_pack (struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
  76 {
  77    struct packet_type *p1;
  78    pt->next = ptype_base;
  79 
  80    /* see if we need to copy it. */
  81    for (p1 = ptype_base; p1 != NULL; p1 = p1->next)
  82      {
  83         if (p1->type == pt->type)
  84           {
  85              pt->copy = 1;
  86              break;
  87           }
  88      }
  89 
  90    ptype_base = pt;
  91    
  92 }
  93 
  94 void
  95 dev_remove_pack (struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
  96 {
  97    struct packet_type *lpt, *pt1;
  98    if (pt == ptype_base)
  99      {
 100         ptype_base = pt->next;
 101         return;
 102      }
 103 
 104    lpt = NULL;
 105 
 106    for (pt1 = ptype_base; pt1->next != NULL; pt1=pt1->next)
 107      {
 108         if (pt1->next == pt )
 109           {
 110              cli();
 111              if (!pt->copy && lpt) 
 112                lpt->copy = 0;
 113              pt1->next = pt->next;
 114              sti();
 115              return;
 116           }
 117 
 118         if (pt1->next -> type == pt ->type)
 119           {
 120              lpt = pt1->next;
 121           }
 122      }
 123 }
 124 
 125 struct device *
 126 get_dev (char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128    struct device *dev;
 129    for (dev = dev_base; dev != NULL; dev=dev->next)
 130      {
 131         if (strcmp (dev->name, name) == 0) return (dev);
 132      }
 133    return (NULL);
 134 }
 135 
 136 void
 137 dev_queue_xmit (struct sk_buff *skb, struct device *dev, int pri)
     /* [previous][next][first][last][top][bottom][index][help] */
 138 {
 139   struct sk_buff *skb2;
 140   PRINTK ("dev_queue_xmit (skb=%X, dev=%X, pri = %d)\n", skb, dev, pri);
 141 
 142   if (dev == NULL)
 143     {
 144       printk ("dev.c: dev_queue_xmit: dev = NULL\n");
 145       return;
 146     }
 147   
 148   skb->dev = dev;
 149   if (skb->next != NULL)
 150     {
 151       /* make sure we haven't missed an interrupt. */
 152        dev->hard_start_xmit (NULL, dev);
 153        return;
 154     }
 155 
 156   if (pri < 0 || pri >= DEV_NUMBUFFS)
 157     {
 158        printk ("bad priority in dev_queue_xmit.\n");
 159        pri = 1;
 160     }
 161 
 162   if (dev->hard_start_xmit(skb, dev) == 0)
 163     {
 164        return;
 165     }
 166 
 167   /* put skb into a bidirectional circular linked list. */
 168   PRINTK ("dev_queue_xmit dev->buffs[%d]=%X\n",pri, dev->buffs[pri]);
 169   /* interrupts should already be cleared by hard_start_xmit. */
 170   cli();
 171   if (dev->buffs[pri] == NULL)
 172     {
 173       dev->buffs[pri]=skb;
 174       skb->next = skb;
 175       skb->prev = skb;
 176     }
 177   else
 178     {
 179       skb2=dev->buffs[pri];
 180       skb->next = skb2;
 181       skb->prev = skb2->prev;
 182       skb->next->prev = skb;
 183       skb->prev->next = skb;
 184     }
 185   sti();
 186 
 187 }
 188 
 189 
 190 /* this routine now just gets the data out of the card and returns.
 191    it's return values now mean.
 192 
 193    1 <- exit even if you have more packets.
 194    0 <- call me again no matter what.
 195   -1 <- last packet not processed, try again. */
 196 
 197 int
 198 dev_rint(unsigned char *buff, unsigned long len, int flags,
     /* [previous][next][first][last][top][bottom][index][help] */
 199          struct device * dev)
 200 {
 201    struct sk_buff *skb=NULL;
 202    struct packet_type *ptype;
 203    unsigned short type;
 204    unsigned char flag =0;
 205    unsigned char *to;
 206    int amount;
 207 
 208    /* try to grab some memory. */
 209    if (len > 0 && buff != NULL)
 210      {
 211         skb = kmalloc (sizeof (*skb) + len, GFP_ATOMIC);
 212         if (skb != NULL)
 213           {
 214             skb->mem_len = sizeof (*skb) + len;
 215             skb->mem_addr = skb;
 216           }
 217      }
 218 
 219    /* firs we copy the packet into a buffer, and save it for later. */
 220    if (buff != NULL && skb != NULL)
 221      {
 222         if ( !(flags & IN_SKBUFF))
 223           {
 224              to = (unsigned char *)(skb+1);
 225              while (len > 0)
 226                {
 227                   amount = min (len, (unsigned long) dev->rmem_end -
 228                                 (unsigned long) buff);
 229                   memcpy (to, buff, amount);
 230                   len -= amount;
 231                   buff += amount;
 232                   to += amount;
 233                   if ((unsigned long)buff == dev->rmem_end)
 234                     buff = (unsigned char *)dev->rmem_start;
 235                }
 236           }
 237         else
 238           {
 239              kfree_s (skb->mem_addr, skb->mem_len);
 240              skb = (struct sk_buff *)buff;
 241           }
 242 
 243         skb->len = len;
 244         skb->dev = dev;
 245         skb->sk = NULL;
 246 
 247         /* now add it to the dev backlog. */
 248         cli();
 249         if (dev-> backlog == NULL)
 250           {
 251              skb->prev = skb;
 252              skb->next = skb;
 253              dev->backlog = skb;
 254           }
 255         else
 256           {
 257              skb ->prev = dev->backlog->prev;
 258              skb->next = dev->backlog;
 259              skb->next->prev = skb;
 260              skb->prev->next = skb;
 261           }
 262         sti();
 263         return (0);
 264      }
 265 
 266    if (skb != NULL) 
 267      kfree_s (skb->mem_addr, skb->mem_len);
 268 
 269    /* anything left to process? */
 270 
 271    if (dev->backlog == NULL)
 272      {
 273         if (buff == NULL)
 274           {
 275              sti();
 276              return (1);
 277           }
 278 
 279         if (skb != NULL)
 280           {
 281              sti();
 282              return (-1);
 283           }
 284 
 285         sti();
 286         printk ("dev_rint:Dropping packets due to lack of memory\n");
 287         return (1);
 288      }
 289 
 290    skb= dev->backlog;
 291    if (skb->next == skb)
 292      {
 293         dev->backlog = NULL;
 294      }
 295    else
 296      {
 297         dev->backlog = skb->next;
 298         skb->next->prev = skb->prev;
 299         skb->prev->next = skb->next;
 300      }
 301    sti();
 302 
 303    /* bump the pointer to the next structure. */
 304    skb->h.raw = (unsigned char *)(skb+1) + dev->hard_header_len;
 305    skb->len -= dev->hard_header_len;
 306 
 307    /* convert the type to an ethernet type. */
 308    type = dev->type_trans (skb, dev);
 309 
 310    /* if there get to be a lot of types we should changes this to
 311       a bunch of linked lists like we do for ip protocols. */
 312    for (ptype = ptype_base; ptype != NULL; ptype=ptype->next)
 313      {
 314         if (ptype->type == type)
 315           {
 316              struct sk_buff *skb2;
 317              /* copy the packet if we need to. */
 318              if (ptype->copy)
 319                {
 320                   skb2 = kmalloc (skb->mem_len, GFP_ATOMIC);
 321                   if (skb2 == NULL) continue;
 322                   memcpy (skb2, skb, skb->mem_len);
 323                   skb2->mem_addr = skb2;
 324                   skb2->h.raw = (void *)((unsigned long)skb2
 325                                          + (unsigned long)skb->h.raw
 326                                          - (unsigned long)skb);
 327 
 328                }
 329              else
 330                {
 331                   skb2 = skb;
 332                   flag = 1;
 333                }
 334                
 335              ptype->func (skb2, dev, ptype);
 336           }
 337      }
 338 
 339    if (!flag)
 340      {
 341         PRINTK ("discarding packet type = %X\n", type);
 342         kfree_skb (skb, FREE_READ);
 343      }
 344 
 345      if (buff == NULL)
 346        return (0);
 347      else
 348        return (-1);
 349 }
 350 
 351 /* This routine is called when an device interface is ready to
 352    transmit a packet.  Buffer points to where the packet should
 353    be put, and the routine returns the length of the packet.  A
 354    length of zero is interrpreted to mean the transmit buffers
 355    are empty, and the transmitter should be shut down. */
 356 
 357 unsigned long
 358 dev_tint(unsigned char *buff,  struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 359 {
 360   int i;
 361   int tmp;
 362   struct sk_buff *skb;
 363   for (i=0; i < DEV_NUMBUFFS; i++)
 364     {
 365       while (dev->buffs[i]!=NULL)
 366         {
 367           cli();
 368           skb=dev->buffs[i];
 369           if (skb->next == skb)
 370             {
 371               dev->buffs[i] = NULL;
 372             }
 373           else
 374             {
 375               dev->buffs[i]=skb->next;
 376               skb->prev->next = skb->next;
 377               skb->next->prev = skb->prev;
 378             }
 379           skb->next = NULL;
 380           skb->prev = NULL;
 381           tmp = skb->len;
 382           if (!skb->arp)
 383             {
 384                if (dev->rebuild_header (skb+1, dev))
 385                  {
 386                    skb->dev = dev;
 387                    sti();
 388                    arp_queue (skb);
 389                    continue;
 390                  }
 391             }
 392              
 393           if (tmp <= dev->mtu)
 394             {
 395                if (dev->send_packet != NULL)
 396                  {
 397                     dev->send_packet(skb, dev);
 398                  }
 399                if (buff != NULL)
 400                  memcpy (buff, skb + 1, tmp);
 401 
 402                PRINTK (">>\n");
 403                print_eth ((struct enet_header *)(skb+1));
 404             }
 405           else
 406             {
 407                printk ("**** bug len bigger than mtu. \n");
 408             }
 409           sti();
 410           if (skb->free)
 411             {
 412                   kfree_skb(skb, FREE_WRITE);
 413             }
 414 
 415           if (tmp != 0)
 416             return (tmp);
 417         }
 418     }
 419   PRINTK ("dev_tint returning 0 \n");
 420   return (0);
 421 }
 422 

/* [previous][next][first][last][top][bottom][index][help] */