Message ID | 1613079324-20166-3-git-send-email-sharathv@codeaurora.org |
---|---|
State | New |
Headers | show |
Series | net:qualcomm:rmnet:Enable Mapv5. | expand |
On Fri, 12 Feb 2021 03:05:23 +0530 Sharath Chandra Vurukala wrote: > +/* MAP CSUM headers */ > +struct rmnet_map_v5_csum_header { > + u8 next_hdr:1; > + u8 header_type:7; > + u8 hw_reserved:5; > + u8 priority:1; > + u8 hw_reserved_bit:1; > + u8 csum_valid_required:1; > + __be16 reserved; > +} __aligned(1); Will this work on big endian?
Hi Sharath, Thank you for the patch! Yet something to improve: [auto build test ERROR on ipvs/master] [also build test ERROR on linus/master sparc-next/master v5.11-rc7 next-20210211] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Sharath-Chandra-Vurukala/docs-networking-Add-documentation-for-MAP-v5/20210212-063547 base: https://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs.git master config: arm64-allyesconfig (attached as .config) compiler: aarch64-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/293142d706c02bf2e6ce7acb4e04ebb6cf4a2a63 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Sharath-Chandra-Vurukala/docs-networking-Add-documentation-for-MAP-v5/20210212-063547 git checkout 293142d706c02bf2e6ce7acb4e04ebb6cf4a2a63 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> Note: the linux-review/Sharath-Chandra-Vurukala/docs-networking-Add-documentation-for-MAP-v5/20210212-063547 HEAD 7f0a1e35c1d1c17de5873aded88d5dadfedce2fb builds fine. It only hurts bisectibility. All errors (new ones prefixed by >>): drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c: In function 'rmnet_map_egress_handler': >> drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c:153:15: error: too few arguments to function 'rmnet_map_add_map_header' 153 | map_header = rmnet_map_add_map_header(skb, additional_header_len, 0); | ^~~~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c:14: drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h:66:26: note: declared here 66 | struct rmnet_map_header *rmnet_map_add_map_header(struct sk_buff *skb, | ^~~~~~~~~~~~~~~~~~~~~~~~ At top level: drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h:76:11: warning: 'rmnet_map_get_next_hdr_type' defined but not used [-Wunused-function] 76 | static u8 rmnet_map_get_next_hdr_type(struct sk_buff *skb) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ -- >> drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:270:26: error: conflicting types for 'rmnet_map_add_map_header' 270 | struct rmnet_map_header *rmnet_map_add_map_header(struct sk_buff *skb, | ^~~~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:12: drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h:66:26: note: previous declaration of 'rmnet_map_add_map_header' was here 66 | struct rmnet_map_header *rmnet_map_add_map_header(struct sk_buff *skb, | ^~~~~~~~~~~~~~~~~~~~~~~~ vim +/rmnet_map_add_map_header +153 drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 129 ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 130 static int rmnet_map_egress_handler(struct sk_buff *skb, 56470c927f1ba1 Subash Abhinov Kasiviswanathan 2017-10-11 131 struct rmnet_port *port, u8 mux_id, ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 132 struct net_device *orig_dev) ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 133 { ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 134 int required_headroom, additional_header_len; ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 135 struct rmnet_map_header *map_header; ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 136 ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 137 additional_header_len = 0; ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 138 required_headroom = sizeof(struct rmnet_map_header); ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 139 14452ca3b5ce30 Subash Abhinov Kasiviswanathan 2018-03-21 140 if (port->data_format & RMNET_FLAGS_EGRESS_MAP_CKSUMV4) { 5eb5f8608ef118 Subash Abhinov Kasiviswanathan 2018-01-07 141 additional_header_len = sizeof(struct rmnet_map_ul_csum_header); 5eb5f8608ef118 Subash Abhinov Kasiviswanathan 2018-01-07 142 required_headroom += additional_header_len; 5eb5f8608ef118 Subash Abhinov Kasiviswanathan 2018-01-07 143 } 5eb5f8608ef118 Subash Abhinov Kasiviswanathan 2018-01-07 144 ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 145 if (skb_headroom(skb) < required_headroom) { 6392ff3c8e4c23 Subash Abhinov Kasiviswanathan 2018-10-02 146 if (pskb_expand_head(skb, required_headroom, 0, GFP_ATOMIC)) 1eece799d3f611 Subash Abhinov Kasiviswanathan 2018-05-15 147 return -ENOMEM; ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 148 } ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 149 14452ca3b5ce30 Subash Abhinov Kasiviswanathan 2018-03-21 150 if (port->data_format & RMNET_FLAGS_EGRESS_MAP_CKSUMV4) 5eb5f8608ef118 Subash Abhinov Kasiviswanathan 2018-01-07 151 rmnet_map_checksum_uplink_packet(skb, orig_dev); 5eb5f8608ef118 Subash Abhinov Kasiviswanathan 2018-01-07 152 ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 @153 map_header = rmnet_map_add_map_header(skb, additional_header_len, 0); ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 154 if (!map_header) 1eece799d3f611 Subash Abhinov Kasiviswanathan 2018-05-15 155 return -ENOMEM; ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 156 56470c927f1ba1 Subash Abhinov Kasiviswanathan 2017-10-11 157 map_header->mux_id = mux_id; ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 158 ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 159 skb->protocol = htons(ETH_P_MAP); ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 160 cf2fe57b0cc220 Subash Abhinov Kasiviswanathan 2017-12-11 161 return 0; ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 162 } ceed73a2cf4aff Subash Abhinov Kasiviswanathan 2017-08-29 163 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
On 2/11/21 8:04 PM, Jakub Kicinski wrote: > On Fri, 12 Feb 2021 03:05:23 +0530 Sharath Chandra Vurukala wrote: >> +/* MAP CSUM headers */ >> +struct rmnet_map_v5_csum_header { >> + u8 next_hdr:1; >> + u8 header_type:7; >> + u8 hw_reserved:5; >> + u8 priority:1; >> + u8 hw_reserved_bit:1; >> + u8 csum_valid_required:1; >> + __be16 reserved; >> +} __aligned(1); > > Will this work on big endian? Sort of related to this point... I'm sure the response to this will be to add two versions of the definition, surrounded __LITTLE_ENDIAN_BITFIELD and __BIG_ENDIAN_BITFIELD tests. I really find this non-intuitive, and every time I look at it I have to think about it a bit to figure out where the bits actually lie in the word. I know this pattern is used elsewhere in the networking code, but that doesn't make it any easier for me to understand... Can we used mask, defined in host byte order, to specify the positions of these fields? I proposed a change at one time that did this and this *_ENDIAN_BITFIELD thing was used instead. I will gladly implement this change (completely separate from what's being done here), but thought it might be best to see what people think about it before doing that work. -Alex
On 2021-02-12 07:01, Alex Elder wrote: > On 2/11/21 8:04 PM, Jakub Kicinski wrote: >> On Fri, 12 Feb 2021 03:05:23 +0530 Sharath Chandra Vurukala wrote: >>> +/* MAP CSUM headers */ >>> +struct rmnet_map_v5_csum_header { >>> + u8 next_hdr:1; >>> + u8 header_type:7; >>> + u8 hw_reserved:5; >>> + u8 priority:1; >>> + u8 hw_reserved_bit:1; >>> + u8 csum_valid_required:1; >>> + __be16 reserved; >>> +} __aligned(1); >> >> Will this work on big endian? > > Sort of related to this point... > > I'm sure the response to this will be to add two versions > of the definition, surrounded __LITTLE_ENDIAN_BITFIELD > and __BIG_ENDIAN_BITFIELD tests. > > I really find this non-intuitive, and every time I > look at it I have to think about it a bit to figure > out where the bits actually lie in the word. > > I know this pattern is used elsewhere in the networking > code, but that doesn't make it any easier for me to > understand... > > Can we used mask, defined in host byte order, to > specify the positions of these fields? > > I proposed a change at one time that did this and > this *_ENDIAN_BITFIELD thing was used instead. > > I will gladly implement this change (completely > separate from what's being done here), but thought > it might be best to see what people think about it > before doing that work. > > -Alex Our preference is to stick with __LITTLE_ENDIAN_BITFIELD & __BIG_ENDIAN_BITFIELD definitions similar to other networking definitions.
On Fri, 12 Feb 2021 08:01:15 -0600 Alex Elder wrote: > On 2/11/21 8:04 PM, Jakub Kicinski wrote: > > On Fri, 12 Feb 2021 03:05:23 +0530 Sharath Chandra Vurukala wrote: > >> +/* MAP CSUM headers */ > >> +struct rmnet_map_v5_csum_header { > >> + u8 next_hdr:1; > >> + u8 header_type:7; > >> + u8 hw_reserved:5; > >> + u8 priority:1; > >> + u8 hw_reserved_bit:1; > >> + u8 csum_valid_required:1; > >> + __be16 reserved; > >> +} __aligned(1); > > > > Will this work on big endian? > > Sort of related to this point... > > I'm sure the response to this will be to add two versions > of the definition, surrounded __LITTLE_ENDIAN_BITFIELD > and __BIG_ENDIAN_BITFIELD tests. > > I really find this non-intuitive, and every time I > look at it I have to think about it a bit to figure > out where the bits actually lie in the word. > > I know this pattern is used elsewhere in the networking > code, but that doesn't make it any easier for me to > understand... > > Can we used mask, defined in host byte order, to > specify the positions of these fields? > > I proposed a change at one time that did this and > this *_ENDIAN_BITFIELD thing was used instead. > > I will gladly implement this change (completely > separate from what's being done here), but thought > it might be best to see what people think about it > before doing that work. Most definitely agree, please convert.
On 2/12/21 12:51 PM, Jakub Kicinski wrote: > On Fri, 12 Feb 2021 08:01:15 -0600 Alex Elder wrote: >> On 2/11/21 8:04 PM, Jakub Kicinski wrote: >>> On Fri, 12 Feb 2021 03:05:23 +0530 Sharath Chandra Vurukala wrote: >>>> +/* MAP CSUM headers */ >>>> +struct rmnet_map_v5_csum_header { >>>> + u8 next_hdr:1; >>>> + u8 header_type:7; >>>> + u8 hw_reserved:5; >>>> + u8 priority:1; >>>> + u8 hw_reserved_bit:1; >>>> + u8 csum_valid_required:1; >>>> + __be16 reserved; >>>> +} __aligned(1); >>> >>> Will this work on big endian? >> >> Sort of related to this point... >> >> I'm sure the response to this will be to add two versions >> of the definition, surrounded __LITTLE_ENDIAN_BITFIELD >> and __BIG_ENDIAN_BITFIELD tests. >> >> I really find this non-intuitive, and every time I >> look at it I have to think about it a bit to figure >> out where the bits actually lie in the word. >> >> I know this pattern is used elsewhere in the networking >> code, but that doesn't make it any easier for me to >> understand... >> >> Can we used mask, defined in host byte order, to >> specify the positions of these fields? >> >> I proposed a change at one time that did this and >> this *_ENDIAN_BITFIELD thing was used instead. >> >> I will gladly implement this change (completely >> separate from what's being done here), but thought >> it might be best to see what people think about it >> before doing that work. > > Most definitely agree, please convert. KS, would you like me to do this to the existing code first? I don't think it will take me very long. If it were a priority I could probably get it done by the end of today, but I'd want to ensure the result worked for the testing you do. -Alex
On 2021-02-12 12:06, Alex Elder wrote: > On 2/12/21 12:51 PM, Jakub Kicinski wrote: >> On Fri, 12 Feb 2021 08:01:15 -0600 Alex Elder wrote: >>> On 2/11/21 8:04 PM, Jakub Kicinski wrote: >>>> On Fri, 12 Feb 2021 03:05:23 +0530 Sharath Chandra Vurukala wrote: >>>>> +/* MAP CSUM headers */ >>>>> +struct rmnet_map_v5_csum_header { >>>>> + u8 next_hdr:1; >>>>> + u8 header_type:7; >>>>> + u8 hw_reserved:5; >>>>> + u8 priority:1; >>>>> + u8 hw_reserved_bit:1; >>>>> + u8 csum_valid_required:1; >>>>> + __be16 reserved; >>>>> +} __aligned(1); >>>> >>>> Will this work on big endian? >>> >>> Sort of related to this point... >>> >>> I'm sure the response to this will be to add two versions >>> of the definition, surrounded __LITTLE_ENDIAN_BITFIELD >>> and __BIG_ENDIAN_BITFIELD tests. >>> >>> I really find this non-intuitive, and every time I >>> look at it I have to think about it a bit to figure >>> out where the bits actually lie in the word. >>> >>> I know this pattern is used elsewhere in the networking >>> code, but that doesn't make it any easier for me to >>> understand... >>> >>> Can we used mask, defined in host byte order, to >>> specify the positions of these fields? >>> >>> I proposed a change at one time that did this and >>> this *_ENDIAN_BITFIELD thing was used instead. >>> >>> I will gladly implement this change (completely >>> separate from what's being done here), but thought >>> it might be best to see what people think about it >>> before doing that work. >> >> Most definitely agree, please convert. > > KS, would you like me to do this to the existing code > first? > > I don't think it will take me very long. If it were > a priority I could probably get it done by the end of > today, but I'd want to ensure the result worked for > the testing you do. > > -Alex Sorry, I am not convinced that it is helping to improve anything. It just adds a big overhead of testing everything again without any apparent improvement of performance or readablity of code.
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h index 8d8d469..d4d61471 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2013-2014, 2016-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2016-2018 The Linux Foundation. + * All rights reserved. * * RMNET Data configuration engine */ diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c index 3d7d3ab..70ad6a7 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, 2021, The Linux Foundation. All rights reserved. * * RMNET Data ingress/egress handler */ @@ -57,8 +57,8 @@ __rmnet_map_ingress_handler(struct sk_buff *skb, struct rmnet_port *port) { struct rmnet_endpoint *ep; + u8 mux_id, next_hdr; u16 len, pad; - u8 mux_id; if (RMNET_MAP_GET_CD_BIT(skb)) { if (port->data_format & RMNET_FLAGS_INGRESS_MAP_COMMANDS) @@ -70,6 +70,7 @@ __rmnet_map_ingress_handler(struct sk_buff *skb, mux_id = RMNET_MAP_GET_MUX_ID(skb); pad = RMNET_MAP_GET_PAD(skb); len = RMNET_MAP_GET_LENGTH(skb) - pad; + next_hdr = RMNET_MAP_GET_NH_BIT(skb); if (mux_id >= RMNET_MAX_LOGICAL_EP) goto free_skb; @@ -80,15 +81,19 @@ __rmnet_map_ingress_handler(struct sk_buff *skb, skb->dev = ep->egress_dev; - /* Subtract MAP header */ - skb_pull(skb, sizeof(struct rmnet_map_header)); - rmnet_set_skb_proto(skb); - - if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) { + if (next_hdr && + (port->data_format & (RMNET_FLAGS_INGRESS_MAP_CKSUMV5))) { + if (rmnet_map_process_next_hdr_packet(skb, len)) + goto free_skb; + } else if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) { if (!rmnet_map_checksum_downlink_packet(skb, len + pad)) skb->ip_summed = CHECKSUM_UNNECESSARY; } + /* Subtract MAP header */ + skb_pull(skb, sizeof(struct rmnet_map_header)); + rmnet_set_skb_proto(skb); + skb_trim(skb, len); rmnet_deliver_skb(skb); return; diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h index 576501d..55d293c 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, 2021, The Linux Foundation. All rights reserved. */ #ifndef _RMNET_MAP_H_ @@ -23,6 +23,12 @@ struct rmnet_map_control_command { }; } __aligned(1); +enum rmnet_map_v5_header_type { + RMNET_MAP_HEADER_TYPE_UNKNOWN, + RMNET_MAP_HEADER_TYPE_CSUM_OFFLOAD = 0x2, + RMNET_MAP_HEADER_TYPE_ENUM_LENGTH +}; + enum rmnet_map_commands { RMNET_MAP_COMMAND_NONE, RMNET_MAP_COMMAND_FLOW_DISABLE, @@ -44,6 +50,9 @@ enum rmnet_map_commands { #define RMNET_MAP_GET_LENGTH(Y) (ntohs(((struct rmnet_map_header *) \ (Y)->data)->pkt_len)) +#define RMNET_MAP_GET_NH_BIT(Y) (((struct rmnet_map_header *) \ + (Y)->data)->next_hdr) + #define RMNET_MAP_COMMAND_REQUEST 0 #define RMNET_MAP_COMMAND_ACK 1 #define RMNET_MAP_COMMAND_UNSUPPORTED 2 @@ -55,10 +64,29 @@ enum rmnet_map_commands { struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb, struct rmnet_port *port); struct rmnet_map_header *rmnet_map_add_map_header(struct sk_buff *skb, - int hdrlen, int pad); + int hdrlen, + struct rmnet_port *port, + int pad); void rmnet_map_command(struct sk_buff *skb, struct rmnet_port *port); int rmnet_map_checksum_downlink_packet(struct sk_buff *skb, u16 len); void rmnet_map_checksum_uplink_packet(struct sk_buff *skb, struct net_device *orig_dev); +int rmnet_map_process_next_hdr_packet(struct sk_buff *skb, u16 len); + +static u8 rmnet_map_get_next_hdr_type(struct sk_buff *skb) +{ + unsigned char *data = skb->data; + + data += sizeof(struct rmnet_map_header); + return ((struct rmnet_map_v5_csum_header *)data)->header_type; +} + +static inline bool rmnet_map_get_csum_valid(struct sk_buff *skb) +{ + unsigned char *data = skb->data; + + data += sizeof(struct rmnet_map_header); + return ((struct rmnet_map_v5_csum_header *)data)->csum_valid_required; +} #endif /* _RMNET_MAP_H_ */ diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c index 21d3816..3d7e03f 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, 2021, The Linux Foundation. All rights reserved. * * RMNET Data MAP protocol */ @@ -311,6 +311,7 @@ struct rmnet_map_header *rmnet_map_add_map_header(struct sk_buff *skb, struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb, struct rmnet_port *port) { + unsigned char *data = skb->data, *next_hdr = NULL; struct rmnet_map_header *maph; struct sk_buff *skbn; u32 packet_len; @@ -323,6 +324,12 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb, if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) packet_len += sizeof(struct rmnet_map_dl_csum_trailer); + else if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV5) { + if (!maph->cd_bit) { + packet_len += sizeof(struct rmnet_map_v5_csum_header); + next_hdr = data + sizeof(*maph); + } + } if (((int)skb->len - (int)packet_len) < 0) return NULL; @@ -331,6 +338,11 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb, if (ntohs(maph->pkt_len) == 0) return NULL; + if (next_hdr && + ((struct rmnet_map_v5_csum_header *)next_hdr)->header_type != + RMNET_MAP_HEADER_TYPE_CSUM_OFFLOAD) + return NULL; + skbn = alloc_skb(packet_len + RMNET_MAP_DEAGGR_SPACING, GFP_ATOMIC); if (!skbn) return NULL; @@ -428,3 +440,33 @@ void rmnet_map_checksum_uplink_packet(struct sk_buff *skb, priv->stats.csum_sw++; } + +/* Process a MAPv5 packet header */ +int rmnet_map_process_next_hdr_packet(struct sk_buff *skb, + u16 len) +{ + struct rmnet_priv *priv = netdev_priv(skb->dev); + int rc = 0; + + switch (rmnet_map_get_next_hdr_type(skb)) { + case RMNET_MAP_HEADER_TYPE_CSUM_OFFLOAD: + if (unlikely(!(skb->dev->features & NETIF_F_RXCSUM))) { + priv->stats.csum_sw++; + } else if (rmnet_map_get_csum_valid(skb)) { + priv->stats.csum_ok++; + skb->ip_summed = CHECKSUM_UNNECESSARY; + } else { + priv->stats.csum_valid_unset++; + } + + /* Pull csum v5 header */ + skb_pull(skb, sizeof(struct rmnet_map_v5_csum_header)); + break; + default: + rc = -EINVAL; + break; + } + + return rc; +} + diff --git a/include/linux/if_rmnet.h b/include/linux/if_rmnet.h index 9661416..81acd0b 100644 --- a/include/linux/if_rmnet.h +++ b/include/linux/if_rmnet.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only - * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019, 2021 The Linux Foundation. All rights reserved. */ #ifndef _LINUX_IF_RMNET_H_ @@ -8,11 +8,11 @@ struct rmnet_map_header { #if defined(__LITTLE_ENDIAN_BITFIELD) u8 pad_len:6; - u8 reserved_bit:1; + u8 next_hdr:1; u8 cd_bit:1; #elif defined (__BIG_ENDIAN_BITFIELD) u8 cd_bit:1; - u8 reserved_bit:1; + u8 next_hdr:1; u8 pad_len:6; #else #error "Please fix <asm/byteorder.h>" @@ -52,4 +52,15 @@ struct rmnet_map_ul_csum_header { #endif } __aligned(1); +/* MAP CSUM headers */ +struct rmnet_map_v5_csum_header { + u8 next_hdr:1; + u8 header_type:7; + u8 hw_reserved:5; + u8 priority:1; + u8 hw_reserved_bit:1; + u8 csum_valid_required:1; + __be16 reserved; +} __aligned(1); + #endif /* !(_LINUX_IF_RMNET_H_) */ diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 82708c6..838bd29 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -1233,6 +1233,7 @@ enum { #define RMNET_FLAGS_INGRESS_MAP_COMMANDS (1U << 1) #define RMNET_FLAGS_INGRESS_MAP_CKSUMV4 (1U << 2) #define RMNET_FLAGS_EGRESS_MAP_CKSUMV4 (1U << 3) +#define RMNET_FLAGS_INGRESS_MAP_CKSUMV5 (1U << 4) enum { IFLA_RMNET_UNSPEC,
Adding support for processing of Mapv5 downlink packets. It involves parsing the Mapv5 packet and checking the csum header to know whether the hardware has validated the checksum and is valid or not. Based on the checksum valid bit the corresponding stats are incremented and skb->ip_summed is marked either CHECKSUM_UNNECESSARY or left as CHEKSUM_NONE to let network stack revalidated the checksum and update the respective snmp stats. Signed-off-by: Sharath Chandra Vurukala <sharathv@codeaurora.org> --- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h | 3 +- .../net/ethernet/qualcomm/rmnet/rmnet_handlers.c | 19 ++++++---- drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h | 32 +++++++++++++++- .../net/ethernet/qualcomm/rmnet/rmnet_map_data.c | 44 +++++++++++++++++++++- include/linux/if_rmnet.h | 17 +++++++-- include/uapi/linux/if_link.h | 1 + 6 files changed, 102 insertions(+), 14 deletions(-)