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

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