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 
  23 #include <asm/segment.h>
  24 #include <asm/system.h>
  25 #include <linux/types.h>
  26 #include <linux/kernel.h>
  27 #include <linux/sched.h>
  28 #include <linux/string.h>
  29 #include <linux/mm.h>
  30 #include <linux/socket.h>
  31 #include <netinet/in.h>
  32 #include "dev.h"
  33 #include "eth.h"
  34 #include "timer.h"
  35 #include "ip.h"
  36 #include "tcp.h"
  37 #include "sock.h"
  38 #include <linux/errno.h>
  39 #include "arp.h"
  40 
  41 #undef DEV_DEBUG
  42 #ifdef DEV_DEBUG
  43 #define PRINTK printk
  44 #else
  45 #define PRINTK dummy_routine
  46 #endif
  47 
  48 
  49 static  unsigned long
  50 min(unsigned long a, unsigned long b)
     /* [previous][next][first][last][top][bottom][index][help] */
  51 {
  52    if (a < b) return (a);
  53    return (b);
  54 }
  55 
  56 void
  57 dev_add_pack (struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
  58 {
  59    struct packet_type *p1;
  60    pt->next = ptype_base;
  61 
  62    /* see if we need to copy it. */
  63    for (p1 = ptype_base; p1 != NULL; p1 = p1->next)
  64      {
  65         if (p1->type == pt->type)
  66           {
  67              pt->copy = 1;
  68              break;
  69           }
  70      }
  71 
  72    ptype_base = pt;
  73    
  74 }
  75 
  76 void
  77 dev_remove_pack (struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
  78 {
  79    struct packet_type *lpt, *pt1;
  80    if (pt == ptype_base)
  81      {
  82         ptype_base = pt->next;
  83         return;
  84      }
  85 
  86    lpt = NULL;
  87 
  88    for (pt1 = ptype_base; pt1->next != NULL; pt1=pt1->next)
  89      {
  90         if (pt1->next == pt )
  91           {
  92              cli();
  93              if (!pt->copy && lpt) 
  94                lpt->copy = 0;
  95              pt1->next = pt->next;
  96              sti();
  97              return;
  98           }
  99 
 100         if (pt1->next -> type == pt ->type)
 101           {
 102              lpt = pt1->next;
 103           }
 104      }
 105 }
 106 
 107 struct device *
 108 get_dev (char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 109 {
 110    struct device *dev;
 111    for (dev = dev_base; dev != NULL; dev=dev->next)
 112      {
 113         if (strcmp (dev->name, name) == 0) return (dev);
 114      }
 115    return (NULL);
 116 }
 117 
 118 void
 119 dev_queue_xmit (struct sk_buff *skb, struct device *dev, int pri)
     /* [previous][next][first][last][top][bottom][index][help] */
 120 {
 121   struct sk_buff *skb2;
 122   PRINTK ("eth_queue_xmit (skb=%X, dev=%X, pri = %d)\n", skb, dev, pri);
 123   skb->dev = dev;
 124   if (pri < 0 || pri >= DEV_NUMBUFFS)
 125     {
 126        printk ("bad priority in dev_queue_xmit.\n");
 127        pri = 1;
 128     }
 129 
 130   if (dev->hard_start_xmit(skb, dev) == 0)
 131     {
 132        return;
 133     }
 134 
 135   if (skb->next != NULL)
 136     {
 137        printk ("retransmitted packet still on queue. \n");
 138        return;
 139     }
 140 
 141   /* used to say it is not currently on a send list. */
 142   skb->next = NULL;
 143 
 144 
 145   /* put skb into a bidirectional circular linked list. */
 146   PRINTK ("eth_queue dev->buffs[%d]=%X\n",pri, dev->buffs[pri]);
 147   /* interrupts should already be cleared by hard_start_xmit. */
 148   cli();
 149   if (dev->buffs[pri] == NULL)
 150     {
 151       dev->buffs[pri]=skb;
 152       skb->next = skb;
 153       skb->prev = skb;
 154     }
 155   else
 156     {
 157       skb2=dev->buffs[pri];
 158       skb->next = skb2;
 159       skb->prev = skb2->prev;
 160       skb->next->prev = skb;
 161       skb->prev->next = skb;
 162     }
 163   sti();
 164 
 165 }
 166 
 167 
 168 /* this routine now just gets the data out of the card and returns.
 169    it's return values now mean.
 170 
 171    1 <- exit even if you have more packets.
 172    0 <- call me again no matter what.
 173   -1 <- last packet not processed, try again. */
 174 
 175 int
 176 dev_rint(unsigned char *buff, unsigned long len, int flags,
     /* [previous][next][first][last][top][bottom][index][help] */
 177          struct device * dev)
 178 {
 179    struct sk_buff *skb=NULL;
 180    struct packet_type *ptype;
 181    unsigned short type;
 182    unsigned char flag =0;
 183    unsigned char *to;
 184    int amount;
 185 
 186    /* try to grab some memory. */
 187    if (len > 0 && buff != NULL)
 188      {
 189         skb = malloc (sizeof (*skb) + len);
 190         if (skb != NULL)
 191           {
 192             skb->mem_len = sizeof (*skb) + len;
 193             skb->mem_addr = skb;
 194           }
 195      }
 196 
 197    /* firs we copy the packet into a buffer, and save it for later. */
 198    if (buff != NULL && skb != NULL)
 199      {
 200         if ( !(flags & IN_SKBUFF))
 201           {
 202              to = (unsigned char *)(skb+1);
 203              while (len > 0)
 204                {
 205                   amount = min (len, (unsigned long) dev->rmem_end -
 206                                 (unsigned long) buff);
 207                   memcpy (to, buff, amount);
 208                   len -= amount;
 209                   buff += amount;
 210                   to += amount;
 211                   if ((unsigned long)buff == dev->rmem_end)
 212                     buff = (unsigned char *)dev->rmem_start;
 213                }
 214           }
 215         else
 216           {
 217              free_s (skb->mem_addr, skb->mem_len);
 218              skb = (struct sk_buff *)buff;
 219           }
 220 
 221         skb->len = len;
 222         skb->dev = dev;
 223         skb->sk = NULL;
 224 
 225         /* now add it to the dev backlog. */
 226         cli();
 227         if (dev-> backlog == NULL)
 228           {
 229              skb->prev = skb;
 230              skb->next = skb;
 231              dev->backlog = skb;
 232           }
 233         else
 234           {
 235              skb ->prev = dev->backlog->prev;
 236              skb->next = dev->backlog;
 237              skb->next->prev = skb;
 238              skb->prev->next = skb;
 239           }
 240         sti();
 241         return (0);
 242      }
 243 
 244    if (skb != NULL) 
 245      free_s (skb->mem_addr, skb->mem_len);
 246 
 247    /* anything left to process? */
 248 
 249    if (dev->backlog == NULL)
 250      {
 251         if (buff == NULL)
 252           {
 253              sti();
 254              return (1);
 255           }
 256 
 257         if (skb != NULL)
 258           {
 259              sti();
 260              return (-1);
 261           }
 262 
 263         sti();
 264         printk ("dev_rint:Dropping packets due to lack of memory\n");
 265         return (1);
 266      }
 267 
 268    skb= dev->backlog;
 269    if (skb->next == skb)
 270      {
 271         dev->backlog = NULL;
 272      }
 273    else
 274      {
 275         dev->backlog = skb->next;
 276         skb->next->prev = skb->prev;
 277         skb->prev->next = skb->next;
 278      }
 279    sti();
 280 
 281    /* bump the pointer to the next structure. */
 282    skb->h.raw = (unsigned char *)(skb+1) + dev->hard_header_len;
 283    skb->len -= dev->hard_header_len;
 284 
 285    /* convert the type to an ethernet type. */
 286    type = dev->type_trans (skb, dev);
 287 
 288    /* if there get to be a lot of types we should changes this to
 289       a bunch of linked lists like we do for ip protocols. */
 290    for (ptype = ptype_base; ptype != NULL; ptype=ptype->next)
 291      {
 292         if (ptype->type == type)
 293           {
 294              struct sk_buff *skb2;
 295              /* copy the packet if we need to. */
 296              if (ptype->copy)
 297                {
 298                   skb2 = malloc (skb->mem_len);
 299                   if (skb2 == NULL) continue;
 300                   memcpy (skb2, skb, skb->mem_len);
 301                   skb2->mem_addr = skb2;
 302                }
 303              else
 304                {
 305                   skb2 = skb;
 306                   flag = 1;
 307                }
 308                
 309              ptype->func (skb2, dev, ptype);
 310           }
 311      }
 312 
 313    if (!flag)
 314      {
 315         PRINTK ("discarding packet type = %X\n", type);
 316         free_skb (skb, FREE_READ);
 317      }
 318 
 319      if (buff == NULL)
 320        return (0);
 321      else
 322        return (-1);
 323 }
 324 
 325 /* This routine is called when an device interface is ready to
 326    transmit a packet.  Buffer points to where the packet should
 327    be put, and the routine returns the length of the packet.  A
 328    length of zero is interrpreted to mean the transmit buffers
 329    are empty, and the transmitter should be shut down. */
 330 
 331 unsigned long
 332 dev_tint(unsigned char *buff,  struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 333 {
 334   int i;
 335   int tmp;
 336   struct sk_buff *skb;
 337   for (i=0; i < DEV_NUMBUFFS; i++)
 338     {
 339       while (dev->buffs[i]!=NULL)
 340         {
 341           cli();
 342           skb=dev->buffs[i];
 343           if (skb->next == skb)
 344             {
 345               dev->buffs[i] = NULL;
 346             }
 347           else
 348             {
 349               dev->buffs[i]=skb->next;
 350               skb->prev->next = skb->next;
 351               skb->next->prev = skb->prev;
 352             }
 353           skb->next = NULL;
 354           skb->prev = NULL;
 355           sti();
 356           tmp = skb->len;
 357           if (!skb->arp)
 358             {
 359                if (dev->rebuild_header (skb+1, dev))
 360                  {
 361                     skb->dev = dev;
 362                     arp_queue (skb);
 363                     continue;
 364                  }
 365             }
 366              
 367           if (tmp <= dev->mtu)
 368             {
 369                if (dev->send_packet != NULL)
 370                  {
 371                     dev->send_packet(skb, dev);
 372                  }
 373                if (buff != NULL)
 374                  memcpy (buff, skb + 1, tmp);
 375 
 376                PRINTK (">>\n");
 377                print_eth ((struct enet_header *)(skb+1));
 378             }
 379           else
 380             {
 381                printk ("**** bug len bigger than mtu. \n");
 382             }
 383 
 384           if (skb->free)
 385             {
 386                   free_skb(skb, FREE_WRITE);
 387             }
 388 
 389           if (tmp != 0)
 390             return (tmp);
 391         }
 392     }
 393   PRINTK ("dev_tint returning 0 \n");
 394   return (0);
 395 }
 396 

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