xref: /dpdk/drivers/net/qede/qede_ethdev.c (revision 1ef4c3a5c1f76b810620b76d82a31ce33a83d3fe)
12ea6f76aSRasesh Mody /*
22ea6f76aSRasesh Mody  * Copyright (c) 2016 QLogic Corporation.
32ea6f76aSRasesh Mody  * All rights reserved.
42ea6f76aSRasesh Mody  * www.qlogic.com
52ea6f76aSRasesh Mody  *
62ea6f76aSRasesh Mody  * See LICENSE.qede_pmd for copyright and licensing details.
72ea6f76aSRasesh Mody  */
82ea6f76aSRasesh Mody 
92ea6f76aSRasesh Mody #include "qede_ethdev.h"
102af14ca7SHarish Patil #include <rte_alarm.h>
117eca78ceSHarish Patil #include <rte_version.h>
122ea6f76aSRasesh Mody 
132ea6f76aSRasesh Mody /* Globals */
142ea6f76aSRasesh Mody static const struct qed_eth_ops *qed_ops;
152af14ca7SHarish Patil static int64_t timer_period = 1;
162ea6f76aSRasesh Mody 
1752d94b57SHarish Patil /* VXLAN tunnel classification mapping */
1852d94b57SHarish Patil const struct _qede_vxlan_tunn_types {
1952d94b57SHarish Patil 	uint16_t rte_filter_type;
2052d94b57SHarish Patil 	enum ecore_filter_ucast_type qede_type;
2152d94b57SHarish Patil 	enum ecore_tunn_clss qede_tunn_clss;
2252d94b57SHarish Patil 	const char *string;
2352d94b57SHarish Patil } qede_tunn_types[] = {
2452d94b57SHarish Patil 	{
2552d94b57SHarish Patil 		ETH_TUNNEL_FILTER_OMAC,
2652d94b57SHarish Patil 		ECORE_FILTER_MAC,
2752d94b57SHarish Patil 		ECORE_TUNN_CLSS_MAC_VLAN,
2852d94b57SHarish Patil 		"outer-mac"
2952d94b57SHarish Patil 	},
3052d94b57SHarish Patil 	{
3152d94b57SHarish Patil 		ETH_TUNNEL_FILTER_TENID,
3252d94b57SHarish Patil 		ECORE_FILTER_VNI,
3352d94b57SHarish Patil 		ECORE_TUNN_CLSS_MAC_VNI,
3452d94b57SHarish Patil 		"vni"
3552d94b57SHarish Patil 	},
3652d94b57SHarish Patil 	{
3752d94b57SHarish Patil 		ETH_TUNNEL_FILTER_IMAC,
3852d94b57SHarish Patil 		ECORE_FILTER_INNER_MAC,
3952d94b57SHarish Patil 		ECORE_TUNN_CLSS_INNER_MAC_VLAN,
4052d94b57SHarish Patil 		"inner-mac"
4152d94b57SHarish Patil 	},
4252d94b57SHarish Patil 	{
4352d94b57SHarish Patil 		ETH_TUNNEL_FILTER_IVLAN,
4452d94b57SHarish Patil 		ECORE_FILTER_INNER_VLAN,
4552d94b57SHarish Patil 		ECORE_TUNN_CLSS_INNER_MAC_VLAN,
4652d94b57SHarish Patil 		"inner-vlan"
4752d94b57SHarish Patil 	},
4852d94b57SHarish Patil 	{
4952d94b57SHarish Patil 		ETH_TUNNEL_FILTER_OMAC | ETH_TUNNEL_FILTER_TENID,
5052d94b57SHarish Patil 		ECORE_FILTER_MAC_VNI_PAIR,
5152d94b57SHarish Patil 		ECORE_TUNN_CLSS_MAC_VNI,
5252d94b57SHarish Patil 		"outer-mac and vni"
5352d94b57SHarish Patil 	},
5452d94b57SHarish Patil 	{
5552d94b57SHarish Patil 		ETH_TUNNEL_FILTER_OMAC | ETH_TUNNEL_FILTER_IMAC,
5652d94b57SHarish Patil 		ECORE_FILTER_UNUSED,
5752d94b57SHarish Patil 		MAX_ECORE_TUNN_CLSS,
5852d94b57SHarish Patil 		"outer-mac and inner-mac"
5952d94b57SHarish Patil 	},
6052d94b57SHarish Patil 	{
6152d94b57SHarish Patil 		ETH_TUNNEL_FILTER_OMAC | ETH_TUNNEL_FILTER_IVLAN,
6252d94b57SHarish Patil 		ECORE_FILTER_UNUSED,
6352d94b57SHarish Patil 		MAX_ECORE_TUNN_CLSS,
6452d94b57SHarish Patil 		"outer-mac and inner-vlan"
6552d94b57SHarish Patil 	},
6652d94b57SHarish Patil 	{
6752d94b57SHarish Patil 		ETH_TUNNEL_FILTER_TENID | ETH_TUNNEL_FILTER_IMAC,
6852d94b57SHarish Patil 		ECORE_FILTER_INNER_MAC_VNI_PAIR,
6952d94b57SHarish Patil 		ECORE_TUNN_CLSS_INNER_MAC_VNI,
7052d94b57SHarish Patil 		"vni and inner-mac",
7152d94b57SHarish Patil 	},
7252d94b57SHarish Patil 	{
7352d94b57SHarish Patil 		ETH_TUNNEL_FILTER_TENID | ETH_TUNNEL_FILTER_IVLAN,
7452d94b57SHarish Patil 		ECORE_FILTER_UNUSED,
7552d94b57SHarish Patil 		MAX_ECORE_TUNN_CLSS,
7652d94b57SHarish Patil 		"vni and inner-vlan",
7752d94b57SHarish Patil 	},
7852d94b57SHarish Patil 	{
7952d94b57SHarish Patil 		ETH_TUNNEL_FILTER_IMAC | ETH_TUNNEL_FILTER_IVLAN,
8052d94b57SHarish Patil 		ECORE_FILTER_INNER_PAIR,
8152d94b57SHarish Patil 		ECORE_TUNN_CLSS_INNER_MAC_VLAN,
8252d94b57SHarish Patil 		"inner-mac and inner-vlan",
8352d94b57SHarish Patil 	},
8452d94b57SHarish Patil 	{
8552d94b57SHarish Patil 		ETH_TUNNEL_FILTER_OIP,
8652d94b57SHarish Patil 		ECORE_FILTER_UNUSED,
8752d94b57SHarish Patil 		MAX_ECORE_TUNN_CLSS,
8852d94b57SHarish Patil 		"outer-IP"
8952d94b57SHarish Patil 	},
9052d94b57SHarish Patil 	{
9152d94b57SHarish Patil 		ETH_TUNNEL_FILTER_IIP,
9252d94b57SHarish Patil 		ECORE_FILTER_UNUSED,
9352d94b57SHarish Patil 		MAX_ECORE_TUNN_CLSS,
9452d94b57SHarish Patil 		"inner-IP"
9552d94b57SHarish Patil 	},
9652d94b57SHarish Patil 	{
9752d94b57SHarish Patil 		RTE_TUNNEL_FILTER_IMAC_IVLAN,
9852d94b57SHarish Patil 		ECORE_FILTER_UNUSED,
9952d94b57SHarish Patil 		MAX_ECORE_TUNN_CLSS,
10052d94b57SHarish Patil 		"IMAC_IVLAN"
10152d94b57SHarish Patil 	},
10252d94b57SHarish Patil 	{
10352d94b57SHarish Patil 		RTE_TUNNEL_FILTER_IMAC_IVLAN_TENID,
10452d94b57SHarish Patil 		ECORE_FILTER_UNUSED,
10552d94b57SHarish Patil 		MAX_ECORE_TUNN_CLSS,
10652d94b57SHarish Patil 		"IMAC_IVLAN_TENID"
10752d94b57SHarish Patil 	},
10852d94b57SHarish Patil 	{
10952d94b57SHarish Patil 		RTE_TUNNEL_FILTER_IMAC_TENID,
11052d94b57SHarish Patil 		ECORE_FILTER_UNUSED,
11152d94b57SHarish Patil 		MAX_ECORE_TUNN_CLSS,
11252d94b57SHarish Patil 		"IMAC_TENID"
11352d94b57SHarish Patil 	},
11452d94b57SHarish Patil 	{
11552d94b57SHarish Patil 		RTE_TUNNEL_FILTER_OMAC_TENID_IMAC,
11652d94b57SHarish Patil 		ECORE_FILTER_UNUSED,
11752d94b57SHarish Patil 		MAX_ECORE_TUNN_CLSS,
11852d94b57SHarish Patil 		"OMAC_TENID_IMAC"
11952d94b57SHarish Patil 	},
12052d94b57SHarish Patil };
12152d94b57SHarish Patil 
122d1216e22SRasesh Mody struct rte_qede_xstats_name_off {
123d1216e22SRasesh Mody 	char name[RTE_ETH_XSTATS_NAME_SIZE];
124d1216e22SRasesh Mody 	uint64_t offset;
125d1216e22SRasesh Mody };
126d1216e22SRasesh Mody 
127d1216e22SRasesh Mody static const struct rte_qede_xstats_name_off qede_xstats_strings[] = {
128d1216e22SRasesh Mody 	{"rx_unicast_bytes", offsetof(struct ecore_eth_stats, rx_ucast_bytes)},
129d1216e22SRasesh Mody 	{"rx_multicast_bytes",
130d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_mcast_bytes)},
131d1216e22SRasesh Mody 	{"rx_broadcast_bytes",
132d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_bcast_bytes)},
133d1216e22SRasesh Mody 	{"rx_unicast_packets", offsetof(struct ecore_eth_stats, rx_ucast_pkts)},
134d1216e22SRasesh Mody 	{"rx_multicast_packets",
135d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_mcast_pkts)},
136d1216e22SRasesh Mody 	{"rx_broadcast_packets",
137d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_bcast_pkts)},
138d1216e22SRasesh Mody 
139d1216e22SRasesh Mody 	{"tx_unicast_bytes", offsetof(struct ecore_eth_stats, tx_ucast_bytes)},
140d1216e22SRasesh Mody 	{"tx_multicast_bytes",
141d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_mcast_bytes)},
142d1216e22SRasesh Mody 	{"tx_broadcast_bytes",
143d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_bcast_bytes)},
144d1216e22SRasesh Mody 	{"tx_unicast_packets", offsetof(struct ecore_eth_stats, tx_ucast_pkts)},
145d1216e22SRasesh Mody 	{"tx_multicast_packets",
146d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_mcast_pkts)},
147d1216e22SRasesh Mody 	{"tx_broadcast_packets",
148d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_bcast_pkts)},
149d1216e22SRasesh Mody 
150d1216e22SRasesh Mody 	{"rx_64_byte_packets",
151d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_64_byte_packets)},
152d1216e22SRasesh Mody 	{"rx_65_to_127_byte_packets",
153d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_65_to_127_byte_packets)},
154d1216e22SRasesh Mody 	{"rx_128_to_255_byte_packets",
155d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_128_to_255_byte_packets)},
156d1216e22SRasesh Mody 	{"rx_256_to_511_byte_packets",
157d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_256_to_511_byte_packets)},
158d1216e22SRasesh Mody 	{"rx_512_to_1023_byte_packets",
159d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_512_to_1023_byte_packets)},
160d1216e22SRasesh Mody 	{"rx_1024_to_1518_byte_packets",
161d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_1024_to_1518_byte_packets)},
162d1216e22SRasesh Mody 	{"rx_1519_to_1522_byte_packets",
163d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_1519_to_1522_byte_packets)},
164d1216e22SRasesh Mody 	{"rx_1519_to_2047_byte_packets",
165d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_1519_to_2047_byte_packets)},
166d1216e22SRasesh Mody 	{"rx_2048_to_4095_byte_packets",
167d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_2048_to_4095_byte_packets)},
168d1216e22SRasesh Mody 	{"rx_4096_to_9216_byte_packets",
169d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_4096_to_9216_byte_packets)},
170d1216e22SRasesh Mody 	{"rx_9217_to_16383_byte_packets",
171d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats,
172d1216e22SRasesh Mody 			 rx_9217_to_16383_byte_packets)},
173d1216e22SRasesh Mody 	{"tx_64_byte_packets",
174d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_64_byte_packets)},
175d1216e22SRasesh Mody 	{"tx_65_to_127_byte_packets",
176d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_65_to_127_byte_packets)},
177d1216e22SRasesh Mody 	{"tx_128_to_255_byte_packets",
178d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_128_to_255_byte_packets)},
179d1216e22SRasesh Mody 	{"tx_256_to_511_byte_packets",
180d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_256_to_511_byte_packets)},
181d1216e22SRasesh Mody 	{"tx_512_to_1023_byte_packets",
182d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_512_to_1023_byte_packets)},
183d1216e22SRasesh Mody 	{"tx_1024_to_1518_byte_packets",
184d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_1024_to_1518_byte_packets)},
185d1216e22SRasesh Mody 	{"trx_1519_to_1522_byte_packets",
186d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_1519_to_2047_byte_packets)},
187d1216e22SRasesh Mody 	{"tx_2048_to_4095_byte_packets",
188d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_2048_to_4095_byte_packets)},
189d1216e22SRasesh Mody 	{"tx_4096_to_9216_byte_packets",
190d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_4096_to_9216_byte_packets)},
191d1216e22SRasesh Mody 	{"tx_9217_to_16383_byte_packets",
192d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats,
193d1216e22SRasesh Mody 			 tx_9217_to_16383_byte_packets)},
194d1216e22SRasesh Mody 
195d1216e22SRasesh Mody 	{"rx_mac_crtl_frames",
196d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_mac_crtl_frames)},
197d1216e22SRasesh Mody 	{"tx_mac_control_frames",
198d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_mac_ctrl_frames)},
199d1216e22SRasesh Mody 	{"rx_pause_frames", offsetof(struct ecore_eth_stats, rx_pause_frames)},
200d1216e22SRasesh Mody 	{"tx_pause_frames", offsetof(struct ecore_eth_stats, tx_pause_frames)},
201d1216e22SRasesh Mody 	{"rx_priority_flow_control_frames",
202d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_pfc_frames)},
203d1216e22SRasesh Mody 	{"tx_priority_flow_control_frames",
204d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_pfc_frames)},
205d1216e22SRasesh Mody 
206d1216e22SRasesh Mody 	{"rx_crc_errors", offsetof(struct ecore_eth_stats, rx_crc_errors)},
207d1216e22SRasesh Mody 	{"rx_align_errors", offsetof(struct ecore_eth_stats, rx_align_errors)},
208d1216e22SRasesh Mody 	{"rx_carrier_errors",
209d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_carrier_errors)},
210d1216e22SRasesh Mody 	{"rx_oversize_packet_errors",
211d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_oversize_packets)},
212d1216e22SRasesh Mody 	{"rx_jabber_errors", offsetof(struct ecore_eth_stats, rx_jabbers)},
213d1216e22SRasesh Mody 	{"rx_undersize_packet_errors",
214d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_undersize_packets)},
215d1216e22SRasesh Mody 	{"rx_fragments", offsetof(struct ecore_eth_stats, rx_fragments)},
216d1216e22SRasesh Mody 	{"rx_host_buffer_not_available",
217d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, no_buff_discards)},
218d1216e22SRasesh Mody 	/* Number of packets discarded because they are bigger than MTU */
219d1216e22SRasesh Mody 	{"rx_packet_too_big_discards",
220d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, packet_too_big_discard)},
221d1216e22SRasesh Mody 	{"rx_ttl_zero_discards",
222d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, ttl0_discard)},
223d1216e22SRasesh Mody 	{"rx_multi_function_tag_filter_discards",
224d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, mftag_filter_discards)},
225d1216e22SRasesh Mody 	{"rx_mac_filter_discards",
226d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, mac_filter_discards)},
227d1216e22SRasesh Mody 	{"rx_hw_buffer_truncates",
228d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, brb_truncates)},
229d1216e22SRasesh Mody 	{"rx_hw_buffer_discards",
230d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, brb_discards)},
231d1216e22SRasesh Mody 	{"tx_lpi_entry_count",
232d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_lpi_entry_count)},
233d1216e22SRasesh Mody 	{"tx_total_collisions",
234d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_total_collisions)},
235d1216e22SRasesh Mody 	{"tx_error_drop_packets",
236d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_err_drop_pkts)},
237d1216e22SRasesh Mody 
238d1216e22SRasesh Mody 	{"rx_mac_bytes", offsetof(struct ecore_eth_stats, rx_mac_bytes)},
239d1216e22SRasesh Mody 	{"rx_mac_unicast_packets",
240d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_mac_uc_packets)},
241d1216e22SRasesh Mody 	{"rx_mac_multicast_packets",
242d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_mac_mc_packets)},
243d1216e22SRasesh Mody 	{"rx_mac_broadcast_packets",
244d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_mac_bc_packets)},
245d1216e22SRasesh Mody 	{"rx_mac_frames_ok",
246d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, rx_mac_frames_ok)},
247d1216e22SRasesh Mody 	{"tx_mac_bytes", offsetof(struct ecore_eth_stats, tx_mac_bytes)},
248d1216e22SRasesh Mody 	{"tx_mac_unicast_packets",
249d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_mac_uc_packets)},
250d1216e22SRasesh Mody 	{"tx_mac_multicast_packets",
251d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_mac_mc_packets)},
252d1216e22SRasesh Mody 	{"tx_mac_broadcast_packets",
253d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tx_mac_bc_packets)},
254d1216e22SRasesh Mody 
255d1216e22SRasesh Mody 	{"lro_coalesced_packets",
256d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tpa_coalesced_pkts)},
257d1216e22SRasesh Mody 	{"lro_coalesced_events",
258d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tpa_coalesced_events)},
259d1216e22SRasesh Mody 	{"lro_aborts_num",
260d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tpa_aborts_num)},
261d1216e22SRasesh Mody 	{"lro_not_coalesced_packets",
262d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tpa_not_coalesced_pkts)},
263d1216e22SRasesh Mody 	{"lro_coalesced_bytes",
264d1216e22SRasesh Mody 		offsetof(struct ecore_eth_stats, tpa_coalesced_bytes)},
265d1216e22SRasesh Mody };
266d1216e22SRasesh Mody 
2677634c5f9SRasesh Mody static const struct rte_qede_xstats_name_off qede_rxq_xstats_strings[] = {
2687634c5f9SRasesh Mody 	{"rx_q_segments",
2697634c5f9SRasesh Mody 		offsetof(struct qede_rx_queue, rx_segs)},
2707634c5f9SRasesh Mody 	{"rx_q_hw_errors",
2717634c5f9SRasesh Mody 		offsetof(struct qede_rx_queue, rx_hw_errors)},
2727634c5f9SRasesh Mody 	{"rx_q_allocation_errors",
2737634c5f9SRasesh Mody 		offsetof(struct qede_rx_queue, rx_alloc_errors)}
2747634c5f9SRasesh Mody };
2757634c5f9SRasesh Mody 
2762ea6f76aSRasesh Mody static void qede_interrupt_action(struct ecore_hwfn *p_hwfn)
2772ea6f76aSRasesh Mody {
2782ea6f76aSRasesh Mody 	ecore_int_sp_dpc((osal_int_ptr_t)(p_hwfn));
2792ea6f76aSRasesh Mody }
2802ea6f76aSRasesh Mody 
2812ea6f76aSRasesh Mody static void
282d4b7f673SJan Blunck qede_interrupt_handler(struct rte_intr_handle *handle, void *param)
2832ea6f76aSRasesh Mody {
2842ea6f76aSRasesh Mody 	struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
2852ea6f76aSRasesh Mody 	struct qede_dev *qdev = eth_dev->data->dev_private;
2862ea6f76aSRasesh Mody 	struct ecore_dev *edev = &qdev->edev;
2872ea6f76aSRasesh Mody 
2882ea6f76aSRasesh Mody 	qede_interrupt_action(ECORE_LEADING_HWFN(edev));
289d4b7f673SJan Blunck 	if (rte_intr_enable(handle))
2902ea6f76aSRasesh Mody 		DP_ERR(edev, "rte_intr_enable failed\n");
2912ea6f76aSRasesh Mody }
2922ea6f76aSRasesh Mody 
2932ea6f76aSRasesh Mody static void
2942ea6f76aSRasesh Mody qede_alloc_etherdev(struct qede_dev *qdev, struct qed_dev_eth_info *info)
2952ea6f76aSRasesh Mody {
2962ea6f76aSRasesh Mody 	rte_memcpy(&qdev->dev_info, info, sizeof(*info));
2972ea6f76aSRasesh Mody 	qdev->num_tc = qdev->dev_info.num_tc;
2982ea6f76aSRasesh Mody 	qdev->ops = qed_ops;
2992ea6f76aSRasesh Mody }
3002ea6f76aSRasesh Mody 
3012ea6f76aSRasesh Mody static void qede_print_adapter_info(struct qede_dev *qdev)
3022ea6f76aSRasesh Mody {
3032ea6f76aSRasesh Mody 	struct ecore_dev *edev = &qdev->edev;
3042ea6f76aSRasesh Mody 	struct qed_dev_info *info = &qdev->dev_info.common;
3057eca78ceSHarish Patil 	static char drv_ver[QEDE_PMD_DRV_VER_STR_SIZE];
3067eca78ceSHarish Patil 	static char ver_str[QEDE_PMD_DRV_VER_STR_SIZE];
3072ea6f76aSRasesh Mody 
3082ea6f76aSRasesh Mody 	DP_INFO(edev, "*********************************\n");
3097eca78ceSHarish Patil 	DP_INFO(edev, " DPDK version:%s\n", rte_version());
3102ea6f76aSRasesh Mody 	DP_INFO(edev, " Chip details : %s%d\n",
3112ea6f76aSRasesh Mody 		  ECORE_IS_BB(edev) ? "BB" : "AH",
3122ea6f76aSRasesh Mody 		  CHIP_REV_IS_A0(edev) ? 0 : 1);
3137eca78ceSHarish Patil 	snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%d.%d.%d.%d",
3147eca78ceSHarish Patil 		 info->fw_major, info->fw_minor, info->fw_rev, info->fw_eng);
3157eca78ceSHarish Patil 	snprintf(drv_ver, QEDE_PMD_DRV_VER_STR_SIZE, "%s_%s",
3167eca78ceSHarish Patil 		 ver_str, QEDE_PMD_VERSION);
3177eca78ceSHarish Patil 	DP_INFO(edev, " Driver version : %s\n", drv_ver);
3182ea6f76aSRasesh Mody 	DP_INFO(edev, " Firmware version : %s\n", ver_str);
3192ea6f76aSRasesh Mody 
3207eca78ceSHarish Patil 	snprintf(ver_str, MCP_DRV_VER_STR_SIZE,
3217eca78ceSHarish Patil 		 "%d.%d.%d.%d",
3222ea6f76aSRasesh Mody 		(info->mfw_rev >> 24) & 0xff,
3232ea6f76aSRasesh Mody 		(info->mfw_rev >> 16) & 0xff,
3242ea6f76aSRasesh Mody 		(info->mfw_rev >> 8) & 0xff, (info->mfw_rev) & 0xff);
3257eca78ceSHarish Patil 	DP_INFO(edev, " Management Firmware version : %s\n", ver_str);
3262ea6f76aSRasesh Mody 	DP_INFO(edev, " Firmware file : %s\n", fw_file);
3272ea6f76aSRasesh Mody 	DP_INFO(edev, "*********************************\n");
3282ea6f76aSRasesh Mody }
3292ea6f76aSRasesh Mody 
33077fac1b5SHarish Patil static void qede_set_ucast_cmn_params(struct ecore_filter_ucast *ucast)
3312ea6f76aSRasesh Mody {
33277fac1b5SHarish Patil 	memset(ucast, 0, sizeof(struct ecore_filter_ucast));
33377fac1b5SHarish Patil 	ucast->is_rx_filter = true;
33477fac1b5SHarish Patil 	ucast->is_tx_filter = true;
33577fac1b5SHarish Patil 	/* ucast->assert_on_error = true; - For debug */
33677fac1b5SHarish Patil }
3372ea6f76aSRasesh Mody 
3380b090fd3SRasesh Mody static void qede_set_cmn_tunn_param(struct ecore_tunnel_info *p_tunn,
3390b090fd3SRasesh Mody 				    uint8_t clss, bool mode, bool mask)
34052d94b57SHarish Patil {
3410b090fd3SRasesh Mody 	memset(p_tunn, 0, sizeof(struct ecore_tunnel_info));
3420b090fd3SRasesh Mody 	p_tunn->vxlan.b_update_mode = mode;
3430b090fd3SRasesh Mody 	p_tunn->vxlan.b_mode_enabled = mask;
3440b090fd3SRasesh Mody 	p_tunn->b_update_rx_cls = true;
3450b090fd3SRasesh Mody 	p_tunn->b_update_tx_cls = true;
3460b090fd3SRasesh Mody 	p_tunn->vxlan.tun_cls = clss;
34752d94b57SHarish Patil }
34852d94b57SHarish Patil 
34977fac1b5SHarish Patil static int
35077fac1b5SHarish Patil qede_ucast_filter(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast,
35177fac1b5SHarish Patil 		  bool add)
35277fac1b5SHarish Patil {
35377fac1b5SHarish Patil 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
35477fac1b5SHarish Patil 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
35577fac1b5SHarish Patil 	struct qede_ucast_entry *tmp = NULL;
35677fac1b5SHarish Patil 	struct qede_ucast_entry *u;
35777fac1b5SHarish Patil 	struct ether_addr *mac_addr;
35877fac1b5SHarish Patil 
35977fac1b5SHarish Patil 	mac_addr  = (struct ether_addr *)ucast->mac;
36077fac1b5SHarish Patil 	if (add) {
36177fac1b5SHarish Patil 		SLIST_FOREACH(tmp, &qdev->uc_list_head, list) {
36277fac1b5SHarish Patil 			if ((memcmp(mac_addr, &tmp->mac,
36377fac1b5SHarish Patil 				    ETHER_ADDR_LEN) == 0) &&
36477fac1b5SHarish Patil 			     ucast->vlan == tmp->vlan) {
36577fac1b5SHarish Patil 				DP_ERR(edev, "Unicast MAC is already added"
36677fac1b5SHarish Patil 				       " with vlan = %u, vni = %u\n",
36777fac1b5SHarish Patil 				       ucast->vlan,  ucast->vni);
36877fac1b5SHarish Patil 					return -EEXIST;
36977fac1b5SHarish Patil 			}
37077fac1b5SHarish Patil 		}
37177fac1b5SHarish Patil 		u = rte_malloc(NULL, sizeof(struct qede_ucast_entry),
37277fac1b5SHarish Patil 			       RTE_CACHE_LINE_SIZE);
37377fac1b5SHarish Patil 		if (!u) {
37477fac1b5SHarish Patil 			DP_ERR(edev, "Did not allocate memory for ucast\n");
37577fac1b5SHarish Patil 			return -ENOMEM;
37677fac1b5SHarish Patil 		}
37777fac1b5SHarish Patil 		ether_addr_copy(mac_addr, &u->mac);
37877fac1b5SHarish Patil 		u->vlan = ucast->vlan;
37952d94b57SHarish Patil 		u->vni = ucast->vni;
38077fac1b5SHarish Patil 		SLIST_INSERT_HEAD(&qdev->uc_list_head, u, list);
38177fac1b5SHarish Patil 		qdev->num_uc_addr++;
38277fac1b5SHarish Patil 	} else {
38377fac1b5SHarish Patil 		SLIST_FOREACH(tmp, &qdev->uc_list_head, list) {
38477fac1b5SHarish Patil 			if ((memcmp(mac_addr, &tmp->mac,
38577fac1b5SHarish Patil 				    ETHER_ADDR_LEN) == 0) &&
38652d94b57SHarish Patil 			    ucast->vlan == tmp->vlan	  &&
38752d94b57SHarish Patil 			    ucast->vni == tmp->vni)
38877fac1b5SHarish Patil 			break;
38977fac1b5SHarish Patil 		}
39077fac1b5SHarish Patil 		if (tmp == NULL) {
39177fac1b5SHarish Patil 			DP_INFO(edev, "Unicast MAC is not found\n");
39277fac1b5SHarish Patil 			return -EINVAL;
39377fac1b5SHarish Patil 		}
39477fac1b5SHarish Patil 		SLIST_REMOVE(&qdev->uc_list_head, tmp, qede_ucast_entry, list);
39577fac1b5SHarish Patil 		qdev->num_uc_addr--;
39677fac1b5SHarish Patil 	}
39777fac1b5SHarish Patil 
39877fac1b5SHarish Patil 	return 0;
39977fac1b5SHarish Patil }
40077fac1b5SHarish Patil 
40177fac1b5SHarish Patil static int
40277fac1b5SHarish Patil qede_mcast_filter(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *mcast,
40377fac1b5SHarish Patil 		  bool add)
40477fac1b5SHarish Patil {
40577fac1b5SHarish Patil 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
40677fac1b5SHarish Patil 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
40777fac1b5SHarish Patil 	struct ether_addr *mac_addr;
40877fac1b5SHarish Patil 	struct qede_mcast_entry *tmp = NULL;
40977fac1b5SHarish Patil 	struct qede_mcast_entry *m;
41077fac1b5SHarish Patil 
41177fac1b5SHarish Patil 	mac_addr  = (struct ether_addr *)mcast->mac;
41277fac1b5SHarish Patil 	if (add) {
41377fac1b5SHarish Patil 		SLIST_FOREACH(tmp, &qdev->mc_list_head, list) {
41477fac1b5SHarish Patil 			if (memcmp(mac_addr, &tmp->mac, ETHER_ADDR_LEN) == 0) {
41577fac1b5SHarish Patil 				DP_ERR(edev,
41677fac1b5SHarish Patil 					"Multicast MAC is already added\n");
41777fac1b5SHarish Patil 				return -EEXIST;
41877fac1b5SHarish Patil 			}
41977fac1b5SHarish Patil 		}
42077fac1b5SHarish Patil 		m = rte_malloc(NULL, sizeof(struct qede_mcast_entry),
42177fac1b5SHarish Patil 			RTE_CACHE_LINE_SIZE);
42277fac1b5SHarish Patil 		if (!m) {
42377fac1b5SHarish Patil 			DP_ERR(edev,
42477fac1b5SHarish Patil 				"Did not allocate memory for mcast\n");
42577fac1b5SHarish Patil 			return -ENOMEM;
42677fac1b5SHarish Patil 		}
42777fac1b5SHarish Patil 		ether_addr_copy(mac_addr, &m->mac);
42877fac1b5SHarish Patil 		SLIST_INSERT_HEAD(&qdev->mc_list_head, m, list);
42977fac1b5SHarish Patil 		qdev->num_mc_addr++;
43077fac1b5SHarish Patil 	} else {
43177fac1b5SHarish Patil 		SLIST_FOREACH(tmp, &qdev->mc_list_head, list) {
43277fac1b5SHarish Patil 			if (memcmp(mac_addr, &tmp->mac, ETHER_ADDR_LEN) == 0)
43377fac1b5SHarish Patil 				break;
43477fac1b5SHarish Patil 		}
43577fac1b5SHarish Patil 		if (tmp == NULL) {
43677fac1b5SHarish Patil 			DP_INFO(edev, "Multicast mac is not found\n");
43777fac1b5SHarish Patil 			return -EINVAL;
43877fac1b5SHarish Patil 		}
43977fac1b5SHarish Patil 		SLIST_REMOVE(&qdev->mc_list_head, tmp,
44077fac1b5SHarish Patil 			     qede_mcast_entry, list);
44177fac1b5SHarish Patil 		qdev->num_mc_addr--;
44277fac1b5SHarish Patil 	}
44377fac1b5SHarish Patil 
44477fac1b5SHarish Patil 	return 0;
44577fac1b5SHarish Patil }
44677fac1b5SHarish Patil 
44777fac1b5SHarish Patil static enum _ecore_status_t
44877fac1b5SHarish Patil qede_mac_int_ops(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast,
44977fac1b5SHarish Patil 		 bool add)
45077fac1b5SHarish Patil {
45177fac1b5SHarish Patil 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
45277fac1b5SHarish Patil 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
45377fac1b5SHarish Patil 	enum _ecore_status_t rc;
45477fac1b5SHarish Patil 	struct ecore_filter_mcast mcast;
45577fac1b5SHarish Patil 	struct qede_mcast_entry *tmp;
45677fac1b5SHarish Patil 	uint16_t j = 0;
45777fac1b5SHarish Patil 
45877fac1b5SHarish Patil 	/* Multicast */
45977fac1b5SHarish Patil 	if (is_multicast_ether_addr((struct ether_addr *)ucast->mac)) {
46077fac1b5SHarish Patil 		if (add) {
46177fac1b5SHarish Patil 			if (qdev->num_mc_addr >= ECORE_MAX_MC_ADDRS) {
46277fac1b5SHarish Patil 				DP_ERR(edev,
46377fac1b5SHarish Patil 				       "Mcast filter table limit exceeded, "
46477fac1b5SHarish Patil 				       "Please enable mcast promisc mode\n");
46577fac1b5SHarish Patil 				return -ECORE_INVAL;
46677fac1b5SHarish Patil 			}
46777fac1b5SHarish Patil 		}
46877fac1b5SHarish Patil 		rc = qede_mcast_filter(eth_dev, ucast, add);
46977fac1b5SHarish Patil 		if (rc == 0) {
47077fac1b5SHarish Patil 			DP_INFO(edev, "num_mc_addrs = %u\n", qdev->num_mc_addr);
47177fac1b5SHarish Patil 			memset(&mcast, 0, sizeof(mcast));
47277fac1b5SHarish Patil 			mcast.num_mc_addrs = qdev->num_mc_addr;
47377fac1b5SHarish Patil 			mcast.opcode = ECORE_FILTER_ADD;
47477fac1b5SHarish Patil 			SLIST_FOREACH(tmp, &qdev->mc_list_head, list) {
47577fac1b5SHarish Patil 				ether_addr_copy(&tmp->mac,
47677fac1b5SHarish Patil 					(struct ether_addr *)&mcast.mac[j]);
47777fac1b5SHarish Patil 				j++;
47877fac1b5SHarish Patil 			}
47977fac1b5SHarish Patil 			rc = ecore_filter_mcast_cmd(edev, &mcast,
48077fac1b5SHarish Patil 						    ECORE_SPQ_MODE_CB, NULL);
48177fac1b5SHarish Patil 		}
48277fac1b5SHarish Patil 		if (rc != ECORE_SUCCESS) {
48377fac1b5SHarish Patil 			DP_ERR(edev, "Failed to add multicast filter"
48477fac1b5SHarish Patil 			       " rc = %d, op = %d\n", rc, add);
48577fac1b5SHarish Patil 		}
48677fac1b5SHarish Patil 	} else { /* Unicast */
48777fac1b5SHarish Patil 		if (add) {
4883320ca8cSRasesh Mody 			if (qdev->num_uc_addr >=
4893320ca8cSRasesh Mody 			    qdev->dev_info.num_mac_filters) {
49077fac1b5SHarish Patil 				DP_ERR(edev,
49177fac1b5SHarish Patil 				       "Ucast filter table limit exceeded,"
49277fac1b5SHarish Patil 				       " Please enable promisc mode\n");
49377fac1b5SHarish Patil 				return -ECORE_INVAL;
49477fac1b5SHarish Patil 			}
49577fac1b5SHarish Patil 		}
49677fac1b5SHarish Patil 		rc = qede_ucast_filter(eth_dev, ucast, add);
49777fac1b5SHarish Patil 		if (rc == 0)
49877fac1b5SHarish Patil 			rc = ecore_filter_ucast_cmd(edev, ucast,
49977fac1b5SHarish Patil 						    ECORE_SPQ_MODE_CB, NULL);
50077fac1b5SHarish Patil 		if (rc != ECORE_SUCCESS) {
50177fac1b5SHarish Patil 			DP_ERR(edev, "MAC filter failed, rc = %d, op = %d\n",
50277fac1b5SHarish Patil 			       rc, add);
50377fac1b5SHarish Patil 		}
50477fac1b5SHarish Patil 	}
50577fac1b5SHarish Patil 
50677fac1b5SHarish Patil 	return rc;
5072ea6f76aSRasesh Mody }
5082ea6f76aSRasesh Mody 
5092ea6f76aSRasesh Mody static void
5102ea6f76aSRasesh Mody qede_mac_addr_add(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr,
5112ea6f76aSRasesh Mody 		  uint32_t index, __rte_unused uint32_t pool)
5122ea6f76aSRasesh Mody {
51377fac1b5SHarish Patil 	struct ecore_filter_ucast ucast;
5142ea6f76aSRasesh Mody 
51577fac1b5SHarish Patil 	qede_set_ucast_cmn_params(&ucast);
51677fac1b5SHarish Patil 	ucast.type = ECORE_FILTER_MAC;
51777fac1b5SHarish Patil 	ether_addr_copy(mac_addr, (struct ether_addr *)&ucast.mac);
51877fac1b5SHarish Patil 	(void)qede_mac_int_ops(eth_dev, &ucast, 1);
5192ea6f76aSRasesh Mody }
5202ea6f76aSRasesh Mody 
5212ea6f76aSRasesh Mody static void
5222ea6f76aSRasesh Mody qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index)
5232ea6f76aSRasesh Mody {
5242ea6f76aSRasesh Mody 	struct qede_dev *qdev = eth_dev->data->dev_private;
5252ea6f76aSRasesh Mody 	struct ecore_dev *edev = &qdev->edev;
5262ea6f76aSRasesh Mody 	struct ether_addr mac_addr;
52777fac1b5SHarish Patil 	struct ecore_filter_ucast ucast;
5282ea6f76aSRasesh Mody 	int rc;
5292ea6f76aSRasesh Mody 
5302ea6f76aSRasesh Mody 	PMD_INIT_FUNC_TRACE(edev);
5312ea6f76aSRasesh Mody 
5323320ca8cSRasesh Mody 	if (index >= qdev->dev_info.num_mac_filters) {
5332ea6f76aSRasesh Mody 		DP_ERR(edev, "Index %u is above MAC filter limit %u\n",
5343320ca8cSRasesh Mody 		       index, qdev->dev_info.num_mac_filters);
5352ea6f76aSRasesh Mody 		return;
5362ea6f76aSRasesh Mody 	}
5372ea6f76aSRasesh Mody 
53877fac1b5SHarish Patil 	qede_set_ucast_cmn_params(&ucast);
53977fac1b5SHarish Patil 	ucast.opcode = ECORE_FILTER_REMOVE;
54077fac1b5SHarish Patil 	ucast.type = ECORE_FILTER_MAC;
54177fac1b5SHarish Patil 
5422ea6f76aSRasesh Mody 	/* Use the index maintained by rte */
54377fac1b5SHarish Patil 	ether_addr_copy(&eth_dev->data->mac_addrs[index],
54477fac1b5SHarish Patil 			(struct ether_addr *)&ucast.mac);
54577fac1b5SHarish Patil 
54677fac1b5SHarish Patil 	ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
5472ea6f76aSRasesh Mody }
5482ea6f76aSRasesh Mody 
5492ea6f76aSRasesh Mody static void
5502ea6f76aSRasesh Mody qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
5512ea6f76aSRasesh Mody {
5522ea6f76aSRasesh Mody 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
5532ea6f76aSRasesh Mody 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
55477fac1b5SHarish Patil 	struct ecore_filter_ucast ucast;
5552ea6f76aSRasesh Mody 	int rc;
5562ea6f76aSRasesh Mody 
55786a2265eSRasesh Mody 	if (IS_VF(edev) && !ecore_vf_check_mac(ECORE_LEADING_HWFN(edev),
55886a2265eSRasesh Mody 					       mac_addr->addr_bytes)) {
55986a2265eSRasesh Mody 		DP_ERR(edev, "Setting MAC address is not allowed\n");
56086a2265eSRasesh Mody 		ether_addr_copy(&qdev->primary_mac,
56186a2265eSRasesh Mody 				&eth_dev->data->mac_addrs[0]);
56286a2265eSRasesh Mody 		return;
56386a2265eSRasesh Mody 	}
56486a2265eSRasesh Mody 
5652ea6f76aSRasesh Mody 	/* First remove the primary mac */
56677fac1b5SHarish Patil 	qede_set_ucast_cmn_params(&ucast);
56777fac1b5SHarish Patil 	ucast.opcode = ECORE_FILTER_REMOVE;
56877fac1b5SHarish Patil 	ucast.type = ECORE_FILTER_MAC;
56977fac1b5SHarish Patil 	ether_addr_copy(&qdev->primary_mac,
57077fac1b5SHarish Patil 			(struct ether_addr *)&ucast.mac);
57177fac1b5SHarish Patil 	rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
57277fac1b5SHarish Patil 	if (rc != 0) {
5732ea6f76aSRasesh Mody 		DP_ERR(edev, "Unable to remove current macaddr"
5742ea6f76aSRasesh Mody 			     " Reverting to previous default mac\n");
5752ea6f76aSRasesh Mody 		ether_addr_copy(&qdev->primary_mac,
5762ea6f76aSRasesh Mody 				&eth_dev->data->mac_addrs[0]);
5772ea6f76aSRasesh Mody 		return;
5782ea6f76aSRasesh Mody 	}
5792ea6f76aSRasesh Mody 
5802ea6f76aSRasesh Mody 	/* Add new MAC */
58177fac1b5SHarish Patil 	ucast.opcode = ECORE_FILTER_ADD;
58277fac1b5SHarish Patil 	ether_addr_copy(mac_addr, (struct ether_addr *)&ucast.mac);
58377fac1b5SHarish Patil 	rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
58477fac1b5SHarish Patil 	if (rc != 0)
5852ea6f76aSRasesh Mody 		DP_ERR(edev, "Unable to add new default mac\n");
5862ea6f76aSRasesh Mody 	else
5872ea6f76aSRasesh Mody 		ether_addr_copy(mac_addr, &qdev->primary_mac);
5882ea6f76aSRasesh Mody }
5892ea6f76aSRasesh Mody 
5902ea6f76aSRasesh Mody static void qede_config_accept_any_vlan(struct qede_dev *qdev, bool action)
5912ea6f76aSRasesh Mody {
5922ea6f76aSRasesh Mody 	struct ecore_dev *edev = &qdev->edev;
5932ea6f76aSRasesh Mody 	struct qed_update_vport_params params = {
5942ea6f76aSRasesh Mody 		.vport_id = 0,
5952ea6f76aSRasesh Mody 		.accept_any_vlan = action,
5962ea6f76aSRasesh Mody 		.update_accept_any_vlan_flg = 1,
5972ea6f76aSRasesh Mody 	};
5982ea6f76aSRasesh Mody 	int rc;
5992ea6f76aSRasesh Mody 
6002ea6f76aSRasesh Mody 	/* Proceed only if action actually needs to be performed */
6012ea6f76aSRasesh Mody 	if (qdev->accept_any_vlan == action)
6022ea6f76aSRasesh Mody 		return;
6032ea6f76aSRasesh Mody 
6042ea6f76aSRasesh Mody 	rc = qdev->ops->vport_update(edev, &params);
6052ea6f76aSRasesh Mody 	if (rc) {
6062ea6f76aSRasesh Mody 		DP_ERR(edev, "Failed to %s accept-any-vlan\n",
6072ea6f76aSRasesh Mody 		       action ? "enable" : "disable");
6082ea6f76aSRasesh Mody 	} else {
6092ea6f76aSRasesh Mody 		DP_INFO(edev, "%s accept-any-vlan\n",
6102ea6f76aSRasesh Mody 			action ? "enabled" : "disabled");
6112ea6f76aSRasesh Mody 		qdev->accept_any_vlan = action;
6122ea6f76aSRasesh Mody 	}
6132ea6f76aSRasesh Mody }
6142ea6f76aSRasesh Mody 
6152ea6f76aSRasesh Mody static int qede_vlan_stripping(struct rte_eth_dev *eth_dev, bool set_stripping)
6162ea6f76aSRasesh Mody {
6172ea6f76aSRasesh Mody 	struct qed_update_vport_params vport_update_params;
6182ea6f76aSRasesh Mody 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
6192ea6f76aSRasesh Mody 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
6202ea6f76aSRasesh Mody 	int rc;
6212ea6f76aSRasesh Mody 
6222ea6f76aSRasesh Mody 	memset(&vport_update_params, 0, sizeof(vport_update_params));
6232ea6f76aSRasesh Mody 	vport_update_params.vport_id = 0;
6242ea6f76aSRasesh Mody 	vport_update_params.update_inner_vlan_removal_flg = 1;
6252ea6f76aSRasesh Mody 	vport_update_params.inner_vlan_removal_flg = set_stripping;
6262ea6f76aSRasesh Mody 	rc = qdev->ops->vport_update(edev, &vport_update_params);
6272ea6f76aSRasesh Mody 	if (rc) {
6282ea6f76aSRasesh Mody 		DP_ERR(edev, "Update V-PORT failed %d\n", rc);
6292ea6f76aSRasesh Mody 		return rc;
6302ea6f76aSRasesh Mody 	}
6312ea6f76aSRasesh Mody 
6322ea6f76aSRasesh Mody 	return 0;
6332ea6f76aSRasesh Mody }
6342ea6f76aSRasesh Mody 
6352ea6f76aSRasesh Mody static void qede_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask)
6362ea6f76aSRasesh Mody {
6372ea6f76aSRasesh Mody 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
6382ea6f76aSRasesh Mody 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
639d87246a4SHarish Patil 	struct rte_eth_rxmode *rxmode = &eth_dev->data->dev_conf.rxmode;
6402ea6f76aSRasesh Mody 
6412ea6f76aSRasesh Mody 	if (mask & ETH_VLAN_STRIP_MASK) {
642d87246a4SHarish Patil 		if (rxmode->hw_vlan_strip)
6432ea6f76aSRasesh Mody 			(void)qede_vlan_stripping(eth_dev, 1);
6442ea6f76aSRasesh Mody 		else
6452ea6f76aSRasesh Mody 			(void)qede_vlan_stripping(eth_dev, 0);
6462ea6f76aSRasesh Mody 	}
6472ea6f76aSRasesh Mody 
648d87246a4SHarish Patil 	if (mask & ETH_VLAN_FILTER_MASK) {
649d87246a4SHarish Patil 		/* VLAN filtering kicks in when a VLAN is added */
650d87246a4SHarish Patil 		if (rxmode->hw_vlan_filter) {
651d87246a4SHarish Patil 			qede_vlan_filter_set(eth_dev, 0, 1);
652d87246a4SHarish Patil 		} else {
653d87246a4SHarish Patil 			if (qdev->configured_vlans > 1) { /* Excluding VLAN0 */
65461a8429fSRasesh Mody 				DP_ERR(edev,
655d87246a4SHarish Patil 				  " Please remove existing VLAN filters"
656d87246a4SHarish Patil 				  " before disabling VLAN filtering\n");
657d87246a4SHarish Patil 				/* Signal app that VLAN filtering is still
658d87246a4SHarish Patil 				 * enabled
659d87246a4SHarish Patil 				 */
660d87246a4SHarish Patil 				rxmode->hw_vlan_filter = true;
661d87246a4SHarish Patil 			} else {
662d87246a4SHarish Patil 				qede_vlan_filter_set(eth_dev, 0, 0);
663d87246a4SHarish Patil 			}
664d87246a4SHarish Patil 		}
665d87246a4SHarish Patil 	}
666d87246a4SHarish Patil 
667d87246a4SHarish Patil 	if (mask & ETH_VLAN_EXTEND_MASK)
668d87246a4SHarish Patil 		DP_INFO(edev, "No offloads are supported with VLAN Q-in-Q"
669d87246a4SHarish Patil 			" and classification is based on outer tag only\n");
670d87246a4SHarish Patil 
671d87246a4SHarish Patil 	DP_INFO(edev, "vlan offload mask %d vlan-strip %d vlan-filter %d\n",
672d87246a4SHarish Patil 		mask, rxmode->hw_vlan_strip, rxmode->hw_vlan_filter);
6732ea6f76aSRasesh Mody }
6742ea6f76aSRasesh Mody 
6752ea6f76aSRasesh Mody static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
6762ea6f76aSRasesh Mody 				uint16_t vlan_id, int on)
6772ea6f76aSRasesh Mody {
6782ea6f76aSRasesh Mody 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
6792ea6f76aSRasesh Mody 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
6802ea6f76aSRasesh Mody 	struct qed_dev_eth_info *dev_info = &qdev->dev_info;
681d6cb1753SHarish Patil 	struct qede_vlan_entry *tmp = NULL;
682d6cb1753SHarish Patil 	struct qede_vlan_entry *vlan;
68377fac1b5SHarish Patil 	struct ecore_filter_ucast ucast;
6842ea6f76aSRasesh Mody 	int rc;
6852ea6f76aSRasesh Mody 
686bec02288SSony Chacko 	if (on) {
687d6cb1753SHarish Patil 		if (qdev->configured_vlans == dev_info->num_vlan_filters) {
68861a8429fSRasesh Mody 			DP_ERR(edev, "Reached max VLAN filter limit"
6892ea6f76aSRasesh Mody 				      " enabling accept_any_vlan\n");
6902ea6f76aSRasesh Mody 			qede_config_accept_any_vlan(qdev, true);
6912ea6f76aSRasesh Mody 			return 0;
6922ea6f76aSRasesh Mody 		}
6932ea6f76aSRasesh Mody 
694d6cb1753SHarish Patil 		SLIST_FOREACH(tmp, &qdev->vlan_list_head, list) {
695d6cb1753SHarish Patil 			if (tmp->vid == vlan_id) {
696d6cb1753SHarish Patil 				DP_ERR(edev, "VLAN %u already configured\n",
6972ea6f76aSRasesh Mody 				       vlan_id);
698d6cb1753SHarish Patil 				return -EEXIST;
699d6cb1753SHarish Patil 			}
7002ea6f76aSRasesh Mody 		}
7012ea6f76aSRasesh Mody 
702d6cb1753SHarish Patil 		vlan = rte_malloc(NULL, sizeof(struct qede_vlan_entry),
703d6cb1753SHarish Patil 				  RTE_CACHE_LINE_SIZE);
704d6cb1753SHarish Patil 
705d6cb1753SHarish Patil 		if (!vlan) {
706d6cb1753SHarish Patil 			DP_ERR(edev, "Did not allocate memory for VLAN\n");
707d6cb1753SHarish Patil 			return -ENOMEM;
708d6cb1753SHarish Patil 		}
709d6cb1753SHarish Patil 
71077fac1b5SHarish Patil 		qede_set_ucast_cmn_params(&ucast);
71177fac1b5SHarish Patil 		ucast.opcode = ECORE_FILTER_ADD;
71277fac1b5SHarish Patil 		ucast.type = ECORE_FILTER_VLAN;
71377fac1b5SHarish Patil 		ucast.vlan = vlan_id;
71477fac1b5SHarish Patil 		rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB,
71577fac1b5SHarish Patil 					    NULL);
71677fac1b5SHarish Patil 		if (rc != 0) {
717d6cb1753SHarish Patil 			DP_ERR(edev, "Failed to add VLAN %u rc %d\n", vlan_id,
718d6cb1753SHarish Patil 			       rc);
719d6cb1753SHarish Patil 			rte_free(vlan);
720d6cb1753SHarish Patil 		} else {
721d6cb1753SHarish Patil 			vlan->vid = vlan_id;
722d6cb1753SHarish Patil 			SLIST_INSERT_HEAD(&qdev->vlan_list_head, vlan, list);
723d6cb1753SHarish Patil 			qdev->configured_vlans++;
724d6cb1753SHarish Patil 			DP_INFO(edev, "VLAN %u added, configured_vlans %u\n",
725d6cb1753SHarish Patil 				vlan_id, qdev->configured_vlans);
726d6cb1753SHarish Patil 		}
727d6cb1753SHarish Patil 	} else {
728d6cb1753SHarish Patil 		SLIST_FOREACH(tmp, &qdev->vlan_list_head, list) {
729d6cb1753SHarish Patil 			if (tmp->vid == vlan_id)
730d6cb1753SHarish Patil 				break;
731d6cb1753SHarish Patil 		}
732d6cb1753SHarish Patil 
733d6cb1753SHarish Patil 		if (!tmp) {
734d6cb1753SHarish Patil 			if (qdev->configured_vlans == 0) {
735d6cb1753SHarish Patil 				DP_INFO(edev,
736d6cb1753SHarish Patil 					"No VLAN filters configured yet\n");
737d6cb1753SHarish Patil 				return 0;
738d6cb1753SHarish Patil 			}
739d6cb1753SHarish Patil 
740d6cb1753SHarish Patil 			DP_ERR(edev, "VLAN %u not configured\n", vlan_id);
741d6cb1753SHarish Patil 			return -EINVAL;
742d6cb1753SHarish Patil 		}
743d6cb1753SHarish Patil 
744d6cb1753SHarish Patil 		SLIST_REMOVE(&qdev->vlan_list_head, tmp, qede_vlan_entry, list);
745d6cb1753SHarish Patil 
74677fac1b5SHarish Patil 		qede_set_ucast_cmn_params(&ucast);
74777fac1b5SHarish Patil 		ucast.opcode = ECORE_FILTER_REMOVE;
74877fac1b5SHarish Patil 		ucast.type = ECORE_FILTER_VLAN;
74977fac1b5SHarish Patil 		ucast.vlan = vlan_id;
75077fac1b5SHarish Patil 		rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB,
75177fac1b5SHarish Patil 					    NULL);
75277fac1b5SHarish Patil 		if (rc != 0) {
753d6cb1753SHarish Patil 			DP_ERR(edev, "Failed to delete VLAN %u rc %d\n",
754d6cb1753SHarish Patil 			       vlan_id, rc);
755d6cb1753SHarish Patil 		} else {
756d6cb1753SHarish Patil 			qdev->configured_vlans--;
757d6cb1753SHarish Patil 			DP_INFO(edev, "VLAN %u removed configured_vlans %u\n",
758d6cb1753SHarish Patil 				vlan_id, qdev->configured_vlans);
759d6cb1753SHarish Patil 		}
760d6cb1753SHarish Patil 	}
7612ea6f76aSRasesh Mody 
7622ea6f76aSRasesh Mody 	return rc;
7632ea6f76aSRasesh Mody }
7642ea6f76aSRasesh Mody 
765dbac54c2SHarish Patil static int qede_init_vport(struct qede_dev *qdev)
766dbac54c2SHarish Patil {
767dbac54c2SHarish Patil 	struct ecore_dev *edev = &qdev->edev;
768dbac54c2SHarish Patil 	struct qed_start_vport_params start = {0};
769dbac54c2SHarish Patil 	int rc;
770dbac54c2SHarish Patil 
771dbac54c2SHarish Patil 	start.remove_inner_vlan = 1;
77229540be7SHarish Patil 	start.enable_lro = qdev->enable_lro;
773dbac54c2SHarish Patil 	start.mtu = ETHER_MTU + QEDE_ETH_OVERHEAD;
774dbac54c2SHarish Patil 	start.vport_id = 0;
775dbac54c2SHarish Patil 	start.drop_ttl0 = false;
776dbac54c2SHarish Patil 	start.clear_stats = 1;
777dbac54c2SHarish Patil 	start.handle_ptp_pkts = 0;
778dbac54c2SHarish Patil 
779dbac54c2SHarish Patil 	rc = qdev->ops->vport_start(edev, &start);
780dbac54c2SHarish Patil 	if (rc) {
781dbac54c2SHarish Patil 		DP_ERR(edev, "Start V-PORT failed %d\n", rc);
782dbac54c2SHarish Patil 		return rc;
783dbac54c2SHarish Patil 	}
784dbac54c2SHarish Patil 
785dbac54c2SHarish Patil 	DP_INFO(edev,
786dbac54c2SHarish Patil 		"Start vport ramrod passed, vport_id = %d, MTU = %u\n",
787dbac54c2SHarish Patil 		start.vport_id, ETHER_MTU);
788dbac54c2SHarish Patil 
789dbac54c2SHarish Patil 	return 0;
790dbac54c2SHarish Patil }
791dbac54c2SHarish Patil 
7927ab35bf6SHarish Patil static void qede_prandom_bytes(uint32_t *buff)
7937ab35bf6SHarish Patil {
7947ab35bf6SHarish Patil 	uint8_t i;
7957ab35bf6SHarish Patil 
7967ab35bf6SHarish Patil 	srand((unsigned int)time(NULL));
7977ab35bf6SHarish Patil 	for (i = 0; i < ECORE_RSS_KEY_SIZE; i++)
7987ab35bf6SHarish Patil 		buff[i] = rand();
7997ab35bf6SHarish Patil }
8007ab35bf6SHarish Patil 
8018130abb3SHarish Patil int qede_config_rss(struct rte_eth_dev *eth_dev)
8027ab35bf6SHarish Patil {
8037ab35bf6SHarish Patil 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
8047ab35bf6SHarish Patil 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
8057ab35bf6SHarish Patil 	uint32_t def_rss_key[ECORE_RSS_KEY_SIZE];
8067ab35bf6SHarish Patil 	struct rte_eth_rss_reta_entry64 reta_conf[2];
8077ab35bf6SHarish Patil 	struct rte_eth_rss_conf rss_conf;
8087ab35bf6SHarish Patil 	uint32_t i, id, pos, q;
8097ab35bf6SHarish Patil 
8107ab35bf6SHarish Patil 	rss_conf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf;
8117ab35bf6SHarish Patil 	if (!rss_conf.rss_key) {
8127ab35bf6SHarish Patil 		DP_INFO(edev, "Applying driver default key\n");
8137ab35bf6SHarish Patil 		rss_conf.rss_key_len = ECORE_RSS_KEY_SIZE * sizeof(uint32_t);
8147ab35bf6SHarish Patil 		qede_prandom_bytes(&def_rss_key[0]);
8157ab35bf6SHarish Patil 		rss_conf.rss_key = (uint8_t *)&def_rss_key[0];
8167ab35bf6SHarish Patil 	}
8177ab35bf6SHarish Patil 
8187ab35bf6SHarish Patil 	/* Configure RSS hash */
8197ab35bf6SHarish Patil 	if (qede_rss_hash_update(eth_dev, &rss_conf))
8207ab35bf6SHarish Patil 		return -EINVAL;
8217ab35bf6SHarish Patil 
8227ab35bf6SHarish Patil 	/* Configure default RETA */
8237ab35bf6SHarish Patil 	memset(reta_conf, 0, sizeof(reta_conf));
8247ab35bf6SHarish Patil 	for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++)
8257ab35bf6SHarish Patil 		reta_conf[i / RTE_RETA_GROUP_SIZE].mask = UINT64_MAX;
8267ab35bf6SHarish Patil 
8277ab35bf6SHarish Patil 	for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++) {
8287ab35bf6SHarish Patil 		id = i / RTE_RETA_GROUP_SIZE;
8297ab35bf6SHarish Patil 		pos = i % RTE_RETA_GROUP_SIZE;
8307ab35bf6SHarish Patil 		q = i % QEDE_RSS_COUNT(qdev);
8317ab35bf6SHarish Patil 		reta_conf[id].reta[pos] = q;
8327ab35bf6SHarish Patil 	}
8337ab35bf6SHarish Patil 	if (qede_rss_reta_update(eth_dev, &reta_conf[0],
8347ab35bf6SHarish Patil 				 ECORE_RSS_IND_TABLE_SIZE))
8357ab35bf6SHarish Patil 		return -EINVAL;
8367ab35bf6SHarish Patil 
8377ab35bf6SHarish Patil 	return 0;
8387ab35bf6SHarish Patil }
8397ab35bf6SHarish Patil 
8402ea6f76aSRasesh Mody static int qede_dev_configure(struct rte_eth_dev *eth_dev)
8412ea6f76aSRasesh Mody {
8422ea6f76aSRasesh Mody 	struct qede_dev *qdev = eth_dev->data->dev_private;
8432ea6f76aSRasesh Mody 	struct ecore_dev *edev = &qdev->edev;
8442ea6f76aSRasesh Mody 	struct rte_eth_rxmode *rxmode = &eth_dev->data->dev_conf.rxmode;
8459c5d0a66SHarish Patil 	int rc, i, j;
8462ea6f76aSRasesh Mody 
8472ea6f76aSRasesh Mody 	PMD_INIT_FUNC_TRACE(edev);
8482ea6f76aSRasesh Mody 
8492af14ca7SHarish Patil 	/* Check requirements for 100G mode */
8502af14ca7SHarish Patil 	if (edev->num_hwfns > 1) {
851cfe28a98SSony Chacko 		if (eth_dev->data->nb_rx_queues < 2 ||
852cfe28a98SSony Chacko 		    eth_dev->data->nb_tx_queues < 2) {
85361a8429fSRasesh Mody 			DP_ERR(edev, "100G mode needs min. 2 RX/TX queues\n");
8542af14ca7SHarish Patil 			return -EINVAL;
8552af14ca7SHarish Patil 		}
8562af14ca7SHarish Patil 
857cfe28a98SSony Chacko 		if ((eth_dev->data->nb_rx_queues % 2 != 0) ||
858cfe28a98SSony Chacko 		    (eth_dev->data->nb_tx_queues % 2 != 0)) {
85961a8429fSRasesh Mody 			DP_ERR(edev,
860cfe28a98SSony Chacko 				  "100G mode needs even no. of RX/TX queues\n");
8612af14ca7SHarish Patil 			return -EINVAL;
8622af14ca7SHarish Patil 		}
8632af14ca7SHarish Patil 	}
8642af14ca7SHarish Patil 
8652ea6f76aSRasesh Mody 	/* Sanity checks and throw warnings */
866bec02288SSony Chacko 	if (rxmode->enable_scatter == 1)
867bec02288SSony Chacko 		eth_dev->data->scattered_rx = 1;
8682ea6f76aSRasesh Mody 
8692ea6f76aSRasesh Mody 	if (!rxmode->hw_strip_crc)
8702ea6f76aSRasesh Mody 		DP_INFO(edev, "L2 CRC stripping is always enabled in hw\n");
8712ea6f76aSRasesh Mody 
8722ea6f76aSRasesh Mody 	if (!rxmode->hw_ip_checksum)
8732ea6f76aSRasesh Mody 		DP_INFO(edev, "IP/UDP/TCP checksum offload is always enabled "
8742ea6f76aSRasesh Mody 			      "in hw\n");
8752ea6f76aSRasesh Mody 
87629540be7SHarish Patil 	if (rxmode->enable_lro) {
87729540be7SHarish Patil 		qdev->enable_lro = true;
87829540be7SHarish Patil 		/* Enable scatter mode for LRO */
87929540be7SHarish Patil 		if (!rxmode->enable_scatter)
88029540be7SHarish Patil 			eth_dev->data->scattered_rx = 1;
88129540be7SHarish Patil 	}
88229540be7SHarish Patil 
883dbac54c2SHarish Patil 	/* Check for the port restart case */
884dbac54c2SHarish Patil 	if (qdev->state != QEDE_DEV_INIT) {
885dbac54c2SHarish Patil 		rc = qdev->ops->vport_stop(edev, 0);
886dbac54c2SHarish Patil 		if (rc != 0)
887dbac54c2SHarish Patil 			return rc;
888dbac54c2SHarish Patil 		qede_dealloc_fp_resc(eth_dev);
889dbac54c2SHarish Patil 	}
8902ea6f76aSRasesh Mody 
8919c5d0a66SHarish Patil 	qdev->fp_num_tx = eth_dev->data->nb_tx_queues;
8929c5d0a66SHarish Patil 	qdev->fp_num_rx = eth_dev->data->nb_rx_queues;
8939c5d0a66SHarish Patil 	qdev->num_queues = qdev->fp_num_tx + qdev->fp_num_rx;
8949c5d0a66SHarish Patil 
895dbac54c2SHarish Patil 	/* Fastpath status block should be initialized before sending
896dbac54c2SHarish Patil 	 * VPORT-START in the case of VF. Anyway, do it for both VF/PF.
897dbac54c2SHarish Patil 	 */
898dbac54c2SHarish Patil 	rc = qede_alloc_fp_resc(qdev);
899dbac54c2SHarish Patil 	if (rc != 0)
900dbac54c2SHarish Patil 		return rc;
9012ea6f76aSRasesh Mody 
902dbac54c2SHarish Patil 	/* Issue VPORT-START with default config values to allow
903dbac54c2SHarish Patil 	 * other port configurations early on.
904dbac54c2SHarish Patil 	 */
905dbac54c2SHarish Patil 	rc = qede_init_vport(qdev);
906dbac54c2SHarish Patil 	if (rc != 0)
907dbac54c2SHarish Patil 		return rc;
908dbac54c2SHarish Patil 
9098130abb3SHarish Patil 	if (!(rxmode->mq_mode == ETH_MQ_RX_RSS ||
9108130abb3SHarish Patil 	    rxmode->mq_mode == ETH_MQ_RX_NONE)) {
9117ab35bf6SHarish Patil 		DP_ERR(edev, "Unsupported RSS mode\n");
9127ab35bf6SHarish Patil 		qdev->ops->vport_stop(edev, 0);
9137ab35bf6SHarish Patil 		qede_dealloc_fp_resc(eth_dev);
9147ab35bf6SHarish Patil 		return -EINVAL;
9157ab35bf6SHarish Patil 	}
9167ab35bf6SHarish Patil 
91762207535SHarish Patil 	/* Flow director mode check */
91862207535SHarish Patil 	rc = qede_check_fdir_support(eth_dev);
91962207535SHarish Patil 	if (rc) {
92062207535SHarish Patil 		qdev->ops->vport_stop(edev, 0);
92162207535SHarish Patil 		qede_dealloc_fp_resc(eth_dev);
92262207535SHarish Patil 		return -EINVAL;
92362207535SHarish Patil 	}
92462207535SHarish Patil 	SLIST_INIT(&qdev->fdir_info.fdir_list_head);
92562207535SHarish Patil 
9269c5d0a66SHarish Patil 	SLIST_INIT(&qdev->vlan_list_head);
9279c5d0a66SHarish Patil 
928dbac54c2SHarish Patil 	/* Add primary mac for PF */
929dbac54c2SHarish Patil 	if (IS_PF(edev))
930dbac54c2SHarish Patil 		qede_mac_addr_set(eth_dev, &qdev->primary_mac);
931dbac54c2SHarish Patil 
932d87246a4SHarish Patil 	/* Enable VLAN offloads by default */
933d87246a4SHarish Patil 	qede_vlan_offload_set(eth_dev, ETH_VLAN_STRIP_MASK  |
934d87246a4SHarish Patil 				       ETH_VLAN_FILTER_MASK |
935d87246a4SHarish Patil 				       ETH_VLAN_EXTEND_MASK);
936d87246a4SHarish Patil 
937dbac54c2SHarish Patil 	qdev->state = QEDE_DEV_CONFIG;
9382ea6f76aSRasesh Mody 
9399c5d0a66SHarish Patil 	DP_INFO(edev, "Allocated RSS=%d TSS=%d (with CoS=%d)\n",
9409c5d0a66SHarish Patil 		(int)QEDE_RSS_COUNT(qdev), (int)QEDE_TSS_COUNT(qdev),
9419c5d0a66SHarish Patil 		qdev->num_tc);
9429c5d0a66SHarish Patil 
9432ea6f76aSRasesh Mody 	return 0;
9442ea6f76aSRasesh Mody }
9452ea6f76aSRasesh Mody 
9462ea6f76aSRasesh Mody /* Info about HW descriptor ring limitations */
9472ea6f76aSRasesh Mody static const struct rte_eth_desc_lim qede_rx_desc_lim = {
9482ea6f76aSRasesh Mody 	.nb_max = NUM_RX_BDS_MAX,
9492ea6f76aSRasesh Mody 	.nb_min = 128,
9502ea6f76aSRasesh Mody 	.nb_align = 128 /* lowest common multiple */
9512ea6f76aSRasesh Mody };
9522ea6f76aSRasesh Mody 
9532ea6f76aSRasesh Mody static const struct rte_eth_desc_lim qede_tx_desc_lim = {
9542ea6f76aSRasesh Mody 	.nb_max = NUM_TX_BDS_MAX,
9552ea6f76aSRasesh Mody 	.nb_min = 256,
95629540be7SHarish Patil 	.nb_align = 256,
95729540be7SHarish Patil 	.nb_seg_max = ETH_TX_MAX_BDS_PER_LSO_PACKET,
95829540be7SHarish Patil 	.nb_mtu_seg_max = ETH_TX_MAX_BDS_PER_NON_LSO_PACKET
9592ea6f76aSRasesh Mody };
9602ea6f76aSRasesh Mody 
9612ea6f76aSRasesh Mody static void
9622ea6f76aSRasesh Mody qede_dev_info_get(struct rte_eth_dev *eth_dev,
9632ea6f76aSRasesh Mody 		  struct rte_eth_dev_info *dev_info)
9642ea6f76aSRasesh Mody {
9652ea6f76aSRasesh Mody 	struct qede_dev *qdev = eth_dev->data->dev_private;
9662ea6f76aSRasesh Mody 	struct ecore_dev *edev = &qdev->edev;
96764c239b7SHarish Patil 	struct qed_link_output link;
9681ea56b80SHarish Patil 	uint32_t speed_cap = 0;
9692ea6f76aSRasesh Mody 
9702ea6f76aSRasesh Mody 	PMD_INIT_FUNC_TRACE(edev);
9712ea6f76aSRasesh Mody 
972eac901ceSJan Blunck 	dev_info->pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
973f6033f24SHarish Patil 	dev_info->min_rx_bufsize = (uint32_t)QEDE_MIN_RX_BUFF_SIZE;
9742ea6f76aSRasesh Mody 	dev_info->max_rx_pktlen = (uint32_t)ETH_TX_MAX_NON_LSO_PKT_LEN;
9752ea6f76aSRasesh Mody 	dev_info->rx_desc_lim = qede_rx_desc_lim;
9762ea6f76aSRasesh Mody 	dev_info->tx_desc_lim = qede_tx_desc_lim;
977528fcfabSHarish Patil 
978528fcfabSHarish Patil 	if (IS_PF(edev))
979528fcfabSHarish Patil 		dev_info->max_rx_queues = (uint16_t)RTE_MIN(
980528fcfabSHarish Patil 			QEDE_MAX_RSS_CNT(qdev), QEDE_PF_NUM_CONNS / 2);
981528fcfabSHarish Patil 	else
982528fcfabSHarish Patil 		dev_info->max_rx_queues = (uint16_t)RTE_MIN(
983528fcfabSHarish Patil 			QEDE_MAX_RSS_CNT(qdev), ECORE_MAX_VF_CHAINS_PER_PF);
9842ea6f76aSRasesh Mody 	dev_info->max_tx_queues = dev_info->max_rx_queues;
985528fcfabSHarish Patil 
9863320ca8cSRasesh Mody 	dev_info->max_mac_addrs = qdev->dev_info.num_mac_filters;
98786a2265eSRasesh Mody 	dev_info->max_vfs = 0;
9885cdd769aSRasesh Mody 	dev_info->reta_size = ECORE_RSS_IND_TABLE_SIZE;
9897ab35bf6SHarish Patil 	dev_info->hash_key_size = ECORE_RSS_KEY_SIZE * sizeof(uint32_t);
9902ea6f76aSRasesh Mody 	dev_info->flow_type_rss_offloads = (uint64_t)QEDE_RSS_OFFLOAD_ALL;
9912ea6f76aSRasesh Mody 
9922ea6f76aSRasesh Mody 	dev_info->default_txconf = (struct rte_eth_txconf) {
9932ea6f76aSRasesh Mody 		.txq_flags = QEDE_TXQ_FLAGS,
9942ea6f76aSRasesh Mody 	};
9952ea6f76aSRasesh Mody 
9962ea6f76aSRasesh Mody 	dev_info->rx_offload_capa = (DEV_RX_OFFLOAD_VLAN_STRIP	|
9972ea6f76aSRasesh Mody 				     DEV_RX_OFFLOAD_IPV4_CKSUM	|
9982ea6f76aSRasesh Mody 				     DEV_RX_OFFLOAD_UDP_CKSUM	|
9993d4bb441SHarish Patil 				     DEV_RX_OFFLOAD_TCP_CKSUM	|
100029540be7SHarish Patil 				     DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
100129540be7SHarish Patil 				     DEV_RX_OFFLOAD_TCP_LRO);
100229540be7SHarish Patil 
10032ea6f76aSRasesh Mody 	dev_info->tx_offload_capa = (DEV_TX_OFFLOAD_VLAN_INSERT	|
10042ea6f76aSRasesh Mody 				     DEV_TX_OFFLOAD_IPV4_CKSUM	|
10052ea6f76aSRasesh Mody 				     DEV_TX_OFFLOAD_UDP_CKSUM	|
10063d4bb441SHarish Patil 				     DEV_TX_OFFLOAD_TCP_CKSUM	|
100729540be7SHarish Patil 				     DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
100829540be7SHarish Patil 				     DEV_TX_OFFLOAD_TCP_TSO |
100929540be7SHarish Patil 				     DEV_TX_OFFLOAD_VXLAN_TNL_TSO);
10102ea6f76aSRasesh Mody 
101164c239b7SHarish Patil 	memset(&link, 0, sizeof(struct qed_link_output));
101264c239b7SHarish Patil 	qdev->ops->common->get_link(edev, &link);
10131ea56b80SHarish Patil 	if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
10141ea56b80SHarish Patil 		speed_cap |= ETH_LINK_SPEED_1G;
10151ea56b80SHarish Patil 	if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
10161ea56b80SHarish Patil 		speed_cap |= ETH_LINK_SPEED_10G;
10171ea56b80SHarish Patil 	if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
10181ea56b80SHarish Patil 		speed_cap |= ETH_LINK_SPEED_25G;
10191ea56b80SHarish Patil 	if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
10201ea56b80SHarish Patil 		speed_cap |= ETH_LINK_SPEED_40G;
10211ea56b80SHarish Patil 	if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
10221ea56b80SHarish Patil 		speed_cap |= ETH_LINK_SPEED_50G;
10231ea56b80SHarish Patil 	if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
10241ea56b80SHarish Patil 		speed_cap |= ETH_LINK_SPEED_100G;
10251ea56b80SHarish Patil 	dev_info->speed_capa = speed_cap;
10262ea6f76aSRasesh Mody }
10272ea6f76aSRasesh Mody 
10282ea6f76aSRasesh Mody /* return 0 means link status changed, -1 means not changed */
10292ea6f76aSRasesh Mody static int
10302ea6f76aSRasesh Mody qede_link_update(struct rte_eth_dev *eth_dev, __rte_unused int wait_to_complete)
10312ea6f76aSRasesh Mody {
10322ea6f76aSRasesh Mody 	struct qede_dev *qdev = eth_dev->data->dev_private;
10332ea6f76aSRasesh Mody 	struct ecore_dev *edev = &qdev->edev;
10342ea6f76aSRasesh Mody 	uint16_t link_duplex;
10352ea6f76aSRasesh Mody 	struct qed_link_output link;
10362ea6f76aSRasesh Mody 	struct rte_eth_link *curr = &eth_dev->data->dev_link;
10372ea6f76aSRasesh Mody 
10382ea6f76aSRasesh Mody 	memset(&link, 0, sizeof(struct qed_link_output));
10392ea6f76aSRasesh Mody 	qdev->ops->common->get_link(edev, &link);
10402ea6f76aSRasesh Mody 
10412ea6f76aSRasesh Mody 	/* Link Speed */
10422ea6f76aSRasesh Mody 	curr->link_speed = link.speed;
10432ea6f76aSRasesh Mody 
10442ea6f76aSRasesh Mody 	/* Link Mode */
10452ea6f76aSRasesh Mody 	switch (link.duplex) {
10462ea6f76aSRasesh Mody 	case QEDE_DUPLEX_HALF:
10472ea6f76aSRasesh Mody 		link_duplex = ETH_LINK_HALF_DUPLEX;
10482ea6f76aSRasesh Mody 		break;
10492ea6f76aSRasesh Mody 	case QEDE_DUPLEX_FULL:
10502ea6f76aSRasesh Mody 		link_duplex = ETH_LINK_FULL_DUPLEX;
10512ea6f76aSRasesh Mody 		break;
10522ea6f76aSRasesh Mody 	case QEDE_DUPLEX_UNKNOWN:
10532ea6f76aSRasesh Mody 	default:
10542ea6f76aSRasesh Mody 		link_duplex = -1;
10552ea6f76aSRasesh Mody 	}
10562ea6f76aSRasesh Mody 	curr->link_duplex = link_duplex;
10572ea6f76aSRasesh Mody 
10582ea6f76aSRasesh Mody 	/* Link Status */
10592ea6f76aSRasesh Mody 	curr->link_status = (link.link_up) ? ETH_LINK_UP : ETH_LINK_DOWN;
10602ea6f76aSRasesh Mody 
10612ea6f76aSRasesh Mody 	/* AN */
10622ea6f76aSRasesh Mody 	curr->link_autoneg = (link.supported_caps & QEDE_SUPPORTED_AUTONEG) ?
10632ea6f76aSRasesh Mody 			     ETH_LINK_AUTONEG : ETH_LINK_FIXED;
10642ea6f76aSRasesh Mody 
10652ea6f76aSRasesh Mody 	DP_INFO(edev, "Link - Speed %u Mode %u AN %u Status %u\n",
10662ea6f76aSRasesh Mody 		curr->link_speed, curr->link_duplex,
10672ea6f76aSRasesh Mody 		curr->link_autoneg, curr->link_status);
10682ea6f76aSRasesh Mody 
10692ea6f76aSRasesh Mody 	/* return 0 means link status changed, -1 means not changed */
10702ea6f76aSRasesh Mody 	return ((curr->link_status == link.link_up) ? -1 : 0);
10712ea6f76aSRasesh Mody }
10722ea6f76aSRasesh Mody 
10732ea6f76aSRasesh Mody static void qede_promiscuous_enable(struct rte_eth_dev *eth_dev)
10742ea6f76aSRasesh Mody {
10752ea6f76aSRasesh Mody 	struct qede_dev *qdev = eth_dev->data->dev_private;
10762ea6f76aSRasesh Mody 	struct ecore_dev *edev = &qdev->edev;
10772ea6f76aSRasesh Mody 
10782ea6f76aSRasesh Mody 	PMD_INIT_FUNC_TRACE(edev);
10792ea6f76aSRasesh Mody 
10802ea6f76aSRasesh Mody 	enum qed_filter_rx_mode_type type = QED_FILTER_RX_MODE_TYPE_PROMISC;
10812ea6f76aSRasesh Mody 
10822ea6f76aSRasesh Mody 	if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1)
10832ea6f76aSRasesh Mody 		type |= QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC;
10842ea6f76aSRasesh Mody 
108577fac1b5SHarish Patil 	qed_configure_filter_rx_mode(eth_dev, type);
10862ea6f76aSRasesh Mody }
10872ea6f76aSRasesh Mody 
10882ea6f76aSRasesh Mody static void qede_promiscuous_disable(struct rte_eth_dev *eth_dev)
10892ea6f76aSRasesh Mody {
10902ea6f76aSRasesh Mody 	struct qede_dev *qdev = eth_dev->data->dev_private;
10912ea6f76aSRasesh Mody 	struct ecore_dev *edev = &qdev->edev;
10922ea6f76aSRasesh Mody 
10932ea6f76aSRasesh Mody 	PMD_INIT_FUNC_TRACE(edev);
10942ea6f76aSRasesh Mody 
10952ea6f76aSRasesh Mody 	if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1)
109677fac1b5SHarish Patil 		qed_configure_filter_rx_mode(eth_dev,
10972ea6f76aSRasesh Mody 				QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC);
10982ea6f76aSRasesh Mody 	else
109977fac1b5SHarish Patil 		qed_configure_filter_rx_mode(eth_dev,
110077fac1b5SHarish Patil 				QED_FILTER_RX_MODE_TYPE_REGULAR);
11012ea6f76aSRasesh Mody }
11022ea6f76aSRasesh Mody 
11032af14ca7SHarish Patil static void qede_poll_sp_sb_cb(void *param)
11042af14ca7SHarish Patil {
11052af14ca7SHarish Patil 	struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
11062af14ca7SHarish Patil 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
11072af14ca7SHarish Patil 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
11082af14ca7SHarish Patil 	int rc;
11092af14ca7SHarish Patil 
11102af14ca7SHarish Patil 	qede_interrupt_action(ECORE_LEADING_HWFN(edev));
11112af14ca7SHarish Patil 	qede_interrupt_action(&edev->hwfns[1]);
11122af14ca7SHarish Patil 
11132af14ca7SHarish Patil 	rc = rte_eal_alarm_set(timer_period * US_PER_S,
11142af14ca7SHarish Patil 			       qede_poll_sp_sb_cb,
11152af14ca7SHarish Patil 			       (void *)eth_dev);
11162af14ca7SHarish Patil 	if (rc != 0) {
11172af14ca7SHarish Patil 		DP_ERR(edev, "Unable to start periodic"
11182af14ca7SHarish Patil 			     " timer rc %d\n", rc);
11192af14ca7SHarish Patil 		assert(false && "Unable to start periodic timer");
11202af14ca7SHarish Patil 	}
11212af14ca7SHarish Patil }
11222af14ca7SHarish Patil 
11232ea6f76aSRasesh Mody static void qede_dev_close(struct rte_eth_dev *eth_dev)
11242ea6f76aSRasesh Mody {
1125eac901ceSJan Blunck 	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
1126dbac54c2SHarish Patil 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
1127dbac54c2SHarish Patil 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
1128dbac54c2SHarish Patil 	int rc;
11292ea6f76aSRasesh Mody 
11302ea6f76aSRasesh Mody 	PMD_INIT_FUNC_TRACE(edev);
11312ea6f76aSRasesh Mody 
113262207535SHarish Patil 	qede_fdir_dealloc_resc(eth_dev);
113362207535SHarish Patil 
11342ea6f76aSRasesh Mody 	/* dev_stop() shall cleanup fp resources in hw but without releasing
11352ea6f76aSRasesh Mody 	 * dma memories and sw structures so that dev_start() can be called
11362ea6f76aSRasesh Mody 	 * by the app without reconfiguration. However, in dev_close() we
11372ea6f76aSRasesh Mody 	 * can release all the resources and device can be brought up newly
11382ea6f76aSRasesh Mody 	 */
1139dbac54c2SHarish Patil 	if (qdev->state != QEDE_DEV_STOP)
11402ea6f76aSRasesh Mody 		qede_dev_stop(eth_dev);
11412ea6f76aSRasesh Mody 	else
11422ea6f76aSRasesh Mody 		DP_INFO(edev, "Device is already stopped\n");
11432ea6f76aSRasesh Mody 
1144dbac54c2SHarish Patil 	rc = qdev->ops->vport_stop(edev, 0);
1145dbac54c2SHarish Patil 	if (rc != 0)
1146dbac54c2SHarish Patil 		DP_ERR(edev, "Failed to stop VPORT\n");
11472ea6f76aSRasesh Mody 
1148dbac54c2SHarish Patil 	qede_dealloc_fp_resc(eth_dev);
11492ea6f76aSRasesh Mody 
11502ea6f76aSRasesh Mody 	qdev->ops->common->slowpath_stop(edev);
11512ea6f76aSRasesh Mody 
11522ea6f76aSRasesh Mody 	qdev->ops->common->remove(edev);
11532ea6f76aSRasesh Mody 
1154d4b7f673SJan Blunck 	rte_intr_disable(&pci_dev->intr_handle);
11552ea6f76aSRasesh Mody 
1156d4b7f673SJan Blunck 	rte_intr_callback_unregister(&pci_dev->intr_handle,
11572ea6f76aSRasesh Mody 				     qede_interrupt_handler, (void *)eth_dev);
11582ea6f76aSRasesh Mody 
11592af14ca7SHarish Patil 	if (edev->num_hwfns > 1)
11602af14ca7SHarish Patil 		rte_eal_alarm_cancel(qede_poll_sp_sb_cb, (void *)eth_dev);
11612af14ca7SHarish Patil 
1162dbac54c2SHarish Patil 	qdev->state = QEDE_DEV_INIT; /* Go back to init state */
11632ea6f76aSRasesh Mody }
11642ea6f76aSRasesh Mody 
11652ea6f76aSRasesh Mody static void
11662ea6f76aSRasesh Mody qede_get_stats(struct rte_eth_dev *eth_dev, struct rte_eth_stats *eth_stats)
11672ea6f76aSRasesh Mody {
11682ea6f76aSRasesh Mody 	struct qede_dev *qdev = eth_dev->data->dev_private;
11692ea6f76aSRasesh Mody 	struct ecore_dev *edev = &qdev->edev;
11702ea6f76aSRasesh Mody 	struct ecore_eth_stats stats;
11717634c5f9SRasesh Mody 	unsigned int i = 0, j = 0, qid;
117206e83c4eSRasesh Mody 	unsigned int rxq_stat_cntrs, txq_stat_cntrs;
11737634c5f9SRasesh Mody 	struct qede_tx_queue *txq;
11742ea6f76aSRasesh Mody 
11752ea6f76aSRasesh Mody 	qdev->ops->get_vport_stats(edev, &stats);
11762ea6f76aSRasesh Mody 
11772ea6f76aSRasesh Mody 	/* RX Stats */
11782ea6f76aSRasesh Mody 	eth_stats->ipackets = stats.rx_ucast_pkts +
11792ea6f76aSRasesh Mody 	    stats.rx_mcast_pkts + stats.rx_bcast_pkts;
11802ea6f76aSRasesh Mody 
11812ea6f76aSRasesh Mody 	eth_stats->ibytes = stats.rx_ucast_bytes +
11822ea6f76aSRasesh Mody 	    stats.rx_mcast_bytes + stats.rx_bcast_bytes;
11832ea6f76aSRasesh Mody 
11842ea6f76aSRasesh Mody 	eth_stats->ierrors = stats.rx_crc_errors +
11852ea6f76aSRasesh Mody 	    stats.rx_align_errors +
11862ea6f76aSRasesh Mody 	    stats.rx_carrier_errors +
11872ea6f76aSRasesh Mody 	    stats.rx_oversize_packets +
11882ea6f76aSRasesh Mody 	    stats.rx_jabbers + stats.rx_undersize_packets;
11892ea6f76aSRasesh Mody 
11902ea6f76aSRasesh Mody 	eth_stats->rx_nombuf = stats.no_buff_discards;
11912ea6f76aSRasesh Mody 
11922ea6f76aSRasesh Mody 	eth_stats->imissed = stats.mftag_filter_discards +
11932ea6f76aSRasesh Mody 	    stats.mac_filter_discards +
11942ea6f76aSRasesh Mody 	    stats.no_buff_discards + stats.brb_truncates + stats.brb_discards;
11952ea6f76aSRasesh Mody 
11962ea6f76aSRasesh Mody 	/* TX stats */
11972ea6f76aSRasesh Mody 	eth_stats->opackets = stats.tx_ucast_pkts +
11982ea6f76aSRasesh Mody 	    stats.tx_mcast_pkts + stats.tx_bcast_pkts;
11992ea6f76aSRasesh Mody 
12002ea6f76aSRasesh Mody 	eth_stats->obytes = stats.tx_ucast_bytes +
12012ea6f76aSRasesh Mody 	    stats.tx_mcast_bytes + stats.tx_bcast_bytes;
12022ea6f76aSRasesh Mody 
12032ea6f76aSRasesh Mody 	eth_stats->oerrors = stats.tx_err_drop_pkts;
12047634c5f9SRasesh Mody 
12057634c5f9SRasesh Mody 	/* Queue stats */
120606e83c4eSRasesh Mody 	rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(qdev),
120706e83c4eSRasesh Mody 			       RTE_ETHDEV_QUEUE_STAT_CNTRS);
120806e83c4eSRasesh Mody 	txq_stat_cntrs = RTE_MIN(QEDE_TSS_COUNT(qdev),
120906e83c4eSRasesh Mody 			       RTE_ETHDEV_QUEUE_STAT_CNTRS);
121006e83c4eSRasesh Mody 	if ((rxq_stat_cntrs != QEDE_RSS_COUNT(qdev)) ||
121106e83c4eSRasesh Mody 	    (txq_stat_cntrs != QEDE_TSS_COUNT(qdev)))
121206e83c4eSRasesh Mody 		DP_VERBOSE(edev, ECORE_MSG_DEBUG,
121306e83c4eSRasesh Mody 		       "Not all the queue stats will be displayed. Set"
121406e83c4eSRasesh Mody 		       " RTE_ETHDEV_QUEUE_STAT_CNTRS config param"
121506e83c4eSRasesh Mody 		       " appropriately and retry.\n");
121606e83c4eSRasesh Mody 
12177634c5f9SRasesh Mody 	for (qid = 0; qid < QEDE_QUEUE_CNT(qdev); qid++) {
12187634c5f9SRasesh Mody 		if (qdev->fp_array[qid].type & QEDE_FASTPATH_RX) {
12197634c5f9SRasesh Mody 			eth_stats->q_ipackets[i] =
12207634c5f9SRasesh Mody 				*(uint64_t *)(
12217634c5f9SRasesh Mody 					((char *)(qdev->fp_array[(qid)].rxq)) +
12227634c5f9SRasesh Mody 					offsetof(struct qede_rx_queue,
12237634c5f9SRasesh Mody 					rcv_pkts));
12247634c5f9SRasesh Mody 			eth_stats->q_errors[i] =
12257634c5f9SRasesh Mody 				*(uint64_t *)(
12267634c5f9SRasesh Mody 					((char *)(qdev->fp_array[(qid)].rxq)) +
12277634c5f9SRasesh Mody 					offsetof(struct qede_rx_queue,
12287634c5f9SRasesh Mody 					rx_hw_errors)) +
12297634c5f9SRasesh Mody 				*(uint64_t *)(
12307634c5f9SRasesh Mody 					((char *)(qdev->fp_array[(qid)].rxq)) +
12317634c5f9SRasesh Mody 					offsetof(struct qede_rx_queue,
12327634c5f9SRasesh Mody 					rx_alloc_errors));
12337634c5f9SRasesh Mody 			i++;
12347634c5f9SRasesh Mody 		}
123506e83c4eSRasesh Mody 		if (i == rxq_stat_cntrs)
123606e83c4eSRasesh Mody 			break;
123706e83c4eSRasesh Mody 	}
12387634c5f9SRasesh Mody 
123906e83c4eSRasesh Mody 	for (qid = 0; qid < QEDE_QUEUE_CNT(qdev); qid++) {
12407634c5f9SRasesh Mody 		if (qdev->fp_array[qid].type & QEDE_FASTPATH_TX) {
12417634c5f9SRasesh Mody 			txq = qdev->fp_array[(qid)].txqs[0];
12427634c5f9SRasesh Mody 			eth_stats->q_opackets[j] =
12437634c5f9SRasesh Mody 				*((uint64_t *)(uintptr_t)
12447634c5f9SRasesh Mody 					(((uint64_t)(uintptr_t)(txq)) +
12457634c5f9SRasesh Mody 					 offsetof(struct qede_tx_queue,
12467634c5f9SRasesh Mody 						  xmit_pkts)));
12477634c5f9SRasesh Mody 			j++;
12487634c5f9SRasesh Mody 		}
124906e83c4eSRasesh Mody 		if (j == txq_stat_cntrs)
125006e83c4eSRasesh Mody 			break;
12517634c5f9SRasesh Mody 	}
12527634c5f9SRasesh Mody }
12537634c5f9SRasesh Mody 
12547634c5f9SRasesh Mody static unsigned
12557634c5f9SRasesh Mody qede_get_xstats_count(struct qede_dev *qdev) {
12567634c5f9SRasesh Mody 	return RTE_DIM(qede_xstats_strings) +
125706e83c4eSRasesh Mody 		(RTE_DIM(qede_rxq_xstats_strings) *
125806e83c4eSRasesh Mody 		 RTE_MIN(QEDE_RSS_COUNT(qdev),
125906e83c4eSRasesh Mody 			 RTE_ETHDEV_QUEUE_STAT_CNTRS));
1260d1216e22SRasesh Mody }
12612ea6f76aSRasesh Mody 
1262d1216e22SRasesh Mody static int
1263d1216e22SRasesh Mody qede_get_xstats_names(__rte_unused struct rte_eth_dev *dev,
1264d1216e22SRasesh Mody 		      struct rte_eth_xstat_name *xstats_names, unsigned limit)
1265d1216e22SRasesh Mody {
12667634c5f9SRasesh Mody 	struct qede_dev *qdev = dev->data->dev_private;
12677634c5f9SRasesh Mody 	const unsigned int stat_cnt = qede_get_xstats_count(qdev);
12687634c5f9SRasesh Mody 	unsigned int i, qid, stat_idx = 0;
126906e83c4eSRasesh Mody 	unsigned int rxq_stat_cntrs;
1270d1216e22SRasesh Mody 
12717634c5f9SRasesh Mody 	if (xstats_names != NULL) {
12727634c5f9SRasesh Mody 		for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) {
12737634c5f9SRasesh Mody 			snprintf(xstats_names[stat_idx].name,
12747634c5f9SRasesh Mody 				sizeof(xstats_names[stat_idx].name),
1275d1216e22SRasesh Mody 				"%s",
1276d1216e22SRasesh Mody 				qede_xstats_strings[i].name);
12777634c5f9SRasesh Mody 			stat_idx++;
12787634c5f9SRasesh Mody 		}
12797634c5f9SRasesh Mody 
128006e83c4eSRasesh Mody 		rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(qdev),
128106e83c4eSRasesh Mody 					 RTE_ETHDEV_QUEUE_STAT_CNTRS);
128206e83c4eSRasesh Mody 		for (qid = 0; qid < rxq_stat_cntrs; qid++) {
12837634c5f9SRasesh Mody 			for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) {
12847634c5f9SRasesh Mody 				snprintf(xstats_names[stat_idx].name,
12857634c5f9SRasesh Mody 					sizeof(xstats_names[stat_idx].name),
12867634c5f9SRasesh Mody 					"%.4s%d%s",
12877634c5f9SRasesh Mody 					qede_rxq_xstats_strings[i].name, qid,
12887634c5f9SRasesh Mody 					qede_rxq_xstats_strings[i].name + 4);
12897634c5f9SRasesh Mody 				stat_idx++;
12907634c5f9SRasesh Mody 			}
12917634c5f9SRasesh Mody 		}
12927634c5f9SRasesh Mody 	}
1293d1216e22SRasesh Mody 
1294d1216e22SRasesh Mody 	return stat_cnt;
1295d1216e22SRasesh Mody }
1296d1216e22SRasesh Mody 
1297d1216e22SRasesh Mody static int
1298d1216e22SRasesh Mody qede_get_xstats(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
1299d1216e22SRasesh Mody 		unsigned int n)
1300d1216e22SRasesh Mody {
1301d1216e22SRasesh Mody 	struct qede_dev *qdev = dev->data->dev_private;
1302d1216e22SRasesh Mody 	struct ecore_dev *edev = &qdev->edev;
1303d1216e22SRasesh Mody 	struct ecore_eth_stats stats;
13047634c5f9SRasesh Mody 	const unsigned int num = qede_get_xstats_count(qdev);
13057634c5f9SRasesh Mody 	unsigned int i, qid, stat_idx = 0;
130606e83c4eSRasesh Mody 	unsigned int rxq_stat_cntrs;
1307d1216e22SRasesh Mody 
1308d1216e22SRasesh Mody 	if (n < num)
1309d1216e22SRasesh Mody 		return num;
1310d1216e22SRasesh Mody 
1311d1216e22SRasesh Mody 	qdev->ops->get_vport_stats(edev, &stats);
1312d1216e22SRasesh Mody 
13137634c5f9SRasesh Mody 	for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) {
13147634c5f9SRasesh Mody 		xstats[stat_idx].value = *(uint64_t *)(((char *)&stats) +
13157634c5f9SRasesh Mody 					     qede_xstats_strings[i].offset);
1316513c78aeSOlivier Matz 		xstats[stat_idx].id = stat_idx;
13177634c5f9SRasesh Mody 		stat_idx++;
13187634c5f9SRasesh Mody 	}
1319d1216e22SRasesh Mody 
132006e83c4eSRasesh Mody 	rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(qdev),
132106e83c4eSRasesh Mody 				 RTE_ETHDEV_QUEUE_STAT_CNTRS);
132206e83c4eSRasesh Mody 	for (qid = 0; qid < rxq_stat_cntrs; qid++) {
13237634c5f9SRasesh Mody 		if (qdev->fp_array[qid].type & QEDE_FASTPATH_RX) {
13247634c5f9SRasesh Mody 			for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) {
13257634c5f9SRasesh Mody 				xstats[stat_idx].value = *(uint64_t *)(
13267634c5f9SRasesh Mody 					((char *)(qdev->fp_array[(qid)].rxq)) +
13277634c5f9SRasesh Mody 					 qede_rxq_xstats_strings[i].offset);
1328513c78aeSOlivier Matz 				xstats[stat_idx].id = stat_idx;
13297634c5f9SRasesh Mody 				stat_idx++;
13307634c5f9SRasesh Mody 			}
13317634c5f9SRasesh Mody 		}
13327634c5f9SRasesh Mody 	}
13337634c5f9SRasesh Mody 
13347634c5f9SRasesh Mody 	return stat_idx;
1335d1216e22SRasesh Mody }
1336d1216e22SRasesh Mody 
1337d1216e22SRasesh Mody static void
1338d1216e22SRasesh Mody qede_reset_xstats(struct rte_eth_dev *dev)
1339d1216e22SRasesh Mody {
1340d1216e22SRasesh Mody 	struct qede_dev *qdev = dev->data->dev_private;
1341d1216e22SRasesh Mody 	struct ecore_dev *edev = &qdev->edev;
1342d1216e22SRasesh Mody 
1343d1216e22SRasesh Mody 	ecore_reset_vport_stats(edev);
13442ea6f76aSRasesh Mody }
13452ea6f76aSRasesh Mody 
13462ea6f76aSRasesh Mody int qede_dev_set_link_state(struct rte_eth_dev *eth_dev, bool link_up)
13472ea6f76aSRasesh Mody {
13482ea6f76aSRasesh Mody 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
13492ea6f76aSRasesh Mody 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
13502ea6f76aSRasesh Mody 	struct qed_link_params link_params;
13512ea6f76aSRasesh Mody 	int rc;
13522ea6f76aSRasesh Mody 
13532ea6f76aSRasesh Mody 	DP_INFO(edev, "setting link state %d\n", link_up);
13542ea6f76aSRasesh Mody 	memset(&link_params, 0, sizeof(link_params));
13552ea6f76aSRasesh Mody 	link_params.link_up = link_up;
13562ea6f76aSRasesh Mody 	rc = qdev->ops->common->set_link(edev, &link_params);
13572ea6f76aSRasesh Mody 	if (rc != ECORE_SUCCESS)
13582ea6f76aSRasesh Mody 		DP_ERR(edev, "Unable to set link state %d\n", link_up);
13592ea6f76aSRasesh Mody 
13602ea6f76aSRasesh Mody 	return rc;
13612ea6f76aSRasesh Mody }
13622ea6f76aSRasesh Mody 
13632ea6f76aSRasesh Mody static int qede_dev_set_link_up(struct rte_eth_dev *eth_dev)
13642ea6f76aSRasesh Mody {
13652ea6f76aSRasesh Mody 	return qede_dev_set_link_state(eth_dev, true);
13662ea6f76aSRasesh Mody }
13672ea6f76aSRasesh Mody 
13682ea6f76aSRasesh Mody static int qede_dev_set_link_down(struct rte_eth_dev *eth_dev)
13692ea6f76aSRasesh Mody {
13702ea6f76aSRasesh Mody 	return qede_dev_set_link_state(eth_dev, false);
13712ea6f76aSRasesh Mody }
13722ea6f76aSRasesh Mody 
13735cdd769aSRasesh Mody static void qede_reset_stats(struct rte_eth_dev *eth_dev)
13745cdd769aSRasesh Mody {
13755cdd769aSRasesh Mody 	struct qede_dev *qdev = eth_dev->data->dev_private;
13765cdd769aSRasesh Mody 	struct ecore_dev *edev = &qdev->edev;
13775cdd769aSRasesh Mody 
13785cdd769aSRasesh Mody 	ecore_reset_vport_stats(edev);
13795cdd769aSRasesh Mody }
13805cdd769aSRasesh Mody 
13812ea6f76aSRasesh Mody static void qede_allmulticast_enable(struct rte_eth_dev *eth_dev)
13822ea6f76aSRasesh Mody {
13832ea6f76aSRasesh Mody 	enum qed_filter_rx_mode_type type =
13842ea6f76aSRasesh Mody 	    QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC;
13852ea6f76aSRasesh Mody 
13862ea6f76aSRasesh Mody 	if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1)
13872ea6f76aSRasesh Mody 		type |= QED_FILTER_RX_MODE_TYPE_PROMISC;
13882ea6f76aSRasesh Mody 
138977fac1b5SHarish Patil 	qed_configure_filter_rx_mode(eth_dev, type);
13902ea6f76aSRasesh Mody }
13912ea6f76aSRasesh Mody 
13922ea6f76aSRasesh Mody static void qede_allmulticast_disable(struct rte_eth_dev *eth_dev)
13932ea6f76aSRasesh Mody {
13942ea6f76aSRasesh Mody 	if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1)
139577fac1b5SHarish Patil 		qed_configure_filter_rx_mode(eth_dev,
139677fac1b5SHarish Patil 				QED_FILTER_RX_MODE_TYPE_PROMISC);
13972ea6f76aSRasesh Mody 	else
139877fac1b5SHarish Patil 		qed_configure_filter_rx_mode(eth_dev,
139977fac1b5SHarish Patil 				QED_FILTER_RX_MODE_TYPE_REGULAR);
14002ea6f76aSRasesh Mody }
14012ea6f76aSRasesh Mody 
14022ea6f76aSRasesh Mody static int qede_flow_ctrl_set(struct rte_eth_dev *eth_dev,
14032ea6f76aSRasesh Mody 			      struct rte_eth_fc_conf *fc_conf)
14042ea6f76aSRasesh Mody {
14052ea6f76aSRasesh Mody 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
14062ea6f76aSRasesh Mody 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
14072ea6f76aSRasesh Mody 	struct qed_link_output current_link;
14082ea6f76aSRasesh Mody 	struct qed_link_params params;
14092ea6f76aSRasesh Mody 
14102ea6f76aSRasesh Mody 	memset(&current_link, 0, sizeof(current_link));
14112ea6f76aSRasesh Mody 	qdev->ops->common->get_link(edev, &current_link);
14122ea6f76aSRasesh Mody 
14132ea6f76aSRasesh Mody 	memset(&params, 0, sizeof(params));
14142ea6f76aSRasesh Mody 	params.override_flags |= QED_LINK_OVERRIDE_PAUSE_CONFIG;
14152ea6f76aSRasesh Mody 	if (fc_conf->autoneg) {
14162ea6f76aSRasesh Mody 		if (!(current_link.supported_caps & QEDE_SUPPORTED_AUTONEG)) {
14172ea6f76aSRasesh Mody 			DP_ERR(edev, "Autoneg not supported\n");
14182ea6f76aSRasesh Mody 			return -EINVAL;
14192ea6f76aSRasesh Mody 		}
14202ea6f76aSRasesh Mody 		params.pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE;
14212ea6f76aSRasesh Mody 	}
14222ea6f76aSRasesh Mody 
14232ea6f76aSRasesh Mody 	/* Pause is assumed to be supported (SUPPORTED_Pause) */
14242ea6f76aSRasesh Mody 	if (fc_conf->mode == RTE_FC_FULL)
14252ea6f76aSRasesh Mody 		params.pause_config |= (QED_LINK_PAUSE_TX_ENABLE |
14262ea6f76aSRasesh Mody 					QED_LINK_PAUSE_RX_ENABLE);
14272ea6f76aSRasesh Mody 	if (fc_conf->mode == RTE_FC_TX_PAUSE)
14282ea6f76aSRasesh Mody 		params.pause_config |= QED_LINK_PAUSE_TX_ENABLE;
14292ea6f76aSRasesh Mody 	if (fc_conf->mode == RTE_FC_RX_PAUSE)
14302ea6f76aSRasesh Mody 		params.pause_config |= QED_LINK_PAUSE_RX_ENABLE;
14312ea6f76aSRasesh Mody 
14322ea6f76aSRasesh Mody 	params.link_up = true;
14332ea6f76aSRasesh Mody 	(void)qdev->ops->common->set_link(edev, &params);
14342ea6f76aSRasesh Mody 
14352ea6f76aSRasesh Mody 	return 0;
14362ea6f76aSRasesh Mody }
14372ea6f76aSRasesh Mody 
14382ea6f76aSRasesh Mody static int qede_flow_ctrl_get(struct rte_eth_dev *eth_dev,
14392ea6f76aSRasesh Mody 			      struct rte_eth_fc_conf *fc_conf)
14402ea6f76aSRasesh Mody {
14412ea6f76aSRasesh Mody 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
14422ea6f76aSRasesh Mody 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
14432ea6f76aSRasesh Mody 	struct qed_link_output current_link;
14442ea6f76aSRasesh Mody 
14452ea6f76aSRasesh Mody 	memset(&current_link, 0, sizeof(current_link));
14462ea6f76aSRasesh Mody 	qdev->ops->common->get_link(edev, &current_link);
14472ea6f76aSRasesh Mody 
14482ea6f76aSRasesh Mody 	if (current_link.pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE)
14492ea6f76aSRasesh Mody 		fc_conf->autoneg = true;
14502ea6f76aSRasesh Mody 
14512ea6f76aSRasesh Mody 	if (current_link.pause_config & (QED_LINK_PAUSE_RX_ENABLE |
14522ea6f76aSRasesh Mody 					 QED_LINK_PAUSE_TX_ENABLE))
14532ea6f76aSRasesh Mody 		fc_conf->mode = RTE_FC_FULL;
14542ea6f76aSRasesh Mody 	else if (current_link.pause_config & QED_LINK_PAUSE_RX_ENABLE)
14552ea6f76aSRasesh Mody 		fc_conf->mode = RTE_FC_RX_PAUSE;
14562ea6f76aSRasesh Mody 	else if (current_link.pause_config & QED_LINK_PAUSE_TX_ENABLE)
14572ea6f76aSRasesh Mody 		fc_conf->mode = RTE_FC_TX_PAUSE;
14582ea6f76aSRasesh Mody 	else
14592ea6f76aSRasesh Mody 		fc_conf->mode = RTE_FC_NONE;
14602ea6f76aSRasesh Mody 
14612ea6f76aSRasesh Mody 	return 0;
14622ea6f76aSRasesh Mody }
14632ea6f76aSRasesh Mody 
14642ea6f76aSRasesh Mody static const uint32_t *
14652ea6f76aSRasesh Mody qede_dev_supported_ptypes_get(struct rte_eth_dev *eth_dev)
14662ea6f76aSRasesh Mody {
14672ea6f76aSRasesh Mody 	static const uint32_t ptypes[] = {
14682ea6f76aSRasesh Mody 		RTE_PTYPE_L3_IPV4,
14692ea6f76aSRasesh Mody 		RTE_PTYPE_L3_IPV6,
14702ea6f76aSRasesh Mody 		RTE_PTYPE_UNKNOWN
14712ea6f76aSRasesh Mody 	};
14722ea6f76aSRasesh Mody 
14732ea6f76aSRasesh Mody 	if (eth_dev->rx_pkt_burst == qede_recv_pkts)
14742ea6f76aSRasesh Mody 		return ptypes;
14752ea6f76aSRasesh Mody 
14762ea6f76aSRasesh Mody 	return NULL;
14772ea6f76aSRasesh Mody }
14782ea6f76aSRasesh Mody 
14797ab35bf6SHarish Patil static void qede_init_rss_caps(uint8_t *rss_caps, uint64_t hf)
14809c5d0a66SHarish Patil {
14819c5d0a66SHarish Patil 	*rss_caps = 0;
14829c5d0a66SHarish Patil 	*rss_caps |= (hf & ETH_RSS_IPV4)              ? ECORE_RSS_IPV4 : 0;
14839c5d0a66SHarish Patil 	*rss_caps |= (hf & ETH_RSS_IPV6)              ? ECORE_RSS_IPV6 : 0;
14849c5d0a66SHarish Patil 	*rss_caps |= (hf & ETH_RSS_IPV6_EX)           ? ECORE_RSS_IPV6 : 0;
14859c5d0a66SHarish Patil 	*rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_TCP)  ? ECORE_RSS_IPV4_TCP : 0;
14869c5d0a66SHarish Patil 	*rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_TCP)  ? ECORE_RSS_IPV6_TCP : 0;
14879c5d0a66SHarish Patil 	*rss_caps |= (hf & ETH_RSS_IPV6_TCP_EX)       ? ECORE_RSS_IPV6_TCP : 0;
148882bd0987SHarish Patil 	*rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_UDP)  ? ECORE_RSS_IPV4_UDP : 0;
148982bd0987SHarish Patil 	*rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_UDP)  ? ECORE_RSS_IPV6_UDP : 0;
14909c5d0a66SHarish Patil }
14919c5d0a66SHarish Patil 
14929c5d0a66SHarish Patil static int qede_rss_hash_update(struct rte_eth_dev *eth_dev,
14934c98f276SSony Chacko 				struct rte_eth_rss_conf *rss_conf)
14944c98f276SSony Chacko {
14957ab35bf6SHarish Patil 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
14967ab35bf6SHarish Patil 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
14977ab35bf6SHarish Patil 	struct ecore_sp_vport_update_params vport_update_params;
14987ab35bf6SHarish Patil 	struct ecore_rss_params rss_params;
14997ab35bf6SHarish Patil 	struct ecore_hwfn *p_hwfn;
15004c98f276SSony Chacko 	uint32_t *key = (uint32_t *)rss_conf->rss_key;
15014c98f276SSony Chacko 	uint64_t hf = rss_conf->rss_hf;
15027ab35bf6SHarish Patil 	uint8_t len = rss_conf->rss_key_len;
150369d7ba88SRasesh Mody 	uint8_t idx;
15047ab35bf6SHarish Patil 	uint8_t i;
15057ab35bf6SHarish Patil 	int rc;
15064c98f276SSony Chacko 
15074c98f276SSony Chacko 	memset(&vport_update_params, 0, sizeof(vport_update_params));
15087ab35bf6SHarish Patil 	memset(&rss_params, 0, sizeof(rss_params));
15097ab35bf6SHarish Patil 
15107ab35bf6SHarish Patil 	DP_INFO(edev, "RSS hf = 0x%lx len = %u key = %p\n",
15117ab35bf6SHarish Patil 		(unsigned long)hf, len, key);
15124c98f276SSony Chacko 
15139c5d0a66SHarish Patil 	if (hf != 0) {
15147ab35bf6SHarish Patil 		/* Enabling RSS */
15157ab35bf6SHarish Patil 		DP_INFO(edev, "Enabling rss\n");
15169c5d0a66SHarish Patil 
15177ab35bf6SHarish Patil 		/* RSS caps */
15187ab35bf6SHarish Patil 		qede_init_rss_caps(&rss_params.rss_caps, hf);
15197ab35bf6SHarish Patil 		rss_params.update_rss_capabilities = 1;
15207ab35bf6SHarish Patil 
15217ab35bf6SHarish Patil 		/* RSS hash key */
15227ab35bf6SHarish Patil 		if (key) {
15237ab35bf6SHarish Patil 			if (len > (ECORE_RSS_KEY_SIZE * sizeof(uint32_t))) {
15247ab35bf6SHarish Patil 				DP_ERR(edev, "RSS key length exceeds limit\n");
15259c5d0a66SHarish Patil 				return -EINVAL;
15267ab35bf6SHarish Patil 			}
15277ab35bf6SHarish Patil 			DP_INFO(edev, "Applying user supplied hash key\n");
15287ab35bf6SHarish Patil 			rss_params.update_rss_key = 1;
15297ab35bf6SHarish Patil 			memcpy(&rss_params.rss_key, key, len);
15307ab35bf6SHarish Patil 		}
15317ab35bf6SHarish Patil 		rss_params.rss_enable = 1;
15324c98f276SSony Chacko 	}
15334c98f276SSony Chacko 
15347ab35bf6SHarish Patil 	rss_params.update_rss_config = 1;
15357ab35bf6SHarish Patil 	/* tbl_size has to be set with capabilities */
15367ab35bf6SHarish Patil 	rss_params.rss_table_size_log = 7;
15377ab35bf6SHarish Patil 	vport_update_params.vport_id = 0;
153869d7ba88SRasesh Mody 	/* pass the L2 handles instead of qids */
153969d7ba88SRasesh Mody 	for (i = 0 ; i < ECORE_RSS_IND_TABLE_SIZE ; i++) {
154069d7ba88SRasesh Mody 		idx = qdev->rss_ind_table[i];
154169d7ba88SRasesh Mody 		rss_params.rss_ind_table[i] = qdev->fp_array[idx].rxq->handle;
154269d7ba88SRasesh Mody 	}
15437ab35bf6SHarish Patil 	vport_update_params.rss_params = &rss_params;
15447ab35bf6SHarish Patil 
15457ab35bf6SHarish Patil 	for_each_hwfn(edev, i) {
15467ab35bf6SHarish Patil 		p_hwfn = &edev->hwfns[i];
15477ab35bf6SHarish Patil 		vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid;
15487ab35bf6SHarish Patil 		rc = ecore_sp_vport_update(p_hwfn, &vport_update_params,
15497ab35bf6SHarish Patil 					   ECORE_SPQ_MODE_EBLOCK, NULL);
15507ab35bf6SHarish Patil 		if (rc) {
15517ab35bf6SHarish Patil 			DP_ERR(edev, "vport-update for RSS failed\n");
15527ab35bf6SHarish Patil 			return rc;
15537ab35bf6SHarish Patil 		}
15547ab35bf6SHarish Patil 	}
15557ab35bf6SHarish Patil 	qdev->rss_enable = rss_params.rss_enable;
15567ab35bf6SHarish Patil 
15577ab35bf6SHarish Patil 	/* Update local structure for hash query */
15587ab35bf6SHarish Patil 	qdev->rss_conf.rss_hf = hf;
15597ab35bf6SHarish Patil 	qdev->rss_conf.rss_key_len = len;
15607ab35bf6SHarish Patil 	if (qdev->rss_enable) {
15617ab35bf6SHarish Patil 		if  (qdev->rss_conf.rss_key == NULL) {
15627ab35bf6SHarish Patil 			qdev->rss_conf.rss_key = (uint8_t *)malloc(len);
15637ab35bf6SHarish Patil 			if (qdev->rss_conf.rss_key == NULL) {
15647ab35bf6SHarish Patil 				DP_ERR(edev, "No memory to store RSS key\n");
15657ab35bf6SHarish Patil 				return -ENOMEM;
15667ab35bf6SHarish Patil 			}
15677ab35bf6SHarish Patil 		}
15687ab35bf6SHarish Patil 		if (key && len) {
15697ab35bf6SHarish Patil 			DP_INFO(edev, "Storing RSS key\n");
15707ab35bf6SHarish Patil 			memcpy(qdev->rss_conf.rss_key, key, len);
15717ab35bf6SHarish Patil 		}
15727ab35bf6SHarish Patil 	} else if (!qdev->rss_enable && len == 0) {
15737ab35bf6SHarish Patil 		if (qdev->rss_conf.rss_key) {
15747ab35bf6SHarish Patil 			free(qdev->rss_conf.rss_key);
15757ab35bf6SHarish Patil 			qdev->rss_conf.rss_key = NULL;
15767ab35bf6SHarish Patil 			DP_INFO(edev, "Free RSS key\n");
15777ab35bf6SHarish Patil 		}
15787ab35bf6SHarish Patil 	}
15797ab35bf6SHarish Patil 
15807ab35bf6SHarish Patil 	return 0;
15817ab35bf6SHarish Patil }
15827ab35bf6SHarish Patil 
15837ab35bf6SHarish Patil static int qede_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
15846d9e26c4SSony Chacko 			   struct rte_eth_rss_conf *rss_conf)
15856d9e26c4SSony Chacko {
15867ab35bf6SHarish Patil 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
15876d9e26c4SSony Chacko 
15887ab35bf6SHarish Patil 	rss_conf->rss_hf = qdev->rss_conf.rss_hf;
15897ab35bf6SHarish Patil 	rss_conf->rss_key_len = qdev->rss_conf.rss_key_len;
15906d9e26c4SSony Chacko 
15917ab35bf6SHarish Patil 	if (rss_conf->rss_key && qdev->rss_conf.rss_key)
15927ab35bf6SHarish Patil 		memcpy(rss_conf->rss_key, qdev->rss_conf.rss_key,
15937ab35bf6SHarish Patil 		       rss_conf->rss_key_len);
15946d9e26c4SSony Chacko 	return 0;
15956d9e26c4SSony Chacko }
15966d9e26c4SSony Chacko 
15979c5d0a66SHarish Patil static int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
1598e8876556SSony Chacko 				struct rte_eth_rss_reta_entry64 *reta_conf,
1599e8876556SSony Chacko 				uint16_t reta_size)
1600e8876556SSony Chacko {
16017ab35bf6SHarish Patil 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
16027ab35bf6SHarish Patil 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
16037ab35bf6SHarish Patil 	struct ecore_sp_vport_update_params vport_update_params;
16047ab35bf6SHarish Patil 	struct ecore_rss_params params;
16057ab35bf6SHarish Patil 	struct ecore_hwfn *p_hwfn;
1606e8876556SSony Chacko 	uint16_t i, idx, shift;
16077ab35bf6SHarish Patil 	uint8_t entry;
16087ab35bf6SHarish Patil 	int rc;
1609e8876556SSony Chacko 
1610e8876556SSony Chacko 	if (reta_size > ETH_RSS_RETA_SIZE_128) {
1611e8876556SSony Chacko 		DP_ERR(edev, "reta_size %d is not supported by hardware\n",
1612e8876556SSony Chacko 		       reta_size);
1613e8876556SSony Chacko 		return -EINVAL;
1614e8876556SSony Chacko 	}
1615e8876556SSony Chacko 
1616e8876556SSony Chacko 	memset(&vport_update_params, 0, sizeof(vport_update_params));
16177ab35bf6SHarish Patil 	memset(&params, 0, sizeof(params));
1618e8876556SSony Chacko 
1619e8876556SSony Chacko 	for (i = 0; i < reta_size; i++) {
1620e8876556SSony Chacko 		idx = i / RTE_RETA_GROUP_SIZE;
1621e8876556SSony Chacko 		shift = i % RTE_RETA_GROUP_SIZE;
1622e8876556SSony Chacko 		if (reta_conf[idx].mask & (1ULL << shift)) {
16237ab35bf6SHarish Patil 			entry = reta_conf[idx].reta[shift];
162469d7ba88SRasesh Mody 			/* Pass rxq handles to ecore */
162569d7ba88SRasesh Mody 			params.rss_ind_table[i] =
162669d7ba88SRasesh Mody 					qdev->fp_array[entry].rxq->handle;
162769d7ba88SRasesh Mody 			/* Update the local copy for RETA query command */
162869d7ba88SRasesh Mody 			qdev->rss_ind_table[i] = entry;
1629e8876556SSony Chacko 		}
1630e8876556SSony Chacko 	}
1631e8876556SSony Chacko 
16327ab35bf6SHarish Patil 	/* Fix up RETA for CMT mode device */
16337ab35bf6SHarish Patil 	if (edev->num_hwfns > 1)
16347ab35bf6SHarish Patil 		qdev->rss_enable = qed_update_rss_parm_cmt(edev,
163569d7ba88SRasesh Mody 					params.rss_ind_table[0]);
16367ab35bf6SHarish Patil 	params.update_rss_ind_table = 1;
16377ab35bf6SHarish Patil 	params.rss_table_size_log = 7;
16387ab35bf6SHarish Patil 	params.update_rss_config = 1;
1639e8876556SSony Chacko 	vport_update_params.vport_id = 0;
16407ab35bf6SHarish Patil 	/* Use the current value of rss_enable */
16417ab35bf6SHarish Patil 	params.rss_enable = qdev->rss_enable;
16427ab35bf6SHarish Patil 	vport_update_params.rss_params = &params;
1643e8876556SSony Chacko 
16447ab35bf6SHarish Patil 	for_each_hwfn(edev, i) {
16457ab35bf6SHarish Patil 		p_hwfn = &edev->hwfns[i];
16467ab35bf6SHarish Patil 		vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid;
16477ab35bf6SHarish Patil 		rc = ecore_sp_vport_update(p_hwfn, &vport_update_params,
16487ab35bf6SHarish Patil 					   ECORE_SPQ_MODE_EBLOCK, NULL);
16497ab35bf6SHarish Patil 		if (rc) {
16507ab35bf6SHarish Patil 			DP_ERR(edev, "vport-update for RSS failed\n");
16517ab35bf6SHarish Patil 			return rc;
16527ab35bf6SHarish Patil 		}
1653e8876556SSony Chacko 	}
1654e8876556SSony Chacko 
16557ab35bf6SHarish Patil 	return 0;
16567ab35bf6SHarish Patil }
16577ab35bf6SHarish Patil 
16587ab35bf6SHarish Patil static int qede_rss_reta_query(struct rte_eth_dev *eth_dev,
16593dadf73eSSony Chacko 			       struct rte_eth_rss_reta_entry64 *reta_conf,
16603dadf73eSSony Chacko 			       uint16_t reta_size)
16613dadf73eSSony Chacko {
16623dadf73eSSony Chacko 	struct qede_dev *qdev = eth_dev->data->dev_private;
16637ab35bf6SHarish Patil 	struct ecore_dev *edev = &qdev->edev;
16643dadf73eSSony Chacko 	uint16_t i, idx, shift;
16657ab35bf6SHarish Patil 	uint8_t entry;
16663dadf73eSSony Chacko 
16673dadf73eSSony Chacko 	if (reta_size > ETH_RSS_RETA_SIZE_128) {
16683dadf73eSSony Chacko 		DP_ERR(edev, "reta_size %d is not supported\n",
16693dadf73eSSony Chacko 		       reta_size);
16707ab35bf6SHarish Patil 		return -EINVAL;
16713dadf73eSSony Chacko 	}
16723dadf73eSSony Chacko 
16733dadf73eSSony Chacko 	for (i = 0; i < reta_size; i++) {
16743dadf73eSSony Chacko 		idx = i / RTE_RETA_GROUP_SIZE;
16753dadf73eSSony Chacko 		shift = i % RTE_RETA_GROUP_SIZE;
16763dadf73eSSony Chacko 		if (reta_conf[idx].mask & (1ULL << shift)) {
16777ab35bf6SHarish Patil 			entry = qdev->rss_ind_table[i];
16783dadf73eSSony Chacko 			reta_conf[idx].reta[shift] = entry;
16793dadf73eSSony Chacko 		}
16803dadf73eSSony Chacko 	}
16813dadf73eSSony Chacko 
16823dadf73eSSony Chacko 	return 0;
16833dadf73eSSony Chacko }
16843dadf73eSSony Chacko 
1685200645acSSony Chacko int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
1686200645acSSony Chacko {
1687*1ef4c3a5SHarish Patil 	struct qede_dev *qdev = QEDE_INIT_QDEV(dev);
1688*1ef4c3a5SHarish Patil 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
1689200645acSSony Chacko 	struct rte_eth_dev_info dev_info = {0};
1690*1ef4c3a5SHarish Patil 	struct qede_fastpath *fp;
1691*1ef4c3a5SHarish Patil 	uint32_t frame_size;
1692*1ef4c3a5SHarish Patil 	uint16_t rx_buf_size;
1693*1ef4c3a5SHarish Patil 	uint16_t bufsz;
1694*1ef4c3a5SHarish Patil 	int i;
1695200645acSSony Chacko 
1696*1ef4c3a5SHarish Patil 	PMD_INIT_FUNC_TRACE(edev);
1697200645acSSony Chacko 	qede_dev_info_get(dev, &dev_info);
1698*1ef4c3a5SHarish Patil 	frame_size = mtu + QEDE_ETH_OVERHEAD;
1699*1ef4c3a5SHarish Patil 	if ((mtu < ETHER_MIN_MTU) || (frame_size > dev_info.max_rx_pktlen)) {
1700*1ef4c3a5SHarish Patil 		DP_ERR(edev, "MTU %u out of range\n", mtu);
1701200645acSSony Chacko 		return -EINVAL;
1702*1ef4c3a5SHarish Patil 	}
1703200645acSSony Chacko 	if (!dev->data->scattered_rx &&
1704*1ef4c3a5SHarish Patil 	    frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) {
1705*1ef4c3a5SHarish Patil 		DP_INFO(edev, "MTU greater than minimum RX buffer size of %u\n",
1706*1ef4c3a5SHarish Patil 			dev->data->min_rx_buf_size);
1707200645acSSony Chacko 		return -EINVAL;
1708*1ef4c3a5SHarish Patil 	}
1709*1ef4c3a5SHarish Patil 	/* Temporarily replace I/O functions with dummy ones. It cannot
1710*1ef4c3a5SHarish Patil 	 * be set to NULL because rte_eth_rx_burst() doesn't check for NULL.
1711*1ef4c3a5SHarish Patil 	 */
1712*1ef4c3a5SHarish Patil 	dev->rx_pkt_burst = qede_rxtx_pkts_dummy;
1713*1ef4c3a5SHarish Patil 	dev->tx_pkt_burst = qede_rxtx_pkts_dummy;
1714*1ef4c3a5SHarish Patil 	qede_dev_stop(dev);
1715*1ef4c3a5SHarish Patil 	rte_delay_ms(1000);
1716*1ef4c3a5SHarish Patil 	qdev->mtu = mtu;
1717*1ef4c3a5SHarish Patil 	/* Fix up RX buf size for all queues of the port */
1718*1ef4c3a5SHarish Patil 	for_each_queue(i) {
1719*1ef4c3a5SHarish Patil 		fp = &qdev->fp_array[i];
1720*1ef4c3a5SHarish Patil 		if (fp->type & QEDE_FASTPATH_RX) {
1721*1ef4c3a5SHarish Patil 			bufsz = (uint16_t)rte_pktmbuf_data_room_size(
1722*1ef4c3a5SHarish Patil 				fp->rxq->mb_pool) - RTE_PKTMBUF_HEADROOM;
1723*1ef4c3a5SHarish Patil 			if (dev->data->scattered_rx)
1724*1ef4c3a5SHarish Patil 				rx_buf_size = bufsz + QEDE_ETH_OVERHEAD;
1725*1ef4c3a5SHarish Patil 			else
1726*1ef4c3a5SHarish Patil 				rx_buf_size = mtu + QEDE_ETH_OVERHEAD;
1727*1ef4c3a5SHarish Patil 			rx_buf_size = QEDE_CEIL_TO_CACHE_LINE_SIZE(rx_buf_size);
1728*1ef4c3a5SHarish Patil 			fp->rxq->rx_buf_size = rx_buf_size;
1729*1ef4c3a5SHarish Patil 			DP_INFO(edev, "buf_size adjusted to %u\n", rx_buf_size);
1730*1ef4c3a5SHarish Patil 		}
1731*1ef4c3a5SHarish Patil 	}
1732*1ef4c3a5SHarish Patil 	qede_dev_start(dev);
1733200645acSSony Chacko 	if (frame_size > ETHER_MAX_LEN)
1734200645acSSony Chacko 		dev->data->dev_conf.rxmode.jumbo_frame = 1;
1735200645acSSony Chacko 	else
1736200645acSSony Chacko 		dev->data->dev_conf.rxmode.jumbo_frame = 0;
1737200645acSSony Chacko 	/* update max frame size */
1738200645acSSony Chacko 	dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
1739*1ef4c3a5SHarish Patil 	/* Reassign back */
1740*1ef4c3a5SHarish Patil 	dev->rx_pkt_burst = qede_recv_pkts;
1741*1ef4c3a5SHarish Patil 	dev->tx_pkt_burst = qede_xmit_pkts;
1742200645acSSony Chacko 
1743200645acSSony Chacko 	return 0;
1744200645acSSony Chacko }
1745200645acSSony Chacko 
174652d94b57SHarish Patil static int
174752d94b57SHarish Patil qede_conf_udp_dst_port(struct rte_eth_dev *eth_dev,
174852d94b57SHarish Patil 		       struct rte_eth_udp_tunnel *tunnel_udp,
174952d94b57SHarish Patil 		       bool add)
175052d94b57SHarish Patil {
175152d94b57SHarish Patil 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
175252d94b57SHarish Patil 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
1753adce1f86SRasesh Mody 	struct ecore_tunnel_info tunn; /* @DPDK */
175452d94b57SHarish Patil 	struct ecore_hwfn *p_hwfn;
175552d94b57SHarish Patil 	int rc, i;
175652d94b57SHarish Patil 
175752d94b57SHarish Patil 	PMD_INIT_FUNC_TRACE(edev);
175852d94b57SHarish Patil 
1759adce1f86SRasesh Mody 	memset(&tunn, 0, sizeof(tunn));
176052d94b57SHarish Patil 	if (tunnel_udp->prot_type == RTE_TUNNEL_TYPE_VXLAN) {
17610b090fd3SRasesh Mody 		tunn.vxlan_port.b_update_port = true;
17620b090fd3SRasesh Mody 		tunn.vxlan_port.port = (add) ? tunnel_udp->udp_port :
176352d94b57SHarish Patil 						  QEDE_VXLAN_DEF_PORT;
176452d94b57SHarish Patil 		for_each_hwfn(edev, i) {
176552d94b57SHarish Patil 			p_hwfn = &edev->hwfns[i];
1766adce1f86SRasesh Mody 			rc = ecore_sp_pf_update_tunn_cfg(p_hwfn, &tunn,
176752d94b57SHarish Patil 						ECORE_SPQ_MODE_CB, NULL);
176852d94b57SHarish Patil 			if (rc != ECORE_SUCCESS) {
176952d94b57SHarish Patil 				DP_ERR(edev, "Unable to config UDP port %u\n",
17700b090fd3SRasesh Mody 				       tunn.vxlan_port.port);
177152d94b57SHarish Patil 				return rc;
177252d94b57SHarish Patil 			}
177352d94b57SHarish Patil 		}
177452d94b57SHarish Patil 	}
177552d94b57SHarish Patil 
177652d94b57SHarish Patil 	return 0;
177752d94b57SHarish Patil }
177852d94b57SHarish Patil 
177952d94b57SHarish Patil int
178052d94b57SHarish Patil qede_udp_dst_port_del(struct rte_eth_dev *eth_dev,
178152d94b57SHarish Patil 		      struct rte_eth_udp_tunnel *tunnel_udp)
178252d94b57SHarish Patil {
178352d94b57SHarish Patil 	return qede_conf_udp_dst_port(eth_dev, tunnel_udp, false);
178452d94b57SHarish Patil }
178552d94b57SHarish Patil 
178652d94b57SHarish Patil int
178752d94b57SHarish Patil qede_udp_dst_port_add(struct rte_eth_dev *eth_dev,
178852d94b57SHarish Patil 		      struct rte_eth_udp_tunnel *tunnel_udp)
178952d94b57SHarish Patil {
179052d94b57SHarish Patil 	return qede_conf_udp_dst_port(eth_dev, tunnel_udp, true);
179152d94b57SHarish Patil }
179252d94b57SHarish Patil 
179352d94b57SHarish Patil static void qede_get_ecore_tunn_params(uint32_t filter, uint32_t *type,
179452d94b57SHarish Patil 				       uint32_t *clss, char *str)
179552d94b57SHarish Patil {
179652d94b57SHarish Patil 	uint16_t j;
179752d94b57SHarish Patil 	*clss = MAX_ECORE_TUNN_CLSS;
179852d94b57SHarish Patil 
179952d94b57SHarish Patil 	for (j = 0; j < RTE_DIM(qede_tunn_types); j++) {
180052d94b57SHarish Patil 		if (filter == qede_tunn_types[j].rte_filter_type) {
180152d94b57SHarish Patil 			*type = qede_tunn_types[j].qede_type;
180252d94b57SHarish Patil 			*clss = qede_tunn_types[j].qede_tunn_clss;
180352d94b57SHarish Patil 			strcpy(str, qede_tunn_types[j].string);
180452d94b57SHarish Patil 			return;
180552d94b57SHarish Patil 		}
180652d94b57SHarish Patil 	}
180752d94b57SHarish Patil }
180852d94b57SHarish Patil 
180952d94b57SHarish Patil static int
181052d94b57SHarish Patil qede_set_ucast_tunn_cmn_param(struct ecore_filter_ucast *ucast,
181152d94b57SHarish Patil 			      const struct rte_eth_tunnel_filter_conf *conf,
181252d94b57SHarish Patil 			      uint32_t type)
181352d94b57SHarish Patil {
181452d94b57SHarish Patil 	/* Init commmon ucast params first */
181552d94b57SHarish Patil 	qede_set_ucast_cmn_params(ucast);
181652d94b57SHarish Patil 
181752d94b57SHarish Patil 	/* Copy out the required fields based on classification type */
181852d94b57SHarish Patil 	ucast->type = type;
181952d94b57SHarish Patil 
182052d94b57SHarish Patil 	switch (type) {
182152d94b57SHarish Patil 	case ECORE_FILTER_VNI:
182252d94b57SHarish Patil 		ucast->vni = conf->tenant_id;
182352d94b57SHarish Patil 	break;
182452d94b57SHarish Patil 	case ECORE_FILTER_INNER_VLAN:
182552d94b57SHarish Patil 		ucast->vlan = conf->inner_vlan;
182652d94b57SHarish Patil 	break;
182752d94b57SHarish Patil 	case ECORE_FILTER_MAC:
182852d94b57SHarish Patil 		memcpy(ucast->mac, conf->outer_mac.addr_bytes,
182952d94b57SHarish Patil 		       ETHER_ADDR_LEN);
183052d94b57SHarish Patil 	break;
183152d94b57SHarish Patil 	case ECORE_FILTER_INNER_MAC:
183252d94b57SHarish Patil 		memcpy(ucast->mac, conf->inner_mac.addr_bytes,
183352d94b57SHarish Patil 		       ETHER_ADDR_LEN);
183452d94b57SHarish Patil 	break;
183552d94b57SHarish Patil 	case ECORE_FILTER_MAC_VNI_PAIR:
183652d94b57SHarish Patil 		memcpy(ucast->mac, conf->outer_mac.addr_bytes,
183752d94b57SHarish Patil 			ETHER_ADDR_LEN);
183852d94b57SHarish Patil 		ucast->vni = conf->tenant_id;
183952d94b57SHarish Patil 	break;
184052d94b57SHarish Patil 	case ECORE_FILTER_INNER_MAC_VNI_PAIR:
184152d94b57SHarish Patil 		memcpy(ucast->mac, conf->inner_mac.addr_bytes,
184252d94b57SHarish Patil 			ETHER_ADDR_LEN);
184352d94b57SHarish Patil 		ucast->vni = conf->tenant_id;
184452d94b57SHarish Patil 	break;
184552d94b57SHarish Patil 	case ECORE_FILTER_INNER_PAIR:
184652d94b57SHarish Patil 		memcpy(ucast->mac, conf->inner_mac.addr_bytes,
184752d94b57SHarish Patil 			ETHER_ADDR_LEN);
184852d94b57SHarish Patil 		ucast->vlan = conf->inner_vlan;
184952d94b57SHarish Patil 	break;
185052d94b57SHarish Patil 	default:
185152d94b57SHarish Patil 		return -EINVAL;
185252d94b57SHarish Patil 	}
185352d94b57SHarish Patil 
185452d94b57SHarish Patil 	return ECORE_SUCCESS;
185552d94b57SHarish Patil }
185652d94b57SHarish Patil 
185752d94b57SHarish Patil static int qede_vxlan_tunn_config(struct rte_eth_dev *eth_dev,
185852d94b57SHarish Patil 				  enum rte_filter_op filter_op,
185952d94b57SHarish Patil 				  const struct rte_eth_tunnel_filter_conf *conf)
186052d94b57SHarish Patil {
186152d94b57SHarish Patil 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
186252d94b57SHarish Patil 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
1863adce1f86SRasesh Mody 	struct ecore_tunnel_info tunn;
186452d94b57SHarish Patil 	struct ecore_hwfn *p_hwfn;
186552d94b57SHarish Patil 	enum ecore_filter_ucast_type type;
186652d94b57SHarish Patil 	enum ecore_tunn_clss clss;
186752d94b57SHarish Patil 	struct ecore_filter_ucast ucast;
186852d94b57SHarish Patil 	char str[80];
186952d94b57SHarish Patil 	uint16_t filter_type;
187052d94b57SHarish Patil 	int rc, i;
187152d94b57SHarish Patil 
187252d94b57SHarish Patil 	filter_type = conf->filter_type | qdev->vxlan_filter_type;
187352d94b57SHarish Patil 	/* First determine if the given filter classification is supported */
187452d94b57SHarish Patil 	qede_get_ecore_tunn_params(filter_type, &type, &clss, str);
187552d94b57SHarish Patil 	if (clss == MAX_ECORE_TUNN_CLSS) {
187652d94b57SHarish Patil 		DP_ERR(edev, "Wrong filter type\n");
187752d94b57SHarish Patil 		return -EINVAL;
187852d94b57SHarish Patil 	}
187952d94b57SHarish Patil 	/* Init tunnel ucast params */
188052d94b57SHarish Patil 	rc = qede_set_ucast_tunn_cmn_param(&ucast, conf, type);
188152d94b57SHarish Patil 	if (rc != ECORE_SUCCESS) {
188252d94b57SHarish Patil 		DP_ERR(edev, "Unsupported VxLAN filter type 0x%x\n",
188352d94b57SHarish Patil 				conf->filter_type);
188452d94b57SHarish Patil 		return rc;
188552d94b57SHarish Patil 	}
188652d94b57SHarish Patil 	DP_INFO(edev, "Rule: \"%s\", op %d, type 0x%x\n",
188752d94b57SHarish Patil 		str, filter_op, ucast.type);
188852d94b57SHarish Patil 	switch (filter_op) {
188952d94b57SHarish Patil 	case RTE_ETH_FILTER_ADD:
189052d94b57SHarish Patil 		ucast.opcode = ECORE_FILTER_ADD;
189152d94b57SHarish Patil 
189252d94b57SHarish Patil 		/* Skip MAC/VLAN if filter is based on VNI */
189352d94b57SHarish Patil 		if (!(filter_type & ETH_TUNNEL_FILTER_TENID)) {
189452d94b57SHarish Patil 			rc = qede_mac_int_ops(eth_dev, &ucast, 1);
189552d94b57SHarish Patil 			if (rc == 0) {
189652d94b57SHarish Patil 				/* Enable accept anyvlan */
189752d94b57SHarish Patil 				qede_config_accept_any_vlan(qdev, true);
189852d94b57SHarish Patil 			}
189952d94b57SHarish Patil 		} else {
190052d94b57SHarish Patil 			rc = qede_ucast_filter(eth_dev, &ucast, 1);
190152d94b57SHarish Patil 			if (rc == 0)
190252d94b57SHarish Patil 				rc = ecore_filter_ucast_cmd(edev, &ucast,
190352d94b57SHarish Patil 						    ECORE_SPQ_MODE_CB, NULL);
190452d94b57SHarish Patil 		}
190552d94b57SHarish Patil 
190652d94b57SHarish Patil 		if (rc != ECORE_SUCCESS)
190752d94b57SHarish Patil 			return rc;
190852d94b57SHarish Patil 
190952d94b57SHarish Patil 		qdev->vxlan_filter_type = filter_type;
191052d94b57SHarish Patil 
191152d94b57SHarish Patil 		DP_INFO(edev, "Enabling VXLAN tunneling\n");
19120b090fd3SRasesh Mody 		qede_set_cmn_tunn_param(&tunn, clss, true, true);
191352d94b57SHarish Patil 		for_each_hwfn(edev, i) {
191452d94b57SHarish Patil 			p_hwfn = &edev->hwfns[i];
191552d94b57SHarish Patil 			rc = ecore_sp_pf_update_tunn_cfg(p_hwfn,
1916adce1f86SRasesh Mody 				&tunn, ECORE_SPQ_MODE_CB, NULL);
191752d94b57SHarish Patil 			if (rc != ECORE_SUCCESS) {
191852d94b57SHarish Patil 				DP_ERR(edev, "Failed to update tunn_clss %u\n",
19190b090fd3SRasesh Mody 				       tunn.vxlan.tun_cls);
192052d94b57SHarish Patil 			}
192152d94b57SHarish Patil 		}
192252d94b57SHarish Patil 		qdev->num_tunn_filters++; /* Filter added successfully */
192352d94b57SHarish Patil 	break;
192452d94b57SHarish Patil 	case RTE_ETH_FILTER_DELETE:
192552d94b57SHarish Patil 		ucast.opcode = ECORE_FILTER_REMOVE;
192652d94b57SHarish Patil 
192752d94b57SHarish Patil 		if (!(filter_type & ETH_TUNNEL_FILTER_TENID)) {
192852d94b57SHarish Patil 			rc = qede_mac_int_ops(eth_dev, &ucast, 0);
192952d94b57SHarish Patil 		} else {
193052d94b57SHarish Patil 			rc = qede_ucast_filter(eth_dev, &ucast, 0);
193152d94b57SHarish Patil 			if (rc == 0)
193252d94b57SHarish Patil 				rc = ecore_filter_ucast_cmd(edev, &ucast,
193352d94b57SHarish Patil 						    ECORE_SPQ_MODE_CB, NULL);
193452d94b57SHarish Patil 		}
193552d94b57SHarish Patil 		if (rc != ECORE_SUCCESS)
193652d94b57SHarish Patil 			return rc;
193752d94b57SHarish Patil 
193852d94b57SHarish Patil 		qdev->vxlan_filter_type = filter_type;
193952d94b57SHarish Patil 		qdev->num_tunn_filters--;
194052d94b57SHarish Patil 
194152d94b57SHarish Patil 		/* Disable VXLAN if VXLAN filters become 0 */
194252d94b57SHarish Patil 		if (qdev->num_tunn_filters == 0) {
194352d94b57SHarish Patil 			DP_INFO(edev, "Disabling VXLAN tunneling\n");
194452d94b57SHarish Patil 
194552d94b57SHarish Patil 			/* Use 0 as tunnel mode */
19460b090fd3SRasesh Mody 			qede_set_cmn_tunn_param(&tunn, clss, false, true);
194752d94b57SHarish Patil 			for_each_hwfn(edev, i) {
194852d94b57SHarish Patil 				p_hwfn = &edev->hwfns[i];
1949adce1f86SRasesh Mody 				rc = ecore_sp_pf_update_tunn_cfg(p_hwfn, &tunn,
1950adce1f86SRasesh Mody 					ECORE_SPQ_MODE_CB, NULL);
195152d94b57SHarish Patil 				if (rc != ECORE_SUCCESS) {
195252d94b57SHarish Patil 					DP_ERR(edev,
195352d94b57SHarish Patil 						"Failed to update tunn_clss %u\n",
19540b090fd3SRasesh Mody 						tunn.vxlan.tun_cls);
195552d94b57SHarish Patil 					break;
195652d94b57SHarish Patil 				}
195752d94b57SHarish Patil 			}
195852d94b57SHarish Patil 		}
195952d94b57SHarish Patil 	break;
196052d94b57SHarish Patil 	default:
196152d94b57SHarish Patil 		DP_ERR(edev, "Unsupported operation %d\n", filter_op);
196252d94b57SHarish Patil 		return -EINVAL;
196352d94b57SHarish Patil 	}
196452d94b57SHarish Patil 	DP_INFO(edev, "Current VXLAN filters %d\n", qdev->num_tunn_filters);
196552d94b57SHarish Patil 
196652d94b57SHarish Patil 	return 0;
196752d94b57SHarish Patil }
196852d94b57SHarish Patil 
196952d94b57SHarish Patil int qede_dev_filter_ctrl(struct rte_eth_dev *eth_dev,
197052d94b57SHarish Patil 			 enum rte_filter_type filter_type,
197152d94b57SHarish Patil 			 enum rte_filter_op filter_op,
197252d94b57SHarish Patil 			 void *arg)
197352d94b57SHarish Patil {
197452d94b57SHarish Patil 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
197552d94b57SHarish Patil 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
197652d94b57SHarish Patil 	struct rte_eth_tunnel_filter_conf *filter_conf =
197752d94b57SHarish Patil 			(struct rte_eth_tunnel_filter_conf *)arg;
197852d94b57SHarish Patil 
197952d94b57SHarish Patil 	switch (filter_type) {
198052d94b57SHarish Patil 	case RTE_ETH_FILTER_TUNNEL:
198152d94b57SHarish Patil 		switch (filter_conf->tunnel_type) {
198252d94b57SHarish Patil 		case RTE_TUNNEL_TYPE_VXLAN:
198352d94b57SHarish Patil 			DP_INFO(edev,
198452d94b57SHarish Patil 				"Packet steering to the specified Rx queue"
198552d94b57SHarish Patil 				" is not supported with VXLAN tunneling");
198652d94b57SHarish Patil 			return(qede_vxlan_tunn_config(eth_dev, filter_op,
198752d94b57SHarish Patil 						      filter_conf));
198852d94b57SHarish Patil 		/* Place holders for future tunneling support */
198952d94b57SHarish Patil 		case RTE_TUNNEL_TYPE_GENEVE:
199052d94b57SHarish Patil 		case RTE_TUNNEL_TYPE_TEREDO:
199152d94b57SHarish Patil 		case RTE_TUNNEL_TYPE_NVGRE:
199252d94b57SHarish Patil 		case RTE_TUNNEL_TYPE_IP_IN_GRE:
199352d94b57SHarish Patil 		case RTE_L2_TUNNEL_TYPE_E_TAG:
199452d94b57SHarish Patil 			DP_ERR(edev, "Unsupported tunnel type %d\n",
199552d94b57SHarish Patil 				filter_conf->tunnel_type);
199652d94b57SHarish Patil 			return -EINVAL;
199752d94b57SHarish Patil 		case RTE_TUNNEL_TYPE_NONE:
199852d94b57SHarish Patil 		default:
199952d94b57SHarish Patil 			return 0;
200052d94b57SHarish Patil 		}
200152d94b57SHarish Patil 		break;
200252d94b57SHarish Patil 	case RTE_ETH_FILTER_FDIR:
200362207535SHarish Patil 		return qede_fdir_filter_conf(eth_dev, filter_op, arg);
200462207535SHarish Patil 	case RTE_ETH_FILTER_NTUPLE:
200562207535SHarish Patil 		return qede_ntuple_filter_conf(eth_dev, filter_op, arg);
200652d94b57SHarish Patil 	case RTE_ETH_FILTER_MACVLAN:
200752d94b57SHarish Patil 	case RTE_ETH_FILTER_ETHERTYPE:
200852d94b57SHarish Patil 	case RTE_ETH_FILTER_FLEXIBLE:
200952d94b57SHarish Patil 	case RTE_ETH_FILTER_SYN:
201052d94b57SHarish Patil 	case RTE_ETH_FILTER_HASH:
201152d94b57SHarish Patil 	case RTE_ETH_FILTER_L2_TUNNEL:
201252d94b57SHarish Patil 	case RTE_ETH_FILTER_MAX:
201352d94b57SHarish Patil 	default:
201452d94b57SHarish Patil 		DP_ERR(edev, "Unsupported filter type %d\n",
201552d94b57SHarish Patil 			filter_type);
201652d94b57SHarish Patil 		return -EINVAL;
201752d94b57SHarish Patil 	}
201852d94b57SHarish Patil 
201952d94b57SHarish Patil 	return 0;
202052d94b57SHarish Patil }
202152d94b57SHarish Patil 
20222ea6f76aSRasesh Mody static const struct eth_dev_ops qede_eth_dev_ops = {
20232ea6f76aSRasesh Mody 	.dev_configure = qede_dev_configure,
20242ea6f76aSRasesh Mody 	.dev_infos_get = qede_dev_info_get,
20252ea6f76aSRasesh Mody 	.rx_queue_setup = qede_rx_queue_setup,
20262ea6f76aSRasesh Mody 	.rx_queue_release = qede_rx_queue_release,
20272ea6f76aSRasesh Mody 	.tx_queue_setup = qede_tx_queue_setup,
20282ea6f76aSRasesh Mody 	.tx_queue_release = qede_tx_queue_release,
20292ea6f76aSRasesh Mody 	.dev_start = qede_dev_start,
20302ea6f76aSRasesh Mody 	.dev_set_link_up = qede_dev_set_link_up,
20312ea6f76aSRasesh Mody 	.dev_set_link_down = qede_dev_set_link_down,
20322ea6f76aSRasesh Mody 	.link_update = qede_link_update,
20332ea6f76aSRasesh Mody 	.promiscuous_enable = qede_promiscuous_enable,
20342ea6f76aSRasesh Mody 	.promiscuous_disable = qede_promiscuous_disable,
20352ea6f76aSRasesh Mody 	.allmulticast_enable = qede_allmulticast_enable,
20362ea6f76aSRasesh Mody 	.allmulticast_disable = qede_allmulticast_disable,
20372ea6f76aSRasesh Mody 	.dev_stop = qede_dev_stop,
20382ea6f76aSRasesh Mody 	.dev_close = qede_dev_close,
20392ea6f76aSRasesh Mody 	.stats_get = qede_get_stats,
20405cdd769aSRasesh Mody 	.stats_reset = qede_reset_stats,
2041d1216e22SRasesh Mody 	.xstats_get = qede_get_xstats,
2042d1216e22SRasesh Mody 	.xstats_reset = qede_reset_xstats,
2043d1216e22SRasesh Mody 	.xstats_get_names = qede_get_xstats_names,
20442ea6f76aSRasesh Mody 	.mac_addr_add = qede_mac_addr_add,
20452ea6f76aSRasesh Mody 	.mac_addr_remove = qede_mac_addr_remove,
20462ea6f76aSRasesh Mody 	.mac_addr_set = qede_mac_addr_set,
20472ea6f76aSRasesh Mody 	.vlan_offload_set = qede_vlan_offload_set,
20482ea6f76aSRasesh Mody 	.vlan_filter_set = qede_vlan_filter_set,
20492ea6f76aSRasesh Mody 	.flow_ctrl_set = qede_flow_ctrl_set,
20502ea6f76aSRasesh Mody 	.flow_ctrl_get = qede_flow_ctrl_get,
20512ea6f76aSRasesh Mody 	.dev_supported_ptypes_get = qede_dev_supported_ptypes_get,
20524c98f276SSony Chacko 	.rss_hash_update = qede_rss_hash_update,
20536d9e26c4SSony Chacko 	.rss_hash_conf_get = qede_rss_hash_conf_get,
2054e8876556SSony Chacko 	.reta_update  = qede_rss_reta_update,
20553dadf73eSSony Chacko 	.reta_query  = qede_rss_reta_query,
2056200645acSSony Chacko 	.mtu_set = qede_set_mtu,
205752d94b57SHarish Patil 	.filter_ctrl = qede_dev_filter_ctrl,
205852d94b57SHarish Patil 	.udp_tunnel_port_add = qede_udp_dst_port_add,
205952d94b57SHarish Patil 	.udp_tunnel_port_del = qede_udp_dst_port_del,
20602ea6f76aSRasesh Mody };
20612ea6f76aSRasesh Mody 
206286a2265eSRasesh Mody static const struct eth_dev_ops qede_eth_vf_dev_ops = {
206386a2265eSRasesh Mody 	.dev_configure = qede_dev_configure,
206486a2265eSRasesh Mody 	.dev_infos_get = qede_dev_info_get,
206586a2265eSRasesh Mody 	.rx_queue_setup = qede_rx_queue_setup,
206686a2265eSRasesh Mody 	.rx_queue_release = qede_rx_queue_release,
206786a2265eSRasesh Mody 	.tx_queue_setup = qede_tx_queue_setup,
206886a2265eSRasesh Mody 	.tx_queue_release = qede_tx_queue_release,
206986a2265eSRasesh Mody 	.dev_start = qede_dev_start,
207086a2265eSRasesh Mody 	.dev_set_link_up = qede_dev_set_link_up,
207186a2265eSRasesh Mody 	.dev_set_link_down = qede_dev_set_link_down,
207286a2265eSRasesh Mody 	.link_update = qede_link_update,
207386a2265eSRasesh Mody 	.promiscuous_enable = qede_promiscuous_enable,
207486a2265eSRasesh Mody 	.promiscuous_disable = qede_promiscuous_disable,
207586a2265eSRasesh Mody 	.allmulticast_enable = qede_allmulticast_enable,
207686a2265eSRasesh Mody 	.allmulticast_disable = qede_allmulticast_disable,
207786a2265eSRasesh Mody 	.dev_stop = qede_dev_stop,
207886a2265eSRasesh Mody 	.dev_close = qede_dev_close,
207986a2265eSRasesh Mody 	.stats_get = qede_get_stats,
208086a2265eSRasesh Mody 	.stats_reset = qede_reset_stats,
2081d1216e22SRasesh Mody 	.xstats_get = qede_get_xstats,
2082d1216e22SRasesh Mody 	.xstats_reset = qede_reset_xstats,
2083d1216e22SRasesh Mody 	.xstats_get_names = qede_get_xstats_names,
208486a2265eSRasesh Mody 	.vlan_offload_set = qede_vlan_offload_set,
208586a2265eSRasesh Mody 	.vlan_filter_set = qede_vlan_filter_set,
208686a2265eSRasesh Mody 	.dev_supported_ptypes_get = qede_dev_supported_ptypes_get,
20874c98f276SSony Chacko 	.rss_hash_update = qede_rss_hash_update,
20886d9e26c4SSony Chacko 	.rss_hash_conf_get = qede_rss_hash_conf_get,
2089e8876556SSony Chacko 	.reta_update  = qede_rss_reta_update,
20903dadf73eSSony Chacko 	.reta_query  = qede_rss_reta_query,
2091200645acSSony Chacko 	.mtu_set = qede_set_mtu,
209286a2265eSRasesh Mody };
209386a2265eSRasesh Mody 
20942ea6f76aSRasesh Mody static void qede_update_pf_params(struct ecore_dev *edev)
20952ea6f76aSRasesh Mody {
20962ea6f76aSRasesh Mody 	struct ecore_pf_params pf_params;
2097528fcfabSHarish Patil 
20982ea6f76aSRasesh Mody 	memset(&pf_params, 0, sizeof(struct ecore_pf_params));
2099528fcfabSHarish Patil 	pf_params.eth_pf_params.num_cons = QEDE_PF_NUM_CONNS;
210062207535SHarish Patil 	pf_params.eth_pf_params.num_arfs_filters = QEDE_RFS_MAX_FLTR;
21012ea6f76aSRasesh Mody 	qed_ops->common->update_pf_params(edev, &pf_params);
21022ea6f76aSRasesh Mody }
21032ea6f76aSRasesh Mody 
21042ea6f76aSRasesh Mody static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
21052ea6f76aSRasesh Mody {
21062ea6f76aSRasesh Mody 	struct rte_pci_device *pci_dev;
21072ea6f76aSRasesh Mody 	struct rte_pci_addr pci_addr;
21082ea6f76aSRasesh Mody 	struct qede_dev *adapter;
21092ea6f76aSRasesh Mody 	struct ecore_dev *edev;
21102ea6f76aSRasesh Mody 	struct qed_dev_eth_info dev_info;
21112ea6f76aSRasesh Mody 	struct qed_slowpath_params params;
21122ea6f76aSRasesh Mody 	static bool do_once = true;
21132ea6f76aSRasesh Mody 	uint8_t bulletin_change;
21142ea6f76aSRasesh Mody 	uint8_t vf_mac[ETHER_ADDR_LEN];
21152ea6f76aSRasesh Mody 	uint8_t is_mac_forced;
21162ea6f76aSRasesh Mody 	bool is_mac_exist;
21172ea6f76aSRasesh Mody 	/* Fix up ecore debug level */
21182ea6f76aSRasesh Mody 	uint32_t dp_module = ~0 & ~ECORE_MSG_HW;
21192ea6f76aSRasesh Mody 	uint8_t dp_level = ECORE_LEVEL_VERBOSE;
21202ea6f76aSRasesh Mody 	uint32_t max_mac_addrs;
21212ea6f76aSRasesh Mody 	int rc;
21222ea6f76aSRasesh Mody 
21232ea6f76aSRasesh Mody 	/* Extract key data structures */
21242ea6f76aSRasesh Mody 	adapter = eth_dev->data->dev_private;
21252ea6f76aSRasesh Mody 	edev = &adapter->edev;
2126eac901ceSJan Blunck 	pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
2127d4b7f673SJan Blunck 	pci_addr = pci_dev->addr;
21282ea6f76aSRasesh Mody 
21292ea6f76aSRasesh Mody 	PMD_INIT_FUNC_TRACE(edev);
21302ea6f76aSRasesh Mody 
21312ea6f76aSRasesh Mody 	snprintf(edev->name, NAME_SIZE, PCI_SHORT_PRI_FMT ":dpdk-port-%u",
21322ea6f76aSRasesh Mody 		 pci_addr.bus, pci_addr.devid, pci_addr.function,
21332ea6f76aSRasesh Mody 		 eth_dev->data->port_id);
21342ea6f76aSRasesh Mody 
21352ea6f76aSRasesh Mody 	eth_dev->rx_pkt_burst = qede_recv_pkts;
21362ea6f76aSRasesh Mody 	eth_dev->tx_pkt_burst = qede_xmit_pkts;
213729540be7SHarish Patil 	eth_dev->tx_pkt_prepare = qede_xmit_prep_pkts;
21382ea6f76aSRasesh Mody 
21392ea6f76aSRasesh Mody 	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
21402ea6f76aSRasesh Mody 		DP_NOTICE(edev, false,
21412ea6f76aSRasesh Mody 			  "Skipping device init from secondary process\n");
21422ea6f76aSRasesh Mody 		return 0;
21432ea6f76aSRasesh Mody 	}
21442ea6f76aSRasesh Mody 
21452ea6f76aSRasesh Mody 	rte_eth_copy_pci_info(eth_dev, pci_dev);
21462ea6f76aSRasesh Mody 
2147fb58ad9eSRasesh Mody 	/* @DPDK */
2148fb58ad9eSRasesh Mody 	edev->vendor_id = pci_dev->id.vendor_id;
2149fb58ad9eSRasesh Mody 	edev->device_id = pci_dev->id.device_id;
2150fb58ad9eSRasesh Mody 
21515cdd769aSRasesh Mody 	qed_ops = qed_get_eth_ops();
21525cdd769aSRasesh Mody 	if (!qed_ops) {
21535cdd769aSRasesh Mody 		DP_ERR(edev, "Failed to get qed_eth_ops_pass\n");
21545cdd769aSRasesh Mody 		return -EINVAL;
21555cdd769aSRasesh Mody 	}
21565cdd769aSRasesh Mody 
21572ea6f76aSRasesh Mody 	DP_INFO(edev, "Starting qede probe\n");
21582ea6f76aSRasesh Mody 
21592ea6f76aSRasesh Mody 	rc = qed_ops->common->probe(edev, pci_dev, QED_PROTOCOL_ETH,
21602ea6f76aSRasesh Mody 				    dp_module, dp_level, is_vf);
21612ea6f76aSRasesh Mody 
21622ea6f76aSRasesh Mody 	if (rc != 0) {
21632ea6f76aSRasesh Mody 		DP_ERR(edev, "qede probe failed rc %d\n", rc);
21642ea6f76aSRasesh Mody 		return -ENODEV;
21652ea6f76aSRasesh Mody 	}
21662ea6f76aSRasesh Mody 
21672ea6f76aSRasesh Mody 	qede_update_pf_params(edev);
21682ea6f76aSRasesh Mody 
2169d4b7f673SJan Blunck 	rte_intr_callback_register(&pci_dev->intr_handle,
21702ea6f76aSRasesh Mody 				   qede_interrupt_handler, (void *)eth_dev);
21712ea6f76aSRasesh Mody 
2172d4b7f673SJan Blunck 	if (rte_intr_enable(&pci_dev->intr_handle)) {
21732ea6f76aSRasesh Mody 		DP_ERR(edev, "rte_intr_enable() failed\n");
21742ea6f76aSRasesh Mody 		return -ENODEV;
21752ea6f76aSRasesh Mody 	}
21762ea6f76aSRasesh Mody 
21772ea6f76aSRasesh Mody 	/* Start the Slowpath-process */
21782ea6f76aSRasesh Mody 	memset(&params, 0, sizeof(struct qed_slowpath_params));
21792ea6f76aSRasesh Mody 	params.int_mode = ECORE_INT_MODE_MSIX;
21807eca78ceSHarish Patil 	params.drv_major = QEDE_PMD_VERSION_MAJOR;
21817eca78ceSHarish Patil 	params.drv_minor = QEDE_PMD_VERSION_MINOR;
21827eca78ceSHarish Patil 	params.drv_rev = QEDE_PMD_VERSION_REVISION;
21837eca78ceSHarish Patil 	params.drv_eng = QEDE_PMD_VERSION_PATCH;
21847eca78ceSHarish Patil 	strncpy((char *)params.name, QEDE_PMD_VER_PREFIX,
21857eca78ceSHarish Patil 		QEDE_PMD_DRV_VER_STR_SIZE);
21862ea6f76aSRasesh Mody 
21872af14ca7SHarish Patil 	/* For CMT mode device do periodic polling for slowpath events.
21882af14ca7SHarish Patil 	 * This is required since uio device uses only one MSI-x
21892af14ca7SHarish Patil 	 * interrupt vector but we need one for each engine.
21902af14ca7SHarish Patil 	 */
2191de027ce7SHarish Patil 	if (edev->num_hwfns > 1 && IS_PF(edev)) {
21922af14ca7SHarish Patil 		rc = rte_eal_alarm_set(timer_period * US_PER_S,
21932af14ca7SHarish Patil 				       qede_poll_sp_sb_cb,
21942af14ca7SHarish Patil 				       (void *)eth_dev);
21952af14ca7SHarish Patil 		if (rc != 0) {
21962af14ca7SHarish Patil 			DP_ERR(edev, "Unable to start periodic"
21972af14ca7SHarish Patil 				     " timer rc %d\n", rc);
21982af14ca7SHarish Patil 			return -EINVAL;
21992af14ca7SHarish Patil 		}
22002af14ca7SHarish Patil 	}
22012af14ca7SHarish Patil 
22022ea6f76aSRasesh Mody 	rc = qed_ops->common->slowpath_start(edev, &params);
22032ea6f76aSRasesh Mody 	if (rc) {
22042ea6f76aSRasesh Mody 		DP_ERR(edev, "Cannot start slowpath rc = %d\n", rc);
22052af14ca7SHarish Patil 		rte_eal_alarm_cancel(qede_poll_sp_sb_cb,
22062af14ca7SHarish Patil 				     (void *)eth_dev);
22072ea6f76aSRasesh Mody 		return -ENODEV;
22082ea6f76aSRasesh Mody 	}
22092ea6f76aSRasesh Mody 
22102ea6f76aSRasesh Mody 	rc = qed_ops->fill_dev_info(edev, &dev_info);
22112ea6f76aSRasesh Mody 	if (rc) {
22122ea6f76aSRasesh Mody 		DP_ERR(edev, "Cannot get device_info rc %d\n", rc);
22132ea6f76aSRasesh Mody 		qed_ops->common->slowpath_stop(edev);
22142ea6f76aSRasesh Mody 		qed_ops->common->remove(edev);
22152af14ca7SHarish Patil 		rte_eal_alarm_cancel(qede_poll_sp_sb_cb,
22162af14ca7SHarish Patil 				     (void *)eth_dev);
22172ea6f76aSRasesh Mody 		return -ENODEV;
22182ea6f76aSRasesh Mody 	}
22192ea6f76aSRasesh Mody 
22202ea6f76aSRasesh Mody 	qede_alloc_etherdev(adapter, &dev_info);
22212ea6f76aSRasesh Mody 
2222de5588afSRasesh Mody 	adapter->ops->common->set_name(edev, edev->name);
22232ea6f76aSRasesh Mody 
22242ea6f76aSRasesh Mody 	if (!is_vf)
22253320ca8cSRasesh Mody 		adapter->dev_info.num_mac_filters =
22262ea6f76aSRasesh Mody 			(uint32_t)RESC_NUM(ECORE_LEADING_HWFN(edev),
22272ea6f76aSRasesh Mody 					    ECORE_MAC);
22282ea6f76aSRasesh Mody 	else
222986a2265eSRasesh Mody 		ecore_vf_get_num_mac_filters(ECORE_LEADING_HWFN(edev),
22303320ca8cSRasesh Mody 				(uint32_t *)&adapter->dev_info.num_mac_filters);
22312ea6f76aSRasesh Mody 
22322ea6f76aSRasesh Mody 	/* Allocate memory for storing MAC addr */
22332ea6f76aSRasesh Mody 	eth_dev->data->mac_addrs = rte_zmalloc(edev->name,
22342ea6f76aSRasesh Mody 					(ETHER_ADDR_LEN *
22353320ca8cSRasesh Mody 					adapter->dev_info.num_mac_filters),
22362ea6f76aSRasesh Mody 					RTE_CACHE_LINE_SIZE);
22372ea6f76aSRasesh Mody 
22382ea6f76aSRasesh Mody 	if (eth_dev->data->mac_addrs == NULL) {
22392ea6f76aSRasesh Mody 		DP_ERR(edev, "Failed to allocate MAC address\n");
22402ea6f76aSRasesh Mody 		qed_ops->common->slowpath_stop(edev);
22412ea6f76aSRasesh Mody 		qed_ops->common->remove(edev);
22422af14ca7SHarish Patil 		rte_eal_alarm_cancel(qede_poll_sp_sb_cb,
22432af14ca7SHarish Patil 				     (void *)eth_dev);
22442ea6f76aSRasesh Mody 		return -ENOMEM;
22452ea6f76aSRasesh Mody 	}
22462ea6f76aSRasesh Mody 
224786a2265eSRasesh Mody 	if (!is_vf) {
22482ea6f76aSRasesh Mody 		ether_addr_copy((struct ether_addr *)edev->hwfns[0].
22492ea6f76aSRasesh Mody 				hw_info.hw_mac_addr,
22502ea6f76aSRasesh Mody 				&eth_dev->data->mac_addrs[0]);
225186a2265eSRasesh Mody 		ether_addr_copy(&eth_dev->data->mac_addrs[0],
225286a2265eSRasesh Mody 				&adapter->primary_mac);
225386a2265eSRasesh Mody 	} else {
225486a2265eSRasesh Mody 		ecore_vf_read_bulletin(ECORE_LEADING_HWFN(edev),
225586a2265eSRasesh Mody 				       &bulletin_change);
225686a2265eSRasesh Mody 		if (bulletin_change) {
225786a2265eSRasesh Mody 			is_mac_exist =
225886a2265eSRasesh Mody 			    ecore_vf_bulletin_get_forced_mac(
225986a2265eSRasesh Mody 						ECORE_LEADING_HWFN(edev),
226086a2265eSRasesh Mody 						vf_mac,
226186a2265eSRasesh Mody 						&is_mac_forced);
226286a2265eSRasesh Mody 			if (is_mac_exist && is_mac_forced) {
226386a2265eSRasesh Mody 				DP_INFO(edev, "VF macaddr received from PF\n");
226486a2265eSRasesh Mody 				ether_addr_copy((struct ether_addr *)&vf_mac,
226586a2265eSRasesh Mody 						&eth_dev->data->mac_addrs[0]);
226686a2265eSRasesh Mody 				ether_addr_copy(&eth_dev->data->mac_addrs[0],
226786a2265eSRasesh Mody 						&adapter->primary_mac);
226886a2265eSRasesh Mody 			} else {
226986a2265eSRasesh Mody 				DP_NOTICE(edev, false,
227086a2265eSRasesh Mody 					  "No VF macaddr assigned\n");
227186a2265eSRasesh Mody 			}
227286a2265eSRasesh Mody 		}
227386a2265eSRasesh Mody 	}
22742ea6f76aSRasesh Mody 
227586a2265eSRasesh Mody 	eth_dev->dev_ops = (is_vf) ? &qede_eth_vf_dev_ops : &qede_eth_dev_ops;
22762ea6f76aSRasesh Mody 
22772ea6f76aSRasesh Mody 	if (do_once) {
22782ea6f76aSRasesh Mody 		qede_print_adapter_info(adapter);
22792ea6f76aSRasesh Mody 		do_once = false;
22802ea6f76aSRasesh Mody 	}
22812ea6f76aSRasesh Mody 
2282dbac54c2SHarish Patil 	adapter->state = QEDE_DEV_INIT;
2283dbac54c2SHarish Patil 
22842ea6f76aSRasesh Mody 	DP_NOTICE(edev, false, "MAC address : %02x:%02x:%02x:%02x:%02x:%02x\n",
22852ea6f76aSRasesh Mody 		  adapter->primary_mac.addr_bytes[0],
22862ea6f76aSRasesh Mody 		  adapter->primary_mac.addr_bytes[1],
22872ea6f76aSRasesh Mody 		  adapter->primary_mac.addr_bytes[2],
22882ea6f76aSRasesh Mody 		  adapter->primary_mac.addr_bytes[3],
22892ea6f76aSRasesh Mody 		  adapter->primary_mac.addr_bytes[4],
22902ea6f76aSRasesh Mody 		  adapter->primary_mac.addr_bytes[5]);
22912ea6f76aSRasesh Mody 
22922ea6f76aSRasesh Mody 	return rc;
22932ea6f76aSRasesh Mody }
22942ea6f76aSRasesh Mody 
22952ea6f76aSRasesh Mody static int qedevf_eth_dev_init(struct rte_eth_dev *eth_dev)
22962ea6f76aSRasesh Mody {
22972ea6f76aSRasesh Mody 	return qede_common_dev_init(eth_dev, 1);
22982ea6f76aSRasesh Mody }
22992ea6f76aSRasesh Mody 
23002ea6f76aSRasesh Mody static int qede_eth_dev_init(struct rte_eth_dev *eth_dev)
23012ea6f76aSRasesh Mody {
23022ea6f76aSRasesh Mody 	return qede_common_dev_init(eth_dev, 0);
23032ea6f76aSRasesh Mody }
23042ea6f76aSRasesh Mody 
23052ea6f76aSRasesh Mody static int qede_dev_common_uninit(struct rte_eth_dev *eth_dev)
23062ea6f76aSRasesh Mody {
23072ea6f76aSRasesh Mody 	/* only uninitialize in the primary process */
23082ea6f76aSRasesh Mody 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
23092ea6f76aSRasesh Mody 		return 0;
23102ea6f76aSRasesh Mody 
23112ea6f76aSRasesh Mody 	/* safe to close dev here */
23122ea6f76aSRasesh Mody 	qede_dev_close(eth_dev);
23132ea6f76aSRasesh Mody 
23142ea6f76aSRasesh Mody 	eth_dev->dev_ops = NULL;
23152ea6f76aSRasesh Mody 	eth_dev->rx_pkt_burst = NULL;
23162ea6f76aSRasesh Mody 	eth_dev->tx_pkt_burst = NULL;
23172ea6f76aSRasesh Mody 
23182ea6f76aSRasesh Mody 	if (eth_dev->data->mac_addrs)
23192ea6f76aSRasesh Mody 		rte_free(eth_dev->data->mac_addrs);
23202ea6f76aSRasesh Mody 
23212ea6f76aSRasesh Mody 	eth_dev->data->mac_addrs = NULL;
23222ea6f76aSRasesh Mody 
23232ea6f76aSRasesh Mody 	return 0;
23242ea6f76aSRasesh Mody }
23252ea6f76aSRasesh Mody 
23262ea6f76aSRasesh Mody static int qede_eth_dev_uninit(struct rte_eth_dev *eth_dev)
23272ea6f76aSRasesh Mody {
23282ea6f76aSRasesh Mody 	return qede_dev_common_uninit(eth_dev);
23292ea6f76aSRasesh Mody }
23302ea6f76aSRasesh Mody 
23312ea6f76aSRasesh Mody static int qedevf_eth_dev_uninit(struct rte_eth_dev *eth_dev)
23322ea6f76aSRasesh Mody {
23332ea6f76aSRasesh Mody 	return qede_dev_common_uninit(eth_dev);
23342ea6f76aSRasesh Mody }
23352ea6f76aSRasesh Mody 
233628a1fd4fSFerruh Yigit static const struct rte_pci_id pci_id_qedevf_map[] = {
23372ea6f76aSRasesh Mody #define QEDEVF_RTE_PCI_DEVICE(dev) RTE_PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, dev)
23382ea6f76aSRasesh Mody 	{
233977f72221SRasesh Mody 		QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_VF)
23402ea6f76aSRasesh Mody 	},
23412ea6f76aSRasesh Mody 	{
234277f72221SRasesh Mody 		QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_IOV)
234377f72221SRasesh Mody 	},
234477f72221SRasesh Mody 	{
234577f72221SRasesh Mody 		QEDEVF_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_IOV)
23462ea6f76aSRasesh Mody 	},
23472ea6f76aSRasesh Mody 	{.vendor_id = 0,}
23482ea6f76aSRasesh Mody };
23492ea6f76aSRasesh Mody 
235028a1fd4fSFerruh Yigit static const struct rte_pci_id pci_id_qede_map[] = {
23512ea6f76aSRasesh Mody #define QEDE_RTE_PCI_DEVICE(dev) RTE_PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, dev)
23522ea6f76aSRasesh Mody 	{
235377f72221SRasesh Mody 		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_57980E)
23542ea6f76aSRasesh Mody 	},
23552ea6f76aSRasesh Mody 	{
235677f72221SRasesh Mody 		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_NX2_57980S)
23572ea6f76aSRasesh Mody 	},
23582ea6f76aSRasesh Mody 	{
235977f72221SRasesh Mody 		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_40)
23602ea6f76aSRasesh Mody 	},
23612ea6f76aSRasesh Mody 	{
236277f72221SRasesh Mody 		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_25)
23632ea6f76aSRasesh Mody 	},
23642af14ca7SHarish Patil 	{
236577f72221SRasesh Mody 		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_100)
236677f72221SRasesh Mody 	},
236777f72221SRasesh Mody 	{
2368e6512107SRasesh Mody 		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_57980S_50)
2369e6512107SRasesh Mody 	},
2370e6512107SRasesh Mody 	{
237177f72221SRasesh Mody 		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_50G)
237277f72221SRasesh Mody 	},
237377f72221SRasesh Mody 	{
237477f72221SRasesh Mody 		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_10G)
237577f72221SRasesh Mody 	},
237677f72221SRasesh Mody 	{
237777f72221SRasesh Mody 		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_40G)
237877f72221SRasesh Mody 	},
237977f72221SRasesh Mody 	{
238077f72221SRasesh Mody 		QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_QLOGIC_AH_25G)
23812af14ca7SHarish Patil 	},
23822ea6f76aSRasesh Mody 	{.vendor_id = 0,}
23832ea6f76aSRasesh Mody };
23842ea6f76aSRasesh Mody 
23852ea6f76aSRasesh Mody static struct eth_driver rte_qedevf_pmd = {
23862ea6f76aSRasesh Mody 	.pci_drv = {
23872ea6f76aSRasesh Mody 		    .id_table = pci_id_qedevf_map,
23882ea6f76aSRasesh Mody 		    .drv_flags =
23892ea6f76aSRasesh Mody 		    RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
2390c830cb29SDavid Marchand 		    .probe = rte_eth_dev_pci_probe,
2391c830cb29SDavid Marchand 		    .remove = rte_eth_dev_pci_remove,
23922ea6f76aSRasesh Mody 		   },
23932ea6f76aSRasesh Mody 	.eth_dev_init = qedevf_eth_dev_init,
23942ea6f76aSRasesh Mody 	.eth_dev_uninit = qedevf_eth_dev_uninit,
23952ea6f76aSRasesh Mody 	.dev_private_size = sizeof(struct qede_dev),
23962ea6f76aSRasesh Mody };
23972ea6f76aSRasesh Mody 
23982ea6f76aSRasesh Mody static struct eth_driver rte_qede_pmd = {
23992ea6f76aSRasesh Mody 	.pci_drv = {
24002ea6f76aSRasesh Mody 		    .id_table = pci_id_qede_map,
24012ea6f76aSRasesh Mody 		    .drv_flags =
24022ea6f76aSRasesh Mody 		    RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
2403c830cb29SDavid Marchand 		    .probe = rte_eth_dev_pci_probe,
2404c830cb29SDavid Marchand 		    .remove = rte_eth_dev_pci_remove,
24052ea6f76aSRasesh Mody 		   },
24062ea6f76aSRasesh Mody 	.eth_dev_init = qede_eth_dev_init,
24072ea6f76aSRasesh Mody 	.eth_dev_uninit = qede_eth_dev_uninit,
24082ea6f76aSRasesh Mody 	.dev_private_size = sizeof(struct qede_dev),
24092ea6f76aSRasesh Mody };
24102ea6f76aSRasesh Mody 
241101f19227SShreyansh Jain RTE_PMD_REGISTER_PCI(net_qede, rte_qede_pmd.pci_drv);
241201f19227SShreyansh Jain RTE_PMD_REGISTER_PCI_TABLE(net_qede, pci_id_qede_map);
24130880c401SOlivier Matz RTE_PMD_REGISTER_KMOD_DEP(net_qede, "* igb_uio | uio_pci_generic | vfio");
241401f19227SShreyansh Jain RTE_PMD_REGISTER_PCI(net_qede_vf, rte_qedevf_pmd.pci_drv);
241501f19227SShreyansh Jain RTE_PMD_REGISTER_PCI_TABLE(net_qede_vf, pci_id_qedevf_map);
24160880c401SOlivier Matz RTE_PMD_REGISTER_KMOD_DEP(net_qede_vf, "* igb_uio | vfio");
2417