xref: /freebsd/sys/dev/enic/enic_res.c (revision e0c4386e)
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.
4  */
5 
6 #include "enic.h"
7 #include "enic_compat.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"
13 #include "vnic_dev.h"
14 #include "vnic_wq.h"
15 #include "vnic_rq.h"
16 #include "vnic_cq.h"
17 #include "vnic_intr.h"
18 #include "vnic_stats.h"
19 #include "vnic_nic.h"
20 #include "vnic_rss.h"
21 #include "enic_res.h"
22 #include "enic.h"
23 
24 int enic_get_vnic_config(struct enic *enic)
25 {
26 	struct vnic_enet_config *c = &enic->config;
27 	int err;
28 	err = vnic_dev_get_mac_addr(enic->vdev, enic->mac_addr);
29 	if (err) {
30 		dev_err(enic_get_dev(enic),
31 			"Error getting MAC addr, %d\n", err);
32 		return err;
33 	}
34 
35 #define GET_CONFIG(m) \
36 	do { \
37 		err = vnic_dev_spec(enic->vdev, \
38 			offsetof(struct vnic_enet_config, m), \
39 			sizeof(c->m), &c->m); \
40 		if (err) { \
41 			dev_err(enic_get_dev(enic), \
42 				"Error getting %s, %d\n", #m, err); \
43 			return err; \
44 		} \
45 	} while (0)
46 
47 	GET_CONFIG(flags);
48 	GET_CONFIG(wq_desc_count);
49 	GET_CONFIG(rq_desc_count);
50 	GET_CONFIG(mtu);
51 	GET_CONFIG(intr_timer_type);
52 	GET_CONFIG(intr_mode);
53 	GET_CONFIG(intr_timer_usec);
54 	GET_CONFIG(loop_tag);
55 	GET_CONFIG(num_arfs);
56 	GET_CONFIG(max_pkt_size);
57 
58 	/* max packet size is only defined in newer VIC firmware
59 	 * and will be 0 for legacy firmware and VICs
60 	 */
61 	if (c->max_pkt_size > ENIC_DEFAULT_RX_MAX_PKT_SIZE)
62 		enic->max_mtu = c->max_pkt_size - (ETHER_HDR_LEN + 4);
63 	else
64 		enic->max_mtu = ENIC_DEFAULT_RX_MAX_PKT_SIZE
65 				- (ETHER_HDR_LEN + 4);
66 	if (c->mtu == 0)
67 		c->mtu = 1500;
68 
69 	enic->adv_filters = vnic_dev_capable_adv_filters(enic->vdev);
70 
71 	err = vnic_dev_capable_filter_mode(enic->vdev, &enic->flow_filter_mode,
72 					   &enic->filter_actions);
73 	if (err) {
74 		dev_err(enic_get_dev(enic),
75 			"Error getting filter modes, %d\n", err);
76 		return err;
77 	}
78 	vnic_dev_capable_udp_rss_weak(enic->vdev, &enic->nic_cfg_chk,
79 				      &enic->udp_rss_weak);
80 
81 	c->wq_desc_count =
82 		min_t(u32, ENIC_MAX_WQ_DESCS,
83 		max_t(u32, ENIC_MIN_WQ_DESCS,
84 		c->wq_desc_count));
85 	c->wq_desc_count &= 0xffffffe0; /* must be aligned to groups of 32 */
86 
87 	c->rq_desc_count =
88 		min_t(u32, ENIC_MAX_RQ_DESCS,
89 		max_t(u32, ENIC_MIN_RQ_DESCS,
90 		c->rq_desc_count));
91 	c->rq_desc_count &= 0xffffffe0; /* must be aligned to groups of 32 */
92 
93 	c->intr_timer_usec = min_t(u32, c->intr_timer_usec,
94 		vnic_dev_get_intr_coal_timer_max(enic->vdev));
95 
96 	dev_info(enic_get_dev(enic),
97 		"vNIC MAC addr %02x:%02x:%02x:%02x:%02x:%02x "
98 		"wq/rq %d/%d mtu d, max mtu:%d\n",
99 		enic->mac_addr[0], enic->mac_addr[1], enic->mac_addr[2],
100 		enic->mac_addr[3], enic->mac_addr[4], enic->mac_addr[5],
101 		c->wq_desc_count, c->rq_desc_count,
102 		 /* enic->rte_dev->data->mtu, */ enic->max_mtu);
103 	dev_info(enic_get_dev(enic), "vNIC csum tx/rx %s/%s "
104 		"rss %s intr mode %s type %s timer %d usec "
105 		"loopback tag 0x%04x\n",
106 		ENIC_SETTING(enic, TXCSUM) ? "yes" : "no",
107 		ENIC_SETTING(enic, RXCSUM) ? "yes" : "no",
108 		ENIC_SETTING(enic, RSS) ?
109 			(ENIC_SETTING(enic, RSSHASH_UDPIPV4) ? "+UDP" :
110 			((enic->udp_rss_weak ? "+udp" :
111 			"yes"))) : "no",
112 		c->intr_mode == VENET_INTR_MODE_INTX ? "INTx" :
113 		c->intr_mode == VENET_INTR_MODE_MSI ? "MSI" :
114 		c->intr_mode == VENET_INTR_MODE_ANY ? "any" :
115 		"unknown",
116 		c->intr_timer_type == VENET_INTR_TYPE_MIN ? "min" :
117 		c->intr_timer_type == VENET_INTR_TYPE_IDLE ? "idle" :
118 		"unknown",
119 		c->intr_timer_usec,
120 		c->loop_tag);
121 
122 	/* RSS settings from vNIC */
123 	enic->reta_size = ENIC_RSS_RETA_SIZE;
124 	enic->hash_key_size = ENIC_RSS_HASH_KEY_SIZE;
125 	enic->flow_type_rss_offloads = 0;
126 
127 	/* Zero offloads if RSS is not enabled */
128 	if (!ENIC_SETTING(enic, RSS))
129 		enic->flow_type_rss_offloads = 0;
130 
131 	enic->vxlan = ENIC_SETTING(enic, VXLAN) &&
132 		vnic_dev_capable_vxlan(enic->vdev);
133 	/*
134 	 * Default hardware capabilities. enic_dev_init() may add additional
135 	 * flags if it enables overlay offloads.
136 	 */
137 	enic->tx_queue_offload_capa = 0;
138 	return 0;
139 }
140 
141 int enic_add_vlan(struct enic *enic, u16 vlanid)
142 {
143 	u64 a0 = vlanid, a1 = 0;
144 	int wait = 1000;
145 	int err;
146 
147 	err = vnic_dev_cmd(enic->vdev, CMD_VLAN_ADD, &a0, &a1, wait);
148 	if (err)
149 		dev_err(enic_get_dev(enic), "Can't add vlan id, %d\n", err);
150 
151 	return err;
152 }
153 
154 int enic_del_vlan(struct enic *enic, u16 vlanid)
155 {
156 	u64 a0 = vlanid, a1 = 0;
157 	int wait = 1000;
158 	int err;
159 
160 	err = vnic_dev_cmd(enic->vdev, CMD_VLAN_DEL, &a0, &a1, wait);
161 	if (err)
162 		dev_err(enic_get_dev(enic), "Can't delete vlan id, %d\n", err);
163 
164 	return err;
165 }
166 
167 int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type,
168 	u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en,
169 	u8 ig_vlan_strip_en)
170 {
171 	enum vnic_devcmd_cmd cmd;
172 	u64 a0, a1;
173 	u32 nic_cfg;
174 	int wait = 1000;
175 
176 	vnic_set_nic_cfg(&nic_cfg, rss_default_cpu,
177 		rss_hash_type, rss_hash_bits, rss_base_cpu,
178 		rss_enable, tso_ipid_split_en, ig_vlan_strip_en);
179 
180 	a0 = nic_cfg;
181 	a1 = 0;
182 	cmd = enic->nic_cfg_chk ? CMD_NIC_CFG_CHK : CMD_NIC_CFG;
183 	return vnic_dev_cmd(enic->vdev, cmd, &a0, &a1, wait);
184 }
185 
186 void enic_get_res_counts(struct enic *enic)
187 {
188 	enic->conf_wq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ);
189 	enic->conf_rq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ);
190 	enic->conf_cq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ);
191 	enic->conf_intr_count = vnic_dev_get_res_count(enic->vdev,
192 		RES_TYPE_INTR_CTRL);
193 
194 	dev_info(enic_get_dev(enic),
195 		"vNIC resources avail: wq %d rq %d cq %d intr %d\n",
196 		enic->conf_wq_count, enic->conf_rq_count,
197 		enic->conf_cq_count, enic->conf_intr_count);
198 	enic->conf_rq_count = min(enic->conf_rq_count, enic->conf_wq_count);
199 	enic->conf_wq_count = enic->conf_rq_count;
200 	enic->conf_cq_count = enic->conf_rq_count + enic->conf_wq_count;
201 	dev_info(enic_get_dev(enic),
202 		"vNIC resources iflib: wq %d rq %d cq %d intr %d\n",
203 		enic->conf_wq_count, enic->conf_rq_count,
204 		enic->conf_cq_count, enic->conf_intr_count);
205 	dev_info(enic_get_dev(enic),
206 		"vNIC resources avail: wq_desc %d rq_desc %d\n",
207 		enic->config.wq_desc_count, enic->config.rq_desc_count);
208 
209 	enic->wq_count = enic->conf_wq_count;
210 	enic->rq_count = enic->conf_rq_count;
211 	enic->cq_count = enic->conf_cq_count;
212 }
213