/** * e1000_mng_host_if_write - 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(struct e1000_hw *hw, u8 *buffer, u16 length, u16 offset, u8 *sum) { u8 *tmp; u8 *bufptr = buffer; u32 data = 0; u16 remaining, i, j, prev_bytes; /* sum = only sum of the data and it is not checksum */ if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) return -E1000_ERR_PARAM; tmp = (u8 *)&data; prev_bytes = offset & 0x3; offset >>= 2; if (prev_bytes) { data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset); for (j = prev_bytes; j < sizeof(u32); j++) { *(tmp + j) = *bufptr++; *sum += *(tmp + j); } E1000_WRITE_REG_ARRAY(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(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(hw, E1000_HOST_IF, offset + i, data); } return 0; }
/** * e1000_read_mbx_pf - Read a message from the mailbox * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer * @vf_number: the VF index * * This function copies a message from the mailbox buffer to the caller's * memory buffer. The presumption is that the caller knows that there was * a message due to a VF request so no polling for message is needed. **/ static s32 e1000_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, u16 vf_number) { s32 ret_val; u16 i; DEBUGFUNC("e1000_read_mbx_pf"); /* lock the mailbox to prevent pf/vf race condition */ ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number); if (ret_val) goto out_no_read; /* copy the message to the mailbox memory buffer */ for (i = 0; i < size; i++) msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i); /* Acknowledge the message and release buffer */ E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK); /* update stats */ hw->mbx.stats.msgs_rx++; out_no_read: return ret_val; }
/** * e1000_read_mbx_vf - Reads a message from the inbox intended for vf * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer * @mbx_id: id of mailbox to read * * returns SUCCESS if it successfuly read message from buffer **/ static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size, u16 E1000_UNUSEDARG mbx_id) { s32 ret_val = E1000_SUCCESS; u16 i; DEBUGFUNC("e1000_read_mbx_vf"); /* lock the mailbox to prevent pf/vf race condition */ ret_val = e1000_obtain_mbx_lock_vf(hw); if (ret_val) goto out_no_read; /* copy the message from the mailbox memory buffer */ for (i = 0; i < size; i++) msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(0), i); /* Acknowledge receipt and release mailbox, then we're done */ E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_ACK); /* update stats */ hw->mbx.stats.msgs_rx++; out_no_read: return ret_val; }
/** * e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx * @hw: pointer to the HW structure * * Enables packet filtering on transmit packets if manageability is enabled * and host interface is enabled. **/ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) { struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie; u32 *buffer = (u32 *)&hw->mng_cookie; u32 offset; s32 ret_val, hdr_csum, csum; u8 i, len; hw->mac.tx_pkt_filtering = true; /* No manageability, no filtering */ if (!hw->mac.ops.check_mng_mode(hw)) { hw->mac.tx_pkt_filtering = false; return hw->mac.tx_pkt_filtering; } /* * If we can't read from the host interface for whatever * reason, disable filtering. */ ret_val = hw->mac.ops.mng_enable_host_if(hw); if (ret_val) { hw->mac.tx_pkt_filtering = false; return hw->mac.tx_pkt_filtering; } /* Read in the header. Length and offset are in dwords. */ len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2; offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2; for (i = 0; i < len; i++) *(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset + i); hdr_csum = hdr->checksum; hdr->checksum = 0; csum = e1000_calculate_checksum((u8 *)hdr, E1000_MNG_DHCP_COOKIE_LENGTH); /* * If either the checksums or signature don't match, then * the cookie area isn't considered valid, in which case we * take the safe route of assuming Tx filtering is enabled. */ if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { hw->mac.tx_pkt_filtering = true; return hw->mac.tx_pkt_filtering; } /* Cookie area is valid, make the final check for filtering. */ if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) hw->mac.tx_pkt_filtering = false; return hw->mac.tx_pkt_filtering; }
/** * e1000_write_vfta_82543 - Write value to VLAN filter table * @hw: pointer to the HW structure * @offset: the 32-bit offset in which to write the value to. * @value: the 32-bit value to write at location offset. * * This writes a 32-bit value to a 32-bit offset in the VLAN filter * table. **/ static void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value) { u32 temp; DEBUGFUNC("e1000_write_vfta_82543"); if ((hw->mac.type == e1000_82544) && (offset & 1)) { temp = E1000_READ_REG_ARRAY(hw, E1000_VFTA, offset - 1); E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value); E1000_WRITE_FLUSH(hw); E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset - 1, temp); E1000_WRITE_FLUSH(hw); } else { e1000_write_vfta_generic(hw, offset, value); } }
static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data, int reg, int offset, u32 mask, u32 write) { u32 pat, val; static const u32 test[] = { 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; for (pat = 0; pat < ARRAY_SIZE(test); pat++) { E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset, (test[pat] & write)); val = E1000_READ_REG_ARRAY(&adapter->hw, reg, offset); if (val != (test[pat] & write & mask)) { e_err("pattern test reg %04X failed: got 0x%08X expected 0x%08X\n", reg + offset, val, (test[pat] & write & mask)); *data = reg; return 1; } } return 0; }