138838a73dbc4d754e82b5ac6fa43213e29de358
[dpdk.git] / drivers / net / ice / ice_dcf_parent.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Intel Corporation
3  */
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <unistd.h>
7
8 #include "ice_dcf_ethdev.h"
9
10 void
11 ice_dcf_handle_pf_event_msg(__rte_unused struct ice_dcf_hw *dcf_hw,
12                             uint8_t *msg, uint16_t msglen)
13 {
14         struct virtchnl_pf_event *pf_msg = (struct virtchnl_pf_event *)msg;
15
16         if (msglen < sizeof(struct virtchnl_pf_event)) {
17                 PMD_DRV_LOG(DEBUG, "Invalid event message length : %u", msglen);
18                 return;
19         }
20
21         switch (pf_msg->event) {
22         case VIRTCHNL_EVENT_RESET_IMPENDING:
23                 PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event");
24                 break;
25         case VIRTCHNL_EVENT_LINK_CHANGE:
26                 PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event");
27                 break;
28         case VIRTCHNL_EVENT_PF_DRIVER_CLOSE:
29                 PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_PF_DRIVER_CLOSE event");
30                 break;
31         default:
32                 PMD_DRV_LOG(ERR, "Unknown event received %u", pf_msg->event);
33                 break;
34         }
35 }
36
37 static int
38 ice_dcf_init_parent_hw(struct ice_hw *hw)
39 {
40         struct ice_aqc_get_phy_caps_data *pcaps;
41         enum ice_status status;
42
43         status = ice_aq_get_fw_ver(hw, NULL);
44         if (status)
45                 return status;
46
47         status = ice_get_caps(hw);
48         if (status)
49                 return status;
50
51         hw->port_info = (struct ice_port_info *)
52                         ice_malloc(hw, sizeof(*hw->port_info));
53         if (!hw->port_info)
54                 return ICE_ERR_NO_MEMORY;
55
56         /* set the back pointer to HW */
57         hw->port_info->hw = hw;
58
59         /* Initialize port_info struct with switch configuration data */
60         status = ice_get_initial_sw_cfg(hw);
61         if (status)
62                 goto err_unroll_alloc;
63
64         pcaps = (struct ice_aqc_get_phy_caps_data *)
65                 ice_malloc(hw, sizeof(*pcaps));
66         if (!pcaps) {
67                 status = ICE_ERR_NO_MEMORY;
68                 goto err_unroll_alloc;
69         }
70
71         /* Initialize port_info struct with PHY capabilities */
72         status = ice_aq_get_phy_caps(hw->port_info, false,
73                                      ICE_AQC_REPORT_TOPO_CAP, pcaps, NULL);
74         ice_free(hw, pcaps);
75         if (status)
76                 goto err_unroll_alloc;
77
78         /* Initialize port_info struct with link information */
79         status = ice_aq_get_link_info(hw->port_info, false, NULL, NULL);
80         if (status)
81                 goto err_unroll_alloc;
82
83         status = ice_init_fltr_mgmt_struct(hw);
84         if (status)
85                 goto err_unroll_alloc;
86
87         status = ice_init_hw_tbls(hw);
88         if (status)
89                 goto err_unroll_fltr_mgmt_struct;
90
91         PMD_INIT_LOG(INFO,
92                      "firmware %d.%d.%d api %d.%d.%d build 0x%08x",
93                      hw->fw_maj_ver, hw->fw_min_ver, hw->fw_patch,
94                      hw->api_maj_ver, hw->api_min_ver, hw->api_patch,
95                      hw->fw_build);
96
97         return ICE_SUCCESS;
98
99 err_unroll_fltr_mgmt_struct:
100         ice_cleanup_fltr_mgmt_struct(hw);
101 err_unroll_alloc:
102         ice_free(hw, hw->port_info);
103         hw->port_info = NULL;
104
105         return status;
106 }
107
108 static void ice_dcf_uninit_parent_hw(struct ice_hw *hw)
109 {
110         ice_cleanup_fltr_mgmt_struct(hw);
111
112         ice_free_seg(hw);
113         ice_free_hw_tbls(hw);
114
115         ice_free(hw, hw->port_info);
116         hw->port_info = NULL;
117
118         ice_clear_all_vsi_ctx(hw);
119 }
120
121 static int
122 ice_dcf_request_pkg_name(struct ice_hw *hw, char *pkg_name)
123 {
124         struct ice_dcf_adapter *dcf_adapter =
125                         container_of(hw, struct ice_dcf_adapter, parent.hw);
126
127         /* TODO: check with DSN firstly by iAVF */
128         PMD_INIT_LOG(DEBUG,
129                      "DCF VSI_ID = %u",
130                      dcf_adapter->real_hw.vsi_id);
131
132         snprintf(pkg_name,
133                  ICE_MAX_PKG_FILENAME_SIZE, "%s", ICE_PKG_FILE_UPDATES);
134         if (!access(pkg_name, 0))
135                 return 0;
136
137         snprintf(pkg_name,
138                  ICE_MAX_PKG_FILENAME_SIZE, "%s", ICE_PKG_FILE_DEFAULT);
139         if (!access(pkg_name, 0))
140                 return 0;
141
142         return -1;
143 }
144
145 static int
146 ice_dcf_load_pkg(struct ice_hw *hw)
147 {
148         char pkg_name[ICE_MAX_PKG_FILENAME_SIZE];
149         uint8_t *pkg_buf;
150         uint32_t buf_len;
151         struct stat st;
152         FILE *fp;
153         int err;
154
155         if (ice_dcf_request_pkg_name(hw, pkg_name)) {
156                 PMD_INIT_LOG(ERR, "Failed to locate the package file");
157                 return -ENOENT;
158         }
159
160         PMD_INIT_LOG(DEBUG, "DDP package name: %s", pkg_name);
161
162         err = stat(pkg_name, &st);
163         if (err) {
164                 PMD_INIT_LOG(ERR, "Failed to get file status");
165                 return err;
166         }
167
168         buf_len = st.st_size;
169         pkg_buf = rte_malloc(NULL, buf_len, 0);
170         if (!pkg_buf) {
171                 PMD_INIT_LOG(ERR, "failed to allocate buffer of size %u for package",
172                              buf_len);
173                 return -1;
174         }
175
176         fp = fopen(pkg_name, "rb");
177         if (!fp)  {
178                 PMD_INIT_LOG(ERR, "failed to open file: %s", pkg_name);
179                 err = -1;
180                 goto ret;
181         }
182
183         err = fread(pkg_buf, buf_len, 1, fp);
184         fclose(fp);
185         if (err != 1) {
186                 PMD_INIT_LOG(ERR, "failed to read package data");
187                 err = -1;
188                 goto ret;
189         }
190
191         err = ice_copy_and_init_pkg(hw, pkg_buf, buf_len);
192         if (err)
193                 PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d", err);
194
195 ret:
196         rte_free(pkg_buf);
197         return err;
198 }
199
200 int
201 ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev)
202 {
203         struct ice_dcf_adapter *adapter = eth_dev->data->dev_private;
204         struct ice_adapter *parent_adapter = &adapter->parent;
205         struct ice_hw *parent_hw = &parent_adapter->hw;
206         struct ice_dcf_hw *hw = &adapter->real_hw;
207         const struct rte_ether_addr *mac;
208         int err;
209
210         parent_adapter->eth_dev = eth_dev;
211         parent_adapter->pf.adapter = parent_adapter;
212         parent_adapter->pf.dev_data = eth_dev->data;
213         parent_hw->back = parent_adapter;
214         parent_hw->mac_type = ICE_MAC_GENERIC;
215         parent_hw->vendor_id = ICE_INTEL_VENDOR_ID;
216
217         ice_init_lock(&parent_hw->adminq.sq_lock);
218         ice_init_lock(&parent_hw->adminq.rq_lock);
219         parent_hw->aq_send_cmd_fn = ice_dcf_send_aq_cmd;
220         parent_hw->aq_send_cmd_param = &adapter->real_hw;
221         parent_hw->dcf_enabled = true;
222
223         err = ice_dcf_init_parent_hw(parent_hw);
224         if (err) {
225                 PMD_INIT_LOG(ERR, "failed to init the DCF parent hardware with error %d",
226                              err);
227                 return err;
228         }
229
230         err = ice_dcf_load_pkg(parent_hw);
231         if (err) {
232                 PMD_INIT_LOG(ERR, "failed to load package with error %d",
233                              err);
234                 goto uninit_hw;
235         }
236         parent_adapter->active_pkg_type = ice_load_pkg_type(parent_hw);
237
238         mac = (const struct rte_ether_addr *)hw->avf.mac.addr;
239         if (rte_is_valid_assigned_ether_addr(mac))
240                 rte_ether_addr_copy(mac, &parent_adapter->pf.dev_addr);
241         else
242                 rte_eth_random_addr(parent_adapter->pf.dev_addr.addr_bytes);
243
244         eth_dev->data->mac_addrs = &parent_adapter->pf.dev_addr;
245
246         return 0;
247
248 uninit_hw:
249         ice_dcf_uninit_parent_hw(parent_hw);
250         return err;
251 }
252
253 void
254 ice_dcf_uninit_parent_adapter(struct rte_eth_dev *eth_dev)
255 {
256         struct ice_dcf_adapter *adapter = eth_dev->data->dev_private;
257         struct ice_adapter *parent_adapter = &adapter->parent;
258         struct ice_hw *parent_hw = &parent_adapter->hw;
259
260         eth_dev->data->mac_addrs = NULL;
261
262         ice_dcf_uninit_parent_hw(parent_hw);
263 }