diff --git a/components/dp/core/inc/wlan_dp_main.h b/components/dp/core/inc/wlan_dp_main.h index 6614220d82..901f56b841 100644 --- a/components/dp/core/inc/wlan_dp_main.h +++ b/components/dp/core/inc/wlan_dp_main.h @@ -427,4 +427,86 @@ void dp_mic_deinit_work(struct wlan_dp_intf *dp_intf); void dp_rx_mic_error_ind(struct cdp_ctrl_objmgr_psoc *psoc, uint8_t pdev_id, struct cdp_rx_mic_err_info *mic_failure_info); +/** + * dp_intf_get_tx_ops: get TX ops from the DP interface + * @psoc: pointer to psoc object + * + * Return: pointer to TX op callback + */ +static inline +struct wlan_dp_psoc_sb_ops *dp_intf_get_tx_ops(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_dp_psoc_context *dp_ctx; + + if (!psoc) { + dp_err("psoc is null"); + return NULL; + } + + dp_ctx = dp_psoc_get_priv(psoc); + if (!dp_ctx) { + dp_err("psoc private object is null"); + return NULL; + } + + return &dp_ctx->sb_ops; +} + +/** + * dp_intf_get_rx_ops: get RX ops from the DP interface + * @psoc: pointer to psoc object + * + * Return: pointer to RX op callback + */ +static inline +struct wlan_dp_psoc_nb_ops *dp_intf_get_rx_ops(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_dp_psoc_context *dp_ctx; + + if (!psoc) { + dp_err("psoc is null"); + return NULL; + } + + dp_ctx = dp_psoc_get_priv(psoc); + if (!dp_ctx) { + dp_err("psoc private object is null"); + return NULL; + } + + return &dp_ctx->nb_ops; +} + +/** + * dp_intf_get_rx_ops: get ARP req context from the DP context + * @psoc: pointer to psoc object + * + * Return: pointer to ARP request ctx. + */ +static inline +void *dp_get_arp_request_ctx(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_dp_psoc_context *dp_ctx; + + dp_ctx = dp_psoc_get_priv(psoc); + if (!dp_ctx) { + dp_err("psoc private object is null"); + return NULL; + } + return dp_ctx->sb_ops.arp_request_ctx; +} + +/** + * dp_get_arp_stats_event_handler() - callback api to update the + * stats received from FW + * @psoc : psoc handle + * @rsp: pointer to data received from FW. + * + * This is called when wlan driver received response event for + * get arp stats to firmware. + * + * Return: None + */ +QDF_STATUS dp_get_arp_stats_event_handler(struct wlan_objmgr_psoc *psoc, + struct dp_rsp_stats *rsp); #endif diff --git a/components/dp/core/inc/wlan_dp_priv.h b/components/dp/core/inc/wlan_dp_priv.h index 885625c6a9..d17dc2eae8 100644 --- a/components/dp/core/inc/wlan_dp_priv.h +++ b/components/dp/core/inc/wlan_dp_priv.h @@ -246,6 +246,10 @@ struct dp_tx_rx_stats { */ struct dp_stats { struct dp_tx_rx_stats tx_rx_stats; + struct dp_arp_stats arp_stats; + struct dp_dns_stats dns_stats; + struct dp_tcp_stats tcp_stats; + struct dp_icmpv4_stats icmpv4_stats; }; /** @@ -285,6 +289,8 @@ struct wlan_dp_intf { qdf_mutex_t sta_periodic_stats_lock; #endif /* WLAN_FEATURE_PERIODIC_STA_STATS */ qdf_net_dev_stats stats; + bool con_status; + bool dad; #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH unsigned long prev_rx_packets; unsigned long prev_tx_packets; diff --git a/components/dp/core/src/wlan_dp_main.c b/components/dp/core/src/wlan_dp_main.c index 5d4bd0a7a7..9df1977089 100644 --- a/components/dp/core/src/wlan_dp_main.c +++ b/components/dp/core/src/wlan_dp_main.c @@ -29,6 +29,8 @@ #include #include "wlan_objmgr_vdev_obj.h" #include +#include "wlan_dp_nud_tracking.h" +#include "target_if_dp_comp.h" /* Global DP context */ static struct wlan_dp_psoc_context *gp_dp_ctx; @@ -497,6 +499,9 @@ dp_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg) dp_ctx->psoc = psoc; dp_cfg_init(dp_ctx); + target_if_dp_register_tx_ops(&dp_ctx->sb_ops); + target_if_dp_register_rx_ops(&dp_ctx->nb_ops); + return status; } @@ -809,3 +814,52 @@ void dp_clear_rps_cpu_mask(struct wlan_dp_psoc_context *dp_ctx) dp_send_rps_disable_ind(dp_intf); } } + +QDF_STATUS dp_get_arp_stats_event_handler(struct wlan_objmgr_psoc *psoc, + struct dp_rsp_stats *rsp) +{ + struct wlan_dp_intf *dp_intf; + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + rsp->vdev_id, + WLAN_DP_ID); + if (!vdev) { + dp_err("Can't get vdev by vdev_id:%d", rsp->vdev_id); + return QDF_STATUS_E_INVAL; + } + + dp_intf = dp_get_vdev_priv_obj(vdev); + if (!dp_intf) { + dp_err("Unable to get DP interface"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_DP_ID); + return QDF_STATUS_E_INVAL; + } + + dp_info("rsp->arp_req_enqueue :%x", rsp->arp_req_enqueue); + dp_info("rsp->arp_req_tx_success :%x", rsp->arp_req_tx_success); + dp_info("rsp->arp_req_tx_failure :%x", rsp->arp_req_tx_failure); + dp_info("rsp->arp_rsp_recvd :%x", rsp->arp_rsp_recvd); + dp_info("rsp->out_of_order_arp_rsp_drop_cnt :%x", + rsp->out_of_order_arp_rsp_drop_cnt); + dp_info("rsp->dad_detected :%x", rsp->dad_detected); + dp_info("rsp->connect_status :%x", rsp->connect_status); + dp_info("rsp->ba_session_establishment_status :%x", + rsp->ba_session_establishment_status); + + dp_intf->dp_stats.arp_stats.rx_fw_cnt = rsp->arp_rsp_recvd; + dp_intf->dad |= rsp->dad_detected; + dp_intf->con_status = rsp->connect_status; + + /* Flag true indicates connectivity check stats present. */ + if (rsp->connect_stats_present) { + dp_info("rsp->tcp_ack_recvd :%x", rsp->tcp_ack_recvd); + dp_info("rsp->icmpv4_rsp_recvd :%x", rsp->icmpv4_rsp_recvd); + dp_intf->dp_stats.tcp_stats.rx_fw_cnt = rsp->tcp_ack_recvd; + dp_intf->dp_stats.icmpv4_stats.rx_fw_cnt = + rsp->icmpv4_rsp_recvd; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_DP_ID); + return QDF_STATUS_SUCCESS; +} diff --git a/components/dp/dispatcher/inc/wlan_dp_public_struct.h b/components/dp/dispatcher/inc/wlan_dp_public_struct.h index eb291afdd5..885b895fd7 100644 --- a/components/dp/dispatcher/inc/wlan_dp_public_struct.h +++ b/components/dp/dispatcher/inc/wlan_dp_public_struct.h @@ -30,6 +30,7 @@ #include #include #include +#include "cdp_txrx_ops.h" #include #ifdef TX_MULTIQ_PER_AC @@ -50,6 +51,191 @@ #define NUM_TX_QUEUES (4 * TX_QUEUES_PER_AC) #endif +/** + * struct dp_arp_stats - arp debug stats count + * @tx_arp_req_count: no. of arp req received from network stack + * @rx_arp_rsp_count: no. of arp res received from FW + * @tx_dropped: no. of arp req dropped at hdd layer + * @rx_dropped: no. of arp res dropped + * @rx_delivered: no. of arp res delivered to network stack + * @rx_refused: no of arp rsp refused (not delivered) to network stack + * @tx_host_fw_sent: no of arp req sent by FW OTA + * @rx_host_drop_reorder: no of arp res dropped by host + * @rx_fw_cnt: no of arp res received by FW + * @tx_ack_cnt: no of arp req acked by FW + */ +struct dp_arp_stats { + uint16_t tx_arp_req_count; + uint16_t rx_arp_rsp_count; + uint16_t tx_dropped; + uint16_t rx_dropped; + uint16_t rx_delivered; + uint16_t rx_refused; + uint16_t tx_host_fw_sent; + uint16_t rx_host_drop_reorder; + uint16_t rx_fw_cnt; + uint16_t tx_ack_cnt; +}; + +/** + * struct dp_set_arp_stats_params - set/reset arp stats + * @vdev_id: session id + * @flag: enable/disable stats + * @pkt_type: type of packet(1 - arp) + * @ip_addr: subnet ipv4 address in case of encrypted packets + * @pkt_type_bitmap: pkt bitmap + * @tcp_src_port: tcp src port for pkt tracking + * @tcp_dst_port: tcp dst port for pkt tracking + * @icmp_ipv4: target ipv4 address to track ping packets + * @reserved: reserved + */ +struct dp_set_arp_stats_params { + uint32_t vdev_id; + uint8_t flag; + uint8_t pkt_type; + uint32_t ip_addr; + uint32_t pkt_type_bitmap; + uint32_t tcp_src_port; + uint32_t tcp_dst_port; + uint32_t icmp_ipv4; + uint32_t reserved; +}; + +/** + * struct dp_get_arp_stats_params - get arp stats from firmware + * @pkt_type: packet type(1 - ARP) + * @vdev_id: session id + */ +struct dp_get_arp_stats_params { + uint8_t pkt_type; + uint32_t vdev_id; +}; + +/** + * struct dp_dns_stats - dns debug stats count + * @tx_dns_req_count: no. of dns query received from network stack + * @rx_dns_rsp_count: no. of dns res received from FW + * @tx_dropped: no. of dns query dropped at hdd layer + * @rx_delivered: no. of dns res delivered to network stack + * @rx_refused: no of dns res refused (not delivered) to network stack + * @tx_host_fw_sent: no of dns query sent by FW OTA + * @rx_host_drop: no of dns res dropped by host + * @tx_ack_cnt: no of dns req acked by FW + */ +struct dp_dns_stats { + uint16_t tx_dns_req_count; + uint16_t rx_dns_rsp_count; + uint16_t tx_dropped; + uint16_t rx_delivered; + uint16_t rx_refused; + uint16_t tx_host_fw_sent; + uint16_t rx_host_drop; + uint16_t tx_ack_cnt; +}; + +/** + * struct dp_tcp_stats - tcp debug stats count + * @tx_tcp_syn_count: no. of tcp syn received from network stack + * @@tx_tcp_ack_count: no. of tcp ack received from network stack + * @rx_tcp_syn_ack_count: no. of tcp syn ack received from FW + * @tx_tcp_syn_dropped: no. of tcp syn dropped at hdd layer + * @tx_tcp_ack_dropped: no. of tcp ack dropped at hdd layer + * @rx_delivered: no. of tcp syn ack delivered to network stack + * @rx_refused: no of tcp syn ack refused (not delivered) to network stack + * @tx_tcp_syn_host_fw_sent: no of tcp syn sent by FW OTA + * @@tx_tcp_ack_host_fw_sent: no of tcp ack sent by FW OTA + * @rx_host_drop: no of tcp syn ack dropped by host + * @tx_tcp_syn_ack_cnt: no of tcp syn acked by FW + * @tx_tcp_syn_ack_cnt: no of tcp ack acked by FW + * @is_tcp_syn_ack_rcv: flag to check tcp syn ack received or not + * @is_tcp_ack_sent: flag to check tcp ack sent or not + */ +struct dp_tcp_stats { + uint16_t tx_tcp_syn_count; + uint16_t tx_tcp_ack_count; + uint16_t rx_tcp_syn_ack_count; + uint16_t tx_tcp_syn_dropped; + uint16_t tx_tcp_ack_dropped; + uint16_t rx_delivered; + uint16_t rx_refused; + uint16_t tx_tcp_syn_host_fw_sent; + uint16_t tx_tcp_ack_host_fw_sent; + uint16_t rx_host_drop; + uint16_t rx_fw_cnt; + uint16_t tx_tcp_syn_ack_cnt; + uint16_t tx_tcp_ack_ack_cnt; + bool is_tcp_syn_ack_rcv; + bool is_tcp_ack_sent; + +}; + +/** + * struct dp_icmpv4_stats - icmpv4 debug stats count + * @tx_icmpv4_req_count: no. of icmpv4 req received from network stack + * @rx_icmpv4_rsp_count: no. of icmpv4 res received from FW + * @tx_dropped: no. of icmpv4 req dropped at hdd layer + * @rx_delivered: no. of icmpv4 res delivered to network stack + * @rx_refused: no of icmpv4 res refused (not delivered) to network stack + * @tx_host_fw_sent: no of icmpv4 req sent by FW OTA + * @rx_host_drop: no of icmpv4 res dropped by host + * @rx_fw_cnt: no of icmpv4 res received by FW + * @tx_ack_cnt: no of icmpv4 req acked by FW + */ +struct dp_icmpv4_stats { + uint16_t tx_icmpv4_req_count; + uint16_t rx_icmpv4_rsp_count; + uint16_t tx_dropped; + uint16_t rx_delivered; + uint16_t rx_refused; + uint16_t tx_host_fw_sent; + uint16_t rx_host_drop; + uint16_t rx_fw_cnt; + uint16_t tx_ack_cnt; +}; + +/** + * struct dp_rsp_stats - arp packet stats + * @arp_req_enqueue: fw tx count + * @arp_req_tx_success: tx ack count + * @arp_req_tx_failure: tx ack fail count + * @arp_rsp_recvd: rx fw count + * @out_of_order_arp_rsp_drop_cnt: out of order count + * @dad_detected: dad detected + * @connect_status: connection status + * @ba_session_establishment_status: BA session status + * @connect_stats_present: connectivity stats present or not + * @tcp_ack_recvd: tcp syn ack's count + * @icmpv4_rsp_recvd: icmpv4 responses count + */ +struct dp_rsp_stats { + uint32_t vdev_id; + uint32_t arp_req_enqueue; + uint32_t arp_req_tx_success; + uint32_t arp_req_tx_failure; + uint32_t arp_rsp_recvd; + uint32_t out_of_order_arp_rsp_drop_cnt; + uint32_t dad_detected; + uint32_t connect_status; + uint32_t ba_session_establishment_status; + bool connect_stats_present; + uint32_t tcp_ack_recvd; + uint32_t icmpv4_rsp_recvd; +}; + +/** + * struct dp_dhcp_ind - DHCP Start/Stop indication message + * @dhcp_start: Is DHCP start idication + * @device_mode: Mode of the device(ex:STA, AP) + * @intf_mac_addr: MAC address of the interface + * @peer_mac_addr: MAC address of the connected peer + */ +struct dp_dhcp_ind { + bool dhcp_start; + uint8_t device_mode; + struct qdf_mac_addr intf_mac_addr; + struct qdf_mac_addr peer_mac_addr; +}; + /** * struct dp_mic_info - mic error info in dp * @ta_mac_addr: transmitter mac address @@ -344,17 +530,40 @@ struct wlan_dp_psoc_callbacks { /** * struct wlan_dp_psoc_sb_ops - struct containing callback * to south bound APIs. callbacks to call traget_if APIs + * @dp_arp_stats_register_event_handler: Callback to register + * arp stas WMI handle + * @dp_arp_stats_unregister_event_handler: Callback to unregister + * arp stas WMI handle + * @dp_get_arp_req_stats: Callback to get arp stats + * @dp_set_arp_req_stats: Callback to set arp stats + * @arp_request_ctx: ARP request context + * @dp_lro_config_cmd: Callback to send LRO config command + * @dp_send_dhcp_ind: Callback to send DHCP indication */ struct wlan_dp_psoc_sb_ops { /*TODO to add target if TX ops*/ + QDF_STATUS (*dp_arp_stats_register_event_handler)(struct wlan_objmgr_psoc *psoc); + QDF_STATUS (*dp_arp_stats_unregister_event_handler)(struct wlan_objmgr_psoc *psoc); + QDF_STATUS (*dp_get_arp_req_stats)(struct wlan_objmgr_psoc *psoc, + struct dp_get_arp_stats_params *req_buf); + QDF_STATUS (*dp_set_arp_req_stats)(struct wlan_objmgr_psoc *psoc, + struct dp_set_arp_stats_params *req_buf); + void *arp_request_ctx; + QDF_STATUS (*dp_lro_config_cmd)(struct wlan_objmgr_psoc *psoc, + struct cdp_lro_hash_config *dp_lro_cmd); + QDF_STATUS (*dp_send_dhcp_ind)(uint16_t vdev_id, + struct dp_dhcp_ind *dhcp_ind); }; /** * struct wlan_dp_psoc_nb_ops - struct containing callback * to north bound APIs. callbacks APIs to be called by target_if APIs + * @osif_dp_get_arp_stats_evt: Callback called on receiving arp stats event */ struct wlan_dp_psoc_nb_ops { /*TODO to add target if RX ops*/ + void (*osif_dp_get_arp_stats_evt)(struct wlan_objmgr_psoc *psoc, + struct dp_rsp_stats *rsp); }; /** diff --git a/components/dp/dispatcher/inc/wlan_dp_ucfg_api.h b/components/dp/dispatcher/inc/wlan_dp_ucfg_api.h index d76822b375..a7b8eb6cb7 100644 --- a/components/dp/dispatcher/inc/wlan_dp_ucfg_api.h +++ b/components/dp/dispatcher/inc/wlan_dp_ucfg_api.h @@ -402,6 +402,27 @@ void ucfg_dp_nud_event(struct qdf_mac_addr *netdev_mac_addr, struct qdf_mac_addr *gw_mac_addr, uint8_t nud_state); +/** + * ucfg_dp_get_arp_stats_event_handler - ARP get stats event handler + * + * @psoc: PSOC Handle + * @rsp : response message + * + * Return : 0 on success else error code. + */ + +QDF_STATUS ucfg_dp_get_arp_stats_event_handler(struct wlan_objmgr_psoc *psoc, + struct dp_rsp_stats *rsp); + +/** + * ucfg_dp_get_arp_request_ctx - Get ARP request context + * + * @psoc: PSOC Handle + * + * Return : ARP request context + */ +void *ucfg_dp_get_arp_request_ctx(struct wlan_objmgr_psoc *psoc); + /** * ucfg_dp_nud_reset_tracking() - reset NUD tracking * @vdev: vdev handle @@ -436,4 +457,14 @@ void ucfg_dp_nud_indicate_roam(struct wlan_objmgr_vdev *vdev); */ void ucfg_dp_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, struct wlan_dp_psoc_callbacks *cb_obj); + +/** + * ucfg_dp_register_event_handler() - Resiter event handler with DP component + * @psoc: psoc handle + * @cb_obj: Callback object + * + * Returns: None + */ +void ucfg_dp_register_event_handler(struct wlan_objmgr_psoc *psoc, + struct wlan_dp_psoc_nb_ops *cb_obj); #endif /* _WLAN_DP_UCFG_API_H_ */ diff --git a/components/dp/dispatcher/src/wlan_dp_ucfg_api.c b/components/dp/dispatcher/src/wlan_dp_ucfg_api.c index c8f0110ea8..cc33fb15d2 100644 --- a/components/dp/dispatcher/src/wlan_dp_ucfg_api.c +++ b/components/dp/dispatcher/src/wlan_dp_ucfg_api.c @@ -636,6 +636,17 @@ void ucfg_dp_nud_event(struct qdf_mac_addr *netdev_mac_addr, dp_nud_netevent_cb(netdev_mac_addr, gw_mac_addr, nud_state); } +QDF_STATUS ucfg_dp_get_arp_stats_event_handler(struct wlan_objmgr_psoc *psoc, + struct dp_rsp_stats *rsp) +{ + return dp_get_arp_stats_event_handler(psoc, rsp); +} + +void *ucfg_dp_get_arp_request_ctx(struct wlan_objmgr_psoc *psoc) +{ + return dp_get_arp_request_ctx(psoc); +} + void ucfg_dp_nud_reset_tracking(struct wlan_objmgr_vdev *vdev) { struct wlan_dp_intf *dp_intf = dp_get_vdev_priv_obj(vdev); @@ -708,3 +719,17 @@ void ucfg_dp_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, dp_ctx->dp_ops.dp_get_pause_map = cb_obj->dp_get_pause_map; dp_ctx->dp_ops.dp_nud_failure_work = cb_obj->dp_nud_failure_work; } + +void ucfg_dp_register_event_handler(struct wlan_objmgr_psoc *psoc, + struct wlan_dp_psoc_nb_ops *cb_obj) +{ + struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc); + + if (!dp_ctx) { + dp_err("DP ctx is NULL"); + return; + } + + dp_ctx->nb_ops.osif_dp_get_arp_stats_evt = + cb_obj->osif_dp_get_arp_stats_evt; +} diff --git a/components/target_if/dp/src/target_if_dp_comp.c b/components/target_if/dp/src/target_if_dp_comp.c index 0ccdfe181c..de535a806b 100644 --- a/components/target_if/dp/src/target_if_dp_comp.c +++ b/components/target_if/dp/src/target_if_dp_comp.c @@ -28,11 +28,340 @@ #include "wlan_objmgr_psoc_obj.h" #include "wlan_dp_public_struct.h" #include "cdp_txrx_cmn.h" +#include "cdp_txrx_ops.h" #include "wlan_dp_main.h" #include +/** + * target_if_dp_arp_stats_event_handler() - arp stats event handler + * @scn: scn + * @data: buffer with event + * @datalen: buffer length + * + * Return: Return: 0 on success, failure code otherwise. + */ +static int +target_if_dp_get_arp_stats_event_handler(ol_scn_t scn, uint8_t *data, + uint32_t datalen) +{ + WMI_VDEV_GET_ARP_STAT_EVENTID_param_tlvs *param_buf; + wmi_vdev_get_arp_stats_event_fixed_param *data_event; + wmi_vdev_get_connectivity_check_stats *connect_stats_event; + struct wlan_objmgr_psoc *psoc; + struct wlan_dp_psoc_nb_ops *nb_ops; + uint8_t *buf_ptr; + struct dp_rsp_stats rsp = {0}; + + if (!scn || !data) { + dp_err("scn: 0x%pK, data: 0x%pK", scn, data); + return -EINVAL; + } + param_buf = (WMI_VDEV_GET_ARP_STAT_EVENTID_param_tlvs *)data; + if (!param_buf) { + dp_err("Invalid get arp stats event"); + return -EINVAL; + } + data_event = param_buf->fixed_param; + if (!data_event) { + dp_err("Invalid get arp stats data event"); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(scn); + if (!psoc) { + dp_err("null psoc"); + return -EINVAL; + } + + nb_ops = dp_intf_get_rx_ops(psoc); + if (!nb_ops) { + dp_err("null tx ops"); + return -EINVAL; + } + + rsp.arp_req_enqueue = data_event->arp_req_enqueue; + rsp.vdev_id = data_event->vdev_id; + rsp.arp_req_tx_success = data_event->arp_req_tx_success; + rsp.arp_req_tx_failure = data_event->arp_req_tx_failure; + rsp.arp_rsp_recvd = data_event->arp_rsp_recvd; + rsp.out_of_order_arp_rsp_drop_cnt = + data_event->out_of_order_arp_rsp_drop_cnt; + rsp.dad_detected = data_event->dad_detected; + rsp.connect_status = data_event->connect_status; + rsp.ba_session_establishment_status = + data_event->ba_session_establishment_status; + + buf_ptr = (uint8_t *)data_event; + buf_ptr = buf_ptr + sizeof(wmi_vdev_get_arp_stats_event_fixed_param) + + WMI_TLV_HDR_SIZE; + connect_stats_event = (wmi_vdev_get_connectivity_check_stats *)buf_ptr; + + if (((connect_stats_event->tlv_header & 0xFFFF0000) >> 16 == + WMITLV_TAG_STRUC_wmi_vdev_get_connectivity_check_stats)) { + rsp.connect_stats_present = true; + rsp.tcp_ack_recvd = connect_stats_event->tcp_ack_recvd; + rsp.icmpv4_rsp_recvd = connect_stats_event->icmpv4_rsp_recvd; + dp_debug("tcp_ack_recvd %d icmpv4_rsp_recvd %d", + connect_stats_event->tcp_ack_recvd, + connect_stats_event->icmpv4_rsp_recvd); + } + + nb_ops->osif_dp_get_arp_stats_evt(psoc, &rsp); + + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_dp_arp_stats_register_event_handler() - register event handler + * @psoc: psoc handle + * + * Return: Return: 0 on success, failure code otherwise. + */ +static QDF_STATUS +target_if_dp_arp_stats_register_event_handler(struct wlan_objmgr_psoc *psoc) +{ + struct wmi_unified *wmi_handle; + QDF_STATUS ret_val; + + if (!psoc) { + dp_err("PSOC is NULL!"); + return QDF_STATUS_E_INVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + dp_err("wmi_handle is null"); + return QDF_STATUS_E_INVAL; + } + + ret_val = wmi_unified_register_event_handler(wmi_handle, + wmi_get_arp_stats_req_id, + target_if_dp_get_arp_stats_event_handler, + WMI_RX_WORK_CTX); + if (QDF_IS_STATUS_ERROR(ret_val)) + dp_err("Failed to register event_handler"); + + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_dp_arp_stats_unregister_event_handler() - unregister event handler + * @psoc: psoc handle + * + * Return: Return: 0 on success, failure code otherwise. + */ +static QDF_STATUS +target_if_dp_arp_stats_unregister_event_handler(struct wlan_objmgr_psoc *psoc) +{ + struct wmi_unified *wmi_handle; + + if (!psoc) { + dp_err("PSOC is NULL!"); + return QDF_STATUS_E_INVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + dp_err("wmi_handle is null"); + return QDF_STATUS_E_INVAL; + } + + wmi_unified_unregister_event_handler(wmi_handle, + wmi_get_arp_stats_req_id); + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_dp_get_arp_req_stats() - send get arp stats request command to fw + * @psoc: psoc handle + * @req_buf: get arp stats request buffer + * + * Return: Return: 0 on success, failure code otherwise. + */ +static QDF_STATUS +target_if_dp_get_arp_req_stats(struct wlan_objmgr_psoc *psoc, + struct dp_get_arp_stats_params *req_buf) +{ + QDF_STATUS status; + struct get_arp_stats *arp_stats; + struct wmi_unified *wmi_handle; + struct wlan_objmgr_vdev *vdev; + + if (!psoc) { + dp_err("PSOC is NULL!"); + return QDF_STATUS_E_INVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + dp_err("wmi_handle is null"); + return QDF_STATUS_E_INVAL; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + req_buf->vdev_id, + WLAN_DP_ID); + if (!vdev) { + dp_err("Can't get vdev by vdev_id:%d", req_buf->vdev_id); + return QDF_STATUS_E_INVAL; + } + if (!wlan_cm_is_vdev_active(vdev)) { + dp_debug("vdev id:%d is not started", req_buf->vdev_id); + status = QDF_STATUS_E_INVAL; + goto release_ref; + } + + arp_stats = (struct get_arp_stats *)req_buf; + status = wmi_unified_get_arp_stats_req(wmi_handle, arp_stats); + if (QDF_IS_STATUS_ERROR(status)) + dp_err("failed to send get arp stats to FW"); +release_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_DP_ID); + return status; +} + +/** + * target_if_dp_set_arp_req_stats() - send set arp stats request command to fw + * @psoc: psoc handle + * @req_buf: set srp stats request buffer + * + * Return: Return: 0 on success, failure code otherwise. + */ +static QDF_STATUS +target_if_dp_set_arp_req_stats(struct wlan_objmgr_psoc *psoc, + struct dp_set_arp_stats_params *req_buf) +{ + QDF_STATUS status; + struct set_arp_stats *arp_stats; + struct wmi_unified *wmi_handle; + struct wlan_objmgr_vdev *vdev; + + if (!psoc) { + dp_err("PSOC is NULL!"); + return QDF_STATUS_E_INVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + dp_err("wmi_handle is null"); + return QDF_STATUS_E_INVAL; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + req_buf->vdev_id, + WLAN_DP_ID); + if (!vdev) { + dp_err("Can't get vdev by vdev_id:%d", req_buf->vdev_id); + return QDF_STATUS_E_INVAL; + } + if (!wlan_vdev_is_up(vdev)) { + dp_debug("vdev id:%d is not started", req_buf->vdev_id); + status = QDF_STATUS_E_INVAL; + goto release_ref; + } + arp_stats = (struct set_arp_stats *)req_buf; + status = wmi_unified_set_arp_stats_req(wmi_handle, arp_stats); + if (QDF_IS_STATUS_ERROR(status)) + dp_err("failed to set arp stats to FW"); + +release_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_DP_ID); + return status; +} + +/** + * target_if_dp_lro_config_cmd() - process the LRO config command + * @psoc: Pointer to psoc handle + * @dp_lro_cmd: Pointer to LRO configuration parameters + * + * This function sends down the LRO configuration parameters to + * the firmware to enable LRO, sets the TCP flags and sets the + * seed values for the toeplitz hash generation + * + * Return: QDF_STATUS_SUCCESS for success otherwise failure + */ +static QDF_STATUS +target_if_dp_lro_config_cmd(struct wlan_objmgr_psoc *psoc, + struct cdp_lro_hash_config *dp_lro_cmd) +{ + struct wmi_lro_config_cmd_t wmi_lro_cmd = {0}; + struct wmi_unified *wmi_handle; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!dp_lro_cmd || !wmi_handle) { + dp_err("Invalid input!"); + return QDF_STATUS_E_FAILURE; + } + + wmi_lro_cmd.lro_enable = dp_lro_cmd->lro_enable; + wmi_lro_cmd.tcp_flag = dp_lro_cmd->tcp_flag; + wmi_lro_cmd.tcp_flag_mask = dp_lro_cmd->tcp_flag_mask; + qdf_mem_copy(wmi_lro_cmd.toeplitz_hash_ipv4, + dp_lro_cmd->toeplitz_hash_ipv4, + LRO_IPV4_SEED_ARR_SZ * sizeof(uint32_t)); + qdf_mem_copy(wmi_lro_cmd.toeplitz_hash_ipv6, + dp_lro_cmd->toeplitz_hash_ipv6, + LRO_IPV6_SEED_ARR_SZ * sizeof(uint32_t)); + + return wmi_unified_lro_config_cmd(wmi_handle, &wmi_lro_cmd); +} + +/** + * target_if_dp_send_dhcp_ind() - process set arp stats request command to fw + * @vdev_id: vdev id + * @dhcp_ind: DHCP indication. + * + * Return: 0 on success, failure code otherwise. + */ +static QDF_STATUS +target_if_dp_send_dhcp_ind(uint16_t vdev_id, + struct dp_dhcp_ind *dhcp_ind) +{ + struct wmi_unified *wmi_handle; + struct wlan_objmgr_psoc *psoc; + wmi_peer_set_param_cmd_fixed_param peer_set_param_fp = {0}; + + psoc = wlan_objmgr_get_psoc_by_id(0, WLAN_PSOC_TARGET_IF_ID); + if (!psoc) { + dp_err("psoc null"); + return QDF_STATUS_E_INVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + dp_err("Unable to get wmi handle"); + return QDF_STATUS_E_NULL_VALUE; + } + + /* fill in values */ + peer_set_param_fp.vdev_id = vdev_id; + peer_set_param_fp.param_id = WMI_PEER_CRIT_PROTO_HINT_ENABLED; + + if (dhcp_ind->dhcp_start) + peer_set_param_fp.param_value = 1; + else + peer_set_param_fp.param_value = 0; + + WMI_CHAR_ARRAY_TO_MAC_ADDR(dhcp_ind->peer_mac_addr.bytes, + &peer_set_param_fp.peer_macaddr); + + return wmi_unified_process_dhcp_ind(wmi_handle, + &peer_set_param_fp); +} + void target_if_dp_register_tx_ops(struct wlan_dp_psoc_sb_ops *sb_ops) { + sb_ops->dp_arp_stats_register_event_handler = + target_if_dp_arp_stats_register_event_handler; + sb_ops->dp_arp_stats_unregister_event_handler = + target_if_dp_arp_stats_unregister_event_handler; + sb_ops->dp_get_arp_req_stats = + target_if_dp_get_arp_req_stats; + sb_ops->dp_set_arp_req_stats = + target_if_dp_set_arp_req_stats; + sb_ops->dp_lro_config_cmd = target_if_dp_lro_config_cmd; + sb_ops->dp_send_dhcp_ind = + target_if_dp_send_dhcp_ind; } void target_if_dp_register_rx_ops(struct wlan_dp_psoc_nb_ops *nb_ops) diff --git a/os_if/dp/src/os_if_dp.c b/os_if/dp/src/os_if_dp.c index 666cece525..40d7a8bad0 100644 --- a/os_if/dp/src/os_if_dp.c +++ b/os_if/dp/src/os_if_dp.c @@ -30,6 +30,7 @@ #include "osif_vdev_sync.h" #include "osif_sync.h" #include +#include "wlan_osif_request_manager.h" #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH /** @@ -252,6 +253,33 @@ osif_dp_process_sap_mic_error(struct dp_mic_error_info *info, GFP_KERNEL); } +/** + * osif_dp_get_arp_stats_event_handler() - ARP get stats event handler + * @psoc: psoc handle + * @rsp: Get ARP stats response + * + * Return: None + */ +static void osif_dp_get_arp_stats_event_handler(struct wlan_objmgr_psoc *psoc, + struct dp_rsp_stats *rsp) +{ + struct osif_request *request = NULL; + void *context; + + context = ucfg_dp_get_arp_request_ctx(psoc); + if (!context) + return; + + request = osif_request_get(context); + if (!request) + return; + + ucfg_dp_get_arp_stats_event_handler(psoc, rsp); + + osif_request_complete(request); + osif_request_put(request); +} + #ifdef WLAN_NUD_TRACKING /** * nud_state_osif_to_dp() - convert os_if to enum @@ -389,6 +417,23 @@ void osif_dp_nud_unregister_netevent_notifier(struct wlan_objmgr_psoc *psoc) { } #endif + +/** + * os_if_dp_register_event_handler() - Register osif event handler + * @psoc: psoc handle + * + * Return: None + */ +static void os_if_dp_register_event_handler(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_dp_psoc_nb_ops cb_obj = {0}; + + cb_obj.osif_dp_get_arp_stats_evt = + osif_dp_get_arp_stats_event_handler; + + ucfg_dp_register_event_handler(psoc, &cb_obj); +} + void os_if_dp_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, struct wlan_dp_psoc_callbacks *cb_obj) { @@ -399,4 +444,5 @@ void os_if_dp_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, cb_obj->osif_dp_process_sap_mic_error = osif_dp_process_sap_mic_error; ucfg_dp_register_hdd_callbacks(psoc, cb_obj); + os_if_dp_register_event_handler(psoc); }