mirror of https://gitee.com/openkylin/linux.git
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
578ce0468f
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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 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)
|
||||
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 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)
|
||||
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_) */
|
||||
|
|
Loading…
Reference in New Issue