linux-old/net/rose/rose_out.c
<<
>>
Prefs
   1/*
   2 *      ROSE release 003
   3 *
   4 *      This code REQUIRES 2.1.15 or higher/ NET3.038
   5 *
   6 *      This module:
   7 *              This module is free software; you can redistribute it and/or
   8 *              modify it under the terms of the GNU General Public License
   9 *              as published by the Free Software Foundation; either version
  10 *              2 of the License, or (at your option) any later version.
  11 *
  12 *      History
  13 *      ROSE 001        Jonathan(G4KLX) Cloned from nr_out.c
  14 *      ROSE 003        Jonathan(G4KLX) New timer architecture.
  15 *                                      Removed M bit processing.
  16 */
  17
  18#include <linux/errno.h>
  19#include <linux/types.h>
  20#include <linux/socket.h>
  21#include <linux/in.h>
  22#include <linux/kernel.h>
  23#include <linux/sched.h>
  24#include <linux/timer.h>
  25#include <linux/string.h>
  26#include <linux/sockios.h>
  27#include <linux/net.h>
  28#include <net/ax25.h>
  29#include <linux/inet.h>
  30#include <linux/netdevice.h>
  31#include <linux/skbuff.h>
  32#include <net/sock.h>
  33#include <asm/segment.h>
  34#include <asm/system.h>
  35#include <linux/fcntl.h>
  36#include <linux/mm.h>
  37#include <linux/interrupt.h>
  38#include <net/rose.h>
  39
  40/* 
  41 *      This procedure is passed a buffer descriptor for an iframe. It builds
  42 *      the rest of the control part of the frame and then writes it out.
  43 */
  44static void rose_send_iframe(struct sock *sk, struct sk_buff *skb)
  45{
  46        if (skb == NULL)
  47                return;
  48
  49        skb->data[2] |= (sk->protinfo.rose->vr << 5) & 0xE0;
  50        skb->data[2] |= (sk->protinfo.rose->vs << 1) & 0x0E;
  51
  52        rose_start_idletimer(sk);
  53
  54        rose_transmit_link(skb, sk->protinfo.rose->neighbour);  
  55}
  56
  57void rose_kick(struct sock *sk)
  58{
  59        struct sk_buff *skb, *skbn;
  60        unsigned short start, end;
  61
  62        if (sk->protinfo.rose->state != ROSE_STATE_3)
  63                return;
  64
  65        if (sk->protinfo.rose->condition & ROSE_COND_PEER_RX_BUSY)
  66                return;
  67
  68        if (skb_peek(&sk->write_queue) == NULL)
  69                return;
  70
  71        start = (skb_peek(&sk->protinfo.rose->ack_queue) == NULL) ? sk->protinfo.rose->va : sk->protinfo.rose->vs;
  72        end   = (sk->protinfo.rose->va + sysctl_rose_window_size) % ROSE_MODULUS;
  73
  74        if (start == end)
  75                return;
  76
  77        sk->protinfo.rose->vs = start;
  78
  79        /*
  80         * Transmit data until either we're out of data to send or
  81         * the window is full.
  82         */
  83
  84        skb  = skb_dequeue(&sk->write_queue);
  85
  86        do {
  87                if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
  88                        skb_queue_head(&sk->write_queue, skb);
  89                        break;
  90                }
  91
  92                skb_set_owner_w(skbn, sk);
  93
  94                /*
  95                 * Transmit the frame copy.
  96                 */
  97                rose_send_iframe(sk, skbn);
  98
  99                sk->protinfo.rose->vs = (sk->protinfo.rose->vs + 1) % ROSE_MODULUS;
 100
 101                /*
 102                 * Requeue the original data frame.
 103                 */
 104                skb_queue_tail(&sk->protinfo.rose->ack_queue, skb);
 105
 106        } while (sk->protinfo.rose->vs != end && (skb = skb_dequeue(&sk->write_queue)) != NULL);
 107
 108        sk->protinfo.rose->vl         = sk->protinfo.rose->vr;
 109        sk->protinfo.rose->condition &= ~ROSE_COND_ACK_PENDING;
 110
 111        rose_stop_timer(sk);
 112}
 113
 114/*
 115 * The following routines are taken from page 170 of the 7th ARRL Computer
 116 * Networking Conference paper, as is the whole state machine.
 117 */
 118
 119void rose_enquiry_response(struct sock *sk)
 120{
 121        if (sk->protinfo.rose->condition & ROSE_COND_OWN_RX_BUSY)
 122                rose_write_internal(sk, ROSE_RNR);
 123        else
 124                rose_write_internal(sk, ROSE_RR);
 125
 126        sk->protinfo.rose->vl         = sk->protinfo.rose->vr;
 127        sk->protinfo.rose->condition &= ~ROSE_COND_ACK_PENDING;
 128
 129        rose_stop_timer(sk);
 130}
 131
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.