net/ice: fix build when Rx descriptor size is 16
[dpdk.git] / drivers / net / ngbe / base / ngbe_mng.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
3  * Copyright(c) 2010-2017 Intel Corporation
4  */
5
6 #include "ngbe_type.h"
7 #include "ngbe_mng.h"
8
9 /**
10  *  ngbe_hic_unlocked - Issue command to manageability block unlocked
11  *  @hw: pointer to the HW structure
12  *  @buffer: command to write and where the return status will be placed
13  *  @length: length of buffer, must be multiple of 4 bytes
14  *  @timeout: time in ms to wait for command completion
15  *
16  *  Communicates with the manageability block. On success return 0
17  *  else returns semaphore error when encountering an error acquiring
18  *  semaphore or NGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
19  *
20  *  This function assumes that the NGBE_MNGSEM_SWMBX semaphore is held
21  *  by the caller.
22  **/
23 static s32
24 ngbe_hic_unlocked(struct ngbe_hw *hw, u32 *buffer, u32 length, u32 timeout)
25 {
26         u32 value, loop;
27         u16 i, dword_len;
28
29         DEBUGFUNC("ngbe_hic_unlocked");
30
31         if (!length || length > NGBE_PMMBX_BSIZE) {
32                 DEBUGOUT("Buffer length failure buffersize=%d.\n", length);
33                 return NGBE_ERR_HOST_INTERFACE_COMMAND;
34         }
35
36         /* Calculate length in DWORDs. We must be DWORD aligned */
37         if (length % sizeof(u32)) {
38                 DEBUGOUT("Buffer length failure, not aligned to dword");
39                 return NGBE_ERR_INVALID_ARGUMENT;
40         }
41
42         dword_len = length >> 2;
43
44         /* The device driver writes the relevant command block
45          * into the ram area.
46          */
47         for (i = 0; i < dword_len; i++) {
48                 wr32a(hw, NGBE_MNGMBX, i, cpu_to_le32(buffer[i]));
49                 buffer[i] = rd32a(hw, NGBE_MNGMBX, i);
50         }
51         ngbe_flush(hw);
52
53         /* Setting this bit tells the ARC that a new command is pending. */
54         wr32m(hw, NGBE_MNGMBXCTL,
55               NGBE_MNGMBXCTL_SWRDY, NGBE_MNGMBXCTL_SWRDY);
56
57         /* Check command completion */
58         loop = po32m(hw, NGBE_MNGMBXCTL,
59                 NGBE_MNGMBXCTL_FWRDY, NGBE_MNGMBXCTL_FWRDY,
60                 &value, timeout, 1000);
61         if (!loop || !(value & NGBE_MNGMBXCTL_FWACK)) {
62                 DEBUGOUT("Command has failed with no status valid.\n");
63                 return NGBE_ERR_HOST_INTERFACE_COMMAND;
64         }
65
66         return 0;
67 }
68
69 /**
70  *  ngbe_host_interface_command - Issue command to manageability block
71  *  @hw: pointer to the HW structure
72  *  @buffer: contains the command to write and where the return status will
73  *   be placed
74  *  @length: length of buffer, must be multiple of 4 bytes
75  *  @timeout: time in ms to wait for command completion
76  *  @return_data: read and return data from the buffer (true) or not (false)
77  *   Needed because FW structures are big endian and decoding of
78  *   these fields can be 8 bit or 16 bit based on command. Decoding
79  *   is not easily understood without making a table of commands.
80  *   So we will leave this up to the caller to read back the data
81  *   in these cases.
82  *
83  *  Communicates with the manageability block. On success return 0
84  *  else returns semaphore error when encountering an error acquiring
85  *  semaphore or NGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
86  **/
87 static s32
88 ngbe_host_interface_command(struct ngbe_hw *hw, u32 *buffer,
89                                  u32 length, u32 timeout, bool return_data)
90 {
91         u32 hdr_size = sizeof(struct ngbe_hic_hdr);
92         struct ngbe_hic_hdr *resp = (struct ngbe_hic_hdr *)buffer;
93         u16 buf_len;
94         s32 err;
95         u32 bi;
96         u32 dword_len;
97
98         DEBUGFUNC("ngbe_host_interface_command");
99
100         if (length == 0 || length > NGBE_PMMBX_BSIZE) {
101                 DEBUGOUT("Buffer length failure buffersize=%d.\n", length);
102                 return NGBE_ERR_HOST_INTERFACE_COMMAND;
103         }
104
105         /* Take management host interface semaphore */
106         err = hw->mac.acquire_swfw_sync(hw, NGBE_MNGSEM_SWMBX);
107         if (err)
108                 return err;
109
110         err = ngbe_hic_unlocked(hw, buffer, length, timeout);
111         if (err)
112                 goto rel_out;
113
114         if (!return_data)
115                 goto rel_out;
116
117         /* Calculate length in DWORDs */
118         dword_len = hdr_size >> 2;
119
120         /* first pull in the header so we know the buffer length */
121         for (bi = 0; bi < dword_len; bi++)
122                 buffer[bi] = rd32a(hw, NGBE_MNGMBX, bi);
123
124         /*
125          * If there is any thing in data position pull it in
126          * Read Flash command requires reading buffer length from
127          * two byes instead of one byte
128          */
129         if (resp->cmd == 0x30) {
130                 for (; bi < dword_len + 2; bi++)
131                         buffer[bi] = rd32a(hw, NGBE_MNGMBX, bi);
132
133                 buf_len = (((u16)(resp->cmd_or_resp.ret_status) << 3)
134                                   & 0xF00) | resp->buf_len;
135                 hdr_size += (2 << 2);
136         } else {
137                 buf_len = resp->buf_len;
138         }
139         if (!buf_len)
140                 goto rel_out;
141
142         if (length < buf_len + hdr_size) {
143                 DEBUGOUT("Buffer not large enough for reply message.\n");
144                 err = NGBE_ERR_HOST_INTERFACE_COMMAND;
145                 goto rel_out;
146         }
147
148         /* Calculate length in DWORDs, add 3 for odd lengths */
149         dword_len = (buf_len + 3) >> 2;
150
151         /* Pull in the rest of the buffer (bi is where we left off) */
152         for (; bi <= dword_len; bi++)
153                 buffer[bi] = rd32a(hw, NGBE_MNGMBX, bi);
154
155 rel_out:
156         hw->mac.release_swfw_sync(hw, NGBE_MNGSEM_SWMBX);
157
158         return err;
159 }
160
161 s32 ngbe_hic_check_cap(struct ngbe_hw *hw)
162 {
163         struct ngbe_hic_read_shadow_ram command;
164         s32 err;
165         int i;
166
167         DEBUGFUNC("\n");
168
169         command.hdr.req.cmd = FW_EEPROM_CHECK_STATUS;
170         command.hdr.req.buf_lenh = 0;
171         command.hdr.req.buf_lenl = 0;
172         command.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
173
174         /* convert offset from words to bytes */
175         command.address = 0;
176         /* one word */
177         command.length = 0;
178
179         for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
180                 err = ngbe_host_interface_command(hw, (u32 *)&command,
181                                 sizeof(command),
182                                 NGBE_HI_COMMAND_TIMEOUT, true);
183                 if (err)
184                         continue;
185
186                 command.hdr.rsp.ret_status &= 0x1F;
187                 if (command.hdr.rsp.ret_status !=
188                         FW_CEM_RESP_STATUS_SUCCESS)
189                         err = NGBE_ERR_HOST_INTERFACE_COMMAND;
190
191                 break;
192         }
193
194         if (!err && command.address != FW_CHECKSUM_CAP_ST_PASS)
195                 err = NGBE_ERR_EEPROM_CHECKSUM;
196
197         return err;
198 }