Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 1 | /* |
Yun Park | f2e213b | 2018-01-09 14:38:45 -0800 | [diff] [blame] | 2 | * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 3 | * |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 4 | * Permission to use, copy, modify, and/or distribute this software for |
| 5 | * any purpose with or without fee is hereby granted, provided that the |
| 6 | * above copyright notice and this permission notice appear in all |
| 7 | * copies. |
| 8 | * |
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| 10 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| 11 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| 12 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| 13 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| 14 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| 15 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| 16 | * PERFORMANCE OF THIS SOFTWARE. |
| 17 | */ |
| 18 | |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 19 | /** |
| 20 | * DOC: wlan_hdd_lro.c |
| 21 | * |
| 22 | * WLAN HDD LRO interface implementation |
| 23 | */ |
| 24 | |
| 25 | #include <wlan_hdd_includes.h> |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame] | 26 | #include <qdf_types.h> |
Dhanashri Atre | 170855e | 2016-12-15 13:26:54 -0800 | [diff] [blame] | 27 | #include <qdf_lro.h> |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 28 | #include <wlan_hdd_lro.h> |
| 29 | #include <wlan_hdd_napi.h> |
| 30 | #include <wma_api.h> |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 31 | |
| 32 | #include <linux/inet_lro.h> |
| 33 | #include <linux/list.h> |
| 34 | #include <linux/random.h> |
| 35 | #include <net/tcp.h> |
| 36 | |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 37 | #define LRO_VALID_FIELDS \ |
| 38 | (LRO_DESC | LRO_ELIGIBILITY_CHECKED | LRO_TCP_ACK_NUM | \ |
| 39 | LRO_TCP_DATA_CSUM | LRO_TCP_SEQ_NUM | LRO_TCP_WIN) |
| 40 | |
psimha | 884025c | 2017-08-01 15:07:32 -0700 | [diff] [blame] | 41 | #if defined(QCA_WIFI_QCA6290) |
Dhanashri Atre | 1a6a4ce | 2017-05-03 19:40:33 -0700 | [diff] [blame] | 42 | static qdf_lro_ctx_t wlan_hdd_get_lro_ctx(struct sk_buff *skb) |
Dhanashri Atre | 170855e | 2016-12-15 13:26:54 -0800 | [diff] [blame] | 43 | { |
Dhanashri Atre | 1a6a4ce | 2017-05-03 19:40:33 -0700 | [diff] [blame] | 44 | return (qdf_lro_ctx_t)QDF_NBUF_CB_RX_LRO_CTX(skb); |
Dhanashri Atre | 170855e | 2016-12-15 13:26:54 -0800 | [diff] [blame] | 45 | } |
Dhanashri Atre | 170855e | 2016-12-15 13:26:54 -0800 | [diff] [blame] | 46 | #else |
Dhanashri Atre | 1a6a4ce | 2017-05-03 19:40:33 -0700 | [diff] [blame] | 47 | static qdf_lro_ctx_t wlan_hdd_get_lro_ctx(struct sk_buff *skb) |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 48 | { |
Dhanashri Atre | 1a6a4ce | 2017-05-03 19:40:33 -0700 | [diff] [blame] | 49 | struct hif_opaque_softc *hif_hdl = |
| 50 | (struct hif_opaque_softc *)cds_get_context(QDF_MODULE_ID_HIF); |
| 51 | if (hif_hdl == NULL) { |
| 52 | hdd_err("hif_hdl is NULL"); |
Yun Park | f2e213b | 2018-01-09 14:38:45 -0800 | [diff] [blame] | 53 | return NULL; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 54 | } |
| 55 | |
Dhanashri Atre | 1a6a4ce | 2017-05-03 19:40:33 -0700 | [diff] [blame] | 56 | return hif_get_lro_info(QDF_NBUF_CB_RX_CTX_ID(skb), hif_hdl); |
Manjunathappa Prakash | 04f2644 | 2016-10-13 14:46:49 -0700 | [diff] [blame] | 57 | } |
Dhanashri Atre | 1a6a4ce | 2017-05-03 19:40:33 -0700 | [diff] [blame] | 58 | #endif |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 59 | |
| 60 | /** |
| 61 | * hdd_lro_rx() - LRO receive function |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 62 | * @adapter: HDD adapter |
| 63 | * @skb: network buffer |
| 64 | * |
| 65 | * Delivers LRO eligible frames to the LRO manager |
| 66 | * |
Manjunathappa Prakash | 7b0ad46 | 2018-04-15 00:37:16 -0700 | [diff] [blame^] | 67 | * Return: QDF_STATUS_SUCCESS - frame delivered to LRO manager |
| 68 | * QDF_STATUS_E_FAILURE - frame not delivered |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 69 | */ |
Manjunathappa Prakash | 7b0ad46 | 2018-04-15 00:37:16 -0700 | [diff] [blame^] | 70 | QDF_STATUS hdd_lro_rx(struct hdd_adapter *adapter, struct sk_buff *skb) |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 71 | { |
Dhanashri Atre | 1a6a4ce | 2017-05-03 19:40:33 -0700 | [diff] [blame] | 72 | qdf_lro_ctx_t ctx; |
Manjunathappa Prakash | 7b0ad46 | 2018-04-15 00:37:16 -0700 | [diff] [blame^] | 73 | QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| 74 | struct qdf_lro_info info; |
| 75 | struct net_lro_desc *lro_desc = NULL; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 76 | |
Manjunathappa Prakash | 7b0ad46 | 2018-04-15 00:37:16 -0700 | [diff] [blame^] | 77 | if ((adapter->dev->features & NETIF_F_LRO) != NETIF_F_LRO) |
| 78 | return QDF_STATUS_E_NOSUPPORT; |
Manjunathappa Prakash | 7b6cb00 | 2017-10-09 00:40:24 -0700 | [diff] [blame] | 79 | |
Manjunathappa Prakash | 7b0ad46 | 2018-04-15 00:37:16 -0700 | [diff] [blame^] | 80 | ctx = wlan_hdd_get_lro_ctx(skb); |
| 81 | if (!ctx) { |
| 82 | hdd_err("LRO mgr is NULL"); |
| 83 | return status; |
| 84 | } |
Manjunathappa Prakash | 04f2644 | 2016-10-13 14:46:49 -0700 | [diff] [blame] | 85 | |
Manjunathappa Prakash | 7b0ad46 | 2018-04-15 00:37:16 -0700 | [diff] [blame^] | 86 | info.iph = skb->data; |
| 87 | info.tcph = skb->data + QDF_NBUF_CB_RX_TCP_OFFSET(skb); |
| 88 | ctx->lro_mgr->dev = adapter->dev; |
| 89 | if (qdf_lro_get_info(ctx, skb, &info, (void **)&lro_desc)) { |
| 90 | struct net_lro_info hdd_lro_info; |
Manjunathappa Prakash | 04f2644 | 2016-10-13 14:46:49 -0700 | [diff] [blame] | 91 | |
Manjunathappa Prakash | 7b0ad46 | 2018-04-15 00:37:16 -0700 | [diff] [blame^] | 92 | hdd_lro_info.valid_fields = LRO_VALID_FIELDS; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 93 | |
Manjunathappa Prakash | 7b0ad46 | 2018-04-15 00:37:16 -0700 | [diff] [blame^] | 94 | hdd_lro_info.lro_desc = lro_desc; |
| 95 | hdd_lro_info.lro_eligible = 1; |
| 96 | hdd_lro_info.tcp_ack_num = QDF_NBUF_CB_RX_TCP_ACK_NUM(skb); |
| 97 | hdd_lro_info.tcp_data_csum = |
| 98 | csum_unfold(htons(QDF_NBUF_CB_RX_TCP_CHKSUM(skb))); |
| 99 | hdd_lro_info.tcp_seq_num = QDF_NBUF_CB_RX_TCP_SEQ_NUM(skb); |
| 100 | hdd_lro_info.tcp_win = QDF_NBUF_CB_RX_TCP_WIN(skb); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 101 | |
Manjunathappa Prakash | 7b0ad46 | 2018-04-15 00:37:16 -0700 | [diff] [blame^] | 102 | lro_receive_skb_ext(ctx->lro_mgr, skb, (void *)adapter, |
| 103 | &hdd_lro_info); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 104 | |
Manjunathappa Prakash | 7b0ad46 | 2018-04-15 00:37:16 -0700 | [diff] [blame^] | 105 | if (!hdd_lro_info.lro_desc->active) |
| 106 | qdf_lro_desc_free(ctx, lro_desc); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 107 | |
Manjunathappa Prakash | 7b0ad46 | 2018-04-15 00:37:16 -0700 | [diff] [blame^] | 108 | status = QDF_STATUS_SUCCESS; |
| 109 | } else { |
| 110 | qdf_lro_flush_pkt(ctx, &info); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 111 | } |
| 112 | return status; |
| 113 | } |
Dhanashri Atre | e7d442a | 2016-07-14 18:20:29 -0700 | [diff] [blame] | 114 | |
| 115 | /** |
Dhanashri Atre | 1a6a4ce | 2017-05-03 19:40:33 -0700 | [diff] [blame] | 116 | * hdd_lro_display_stats() - display LRO statistics |
Dhanashri Atre | e7d442a | 2016-07-14 18:20:29 -0700 | [diff] [blame] | 117 | * @hdd_ctx: hdd context |
| 118 | * |
| 119 | * Return: none |
| 120 | */ |
Jeff Johnson | 28c3e62 | 2017-08-28 11:54:45 -0700 | [diff] [blame] | 121 | void hdd_lro_display_stats(struct hdd_context *hdd_ctx) |
Dhanashri Atre | e7d442a | 2016-07-14 18:20:29 -0700 | [diff] [blame] | 122 | { |
Srinivas Girigowda | f91ec57 | 2017-03-06 17:20:19 -0800 | [diff] [blame] | 123 | hdd_debug("LRO stats is broken, will fix it"); |
Dhanashri Atre | e7d442a | 2016-07-14 18:20:29 -0700 | [diff] [blame] | 124 | } |
Manjunathappa Prakash | 7b6cb00 | 2017-10-09 00:40:24 -0700 | [diff] [blame] | 125 | |
Poddar, Siddarth | 4b3f731 | 2017-11-02 17:00:20 +0530 | [diff] [blame] | 126 | QDF_STATUS |
| 127 | hdd_lro_set_reset(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter, |
| 128 | uint8_t enable_flag) |
| 129 | { |
Manjunathappa Prakash | 7b0ad46 | 2018-04-15 00:37:16 -0700 | [diff] [blame^] | 130 | if ((hdd_ctx->ol_enable != CFG_LRO_ENABLED) || |
| 131 | (adapter->device_mode != QDF_STA_MODE)) { |
Poddar, Siddarth | 4b3f731 | 2017-11-02 17:00:20 +0530 | [diff] [blame] | 132 | hdd_debug("LRO is already Disabled"); |
| 133 | return 0; |
| 134 | } |
| 135 | |
| 136 | if (enable_flag) { |
| 137 | qdf_atomic_set(&hdd_ctx->vendor_disable_lro_flag, 0); |
| 138 | adapter->dev->features |= NETIF_F_LRO; |
| 139 | } else { |
| 140 | /* Disable LRO, Enable tcpdelack*/ |
| 141 | qdf_atomic_set(&hdd_ctx->vendor_disable_lro_flag, 1); |
| 142 | adapter->dev->features &= ~NETIF_F_LRO; |
| 143 | hdd_debug("LRO Disabled"); |
| 144 | |
| 145 | if (hdd_ctx->en_tcp_delack_no_lro) { |
| 146 | struct wlan_rx_tp_data rx_tp_data; |
| 147 | |
| 148 | hdd_debug("Enable TCP delack as LRO is disabled"); |
| 149 | rx_tp_data.rx_tp_flags = TCP_DEL_ACK_IND; |
Lin Bai | 556a192 | 2017-11-10 20:32:04 +0800 | [diff] [blame] | 150 | rx_tp_data.level = GET_CUR_RX_LVL(hdd_ctx); |
Poddar, Siddarth | 4b3f731 | 2017-11-02 17:00:20 +0530 | [diff] [blame] | 151 | wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, |
| 152 | WLAN_SVC_WLAN_TP_IND, |
| 153 | &rx_tp_data, |
| 154 | sizeof(rx_tp_data)); |
| 155 | hdd_ctx->en_tcp_delack_no_lro = 1; |
| 156 | } |
| 157 | } |
| 158 | return 0; |
| 159 | } |
| 160 | |
Manjunathappa Prakash | 7b6cb00 | 2017-10-09 00:40:24 -0700 | [diff] [blame] | 161 | |