1e974f91cSConrad Meyer /*- 2e974f91cSConrad Meyer * Copyright (C) 2012 Intel Corporation 3e974f91cSConrad Meyer * All rights reserved. 4e974f91cSConrad Meyer * 5e974f91cSConrad Meyer * Redistribution and use in source and binary forms, with or without 6e974f91cSConrad Meyer * modification, are permitted provided that the following conditions 7e974f91cSConrad Meyer * are met: 8e974f91cSConrad Meyer * 1. Redistributions of source code must retain the above copyright 9e974f91cSConrad Meyer * notice, this list of conditions and the following disclaimer. 10e974f91cSConrad Meyer * 2. Redistributions in binary form must reproduce the above copyright 11e974f91cSConrad Meyer * notice, this list of conditions and the following disclaimer in the 12e974f91cSConrad Meyer * documentation and/or other materials provided with the distribution. 13e974f91cSConrad Meyer * 14e974f91cSConrad Meyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15e974f91cSConrad Meyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16e974f91cSConrad Meyer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17e974f91cSConrad Meyer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18e974f91cSConrad Meyer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19e974f91cSConrad Meyer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20e974f91cSConrad Meyer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21e974f91cSConrad Meyer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22e974f91cSConrad Meyer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23e974f91cSConrad Meyer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24e974f91cSConrad Meyer * SUCH DAMAGE. 25e974f91cSConrad Meyer */ 26e974f91cSConrad Meyer 27e974f91cSConrad Meyer __FBSDID("$FreeBSD$"); 28e974f91cSConrad Meyer 29e974f91cSConrad Meyer #ifndef __IOAT_INTERNAL_H__ 30e974f91cSConrad Meyer #define __IOAT_INTERNAL_H__ 31e974f91cSConrad Meyer 32374b05e1SConrad Meyer #include <sys/_task.h> 33374b05e1SConrad Meyer 34e974f91cSConrad Meyer #define DEVICE2SOFTC(dev) ((struct ioat_softc *) device_get_softc(dev)) 3543fc1847SConrad Meyer #define KTR_IOAT KTR_SPARE3 36e974f91cSConrad Meyer 37e974f91cSConrad Meyer #define ioat_read_chancnt(ioat) \ 38e974f91cSConrad Meyer ioat_read_1((ioat), IOAT_CHANCNT_OFFSET) 39e974f91cSConrad Meyer 40e974f91cSConrad Meyer #define ioat_read_xfercap(ioat) \ 41b81eee4aSConrad Meyer (ioat_read_1((ioat), IOAT_XFERCAP_OFFSET) & IOAT_XFERCAP_VALID_MASK) 42e974f91cSConrad Meyer 43e974f91cSConrad Meyer #define ioat_write_intrctrl(ioat, value) \ 44e974f91cSConrad Meyer ioat_write_1((ioat), IOAT_INTRCTRL_OFFSET, (value)) 45e974f91cSConrad Meyer 46e974f91cSConrad Meyer #define ioat_read_cbver(ioat) \ 47e974f91cSConrad Meyer (ioat_read_1((ioat), IOAT_CBVER_OFFSET) & 0xFF) 48e974f91cSConrad Meyer 49e974f91cSConrad Meyer #define ioat_read_dmacapability(ioat) \ 50e974f91cSConrad Meyer ioat_read_4((ioat), IOAT_DMACAPABILITY_OFFSET) 51e974f91cSConrad Meyer 52e974f91cSConrad Meyer #define ioat_write_chanctrl(ioat, value) \ 53e974f91cSConrad Meyer ioat_write_2((ioat), IOAT_CHANCTRL_OFFSET, (value)) 54e974f91cSConrad Meyer 55e974f91cSConrad Meyer static __inline uint64_t 56e974f91cSConrad Meyer ioat_bus_space_read_8_lower_first(bus_space_tag_t tag, 57e974f91cSConrad Meyer bus_space_handle_t handle, bus_size_t offset) 58e974f91cSConrad Meyer { 59e974f91cSConrad Meyer return (bus_space_read_4(tag, handle, offset) | 60e974f91cSConrad Meyer ((uint64_t)bus_space_read_4(tag, handle, offset + 4)) << 32); 61e974f91cSConrad Meyer } 62e974f91cSConrad Meyer 63e974f91cSConrad Meyer static __inline void 64e974f91cSConrad Meyer ioat_bus_space_write_8_lower_first(bus_space_tag_t tag, 65e974f91cSConrad Meyer bus_space_handle_t handle, bus_size_t offset, uint64_t val) 66e974f91cSConrad Meyer { 67e974f91cSConrad Meyer bus_space_write_4(tag, handle, offset, val); 68e974f91cSConrad Meyer bus_space_write_4(tag, handle, offset + 4, val >> 32); 69e974f91cSConrad Meyer } 70e974f91cSConrad Meyer 71f3e30f97SConrad Meyer #ifdef __i386__ 72e974f91cSConrad Meyer #define ioat_bus_space_read_8 ioat_bus_space_read_8_lower_first 73e974f91cSConrad Meyer #define ioat_bus_space_write_8 ioat_bus_space_write_8_lower_first 74e974f91cSConrad Meyer #else 75e974f91cSConrad Meyer #define ioat_bus_space_read_8(tag, handle, offset) \ 76e974f91cSConrad Meyer bus_space_read_8((tag), (handle), (offset)) 77e974f91cSConrad Meyer #define ioat_bus_space_write_8(tag, handle, offset, val) \ 78e974f91cSConrad Meyer bus_space_write_8((tag), (handle), (offset), (val)) 79e974f91cSConrad Meyer #endif 80e974f91cSConrad Meyer 81e974f91cSConrad Meyer #define ioat_read_1(ioat, offset) \ 82e974f91cSConrad Meyer bus_space_read_1((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \ 83e974f91cSConrad Meyer (offset)) 84e974f91cSConrad Meyer 85e974f91cSConrad Meyer #define ioat_read_2(ioat, offset) \ 86e974f91cSConrad Meyer bus_space_read_2((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \ 87e974f91cSConrad Meyer (offset)) 88e974f91cSConrad Meyer 89e974f91cSConrad Meyer #define ioat_read_4(ioat, offset) \ 90e974f91cSConrad Meyer bus_space_read_4((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \ 91e974f91cSConrad Meyer (offset)) 92e974f91cSConrad Meyer 93e974f91cSConrad Meyer #define ioat_read_8(ioat, offset) \ 94e974f91cSConrad Meyer ioat_bus_space_read_8((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \ 95e974f91cSConrad Meyer (offset)) 96e974f91cSConrad Meyer 97e974f91cSConrad Meyer #define ioat_read_double_4(ioat, offset) \ 98e974f91cSConrad Meyer ioat_bus_space_read_8_lower_first((ioat)->pci_bus_tag, \ 99e974f91cSConrad Meyer (ioat)->pci_bus_handle, (offset)) 100e974f91cSConrad Meyer 101e974f91cSConrad Meyer #define ioat_write_1(ioat, offset, value) \ 102e974f91cSConrad Meyer bus_space_write_1((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \ 103e974f91cSConrad Meyer (offset), (value)) 104e974f91cSConrad Meyer 105e974f91cSConrad Meyer #define ioat_write_2(ioat, offset, value) \ 106e974f91cSConrad Meyer bus_space_write_2((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \ 107e974f91cSConrad Meyer (offset), (value)) 108e974f91cSConrad Meyer 109e974f91cSConrad Meyer #define ioat_write_4(ioat, offset, value) \ 110e974f91cSConrad Meyer bus_space_write_4((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \ 111e974f91cSConrad Meyer (offset), (value)) 112e974f91cSConrad Meyer 113e974f91cSConrad Meyer #define ioat_write_8(ioat, offset, value) \ 114e974f91cSConrad Meyer ioat_bus_space_write_8((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \ 115e974f91cSConrad Meyer (offset), (value)) 116e974f91cSConrad Meyer 117e974f91cSConrad Meyer #define ioat_write_double_4(ioat, offset, value) \ 118e974f91cSConrad Meyer ioat_bus_space_write_8_lower_first((ioat)->pci_bus_tag, \ 119e974f91cSConrad Meyer (ioat)->pci_bus_handle, (offset), (value)) 120e974f91cSConrad Meyer 121e974f91cSConrad Meyer MALLOC_DECLARE(M_IOAT); 122e974f91cSConrad Meyer 123e974f91cSConrad Meyer SYSCTL_DECL(_hw_ioat); 124e974f91cSConrad Meyer 1251c25420eSConrad Meyer extern int g_ioat_debug_level; 126e974f91cSConrad Meyer 1279e3bbf26SConrad Meyer struct generic_dma_control { 1289e3bbf26SConrad Meyer uint32_t int_enable:1; 1299e3bbf26SConrad Meyer uint32_t src_snoop_disable:1; 1309e3bbf26SConrad Meyer uint32_t dest_snoop_disable:1; 1319e3bbf26SConrad Meyer uint32_t completion_update:1; 1329e3bbf26SConrad Meyer uint32_t fence:1; 1339e3bbf26SConrad Meyer uint32_t reserved1:1; 1349e3bbf26SConrad Meyer uint32_t src_page_break:1; 1359e3bbf26SConrad Meyer uint32_t dest_page_break:1; 1369e3bbf26SConrad Meyer uint32_t bundle:1; 1379e3bbf26SConrad Meyer uint32_t dest_dca:1; 1389e3bbf26SConrad Meyer uint32_t hint:1; 1399e3bbf26SConrad Meyer uint32_t reserved2:13; 1409e3bbf26SConrad Meyer uint32_t op:8; 1419e3bbf26SConrad Meyer }; 1429e3bbf26SConrad Meyer 1439e3bbf26SConrad Meyer struct ioat_generic_hw_descriptor { 1449e3bbf26SConrad Meyer uint32_t size; 1459e3bbf26SConrad Meyer union { 1469e3bbf26SConrad Meyer uint32_t control_raw; 1479e3bbf26SConrad Meyer struct generic_dma_control control_generic; 1489e3bbf26SConrad Meyer } u; 1499e3bbf26SConrad Meyer uint64_t src_addr; 1509e3bbf26SConrad Meyer uint64_t dest_addr; 1519e3bbf26SConrad Meyer uint64_t next; 1529e3bbf26SConrad Meyer uint64_t reserved[4]; 1539e3bbf26SConrad Meyer }; 1549e3bbf26SConrad Meyer 155e974f91cSConrad Meyer struct ioat_dma_hw_descriptor { 156e974f91cSConrad Meyer uint32_t size; 157e974f91cSConrad Meyer union { 158e974f91cSConrad Meyer uint32_t control_raw; 1599e3bbf26SConrad Meyer struct generic_dma_control control_generic; 160e974f91cSConrad Meyer struct { 161e974f91cSConrad Meyer uint32_t int_enable:1; 162e974f91cSConrad Meyer uint32_t src_snoop_disable:1; 163e974f91cSConrad Meyer uint32_t dest_snoop_disable:1; 164e974f91cSConrad Meyer uint32_t completion_update:1; 165e974f91cSConrad Meyer uint32_t fence:1; 166e974f91cSConrad Meyer uint32_t null:1; 167e974f91cSConrad Meyer uint32_t src_page_break:1; 168e974f91cSConrad Meyer uint32_t dest_page_break:1; 169e974f91cSConrad Meyer uint32_t bundle:1; 170e974f91cSConrad Meyer uint32_t dest_dca:1; 171e974f91cSConrad Meyer uint32_t hint:1; 172e974f91cSConrad Meyer uint32_t reserved:13; 173e974f91cSConrad Meyer #define IOAT_OP_COPY 0x00 174e974f91cSConrad Meyer uint32_t op:8; 175e974f91cSConrad Meyer } control; 176e974f91cSConrad Meyer } u; 177e974f91cSConrad Meyer uint64_t src_addr; 178e974f91cSConrad Meyer uint64_t dest_addr; 179e974f91cSConrad Meyer uint64_t next; 1809950fde0SConrad Meyer uint64_t next_src_addr; 1819950fde0SConrad Meyer uint64_t next_dest_addr; 182e974f91cSConrad Meyer uint64_t user1; 183e974f91cSConrad Meyer uint64_t user2; 184e974f91cSConrad Meyer }; 185e974f91cSConrad Meyer 186e974f91cSConrad Meyer struct ioat_fill_hw_descriptor { 187e974f91cSConrad Meyer uint32_t size; 188e974f91cSConrad Meyer union { 189e974f91cSConrad Meyer uint32_t control_raw; 1909e3bbf26SConrad Meyer struct generic_dma_control control_generic; 191e974f91cSConrad Meyer struct { 192e974f91cSConrad Meyer uint32_t int_enable:1; 193e974f91cSConrad Meyer uint32_t reserved:1; 194e974f91cSConrad Meyer uint32_t dest_snoop_disable:1; 195e974f91cSConrad Meyer uint32_t completion_update:1; 196e974f91cSConrad Meyer uint32_t fence:1; 197e974f91cSConrad Meyer uint32_t reserved2:2; 198e974f91cSConrad Meyer uint32_t dest_page_break:1; 199e974f91cSConrad Meyer uint32_t bundle:1; 200e974f91cSConrad Meyer uint32_t reserved3:15; 201e974f91cSConrad Meyer #define IOAT_OP_FILL 0x01 202e974f91cSConrad Meyer uint32_t op:8; 203e974f91cSConrad Meyer } control; 204e974f91cSConrad Meyer } u; 205e974f91cSConrad Meyer uint64_t src_data; 206e974f91cSConrad Meyer uint64_t dest_addr; 207e974f91cSConrad Meyer uint64_t next; 208e974f91cSConrad Meyer uint64_t reserved; 209e974f91cSConrad Meyer uint64_t next_dest_addr; 210e974f91cSConrad Meyer uint64_t user1; 211e974f91cSConrad Meyer uint64_t user2; 212e974f91cSConrad Meyer }; 213e974f91cSConrad Meyer 214be3cbf60SConrad Meyer struct ioat_crc32_hw_descriptor { 215be3cbf60SConrad Meyer uint32_t size; 216be3cbf60SConrad Meyer union { 217be3cbf60SConrad Meyer uint32_t control_raw; 218be3cbf60SConrad Meyer struct generic_dma_control control_generic; 219be3cbf60SConrad Meyer struct { 220be3cbf60SConrad Meyer uint32_t int_enable:1; 221be3cbf60SConrad Meyer uint32_t src_snoop_disable:1; 222be3cbf60SConrad Meyer uint32_t dest_snoop_disable:1; 223be3cbf60SConrad Meyer uint32_t completion_update:1; 224be3cbf60SConrad Meyer uint32_t fence:1; 225be3cbf60SConrad Meyer uint32_t reserved1:3; 226be3cbf60SConrad Meyer uint32_t bundle:1; 227be3cbf60SConrad Meyer uint32_t dest_dca:1; 228be3cbf60SConrad Meyer uint32_t hint:1; 229be3cbf60SConrad Meyer uint32_t use_seed:1; 230be3cbf60SConrad Meyer /* 231be3cbf60SConrad Meyer * crc_location: 232be3cbf60SConrad Meyer * For IOAT_OP_MOVECRC_TEST and IOAT_OP_CRC_TEST: 233be3cbf60SConrad Meyer * 0: comparison value is pointed to by CRC Address 234be3cbf60SConrad Meyer * field. 235be3cbf60SConrad Meyer * 1: comparison value follows data in wire format 236be3cbf60SConrad Meyer * ("inverted reflected bit order") in the 4 bytes 237be3cbf60SConrad Meyer * following the source data. 238be3cbf60SConrad Meyer * 239be3cbf60SConrad Meyer * For IOAT_OP_CRC_STORE: 240be3cbf60SConrad Meyer * 0: Result will be stored at location pointed to by 241be3cbf60SConrad Meyer * CRC Address field (in wire format). 242be3cbf60SConrad Meyer * 1: Result will be stored directly following the 243be3cbf60SConrad Meyer * source data. 244be3cbf60SConrad Meyer * 245be3cbf60SConrad Meyer * For IOAT_OP_MOVECRC_STORE: 246be3cbf60SConrad Meyer * 0: Result will be stored at location pointed to by 247be3cbf60SConrad Meyer * CRC Address field (in wire format). 248be3cbf60SConrad Meyer * 1: Result will be stored directly following the 249be3cbf60SConrad Meyer * *destination* data. 250be3cbf60SConrad Meyer */ 251be3cbf60SConrad Meyer uint32_t crc_location:1; 252be3cbf60SConrad Meyer uint32_t reserved2:11; 253be3cbf60SConrad Meyer /* 254be3cbf60SConrad Meyer * MOVECRC - Move data in the same way as standard copy 255be3cbf60SConrad Meyer * operation, but also compute CRC32. 256be3cbf60SConrad Meyer * 257be3cbf60SConrad Meyer * CRC - Only compute CRC on source data. 258be3cbf60SConrad Meyer * 259be3cbf60SConrad Meyer * There is a CRC accumulator register in the hardware. 260be3cbf60SConrad Meyer * If 'initial' is set, it is initialized to the value 261be3cbf60SConrad Meyer * in 'seed.' 262be3cbf60SConrad Meyer * 263be3cbf60SConrad Meyer * In all modes, these operators accumulate size bytes 264be3cbf60SConrad Meyer * at src_addr into the running CRC32C. 265be3cbf60SConrad Meyer * 266be3cbf60SConrad Meyer * Store mode emits the accumulated CRC, in wire 267be3cbf60SConrad Meyer * format, as specified by the crc_location bit above. 268be3cbf60SConrad Meyer * 269be3cbf60SConrad Meyer * Test mode compares the accumulated CRC against the 270be3cbf60SConrad Meyer * reference CRC, as described in crc_location above. 271be3cbf60SConrad Meyer * On failure, halts the DMA engine with a CRC error 272be3cbf60SConrad Meyer * status. 273be3cbf60SConrad Meyer */ 274be3cbf60SConrad Meyer #define IOAT_OP_MOVECRC 0x41 275be3cbf60SConrad Meyer #define IOAT_OP_MOVECRC_TEST 0x42 276be3cbf60SConrad Meyer #define IOAT_OP_MOVECRC_STORE 0x43 277be3cbf60SConrad Meyer #define IOAT_OP_CRC 0x81 278be3cbf60SConrad Meyer #define IOAT_OP_CRC_TEST 0x82 279be3cbf60SConrad Meyer #define IOAT_OP_CRC_STORE 0x83 280be3cbf60SConrad Meyer uint32_t op:8; 281be3cbf60SConrad Meyer } control; 282be3cbf60SConrad Meyer } u; 283be3cbf60SConrad Meyer uint64_t src_addr; 284be3cbf60SConrad Meyer uint64_t dest_addr; 285be3cbf60SConrad Meyer uint64_t next; 286be3cbf60SConrad Meyer uint64_t next_src_addr; 287be3cbf60SConrad Meyer uint64_t next_dest_addr; 288be3cbf60SConrad Meyer uint32_t seed; 289be3cbf60SConrad Meyer uint32_t reserved; 290be3cbf60SConrad Meyer uint64_t crc_address; 291be3cbf60SConrad Meyer }; 292be3cbf60SConrad Meyer 293e974f91cSConrad Meyer struct ioat_xor_hw_descriptor { 294e974f91cSConrad Meyer uint32_t size; 295e974f91cSConrad Meyer union { 296e974f91cSConrad Meyer uint32_t control_raw; 2979e3bbf26SConrad Meyer struct generic_dma_control control_generic; 298e974f91cSConrad Meyer struct { 299e974f91cSConrad Meyer uint32_t int_enable:1; 300e974f91cSConrad Meyer uint32_t src_snoop_disable:1; 301e974f91cSConrad Meyer uint32_t dest_snoop_disable:1; 302e974f91cSConrad Meyer uint32_t completion_update:1; 303e974f91cSConrad Meyer uint32_t fence:1; 304e974f91cSConrad Meyer uint32_t src_count:3; 305e974f91cSConrad Meyer uint32_t bundle:1; 306e974f91cSConrad Meyer uint32_t dest_dca:1; 307e974f91cSConrad Meyer uint32_t hint:1; 308e974f91cSConrad Meyer uint32_t reserved:13; 309e974f91cSConrad Meyer #define IOAT_OP_XOR 0x87 310e974f91cSConrad Meyer #define IOAT_OP_XOR_VAL 0x88 311e974f91cSConrad Meyer uint32_t op:8; 312e974f91cSConrad Meyer } control; 313e974f91cSConrad Meyer } u; 314e974f91cSConrad Meyer uint64_t src_addr; 315e974f91cSConrad Meyer uint64_t dest_addr; 316e974f91cSConrad Meyer uint64_t next; 317e974f91cSConrad Meyer uint64_t src_addr2; 318e974f91cSConrad Meyer uint64_t src_addr3; 319e974f91cSConrad Meyer uint64_t src_addr4; 320e974f91cSConrad Meyer uint64_t src_addr5; 321e974f91cSConrad Meyer }; 322e974f91cSConrad Meyer 323e974f91cSConrad Meyer struct ioat_xor_ext_hw_descriptor { 324e974f91cSConrad Meyer uint64_t src_addr6; 325e974f91cSConrad Meyer uint64_t src_addr7; 326e974f91cSConrad Meyer uint64_t src_addr8; 327e974f91cSConrad Meyer uint64_t next; 328e974f91cSConrad Meyer uint64_t reserved[4]; 329e974f91cSConrad Meyer }; 330e974f91cSConrad Meyer 331e974f91cSConrad Meyer struct ioat_pq_hw_descriptor { 332e974f91cSConrad Meyer uint32_t size; 333e974f91cSConrad Meyer union { 334e974f91cSConrad Meyer uint32_t control_raw; 3359e3bbf26SConrad Meyer struct generic_dma_control control_generic; 336e974f91cSConrad Meyer struct { 337e974f91cSConrad Meyer uint32_t int_enable:1; 338e974f91cSConrad Meyer uint32_t src_snoop_disable:1; 339e974f91cSConrad Meyer uint32_t dest_snoop_disable:1; 340e974f91cSConrad Meyer uint32_t completion_update:1; 341e974f91cSConrad Meyer uint32_t fence:1; 342e974f91cSConrad Meyer uint32_t src_count:3; 343e974f91cSConrad Meyer uint32_t bundle:1; 344e974f91cSConrad Meyer uint32_t dest_dca:1; 345e974f91cSConrad Meyer uint32_t hint:1; 346e974f91cSConrad Meyer uint32_t p_disable:1; 347e974f91cSConrad Meyer uint32_t q_disable:1; 348e974f91cSConrad Meyer uint32_t reserved:11; 349e974f91cSConrad Meyer #define IOAT_OP_PQ 0x89 350e974f91cSConrad Meyer #define IOAT_OP_PQ_VAL 0x8a 351e974f91cSConrad Meyer uint32_t op:8; 352e974f91cSConrad Meyer } control; 353e974f91cSConrad Meyer } u; 354e974f91cSConrad Meyer uint64_t src_addr; 355e974f91cSConrad Meyer uint64_t p_addr; 356e974f91cSConrad Meyer uint64_t next; 357e974f91cSConrad Meyer uint64_t src_addr2; 358e974f91cSConrad Meyer uint64_t src_addr3; 359e974f91cSConrad Meyer uint8_t coef[8]; 360e974f91cSConrad Meyer uint64_t q_addr; 361e974f91cSConrad Meyer }; 362e974f91cSConrad Meyer 363e974f91cSConrad Meyer struct ioat_pq_ext_hw_descriptor { 364e974f91cSConrad Meyer uint64_t src_addr4; 365e974f91cSConrad Meyer uint64_t src_addr5; 366e974f91cSConrad Meyer uint64_t src_addr6; 367e974f91cSConrad Meyer uint64_t next; 368e974f91cSConrad Meyer uint64_t src_addr7; 369e974f91cSConrad Meyer uint64_t src_addr8; 370e974f91cSConrad Meyer uint64_t reserved[2]; 371e974f91cSConrad Meyer }; 372e974f91cSConrad Meyer 373e974f91cSConrad Meyer struct ioat_pq_update_hw_descriptor { 374e974f91cSConrad Meyer uint32_t size; 375e974f91cSConrad Meyer union { 376e974f91cSConrad Meyer uint32_t control_raw; 3779e3bbf26SConrad Meyer struct generic_dma_control control_generic; 378e974f91cSConrad Meyer struct { 379e974f91cSConrad Meyer uint32_t int_enable:1; 380e974f91cSConrad Meyer uint32_t src_snoop_disable:1; 381e974f91cSConrad Meyer uint32_t dest_snoop_disable:1; 382e974f91cSConrad Meyer uint32_t completion_update:1; 383e974f91cSConrad Meyer uint32_t fence:1; 384e974f91cSConrad Meyer uint32_t src_cnt:3; 385e974f91cSConrad Meyer uint32_t bundle:1; 386e974f91cSConrad Meyer uint32_t dest_dca:1; 387e974f91cSConrad Meyer uint32_t hint:1; 388e974f91cSConrad Meyer uint32_t p_disable:1; 389e974f91cSConrad Meyer uint32_t q_disable:1; 390e974f91cSConrad Meyer uint32_t reserved:3; 391e974f91cSConrad Meyer uint32_t coef:8; 392e974f91cSConrad Meyer #define IOAT_OP_PQ_UP 0x8b 393e974f91cSConrad Meyer uint32_t op:8; 394e974f91cSConrad Meyer } control; 395e974f91cSConrad Meyer } u; 396e974f91cSConrad Meyer uint64_t src_addr; 397e974f91cSConrad Meyer uint64_t p_addr; 398e974f91cSConrad Meyer uint64_t next; 399e974f91cSConrad Meyer uint64_t src_addr2; 400e974f91cSConrad Meyer uint64_t p_src; 401e974f91cSConrad Meyer uint64_t q_src; 402e974f91cSConrad Meyer uint64_t q_addr; 403e974f91cSConrad Meyer }; 404e974f91cSConrad Meyer 405e974f91cSConrad Meyer struct ioat_raw_hw_descriptor { 406e974f91cSConrad Meyer uint64_t field[8]; 407e974f91cSConrad Meyer }; 408e974f91cSConrad Meyer 409e974f91cSConrad Meyer struct bus_dmadesc { 410e974f91cSConrad Meyer bus_dmaengine_callback_t callback_fn; 411e974f91cSConrad Meyer void *callback_arg; 412e974f91cSConrad Meyer }; 413e974f91cSConrad Meyer 414e974f91cSConrad Meyer struct ioat_descriptor { 415e974f91cSConrad Meyer struct bus_dmadesc bus_dmadesc; 416e974f91cSConrad Meyer union { 4179e3bbf26SConrad Meyer struct ioat_generic_hw_descriptor *generic; 418e974f91cSConrad Meyer struct ioat_dma_hw_descriptor *dma; 419e974f91cSConrad Meyer struct ioat_fill_hw_descriptor *fill; 420be3cbf60SConrad Meyer struct ioat_crc32_hw_descriptor *crc32; 421e974f91cSConrad Meyer struct ioat_xor_hw_descriptor *xor; 422e974f91cSConrad Meyer struct ioat_xor_ext_hw_descriptor *xor_ext; 423e974f91cSConrad Meyer struct ioat_pq_hw_descriptor *pq; 424e974f91cSConrad Meyer struct ioat_pq_ext_hw_descriptor *pq_ext; 425e974f91cSConrad Meyer struct ioat_raw_hw_descriptor *raw; 426e974f91cSConrad Meyer } u; 427e974f91cSConrad Meyer uint32_t id; 428e974f91cSConrad Meyer bus_addr_t hw_desc_bus_addr; 429e974f91cSConrad Meyer }; 430e974f91cSConrad Meyer 431be3cbf60SConrad Meyer /* Unused by this driver at this time. */ 432564af7a6SConrad Meyer #define IOAT_OP_MARKER 0x84 433564af7a6SConrad Meyer 434564af7a6SConrad Meyer /* 435564af7a6SConrad Meyer * Deprecated OPs -- v3 DMA generates an abort if given these. And this driver 436564af7a6SConrad Meyer * doesn't support anything older than v3. 437564af7a6SConrad Meyer */ 438564af7a6SConrad Meyer #define IOAT_OP_OLD_XOR 0x85 439564af7a6SConrad Meyer #define IOAT_OP_OLD_XOR_VAL 0x86 440564af7a6SConrad Meyer 441466b3540SConrad Meyer enum ioat_ref_kind { 442466b3540SConrad Meyer IOAT_DMAENGINE_REF = 0, 443466b3540SConrad Meyer IOAT_ACTIVE_DESCR_REF, 444466b3540SConrad Meyer IOAT_NUM_REF_KINDS 445466b3540SConrad Meyer }; 446466b3540SConrad Meyer 447e974f91cSConrad Meyer /* One of these per allocated PCI device. */ 448e974f91cSConrad Meyer struct ioat_softc { 449e974f91cSConrad Meyer bus_dmaengine_t dmaengine; 450e974f91cSConrad Meyer #define to_ioat_softc(_dmaeng) \ 451e974f91cSConrad Meyer ({ \ 452e974f91cSConrad Meyer bus_dmaengine_t *_p = (_dmaeng); \ 453e974f91cSConrad Meyer (struct ioat_softc *)((char *)_p - \ 454e974f91cSConrad Meyer offsetof(struct ioat_softc, dmaengine)); \ 455e974f91cSConrad Meyer }) 456e974f91cSConrad Meyer 457e974f91cSConrad Meyer int version; 458df1928aaSConrad Meyer unsigned chan_idx; 459e974f91cSConrad Meyer 460e974f91cSConrad Meyer struct mtx submit_lock; 461e974f91cSConrad Meyer device_t device; 462e974f91cSConrad Meyer bus_space_tag_t pci_bus_tag; 463e974f91cSConrad Meyer bus_space_handle_t pci_bus_handle; 464e974f91cSConrad Meyer int pci_resource_id; 465e974f91cSConrad Meyer struct resource *pci_resource; 466e974f91cSConrad Meyer uint32_t max_xfer_size; 4671693d27bSConrad Meyer uint32_t capabilities; 4685ca9fc2aSConrad Meyer uint16_t intrdelay_max; 4695ca9fc2aSConrad Meyer uint16_t cached_intrdelay; 470e974f91cSConrad Meyer 471e974f91cSConrad Meyer struct resource *res; 472e974f91cSConrad Meyer int rid; 473e974f91cSConrad Meyer void *tag; 474e974f91cSConrad Meyer 475e974f91cSConrad Meyer bus_dma_tag_t hw_desc_tag; 476e974f91cSConrad Meyer bus_dmamap_t hw_desc_map; 477e974f91cSConrad Meyer 478e974f91cSConrad Meyer bus_dma_tag_t comp_update_tag; 479e974f91cSConrad Meyer bus_dmamap_t comp_update_map; 480e974f91cSConrad Meyer uint64_t *comp_update; 481e974f91cSConrad Meyer bus_addr_t comp_update_bus_addr; 482e974f91cSConrad Meyer 4835ac77963SConrad Meyer struct callout poll_timer; 4845ac77963SConrad Meyer struct callout shrink_timer; 485374b05e1SConrad Meyer struct task reset_task; 486e974f91cSConrad Meyer 4875f77bd3eSConrad Meyer boolean_t quiescing; 4880ff814e8SConrad Meyer boolean_t destroying; 489e974f91cSConrad Meyer boolean_t is_resize_pending; 4905ac77963SConrad Meyer boolean_t is_completion_pending; /* submit_lock */ 491e974f91cSConrad Meyer boolean_t is_reset_pending; 492e974f91cSConrad Meyer boolean_t is_channel_running; 4935ca9fc2aSConrad Meyer boolean_t intrdelay_supported; 494*fe8712f8SConrad Meyer boolean_t resetting; /* submit_lock */ 495*fe8712f8SConrad Meyer boolean_t resetting_cleanup; /* cleanup_lock */ 496e974f91cSConrad Meyer 497e974f91cSConrad Meyer uint32_t head; 498e974f91cSConrad Meyer uint32_t tail; 499bf8553eaSConrad Meyer uint32_t hw_head; 500e974f91cSConrad Meyer uint32_t ring_size_order; 501e974f91cSConrad Meyer bus_addr_t last_seen; 502e974f91cSConrad Meyer 503e974f91cSConrad Meyer struct ioat_descriptor **ring; 504e974f91cSConrad Meyer 505e974f91cSConrad Meyer struct mtx cleanup_lock; 506466b3540SConrad Meyer volatile uint32_t refcnt; 507466b3540SConrad Meyer #ifdef INVARIANTS 508466b3540SConrad Meyer volatile uint32_t refkinds[IOAT_NUM_REF_KINDS]; 509466b3540SConrad Meyer #endif 51001fbbc88SConrad Meyer 51101fbbc88SConrad Meyer struct { 51201fbbc88SConrad Meyer uint64_t interrupts; 51301fbbc88SConrad Meyer uint64_t descriptors_processed; 51401fbbc88SConrad Meyer uint64_t descriptors_error; 51501fbbc88SConrad Meyer uint64_t descriptors_submitted; 51601fbbc88SConrad Meyer 51701fbbc88SConrad Meyer uint32_t channel_halts; 51801fbbc88SConrad Meyer uint32_t last_halt_chanerr; 51901fbbc88SConrad Meyer } stats; 520e974f91cSConrad Meyer }; 521e974f91cSConrad Meyer 5227afbb263SConrad Meyer void ioat_test_attach(void); 5237afbb263SConrad Meyer void ioat_test_detach(void); 5247afbb263SConrad Meyer 525e974f91cSConrad Meyer static inline uint64_t 526e974f91cSConrad Meyer ioat_get_chansts(struct ioat_softc *ioat) 527e974f91cSConrad Meyer { 528e974f91cSConrad Meyer uint64_t status; 529e974f91cSConrad Meyer 530e974f91cSConrad Meyer if (ioat->version >= IOAT_VER_3_3) 531e974f91cSConrad Meyer status = ioat_read_8(ioat, IOAT_CHANSTS_OFFSET); 532e974f91cSConrad Meyer else 533e974f91cSConrad Meyer /* Must read lower 4 bytes before upper 4 bytes. */ 534e974f91cSConrad Meyer status = ioat_read_double_4(ioat, IOAT_CHANSTS_OFFSET); 535e974f91cSConrad Meyer return (status); 536e974f91cSConrad Meyer } 537e974f91cSConrad Meyer 538e974f91cSConrad Meyer static inline void 539e974f91cSConrad Meyer ioat_write_chancmp(struct ioat_softc *ioat, uint64_t addr) 540e974f91cSConrad Meyer { 541e974f91cSConrad Meyer 542e974f91cSConrad Meyer if (ioat->version >= IOAT_VER_3_3) 543e974f91cSConrad Meyer ioat_write_8(ioat, IOAT_CHANCMP_OFFSET_LOW, addr); 544e974f91cSConrad Meyer else 545e974f91cSConrad Meyer ioat_write_double_4(ioat, IOAT_CHANCMP_OFFSET_LOW, addr); 546e974f91cSConrad Meyer } 547e974f91cSConrad Meyer 548e974f91cSConrad Meyer static inline void 549e974f91cSConrad Meyer ioat_write_chainaddr(struct ioat_softc *ioat, uint64_t addr) 550e974f91cSConrad Meyer { 551e974f91cSConrad Meyer 552e974f91cSConrad Meyer if (ioat->version >= IOAT_VER_3_3) 553e974f91cSConrad Meyer ioat_write_8(ioat, IOAT_CHAINADDR_OFFSET_LOW, addr); 554e974f91cSConrad Meyer else 555e974f91cSConrad Meyer ioat_write_double_4(ioat, IOAT_CHAINADDR_OFFSET_LOW, addr); 556e974f91cSConrad Meyer } 557e974f91cSConrad Meyer 558e974f91cSConrad Meyer static inline boolean_t 559e974f91cSConrad Meyer is_ioat_active(uint64_t status) 560e974f91cSConrad Meyer { 561e974f91cSConrad Meyer return ((status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_ACTIVE); 562e974f91cSConrad Meyer } 563e974f91cSConrad Meyer 564e974f91cSConrad Meyer static inline boolean_t 565e974f91cSConrad Meyer is_ioat_idle(uint64_t status) 566e974f91cSConrad Meyer { 567e974f91cSConrad Meyer return ((status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_IDLE); 568e974f91cSConrad Meyer } 569e974f91cSConrad Meyer 570e974f91cSConrad Meyer static inline boolean_t 571e974f91cSConrad Meyer is_ioat_halted(uint64_t status) 572e974f91cSConrad Meyer { 573e974f91cSConrad Meyer return ((status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_HALTED); 574e974f91cSConrad Meyer } 575e974f91cSConrad Meyer 576e974f91cSConrad Meyer static inline boolean_t 577e974f91cSConrad Meyer is_ioat_suspended(uint64_t status) 578e974f91cSConrad Meyer { 579e974f91cSConrad Meyer return ((status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_SUSPENDED); 580e974f91cSConrad Meyer } 581e974f91cSConrad Meyer 582e974f91cSConrad Meyer static inline void 583e974f91cSConrad Meyer ioat_suspend(struct ioat_softc *ioat) 584e974f91cSConrad Meyer { 585e974f91cSConrad Meyer ioat_write_1(ioat, IOAT_CHANCMD_OFFSET, IOAT_CHANCMD_SUSPEND); 586e974f91cSConrad Meyer } 587e974f91cSConrad Meyer 588e974f91cSConrad Meyer static inline void 589e974f91cSConrad Meyer ioat_reset(struct ioat_softc *ioat) 590e974f91cSConrad Meyer { 591e974f91cSConrad Meyer ioat_write_1(ioat, IOAT_CHANCMD_OFFSET, IOAT_CHANCMD_RESET); 592e974f91cSConrad Meyer } 593e974f91cSConrad Meyer 594e974f91cSConrad Meyer static inline boolean_t 595e974f91cSConrad Meyer ioat_reset_pending(struct ioat_softc *ioat) 596e974f91cSConrad Meyer { 597e974f91cSConrad Meyer uint8_t cmd; 598e974f91cSConrad Meyer 599e974f91cSConrad Meyer cmd = ioat_read_1(ioat, IOAT_CHANCMD_OFFSET); 600e974f91cSConrad Meyer return ((cmd & IOAT_CHANCMD_RESET) != 0); 601e974f91cSConrad Meyer } 602e974f91cSConrad Meyer 603e974f91cSConrad Meyer #endif /* __IOAT_INTERNAL_H__ */ 604