/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * This procedure is passed a buffer descriptor for an iframe. It builds * the rest of the control part of the frame and then writes it out. */ static void rose_send_iframe(struct sock *sk, struct sk_buff *skb) { struct rose_sock *rose = rose_sk(sk); if (skb == NULL) return; skb->data[2] |= (rose->vr << 5) & 0xE0; skb->data[2] |= (rose->vs << 1) & 0x0E; rose_start_idletimer(sk); rose_transmit_link(skb, rose->neighbour); } void rose_kick(struct sock *sk) { struct rose_sock *rose = rose_sk(sk); struct sk_buff *skb, *skbn; unsigned short start, end; if (rose->state != ROSE_STATE_3) return; if (rose->condition & ROSE_COND_PEER_RX_BUSY) return; if (!skb_peek(&sk->sk_write_queue)) return; start = (skb_peek(&rose->ack_queue) == NULL) ? rose->va : rose->vs; end = (rose->va + sysctl_rose_window_size) % ROSE_MODULUS; if (start == end) return; rose->vs = start; /* * Transmit data until either we're out of data to send or * the window is full. */ skb = skb_dequeue(&sk->sk_write_queue); do { if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { skb_queue_head(&sk->sk_write_queue, skb); break; } skb_set_owner_w(skbn, sk); /* * Transmit the frame copy. */ rose_send_iframe(sk, skbn); rose->vs = (rose->vs + 1) % ROSE_MODULUS; /* * Requeue the original data frame. */ skb_queue_tail(&rose->ack_queue, skb); } while (rose->vs != end && (skb = skb_dequeue(&sk->sk_write_queue)) != NULL); rose->vl = rose->vr; rose->condition &= ~ROSE_COND_ACK_PENDING; rose_stop_timer(sk); } /* * The following routines are taken from page 170 of the 7th ARRL Computer * Networking Conference paper, as is the whole state machine. */ void rose_enquiry_response(struct sock *sk) { struct rose_sock *rose = rose_sk(sk); if (rose->condition & ROSE_COND_OWN_RX_BUSY) rose_write_internal(sk, ROSE_RNR); else rose_write_internal(sk, ROSE_RR); rose->vl = rose->vr; rose->condition &= ~ROSE_COND_ACK_PENDING; rose_stop_timer(sk); } ='2'>2space:mode:
authorDan Carpenter <dan.carpenter@oracle.com>2017-02-07 16:15:27 +0300
committerDavid S. Miller <davem@davemloft.net>2017-02-08 13:27:06 -0500
commitff4cf0e5ce952488074aa7f47734af1794f55fbc (patch)
treea8558eaf3e54f9a65ab9f11f5755c192883a01f0
parent3efa70d78f218e4c9276b0bac0545e5184c1c47b (diff)
net: dsa: bcm_sf2: cleanup bcm_sf2_cfp_rule_get() a little
This patch doesn't affect how the code works. My static checker complains that the mask and shift doesn't make sense because 0xffffff << 16 goes beyond the end of 32 bits. It should be 0xffff instead but the existing code won't cause runtime bugs. Also the casting here is not needed and not consistent with the rest of the code. Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>