1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2015-2020
5 #include "txgbe_type.h"
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.
16 txgbe_calculate_checksum(u8 *buffer, u32 length)
21 for (i = 0; i < length; i++)
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
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.
38 * This function assumes that the TXGBE_MNGSEM_SWMBX semaphore is held
42 txgbe_hic_unlocked(struct txgbe_hw *hw, u32 *buffer, u32 length, u32 timeout)
47 DEBUGFUNC("txgbe_hic_unlocked");
49 if (!length || length > TXGBE_PMMBX_BSIZE) {
50 DEBUGOUT("Buffer length failure buffersize=%d.\n", length);
51 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
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;
60 dword_len = length >> 2;
62 /* The device driver writes the relevant command block
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);
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);
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;
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
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
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.
106 txgbe_host_interface_command(struct txgbe_hw *hw, u32 *buffer,
107 u32 length, u32 timeout, bool return_data)
109 u32 hdr_size = sizeof(struct txgbe_hic_hdr);
110 struct txgbe_hic_hdr *resp = (struct txgbe_hic_hdr *)buffer;
116 DEBUGFUNC("txgbe_host_interface_command");
118 if (length == 0 || length > TXGBE_PMMBX_BSIZE) {
119 DEBUGOUT("Buffer length failure buffersize=%d.\n", length);
120 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
123 /* Take management host interface semaphore */
124 err = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWMBX);
128 err = txgbe_hic_unlocked(hw, buffer, length, timeout);
135 /* Calculate length in DWORDs */
136 dword_len = hdr_size >> 2;
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);
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
147 if (resp->cmd == 0x30) {
148 for (; bi < dword_len + 2; bi++)
149 buffer[bi] = rd32a(hw, TXGBE_MNGMBX, bi);
151 buf_len = (((u16)(resp->cmd_or_resp.ret_status) << 3)
152 & 0xF00) | resp->buf_len;
153 hdr_size += (2 << 2);
155 buf_len = resp->buf_len;
160 if (length < buf_len + hdr_size) {
161 DEBUGOUT("Buffer not large enough for reply message.\n");
162 err = TXGBE_ERR_HOST_INTERFACE_COMMAND;
166 /* Calculate length in DWORDs, add 3 for odd lengths */
167 dword_len = (buf_len + 3) >> 2;
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);
174 hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWMBX);
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
186 * Reads a 16 bit word from the EEPROM using the hostif.
188 s32 txgbe_hic_sr_read(struct txgbe_hw *hw, u32 addr, u8 *buf, int len)
190 struct txgbe_hic_read_shadow_ram command;
192 int err, i = 0, j = 0;
194 if (len > TXGBE_PMMBX_DATA_SIZE)
195 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
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);
205 err = txgbe_hic_unlocked(hw, (u32 *)&command,
206 sizeof(command), TXGBE_HI_COMMAND_TIMEOUT);
210 while (i < (len >> 2)) {
211 value = rd32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + i);
212 ((u32 *)buf)[i] = value;
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++];
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
229 * Write a 16 bit word to the EEPROM using the hostif.
231 s32 txgbe_hic_sr_write(struct txgbe_hw *hw, u32 addr, u8 *buf, int len)
233 struct txgbe_hic_write_shadow_ram command;
235 int err = 0, i = 0, j = 0;
237 if (len > TXGBE_PMMBX_DATA_SIZE)
238 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
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);
248 while (i < (len >> 2)) {
249 value = ((u32 *)buf)[i];
250 wr32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + i, value);
254 for (i <<= 2; i < len; i++)
255 ((u8 *)&value)[j++] = ((u8 *)buf)[i];
257 wr32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + (i >> 2), value);
259 UNREFERENCED_PARAMETER(&command);
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
272 * @driver_ver: unused
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.
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)
283 struct txgbe_hic_drv_info fw_cmd;
287 DEBUGFUNC("txgbe_hic_set_drv_ver");
288 UNREFERENCED_PARAMETER(len, driver_ver);
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;
301 fw_cmd.hdr.checksum = txgbe_calculate_checksum((u8 *)&fw_cmd,
302 (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
304 for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
305 ret_val = txgbe_host_interface_command(hw, (u32 *)&fw_cmd,
307 TXGBE_HI_COMMAND_TIMEOUT,
312 if (fw_cmd.hdr.cmd_or_resp.ret_status ==
313 FW_CEM_RESP_STATUS_SUCCESS)
316 ret_val = TXGBE_ERR_HOST_INTERFACE_COMMAND;
325 * txgbe_hic_reset - send reset cmd to fw
326 * @hw: pointer to hardware structure
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.
334 txgbe_hic_reset(struct txgbe_hw *hw)
336 struct txgbe_hic_reset reset_cmd;
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));
351 for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
352 err = txgbe_host_interface_command(hw, (u32 *)&reset_cmd,
354 TXGBE_HI_COMMAND_TIMEOUT,
359 if (reset_cmd.hdr.cmd_or_resp.ret_status ==
360 FW_CEM_RESP_STATUS_SUCCESS)
363 err = TXGBE_ERR_HOST_INTERFACE_COMMAND;
372 * txgbe_mng_present - returns true when management capability is present
373 * @hw: pointer to hardware structure
376 txgbe_mng_present(struct txgbe_hw *hw)
378 if (hw->mac.type == txgbe_mac_unknown)
381 return !!rd32m(hw, TXGBE_STAT, TXGBE_STAT_MNGINIT);
385 * txgbe_mng_enabled - Is the manageability engine enabled?
386 * @hw: pointer to hardware structure
388 * Returns true if the manageability engine is enabled.
391 txgbe_mng_enabled(struct txgbe_hw *hw)
393 UNREFERENCED_PARAMETER(hw);
394 /* firmware does not control laser */