xref: /aosp_15_r20/external/libnl/lib/route/link/sriov.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker  * Copyright (c) 2016 Intel Corp. All rights reserved.
4*4dc78e53SAndroid Build Coastguard Worker  * Copyright (c) 2016 Jef Oliver <[email protected]>
5*4dc78e53SAndroid Build Coastguard Worker  */
6*4dc78e53SAndroid Build Coastguard Worker 
7*4dc78e53SAndroid Build Coastguard Worker /**
8*4dc78e53SAndroid Build Coastguard Worker  * @ingroup link
9*4dc78e53SAndroid Build Coastguard Worker  * @defgroup sriov SRIOV
10*4dc78e53SAndroid Build Coastguard Worker  * SR-IOV VF link module
11*4dc78e53SAndroid Build Coastguard Worker  *
12*4dc78e53SAndroid Build Coastguard Worker  * @details
13*4dc78e53SAndroid Build Coastguard Worker  * SR-IOV (Single Root Input/Output Virtualization) is a network interface
14*4dc78e53SAndroid Build Coastguard Worker  * that allows for the isolation of the PCI Express resources. In a virtual
15*4dc78e53SAndroid Build Coastguard Worker  * environment, SR-IOV allows multiple virtual machines can share a single
16*4dc78e53SAndroid Build Coastguard Worker  * PCI Express hardware interface. This is done via VFs (Virtual Functions),
17*4dc78e53SAndroid Build Coastguard Worker  * virtual hardware devices with their own PCI address.
18*4dc78e53SAndroid Build Coastguard Worker  *
19*4dc78e53SAndroid Build Coastguard Worker  * @{
20*4dc78e53SAndroid Build Coastguard Worker  */
21*4dc78e53SAndroid Build Coastguard Worker 
22*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
23*4dc78e53SAndroid Build Coastguard Worker 
24*4dc78e53SAndroid Build Coastguard Worker #include <linux/if_ether.h>
25*4dc78e53SAndroid Build Coastguard Worker #include <linux/if_link.h>
26*4dc78e53SAndroid Build Coastguard Worker 
27*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
28*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/link.h>
29*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/link/sriov.h>
30*4dc78e53SAndroid Build Coastguard Worker 
31*4dc78e53SAndroid Build Coastguard Worker #include "nl-route.h"
32*4dc78e53SAndroid Build Coastguard Worker #include "link-sriov.h"
33*4dc78e53SAndroid Build Coastguard Worker #include "link-api.h"
34*4dc78e53SAndroid Build Coastguard Worker 
35*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
36*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf {
37*4dc78e53SAndroid Build Coastguard Worker 	struct nl_list_head vf_list;
38*4dc78e53SAndroid Build Coastguard Worker 	int ce_refcnt;
39*4dc78e53SAndroid Build Coastguard Worker 	uint32_t ce_mask;
40*4dc78e53SAndroid Build Coastguard Worker 	uint32_t vf_index;
41*4dc78e53SAndroid Build Coastguard Worker 	uint64_t vf_guid_node;
42*4dc78e53SAndroid Build Coastguard Worker 	uint64_t vf_guid_port;
43*4dc78e53SAndroid Build Coastguard Worker 	uint32_t vf_linkstate;
44*4dc78e53SAndroid Build Coastguard Worker 	struct nl_addr *vf_lladdr;
45*4dc78e53SAndroid Build Coastguard Worker 	uint32_t vf_max_tx_rate;
46*4dc78e53SAndroid Build Coastguard Worker 	uint32_t vf_min_tx_rate;
47*4dc78e53SAndroid Build Coastguard Worker 	uint32_t vf_rate;
48*4dc78e53SAndroid Build Coastguard Worker 	uint32_t vf_rss_query_en;
49*4dc78e53SAndroid Build Coastguard Worker 	uint32_t vf_spoofchk;
50*4dc78e53SAndroid Build Coastguard Worker 	uint64_t vf_stats[RTNL_LINK_VF_STATS_MAX + 1];
51*4dc78e53SAndroid Build Coastguard Worker 	uint32_t vf_trust;
52*4dc78e53SAndroid Build Coastguard Worker 	struct nl_vf_vlans *vf_vlans;
53*4dc78e53SAndroid Build Coastguard Worker };
54*4dc78e53SAndroid Build Coastguard Worker 
55*4dc78e53SAndroid Build Coastguard Worker #define SRIOVON "on"
56*4dc78e53SAndroid Build Coastguard Worker #define SRIOVOFF "off"
57*4dc78e53SAndroid Build Coastguard Worker 
58*4dc78e53SAndroid Build Coastguard Worker #define SET_VF_STAT(link, vf_num, stb, stat, attr) \
59*4dc78e53SAndroid Build Coastguard Worker 	vf_data->vf_stats[stat] = nla_get_u64(stb[attr])
60*4dc78e53SAndroid Build Coastguard Worker 
61*4dc78e53SAndroid Build Coastguard Worker /* SRIOV-VF Attributes */
62*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_INDEX 		(1 <<  0)
63*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_ADDR 		(1 <<  1)
64*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_VLAN 		(1 <<  2)
65*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_TX_RATE 		(1 <<  3)
66*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_SPOOFCHK 		(1 <<  4)
67*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_RATE_MAX 		(1 <<  5)
68*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_RATE_MIN 		(1 <<  6)
69*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_LINK_STATE 		(1 <<  7)
70*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_RSS_QUERY_EN 	(1 <<  8)
71*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_STATS 		(1 <<  9)
72*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_TRUST 		(1 << 10)
73*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_IB_NODE_GUID 	(1 << 11)
74*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_IB_PORT_GUID 	(1 << 12)
75*4dc78e53SAndroid Build Coastguard Worker 
76*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy sriov_info_policy[IFLA_VF_MAX+1] = {
77*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_MAC]		= { .minlen = sizeof(struct ifla_vf_mac) },
78*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_VLAN]		= { .minlen = sizeof(struct ifla_vf_vlan) },
79*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_VLAN_LIST]     = { .type = NLA_NESTED },
80*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_TX_RATE]	= { .minlen = sizeof(struct ifla_vf_tx_rate) },
81*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_SPOOFCHK]	= { .minlen = sizeof(struct ifla_vf_spoofchk) },
82*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_RATE]		= { .minlen = sizeof(struct ifla_vf_rate) },
83*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_LINK_STATE]	= { .minlen = sizeof(struct ifla_vf_link_state) },
84*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_RSS_QUERY_EN]	= { .minlen = sizeof(struct ifla_vf_rss_query_en) },
85*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_STATS]		= { .type = NLA_NESTED },
86*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_TRUST]		= { .minlen = sizeof(struct ifla_vf_trust) },
87*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_IB_NODE_GUID]	= { .minlen = sizeof(struct ifla_vf_guid) },
88*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_IB_PORT_GUID]	= { .minlen = sizeof(struct ifla_vf_guid) },
89*4dc78e53SAndroid Build Coastguard Worker };
90*4dc78e53SAndroid Build Coastguard Worker 
91*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy sriov_stats_policy[IFLA_VF_STATS_MAX+1] = {
92*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_STATS_RX_PACKETS]	= { .type = NLA_U64 },
93*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_STATS_TX_PACKETS]	= { .type = NLA_U64 },
94*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_STATS_RX_BYTES]	= { .type = NLA_U64 },
95*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_STATS_TX_BYTES]	= { .type = NLA_U64 },
96*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_STATS_BROADCAST]	= { .type = NLA_U64 },
97*4dc78e53SAndroid Build Coastguard Worker 	[IFLA_VF_STATS_MULTICAST]	= { .type = NLA_U64 },
98*4dc78e53SAndroid Build Coastguard Worker };
99*4dc78e53SAndroid Build Coastguard Worker 
100*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
101*4dc78e53SAndroid Build Coastguard Worker 
102*4dc78e53SAndroid Build Coastguard Worker /* Clone SRIOV VF list in link object */
rtnl_link_sriov_clone(struct rtnl_link * dst,struct rtnl_link * src)103*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_sriov_clone(struct rtnl_link *dst, struct rtnl_link *src) {
104*4dc78e53SAndroid Build Coastguard Worker 	int err = 0;
105*4dc78e53SAndroid Build Coastguard Worker 	struct nl_addr *vf_addr;
106*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link_vf *s_list, *d_vf, *s_vf, *next, *dest_h = NULL;
107*4dc78e53SAndroid Build Coastguard Worker 	nl_vf_vlans_t *src_vlans = NULL, *dst_vlans = NULL;
108*4dc78e53SAndroid Build Coastguard Worker 	nl_vf_vlan_info_t *src_vlan_info = NULL, *dst_vlan_info = NULL;
109*4dc78e53SAndroid Build Coastguard Worker 
110*4dc78e53SAndroid Build Coastguard Worker 	if (!rtnl_link_has_vf_list(src))
111*4dc78e53SAndroid Build Coastguard Worker 		return 0;
112*4dc78e53SAndroid Build Coastguard Worker 
113*4dc78e53SAndroid Build Coastguard Worker 	dst->l_vf_list = rtnl_link_vf_alloc();
114*4dc78e53SAndroid Build Coastguard Worker 	if (!dst->l_vf_list)
115*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
116*4dc78e53SAndroid Build Coastguard Worker 	dest_h = dst->l_vf_list;
117*4dc78e53SAndroid Build Coastguard Worker 	s_list = src->l_vf_list;
118*4dc78e53SAndroid Build Coastguard Worker 
119*4dc78e53SAndroid Build Coastguard Worker 	nl_list_for_each_entry_safe(s_vf, next, &s_list->vf_list, vf_list) {
120*4dc78e53SAndroid Build Coastguard Worker 		if (!(d_vf = rtnl_link_vf_alloc()))
121*4dc78e53SAndroid Build Coastguard Worker 			return -NLE_NOMEM;
122*4dc78e53SAndroid Build Coastguard Worker 
123*4dc78e53SAndroid Build Coastguard Worker 		memcpy(d_vf, s_vf, sizeof(*s_vf));
124*4dc78e53SAndroid Build Coastguard Worker 
125*4dc78e53SAndroid Build Coastguard Worker 		if (s_vf->ce_mask & SRIOV_ATTR_ADDR) {
126*4dc78e53SAndroid Build Coastguard Worker 			vf_addr = nl_addr_clone(s_vf->vf_lladdr);
127*4dc78e53SAndroid Build Coastguard Worker 			if (!vf_addr) {
128*4dc78e53SAndroid Build Coastguard Worker 				rtnl_link_vf_put(d_vf);
129*4dc78e53SAndroid Build Coastguard Worker 				return -NLE_NOMEM;
130*4dc78e53SAndroid Build Coastguard Worker 			}
131*4dc78e53SAndroid Build Coastguard Worker 			d_vf->vf_lladdr = vf_addr;
132*4dc78e53SAndroid Build Coastguard Worker 		}
133*4dc78e53SAndroid Build Coastguard Worker 
134*4dc78e53SAndroid Build Coastguard Worker 		if (s_vf->ce_mask & SRIOV_ATTR_VLAN) {
135*4dc78e53SAndroid Build Coastguard Worker 			src_vlans = s_vf->vf_vlans;
136*4dc78e53SAndroid Build Coastguard Worker 			src_vlan_info = src_vlans->vlans;
137*4dc78e53SAndroid Build Coastguard Worker 
138*4dc78e53SAndroid Build Coastguard Worker 			err = rtnl_link_vf_vlan_alloc(&dst_vlans,
139*4dc78e53SAndroid Build Coastguard Worker 						      src_vlans->size);
140*4dc78e53SAndroid Build Coastguard Worker 			if (err < 0) {
141*4dc78e53SAndroid Build Coastguard Worker 				rtnl_link_vf_put(d_vf);
142*4dc78e53SAndroid Build Coastguard Worker 				return err;
143*4dc78e53SAndroid Build Coastguard Worker 			}
144*4dc78e53SAndroid Build Coastguard Worker 			dst_vlan_info = dst_vlans->vlans;
145*4dc78e53SAndroid Build Coastguard Worker 			memcpy(dst_vlans, src_vlans, sizeof(nl_vf_vlans_t));
146*4dc78e53SAndroid Build Coastguard Worker 			memcpy(dst_vlan_info, src_vlan_info,
147*4dc78e53SAndroid Build Coastguard Worker 			       dst_vlans->size * sizeof(*dst_vlan_info));
148*4dc78e53SAndroid Build Coastguard Worker 			d_vf->vf_vlans = dst_vlans;
149*4dc78e53SAndroid Build Coastguard Worker 		}
150*4dc78e53SAndroid Build Coastguard Worker 
151*4dc78e53SAndroid Build Coastguard Worker 		nl_list_add_head(&d_vf->vf_list, &dest_h->vf_list);
152*4dc78e53SAndroid Build Coastguard Worker 		dest_h = d_vf;
153*4dc78e53SAndroid Build Coastguard Worker 	}
154*4dc78e53SAndroid Build Coastguard Worker 
155*4dc78e53SAndroid Build Coastguard Worker 	return 0;
156*4dc78e53SAndroid Build Coastguard Worker }
157*4dc78e53SAndroid Build Coastguard Worker 
158*4dc78e53SAndroid Build Coastguard Worker /* Dump VLAN details for each SRIOV VF */
dump_sriov_vlans(nl_vf_vlans_t * vlans,struct nl_dump_params * p)159*4dc78e53SAndroid Build Coastguard Worker static void dump_sriov_vlans(nl_vf_vlans_t *vlans,
160*4dc78e53SAndroid Build Coastguard Worker 			     struct nl_dump_params *p) {
161*4dc78e53SAndroid Build Coastguard Worker 	char buf[64];
162*4dc78e53SAndroid Build Coastguard Worker 	int cur = 0;
163*4dc78e53SAndroid Build Coastguard Worker 	nl_vf_vlan_info_t *vlan_data;
164*4dc78e53SAndroid Build Coastguard Worker 	uint16_t prot;
165*4dc78e53SAndroid Build Coastguard Worker 
166*4dc78e53SAndroid Build Coastguard Worker 	vlan_data = vlans->vlans;
167*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "\t      VLANS:\n");
168*4dc78e53SAndroid Build Coastguard Worker 	while (cur < vlans->size) {
169*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, "\t      vlan %u", vlan_data[cur].vf_vlan);
170*4dc78e53SAndroid Build Coastguard Worker 		if (vlan_data[cur].vf_vlan_qos)
171*4dc78e53SAndroid Build Coastguard Worker 			nl_dump(p, " qos %u", vlan_data[cur].vf_vlan_qos);
172*4dc78e53SAndroid Build Coastguard Worker 		if (vlan_data[cur].vf_vlan_proto) {
173*4dc78e53SAndroid Build Coastguard Worker 			prot = vlan_data[cur].vf_vlan_proto;
174*4dc78e53SAndroid Build Coastguard Worker 			nl_dump(p, " proto %s",
175*4dc78e53SAndroid Build Coastguard Worker 				rtnl_link_vf_vlanproto2str(prot, buf,
176*4dc78e53SAndroid Build Coastguard Worker 							   sizeof(buf)));
177*4dc78e53SAndroid Build Coastguard Worker 		}
178*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, "\n");
179*4dc78e53SAndroid Build Coastguard Worker 		cur++;
180*4dc78e53SAndroid Build Coastguard Worker 	}
181*4dc78e53SAndroid Build Coastguard Worker 
182*4dc78e53SAndroid Build Coastguard Worker 	return;
183*4dc78e53SAndroid Build Coastguard Worker }
184*4dc78e53SAndroid Build Coastguard Worker 
185*4dc78e53SAndroid Build Coastguard Worker /* Dump details for each SRIOV VF */
dump_vf_details(struct rtnl_link_vf * vf_data,struct nl_dump_params * p)186*4dc78e53SAndroid Build Coastguard Worker static void dump_vf_details(struct rtnl_link_vf *vf_data,
187*4dc78e53SAndroid Build Coastguard Worker 			    struct nl_dump_params *p) {
188*4dc78e53SAndroid Build Coastguard Worker 	char buf[64];
189*4dc78e53SAndroid Build Coastguard Worker 	int err = 0;
190*4dc78e53SAndroid Build Coastguard Worker 	struct nl_vf_rate vf_rate;
191*4dc78e53SAndroid Build Coastguard Worker 	uint32_t v = 0;
192*4dc78e53SAndroid Build Coastguard Worker 
193*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "\tvf %u: ", vf_data->vf_index);
194*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE) {
195*4dc78e53SAndroid Build Coastguard Worker 		v = vf_data->vf_linkstate;
196*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, "state %s ",
197*4dc78e53SAndroid Build Coastguard Worker 			rtnl_link_vf_linkstate2str(v, buf, sizeof(buf)));
198*4dc78e53SAndroid Build Coastguard Worker 	}
199*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_ADDR) {
200*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, "addr %s ",
201*4dc78e53SAndroid Build Coastguard Worker 			nl_addr2str(vf_data->vf_lladdr, buf, sizeof(buf)));
202*4dc78e53SAndroid Build Coastguard Worker 	}
203*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "\n");
204*4dc78e53SAndroid Build Coastguard Worker 
205*4dc78e53SAndroid Build Coastguard Worker 	v = vf_data->vf_spoofchk;
206*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "\t      spoofchk %s ", v ? SRIOVON : SRIOVOFF);
207*4dc78e53SAndroid Build Coastguard Worker 	v = vf_data->vf_trust;
208*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "trust %s ", v ? SRIOVON : SRIOVOFF);
209*4dc78e53SAndroid Build Coastguard Worker 	v = vf_data->vf_rss_query_en;
210*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "rss_query %s\n", v ? SRIOVON : SRIOVOFF);
211*4dc78e53SAndroid Build Coastguard Worker 
212*4dc78e53SAndroid Build Coastguard Worker 	err = rtnl_link_vf_get_rate(vf_data, &vf_rate);
213*4dc78e53SAndroid Build Coastguard Worker 	if (!err) {
214*4dc78e53SAndroid Build Coastguard Worker 		if (vf_rate.api == RTNL_LINK_VF_RATE_API_OLD)
215*4dc78e53SAndroid Build Coastguard Worker 			nl_dump(p, "\t      rate_api old rate %u\n",
216*4dc78e53SAndroid Build Coastguard Worker 				vf_rate.rate);
217*4dc78e53SAndroid Build Coastguard Worker 		else if (vf_rate.api == RTNL_LINK_VF_RATE_API_NEW)
218*4dc78e53SAndroid Build Coastguard Worker 			nl_dump(p, "\t      rate_api new min_rate %u "
219*4dc78e53SAndroid Build Coastguard Worker 					"max_rate %u\n", vf_rate.min_tx_rate,
220*4dc78e53SAndroid Build Coastguard Worker 				vf_rate.max_tx_rate);
221*4dc78e53SAndroid Build Coastguard Worker 	}
222*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_VLAN)
223*4dc78e53SAndroid Build Coastguard Worker 		dump_sriov_vlans(vf_data->vf_vlans, p);
224*4dc78e53SAndroid Build Coastguard Worker 
225*4dc78e53SAndroid Build Coastguard Worker 	return;
226*4dc78e53SAndroid Build Coastguard Worker }
227*4dc78e53SAndroid Build Coastguard Worker 
228*4dc78e53SAndroid Build Coastguard Worker /* Loop through SRIOV VF list dump details */
rtnl_link_sriov_dump_details(struct rtnl_link * link,struct nl_dump_params * p)229*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_sriov_dump_details(struct rtnl_link *link,
230*4dc78e53SAndroid Build Coastguard Worker 				  struct nl_dump_params *p) {
231*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link_vf *vf_data, *list, *next;
232*4dc78e53SAndroid Build Coastguard Worker 
233*4dc78e53SAndroid Build Coastguard Worker 	if (!rtnl_link_has_vf_list(link))
234*4dc78e53SAndroid Build Coastguard Worker 		BUG();
235*4dc78e53SAndroid Build Coastguard Worker 
236*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "    SRIOV VF List\n");
237*4dc78e53SAndroid Build Coastguard Worker 	list = link->l_vf_list;
238*4dc78e53SAndroid Build Coastguard Worker 	nl_list_for_each_entry_safe(vf_data, next, &list->vf_list, vf_list) {
239*4dc78e53SAndroid Build Coastguard Worker 		if (vf_data->ce_mask & SRIOV_ATTR_INDEX)
240*4dc78e53SAndroid Build Coastguard Worker 			dump_vf_details(vf_data, p);
241*4dc78e53SAndroid Build Coastguard Worker 	}
242*4dc78e53SAndroid Build Coastguard Worker 
243*4dc78e53SAndroid Build Coastguard Worker 	return;
244*4dc78e53SAndroid Build Coastguard Worker }
245*4dc78e53SAndroid Build Coastguard Worker 
246*4dc78e53SAndroid Build Coastguard Worker /* Dump stats for each SRIOV VF */
dump_vf_stats(struct rtnl_link_vf * vf_data,struct nl_dump_params * p)247*4dc78e53SAndroid Build Coastguard Worker static void dump_vf_stats(struct rtnl_link_vf *vf_data,
248*4dc78e53SAndroid Build Coastguard Worker 			  struct nl_dump_params *p) {
249*4dc78e53SAndroid Build Coastguard Worker 	char *unit;
250*4dc78e53SAndroid Build Coastguard Worker 	float res;
251*4dc78e53SAndroid Build Coastguard Worker 
252*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "    VF %u Stats:\n", vf_data->vf_index);
253*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p, "\tRX:    %-14s %-10s   %-10s %-10s\n",
254*4dc78e53SAndroid Build Coastguard Worker 		     "bytes", "packets", "multicast", "broadcast");
255*4dc78e53SAndroid Build Coastguard Worker 
256*4dc78e53SAndroid Build Coastguard Worker 	res = nl_cancel_down_bytes(vf_data->vf_stats[RTNL_LINK_VF_STATS_RX_BYTES],
257*4dc78e53SAndroid Build Coastguard Worker 				   &unit);
258*4dc78e53SAndroid Build Coastguard Worker 
259*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p,
260*4dc78e53SAndroid Build Coastguard Worker 		"\t%10.2f %3s   %10" PRIu64 "   %10" PRIu64 " %10" PRIu64 "\n",
261*4dc78e53SAndroid Build Coastguard Worker 		res, unit,
262*4dc78e53SAndroid Build Coastguard Worker 		vf_data->vf_stats[RTNL_LINK_VF_STATS_RX_PACKETS],
263*4dc78e53SAndroid Build Coastguard Worker 		vf_data->vf_stats[RTNL_LINK_VF_STATS_MULTICAST],
264*4dc78e53SAndroid Build Coastguard Worker 		vf_data->vf_stats[RTNL_LINK_VF_STATS_BROADCAST]);
265*4dc78e53SAndroid Build Coastguard Worker 
266*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p, "\tTX:    %-14s %-10s\n", "bytes", "packets");
267*4dc78e53SAndroid Build Coastguard Worker 
268*4dc78e53SAndroid Build Coastguard Worker 	res = nl_cancel_down_bytes(vf_data->vf_stats[RTNL_LINK_VF_STATS_TX_BYTES],
269*4dc78e53SAndroid Build Coastguard Worker 				   &unit);
270*4dc78e53SAndroid Build Coastguard Worker 
271*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p, "\t%10.2f %3s   %10" PRIu64 "\n", res, unit,
272*4dc78e53SAndroid Build Coastguard Worker 		vf_data->vf_stats[RTNL_LINK_VF_STATS_TX_PACKETS]);
273*4dc78e53SAndroid Build Coastguard Worker 
274*4dc78e53SAndroid Build Coastguard Worker 	return;
275*4dc78e53SAndroid Build Coastguard Worker }
276*4dc78e53SAndroid Build Coastguard Worker 
277*4dc78e53SAndroid Build Coastguard Worker /* Loop through SRIOV VF list dump stats */
rtnl_link_sriov_dump_stats(struct rtnl_link * link,struct nl_dump_params * p)278*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_sriov_dump_stats(struct rtnl_link *link,
279*4dc78e53SAndroid Build Coastguard Worker 				struct nl_dump_params *p) {
280*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link_vf *vf_data, *list, *next;
281*4dc78e53SAndroid Build Coastguard Worker 
282*4dc78e53SAndroid Build Coastguard Worker 	list = link->l_vf_list;
283*4dc78e53SAndroid Build Coastguard Worker 	nl_list_for_each_entry_safe(vf_data, next, &list->vf_list, vf_list) {
284*4dc78e53SAndroid Build Coastguard Worker 		if (vf_data->ce_mask & SRIOV_ATTR_INDEX)
285*4dc78e53SAndroid Build Coastguard Worker 			dump_vf_stats(vf_data, p);
286*4dc78e53SAndroid Build Coastguard Worker 	}
287*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "\n");
288*4dc78e53SAndroid Build Coastguard Worker 
289*4dc78e53SAndroid Build Coastguard Worker 	return;
290*4dc78e53SAndroid Build Coastguard Worker }
291*4dc78e53SAndroid Build Coastguard Worker 
292*4dc78e53SAndroid Build Coastguard Worker /* Free stored SRIOV VF data */
rtnl_link_sriov_free_data(struct rtnl_link * link)293*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_sriov_free_data(struct rtnl_link *link) {
294*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link_vf *list, *vf, *next;
295*4dc78e53SAndroid Build Coastguard Worker 
296*4dc78e53SAndroid Build Coastguard Worker 	if (!rtnl_link_has_vf_list(link))
297*4dc78e53SAndroid Build Coastguard Worker 		return;
298*4dc78e53SAndroid Build Coastguard Worker 
299*4dc78e53SAndroid Build Coastguard Worker 	list = link->l_vf_list;
300*4dc78e53SAndroid Build Coastguard Worker 	nl_list_for_each_entry_safe(vf, next, &list->vf_list, vf_list) {
301*4dc78e53SAndroid Build Coastguard Worker 		nl_list_del(&vf->vf_list);
302*4dc78e53SAndroid Build Coastguard Worker 		rtnl_link_vf_put(vf);
303*4dc78e53SAndroid Build Coastguard Worker 	}
304*4dc78e53SAndroid Build Coastguard Worker 
305*4dc78e53SAndroid Build Coastguard Worker 	rtnl_link_vf_put(link->l_vf_list);
306*4dc78e53SAndroid Build Coastguard Worker 
307*4dc78e53SAndroid Build Coastguard Worker 	return;
308*4dc78e53SAndroid Build Coastguard Worker }
309*4dc78e53SAndroid Build Coastguard Worker 
310*4dc78e53SAndroid Build Coastguard Worker /* Fill VLAN info array */
rtnl_link_vf_vlan_info(int len,struct ifla_vf_vlan_info ** vi,nl_vf_vlans_t ** nvi)311*4dc78e53SAndroid Build Coastguard Worker static int rtnl_link_vf_vlan_info(int len, struct ifla_vf_vlan_info **vi,
312*4dc78e53SAndroid Build Coastguard Worker 				  nl_vf_vlans_t **nvi) {
313*4dc78e53SAndroid Build Coastguard Worker 	int cur = 0, err;
314*4dc78e53SAndroid Build Coastguard Worker 	nl_vf_vlans_t *vlans;
315*4dc78e53SAndroid Build Coastguard Worker 
316*4dc78e53SAndroid Build Coastguard Worker 	if (len <= 0)
317*4dc78e53SAndroid Build Coastguard Worker 		return 0;
318*4dc78e53SAndroid Build Coastguard Worker 
319*4dc78e53SAndroid Build Coastguard Worker 	if ((err = rtnl_link_vf_vlan_alloc(&vlans, len)) < 0)
320*4dc78e53SAndroid Build Coastguard Worker 		return err;
321*4dc78e53SAndroid Build Coastguard Worker 
322*4dc78e53SAndroid Build Coastguard Worker 	cur = 0;
323*4dc78e53SAndroid Build Coastguard Worker 	while (cur < len) {
324*4dc78e53SAndroid Build Coastguard Worker 		vlans->vlans[cur].vf_vlan = vi[cur]->vlan ? vi[cur]->vlan : 0;
325*4dc78e53SAndroid Build Coastguard Worker 		vlans->vlans[cur].vf_vlan_qos = vi[cur]->qos ? vi[cur]->qos : 0;
326*4dc78e53SAndroid Build Coastguard Worker 		if (vi[cur]->vlan_proto) {
327*4dc78e53SAndroid Build Coastguard Worker 			vlans->vlans[cur].vf_vlan_proto = ntohs(vi[cur]->vlan_proto);
328*4dc78e53SAndroid Build Coastguard Worker 		} else {
329*4dc78e53SAndroid Build Coastguard Worker 			vlans->vlans[cur].vf_vlan_proto = ETH_P_8021Q;
330*4dc78e53SAndroid Build Coastguard Worker 		}
331*4dc78e53SAndroid Build Coastguard Worker 		cur++;
332*4dc78e53SAndroid Build Coastguard Worker 	}
333*4dc78e53SAndroid Build Coastguard Worker 
334*4dc78e53SAndroid Build Coastguard Worker 	*nvi = vlans;
335*4dc78e53SAndroid Build Coastguard Worker 	return 0;
336*4dc78e53SAndroid Build Coastguard Worker }
337*4dc78e53SAndroid Build Coastguard Worker 
338*4dc78e53SAndroid Build Coastguard Worker /* Fill the IFLA_VF_VLAN attribute */
sriov_fill_vf_vlan(struct nl_msg * msg,nl_vf_vlan_info_t * vinfo,uint32_t index)339*4dc78e53SAndroid Build Coastguard Worker static void sriov_fill_vf_vlan(struct nl_msg *msg, nl_vf_vlan_info_t *vinfo,
340*4dc78e53SAndroid Build Coastguard Worker 			       uint32_t index) {
341*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_vlan vlan;
342*4dc78e53SAndroid Build Coastguard Worker 
343*4dc78e53SAndroid Build Coastguard Worker 	vlan.vf = index;
344*4dc78e53SAndroid Build Coastguard Worker 	vlan.vlan = vinfo[0].vf_vlan;
345*4dc78e53SAndroid Build Coastguard Worker 	vlan.qos = vinfo[0].vf_vlan_qos;
346*4dc78e53SAndroid Build Coastguard Worker 	NLA_PUT(msg, IFLA_VF_VLAN, sizeof(vlan), &vlan);
347*4dc78e53SAndroid Build Coastguard Worker 
348*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
349*4dc78e53SAndroid Build Coastguard Worker 	return;
350*4dc78e53SAndroid Build Coastguard Worker }
351*4dc78e53SAndroid Build Coastguard Worker 
352*4dc78e53SAndroid Build Coastguard Worker /* Fill the IFLA_VF_VLAN_LIST attribute */
sriov_fill_vf_vlan_list(struct nl_msg * msg,nl_vf_vlans_t * vlans,uint32_t index)353*4dc78e53SAndroid Build Coastguard Worker static int sriov_fill_vf_vlan_list(struct nl_msg *msg, nl_vf_vlans_t *vlans,
354*4dc78e53SAndroid Build Coastguard Worker 				   uint32_t index) {
355*4dc78e53SAndroid Build Coastguard Worker 	int cur = 0;
356*4dc78e53SAndroid Build Coastguard Worker 	nl_vf_vlan_info_t *vlan_info = vlans->vlans;
357*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_vlan_info vlan;
358*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *list;
359*4dc78e53SAndroid Build Coastguard Worker 
360*4dc78e53SAndroid Build Coastguard Worker 	if (!(list = nla_nest_start(msg, IFLA_VF_VLAN_LIST)))
361*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MSGSIZE;
362*4dc78e53SAndroid Build Coastguard Worker 
363*4dc78e53SAndroid Build Coastguard Worker 	vlan.vf = index;
364*4dc78e53SAndroid Build Coastguard Worker 	while (cur < vlans->size) {
365*4dc78e53SAndroid Build Coastguard Worker 		vlan.vlan = vlan_info[cur].vf_vlan;
366*4dc78e53SAndroid Build Coastguard Worker 		vlan.qos = vlan_info[cur].vf_vlan_qos;
367*4dc78e53SAndroid Build Coastguard Worker 		vlan.vlan_proto = vlan_info[cur].vf_vlan_proto;
368*4dc78e53SAndroid Build Coastguard Worker 
369*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT(msg, IFLA_VF_VLAN_INFO, sizeof(vlan), &vlan);
370*4dc78e53SAndroid Build Coastguard Worker 
371*4dc78e53SAndroid Build Coastguard Worker 		cur++;
372*4dc78e53SAndroid Build Coastguard Worker 	}
373*4dc78e53SAndroid Build Coastguard Worker 
374*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
375*4dc78e53SAndroid Build Coastguard Worker 	nla_nest_end(msg, list);
376*4dc78e53SAndroid Build Coastguard Worker 
377*4dc78e53SAndroid Build Coastguard Worker 	return 0;
378*4dc78e53SAndroid Build Coastguard Worker }
379*4dc78e53SAndroid Build Coastguard Worker 
380*4dc78e53SAndroid Build Coastguard Worker /* Fill individual IFLA_VF_INFO attributes */
sriov_fill_vfinfo(struct nl_msg * msg,struct rtnl_link_vf * vf_data)381*4dc78e53SAndroid Build Coastguard Worker static int sriov_fill_vfinfo(struct nl_msg *msg,
382*4dc78e53SAndroid Build Coastguard Worker 			     struct rtnl_link_vf *vf_data) {
383*4dc78e53SAndroid Build Coastguard Worker 	int err = 0, new_rate = 0;
384*4dc78e53SAndroid Build Coastguard Worker 	nl_vf_vlans_t *vlan_list;
385*4dc78e53SAndroid Build Coastguard Worker 	nl_vf_vlan_info_t *vlan_info;
386*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_guid vf_node_guid;
387*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_guid vf_port_guid;
388*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_link_state vf_link_state;
389*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_mac vf_mac;
390*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_rate new_vf_rate;
391*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_rss_query_en vf_rss_query_en;
392*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_spoofchk vf_spoofchk;
393*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_trust vf_trust;
394*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_tx_rate vf_rate;
395*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *list;
396*4dc78e53SAndroid Build Coastguard Worker 	uint16_t proto;
397*4dc78e53SAndroid Build Coastguard Worker 
398*4dc78e53SAndroid Build Coastguard Worker 	if (!(vf_data->ce_mask & SRIOV_ATTR_INDEX))
399*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
400*4dc78e53SAndroid Build Coastguard Worker 
401*4dc78e53SAndroid Build Coastguard Worker 	if (!(list = nla_nest_start(msg, IFLA_VF_INFO)))
402*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MSGSIZE;
403*4dc78e53SAndroid Build Coastguard Worker 
404*4dc78e53SAndroid Build Coastguard Worker 	/* IFLA_VF_MAC */
405*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_ADDR) {
406*4dc78e53SAndroid Build Coastguard Worker 		vf_mac.vf = vf_data->vf_index;
407*4dc78e53SAndroid Build Coastguard Worker 		memset(vf_mac.mac, 0, sizeof(vf_mac.mac));
408*4dc78e53SAndroid Build Coastguard Worker 		memcpy(vf_mac.mac, nl_addr_get_binary_addr(vf_data->vf_lladdr),
409*4dc78e53SAndroid Build Coastguard Worker 		       nl_addr_get_len(vf_data->vf_lladdr));
410*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT(msg, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac);
411*4dc78e53SAndroid Build Coastguard Worker 	}
412*4dc78e53SAndroid Build Coastguard Worker 
413*4dc78e53SAndroid Build Coastguard Worker 	/* IFLA_VF_VLAN IFLA_VF_VLAN_LIST */
414*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_VLAN) {
415*4dc78e53SAndroid Build Coastguard Worker 		vlan_list = vf_data->vf_vlans;
416*4dc78e53SAndroid Build Coastguard Worker 		vlan_info = vlan_list->vlans;
417*4dc78e53SAndroid Build Coastguard Worker 		proto = vlan_info[0].vf_vlan_proto;
418*4dc78e53SAndroid Build Coastguard Worker 		if (!proto)
419*4dc78e53SAndroid Build Coastguard Worker 			proto = ETH_P_8021Q;
420*4dc78e53SAndroid Build Coastguard Worker 
421*4dc78e53SAndroid Build Coastguard Worker 		if ((vlan_list->size == 1) && (proto == ETH_P_8021Q))
422*4dc78e53SAndroid Build Coastguard Worker 			sriov_fill_vf_vlan(msg, vlan_info, vf_data->vf_index);
423*4dc78e53SAndroid Build Coastguard Worker 		else
424*4dc78e53SAndroid Build Coastguard Worker 			err = sriov_fill_vf_vlan_list(msg, vlan_list,
425*4dc78e53SAndroid Build Coastguard Worker 						      vf_data->vf_index);
426*4dc78e53SAndroid Build Coastguard Worker 	}
427*4dc78e53SAndroid Build Coastguard Worker 
428*4dc78e53SAndroid Build Coastguard Worker 	/* IFLA_VF_TX_RATE */
429*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_TX_RATE) {
430*4dc78e53SAndroid Build Coastguard Worker 		vf_rate.vf = vf_data->vf_index;
431*4dc78e53SAndroid Build Coastguard Worker 		vf_rate.rate = vf_data->vf_rate;
432*4dc78e53SAndroid Build Coastguard Worker 
433*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT(msg, IFLA_VF_TX_RATE, sizeof(vf_rate), &vf_rate);
434*4dc78e53SAndroid Build Coastguard Worker 	}
435*4dc78e53SAndroid Build Coastguard Worker 
436*4dc78e53SAndroid Build Coastguard Worker 	/* IFLA_VF_RATE */
437*4dc78e53SAndroid Build Coastguard Worker 	new_vf_rate.min_tx_rate = 0;
438*4dc78e53SAndroid Build Coastguard Worker 	new_vf_rate.max_tx_rate = 0;
439*4dc78e53SAndroid Build Coastguard Worker 	new_vf_rate.vf = vf_data->vf_index;
440*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_RATE_MIN) {
441*4dc78e53SAndroid Build Coastguard Worker 		new_vf_rate.min_tx_rate = vf_data->vf_min_tx_rate;
442*4dc78e53SAndroid Build Coastguard Worker 		new_rate = 1;
443*4dc78e53SAndroid Build Coastguard Worker 	}
444*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_RATE_MAX) {
445*4dc78e53SAndroid Build Coastguard Worker 		new_vf_rate.max_tx_rate = vf_data->vf_max_tx_rate;
446*4dc78e53SAndroid Build Coastguard Worker 		new_rate = 1;
447*4dc78e53SAndroid Build Coastguard Worker 	}
448*4dc78e53SAndroid Build Coastguard Worker 	if (new_rate)
449*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT(msg, IFLA_VF_RATE, sizeof(new_vf_rate), &new_vf_rate);
450*4dc78e53SAndroid Build Coastguard Worker 
451*4dc78e53SAndroid Build Coastguard Worker 	/* IFLA_VF_SPOOFCHK */
452*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_SPOOFCHK) {
453*4dc78e53SAndroid Build Coastguard Worker 		vf_spoofchk.vf = vf_data->vf_index;
454*4dc78e53SAndroid Build Coastguard Worker 		vf_spoofchk.setting = vf_data->vf_spoofchk;
455*4dc78e53SAndroid Build Coastguard Worker 
456*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT(msg, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
457*4dc78e53SAndroid Build Coastguard Worker 			&vf_spoofchk);
458*4dc78e53SAndroid Build Coastguard Worker 	}
459*4dc78e53SAndroid Build Coastguard Worker 
460*4dc78e53SAndroid Build Coastguard Worker 	/* IFLA_VF_LINK_STATE */
461*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE) {
462*4dc78e53SAndroid Build Coastguard Worker 		vf_link_state.vf = vf_data->vf_index;
463*4dc78e53SAndroid Build Coastguard Worker 		vf_link_state.link_state = vf_data->vf_linkstate;
464*4dc78e53SAndroid Build Coastguard Worker 
465*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT(msg, IFLA_VF_LINK_STATE, sizeof(vf_link_state),
466*4dc78e53SAndroid Build Coastguard Worker 			&vf_link_state);
467*4dc78e53SAndroid Build Coastguard Worker 	}
468*4dc78e53SAndroid Build Coastguard Worker 
469*4dc78e53SAndroid Build Coastguard Worker 	/* IFLA_VF_RSS_QUERY_EN */
470*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_RSS_QUERY_EN) {
471*4dc78e53SAndroid Build Coastguard Worker 		vf_rss_query_en.vf = vf_data->vf_index;
472*4dc78e53SAndroid Build Coastguard Worker 		vf_rss_query_en.setting = vf_data->vf_rss_query_en;
473*4dc78e53SAndroid Build Coastguard Worker 
474*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT(msg, IFLA_VF_RSS_QUERY_EN, sizeof(vf_rss_query_en),
475*4dc78e53SAndroid Build Coastguard Worker 			&vf_rss_query_en);
476*4dc78e53SAndroid Build Coastguard Worker 	}
477*4dc78e53SAndroid Build Coastguard Worker 
478*4dc78e53SAndroid Build Coastguard Worker 	/* IFLA_VF_TRUST */
479*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_TRUST) {
480*4dc78e53SAndroid Build Coastguard Worker 		vf_trust.vf = vf_data->vf_index;
481*4dc78e53SAndroid Build Coastguard Worker 		vf_trust.setting = vf_data->vf_trust;
482*4dc78e53SAndroid Build Coastguard Worker 
483*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT(msg, IFLA_VF_TRUST, sizeof(vf_trust), &vf_trust);
484*4dc78e53SAndroid Build Coastguard Worker 	}
485*4dc78e53SAndroid Build Coastguard Worker 
486*4dc78e53SAndroid Build Coastguard Worker 	/* IFLA_VF_IB_NODE_GUID */
487*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_IB_NODE_GUID) {
488*4dc78e53SAndroid Build Coastguard Worker 		vf_node_guid.vf = vf_data->vf_index;
489*4dc78e53SAndroid Build Coastguard Worker 		vf_node_guid.guid = vf_data->vf_guid_node;
490*4dc78e53SAndroid Build Coastguard Worker 
491*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT(msg, IFLA_VF_IB_NODE_GUID, sizeof(vf_node_guid),
492*4dc78e53SAndroid Build Coastguard Worker 			&vf_node_guid);
493*4dc78e53SAndroid Build Coastguard Worker 	}
494*4dc78e53SAndroid Build Coastguard Worker 
495*4dc78e53SAndroid Build Coastguard Worker 	/* IFLA_VF_IB_PORT_GUID */
496*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_IB_PORT_GUID) {
497*4dc78e53SAndroid Build Coastguard Worker 		vf_port_guid.vf = vf_data->vf_index;
498*4dc78e53SAndroid Build Coastguard Worker 		vf_port_guid.guid = vf_data->vf_guid_port;
499*4dc78e53SAndroid Build Coastguard Worker 
500*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT(msg, IFLA_VF_IB_PORT_GUID, sizeof(vf_port_guid),
501*4dc78e53SAndroid Build Coastguard Worker 			&vf_port_guid);
502*4dc78e53SAndroid Build Coastguard Worker 	}
503*4dc78e53SAndroid Build Coastguard Worker 
504*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
505*4dc78e53SAndroid Build Coastguard Worker 	nla_nest_end(msg, list);
506*4dc78e53SAndroid Build Coastguard Worker 
507*4dc78e53SAndroid Build Coastguard Worker 	return err;
508*4dc78e53SAndroid Build Coastguard Worker }
509*4dc78e53SAndroid Build Coastguard Worker 
510*4dc78e53SAndroid Build Coastguard Worker /* Fill the IFLA_VFINFO_LIST attribute */
rtnl_link_sriov_fill_vflist(struct nl_msg * msg,struct rtnl_link * link)511*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_sriov_fill_vflist(struct nl_msg *msg, struct rtnl_link *link) {
512*4dc78e53SAndroid Build Coastguard Worker 	int err = 0;
513*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *data;
514*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link_vf *list, *vf, *next;
515*4dc78e53SAndroid Build Coastguard Worker 
516*4dc78e53SAndroid Build Coastguard Worker 	if (!(err = rtnl_link_has_vf_list(link)))
517*4dc78e53SAndroid Build Coastguard Worker 		return 0;
518*4dc78e53SAndroid Build Coastguard Worker 
519*4dc78e53SAndroid Build Coastguard Worker 	if (!(data = nla_nest_start(msg, IFLA_VFINFO_LIST)))
520*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MSGSIZE;
521*4dc78e53SAndroid Build Coastguard Worker 
522*4dc78e53SAndroid Build Coastguard Worker 	list = link->l_vf_list;
523*4dc78e53SAndroid Build Coastguard Worker 	nl_list_for_each_entry_safe(vf, next, &list->vf_list, vf_list) {
524*4dc78e53SAndroid Build Coastguard Worker 		if (vf->ce_mask & SRIOV_ATTR_INDEX) {
525*4dc78e53SAndroid Build Coastguard Worker 			if ((err = sriov_fill_vfinfo(msg, vf)) < 0)
526*4dc78e53SAndroid Build Coastguard Worker 				goto nla_nest_list_failure;
527*4dc78e53SAndroid Build Coastguard Worker 		}
528*4dc78e53SAndroid Build Coastguard Worker 	}
529*4dc78e53SAndroid Build Coastguard Worker 
530*4dc78e53SAndroid Build Coastguard Worker nla_nest_list_failure:
531*4dc78e53SAndroid Build Coastguard Worker 	nla_nest_end(msg, data);
532*4dc78e53SAndroid Build Coastguard Worker 
533*4dc78e53SAndroid Build Coastguard Worker 	return err;
534*4dc78e53SAndroid Build Coastguard Worker }
535*4dc78e53SAndroid Build Coastguard Worker 
536*4dc78e53SAndroid Build Coastguard Worker /* Parse IFLA_VFINFO_LIST and IFLA_VF_INFO attributes */
rtnl_link_sriov_parse_vflist(struct rtnl_link * link,struct nlattr ** tb)537*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_sriov_parse_vflist(struct rtnl_link *link, struct nlattr **tb) {
538*4dc78e53SAndroid Build Coastguard Worker 	int err, len, list_len, list_rem;
539*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_mac *vf_lladdr;
540*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_vlan *vf_vlan;
541*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_vlan_info *vf_vlan_info[MAX_VLAN_LIST_LEN];
542*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_tx_rate *vf_tx_rate;
543*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_spoofchk *vf_spoofchk;
544*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_link_state *vf_linkstate;
545*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_rate *vf_rate;
546*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_rss_query_en *vf_rss_query;
547*4dc78e53SAndroid Build Coastguard Worker 	struct ifla_vf_trust *vf_trust;
548*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *nla, *nla_list, *t[IFLA_VF_MAX+1],
549*4dc78e53SAndroid Build Coastguard Worker 		*stb[RTNL_LINK_VF_STATS_MAX+1];
550*4dc78e53SAndroid Build Coastguard Worker 	nl_vf_vlans_t *vf_vlans = NULL;
551*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link_vf *vf_data, *vf_head = NULL;
552*4dc78e53SAndroid Build Coastguard Worker 
553*4dc78e53SAndroid Build Coastguard Worker 	len = nla_len(tb[IFLA_VFINFO_LIST]);
554*4dc78e53SAndroid Build Coastguard Worker 	link->l_vf_list = rtnl_link_vf_alloc();
555*4dc78e53SAndroid Build Coastguard Worker 	if (!link->l_vf_list)
556*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
557*4dc78e53SAndroid Build Coastguard Worker 	vf_head = link->l_vf_list;
558*4dc78e53SAndroid Build Coastguard Worker 
559*4dc78e53SAndroid Build Coastguard Worker 	for (nla = nla_data(tb[IFLA_VFINFO_LIST]); nla_ok(nla, len);
560*4dc78e53SAndroid Build Coastguard Worker 	     nla = nla_next(nla, &len)) {
561*4dc78e53SAndroid Build Coastguard Worker 		err = nla_parse(t, IFLA_VF_MAX, nla_data(nla), nla_len(nla),
562*4dc78e53SAndroid Build Coastguard Worker 				sriov_info_policy);
563*4dc78e53SAndroid Build Coastguard Worker 		if (err < 0)
564*4dc78e53SAndroid Build Coastguard Worker 			return err;
565*4dc78e53SAndroid Build Coastguard Worker 
566*4dc78e53SAndroid Build Coastguard Worker 		vf_data = rtnl_link_vf_alloc();
567*4dc78e53SAndroid Build Coastguard Worker 		if (!vf_data)
568*4dc78e53SAndroid Build Coastguard Worker 			return -NLE_NOMEM;
569*4dc78e53SAndroid Build Coastguard Worker 
570*4dc78e53SAndroid Build Coastguard Worker 		if (t[IFLA_VF_MAC]) {
571*4dc78e53SAndroid Build Coastguard Worker 			vf_lladdr = nla_data(t[IFLA_VF_MAC]);
572*4dc78e53SAndroid Build Coastguard Worker 
573*4dc78e53SAndroid Build Coastguard Worker 			vf_data->vf_index = vf_lladdr->vf;
574*4dc78e53SAndroid Build Coastguard Worker 			vf_data->ce_mask |= SRIOV_ATTR_INDEX;
575*4dc78e53SAndroid Build Coastguard Worker 
576*4dc78e53SAndroid Build Coastguard Worker 			vf_data->vf_lladdr = nl_addr_build(AF_LLC,
577*4dc78e53SAndroid Build Coastguard Worker 							   vf_lladdr->mac, 6);
578*4dc78e53SAndroid Build Coastguard Worker 			if (vf_data->vf_lladdr == NULL) {
579*4dc78e53SAndroid Build Coastguard Worker 				rtnl_link_vf_put(vf_data);
580*4dc78e53SAndroid Build Coastguard Worker 				return -NLE_NOMEM;
581*4dc78e53SAndroid Build Coastguard Worker 			}
582*4dc78e53SAndroid Build Coastguard Worker 			nl_addr_set_family(vf_data->vf_lladdr, AF_LLC);
583*4dc78e53SAndroid Build Coastguard Worker 			vf_data->ce_mask |= SRIOV_ATTR_ADDR;
584*4dc78e53SAndroid Build Coastguard Worker 		}
585*4dc78e53SAndroid Build Coastguard Worker 
586*4dc78e53SAndroid Build Coastguard Worker 		if (t[IFLA_VF_VLAN_LIST]) {
587*4dc78e53SAndroid Build Coastguard Worker 			list_len = 0;
588*4dc78e53SAndroid Build Coastguard Worker 			nla_for_each_nested(nla_list, t[IFLA_VF_VLAN_LIST],
589*4dc78e53SAndroid Build Coastguard Worker 					    list_rem) {
590*4dc78e53SAndroid Build Coastguard Worker 				if (list_len >= MAX_VLAN_LIST_LEN)
591*4dc78e53SAndroid Build Coastguard Worker 					break;
592*4dc78e53SAndroid Build Coastguard Worker 				vf_vlan_info[list_len] = nla_data(nla_list);
593*4dc78e53SAndroid Build Coastguard Worker 				list_len++;
594*4dc78e53SAndroid Build Coastguard Worker 			}
595*4dc78e53SAndroid Build Coastguard Worker 
596*4dc78e53SAndroid Build Coastguard Worker 			err = rtnl_link_vf_vlan_info(list_len, vf_vlan_info,
597*4dc78e53SAndroid Build Coastguard Worker 						     &vf_vlans);
598*4dc78e53SAndroid Build Coastguard Worker 			if (err < 0) {
599*4dc78e53SAndroid Build Coastguard Worker 				rtnl_link_vf_put(vf_data);
600*4dc78e53SAndroid Build Coastguard Worker 				return err;
601*4dc78e53SAndroid Build Coastguard Worker 			}
602*4dc78e53SAndroid Build Coastguard Worker 
603*4dc78e53SAndroid Build Coastguard Worker 			vf_data->vf_vlans = vf_vlans;
604*4dc78e53SAndroid Build Coastguard Worker 			vf_data->ce_mask |= SRIOV_ATTR_VLAN;
605*4dc78e53SAndroid Build Coastguard Worker 		} else if (t[IFLA_VF_VLAN]) {
606*4dc78e53SAndroid Build Coastguard Worker 			vf_vlan = nla_data(t[IFLA_VF_VLAN]);
607*4dc78e53SAndroid Build Coastguard Worker 
608*4dc78e53SAndroid Build Coastguard Worker 			if (vf_vlan->vlan) {
609*4dc78e53SAndroid Build Coastguard Worker 				err = rtnl_link_vf_vlan_alloc(&vf_vlans, 1);
610*4dc78e53SAndroid Build Coastguard Worker 				if (err < 0) {
611*4dc78e53SAndroid Build Coastguard Worker 					rtnl_link_vf_put(vf_data);
612*4dc78e53SAndroid Build Coastguard Worker 					return err;
613*4dc78e53SAndroid Build Coastguard Worker 				}
614*4dc78e53SAndroid Build Coastguard Worker 
615*4dc78e53SAndroid Build Coastguard Worker 				vf_vlans->vlans[0].vf_vlan = vf_vlan->vlan;
616*4dc78e53SAndroid Build Coastguard Worker 				vf_vlans->vlans[0].vf_vlan_qos = vf_vlan->qos;
617*4dc78e53SAndroid Build Coastguard Worker 				vf_vlans->vlans[0].vf_vlan_proto = ETH_P_8021Q;
618*4dc78e53SAndroid Build Coastguard Worker 
619*4dc78e53SAndroid Build Coastguard Worker 				vf_data->vf_vlans = vf_vlans;
620*4dc78e53SAndroid Build Coastguard Worker 				vf_data->ce_mask |= SRIOV_ATTR_VLAN;
621*4dc78e53SAndroid Build Coastguard Worker 			}
622*4dc78e53SAndroid Build Coastguard Worker 		}
623*4dc78e53SAndroid Build Coastguard Worker 
624*4dc78e53SAndroid Build Coastguard Worker 		if (t[IFLA_VF_TX_RATE]) {
625*4dc78e53SAndroid Build Coastguard Worker 			vf_tx_rate = nla_data(t[IFLA_VF_TX_RATE]);
626*4dc78e53SAndroid Build Coastguard Worker 
627*4dc78e53SAndroid Build Coastguard Worker 			if (vf_tx_rate->rate) {
628*4dc78e53SAndroid Build Coastguard Worker 				vf_data->vf_rate = vf_tx_rate->rate;
629*4dc78e53SAndroid Build Coastguard Worker 				vf_data->ce_mask |= SRIOV_ATTR_TX_RATE;
630*4dc78e53SAndroid Build Coastguard Worker 			}
631*4dc78e53SAndroid Build Coastguard Worker 		}
632*4dc78e53SAndroid Build Coastguard Worker 
633*4dc78e53SAndroid Build Coastguard Worker 		if (t[IFLA_VF_SPOOFCHK]) {
634*4dc78e53SAndroid Build Coastguard Worker 			vf_spoofchk = nla_data(t[IFLA_VF_SPOOFCHK]);
635*4dc78e53SAndroid Build Coastguard Worker 
636*4dc78e53SAndroid Build Coastguard Worker 			if (vf_spoofchk->setting != ((uint32_t)-1)) {
637*4dc78e53SAndroid Build Coastguard Worker 				vf_data->vf_spoofchk = vf_spoofchk->setting ? 1 : 0;
638*4dc78e53SAndroid Build Coastguard Worker 				vf_data->ce_mask |= SRIOV_ATTR_SPOOFCHK;
639*4dc78e53SAndroid Build Coastguard Worker 			}
640*4dc78e53SAndroid Build Coastguard Worker 		}
641*4dc78e53SAndroid Build Coastguard Worker 
642*4dc78e53SAndroid Build Coastguard Worker 		if (t[IFLA_VF_LINK_STATE]) {
643*4dc78e53SAndroid Build Coastguard Worker 			vf_linkstate = nla_data(t[IFLA_VF_LINK_STATE]);
644*4dc78e53SAndroid Build Coastguard Worker 
645*4dc78e53SAndroid Build Coastguard Worker 			vf_data->vf_linkstate = vf_linkstate->link_state;
646*4dc78e53SAndroid Build Coastguard Worker 			vf_data->ce_mask |= SRIOV_ATTR_LINK_STATE;
647*4dc78e53SAndroid Build Coastguard Worker 		}
648*4dc78e53SAndroid Build Coastguard Worker 
649*4dc78e53SAndroid Build Coastguard Worker 		if (t[IFLA_VF_RATE]) {
650*4dc78e53SAndroid Build Coastguard Worker 			vf_rate = nla_data(t[IFLA_VF_RATE]);
651*4dc78e53SAndroid Build Coastguard Worker 
652*4dc78e53SAndroid Build Coastguard Worker 			if (vf_rate->max_tx_rate) {
653*4dc78e53SAndroid Build Coastguard Worker 				vf_data->vf_max_tx_rate = vf_rate->max_tx_rate;
654*4dc78e53SAndroid Build Coastguard Worker 				vf_data->ce_mask |= SRIOV_ATTR_RATE_MAX;
655*4dc78e53SAndroid Build Coastguard Worker 			}
656*4dc78e53SAndroid Build Coastguard Worker 			if (vf_rate->min_tx_rate) {
657*4dc78e53SAndroid Build Coastguard Worker 				vf_data->vf_min_tx_rate = vf_rate->min_tx_rate;
658*4dc78e53SAndroid Build Coastguard Worker 				vf_data->ce_mask |= SRIOV_ATTR_RATE_MIN;
659*4dc78e53SAndroid Build Coastguard Worker 			}
660*4dc78e53SAndroid Build Coastguard Worker 		}
661*4dc78e53SAndroid Build Coastguard Worker 
662*4dc78e53SAndroid Build Coastguard Worker 		if (t[IFLA_VF_RSS_QUERY_EN]) {
663*4dc78e53SAndroid Build Coastguard Worker 			vf_rss_query = nla_data(t[IFLA_VF_RSS_QUERY_EN]);
664*4dc78e53SAndroid Build Coastguard Worker 
665*4dc78e53SAndroid Build Coastguard Worker 			if (vf_rss_query->setting != ((uint32_t)-1)) {
666*4dc78e53SAndroid Build Coastguard Worker 				vf_data->vf_rss_query_en = vf_rss_query->setting ? 1 : 0;
667*4dc78e53SAndroid Build Coastguard Worker 				vf_data->ce_mask |= SRIOV_ATTR_RSS_QUERY_EN;
668*4dc78e53SAndroid Build Coastguard Worker 			}
669*4dc78e53SAndroid Build Coastguard Worker 		}
670*4dc78e53SAndroid Build Coastguard Worker 
671*4dc78e53SAndroid Build Coastguard Worker 		if (t[IFLA_VF_STATS]) {
672*4dc78e53SAndroid Build Coastguard Worker 			err = nla_parse_nested(stb, RTNL_LINK_VF_STATS_MAX,
673*4dc78e53SAndroid Build Coastguard Worker 					       t[IFLA_VF_STATS],
674*4dc78e53SAndroid Build Coastguard Worker 					       sriov_stats_policy);
675*4dc78e53SAndroid Build Coastguard Worker 			if (err < 0) {
676*4dc78e53SAndroid Build Coastguard Worker 				rtnl_link_vf_put(vf_data);
677*4dc78e53SAndroid Build Coastguard Worker 				return err;
678*4dc78e53SAndroid Build Coastguard Worker 			}
679*4dc78e53SAndroid Build Coastguard Worker 
680*4dc78e53SAndroid Build Coastguard Worker 			SET_VF_STAT(link, cur, stb,
681*4dc78e53SAndroid Build Coastguard Worker 				    RTNL_LINK_VF_STATS_RX_PACKETS,
682*4dc78e53SAndroid Build Coastguard Worker 				    IFLA_VF_STATS_RX_PACKETS);
683*4dc78e53SAndroid Build Coastguard Worker 			SET_VF_STAT(link, cur, stb,
684*4dc78e53SAndroid Build Coastguard Worker 				    RTNL_LINK_VF_STATS_TX_PACKETS,
685*4dc78e53SAndroid Build Coastguard Worker 				    IFLA_VF_STATS_TX_PACKETS);
686*4dc78e53SAndroid Build Coastguard Worker 			SET_VF_STAT(link, cur, stb,
687*4dc78e53SAndroid Build Coastguard Worker 				    RTNL_LINK_VF_STATS_RX_BYTES,
688*4dc78e53SAndroid Build Coastguard Worker 				    IFLA_VF_STATS_RX_BYTES);
689*4dc78e53SAndroid Build Coastguard Worker 			SET_VF_STAT(link, cur, stb,
690*4dc78e53SAndroid Build Coastguard Worker 				    RTNL_LINK_VF_STATS_TX_BYTES,
691*4dc78e53SAndroid Build Coastguard Worker 				    IFLA_VF_STATS_TX_BYTES);
692*4dc78e53SAndroid Build Coastguard Worker 			SET_VF_STAT(link, cur, stb,
693*4dc78e53SAndroid Build Coastguard Worker 				    RTNL_LINK_VF_STATS_BROADCAST,
694*4dc78e53SAndroid Build Coastguard Worker 				    IFLA_VF_STATS_BROADCAST);
695*4dc78e53SAndroid Build Coastguard Worker 			SET_VF_STAT(link, cur, stb,
696*4dc78e53SAndroid Build Coastguard Worker 				    RTNL_LINK_VF_STATS_MULTICAST,
697*4dc78e53SAndroid Build Coastguard Worker 				    IFLA_VF_STATS_MULTICAST);
698*4dc78e53SAndroid Build Coastguard Worker 
699*4dc78e53SAndroid Build Coastguard Worker 			vf_data->ce_mask |= SRIOV_ATTR_STATS;
700*4dc78e53SAndroid Build Coastguard Worker 		}
701*4dc78e53SAndroid Build Coastguard Worker 
702*4dc78e53SAndroid Build Coastguard Worker 		if (t[IFLA_VF_TRUST]) {
703*4dc78e53SAndroid Build Coastguard Worker 			vf_trust = nla_data(t[IFLA_VF_TRUST]);
704*4dc78e53SAndroid Build Coastguard Worker 
705*4dc78e53SAndroid Build Coastguard Worker 			if (vf_trust->setting != ((uint32_t)-1)) {
706*4dc78e53SAndroid Build Coastguard Worker 				vf_data->vf_trust = vf_trust->setting ? 1 : 0;
707*4dc78e53SAndroid Build Coastguard Worker 				vf_data->ce_mask |= SRIOV_ATTR_TRUST;
708*4dc78e53SAndroid Build Coastguard Worker 			}
709*4dc78e53SAndroid Build Coastguard Worker 		}
710*4dc78e53SAndroid Build Coastguard Worker 
711*4dc78e53SAndroid Build Coastguard Worker 		nl_list_add_head(&vf_data->vf_list, &vf_head->vf_list);
712*4dc78e53SAndroid Build Coastguard Worker 		vf_head = vf_data;
713*4dc78e53SAndroid Build Coastguard Worker 	}
714*4dc78e53SAndroid Build Coastguard Worker 
715*4dc78e53SAndroid Build Coastguard Worker 	return 0;
716*4dc78e53SAndroid Build Coastguard Worker }
717*4dc78e53SAndroid Build Coastguard Worker 
718*4dc78e53SAndroid Build Coastguard Worker /**
719*4dc78e53SAndroid Build Coastguard Worker  * @name SR-IOV Sub-Object
720*4dc78e53SAndroid Build Coastguard Worker  * @{
721*4dc78e53SAndroid Build Coastguard Worker  */
722*4dc78e53SAndroid Build Coastguard Worker 
723*4dc78e53SAndroid Build Coastguard Worker /**
724*4dc78e53SAndroid Build Coastguard Worker  * Add a SRIOV VF object to a link object
725*4dc78e53SAndroid Build Coastguard Worker  * @param link  	Link object to add to
726*4dc78e53SAndroid Build Coastguard Worker  * @param vf_data 	SRIOV VF object to add
727*4dc78e53SAndroid Build Coastguard Worker  *
728*4dc78e53SAndroid Build Coastguard Worker  * @return 0 if SRIOV VF object added successfully
729*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_OBJ_NOTFOUND if \p link or \p vf_data not provided
730*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_NOMEM if out of memory
731*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_add(struct rtnl_link * link,struct rtnl_link_vf * vf_data)732*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_add(struct rtnl_link *link, struct rtnl_link_vf *vf_data) {
733*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link_vf *vf_head = NULL;
734*4dc78e53SAndroid Build Coastguard Worker 
735*4dc78e53SAndroid Build Coastguard Worker 	if (!link||!vf_data)
736*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_OBJ_NOTFOUND;
737*4dc78e53SAndroid Build Coastguard Worker 
738*4dc78e53SAndroid Build Coastguard Worker 	if (!link->l_vf_list) {
739*4dc78e53SAndroid Build Coastguard Worker 		link->l_vf_list = rtnl_link_vf_alloc();
740*4dc78e53SAndroid Build Coastguard Worker 		if (!link->l_vf_list)
741*4dc78e53SAndroid Build Coastguard Worker 			return -NLE_NOMEM;
742*4dc78e53SAndroid Build Coastguard Worker 	}
743*4dc78e53SAndroid Build Coastguard Worker 
744*4dc78e53SAndroid Build Coastguard Worker 	vf_head = vf_data;
745*4dc78e53SAndroid Build Coastguard Worker 	vf_head->ce_refcnt++;
746*4dc78e53SAndroid Build Coastguard Worker 
747*4dc78e53SAndroid Build Coastguard Worker 	vf_head = link->l_vf_list;
748*4dc78e53SAndroid Build Coastguard Worker 	nl_list_add_head(&vf_data->vf_list, &vf_head->vf_list);
749*4dc78e53SAndroid Build Coastguard Worker 	link->l_vf_list = vf_head;
750*4dc78e53SAndroid Build Coastguard Worker 
751*4dc78e53SAndroid Build Coastguard Worker 	rtnl_link_set_vf_list(link);
752*4dc78e53SAndroid Build Coastguard Worker 
753*4dc78e53SAndroid Build Coastguard Worker 	return 0;
754*4dc78e53SAndroid Build Coastguard Worker }
755*4dc78e53SAndroid Build Coastguard Worker 
756*4dc78e53SAndroid Build Coastguard Worker /**
757*4dc78e53SAndroid Build Coastguard Worker  * Allocate a new SRIOV VF object
758*4dc78e53SAndroid Build Coastguard Worker  *
759*4dc78e53SAndroid Build Coastguard Worker  * @return NULL if out of memory
760*4dc78e53SAndroid Build Coastguard Worker  * @return New VF Object
761*4dc78e53SAndroid Build Coastguard Worker  *
762*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_put()
763*4dc78e53SAndroid Build Coastguard Worker  *
764*4dc78e53SAndroid Build Coastguard Worker  * The SRIOV VF object must be returned to the link object with
765*4dc78e53SAndroid Build Coastguard Worker  * rtnl_link_vf_put() when operations are done to prevent memory leaks.
766*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_alloc(void)767*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *rtnl_link_vf_alloc(void) {
768*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link_vf *vf;
769*4dc78e53SAndroid Build Coastguard Worker 
770*4dc78e53SAndroid Build Coastguard Worker 	if (!(vf = calloc(1, sizeof(*vf))))
771*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
772*4dc78e53SAndroid Build Coastguard Worker 
773*4dc78e53SAndroid Build Coastguard Worker 	NL_INIT_LIST_HEAD(&vf->vf_list);
774*4dc78e53SAndroid Build Coastguard Worker 	vf->ce_refcnt = 1;
775*4dc78e53SAndroid Build Coastguard Worker 
776*4dc78e53SAndroid Build Coastguard Worker 	NL_DBG(4, "Allocated new SRIOV VF object %p\n", vf);
777*4dc78e53SAndroid Build Coastguard Worker 
778*4dc78e53SAndroid Build Coastguard Worker 	return vf;
779*4dc78e53SAndroid Build Coastguard Worker }
780*4dc78e53SAndroid Build Coastguard Worker 
781*4dc78e53SAndroid Build Coastguard Worker /**
782*4dc78e53SAndroid Build Coastguard Worker  * Free SRIOV VF object.
783*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_data 	SRIOV VF data object
784*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_free(struct rtnl_link_vf * vf_data)785*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_free(struct rtnl_link_vf *vf_data) {
786*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_data)
787*4dc78e53SAndroid Build Coastguard Worker 		return;
788*4dc78e53SAndroid Build Coastguard Worker 
789*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_refcnt > 0)
790*4dc78e53SAndroid Build Coastguard Worker 		NL_DBG(1, "Warning: Freeing SRIOV VF object in use...\n");
791*4dc78e53SAndroid Build Coastguard Worker 
792*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_ADDR)
793*4dc78e53SAndroid Build Coastguard Worker 		nl_addr_put(vf_data->vf_lladdr);
794*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_VLAN)
795*4dc78e53SAndroid Build Coastguard Worker 		rtnl_link_vf_vlan_put(vf_data->vf_vlans);
796*4dc78e53SAndroid Build Coastguard Worker 
797*4dc78e53SAndroid Build Coastguard Worker 	NL_DBG(4, "Freed SRIOV VF object %p\n", vf_data);
798*4dc78e53SAndroid Build Coastguard Worker 	free(vf_data);
799*4dc78e53SAndroid Build Coastguard Worker 
800*4dc78e53SAndroid Build Coastguard Worker 	return;
801*4dc78e53SAndroid Build Coastguard Worker }
802*4dc78e53SAndroid Build Coastguard Worker 
803*4dc78e53SAndroid Build Coastguard Worker /**
804*4dc78e53SAndroid Build Coastguard Worker  * Lookup SRIOV VF in link object by VF index.
805*4dc78e53SAndroid Build Coastguard Worker  *
806*4dc78e53SAndroid Build Coastguard Worker  * @return NULL if VF not found
807*4dc78e53SAndroid Build Coastguard Worker  * @return VF Object
808*4dc78e53SAndroid Build Coastguard Worker  *
809*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_put()
810*4dc78e53SAndroid Build Coastguard Worker  *
811*4dc78e53SAndroid Build Coastguard Worker  * The SRIOV VF object must be returned to the link object with
812*4dc78e53SAndroid Build Coastguard Worker  * rtnl_link_vf_put() when operations are done to prevent memory leaks.
813*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_get(struct rtnl_link * link,uint32_t vf_num)814*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *rtnl_link_vf_get(struct rtnl_link *link, uint32_t vf_num) {
815*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link_vf *list, *vf, *next, *ret = NULL;
816*4dc78e53SAndroid Build Coastguard Worker 
817*4dc78e53SAndroid Build Coastguard Worker 	list = link->l_vf_list;
818*4dc78e53SAndroid Build Coastguard Worker 	nl_list_for_each_entry_safe(vf, next, &list->vf_list, vf_list) {
819*4dc78e53SAndroid Build Coastguard Worker 		if (vf->vf_index == vf_num) {
820*4dc78e53SAndroid Build Coastguard Worker 			ret = vf;
821*4dc78e53SAndroid Build Coastguard Worker 			break;
822*4dc78e53SAndroid Build Coastguard Worker 		}
823*4dc78e53SAndroid Build Coastguard Worker 	}
824*4dc78e53SAndroid Build Coastguard Worker 
825*4dc78e53SAndroid Build Coastguard Worker 	if (ret) {
826*4dc78e53SAndroid Build Coastguard Worker 		ret->ce_refcnt++;
827*4dc78e53SAndroid Build Coastguard Worker 		NL_DBG(4, "New reference to SRIOV VF object %p, total %i\n",
828*4dc78e53SAndroid Build Coastguard Worker 		       ret, ret->ce_refcnt);
829*4dc78e53SAndroid Build Coastguard Worker 	}
830*4dc78e53SAndroid Build Coastguard Worker 
831*4dc78e53SAndroid Build Coastguard Worker 	return ret;
832*4dc78e53SAndroid Build Coastguard Worker }
833*4dc78e53SAndroid Build Coastguard Worker 
834*4dc78e53SAndroid Build Coastguard Worker /**
835*4dc78e53SAndroid Build Coastguard Worker  * Return SRIOV VF object to the owning link object.
836*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_data 	SRIOV VF data object
837*4dc78e53SAndroid Build Coastguard Worker  *
838*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_alloc()
839*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_get()
840*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_put(struct rtnl_link_vf * vf_data)841*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_put(struct rtnl_link_vf *vf_data) {
842*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_data)
843*4dc78e53SAndroid Build Coastguard Worker 		return;
844*4dc78e53SAndroid Build Coastguard Worker 
845*4dc78e53SAndroid Build Coastguard Worker 	vf_data->ce_refcnt--;
846*4dc78e53SAndroid Build Coastguard Worker 	NL_DBG(4, "Returned SRIOV VF object reference %p, %i remaining\n",
847*4dc78e53SAndroid Build Coastguard Worker 	       vf_data, vf_data->ce_refcnt);
848*4dc78e53SAndroid Build Coastguard Worker 
849*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_refcnt < 0)
850*4dc78e53SAndroid Build Coastguard Worker 		BUG();
851*4dc78e53SAndroid Build Coastguard Worker 
852*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_refcnt <= 0)
853*4dc78e53SAndroid Build Coastguard Worker 		rtnl_link_vf_free(vf_data);
854*4dc78e53SAndroid Build Coastguard Worker 
855*4dc78e53SAndroid Build Coastguard Worker 	return;
856*4dc78e53SAndroid Build Coastguard Worker }
857*4dc78e53SAndroid Build Coastguard Worker 
858*4dc78e53SAndroid Build Coastguard Worker /**
859*4dc78e53SAndroid Build Coastguard Worker  * Get link layer address of SRIOV Virtual Function
860*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_data 	SRIOV VF object
861*4dc78e53SAndroid Build Coastguard Worker  * @arg addr 		Pointer to store Link Layer address
862*4dc78e53SAndroid Build Coastguard Worker  *
863*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_get_num_vf()
864*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_set_addr()
865*4dc78e53SAndroid Build Coastguard Worker  *
866*4dc78e53SAndroid Build Coastguard Worker  * @copydoc pointer_lifetime_warning
867*4dc78e53SAndroid Build Coastguard Worker  * @return 0 if addr is present and addr is set to pointer containing address
868*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
869*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_NOATTR if the link layer address is not set
870*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_get_addr(struct rtnl_link_vf * vf_data,struct nl_addr ** addr)871*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_addr(struct rtnl_link_vf *vf_data, struct nl_addr **addr)
872*4dc78e53SAndroid Build Coastguard Worker {
873*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_data)
874*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_OBJ_NOTFOUND;
875*4dc78e53SAndroid Build Coastguard Worker 
876*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_ADDR)
877*4dc78e53SAndroid Build Coastguard Worker 		*addr = vf_data->vf_lladdr;
878*4dc78e53SAndroid Build Coastguard Worker 	else
879*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOATTR;
880*4dc78e53SAndroid Build Coastguard Worker 
881*4dc78e53SAndroid Build Coastguard Worker 	return 0;
882*4dc78e53SAndroid Build Coastguard Worker }
883*4dc78e53SAndroid Build Coastguard Worker 
884*4dc78e53SAndroid Build Coastguard Worker /**
885*4dc78e53SAndroid Build Coastguard Worker  * Set link layer address of SRIOV Virtual Function object
886*4dc78e53SAndroid Build Coastguard Worker  * @param vf_data 	SRIOV VF object
887*4dc78e53SAndroid Build Coastguard Worker  * @param addr 		New link layer address
888*4dc78e53SAndroid Build Coastguard Worker  *
889*4dc78e53SAndroid Build Coastguard Worker  * This function increments the reference counter of the address object
890*4dc78e53SAndroid Build Coastguard Worker  * and overwrites any existing link layer address previously assigned.
891*4dc78e53SAndroid Build Coastguard Worker  *
892*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_get_addr()
893*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_set_addr(struct rtnl_link_vf * vf_data,struct nl_addr * addr)894*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_addr(struct rtnl_link_vf *vf_data, struct nl_addr *addr) {
895*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->vf_lladdr)
896*4dc78e53SAndroid Build Coastguard Worker 		nl_addr_put(vf_data->vf_lladdr);
897*4dc78e53SAndroid Build Coastguard Worker 
898*4dc78e53SAndroid Build Coastguard Worker 	nl_addr_get(addr);
899*4dc78e53SAndroid Build Coastguard Worker 	vf_data->vf_lladdr = addr;
900*4dc78e53SAndroid Build Coastguard Worker 	vf_data->ce_mask |= SRIOV_ATTR_ADDR;
901*4dc78e53SAndroid Build Coastguard Worker 
902*4dc78e53SAndroid Build Coastguard Worker 	return;
903*4dc78e53SAndroid Build Coastguard Worker }
904*4dc78e53SAndroid Build Coastguard Worker 
905*4dc78e53SAndroid Build Coastguard Worker /**
906*4dc78e53SAndroid Build Coastguard Worker  * Set the Infiniband node GUID for the SRIOV Virtual Function object
907*4dc78e53SAndroid Build Coastguard Worker  * @param vf_data 	SRIOV VF object
908*4dc78e53SAndroid Build Coastguard Worker  * @param guid  	node GUID
909*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_set_ib_node_guid(struct rtnl_link_vf * vf_data,uint64_t guid)910*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_ib_node_guid(struct rtnl_link_vf *vf_data,
911*4dc78e53SAndroid Build Coastguard Worker 				   uint64_t guid) {
912*4dc78e53SAndroid Build Coastguard Worker 	vf_data->vf_guid_node = guid;
913*4dc78e53SAndroid Build Coastguard Worker 	vf_data->ce_mask |= SRIOV_ATTR_IB_NODE_GUID;
914*4dc78e53SAndroid Build Coastguard Worker 
915*4dc78e53SAndroid Build Coastguard Worker 	return;
916*4dc78e53SAndroid Build Coastguard Worker }
917*4dc78e53SAndroid Build Coastguard Worker 
918*4dc78e53SAndroid Build Coastguard Worker /**
919*4dc78e53SAndroid Build Coastguard Worker  * Set the Infiniband port GUID for the SRIOV Virtual Function object
920*4dc78e53SAndroid Build Coastguard Worker  * @param vf_data 	SRIOV VF object
921*4dc78e53SAndroid Build Coastguard Worker  * @param guid  	port GUID
922*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_set_ib_port_guid(struct rtnl_link_vf * vf_data,uint64_t guid)923*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_ib_port_guid(struct rtnl_link_vf *vf_data,
924*4dc78e53SAndroid Build Coastguard Worker 				   uint64_t guid) {
925*4dc78e53SAndroid Build Coastguard Worker 	vf_data->vf_guid_port = guid;
926*4dc78e53SAndroid Build Coastguard Worker 	vf_data->ce_mask |= SRIOV_ATTR_IB_PORT_GUID;
927*4dc78e53SAndroid Build Coastguard Worker 
928*4dc78e53SAndroid Build Coastguard Worker 	return;
929*4dc78e53SAndroid Build Coastguard Worker }
930*4dc78e53SAndroid Build Coastguard Worker 
931*4dc78e53SAndroid Build Coastguard Worker /**
932*4dc78e53SAndroid Build Coastguard Worker  * Get index of SRIOV Virtual Function
933*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_data 	SRIOV VF object
934*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_index 	Pointer to store VF index
935*4dc78e53SAndroid Build Coastguard Worker  *
936*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_get_num_vf()
937*4dc78e53SAndroid Build Coastguard Worker  *
938*4dc78e53SAndroid Build Coastguard Worker  * @return 0 if index is present and vf_index is set
939*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
940*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_NOATTR if the VF index is not set
941*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_get_index(struct rtnl_link_vf * vf_data,uint32_t * vf_index)942*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_index(struct rtnl_link_vf *vf_data, uint32_t *vf_index)
943*4dc78e53SAndroid Build Coastguard Worker {
944*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_data)
945*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_OBJ_NOTFOUND;
946*4dc78e53SAndroid Build Coastguard Worker 
947*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_INDEX)
948*4dc78e53SAndroid Build Coastguard Worker 		*vf_index = vf_data->vf_index;
949*4dc78e53SAndroid Build Coastguard Worker 	else
950*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOATTR;
951*4dc78e53SAndroid Build Coastguard Worker 
952*4dc78e53SAndroid Build Coastguard Worker 	return 0;
953*4dc78e53SAndroid Build Coastguard Worker }
954*4dc78e53SAndroid Build Coastguard Worker 
955*4dc78e53SAndroid Build Coastguard Worker /**
956*4dc78e53SAndroid Build Coastguard Worker  * Set index of SRIOV Virtual Function object
957*4dc78e53SAndroid Build Coastguard Worker  * @param vf_data 	SRIOV VF object
958*4dc78e53SAndroid Build Coastguard Worker  * @param vf_index 	Index value
959*4dc78e53SAndroid Build Coastguard Worker  *
960*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_get_index()
961*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_set_index(struct rtnl_link_vf * vf_data,uint32_t vf_index)962*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_index(struct rtnl_link_vf *vf_data, uint32_t vf_index)
963*4dc78e53SAndroid Build Coastguard Worker {
964*4dc78e53SAndroid Build Coastguard Worker 	vf_data->vf_index = vf_index;
965*4dc78e53SAndroid Build Coastguard Worker 	vf_data->ce_mask |= SRIOV_ATTR_INDEX;
966*4dc78e53SAndroid Build Coastguard Worker 
967*4dc78e53SAndroid Build Coastguard Worker 	return;
968*4dc78e53SAndroid Build Coastguard Worker }
969*4dc78e53SAndroid Build Coastguard Worker 
970*4dc78e53SAndroid Build Coastguard Worker /**
971*4dc78e53SAndroid Build Coastguard Worker  * Get link state of SRIOV Virtual Function
972*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_data  	SRIOV VF object
973*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_linkstate 	Pointer to store VF link state
974*4dc78e53SAndroid Build Coastguard Worker  *
975*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_get_num_vf()
976*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_set_linkstate()
977*4dc78e53SAndroid Build Coastguard Worker  *
978*4dc78e53SAndroid Build Coastguard Worker  * @return 0 if link state is present and vf_linkstate is set
979*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
980*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_NOATTR if the VF link state is not set
981*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_get_linkstate(struct rtnl_link_vf * vf_data,uint32_t * vf_linkstate)982*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_linkstate(struct rtnl_link_vf *vf_data,
983*4dc78e53SAndroid Build Coastguard Worker 			       uint32_t *vf_linkstate)
984*4dc78e53SAndroid Build Coastguard Worker {
985*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_data)
986*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_OBJ_NOTFOUND;
987*4dc78e53SAndroid Build Coastguard Worker 
988*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE)
989*4dc78e53SAndroid Build Coastguard Worker 		*vf_linkstate = vf_data->vf_linkstate;
990*4dc78e53SAndroid Build Coastguard Worker 	else
991*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOATTR;
992*4dc78e53SAndroid Build Coastguard Worker 
993*4dc78e53SAndroid Build Coastguard Worker 	return 0;
994*4dc78e53SAndroid Build Coastguard Worker }
995*4dc78e53SAndroid Build Coastguard Worker 
996*4dc78e53SAndroid Build Coastguard Worker /**
997*4dc78e53SAndroid Build Coastguard Worker  * Set link state of SRIOV Virtual Function object
998*4dc78e53SAndroid Build Coastguard Worker  * @param vf_data 	SRIOV VF object
999*4dc78e53SAndroid Build Coastguard Worker  * @param vf_linkstate Link state value
1000*4dc78e53SAndroid Build Coastguard Worker  *
1001*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_get_linkstate()
1002*4dc78e53SAndroid Build Coastguard Worker  *
1003*4dc78e53SAndroid Build Coastguard Worker  * Not all hardware supports setting link state. If the feature is unsupported,
1004*4dc78e53SAndroid Build Coastguard Worker  * the link change request will fail with -NLE_OPNOTSUPP
1005*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_set_linkstate(struct rtnl_link_vf * vf_data,uint32_t vf_linkstate)1006*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_linkstate(struct rtnl_link_vf *vf_data,
1007*4dc78e53SAndroid Build Coastguard Worker 				uint32_t vf_linkstate) {
1008*4dc78e53SAndroid Build Coastguard Worker 	vf_data->vf_linkstate = vf_linkstate;
1009*4dc78e53SAndroid Build Coastguard Worker 	vf_data->ce_mask |= SRIOV_ATTR_LINK_STATE;
1010*4dc78e53SAndroid Build Coastguard Worker 
1011*4dc78e53SAndroid Build Coastguard Worker 	return;
1012*4dc78e53SAndroid Build Coastguard Worker }
1013*4dc78e53SAndroid Build Coastguard Worker 
1014*4dc78e53SAndroid Build Coastguard Worker /**
1015*4dc78e53SAndroid Build Coastguard Worker  * Get TX Rate Limit of SRIOV Virtual Function
1016*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_data 	SRIOV VF object
1017*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_rate 	Pointer to store VF rate limiting data
1018*4dc78e53SAndroid Build Coastguard Worker  *
1019*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_get_num_vf()
1020*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_set_rate()
1021*4dc78e53SAndroid Build Coastguard Worker  *
1022*4dc78e53SAndroid Build Coastguard Worker  * When the older rate API has been implemented, the rate member of the struct
1023*4dc78e53SAndroid Build Coastguard Worker  * will be set, and the api member will be set to RTNL_LINK_VF_API_OLD.
1024*4dc78e53SAndroid Build Coastguard Worker  * When the newer rate API has been implemented, the max_tx_rate
1025*4dc78e53SAndroid Build Coastguard Worker  * and/or the minx_tx_rate will be set, and the api member will be set to
1026*4dc78e53SAndroid Build Coastguard Worker  * RTNL_LINK_VF_API_NEW.
1027*4dc78e53SAndroid Build Coastguard Worker  *
1028*4dc78e53SAndroid Build Coastguard Worker  * Old rate API supports only a maximum TX rate.
1029*4dc78e53SAndroid Build Coastguard Worker  *   ip link set dev vf 0 rate
1030*4dc78e53SAndroid Build Coastguard Worker  * New rate API supports minumum and maximum TX rates.
1031*4dc78e53SAndroid Build Coastguard Worker  *   ip link set dev vf 0 min_tx_rate
1032*4dc78e53SAndroid Build Coastguard Worker  *   ip link set dev vf 0 max_tx_rate
1033*4dc78e53SAndroid Build Coastguard Worker  *
1034*4dc78e53SAndroid Build Coastguard Worker  * @return 0 if rate is present and vf_rate is set
1035*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1036*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_NOATTR if the VF rate is not set
1037*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_get_rate(struct rtnl_link_vf * vf_data,struct nl_vf_rate * vf_rate)1038*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_rate(struct rtnl_link_vf *vf_data,
1039*4dc78e53SAndroid Build Coastguard Worker 			  struct nl_vf_rate *vf_rate)
1040*4dc78e53SAndroid Build Coastguard Worker {
1041*4dc78e53SAndroid Build Coastguard Worker 	int set = 0;
1042*4dc78e53SAndroid Build Coastguard Worker 
1043*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_data)
1044*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_OBJ_NOTFOUND;
1045*4dc78e53SAndroid Build Coastguard Worker 
1046*4dc78e53SAndroid Build Coastguard Worker 	vf_rate->api = RTNL_LINK_VF_RATE_API_UNSPEC;
1047*4dc78e53SAndroid Build Coastguard Worker 	vf_rate->rate = 0;
1048*4dc78e53SAndroid Build Coastguard Worker 	vf_rate->max_tx_rate = 0;
1049*4dc78e53SAndroid Build Coastguard Worker 	vf_rate->min_tx_rate = 0;
1050*4dc78e53SAndroid Build Coastguard Worker 
1051*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_RATE_MAX) {
1052*4dc78e53SAndroid Build Coastguard Worker 		if (vf_data->vf_max_tx_rate) {
1053*4dc78e53SAndroid Build Coastguard Worker 			vf_rate->api = RTNL_LINK_VF_RATE_API_NEW;
1054*4dc78e53SAndroid Build Coastguard Worker 			vf_rate->max_tx_rate = vf_data->vf_max_tx_rate;
1055*4dc78e53SAndroid Build Coastguard Worker 			set = 1;
1056*4dc78e53SAndroid Build Coastguard Worker 		}
1057*4dc78e53SAndroid Build Coastguard Worker 	}
1058*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_RATE_MIN) {
1059*4dc78e53SAndroid Build Coastguard Worker 		if (vf_data->vf_min_tx_rate) {
1060*4dc78e53SAndroid Build Coastguard Worker 			vf_rate->api = RTNL_LINK_VF_RATE_API_NEW;
1061*4dc78e53SAndroid Build Coastguard Worker 			vf_rate->min_tx_rate = vf_data->vf_min_tx_rate;
1062*4dc78e53SAndroid Build Coastguard Worker 			set = 1;
1063*4dc78e53SAndroid Build Coastguard Worker 		}
1064*4dc78e53SAndroid Build Coastguard Worker 	}
1065*4dc78e53SAndroid Build Coastguard Worker 	if ((!set) && (vf_data->ce_mask & SRIOV_ATTR_TX_RATE)) {
1066*4dc78e53SAndroid Build Coastguard Worker 		if (vf_data->vf_rate) {
1067*4dc78e53SAndroid Build Coastguard Worker 			vf_rate->api = RTNL_LINK_VF_RATE_API_OLD;
1068*4dc78e53SAndroid Build Coastguard Worker 			vf_rate->rate = vf_data->vf_rate;
1069*4dc78e53SAndroid Build Coastguard Worker 			set = 1;
1070*4dc78e53SAndroid Build Coastguard Worker 		}
1071*4dc78e53SAndroid Build Coastguard Worker 	}
1072*4dc78e53SAndroid Build Coastguard Worker 
1073*4dc78e53SAndroid Build Coastguard Worker 	if (!set)
1074*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOATTR;
1075*4dc78e53SAndroid Build Coastguard Worker 
1076*4dc78e53SAndroid Build Coastguard Worker 	return 0;
1077*4dc78e53SAndroid Build Coastguard Worker }
1078*4dc78e53SAndroid Build Coastguard Worker 
1079*4dc78e53SAndroid Build Coastguard Worker /**
1080*4dc78e53SAndroid Build Coastguard Worker  * Set TX Rate Limit of SRIOV Virtual Function object
1081*4dc78e53SAndroid Build Coastguard Worker  * @param vf_data 	SRIOV VF object
1082*4dc78e53SAndroid Build Coastguard Worker  * @param vf_rate 	Rate limiting structure
1083*4dc78e53SAndroid Build Coastguard Worker  *
1084*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_get_rate()
1085*4dc78e53SAndroid Build Coastguard Worker  *
1086*4dc78e53SAndroid Build Coastguard Worker  * When setting the rate, the API level must be specificed.
1087*4dc78e53SAndroid Build Coastguard Worker  * Valid API levels:
1088*4dc78e53SAndroid Build Coastguard Worker  *   RTNL_LINK_VF_RATE_API_NEW
1089*4dc78e53SAndroid Build Coastguard Worker  *   RTNL_LINK_VF_RATE_API_OLD
1090*4dc78e53SAndroid Build Coastguard Worker  *
1091*4dc78e53SAndroid Build Coastguard Worker  * When using the new API, if either the min_tx_rate or
1092*4dc78e53SAndroid Build Coastguard Worker  * max_tx_rate has been set, and the other is being changed,
1093*4dc78e53SAndroid Build Coastguard Worker  * you must specify the currently set values to preserve
1094*4dc78e53SAndroid Build Coastguard Worker  * them. If this is not done, that setting will be disabled.
1095*4dc78e53SAndroid Build Coastguard Worker  *
1096*4dc78e53SAndroid Build Coastguard Worker  * Old rate API supports only a maximum TX rate.
1097*4dc78e53SAndroid Build Coastguard Worker  *   ip link set dev vf 0 rate
1098*4dc78e53SAndroid Build Coastguard Worker  * New rate API supports minumum and maximum TX rates.
1099*4dc78e53SAndroid Build Coastguard Worker  *   ip link set dev vf 0 min_tx_rate
1100*4dc78e53SAndroid Build Coastguard Worker  *   ip link set dev vf 0 max_tx_rate
1101*4dc78e53SAndroid Build Coastguard Worker  *
1102*4dc78e53SAndroid Build Coastguard Worker  * Not all hardware supports min_tx_rate.
1103*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_set_rate(struct rtnl_link_vf * vf_data,struct nl_vf_rate * vf_rate)1104*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_rate(struct rtnl_link_vf *vf_data,
1105*4dc78e53SAndroid Build Coastguard Worker 			   struct nl_vf_rate *vf_rate) {
1106*4dc78e53SAndroid Build Coastguard Worker 	if (vf_rate->api == RTNL_LINK_VF_RATE_API_OLD) {
1107*4dc78e53SAndroid Build Coastguard Worker 		vf_data->vf_rate = vf_rate->rate;
1108*4dc78e53SAndroid Build Coastguard Worker 		vf_data->ce_mask |= SRIOV_ATTR_TX_RATE;
1109*4dc78e53SAndroid Build Coastguard Worker 	} else if (vf_rate->api == RTNL_LINK_VF_RATE_API_NEW) {
1110*4dc78e53SAndroid Build Coastguard Worker 		vf_data->vf_max_tx_rate = vf_rate->max_tx_rate;
1111*4dc78e53SAndroid Build Coastguard Worker 		vf_data->ce_mask |= SRIOV_ATTR_RATE_MAX;
1112*4dc78e53SAndroid Build Coastguard Worker 
1113*4dc78e53SAndroid Build Coastguard Worker 		vf_data->vf_min_tx_rate = vf_rate->min_tx_rate;
1114*4dc78e53SAndroid Build Coastguard Worker 		vf_data->ce_mask |= SRIOV_ATTR_RATE_MIN;
1115*4dc78e53SAndroid Build Coastguard Worker 	}
1116*4dc78e53SAndroid Build Coastguard Worker 
1117*4dc78e53SAndroid Build Coastguard Worker 	return;
1118*4dc78e53SAndroid Build Coastguard Worker }
1119*4dc78e53SAndroid Build Coastguard Worker 
1120*4dc78e53SAndroid Build Coastguard Worker /**
1121*4dc78e53SAndroid Build Coastguard Worker  * Get RSS Query EN value of SRIOV Virtual Function
1122*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_data 	SRIOV VF object
1123*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_rss_query_en	Pointer to store VF RSS Query value
1124*4dc78e53SAndroid Build Coastguard Worker  *
1125*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_get_num_vf()
1126*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_set_rss_query_en()
1127*4dc78e53SAndroid Build Coastguard Worker  *
1128*4dc78e53SAndroid Build Coastguard Worker  * @return 0 if rss_query_en is present and vf_rss_query_en is set
1129*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1130*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_NOATTR if the VF RSS Query EN value is not set
1131*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_get_rss_query_en(struct rtnl_link_vf * vf_data,uint32_t * vf_rss_query_en)1132*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_rss_query_en(struct rtnl_link_vf *vf_data,
1133*4dc78e53SAndroid Build Coastguard Worker 				  uint32_t *vf_rss_query_en)
1134*4dc78e53SAndroid Build Coastguard Worker {
1135*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_data)
1136*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_OBJ_NOTFOUND;
1137*4dc78e53SAndroid Build Coastguard Worker 
1138*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_RSS_QUERY_EN)
1139*4dc78e53SAndroid Build Coastguard Worker 		*vf_rss_query_en = vf_data->vf_rss_query_en;
1140*4dc78e53SAndroid Build Coastguard Worker 	else
1141*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOATTR;
1142*4dc78e53SAndroid Build Coastguard Worker 
1143*4dc78e53SAndroid Build Coastguard Worker 	return 0;
1144*4dc78e53SAndroid Build Coastguard Worker }
1145*4dc78e53SAndroid Build Coastguard Worker 
1146*4dc78e53SAndroid Build Coastguard Worker /**
1147*4dc78e53SAndroid Build Coastguard Worker  * Set RSS configuration querying of SRIOV Virtual Function Object
1148*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_data 	SRIOV VF object
1149*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_rss_query_en	RSS Query value
1150*4dc78e53SAndroid Build Coastguard Worker  *
1151*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_get_rss_query_en()
1152*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_set_rss_query_en(struct rtnl_link_vf * vf_data,uint32_t vf_rss_query_en)1153*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_rss_query_en(struct rtnl_link_vf *vf_data,
1154*4dc78e53SAndroid Build Coastguard Worker 				  uint32_t vf_rss_query_en) {
1155*4dc78e53SAndroid Build Coastguard Worker 	vf_data->vf_rss_query_en = vf_rss_query_en;
1156*4dc78e53SAndroid Build Coastguard Worker 	vf_data->ce_mask |= SRIOV_ATTR_RSS_QUERY_EN;
1157*4dc78e53SAndroid Build Coastguard Worker 
1158*4dc78e53SAndroid Build Coastguard Worker 	return;
1159*4dc78e53SAndroid Build Coastguard Worker }
1160*4dc78e53SAndroid Build Coastguard Worker 
1161*4dc78e53SAndroid Build Coastguard Worker /**
1162*4dc78e53SAndroid Build Coastguard Worker  * Get spoof checking value of SRIOV Virtual Function
1163*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_data 	SRIOV VF object
1164*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_spoofchk 	Pointer to store VF spoofchk value
1165*4dc78e53SAndroid Build Coastguard Worker  *
1166*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_get_num_vf()
1167*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_set_spoofchk()
1168*4dc78e53SAndroid Build Coastguard Worker  *
1169*4dc78e53SAndroid Build Coastguard Worker  * @return 0 if spoofchk is present and vf_spoofchk is set
1170*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1171*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_NOATTR if the VF spoofcheck is not set
1172*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_get_spoofchk(struct rtnl_link_vf * vf_data,uint32_t * vf_spoofchk)1173*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_spoofchk(struct rtnl_link_vf *vf_data,
1174*4dc78e53SAndroid Build Coastguard Worker 			      uint32_t *vf_spoofchk)
1175*4dc78e53SAndroid Build Coastguard Worker {
1176*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_data)
1177*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_OBJ_NOTFOUND;
1178*4dc78e53SAndroid Build Coastguard Worker 
1179*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_SPOOFCHK)
1180*4dc78e53SAndroid Build Coastguard Worker 		*vf_spoofchk = vf_data->vf_spoofchk;
1181*4dc78e53SAndroid Build Coastguard Worker 	else
1182*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOATTR;
1183*4dc78e53SAndroid Build Coastguard Worker 
1184*4dc78e53SAndroid Build Coastguard Worker 	return 0;
1185*4dc78e53SAndroid Build Coastguard Worker }
1186*4dc78e53SAndroid Build Coastguard Worker 
1187*4dc78e53SAndroid Build Coastguard Worker /**
1188*4dc78e53SAndroid Build Coastguard Worker  * Set spoof checking value of SRIOV Virtual Function Object
1189*4dc78e53SAndroid Build Coastguard Worker  * @param vf_data
1190*4dc78e53SAndroid Build Coastguard Worker  * @param vf_spoofchk
1191*4dc78e53SAndroid Build Coastguard Worker  *
1192*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_get_spoofchk()
1193*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_set_spoofchk(struct rtnl_link_vf * vf_data,uint32_t vf_spoofchk)1194*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_spoofchk(struct rtnl_link_vf *vf_data,
1195*4dc78e53SAndroid Build Coastguard Worker 			       uint32_t vf_spoofchk) {
1196*4dc78e53SAndroid Build Coastguard Worker 	vf_data->vf_spoofchk = vf_spoofchk;
1197*4dc78e53SAndroid Build Coastguard Worker 	vf_data->ce_mask |= SRIOV_ATTR_SPOOFCHK;
1198*4dc78e53SAndroid Build Coastguard Worker 
1199*4dc78e53SAndroid Build Coastguard Worker 	return;
1200*4dc78e53SAndroid Build Coastguard Worker }
1201*4dc78e53SAndroid Build Coastguard Worker 
1202*4dc78e53SAndroid Build Coastguard Worker /**
1203*4dc78e53SAndroid Build Coastguard Worker  * Get value of stat counter for SRIOV Virtual Function
1204*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_data 	SRIOV VF object
1205*4dc78e53SAndroid Build Coastguard Worker  * @arg stat 		Identifier of statistical counter
1206*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_stat 	Pointer to store VF stat value in
1207*4dc78e53SAndroid Build Coastguard Worker  *
1208*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_get_num_vf()
1209*4dc78e53SAndroid Build Coastguard Worker  *
1210*4dc78e53SAndroid Build Coastguard Worker  * @return 0 if stat is present and vf_stat is set
1211*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1212*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_NOATTR if the VF stat is not set
1213*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_get_stat(struct rtnl_link_vf * vf_data,rtnl_link_vf_stats_t stat,uint64_t * vf_stat)1214*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_stat(struct rtnl_link_vf *vf_data,
1215*4dc78e53SAndroid Build Coastguard Worker 			  rtnl_link_vf_stats_t stat, uint64_t *vf_stat)
1216*4dc78e53SAndroid Build Coastguard Worker {
1217*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_data)
1218*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_OBJ_NOTFOUND;
1219*4dc78e53SAndroid Build Coastguard Worker 
1220*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_STATS)
1221*4dc78e53SAndroid Build Coastguard Worker 		*vf_stat = vf_data->vf_stats[stat];
1222*4dc78e53SAndroid Build Coastguard Worker 	else
1223*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOATTR;
1224*4dc78e53SAndroid Build Coastguard Worker 
1225*4dc78e53SAndroid Build Coastguard Worker 	return 0;
1226*4dc78e53SAndroid Build Coastguard Worker }
1227*4dc78e53SAndroid Build Coastguard Worker 
1228*4dc78e53SAndroid Build Coastguard Worker /**
1229*4dc78e53SAndroid Build Coastguard Worker  * Get trust setting of SRIOV Virtual Function
1230*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_data 	SRIOV VF object
1231*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_trust 	Pointer to store VF trust value
1232*4dc78e53SAndroid Build Coastguard Worker  *
1233*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_get_num_vf()
1234*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_set_trust()
1235*4dc78e53SAndroid Build Coastguard Worker  *
1236*4dc78e53SAndroid Build Coastguard Worker  * @return 0 if trust is present and vf_trust is set
1237*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1238*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_NOATTR if the VF trust setting is not set
1239*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_get_trust(struct rtnl_link_vf * vf_data,uint32_t * vf_trust)1240*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_trust(struct rtnl_link_vf *vf_data, uint32_t *vf_trust)
1241*4dc78e53SAndroid Build Coastguard Worker {
1242*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_data)
1243*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_OBJ_NOTFOUND;
1244*4dc78e53SAndroid Build Coastguard Worker 
1245*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_TRUST)
1246*4dc78e53SAndroid Build Coastguard Worker 		*vf_trust = vf_data->vf_trust;
1247*4dc78e53SAndroid Build Coastguard Worker 	else
1248*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOATTR;
1249*4dc78e53SAndroid Build Coastguard Worker 
1250*4dc78e53SAndroid Build Coastguard Worker 	return 0;
1251*4dc78e53SAndroid Build Coastguard Worker }
1252*4dc78e53SAndroid Build Coastguard Worker 
1253*4dc78e53SAndroid Build Coastguard Worker /**
1254*4dc78e53SAndroid Build Coastguard Worker  * Set user trust setting on SRIOV Virtual Function Object
1255*4dc78e53SAndroid Build Coastguard Worker  * @param vf_data
1256*4dc78e53SAndroid Build Coastguard Worker  * @param vf_trust
1257*4dc78e53SAndroid Build Coastguard Worker  *
1258*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_get_trust()
1259*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_set_trust(struct rtnl_link_vf * vf_data,uint32_t vf_trust)1260*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_trust(struct rtnl_link_vf *vf_data, uint32_t vf_trust) {
1261*4dc78e53SAndroid Build Coastguard Worker 	vf_data->vf_trust = vf_trust;
1262*4dc78e53SAndroid Build Coastguard Worker 	vf_data->ce_mask |= SRIOV_ATTR_TRUST;
1263*4dc78e53SAndroid Build Coastguard Worker 
1264*4dc78e53SAndroid Build Coastguard Worker 	return;
1265*4dc78e53SAndroid Build Coastguard Worker }
1266*4dc78e53SAndroid Build Coastguard Worker 
1267*4dc78e53SAndroid Build Coastguard Worker /**
1268*4dc78e53SAndroid Build Coastguard Worker  * Get an array of VLANS on SRIOV Virtual Function
1269*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_data 	SRIOV VF object
1270*4dc78e53SAndroid Build Coastguard Worker  * @arg vf_vlans 	Pointer to nl_vf_vlans_t struct to store vlan info.
1271*4dc78e53SAndroid Build Coastguard Worker  *
1272*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_get_num_vf()
1273*4dc78e53SAndroid Build Coastguard Worker  *
1274*4dc78e53SAndroid Build Coastguard Worker  * The SRIOV VF VLANs object must be returned to the SRIOV VF object with
1275*4dc78e53SAndroid Build Coastguard Worker  * rtnl_link_vf_vlans_put() when operations are done to prevent memory leaks.
1276*4dc78e53SAndroid Build Coastguard Worker  *
1277*4dc78e53SAndroid Build Coastguard Worker  * @copydoc pointer_lifetime_warning
1278*4dc78e53SAndroid Build Coastguard Worker  * @return 0 if VLAN info is present and vf_vlans is set
1279*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1280*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_NOATTR if the VF vlans is not set
1281*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_get_vlans(struct rtnl_link_vf * vf_data,nl_vf_vlans_t ** vf_vlans)1282*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_vlans(struct rtnl_link_vf *vf_data,
1283*4dc78e53SAndroid Build Coastguard Worker 			   nl_vf_vlans_t **vf_vlans) {
1284*4dc78e53SAndroid Build Coastguard Worker 	nl_vf_vlans_t *vf;
1285*4dc78e53SAndroid Build Coastguard Worker 
1286*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_data)
1287*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_OBJ_NOTFOUND;
1288*4dc78e53SAndroid Build Coastguard Worker 
1289*4dc78e53SAndroid Build Coastguard Worker 	if (vf_data->ce_mask & SRIOV_ATTR_VLAN) {
1290*4dc78e53SAndroid Build Coastguard Worker 		vf = vf_data->vf_vlans;
1291*4dc78e53SAndroid Build Coastguard Worker 		vf->ce_refcnt++;
1292*4dc78e53SAndroid Build Coastguard Worker 		*vf_vlans = vf;
1293*4dc78e53SAndroid Build Coastguard Worker 	} else
1294*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOATTR;
1295*4dc78e53SAndroid Build Coastguard Worker 
1296*4dc78e53SAndroid Build Coastguard Worker 	return 0;
1297*4dc78e53SAndroid Build Coastguard Worker }
1298*4dc78e53SAndroid Build Coastguard Worker 
1299*4dc78e53SAndroid Build Coastguard Worker /**
1300*4dc78e53SAndroid Build Coastguard Worker  * Add a SRIOV VF VLANs object to the SRIOV Virtual Function Object
1301*4dc78e53SAndroid Build Coastguard Worker  * @param vf_data 	SRIOV VF object
1302*4dc78e53SAndroid Build Coastguard Worker  * @param vf_vlans 	SRIOV VF VLANs object
1303*4dc78e53SAndroid Build Coastguard Worker  *
1304*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_get_vlans()
1305*4dc78e53SAndroid Build Coastguard Worker  * @see rtnl_link_vf_vlan_alloc()
1306*4dc78e53SAndroid Build Coastguard Worker  *
1307*4dc78e53SAndroid Build Coastguard Worker  * This function assigns ownership of the SRIOV VF object \p vf_vlans
1308*4dc78e53SAndroid Build Coastguard Worker  * to the SRIOV Virtual Function object \p vf_data. Do not use
1309*4dc78e53SAndroid Build Coastguard Worker  * rtnl_link_vf_vlan_put() on \p vf_vlans after this.
1310*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_set_vlans(struct rtnl_link_vf * vf_data,nl_vf_vlans_t * vf_vlans)1311*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_vlans(struct rtnl_link_vf *vf_data,
1312*4dc78e53SAndroid Build Coastguard Worker 			    nl_vf_vlans_t *vf_vlans) {
1313*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_data||!vf_vlans)
1314*4dc78e53SAndroid Build Coastguard Worker 		return;
1315*4dc78e53SAndroid Build Coastguard Worker 
1316*4dc78e53SAndroid Build Coastguard Worker 	vf_data->vf_vlans = vf_vlans;
1317*4dc78e53SAndroid Build Coastguard Worker 	vf_data->vf_vlans->ce_refcnt++;
1318*4dc78e53SAndroid Build Coastguard Worker 	vf_data->ce_mask |= SRIOV_ATTR_VLAN;
1319*4dc78e53SAndroid Build Coastguard Worker 
1320*4dc78e53SAndroid Build Coastguard Worker 	return;
1321*4dc78e53SAndroid Build Coastguard Worker }
1322*4dc78e53SAndroid Build Coastguard Worker 
1323*4dc78e53SAndroid Build Coastguard Worker /**
1324*4dc78e53SAndroid Build Coastguard Worker  * Allocate a SRIOV VF VLAN object
1325*4dc78e53SAndroid Build Coastguard Worker  * @param vf_vlans 	Pointer to store VLAN object at
1326*4dc78e53SAndroid Build Coastguard Worker  * @param vlan_count 	Number of VLANs that will be stored in VLAN object
1327*4dc78e53SAndroid Build Coastguard Worker  *
1328*4dc78e53SAndroid Build Coastguard Worker  * The SRIOV VF VLANs object must be returned to the sRIOV VF object with
1329*4dc78e53SAndroid Build Coastguard Worker  * rtnl_link_vf_vlan_put() when operations are done to prevent memory leaks.
1330*4dc78e53SAndroid Build Coastguard Worker  *
1331*4dc78e53SAndroid Build Coastguard Worker  * @return 0 if VLAN object is created and vf_vlans is set.
1332*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_NOMEM if object could not be allocated.
1333*4dc78e53SAndroid Build Coastguard Worker  * @return -NLE_INVAL if vlan_count is more than supported by SRIOV VF
1334*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_vlan_alloc(nl_vf_vlans_t ** vf_vlans,int vlan_count)1335*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_vlan_alloc(nl_vf_vlans_t **vf_vlans, int vlan_count) {
1336*4dc78e53SAndroid Build Coastguard Worker 	nl_vf_vlans_t *vlans;
1337*4dc78e53SAndroid Build Coastguard Worker 	nl_vf_vlan_info_t *vlan_info;
1338*4dc78e53SAndroid Build Coastguard Worker 
1339*4dc78e53SAndroid Build Coastguard Worker 	if (vlan_count > MAX_VLAN_LIST_LEN)
1340*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
1341*4dc78e53SAndroid Build Coastguard Worker 
1342*4dc78e53SAndroid Build Coastguard Worker 	vlans = calloc(1, sizeof(*vlans));
1343*4dc78e53SAndroid Build Coastguard Worker 	if (!vlans)
1344*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
1345*4dc78e53SAndroid Build Coastguard Worker 
1346*4dc78e53SAndroid Build Coastguard Worker 	vlan_info = calloc(vlan_count+1, sizeof(*vlan_info));
1347*4dc78e53SAndroid Build Coastguard Worker 	if (!vlan_info) {
1348*4dc78e53SAndroid Build Coastguard Worker 		free(vlans);
1349*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
1350*4dc78e53SAndroid Build Coastguard Worker 	}
1351*4dc78e53SAndroid Build Coastguard Worker 
1352*4dc78e53SAndroid Build Coastguard Worker 	NL_DBG(4, "Allocated new SRIOV VF VLANs object %p\n", vlans);
1353*4dc78e53SAndroid Build Coastguard Worker 
1354*4dc78e53SAndroid Build Coastguard Worker 	vlans->ce_refcnt = 1;
1355*4dc78e53SAndroid Build Coastguard Worker 	vlans->size = vlan_count;
1356*4dc78e53SAndroid Build Coastguard Worker 	vlans->vlans = vlan_info;
1357*4dc78e53SAndroid Build Coastguard Worker 	*vf_vlans = vlans;
1358*4dc78e53SAndroid Build Coastguard Worker 
1359*4dc78e53SAndroid Build Coastguard Worker 	return 0;
1360*4dc78e53SAndroid Build Coastguard Worker }
1361*4dc78e53SAndroid Build Coastguard Worker 
1362*4dc78e53SAndroid Build Coastguard Worker /**
1363*4dc78e53SAndroid Build Coastguard Worker  * Free an allocated SRIOV VF VLANs object
1364*4dc78e53SAndroid Build Coastguard Worker  * @param vf_vlans 	SRIOV VF VLANs object
1365*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_vlan_free(nl_vf_vlans_t * vf_vlans)1366*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_vlan_free(nl_vf_vlans_t *vf_vlans) {
1367*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_vlans)
1368*4dc78e53SAndroid Build Coastguard Worker 		return;
1369*4dc78e53SAndroid Build Coastguard Worker 
1370*4dc78e53SAndroid Build Coastguard Worker 	if (vf_vlans->ce_refcnt > 0)
1371*4dc78e53SAndroid Build Coastguard Worker 		NL_DBG(1, "Warning: Freeing SRIOV VF VLANs object in use...\n");
1372*4dc78e53SAndroid Build Coastguard Worker 
1373*4dc78e53SAndroid Build Coastguard Worker 	NL_DBG(4, "Freed SRIOV VF object %p\n", vf_vlans);
1374*4dc78e53SAndroid Build Coastguard Worker 	free(vf_vlans->vlans);
1375*4dc78e53SAndroid Build Coastguard Worker 	free(vf_vlans);
1376*4dc78e53SAndroid Build Coastguard Worker 
1377*4dc78e53SAndroid Build Coastguard Worker 	return;
1378*4dc78e53SAndroid Build Coastguard Worker }
1379*4dc78e53SAndroid Build Coastguard Worker 
1380*4dc78e53SAndroid Build Coastguard Worker /**
1381*4dc78e53SAndroid Build Coastguard Worker  * Return SRIOV VF VLANs object to the owning SRIOV VF object.
1382*4dc78e53SAndroid Build Coastguard Worker  * @param vf_vlans 	SRIOV VF VLANs object
1383*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_vlan_put(nl_vf_vlans_t * vf_vlans)1384*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_vlan_put(nl_vf_vlans_t *vf_vlans) {
1385*4dc78e53SAndroid Build Coastguard Worker 	if (!vf_vlans)
1386*4dc78e53SAndroid Build Coastguard Worker 		return;
1387*4dc78e53SAndroid Build Coastguard Worker 
1388*4dc78e53SAndroid Build Coastguard Worker 	vf_vlans->ce_refcnt--;
1389*4dc78e53SAndroid Build Coastguard Worker 	NL_DBG(4, "Returned SRIOV VF VLANs object reference %p, %i remaining\n",
1390*4dc78e53SAndroid Build Coastguard Worker 	       vf_vlans, vf_vlans->ce_refcnt);
1391*4dc78e53SAndroid Build Coastguard Worker 
1392*4dc78e53SAndroid Build Coastguard Worker 	if (vf_vlans->ce_refcnt < 0)
1393*4dc78e53SAndroid Build Coastguard Worker 		BUG();
1394*4dc78e53SAndroid Build Coastguard Worker 
1395*4dc78e53SAndroid Build Coastguard Worker 	if (vf_vlans->ce_refcnt <= 0)
1396*4dc78e53SAndroid Build Coastguard Worker 		rtnl_link_vf_vlan_free(vf_vlans);
1397*4dc78e53SAndroid Build Coastguard Worker 
1398*4dc78e53SAndroid Build Coastguard Worker 	return;
1399*4dc78e53SAndroid Build Coastguard Worker }
1400*4dc78e53SAndroid Build Coastguard Worker 
1401*4dc78e53SAndroid Build Coastguard Worker /** @} */
1402*4dc78e53SAndroid Build Coastguard Worker 
1403*4dc78e53SAndroid Build Coastguard Worker /**
1404*4dc78e53SAndroid Build Coastguard Worker  * @name Utilities
1405*4dc78e53SAndroid Build Coastguard Worker  * @{
1406*4dc78e53SAndroid Build Coastguard Worker  */
1407*4dc78e53SAndroid Build Coastguard Worker 
1408*4dc78e53SAndroid Build Coastguard Worker static const struct trans_tbl vf_link_states[] = {
1409*4dc78e53SAndroid Build Coastguard Worker 	__ADD(IFLA_VF_LINK_STATE_AUTO, autodetect),
1410*4dc78e53SAndroid Build Coastguard Worker 	__ADD(IFLA_VF_LINK_STATE_ENABLE, up),
1411*4dc78e53SAndroid Build Coastguard Worker 	__ADD(IFLA_VF_LINK_STATE_DISABLE, down),
1412*4dc78e53SAndroid Build Coastguard Worker };
1413*4dc78e53SAndroid Build Coastguard Worker 
rtnl_link_vf_linkstate2str(uint32_t ls,char * buf,size_t len)1414*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_vf_linkstate2str(uint32_t ls, char *buf, size_t len)
1415*4dc78e53SAndroid Build Coastguard Worker {
1416*4dc78e53SAndroid Build Coastguard Worker 	return __type2str(ls, buf, len, vf_link_states,
1417*4dc78e53SAndroid Build Coastguard Worker 			  ARRAY_SIZE(vf_link_states));
1418*4dc78e53SAndroid Build Coastguard Worker }
1419*4dc78e53SAndroid Build Coastguard Worker 
rtnl_link_vf_str2linkstate(const char * name)1420*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_str2linkstate(const char *name)
1421*4dc78e53SAndroid Build Coastguard Worker {
1422*4dc78e53SAndroid Build Coastguard Worker 	return __str2type(name, vf_link_states, ARRAY_SIZE(vf_link_states));
1423*4dc78e53SAndroid Build Coastguard Worker }
1424*4dc78e53SAndroid Build Coastguard Worker 
1425*4dc78e53SAndroid Build Coastguard Worker static const struct trans_tbl vf_vlan_proto[] = {
1426*4dc78e53SAndroid Build Coastguard Worker 	__ADD(ETH_P_8021Q, 8021Q),
1427*4dc78e53SAndroid Build Coastguard Worker 	__ADD(ETH_P_8021AD, 8021AD),
1428*4dc78e53SAndroid Build Coastguard Worker };
1429*4dc78e53SAndroid Build Coastguard Worker 
rtnl_link_vf_vlanproto2str(uint16_t proto,char * buf,size_t len)1430*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_vf_vlanproto2str(uint16_t proto, char *buf, size_t len)
1431*4dc78e53SAndroid Build Coastguard Worker {
1432*4dc78e53SAndroid Build Coastguard Worker 	return __type2str(proto, buf, len, vf_vlan_proto,
1433*4dc78e53SAndroid Build Coastguard Worker 			  ARRAY_SIZE(vf_vlan_proto));
1434*4dc78e53SAndroid Build Coastguard Worker }
1435*4dc78e53SAndroid Build Coastguard Worker 
rtnl_link_vf_str2vlanproto(const char * name)1436*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_str2vlanproto(const char *name)
1437*4dc78e53SAndroid Build Coastguard Worker {
1438*4dc78e53SAndroid Build Coastguard Worker 	return __str2type(name, vf_vlan_proto, ARRAY_SIZE(vf_vlan_proto));
1439*4dc78e53SAndroid Build Coastguard Worker }
1440*4dc78e53SAndroid Build Coastguard Worker 
1441*4dc78e53SAndroid Build Coastguard Worker /* Return a guid from a format checked string.
1442*4dc78e53SAndroid Build Coastguard Worker  * Format string must be xx:xx:xx:xx:xx:xx:xx:xx where XX can be an
1443*4dc78e53SAndroid Build Coastguard Worker  * arbitrary hex digit
1444*4dc78e53SAndroid Build Coastguard Worker  *
1445*4dc78e53SAndroid Build Coastguard Worker  * Function modified from original at iproute2/lib/utils.c:get_guid()
1446*4dc78e53SAndroid Build Coastguard Worker  * Original by Eli Cohen <[email protected]>.
1447*4dc78e53SAndroid Build Coastguard Worker  * iproute2 git commit d91fb3f4c7e4dba806541bdc90b1fb60a3581541
1448*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_vf_str2guid(uint64_t * guid,const char * guid_s)1449*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_str2guid(uint64_t *guid, const char *guid_s) {
1450*4dc78e53SAndroid Build Coastguard Worker 	unsigned long int tmp;
1451*4dc78e53SAndroid Build Coastguard Worker 	char *endptr;
1452*4dc78e53SAndroid Build Coastguard Worker 	int i;
1453*4dc78e53SAndroid Build Coastguard Worker 
1454*4dc78e53SAndroid Build Coastguard Worker 	if (strlen(guid_s) != RTNL_VF_GUID_STR_LEN)
1455*4dc78e53SAndroid Build Coastguard Worker 		return -1;
1456*4dc78e53SAndroid Build Coastguard Worker 
1457*4dc78e53SAndroid Build Coastguard Worker 	for (i = 0; i < 7; i++) {
1458*4dc78e53SAndroid Build Coastguard Worker 		if (guid_s[2 + i * 3] != ':')
1459*4dc78e53SAndroid Build Coastguard Worker 			return -1;
1460*4dc78e53SAndroid Build Coastguard Worker 	}
1461*4dc78e53SAndroid Build Coastguard Worker 
1462*4dc78e53SAndroid Build Coastguard Worker 	*guid = 0;
1463*4dc78e53SAndroid Build Coastguard Worker 	for (i = 0; i < 8; i++) {
1464*4dc78e53SAndroid Build Coastguard Worker 		tmp = strtoul(guid_s + i * 3, &endptr, 16);
1465*4dc78e53SAndroid Build Coastguard Worker 		if (endptr != guid_s + i * 3 + 2)
1466*4dc78e53SAndroid Build Coastguard Worker 			return -1;
1467*4dc78e53SAndroid Build Coastguard Worker 
1468*4dc78e53SAndroid Build Coastguard Worker 		if (tmp > 255)
1469*4dc78e53SAndroid Build Coastguard Worker 			return -1;
1470*4dc78e53SAndroid Build Coastguard Worker 
1471*4dc78e53SAndroid Build Coastguard Worker 		*guid |= tmp << (56 - 8 * i);
1472*4dc78e53SAndroid Build Coastguard Worker 	}
1473*4dc78e53SAndroid Build Coastguard Worker 
1474*4dc78e53SAndroid Build Coastguard Worker 	return 0;
1475*4dc78e53SAndroid Build Coastguard Worker }
1476*4dc78e53SAndroid Build Coastguard Worker 
1477*4dc78e53SAndroid Build Coastguard Worker /** @} */
1478*4dc78e53SAndroid Build Coastguard Worker 
1479*4dc78e53SAndroid Build Coastguard Worker /** @} */
1480