Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *
0004  * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
0005  */
0006 #include <linux/errno.h>
0007 #include <linux/types.h>
0008 #include <linux/socket.h>
0009 #include <linux/in.h>
0010 #include <linux/kernel.h>
0011 #include <linux/timer.h>
0012 #include <linux/string.h>
0013 #include <linux/sockios.h>
0014 #include <linux/net.h>
0015 #include <linux/gfp.h>
0016 #include <net/ax25.h>
0017 #include <linux/inet.h>
0018 #include <linux/netdevice.h>
0019 #include <linux/skbuff.h>
0020 #include <net/sock.h>
0021 #include <linux/fcntl.h>
0022 #include <linux/mm.h>
0023 #include <linux/interrupt.h>
0024 #include <net/rose.h>
0025 
0026 /*
0027  *  This procedure is passed a buffer descriptor for an iframe. It builds
0028  *  the rest of the control part of the frame and then writes it out.
0029  */
0030 static void rose_send_iframe(struct sock *sk, struct sk_buff *skb)
0031 {
0032     struct rose_sock *rose = rose_sk(sk);
0033 
0034     if (skb == NULL)
0035         return;
0036 
0037     skb->data[2] |= (rose->vr << 5) & 0xE0;
0038     skb->data[2] |= (rose->vs << 1) & 0x0E;
0039 
0040     rose_start_idletimer(sk);
0041 
0042     rose_transmit_link(skb, rose->neighbour);
0043 }
0044 
0045 void rose_kick(struct sock *sk)
0046 {
0047     struct rose_sock *rose = rose_sk(sk);
0048     struct sk_buff *skb, *skbn;
0049     unsigned short start, end;
0050 
0051     if (rose->state != ROSE_STATE_3)
0052         return;
0053 
0054     if (rose->condition & ROSE_COND_PEER_RX_BUSY)
0055         return;
0056 
0057     if (!skb_peek(&sk->sk_write_queue))
0058         return;
0059 
0060     start = (skb_peek(&rose->ack_queue) == NULL) ? rose->va : rose->vs;
0061     end   = (rose->va + sysctl_rose_window_size) % ROSE_MODULUS;
0062 
0063     if (start == end)
0064         return;
0065 
0066     rose->vs = start;
0067 
0068     /*
0069      * Transmit data until either we're out of data to send or
0070      * the window is full.
0071      */
0072 
0073     skb  = skb_dequeue(&sk->sk_write_queue);
0074 
0075     do {
0076         if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
0077             skb_queue_head(&sk->sk_write_queue, skb);
0078             break;
0079         }
0080 
0081         skb_set_owner_w(skbn, sk);
0082 
0083         /*
0084          * Transmit the frame copy.
0085          */
0086         rose_send_iframe(sk, skbn);
0087 
0088         rose->vs = (rose->vs + 1) % ROSE_MODULUS;
0089 
0090         /*
0091          * Requeue the original data frame.
0092          */
0093         skb_queue_tail(&rose->ack_queue, skb);
0094 
0095     } while (rose->vs != end &&
0096          (skb = skb_dequeue(&sk->sk_write_queue)) != NULL);
0097 
0098     rose->vl         = rose->vr;
0099     rose->condition &= ~ROSE_COND_ACK_PENDING;
0100 
0101     rose_stop_timer(sk);
0102 }
0103 
0104 /*
0105  * The following routines are taken from page 170 of the 7th ARRL Computer
0106  * Networking Conference paper, as is the whole state machine.
0107  */
0108 
0109 void rose_enquiry_response(struct sock *sk)
0110 {
0111     struct rose_sock *rose = rose_sk(sk);
0112 
0113     if (rose->condition & ROSE_COND_OWN_RX_BUSY)
0114         rose_write_internal(sk, ROSE_RNR);
0115     else
0116         rose_write_internal(sk, ROSE_RR);
0117 
0118     rose->vl         = rose->vr;
0119     rose->condition &= ~ROSE_COND_ACK_PENDING;
0120 
0121     rose_stop_timer(sk);
0122 }