void ax25_kick(ax25_cb *ax25)
{
    struct sk_buff *skb, *skbn;
    int last = 1;
    unsigned short start, end, next;

    if (ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4)
        return;

    if (ax25->condition & AX25_COND_PEER_RX_BUSY)
        return;

    if (skb_peek(&ax25->write_queue) == NULL)
        return;

    start = (skb_peek(&ax25->ack_queue) == NULL) ? ax25->va : ax25->vs;
    end   = (ax25->va + ax25->window) % ax25->modulus;

    if (start == end)
        return;

    /*
     * Transmit data until either we're out of data to send or
     * the window is full. Send a poll on the final I frame if
     * the window is filled.
     */

    /*
     * Dequeue the frame and copy it.
     * Check for race with ax25_clear_queues().
     */
    skb  = skb_dequeue(&ax25->write_queue);
    if (!skb)
        return;

    ax25->vs = start;

    do {
        if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
            skb_queue_head(&ax25->write_queue, skb);
            break;
        }

        if (skb->sk != NULL)
            skb_set_owner_w(skbn, skb->sk);

        next = (ax25->vs + 1) % ax25->modulus;
        last = (next == end);

        /*
         * Transmit the frame copy.
         * bke 960114: do not set the Poll bit on the last frame
         * in DAMA mode.
         */
        switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
        case AX25_PROTO_STD_SIMPLEX:
        case AX25_PROTO_STD_DUPLEX:
            ax25_send_iframe(ax25, skbn, (last) ? AX25_POLLON : AX25_POLLOFF);
            break;

#ifdef CONFIG_AX25_DAMA_SLAVE
        case AX25_PROTO_DAMA_SLAVE:
            ax25_send_iframe(ax25, skbn, AX25_POLLOFF);
            break;
#endif
        }

        ax25->vs = next;

        /*
         * Requeue the original data frame.
         */
        skb_queue_tail(&ax25->ack_queue, skb);

    } while (!last && (skb = skb_dequeue(&ax25->write_queue)) != NULL);

    ax25->condition &= ~AX25_COND_ACK_PENDING;

    if (!ax25_t1timer_running(ax25)) {
        ax25_stop_t3timer(ax25);
        ax25_calculate_t1(ax25);
        ax25_start_t1timer(ax25);
    }
}
Beispiel #2
0
void ax25_kick(ax25_cb *ax25)
{
	struct sk_buff *skb, *skbn;
	int last = 1;
	unsigned short start, end, next;

	del_timer(&ax25->timer);

	start = (skb_peek(&ax25->ack_queue) == NULL) ? ax25->va : ax25->vs;
	end   = (ax25->va + ax25->window) % ax25->modulus;

	if (!(ax25->condition & PEER_RX_BUSY_CONDITION) &&
	    start != end                                   &&
	    skb_peek(&ax25->write_queue) != NULL) {

		ax25->vs = start;

		/*
		 * Transmit data until either we're out of data to send or
		 * the window is full. Send a poll on the final I frame if
		 * the window is filled.
		 */

		/*
		 * Dequeue the frame and copy it.
		 */
		skb  = skb_dequeue(&ax25->write_queue);

		do {
			if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
				skb_queue_head(&ax25->write_queue, skb);
				break;
			}

			next = (ax25->vs + 1) % ax25->modulus;
#ifdef notdef
			last = (next == end) || skb_peek(&ax25->write_queue) == NULL;
#else
			last = (next == end);
#endif
			/*
			 * Transmit the frame copy.
			 * bke 960114: do not set the Poll bit on the last frame
			 * in DAMA mode.
			 */
			ax25_send_iframe(ax25, skbn, (last && !ax25->dama_slave) ? POLLON : POLLOFF);

			ax25->vs = next;

			/*
			 * Requeue the original data frame.
			 */
			skb_queue_tail(&ax25->ack_queue, skb);
#ifdef notdef
		} while (!last);
#else
		} while (!last && (skb = skb_dequeue(&ax25->write_queue)) != NULL);
#endif
		ax25->condition &= ~ACK_PENDING_CONDITION;

		if (ax25->t1timer == 0) {
			ax25->t3timer = 0;
			ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
		}
	}