summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>2016-02-10 13:27:46 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:09:47 -0700
commit410646778a98f65bd73a82d29734fe0f090e27b7 (patch)
tree368939c3b277598d332c6663caaf75617b448aee /net
parent2a7e0a52fa90495343ccdb037b1004630e7882b2 (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>
Diffstat (limited to 'net')
-rw-r--r--net/rmnet_data/rmnet_map_command.c21
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;
}