aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ice/ice_lib.c
diff options
context:
space:
mode:
authorAnirudh Venkataramanan <anirudh.venkataramanan@intel.com>2018-09-19 20:23:04 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2018-10-01 15:39:40 -0400
commit45d3d428eafcbb18027c419624ce950b4db3a4b4 (patch)
treec33223eb6b3dca3b909a32fc09b284a0eee61ba4 /drivers/net/ethernet/intel/ice/ice_lib.c
parent3b6bf296c44f2b1233b7622c847a6ac5b1aeba0f (diff)
ice: Move common functions out of ice_main.c part 1/7
The functions that are used for PF VSI/netdev setup will also be used for SR-IOV support. To allow reuse of these functions, move these functions out of ice_main.c to ice_common.c/ice_lib.c This move is done across multiple patches. Each patch moves a few functions and may have minor adjustments. For example, a function that was previously static in ice_main.c will be made non-static temporarily in its new location to allow the driver to build cleanly. These adjustments will be removed in subsequent patches where more code is moved out of ice_main.c In this particular patch, the following functions were moved out of ice_main.c: int ice_add_mac_to_list ice_free_fltr_list ice_stat_update40 ice_stat_update32 ice_update_eth_stats ice_vsi_add_vlan ice_vsi_kill_vlan ice_vsi_manage_vlan_insertion ice_vsi_manage_vlan_stripping Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_lib.c')
-rw-r--r--drivers/net/ethernet/intel/ice/ice_lib.c258
1 files changed, 258 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
new file mode 100644
index 000000000000..1cf4dca12495
--- /dev/null
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -0,0 +1,258 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2018, Intel Corporation. */
3
4#include "ice.h"
5#include "ice_lib.h"
6
7/**
8 * ice_add_mac_to_list - Add a mac address filter entry to the list
9 * @vsi: the VSI to be forwarded to
10 * @add_list: pointer to the list which contains MAC filter entries
11 * @macaddr: the MAC address to be added.
12 *
13 * Adds mac address filter entry to the temp list
14 *
15 * Returns 0 on success or ENOMEM on failure.
16 */
17int ice_add_mac_to_list(struct ice_vsi *vsi, struct list_head *add_list,
18 const u8 *macaddr)
19{
20 struct ice_fltr_list_entry *tmp;
21 struct ice_pf *pf = vsi->back;
22
23 tmp = devm_kzalloc(&pf->pdev->dev, sizeof(*tmp), GFP_ATOMIC);
24 if (!tmp)
25 return -ENOMEM;
26
27 tmp->fltr_info.flag = ICE_FLTR_TX;
28 tmp->fltr_info.src = vsi->vsi_num;
29 tmp->fltr_info.lkup_type = ICE_SW_LKUP_MAC;
30 tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
31 tmp->fltr_info.fwd_id.vsi_id = vsi->vsi_num;
32 ether_addr_copy(tmp->fltr_info.l_data.mac.mac_addr, macaddr);
33
34 INIT_LIST_HEAD(&tmp->list_entry);
35 list_add(&tmp->list_entry, add_list);
36
37 return 0;
38}
39
40/**
41 * ice_update_eth_stats - Update VSI-specific ethernet statistics counters
42 * @vsi: the VSI to be updated
43 */
44void ice_update_eth_stats(struct ice_vsi *vsi)
45{
46 struct ice_eth_stats *prev_es, *cur_es;
47 struct ice_hw *hw = &vsi->back->hw;
48 u16 vsi_num = vsi->vsi_num; /* HW absolute index of a VSI */
49
50 prev_es = &vsi->eth_stats_prev;
51 cur_es = &vsi->eth_stats;
52
53 ice_stat_update40(hw, GLV_GORCH(vsi_num), GLV_GORCL(vsi_num),
54 vsi->stat_offsets_loaded, &prev_es->rx_bytes,
55 &cur_es->rx_bytes);
56
57 ice_stat_update40(hw, GLV_UPRCH(vsi_num), GLV_UPRCL(vsi_num),
58 vsi->stat_offsets_loaded, &prev_es->rx_unicast,
59 &cur_es->rx_unicast);
60
61 ice_stat_update40(hw, GLV_MPRCH(vsi_num), GLV_MPRCL(vsi_num),
62 vsi->stat_offsets_loaded, &prev_es->rx_multicast,
63 &cur_es->rx_multicast);
64
65 ice_stat_update40(hw, GLV_BPRCH(vsi_num), GLV_BPRCL(vsi_num),
66 vsi->stat_offsets_loaded, &prev_es->rx_broadcast,
67 &cur_es->rx_broadcast);
68
69 ice_stat_update32(hw, GLV_RDPC(vsi_num), vsi->stat_offsets_loaded,
70 &prev_es->rx_discards, &cur_es->rx_discards);
71
72 ice_stat_update40(hw, GLV_GOTCH(vsi_num), GLV_GOTCL(vsi_num),
73 vsi->stat_offsets_loaded, &prev_es->tx_bytes,
74 &cur_es->tx_bytes);
75
76 ice_stat_update40(hw, GLV_UPTCH(vsi_num), GLV_UPTCL(vsi_num),
77 vsi->stat_offsets_loaded, &prev_es->tx_unicast,
78 &cur_es->tx_unicast);
79
80 ice_stat_update40(hw, GLV_MPTCH(vsi_num), GLV_MPTCL(vsi_num),
81 vsi->stat_offsets_loaded, &prev_es->tx_multicast,
82 &cur_es->tx_multicast);
83
84 ice_stat_update40(hw, GLV_BPTCH(vsi_num), GLV_BPTCL(vsi_num),
85 vsi->stat_offsets_loaded, &prev_es->tx_broadcast,
86 &cur_es->tx_broadcast);
87
88 ice_stat_update32(hw, GLV_TEPC(vsi_num), vsi->stat_offsets_loaded,
89 &prev_es->tx_errors, &cur_es->tx_errors);
90
91 vsi->stat_offsets_loaded = true;
92}
93
94/**
95 * ice_free_fltr_list - free filter lists helper
96 * @dev: pointer to the device struct
97 * @h: pointer to the list head to be freed
98 *
99 * Helper function to free filter lists previously created using
100 * ice_add_mac_to_list
101 */
102void ice_free_fltr_list(struct device *dev, struct list_head *h)
103{
104 struct ice_fltr_list_entry *e, *tmp;
105
106 list_for_each_entry_safe(e, tmp, h, list_entry) {
107 list_del(&e->list_entry);
108 devm_kfree(dev, e);
109 }
110}
111
112/**
113 * ice_vsi_add_vlan - Add VSI membership for given VLAN
114 * @vsi: the VSI being configured
115 * @vid: VLAN id to be added
116 */
117int ice_vsi_add_vlan(struct ice_vsi *vsi, u16 vid)
118{
119 struct ice_fltr_list_entry *tmp;
120 struct ice_pf *pf = vsi->back;
121 LIST_HEAD(tmp_add_list);
122 enum ice_status status;
123 int err = 0;
124
125 tmp = devm_kzalloc(&pf->pdev->dev, sizeof(*tmp), GFP_KERNEL);
126 if (!tmp)
127 return -ENOMEM;
128
129 tmp->fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
130 tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
131 tmp->fltr_info.flag = ICE_FLTR_TX;
132 tmp->fltr_info.src = vsi->vsi_num;
133 tmp->fltr_info.fwd_id.vsi_id = vsi->vsi_num;
134 tmp->fltr_info.l_data.vlan.vlan_id = vid;
135
136 INIT_LIST_HEAD(&tmp->list_entry);
137 list_add(&tmp->list_entry, &tmp_add_list);
138
139 status = ice_add_vlan(&pf->hw, &tmp_add_list);
140 if (status) {
141 err = -ENODEV;
142 dev_err(&pf->pdev->dev, "Failure Adding VLAN %d on VSI %i\n",
143 vid, vsi->vsi_num);
144 }
145
146 ice_free_fltr_list(&pf->pdev->dev, &tmp_add_list);
147 return err;
148}
149
150/**
151 * ice_vsi_kill_vlan - Remove VSI membership for a given VLAN
152 * @vsi: the VSI being configured
153 * @vid: VLAN id to be removed
154 *
155 * Returns 0 on success and negative on failure
156 */
157int ice_vsi_kill_vlan(struct ice_vsi *vsi, u16 vid)
158{
159 struct ice_fltr_list_entry *list;
160 struct ice_pf *pf = vsi->back;
161 LIST_HEAD(tmp_add_list);
162 int status = 0;
163
164 list = devm_kzalloc(&pf->pdev->dev, sizeof(*list), GFP_KERNEL);
165 if (!list)
166 return -ENOMEM;
167
168 list->fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
169 list->fltr_info.fwd_id.vsi_id = vsi->vsi_num;
170 list->fltr_info.fltr_act = ICE_FWD_TO_VSI;
171 list->fltr_info.l_data.vlan.vlan_id = vid;
172 list->fltr_info.flag = ICE_FLTR_TX;
173 list->fltr_info.src = vsi->vsi_num;
174
175 INIT_LIST_HEAD(&list->list_entry);
176 list_add(&list->list_entry, &tmp_add_list);
177
178 if (ice_remove_vlan(&pf->hw, &tmp_add_list)) {
179 dev_err(&pf->pdev->dev, "Error removing VLAN %d on vsi %i\n",
180 vid, vsi->vsi_num);
181 status = -EIO;
182 }
183
184 ice_free_fltr_list(&pf->pdev->dev, &tmp_add_list);
185 return status;
186}
187
188/**
189 * ice_vsi_manage_vlan_insertion - Manage VLAN insertion for the VSI for Tx
190 * @vsi: the VSI being changed
191 */
192int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi)
193{
194 struct device *dev = &vsi->back->pdev->dev;
195 struct ice_hw *hw = &vsi->back->hw;
196 struct ice_vsi_ctx ctxt = { 0 };
197 enum ice_status status;
198
199 /* Here we are configuring the VSI to let the driver add VLAN tags by
200 * setting vlan_flags to ICE_AQ_VSI_VLAN_MODE_ALL. The actual VLAN tag
201 * insertion happens in the Tx hot path, in ice_tx_map.
202 */
203 ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_ALL;
204
205 ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
206 ctxt.vsi_num = vsi->vsi_num;
207
208 status = ice_aq_update_vsi(hw, &ctxt, NULL);
209 if (status) {
210 dev_err(dev, "update VSI for VLAN insert failed, err %d aq_err %d\n",
211 status, hw->adminq.sq_last_status);
212 return -EIO;
213 }
214
215 vsi->info.vlan_flags = ctxt.info.vlan_flags;
216 return 0;
217}
218
219/**
220 * ice_vsi_manage_vlan_stripping - Manage VLAN stripping for the VSI for Rx
221 * @vsi: the VSI being changed
222 * @ena: boolean value indicating if this is a enable or disable request
223 */
224int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena)
225{
226 struct device *dev = &vsi->back->pdev->dev;
227 struct ice_hw *hw = &vsi->back->hw;
228 struct ice_vsi_ctx ctxt = { 0 };
229 enum ice_status status;
230
231 /* Here we are configuring what the VSI should do with the VLAN tag in
232 * the Rx packet. We can either leave the tag in the packet or put it in
233 * the Rx descriptor.
234 */
235 if (ena) {
236 /* Strip VLAN tag from Rx packet and put it in the desc */
237 ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_STR_BOTH;
238 } else {
239 /* Disable stripping. Leave tag in packet */
240 ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_NOTHING;
241 }
242
243 /* Allow all packets untagged/tagged */
244 ctxt.info.vlan_flags |= ICE_AQ_VSI_VLAN_MODE_ALL;
245
246 ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
247 ctxt.vsi_num = vsi->vsi_num;
248
249 status = ice_aq_update_vsi(hw, &ctxt, NULL);
250 if (status) {
251 dev_err(dev, "update VSI for VLAN strip failed, ena = %d err %d aq_err %d\n",
252 ena, status, hw->adminq.sq_last_status);
253 return -EIO;
254 }
255
256 vsi->info.vlan_flags = ctxt.info.vlan_flags;
257 return 0;
258}