Commit 16653c16 authored by Alex Elder's avatar Alex Elder Committed by David S. Miller

net: qualcomm: rmnet: use masks instead of C bit-fields

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: default avatarAlex Elder <elder@linaro.org>
Reviewed-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: default avatarAlexander Duyck <alexanderduyck@fb.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9d131d04
...@@ -61,7 +61,7 @@ __rmnet_map_ingress_handler(struct sk_buff *skb, ...@@ -61,7 +61,7 @@ __rmnet_map_ingress_handler(struct sk_buff *skb,
u16 len, pad; u16 len, pad;
u8 mux_id; u8 mux_id;
if (map_header->cd_bit) { if (map_header->flags & MAP_CMD_FLAG) {
/* Packet contains a MAP command (not data) */ /* Packet contains a MAP command (not data) */
if (port->data_format & RMNET_FLAGS_INGRESS_MAP_COMMANDS) if (port->data_format & RMNET_FLAGS_INGRESS_MAP_COMMANDS)
return rmnet_map_command(skb, port); return rmnet_map_command(skb, port);
...@@ -70,7 +70,7 @@ __rmnet_map_ingress_handler(struct sk_buff *skb, ...@@ -70,7 +70,7 @@ __rmnet_map_ingress_handler(struct sk_buff *skb,
} }
mux_id = map_header->mux_id; 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; len = ntohs(map_header->pkt_len) - pad;
if (mux_id >= RMNET_MAX_LOGICAL_EP) if (mux_id >= RMNET_MAX_LOGICAL_EP)
......
...@@ -280,6 +280,7 @@ struct rmnet_map_header *rmnet_map_add_map_header(struct sk_buff *skb, ...@@ -280,6 +280,7 @@ struct rmnet_map_header *rmnet_map_add_map_header(struct sk_buff *skb,
return map_header; return map_header;
} }
BUILD_BUG_ON(MAP_PAD_LEN_MASK < 3);
padding = ALIGN(map_datalen, 4) - map_datalen; padding = ALIGN(map_datalen, 4) - map_datalen;
if (padding == 0) if (padding == 0)
...@@ -293,7 +294,8 @@ struct rmnet_map_header *rmnet_map_add_map_header(struct sk_buff *skb, ...@@ -293,7 +294,8 @@ struct rmnet_map_header *rmnet_map_add_map_header(struct sk_buff *skb,
done: done:
map_header->pkt_len = htons(map_datalen + padding); 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; return map_header;
} }
......
...@@ -6,21 +6,18 @@ ...@@ -6,21 +6,18 @@
#define _LINUX_IF_RMNET_H_ #define _LINUX_IF_RMNET_H_
struct rmnet_map_header { struct rmnet_map_header {
#if defined(__LITTLE_ENDIAN_BITFIELD) u8 flags; /* MAP_CMD_FLAG, MAP_PAD_LEN_MASK */
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; u8 mux_id;
__be16 pkt_len; __be16 pkt_len; /* Length of packet, including pad */
} __aligned(1); } __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 { struct rmnet_map_dl_csum_trailer {
u8 reserved1; u8 reserved1;
#if defined(__LITTLE_ENDIAN_BITFIELD) #if defined(__LITTLE_ENDIAN_BITFIELD)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment