1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2008-2017 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
6 #include "enic_compat.h"
7 #include "rte_ethdev_driver.h"
8 #include "wq_enet_desc.h"
9 #include "rq_enet_desc.h"
10 #include "cq_enet_desc.h"
11 #include "vnic_resource.h"
12 #include "vnic_enet.h"
17 #include "vnic_intr.h"
18 #include "vnic_stats.h"
24 int enic_get_vnic_config(struct enic
*enic
)
26 struct vnic_enet_config
*c
= &enic
->config
;
29 err
= vnic_dev_get_mac_addr(enic
->vdev
, enic
->mac_addr
);
31 dev_err(enic_get_dev(enic
),
32 "Error getting MAC addr, %d\n", err
);
37 #define GET_CONFIG(m) \
39 err = vnic_dev_spec(enic->vdev, \
40 offsetof(struct vnic_enet_config, m), \
41 sizeof(c->m), &c->m); \
43 dev_err(enic_get_dev(enic), \
44 "Error getting %s, %d\n", #m, err); \
50 GET_CONFIG(wq_desc_count
);
51 GET_CONFIG(rq_desc_count
);
53 GET_CONFIG(intr_timer_type
);
54 GET_CONFIG(intr_mode
);
55 GET_CONFIG(intr_timer_usec
);
58 GET_CONFIG(max_pkt_size
);
60 /* max packet size is only defined in newer VIC firmware
61 * and will be 0 for legacy firmware and VICs
63 if (c
->max_pkt_size
> ENIC_DEFAULT_RX_MAX_PKT_SIZE
)
64 enic
->max_mtu
= c
->max_pkt_size
- ETHER_HDR_LEN
;
66 enic
->max_mtu
= ENIC_DEFAULT_RX_MAX_PKT_SIZE
- ETHER_HDR_LEN
;
70 enic
->rte_dev
->data
->mtu
= min_t(u16
, enic
->max_mtu
,
71 max_t(u16
, ENIC_MIN_MTU
, c
->mtu
));
73 enic
->adv_filters
= vnic_dev_capable_adv_filters(enic
->vdev
);
74 dev_info(enic
, "Advanced Filters %savailable\n", ((enic
->adv_filters
)
77 err
= vnic_dev_capable_filter_mode(enic
->vdev
, &enic
->flow_filter_mode
,
78 &enic
->filter_actions
);
80 dev_err(enic_get_dev(enic
),
81 "Error getting filter modes, %d\n", err
);
84 vnic_dev_capable_udp_rss_weak(enic
->vdev
, &enic
->nic_cfg_chk
,
87 dev_info(enic
, "Flow api filter mode: %s Actions: %s%s%s%s\n",
88 ((enic
->flow_filter_mode
== FILTER_DPDK_1
) ? "DPDK" :
89 ((enic
->flow_filter_mode
== FILTER_USNIC_IP
) ? "USNIC" :
90 ((enic
->flow_filter_mode
== FILTER_IPV4_5TUPLE
) ? "5TUPLE" :
92 ((enic
->filter_actions
& FILTER_ACTION_RQ_STEERING_FLAG
) ?
94 ((enic
->filter_actions
& FILTER_ACTION_FILTER_ID_FLAG
) ?
96 ((enic
->filter_actions
& FILTER_ACTION_DROP_FLAG
) ?
98 ((enic
->filter_actions
& FILTER_ACTION_COUNTER_FLAG
) ?
102 min_t(u32
, ENIC_MAX_WQ_DESCS
,
103 max_t(u32
, ENIC_MIN_WQ_DESCS
,
105 c
->wq_desc_count
&= 0xffffffe0; /* must be aligned to groups of 32 */
108 min_t(u32
, ENIC_MAX_RQ_DESCS
,
109 max_t(u32
, ENIC_MIN_RQ_DESCS
,
111 c
->rq_desc_count
&= 0xffffffe0; /* must be aligned to groups of 32 */
113 c
->intr_timer_usec
= min_t(u32
, c
->intr_timer_usec
,
114 vnic_dev_get_intr_coal_timer_max(enic
->vdev
));
116 dev_info(enic_get_dev(enic
),
117 "vNIC MAC addr %02x:%02x:%02x:%02x:%02x:%02x "
118 "wq/rq %d/%d mtu %d, max mtu:%d\n",
119 enic
->mac_addr
[0], enic
->mac_addr
[1], enic
->mac_addr
[2],
120 enic
->mac_addr
[3], enic
->mac_addr
[4], enic
->mac_addr
[5],
121 c
->wq_desc_count
, c
->rq_desc_count
,
122 enic
->rte_dev
->data
->mtu
, enic
->max_mtu
);
123 dev_info(enic_get_dev(enic
), "vNIC csum tx/rx %s/%s "
124 "rss %s intr mode %s type %s timer %d usec "
125 "loopback tag 0x%04x\n",
126 ENIC_SETTING(enic
, TXCSUM
) ? "yes" : "no",
127 ENIC_SETTING(enic
, RXCSUM
) ? "yes" : "no",
128 ENIC_SETTING(enic
, RSS
) ?
129 (ENIC_SETTING(enic
, RSSHASH_UDPIPV4
) ? "+UDP" :
130 ((enic
->udp_rss_weak
? "+udp" :
132 c
->intr_mode
== VENET_INTR_MODE_INTX
? "INTx" :
133 c
->intr_mode
== VENET_INTR_MODE_MSI
? "MSI" :
134 c
->intr_mode
== VENET_INTR_MODE_ANY
? "any" :
136 c
->intr_timer_type
== VENET_INTR_TYPE_MIN
? "min" :
137 c
->intr_timer_type
== VENET_INTR_TYPE_IDLE
? "idle" :
142 /* RSS settings from vNIC */
143 enic
->reta_size
= ENIC_RSS_RETA_SIZE
;
144 enic
->hash_key_size
= ENIC_RSS_HASH_KEY_SIZE
;
145 enic
->flow_type_rss_offloads
= 0;
146 if (ENIC_SETTING(enic
, RSSHASH_IPV4
))
148 * IPV4 hash type handles both non-frag and frag packet types.
149 * TCP/UDP is controlled via a separate flag below.
151 enic
->flow_type_rss_offloads
|= ETH_RSS_IPV4
|
152 ETH_RSS_FRAG_IPV4
| ETH_RSS_NONFRAG_IPV4_OTHER
;
153 if (ENIC_SETTING(enic
, RSSHASH_TCPIPV4
))
154 enic
->flow_type_rss_offloads
|= ETH_RSS_NONFRAG_IPV4_TCP
;
155 if (ENIC_SETTING(enic
, RSSHASH_IPV6
))
157 * The VIC adapter can perform RSS on IPv6 packets with and
158 * without extension headers. An IPv6 "fragment" is an IPv6
159 * packet with the fragment extension header.
161 enic
->flow_type_rss_offloads
|= ETH_RSS_IPV6
|
162 ETH_RSS_IPV6_EX
| ETH_RSS_FRAG_IPV6
|
163 ETH_RSS_NONFRAG_IPV6_OTHER
;
164 if (ENIC_SETTING(enic
, RSSHASH_TCPIPV6
))
165 enic
->flow_type_rss_offloads
|= ETH_RSS_NONFRAG_IPV6_TCP
|
167 if (enic
->udp_rss_weak
)
168 enic
->flow_type_rss_offloads
|=
169 ETH_RSS_NONFRAG_IPV4_UDP
| ETH_RSS_NONFRAG_IPV6_UDP
|
171 if (ENIC_SETTING(enic
, RSSHASH_UDPIPV4
))
172 enic
->flow_type_rss_offloads
|= ETH_RSS_NONFRAG_IPV4_UDP
;
173 if (ENIC_SETTING(enic
, RSSHASH_UDPIPV6
))
174 enic
->flow_type_rss_offloads
|= ETH_RSS_NONFRAG_IPV6_UDP
|
177 /* Zero offloads if RSS is not enabled */
178 if (!ENIC_SETTING(enic
, RSS
))
179 enic
->flow_type_rss_offloads
= 0;
181 enic
->vxlan
= ENIC_SETTING(enic
, VXLAN
) &&
182 vnic_dev_capable_vxlan(enic
->vdev
);
184 * Default hardware capabilities. enic_dev_init() may add additional
185 * flags if it enables overlay offloads.
187 enic
->tx_queue_offload_capa
= 0;
188 enic
->tx_offload_capa
=
189 enic
->tx_queue_offload_capa
|
190 DEV_TX_OFFLOAD_MULTI_SEGS
|
191 DEV_TX_OFFLOAD_VLAN_INSERT
|
192 DEV_TX_OFFLOAD_IPV4_CKSUM
|
193 DEV_TX_OFFLOAD_UDP_CKSUM
|
194 DEV_TX_OFFLOAD_TCP_CKSUM
|
195 DEV_TX_OFFLOAD_TCP_TSO
;
196 enic
->rx_offload_capa
=
197 DEV_RX_OFFLOAD_SCATTER
|
198 DEV_RX_OFFLOAD_JUMBO_FRAME
|
199 DEV_RX_OFFLOAD_VLAN_STRIP
|
200 DEV_RX_OFFLOAD_IPV4_CKSUM
|
201 DEV_RX_OFFLOAD_UDP_CKSUM
|
202 DEV_RX_OFFLOAD_TCP_CKSUM
;
203 enic
->tx_offload_mask
=
214 int enic_set_nic_cfg(struct enic
*enic
, u8 rss_default_cpu
, u8 rss_hash_type
,
215 u8 rss_hash_bits
, u8 rss_base_cpu
, u8 rss_enable
, u8 tso_ipid_split_en
,
218 enum vnic_devcmd_cmd cmd
;
223 vnic_set_nic_cfg(&nic_cfg
, rss_default_cpu
,
224 rss_hash_type
, rss_hash_bits
, rss_base_cpu
,
225 rss_enable
, tso_ipid_split_en
, ig_vlan_strip_en
);
229 cmd
= enic
->nic_cfg_chk
? CMD_NIC_CFG_CHK
: CMD_NIC_CFG
;
230 return vnic_dev_cmd(enic
->vdev
, cmd
, &a0
, &a1
, wait
);
233 int enic_set_rss_key(struct enic
*enic
, dma_addr_t key_pa
, u64 len
)
235 u64 a0
= (u64
)key_pa
, a1
= len
;
238 return vnic_dev_cmd(enic
->vdev
, CMD_RSS_KEY
, &a0
, &a1
, wait
);
241 int enic_set_rss_cpu(struct enic
*enic
, dma_addr_t cpu_pa
, u64 len
)
243 u64 a0
= (u64
)cpu_pa
, a1
= len
;
246 return vnic_dev_cmd(enic
->vdev
, CMD_RSS_CPU
, &a0
, &a1
, wait
);
249 void enic_free_vnic_resources(struct enic
*enic
)
253 for (i
= 0; i
< enic
->wq_count
; i
++)
254 vnic_wq_free(&enic
->wq
[i
]);
255 for (i
= 0; i
< enic_vnic_rq_count(enic
); i
++)
256 if (enic
->rq
[i
].in_use
)
257 vnic_rq_free(&enic
->rq
[i
]);
258 for (i
= 0; i
< enic
->cq_count
; i
++)
259 vnic_cq_free(&enic
->cq
[i
]);
260 for (i
= 0; i
< enic
->intr_count
; i
++)
261 vnic_intr_free(&enic
->intr
[i
]);
264 void enic_get_res_counts(struct enic
*enic
)
266 enic
->conf_wq_count
= vnic_dev_get_res_count(enic
->vdev
, RES_TYPE_WQ
);
267 enic
->conf_rq_count
= vnic_dev_get_res_count(enic
->vdev
, RES_TYPE_RQ
);
268 enic
->conf_cq_count
= vnic_dev_get_res_count(enic
->vdev
, RES_TYPE_CQ
);
269 enic
->conf_intr_count
= vnic_dev_get_res_count(enic
->vdev
,
272 dev_info(enic_get_dev(enic
),
273 "vNIC resources avail: wq %d rq %d cq %d intr %d\n",
274 enic
->conf_wq_count
, enic
->conf_rq_count
,
275 enic
->conf_cq_count
, enic
->conf_intr_count
);