Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 1 | /* |
Tallapragada Kalyan | 1b4d08d | 2016-12-15 22:19:58 +0530 | [diff] [blame] | 2 | * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 3 | * |
| 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 | |
| 19 | #include "dp_types.h" |
| 20 | #include "dp_rx.h" |
| 21 | #include "dp_peer.h" |
| 22 | #include "hal_rx.h" |
| 23 | #include "hal_api.h" |
| 24 | #include "qdf_nbuf.h" |
| 25 | #include <ieee80211.h> |
Venkateswara Swamy Bandaru | c14b1b6 | 2017-02-24 12:26:08 +0530 | [diff] [blame] | 26 | #ifdef MESH_MODE_SUPPORT |
| 27 | #include "if_meta_hdr.h" |
| 28 | #endif |
Ishank Jain | bc2d91f | 2017-01-03 18:14:54 +0530 | [diff] [blame] | 29 | #include "dp_internal.h" |
Pratik Gandhi | 3da3bc7 | 2017-03-16 18:20:22 +0530 | [diff] [blame] | 30 | #include "dp_rx_mon.h" |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 31 | |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 32 | /* |
| 33 | * dp_rx_buffers_replenish() - replenish rxdma ring with rx nbufs |
| 34 | * called during dp rx initialization |
| 35 | * and at the end of dp_rx_process. |
| 36 | * |
| 37 | * @soc: core txrx main context |
| 38 | * @mac_id: mac_id which is one of 3 mac_ids |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 39 | * @dp_rxdma_srng: dp rxdma circular ring |
| 40 | * @rx_desc_pool: Poiter to free Rx descriptor pool |
| 41 | * @num_req_buffers: number of buffer to be replenished |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 42 | * @desc_list: list of descs if called from dp_rx_process |
| 43 | * or NULL during dp rx initialization or out of buffer |
| 44 | * interrupt. |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 45 | * @tail: tail of descs list |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 46 | * @owner: who owns the nbuf (host, NSS etc...) |
| 47 | * Return: return success or failure |
| 48 | */ |
| 49 | QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 50 | struct dp_srng *dp_rxdma_srng, |
| 51 | struct rx_desc_pool *rx_desc_pool, |
| 52 | uint32_t num_req_buffers, |
| 53 | union dp_rx_desc_list_elem_t **desc_list, |
| 54 | union dp_rx_desc_list_elem_t **tail, |
| 55 | uint8_t owner) |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 56 | { |
| 57 | uint32_t num_alloc_desc; |
| 58 | uint16_t num_desc_to_free = 0; |
| 59 | struct dp_pdev *dp_pdev = dp_soc->pdev_list[mac_id]; |
| 60 | uint32_t num_entries_avail; |
| 61 | uint32_t count; |
| 62 | int sync_hw_ptr = 1; |
| 63 | qdf_dma_addr_t paddr; |
| 64 | qdf_nbuf_t rx_netbuf; |
| 65 | void *rxdma_ring_entry; |
| 66 | union dp_rx_desc_list_elem_t *next; |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 67 | QDF_STATUS ret; |
| 68 | |
| 69 | void *rxdma_srng; |
| 70 | |
| 71 | rxdma_srng = dp_rxdma_srng->hal_srng; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 72 | |
| 73 | if (!rxdma_srng) { |
| 74 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, |
| 75 | "rxdma srng not initialized"); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 76 | DP_STATS_INC(dp_pdev, replenish.rxdma_err, num_req_buffers); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 77 | return QDF_STATUS_E_FAILURE; |
| 78 | } |
| 79 | |
Karunakar Dasineni | 1d891ed | 2017-03-29 15:42:02 -0700 | [diff] [blame] | 80 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 81 | "requested %d buffers for replenish", num_req_buffers); |
| 82 | |
| 83 | /* |
| 84 | * if desc_list is NULL, allocate the descs from freelist |
| 85 | */ |
| 86 | if (!(*desc_list)) { |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 87 | |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 88 | num_alloc_desc = dp_rx_get_free_desc_list(dp_soc, mac_id, |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 89 | rx_desc_pool, |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 90 | num_req_buffers, |
| 91 | desc_list, |
| 92 | tail); |
| 93 | |
| 94 | if (!num_alloc_desc) { |
| 95 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, |
| 96 | "no free rx_descs in freelist"); |
Ishank Jain | 1e7401c | 2017-02-17 15:38:39 +0530 | [diff] [blame] | 97 | DP_STATS_INC(dp_pdev, err.desc_alloc_fail, |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 98 | num_req_buffers); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 99 | return QDF_STATUS_E_NOMEM; |
| 100 | } |
| 101 | |
Karunakar Dasineni | 1d891ed | 2017-03-29 15:42:02 -0700 | [diff] [blame] | 102 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 103 | "%d rx desc allocated", num_alloc_desc); |
| 104 | num_req_buffers = num_alloc_desc; |
| 105 | } |
| 106 | |
| 107 | hal_srng_access_start(dp_soc->hal_soc, rxdma_srng); |
| 108 | num_entries_avail = hal_srng_src_num_avail(dp_soc->hal_soc, |
| 109 | rxdma_srng, |
| 110 | sync_hw_ptr); |
| 111 | |
Karunakar Dasineni | 1d891ed | 2017-03-29 15:42:02 -0700 | [diff] [blame] | 112 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 113 | "no of availble entries in rxdma ring: %d", |
| 114 | num_entries_avail); |
| 115 | |
| 116 | if (num_entries_avail < num_req_buffers) { |
| 117 | num_desc_to_free = num_req_buffers - num_entries_avail; |
| 118 | num_req_buffers = num_entries_avail; |
| 119 | } |
| 120 | |
Tallapragada Kalyan | 4e3341a | 2017-02-06 12:19:43 +0530 | [diff] [blame] | 121 | count = 0; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 122 | |
Tallapragada Kalyan | 4e3341a | 2017-02-06 12:19:43 +0530 | [diff] [blame] | 123 | while (count < num_req_buffers) { |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 124 | rx_netbuf = qdf_nbuf_alloc(dp_pdev->osif_pdev, |
| 125 | RX_BUFFER_SIZE, |
| 126 | RX_BUFFER_RESERVATION, |
| 127 | RX_BUFFER_ALIGNMENT, |
| 128 | FALSE); |
| 129 | |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 130 | if (rx_netbuf == NULL) { |
| 131 | DP_STATS_INC(dp_pdev, replenish.nbuf_alloc_fail, 1); |
Tallapragada Kalyan | 4e3341a | 2017-02-06 12:19:43 +0530 | [diff] [blame] | 132 | continue; |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 133 | } |
Houston Hoffman | fc0a960 | 2017-01-26 22:36:31 -0800 | [diff] [blame] | 134 | |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 135 | ret = qdf_nbuf_map_single(dp_soc->osdev, rx_netbuf, |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 136 | QDF_DMA_BIDIRECTIONAL); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 137 | if (ret == QDF_STATUS_E_FAILURE) { |
| 138 | DP_STATS_INC(dp_pdev, replenish.map_err, 1); |
| 139 | continue; |
| 140 | } |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 141 | |
| 142 | paddr = qdf_nbuf_get_frag_paddr(rx_netbuf, 0); |
| 143 | |
Tallapragada Kalyan | 4e3341a | 2017-02-06 12:19:43 +0530 | [diff] [blame] | 144 | /* |
| 145 | * check if the physical address of nbuf->data is |
| 146 | * less then 0x50000000 then free the nbuf and try |
| 147 | * allocating new nbuf. We can try for 100 times. |
| 148 | * this is a temp WAR till we fix it properly. |
| 149 | */ |
| 150 | ret = check_x86_paddr(dp_soc, &rx_netbuf, &paddr, dp_pdev); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 151 | if (ret == QDF_STATUS_E_FAILURE) { |
| 152 | DP_STATS_INC(dp_pdev, replenish.x86_fail, 1); |
Tallapragada Kalyan | 4e3341a | 2017-02-06 12:19:43 +0530 | [diff] [blame] | 153 | break; |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 154 | } |
Tallapragada Kalyan | 4e3341a | 2017-02-06 12:19:43 +0530 | [diff] [blame] | 155 | |
| 156 | count++; |
| 157 | |
| 158 | rxdma_ring_entry = hal_srng_src_get_next(dp_soc->hal_soc, |
| 159 | rxdma_srng); |
| 160 | |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 161 | next = (*desc_list)->next; |
| 162 | |
| 163 | (*desc_list)->rx_desc.nbuf = rx_netbuf; |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 164 | |
| 165 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, |
| 166 | "rx_netbuf=%p, buf=%p, paddr=0x%llx, cookie=%d\n", |
| 167 | rx_netbuf, qdf_nbuf_data(rx_netbuf), |
| 168 | (unsigned long long)paddr, (*desc_list)->rx_desc.cookie); |
| 169 | |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 170 | hal_rxdma_buff_addr_info_set(rxdma_ring_entry, paddr, |
| 171 | (*desc_list)->rx_desc.cookie, |
| 172 | owner); |
| 173 | |
| 174 | *desc_list = next; |
| 175 | } |
| 176 | |
| 177 | hal_srng_access_end(dp_soc->hal_soc, rxdma_srng); |
| 178 | |
Karunakar Dasineni | 1d891ed | 2017-03-29 15:42:02 -0700 | [diff] [blame] | 179 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 180 | "successfully replenished %d buffers", num_req_buffers); |
Karunakar Dasineni | 1d891ed | 2017-03-29 15:42:02 -0700 | [diff] [blame] | 181 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 182 | "%d rx desc added back to free list", num_desc_to_free); |
Ishank Jain | 1e7401c | 2017-02-17 15:38:39 +0530 | [diff] [blame] | 183 | DP_STATS_INC(dp_pdev, buf_freelist, num_desc_to_free); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 184 | DP_STATS_INC_PKT(dp_pdev, replenish.pkts, num_req_buffers, |
| 185 | (RX_BUFFER_SIZE * num_req_buffers)); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 186 | |
| 187 | /* |
| 188 | * add any available free desc back to the free list |
| 189 | */ |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 190 | |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 191 | if (*desc_list) |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 192 | dp_rx_add_desc_list_to_free_list(dp_soc, desc_list, tail, |
| 193 | mac_id, rx_desc_pool); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 194 | |
| 195 | return QDF_STATUS_SUCCESS; |
| 196 | } |
| 197 | |
Kalyan Tallapragada | 277f45e | 2017-01-30 14:25:27 +0530 | [diff] [blame] | 198 | /* |
| 199 | * dp_rx_deliver_raw() - process RAW mode pkts and hand over the |
| 200 | * pkts to RAW mode simulation to |
| 201 | * decapsulate the pkt. |
| 202 | * |
| 203 | * @vdev: vdev on which RAW mode is enabled |
| 204 | * @nbuf_list: list of RAW pkts to process |
| 205 | * |
| 206 | * Return: void |
| 207 | */ |
Tallapragada Kalyan | 3a0005c | 2017-03-10 15:22:57 +0530 | [diff] [blame] | 208 | void |
Kalyan Tallapragada | 277f45e | 2017-01-30 14:25:27 +0530 | [diff] [blame] | 209 | dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list) |
| 210 | { |
| 211 | qdf_nbuf_t deliver_list_head = NULL; |
| 212 | qdf_nbuf_t deliver_list_tail = NULL; |
| 213 | qdf_nbuf_t nbuf; |
| 214 | |
| 215 | nbuf = nbuf_list; |
| 216 | while (nbuf) { |
| 217 | qdf_nbuf_t next = qdf_nbuf_next(nbuf); |
| 218 | |
| 219 | DP_RX_LIST_APPEND(deliver_list_head, deliver_list_tail, nbuf); |
| 220 | |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 221 | DP_STATS_INC(vdev->pdev, rx_raw_pkts, 1); |
Kalyan Tallapragada | 277f45e | 2017-01-30 14:25:27 +0530 | [diff] [blame] | 222 | /* |
| 223 | * reset the chfrag_start and chfrag_end bits in nbuf cb |
| 224 | * as this is a non-amsdu pkt and RAW mode simulation expects |
| 225 | * these bit s to be 0 for non-amsdu pkt. |
| 226 | */ |
| 227 | if (qdf_nbuf_is_chfrag_start(nbuf) && |
| 228 | qdf_nbuf_is_chfrag_end(nbuf)) { |
| 229 | qdf_nbuf_set_chfrag_start(nbuf, 0); |
| 230 | qdf_nbuf_set_chfrag_end(nbuf, 0); |
| 231 | } |
| 232 | |
| 233 | nbuf = next; |
| 234 | } |
| 235 | |
| 236 | vdev->osif_rsim_rx_decap(vdev->osif_vdev, &deliver_list_head, |
| 237 | &deliver_list_tail); |
| 238 | |
| 239 | vdev->osif_rx(vdev->osif_vdev, deliver_list_head); |
| 240 | } |
| 241 | |
| 242 | |
Pramod Simha | b17d067 | 2017-03-06 17:20:13 -0800 | [diff] [blame] | 243 | #ifdef DP_LFR |
| 244 | /* |
| 245 | * In case of LFR, data of a new peer might be sent up |
| 246 | * even before peer is added. |
| 247 | */ |
| 248 | static inline struct dp_vdev * |
| 249 | dp_get_vdev_from_peer(struct dp_soc *soc, |
| 250 | uint16_t peer_id, |
| 251 | struct dp_peer *peer, |
| 252 | struct hal_rx_mpdu_desc_info mpdu_desc_info) |
| 253 | { |
| 254 | struct dp_vdev *vdev; |
| 255 | uint8_t vdev_id; |
Kalyan Tallapragada | 277f45e | 2017-01-30 14:25:27 +0530 | [diff] [blame] | 256 | |
Pramod Simha | b17d067 | 2017-03-06 17:20:13 -0800 | [diff] [blame] | 257 | if (unlikely(!peer)) { |
| 258 | if (peer_id != HTT_INVALID_PEER) { |
| 259 | vdev_id = DP_PEER_METADATA_ID_GET( |
| 260 | mpdu_desc_info.peer_meta_data); |
| 261 | QDF_TRACE(QDF_MODULE_ID_DP, |
| 262 | QDF_TRACE_LEVEL_ERROR, |
| 263 | FL("PeerID %d not found use vdevID %d"), |
| 264 | peer_id, vdev_id); |
| 265 | vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, |
| 266 | vdev_id); |
| 267 | } else { |
| 268 | QDF_TRACE(QDF_MODULE_ID_DP, |
| 269 | QDF_TRACE_LEVEL_ERROR, |
| 270 | FL("Invalid PeerID %d"), |
| 271 | peer_id); |
| 272 | return NULL; |
| 273 | } |
| 274 | } else { |
| 275 | vdev = peer->vdev; |
| 276 | } |
| 277 | return vdev; |
| 278 | } |
| 279 | #else |
| 280 | static inline struct dp_vdev * |
| 281 | dp_get_vdev_from_peer(struct dp_soc *soc, |
| 282 | uint16_t peer_id, |
| 283 | struct dp_peer *peer, |
| 284 | struct hal_rx_mpdu_desc_info mpdu_desc_info) |
| 285 | { |
| 286 | if (unlikely(!peer)) { |
| 287 | QDF_TRACE(QDF_MODULE_ID_DP, |
| 288 | QDF_TRACE_LEVEL_ERROR, |
| 289 | FL("Peer not found for peerID %d"), |
| 290 | peer_id); |
| 291 | return NULL; |
| 292 | } else { |
| 293 | return peer->vdev; |
| 294 | } |
| 295 | } |
| 296 | #endif |
Tallapragada Kalyan | 3a0005c | 2017-03-10 15:22:57 +0530 | [diff] [blame] | 297 | |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 298 | /** |
| 299 | * dp_rx_intrabss_fwd() - Implements the Intra-BSS forwarding logic |
| 300 | * |
| 301 | * @soc: core txrx main context |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 302 | * @sa_peer : source peer entry |
| 303 | * @rx_tlv_hdr : start address of rx tlvs |
| 304 | * @nbuf : nbuf that has to be intrabss forwarded |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 305 | * |
| 306 | * Return: bool: true if it is forwarded else false |
| 307 | */ |
| 308 | static bool |
| 309 | dp_rx_intrabss_fwd(struct dp_soc *soc, |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 310 | struct dp_peer *sa_peer, |
| 311 | uint8_t *rx_tlv_hdr, |
| 312 | qdf_nbuf_t nbuf) |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 313 | { |
Tallapragada Kalyan | 6f6166e | 2017-02-17 17:00:23 +0530 | [diff] [blame] | 314 | uint16_t da_idx; |
| 315 | uint16_t len; |
| 316 | struct dp_peer *da_peer; |
| 317 | struct dp_ast_entry *ast_entry; |
| 318 | qdf_nbuf_t nbuf_copy; |
| 319 | |
| 320 | /* check if the destination peer is available in peer table |
| 321 | * and also check if the source peer and destination peer |
| 322 | * belong to the same vap and destination peer is not bss peer. |
| 323 | */ |
| 324 | if ((hal_rx_msdu_end_da_is_valid_get(rx_tlv_hdr) && |
| 325 | !hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr))) { |
| 326 | da_idx = hal_rx_msdu_end_da_idx_get(rx_tlv_hdr); |
| 327 | |
| 328 | ast_entry = soc->ast_table[da_idx]; |
| 329 | if (!ast_entry) |
| 330 | return false; |
| 331 | |
| 332 | da_peer = ast_entry->peer; |
| 333 | |
| 334 | if (!da_peer) |
| 335 | return false; |
| 336 | |
| 337 | if (da_peer->vdev == sa_peer->vdev && !da_peer->bss_peer) { |
| 338 | memset(nbuf->cb, 0x0, sizeof(nbuf->cb)); |
| 339 | len = qdf_nbuf_len(nbuf); |
| 340 | if (!dp_tx_send(sa_peer->vdev, nbuf)) { |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 341 | DP_STATS_INC_PKT(sa_peer, rx.intra_bss.pkts, |
| 342 | 1, len); |
Tallapragada Kalyan | 6f6166e | 2017-02-17 17:00:23 +0530 | [diff] [blame] | 343 | return true; |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 344 | } else { |
| 345 | DP_STATS_INC_PKT(sa_peer, rx.intra_bss.fail, 1, |
| 346 | len); |
Tallapragada Kalyan | 6f6166e | 2017-02-17 17:00:23 +0530 | [diff] [blame] | 347 | return false; |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 348 | } |
Tallapragada Kalyan | 6f6166e | 2017-02-17 17:00:23 +0530 | [diff] [blame] | 349 | } |
| 350 | } |
| 351 | /* if it is a broadcast pkt (eg: ARP) and it is not its own |
| 352 | * source, then clone the pkt and send the cloned pkt for |
| 353 | * intra BSS forwarding and original pkt up the network stack |
| 354 | * Note: how do we handle multicast pkts. do we forward |
| 355 | * all multicast pkts as is or let a higher layer module |
| 356 | * like igmpsnoop decide whether to forward or not with |
| 357 | * Mcast enhancement. |
| 358 | */ |
| 359 | else if (qdf_unlikely((hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr) && |
| 360 | !sa_peer->bss_peer))) { |
| 361 | nbuf_copy = qdf_nbuf_copy(nbuf); |
| 362 | if (!nbuf_copy) |
| 363 | return false; |
| 364 | memset(nbuf_copy->cb, 0x0, sizeof(nbuf_copy->cb)); |
| 365 | len = qdf_nbuf_len(nbuf_copy); |
| 366 | if (dp_tx_send(sa_peer->vdev, nbuf_copy)) |
| 367 | qdf_nbuf_free(nbuf_copy); |
| 368 | else |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 369 | DP_STATS_INC_PKT(sa_peer, rx.intra_bss.pkts, 1, len); |
Tallapragada Kalyan | 6f6166e | 2017-02-17 17:00:23 +0530 | [diff] [blame] | 370 | } |
| 371 | /* return false as we have to still send the original pkt |
| 372 | * up the stack |
| 373 | */ |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 374 | return false; |
| 375 | } |
| 376 | |
Venkateswara Swamy Bandaru | c14b1b6 | 2017-02-24 12:26:08 +0530 | [diff] [blame] | 377 | #ifdef MESH_MODE_SUPPORT |
| 378 | |
| 379 | /** |
| 380 | * dp_rx_fill_mesh_stats() - Fills the mesh per packet receive stats |
| 381 | * |
| 382 | * @vdev: DP Virtual device handle |
| 383 | * @nbuf: Buffer pointer |
| 384 | * |
| 385 | * This function allocated memory for mesh receive stats and fill the |
| 386 | * required stats. Stores the memory address in skb cb. |
| 387 | * |
| 388 | * Return: void |
| 389 | */ |
| 390 | static |
| 391 | void dp_rx_fill_mesh_stats(struct dp_vdev *vdev, qdf_nbuf_t nbuf) |
| 392 | { |
| 393 | struct mesh_recv_hdr_s *rx_info = NULL; |
| 394 | uint32_t pkt_type; |
| 395 | uint32_t nss; |
| 396 | uint32_t rate_mcs; |
| 397 | uint8_t *rx_tlv_hdr = qdf_nbuf_data(nbuf); |
| 398 | |
| 399 | /* fill recv mesh stats */ |
| 400 | rx_info = qdf_mem_malloc(sizeof(struct mesh_recv_hdr_s)); |
| 401 | |
| 402 | /* upper layers are resposible to free this memory */ |
| 403 | |
| 404 | if (rx_info == NULL) { |
| 405 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, |
| 406 | "Memory allocation failed for mesh rx stats"); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 407 | DP_STATS_INC(vdev->pdev, mesh_mem_alloc, 1); |
Venkateswara Swamy Bandaru | c14b1b6 | 2017-02-24 12:26:08 +0530 | [diff] [blame] | 408 | return; |
| 409 | } |
| 410 | |
| 411 | if (qdf_nbuf_is_chfrag_start(nbuf)) |
| 412 | rx_info->rs_flags |= MESH_RX_FIRST_MSDU; |
| 413 | |
| 414 | if (qdf_nbuf_is_chfrag_end(nbuf)) |
| 415 | rx_info->rs_flags |= MESH_RX_LAST_MSDU; |
| 416 | |
| 417 | if (hal_rx_attn_msdu_get_is_decrypted(rx_tlv_hdr)) { |
| 418 | rx_info->rs_flags |= MESH_RX_DECRYPTED; |
| 419 | rx_info->rs_keyix = hal_rx_msdu_get_keyid(rx_tlv_hdr); |
| 420 | rx_info->rs_flags |= MESH_KEY_NOTFILLED; |
| 421 | } |
| 422 | |
| 423 | rx_info->rs_rssi = hal_rx_msdu_start_get_rssi(rx_tlv_hdr); |
| 424 | rx_info->rs_channel = hal_rx_msdu_start_get_freq(rx_tlv_hdr); |
| 425 | pkt_type = hal_rx_msdu_start_get_pkt_type(rx_tlv_hdr); |
| 426 | rate_mcs = hal_rx_msdu_start_rate_mcs_get(rx_tlv_hdr); |
| 427 | nss = hal_rx_msdu_start_nss_get(rx_tlv_hdr); |
| 428 | rx_info->rs_ratephy1 = rate_mcs | (nss << 0x4) | (pkt_type << 6); |
| 429 | |
| 430 | qdf_nbuf_set_fctx_type(nbuf, (void *)rx_info, CB_FTYPE_MESH_RX_INFO); |
Venkateswara Swamy Bandaru | c64c862 | 2017-02-27 20:08:33 +0530 | [diff] [blame] | 431 | |
| 432 | QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, |
| 433 | FL("Mesh rx stats: flags %x, rssi %x, chn %x, rate %x, kix %x"), |
| 434 | rx_info->rs_flags, |
| 435 | rx_info->rs_rssi, |
| 436 | rx_info->rs_channel, |
| 437 | rx_info->rs_ratephy1, |
| 438 | rx_info->rs_keyix); |
| 439 | |
Venkateswara Swamy Bandaru | c14b1b6 | 2017-02-24 12:26:08 +0530 | [diff] [blame] | 440 | } |
Venkateswara Swamy Bandaru | ec4f8e6 | 2017-03-07 11:04:28 +0530 | [diff] [blame] | 441 | |
| 442 | /** |
| 443 | * dp_rx_fill_mesh_stats() - Filters mesh unwanted packets |
| 444 | * |
| 445 | * @vdev: DP Virtual device handle |
| 446 | * @nbuf: Buffer pointer |
| 447 | * |
| 448 | * This checks if the received packet is matching any filter out |
| 449 | * catogery and and drop the packet if it matches. |
| 450 | * |
| 451 | * Return: status(0 indicates drop, 1 indicate to no drop) |
| 452 | */ |
| 453 | |
| 454 | static inline |
| 455 | QDF_STATUS dp_rx_filter_mesh_packets(struct dp_vdev *vdev, qdf_nbuf_t nbuf) |
| 456 | { |
| 457 | uint8_t *rx_tlv_hdr = qdf_nbuf_data(nbuf); |
| 458 | union dp_align_mac_addr mac_addr; |
| 459 | |
| 460 | if (qdf_unlikely(vdev->mesh_rx_filter)) { |
| 461 | if (vdev->mesh_rx_filter & MESH_FILTER_OUT_FROMDS) |
| 462 | if (hal_rx_mpdu_get_fr_ds(rx_tlv_hdr)) |
| 463 | return QDF_STATUS_SUCCESS; |
| 464 | |
| 465 | if (vdev->mesh_rx_filter & MESH_FILTER_OUT_TODS) |
| 466 | if (hal_rx_mpdu_get_to_ds(rx_tlv_hdr)) |
| 467 | return QDF_STATUS_SUCCESS; |
| 468 | |
| 469 | if (vdev->mesh_rx_filter & MESH_FILTER_OUT_NODS) |
| 470 | if (!hal_rx_mpdu_get_fr_ds(rx_tlv_hdr) |
| 471 | && !hal_rx_mpdu_get_to_ds(rx_tlv_hdr)) |
| 472 | return QDF_STATUS_SUCCESS; |
| 473 | |
| 474 | if (vdev->mesh_rx_filter & MESH_FILTER_OUT_RA) { |
| 475 | if (hal_rx_mpdu_get_addr1(rx_tlv_hdr, |
| 476 | &mac_addr.raw[0])) |
| 477 | return QDF_STATUS_E_FAILURE; |
| 478 | |
| 479 | if (!qdf_mem_cmp(&mac_addr.raw[0], |
| 480 | &vdev->mac_addr.raw[0], |
| 481 | DP_MAC_ADDR_LEN)) |
| 482 | return QDF_STATUS_SUCCESS; |
| 483 | } |
| 484 | |
| 485 | if (vdev->mesh_rx_filter & MESH_FILTER_OUT_TA) { |
| 486 | if (hal_rx_mpdu_get_addr2(rx_tlv_hdr, |
| 487 | &mac_addr.raw[0])) |
| 488 | return QDF_STATUS_E_FAILURE; |
| 489 | |
| 490 | if (!qdf_mem_cmp(&mac_addr.raw[0], |
| 491 | &vdev->mac_addr.raw[0], |
| 492 | DP_MAC_ADDR_LEN)) |
| 493 | return QDF_STATUS_SUCCESS; |
| 494 | } |
| 495 | } |
| 496 | |
| 497 | return QDF_STATUS_E_FAILURE; |
| 498 | } |
| 499 | |
Venkateswara Swamy Bandaru | c14b1b6 | 2017-02-24 12:26:08 +0530 | [diff] [blame] | 500 | #else |
| 501 | static |
| 502 | void dp_rx_fill_mesh_stats(struct dp_vdev *vdev, qdf_nbuf_t nbuf) |
| 503 | { |
| 504 | } |
| 505 | |
Venkateswara Swamy Bandaru | ec4f8e6 | 2017-03-07 11:04:28 +0530 | [diff] [blame] | 506 | static inline |
| 507 | QDF_STATUS dp_rx_filter_mesh_packets(struct dp_vdev *vdev, qdf_nbuf_t nbuf) |
| 508 | { |
| 509 | return QDF_STATUS_E_FAILURE; |
| 510 | } |
| 511 | |
Venkateswara Swamy Bandaru | c14b1b6 | 2017-02-24 12:26:08 +0530 | [diff] [blame] | 512 | #endif |
| 513 | |
Ishank Jain | 9f174c6 | 2017-03-30 18:37:42 +0530 | [diff] [blame] | 514 | #ifdef CONFIG_WIN |
| 515 | /** |
Pratik Gandhi | 3da3bc7 | 2017-03-16 18:20:22 +0530 | [diff] [blame] | 516 | * dp_rx_nac_filter(): Function to perform filtering of non-associated |
| 517 | * clients |
| 518 | * @pdev: DP pdev handle |
| 519 | * @rx_pkt_hdr: Rx packet Header |
| 520 | * |
| 521 | * return: dp_vdev* |
| 522 | */ |
| 523 | static |
| 524 | struct dp_vdev *dp_rx_nac_filter(struct dp_pdev *pdev, |
| 525 | uint8_t *rx_pkt_hdr) |
| 526 | { |
| 527 | struct ieee80211_frame *wh; |
| 528 | struct dp_neighbour_peer *peer = NULL; |
| 529 | |
| 530 | wh = (struct ieee80211_frame *)rx_pkt_hdr; |
| 531 | |
| 532 | if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != IEEE80211_FC1_DIR_TODS) |
| 533 | return NULL; |
| 534 | |
| 535 | qdf_spin_lock_bh(&pdev->neighbour_peer_mutex); |
| 536 | TAILQ_FOREACH(peer, &pdev->neighbour_peers_list, |
| 537 | neighbour_peer_list_elem) { |
| 538 | if (qdf_mem_cmp(&peer->neighbour_peers_macaddr.raw[0], |
| 539 | wh->i_addr2, DP_MAC_ADDR_LEN) == 0) { |
| 540 | QDF_TRACE( |
| 541 | QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, |
| 542 | FL("NAC configuration matched for mac-%2x:%2x:%2x:%2x:%2x:%2x"), |
| 543 | peer->neighbour_peers_macaddr.raw[0], |
| 544 | peer->neighbour_peers_macaddr.raw[1], |
| 545 | peer->neighbour_peers_macaddr.raw[2], |
| 546 | peer->neighbour_peers_macaddr.raw[3], |
| 547 | peer->neighbour_peers_macaddr.raw[4], |
| 548 | peer->neighbour_peers_macaddr.raw[5]); |
| 549 | return pdev->monitor_vdev; |
| 550 | } |
| 551 | } |
| 552 | qdf_spin_unlock_bh(&pdev->neighbour_peer_mutex); |
| 553 | |
| 554 | return NULL; |
| 555 | } |
| 556 | |
| 557 | /** |
Ishank Jain | 9f174c6 | 2017-03-30 18:37:42 +0530 | [diff] [blame] | 558 | * dp_rx_process_invalid_peer(): Function to pass invalid peer list to umac |
| 559 | * @soc: DP SOC handle |
Pratik Gandhi | 3da3bc7 | 2017-03-16 18:20:22 +0530 | [diff] [blame] | 560 | * @mpdu: mpdu for which peer is invalid |
Ishank Jain | 9f174c6 | 2017-03-30 18:37:42 +0530 | [diff] [blame] | 561 | * |
| 562 | * return: integer type |
| 563 | */ |
Pratik Gandhi | 3da3bc7 | 2017-03-16 18:20:22 +0530 | [diff] [blame] | 564 | uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu) |
Ishank Jain | 9f174c6 | 2017-03-30 18:37:42 +0530 | [diff] [blame] | 565 | { |
| 566 | struct dp_invalid_peer_msg msg; |
| 567 | struct dp_vdev *vdev = NULL; |
| 568 | struct dp_pdev *pdev = NULL; |
| 569 | struct ieee80211_frame *wh; |
| 570 | uint8_t i; |
| 571 | uint8_t *rx_pkt_hdr; |
| 572 | |
Pratik Gandhi | 3da3bc7 | 2017-03-16 18:20:22 +0530 | [diff] [blame] | 573 | rx_pkt_hdr = hal_rx_pkt_hdr_get(qdf_nbuf_data(mpdu)); |
Ishank Jain | 9f174c6 | 2017-03-30 18:37:42 +0530 | [diff] [blame] | 574 | wh = (struct ieee80211_frame *)rx_pkt_hdr; |
| 575 | |
| 576 | if (!DP_FRAME_IS_DATA(wh)) { |
| 577 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, |
| 578 | "NAWDS valid only for data frames"); |
| 579 | return 1; |
| 580 | } |
| 581 | |
Pratik Gandhi | 3da3bc7 | 2017-03-16 18:20:22 +0530 | [diff] [blame] | 582 | if (qdf_nbuf_len(mpdu) < sizeof(struct ieee80211_frame)) { |
Ishank Jain | 9f174c6 | 2017-03-30 18:37:42 +0530 | [diff] [blame] | 583 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, |
| 584 | "Invalid nbuf length"); |
| 585 | return 1; |
| 586 | } |
| 587 | |
| 588 | |
| 589 | for (i = 0; i < MAX_PDEV_CNT; i++) { |
| 590 | pdev = soc->pdev_list[i]; |
| 591 | if (!pdev) { |
| 592 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, |
| 593 | "PDEV not found"); |
| 594 | continue; |
| 595 | } |
| 596 | |
Pratik Gandhi | 3da3bc7 | 2017-03-16 18:20:22 +0530 | [diff] [blame] | 597 | if (pdev->filter_neighbour_peers) { |
| 598 | /* Next Hop scenario not yet handle */ |
| 599 | vdev = dp_rx_nac_filter(pdev, rx_pkt_hdr); |
| 600 | if (vdev) { |
| 601 | dp_rx_mon_deliver(soc, i, |
| 602 | soc->invalid_peer_head_msdu, |
| 603 | soc->invalid_peer_tail_msdu); |
| 604 | return 0; |
| 605 | } |
| 606 | } |
Ishank Jain | 9f174c6 | 2017-03-30 18:37:42 +0530 | [diff] [blame] | 607 | TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { |
| 608 | if (qdf_mem_cmp(wh->i_addr1, vdev->mac_addr.raw, |
| 609 | DP_MAC_ADDR_LEN) == 0) { |
| 610 | goto out; |
| 611 | } |
| 612 | } |
| 613 | } |
| 614 | |
| 615 | if (!vdev) { |
| 616 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, |
| 617 | "VDEV not found"); |
| 618 | return 1; |
| 619 | } |
| 620 | |
| 621 | out: |
| 622 | msg.wh = wh; |
Pratik Gandhi | 3da3bc7 | 2017-03-16 18:20:22 +0530 | [diff] [blame] | 623 | qdf_nbuf_pull_head(mpdu, RX_PKT_TLVS_LEN); |
| 624 | msg.nbuf = mpdu; |
Ishank Jain | 9f174c6 | 2017-03-30 18:37:42 +0530 | [diff] [blame] | 625 | msg.vdev_id = vdev->vdev_id; |
| 626 | if (pdev->soc->cdp_soc.ol_ops->rx_invalid_peer) |
| 627 | return pdev->soc->cdp_soc.ol_ops->rx_invalid_peer( |
| 628 | pdev->osif_pdev, &msg); |
| 629 | |
| 630 | return 0; |
| 631 | } |
| 632 | #else |
Pratik Gandhi | 3da3bc7 | 2017-03-16 18:20:22 +0530 | [diff] [blame] | 633 | uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu) |
Ishank Jain | 9f174c6 | 2017-03-30 18:37:42 +0530 | [diff] [blame] | 634 | { |
| 635 | return 0; |
| 636 | } |
| 637 | #endif |
| 638 | |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 639 | /** |
Dhanashri Atre | 0da3122 | 2017-03-23 12:30:58 -0700 | [diff] [blame] | 640 | * dp_rx_lro() - LRO related processing |
| 641 | * @rx_tlv: TLV data extracted from the rx packet |
| 642 | * @peer: destination peer of the msdu |
| 643 | * @msdu: network buffer |
| 644 | * @ctx: LRO context |
| 645 | * |
| 646 | * This function performs the LRO related processing of the msdu |
| 647 | * |
| 648 | * Return: true: LRO enabled false: LRO is not enabled |
| 649 | */ |
| 650 | #if defined(FEATURE_LRO) |
| 651 | static bool dp_rx_lro(uint8_t *rx_tlv, struct dp_peer *peer, |
| 652 | qdf_nbuf_t msdu, qdf_lro_ctx_t ctx) |
| 653 | { |
| 654 | qdf_assert(rx_tlv); |
| 655 | if (peer->vdev->lro_enable && |
| 656 | HAL_RX_TLV_GET_TCP_PROTO(rx_tlv)) { |
| 657 | QDF_NBUF_CB_RX_LRO_ELIGIBLE(msdu) = |
| 658 | HAL_RX_TLV_GET_LRO_ELIGIBLE(rx_tlv) && |
| 659 | !HAL_RX_TLV_GET_TCP_PURE_ACK(rx_tlv); |
| 660 | |
| 661 | if (QDF_NBUF_CB_RX_LRO_ELIGIBLE(msdu)) { |
| 662 | QDF_NBUF_CB_RX_LRO_CTX(msdu) = ctx; |
| 663 | QDF_NBUF_CB_RX_TCP_ACK_NUM(msdu) = |
| 664 | HAL_RX_TLV_GET_TCP_ACK(rx_tlv); |
| 665 | QDF_NBUF_CB_RX_TCP_WIN(msdu) = |
| 666 | HAL_RX_TLV_GET_TCP_WIN(rx_tlv); |
| 667 | QDF_NBUF_CB_RX_TCP_SEQ_NUM(msdu) = |
| 668 | HAL_RX_TLV_GET_TCP_SEQ(rx_tlv); |
| 669 | QDF_NBUF_CB_RX_TCP_CHKSUM(msdu) = |
| 670 | HAL_RX_TLV_GET_TCP_CHKSUM |
| 671 | (rx_tlv); |
| 672 | QDF_NBUF_CB_RX_FLOW_ID_TOEPLITZ(msdu) = |
| 673 | HAL_RX_TLV_GET_FLOW_ID_TOEPLITZ |
| 674 | (rx_tlv); |
| 675 | QDF_NBUF_CB_RX_TCP_OFFSET(msdu) = |
| 676 | HAL_RX_TLV_GET_TCP_OFFSET |
| 677 | (rx_tlv); |
| 678 | QDF_NBUF_CB_RX_IPV6_PROTO(msdu) = |
| 679 | HAL_RX_TLV_GET_IPV6(rx_tlv); |
| 680 | |
| 681 | QDF_NBUF_CB_RX_LRO_ELIGIBLE(msdu) = |
| 682 | qdf_lro_update_info(ctx, msdu); |
| 683 | } |
| 684 | /* LRO 'enabled' packet, it may not be LRO 'eligible' */ |
| 685 | return true; |
| 686 | } |
| 687 | |
| 688 | /* LRO not supported on this vdev or a non-TCP packet */ |
| 689 | return false; |
| 690 | } |
| 691 | #else |
| 692 | static bool dp_rx_lro(uint8_t *rx_tlv, struct dp_peer *peer, |
| 693 | qdf_nbuf_t msdu, qdf_lro_ctx_t ctx) |
| 694 | { |
| 695 | return false; |
| 696 | } |
| 697 | #endif |
| 698 | |
| 699 | /** |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 700 | * dp_rx_process() - Brain of the Rx processing functionality |
| 701 | * Called from the bottom half (tasklet/NET_RX_SOFTIRQ) |
| 702 | * @soc: core txrx main context |
| 703 | * @hal_ring: opaque pointer to the HAL Rx Ring, which will be serviced |
| 704 | * @quota: No. of units (packets) that can be serviced in one shot. |
| 705 | * |
| 706 | * This function implements the core of Rx functionality. This is |
| 707 | * expected to handle only non-error frames. |
| 708 | * |
| 709 | * Return: uint32_t: No. of elements processed |
| 710 | */ |
| 711 | uint32_t |
Dhanashri Atre | 0da3122 | 2017-03-23 12:30:58 -0700 | [diff] [blame] | 712 | dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint32_t quota) |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 713 | { |
| 714 | void *hal_soc; |
| 715 | void *ring_desc; |
Dhanashri Atre | 0da3122 | 2017-03-23 12:30:58 -0700 | [diff] [blame] | 716 | struct dp_rx_desc *rx_desc = NULL; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 717 | qdf_nbuf_t nbuf; |
Tallapragada Kalyan | aae8c41 | 2017-02-13 12:00:17 +0530 | [diff] [blame] | 718 | union dp_rx_desc_list_elem_t *head[MAX_PDEV_CNT] = { NULL }; |
| 719 | union dp_rx_desc_list_elem_t *tail[MAX_PDEV_CNT] = { NULL }; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 720 | uint32_t rx_bufs_used = 0, rx_buf_cookie, l2_hdr_offset; |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 721 | uint16_t msdu_len; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 722 | uint16_t peer_id; |
| 723 | struct dp_peer *peer = NULL; |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 724 | struct dp_vdev *vdev = NULL; |
Tallapragada Kalyan | aae8c41 | 2017-02-13 12:00:17 +0530 | [diff] [blame] | 725 | struct dp_vdev *vdev_list[WLAN_UMAC_PSOC_MAX_VDEVS] = { NULL }; |
Ishank Jain | bc2d91f | 2017-01-03 18:14:54 +0530 | [diff] [blame] | 726 | uint32_t pkt_len; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 727 | struct hal_rx_mpdu_desc_info mpdu_desc_info; |
Kalyan Tallapragada | 277f45e | 2017-01-30 14:25:27 +0530 | [diff] [blame] | 728 | struct hal_rx_msdu_desc_info msdu_desc_info; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 729 | enum hal_reo_error_status error; |
Tallapragada Kalyan | e7d51ef | 2017-02-06 11:58:21 +0530 | [diff] [blame] | 730 | static uint32_t peer_mdata; |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 731 | uint8_t *rx_tlv_hdr; |
Tallapragada Kalyan | aae8c41 | 2017-02-13 12:00:17 +0530 | [diff] [blame] | 732 | uint32_t rx_bufs_reaped[MAX_PDEV_CNT] = { 0 }; |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 733 | uint32_t sgi, mcs, tid, nss, bw, reception_type, pkt_type; |
Tallapragada Kalyan | aae8c41 | 2017-02-13 12:00:17 +0530 | [diff] [blame] | 734 | uint64_t vdev_map = 0; |
| 735 | uint8_t mac_id; |
| 736 | uint16_t i, vdev_cnt = 0; |
Ishank Jain | bc2d91f | 2017-01-03 18:14:54 +0530 | [diff] [blame] | 737 | uint32_t ampdu_flag, amsdu_flag; |
Ishank Jain | 1e7401c | 2017-02-17 15:38:39 +0530 | [diff] [blame] | 738 | struct ether_header *eh; |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 739 | struct dp_pdev *pdev; |
| 740 | struct dp_srng *dp_rxdma_srng; |
| 741 | struct rx_desc_pool *rx_desc_pool; |
Dhanashri Atre | 0da3122 | 2017-03-23 12:30:58 -0700 | [diff] [blame] | 742 | struct dp_soc *soc = int_ctx->soc; |
Venkata Sharath Chandra Manchala | 918aefe | 2017-04-10 10:21:56 -0700 | [diff] [blame] | 743 | uint8_t ring_id; |
| 744 | uint8_t core_id; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 745 | |
Venkata Sharath Chandra Manchala | a405eb7 | 2017-03-06 14:35:00 -0800 | [diff] [blame] | 746 | DP_HIST_INIT(); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 747 | /* Debug -- Remove later */ |
| 748 | qdf_assert(soc && hal_ring); |
| 749 | |
| 750 | hal_soc = soc->hal_soc; |
| 751 | |
| 752 | /* Debug -- Remove later */ |
| 753 | qdf_assert(hal_soc); |
| 754 | |
| 755 | if (qdf_unlikely(hal_srng_access_start(hal_soc, hal_ring))) { |
| 756 | |
| 757 | /* |
| 758 | * Need API to convert from hal_ring pointer to |
| 759 | * Ring Type / Ring Id combo |
| 760 | */ |
Venkata Sharath Chandra Manchala | a405eb7 | 2017-03-06 14:35:00 -0800 | [diff] [blame] | 761 | DP_STATS_INC(soc, rx.err.hal_ring_access_fail, 1); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 762 | QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, |
Tallapragada Kalyan | 1ef5480 | 2016-11-30 12:54:55 +0530 | [diff] [blame] | 763 | FL("HAL RING Access Failed -- %p"), hal_ring); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 764 | hal_srng_access_end(hal_soc, hal_ring); |
| 765 | goto done; |
| 766 | } |
| 767 | |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 768 | /* |
| 769 | * start reaping the buffers from reo ring and queue |
| 770 | * them in per vdev queue. |
| 771 | * Process the received pkts in a different per vdev loop. |
| 772 | */ |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 773 | while (qdf_likely((ring_desc = |
| 774 | hal_srng_dst_get_next(hal_soc, hal_ring)) |
| 775 | && quota--)) { |
| 776 | |
| 777 | error = HAL_RX_ERROR_STATUS_GET(ring_desc); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 778 | ring_id = hal_srng_ring_id_get(hal_ring); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 779 | |
| 780 | if (qdf_unlikely(error == HAL_REO_ERROR_DETECTED)) { |
| 781 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, |
Tallapragada Kalyan | 1ef5480 | 2016-11-30 12:54:55 +0530 | [diff] [blame] | 782 | FL("HAL RING 0x%p:error %d"), hal_ring, error); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 783 | DP_STATS_INC(soc, rx.err.hal_reo_error[ring_id], 1); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 784 | /* Don't know how to deal with this -- assert */ |
| 785 | qdf_assert(0); |
| 786 | } |
| 787 | |
| 788 | rx_buf_cookie = HAL_RX_REO_BUF_COOKIE_GET(ring_desc); |
| 789 | |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 790 | rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc, rx_buf_cookie); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 791 | |
| 792 | qdf_assert(rx_desc); |
Tallapragada Kalyan | aae8c41 | 2017-02-13 12:00:17 +0530 | [diff] [blame] | 793 | rx_bufs_reaped[rx_desc->pool_id]++; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 794 | |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 795 | /* TODO */ |
| 796 | /* |
| 797 | * Need a separate API for unmapping based on |
| 798 | * phyiscal address |
| 799 | */ |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 800 | qdf_nbuf_unmap_single(soc->osdev, rx_desc->nbuf, |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 801 | QDF_DMA_BIDIRECTIONAL); |
| 802 | |
Venkata Sharath Chandra Manchala | 918aefe | 2017-04-10 10:21:56 -0700 | [diff] [blame] | 803 | core_id = smp_processor_id(); |
| 804 | DP_STATS_INC(soc, rx.ring_packets[core_id][ring_id], 1); |
| 805 | |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 806 | /* Get MPDU DESC info */ |
| 807 | hal_rx_mpdu_desc_info_get(ring_desc, &mpdu_desc_info); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 808 | peer_id = DP_PEER_METADATA_PEER_ID_GET( |
| 809 | mpdu_desc_info.peer_meta_data); |
| 810 | |
| 811 | peer = dp_peer_find_by_id(soc, peer_id); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 812 | |
Pramod Simha | b17d067 | 2017-03-06 17:20:13 -0800 | [diff] [blame] | 813 | vdev = dp_get_vdev_from_peer(soc, peer_id, peer, |
| 814 | mpdu_desc_info); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 815 | |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 816 | if (!vdev) { |
| 817 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, |
| 818 | FL("vdev is NULL")); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 819 | DP_STATS_INC(soc, rx.err.invalid_vdev, 1); |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 820 | qdf_nbuf_free(rx_desc->nbuf); |
| 821 | goto fail; |
Tallapragada Kalyan | aae8c41 | 2017-02-13 12:00:17 +0530 | [diff] [blame] | 822 | |
| 823 | } |
| 824 | |
| 825 | if (!((vdev_map >> vdev->vdev_id) & 1)) { |
| 826 | vdev_map |= 1 << vdev->vdev_id; |
| 827 | vdev_list[vdev_cnt] = vdev; |
| 828 | vdev_cnt++; |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 829 | } |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 830 | |
Kalyan Tallapragada | 277f45e | 2017-01-30 14:25:27 +0530 | [diff] [blame] | 831 | /* Get MSDU DESC info */ |
| 832 | hal_rx_msdu_desc_info_get(ring_desc, &msdu_desc_info); |
| 833 | |
| 834 | /* |
| 835 | * save msdu flags first, last and continuation msdu in |
| 836 | * nbuf->cb |
| 837 | */ |
| 838 | if (msdu_desc_info.msdu_flags & HAL_MSDU_F_FIRST_MSDU_IN_MPDU) |
| 839 | qdf_nbuf_set_chfrag_start(rx_desc->nbuf, 1); |
| 840 | |
| 841 | if (msdu_desc_info.msdu_flags & HAL_MSDU_F_MSDU_CONTINUATION) |
| 842 | qdf_nbuf_set_chfrag_cont(rx_desc->nbuf, 1); |
| 843 | |
| 844 | if (msdu_desc_info.msdu_flags & HAL_MSDU_F_LAST_MSDU_IN_MPDU) |
| 845 | qdf_nbuf_set_chfrag_end(rx_desc->nbuf, 1); |
| 846 | |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 847 | DP_STATS_INC_PKT(peer, rx.rcvd_reo[ring_id], 1, |
Ishank Jain | bc2d91f | 2017-01-03 18:14:54 +0530 | [diff] [blame] | 848 | qdf_nbuf_len(rx_desc->nbuf)); |
| 849 | |
| 850 | ampdu_flag = (mpdu_desc_info.mpdu_flags & |
| 851 | HAL_MPDU_F_AMPDU_FLAG); |
Venkata Sharath Chandra Manchala | a405eb7 | 2017-03-06 14:35:00 -0800 | [diff] [blame] | 852 | |
Venkata Sharath Chandra Manchala | 87686d9 | 2017-03-27 11:40:26 -0700 | [diff] [blame] | 853 | DP_STATS_INCC(peer, rx.ampdu_cnt, 1, ampdu_flag); |
| 854 | DP_STATS_INCC(peer, rx.non_ampdu_cnt, 1, !(ampdu_flag)); |
Ishank Jain | bc2d91f | 2017-01-03 18:14:54 +0530 | [diff] [blame] | 855 | |
| 856 | hal_rx_msdu_desc_info_get(ring_desc, &msdu_desc_info); |
| 857 | amsdu_flag = ((msdu_desc_info.msdu_flags & |
| 858 | HAL_MSDU_F_FIRST_MSDU_IN_MPDU) && |
| 859 | (msdu_desc_info.msdu_flags & |
| 860 | HAL_MSDU_F_LAST_MSDU_IN_MPDU)); |
| 861 | |
Venkata Sharath Chandra Manchala | 87686d9 | 2017-03-27 11:40:26 -0700 | [diff] [blame] | 862 | DP_STATS_INCC(peer, rx.non_amsdu_cnt, 1, |
Ishank Jain | bc2d91f | 2017-01-03 18:14:54 +0530 | [diff] [blame] | 863 | amsdu_flag); |
Venkata Sharath Chandra Manchala | 87686d9 | 2017-03-27 11:40:26 -0700 | [diff] [blame] | 864 | DP_STATS_INCC(peer, rx.amsdu_cnt, 1, |
Ishank Jain | bc2d91f | 2017-01-03 18:14:54 +0530 | [diff] [blame] | 865 | !(amsdu_flag)); |
| 866 | |
Venkata Sharath Chandra Manchala | a405eb7 | 2017-03-06 14:35:00 -0800 | [diff] [blame] | 867 | DP_HIST_PACKET_COUNT_INC(vdev->pdev->pdev_id); |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 868 | qdf_nbuf_queue_add(&vdev->rxq, rx_desc->nbuf); |
| 869 | fail: |
Tallapragada Kalyan | aae8c41 | 2017-02-13 12:00:17 +0530 | [diff] [blame] | 870 | dp_rx_add_to_free_desc_list(&head[rx_desc->pool_id], |
| 871 | &tail[rx_desc->pool_id], |
| 872 | rx_desc); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 873 | } |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 874 | done: |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 875 | hal_srng_access_end(hal_soc, hal_ring); |
| 876 | |
Venkata Sharath Chandra Manchala | a405eb7 | 2017-03-06 14:35:00 -0800 | [diff] [blame] | 877 | /* Update histogram statistics by looping through pdev's */ |
| 878 | DP_RX_HIST_STATS_PER_PDEV(); |
| 879 | |
Tallapragada Kalyan | aae8c41 | 2017-02-13 12:00:17 +0530 | [diff] [blame] | 880 | for (mac_id = 0; mac_id < MAX_PDEV_CNT; mac_id++) { |
| 881 | /* |
| 882 | * continue with next mac_id if no pkts were reaped |
| 883 | * from that pool |
| 884 | */ |
| 885 | if (!rx_bufs_reaped[mac_id]) |
| 886 | continue; |
| 887 | |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 888 | pdev = soc->pdev_list[mac_id]; |
| 889 | dp_rxdma_srng = &pdev->rx_refill_buf_ring; |
| 890 | rx_desc_pool = &soc->rx_desc_buf[mac_id]; |
| 891 | |
| 892 | dp_rx_buffers_replenish(soc, mac_id, dp_rxdma_srng, |
| 893 | rx_desc_pool, rx_bufs_reaped[mac_id], |
| 894 | &head[mac_id], &tail[mac_id], |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 895 | HAL_RX_BUF_RBM_SW3_BM); |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 896 | } |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 897 | |
Tallapragada Kalyan | aae8c41 | 2017-02-13 12:00:17 +0530 | [diff] [blame] | 898 | for (i = 0; i < vdev_cnt; i++) { |
Dhanashri Atre | bda02dc | 2017-02-02 16:28:12 -0800 | [diff] [blame] | 899 | qdf_nbuf_t deliver_list_head = NULL; |
| 900 | qdf_nbuf_t deliver_list_tail = NULL; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 901 | |
Tallapragada Kalyan | aae8c41 | 2017-02-13 12:00:17 +0530 | [diff] [blame] | 902 | vdev = vdev_list[i]; |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 903 | while ((nbuf = qdf_nbuf_queue_remove(&vdev->rxq))) { |
| 904 | rx_tlv_hdr = qdf_nbuf_data(nbuf); |
Ishank Jain | 1e7401c | 2017-02-17 15:38:39 +0530 | [diff] [blame] | 905 | eh = (struct ether_header *)qdf_nbuf_data(nbuf); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 906 | |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 907 | /* |
| 908 | * Check if DMA completed -- msdu_done is the last bit |
| 909 | * to be written |
| 910 | */ |
| 911 | if (!hal_rx_attn_msdu_done_get(rx_tlv_hdr)) { |
| 912 | |
| 913 | QDF_TRACE(QDF_MODULE_ID_DP, |
| 914 | QDF_TRACE_LEVEL_ERROR, |
Tallapragada Kalyan | 67ad342 | 2017-02-06 15:59:45 +0530 | [diff] [blame] | 915 | FL("MSDU DONE failure")); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 916 | DP_STATS_INC(vdev->pdev, dropped.msdu_not_done, |
| 917 | 1); |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 918 | |
Tallapragada Kalyan | 67ad342 | 2017-02-06 15:59:45 +0530 | [diff] [blame] | 919 | hal_rx_dump_pkt_tlvs(rx_tlv_hdr, |
| 920 | QDF_TRACE_LEVEL_INFO); |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 921 | qdf_assert(0); |
| 922 | } |
| 923 | |
Tallapragada Kalyan | e7d51ef | 2017-02-06 11:58:21 +0530 | [diff] [blame] | 924 | if (qdf_nbuf_is_chfrag_start(nbuf)) |
| 925 | peer_mdata = hal_rx_mpdu_peer_meta_data_get(rx_tlv_hdr); |
| 926 | |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 927 | peer_id = DP_PEER_METADATA_PEER_ID_GET(peer_mdata); |
| 928 | peer = dp_peer_find_by_id(soc, peer_id); |
| 929 | |
| 930 | /* TODO */ |
| 931 | /* |
| 932 | * In case of roaming peer object may not be |
| 933 | * immediately available -- need to handle this |
| 934 | * Cannot drop these packets right away. |
| 935 | */ |
| 936 | /* Peer lookup failed */ |
Pramod Simha | b17d067 | 2017-03-06 17:20:13 -0800 | [diff] [blame] | 937 | if (!peer && !vdev) { |
Ishank Jain | 9f174c6 | 2017-03-30 18:37:42 +0530 | [diff] [blame] | 938 | dp_rx_process_invalid_peer(soc, nbuf); |
Ishank Jain | e73c403 | 2017-03-16 11:48:15 +0530 | [diff] [blame] | 939 | DP_STATS_INC_PKT(soc, rx.err.rx_invalid_peer, 1, |
| 940 | qdf_nbuf_len(nbuf)); |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 941 | /* Drop & free packet */ |
| 942 | qdf_nbuf_free(nbuf); |
| 943 | |
| 944 | /* Statistics */ |
| 945 | continue; |
| 946 | } |
| 947 | |
Pramod Simha | b17d067 | 2017-03-06 17:20:13 -0800 | [diff] [blame] | 948 | if (peer && qdf_unlikely(peer->bss_peer)) { |
Tallapragada Kalyan | 3549b43 | 2017-02-06 16:34:42 +0530 | [diff] [blame] | 949 | QDF_TRACE(QDF_MODULE_ID_DP, |
| 950 | QDF_TRACE_LEVEL_INFO, |
| 951 | FL("received pkt with same src MAC")); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 952 | DP_STATS_INC(vdev->pdev, dropped.mec, 1); |
Tallapragada Kalyan | 3549b43 | 2017-02-06 16:34:42 +0530 | [diff] [blame] | 953 | |
| 954 | /* Drop & free packet */ |
| 955 | qdf_nbuf_free(nbuf); |
| 956 | /* Statistics */ |
| 957 | continue; |
| 958 | } |
Tallapragada Kalyan | 1b4d08d | 2016-12-15 22:19:58 +0530 | [diff] [blame] | 959 | |
| 960 | sgi = hal_rx_msdu_start_sgi_get(rx_tlv_hdr); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 961 | mcs = hal_rx_msdu_start_rate_mcs_get(rx_tlv_hdr); |
Tallapragada Kalyan | 1b4d08d | 2016-12-15 22:19:58 +0530 | [diff] [blame] | 962 | tid = hal_rx_mpdu_start_tid_get(rx_tlv_hdr); |
| 963 | |
| 964 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 965 | "%s: %d, SGI: %d, tid: %d", |
| 966 | __func__, __LINE__, sgi, tid); |
Tallapragada Kalyan | 1b4d08d | 2016-12-15 22:19:58 +0530 | [diff] [blame] | 967 | |
Ishank Jain | bc2d91f | 2017-01-03 18:14:54 +0530 | [diff] [blame] | 968 | bw = hal_rx_msdu_start_bw_get(rx_tlv_hdr); |
| 969 | reception_type = hal_rx_msdu_start_reception_type_get( |
| 970 | rx_tlv_hdr); |
| 971 | nss = hal_rx_msdu_start_nss_get(rx_tlv_hdr); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 972 | pkt_type = hal_rx_msdu_start_get_pkt_type(rx_tlv_hdr); |
Ishank Jain | bc2d91f | 2017-01-03 18:14:54 +0530 | [diff] [blame] | 973 | |
| 974 | DP_STATS_INC(vdev->pdev, rx.bw[bw], 1); |
| 975 | DP_STATS_INC(vdev->pdev, |
| 976 | rx.reception_type[reception_type], 1); |
| 977 | DP_STATS_INCC(vdev->pdev, rx.nss[nss], 1, |
Ishank Jain | 1e7401c | 2017-02-17 15:38:39 +0530 | [diff] [blame] | 978 | ((reception_type == REPT_MU_MIMO) || |
| 979 | (reception_type == REPT_MU_OFDMA_MIMO)) |
| 980 | ); |
| 981 | DP_STATS_INC(peer, rx.sgi_count[sgi], 1); |
Ishank Jain | 1e7401c | 2017-02-17 15:38:39 +0530 | [diff] [blame] | 982 | DP_STATS_INCC(peer, rx.err.mic_err, 1, |
| 983 | hal_rx_mpdu_end_mic_err_get( |
| 984 | rx_tlv_hdr)); |
| 985 | DP_STATS_INCC(peer, rx.err.decrypt_err, 1, |
| 986 | hal_rx_mpdu_end_decrypt_err_get( |
| 987 | rx_tlv_hdr)); |
| 988 | |
| 989 | DP_STATS_INC(peer, rx.wme_ac_type[TID_TO_WME_AC(tid)], |
| 990 | 1); |
| 991 | DP_STATS_INC(peer, rx.bw[bw], 1); |
| 992 | DP_STATS_INC(peer, rx.reception_type[reception_type], |
| 993 | 1); |
Ishank Jain | bc2d91f | 2017-01-03 18:14:54 +0530 | [diff] [blame] | 994 | |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 995 | DP_STATS_INCC(peer, rx.pkt_type[pkt_type]. |
| 996 | mcs_count[MAX_MCS], 1, |
| 997 | ((mcs >= MAX_MCS_11A) && (pkt_type |
| 998 | == DOT11_A))); |
| 999 | DP_STATS_INCC(peer, rx.pkt_type[pkt_type]. |
| 1000 | mcs_count[mcs], 1, |
| 1001 | ((mcs <= MAX_MCS_11A) && (pkt_type |
| 1002 | == DOT11_A))); |
| 1003 | DP_STATS_INCC(peer, rx.pkt_type[pkt_type]. |
| 1004 | mcs_count[MAX_MCS], 1, |
| 1005 | ((mcs >= MAX_MCS_11B) |
| 1006 | && (pkt_type == DOT11_B))); |
| 1007 | DP_STATS_INCC(peer, rx.pkt_type[pkt_type]. |
| 1008 | mcs_count[mcs], 1, |
| 1009 | ((mcs <= MAX_MCS_11B) |
| 1010 | && (pkt_type == DOT11_B))); |
| 1011 | DP_STATS_INCC(peer, rx.pkt_type[pkt_type]. |
| 1012 | mcs_count[MAX_MCS], 1, |
| 1013 | ((mcs >= MAX_MCS_11A) |
| 1014 | && (pkt_type == DOT11_N))); |
| 1015 | DP_STATS_INCC(peer, rx.pkt_type[pkt_type]. |
| 1016 | mcs_count[mcs], 1, |
| 1017 | ((mcs <= MAX_MCS_11A) |
| 1018 | && (pkt_type == DOT11_N))); |
| 1019 | DP_STATS_INCC(peer, rx.pkt_type[pkt_type]. |
| 1020 | mcs_count[MAX_MCS], 1, |
| 1021 | ((mcs >= MAX_MCS_11AC) |
| 1022 | && (pkt_type == DOT11_AC))); |
| 1023 | DP_STATS_INCC(peer, rx.pkt_type[pkt_type]. |
| 1024 | mcs_count[mcs], 1, |
| 1025 | ((mcs <= MAX_MCS_11AC) |
| 1026 | && (pkt_type == DOT11_AC))); |
| 1027 | DP_STATS_INCC(peer, rx.pkt_type[pkt_type]. |
| 1028 | mcs_count[MAX_MCS], 1, |
| 1029 | ((mcs >= MAX_MCS) |
| 1030 | && (pkt_type == DOT11_AX))); |
| 1031 | DP_STATS_INCC(peer, rx.pkt_type[pkt_type]. |
| 1032 | mcs_count[mcs], 1, |
| 1033 | ((mcs <= MAX_MCS) |
| 1034 | && (pkt_type == DOT11_AX))); |
| 1035 | |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 1036 | /* |
| 1037 | * HW structures call this L3 header padding -- |
| 1038 | * even though this is actually the offset from |
| 1039 | * the buffer beginning where the L2 header |
| 1040 | * begins. |
| 1041 | */ |
Dhanashri Atre | 1404917 | 2016-11-11 18:32:36 -0800 | [diff] [blame] | 1042 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, |
| 1043 | FL("rxhash: flow id toeplitz: 0x%x\n"), |
| 1044 | hal_rx_msdu_start_toeplitz_get(rx_tlv_hdr)); |
| 1045 | |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 1046 | l2_hdr_offset = |
| 1047 | hal_rx_msdu_end_l3_hdr_padding_get(rx_tlv_hdr); |
| 1048 | |
| 1049 | msdu_len = hal_rx_msdu_start_msdu_len_get(rx_tlv_hdr); |
| 1050 | pkt_len = msdu_len + l2_hdr_offset + RX_PKT_TLVS_LEN; |
| 1051 | |
| 1052 | /* Set length in nbuf */ |
| 1053 | qdf_nbuf_set_pktlen(nbuf, pkt_len); |
| 1054 | |
Venkateswara Swamy Bandaru | ec4f8e6 | 2017-03-07 11:04:28 +0530 | [diff] [blame] | 1055 | if (qdf_unlikely(vdev->mesh_vdev)) { |
| 1056 | if (dp_rx_filter_mesh_packets(vdev, nbuf) |
| 1057 | == QDF_STATUS_SUCCESS) { |
| 1058 | QDF_TRACE(QDF_MODULE_ID_DP, |
| 1059 | QDF_TRACE_LEVEL_INFO_MED, |
| 1060 | FL("mesh pkt filtered")); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 1061 | DP_STATS_INC(vdev->pdev, dropped.mesh_filter, |
| 1062 | 1); |
Venkateswara Swamy Bandaru | ec4f8e6 | 2017-03-07 11:04:28 +0530 | [diff] [blame] | 1063 | |
| 1064 | qdf_nbuf_free(nbuf); |
| 1065 | continue; |
| 1066 | } |
Venkateswara Swamy Bandaru | c14b1b6 | 2017-02-24 12:26:08 +0530 | [diff] [blame] | 1067 | dp_rx_fill_mesh_stats(vdev, nbuf); |
Venkateswara Swamy Bandaru | ec4f8e6 | 2017-03-07 11:04:28 +0530 | [diff] [blame] | 1068 | } |
Venkateswara Swamy Bandaru | c14b1b6 | 2017-02-24 12:26:08 +0530 | [diff] [blame] | 1069 | |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 1070 | /* |
| 1071 | * Advance the packet start pointer by total size of |
| 1072 | * pre-header TLV's |
| 1073 | */ |
| 1074 | qdf_nbuf_pull_head(nbuf, |
| 1075 | RX_PKT_TLVS_LEN + l2_hdr_offset); |
| 1076 | |
Debashis Dutt | af64522 | 2017-01-20 19:29:25 -0800 | [diff] [blame] | 1077 | #ifdef QCA_WIFI_NAPIER_EMULATION /* Debug code, remove later */ |
| 1078 | QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, |
| 1079 | "p_id %d msdu_len %d hdr_off %d", |
| 1080 | peer_id, msdu_len, l2_hdr_offset); |
| 1081 | |
| 1082 | print_hex_dump(KERN_ERR, |
| 1083 | "\t Pkt Data:", DUMP_PREFIX_NONE, 32, 4, |
| 1084 | qdf_nbuf_data(nbuf), 128, false); |
| 1085 | #endif /* NAPIER_EMULATION */ |
| 1086 | |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 1087 | /* WDS Source Port Learning */ |
Karunakar Dasineni | ca79254 | 2017-01-16 10:08:58 -0800 | [diff] [blame] | 1088 | if (qdf_likely((vdev->wds_enabled) && |
| 1089 | (vdev->rx_decap_type == |
| 1090 | htt_cmn_pkt_type_ethernet))) |
Tallapragada Kalyan | 3a0005c | 2017-03-10 15:22:57 +0530 | [diff] [blame] | 1091 | dp_rx_wds_srcport_learn(soc, rx_tlv_hdr, peer, |
Karunakar Dasineni | ca79254 | 2017-01-16 10:08:58 -0800 | [diff] [blame] | 1092 | nbuf); |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 1093 | |
| 1094 | /* Intrabss-fwd */ |
Tallapragada Kalyan | 6f6166e | 2017-02-17 17:00:23 +0530 | [diff] [blame] | 1095 | if (vdev->opmode != wlan_op_mode_sta) |
| 1096 | if (dp_rx_intrabss_fwd(soc, peer, rx_tlv_hdr, |
| 1097 | nbuf)) |
| 1098 | continue; /* Get next descriptor */ |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 1099 | |
| 1100 | rx_bufs_used++; |
Dhanashri Atre | 0da3122 | 2017-03-23 12:30:58 -0700 | [diff] [blame] | 1101 | |
| 1102 | if (!dp_rx_lro(rx_tlv_hdr, peer, nbuf, int_ctx->lro_ctx)) |
| 1103 | QDF_NBUF_CB_RX_LRO_CTX(nbuf) = NULL; |
| 1104 | |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 1105 | DP_RX_LIST_APPEND(deliver_list_head, |
| 1106 | deliver_list_tail, |
| 1107 | nbuf); |
Ishank Jain | 1e7401c | 2017-02-17 15:38:39 +0530 | [diff] [blame] | 1108 | |
| 1109 | DP_STATS_INCC_PKT(peer, rx.multicast, 1, pkt_len, |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 1110 | hal_rx_msdu_end_da_is_mcbc_get( |
| 1111 | rx_tlv_hdr)); |
Ishank Jain | 1e7401c | 2017-02-17 15:38:39 +0530 | [diff] [blame] | 1112 | DP_STATS_INC_PKT(peer, rx.to_stack, 1, |
| 1113 | pkt_len); |
| 1114 | |
| 1115 | if (hal_rx_attn_first_mpdu_get(rx_tlv_hdr)) { |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 1116 | if (soc->cdp_soc.ol_ops->update_dp_stats) { |
Ishank Jain | 1e7401c | 2017-02-17 15:38:39 +0530 | [diff] [blame] | 1117 | soc->cdp_soc.ol_ops->update_dp_stats( |
| 1118 | vdev->pdev->osif_pdev, |
| 1119 | &peer->stats, |
| 1120 | peer_id, |
| 1121 | UPDATE_PEER_STATS); |
| 1122 | |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 1123 | dp_aggregate_vdev_stats(peer->vdev); |
Ishank Jain | 1e7401c | 2017-02-17 15:38:39 +0530 | [diff] [blame] | 1124 | |
Ishank Jain | 1e7401c | 2017-02-17 15:38:39 +0530 | [diff] [blame] | 1125 | soc->cdp_soc.ol_ops->update_dp_stats( |
| 1126 | vdev->pdev->osif_pdev, |
| 1127 | &peer->vdev->stats, |
| 1128 | peer->vdev->vdev_id, |
| 1129 | UPDATE_VDEV_STATS); |
Ishank Jain | 57c42a1 | 2017-04-12 10:42:22 +0530 | [diff] [blame^] | 1130 | } |
Ishank Jain | 1e7401c | 2017-02-17 15:38:39 +0530 | [diff] [blame] | 1131 | } |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 1132 | } |
| 1133 | |
Tallapragada | aa3bfcc | 2017-04-10 14:25:36 +0530 | [diff] [blame] | 1134 | if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw) || |
| 1135 | (vdev->rx_decap_type == htt_cmn_pkt_type_native_wifi)) |
Kalyan Tallapragada | 277f45e | 2017-01-30 14:25:27 +0530 | [diff] [blame] | 1136 | dp_rx_deliver_raw(vdev, deliver_list_head); |
| 1137 | else if (qdf_likely(vdev->osif_rx) && deliver_list_head) |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 1138 | vdev->osif_rx(vdev->osif_vdev, deliver_list_head); |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 1139 | } |
Dhanashri Atre | 0da3122 | 2017-03-23 12:30:58 -0700 | [diff] [blame] | 1140 | |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 1141 | return rx_bufs_used; /* Assume no scale factor for now */ |
| 1142 | } |
| 1143 | |
| 1144 | /** |
| 1145 | * dp_rx_detach() - detach dp rx |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 1146 | * @pdev: core txrx pdev context |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 1147 | * |
| 1148 | * This function will detach DP RX into main device context |
| 1149 | * will free DP Rx resources. |
| 1150 | * |
| 1151 | * Return: void |
| 1152 | */ |
| 1153 | void |
| 1154 | dp_rx_pdev_detach(struct dp_pdev *pdev) |
| 1155 | { |
| 1156 | uint8_t pdev_id = pdev->pdev_id; |
| 1157 | struct dp_soc *soc = pdev->soc; |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 1158 | struct rx_desc_pool *rx_desc_pool; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 1159 | |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 1160 | rx_desc_pool = &soc->rx_desc_buf[pdev_id]; |
| 1161 | |
| 1162 | dp_rx_desc_pool_free(soc, pdev_id, rx_desc_pool); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 1163 | qdf_spinlock_destroy(&soc->rx_desc_mutex[pdev_id]); |
Tallapragada Kalyan | 603c594 | 2016-12-07 21:30:44 +0530 | [diff] [blame] | 1164 | |
| 1165 | return; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 1166 | } |
| 1167 | |
| 1168 | /** |
| 1169 | * dp_rx_attach() - attach DP RX |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 1170 | * @pdev: core txrx pdev context |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 1171 | * |
| 1172 | * This function will attach a DP RX instance into the main |
| 1173 | * device (SOC) context. Will allocate dp rx resource and |
| 1174 | * initialize resources. |
| 1175 | * |
| 1176 | * Return: QDF_STATUS_SUCCESS: success |
| 1177 | * QDF_STATUS_E_RESOURCES: Error return |
| 1178 | */ |
| 1179 | QDF_STATUS |
| 1180 | dp_rx_pdev_attach(struct dp_pdev *pdev) |
| 1181 | { |
| 1182 | uint8_t pdev_id = pdev->pdev_id; |
| 1183 | struct dp_soc *soc = pdev->soc; |
| 1184 | struct dp_srng rxdma_srng; |
| 1185 | uint32_t rxdma_entries; |
| 1186 | union dp_rx_desc_list_elem_t *desc_list = NULL; |
| 1187 | union dp_rx_desc_list_elem_t *tail = NULL; |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 1188 | struct dp_srng *dp_rxdma_srng; |
| 1189 | struct rx_desc_pool *rx_desc_pool; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 1190 | |
| 1191 | qdf_spinlock_create(&soc->rx_desc_mutex[pdev_id]); |
| 1192 | pdev = soc->pdev_list[pdev_id]; |
Dhanashri Atre | 7351d17 | 2016-10-12 13:08:09 -0700 | [diff] [blame] | 1193 | rxdma_srng = pdev->rx_refill_buf_ring; |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 1194 | |
| 1195 | rxdma_entries = rxdma_srng.alloc_size/hal_srng_get_entrysize( |
| 1196 | soc->hal_soc, RXDMA_BUF); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 1197 | |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 1198 | rx_desc_pool = &soc->rx_desc_buf[pdev_id]; |
| 1199 | |
| 1200 | dp_rx_desc_pool_alloc(soc, pdev_id, rxdma_entries*3, rx_desc_pool); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 1201 | /* For Rx buffers, WBM release ring is SW RING 3,for all pdev's */ |
Kai Chen | 6eca1a6 | 2017-01-12 10:17:53 -0800 | [diff] [blame] | 1202 | dp_rxdma_srng = &pdev->rx_refill_buf_ring; |
| 1203 | dp_rx_buffers_replenish(soc, pdev_id, dp_rxdma_srng, rx_desc_pool, |
| 1204 | rxdma_entries, &desc_list, &tail, HAL_RX_BUF_RBM_SW3_BM); |
Debashis Dutt | c4c52dc | 2016-10-04 17:12:23 -0700 | [diff] [blame] | 1205 | |
| 1206 | return QDF_STATUS_SUCCESS; |
| 1207 | } |