1 /* 2 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. 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 * DOC: wlan_dp_txrx.c 20 * DP TX/RX path implementation 21 * 22 * 23 */ 24 25 #include <wlan_dp_priv.h> 26 #include <wlan_dp_main.h> 27 #include <wlan_dp_txrx.h> 28 #include <qdf_types.h> 29 #include <cdp_txrx_cmn.h> 30 #include <cdp_txrx_peer_ops.h> 31 #include <cdp_txrx_misc.h> 32 #include <cdp_txrx_flow_ctrl_v2.h> 33 #include "wlan_dp_rx_thread.h" 34 #if defined(WLAN_SUPPORT_RX_FISA) 35 #include "wlan_dp_fisa_rx.h" 36 #endif 37 #include "nan_public_structs.h" 38 #include "wlan_nan_api_i.h" 39 #include <wlan_cm_api.h> 40 #include <enet.h> 41 #include <cds_utils.h> 42 #include <wlan_dp_bus_bandwidth.h> 43 #include "wlan_tdls_api.h" 44 #include <qdf_trace.h> 45 #include <qdf_net_stats.h> 46 47 uint32_t wlan_dp_intf_get_pkt_type_bitmap_value(void *intf_ctx) 48 { 49 struct wlan_dp_intf *dp_intf = (struct wlan_dp_intf *)intf_ctx; 50 51 if (!dp_intf) { 52 dp_err_rl("DP Context is NULL"); 53 return 0; 54 } 55 56 return dp_intf->pkt_type_bitmap; 57 } 58 59 #if defined(WLAN_SUPPORT_RX_FISA) 60 void dp_rx_skip_fisa(struct wlan_dp_psoc_context *dp_ctx, uint32_t value) 61 { 62 qdf_atomic_set(&dp_ctx->skip_fisa_param.skip_fisa, !value); 63 } 64 #endif 65 66 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL 67 void dp_get_tx_resource(struct wlan_dp_link *dp_link, 68 struct qdf_mac_addr *mac_addr) 69 { 70 struct wlan_dp_intf *dp_intf = dp_link->dp_intf; 71 struct wlan_dp_psoc_callbacks *dp_ops = &dp_intf->dp_ctx->dp_ops; 72 73 dp_ops->dp_get_tx_resource(dp_link->link_id, 74 mac_addr); 75 } 76 #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ 77 78 #ifdef FEATURE_WLAN_DIAG_SUPPORT 79 /** 80 * dp_event_eapol_log() - send event to wlan diag 81 * @nbuf: Network buffer ptr 82 * @dir: direction 83 * 84 * Return: None 85 */ 86 void dp_event_eapol_log(qdf_nbuf_t nbuf, enum qdf_proto_dir dir) 87 { 88 int16_t eapol_key_info; 89 90 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct host_event_wlan_eapol); 91 92 if (dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_EAPOL != 93 QDF_NBUF_CB_GET_PACKET_TYPE(nbuf)) 94 return; 95 else if (!qdf_nbuf_is_ipv4_eapol_pkt(nbuf)) 96 return; 97 98 eapol_key_info = (uint16_t)(*(uint16_t *) 99 (nbuf->data + EAPOL_KEY_INFO_OFFSET)); 100 101 wlan_diag_event.event_sub_type = 102 (dir == QDF_TX ? 103 WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED : 104 WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED); 105 wlan_diag_event.eapol_packet_type = (uint8_t)(*(uint8_t *) 106 (nbuf->data + EAPOL_PACKET_TYPE_OFFSET)); 107 wlan_diag_event.eapol_key_info = eapol_key_info; 108 wlan_diag_event.eapol_rate = 0; 109 qdf_mem_copy(wlan_diag_event.dest_addr, 110 (nbuf->data + QDF_NBUF_DEST_MAC_OFFSET), 111 sizeof(wlan_diag_event.dest_addr)); 112 qdf_mem_copy(wlan_diag_event.src_addr, 113 (nbuf->data + QDF_NBUF_SRC_MAC_OFFSET), 114 sizeof(wlan_diag_event.src_addr)); 115 116 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_EAPOL); 117 } 118 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 119 120 static int dp_intf_is_tx_allowed(qdf_nbuf_t nbuf, 121 uint8_t intf_id, void *soc, 122 uint8_t *peer_mac) 123 { 124 enum ol_txrx_peer_state peer_state; 125 126 peer_state = cdp_peer_state_get(soc, intf_id, peer_mac); 127 if (qdf_likely(OL_TXRX_PEER_STATE_AUTH == peer_state)) 128 return true; 129 if (OL_TXRX_PEER_STATE_CONN == peer_state && 130 (qdf_ntohs(qdf_nbuf_get_protocol(nbuf)) == ETHERTYPE_PAE || 131 IS_DP_ETHERTYPE_WAI(nbuf))) 132 return true; 133 134 dp_info("Invalid peer state for Tx: %d", peer_state); 135 return false; 136 } 137 138 /** 139 * dp_tx_rx_is_dns_domain_name_match() - function to check whether dns 140 * domain name in the received nbuf matches with the tracking dns domain 141 * name or not 142 * 143 * @nbuf: Network buffer pointer 144 * @dp_intf: DP interface pointer 145 * 146 * Returns: true if matches else false 147 */ 148 static bool dp_tx_rx_is_dns_domain_name_match(qdf_nbuf_t nbuf, 149 struct wlan_dp_intf *dp_intf) 150 { 151 uint8_t *domain_name; 152 153 if (dp_intf->track_dns_domain_len == 0) 154 return false; 155 156 /* check OOB , is strncmp accessing data more than skb->len */ 157 if ((dp_intf->track_dns_domain_len + 158 QDF_NBUF_PKT_DNS_NAME_OVER_UDP_OFFSET) > qdf_nbuf_len(nbuf)) 159 return false; 160 161 domain_name = qdf_nbuf_get_dns_domain_name(nbuf, 162 dp_intf->track_dns_domain_len); 163 if (qdf_str_ncmp(domain_name, dp_intf->dns_payload, 164 dp_intf->track_dns_domain_len) == 0) 165 return true; 166 else 167 return false; 168 } 169 170 /** 171 * dp_clear_tx_rx_connectivity_stats() - clear connectivity stats 172 * @dp_intf: pointer to DP interface 173 * 174 * Return: None 175 */ 176 static void dp_clear_tx_rx_connectivity_stats(struct wlan_dp_intf *dp_intf) 177 { 178 dp_debug("Clear txrx connectivity stats"); 179 qdf_mem_zero(&dp_intf->dp_stats.arp_stats, 180 sizeof(dp_intf->dp_stats.arp_stats)); 181 qdf_mem_zero(&dp_intf->dp_stats.dns_stats, 182 sizeof(dp_intf->dp_stats.dns_stats)); 183 qdf_mem_zero(&dp_intf->dp_stats.tcp_stats, 184 sizeof(dp_intf->dp_stats.tcp_stats)); 185 qdf_mem_zero(&dp_intf->dp_stats.icmpv4_stats, 186 sizeof(dp_intf->dp_stats.icmpv4_stats)); 187 dp_intf->pkt_type_bitmap = 0; 188 dp_intf->track_arp_ip = 0; 189 qdf_mem_zero(dp_intf->dns_payload, dp_intf->track_dns_domain_len); 190 dp_intf->track_dns_domain_len = 0; 191 dp_intf->track_src_port = 0; 192 dp_intf->track_dest_port = 0; 193 dp_intf->track_dest_ipv4 = 0; 194 } 195 196 void dp_reset_all_intfs_connectivity_stats(struct wlan_dp_psoc_context *dp_ctx) 197 { 198 struct wlan_dp_intf *dp_intf = NULL; 199 200 qdf_spin_lock_bh(&dp_ctx->intf_list_lock); 201 for (dp_get_front_intf_no_lock(dp_ctx, &dp_intf); dp_intf; 202 dp_get_next_intf_no_lock(dp_ctx, dp_intf, &dp_intf)) { 203 dp_clear_tx_rx_connectivity_stats(dp_intf); 204 } 205 qdf_spin_unlock_bh(&dp_ctx->intf_list_lock); 206 } 207 208 void 209 dp_tx_rx_collect_connectivity_stats_info(qdf_nbuf_t nbuf, void *context, 210 enum connectivity_stats_pkt_status action, uint8_t *pkt_type) 211 { 212 uint32_t pkt_type_bitmap; 213 struct wlan_dp_link *dp_link = (struct wlan_dp_link *)context; 214 struct wlan_dp_intf *dp_intf = dp_link->dp_intf; 215 216 /* ARP tracking is done already. */ 217 pkt_type_bitmap = dp_intf->pkt_type_bitmap; 218 219 pkt_type_bitmap &= ~dp_intf->dp_ctx->arp_connectivity_map; 220 221 if (!pkt_type_bitmap) 222 return; 223 224 switch (action) { 225 case PKT_TYPE_REQ: 226 case PKT_TYPE_TX_HOST_FW_SENT: 227 if (qdf_nbuf_is_icmp_pkt(nbuf)) { 228 if (qdf_nbuf_data_is_icmpv4_req(nbuf) && 229 dp_intf->track_dest_ipv4 == 230 qdf_nbuf_get_icmpv4_tgt_ip(nbuf)) { 231 *pkt_type = DP_CONNECTIVITY_CHECK_SET_ICMPV4; 232 if (action == PKT_TYPE_REQ) { 233 ++dp_intf->dp_stats.icmpv4_stats. 234 tx_icmpv4_req_count; 235 dp_info("ICMPv4 Req packet"); 236 } else 237 /* host receives tx completion */ 238 ++dp_intf->dp_stats.icmpv4_stats. 239 tx_host_fw_sent; 240 } 241 } else if (qdf_nbuf_is_ipv4_tcp_pkt(nbuf)) { 242 if (qdf_nbuf_data_is_tcp_syn(nbuf) && 243 dp_intf->track_dest_port == 244 qdf_nbuf_data_get_tcp_dst_port(nbuf)) { 245 *pkt_type = DP_CONNECTIVITY_CHECK_SET_TCP_SYN; 246 if (action == PKT_TYPE_REQ) { 247 ++dp_intf->dp_stats.tcp_stats. 248 tx_tcp_syn_count; 249 dp_info("TCP Syn packet"); 250 } else { 251 /* host receives tx completion */ 252 ++dp_intf->dp_stats.tcp_stats. 253 tx_tcp_syn_host_fw_sent; 254 } 255 } else if ((dp_intf->dp_stats.tcp_stats. 256 is_tcp_syn_ack_rcv || dp_intf->dp_stats. 257 tcp_stats.is_tcp_ack_sent) && 258 qdf_nbuf_data_is_tcp_ack(nbuf) && 259 (dp_intf->track_dest_port == 260 qdf_nbuf_data_get_tcp_dst_port(nbuf))) { 261 *pkt_type = DP_CONNECTIVITY_CHECK_SET_TCP_ACK; 262 if (action == PKT_TYPE_REQ && 263 dp_intf->dp_stats.tcp_stats. 264 is_tcp_syn_ack_rcv) { 265 ++dp_intf->dp_stats.tcp_stats. 266 tx_tcp_ack_count; 267 dp_intf->dp_stats.tcp_stats. 268 is_tcp_syn_ack_rcv = false; 269 dp_intf->dp_stats.tcp_stats. 270 is_tcp_ack_sent = true; 271 dp_info("TCP Ack packet"); 272 } else if (action == PKT_TYPE_TX_HOST_FW_SENT && 273 dp_intf->dp_stats.tcp_stats. 274 is_tcp_ack_sent) { 275 /* host receives tx completion */ 276 ++dp_intf->dp_stats.tcp_stats. 277 tx_tcp_ack_host_fw_sent; 278 dp_intf->dp_stats.tcp_stats. 279 is_tcp_ack_sent = false; 280 } 281 } 282 } else if (qdf_nbuf_is_ipv4_udp_pkt(nbuf)) { 283 if (qdf_nbuf_data_is_dns_query(nbuf) && 284 dp_tx_rx_is_dns_domain_name_match(nbuf, dp_intf)) { 285 *pkt_type = DP_CONNECTIVITY_CHECK_SET_DNS; 286 if (action == PKT_TYPE_REQ) { 287 ++dp_intf->dp_stats.dns_stats. 288 tx_dns_req_count; 289 dp_info("DNS query packet"); 290 } else 291 /* host receives tx completion */ 292 ++dp_intf->dp_stats.dns_stats. 293 tx_host_fw_sent; 294 } 295 } 296 break; 297 298 case PKT_TYPE_RSP: 299 if (qdf_nbuf_is_icmp_pkt(nbuf)) { 300 if (qdf_nbuf_data_is_icmpv4_rsp(nbuf) && 301 (dp_intf->track_dest_ipv4 == 302 qdf_nbuf_get_icmpv4_src_ip(nbuf))) { 303 ++dp_intf->dp_stats.icmpv4_stats. 304 rx_icmpv4_rsp_count; 305 *pkt_type = 306 DP_CONNECTIVITY_CHECK_SET_ICMPV4; 307 dp_info("ICMPv4 resp packet"); 308 } 309 } else if (qdf_nbuf_is_ipv4_tcp_pkt(nbuf)) { 310 if (qdf_nbuf_data_is_tcp_syn_ack(nbuf) && 311 (dp_intf->track_dest_port == 312 qdf_nbuf_data_get_tcp_src_port(nbuf))) { 313 ++dp_intf->dp_stats.tcp_stats. 314 rx_tcp_syn_ack_count; 315 dp_intf->dp_stats.tcp_stats. 316 is_tcp_syn_ack_rcv = true; 317 *pkt_type = 318 DP_CONNECTIVITY_CHECK_SET_TCP_SYN_ACK; 319 dp_info("TCP Syn ack packet"); 320 } 321 } else if (qdf_nbuf_is_ipv4_udp_pkt(nbuf)) { 322 if (qdf_nbuf_data_is_dns_response(nbuf) && 323 dp_tx_rx_is_dns_domain_name_match(nbuf, dp_intf)) { 324 ++dp_intf->dp_stats.dns_stats. 325 rx_dns_rsp_count; 326 *pkt_type = DP_CONNECTIVITY_CHECK_SET_DNS; 327 dp_info("DNS resp packet"); 328 } 329 } 330 break; 331 332 case PKT_TYPE_TX_DROPPED: 333 switch (*pkt_type) { 334 case DP_CONNECTIVITY_CHECK_SET_ICMPV4: 335 ++dp_intf->dp_stats.icmpv4_stats.tx_dropped; 336 dp_info("ICMPv4 Req packet dropped"); 337 break; 338 case DP_CONNECTIVITY_CHECK_SET_TCP_SYN: 339 ++dp_intf->dp_stats.tcp_stats.tx_tcp_syn_dropped; 340 dp_info("TCP syn packet dropped"); 341 break; 342 case DP_CONNECTIVITY_CHECK_SET_TCP_ACK: 343 ++dp_intf->dp_stats.tcp_stats.tx_tcp_ack_dropped; 344 dp_info("TCP ack packet dropped"); 345 break; 346 case DP_CONNECTIVITY_CHECK_SET_DNS: 347 ++dp_intf->dp_stats.dns_stats.tx_dropped; 348 dp_info("DNS query packet dropped"); 349 break; 350 default: 351 break; 352 } 353 break; 354 case PKT_TYPE_RX_DELIVERED: 355 switch (*pkt_type) { 356 case DP_CONNECTIVITY_CHECK_SET_ICMPV4: 357 ++dp_intf->dp_stats.icmpv4_stats.rx_delivered; 358 break; 359 case DP_CONNECTIVITY_CHECK_SET_TCP_SYN_ACK: 360 ++dp_intf->dp_stats.tcp_stats.rx_delivered; 361 break; 362 case DP_CONNECTIVITY_CHECK_SET_DNS: 363 ++dp_intf->dp_stats.dns_stats.rx_delivered; 364 break; 365 default: 366 break; 367 } 368 break; 369 case PKT_TYPE_RX_REFUSED: 370 switch (*pkt_type) { 371 case DP_CONNECTIVITY_CHECK_SET_ICMPV4: 372 ++dp_intf->dp_stats.icmpv4_stats.rx_refused; 373 break; 374 case DP_CONNECTIVITY_CHECK_SET_TCP_SYN_ACK: 375 ++dp_intf->dp_stats.tcp_stats.rx_refused; 376 break; 377 case DP_CONNECTIVITY_CHECK_SET_DNS: 378 ++dp_intf->dp_stats.dns_stats.rx_refused; 379 break; 380 default: 381 break; 382 } 383 break; 384 case PKT_TYPE_TX_ACK_CNT: 385 switch (*pkt_type) { 386 case DP_CONNECTIVITY_CHECK_SET_ICMPV4: 387 ++dp_intf->dp_stats.icmpv4_stats.tx_ack_cnt; 388 break; 389 case DP_CONNECTIVITY_CHECK_SET_TCP_SYN: 390 ++dp_intf->dp_stats.tcp_stats.tx_tcp_syn_ack_cnt; 391 break; 392 case DP_CONNECTIVITY_CHECK_SET_TCP_ACK: 393 ++dp_intf->dp_stats.tcp_stats.tx_tcp_ack_ack_cnt; 394 break; 395 case DP_CONNECTIVITY_CHECK_SET_DNS: 396 ++dp_intf->dp_stats.dns_stats.tx_ack_cnt; 397 break; 398 default: 399 break; 400 } 401 break; 402 default: 403 break; 404 } 405 } 406 407 /** 408 * dp_get_transmit_mac_addr() - Get the mac address to validate the xmit 409 * @dp_link: DP link handle 410 * @nbuf: The network buffer 411 * @mac_addr_tx_allowed: The mac address to be filled 412 * 413 * Return: None 414 */ 415 static 416 void dp_get_transmit_mac_addr(struct wlan_dp_link *dp_link, 417 qdf_nbuf_t nbuf, 418 struct qdf_mac_addr *mac_addr_tx_allowed) 419 { 420 struct wlan_dp_intf *dp_intf = dp_link->dp_intf; 421 bool is_mc_bc_addr = false; 422 enum nan_datapath_state state; 423 424 /* Check for VDEV validity before accessing it. Since VDEV references 425 * are not taken in the per packet path, there is a change for VDEV 426 * getting deleted in a parallel context. Because DP VDEV object is 427 * protected by dp_intf::num_active_task, the chance of VDEV object 428 * getting deleted while executing dp_start_xmit() is sparse. So, a 429 * simple VDEV NULL check should be sufficient to handle the case of 430 * VDEV getting destroyed first followed by dp_start_xmit(). 431 */ 432 if (!dp_link->vdev) 433 return; 434 435 switch (dp_intf->device_mode) { 436 case QDF_NDI_MODE: 437 state = wlan_nan_get_ndi_state(dp_link->vdev); 438 if (state == NAN_DATA_NDI_CREATED_STATE || 439 state == NAN_DATA_CONNECTED_STATE || 440 state == NAN_DATA_CONNECTING_STATE || 441 state == NAN_DATA_PEER_CREATE_STATE) { 442 if (QDF_NBUF_CB_GET_IS_BCAST(nbuf) || 443 QDF_NBUF_CB_GET_IS_MCAST(nbuf)) 444 is_mc_bc_addr = true; 445 if (is_mc_bc_addr) 446 qdf_copy_macaddr(mac_addr_tx_allowed, 447 &dp_intf->mac_addr); 448 else 449 qdf_copy_macaddr(mac_addr_tx_allowed, 450 (struct qdf_mac_addr *)qdf_nbuf_data(nbuf)); 451 } 452 break; 453 case QDF_STA_MODE: 454 case QDF_P2P_CLIENT_MODE: 455 if (wlan_cm_is_vdev_active(dp_link->vdev)) 456 qdf_copy_macaddr(mac_addr_tx_allowed, 457 &dp_link->conn_info.bssid); 458 break; 459 default: 460 break; 461 } 462 } 463 464 #ifdef HANDLE_BROADCAST_EAPOL_TX_FRAME 465 /** 466 * dp_fix_broadcast_eapol() - Fix broadcast eapol 467 * @dp_link: pointer to dp link 468 * @nbuf: pointer to nbuf 469 * 470 * Override DA of broadcast eapol with bssid addr. 471 * 472 * Return: None 473 */ 474 static void dp_fix_broadcast_eapol(struct wlan_dp_link *dp_link, 475 qdf_nbuf_t nbuf) 476 { 477 qdf_ether_header_t *eth_hdr = (qdf_ether_header_t *)qdf_nbuf_data(nbuf); 478 unsigned char *ap_mac_addr = 479 &dp_link->conn_info.bssid.bytes[0]; 480 481 if (qdf_unlikely((QDF_NBUF_CB_GET_PACKET_TYPE(nbuf) == 482 QDF_NBUF_CB_PACKET_TYPE_EAPOL) && 483 QDF_NBUF_CB_GET_IS_BCAST(nbuf))) { 484 dp_debug("SA: "QDF_MAC_ADDR_FMT " override DA: "QDF_MAC_ADDR_FMT " with AP mac address "QDF_MAC_ADDR_FMT, 485 QDF_MAC_ADDR_REF(ð_hdr->ether_shost[0]), 486 QDF_MAC_ADDR_REF(ð_hdr->ether_dhost[0]), 487 QDF_MAC_ADDR_REF(ap_mac_addr)); 488 489 qdf_mem_copy(ð_hdr->ether_dhost, ap_mac_addr, 490 QDF_MAC_ADDR_SIZE); 491 } 492 } 493 #else 494 static void dp_fix_broadcast_eapol(struct wlan_dp_link *dp_link, 495 qdf_nbuf_t nbuf) 496 { 497 } 498 #endif /* HANDLE_BROADCAST_EAPOL_TX_FRAME */ 499 500 #ifdef WLAN_DP_FEATURE_MARK_ICMP_REQ_TO_FW 501 /** 502 * dp_mark_icmp_req_to_fw() - Mark the ICMP request at a certain time interval 503 * to be sent to the FW. 504 * @dp_ctx: Global dp context 505 * @nbuf: packet to be transmitted 506 * 507 * This func sets the "to_fw" flag in the packet context block, if the 508 * current packet is an ICMP request packet. This marking is done at a 509 * specific time interval, unless the INI value indicates to disable/enable 510 * this for all frames. 511 * 512 * Return: none 513 */ 514 static void dp_mark_icmp_req_to_fw(struct wlan_dp_psoc_context *dp_ctx, 515 qdf_nbuf_t nbuf) 516 { 517 uint64_t curr_time, time_delta; 518 int time_interval_ms = dp_ctx->dp_cfg.icmp_req_to_fw_mark_interval; 519 static uint64_t prev_marked_icmp_time; 520 521 if (!dp_ctx->dp_cfg.icmp_req_to_fw_mark_interval) 522 return; 523 524 if ((qdf_nbuf_get_icmp_subtype(nbuf) != QDF_PROTO_ICMP_REQ) && 525 (qdf_nbuf_get_icmpv6_subtype(nbuf) != QDF_PROTO_ICMPV6_REQ)) 526 return; 527 528 /* Mark all ICMP request to be sent to FW */ 529 if (time_interval_ms == WLAN_CFG_ICMP_REQ_TO_FW_MARK_ALL) 530 QDF_NBUF_CB_TX_PACKET_TO_FW(nbuf) = 1; 531 532 /* For fragment IPV4 ICMP frames 533 * only mark last segment once to FW 534 */ 535 if (qdf_nbuf_is_ipv4_pkt(nbuf) && 536 qdf_nbuf_is_ipv4_fragment(nbuf)) 537 return; 538 539 curr_time = qdf_get_log_timestamp(); 540 time_delta = curr_time - prev_marked_icmp_time; 541 if (time_delta >= (time_interval_ms * 542 QDF_LOG_TIMESTAMP_CYCLES_PER_10_US * 100)) { 543 QDF_NBUF_CB_TX_PACKET_TO_FW(nbuf) = 1; 544 prev_marked_icmp_time = curr_time; 545 } 546 } 547 #else 548 static void dp_mark_icmp_req_to_fw(struct wlan_dp_psoc_context *dp_ctx, 549 qdf_nbuf_t nbuf) 550 { 551 } 552 #endif 553 554 #ifdef CONFIG_DP_PKT_ADD_TIMESTAMP 555 void wlan_dp_pkt_add_timestamp(struct wlan_dp_intf *dp_intf, 556 enum qdf_pkt_timestamp_index index, 557 qdf_nbuf_t nbuf) 558 { 559 struct wlan_dp_psoc_callbacks *dp_ops; 560 561 if (qdf_unlikely(qdf_is_dp_pkt_timestamp_enabled())) { 562 uint64_t tsf_time; 563 564 dp_ops = &dp_intf->dp_ctx->dp_ops; 565 dp_ops->dp_get_tsf_time(dp_intf->dev, 566 qdf_get_log_timestamp(), 567 &tsf_time); 568 qdf_add_dp_pkt_timestamp(nbuf, index, tsf_time); 569 } 570 } 571 #endif 572 573 QDF_STATUS 574 dp_start_xmit(struct wlan_dp_link *dp_link, qdf_nbuf_t nbuf) 575 { 576 struct wlan_dp_intf *dp_intf = dp_link->dp_intf; 577 struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; 578 struct dp_tx_rx_stats *stats; 579 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 580 enum qdf_proto_subtype subtype = QDF_PROTO_INVALID; 581 bool is_arp = false; 582 bool is_eapol = false; 583 bool is_dhcp = false; 584 uint8_t pkt_type; 585 struct qdf_mac_addr mac_addr_tx_allowed = QDF_MAC_ADDR_ZERO_INIT; 586 int cpu = qdf_get_smp_processor_id(); 587 588 stats = &dp_intf->dp_stats.tx_rx_stats; 589 ++stats->per_cpu[cpu].tx_called; 590 stats->cont_txtimeout_cnt = 0; 591 592 if (qdf_unlikely(cds_is_driver_transitioning())) { 593 dp_err_rl("driver is transitioning, drop pkt"); 594 goto drop_pkt; 595 } 596 597 if (qdf_unlikely(dp_ctx->is_suspend)) { 598 dp_err_rl("Device is system suspended, drop pkt"); 599 goto drop_pkt; 600 } 601 602 QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(nbuf) = 1; 603 604 pkt_type = QDF_NBUF_CB_GET_PACKET_TYPE(nbuf); 605 606 if (pkt_type == QDF_NBUF_CB_PACKET_TYPE_ARP) { 607 if (qdf_nbuf_data_is_arp_req(nbuf) && 608 (dp_intf->track_arp_ip == qdf_nbuf_get_arp_tgt_ip(nbuf))) { 609 is_arp = true; 610 ++dp_intf->dp_stats.arp_stats.tx_arp_req_count; 611 dp_info("ARP packet"); 612 } 613 } else if (pkt_type == QDF_NBUF_CB_PACKET_TYPE_EAPOL) { 614 subtype = qdf_nbuf_get_eapol_subtype(nbuf); 615 if (subtype == QDF_PROTO_EAPOL_M2) { 616 ++dp_intf->dp_stats.eapol_stats.eapol_m2_count; 617 is_eapol = true; 618 } else if (subtype == QDF_PROTO_EAPOL_M4) { 619 ++dp_intf->dp_stats.eapol_stats.eapol_m4_count; 620 is_eapol = true; 621 } 622 } else if (pkt_type == QDF_NBUF_CB_PACKET_TYPE_DHCP) { 623 subtype = qdf_nbuf_get_dhcp_subtype(nbuf); 624 if (subtype == QDF_PROTO_DHCP_DISCOVER) { 625 ++dp_intf->dp_stats.dhcp_stats.dhcp_dis_count; 626 is_dhcp = true; 627 } else if (subtype == QDF_PROTO_DHCP_REQUEST) { 628 ++dp_intf->dp_stats.dhcp_stats.dhcp_req_count; 629 is_dhcp = true; 630 } 631 } else if ((pkt_type == QDF_NBUF_CB_PACKET_TYPE_ICMP) || 632 (pkt_type == QDF_NBUF_CB_PACKET_TYPE_ICMPv6)) { 633 dp_mark_icmp_req_to_fw(dp_ctx, nbuf); 634 } 635 636 wlan_dp_pkt_add_timestamp(dp_intf, QDF_PKT_TX_DRIVER_ENTRY, nbuf); 637 638 /* track connectivity stats */ 639 if (dp_intf->pkt_type_bitmap) 640 dp_tx_rx_collect_connectivity_stats_info(nbuf, dp_link, 641 PKT_TYPE_REQ, 642 &pkt_type); 643 644 dp_get_transmit_mac_addr(dp_link, nbuf, &mac_addr_tx_allowed); 645 if (qdf_is_macaddr_zero(&mac_addr_tx_allowed)) { 646 dp_info_rl("tx not allowed, transmit operation suspended"); 647 goto drop_pkt; 648 } 649 650 dp_get_tx_resource(dp_link, &mac_addr_tx_allowed); 651 652 if (!qdf_nbuf_ipa_owned_get(nbuf)) { 653 nbuf = dp_nbuf_orphan(dp_intf, nbuf); 654 if (!nbuf) 655 goto drop_pkt_accounting; 656 } 657 658 /* 659 * Add SKB to internal tracking table before further processing 660 * in WLAN driver. 661 */ 662 qdf_net_buf_debug_acquire_skb(nbuf, __FILE__, __LINE__); 663 664 qdf_net_stats_add_tx_bytes(&dp_intf->stats, qdf_nbuf_len(nbuf)); 665 666 if (qdf_nbuf_is_tso(nbuf)) { 667 qdf_net_stats_add_tx_pkts(&dp_intf->stats, 668 qdf_nbuf_get_tso_num_seg(nbuf)); 669 } else { 670 qdf_net_stats_add_tx_pkts(&dp_intf->stats, 1); 671 dp_ctx->no_tx_offload_pkt_cnt++; 672 } 673 674 dp_event_eapol_log(nbuf, QDF_TX); 675 QDF_NBUF_CB_TX_PACKET_TRACK(nbuf) = QDF_NBUF_TX_PKT_DATA_TRACK; 676 QDF_NBUF_UPDATE_TX_PKT_COUNT(nbuf, QDF_NBUF_TX_PKT_DP); 677 678 qdf_dp_trace_set_track(nbuf, QDF_TX); 679 680 DPTRACE(qdf_dp_trace(nbuf, QDF_DP_TRACE_TX_PACKET_PTR_RECORD, 681 QDF_TRACE_DEFAULT_PDEV_ID, 682 qdf_nbuf_data_addr(nbuf), 683 sizeof(qdf_nbuf_data(nbuf)), 684 QDF_TX)); 685 686 if (!dp_intf_is_tx_allowed(nbuf, dp_link->link_id, soc, 687 mac_addr_tx_allowed.bytes)) { 688 dp_info("Tx not allowed for sta:" QDF_MAC_ADDR_FMT, 689 QDF_MAC_ADDR_REF(mac_addr_tx_allowed.bytes)); 690 goto drop_pkt_and_release_nbuf; 691 } 692 693 /* check whether need to linearize nbuf, like non-linear udp data */ 694 if (dp_nbuf_nontso_linearize(nbuf) != QDF_STATUS_SUCCESS) { 695 dp_err_rl(" nbuf %pK linearize failed. drop the pkt", nbuf); 696 goto drop_pkt_and_release_nbuf; 697 } 698 699 /* 700 * If a transmit function is not registered, drop packet 701 */ 702 if (!dp_intf->txrx_ops.tx.tx) { 703 dp_err_rl("TX function not registered by the data path"); 704 goto drop_pkt_and_release_nbuf; 705 } 706 707 dp_fix_broadcast_eapol(dp_link, nbuf); 708 709 if (dp_intf->txrx_ops.tx.tx(soc, dp_link->link_id, nbuf)) { 710 dp_debug_rl("Failed to send packet from adapter %u", 711 dp_link->link_id); 712 goto drop_pkt_and_release_nbuf; 713 } 714 715 return QDF_STATUS_SUCCESS; 716 717 drop_pkt_and_release_nbuf: 718 qdf_net_buf_debug_release_skb(nbuf); 719 drop_pkt: 720 721 /* track connectivity stats */ 722 if (dp_intf->pkt_type_bitmap) 723 dp_tx_rx_collect_connectivity_stats_info(nbuf, dp_link, 724 PKT_TYPE_TX_DROPPED, 725 &pkt_type); 726 qdf_dp_trace_data_pkt(nbuf, QDF_TRACE_DEFAULT_PDEV_ID, 727 QDF_DP_TRACE_DROP_PACKET_RECORD, 0, 728 QDF_TX); 729 qdf_nbuf_kfree(nbuf); 730 731 drop_pkt_accounting: 732 733 qdf_net_stats_inc_tx_dropped(&dp_intf->stats); 734 ++stats->per_cpu[cpu].tx_dropped; 735 if (is_arp) { 736 ++dp_intf->dp_stats.arp_stats.tx_dropped; 737 dp_info_rl("ARP packet dropped"); 738 } else if (is_eapol) { 739 ++dp_intf->dp_stats.eapol_stats. 740 tx_dropped[subtype - QDF_PROTO_EAPOL_M1]; 741 } else if (is_dhcp) { 742 ++dp_intf->dp_stats.dhcp_stats. 743 tx_dropped[subtype - QDF_PROTO_DHCP_DISCOVER]; 744 } 745 746 return QDF_STATUS_E_FAILURE; 747 } 748 749 void dp_tx_timeout(struct wlan_dp_intf *dp_intf) 750 { 751 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 752 u64 diff_time; 753 754 cdp_dump_flow_pool_info(soc); 755 756 ++dp_intf->dp_stats.tx_rx_stats.tx_timeout_cnt; 757 ++dp_intf->dp_stats.tx_rx_stats.cont_txtimeout_cnt; 758 759 diff_time = qdf_system_ticks() - 760 dp_intf->dp_stats.tx_rx_stats.last_txtimeout; 761 762 if ((dp_intf->dp_stats.tx_rx_stats.cont_txtimeout_cnt > 1) && 763 (diff_time > (DP_TX_TIMEOUT * 2))) { 764 /* 765 * In case when there is no traffic is running, it may 766 * possible tx time-out may once happen and later system 767 * recovered then continuous tx timeout count has to be 768 * reset as it is gets modified only when traffic is running. 769 * If over a period of time if this count reaches to threshold 770 * then host triggers a false subsystem restart. In genuine 771 * time out case OS will call the tx time-out back to back 772 * at interval of DP_TX_TIMEOUT. Here now check if previous 773 * TX TIME out has occurred more than twice of DP_TX_TIMEOUT 774 * back then host may recovered here from data stall. 775 */ 776 dp_intf->dp_stats.tx_rx_stats.cont_txtimeout_cnt = 0; 777 dp_info("Reset continuous tx timeout stat"); 778 } 779 780 dp_intf->dp_stats.tx_rx_stats.last_txtimeout = qdf_system_ticks(); 781 782 if (dp_intf->dp_stats.tx_rx_stats.cont_txtimeout_cnt > 783 DP_TX_STALL_THRESHOLD) { 784 dp_err("Data stall due to continuous TX timeouts"); 785 dp_intf->dp_stats.tx_rx_stats.cont_txtimeout_cnt = 0; 786 787 if (dp_is_data_stall_event_enabled(DP_HOST_STA_TX_TIMEOUT)) 788 cdp_post_data_stall_event(soc, 789 DATA_STALL_LOG_INDICATOR_HOST_DRIVER, 790 DATA_STALL_LOG_HOST_STA_TX_TIMEOUT, 791 OL_TXRX_PDEV_ID, 0xFF, 792 DATA_STALL_LOG_RECOVERY_TRIGGER_PDR); 793 } 794 } 795 796 void dp_sta_notify_tx_comp_cb(qdf_nbuf_t nbuf, void *ctx, uint16_t flag) 797 { 798 struct wlan_dp_link *dp_link = ctx; 799 struct wlan_dp_intf *dp_intf = dp_link->dp_intf; 800 enum qdf_proto_subtype subtype; 801 struct qdf_mac_addr *dest_mac_addr; 802 QDF_STATUS status; 803 804 if (is_dp_intf_valid(dp_intf)) 805 return; 806 807 dest_mac_addr = (struct qdf_mac_addr *)qdf_nbuf_data(nbuf); 808 809 switch (QDF_NBUF_CB_GET_PACKET_TYPE(nbuf)) { 810 case QDF_NBUF_CB_PACKET_TYPE_ARP: 811 if (flag & BIT(QDF_TX_RX_STATUS_DOWNLOAD_SUCC)) 812 ++dp_intf->dp_stats.arp_stats. 813 tx_host_fw_sent; 814 if (flag & BIT(QDF_TX_RX_STATUS_OK)) 815 ++dp_intf->dp_stats.arp_stats.tx_ack_cnt; 816 break; 817 case QDF_NBUF_CB_PACKET_TYPE_EAPOL: 818 subtype = qdf_nbuf_get_eapol_subtype(nbuf); 819 if (!(flag & BIT(QDF_TX_RX_STATUS_OK)) && 820 subtype != QDF_PROTO_INVALID && 821 subtype <= QDF_PROTO_EAPOL_M4) 822 ++dp_intf->dp_stats.eapol_stats. 823 tx_noack_cnt[subtype - QDF_PROTO_EAPOL_M1]; 824 break; 825 case QDF_NBUF_CB_PACKET_TYPE_DHCP: 826 subtype = qdf_nbuf_get_dhcp_subtype(nbuf); 827 if (!(flag & BIT(QDF_TX_RX_STATUS_OK)) && 828 subtype != QDF_PROTO_INVALID && 829 subtype <= QDF_PROTO_DHCP_ACK) 830 ++dp_intf->dp_stats.dhcp_stats. 831 tx_noack_cnt[subtype - QDF_PROTO_DHCP_DISCOVER]; 832 break; 833 default: 834 break; 835 } 836 837 /* Since it is TDLS call took TDLS vdev ref*/ 838 status = wlan_objmgr_vdev_try_get_ref(dp_link->vdev, WLAN_TDLS_SB_ID); 839 if (QDF_IS_STATUS_SUCCESS(status)) { 840 wlan_tdls_update_tx_pkt_cnt(dp_link->vdev, dest_mac_addr); 841 wlan_objmgr_vdev_release_ref(dp_link->vdev, WLAN_TDLS_SB_ID); 842 } 843 } 844 845 #ifdef FEATURE_MONITOR_MODE_SUPPORT 846 QDF_STATUS dp_mon_rx_packet_cbk(void *context, qdf_nbuf_t rxbuf) 847 { 848 struct wlan_dp_intf *dp_intf; 849 struct wlan_dp_link *dp_link; 850 QDF_STATUS status; 851 qdf_nbuf_t nbuf; 852 qdf_nbuf_t nbuf_next; 853 unsigned int cpu_index; 854 struct dp_tx_rx_stats *stats; 855 enum dp_nbuf_push_type type; 856 857 /* Sanity check on inputs */ 858 if ((!context) || (!rxbuf)) { 859 dp_err_rl("Null params being passed"); 860 return QDF_STATUS_E_FAILURE; 861 } 862 863 dp_link = (struct wlan_dp_link *)context; 864 dp_intf = dp_link->dp_intf; 865 if (!dp_intf) { 866 dp_err_rl("dp_intf is NULL for dp_link %pK", dp_link); 867 return QDF_STATUS_E_FAILURE; 868 } 869 870 cpu_index = qdf_get_cpu(); 871 stats = &dp_intf->dp_stats.tx_rx_stats; 872 873 /* walk the chain until all are processed */ 874 nbuf = rxbuf; 875 while (nbuf) { 876 nbuf_next = qdf_nbuf_next(nbuf); 877 qdf_nbuf_set_dev(nbuf, dp_intf->dev); 878 879 ++stats->per_cpu[cpu_index].rx_packets; 880 qdf_net_stats_add_rx_pkts(&dp_intf->stats, 1); 881 qdf_net_stats_add_rx_bytes(&dp_intf->stats, 882 qdf_nbuf_len(nbuf)); 883 884 /* Remove SKB from internal tracking table before submitting 885 * it to stack 886 */ 887 qdf_net_buf_debug_release_skb(nbuf); 888 889 /* 890 * If this is not a last packet on the chain 891 * Just put packet into backlog queue, not scheduling RX sirq 892 */ 893 if (qdf_nbuf_next(nbuf)) { 894 status = dp_intf->dp_ctx->dp_ops.dp_nbuf_push_pkt(nbuf, 895 DP_NBUF_PUSH_SIMPLE); 896 } else { 897 /* 898 * This is the last packet on the chain 899 * Scheduling rx sirq 900 */ 901 type = qdf_in_atomic() ? DP_NBUF_PUSH_NAPI : 902 DP_NBUF_PUSH_BH_DISABLE; 903 status = dp_intf->dp_ctx->dp_ops.dp_nbuf_push_pkt(nbuf, 904 type); 905 } 906 907 if (QDF_IS_STATUS_SUCCESS(status)) 908 ++stats->per_cpu[cpu_index].rx_delivered; 909 else 910 ++stats->per_cpu[cpu_index].rx_refused; 911 912 nbuf = nbuf_next; 913 } 914 915 return QDF_STATUS_SUCCESS; 916 } 917 918 void dp_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx, 919 ol_txrx_rx_mon_fp rx_monitor_cb) 920 { 921 txrx->rx.mon = rx_monitor_cb; 922 } 923 924 void dp_rx_monitor_callback(ol_osif_vdev_handle context, 925 qdf_nbuf_t rxbuf, 926 void *rx_status) 927 { 928 dp_mon_rx_packet_cbk(context, rxbuf); 929 } 930 #endif 931 932 /** 933 * dp_is_rx_wake_lock_needed() - check if wake lock is needed 934 * @nbuf: pointer to sk_buff 935 * 936 * RX wake lock is needed for: 937 * 1) Unicast data packet OR 938 * 2) Local ARP data packet 939 * 940 * Return: true if wake lock is needed or false otherwise. 941 */ 942 static bool dp_is_rx_wake_lock_needed(qdf_nbuf_t nbuf) 943 { 944 if ((!qdf_nbuf_pkt_type_is_mcast(nbuf) && 945 !qdf_nbuf_pkt_type_is_bcast(nbuf)) || 946 qdf_nbuf_is_arp_local(nbuf)) 947 return true; 948 949 return false; 950 } 951 952 #ifdef RECEIVE_OFFLOAD 953 /** 954 * dp_resolve_rx_ol_mode() - Resolve Rx offload method, LRO or GRO 955 * @dp_ctx: pointer to DP psoc Context 956 * 957 * Return: None 958 */ 959 static void dp_resolve_rx_ol_mode(struct wlan_dp_psoc_context *dp_ctx) 960 { 961 void *soc; 962 963 soc = cds_get_context(QDF_MODULE_ID_SOC); 964 965 if (!(cdp_cfg_get(soc, cfg_dp_lro_enable) ^ 966 cdp_cfg_get(soc, cfg_dp_gro_enable))) { 967 cdp_cfg_get(soc, cfg_dp_lro_enable) && 968 cdp_cfg_get(soc, cfg_dp_gro_enable) ? 969 dp_info("Can't enable both LRO and GRO, disabling Rx offload"): 970 dp_info("LRO and GRO both are disabled"); 971 dp_ctx->ol_enable = 0; 972 } else if (cdp_cfg_get(soc, cfg_dp_lro_enable)) { 973 dp_info("Rx offload LRO is enabled"); 974 dp_ctx->ol_enable = CFG_LRO_ENABLED; 975 } else { 976 dp_info("Rx offload: GRO is enabled"); 977 dp_ctx->ol_enable = CFG_GRO_ENABLED; 978 } 979 } 980 981 #ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION 982 /** 983 * dp_gro_rx_bh_disable() - GRO RX/flush function. 984 * @dp_intf: DP interface pointer 985 * @napi_to_use: napi to be used to give packets to the stack, gro flush 986 * @nbuf: pointer to n/w buff 987 * 988 * Function calls napi_gro_receive for the skb. If the skb indicates that a 989 * flush needs to be done (set by the lower DP layer), the function also calls 990 * napi_gro_flush. Local softirqs are disabled (and later enabled) while making 991 * napi_gro__ calls. 992 * 993 * Return: QDF_STATUS_SUCCESS if not dropped by napi_gro_receive or 994 * QDF error code. 995 */ 996 static QDF_STATUS dp_gro_rx_bh_disable(struct wlan_dp_intf *dp_intf, 997 qdf_napi_struct *napi_to_use, 998 qdf_nbuf_t nbuf) 999 { 1000 QDF_STATUS status = QDF_STATUS_SUCCESS; 1001 struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; 1002 uint32_t rx_aggregation; 1003 uint8_t rx_ctx_id = QDF_NBUF_CB_RX_CTX_ID(nbuf); 1004 uint8_t low_tput_force_flush = 0; 1005 int32_t gro_disallowed; 1006 1007 rx_aggregation = qdf_atomic_read(&dp_ctx->dp_agg_param.rx_aggregation); 1008 gro_disallowed = qdf_atomic_read(&dp_intf->gro_disallowed); 1009 1010 if (dp_get_current_throughput_level(dp_ctx) == PLD_BUS_WIDTH_IDLE || 1011 !rx_aggregation || gro_disallowed) { 1012 status = dp_ctx->dp_ops.dp_rx_napi_gro_flush(napi_to_use, nbuf, 1013 &low_tput_force_flush); 1014 if (!low_tput_force_flush) 1015 dp_intf->dp_stats.tx_rx_stats. 1016 rx_gro_low_tput_flush++; 1017 if (!rx_aggregation) 1018 dp_ctx->dp_agg_param.gro_force_flush[rx_ctx_id] = 1; 1019 if (gro_disallowed) 1020 dp_intf->gro_flushed[rx_ctx_id] = 1; 1021 } else { 1022 status = dp_ctx->dp_ops.dp_rx_napi_gro_receive(napi_to_use, 1023 nbuf); 1024 } 1025 1026 return status; 1027 } 1028 1029 #else /* WLAN_FEATURE_DYNAMIC_RX_AGGREGATION */ 1030 1031 /** 1032 * dp_gro_rx_bh_disable() - GRO RX/flush function. 1033 * @dp_intf: DP interface pointer 1034 * @napi_to_use: napi to be used to give packets to the stack, gro flush 1035 * @nbuf: pointer to nbuff 1036 * 1037 * Function calls napi_gro_receive for the skb. If the skb indicates that a 1038 * flush needs to be done (set by the lower DP layer), the function also calls 1039 * napi_gro_flush. Local softirqs are disabled (and later enabled) while making 1040 * napi_gro__ calls. 1041 * 1042 * Return: QDF_STATUS_SUCCESS if not dropped by napi_gro_receive or 1043 * QDF error code. 1044 */ 1045 1046 static QDF_STATUS dp_gro_rx_bh_disable(struct wlan_dp_intf *dp_intf, 1047 qdf_napi_struct *napi_to_use, 1048 qdf_nbuf_t nbuf) 1049 { 1050 QDF_STATUS status = QDF_STATUS_SUCCESS; 1051 struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; 1052 uint8_t low_tput_force_flush = 0; 1053 1054 if (dp_get_current_throughput_level(dp_ctx) == PLD_BUS_WIDTH_IDLE) { 1055 status = dp_ctx->dp_ops.dp_rx_napi_gro_flush(napi_to_use, nbuf, 1056 &low_tput_force_flush); 1057 if (!low_tput_force_flush) 1058 dp_intf->dp_stats.tx_rx_stats. 1059 rx_gro_low_tput_flush++; 1060 } else { 1061 status = dp_ctx->dp_ops.dp_rx_napi_gro_receive(napi_to_use, 1062 nbuf); 1063 } 1064 1065 return status; 1066 } 1067 #endif /* WLAN_FEATURE_DYNAMIC_RX_AGGREGATION */ 1068 1069 #if defined(FEATURE_LRO) 1070 /** 1071 * dp_lro_rx() - Handle Rx processing via LRO 1072 * @dp_intf: pointer to DP interface 1073 * @nbuf: pointer to n/w buff 1074 * 1075 * Return: QDF_STATUS_SUCCESS if processed via LRO or non zero return code 1076 */ 1077 static inline QDF_STATUS 1078 dp_lro_rx(struct wlan_dp_intf *dp_intf, qdf_nbuf_t nbuf) 1079 { 1080 struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; 1081 1082 return dp_ctx->dp_ops.dp_lro_rx_cb(dp_intf->dev, nbuf); 1083 } 1084 1085 /** 1086 * dp_is_lro_enabled() - Is LRO enabled 1087 * @dp_ctx: DP interface 1088 * 1089 * This function checks if LRO is enabled in DP context. 1090 * 1091 * Return: 0 - success, < 0 - failure 1092 */ 1093 static inline QDF_STATUS 1094 dp_is_lro_enabled(struct wlan_dp_psoc_context *dp_ctx) 1095 { 1096 if (dp_ctx->ol_enable != CFG_LRO_ENABLED) 1097 return QDF_STATUS_E_NOSUPPORT; 1098 } 1099 1100 QDF_STATUS dp_lro_set_reset(struct wlan_dp_intf *dp_intf, uint8_t enable_flag) 1101 { 1102 struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; 1103 1104 if ((dp_ctx->ol_enable != CFG_LRO_ENABLED) || 1105 (dp_intf->device_mode != QDF_STA_MODE)) { 1106 dp_info("LRO is already Disabled"); 1107 return QDF_STATUS_E_INVAL; 1108 } 1109 1110 if (enable_flag) { 1111 qdf_atomic_set(&dp_ctx->vendor_disable_lro_flag, 0); 1112 } else { 1113 /* Disable LRO, Enable tcpdelack*/ 1114 qdf_atomic_set(&dp_ctx->vendor_disable_lro_flag, 1); 1115 dp_info("LRO Disabled"); 1116 1117 if (dp_ctx->dp_cfg.enable_tcp_delack) { 1118 struct wlan_rx_tp_data rx_tp_data; 1119 1120 dp_info("Enable TCP delack as LRO is disabled"); 1121 rx_tp_data.rx_tp_flags = TCP_DEL_ACK_IND; 1122 rx_tp_data.level = 1123 DP_BUS_BW_CFG(dp_ctx->dp_cfg.cur_rx_level); 1124 wlan_dp_update_tcp_rx_param(dp_ctx, &rx_tp_data); 1125 dp_ctx->en_tcp_delack_no_lro = 1; 1126 } 1127 } 1128 1129 return QDF_STATUS_SUCCESS; 1130 } 1131 #else 1132 static inline 1133 QDF_STATUS dp_lro_rx(struct wlan_dp_intf *dp_intf, 1134 qdf_nbuf_t nbuf) 1135 { 1136 return QDF_STATUS_E_NOSUPPORT; 1137 } 1138 1139 static inline 1140 int dp_is_lro_enabled(struct wlan_dp_psoc_context *dp_ctx) 1141 { 1142 return QDF_STATUS_E_NOSUPPORT; 1143 } 1144 #endif /* FEATURE_LRO */ 1145 1146 /** 1147 * dp_gro_rx_thread() - Handle Rx processing via GRO for DP thread 1148 * @dp_intf: pointer to DP interface 1149 * @nbuf: pointer to n/w buff 1150 * 1151 * Return: QDF_STATUS_SUCCESS if processed via GRO or non zero return code 1152 */ 1153 static 1154 QDF_STATUS dp_gro_rx_thread(struct wlan_dp_intf *dp_intf, 1155 qdf_nbuf_t nbuf) 1156 { 1157 qdf_napi_struct *napi_to_use = NULL; 1158 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1159 1160 if (!dp_intf->dp_ctx->enable_dp_rx_threads) { 1161 dp_err_rl("gro not supported without DP RX thread!"); 1162 return status; 1163 } 1164 1165 napi_to_use = 1166 (qdf_napi_struct *)dp_rx_get_napi_context(cds_get_context(QDF_MODULE_ID_SOC), 1167 QDF_NBUF_CB_RX_CTX_ID(nbuf)); 1168 1169 if (!napi_to_use) { 1170 dp_err_rl("no napi to use for GRO!"); 1171 return status; 1172 } 1173 1174 return dp_gro_rx_bh_disable(dp_intf, napi_to_use, nbuf); 1175 } 1176 1177 /** 1178 * dp_gro_rx_legacy() - Handle Rx processing via GRO for ihelium based targets 1179 * @dp_intf: pointer to DP interface 1180 * @nbuf: pointer to n/w buf 1181 * 1182 * Supports GRO for only station mode 1183 * 1184 * Return: QDF_STATUS_SUCCESS if processed via GRO or non zero return code 1185 */ 1186 static 1187 QDF_STATUS dp_gro_rx_legacy(struct wlan_dp_intf *dp_intf, qdf_nbuf_t nbuf) 1188 { 1189 qdf_napi_struct *napi_to_use; 1190 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1191 struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; 1192 1193 /* Only enabling it for STA mode like LRO today */ 1194 if (QDF_STA_MODE != dp_intf->device_mode) 1195 return QDF_STATUS_E_NOSUPPORT; 1196 1197 if (qdf_atomic_read(&dp_ctx->disable_rx_ol_in_low_tput) || 1198 qdf_atomic_read(&dp_ctx->disable_rx_ol_in_concurrency)) 1199 return QDF_STATUS_E_NOSUPPORT; 1200 1201 napi_to_use = dp_ctx->dp_ops.dp_gro_rx_legacy_get_napi(nbuf, 1202 dp_ctx->enable_rxthread); 1203 if (!napi_to_use) 1204 goto out; 1205 1206 status = dp_gro_rx_bh_disable(dp_intf, napi_to_use, nbuf); 1207 out: 1208 1209 return status; 1210 } 1211 1212 /** 1213 * dp_register_rx_ol_cb() - Register LRO/GRO rx processing callbacks 1214 * @dp_ctx: pointer to dp_ctx 1215 * @wifi3_0_target: whether its a lithium/beryllium arch based target or not 1216 * 1217 * Return: none 1218 */ 1219 static void dp_register_rx_ol_cb(struct wlan_dp_psoc_context *dp_ctx, 1220 bool wifi3_0_target) 1221 { 1222 if (!dp_ctx) { 1223 dp_err("DP context is NULL"); 1224 return; 1225 } 1226 1227 dp_ctx->en_tcp_delack_no_lro = 0; 1228 1229 if (!dp_is_lro_enabled(dp_ctx)) { 1230 dp_ctx->dp_ops.dp_register_rx_offld_flush_cb(DP_RX_FLUSH_LRO); 1231 dp_ctx->receive_offload_cb = dp_lro_rx; 1232 dp_info("LRO is enabled"); 1233 } else if (dp_ctx->ol_enable == CFG_GRO_ENABLED) { 1234 qdf_atomic_set(&dp_ctx->dp_agg_param.rx_aggregation, 1); 1235 if (wifi3_0_target) { 1236 /* no flush registration needed, it happens in DP thread */ 1237 dp_ctx->receive_offload_cb = dp_gro_rx_thread; 1238 } else { 1239 /*ihelium based targets */ 1240 if (dp_ctx->enable_rxthread) 1241 dp_ctx->dp_ops.dp_register_rx_offld_flush_cb( 1242 DP_RX_FLUSH_THREAD); 1243 else 1244 dp_ctx->dp_ops.dp_register_rx_offld_flush_cb( 1245 DP_RX_FLUSH_NAPI); 1246 dp_ctx->receive_offload_cb = dp_gro_rx_legacy; 1247 } 1248 dp_info("GRO is enabled"); 1249 } else if (DP_BUS_BW_CFG(dp_ctx->dp_cfg.enable_tcp_delack)) { 1250 dp_ctx->en_tcp_delack_no_lro = 1; 1251 dp_info("TCP Del ACK is enabled"); 1252 } 1253 } 1254 1255 /** 1256 * dp_rx_ol_send_config() - Send RX offload configuration to FW 1257 * @dp_ctx: pointer to DP_ctx 1258 * 1259 * This function is only used for non lithium targets. Lithium based targets are 1260 * sending LRO config to FW in vdev attach implemented in cmn DP layer. 1261 * 1262 * Return: 0 on success, non zero on failure 1263 */ 1264 static QDF_STATUS dp_rx_ol_send_config(struct wlan_dp_psoc_context *dp_ctx) 1265 { 1266 struct cdp_lro_hash_config lro_config = {0}; 1267 QDF_STATUS status = QDF_STATUS_SUCCESS; 1268 1269 /* 1270 * This will enable flow steering and Toeplitz hash 1271 * So enable it for LRO or GRO processing. 1272 */ 1273 if (dp_ctx->dp_cfg.gro_enable || 1274 dp_ctx->dp_cfg.lro_enable) { 1275 lro_config.lro_enable = 1; 1276 lro_config.tcp_flag = QDF_TCPHDR_ACK; 1277 lro_config.tcp_flag_mask = QDF_TCPHDR_FIN | QDF_TCPHDR_SYN | 1278 QDF_TCPHDR_RST | QDF_TCPHDR_ACK | 1279 QDF_TCPHDR_URG | QDF_TCPHDR_ECE | 1280 QDF_TCPHDR_CWR; 1281 } 1282 1283 qdf_get_random_bytes(lro_config.toeplitz_hash_ipv4, 1284 (sizeof(lro_config.toeplitz_hash_ipv4[0]) * 1285 LRO_IPV4_SEED_ARR_SZ)); 1286 1287 qdf_get_random_bytes(lro_config.toeplitz_hash_ipv6, 1288 (sizeof(lro_config.toeplitz_hash_ipv6[0]) * 1289 LRO_IPV6_SEED_ARR_SZ)); 1290 1291 status = dp_ctx->sb_ops.dp_lro_config_cmd(dp_ctx->psoc, &lro_config); 1292 dp_info("LRO Config: lro_enable: 0x%x tcp_flag 0x%x tcp_flag_mask 0x%x", 1293 lro_config.lro_enable, lro_config.tcp_flag, 1294 lro_config.tcp_flag_mask); 1295 1296 return status; 1297 } 1298 1299 QDF_STATUS dp_rx_ol_init(struct wlan_dp_psoc_context *dp_ctx, 1300 bool is_wifi3_0_target) 1301 { 1302 QDF_STATUS status = QDF_STATUS_SUCCESS; 1303 1304 dp_resolve_rx_ol_mode(dp_ctx); 1305 dp_register_rx_ol_cb(dp_ctx, is_wifi3_0_target); 1306 1307 dp_info("ol init"); 1308 if (!is_wifi3_0_target) { 1309 status = dp_rx_ol_send_config(dp_ctx); 1310 if (status) { 1311 dp_ctx->ol_enable = 0; 1312 dp_err("Failed to send LRO/GRO configuration! %u", status); 1313 return status; 1314 } 1315 } 1316 1317 return 0; 1318 } 1319 1320 void dp_disable_rx_ol_for_low_tput(struct wlan_dp_psoc_context *dp_ctx, 1321 bool disable) 1322 { 1323 if (disable) 1324 qdf_atomic_set(&dp_ctx->disable_rx_ol_in_low_tput, 1); 1325 else 1326 qdf_atomic_set(&dp_ctx->disable_rx_ol_in_low_tput, 0); 1327 } 1328 1329 #else /* RECEIVE_OFFLOAD */ 1330 void dp_disable_rx_ol_for_low_tput(struct wlan_dp_psoc_context *dp_ctx, 1331 bool disable) 1332 { 1333 } 1334 #endif /* RECEIVE_OFFLOAD */ 1335 1336 #ifdef WLAN_FEATURE_TSF_PLUS_SOCK_TS 1337 static inline void dp_tsf_timestamp_rx(struct wlan_dp_psoc_context *dp_ctx, 1338 qdf_nbuf_t netbuf) 1339 { 1340 dp_ctx->dp_ops.dp_tsf_timestamp_rx(dp_ctx->dp_ops.callback_ctx, 1341 netbuf); 1342 } 1343 #else 1344 static inline void dp_tsf_timestamp_rx(struct wlan_dp_psoc_context *dp_ctx, 1345 qdf_nbuf_t netbuf) 1346 { 1347 } 1348 #endif 1349 1350 QDF_STATUS 1351 dp_rx_thread_gro_flush_ind_cbk(void *link_ctx, int rx_ctx_id) 1352 { 1353 struct wlan_dp_link *dp_link = link_ctx; 1354 struct wlan_dp_intf *dp_intf; 1355 enum dp_rx_gro_flush_code gro_flush_code = DP_RX_GRO_NORMAL_FLUSH; 1356 1357 if (qdf_unlikely((!dp_link) || (!dp_link->dp_intf) || 1358 (!dp_link->dp_intf->dp_ctx))) { 1359 dp_err("Null params being passed"); 1360 return QDF_STATUS_E_FAILURE; 1361 } 1362 1363 dp_intf = dp_link->dp_intf; 1364 if (dp_intf->runtime_disable_rx_thread) 1365 return QDF_STATUS_SUCCESS; 1366 1367 if (dp_is_low_tput_gro_enable(dp_intf->dp_ctx)) { 1368 dp_intf->dp_stats.tx_rx_stats.rx_gro_flush_skip++; 1369 gro_flush_code = DP_RX_GRO_LOW_TPUT_FLUSH; 1370 } 1371 1372 return dp_rx_gro_flush_ind(cds_get_context(QDF_MODULE_ID_SOC), 1373 rx_ctx_id, gro_flush_code); 1374 } 1375 1376 QDF_STATUS dp_rx_pkt_thread_enqueue_cbk(void *link_ctx, 1377 qdf_nbuf_t nbuf_list) 1378 { 1379 struct wlan_dp_intf *dp_intf; 1380 struct wlan_dp_link *dp_link; 1381 uint8_t link_id; 1382 qdf_nbuf_t head_ptr; 1383 1384 if (qdf_unlikely(!link_ctx || !nbuf_list)) { 1385 dp_err_rl("Null params being passed"); 1386 return QDF_STATUS_E_FAILURE; 1387 } 1388 1389 dp_link = (struct wlan_dp_link *)link_ctx; 1390 if (!is_dp_link_valid(dp_link)) 1391 return QDF_STATUS_E_FAILURE; 1392 1393 dp_intf = dp_link->dp_intf; 1394 if (dp_intf->runtime_disable_rx_thread && 1395 dp_intf->txrx_ops.rx.rx_stack) 1396 return dp_intf->txrx_ops.rx.rx_stack(dp_link, nbuf_list); 1397 1398 link_id = dp_link->link_id; 1399 1400 head_ptr = nbuf_list; 1401 while (head_ptr) { 1402 qdf_nbuf_cb_update_vdev_id(head_ptr, 1403 link_id); 1404 head_ptr = qdf_nbuf_next(head_ptr); 1405 } 1406 1407 return dp_rx_enqueue_pkt(cds_get_context(QDF_MODULE_ID_SOC), nbuf_list); 1408 } 1409 1410 #ifdef CONFIG_HL_SUPPORT 1411 QDF_STATUS wlan_dp_rx_deliver_to_stack(struct wlan_dp_intf *dp_intf, 1412 qdf_nbuf_t nbuf) 1413 { 1414 struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; 1415 1416 dp_intf->dp_stats.tx_rx_stats.rx_non_aggregated++; 1417 dp_ctx->no_rx_offload_pkt_cnt++; 1418 1419 return dp_ctx->dp_ops.dp_nbuf_push_pkt(nbuf, DP_NBUF_PUSH_NI); 1420 } 1421 #else 1422 1423 #if defined(WLAN_SUPPORT_RX_FISA) 1424 /** 1425 * wlan_dp_set_fisa_disallowed_for_intf() - Set fisa disallowed bit for an intf 1426 * @soc: DP soc handle 1427 * @dp_intf: DP interface handle 1428 * @rx_ctx_id: rx context id 1429 * @val: Enable or disable 1430 * 1431 * The function sets the fisa disallowed flag for a given vdev 1432 * 1433 * Return: None 1434 */ 1435 static inline 1436 void wlan_dp_set_fisa_disallowed_for_intf(ol_txrx_soc_handle soc, 1437 struct wlan_dp_intf *dp_intf, 1438 uint8_t rx_ctx_id, uint8_t val) 1439 { 1440 dp_intf->fisa_disallowed[rx_ctx_id] = val; 1441 } 1442 #else 1443 static inline 1444 void wlan_dp_set_fisa_disallowed_for_intf(ol_txrx_soc_handle soc, 1445 struct wlan_dp_intf *dp_intf, 1446 uint8_t rx_ctx_id, uint8_t val) 1447 { 1448 } 1449 #endif 1450 1451 #ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION 1452 QDF_STATUS wlan_dp_rx_deliver_to_stack(struct wlan_dp_intf *dp_intf, 1453 qdf_nbuf_t nbuf) 1454 { 1455 struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; 1456 struct wlan_dp_psoc_callbacks *dp_ops = &dp_ctx->dp_ops; 1457 int status = QDF_STATUS_E_FAILURE; 1458 bool nbuf_receive_offload_ok = false; 1459 enum dp_nbuf_push_type push_type; 1460 uint8_t rx_ctx_id = QDF_NBUF_CB_RX_CTX_ID(nbuf); 1461 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); 1462 int32_t gro_disallowed; 1463 1464 if (QDF_NBUF_CB_RX_TCP_PROTO(nbuf) && 1465 !QDF_NBUF_CB_RX_PEER_CACHED_FRM(nbuf)) 1466 nbuf_receive_offload_ok = true; 1467 1468 gro_disallowed = qdf_atomic_read(&dp_intf->gro_disallowed); 1469 if (gro_disallowed == 0 && 1470 dp_intf->gro_flushed[rx_ctx_id] != 0) { 1471 if (qdf_likely(soc)) 1472 wlan_dp_set_fisa_disallowed_for_intf(soc, dp_intf, 1473 rx_ctx_id, 0); 1474 dp_intf->gro_flushed[rx_ctx_id] = 0; 1475 } else if (gro_disallowed && 1476 dp_intf->gro_flushed[rx_ctx_id] == 0) { 1477 if (qdf_likely(soc)) 1478 wlan_dp_set_fisa_disallowed_for_intf(soc, dp_intf, 1479 rx_ctx_id, 1); 1480 } 1481 1482 if (nbuf_receive_offload_ok && dp_ctx->receive_offload_cb && 1483 !dp_ctx->dp_agg_param.gro_force_flush[rx_ctx_id] && 1484 !dp_intf->gro_flushed[rx_ctx_id] && 1485 !dp_intf->runtime_disable_rx_thread) { 1486 status = dp_ctx->receive_offload_cb(dp_intf, nbuf); 1487 1488 if (QDF_IS_STATUS_SUCCESS(status)) { 1489 dp_intf->dp_stats.tx_rx_stats.rx_aggregated++; 1490 return status; 1491 } 1492 1493 if (status == QDF_STATUS_E_GRO_DROP) { 1494 dp_intf->dp_stats.tx_rx_stats.rx_gro_dropped++; 1495 return status; 1496 } 1497 } 1498 1499 /* 1500 * The below case handles the scenario when rx_aggregation is 1501 * re-enabled dynamically, in which case gro_force_flush needs 1502 * to be reset to 0 to allow GRO. 1503 */ 1504 if (qdf_atomic_read(&dp_ctx->dp_agg_param.rx_aggregation) && 1505 dp_ctx->dp_agg_param.gro_force_flush[rx_ctx_id]) 1506 dp_ctx->dp_agg_param.gro_force_flush[rx_ctx_id] = 0; 1507 1508 dp_intf->dp_stats.tx_rx_stats.rx_non_aggregated++; 1509 1510 /* Account for GRO/LRO ineligible packets, mostly UDP */ 1511 if (qdf_nbuf_get_gso_segs(nbuf) == 0) 1512 dp_ctx->no_rx_offload_pkt_cnt++; 1513 1514 if (qdf_likely((dp_ctx->enable_dp_rx_threads || 1515 dp_ctx->enable_rxthread) && 1516 !dp_intf->runtime_disable_rx_thread)) { 1517 push_type = DP_NBUF_PUSH_BH_DISABLE; 1518 } else if (qdf_unlikely(QDF_NBUF_CB_RX_PEER_CACHED_FRM(nbuf))) { 1519 /* 1520 * Frames before peer is registered to avoid contention with 1521 * NAPI softirq. 1522 * Refer fix: 1523 * qcacld-3.0: Do netif_rx_ni() for frames received before 1524 * peer assoc 1525 */ 1526 push_type = DP_NBUF_PUSH_NI; 1527 } else { /* NAPI Context */ 1528 push_type = DP_NBUF_PUSH_NAPI; 1529 } 1530 1531 return dp_ops->dp_nbuf_push_pkt(nbuf, push_type); 1532 } 1533 1534 #else /* WLAN_FEATURE_DYNAMIC_RX_AGGREGATION */ 1535 1536 QDF_STATUS wlan_dp_rx_deliver_to_stack(struct wlan_dp_intf *dp_intf, 1537 qdf_nbuf_t nbuf) 1538 { 1539 struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; 1540 struct wlan_dp_psoc_callbacks *dp_ops = &dp_ctx->dp_ops; 1541 int status = QDF_STATUS_E_FAILURE; 1542 bool nbuf_receive_offload_ok = false; 1543 enum dp_nbuf_push_type push_type; 1544 1545 if (QDF_NBUF_CB_RX_TCP_PROTO(nbuf) && 1546 !QDF_NBUF_CB_RX_PEER_CACHED_FRM(nbuf)) 1547 nbuf_receive_offload_ok = true; 1548 1549 if (nbuf_receive_offload_ok && dp_ctx->receive_offload_cb) { 1550 status = dp_ctx->receive_offload_cb(dp_intf, nbuf); 1551 1552 if (QDF_IS_STATUS_SUCCESS(status)) { 1553 dp_intf->dp_stats.tx_rx_stats.rx_aggregated++; 1554 return status; 1555 } 1556 1557 if (status == QDF_STATUS_E_GRO_DROP) { 1558 dp_intf->dp_stats.tx_rx_stats.rx_gro_dropped++; 1559 return status; 1560 } 1561 } 1562 1563 dp_intf->dp_stats.tx_rx_stats.rx_non_aggregated++; 1564 1565 /* Account for GRO/LRO ineligible packets, mostly UDP */ 1566 if (qdf_nbuf_get_gso_segs(nbuf) == 0) 1567 dp_ctx->no_rx_offload_pkt_cnt++; 1568 1569 if (qdf_likely((dp_ctx->enable_dp_rx_threads || 1570 dp_ctx->enable_rxthread) && 1571 !dp_intf->runtime_disable_rx_thread)) { 1572 push_type = DP_NBUF_PUSH_BH_DISABLE; 1573 } else if (qdf_unlikely(QDF_NBUF_CB_RX_PEER_CACHED_FRM(nbuf))) { 1574 /* 1575 * Frames before peer is registered to avoid contention with 1576 * NAPI softirq. 1577 * Refer fix: 1578 * qcacld-3.0: Do netif_rx_ni() for frames received before 1579 * peer assoc 1580 */ 1581 push_type = DP_NBUF_PUSH_NI; 1582 } else { /* NAPI Context */ 1583 push_type = DP_NBUF_PUSH_NAPI; 1584 } 1585 1586 return dp_ops->dp_nbuf_push_pkt(nbuf, push_type); 1587 } 1588 #endif /* WLAN_FEATURE_DYNAMIC_RX_AGGREGATION */ 1589 #endif 1590 1591 static inline bool 1592 dp_is_gratuitous_arp_unsolicited_na(struct wlan_dp_psoc_context *dp_ctx, 1593 qdf_nbuf_t nbuf) 1594 { 1595 if (qdf_unlikely(dp_ctx->dp_ops.dp_is_gratuitous_arp_unsolicited_na)) 1596 return dp_ctx->dp_ops.dp_is_gratuitous_arp_unsolicited_na(nbuf); 1597 1598 return false; 1599 } 1600 1601 QDF_STATUS dp_rx_flush_packet_cbk(void *dp_link_context, uint8_t link_id) 1602 { 1603 struct wlan_dp_link *dp_link = (struct wlan_dp_link *)dp_link_context; 1604 struct wlan_dp_intf *dp_intf = dp_link->dp_intf; 1605 struct wlan_dp_psoc_context *dp_ctx; 1606 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); 1607 1608 if (qdf_unlikely(!soc)) 1609 return QDF_STATUS_E_FAILURE; 1610 1611 dp_ctx = dp_intf->dp_ctx; 1612 if (qdf_unlikely(!dp_ctx)) 1613 return QDF_STATUS_E_FAILURE; 1614 1615 qdf_atomic_inc(&dp_intf->num_active_task); 1616 1617 /* do fisa flush for this vdev */ 1618 if (wlan_dp_cfg_is_rx_fisa_enabled(&dp_ctx->dp_cfg)) 1619 wlan_dp_rx_fisa_flush_by_vdev_id((struct dp_soc *)soc, link_id); 1620 1621 if (dp_ctx->enable_dp_rx_threads) 1622 dp_txrx_flush_pkts_by_vdev_id(soc, link_id); 1623 1624 qdf_atomic_dec(&dp_intf->num_active_task); 1625 1626 return QDF_STATUS_SUCCESS; 1627 } 1628 1629 #if defined(WLAN_SUPPORT_RX_FISA) 1630 QDF_STATUS wlan_dp_rx_fisa_cbk(void *dp_soc, 1631 void *dp_vdev, qdf_nbuf_t nbuf_list) 1632 { 1633 struct wlan_dp_psoc_context *dp_ctx = dp_get_context(); 1634 1635 return dp_fisa_rx(dp_ctx, dp_vdev, nbuf_list); 1636 } 1637 1638 QDF_STATUS wlan_dp_rx_fisa_flush_by_ctx_id(void *dp_soc, int ring_num) 1639 { 1640 return dp_rx_fisa_flush_by_ctx_id((struct dp_soc *)dp_soc, ring_num); 1641 } 1642 1643 QDF_STATUS wlan_dp_rx_fisa_flush_by_vdev_id(void *dp_soc, uint8_t vdev_id) 1644 { 1645 return dp_rx_fisa_flush_by_vdev_id((struct dp_soc *)dp_soc, vdev_id); 1646 } 1647 #endif 1648 1649 QDF_STATUS dp_rx_packet_cbk(void *dp_link_context, 1650 qdf_nbuf_t rxBuf) 1651 { 1652 struct wlan_dp_intf *dp_intf = NULL; 1653 struct wlan_dp_link *dp_link = NULL; 1654 struct wlan_dp_psoc_context *dp_ctx = NULL; 1655 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 1656 qdf_nbuf_t nbuf = NULL; 1657 qdf_nbuf_t next = NULL; 1658 unsigned int cpu_index; 1659 struct qdf_mac_addr *mac_addr, *dest_mac_addr; 1660 bool wake_lock = false; 1661 bool track_arp = false; 1662 enum qdf_proto_subtype subtype = QDF_PROTO_INVALID; 1663 bool is_eapol, send_over_nl; 1664 bool is_dhcp; 1665 struct dp_tx_rx_stats *stats; 1666 QDF_STATUS status; 1667 uint8_t pkt_type; 1668 1669 /* Sanity check on inputs */ 1670 if (qdf_unlikely((!dp_link_context) || (!rxBuf))) { 1671 dp_err_rl("Null params being passed"); 1672 return QDF_STATUS_E_FAILURE; 1673 } 1674 1675 dp_link = (struct wlan_dp_link *)dp_link_context; 1676 dp_intf = dp_link->dp_intf; 1677 dp_ctx = dp_intf->dp_ctx; 1678 1679 cpu_index = qdf_get_cpu(); 1680 stats = &dp_intf->dp_stats.tx_rx_stats; 1681 1682 next = rxBuf; 1683 1684 while (next) { 1685 nbuf = next; 1686 next = qdf_nbuf_next(nbuf); 1687 qdf_nbuf_set_next(nbuf, NULL); 1688 is_eapol = false; 1689 is_dhcp = false; 1690 send_over_nl = false; 1691 1692 if (qdf_nbuf_is_ipv4_arp_pkt(nbuf)) { 1693 if (qdf_nbuf_data_is_arp_rsp(nbuf) && 1694 (dp_intf->track_arp_ip == 1695 qdf_nbuf_get_arp_src_ip(nbuf))) { 1696 ++dp_intf->dp_stats.arp_stats. 1697 rx_arp_rsp_count; 1698 dp_debug("ARP packet received"); 1699 track_arp = true; 1700 } 1701 } else if (qdf_nbuf_is_ipv4_eapol_pkt(nbuf)) { 1702 subtype = qdf_nbuf_get_eapol_subtype(nbuf); 1703 send_over_nl = true; 1704 1705 /* Mac address check between RX packet DA and dp_intf's */ 1706 dp_rx_pkt_da_check(dp_intf, nbuf); 1707 if (subtype == QDF_PROTO_EAPOL_M1) { 1708 ++dp_intf->dp_stats.eapol_stats. 1709 eapol_m1_count; 1710 is_eapol = true; 1711 } else if (subtype == QDF_PROTO_EAPOL_M3) { 1712 ++dp_intf->dp_stats.eapol_stats. 1713 eapol_m3_count; 1714 is_eapol = true; 1715 } 1716 } else if (qdf_nbuf_is_ipv4_dhcp_pkt(nbuf)) { 1717 subtype = qdf_nbuf_get_dhcp_subtype(nbuf); 1718 if (subtype == QDF_PROTO_DHCP_OFFER) { 1719 ++dp_intf->dp_stats.dhcp_stats. 1720 dhcp_off_count; 1721 is_dhcp = true; 1722 } else if (subtype == QDF_PROTO_DHCP_ACK) { 1723 ++dp_intf->dp_stats.dhcp_stats. 1724 dhcp_ack_count; 1725 is_dhcp = true; 1726 } 1727 } 1728 1729 wlan_dp_pkt_add_timestamp(dp_intf, QDF_PKT_RX_DRIVER_EXIT, 1730 nbuf); 1731 1732 /* track connectivity stats */ 1733 if (dp_intf->pkt_type_bitmap) 1734 dp_tx_rx_collect_connectivity_stats_info(nbuf, dp_link, 1735 PKT_TYPE_RSP, 1736 &pkt_type); 1737 1738 if ((dp_link->conn_info.proxy_arp_service) && 1739 dp_is_gratuitous_arp_unsolicited_na(dp_ctx, nbuf)) { 1740 qdf_atomic_inc(&stats->rx_usolict_arp_n_mcast_drp); 1741 /* Remove SKB from internal tracking table before 1742 * submitting it to stack. 1743 */ 1744 qdf_nbuf_free(nbuf); 1745 continue; 1746 } 1747 1748 dp_event_eapol_log(nbuf, QDF_RX); 1749 qdf_dp_trace_log_pkt(dp_link->link_id, nbuf, QDF_RX, 1750 QDF_TRACE_DEFAULT_PDEV_ID, 1751 dp_intf->device_mode); 1752 1753 DPTRACE(qdf_dp_trace(nbuf, 1754 QDF_DP_TRACE_RX_PACKET_PTR_RECORD, 1755 QDF_TRACE_DEFAULT_PDEV_ID, 1756 qdf_nbuf_data_addr(nbuf), 1757 sizeof(qdf_nbuf_data(nbuf)), QDF_RX)); 1758 1759 DPTRACE(qdf_dp_trace_data_pkt(nbuf, QDF_TRACE_DEFAULT_PDEV_ID, 1760 QDF_DP_TRACE_RX_PACKET_RECORD, 1761 0, QDF_RX)); 1762 1763 dest_mac_addr = (struct qdf_mac_addr *)(qdf_nbuf_data(nbuf) + 1764 QDF_NBUF_DEST_MAC_OFFSET); 1765 mac_addr = (struct qdf_mac_addr *)(qdf_nbuf_data(nbuf) + 1766 QDF_NBUF_SRC_MAC_OFFSET); 1767 1768 status = wlan_objmgr_vdev_try_get_ref(dp_link->vdev, 1769 WLAN_TDLS_SB_ID); 1770 if (QDF_IS_STATUS_SUCCESS(status)) { 1771 wlan_tdls_update_rx_pkt_cnt(dp_link->vdev, mac_addr, 1772 dest_mac_addr); 1773 wlan_objmgr_vdev_release_ref(dp_link->vdev, 1774 WLAN_TDLS_SB_ID); 1775 } 1776 1777 if (dp_rx_pkt_tracepoints_enabled()) 1778 qdf_trace_dp_packet(nbuf, QDF_RX, NULL, 0); 1779 1780 qdf_nbuf_set_dev(nbuf, dp_intf->dev); 1781 qdf_nbuf_set_protocol_eth_tye_trans(nbuf); 1782 ++stats->per_cpu[cpu_index].rx_packets; 1783 qdf_net_stats_add_rx_pkts(&dp_intf->stats, 1); 1784 /* count aggregated RX frame into stats */ 1785 qdf_net_stats_add_rx_pkts(&dp_intf->stats, 1786 qdf_nbuf_get_gso_segs(nbuf)); 1787 qdf_net_stats_add_rx_bytes(&dp_intf->stats, 1788 qdf_nbuf_len(nbuf)); 1789 1790 /* Incr GW Rx count for NUD tracking based on GW mac addr */ 1791 dp_nud_incr_gw_rx_pkt_cnt(dp_intf, mac_addr); 1792 1793 /* Check & drop replayed mcast packets (for IPV6) */ 1794 if (dp_ctx->dp_cfg.multicast_replay_filter && 1795 qdf_nbuf_is_mcast_replay(nbuf)) { 1796 qdf_atomic_inc(&stats->rx_usolict_arp_n_mcast_drp); 1797 qdf_nbuf_free(nbuf); 1798 continue; 1799 } 1800 1801 /* hold configurable wakelock for unicast traffic */ 1802 if (!dp_is_current_high_throughput(dp_ctx) && 1803 dp_ctx->dp_cfg.rx_wakelock_timeout && 1804 dp_link->conn_info.is_authenticated) 1805 wake_lock = dp_is_rx_wake_lock_needed(nbuf); 1806 1807 if (wake_lock) { 1808 cds_host_diag_log_work(&dp_ctx->rx_wake_lock, 1809 dp_ctx->dp_cfg.rx_wakelock_timeout, 1810 WIFI_POWER_EVENT_WAKELOCK_HOLD_RX); 1811 qdf_wake_lock_timeout_acquire(&dp_ctx->rx_wake_lock, 1812 dp_ctx->dp_cfg.rx_wakelock_timeout); 1813 } 1814 1815 /* Remove SKB from internal tracking table before submitting 1816 * it to stack 1817 */ 1818 qdf_net_buf_debug_release_skb(nbuf); 1819 1820 dp_tsf_timestamp_rx(dp_ctx, nbuf); 1821 1822 if (send_over_nl && dp_ctx->dp_ops.dp_send_rx_pkt_over_nl) { 1823 if (dp_ctx->dp_ops.dp_send_rx_pkt_over_nl(dp_intf->dev, 1824 (u8 *)&dp_link->conn_info.peer_macaddr, 1825 nbuf, false)) 1826 qdf_status = QDF_STATUS_SUCCESS; 1827 else 1828 qdf_status = QDF_STATUS_E_INVAL; 1829 qdf_nbuf_dev_kfree(nbuf); 1830 } else { 1831 qdf_status = wlan_dp_rx_deliver_to_stack(dp_intf, nbuf); 1832 } 1833 1834 if (QDF_IS_STATUS_SUCCESS(qdf_status)) { 1835 ++stats->per_cpu[cpu_index].rx_delivered; 1836 if (track_arp) 1837 ++dp_intf->dp_stats.arp_stats.rx_delivered; 1838 if (is_eapol) 1839 ++dp_intf->dp_stats.eapol_stats. 1840 rx_delivered[subtype - QDF_PROTO_EAPOL_M1]; 1841 else if (is_dhcp) 1842 ++dp_intf->dp_stats.dhcp_stats. 1843 rx_delivered[subtype - QDF_PROTO_DHCP_DISCOVER]; 1844 1845 /* track connectivity stats */ 1846 if (dp_intf->pkt_type_bitmap) 1847 dp_tx_rx_collect_connectivity_stats_info( 1848 nbuf, dp_link, 1849 PKT_TYPE_RX_DELIVERED, 1850 &pkt_type); 1851 } else { 1852 ++stats->per_cpu[cpu_index].rx_refused; 1853 if (track_arp) 1854 ++dp_intf->dp_stats.arp_stats.rx_refused; 1855 1856 if (is_eapol) 1857 ++dp_intf->dp_stats.eapol_stats. 1858 rx_refused[subtype - QDF_PROTO_EAPOL_M1]; 1859 else if (is_dhcp) 1860 ++dp_intf->dp_stats.dhcp_stats. 1861 rx_refused[subtype - QDF_PROTO_DHCP_DISCOVER]; 1862 1863 /* track connectivity stats */ 1864 if (dp_intf->pkt_type_bitmap) 1865 dp_tx_rx_collect_connectivity_stats_info( 1866 nbuf, dp_link, 1867 PKT_TYPE_RX_REFUSED, 1868 &pkt_type); 1869 } 1870 } 1871 1872 return QDF_STATUS_SUCCESS; 1873 } 1874 1875