_CPU_TO_LE16(IXGBE_ACI_FLAG_BUF)) { + if ((buf && buf_size == 0) || + (buf == NULL && buf_size)) { + status = IXGBE_ERR_PARAM; + break; + } + if (buf && buf_size) + valid_buf = true; + } + + if (valid_buf == true) { + if (buf_size % 4 == 0) + tmp_buf_size = buf_size; + else + tmp_buf_size = (buf_size & (u16)(~0x03)) + 4; + + tmp_buf = (u32*)ixgbe_malloc(hw, tmp_buf_size); + if (!tmp_buf) + return IXGBE_ERR_OUT_OF_MEM; + + /* tmp_buf will be firstly filled with 0xFF and after + * that the content of buf will be written into it. + * This approach lets us use valid buf_size and + * prevents us from reading past buf area + * when buf_size mod 4 not equal to 0. + */ + memset(tmp_buf, 0xFF, tmp_buf_size); + memcpy(tmp_buf, buf, buf_size); + + if (tmp_buf_size > IXGBE_ACI_LG_BUF) + desc->flags |= + IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_LB); + + desc->datalen = IXGBE_CPU_TO_LE16(buf_size); + + if (desc->flags & IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD)) { + for (i = 0; i < tmp_buf_size / 4; i++) { + IXGBE_WRITE_REG(hw, PF_HIBA(i), + IXGBE_LE32_TO_CPU(tmp_buf[i])); + } + } + } + + /* Descriptor is written to specific registers */ + for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++) + IXGBE_WRITE_REG(hw, PF_HIDA(i), + IXGBE_LE32_TO_CPU(raw_desc[i])); + + /* SW has to set PF_HICR.C bit and clear PF_HICR.SV and + * PF_HICR_EV + */ + hicr = IXGBE_READ_REG(hw, PF_HICR); + hicr = (hicr | PF_HICR_C) & ~(PF_HICR_SV | PF_HICR_EV); + IXGBE_WRITE_REG(hw, PF_HICR, hicr); + + /* Wait for sync Admin Command response */ + for (i = 0; i < IXGBE_ACI_SYNC_RESPONSE_TIMEOUT; i += 1) { + hicr = IXGBE_READ_REG(hw, PF_HICR); + if ((hicr & PF_HICR_SV) || !(hicr & PF_HICR_C)) + break; + + msec_delay(1); + } + + /* Wait for async Admin Command response */ + if ((hicr & PF_HICR_SV) && (hicr & PF_HICR_C)) { + for (i = 0; i < IXGBE_ACI_ASYNC_RESPONSE_TIMEOUT; + i += 1) { + hicr = IXGBE_READ_REG(hw, PF_HICR); + if ((hicr & PF_HICR_EV) || !(hicr & PF_HICR_C)) + break; + + msec_delay(1); + } + } + + /* Read sync Admin Command response */ + if ((hicr & PF_HICR_SV)) { + for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++) { + raw_desc[i] = IXGBE_READ_REG(hw, PF_HIDA(i)); + raw_desc[i] = IXGBE_CPU_TO_LE32(raw_desc[i]); + } + } + + /* Read async Admin Command response */ + if ((hicr & PF_HICR_EV) && !(hicr & PF_HICR_C)) { + for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++) { + raw_desc[i] = IXGBE_READ_REG(hw, PF_HIDA_2(i)); *** 8203 LINES SKIPPED ***