Эх сурвалжийг харах

qcacmn: Add support for TCP delayed ack in driver

qcacld-2.0 to qcacmn propagation

This change adds support for driver supported TCP
delayed ack to increase TCP RX performance in
third-party platform which don't support kernel
TCP delayed ack feature.

TCP delayed ack is dependent on count and timer
values. Whatever is achieved first will trigger
sending TCP ack.

This feature can be controlled through ini values.
gDriverDelAckTimerValue - timer value in ms
gDriverDelAckPktCount - delayed ack count
gDriverDelAckEnable - enable/disable feature

Change-Id: I8105bbb90965295b5a4aefeb00d344a90155974d
CRs-fixed: 2414231
Tiger Yu 6 жил өмнө
parent
commit
6f1fc0070f

+ 51 - 0
dp/inc/cdp_txrx_misc.h

@@ -620,4 +620,55 @@ static inline void cdp_deregister_packetdump_cb(ol_txrx_soc_handle soc)
 	if (soc->ops->misc_ops->unregister_pktdump_cb)
 		return soc->ops->misc_ops->unregister_pktdump_cb();
 }
+
+/**
+ * cdp_pdev_reset_driver_del_ack() - reset driver TCP delayed ack flag
+ * @soc - data path soc handle
+ * @pdev - data path device instance
+ *
+ * Return: none
+ */
+static inline void cdp_pdev_reset_driver_del_ack(void *psoc,
+						 struct cdp_pdev *pdev)
+{
+	ol_txrx_soc_handle soc = psoc;
+
+	if (!soc || !soc->ops || !soc->ops->misc_ops) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
+			  "%s invalid instance", __func__);
+		return;
+	}
+
+	if (soc->ops->misc_ops->pdev_reset_driver_del_ack)
+		return soc->ops->misc_ops->pdev_reset_driver_del_ack(pdev);
+}
+
+/*
+ * cdp_vdev_set_driver_del_ack_enable() - set driver delayed ack enabled flag
+ * @soc - data path soc handle
+ * @vdev_id: vdev id
+ * @rx_packets: number of rx packets
+ * @time_in_ms: time in ms
+ * @high_th: high threshold
+ * @low_th: low threshold
+ *
+ * Return: none
+ */
+static inline void cdp_vdev_set_driver_del_ack_enable(ol_txrx_soc_handle soc,
+						      uint8_t vdev_id,
+						      unsigned long rx_packets,
+						      uint32_t time_in_ms,
+						      uint32_t high_th,
+						      uint32_t low_th)
+{
+	if (!soc || !soc->ops || !soc->ops->misc_ops) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
+			  "%s invalid instance", __func__);
+		return;
+	}
+
+	if (soc->ops->misc_ops->vdev_set_driver_del_ack_enable)
+		return soc->ops->misc_ops->vdev_set_driver_del_ack_enable(
+			vdev_id, rx_packets, time_in_ms, high_th, low_th);
+}
 #endif /* _CDP_TXRX_MISC_H_ */

+ 9 - 0
dp/inc/cdp_txrx_mob_def.h

@@ -291,6 +291,15 @@ struct txrx_pdev_cfg_param_t {
 	/* Start queue offset in percentage */
 	uint32_t tx_flow_start_queue_offset;
 
+#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK
+	/* enable the tcp delay ack feature in the driver */
+	bool  del_ack_enable;
+	/* timeout if no more tcp ack frames, unit is ms */
+	uint16_t del_ack_timer_value;
+	/* the maximum number of replaced tcp ack frames */
+	uint16_t del_ack_pkt_count;
+#endif
+
 	struct ol_tx_sched_wrr_ac_specs_t ac_specs[TX_WMM_AC_NUM];
 	bool gro_enable;
 	bool tso_enable;

+ 8 - 0
dp/inc/cdp_txrx_ops.h

@@ -986,6 +986,8 @@ struct ol_if_ops {
  * @runtime_resume:
  * @register_packetdump_cb:
  * @unregister_packetdump_cb:
+ * @pdev_reset_driver_del_ack:
+ * @vdev_set_driver_del_ack_enable:
  */
 struct cdp_misc_ops {
 	uint16_t (*set_ibss_vdev_heart_beat_timer)(struct cdp_vdev *vdev,
@@ -1023,6 +1025,12 @@ struct cdp_misc_ops {
 	void (*register_pktdump_cb)(ol_txrx_pktdump_cb tx_cb,
 				    ol_txrx_pktdump_cb rx_cb);
 	void (*unregister_pktdump_cb)(void);
+	void (*pdev_reset_driver_del_ack)(struct cdp_pdev *ppdev);
+	void (*vdev_set_driver_del_ack_enable)(uint8_t vdev_id,
+					       unsigned long rx_packets,
+					       uint32_t time_in_ms,
+					       uint32_t high_th,
+					       uint32_t low_th);
 };
 
 /**

+ 8 - 0
qdf/inc/qdf_nbuf.h

@@ -44,6 +44,7 @@
 #define QDF_NBUF_PKT_ERROR			1
 
 #define QDF_NBUF_TRAC_IPV4_OFFSET		14
+#define QDF_NBUF_TRAC_IPV4_HEADER_MASK		0xF
 #define QDF_NBUF_TRAC_IPV4_HEADER_SIZE		20
 #define QDF_NBUF_TRAC_DHCP_SRV_PORT		67
 #define QDF_NBUF_TRAC_DHCP_CLI_PORT		68
@@ -60,6 +61,7 @@
 #define QDF_NBUF_SRC_MAC_OFFSET			6
 #define QDF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET  23
 #define QDF_NBUF_TRAC_IPV4_DEST_ADDR_OFFSET   30
+#define QDF_NBUF_TRAC_IPV4_SRC_ADDR_OFFSET    26
 #define QDF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET  20
 #define QDF_NBUF_TRAC_IPV4_ADDR_MCAST_MASK    0xE0000000
 #define QDF_NBUF_TRAC_IPV4_ADDR_BCAST_MASK    0xF0000000
@@ -69,6 +71,12 @@
 #define QDF_NBUF_TRAC_IPV6_HEADER_SIZE   40
 #define QDF_NBUF_TRAC_ICMP_TYPE         1
 #define QDF_NBUF_TRAC_TCP_TYPE          6
+#define QDF_NBUF_TRAC_TCP_FLAGS_OFFSET       (47 - 34)
+#define QDF_NBUF_TRAC_TCP_ACK_OFFSET         (42 - 34)
+#define QDF_NBUF_TRAC_TCP_HEADER_LEN_OFFSET  (46 - 34)
+#define QDF_NBUF_TRAC_TCP_ACK_MASK           0x10
+#define QDF_NBUF_TRAC_TCP_SPORT_OFFSET       (34 - 34)
+#define QDF_NBUF_TRAC_TCP_DPORT_OFFSET       (36 - 34)
 #define QDF_NBUF_TRAC_UDP_TYPE          17
 #define QDF_NBUF_TRAC_ICMPV6_TYPE       0x3a
 #define QDF_NBUF_TRAC_DHCP6_SRV_PORT		547

+ 22 - 5
qdf/linux/src/i_qdf_hrtimer.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -39,6 +39,20 @@ typedef struct {
 	enum qdf_context_mode ctx;
 } __qdf_hrtimer_data_t;
 
+/**
+ * __qdf_hrtimer_get_mode() - Get hrtimer_mode with qdf mode
+ * @mode: mode of hrtimer
+ *
+ * Get hrtimer_mode with qdf hrtimer mode
+ *
+ * Return: void
+ */
+static inline
+enum hrtimer_mode __qdf_hrtimer_get_mode(enum qdf_hrtimer_mode mode)
+{
+	return (enum hrtimer_mode)mode;
+}
+
 /**
  * __qdf_hrtimer_start() - Starts hrtimer in given context
  * @timer: pointer to the hrtimer object
@@ -53,11 +67,13 @@ static inline
 void __qdf_hrtimer_start(__qdf_hrtimer_data_t *timer, ktime_t interval,
 			 enum qdf_hrtimer_mode mode)
 {
+	enum hrtimer_mode hrt_mode = __qdf_hrtimer_get_mode(mode);
+
 	if (timer->ctx == QDF_CONTEXT_HARDWARE)
-		hrtimer_start(&timer->u.hrtimer, interval, mode);
+		hrtimer_start(&timer->u.hrtimer, interval, hrt_mode);
 	else if (timer->ctx == QDF_CONTEXT_TASKLET)
 		tasklet_hrtimer_start(&timer->u.tasklet_hrtimer,
-				      interval, mode);
+				      interval, hrt_mode);
 }
 
 /**
@@ -98,14 +114,15 @@ static inline void  __qdf_hrtimer_init(__qdf_hrtimer_data_t *timer,
 {
 	struct hrtimer *hrtimer = &timer->u.hrtimer;
 	struct tasklet_hrtimer *tasklet_hrtimer = &timer->u.tasklet_hrtimer;
+	enum hrtimer_mode hrt_mode = __qdf_hrtimer_get_mode(mode);
 
 	timer->ctx = ctx;
 
 	if (timer->ctx == QDF_CONTEXT_HARDWARE) {
-		hrtimer_init(hrtimer, clock, mode);
+		hrtimer_init(hrtimer, clock, hrt_mode);
 		hrtimer->function = cback;
 	} else if (timer->ctx == QDF_CONTEXT_TASKLET) {
-		tasklet_hrtimer_init(tasklet_hrtimer, cback, clock, mode);
+		tasklet_hrtimer_init(tasklet_hrtimer, cback, clock, hrt_mode);
 	}
 }