diff options
author | Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> | 2016-02-10 13:27:46 -0700 |
---|---|---|
committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:09:47 -0700 |
commit | 410646778a98f65bd73a82d29734fe0f090e27b7 (patch) | |
tree | 368939c3b277598d332c6663caaf75617b448aee | |
parent | 2a7e0a52fa90495343ccdb037b1004630e7882b2 (diff) |
net: rmnet_data: Fix QMAP ACK's to work with DL checksum offload
Specifications state that the MAP packet length in the MAP header do
not account for the number of bytes of packet trailer from DL checksum
offload. Current implementation takes this into account for data
packets but not for command packets. As a result, the additional
8 bytes were sent to hardware as part of the MAP ACK's and were
subsequently dropped.
Fix this by truncating the extra bytes of the DL checksum trailer from
the MAP ACK.
CRs-Fixed: 961336
Change-Id: I175dde695e7ee09d16c99fb71898d635c7a812ab
Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
-rw-r--r-- | net/rmnet_data/rmnet_map_command.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/net/rmnet_data/rmnet_map_command.c b/net/rmnet_data/rmnet_map_command.c index 2f860db86ae2..733fa241665b 100644 --- a/net/rmnet_data/rmnet_map_command.c +++ b/net/rmnet_data/rmnet_map_command.c @@ -103,6 +103,7 @@ static uint8_t rmnet_map_do_flow_control(struct sk_buff *skb, * rmnet_map_send_ack() - Send N/ACK message for MAP commands * @skb: Socket buffer containing the MAP command message * @type: N/ACK message selector + * @config: Physical end-point configuration of ingress device * * skb is modified to contain the message type selector. The message is then * transmitted on skb->dev. Note that this function grabs global Tx lock on @@ -112,7 +113,8 @@ static uint8_t rmnet_map_do_flow_control(struct sk_buff *skb, * - void */ static void rmnet_map_send_ack(struct sk_buff *skb, - unsigned char type) + unsigned char type, + struct rmnet_phys_ep_conf_s *config) { struct rmnet_map_control_command_s *cmd; int xmit_status; @@ -121,6 +123,21 @@ static void rmnet_map_send_ack(struct sk_buff *skb, BUG(); skb->protocol = htons(ETH_P_MAP); + + if ((config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV3) || + (config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV4)) { + if (unlikely(skb->len < (sizeof(struct rmnet_map_header_s) + + + RMNET_MAP_GET_LENGTH(skb) + + sizeof(struct rmnet_map_dl_checksum_trailer_s)))) { + rmnet_stats_dl_checksum( + RMNET_MAP_CHECKSUM_ERR_BAD_BUFFER); + return; + } + + skb_trim(skb, skb->len - + sizeof(struct rmnet_map_dl_checksum_trailer_s)); + } + cmd = RMNET_MAP_GET_CMD_START(skb); cmd->cmd_type = type & 0x03; @@ -173,6 +190,6 @@ rx_handler_result_t rmnet_map_command(struct sk_buff *skb, rc = RMNET_MAP_COMMAND_UNSUPPORTED; break; } - rmnet_map_send_ack(skb, rc); + rmnet_map_send_ack(skb, rc, config); return RX_HANDLER_CONSUMED; } |