1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2015-2020 Beijing WangXun Technology Co., Ltd.
3 * Copyright(c) 2010-2017 Intel Corporation
6 #include "txgbe_type.h"
10 * txgbe_calculate_checksum - Calculate checksum for buffer
11 * @buffer: pointer to EEPROM
12 * @length: size of EEPROM to calculate a checksum for
13 * Calculates the checksum for some buffer on a specified length. The
14 * checksum calculated is returned.
17 txgbe_calculate_checksum(u8 *buffer, u32 length)
22 for (i = 0; i < length; i++)
29 * txgbe_hic_unlocked - Issue command to manageability block unlocked
30 * @hw: pointer to the HW structure
31 * @buffer: command to write and where the return status will be placed
32 * @length: length of buffer, must be multiple of 4 bytes
33 * @timeout: time in ms to wait for command completion
35 * Communicates with the manageability block. On success return 0
36 * else returns semaphore error when encountering an error acquiring
37 * semaphore or TXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
39 * This function assumes that the TXGBE_MNGSEM_SWMBX semaphore is held
43 txgbe_hic_unlocked(struct txgbe_hw *hw, u32 *buffer, u32 length, u32 timeout)
48 DEBUGFUNC("txgbe_hic_unlocked");
50 if (!length || length > TXGBE_PMMBX_BSIZE) {
51 DEBUGOUT("Buffer length failure buffersize=%d.\n", length);
52 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
55 /* Calculate length in DWORDs. We must be DWORD aligned */
56 if (length % sizeof(u32)) {
57 DEBUGOUT("Buffer length failure, not aligned to dword");
58 return TXGBE_ERR_INVALID_ARGUMENT;
61 dword_len = length >> 2;
63 /* The device driver writes the relevant command block
66 for (i = 0; i < dword_len; i++) {
67 wr32a(hw, TXGBE_MNGMBX, i, cpu_to_le32(buffer[i]));
68 buffer[i] = rd32a(hw, TXGBE_MNGMBX, i);
72 /* Setting this bit tells the ARC that a new command is pending. */
73 wr32m(hw, TXGBE_MNGMBXCTL,
74 TXGBE_MNGMBXCTL_SWRDY, TXGBE_MNGMBXCTL_SWRDY);
76 /* Check command completion */
77 loop = po32m(hw, TXGBE_MNGMBXCTL,
78 TXGBE_MNGMBXCTL_FWRDY, TXGBE_MNGMBXCTL_FWRDY,
79 &value, timeout, 1000);
80 if (!loop || !(value & TXGBE_MNGMBXCTL_FWACK)) {
81 DEBUGOUT("Command has failed with no status valid.\n");
82 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
89 * txgbe_host_interface_command - Issue command to manageability block
90 * @hw: pointer to the HW structure
91 * @buffer: contains the command to write and where the return status will
93 * @length: length of buffer, must be multiple of 4 bytes
94 * @timeout: time in ms to wait for command completion
95 * @return_data: read and return data from the buffer (true) or not (false)
96 * Needed because FW structures are big endian and decoding of
97 * these fields can be 8 bit or 16 bit based on command. Decoding
98 * is not easily understood without making a table of commands.
99 * So we will leave this up to the caller to read back the data
102 * Communicates with the manageability block. On success return 0
103 * else returns semaphore error when encountering an error acquiring
104 * semaphore or TXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
107 txgbe_host_interface_command(struct txgbe_hw *hw, u32 *buffer,
108 u32 length, u32 timeout, bool return_data)
110 u32 hdr_size = sizeof(struct txgbe_hic_hdr);
111 struct txgbe_hic_hdr *resp = (struct txgbe_hic_hdr *)buffer;
117 DEBUGFUNC("txgbe_host_interface_command");
119 if (length == 0 || length > TXGBE_PMMBX_BSIZE) {
120 DEBUGOUT("Buffer length failure buffersize=%d.\n", length);
121 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
124 /* Take management host interface semaphore */
125 err = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWMBX);
129 err = txgbe_hic_unlocked(hw, buffer, length, timeout);
136 /* Calculate length in DWORDs */
137 dword_len = hdr_size >> 2;
139 /* first pull in the header so we know the buffer length */
140 for (bi = 0; bi < dword_len; bi++)
141 buffer[bi] = rd32a(hw, TXGBE_MNGMBX, bi);
144 * If there is any thing in data position pull it in
145 * Read Flash command requires reading buffer length from
146 * two byes instead of one byte
148 if (resp->cmd == 0x30) {
149 for (; bi < dword_len + 2; bi++)
150 buffer[bi] = rd32a(hw, TXGBE_MNGMBX, bi);
152 buf_len = (((u16)(resp->cmd_or_resp.ret_status) << 3)
153 & 0xF00) | resp->buf_len;
154 hdr_size += (2 << 2);
156 buf_len = resp->buf_len;
161 if (length < buf_len + hdr_size) {
162 DEBUGOUT("Buffer not large enough for reply message.\n");
163 err = TXGBE_ERR_HOST_INTERFACE_COMMAND;
167 /* Calculate length in DWORDs, add 3 for odd lengths */
168 dword_len = (buf_len + 3) >> 2;
170 /* Pull in the rest of the buffer (bi is where we left off) */
171 for (; bi <= dword_len; bi++)
172 buffer[bi] = rd32a(hw, TXGBE_MNGMBX, bi);
175 hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWMBX);
181 * txgbe_hic_sr_read - Read EEPROM word using a host interface cmd
182 * assuming that the semaphore is already obtained.
183 * @hw: pointer to hardware structure
184 * @offset: offset of word in the EEPROM to read
185 * @data: word read from the EEPROM
187 * Reads a 16 bit word from the EEPROM using the hostif.
189 s32 txgbe_hic_sr_read(struct txgbe_hw *hw, u32 addr, u8 *buf, int len)
191 struct txgbe_hic_read_shadow_ram command;
193 int err, i = 0, j = 0;
195 if (len > TXGBE_PMMBX_DATA_SIZE)
196 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
198 memset(&command, 0, sizeof(command));
199 command.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
200 command.hdr.req.buf_lenh = 0;
201 command.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
202 command.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
203 command.address = cpu_to_be32(addr);
204 command.length = cpu_to_be16(len);
206 err = txgbe_hic_unlocked(hw, (u32 *)&command,
207 sizeof(command), TXGBE_HI_COMMAND_TIMEOUT);
211 while (i < (len >> 2)) {
212 value = rd32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + i);
213 ((u32 *)buf)[i] = value;
217 value = rd32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + i);
218 for (i <<= 2; i < len; i++)
219 ((u8 *)buf)[i] = ((u8 *)&value)[j++];
225 * txgbe_hic_sr_write - Write EEPROM word using hostif
226 * @hw: pointer to hardware structure
227 * @offset: offset of word in the EEPROM to write
228 * @data: word write to the EEPROM
230 * Write a 16 bit word to the EEPROM using the hostif.
232 s32 txgbe_hic_sr_write(struct txgbe_hw *hw, u32 addr, u8 *buf, int len)
234 struct txgbe_hic_write_shadow_ram command;
236 int err = 0, i = 0, j = 0;
238 if (len > TXGBE_PMMBX_DATA_SIZE)
239 return TXGBE_ERR_HOST_INTERFACE_COMMAND;
241 memset(&command, 0, sizeof(command));
242 command.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
243 command.hdr.req.buf_lenh = 0;
244 command.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
245 command.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
246 command.address = cpu_to_be32(addr);
247 command.length = cpu_to_be16(len);
249 while (i < (len >> 2)) {
250 value = ((u32 *)buf)[i];
251 wr32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + i, value);
255 for (i <<= 2; i < len; i++)
256 ((u8 *)&value)[j++] = ((u8 *)buf)[i];
258 wr32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + (i >> 2), value);
260 UNREFERENCED_PARAMETER(&command);
266 * txgbe_hic_set_drv_ver - Sends driver version to firmware
267 * @hw: pointer to the HW structure
268 * @maj: driver version major number
269 * @min: driver version minor number
270 * @build: driver version build number
271 * @sub: driver version sub build number
273 * @driver_ver: unused
275 * Sends driver version number to firmware through the manageability
276 * block. On success return 0
277 * else returns TXGBE_ERR_SWFW_SYNC when encountering an error acquiring
278 * semaphore or TXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
280 s32 txgbe_hic_set_drv_ver(struct txgbe_hw *hw, u8 maj, u8 min,
281 u8 build, u8 sub, u16 len,
282 const char *driver_ver)
284 struct txgbe_hic_drv_info fw_cmd;
288 DEBUGFUNC("txgbe_hic_set_drv_ver");
289 UNREFERENCED_PARAMETER(len, driver_ver);
291 fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
292 fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN;
293 fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
294 fw_cmd.port_num = (u8)hw->bus.func;
295 fw_cmd.ver_maj = maj;
296 fw_cmd.ver_min = min;
297 fw_cmd.ver_build = build;
298 fw_cmd.ver_sub = sub;
299 fw_cmd.hdr.checksum = 0;
302 fw_cmd.hdr.checksum = txgbe_calculate_checksum((u8 *)&fw_cmd,
303 (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
305 for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
306 ret_val = txgbe_host_interface_command(hw, (u32 *)&fw_cmd,
308 TXGBE_HI_COMMAND_TIMEOUT,
313 if (fw_cmd.hdr.cmd_or_resp.ret_status ==
314 FW_CEM_RESP_STATUS_SUCCESS)
317 ret_val = TXGBE_ERR_HOST_INTERFACE_COMMAND;
326 * txgbe_hic_reset - send reset cmd to fw
327 * @hw: pointer to hardware structure
329 * Sends reset cmd to firmware through the manageability
330 * block. On success return 0
331 * else returns TXGBE_ERR_SWFW_SYNC when encountering an error acquiring
332 * semaphore or TXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
335 txgbe_hic_reset(struct txgbe_hw *hw)
337 struct txgbe_hic_reset reset_cmd;
343 reset_cmd.hdr.cmd = FW_RESET_CMD;
344 reset_cmd.hdr.buf_len = FW_RESET_LEN;
345 reset_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
346 reset_cmd.lan_id = hw->bus.lan_id;
347 reset_cmd.reset_type = (u16)hw->reset_type;
348 reset_cmd.hdr.checksum = 0;
349 reset_cmd.hdr.checksum = txgbe_calculate_checksum((u8 *)&reset_cmd,
350 (FW_CEM_HDR_LEN + reset_cmd.hdr.buf_len));
352 for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
353 err = txgbe_host_interface_command(hw, (u32 *)&reset_cmd,
355 TXGBE_HI_COMMAND_TIMEOUT,
360 if (reset_cmd.hdr.cmd_or_resp.ret_status ==
361 FW_CEM_RESP_STATUS_SUCCESS)
364 err = TXGBE_ERR_HOST_INTERFACE_COMMAND;
373 * txgbe_mng_present - returns true when management capability is present
374 * @hw: pointer to hardware structure
377 txgbe_mng_present(struct txgbe_hw *hw)
379 if (hw->mac.type == txgbe_mac_unknown)
382 return !!rd32m(hw, TXGBE_STAT, TXGBE_STAT_MNGINIT);
386 * txgbe_mng_enabled - Is the manageability engine enabled?
387 * @hw: pointer to hardware structure
389 * Returns true if the manageability engine is enabled.
392 txgbe_mng_enabled(struct txgbe_hw *hw)
394 UNREFERENCED_PARAMETER(hw);
395 /* firmware does not control laser */