Commit 578ce046 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-qualcomm-rmnet-stop-using-C-bit-fields'

Alex Elder says:

====================
net: qualcomm: rmnet: stop using C bit-fields

Version 6 is the same as version 5, but has been rebased on updated
net-next/master.  With any luck, the patches I'm sending out this
time won't contain garbage.

Version 5 of this series responds to a suggestion made by Alexander
Duyck, to determine the offset to the checksummed range of a packet
using skb_network_header_len() on patch 2.  I have added his
Reviewed-by tag to all (other) patches, and removed Bjorn's from
patch 2.

The change required some updates to the subsequent patches, and I
reordered some assignments in a minor way in the last patch.

I don't expect any more discussion on this series (but will respond
if there is any).  So at this point I would really appreciate it
if KS and/or Sean would offer a review, or at least acknowledge it.
I presume you two are able to independently test the code as well,
so I request that, and hope you are willing to do so.

Version 4 of this series is here:
  https://lore.kernel.org/netdev/20210315133455.1576188-1-elder@linaro.org


====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0f13b5e6 86ca860e
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -56,20 +56,22 @@ static void
__rmnet_map_ingress_handler(struct sk_buff *skb,
			    struct rmnet_port *port)
{
	struct rmnet_map_header *map_header = (void *)skb->data;
	struct rmnet_endpoint *ep;
	u16 len, pad;
	u8 mux_id;

	if (RMNET_MAP_GET_CD_BIT(skb)) {
	if (map_header->flags & MAP_CMD_FLAG) {
		/* Packet contains a MAP command (not data) */
		if (port->data_format & RMNET_FLAGS_INGRESS_MAP_COMMANDS)
			return rmnet_map_command(skb, port);

		goto free_skb;
	}

	mux_id = RMNET_MAP_GET_MUX_ID(skb);
	pad = RMNET_MAP_GET_PAD(skb);
	len = RMNET_MAP_GET_LENGTH(skb) - pad;
	mux_id = map_header->mux_id;
	pad = map_header->flags & MAP_PAD_LEN_MASK;
	len = ntohs(map_header->pkt_len) - pad;

	if (mux_id >= RMNET_MAX_LOGICAL_EP)
		goto free_skb;
+0 −12
Original line number Diff line number Diff line
@@ -32,18 +32,6 @@ enum rmnet_map_commands {
	RMNET_MAP_COMMAND_ENUM_LENGTH
};

#define RMNET_MAP_GET_MUX_ID(Y) (((struct rmnet_map_header *) \
				 (Y)->data)->mux_id)
#define RMNET_MAP_GET_CD_BIT(Y) (((struct rmnet_map_header *) \
				(Y)->data)->cd_bit)
#define RMNET_MAP_GET_PAD(Y) (((struct rmnet_map_header *) \
				(Y)->data)->pad_len)
#define RMNET_MAP_GET_CMD_START(Y) ((struct rmnet_map_control_command *) \
				    ((Y)->data + \
				      sizeof(struct rmnet_map_header)))
#define RMNET_MAP_GET_LENGTH(Y) (ntohs(((struct rmnet_map_header *) \
					(Y)->data)->pkt_len))

#define RMNET_MAP_COMMAND_REQUEST     0
#define RMNET_MAP_COMMAND_ACK         1
#define RMNET_MAP_COMMAND_UNSUPPORTED 2
+8 −3
Original line number Diff line number Diff line
@@ -12,12 +12,13 @@ static u8 rmnet_map_do_flow_control(struct sk_buff *skb,
				    struct rmnet_port *port,
				    int enable)
{
	struct rmnet_map_header *map_header = (void *)skb->data;
	struct rmnet_endpoint *ep;
	struct net_device *vnd;
	u8 mux_id;
	int r;

	mux_id = RMNET_MAP_GET_MUX_ID(skb);
	mux_id = map_header->mux_id;

	if (mux_id >= RMNET_MAX_LOGICAL_EP) {
		kfree_skb(skb);
@@ -49,6 +50,7 @@ static void rmnet_map_send_ack(struct sk_buff *skb,
			       unsigned char type,
			       struct rmnet_port *port)
{
	struct rmnet_map_header *map_header = (void *)skb->data;
	struct rmnet_map_control_command *cmd;
	struct net_device *dev = skb->dev;

@@ -58,7 +60,8 @@ static void rmnet_map_send_ack(struct sk_buff *skb,

	skb->protocol = htons(ETH_P_MAP);

	cmd = RMNET_MAP_GET_CMD_START(skb);
	/* Command data immediately follows the MAP header */
	cmd = (struct rmnet_map_control_command *)(map_header + 1);
	cmd->cmd_type = type & 0x03;

	netif_tx_lock(dev);
@@ -71,11 +74,13 @@ static void rmnet_map_send_ack(struct sk_buff *skb,
 */
void rmnet_map_command(struct sk_buff *skb, struct rmnet_port *port)
{
	struct rmnet_map_header *map_header = (void *)skb->data;
	struct rmnet_map_control_command *cmd;
	unsigned char command_name;
	unsigned char rc = 0;

	cmd = RMNET_MAP_GET_CMD_START(skb);
	/* Command data immediately follows the MAP header */
	cmd = (struct rmnet_map_control_command *)(map_header + 1);
	command_name = cmd->command_name;

	switch (command_name) {
+21 −35
Original line number Diff line number Diff line
@@ -197,22 +197,16 @@ rmnet_map_ipv4_ul_csum_header(void *iphdr,
			      struct rmnet_map_ul_csum_header *ul_header,
			      struct sk_buff *skb)
{
	struct iphdr *ip4h = (struct iphdr *)iphdr;
	__be16 *hdr = (__be16 *)ul_header, offset;
	struct iphdr *ip4h = iphdr;
	u16 val;

	offset = htons((__force u16)(skb_transport_header(skb) -
				     (unsigned char *)iphdr));
	ul_header->csum_start_offset = offset;
	ul_header->csum_insert_offset = skb->csum_offset;
	ul_header->csum_enabled = 1;
	val = MAP_CSUM_UL_ENABLED_FLAG;
	if (ip4h->protocol == IPPROTO_UDP)
		ul_header->udp_ind = 1;
	else
		ul_header->udp_ind = 0;
		val |= MAP_CSUM_UL_UDP_FLAG;
	val |= skb->csum_offset & MAP_CSUM_UL_OFFSET_MASK;

	/* Changing remaining fields to network order */
	hdr++;
	*hdr = htons((__force u16)*hdr);
	ul_header->csum_start_offset = htons(skb_network_header_len(skb));
	ul_header->csum_info = htons(val);

	skb->ip_summed = CHECKSUM_NONE;

@@ -239,23 +233,16 @@ rmnet_map_ipv6_ul_csum_header(void *ip6hdr,
			      struct rmnet_map_ul_csum_header *ul_header,
			      struct sk_buff *skb)
{
	struct ipv6hdr *ip6h = (struct ipv6hdr *)ip6hdr;
	__be16 *hdr = (__be16 *)ul_header, offset;

	offset = htons((__force u16)(skb_transport_header(skb) -
				     (unsigned char *)ip6hdr));
	ul_header->csum_start_offset = offset;
	ul_header->csum_insert_offset = skb->csum_offset;
	ul_header->csum_enabled = 1;
	struct ipv6hdr *ip6h = ip6hdr;
	u16 val;

	val = MAP_CSUM_UL_ENABLED_FLAG;
	if (ip6h->nexthdr == IPPROTO_UDP)
		ul_header->udp_ind = 1;
	else
		ul_header->udp_ind = 0;
		val |= MAP_CSUM_UL_UDP_FLAG;
	val |= skb->csum_offset & MAP_CSUM_UL_OFFSET_MASK;

	/* Changing remaining fields to network order */
	hdr++;
	*hdr = htons((__force u16)*hdr);
	ul_header->csum_start_offset = htons(skb_network_header_len(skb));
	ul_header->csum_info = htons(val);

	skb->ip_summed = CHECKSUM_NONE;

@@ -284,6 +271,7 @@ struct rmnet_map_header *rmnet_map_add_map_header(struct sk_buff *skb,
		return map_header;
	}

	BUILD_BUG_ON(MAP_PAD_LEN_MASK < 3);
	padding = ALIGN(map_datalen, 4) - map_datalen;

	if (padding == 0)
@@ -297,7 +285,8 @@ struct rmnet_map_header *rmnet_map_add_map_header(struct sk_buff *skb,

done:
	map_header->pkt_len = htons(map_datalen + padding);
	map_header->pad_len = padding & 0x3F;
	/* This is a data packet, so the CMD bit is 0 */
	map_header->flags = padding & MAP_PAD_LEN_MASK;

	return map_header;
}
@@ -319,7 +308,7 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb,
		return NULL;

	maph = (struct rmnet_map_header *)skb->data;
	packet_len = ntohs(maph->pkt_len) + sizeof(struct rmnet_map_header);
	packet_len = ntohs(maph->pkt_len) + sizeof(*maph);

	if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4)
		packet_len += sizeof(struct rmnet_map_dl_csum_trailer);
@@ -328,7 +317,7 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb,
		return NULL;

	/* Some hardware can send us empty frames. Catch them */
	if (ntohs(maph->pkt_len) == 0)
	if (!maph->pkt_len)
		return NULL;

	skbn = alloc_skb(packet_len + RMNET_MAP_DEAGGR_SPACING, GFP_ATOMIC);
@@ -361,7 +350,7 @@ int rmnet_map_checksum_downlink_packet(struct sk_buff *skb, u16 len)

	csum_trailer = (struct rmnet_map_dl_csum_trailer *)(skb->data + len);

	if (!csum_trailer->valid) {
	if (!(csum_trailer->flags & MAP_CSUM_DL_VALID_FLAG)) {
		priv->stats.csum_valid_unset++;
		return -EINVAL;
	}
@@ -421,10 +410,7 @@ void rmnet_map_checksum_uplink_packet(struct sk_buff *skb,
	}

sw_csum:
	ul_header->csum_start_offset = 0;
	ul_header->csum_insert_offset = 0;
	ul_header->csum_enabled = 0;
	ul_header->udp_ind = 0;
	memset(ul_header, 0, sizeof(*ul_header));

	priv->stats.csum_sw++;
}
+29 −36
Original line number Diff line number Diff line
@@ -6,50 +6,43 @@
#define _LINUX_IF_RMNET_H_

struct rmnet_map_header {
#if defined(__LITTLE_ENDIAN_BITFIELD)
	u8  pad_len:6;
	u8  reserved_bit:1;
	u8  cd_bit:1;
#elif defined (__BIG_ENDIAN_BITFIELD)
	u8  cd_bit:1;
	u8  reserved_bit:1;
	u8  pad_len:6;
#else
#error	"Please fix <asm/byteorder.h>"
#endif
	u8 flags;			/* MAP_CMD_FLAG, MAP_PAD_LEN_MASK */
	u8 mux_id;
	__be16 pkt_len;
	__be16 pkt_len;			/* Length of packet, including pad */
}  __aligned(1);

/* rmnet_map_header flags field:
 *  PAD_LEN:	number of pad bytes following packet data
 *  CMD:	1 = packet contains a MAP command; 0 = packet contains data
 */
#define MAP_PAD_LEN_MASK		GENMASK(5, 0)
#define MAP_CMD_FLAG			BIT(7)

struct rmnet_map_dl_csum_trailer {
	u8 reserved1;
#if defined(__LITTLE_ENDIAN_BITFIELD)
	u8  valid:1;
	u8  reserved2:7;
#elif defined (__BIG_ENDIAN_BITFIELD)
	u8  reserved2:7;
	u8  valid:1;
#else
#error	"Please fix <asm/byteorder.h>"
#endif
	u16 csum_start_offset;
	u16 csum_length;
	u8 flags;			/* MAP_CSUM_DL_VALID_FLAG */
	__be16 csum_start_offset;
	__be16 csum_length;
	__be16 csum_value;
} __aligned(1);

/* rmnet_map_dl_csum_trailer flags field:
 *  VALID:	1 = checksum and length valid; 0 = ignore them
 */
#define MAP_CSUM_DL_VALID_FLAG		BIT(0)

struct rmnet_map_ul_csum_header {
	__be16 csum_start_offset;
#if defined(__LITTLE_ENDIAN_BITFIELD)
	u16 csum_insert_offset:14;
	u16 udp_ind:1;
	u16 csum_enabled:1;
#elif defined (__BIG_ENDIAN_BITFIELD)
	u16 csum_enabled:1;
	u16 udp_ind:1;
	u16 csum_insert_offset:14;
#else
#error	"Please fix <asm/byteorder.h>"
#endif
	__be16 csum_info;		/* MAP_CSUM_UL_* */
} __aligned(1);

/* csum_info field:
 *  OFFSET:	where (offset in bytes) to insert computed checksum
 *  UDP:	1 = UDP checksum (zero checkum means no checksum)
 *  ENABLED:	1 = checksum computation requested
 */
#define MAP_CSUM_UL_OFFSET_MASK		GENMASK(13, 0)
#define MAP_CSUM_UL_UDP_FLAG		BIT(14)
#define MAP_CSUM_UL_ENABLED_FLAG	BIT(15)

#endif /* !(_LINUX_IF_RMNET_H_) */