linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields
@ 2021-03-15 21:51 Alex Elder
  2021-03-15 21:51 ` [PATCH net-next v6 1/6] net: qualcomm: rmnet: mark trailer field endianness Alex Elder
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Alex Elder @ 2021-03-15 21:51 UTC (permalink / raw)
  To: subashab, stranche, davem, kuba
  Cc: sharathv, bjorn.andersson, evgreen, cpratapa, David.Laight,
	olteanv, alexander.duyck, elder, netdev, linux-kernel

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

					-Alex


Alex Elder (6):
  net: qualcomm: rmnet: mark trailer field endianness
  net: qualcomm: rmnet: simplify some byte order logic
  net: qualcomm: rmnet: kill RMNET_MAP_GET_*() accessor macros
  net: qualcomm: rmnet: use masks instead of C bit-fields
  net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum trailer
  net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum header

 .../ethernet/qualcomm/rmnet/rmnet_handlers.c  | 10 +--
 .../net/ethernet/qualcomm/rmnet/rmnet_map.h   | 12 ----
 .../qualcomm/rmnet/rmnet_map_command.c        | 11 +++-
 .../ethernet/qualcomm/rmnet/rmnet_map_data.c  | 56 ++++++----------
 include/linux/if_rmnet.h                      | 65 +++++++++----------
 5 files changed, 64 insertions(+), 90 deletions(-)

-- 
2.27.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH net-next v6 1/6] net: qualcomm: rmnet: mark trailer field endianness
  2021-03-15 21:51 [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields Alex Elder
@ 2021-03-15 21:51 ` Alex Elder
  2021-03-15 21:51 ` [PATCH net-next v6 2/6] net: qualcomm: rmnet: simplify some byte order logic Alex Elder
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Alex Elder @ 2021-03-15 21:51 UTC (permalink / raw)
  To: subashab, stranche, davem, kuba
  Cc: sharathv, bjorn.andersson, evgreen, cpratapa, David.Laight,
	olteanv, alexander.duyck, elder, netdev, linux-kernel,
	Alexander Duyck

The fields in the checksum trailer structure used for QMAP protocol
RX packets are all big-endian format, so define them that way.

It turns out these fields are never actually used by the RMNet code.
The start offset is always assumed to be zero, and the length is
taken from the other packet headers.  So making these fields
explicitly big endian has no effect on the behavior of the code.

Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
---
 include/linux/if_rmnet.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/if_rmnet.h b/include/linux/if_rmnet.h
index 9661416a9bb47..8c7845baf3837 100644
--- a/include/linux/if_rmnet.h
+++ b/include/linux/if_rmnet.h
@@ -32,8 +32,8 @@ struct rmnet_map_dl_csum_trailer {
 #else
 #error	"Please fix <asm/byteorder.h>"
 #endif
-	u16 csum_start_offset;
-	u16 csum_length;
+	__be16 csum_start_offset;
+	__be16 csum_length;
 	__be16 csum_value;
 } __aligned(1);
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next v6 2/6] net: qualcomm: rmnet: simplify some byte order logic
  2021-03-15 21:51 [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields Alex Elder
  2021-03-15 21:51 ` [PATCH net-next v6 1/6] net: qualcomm: rmnet: mark trailer field endianness Alex Elder
@ 2021-03-15 21:51 ` Alex Elder
  2021-03-15 21:51 ` [PATCH net-next v6 3/6] net: qualcomm: rmnet: kill RMNET_MAP_GET_*() accessor macros Alex Elder
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Alex Elder @ 2021-03-15 21:51 UTC (permalink / raw)
  To: subashab, stranche, davem, kuba
  Cc: sharathv, bjorn.andersson, evgreen, cpratapa, David.Laight,
	olteanv, alexander.duyck, elder, netdev, linux-kernel

In rmnet_map_ipv4_ul_csum_header() and rmnet_map_ipv6_ul_csum_header()
the offset within a packet at which checksumming should commence is
calculated.  This calculation involves byte swapping and a forced type
conversion that makes it hard to understand.

Simplify this by computing the offset in host byte order, then
converting the result when assigning it into the header field.

Signed-off-by: Alex Elder <elder@linaro.org>
---
v5: - Use skb_network_header_len() to decide the checksum offset.

 .../net/ethernet/qualcomm/rmnet/rmnet_map_data.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
index 21d38167f9618..0bfe69698b278 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
@@ -197,12 +197,10 @@ 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;
+	__be16 *hdr = (__be16 *)ul_header;
+	struct iphdr *ip4h = iphdr;
 
-	offset = htons((__force u16)(skb_transport_header(skb) -
-				     (unsigned char *)iphdr));
-	ul_header->csum_start_offset = offset;
+	ul_header->csum_start_offset = htons(skb_network_header_len(skb));
 	ul_header->csum_insert_offset = skb->csum_offset;
 	ul_header->csum_enabled = 1;
 	if (ip4h->protocol == IPPROTO_UDP)
@@ -239,12 +237,10 @@ 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;
+	__be16 *hdr = (__be16 *)ul_header;
+	struct ipv6hdr *ip6h = ip6hdr;
 
-	offset = htons((__force u16)(skb_transport_header(skb) -
-				     (unsigned char *)ip6hdr));
-	ul_header->csum_start_offset = offset;
+	ul_header->csum_start_offset = htons(skb_network_header_len(skb));
 	ul_header->csum_insert_offset = skb->csum_offset;
 	ul_header->csum_enabled = 1;
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next v6 3/6] net: qualcomm: rmnet: kill RMNET_MAP_GET_*() accessor macros
  2021-03-15 21:51 [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields Alex Elder
  2021-03-15 21:51 ` [PATCH net-next v6 1/6] net: qualcomm: rmnet: mark trailer field endianness Alex Elder
  2021-03-15 21:51 ` [PATCH net-next v6 2/6] net: qualcomm: rmnet: simplify some byte order logic Alex Elder
@ 2021-03-15 21:51 ` Alex Elder
  2021-03-15 21:51 ` [PATCH net-next v6 4/6] net: qualcomm: rmnet: use masks instead of C bit-fields Alex Elder
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Alex Elder @ 2021-03-15 21:51 UTC (permalink / raw)
  To: subashab, stranche, davem, kuba
  Cc: sharathv, bjorn.andersson, evgreen, cpratapa, David.Laight,
	olteanv, alexander.duyck, elder, netdev, linux-kernel,
	Alexander Duyck

The following macros, defined in "rmnet_map.h", assume a socket
buffer is provided as an argument without any real indication this
is the case.
    RMNET_MAP_GET_MUX_ID()
    RMNET_MAP_GET_CD_BIT()
    RMNET_MAP_GET_PAD()
    RMNET_MAP_GET_CMD_START()
    RMNET_MAP_GET_LENGTH()
What they hide is pretty trivial accessing of fields in a structure,
and it's much clearer to see this if we do these accesses directly.

So rather than using these accessor macros, assign a local
variable of the map header pointer type to the socket buffer data
pointer, and derereference that pointer variable.

In "rmnet_map_data.c", use sizeof(object) rather than sizeof(type)
in one spot.  Also, there's no need to byte swap 0; it's all zeros
irrespective of endianness.

Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
---
 drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c | 10 ++++++----
 drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h      | 12 ------------
 .../net/ethernet/qualcomm/rmnet/rmnet_map_command.c  | 11 ++++++++---
 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c |  4 ++--
 4 files changed, 16 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
index 3d00b32323084..2a6b2a609884c 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
@@ -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->cd_bit) {
+		/* 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->pad_len;
+	len = ntohs(map_header->pkt_len) - pad;
 
 	if (mux_id >= RMNET_MAX_LOGICAL_EP)
 		goto free_skb;
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h
index 576501db2a0bc..2aea153f42473 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h
@@ -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
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c
index beaee49621287..add0f5ade2e61 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c
@@ -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) {
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
index 0bfe69698b278..3af68368fc315 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
@@ -315,7 +315,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);
@@ -324,7 +324,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);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next v6 4/6] net: qualcomm: rmnet: use masks instead of C bit-fields
  2021-03-15 21:51 [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields Alex Elder
                   ` (2 preceding siblings ...)
  2021-03-15 21:51 ` [PATCH net-next v6 3/6] net: qualcomm: rmnet: kill RMNET_MAP_GET_*() accessor macros Alex Elder
@ 2021-03-15 21:51 ` Alex Elder
  2021-03-15 21:51 ` [PATCH net-next v6 5/6] net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum trailer Alex Elder
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Alex Elder @ 2021-03-15 21:51 UTC (permalink / raw)
  To: subashab, stranche, davem, kuba
  Cc: sharathv, bjorn.andersson, evgreen, cpratapa, David.Laight,
	olteanv, alexander.duyck, elder, netdev, linux-kernel,
	Alexander Duyck

The actual layout of bits defined in C bit-fields (e.g. int foo : 3)
is implementation-defined.  Structures defined in <linux/if_rmnet.h>
address this by specifying all bit-fields twice, to cover two
possible layouts.

I think this pattern is repetitive and noisy, and I find the whole
notion of compiler "bitfield endianness" to be non-intuitive.

Stop using C bit-fields for the command/data flag and the pad length
fields in the rmnet_map structure, and define a single-byte flags
field instead.  Define a mask for the single-bit "command" flag,
and another mask for the encoded pad length.  The content of both
fields can be accessed using a simple bitwise AND operation.

Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
---
v4: - Don't use u8_get_bits() to access the pad length
    - Added BUILD_BUG_ON() to ensure field width is adequate
v3: - Use BIT(x) and don't use u8_get_bits() for the command flag

 .../ethernet/qualcomm/rmnet/rmnet_handlers.c  |  4 ++--
 .../ethernet/qualcomm/rmnet/rmnet_map_data.c  |  4 +++-
 include/linux/if_rmnet.h                      | 23 ++++++++-----------
 3 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
index 2a6b2a609884c..0be5ac7ab2617 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
@@ -61,7 +61,7 @@ __rmnet_map_ingress_handler(struct sk_buff *skb,
 	u16 len, pad;
 	u8 mux_id;
 
-	if (map_header->cd_bit) {
+	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);
@@ -70,7 +70,7 @@ __rmnet_map_ingress_handler(struct sk_buff *skb,
 	}
 
 	mux_id = map_header->mux_id;
-	pad = map_header->pad_len;
+	pad = map_header->flags & MAP_PAD_LEN_MASK;
 	len = ntohs(map_header->pkt_len) - pad;
 
 	if (mux_id >= RMNET_MAX_LOGICAL_EP)
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
index 3af68368fc315..e7d0394cb2979 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
@@ -280,6 +280,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)
@@ -293,7 +294,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;
 }
diff --git a/include/linux/if_rmnet.h b/include/linux/if_rmnet.h
index 8c7845baf3837..a02f0a3df1d9a 100644
--- a/include/linux/if_rmnet.h
+++ b/include/linux/if_rmnet.h
@@ -6,21 +6,18 @@
 #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  mux_id;
-	__be16 pkt_len;
+	u8 flags;			/* MAP_CMD_FLAG, MAP_PAD_LEN_MASK */
+	u8 mux_id;
+	__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)
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next v6 5/6] net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum trailer
  2021-03-15 21:51 [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields Alex Elder
                   ` (3 preceding siblings ...)
  2021-03-15 21:51 ` [PATCH net-next v6 4/6] net: qualcomm: rmnet: use masks instead of C bit-fields Alex Elder
@ 2021-03-15 21:51 ` Alex Elder
  2021-03-15 21:51 ` [PATCH net-next v6 6/6] net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum header Alex Elder
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Alex Elder @ 2021-03-15 21:51 UTC (permalink / raw)
  To: subashab, stranche, davem, kuba
  Cc: sharathv, bjorn.andersson, evgreen, cpratapa, David.Laight,
	olteanv, alexander.duyck, elder, netdev, linux-kernel,
	Alexander Duyck

Replace the use of C bit-fields in the rmnet_map_dl_csum_trailer
structure with a single one-byte field, using constant field masks
to encode or get at embedded values.

Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
---
v3: - Use BIT(x) and don't use u8_get_bits() for the checksum valid flag

 .../ethernet/qualcomm/rmnet/rmnet_map_data.c    |  2 +-
 include/linux/if_rmnet.h                        | 17 +++++++----------
 2 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
index e7d0394cb2979..c336c17e01fe4 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
@@ -359,7 +359,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;
 	}
diff --git a/include/linux/if_rmnet.h b/include/linux/if_rmnet.h
index a02f0a3df1d9a..941997df9e088 100644
--- a/include/linux/if_rmnet.h
+++ b/include/linux/if_rmnet.h
@@ -19,21 +19,18 @@ struct rmnet_map_header {
 #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
+	u8 reserved1;
+	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)
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next v6 6/6] net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum header
  2021-03-15 21:51 [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields Alex Elder
                   ` (4 preceding siblings ...)
  2021-03-15 21:51 ` [PATCH net-next v6 5/6] net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum trailer Alex Elder
@ 2021-03-15 21:51 ` Alex Elder
  2021-03-16  2:38 ` [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields subashab
  2021-03-16  4:00 ` patchwork-bot+netdevbpf
  7 siblings, 0 replies; 9+ messages in thread
From: Alex Elder @ 2021-03-15 21:51 UTC (permalink / raw)
  To: subashab, stranche, davem, kuba
  Cc: sharathv, bjorn.andersson, evgreen, cpratapa, David.Laight,
	olteanv, alexander.duyck, elder, netdev, linux-kernel,
	Alexander Duyck

Replace the use of C bit-fields in the rmnet_map_ul_csum_header
structure with a single two-byte (big endian) structure member,
and use masks to encode or get values within it.  The content of
these fields can be accessed using simple bitwise AND and OR
operations on the (host byte order) value of the new structure
member.

Previously rmnet_map_ipv4_ul_csum_header() would update C bit-field
values in host byte order, then forcibly fix their byte order using
a combination of byte swap operations and types.

Instead, just compute the value that needs to go into the new
structure member and save it with a simple byte-order conversion.

Make similar simplifications in rmnet_map_ipv6_ul_csum_header().

Finally, in rmnet_map_checksum_uplink_packet() a set of assignments
zeroes every field in the upload checksum header.  Replace that with
a single memset() operation.

Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
---
v5: - Assign checksum start offset a little later (with csum_info)
v4: - Don't use u16_get_bits() to access the checksum field offset
v3: - Use BIT(x) and don't use u16_get_bits() for single-bit flags
v2: - Fixed to use u16_encode_bits() instead of be16_encode_bits()

 .../ethernet/qualcomm/rmnet/rmnet_map_data.c  | 38 +++++++------------
 include/linux/if_rmnet.h                      | 21 +++++-----
 2 files changed, 23 insertions(+), 36 deletions(-)

diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
index c336c17e01fe4..0ac2ff828320c 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
@@ -197,20 +197,16 @@ rmnet_map_ipv4_ul_csum_header(void *iphdr,
 			      struct rmnet_map_ul_csum_header *ul_header,
 			      struct sk_buff *skb)
 {
-	__be16 *hdr = (__be16 *)ul_header;
 	struct iphdr *ip4h = iphdr;
+	u16 val;
 
-	ul_header->csum_start_offset = htons(skb_network_header_len(skb));
-	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;
 
@@ -237,21 +233,16 @@ rmnet_map_ipv6_ul_csum_header(void *ip6hdr,
 			      struct rmnet_map_ul_csum_header *ul_header,
 			      struct sk_buff *skb)
 {
-	__be16 *hdr = (__be16 *)ul_header;
 	struct ipv6hdr *ip6h = ip6hdr;
+	u16 val;
 
-	ul_header->csum_start_offset = htons(skb_network_header_len(skb));
-	ul_header->csum_insert_offset = skb->csum_offset;
-	ul_header->csum_enabled = 1;
-
+	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;
 
@@ -419,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++;
 }
diff --git a/include/linux/if_rmnet.h b/include/linux/if_rmnet.h
index 941997df9e088..4efb537f57f31 100644
--- a/include/linux/if_rmnet.h
+++ b/include/linux/if_rmnet.h
@@ -33,17 +33,16 @@ struct rmnet_map_dl_csum_trailer {
 
 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_) */
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields
  2021-03-15 21:51 [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields Alex Elder
                   ` (5 preceding siblings ...)
  2021-03-15 21:51 ` [PATCH net-next v6 6/6] net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum header Alex Elder
@ 2021-03-16  2:38 ` subashab
  2021-03-16  4:00 ` patchwork-bot+netdevbpf
  7 siblings, 0 replies; 9+ messages in thread
From: subashab @ 2021-03-16  2:38 UTC (permalink / raw)
  To: Alex Elder
  Cc: stranche, davem, kuba, sharathv, bjorn.andersson, evgreen,
	cpratapa, David.Laight, olteanv, alexander.duyck, elder, netdev,
	linux-kernel

On 2021-03-15 15:51, Alex Elder wrote:
> 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
> 
> 					-Alex
> 
> 
> Alex Elder (6):
>   net: qualcomm: rmnet: mark trailer field endianness
>   net: qualcomm: rmnet: simplify some byte order logic
>   net: qualcomm: rmnet: kill RMNET_MAP_GET_*() accessor macros
>   net: qualcomm: rmnet: use masks instead of C bit-fields
>   net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum 
> trailer
>   net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum header
> 
>  .../ethernet/qualcomm/rmnet/rmnet_handlers.c  | 10 +--
>  .../net/ethernet/qualcomm/rmnet/rmnet_map.h   | 12 ----
>  .../qualcomm/rmnet/rmnet_map_command.c        | 11 +++-
>  .../ethernet/qualcomm/rmnet/rmnet_map_data.c  | 56 ++++++----------
>  include/linux/if_rmnet.h                      | 65 +++++++++----------
>  5 files changed, 64 insertions(+), 90 deletions(-)

For the series

Reviewed-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields
  2021-03-15 21:51 [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields Alex Elder
                   ` (6 preceding siblings ...)
  2021-03-16  2:38 ` [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields subashab
@ 2021-03-16  4:00 ` patchwork-bot+netdevbpf
  7 siblings, 0 replies; 9+ messages in thread
From: patchwork-bot+netdevbpf @ 2021-03-16  4:00 UTC (permalink / raw)
  To: Alex Elder
  Cc: subashab, stranche, davem, kuba, sharathv, bjorn.andersson,
	evgreen, cpratapa, David.Laight, olteanv, alexander.duyck, elder,
	netdev, linux-kernel

Hello:

This series was applied to netdev/net-next.git (refs/heads/master):

On Mon, 15 Mar 2021 16:51:45 -0500 you wrote:
> 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.
> 
> [...]

Here is the summary with links:
  - [net-next,v6,1/6] net: qualcomm: rmnet: mark trailer field endianness
    https://git.kernel.org/netdev/net-next/c/45f3a13c8166
  - [net-next,v6,2/6] net: qualcomm: rmnet: simplify some byte order logic
    https://git.kernel.org/netdev/net-next/c/50c62a111c48
  - [net-next,v6,3/6] net: qualcomm: rmnet: kill RMNET_MAP_GET_*() accessor macros
    https://git.kernel.org/netdev/net-next/c/9d131d044f89
  - [net-next,v6,4/6] net: qualcomm: rmnet: use masks instead of C bit-fields
    https://git.kernel.org/netdev/net-next/c/16653c16d282
  - [net-next,v6,5/6] net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum trailer
    https://git.kernel.org/netdev/net-next/c/cc1b21ba6251
  - [net-next,v6,6/6] net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum header
    https://git.kernel.org/netdev/net-next/c/86ca860e12ec

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-03-16  4:01 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-15 21:51 [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields Alex Elder
2021-03-15 21:51 ` [PATCH net-next v6 1/6] net: qualcomm: rmnet: mark trailer field endianness Alex Elder
2021-03-15 21:51 ` [PATCH net-next v6 2/6] net: qualcomm: rmnet: simplify some byte order logic Alex Elder
2021-03-15 21:51 ` [PATCH net-next v6 3/6] net: qualcomm: rmnet: kill RMNET_MAP_GET_*() accessor macros Alex Elder
2021-03-15 21:51 ` [PATCH net-next v6 4/6] net: qualcomm: rmnet: use masks instead of C bit-fields Alex Elder
2021-03-15 21:51 ` [PATCH net-next v6 5/6] net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum trailer Alex Elder
2021-03-15 21:51 ` [PATCH net-next v6 6/6] net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum header Alex Elder
2021-03-16  2:38 ` [PATCH net-next v6 0/6] net: qualcomm: rmnet: stop using C bit-fields subashab
2021-03-16  4:00 ` patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).