Merge "[qca-nss-drv] Added statistics for worker threads."
diff --git a/Makefile b/Makefile
index 0475975..4cab556 100644
--- a/Makefile
+++ b/Makefile
@@ -54,6 +54,7 @@
nss_tunipip6.o \
nss_virt_if.o \
nss_vlan.o \
+ nss_tstamp.o \
nss_wifi.o \
nss_wifi_vdev.o \
nss_wifi_if.o \
diff --git a/exports/nss_api_if.h b/exports/nss_api_if.h
index 10260ac..d23e18c 100644
--- a/exports/nss_api_if.h
+++ b/exports/nss_api_if.h
@@ -206,6 +206,24 @@
/**< Special interface number for project node. */
/**
+ * Wireless Multimedia Extention Access Category to TID.
+ */
+#define NSS_WIFILI_WME_AC_TO_TID(_ac) ( \
+ ((_ac) == NSS_WIFILI_WME_AC_VO) ? 6 : \
+ (((_ac) == NSS_WIFILI_WME_AC_VI) ? 5 : \
+ (((_ac) == NSS_WIFILI_WME_AC_BK) ? 1 : \
+ 0)))
+
+/**
+ * Wireless TID to Wireless Extension Multimedia Access Category.
+ */
+#define NSS_WIFILI_TID_TO_WME_AC(_tid) ( \
+ (((_tid) == 0) || ((_tid) == 3)) ? NSS_WIFILI_WME_AC_BE : \
+ ((((_tid) == 1) || ((_tid) == 2)) ? NSS_WIFILI_WME_AC_BK : \
+ ((((_tid) == 4) || ((_tid) == 5)) ? NSS_WIFILI_WME_AC_VI : \
+ NSS_WIFILI_WME_AC_VO)))
+
+/**
* Converts the format of an IPv6 address from Linux to NSS. @hideinitializer
*/
#define IN6_ADDR_TO_IPV6_ADDR(ipv6, in6) \
diff --git a/exports/nss_cmn.h b/exports/nss_cmn.h
index ed464b5..cb078a0 100644
--- a/exports/nss_cmn.h
+++ b/exports/nss_cmn.h
@@ -252,7 +252,7 @@
* @return
* TRUE if the number is a virtual interface. Otherwise FALSE.
*/
-extern bool nss_cmn_interface_is_virtual(void *nss_ctx, int32_t interface_num);
+extern bool nss_cmn_interface_is_virtual(struct nss_ctx_instance *nss_ctx, int32_t interface_num);
/**
* nss_cmn_get_interface_dev
diff --git a/exports/nss_dynamic_interface.h b/exports/nss_dynamic_interface.h
index 7441a06..fc1e940 100644
--- a/exports/nss_dynamic_interface.h
+++ b/exports/nss_dynamic_interface.h
@@ -111,20 +111,6 @@
};
/**
- * nss_dynamic_interface_pvt
- * Private data information for the dynamic interface.
- */
-struct nss_dynamic_interface_pvt {
- struct semaphore sem; /**< Semaphore for sending one message at a time. */
- struct completion complete; /**< Blocks the thread until an acknowledgment is received. */
- int current_if_num; /**< Current interface number. */
- enum nss_cmn_response response;
- /**< Holds the return message from NSS firmware. */
- nss_dynamic_interface_assigned type[NSS_MAX_DYNAMIC_INTERFACES];
- /**< Array of assigned interface types. */
-};
-
-/**
* nss_dynamic_interface_alloc_node
* Allocates a node for a dynamic interface.
*
@@ -170,12 +156,13 @@
* nss_dynamic_interface_get_type
* Returns the type of dynamic interface.
*
- * @param[in] if_num Dynamic interface number.
+ * @param[in] nss_ctx Pointer to the NSS context.
+ * @param[in] if_num Interface number of dynamic interface.
*
* @return
* Type of dynamic interface per the dynamic interface number.
*/
-extern enum nss_dynamic_interface_type nss_dynamic_interface_get_type(int if_num);
+extern enum nss_dynamic_interface_type nss_dynamic_interface_get_type(struct nss_ctx_instance *nss_ctx, int if_num);
/**
* nss_dynamic_interface_tx
diff --git a/exports/nss_edma.h b/exports/nss_edma.h
index b1129d2..d21b3e6 100644
--- a/exports/nss_edma.h
+++ b/exports/nss_edma.h
@@ -144,13 +144,14 @@
struct nss_edma_misc_err_stats {
uint32_t axi_rd_err; /**< EDMA AXI read error. */
uint32_t axi_wr_err; /**< EDMA AXI write error. */
- uint32_t rx_desc_fifo_full_err; /**< EDMA Receive descriptor FIFO full error. */
- uint32_t rx_buf_size_err; /**< EDMA Receive buffer size error. */
- uint32_t tx_sram_full_err; /**< EDMA Transmit SRAM full error. */
- uint32_t tx_cmpl_buf_full_err; /**< EDMA Transmit completion buffer full error. */
+ uint32_t rx_desc_fifo_full_err; /**< EDMA receive descriptor FIFO full error. */
+ uint32_t rx_buf_size_err; /**< EDMA receive buffer size error. */
+ uint32_t tx_sram_full_err; /**< EDMA transmit SRAM full error. */
+ uint32_t tx_cmpl_buf_full_err; /**< EDMA transmit completion buffer full error. */
uint32_t pkt_len_la64k_err; /**< EDMA packet length greater than 64k error. */
uint32_t pkt_len_le33_err; /**< EDMA packet length smaller than 33b error. */
uint32_t data_len_err; /**< EDMA data length error. */
+ uint32_t alloc_fail_cnt; /**< EDMA number of times the allocation of pbuf for statistics failed. */
};
/**
diff --git a/exports/nss_ipv4.h b/exports/nss_ipv4.h
index d135bbd..c05db64 100644
--- a/exports/nss_ipv4.h
+++ b/exports/nss_ipv4.h
@@ -43,6 +43,7 @@
NSS_IPV4_TX_CREATE_MC_RULE_MSG,
NSS_IPV4_TX_CONN_STATS_SYNC_MANY_MSG,
NSS_IPV4_TX_ACCEL_MODE_CFG_MSG,
+ NSS_IPV4_TX_CONN_CFG_INQUIRY_MSG,
NSS_IPV4_MAX_MSG_TYPES,
};
@@ -335,6 +336,17 @@
};
/**
+ * nss_ipv4__inquiry_msg
+ * IPv4 connection inquiry naming structure.
+ */
+struct nss_ipv4_inquiry_msg {
+ /*
+ * Request by its 5 tuple and get Response for other items.
+ */
+ struct nss_ipv4_rule_create_msg rr;
+};
+
+/**
* nss_ipv4_mc_if_rule
* IPv4 multicast rule for creating per-interface information.
*/
@@ -677,6 +689,8 @@
/**< Synchronize multiple connection statistics. */
struct nss_ipv4_accel_mode_cfg_msg accel_mode_cfg;
/**< Acceleration mode. */
+ struct nss_ipv4_inquiry_msg inquiry;
+ /**< Inquiry if a connection has created. */
} msg; /**< Message payload. */
};
diff --git a/exports/nss_ipv6.h b/exports/nss_ipv6.h
index 49aaf4f..2d2566f 100644
--- a/exports/nss_ipv6.h
+++ b/exports/nss_ipv6.h
@@ -43,6 +43,7 @@
NSS_IPV6_TX_CREATE_MC_RULE_MSG,
NSS_IPV6_TX_CONN_STATS_SYNC_MANY_MSG,
NSS_IPV6_TX_ACCEL_MODE_CFG_MSG,
+ NSS_IPV6_TX_CONN_CFG_INQUIRY_MSG,
NSS_IPV6_MAX_MSG_TYPES,
};
@@ -398,6 +399,17 @@
};
/**
+ * nss_ipv6_inquiry_msg
+ * IPv6 connection inquiry sub-messages.
+ */
+struct nss_ipv6_inquiry_msg {
+ /*
+ * Request by 5 tuple, and Response in other items.
+ */
+ struct nss_ipv6_rule_create_msg rr;
+};
+
+/**
* nss_ipv6_mc_if_rule
* IPv6 multicast rule for creating a per-interface payload.
*/
@@ -642,6 +654,8 @@
/**< Synchronize multiple connection statistics. */
struct nss_ipv6_accel_mode_cfg_msg accel_mode_cfg;
/**< Configure acceleration mode. */
+ struct nss_ipv6_inquiry_msg inquiry;
+ /**< Inquiry if a connection has been created. */
} msg; /**< Message payload. */
};
diff --git a/exports/nss_n2h.h b/exports/nss_n2h.h
index 8ebcd07..4ea418b 100644
--- a/exports/nss_n2h.h
+++ b/exports/nss_n2h.h
@@ -29,6 +29,10 @@
#define MAX_PAGES_PER_MSG 32 /**< Maximum number of pages per message. */
+#define NSS_MAX_NUM_PRI 4 /**< Maximum number of pnode ingress priorities. */
+#define NSS_DEFAULT_NUM_PRI 1 /**< Default priority. */
+#define NSS_DEFAULT_QUEUE_LIMIT 256 /**< Default pnode queue limit. */
+
/**
* nss_n2h_cfg_pvt
* N2H private data configuration.
@@ -60,6 +64,7 @@
NSS_TX_METADATA_TYPE_GET_PAYLOAD_INFO,
NSS_TX_METADATA_TYPE_N2H_WIFI_POOL_BUF_CFG,
NSS_TX_DDR_INFO_VIA_N2H_CFG,
+ NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG,
NSS_METADATA_TYPE_N2H_MAX,
};
@@ -110,6 +115,21 @@
};
/**
+ * nss_n2h_pnode_queue_config
+ * N2H pnode queue configuration.
+ */
+struct nss_n2h_pnode_queue_config {
+ uint8_t num_pri; /**< Maximum number of priorities. */
+ uint8_t mq_en; /**< Enable multiple queues. */
+ uint16_t reserved1; /**< Reserved for alignment. */
+ uint16_t qlimits[NSS_MAX_NUM_PRI];
+ /**< Limits of each queue. */
+#if (NSS_MAX_NUM_PRI & 1)
+ uint16_t reserved2;
+#endif
+};
+
+/**
* nss_n2h_empty_pool_buf
* Old way of setting the number of empty pool buffers (payloads).
*
@@ -265,6 +285,8 @@
/**< Sets the number of Wi-Fi payloads. */
struct nss_mmu_ddr_info mmu;
/**< Gets the DDR size and start address to configure the MMU. */
+ struct nss_n2h_pnode_queue_config pn_q_cfg;
+ /**< Pnode queueing configuration. */
} msg; /**< Message payload. */
};
@@ -352,9 +374,21 @@
nss_n2h_msg_callback_t cb, void *app_data);
/**
+ * nss_n2h_update_queue_config
+ * Update pnode queue configuration to NSS.
+ *
+ * @param[in] max_pri Maximum number of ingress priorities.
+ * @param[in] mq_en Enable multiple pnode queues.
+ * @param[in] pri_num Number of ingress priorities.
+ * @param[in] qlimits Maximum number of packets in each queues.
+ *
+ * @return
+ * Status of the configuration update operation.
+ */
+extern nss_tx_status_t nss_n2h_update_queue_config(int max_pri, bool mq_en, int pri_num, int *qlimits);
+
+/**
* @}
*/
#endif /* __NSS_N2H_H */
-
-
diff --git a/exports/nss_ppe.h b/exports/nss_ppe.h
index 1d1258b..d9f534b 100644
--- a/exports/nss_ppe.h
+++ b/exports/nss_ppe.h
@@ -39,6 +39,7 @@
*/
enum nss_ppe_metadata_types {
NSS_PPE_MSG_SYNC_STATS,
+ NSS_PPE_MSG_L2_EXCEPTION,
NSS_PPE_MSG_MAX,
};
@@ -108,6 +109,14 @@
/**< Request failed because the flow QoS group is full. */
};
+/*
+ * nss_ppe_l2_exception_msg
+ * Message structure for L2 exception.
+ */
+struct nss_ppe_l2_exception_msg {
+ uint32_t l2_exception_enable; /**< Enable/Disable L2 exception */
+};
+
/**
* nss_ppe_msg
* Data for sending and receiving PPE host-to-NSS messages.
@@ -121,10 +130,23 @@
union {
struct nss_ppe_sync_stats_msg stats;
/**< Synchronization statistics. */
+ struct nss_ppe_l2_exception_msg l2_exception;
+ /**< L2 exception message. */
} msg; /**< Message payload. */
};
/**
+ * Callback function for receiving PPE messages.
+ *
+ * @datatypes
+ * nss_ppe_msg
+ *
+ * @param[in] app_data Pointer to the application context of the message.
+ * @param[in] msg Pointer to the message data.
+ */
+typedef void (*nss_ppe_msg_callback_t)(void *app_data, struct nss_ppe_msg *msg);
+
+/**
* nss_ppe_register_handler
* Registers the PPE interface with NSS.
*
@@ -134,6 +156,78 @@
extern void nss_ppe_register_handler(void);
/**
+ * nss_ppe_tx_msg
+ * Sends PPE messages to the NSS.
+ *
+ * @datatypes
+ * nss_ctx_instance \n
+ * nss_ppe_msg
+ *
+ * @param[in] nss_ctx Pointer to the NSS context.
+ * @param[in] msg Pointer to the message data.
+ *
+ * @return
+ * Status of the Tx operation.
+ */
+nss_tx_status_t nss_ppe_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *msg);
+
+/**
+ * nss_ppe_tx_msg_sync
+ * Sends PPE messages synchronously to the NSS.
+ *
+ * @datatypes
+ * nss_ctx_instance \n
+ * nss_ppe_msg
+ *
+ * @param[in] nss_ctx Pointer to the NSS context.
+ * @param[in,out] msg Pointer to the message data.
+ *
+ * @return
+ * Status of the Tx operation.
+ */
+nss_tx_status_t nss_ppe_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *msg);
+
+/**
+ * nss_ppe_msg_init
+ * Initializes a PPE message.
+ *
+ * @datatypes
+ * nss_ppe_msg
+ *
+ * @param[in,out] ncm Pointer to the message.
+ * @param[in] if_num Interface number
+ * @param[in] type Type of message.
+ * @param[in] len Size of the payload.
+ * @param[in] cb Callback function for the message.
+ * @param[in] app_data Pointer to the application context of the message.
+ *
+ * @return
+ * None.
+ */
+void nss_ppe_msg_init(struct nss_ppe_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data);
+
+/**
+ * nss_ppe_get_context
+ * Gets the PPE context used in nss_ppe_tx.
+ *
+ * @return
+ * Pointer to the NSS core context.
+ */
+struct nss_ctx_instance *nss_ppe_get_context(void);
+
+/**
+ * nss_ppe_tx_l2_exception_msg
+ * Sends the PPE a message to enable/disable L2 exceptions.
+ *
+ * @param[in] if_num Interface number of the PPE.
+ * @param[in] exception_enable Enable/disable flag.
+ *
+ * @return
+ * Status of the Tx operation.
+ */
+nss_tx_status_t nss_ppe_tx_l2_exception_msg(uint32_t if_num, bool exception_enable);
+
+/**
* nss_ppe_stats_conn_get
* Gets PPE connection statistics.
*
diff --git a/exports/nss_tstamp.h b/exports/nss_tstamp.h
new file mode 100644
index 0000000..001a1b7
--- /dev/null
+++ b/exports/nss_tstamp.h
@@ -0,0 +1,55 @@
+
+/*
+ **************************************************************************
+ * Copyright (c) 2017, 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
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/**
+ * @file nss_tstamp.h
+ * NSS to HLOS Tstamp interface definitions.
+ */
+
+#ifndef __NSS_TSTAMP_H
+#define __NSS_TSTAMP_H
+
+/**
+ * @brief Metadata added by the tstamp HLOS driver
+ * while sending the packet to NSS tstamp module.
+ */
+struct nss_tstamp_h2n_pre_hdr {
+ uint32_t ts_ifnum; /**< Time stamp interface number. */
+ uint32_t ts_tx_hdr_sz; /**< Total header size. */
+};
+
+/**
+ * @brief Metadata added by the NSS tstamp module before sending
+ * the packet to host.
+ */
+struct nss_tstamp_n2h_pre_hdr {
+ uint32_t ts_ifnum; /**< Time stamp interface number. */
+ uint32_t ts_data_lo; /**< Time stamp lower order bits. */
+ uint32_t ts_data_hi; /**< Time stamp higher order bits. */
+
+ uint32_t ts_tx; /**< Time stamp direction. */
+ uint32_t ts_hdr_sz; /**< Size of the header including the skb data alignment padding. */
+};
+
+/**
+ * @brief transfer the packet to Tstamp NSS module
+ *
+ * @return nss_tx_status
+ */
+nss_tx_status_t nss_tstamp_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *skb, uint32_t if_num);
+
+#endif /* __NSS_TSTAMP_H */
diff --git a/exports/nss_wifi_vdev.h b/exports/nss_wifi_vdev.h
index 035afb8..b62d850 100644
--- a/exports/nss_wifi_vdev.h
+++ b/exports/nss_wifi_vdev.h
@@ -398,6 +398,8 @@
struct nss_wifi_vdev_mesh_per_packet_metadata {
uint32_t status; /**< Meshmode Status. */
uint32_t rssi; /**< RSSI. */
+ uint32_t tsf; /**< Tx expiry time. */
+ uint16_t tx_retries; /**< Retry count. */
};
/**
@@ -549,8 +551,14 @@
* Metadata payload for Mesh mode receive.
*/
struct nss_wifi_vdev_meshmode_rx_metadata {
+ uint16_t rs_ratephy; /**< PHY rate. */
uint16_t vdev_id; /**< Virtual device ID. */
uint16_t peer_id; /**< Peer ID. */
+ uint16_t rs_rssi; /**< RSSI (noise floor adjusted). */
+ uint8_t rs_flags; /**< First/last MSDU flags. */
+ uint8_t rs_channel; /**< Operational channel. */
+ uint8_t rs_keyix; /**< Key index. */
+ uint8_t padd; /**< Padding to ensure alignment. */
};
/**
diff --git a/exports/nss_wifili_if.h b/exports/nss_wifili_if.h
index 0bba091..331f84e 100644
--- a/exports/nss_wifili_if.h
+++ b/exports/nss_wifili_if.h
@@ -17,33 +17,80 @@
/**
* @file nss_wifili.h
* NSS TO HLOS interface definitions.
+ * NOTE: Here we will use wifili as a reference to
+ * the IPQ807x Wi-Fi object.
*/
#ifndef __NSS_WIFILI_H
#define __NSS_WIFILI_H
#define NSS_WIFILI_MAX_SRNG_REG_GROUPS_MSG 2
- /**< Max srng register groups. */
+ /**< Maximum srng (ring) register groups. */
#define NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG 32
- /**< Max number of pages allocated from host. */
+ /**< Maximum number of pages allocated from host. */
#define NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG 4
- /**< Max number of tcl data ring for NSS. */
+ /**< Maximum number of Transmit Classifier data ring for NSS. */
#define NSS_WIFILI_MAX_REO_DATA_RINGS_MSG 4
- /**< Max number of reo data ring for NSS. */
+ /**< Maximum number of Reorder (reo) data ring for NSS. */
#define NSS_WIFILI_SOC_PER_PACKET_METADATA_OFFSET 4
- /**< Metadata area for storing rx stats. */
+ /**< Metadata area for storing Rx statistics. */
#define NSS_WIFILI_MAX_TXDESC_POOLS_MSG 4
- /**< Max number of txdesc sw pools */
+ /**< Maximum number of Tx Descriptor software pools. */
#define NSS_WIFILI_MAX_TX_EXT_DESC_POOLS_MSG 4
- /**< Max number of txdesc ext sw pools */
+ /**< Maximum number of Tx Descriptor Extended software pools. */
#define NSS_WIFILI_MAX_PDEV_NUM_MSG 3
- /**< Max number of pdev devices*/
+ /**< Maximum number of pdev devices. */
+#define NSS_WIFILI_MAX_MCS 12
+ /**< Maximum Modulaton And Coding Scheme (MCS) count. */
+#define NSS_WIFILI_MAX_MCS_11A 8
+ /**< Maximum MCS for 11a mode. */
+#define NSS_WIFILI_MAX_MCS_11B 7
+ /**< Maximum MCS for 11b mode. */
+#define NSS_WIFILI_MAX_MCS_11AC 10
+ /**< Maximum MCS for 11ac mode. */
+#define NSS_WIFILI_MAX_MCS_11AX 10
+ /**< Maximum MCS for 11ax mode. */
+#define NSS_WIFILI_SS_COUNT 8
+ /**< Maximum spatial streams count. */
+#define NSS_WIFILI_SUPPORTED_BW 4
+ /**< Maximum number of bandwidth supported. */
+#define NSS_WIFILI_REPT_MU_MIMO 1
+#define NSS_WIFILI_REPT_MU_OFDMA_MIMO 3
+#define NSS_WIFILI_SUPPORTED_RECEPTION_TYPES 4
+ /**< Maximum supported reception types. */
+#define NSS_WIFILI_SOC_PER_PACKET_METADATA_SIZE 60
+ /**< Metadata area total size. */
+
+/**
+ * nss_wifili_wme_stream_classes
+ * WME stream classes.
+ */
+enum nss_wifili_wme_stream_classes {
+ NSS_WIFILI_WME_AC_BE, /**< Best effort. */
+ NSS_WIFILI_WME_AC_BK, /**< Background. */
+ NSS_WIFILI_WME_AC_VI, /**< Video. */
+ NSS_WIFILI_WME_AC_VO, /**< Voice. */
+ NSS_WIFILI_WME_AC_MAX /**< Maximum AC Value. */
+};
+
+/**
+ * nss_wifili_packet_type
+ * Different Packet Types.
+ */
+enum nss_wifili_packet_type {
+ NSS_WIFILI_DOT11_A, /**< 802.11a packet type. */
+ NSS_WIFILI_DOT11_B, /**< 802.11b packet type. */
+ NSS_WIFILI_DOT11_N, /**< 802.11n packet type. */
+ NSS_WIFILI_DOT11_AC, /**< 802.11ac packet type. */
+ NSS_WIFILI_DOT11_AX , /**< 802.11ax packet type. */
+ NSS_WIFILI_DOT11_MAX /**< Maximum 802.11 packet types. */
+};
/**
* nss_wifili_msg_types
- * nss_wifili messages
+ * NSS wifili messages.
*/
enum nss_wifili_msg_types {
- NSS_WIFILI_INIT_MSG = 0,
+ NSS_WIFILI_INIT_MSG,
NSS_WIFILI_SOC_RESET_MSG,
NSS_WIFILI_PDEV_INIT_MSG,
NSS_WIFILI_PDEV_DEINIT_MSG,
@@ -55,454 +102,569 @@
NSS_WIFILI_PEER_FREELIST_APPEND_MSG,
NSS_WIFILI_STATS_MSG,
NSS_WIFILI_WDS_VENDOR_MSG,
+ NSS_WIFILI_PEER_STATS_MSG,
NSS_WIFILI_MAX_MSG
};
/**
- * wifili_error_types
- * wifili msg error types
+ * nss_wifili_error_types
+ * Wifili error message types for functions.
*/
-enum wifili_error_types {
- NSS_WIFILI_EMSG_NONE = 0,
- /**< no error */
+enum nss_wifili_error_types {
+ NSS_WIFILI_EMSG_NONE,
+ /**< No error. */
NSS_WIFILI_EMSG_RINGS_INIT_FAIL,
- /**< device ring initialization fail */
+ /**< Device ring initialization failure. */
NSS_WIFILI_EMSG_PDEV_INIT_IMPROPER_STATE_FAIL,
- /**< radio init fail due to improper state of device */
+ /**< Radio initialization failure due to improper state of device. */
NSS_WIFILI_EMSG_PDEV_INIT_INVALID_RADIOID_FAIL,
- /**< radio init failed due to invalid radio id */
+ /**< Radio initialization failed due to invalid radio ID. */
NSS_WIFILI_EMSG_PDEV_RESET_INVALID_RADIOID_FAIL,
- /**< radio reset failed due to invalid radio id */
+ /**< Radio reset failed due to invalid radio ID. */
NSS_WIFILI_EMSG_START_IMPROPER_STATE_FAIL,
- /**< device start fail due to improper state */
+ /**< Device start failure due to improper state. */
NSS_WIFILI_EMSG_PEER_CREATE_FAIL,
- /**< peed creat fail */
+ /**< Peer creation failure. */
NSS_WIFILI_EMSG_PEER_DELETE_FAIL,
- /**< peer delete fail */
+ /**< Peer delete failure. */
NSS_WIFILI_EMSG_HASHMEM_INIT_FAIL,
- /**< peer hash mem init fail */
+ /**< Peer hash memory initialization failure. */
NSS_WIFILI_EMSG_PEER_FREELIST_APPEND_FAIL,
- /**< peer freelist append fail*/
+ /**< Peer freelist append failure. */
NSS_WIFILI_EMSG_PEER_CREATE_INVALID_VDEVID_FAIL,
- /**< peer create fail due to invalide vdev_id */
+ /**< Peer creation failure due to invalid vdev ID. */
NSS_WIFILI_EMSG_PEER_CREATE_INVALID_PEER_ID_FAIL,
- /**< peer create fail due to invalide peer_id */
+ /**< Peer creation failure due to invalid peer ID. */
NSS_WIFILI_EMSG_PEER_CREATE_VDEV_NULL_FAIL,
- /**< peer create fail due to vdev null */
+ /**< Peer creation failure due to null vdev. */
NSS_WIFILI_EMSG_PEER_CREATE_PDEV_NULL_FAIL,
- /**< peer create fail due to peer null */
+ /**< Peer creation failure due to null peer. */
NSS_WIFILI_EMSG_PEER_CREATE_ALLOC_FAIL,
- /**< peer create fail due to mem alloc fail */
+ /**< Peer creation failure due to memory allocation failure. */
NSS_WIFILI_EMSG_PEER_DELETE_VAPID_INVALID_FAIL,
- /**< peer delete fail due to invalide vdev_id */
+ /**< Peer delete failure due to invalid vdev_ID. */
NSS_WIFILI_EMSG_PEER_DELETE_INVALID_PEERID_FAIL,
- /**< peer delete fail due to invalide peer_id */
+ /**< Peer delete failure due to invalid peer ID. */
NSS_WIFILI_EMSG_PEER_DELETE_VDEV_NULL_FAIL,
- /**< peer delete fail due to vdev null */
+ /**< Peer delete failure due to null vdev. */
NSS_WIFILI_EMSG_PEER_DELETE_PDEV_NULL_FAIL,
- /**< peer create fail due to pdev null */
+ /**< Peer creation failure due to null vdev. */
NSS_WIFILI_EMSG_PEER_DELETE_PEER_NULL_FAIL,
- /**< peer create fail due to peer null */
+ /**< Peer creation failure due to null peer. */
NSS_WIFILI_EMSG_PEER_DELETE_PEER_CORRUPTED_FAIL,
- /**< peer create fail due to corrupted peer */
+ /**< Peer creation failure due to corrupted peer. */
NSS_WIFILI_EMSG_GROUP0_TIMER_ALLOC_FAIL,
- /**< timer alloc fail */
+ /**< Timer allocation failure. */
NSS_WIFILI_EMSG_INSUFFICIENT_WT_FAIL,
- /**< insufficient worker thread error */
+ /**< Insufficient worker thread error. */
NSS_WIFILI_EMSG_INVALID_NUM_TCL_RING_FAIL,
- /**< invlalid number of tcl ring provided in init msg */
+ /**< Invlalid number of Transmit Classifier ring provided in initialization message. */
NSS_WIFILI_EMSG_INVALID_NUM_REO_DST_RING_FAIL,
- /**< invalid number of reo dst ring in init msg */
+ /**< Invalid number of reorder destination ring in initialization message. */
NSS_WIFILI_EMSG_HAL_SRNG_SOC_ALLOC_FAIL,
- /**< srng soc memory allocation failure */
+ /**< Srng SoC memory allocation failure. */
NSS_WIFILI_EMSG_HAL_TCL_SRNG_ALLOC_FAIL,
- /**< tcl srng ring alloc fail */
+ /**< Transmit Classifier srng ring allocation failure. */
NSS_WIFILI_EMSG_HAL_TXCOMP_SRNG_ALLOC_FAIL,
- /**< txcomp srng ring alloc fail */
+ /**< Txcomp srng ring allocation failure. */
NSS_WIFILI_EMSG_HAL_REODST_SRNG_ALLOC_FAIL,
- /**< reo dst srng ring alloc fail */
+ /**< Reorder destination srng ring allocation failure. */
NSS_WIFILI_EMSG_HAL_REOREINJECT_SRNG_ALLOC_FAIL,
- /**< reo reinject srng ring alloc fail */
+ /**< Reorder reinject srng ring allocation failure. */
NSS_WIFILI_EMSG_HAL_RXRELEASE_SRNG_ALLOC_FAIL,
- /**< rx release srng ring alloc fail */
+ /**< Rx release srng ring allocation failure. */
NSS_WIFILI_EMSG_HAL_RXEXCP_SRNG_ALLOC_FAIL,
- /**< rx exception srng ring alloc fail */
+ /**< Rx exception srng ring allocation failure. */
NSS_WIFILI_EMSG_HAL_TX_MEMALLOC_FAIL,
- /**< tx hal srng ring alloc fail */
+ /**< Tx hal (hardware Abstraction Layer) srng ring allocation failure. */
NSS_WIFILI_EMSG_HAL_TX_INVLID_POOL_NUM_FAIL,
- /**< invalid pool num in init msg */
+ /**< Invalid pool number in initialization message. */
NSS_WIFILI_EMSG_HAL_TX_INVALID_PAGE_NUM_FAIL,
- /**< invalid page num in init msg */
+ /**< Invalid page numner in initialization message. */
NSS_WIFILI_EMSG_HAL_TX_DESC_MEM_ALLOC_FAIL,
- /**< tx desc mem allocation fail */
+ /**< Tx descriptor memory allocation failure. */
NSS_WIFILI_EMSG_HAL_RX_MEMALLOC_FAIL,
- /**< rx memalloc fail */
+ /**< Rx memory allocation failure. */
NSS_WIFILI_EMSG_UNKNOWN
- /**< unknown error message */
+ /**< Unknown error message. */
};
/**
- * wifili_soc_extended_data_types
- * enumeration of extended data type to host
+ * nss_wifili_soc_extended_data_types
+ * Enumeration of extended data type to host.
*/
-enum wifili_soc_extended_data_types {
- WIFILI_SOC_EXT_DATA_PKT_TYPE_NONE,
- WIFILI_SOC_EXT_DATA_PKT_MSDU_LINK_DESC,
- WIFILI_SOC_EXT_DATA_PKT_TYPE_MAX
+enum nss_wifili_soc_extended_data_types {
+ WIFILI_SOC_EXT_DATA_PKT_TYPE_NONE, /**< Packet type is none. */
+ WIFILI_SOC_EXT_DATA_PKT_MSDU_LINK_DESC, /**< Packet type is MSDU link desctriptor. */
+ WIFILI_SOC_EXT_DATA_PKT_INVALID_PEER, /**< Packet type is Invalid peer. */
+ WIFILI_SOC_EXT_DATA_PKT_TYPE_MAX /**< Maximum extended data types. */
};
/**
* nss_wifili_hal_srng_info
- * wifili hal srng info
+ * Wifili hal srng information.
*/
struct nss_wifili_hal_srng_info{
uint8_t ring_id;
- /**< ring id */
+ /**< Ring ID. */
uint8_t mac_id;
- /**< pdev id */
+ /**< Pdev ID. */
uint8_t resv[2];
uint32_t ring_base_paddr;
- /**< physical base address of the ring */
+ /**< Physical base address of the ring. */
uint32_t num_entries;
- /**< number of entries in ring */
- uint32_t flags; /**< misc flags */
+ /**< Number of entries in ring. */
+ uint32_t flags; /**< Miscellaneous flags. */
uint32_t ring_dir;
- /**< ring direction: source or dest */
+ /**< Ring direction: source or destination. */
uint32_t entry_size;
- /**< ring entry size */
+ /**< Ring entry size. */
uint32_t low_threshold;
- /**< Low threshold – in number of ring entries (valid for src rings only) */
+ /**< Low threshold – in number of ring entries (valid for source rings only). */
uint32_t hwreg_base[NSS_WIFILI_MAX_SRNG_REG_GROUPS_MSG];
- /**< hw ring base address */
+ /**< Hardware ring base address. */
};
/**
* nss_wifili_hal_srng_soc_msg
- * wifi li hal srng message
+ * Wifili hal srng message.
*/
struct nss_wifili_hal_srng_soc_msg {
uint32_t dev_base_addr;
- /**< base address of wlan dev */
+ /**< Base address of wlan dev. */
uint32_t shadow_rdptr_mem_addr;
- /**< shadow rdptr address */
+ /**< Shadow read pointer address. */
uint32_t shadow_wrptr_mem_addr;
- /**< shadow wrptr address */
+ /**< Shadow write pointer address. */
};
/**
* nss_wifili_tx_desc_init_msg
- * wifi li software desc pool init msg
+ * Wifili software descriptor pool initialization message.
*/
struct nss_wifili_tx_desc_init_msg {
uint32_t num_tx_desc;
- /**< count of the sw descriptors */
+ /**< Count of the software descriptors. */
uint32_t num_tx_desc_ext;
- /**< count of sw extention descriptors */
+ /**< Count of software extented descriptors. */
uint32_t num_pool;
- /**< number of descriptor pools */
+ /**< Number of descriptor pools. */
uint32_t memory_addr[NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG];
- /**< memory start address of each page */
+ /**< Memory start address of each page. */
uint32_t memory_size[NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG];
- /**< memory size */
+ /**< Memory size. */
uint32_t num_memaddr;
- /**< number of mem address */
+ /**< Number of memory address. */
uint32_t ext_desc_page_num;
- /**< ext_desc_page number */
+ /**< Extended descriptor page number. */
};
/**
* nss_wifili_init_msg
- * Lithium soc init msg
+ * Wifili SoC initialization message.
*/
struct nss_wifili_init_msg {
struct nss_wifili_hal_srng_soc_msg hssm;
uint8_t num_tcl_data_rings;
- /**< number of tcl data rings */
+ /**< Number of Transmit Classifier data rings. */
uint8_t num_reo_dest_rings;
- /**< number of reo rings */
+ /**< Number of reorder rings. */
uint8_t resv[2];
- /**< reserve for alignment */
+ /**< Reserve for alignment. */
struct nss_wifili_hal_srng_info tcl_ring_info[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG];
- /**< tcl data ring config info */
+ /**< Transmit Classifier data ring configuration information. */
struct nss_wifili_hal_srng_info tx_comp_ring[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG];
- /**< tx completion ring config info */
+ /**< Tx completion ring configuration information. */
struct nss_wifili_hal_srng_info reo_dest_ring[NSS_WIFILI_MAX_REO_DATA_RINGS_MSG];
- /**< reo destination ring config info */
+ /**< Reorder destination ring configuration information. */
struct nss_wifili_hal_srng_info reo_exception_ring;
- /**< reo exception ring config info */
+ /**< Reorder exception ring configuration information. */
struct nss_wifili_hal_srng_info rx_rel_ring;
- /**< wbm release ring config info */
+ /**< WBM (Wireless Buffer manager) release ring configuration information. */
struct nss_wifili_hal_srng_info reo_reinject_ring;
- /**< reinject ring config info */
+ /**< Reinject ring configuration information. */
struct nss_wifili_tx_desc_init_msg wtdim;
- /**< tx descriptor init message */
+ /**< Tx descriptor initialization message. */
};
/**
* nss_wifili_pdev_deinit_msg
- * li pdev deinit msg
+ * Wifili pdev deinit message.
*/
struct nss_wifili_pdev_deinit_msg {
- uint32_t ifnum; /**< nss ifnum of pdev */
+ uint32_t ifnum; /**< NSS interface number of pdev. */
};
/**
* nss_wifili_pdev_init_msg
- * li pdev init msg
+ * Wifili pdev initialization message.
*/
struct nss_wifili_pdev_init_msg {
struct nss_wifili_hal_srng_info rxdma_ring;
- /**< mac ring configuration */
+ /**< MAC (Media Access Point) ring configuration. */
uint32_t radio_id;
- /**< mac radio id */
+ /**< MAC radio ID. */
uint32_t hwmode;
- /**< mac hw mode */
+ /**< MAC hardware mode. */
};
/**
* nss_wifili_peer_msg
- * wifili peer create message.
+ * Wifili peer creation message.
*/
struct nss_wifili_peer_msg {
uint8_t peer_mac_addr[6];
- /**< peer mac address */
+ /**< Peer MAC address. */
uint16_t vdev_id;
- /**< vap id */
+ /**< VAP ID. */
uint16_t peer_id;
- /**< peer id */
+ /**< Peer ID. */
uint16_t hw_ast_idx;
- /**< hw address search table index */
+ /**< Hardware address search table index. */
uint8_t is_nawds;
- /**< is NAWDS enabled for peer */
+ /**< NAWDS enabled for peer. */
};
/**
* nss_wifili_peer_freelist_append_msg
- * peer memory request
+ * Peer memory request.
*/
struct nss_wifili_peer_freelist_append_msg {
uint32_t addr;
- /**< starting address of peer_freelist pool */
+ /**< Starting address of peer_freelist pool. */
uint32_t length;
- /**< length of peer_freelist pool */
+ /**< Length of peer freelist pool. */
uint32_t num_peers;
- /**< max number of peer entries supported in pool */
+ /**< Maximum number of peer entries supported in pool. */
};
/**
* nss_wifili_tx_stats
- * tx statistics
+ * Tx statistics.
*/
struct nss_wifili_tx_stats {
uint32_t tx_enqueue_dropped;
- /**< tx enqueue drop count */
+ /**< Tx enqueue drop count. */
uint32_t tx_enqueue_cnt;
- /**< tx enqueue succesful count */
+ /**< Tx enqueue succesful count. */
uint32_t tx_dequeue_cnt;
- /**< tx dequeue count */
+ /**< Tx dequeue count. */
uint32_t tx_send_fail_cnt;
- /**< hw send fail count */
+ /**< Hardware send failure count. */
uint32_t inv_peer;
- /**< invalid peer enqueue count */
+ /**< Invalid peer enqueue count. */
uint32_t inv_peer_drop_byte_cnt;
- /**< invalid peer drop byte count */
+ /**< Invalid peer drop byte count. */
uint32_t tx_input_pkt;
- /**< tx packets ready to sent */
+ /**< Tx packets ready to sent. */
uint32_t tx_processed_pkt;
- /**< tx no of packets sent */
+ /**< Tx numner of packets sent. */
uint32_t tx_processed_bytes;
- /**< tx no of bytes processed */
+ /**< Tx number of bytes processed. */
};
-/*
+/**
* nss_wifili_rx_stats
- * rx statistics
+ * Rx statistics.
*/
struct nss_wifili_rx_stats {
uint32_t rx_msdu_err;
- /**< rx msdu error count */
+ /**< Rx msdu error count. */
uint32_t rx_inv_peer;
- /**< rx invalid peer count */
+ /**< Rx invalid peer count. */
uint32_t rx_scatter_inv_peer;
- /**< rx scatter invalid peer count */
+ /**< Rx scatter invalid peer count. */
uint32_t rx_wds_learn_send;
- /**< wds src port learn packet */
+ /**< WDS source port learn packet. */
uint32_t rx_wds_learn_send_fail;
- /**< wds src port learn exception send fail cnt */
+ /**< WDS source port learn exception send failure count. */
uint32_t rx_send_dropped;
- /**< rx send dropped count */
+ /**< Rx send dropped count. */
uint32_t rx_deliver_cnt;
- /**< rx deliver count to next node */
+ /**< Rx deliver count to next node. */
uint32_t rx_deliver_cnt_fail;
- /**< rx deliver count fail*/
+ /**< Rx deliver count failure. */
uint32_t rx_intra_bss_ucast_send;
- /**< intrabss unicast sent count */
+ /**< Intra-BSS unicast sent count. */
uint32_t rx_intra_bss_ucast_send_fail;
- /**< intrabss unicast send fail count */
+ /**< Intra-BSS unicast send failure count. */
uint32_t rx_intra_bss_mcast_send;
- /**< intrabss mcast send count */
+ /**< Intra-BSS mcast send count. */
uint32_t rx_intra_bss_mcast_send_fail;
- /**< intrabss mcast send fail count */
+ /**< Intra-BSS mcast send failure count. */
uint32_t rx_sg_recv_send;
- /**< rx sg receive send count */
+ /**< Rx scatter-gather receive send count. */
uint32_t rx_sg_recv_fail;
- /**< rx sg receive fail count */
+ /**< Rx scatter-gather receive failure count. */
};
/**
* nss_wifili_tx_tcl_ring_stats
- * tcl ring specific statistics;
+ * Transmit Classifier ring specific statistics.
*/
struct nss_wifili_tx_tcl_ring_stats {
- uint32_t tcl_no_hw_desc; /**< no of tcl hw descriptors*/
- uint32_t tcl_ring_full; /**< no of times tcl ring full*/
- uint32_t tcl_ring_sent; /**< totall no of ring sent*/
+ uint32_t tcl_no_hw_desc; /**< Number of Transmit Classifier hardware descriptors. */
+ uint32_t tcl_ring_full; /**< Number of times Transmit Classifier ring full. */
+ uint32_t tcl_ring_sent; /**< Total number of ring sent. */
};
/**
* nss_wifili_tx_comp_ring_stats
- * Tx completion ring statistics
+ * Tx completion ring statistics.
*/
struct nss_wifili_tx_comp_ring_stats {
- uint32_t invalid_bufsrc; /**< tx comp ring desc invalid bufsrc */
- uint32_t invalid_cookie; /**< tx com ring desc invalid cookie */
- uint32_t hw_ring_empty; /**< tx comp no comp ring available */
- uint32_t ring_reaped; /**< tx comp successfull ring reaped*/
+ uint32_t invalid_bufsrc; /**< Tx comp (Completion) ring descriptor invalid buffer source. */
+ uint32_t invalid_cookie; /**< Tx comletion ring descriptor has invalid cookies. */
+ uint32_t hw_ring_empty; /**< Tx completion hardware ring empty. */
+ uint32_t ring_reaped; /**< Tx completion successfull ring reaped. */
};
/**
* nss_wifili_tx_sw_pool_stats
- * Tx completion sw stats
+ * Tx completion sw statistics.
*/
struct nss_wifili_tx_sw_pool_stats {
- uint32_t desc_alloc; /**< tx desc sw pool desc in use*/
- uint32_t desc_alloc_fail; /**< tx desc sw pool alloc fail */
- uint32_t desc_already_allocated; /**< tx desc re-alloc for allocated desc */
- uint32_t desc_invalid_free; /**< tx desc freeing of allocated desc */
- uint32_t tx_rel_src_fw; /**< tx desc src is fw */
- uint32_t tx_rel_ext_desc; /**< tx desc sg */
- uint32_t tx_rel_tx_desc; /**< tx desc src is hw*/
- uint32_t tx_rel_no_pb; /**< tx desc has pbuf present */
+ uint32_t desc_alloc; /**< Tx descriptor software pool descriptor in use. */
+ uint32_t desc_alloc_fail; /**< Tx descriptor software pool allocation failure . */
+ uint32_t desc_already_allocated; /**< Tx descriptor re-allocation for allocated descriptor. */
+ uint32_t desc_invalid_free; /**< Tx descriptor freeing of allocated descriptor. */
+ uint32_t tx_rel_src_fw; /**< Tx descriptor source is firmware. */
+ uint32_t tx_rel_ext_desc; /**< Tx descriptor scatter-gather. */
+ uint32_t tx_rel_tx_desc; /**< Tx descriptor source is hardware*/
+ uint32_t tx_rel_no_pb; /**< Tx descriptor has pbuf present. */
};
-/*
+/**
* wifili_tx_ext_sw_pool_stats
- * Tx ext desc pool
+ * Tx extended descriptor pool.
*/
struct nss_wifili_tx_ext_sw_pool_stats {
- uint32_t desc_alloc; /**< tx ext(sg) desc in use */
- uint32_t desc_alloc_fail; /**< tx ext desc alloc fail */
- uint32_t desc_already_allocated; /**< tx ext desc already allocated */
- uint32_t desc_invalid_free; /**< tx desc invalid src */
+ uint32_t desc_alloc; /**< Tx extend (scatter gather) descriptor in use. */
+ uint32_t desc_alloc_fail; /**< Tx extend descriptor allocation failure. */
+ uint32_t desc_already_allocated; /**< Tx extend descriptor already allocated. */
+ uint32_t desc_invalid_free; /**< Tx descriptor invalid source. */
};
/**
* nss_wifili_rx_wbm_ring_stats
- * wbm release ring statistics
+ * WBM (Wireless Buffer Manager) release ring statistics.
*/
struct nss_wifili_rx_wbm_ring_stats {
- uint32_t invalid_buf_mgr; /**< wbm invalid buffer manager */
- uint32_t err_src_rxdma; /**< wbm src is rdma ring */
- uint32_t err_src_rxdma_code_inv; /**< wbm src dma reason unknown */
- uint32_t err_src_reo; /**< wbm src is reo */
- uint32_t err_src_reo_code_nullq; /**< wbm src reo because of null tlv */
- uint32_t err_src_reo_code_inv; /**< wbm src reo reason unknown */
- uint32_t err_src_invalid; /**< wbm src is unknown */
+ uint32_t invalid_buf_mgr; /**< Invalid buffer manager. */
+ uint32_t err_src_rxdma; /**< WBM source is rdma ring. */
+ uint32_t err_src_rxdma_code_inv; /**< WBM source DMA reason unknown. */
+ uint32_t err_src_reo; /**< WBM source is reorder ring. */
+ uint32_t err_src_reo_code_nullq; /**< WBM source reorder ring because of null tlv. */
+ uint32_t err_src_reo_code_inv; /**< WBM source reorder ring reason unknown. */
+ uint32_t err_src_invalid; /**< WBM source is unknown. */
};
/**
* nss_wifili_rx_reo_ring_stats
- * reo error statistics
+ * Reorder error statistics.
*/
struct nss_wifili_rx_reo_ring_stats {
- uint32_t ring_error; /**< reo ring error*/
- uint32_t ring_reaped; /**< no of ring desc reaped */
- uint32_t invalid_cookie; /**< no of invalid cookie */
+ uint32_t ring_error; /**< Reorder ring error. */
+ uint32_t ring_reaped; /**< Number of ring descriptor reaped. */
+ uint32_t invalid_cookie; /**< Number of invalid cookie. */
};
/**
* nss_wifili_rx sw_pool_stats
- * nss_wifoli dma sw pool stats
+ * Wifili DMA sw pool statistics.
*/
struct nss_wifili_rx_sw_pool_stats {
- uint32_t rx_no_pb; /**< rx sw desc no buff avail */
- uint32_t desc_alloc; /**< no of desc in use */
- uint32_t desc_alloc_fail; /**< no of desc alloc fail */
+ uint32_t rx_no_pb; /**< Rx software descriptor number of buffer available. */
+ uint32_t desc_alloc; /**< Number of descriptor in use. */
+ uint32_t desc_alloc_fail; /**< Number of descriptor allocation failure. */
};
-/*
- * wifili rx dma ring stats
- * nss_wifli dma ring statistics
+/**
+ * nss_wifili_rx_dma_ring_stats
+ * Wifili Rx DMA ring statistics.
*/
struct nss_wifili_rx_dma_ring_stats {
- uint32_t rx_hw_desc_unavailable; /**< no of times hw desc is unavailable */
+ uint32_t rx_hw_desc_unavailable; /**< Number of times hardware descriptor is unavailable. */
};
/**
* nss_wifili_device_stats
- * wifili device specific stats
+ * Wifili specific statistics.
*/
struct nss_wifili_device_stats {
struct nss_wifili_tx_tcl_ring_stats tcl_stats[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG];
- /**< tcl ring stats */
+ /**< Transmit Classifier ring statistics. */
struct nss_wifili_tx_comp_ring_stats txcomp_stats[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG];
- /**< tx comp ring stats*/
+ /**< Tx completion ring stats. */
struct nss_wifili_tx_sw_pool_stats tx_sw_pool_stats[NSS_WIFILI_MAX_TXDESC_POOLS_MSG];
- /**< tx sw pool stats */
+ /**< Tx software pool statistics. */
struct nss_wifili_tx_ext_sw_pool_stats tx_ext_sw_pool_stats[NSS_WIFILI_MAX_TX_EXT_DESC_POOLS_MSG];
- /**< tx ext ext sw pool stats */
+ /**< Tx extended software pool statistics. */
struct nss_wifili_tx_stats tx_data_stats[NSS_WIFILI_MAX_PDEV_NUM_MSG];
- /**< tx data stats for each pdev */
+ /**< Tx data statistics for each pdev. */
struct nss_wifili_rx_reo_ring_stats rxreo_stats[NSS_WIFILI_MAX_REO_DATA_RINGS_MSG];
- /**< rx reo ring stats */
+ /**< Rx reorder ring statistics. */
struct nss_wifili_rx_sw_pool_stats rx_sw_pool_stats[NSS_WIFILI_MAX_PDEV_NUM_MSG];
- /**< rx dma sw pool stats */
+ /**< Rx DMA software pool statistics. */
struct nss_wifili_rx_stats rx_data_stats[NSS_WIFILI_MAX_PDEV_NUM_MSG];
- /**< rx data stats for each pdev */
+ /**< Rx data statistics for each pdev. */
struct nss_wifili_rx_dma_ring_stats rxdma_stats[NSS_WIFILI_MAX_PDEV_NUM_MSG];
- /**< rx dma ring stats */
+ /**< Rx DMA ring statistics. */
struct nss_wifili_rx_wbm_ring_stats rxwbm_stats;
- /**< wbm ring stats */
+ /**< WBM ring statistics. */
};
/**
* nss_wifili_stats_sync_msg
- * li stats sync msg
+ * Wifili SoC statistics synchronization message.
*/
struct nss_wifili_stats_sync_msg {
struct nss_wifili_device_stats stats;
- /**< device statistics */
+ /**< Device statistics. */
};
/**
- * wifili_soc_linkdesc_per_packet_metadata
- * linkdesc per packet metadata
+ * nss_wifili_soc_linkdesc_per_packet_metadata
+ * Link descriptor per packet metadata.
*/
-struct wifili_soc_linkdesc_per_packet_metadata
+struct nss_wifili_soc_linkdesc_per_packet_metadata
{
- uint32_t desc_addr; /**< link descriptor address */
+ uint32_t desc_addr; /**< Link descriptor address. */
};
/**
- * wifili_soc_per_packet_metadata
- * Per packet special data that has to be sent to host
+ * nss_wifili_soc_per_packet_metadata
+ * Per packet special data that has to be sent to host.
*/
-struct wifili_soc_per_packet_metadata {
+struct nss_wifili_soc_per_packet_metadata {
uint32_t pkt_type;
union {
- struct wifili_soc_linkdesc_per_packet_metadata linkdesc_metadata;
+ struct nss_wifili_soc_linkdesc_per_packet_metadata linkdesc_metadata;
} metadata;
};
/**
+ * nss_wifili_tx_mcs
+ * Peer MCS count.
+ */
+struct nss_wifili_tx_mcs {
+ uint32_t mcs_count[NSS_WIFILI_MAX_MCS + 1]; /**< MCS count. */
+};
+
+/**
+ * Packets dropped on the Tx side
+ * Tx peer dropped packets.
+ */
+struct nss_wifili_tx_dropped {
+ uint32_t dma_map_error; /**< Discarded by firmware. */
+ uint32_t ring_full; /**< Dropped due to ring full. */
+ uint32_t fw_discard; /**< Discarded by firmware. */
+ uint32_t fw_discard_retired; /**< Firmware discard retired. */
+ uint32_t fw_discard_untransmitted; /**< Firmware discard untransmitted. */
+ uint32_t mpdu_age_out; /**< Number of PDU aged out. */
+ uint32_t fw_discard_reason1; /**< Firmware discarded PDU reason 1. */
+ uint32_t fw_discard_reason2; /**< Firmware discarded PDU reason 2. */
+ uint32_t fw_discard_reason3; /**< Firmware discarded PDU reason 3. */
+};
+
+/**
+ * nss_wifili_tx_ctrl_stats
+ * Tx peer statistics.
+ */
+struct nss_wifili_tx_ctrl_stats {
+ uint32_t tx_failed; /**< Total Tx failure. */
+ uint32_t ofdma; /**< Total number of OFDMA packets. */
+ uint32_t stbc; /**< Packets in STBC. */
+ uint32_t ldpc; /**< Packets in LDPC. */
+ uint32_t retries; /**< Packet retries. */
+ uint32_t non_amsdu_cnt; /**< Number of MSDUs with no MSDU level aggregation. */
+ uint32_t amsdu_cnt; /**< Number of MSDUs part of AMSDU. */
+ uint32_t last_ack_rssi; /**< RSSI of last packet. */
+
+ struct nss_wifili_tx_mcs pkt_type[NSS_WIFILI_DOT11_MAX]; /**< MCS count. */
+ uint32_t sgi_count[NSS_WIFILI_MAX_MCS + 1]; /**< SGI count. */
+ uint32_t bw[NSS_WIFILI_SUPPORTED_BW]; /**< Packet Count for different bandwidths. */
+ uint32_t wme_ac_type[NSS_WIFILI_WME_AC_MAX]; /**< Wireless Multimedia type Count. */
+ uint32_t excess_retries_ac[NSS_WIFILI_WME_AC_MAX]; /**< Wireless Multimedia type Count. */
+ struct nss_wifili_tx_dropped dropped; /**< Tx peer dropped. */
+ uint32_t complete_pkt; /**< Complete packet count. */
+ uint32_t complete_byte; /**< Complete byte count. */
+ uint32_t failed; /**< Failed packet count. */
+ uint32_t success; /**< Success packet count. */
+ uint32_t success_bytes; /**< Success bytes count. */
+};
+
+/**
+ * nss_wifili_peer_rx_err
+ * Rx peer errors.
+ */
+struct nss_wifili_rx_err {
+ uint32_t mic_err; /**< Rx MIC errors. */
+ uint32_t decrypt_err; /**< Rx Decryption errors. */
+};
+
+/**
+ * nss_wifili_rx_ctrl_stats
+ * Peer Rx statistics.
+ */
+struct nss_wifili_rx_ctrl_stats {
+ struct nss_wifili_rx_err err; /**< Rx peer errors. */
+ uint32_t wme_ac_type[NSS_WIFILI_WME_AC_MAX]; /**< Wireless Multimedia type Count. */
+ uint32_t reception_type[NSS_WIFILI_SUPPORTED_RECEPTION_TYPES]; /**< Reception type OS packets. */
+ uint32_t mcs_count[NSS_WIFILI_MAX_MCS + 1]; /**< Packets in different MCS rates. */
+ uint32_t sgi_count[NSS_WIFILI_MAX_MCS + 1]; /**< SGI count. */
+ uint32_t nss[NSS_WIFILI_SS_COUNT]; /**< Packet count in spatiel Streams. */
+ uint32_t bw[NSS_WIFILI_SUPPORTED_BW]; /**< Packet Count in different bandwidths. */
+ uint32_t non_ampdu_cnt; /**< Number of MSDUs with no MPDU level aggregation. */
+ uint32_t ampdu_cnt; /**< Number of MSDUs part of AMPDU. */
+ uint32_t non_amsdu_cnt; /**< Number of MSDUs with no MSDU level aggregation. */
+ uint32_t amsdu_cnt; /**< Number of MSDUs part of AMSDU. */
+ uint32_t mcast_rcv_cnt; /**< Total number of mcast packets received. */
+ uint32_t ucast_rcv_cnt; /**< Unicast received count. */
+ uint32_t rx_recvd; /**< Total Rx received count. */
+};
+
+/**
+ * nss_wifili_peer_ctrl_stats
+ * Wifili peer control statistics.
+ */
+struct nss_wifili_peer_ctrl_stats {
+ uint32_t peer_id; /**< Peer ID. */
+ struct nss_wifili_tx_ctrl_stats tx;
+ /**< Peer Tx control statistics. */
+ struct nss_wifili_rx_ctrl_stats rx;
+ /**< Peer Rx control statistics. */
+};
+
+/**
+ * nss_wifili peer stats
+ * Wifili peer statistics.
+ */
+struct nss_wifili_peer_stats {
+ uint32_t npeers; /**< Number of entries of peer statistics. */
+ struct nss_wifili_peer_ctrl_stats wpcs[1];
+ /**< Wifili peer control statistics. */
+};
+
+/**
+ * wifili_peer_stats_msg
+ * Wifili peer statistics message.
+ */
+struct nss_wifili_peer_stats_msg {
+ struct nss_wifili_peer_stats stats;
+ /**< Wifili peer statistics. */
+};
+
+
+/**
* nss_wifili_msg
- * Structure that describes wifi li messages
+ * Structure that describes wifili messages.
*/
struct nss_wifili_msg {
- struct nss_cmn_msg cm; /**< Common message Header */
+ struct nss_cmn_msg cm; /**< Common message header. */
union {
struct nss_wifili_init_msg init;
/**< Wi-Fi initialization data. */
@@ -516,19 +678,21 @@
/**< Information for creating a peer freelist. */
struct nss_wifili_stats_sync_msg wlsoc_stats;
/**< Synchronization statistics. */
+ struct nss_wifili_peer_stats_msg peer_stats;
+ /**< Wifili peer statistics. */
} msg;
};
/**
* nss_wifili_tx_msg
- * Send wifili messages
+ * Send wifili messages.
*
* @datatypes
* nss_ctx_instance \n
* nss_wifili_msg
*
* @param[in] nss_ctx NSS context.
- * @param[in] msg NSS wifi message.
+ * @param[in] msg NSS Wi-Fi message.
*
* @return
* nss_tx_status_t Tx status
@@ -537,7 +701,7 @@
/**
* nss_wifili_msg_callback_t
- * Callback to receive wifili messages
+ * Callback to receive wifili messages.
*
* @datatypes
* nss_wifili_msg
@@ -552,7 +716,7 @@
/**
* nss_wifili_callback_t
- * Callback to receive wifi data
+ * Callback to receive Wi-Fi data.
*
* @datatypes
* net_device \n
@@ -571,7 +735,7 @@
/**
* nss_register_wifili_if
- * Register to send/receive wifi li soc messages to NSS
+ * Register to send/receive wifili SoC messages to NSS.
*
* @datatypes
* nss_wifili_callback_t \n
@@ -594,7 +758,7 @@
/**
* nss_unregister_wifili_if
- * Unregister wifi li soc interface with NSS
+ * Deregister wifili SoC interface with NSS.
*
* @param[in] if_num NSS interface number
*
@@ -605,7 +769,7 @@
/**
* nss_register_wifili_radio_if
- * Register to send/receive wifi li radio messages to NSS
+ * Register to send/receive wifili radio messages to NSS.
*
* @datatypes
* nss_wifili_callback_t \n
@@ -628,7 +792,7 @@
/**
* nss_unregister_wifili_radio_if
- * Unregister wifi li radio interface with NSS
+ * Deregister wifili radio interface with NSS.
*
* @param[in] if_num NSS interface number
*
diff --git a/nss_bridge.c b/nss_bridge.c
index 88b5d73..8c465b7 100644
--- a/nss_bridge.c
+++ b/nss_bridge.c
@@ -82,6 +82,15 @@
}
/*
+ * nss_bridge_get_context()
+ */
+struct nss_ctx_instance *nss_bridge_get_context(void)
+{
+ return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.bridge_handler_id];
+}
+EXPORT_SYMBOL(nss_bridge_get_context);
+
+/*
* nss_bridge_verify_if_num()
* Verify if_num passed to us.
*/
@@ -91,7 +100,7 @@
return false;
}
- if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE) {
+ if (nss_dynamic_interface_get_type(nss_bridge_get_context(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE) {
return false;
}
@@ -221,15 +230,6 @@
EXPORT_SYMBOL(nss_bridge_tx_msg_sync);
/*
- * nss_bridge_get_context()
- */
-struct nss_ctx_instance *nss_bridge_get_context(void)
-{
- return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.bridge_handler_id];
-}
-EXPORT_SYMBOL(nss_bridge_get_context);
-
-/*
* nss_bridge_msg_init()
* Initialize nss_bridge_msg.
*/
diff --git a/nss_capwap.c b/nss_capwap.c
index 13df093..3c0af95 100644
--- a/nss_capwap.c
+++ b/nss_capwap.c
@@ -55,7 +55,7 @@
return false;
}
- if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) {
+ if (nss_dynamic_interface_get_type(nss_capwap_get_ctx(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) {
return false;
}
diff --git a/nss_cmn.c b/nss_cmn.c
index 9c2b108..44dc27b 100644
--- a/nss_cmn.c
+++ b/nss_cmn.c
@@ -156,11 +156,11 @@
* nss_cmn_interface_is_virtual()
* Return true if the interface number is a virtual NSS interface
*/
-bool nss_cmn_interface_is_virtual(void *nss_ctx, int32_t interface_num)
+bool nss_cmn_interface_is_virtual(struct nss_ctx_instance *nss_ctx, int32_t interface_num)
{
- return ((nss_dynamic_interface_get_type(interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_WIFI)
- || (nss_dynamic_interface_get_type(interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR)
- || (nss_dynamic_interface_get_type(interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED));
+ return (nss_dynamic_interface_get_type(nss_ctx, interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_WIFI)
+ || (nss_dynamic_interface_get_type(nss_ctx, interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR)
+ || (nss_dynamic_interface_get_type(nss_ctx, interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED);
}
/*
diff --git a/nss_core.c b/nss_core.c
index 2395be1..89672a0 100644
--- a/nss_core.c
+++ b/nss_core.c
@@ -56,11 +56,25 @@
module_param(max_ipv6_conn, int, S_IRUGO);
MODULE_PARM_DESC(max_ipv6_conn, "Max number of IPv6 connections");
+static bool pn_mq_en = false;
+module_param(pn_mq_en, bool, S_IRUGO);
+MODULE_PARM_DESC(pn_mq_en, "Enable pnode ingress Qos");
+
+static int pn_pri_num = NSS_MAX_NUM_PRI;
+module_param(pn_pri_num, int, S_IRUGO);
+MODULE_PARM_DESC(pn_pri_num, "Maximum number of queue priority");
+
+static int pn_qlimits[NSS_MAX_NUM_PRI] = { NSS_DEFAULT_QUEUE_LIMIT, NSS_DEFAULT_QUEUE_LIMIT,
+ NSS_DEFAULT_QUEUE_LIMIT, NSS_DEFAULT_QUEUE_LIMIT};
+module_param_array(pn_qlimits, int, NULL, 0);
+MODULE_PARM_DESC(pn_qlimits, "Default queue limit");
+
/*
* Track IPv4/IPv6 max connection update done
*/
static int max_ipv4_conn_update_done;
static int max_ipv6_conn_update_done;
+static int pn_q_update_done;
/*
* Atomic variables to control jumbo_mru & paged_mode
@@ -1221,6 +1235,7 @@
int32_t i;
struct nss_top_instance *nss_top;
bool is_scheduled = true;
+ int ret;
/*
* NOTE: A commonly found error is that sizes and start address of per core
@@ -1264,6 +1279,17 @@
}
if (is_scheduled) {
+
+ /*
+ * Send pnode queue config message
+ */
+ if (pn_q_update_done == 0) {
+ ret = nss_n2h_update_queue_config(nss_top->num_pri, pn_mq_en, pn_pri_num, pn_qlimits);
+ if (ret == NSS_TX_SUCCESS) {
+ pn_q_update_done = 1;
+ }
+ }
+
/*
* Configure the maximum number of IPv4/IPv6
* connections supported by the accelerator.
@@ -1577,16 +1603,9 @@
return NSS_N2H_INTR_DATA_QUEUE_3;
}
- if (cause & NSS_N2H_INTR_COREDUMP_COMPLETE_0) {
- printk("NSS core 0 signal COREDUMP COMPLETE %x ", cause);
+ if (cause & NSS_N2H_INTR_COREDUMP_COMPLETE) {
*type = NSS_INTR_CAUSE_EMERGENCY;
- return NSS_N2H_INTR_COREDUMP_COMPLETE_0;
- }
-
- if (cause & NSS_N2H_INTR_COREDUMP_COMPLETE_1) {
- printk("NSS core 1 signal COREDUMP COMPLETE %x\n", cause);
- *type = NSS_INTR_CAUSE_EMERGENCY;
- return NSS_N2H_INTR_COREDUMP_COMPLETE_1;
+ return NSS_N2H_INTR_COREDUMP_COMPLETE;
}
return 0;
@@ -1648,6 +1667,8 @@
break;
case NSS_INTR_CAUSE_EMERGENCY:
+ nss_info_always("NSS core %d signal COREDUMP COMPLETE %x\n",
+ nss_ctx->id, int_ctx->cause);
nss_fw_coredump_notify(nss_ctx, prio_cause);
int_ctx->cause &= ~prio_cause;
break;
@@ -1677,6 +1698,22 @@
}
/*
+ * nss_core_handle_napi_emergency()
+ * NAPI handler for NSS crash
+ */
+int nss_core_handle_napi_emergency(struct napi_struct *napi, int budget)
+{
+ struct netdev_priv_instance *ndev_priv = netdev_priv(napi->dev);
+ struct int_ctx_instance *int_ctx = ndev_priv->int_ctx;
+
+ nss_info_always("NSS core %d signal COREDUMP COMPLETE %x\n",
+ int_ctx->nss_ctx->id, int_ctx->cause);
+ nss_fw_coredump_notify(int_ctx->nss_ctx, 0);
+
+ return 0;
+}
+
+/*
* nss_core_handle_napi_queue()
* NAPI handler for NSS queue cause
*/
diff --git a/nss_core.h b/nss_core.h
index 1871f89..2608bca 100644
--- a/nss_core.h
+++ b/nss_core.h
@@ -163,7 +163,7 @@
*/
#if defined(NSS_HAL_IPQ807x_SUPPORT)
#define NSS_MAX_IRQ_PER_INSTANCE 4
-#define NSS_MAX_IRQ_PER_CORE 7
+#define NSS_MAX_IRQ_PER_CORE 8
#else
#define NSS_MAX_IRQ_PER_INSTANCE 1
#define NSS_MAX_IRQ_PER_CORE 2
@@ -201,6 +201,10 @@
#define NSS_FREQ_110_MIN 0x03000 /* Instructions Per ms Min */
#define NSS_FREQ_110_MAX 0x07000 /* Instructions Per ms Max */
+#define NSS_FREQ_187 187200000 /* Frequency in hz */
+#define NSS_FREQ_187_MIN 0x03000 /* Instructions Per ms Min */
+#define NSS_FREQ_187_MAX 0x07000 /* Instructions Per ms Max */
+
#define NSS_FREQ_275 275000000 /* Frequency in hz */
#define NSS_FREQ_275_MIN 0x03000 /* Instructions Per ms Min */
#define NSS_FREQ_275_MAX 0x07000 /* Instructions Per ms Max */
@@ -217,10 +221,22 @@
#define NSS_FREQ_733_MIN 0x07000 /* Instructions Per ms Min */
#define NSS_FREQ_733_MAX 0x25000 /* Instructions Per ms Max */
+#define NSS_FREQ_748 748800000 /* Frequency in hz */
+#define NSS_FREQ_748_MIN 0x07000 /* Instructions Per ms Min */
+#define NSS_FREQ_748_MAX 0x10000 /* Instructions Per ms Max */
+
#define NSS_FREQ_800 800000000 /* Frequency in hz */
#define NSS_FREQ_800_MIN 0x07000 /* Instructions Per ms Min */
#define NSS_FREQ_800_MAX 0x25000 /* Instructions Per ms Max */
+#define NSS_FREQ_1497 1497600000 /* Frequency in hz */
+#define NSS_FREQ_1497_MIN 0x10000 /* Instructions Per ms Min */
+#define NSS_FREQ_1497_MAX 0x25000 /* Instructions Per ms Max */
+
+#define NSS_FREQ_1689 1689600000 /* Frequency in hz */
+#define NSS_FREQ_1689_MIN 0x10000 /* Instructions Per ms Min */
+#define NSS_FREQ_1689_MAX 0x25000 /* Instructions Per ms Max */
+
#if (NSS_DT_SUPPORT == 1)
#define NSSTCM_FREQ 400000000 /* NSS TCM Frequency in Hz */
@@ -1294,6 +1310,7 @@
NSS_EDMA_PKT_LEN_LA64K_ERR,
NSS_EDMA_PKT_LEN_LE33_ERR,
NSS_EDMA_DATA_LEN_ERR,
+ NSS_EDMA_ALLOC_FAIL_CNT,
NSS_EDMA_ERR_STATS_MAX
};
@@ -1512,6 +1529,7 @@
struct nss_top_instance {
uint8_t num_nss; /* Number of NSS cores supported */
uint8_t num_phys_ports; /* Number of physical ports supported */
+ uint8_t num_pri; /* Maximum number of priority */
uint32_t clk_src; /* Clock source: default/alternate */
spinlock_t lock; /* Big lock for NSS driver */
spinlock_t stats_lock; /* Statistics lock */
@@ -1835,6 +1853,7 @@
uint32_t id; /* NSS core ID */
uint32_t num_queue; /* No. of queues supported per core */
uint32_t num_irq; /* No. of irq binded per queue */
+ uint8_t num_pri; /* Maximum number of priority supported. */
uint32_t irq[NSS_MAX_IRQ_PER_CORE]; /* IRQ numbers per queue */
void __iomem *nmap; /* Virtual addr of NSS CSM space */
void __iomem *vmap; /* Virtual addr of NSS virtual register map */
@@ -1933,6 +1952,7 @@
extern int nss_core_handle_napi(struct napi_struct *napi, int budget);
extern int nss_core_handle_napi_queue(struct napi_struct *napi, int budget);
extern int nss_core_handle_napi_non_queue(struct napi_struct *napi, int budget);
+extern int nss_core_handle_napi_emergency(struct napi_struct *napi, int budget);
extern int32_t nss_core_send_buffer(struct nss_ctx_instance *nss_ctx, uint32_t if_num,
struct sk_buff *nbuf, uint16_t qid,
uint8_t buffer_type, uint16_t flags);
diff --git a/nss_dtls.c b/nss_dtls.c
index f526224..c26b730 100644
--- a/nss_dtls.c
+++ b/nss_dtls.c
@@ -36,7 +36,6 @@
void *app_data;
} dtls_pvt;
-
/*
* nss_dtls_verify_if_num()
* Verify if_num passed to us.
@@ -46,7 +45,7 @@
if (nss_is_dynamic_interface(if_num) == false)
return false;
- if (nss_dynamic_interface_get_type(if_num)
+ if (nss_dynamic_interface_get_type(nss_dtls_get_context(), if_num)
!= NSS_DYNAMIC_INTERFACE_TYPE_DTLS)
return false;
diff --git a/nss_dynamic_interface.c b/nss_dynamic_interface.c
index fdcb80d..5f3ae90 100644
--- a/nss_dynamic_interface.c
+++ b/nss_dynamic_interface.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017, 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
* above copyright notice and this permission notice appear in all copies.
@@ -18,7 +18,16 @@
#define NSS_DYNAMIC_INTERFACE_COMP_TIMEOUT 60000 /* 60 Sec */
-static struct nss_dynamic_interface_pvt di;
+/*
+ * Message data structure to store the message result
+ */
+struct nss_dynamic_interface_msg_data {
+ struct completion complete; /* completion structure */
+ int if_num; /* Interface number */
+ enum nss_cmn_response response; /* Message response */
+};
+
+static nss_dynamic_interface_assigned nss_dynamic_interface_assigned_types[NSS_CORE_MAX][NSS_MAX_DYNAMIC_INTERFACES]; /* Array of assigned interface types */
/*
* nss_dynamic_interface_handler()
@@ -57,10 +66,9 @@
case NSS_DYNAMIC_INTERFACE_ALLOC_NODE:
if (ncm->response == NSS_CMN_RESPONSE_ACK) {
nss_info("%p alloc_node response ack if_num %d\n", nss_ctx, ndim->msg.alloc_node.if_num);
- di.current_if_num = ndim->msg.alloc_node.if_num;
- if_num = di.current_if_num;
+ if_num = ndim->msg.alloc_node.if_num;
if (if_num > 0) {
- di.type[if_num - NSS_DYNAMIC_IF_START] = ndim->msg.alloc_node.type;
+ nss_dynamic_interface_assigned_types[nss_ctx->id][if_num - NSS_DYNAMIC_IF_START] = ndim->msg.alloc_node.type;
} else {
nss_warning("%p: if_num < 0\n", nss_ctx);
}
@@ -71,9 +79,8 @@
case NSS_DYNAMIC_INTERFACE_DEALLOC_NODE:
if (ncm->response == NSS_CMN_RESPONSE_ACK) {
nss_info("%p dealloc_node response ack if_num %d\n", nss_ctx, ndim->msg.dealloc_node.if_num);
- di.current_if_num = ndim->msg.dealloc_node.if_num;
- if_num = di.current_if_num;
- di.type[if_num - NSS_DYNAMIC_IF_START] = NSS_DYNAMIC_INTERFACE_TYPE_NONE;
+ if_num = ndim->msg.dealloc_node.if_num;
+ nss_dynamic_interface_assigned_types[nss_ctx->id][if_num - NSS_DYNAMIC_IF_START] = NSS_DYNAMIC_INTERFACE_TYPE_NONE;
}
break;
@@ -105,52 +112,16 @@
*/
static void nss_dynamic_interface_callback(void *app_data, struct nss_cmn_msg *ncm)
{
+ struct nss_dynamic_interface_msg_data *di_data = (struct nss_dynamic_interface_msg_data *)app_data;
+ struct nss_dynamic_interface_msg *ndim = (struct nss_dynamic_interface_msg *)ncm;
+
+ di_data->response = ncm->response;
+ di_data->if_num = ndim->msg.alloc_node.if_num;
+
/*
* Unblock the sleeping function.
*/
- di.response = ncm->response;
- complete(&di.complete);
-}
-
-/*
- * nss_dynamic_interface_tx_sync()
- * Send the message to NSS and wait till we get an ACK or NACK for this msg.
- */
-static nss_tx_status_t nss_dynamic_interface_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_dynamic_interface_msg *ndim)
-{
- nss_tx_status_t status;
- int ret;
-
- if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
- nss_warning("%p: dynamic if msg dropped as core not ready", nss_ctx);
- return NSS_TX_FAILURE_NOT_READY;
- }
-
- /*
- * Acquring a semaphore , so that only one caller can send msg at a time.
- */
- down(&di.sem);
- di.response = false;
-
- status = nss_dynamic_interface_tx(nss_ctx, ndim);
- if (status != NSS_TX_SUCCESS) {
- up(&di.sem);
- nss_warning("%p: not able to transmit msg successfully\n", nss_ctx);
- return status;
- }
-
- /*
- * Blocking call, wait till we get ACK for this msg.
- */
- ret = wait_for_completion_timeout(&di.complete, msecs_to_jiffies(NSS_DYNAMIC_INTERFACE_COMP_TIMEOUT));
- if (ret == 0) {
- up(&di.sem);
- nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
- return NSS_TX_FAILURE;
- }
-
- up(&di.sem);
- return status;
+ complete(&di_data->complete);
}
/*
@@ -216,6 +187,34 @@
}
/*
+ * nss_dynamic_interface_tx_sync()
+ * Send the message to NSS and wait till we get an ACK or NACK for this msg.
+ */
+static nss_tx_status_t nss_dynamic_interface_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_dynamic_interface_msg_data *di_data,
+ struct nss_dynamic_interface_msg *ndim)
+{
+ nss_tx_status_t status;
+ int ret;
+
+ status = nss_dynamic_interface_tx(nss_ctx, ndim);
+ if (status != NSS_TX_SUCCESS) {
+ nss_warning("%p: not able to transmit msg successfully\n", nss_ctx);
+ return status;
+ }
+
+ /*
+ * Blocking call, wait till we get ACK for this msg.
+ */
+ ret = wait_for_completion_timeout(&di_data->complete, msecs_to_jiffies(NSS_DYNAMIC_INTERFACE_COMP_TIMEOUT));
+ if (ret == 0) {
+ nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
+ return NSS_TX_FAILURE;
+ }
+
+ return status;
+}
+
+/*
* nss_dynamic_interface_alloc_node()
* Allocates node of perticular type on NSS and returns interface_num for this node or -1 in case of failure.
*
@@ -227,6 +226,7 @@
struct nss_ctx_instance *nss_ctx = NULL;
struct nss_dynamic_interface_msg ndim;
struct nss_dynamic_interface_alloc_node_msg *ndia;
+ struct nss_dynamic_interface_msg_data di_data;
uint32_t core_id;
nss_tx_status_t status;
@@ -237,9 +237,12 @@
core_id = nss_top_main.dynamic_interface_table[type];
nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[core_id];
+ di_data.if_num = -1;
+ di_data.response = false;
+ init_completion(&di_data.complete);
nss_dynamic_interface_msg_init(&ndim, NSS_DYNAMIC_INTERFACE, NSS_DYNAMIC_INTERFACE_ALLOC_NODE,
- sizeof(struct nss_dynamic_interface_alloc_node_msg), nss_dynamic_interface_callback, (void *)nss_ctx);
+ sizeof(struct nss_dynamic_interface_alloc_node_msg), nss_dynamic_interface_callback, (void *)&di_data);
ndia = &ndim.msg.alloc_node;
ndia->type = type;
@@ -253,21 +256,21 @@
/*
* Calling synchronous transmit function.
*/
- status = nss_dynamic_interface_tx_sync(nss_ctx, &ndim);
+ status = nss_dynamic_interface_tx_sync(nss_ctx, &di_data, &ndim);
if (status != NSS_TX_SUCCESS) {
nss_warning("%p not able to transmit alloc node msg\n", nss_ctx);
return -1;
}
/*
- * Check di.response and return -1 if its a NACK else proceed.
+ * Check response and return -1 if its a NACK else proceed.
*/
- if (di.response != NSS_CMN_RESPONSE_ACK) {
- nss_warning("%p Received NACK from NSS - Response:%d\n", nss_ctx, di.response);
+ if (di_data.response != NSS_CMN_RESPONSE_ACK) {
+ nss_warning("%p Received NACK from NSS - Response:%d\n", nss_ctx, di_data.response);
return -1;
}
- return di.current_if_num;
+ return di_data.if_num;
}
/*
@@ -283,6 +286,7 @@
struct nss_ctx_instance *nss_ctx = NULL;
struct nss_dynamic_interface_msg ndim;
struct nss_dynamic_interface_dealloc_node_msg *ndid;
+ struct nss_dynamic_interface_msg_data di_data;
uint32_t core_id;
nss_tx_status_t status;
@@ -293,6 +297,8 @@
core_id = nss_top_main.dynamic_interface_table[type];
nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[core_id];
+ di_data.response = false;
+ init_completion(&di_data.complete);
if (nss_is_dynamic_interface(if_num) == false) {
nss_warning("%p: nss_dynamic_interface if_num is not in range %d\n", nss_ctx, if_num);
@@ -300,7 +306,7 @@
}
nss_dynamic_interface_msg_init(&ndim, NSS_DYNAMIC_INTERFACE, NSS_DYNAMIC_INTERFACE_DEALLOC_NODE,
- sizeof(struct nss_dynamic_interface_dealloc_node_msg), nss_dynamic_interface_callback, (void *)nss_ctx);
+ sizeof(struct nss_dynamic_interface_dealloc_node_msg), nss_dynamic_interface_callback, (void *)&di_data);
ndid = &ndim.msg.dealloc_node;
ndid->type = type;
@@ -309,13 +315,13 @@
/*
* Calling synchronous transmit function.
*/
- status = nss_dynamic_interface_tx_sync(nss_ctx, &ndim);
+ status = nss_dynamic_interface_tx_sync(nss_ctx, &di_data, &ndim);
if (status != NSS_TX_SUCCESS) {
nss_warning("%p not able to transmit alloc node msg\n", nss_ctx);
return status;
}
- if (di.response != NSS_CMN_RESPONSE_ACK) {
+ if (di_data.response != NSS_CMN_RESPONSE_ACK) {
nss_warning("%p Received NACK from NSS\n", nss_ctx);
return -1;
}
@@ -329,10 +335,6 @@
void nss_dynamic_interface_register_handler(struct nss_ctx_instance *nss_ctx)
{
nss_core_register_handler(nss_ctx, NSS_DYNAMIC_INTERFACE, nss_dynamic_interface_handler, NULL);
-
- sema_init(&di.sem, 1);
- init_completion(&di.complete);
- di.current_if_num = -1;
}
/*
@@ -348,13 +350,13 @@
* nss_dynamic_interface_get_type()
* Gets the type of dynamic interface
*/
-enum nss_dynamic_interface_type nss_dynamic_interface_get_type(int if_num)
+enum nss_dynamic_interface_type nss_dynamic_interface_get_type(struct nss_ctx_instance *nss_ctx, int if_num)
{
if (nss_is_dynamic_interface(if_num) == false) {
return NSS_DYNAMIC_INTERFACE_TYPE_NONE;
}
- return di.type[if_num - NSS_DYNAMIC_IF_START];
+ return nss_dynamic_interface_assigned_types[nss_ctx->id][if_num - NSS_DYNAMIC_IF_START];
}
/*
diff --git a/nss_edma.c b/nss_edma.c
index 7037010..ed63365 100644
--- a/nss_edma.c
+++ b/nss_edma.c
@@ -123,6 +123,7 @@
nss_top->stats_edma.misc_err[NSS_EDMA_PKT_LEN_LA64K_ERR] += nerss->msg_err_stats.pkt_len_la64k_err;
nss_top->stats_edma.misc_err[NSS_EDMA_PKT_LEN_LE33_ERR] += nerss->msg_err_stats.pkt_len_le33_err;
nss_top->stats_edma.misc_err[NSS_EDMA_DATA_LEN_ERR] += nerss->msg_err_stats.data_len_err;
+ nss_top->stats_edma.misc_err[NSS_EDMA_ALLOC_FAIL_CNT] += nerss->msg_err_stats.alloc_fail_cnt;
spin_unlock_bh(&nss_top->stats_lock);
}
diff --git a/nss_gre_tunnel.c b/nss_gre_tunnel.c
index d8457fb..eea09d5 100644
--- a/nss_gre_tunnel.c
+++ b/nss_gre_tunnel.c
@@ -45,7 +45,7 @@
if (nss_is_dynamic_interface(if_num) == false)
return false;
- if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL)
+ if (nss_dynamic_interface_get_type(nss_gre_tunnel_get_ctx(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL)
return false;
return true;
diff --git a/nss_hal/fsm9010/nss_hal_pvt.c b/nss_hal/fsm9010/nss_hal_pvt.c
index acb80e2..8b16ed6 100644
--- a/nss_hal/fsm9010/nss_hal_pvt.c
+++ b/nss_hal/fsm9010/nss_hal_pvt.c
@@ -104,6 +104,10 @@
npd->num_irq = nss_hal_get_num_irqs(np);
}
+ if (of_property_read_u8(np, "qcom,num-pri", &npd->num_pri)) {
+ npd->num_pri = NSS_DEFAULT_NUM_PRI;
+ }
+
if (npd->num_irq < npd->num_queue) {
pr_err("%s: not enough interrupts configured for all the queues\n", np->name);
goto out;
diff --git a/nss_hal/include/nss_hal.h b/nss_hal/include/nss_hal.h
index 1ac6e20..ec27362 100644
--- a/nss_hal/include/nss_hal.h
+++ b/nss_hal/include/nss_hal.h
@@ -28,6 +28,7 @@
#include <nss_hal_ops.h>
extern struct clk *nss_core0_clk;
+extern struct clk *nss_core1_clk;
extern struct nss_runtime_sampling nss_runtime_samples;
extern struct clk *nss_fab0_clk;
extern struct clk *nss_fab1_clk;
@@ -47,8 +48,7 @@
NSS_N2H_INTR_DATA_QUEUE_1 | \
NSS_N2H_INTR_EMPTY_BUFFERS_SOS | \
NSS_N2H_INTR_TX_UNBLOCKED | \
- NSS_N2H_INTR_COREDUMP_COMPLETE_0 | \
- NSS_N2H_INTR_COREDUMP_COMPLETE_1)
+ NSS_N2H_INTR_COREDUMP_COMPLETE)
/*
* nss_hal_read_interrupt_cause()
diff --git a/nss_hal/include/nss_regs.h b/nss_hal/include/nss_regs.h
index 9af9508..e9b1fdf 100644
--- a/nss_hal/include/nss_regs.h
+++ b/nss_hal/include/nss_regs.h
@@ -66,8 +66,7 @@
#define NSS_N2H_INTR_DATA_QUEUE_3 (1 << 4)
#define NSS_N2H_INTR_EMPTY_BUFFERS_SOS (1 << 10)
#define NSS_N2H_INTR_TX_UNBLOCKED (1 << 11)
-#define NSS_N2H_INTR_COREDUMP_COMPLETE_1 (1 << 13)
-#define NSS_N2H_INTR_COREDUMP_COMPLETE_0 (1 << 14)
+#define NSS_N2H_INTR_COREDUMP_COMPLETE (1 << 14)
/*
* Types of H2N interrupts
diff --git a/nss_hal/ipq806x/nss_hal_pvt.c b/nss_hal/ipq806x/nss_hal_pvt.c
index d325e53..beaa398 100644
--- a/nss_hal/ipq806x/nss_hal_pvt.c
+++ b/nss_hal/ipq806x/nss_hal_pvt.c
@@ -301,6 +301,10 @@
goto out;
}
+ if (of_property_read_u8(np, "qcom,num-pri", &npd->num_pri)) {
+ npd->num_pri = NSS_DEFAULT_NUM_PRI;
+ }
+
/*
* Read frequencies. If failure, load default values.
*/
diff --git a/nss_hal/ipq807x/nss_hal_pvt.c b/nss_hal/ipq807x/nss_hal_pvt.c
index 61363ba..7689e9b 100644
--- a/nss_hal/ipq807x/nss_hal_pvt.c
+++ b/nss_hal/ipq807x/nss_hal_pvt.c
@@ -132,6 +132,10 @@
goto out;
}
+ if (of_property_read_u8(np, "qcom,num-pri", &npd->num_pri)) {
+ npd->num_pri = NSS_DEFAULT_NUM_PRI;
+ }
+
/*
* Read frequencies. If failure, load default values.
*/
@@ -398,11 +402,9 @@
*/
static int __nss_hal_clock_configure(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd)
{
- if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_AHB_CLK, 200000000)) {
- return -EFAULT;
- }
+ uint32_t i;
- if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, 1497600000)) {
+ if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_AHB_CLK, 200000000)) {
return -EFAULT;
}
@@ -422,6 +424,85 @@
return -EFAULT;
}
+ /*
+ * No entries, then just load default
+ */
+ if ((nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency == 0) ||
+ (nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency == 0) ||
+ (nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency == 0)) {
+ nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency = NSS_FREQ_187;
+ nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency = NSS_FREQ_748;
+ nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency = NSS_FREQ_1497;
+ }
+
+ /*
+ * Test frequency from dtsi, if fail, try to set default frequency.
+ */
+ if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency)) {
+ if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, NSS_FREQ_1497)) {
+ return -EFAULT;
+ }
+ }
+
+ /*
+ * Setup ranges, test frequency, and display.
+ */
+ for (i = 0; i < NSS_FREQ_MAX_SCALE; i++) {
+ if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_187) {
+ nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_187_MIN;
+ nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_187_MAX;
+ } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_748) {
+ nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_748_MIN;
+ nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_748_MAX;
+ } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1497) {
+ nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_1497_MIN;
+ nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_1497_MAX;
+ } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1689) {
+ nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_1689_MIN;
+ nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_1689_MAX;
+ } else {
+ nss_info_always("Frequency not found %d", nss_runtime_samples.freq_scale[i].frequency);
+ return -EFAULT;
+ }
+
+ /*
+ * Test the frequency, if fail, then default to safe frequency and abort
+ */
+ if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[i].frequency)) {
+ return -EFAULT;
+ }
+ }
+
+ nss_info_always("Supported Frequencies - ");
+ for (i = 0; i < NSS_FREQ_MAX_SCALE; i++) {
+ if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_187) {
+ nss_info_always("187 MHz ");
+ } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_748) {
+ nss_info_always("748 MHz ");
+ } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1497) {
+ nss_info_always("1.4976 GHz ");
+ } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1689) {
+ nss_info_always("1.689 GHz ");
+ } else {
+ nss_info_always("Error\nNo Table/Invalid Frequency Found");
+ return -EFAULT;
+ }
+ }
+ nss_info_always("\n");
+
+ /*
+ * Set values only once for core0. Grab the proper clock.
+ */
+ if (nss_ctx->id) {
+ nss_core1_clk = clk_get(&nss_dev->dev, NSS_CORE_CLK);
+ } else {
+ nss_core0_clk = clk_get(&nss_dev->dev, NSS_CORE_CLK);
+ }
+
+ if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency)) {
+ return -EFAULT;
+ }
+
return 0;
}
@@ -517,6 +598,12 @@
err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue3", int_ctx);
}
+ if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_COREDUMP_COMPLETE) {
+ int_ctx->cause = NSS_N2H_INTR_COREDUMP_COMPLETE;
+ netif_napi_add(int_ctx->ndev, &int_ctx->napi, nss_core_handle_napi_emergency, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+ err = request_irq(irq, nss_hal_handle_irq, 0, "nss_coredump_complete", int_ctx);
+ }
+
if (err) {
return err;
}
@@ -542,4 +629,3 @@
.clear_interrupt_cause = __nss_hal_clear_interrupt_cause,
.read_interrupt_cause = __nss_hal_read_interrupt_cause,
};
-
diff --git a/nss_hal/nss_hal.c b/nss_hal/nss_hal.c
index d0959e9..28372f2 100644
--- a/nss_hal/nss_hal.c
+++ b/nss_hal/nss_hal.c
@@ -326,6 +326,8 @@
}
spin_lock_bh(&(nss_top->lock));
+ nss_top->num_pri = npd->num_pri;
+
/*
* Features that will always be enabled on both cores
*/
diff --git a/nss_init.c b/nss_init.c
index 826ca80..433d508 100644
--- a/nss_init.c
+++ b/nss_init.c
@@ -73,6 +73,7 @@
* Handler to send NSS messages
*/
struct clk *nss_core0_clk;
+struct clk *nss_core1_clk;
/*
* Handle fabric requests - only on new kernel
@@ -197,10 +198,14 @@
nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 0);
}
clk_set_rate(nss_core0_clk, my_work->frequency);
+
nss_freq_change(&nss_top_main.nss[NSS_CORE_0], my_work->frequency, my_work->stats_enable, 1);
if (nss_top_main.nss[NSS_CORE_1].state == NSS_CORE_STATE_INITIALIZED) {
nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 1);
}
+#if defined(NSS_HAL_IPQ807x_SUPPORT)
+ clk_set_rate(nss_core1_clk, my_work->frequency);
+#endif
/*
* If we are running NSS_PM_SUPPORT, we are on banana
diff --git a/nss_ipv4.c b/nss_ipv4.c
index 7930be3..b2b9e8a 100644
--- a/nss_ipv4.c
+++ b/nss_ipv4.c
@@ -55,6 +55,37 @@
EXPORT_SYMBOL(nss_ipv4_max_conn_count);
/*
+ * nss_ipv4_conn_inquiry()
+ * Inquiry if a connection has been established in NSS FW
+ */
+nss_tx_status_t nss_ipv4_conn_inquiry(struct nss_ipv4_5tuple *ipv4_5t_p,
+ nss_ipv4_msg_callback_t cb)
+{
+ nss_tx_status_t nss_tx_status;
+ struct nss_ipv4_msg nim;
+ struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[0];
+
+ /*
+ * Initialize inquiry message structure.
+ * This is async message and the result will be returned
+ * to the caller by the msg_callback passed in.
+ */
+ memset(&nim, 0, sizeof(nim));
+ nss_ipv4_msg_init(&nim, NSS_IPV4_RX_INTERFACE,
+ NSS_IPV4_TX_CONN_CFG_INQUIRY_MSG,
+ sizeof(struct nss_ipv4_inquiry_msg),
+ cb, NULL);
+ nim.msg.inquiry.rr.tuple = *ipv4_5t_p;
+ nss_tx_status = nss_ipv4_tx(nss_ctx, &nim);
+ if (nss_tx_status != NSS_TX_SUCCESS) {
+ nss_warning("%p: Send inquiry message failed\n", ipv4_5t_p);
+ }
+
+ return nss_tx_status;
+}
+EXPORT_SYMBOL(nss_ipv4_conn_inquiry);
+
+/*
* nss_ipv4_driver_conn_sync_update()
* Update driver specific information from the messsage.
*/
diff --git a/nss_ipv6.c b/nss_ipv6.c
index 430d260..c5a6590 100644
--- a/nss_ipv6.c
+++ b/nss_ipv6.c
@@ -54,6 +54,37 @@
EXPORT_SYMBOL(nss_ipv6_max_conn_count);
/*
+ * nss_ipv6_conn_inquiry()
+ * Inquiry if a connection has been established in NSS FW
+ */
+nss_tx_status_t nss_ipv6_conn_inquiry(struct nss_ipv6_5tuple *ipv6_5t_p,
+ nss_ipv6_msg_callback_t cb)
+{
+ nss_tx_status_t nss_tx_status;
+ struct nss_ipv6_msg nim;
+ struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[0];
+
+ /*
+ * Initialize inquiry message structure.
+ * This is async message and the result will be returned
+ * to the caller by the msg_callback passed in.
+ */
+ memset(&nim, 0, sizeof(nim));
+ nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE,
+ NSS_IPV6_TX_CONN_CFG_INQUIRY_MSG,
+ sizeof(struct nss_ipv6_inquiry_msg),
+ cb, NULL);
+ nim.msg.inquiry.rr.tuple = *ipv6_5t_p;
+ nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
+ if (nss_tx_status != NSS_TX_SUCCESS) {
+ nss_warning("%p: Send inquiry message failed\n", ipv6_5t_p);
+ }
+
+ return nss_tx_status;
+}
+EXPORT_SYMBOL(nss_ipv6_conn_inquiry);
+
+/*
* nss_ipv6_driver_conn_sync_update()
* Update driver specific information from the messsage.
*/
diff --git a/nss_map_t.c b/nss_map_t.c
index e88b369..b40f227 100644
--- a/nss_map_t.c
+++ b/nss_map_t.c
@@ -45,7 +45,7 @@
return false;
}
- if (nss_dynamic_interface_get_type(if_num)
+ if (nss_dynamic_interface_get_type(nss_map_t_get_context(), if_num)
!= NSS_DYNAMIC_INTERFACE_TYPE_MAP_T) {
return false;
}
diff --git a/nss_n2h.c b/nss_n2h.c
index 7981a01..f7a2717 100644
--- a/nss_n2h.c
+++ b/nss_n2h.c
@@ -777,6 +777,58 @@
}
/*
+ * nss_n2h_update_queue_config()
+ * Updates pnode queue configuration and limits
+ */
+nss_tx_status_t nss_n2h_update_queue_config(int max_pri, bool mq_en, int num_pri, int *qlimits)
+{
+ struct nss_n2h_msg nnm;
+ struct nss_n2h_pnode_queue_config *cfg;
+ nss_tx_status_t status;
+ struct nss_top_instance *nss_top = &nss_top_main;
+ struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
+ int i;
+
+ if (!mq_en) {
+ return NSS_TX_SUCCESS;
+ }
+
+ if (num_pri <= 0) {
+ nss_warning("%p: nss_tx error in pnode queue config param", nss_ctx);
+ return NSS_TX_FAILURE_BAD_PARAM;
+ }
+
+ if (max_pri < num_pri) {
+ nss_warning("%p: nss_tx error in pnode queue config param, maximum supported priority is %d", nss_ctx, max_pri);
+ return NSS_TX_FAILURE_BAD_PARAM;
+ }
+
+ cfg = &nnm.msg.pn_q_cfg;
+ cfg->num_pri = num_pri;
+ for (i = 0; i < num_pri; i++) {
+ cfg->qlimits[i] = qlimits[i];
+ }
+ cfg->mq_en = true;
+
+ /*
+ * Create message for FW
+ */
+ nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
+ NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG,
+ sizeof(struct nss_n2h_pnode_queue_config), NULL, 0);
+
+ status = nss_n2h_tx_msg(nss_ctx, &nnm);
+ if (status != NSS_TX_SUCCESS) {
+ nss_warning("%p: nss_tx error to send pnode queue config\n", nss_ctx);
+ return status;
+ }
+
+ return NSS_TX_SUCCESS;
+
+}
+EXPORT_SYMBOL(nss_n2h_update_queue_config);
+
+/*
* nss_n2h_rps_cfg()
* Send Message to NSS to enable RPS.
*/
@@ -1235,7 +1287,6 @@
{ }
};
-
static struct ctl_table nss_n2h_root_dir[] = {
{
.procname = "nss",
@@ -1334,7 +1385,6 @@
return NSS_TX_FAILURE;
}
-
nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
if (unlikely(!nbuf)) {
NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]);
diff --git a/nss_phys_if.c b/nss_phys_if.c
index 2f1cd2f..9752c36 100644
--- a/nss_phys_if.c
+++ b/nss_phys_if.c
@@ -20,6 +20,7 @@
*/
#include "nss_tx_rx_common.h"
+#include "nss_tstamp.h"
#define NSS_PHYS_IF_TX_TIMEOUT 3000 /* 3 Seconds */
@@ -169,9 +170,12 @@
return NSS_TX_FAILURE_NOT_READY;
}
- /* Check if we need the packet to be timestamped by GMAC Hardware at Tx */
+ /*
+ * If we need the packet to be timestamped by GMAC Hardware at Tx
+ * send the packet to tstamp NSS module
+ */
if (unlikely(skb_shinfo(os_buf)->tx_flags & SKBTX_HW_TSTAMP)) {
- flags |= H2N_BIT_FLAG_TX_TS_REQUIRED;
+ return nss_tstamp_tx_buf(nss_ctx, os_buf, if_num);
}
status = nss_core_send_buffer(nss_ctx, if_num, os_buf, NSS_IF_DATA_QUEUE_0, H2N_BUFFER_PACKET, flags);
@@ -190,6 +194,7 @@
nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_PACKET]);
+
return NSS_TX_SUCCESS;
}
diff --git a/nss_portid.c b/nss_portid.c
index cf317e6..bc9b30a 100644
--- a/nss_portid.c
+++ b/nss_portid.c
@@ -174,7 +174,7 @@
return false;
}
- if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_PORTID) {
+ if (nss_dynamic_interface_get_type(nss_portid_get_ctx(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_PORTID) {
return false;
}
diff --git a/nss_ppe.c b/nss_ppe.c
index 1ccd7d6..c66327e 100644
--- a/nss_ppe.c
+++ b/nss_ppe.c
@@ -158,13 +158,177 @@
}
/*
+ * nss_ppe_callback()
+ * Callback to handle the completion of NSS->HLOS messages.
+ */
+static void nss_ppe_callback(void *app_data, struct nss_ppe_msg *npm)
+{
+ nss_ppe_msg_callback_t callback = (nss_ppe_msg_callback_t)ppe_pvt.cb;
+ void *data = ppe_pvt.app_data;
+
+ ppe_pvt.response = NSS_TX_SUCCESS;
+ ppe_pvt.cb = NULL;
+ ppe_pvt.app_data = NULL;
+
+ if (npm->cm.response != NSS_CMN_RESPONSE_ACK) {
+ nss_warning("ppe error response %d\n", npm->cm.response);
+ ppe_pvt.response = npm->cm.response;
+ }
+
+ if (callback) {
+ callback(data, npm);
+ }
+ complete(&ppe_pvt.complete);
+}
+
+/*
+ * nss_ppe_tx_msg()
+ * Transmit a ppe message to NSSFW
+ */
+nss_tx_status_t nss_ppe_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *msg)
+{
+ struct nss_ppe_msg *nm;
+ struct nss_cmn_msg *ncm = &msg->cm;
+ struct sk_buff *nbuf;
+ int32_t status;
+
+ NSS_VERIFY_CTX_MAGIC(nss_ctx);
+ if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
+ nss_warning("%p: ppe msg dropped as core not ready\n", nss_ctx);
+ return NSS_TX_FAILURE_NOT_READY;
+ }
+
+ /*
+ * Sanity check the message
+ */
+ if (ncm->type >= NSS_PPE_MSG_MAX) {
+ nss_warning("%p: message type out of range: %d\n", nss_ctx, ncm->type);
+ return NSS_TX_FAILURE;
+ }
+
+ if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ppe_msg)) {
+ nss_warning("%p: message length is invalid: %d\n", nss_ctx, nss_cmn_get_msg_len(ncm));
+ return NSS_TX_FAILURE;
+ }
+
+ nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
+ if (unlikely(!nbuf)) {
+ NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]);
+ nss_warning("%p: msg dropped as command allocation failed\n", nss_ctx);
+ return NSS_TX_FAILURE;
+ }
+
+ /*
+ * Copy the message to our skb
+ */
+ nm = (struct nss_ppe_msg *)skb_put(nbuf, sizeof(struct nss_ppe_msg));
+ memcpy(nm, msg, sizeof(struct nss_ppe_msg));
+
+ status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
+ if (status != NSS_CORE_STATUS_SUCCESS) {
+ dev_kfree_skb_any(nbuf);
+ nss_warning("%p: Unable to enqueue 'ppe message'\n", nss_ctx);
+ return NSS_TX_FAILURE;
+ }
+
+ nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
+
+ NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
+ return NSS_TX_SUCCESS;
+}
+EXPORT_SYMBOL(nss_ppe_tx_msg);
+
+/*
+ * nss_ppe_tx_msg_sync()
+ * Transmit a ppe message to NSS firmware synchronously.
+ */
+nss_tx_status_t nss_ppe_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *npm)
+{
+ nss_tx_status_t status;
+ int ret = 0;
+
+ down(&ppe_pvt.sem);
+ ppe_pvt.cb = (void *)npm->cm.cb;
+ ppe_pvt.app_data = (void *)npm->cm.app_data;
+
+ npm->cm.cb = (nss_ptr_t)nss_ppe_callback;
+ npm->cm.app_data = (nss_ptr_t)NULL;
+
+ status = nss_ppe_tx_msg(nss_ctx, npm);
+ if (status != NSS_TX_SUCCESS) {
+ nss_warning("%p: ppe_tx_msg failed\n", nss_ctx);
+ up(&ppe_pvt.sem);
+ return status;
+ }
+
+ ret = wait_for_completion_timeout(&ppe_pvt.complete, msecs_to_jiffies(NSS_PPE_TX_TIMEOUT));
+ if (!ret) {
+ nss_warning("%p: ppe msg tx failed due to timeout\n", nss_ctx);
+ ppe_pvt.response = NSS_TX_FAILURE;
+ }
+
+ status = ppe_pvt.response;
+ up(&ppe_pvt.sem);
+ return status;
+}
+EXPORT_SYMBOL(nss_ppe_tx_msg_sync);
+
+/*
+ * nss_ppe_get_context()
+ * Get NSS context instance for ppe
+ */
+struct nss_ctx_instance *nss_ppe_get_context(void)
+{
+ return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.ppe_handler_id];
+}
+EXPORT_SYMBOL(nss_ppe_get_context);
+
+/*
+ * nss_ppe_msg_init()
+ * Initialize nss_ppe_msg.
+ */
+void nss_ppe_msg_init(struct nss_ppe_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data)
+{
+ nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data);
+}
+EXPORT_SYMBOL(nss_ppe_msg_init);
+
+/*
+ * nss_ppe_tx_l2_exception_msg
+ * API to send vsi assign message to NSS FW
+ */
+nss_tx_status_t nss_ppe_tx_l2_exception_msg(uint32_t if_num, bool exception_enable)
+{
+ struct nss_ctx_instance *nss_ctx = nss_ppe_get_context();
+ struct nss_ppe_msg npm;
+
+ if (!nss_ctx) {
+ nss_warning("Can't get nss context\n");
+ return NSS_TX_FAILURE;
+ }
+
+ if (!nss_ppe_verify_ifnum(if_num)) {
+ nss_warning("%p: invalid interface %d\n", nss_ctx, if_num);
+ return NSS_TX_FAILURE;
+ }
+
+ nss_ppe_msg_init(&npm, if_num, NSS_PPE_MSG_L2_EXCEPTION,
+ sizeof(struct nss_ppe_l2_exception_msg), NULL, NULL);
+
+ npm.msg.l2_exception.l2_exception_enable = exception_enable;
+
+ return nss_ppe_tx_msg_sync(nss_ctx, &npm);
+}
+EXPORT_SYMBOL(nss_ppe_tx_l2_exception_msg);
+
+/*
* nss_ppe_stats_conn_get()
* Get ppe connection stats.
*/
void nss_ppe_stats_conn_get(uint32_t *stats)
{
if (!stats) {
- nss_warning("No memory to copy ppe connection stats");
+ nss_warning("No memory to copy ppe connection stats\n");
return;
}
@@ -348,25 +512,28 @@
/*
* nss_ppe_handler()
- * Handle NSS -> HLOS messages for ppe tunnel
+ * Handle NSS -> HLOS messages for ppe
*/
static void nss_ppe_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data)
{
struct nss_ppe_msg *msg = (struct nss_ppe_msg *)ncm;
+ void *ctx;
- nss_trace("nss_ctx: %p ppe msg: %p", nss_ctx, msg);
+ nss_ppe_msg_callback_t cb;
+
+ nss_trace("nss_ctx: %p ppe msg: %p\n", nss_ctx, msg);
BUG_ON(!nss_ppe_verify_ifnum(ncm->interface));
/*
* Is this a valid request/response packet?
*/
if (ncm->type >= NSS_PPE_MSG_MAX) {
- nss_warning("%p: received invalid message %d for PPE interface", nss_ctx, ncm->type);
+ nss_warning("%p: received invalid message %d for PPE interface\n", nss_ctx, ncm->type);
return;
}
if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ppe_msg)) {
- nss_warning("%p: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
+ nss_warning("%p: Length of message is greater than required: %d\n", nss_ctx, nss_cmn_get_msg_len(ncm));
return;
}
@@ -376,19 +543,29 @@
* session debug stats embeded in session stats msg
*/
nss_ppe_stats_sync(nss_ctx, &msg->msg.stats, ncm->interface);
- break;
+ return;
}
-}
-/*
- * nss_ppe_get_context()
- * get NSS context instance for ppe
- */
-struct nss_ctx_instance *nss_ppe_get_context(void)
-{
- return &nss_top_main.nss[nss_top_main.ppe_handler_id];
+ /*
+ * Log failures
+ */
+ nss_core_log_msg_failures(nss_ctx, ncm);
+
+ /*
+ * Do we have a call back
+ */
+ if (!ncm->cb) {
+ return;
+ }
+
+ /*
+ * callback
+ */
+ cb = (nss_ppe_msg_callback_t)ncm->cb;
+ ctx = (void *)ncm->app_data;
+
+ cb(ctx, msg);
}
-EXPORT_SYMBOL(nss_ppe_get_context);
/*
* nss_ppe_register_handler()
@@ -456,4 +633,7 @@
nss_ppe_debug_stats.if_num = 0;
nss_ppe_debug_stats.if_index = 0;
spin_unlock_bh(&nss_ppe_stats_lock);
+
+ sema_init(&ppe_pvt.sem, 1);
+ init_completion(&ppe_pvt.complete);
}
diff --git a/nss_ppe.h b/nss_ppe.h
index d0889a5..7139819 100644
--- a/nss_ppe.h
+++ b/nss_ppe.h
@@ -68,6 +68,8 @@
#define PPE_DROP_CODE_IDX(code, src_port) (PPE_CPU_CODE_MAX_NUM + (8 * (code)) + (src_port))
#define PPE_DROP_CODE_OFFSET(code, src_port) (PPE_DROP_CPU_CNT_TBL_BASE_OFFSET + ((PPE_DROP_CODE_IDX(code, src_port)) * PPE_DROP_CPU_CNT_TBL_ENTRY_SIZE))
+#define NSS_PPE_TX_TIMEOUT 1000 /* 1 Second */
+
/*
* Data structures to store ppe nss debug stats
*/
@@ -79,6 +81,11 @@
*/
static struct nss_ppe_pvt {
void * __iomem ppe_base;
+ struct semaphore sem;
+ struct completion complete;
+ int response;
+ void *cb;
+ void *app_data;
} ppe_pvt;
/*
diff --git a/nss_stats.c b/nss_stats.c
index 6a22315..d8adebc 100644
--- a/nss_stats.c
+++ b/nss_stats.c
@@ -281,7 +281,8 @@
"tx_cmpl_buf_full_err",
"pkt_len_la64k_err",
"pkt_len_le33_err",
- "data_len_err"
+ "data_len_err",
+ "alloc_fail_cnt"
};
/*
@@ -3707,7 +3708,7 @@
continue;
}
- if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) {
+ if (nss_dynamic_interface_get_type(nss_capwap_get_ctx(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) {
continue;
}
@@ -3904,6 +3905,7 @@
static ssize_t nss_stats_wifi_if_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
{
struct nss_stats_data *data = fp->private_data;
+ struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
int32_t if_num = NSS_DYNAMIC_IF_START;
int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
size_t bytes = 0;
@@ -3920,7 +3922,7 @@
}
for (; if_num < max_if_num; if_num++) {
- if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_WIFI)
+ if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_WIFI)
continue;
bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
@@ -3985,6 +3987,7 @@
size_t sz, loff_t *ppos)
{
struct nss_stats_data *data = fp->private_data;
+ struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
int32_t if_num = NSS_DYNAMIC_IF_START;
int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
size_t bytes = 0;
@@ -4001,7 +4004,7 @@
}
for (; if_num < max_if_num; if_num++) {
- if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR)
+ if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR)
continue;
bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
@@ -4066,6 +4069,7 @@
size_t sz, loff_t *ppos)
{
struct nss_stats_data *data = fp->private_data;
+ struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
int32_t if_num = NSS_DYNAMIC_IF_START;
int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
size_t bytes = 0;
@@ -4082,7 +4086,7 @@
}
for (; if_num < max_if_num; if_num++) {
- if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED)
+ if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED)
continue;
bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
diff --git a/nss_tstamp.c b/nss_tstamp.c
index a59e286..ba04b35 100644
--- a/nss_tstamp.c
+++ b/nss_tstamp.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2015, 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, 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
* above copyright notice and this permission notice appear in all copies.
@@ -19,24 +19,26 @@
* NSS Tstamp APIs
*/
-#include "nss_tx_rx_common.h"
+#include <linux/ip.h>
+#include <linux/ipv6.h>
#include <linux/etherdevice.h>
+#include <linux/netdevice.h>
+#include <net/route.h>
+#include <net/ip6_route.h>
+#include "nss_tx_rx_common.h"
+#include "nss_tstamp.h"
+
+#define NSS_TSTAMP_HEADER_SIZE max(sizeof(struct nss_tstamp_h2n_pre_hdr), sizeof(struct nss_tstamp_n2h_pre_hdr))
static struct net_device_stats *nss_tstamp_ndev_stats(struct net_device *ndev);
+/*
+ * dummy netdevice ops
+ */
static const struct net_device_ops nss_tstamp_ndev_ops = {
.ndo_get_stats = nss_tstamp_ndev_stats,
};
-struct nss_tstamp_data {
- uint32_t ts_ifnum; /* time stamp interface number */
- uint32_t ts_data_lo; /* time stamp lower order bits */
- uint32_t ts_data_hi; /* time stamp higher order bits */
-
- uint8_t ts_tx; /* time stamp direction */
- uint8_t ts_hdr_sz; /* padding bytes */
-};
-
/*
* nss_tstamp_ndev_setup()
* Dummy setup for net_device handler
@@ -53,13 +55,13 @@
static struct net_device_stats *nss_tstamp_ndev_stats(struct net_device *ndev)
{
return &ndev->stats;
-};
+}
/*
* nss_tstamp_copy_data()
* Copy timestamps from received nss frame into skb
*/
-static void nss_tstamp_copy_data(struct nss_tstamp_data *ntm, struct sk_buff *skb)
+static void nss_tstamp_copy_data(struct nss_tstamp_n2h_pre_hdr *ntm, struct sk_buff *skb)
{
struct skb_shared_hwtstamps *tstamp;
@@ -71,39 +73,91 @@
}
/*
+ * nss_tstamp_get_dev()
+ * Get the net_device associated with the packet.
+ */
+static struct net_device *nss_tstamp_get_dev(struct sk_buff *skb)
+{
+ struct dst_entry *dst;
+ struct net_device *dev;
+ struct rtable *rt;
+ struct flowi6 fl6;
+ uint32_t ip_addr;
+
+ /*
+ * It seems like the data came over IPsec, hence indicate
+ * it to the Linux over this interface
+ */
+ skb_reset_network_header(skb);
+ skb_reset_mac_header(skb);
+
+ skb->pkt_type = PACKET_HOST;
+
+ switch (ip_hdr(skb)->version) {
+ case IPVERSION:
+ ip_addr = ip_hdr(skb)->saddr;
+
+ rt = ip_route_output(&init_net, ip_addr, 0, 0, 0);
+ if (IS_ERR(rt)) {
+ return NULL;
+ }
+
+ dst = (struct dst_entry *)rt;
+ skb->protocol = cpu_to_be16(ETH_P_IP);
+ break;
+
+ case 6:
+ memset(&fl6, 0, sizeof(fl6));
+ memcpy(&fl6.daddr, &ipv6_hdr(skb)->saddr, sizeof(fl6.daddr));
+
+ dst = ip6_route_output(&init_net, NULL, &fl6);
+ if (IS_ERR(dst)) {
+ return NULL;
+ }
+
+ skb->protocol = cpu_to_be16(ETH_P_IPV6);
+ break;
+
+ default:
+ nss_warning("%p:could not get dev for the skb\n", skb);
+ return NULL;
+ }
+
+ dev = dst->dev;
+ dev_hold(dev);
+
+ dst_release(dst);
+ return dev;
+}
+
+/*
* nss_tstamp_buf_receive()
* Receive nss exception packets.
*/
static void nss_tstamp_buf_receive(struct net_device *ndev, struct sk_buff *skb, struct napi_struct *napi)
{
- struct nss_tstamp_data *ntm = (struct nss_tstamp_data *)skb->data;
+ struct nss_tstamp_n2h_pre_hdr *n2h_hdr = (struct nss_tstamp_n2h_pre_hdr *)skb->data;
struct nss_ctx_instance *nss_ctx;
struct net_device *dev;
uint32_t tstamp_sz;
- BUG_ON(!ntm);
- tstamp_sz = ntm->ts_hdr_sz;
+ BUG_ON(!n2h_hdr);
+
+ tstamp_sz = n2h_hdr->ts_hdr_sz;
+ if (tstamp_sz > (NSS_TSTAMP_HEADER_SIZE + sizeof(uint32_t))) {
+ goto free;
+ }
nss_ctx = &nss_top_main.nss[nss_top_main.tstamp_handler_id];
BUG_ON(!nss_ctx);
- skb_pull(skb, tstamp_sz);
-
- dev = nss_cmn_get_interface_dev(nss_ctx, ntm->ts_ifnum);
- if (!dev) {
- nss_warning("Tstamp: Invalid net device\n");
- dev_kfree_skb_any(skb);
- return;
- }
-
- skb->dev = dev;
+ skb_pull_inline(skb, tstamp_sz);
/*
* copy the time stamp and convert into ktime_t
*/
- nss_tstamp_copy_data(ntm, skb);
-
- if (unlikely(ntm->ts_tx)) {
+ nss_tstamp_copy_data(n2h_hdr, skb);
+ if (unlikely(n2h_hdr->ts_tx)) {
/*
* We are in TX Path
*/
@@ -111,26 +165,34 @@
ndev->stats.tx_packets++;
ndev->stats.tx_bytes += skb->len;
-
- dev_kfree_skb_any(skb);
- return;
+ goto free;
}
/*
- * We are in RX Path
+ * We are in RX path.
*/
+ dev = nss_cmn_get_interface_dev(nss_ctx, n2h_hdr->ts_ifnum);
+ if (!dev) {
+ ndev->stats.rx_dropped++;
+ goto free;
+ }
+
+ /*
+ * Hold the dev until we finish
+ */
+ dev_hold(dev);
+
switch(dev->type) {
case NSS_IPSEC_ARPHRD_IPSEC:
/*
- * It seems like the data came over IPsec, hence indicate
- * it to the Linux over this interface
+ * Release the prev dev reference
*/
- skb_reset_network_header(skb);
- skb_reset_mac_header(skb);
+ dev_put(dev);
- skb->pkt_type = PACKET_HOST;
- skb->protocol = cpu_to_be16(ETH_P_IP);
- skb->skb_iif = dev->ifindex;
+ /*
+ * find the actual IPsec tunnel device
+ */
+ dev = nss_tstamp_get_dev(skb);
break;
default:
@@ -141,14 +203,27 @@
break;
}
- netif_receive_skb(skb);
+ skb->skb_iif = dev->ifindex;
+ skb->dev = dev;
ndev->stats.rx_packets++;
ndev->stats.rx_bytes += skb->len;
+
+ netif_receive_skb(skb);
+
+ /*
+ * release the device as we are done
+ */
+ dev_put(dev);
+ return;
+free:
+ dev_kfree_skb_any(skb);
+ return;
}
/*
* nss_tstamp_register_netdev()
+ * register dummy netdevice for tstamp interface
*/
struct net_device *nss_tstamp_register_netdev(void)
{
@@ -192,4 +267,66 @@
nss_ctx->subsys_dp_register[NSS_TSTAMP_INTERFACE].features = features;
}
+/*
+ * nss_tstamp_tx_buf()
+ * Send data packet for tstamp processing
+ */
+nss_tx_status_t nss_tstamp_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *skb, uint32_t if_num)
+{
+ struct nss_tstamp_h2n_pre_hdr *h2n_hdr;
+ nss_tx_status_t status;
+ bool expand_head;
+ char *align_data;
+ uint32_t hdr_sz;
+
+ nss_trace("%p: Tstamp If Tx packet, id:%d, data=%p", nss_ctx, NSS_TSTAMP_INTERFACE, skb->data);
+
+ if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
+ nss_trace("%p: tstamp tx_packet dropped as core is not ready", nss_ctx);
+ return NSS_TX_FAILURE_NOT_READY;
+ }
+
+ /*
+ * header size + alignment size
+ */
+ hdr_sz = NSS_TSTAMP_HEADER_SIZE + sizeof(uint32_t);
+ expand_head = (hdr_sz > skb_headroom(skb));
+
+ /*
+ * Expand the head for h2n_hdr
+ */
+ if (expand_head && pskb_expand_head(skb, hdr_sz, 0, GFP_KERNEL)) {
+ nss_trace("%p: expand head room failed", nss_ctx);
+ return NSS_TX_FAILURE;
+ }
+
+ align_data = PTR_ALIGN((skb->data - hdr_sz), sizeof(uint32_t));
+ hdr_sz = (nss_ptr_t)skb->data - (nss_ptr_t)align_data;
+
+ h2n_hdr = (struct nss_tstamp_h2n_pre_hdr *)skb_push(skb, hdr_sz);
+ h2n_hdr->ts_ifnum = if_num;
+ h2n_hdr->ts_tx_hdr_sz = hdr_sz;
+
+ status = nss_core_send_buffer(nss_ctx, NSS_TSTAMP_INTERFACE, skb, NSS_IF_DATA_QUEUE_0,
+ H2N_BUFFER_PACKET, H2N_BIT_FLAG_VIRTUAL_BUFFER);
+
+ switch (status) {
+ case NSS_CORE_STATUS_SUCCESS:
+ /*
+ * Kick the NSS awake so it can process our new entry.
+ */
+ nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
+ NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_PACKET]);
+ break;
+
+ case NSS_CORE_STATUS_FAILURE_QUEUE:
+ return NSS_TX_FAILURE_QUEUE;
+
+ default:
+ return NSS_TX_FAILURE;
+ }
+
+ return NSS_TX_SUCCESS;
+}
+EXPORT_SYMBOL(nss_tstamp_tx_buf);
diff --git a/nss_vlan.c b/nss_vlan.c
index d562127..1fd5d3f 100644
--- a/nss_vlan.c
+++ b/nss_vlan.c
@@ -30,6 +30,15 @@
} vlan_pvt;
/*
+ * nss_vlan_get_context()
+ */
+struct nss_ctx_instance *nss_vlan_get_context(void)
+{
+ return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.vlan_handler_id];
+}
+EXPORT_SYMBOL(nss_vlan_get_context);
+
+/*
* nss_vlan_verify_if_num()
* Verify if_num passed to us.
*/
@@ -39,7 +48,7 @@
return false;
}
- if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_VLAN) {
+ if (nss_dynamic_interface_get_type(nss_vlan_get_context(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_VLAN) {
return false;
}
@@ -220,15 +229,6 @@
EXPORT_SYMBOL(nss_vlan_tx_msg_sync);
/*
- * nss_vlan_get_context()
- */
-struct nss_ctx_instance *nss_vlan_get_context(void)
-{
- return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.vlan_handler_id];
-}
-EXPORT_SYMBOL(nss_vlan_get_context);
-
-/*
* nss_vlan_msg_init()
* Initialize nss_vlan_msg.
*/