diff options
author | Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> | 2018-09-19 20:23:04 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2018-10-01 15:39:40 -0400 |
commit | 45d3d428eafcbb18027c419624ce950b4db3a4b4 (patch) | |
tree | c33223eb6b3dca3b909a32fc09b284a0eee61ba4 /drivers/net/ethernet/intel/ice/ice_lib.c | |
parent | 3b6bf296c44f2b1233b7622c847a6ac5b1aeba0f (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.c | 258 |
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 | */ | ||
17 | int 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 | */ | ||
44 | void 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 | */ | ||
102 | void 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 | */ | ||
117 | int 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 | */ | ||
157 | int 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 | */ | ||
192 | int 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 | */ | ||
224 | int 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 | } | ||