net/hns3: fix typos on comments
[dpdk.git] / drivers / net / txgbe / base / txgbe_mng.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2015-2020
3  */
4
5 #include "txgbe_type.h"
6 #include "txgbe_mng.h"
7
8 /**
9  *  txgbe_calculate_checksum - Calculate checksum for buffer
10  *  @buffer: pointer to EEPROM
11  *  @length: size of EEPROM to calculate a checksum for
12  *  Calculates the checksum for some buffer on a specified length.  The
13  *  checksum calculated is returned.
14  **/
15 static u8
16 txgbe_calculate_checksum(u8 *buffer, u32 length)
17 {
18         u32 i;
19         u8 sum = 0;
20
21         for (i = 0; i < length; i++)
22                 sum += buffer[i];
23
24         return (u8)(0 - sum);
25 }
26
27 /**
28  *  txgbe_hic_unlocked - Issue command to manageability block unlocked
29  *  @hw: pointer to the HW structure
30  *  @buffer: command to write and where the return status will be placed
31  *  @length: length of buffer, must be multiple of 4 bytes
32  *  @timeout: time in ms to wait for command completion
33  *
34  *  Communicates with the manageability block. On success return 0
35  *  else returns semaphore error when encountering an error acquiring
36  *  semaphore or TXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
37  *
38  *  This function assumes that the TXGBE_MNGSEM_SWMBX semaphore is held
39  *  by the caller.
40  **/
41 static s32
42 txgbe_hic_unlocked(struct txgbe_hw *hw, u32 *buffer, u32 length, u32 timeout)
43 {
44         u32 value, loop;
45         u16 i, dword_len;
46
47         DEBUGFUNC("txgbe_hic_unlocked");
48
49         if (!length || length > TXGBE_PMMBX_BSIZE) {
50                 DEBUGOUT("Buffer length failure buffersize=%d.\n", length);
51                 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
52         }
53
54         /* Calculate length in DWORDs. We must be DWORD aligned */
55         if (length % sizeof(u32)) {
56                 DEBUGOUT("Buffer length failure, not aligned to dword");
57                 return TXGBE_ERR_INVALID_ARGUMENT;
58         }
59
60         dword_len = length >> 2;
61
62         /* The device driver writes the relevant command block
63          * into the ram area.
64          */
65         for (i = 0; i < dword_len; i++) {
66                 wr32a(hw, TXGBE_MNGMBX, i, cpu_to_le32(buffer[i]));
67                 buffer[i] = rd32a(hw, TXGBE_MNGMBX, i);
68         }
69         txgbe_flush(hw);
70
71         /* Setting this bit tells the ARC that a new command is pending. */
72         wr32m(hw, TXGBE_MNGMBXCTL,
73               TXGBE_MNGMBXCTL_SWRDY, TXGBE_MNGMBXCTL_SWRDY);
74
75         /* Check command completion */
76         loop = po32m(hw, TXGBE_MNGMBXCTL,
77                 TXGBE_MNGMBXCTL_FWRDY, TXGBE_MNGMBXCTL_FWRDY,
78                 &value, timeout, 1000);
79         if (!loop || !(value & TXGBE_MNGMBXCTL_FWACK)) {
80                 DEBUGOUT("Command has failed with no status valid.\n");
81                 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
82         }
83
84         return 0;
85 }
86
87 /**
88  *  txgbe_host_interface_command - Issue command to manageability block
89  *  @hw: pointer to the HW structure
90  *  @buffer: contains the command to write and where the return status will
91  *   be placed
92  *  @length: length of buffer, must be multiple of 4 bytes
93  *  @timeout: time in ms to wait for command completion
94  *  @return_data: read and return data from the buffer (true) or not (false)
95  *   Needed because FW structures are big endian and decoding of
96  *   these fields can be 8 bit or 16 bit based on command. Decoding
97  *   is not easily understood without making a table of commands.
98  *   So we will leave this up to the caller to read back the data
99  *   in these cases.
100  *
101  *  Communicates with the manageability block. On success return 0
102  *  else returns semaphore error when encountering an error acquiring
103  *  semaphore or TXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
104  **/
105 static s32
106 txgbe_host_interface_command(struct txgbe_hw *hw, u32 *buffer,
107                                  u32 length, u32 timeout, bool return_data)
108 {
109         u32 hdr_size = sizeof(struct txgbe_hic_hdr);
110         struct txgbe_hic_hdr *resp = (struct txgbe_hic_hdr *)buffer;
111         u16 buf_len;
112         s32 err;
113         u32 bi;
114         u32 dword_len;
115
116         DEBUGFUNC("txgbe_host_interface_command");
117
118         if (length == 0 || length > TXGBE_PMMBX_BSIZE) {
119                 DEBUGOUT("Buffer length failure buffersize=%d.\n", length);
120                 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
121         }
122
123         /* Take management host interface semaphore */
124         err = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWMBX);
125         if (err)
126                 return err;
127
128         err = txgbe_hic_unlocked(hw, buffer, length, timeout);
129         if (err)
130                 goto rel_out;
131
132         if (!return_data)
133                 goto rel_out;
134
135         /* Calculate length in DWORDs */
136         dword_len = hdr_size >> 2;
137
138         /* first pull in the header so we know the buffer length */
139         for (bi = 0; bi < dword_len; bi++)
140                 buffer[bi] = rd32a(hw, TXGBE_MNGMBX, bi);
141
142         /*
143          * If there is any thing in data position pull it in
144          * Read Flash command requires reading buffer length from
145          * two byes instead of one byte
146          */
147         if (resp->cmd == 0x30) {
148                 for (; bi < dword_len + 2; bi++)
149                         buffer[bi] = rd32a(hw, TXGBE_MNGMBX, bi);
150
151                 buf_len = (((u16)(resp->cmd_or_resp.ret_status) << 3)
152                                   & 0xF00) | resp->buf_len;
153                 hdr_size += (2 << 2);
154         } else {
155                 buf_len = resp->buf_len;
156         }
157         if (!buf_len)
158                 goto rel_out;
159
160         if (length < buf_len + hdr_size) {
161                 DEBUGOUT("Buffer not large enough for reply message.\n");
162                 err = TXGBE_ERR_HOST_INTERFACE_COMMAND;
163                 goto rel_out;
164         }
165
166         /* Calculate length in DWORDs, add 3 for odd lengths */
167         dword_len = (buf_len + 3) >> 2;
168
169         /* Pull in the rest of the buffer (bi is where we left off) */
170         for (; bi <= dword_len; bi++)
171                 buffer[bi] = rd32a(hw, TXGBE_MNGMBX, bi);
172
173 rel_out:
174         hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWMBX);
175
176         return err;
177 }
178
179 /**
180  *  txgbe_hic_sr_read - Read EEPROM word using a host interface cmd
181  *  assuming that the semaphore is already obtained.
182  *  @hw: pointer to hardware structure
183  *  @offset: offset of  word in the EEPROM to read
184  *  @data: word read from the EEPROM
185  *
186  *  Reads a 16 bit word from the EEPROM using the hostif.
187  **/
188 s32 txgbe_hic_sr_read(struct txgbe_hw *hw, u32 addr, u8 *buf, int len)
189 {
190         struct txgbe_hic_read_shadow_ram command;
191         u32 value;
192         int err, i = 0, j = 0;
193
194         if (len > TXGBE_PMMBX_DATA_SIZE)
195                 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
196
197         memset(&command, 0, sizeof(command));
198         command.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
199         command.hdr.req.buf_lenh = 0;
200         command.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
201         command.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
202         command.address = cpu_to_be32(addr);
203         command.length = cpu_to_be16(len);
204
205         err = txgbe_hic_unlocked(hw, (u32 *)&command,
206                         sizeof(command), TXGBE_HI_COMMAND_TIMEOUT);
207         if (err)
208                 return err;
209
210         while (i < (len >> 2)) {
211                 value = rd32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + i);
212                 ((u32 *)buf)[i] = value;
213                 i++;
214         }
215
216         value = rd32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + i);
217         for (i <<= 2; i < len; i++)
218                 ((u8 *)buf)[i] = ((u8 *)&value)[j++];
219
220         return 0;
221 }
222
223 /**
224  *  txgbe_hic_sr_write - Write EEPROM word using hostif
225  *  @hw: pointer to hardware structure
226  *  @offset: offset of  word in the EEPROM to write
227  *  @data: word write to the EEPROM
228  *
229  *  Write a 16 bit word to the EEPROM using the hostif.
230  **/
231 s32 txgbe_hic_sr_write(struct txgbe_hw *hw, u32 addr, u8 *buf, int len)
232 {
233         struct txgbe_hic_write_shadow_ram command;
234         u32 value;
235         int err = 0, i = 0, j = 0;
236
237         if (len > TXGBE_PMMBX_DATA_SIZE)
238                 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
239
240         memset(&command, 0, sizeof(command));
241         command.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
242         command.hdr.req.buf_lenh = 0;
243         command.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
244         command.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
245         command.address = cpu_to_be32(addr);
246         command.length = cpu_to_be16(len);
247
248         while (i < (len >> 2)) {
249                 value = ((u32 *)buf)[i];
250                 wr32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + i, value);
251                 i++;
252         }
253
254         for (i <<= 2; i < len; i++)
255                 ((u8 *)&value)[j++] = ((u8 *)buf)[i];
256
257         wr32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + (i >> 2), value);
258
259         UNREFERENCED_PARAMETER(&command);
260
261         return err;
262 }
263
264 /**
265  *  txgbe_hic_set_drv_ver - Sends driver version to firmware
266  *  @hw: pointer to the HW structure
267  *  @maj: driver version major number
268  *  @min: driver version minor number
269  *  @build: driver version build number
270  *  @sub: driver version sub build number
271  *  @len: unused
272  *  @driver_ver: unused
273  *
274  *  Sends driver version number to firmware through the manageability
275  *  block.  On success return 0
276  *  else returns TXGBE_ERR_SWFW_SYNC when encountering an error acquiring
277  *  semaphore or TXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
278  **/
279 s32 txgbe_hic_set_drv_ver(struct txgbe_hw *hw, u8 maj, u8 min,
280                                  u8 build, u8 sub, u16 len,
281                                  const char *driver_ver)
282 {
283         struct txgbe_hic_drv_info fw_cmd;
284         int i;
285         s32 ret_val = 0;
286
287         DEBUGFUNC("txgbe_hic_set_drv_ver");
288         UNREFERENCED_PARAMETER(len, driver_ver);
289
290         fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
291         fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN;
292         fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
293         fw_cmd.port_num = (u8)hw->bus.func;
294         fw_cmd.ver_maj = maj;
295         fw_cmd.ver_min = min;
296         fw_cmd.ver_build = build;
297         fw_cmd.ver_sub = sub;
298         fw_cmd.hdr.checksum = 0;
299         fw_cmd.pad = 0;
300         fw_cmd.pad2 = 0;
301         fw_cmd.hdr.checksum = txgbe_calculate_checksum((u8 *)&fw_cmd,
302                                 (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
303
304         for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
305                 ret_val = txgbe_host_interface_command(hw, (u32 *)&fw_cmd,
306                                                        sizeof(fw_cmd),
307                                                        TXGBE_HI_COMMAND_TIMEOUT,
308                                                        true);
309                 if (ret_val != 0)
310                         continue;
311
312                 if (fw_cmd.hdr.cmd_or_resp.ret_status ==
313                     FW_CEM_RESP_STATUS_SUCCESS)
314                         ret_val = 0;
315                 else
316                         ret_val = TXGBE_ERR_HOST_INTERFACE_COMMAND;
317
318                 break;
319         }
320
321         return ret_val;
322 }
323
324 /**
325  *  txgbe_hic_reset - send reset cmd to fw
326  *  @hw: pointer to hardware structure
327  *
328  *  Sends reset cmd to firmware through the manageability
329  *  block.  On success return 0
330  *  else returns TXGBE_ERR_SWFW_SYNC when encountering an error acquiring
331  *  semaphore or TXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
332  **/
333 s32
334 txgbe_hic_reset(struct txgbe_hw *hw)
335 {
336         struct txgbe_hic_reset reset_cmd;
337         int i;
338         s32 err = 0;
339
340         DEBUGFUNC("\n");
341
342         reset_cmd.hdr.cmd = FW_RESET_CMD;
343         reset_cmd.hdr.buf_len = FW_RESET_LEN;
344         reset_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
345         reset_cmd.lan_id = hw->bus.lan_id;
346         reset_cmd.reset_type = (u16)hw->reset_type;
347         reset_cmd.hdr.checksum = 0;
348         reset_cmd.hdr.checksum = txgbe_calculate_checksum((u8 *)&reset_cmd,
349                                 (FW_CEM_HDR_LEN + reset_cmd.hdr.buf_len));
350
351         for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
352                 err = txgbe_host_interface_command(hw, (u32 *)&reset_cmd,
353                                                        sizeof(reset_cmd),
354                                                        TXGBE_HI_COMMAND_TIMEOUT,
355                                                        true);
356                 if (err != 0)
357                         continue;
358
359                 if (reset_cmd.hdr.cmd_or_resp.ret_status ==
360                     FW_CEM_RESP_STATUS_SUCCESS)
361                         err = 0;
362                 else
363                         err = TXGBE_ERR_HOST_INTERFACE_COMMAND;
364
365                 break;
366         }
367
368         return err;
369 }
370
371 /**
372  * txgbe_mng_present - returns true when management capability is present
373  * @hw: pointer to hardware structure
374  */
375 bool
376 txgbe_mng_present(struct txgbe_hw *hw)
377 {
378         if (hw->mac.type == txgbe_mac_unknown)
379                 return false;
380
381         return !!rd32m(hw, TXGBE_STAT, TXGBE_STAT_MNGINIT);
382 }
383
384 /**
385  * txgbe_mng_enabled - Is the manageability engine enabled?
386  * @hw: pointer to hardware structure
387  *
388  * Returns true if the manageability engine is enabled.
389  **/
390 bool
391 txgbe_mng_enabled(struct txgbe_hw *hw)
392 {
393         UNREFERENCED_PARAMETER(hw);
394         /* firmware does not control laser */
395         return false;
396 }