/** * e1000_mng_write_cmd_header_generic - Writes manageability command header * @hw: pointer to the HW structure * @hdr: pointer to the host interface command header * * Writes the command header after does the checksum calculation. **/ s32 e1000_mng_write_cmd_header_generic(struct e1000_hw * hw, struct e1000_host_mng_command_header * hdr) { u16 i, length = sizeof(struct e1000_host_mng_command_header); DEBUGFUNC("e1000_mng_write_cmd_header_generic"); /* Write the whole command header structure with new checksum. */ hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length); length >>= 2; /* Write the relevant command block into the ram area. */ for (i = 0; i < length; i++) { E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i, *((u32 *) hdr + i)); E1000_WRITE_FLUSH(hw); } return E1000_SUCCESS; }
/** * e1000_mng_host_if_write_generic - Write to the manageability host interface * @hw: pointer to the HW structure * @buffer: pointer to the host interface buffer * @length: size of the buffer * @offset: location in the buffer to write to * @sum: sum of the data (not checksum) * * This function writes the buffer content at the offset given on the host if. * It also does alignment considerations to do the writes in most efficient * way. Also fills up the sum of the buffer in *buffer parameter. **/ s32 e1000_mng_host_if_write_generic(struct e1000_hw * hw, u8 *buffer, u16 length, u16 offset, u8 *sum) { u8 *tmp; u8 *bufptr = buffer; u32 data = 0; s32 ret_val = E1000_SUCCESS; u16 remaining, i, j, prev_bytes; DEBUGFUNC("e1000_mng_host_if_write_generic"); /* sum = only sum of the data and it is not checksum */ if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) { ret_val = -E1000_ERR_PARAM; goto out; } tmp = (u8 *)&data; prev_bytes = offset & 0x3; offset >>= 2; if (prev_bytes) { data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset); for (j = prev_bytes; j < sizeof(u32); j++) { *(tmp + j) = *bufptr++; *sum += *(tmp + j); } E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data); length -= j - prev_bytes; offset++; } remaining = length & 0x3; length -= remaining; /* Calculate length in DWORDs */ length >>= 2; /* * The device driver writes the relevant command block into the * ram area. */ for (i = 0; i < length; i++) { for (j = 0; j < sizeof(u32); j++) { *(tmp + j) = *bufptr++; *sum += *(tmp + j); } E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data); } if (remaining) { for (j = 0; j < sizeof(u32); j++) { if (j < remaining) *(tmp + j) = *bufptr++; else *(tmp + j) = 0; *sum += *(tmp + j); } E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data); } out: return ret_val; }
/** * e1000_host_interface_command - Writes buffer to host interface * @hw: pointer to the HW structure * @buffer: contains a command to write * @length: the byte length of the buffer, must be multiple of 4 bytes * * Writes a buffer to the Host Interface. Upon success, returns E1000_SUCCESS * else returns E1000_ERR_HOST_INTERFACE_COMMAND. **/ s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length) { u32 hicr, i; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_host_interface_command"); if (!(hw->mac.arc_subsystem_valid)) { DEBUGOUT("Hardware doesn't support host interface command.\n"); goto out; } if (!hw->mac.asf_firmware_present) { DEBUGOUT("Firmware is not present.\n"); goto out; } if (length == 0 || length & 0x3 || length > E1000_HI_MAX_BLOCK_BYTE_LENGTH) { DEBUGOUT("Buffer length failure.\n"); ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; goto out; } /* Check that the host interface is enabled. */ hicr = E1000_READ_REG(hw, E1000_HICR); if ((hicr & E1000_HICR_EN) == 0) { DEBUGOUT("E1000_HOST_EN bit disabled.\n"); ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; goto out; } /* Calculate length in DWORDs */ length >>= 2; /* * The device driver writes the relevant command block * into the ram area. */ for (i = 0; i < length; i++) E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i, *((u32 *)buffer + i)); /* Setting this bit tells the ARC that a new command is pending. */ E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C); for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) { hicr = E1000_READ_REG(hw, E1000_HICR); if (!(hicr & E1000_HICR_C)) break; msec_delay(1); } /* Check command successful completion. */ if (i == E1000_HI_COMMAND_TIMEOUT || (!(E1000_READ_REG(hw, E1000_HICR) & E1000_HICR_SV))) { DEBUGOUT("Command has failed with no status valid.\n"); ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; goto out; } for (i = 0; i < length; i++) *((u32 *)buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i); out: return ret_val; }