Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fea93ece authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont Committed by David S. Miller
Browse files

Phonet: zero-copy GPRS TX



Send aligned pipe payload if requested to do so. Then, the socket buffer
needs not be fragmented anymore.

Signed-off-by: default avatarRémi Denis-Courmont <remi.denis-courmont@nokia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fc6a1107
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ struct pep_sock {
	u8			rx_fc;	/* RX flow control */
	u8			tx_fc;	/* TX flow control */
	u8			init_enable;	/* auto-enable at creation */
	u8			aligned;
};

static inline struct pep_sock *pep_sk(struct sock *sk)
@@ -139,6 +140,7 @@ enum {
	PN_PIPE_SB_NEGOTIATED_FC,
	PN_PIPE_SB_REQUIRED_FC_TX,
	PN_PIPE_SB_PREFERRED_FC_RX,
	PN_PIPE_SB_ALIGNED_DATA,
};

/* Phonet pipe flow control models */
+14 −2
Original line number Diff line number Diff line
@@ -444,6 +444,7 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb)
	struct sockaddr_pn dst;
	u16 peer_type;
	u8 pipe_handle, enabled, n_sb;
	u8 aligned = 0;

	if (!pskb_pull(skb, sizeof(*hdr) + 4))
		return -EINVAL;
@@ -482,6 +483,9 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb)
				return -EINVAL;
			peer_type = (peer_type & 0xff00) | data[0];
			break;
		case PN_PIPE_SB_ALIGNED_DATA:
			aligned = data[0] != 0;
			break;
		}
		n_sb--;
	}
@@ -513,6 +517,7 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb)
	newpn->rx_credits = 0;
	newpn->rx_fc = newpn->tx_fc = PN_LEGACY_FLOW_CONTROL;
	newpn->init_enable = enabled;
	newpn->aligned = aligned;

	BUG_ON(!skb_queue_empty(&newsk->sk_receive_queue));
	skb_queue_head(&newsk->sk_receive_queue, skb);
@@ -832,10 +837,14 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb)
		return -ENOBUFS;
	}

	skb_push(skb, 3);
	skb_push(skb, 3 + pn->aligned);
	skb_reset_transport_header(skb);
	ph = pnp_hdr(skb);
	ph->utid = 0;
	if (pn->aligned) {
		ph->message_id = PNS_PIPE_ALIGNED_DATA;
		ph->data[0] = 0; /* padding */
	} else
		ph->message_id = PNS_PIPE_DATA;
	ph->pipe_handle = pn->pipe_handle;

@@ -930,6 +939,9 @@ int pep_write(struct sock *sk, struct sk_buff *skb)
	struct sk_buff *rskb, *fs;
	int flen = 0;

	if (pep_sk(sk)->aligned)
		return pipe_skb_send(sk, skb);

	rskb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC);
	if (!rskb) {
		kfree_skb(skb);