diff options
Diffstat (limited to 'drivers/net/sfc/bitfield.h')
-rw-r--r-- | drivers/net/sfc/bitfield.h | 178 |
1 files changed, 111 insertions, 67 deletions
diff --git a/drivers/net/sfc/bitfield.h b/drivers/net/sfc/bitfield.h index 2c79d27404e0..d95c21828014 100644 --- a/drivers/net/sfc/bitfield.h +++ b/drivers/net/sfc/bitfield.h | |||
@@ -52,9 +52,9 @@ | |||
52 | * | 52 | * |
53 | * The maximum width mask that can be generated is 64 bits. | 53 | * The maximum width mask that can be generated is 64 bits. |
54 | */ | 54 | */ |
55 | #define EFX_MASK64(field) \ | 55 | #define EFX_MASK64(width) \ |
56 | (EFX_WIDTH(field) == 64 ? ~((u64) 0) : \ | 56 | ((width) == 64 ? ~((u64) 0) : \ |
57 | (((((u64) 1) << EFX_WIDTH(field))) - 1)) | 57 | (((((u64) 1) << (width))) - 1)) |
58 | 58 | ||
59 | /* Mask equal in width to the specified field. | 59 | /* Mask equal in width to the specified field. |
60 | * | 60 | * |
@@ -63,9 +63,9 @@ | |||
63 | * The maximum width mask that can be generated is 32 bits. Use | 63 | * The maximum width mask that can be generated is 32 bits. Use |
64 | * EFX_MASK64 for higher width fields. | 64 | * EFX_MASK64 for higher width fields. |
65 | */ | 65 | */ |
66 | #define EFX_MASK32(field) \ | 66 | #define EFX_MASK32(width) \ |
67 | (EFX_WIDTH(field) == 32 ? ~((u32) 0) : \ | 67 | ((width) == 32 ? ~((u32) 0) : \ |
68 | (((((u32) 1) << EFX_WIDTH(field))) - 1)) | 68 | (((((u32) 1) << (width))) - 1)) |
69 | 69 | ||
70 | /* A doubleword (i.e. 4 byte) datatype - little-endian in HW */ | 70 | /* A doubleword (i.e. 4 byte) datatype - little-endian in HW */ |
71 | typedef union efx_dword { | 71 | typedef union efx_dword { |
@@ -138,44 +138,49 @@ typedef union efx_oword { | |||
138 | EFX_EXTRACT_NATIVE(le32_to_cpu(element), min, max, low, high) | 138 | EFX_EXTRACT_NATIVE(le32_to_cpu(element), min, max, low, high) |
139 | 139 | ||
140 | #define EFX_EXTRACT_OWORD64(oword, low, high) \ | 140 | #define EFX_EXTRACT_OWORD64(oword, low, high) \ |
141 | (EFX_EXTRACT64((oword).u64[0], 0, 63, low, high) | \ | 141 | ((EFX_EXTRACT64((oword).u64[0], 0, 63, low, high) | \ |
142 | EFX_EXTRACT64((oword).u64[1], 64, 127, low, high)) | 142 | EFX_EXTRACT64((oword).u64[1], 64, 127, low, high)) & \ |
143 | EFX_MASK64(high + 1 - low)) | ||
143 | 144 | ||
144 | #define EFX_EXTRACT_QWORD64(qword, low, high) \ | 145 | #define EFX_EXTRACT_QWORD64(qword, low, high) \ |
145 | EFX_EXTRACT64((qword).u64[0], 0, 63, low, high) | 146 | (EFX_EXTRACT64((qword).u64[0], 0, 63, low, high) & \ |
147 | EFX_MASK64(high + 1 - low)) | ||
146 | 148 | ||
147 | #define EFX_EXTRACT_OWORD32(oword, low, high) \ | 149 | #define EFX_EXTRACT_OWORD32(oword, low, high) \ |
148 | (EFX_EXTRACT32((oword).u32[0], 0, 31, low, high) | \ | 150 | ((EFX_EXTRACT32((oword).u32[0], 0, 31, low, high) | \ |
149 | EFX_EXTRACT32((oword).u32[1], 32, 63, low, high) | \ | 151 | EFX_EXTRACT32((oword).u32[1], 32, 63, low, high) | \ |
150 | EFX_EXTRACT32((oword).u32[2], 64, 95, low, high) | \ | 152 | EFX_EXTRACT32((oword).u32[2], 64, 95, low, high) | \ |
151 | EFX_EXTRACT32((oword).u32[3], 96, 127, low, high)) | 153 | EFX_EXTRACT32((oword).u32[3], 96, 127, low, high)) & \ |
154 | EFX_MASK32(high + 1 - low)) | ||
152 | 155 | ||
153 | #define EFX_EXTRACT_QWORD32(qword, low, high) \ | 156 | #define EFX_EXTRACT_QWORD32(qword, low, high) \ |
154 | (EFX_EXTRACT32((qword).u32[0], 0, 31, low, high) | \ | 157 | ((EFX_EXTRACT32((qword).u32[0], 0, 31, low, high) | \ |
155 | EFX_EXTRACT32((qword).u32[1], 32, 63, low, high)) | 158 | EFX_EXTRACT32((qword).u32[1], 32, 63, low, high)) & \ |
159 | EFX_MASK32(high + 1 - low)) | ||
156 | 160 | ||
157 | #define EFX_EXTRACT_DWORD(dword, low, high) \ | 161 | #define EFX_EXTRACT_DWORD(dword, low, high) \ |
158 | EFX_EXTRACT32((dword).u32[0], 0, 31, low, high) | 162 | (EFX_EXTRACT32((dword).u32[0], 0, 31, low, high) & \ |
163 | EFX_MASK32(high + 1 - low)) | ||
159 | 164 | ||
160 | #define EFX_OWORD_FIELD64(oword, field) \ | 165 | #define EFX_OWORD_FIELD64(oword, field) \ |
161 | (EFX_EXTRACT_OWORD64(oword, EFX_LOW_BIT(field), EFX_HIGH_BIT(field)) \ | 166 | EFX_EXTRACT_OWORD64(oword, EFX_LOW_BIT(field), \ |
162 | & EFX_MASK64(field)) | 167 | EFX_HIGH_BIT(field)) |
163 | 168 | ||
164 | #define EFX_QWORD_FIELD64(qword, field) \ | 169 | #define EFX_QWORD_FIELD64(qword, field) \ |
165 | (EFX_EXTRACT_QWORD64(qword, EFX_LOW_BIT(field), EFX_HIGH_BIT(field)) \ | 170 | EFX_EXTRACT_QWORD64(qword, EFX_LOW_BIT(field), \ |
166 | & EFX_MASK64(field)) | 171 | EFX_HIGH_BIT(field)) |
167 | 172 | ||
168 | #define EFX_OWORD_FIELD32(oword, field) \ | 173 | #define EFX_OWORD_FIELD32(oword, field) \ |
169 | (EFX_EXTRACT_OWORD32(oword, EFX_LOW_BIT(field), EFX_HIGH_BIT(field)) \ | 174 | EFX_EXTRACT_OWORD32(oword, EFX_LOW_BIT(field), \ |
170 | & EFX_MASK32(field)) | 175 | EFX_HIGH_BIT(field)) |
171 | 176 | ||
172 | #define EFX_QWORD_FIELD32(qword, field) \ | 177 | #define EFX_QWORD_FIELD32(qword, field) \ |
173 | (EFX_EXTRACT_QWORD32(qword, EFX_LOW_BIT(field), EFX_HIGH_BIT(field)) \ | 178 | EFX_EXTRACT_QWORD32(qword, EFX_LOW_BIT(field), \ |
174 | & EFX_MASK32(field)) | 179 | EFX_HIGH_BIT(field)) |
175 | 180 | ||
176 | #define EFX_DWORD_FIELD(dword, field) \ | 181 | #define EFX_DWORD_FIELD(dword, field) \ |
177 | (EFX_EXTRACT_DWORD(dword, EFX_LOW_BIT(field), EFX_HIGH_BIT(field)) \ | 182 | EFX_EXTRACT_DWORD(dword, EFX_LOW_BIT(field), \ |
178 | & EFX_MASK32(field)) | 183 | EFX_HIGH_BIT(field)) |
179 | 184 | ||
180 | #define EFX_OWORD_IS_ZERO64(oword) \ | 185 | #define EFX_OWORD_IS_ZERO64(oword) \ |
181 | (((oword).u64[0] | (oword).u64[1]) == (__force __le64) 0) | 186 | (((oword).u64[0] | (oword).u64[1]) == (__force __le64) 0) |
@@ -411,69 +416,102 @@ typedef union efx_oword { | |||
411 | * for read-modify-write operations. | 416 | * for read-modify-write operations. |
412 | * | 417 | * |
413 | */ | 418 | */ |
414 | |||
415 | #define EFX_INVERT_OWORD(oword) do { \ | 419 | #define EFX_INVERT_OWORD(oword) do { \ |
416 | (oword).u64[0] = ~((oword).u64[0]); \ | 420 | (oword).u64[0] = ~((oword).u64[0]); \ |
417 | (oword).u64[1] = ~((oword).u64[1]); \ | 421 | (oword).u64[1] = ~((oword).u64[1]); \ |
418 | } while (0) | 422 | } while (0) |
419 | 423 | ||
420 | #define EFX_INSERT_FIELD64(...) \ | 424 | #define EFX_AND_OWORD(oword, from, mask) \ |
421 | cpu_to_le64(EFX_INSERT_FIELD_NATIVE(__VA_ARGS__)) | 425 | do { \ |
426 | (oword).u64[0] = (from).u64[0] & (mask).u64[0]; \ | ||
427 | (oword).u64[1] = (from).u64[1] & (mask).u64[1]; \ | ||
428 | } while (0) | ||
429 | |||
430 | #define EFX_OR_OWORD(oword, from, mask) \ | ||
431 | do { \ | ||
432 | (oword).u64[0] = (from).u64[0] | (mask).u64[0]; \ | ||
433 | (oword).u64[1] = (from).u64[1] | (mask).u64[1]; \ | ||
434 | } while (0) | ||
422 | 435 | ||
423 | #define EFX_INSERT_FIELD32(...) \ | 436 | #define EFX_INSERT64(min, max, low, high, value) \ |
424 | cpu_to_le32(EFX_INSERT_FIELD_NATIVE(__VA_ARGS__)) | 437 | cpu_to_le64(EFX_INSERT_NATIVE(min, max, low, high, value)) |
425 | 438 | ||
426 | #define EFX_INPLACE_MASK64(min, max, field) \ | 439 | #define EFX_INSERT32(min, max, low, high, value) \ |
427 | EFX_INSERT_FIELD64(min, max, field, EFX_MASK64(field)) | 440 | cpu_to_le32(EFX_INSERT_NATIVE(min, max, low, high, value)) |
428 | 441 | ||
429 | #define EFX_INPLACE_MASK32(min, max, field) \ | 442 | #define EFX_INPLACE_MASK64(min, max, low, high) \ |
430 | EFX_INSERT_FIELD32(min, max, field, EFX_MASK32(field)) | 443 | EFX_INSERT64(min, max, low, high, EFX_MASK64(high + 1 - low)) |
431 | 444 | ||
432 | #define EFX_SET_OWORD_FIELD64(oword, field, value) do { \ | 445 | #define EFX_INPLACE_MASK32(min, max, low, high) \ |
446 | EFX_INSERT32(min, max, low, high, EFX_MASK32(high + 1 - low)) | ||
447 | |||
448 | #define EFX_SET_OWORD64(oword, low, high, value) do { \ | ||
433 | (oword).u64[0] = (((oword).u64[0] \ | 449 | (oword).u64[0] = (((oword).u64[0] \ |
434 | & ~EFX_INPLACE_MASK64(0, 63, field)) \ | 450 | & ~EFX_INPLACE_MASK64(0, 63, low, high)) \ |
435 | | EFX_INSERT_FIELD64(0, 63, field, value)); \ | 451 | | EFX_INSERT64(0, 63, low, high, value)); \ |
436 | (oword).u64[1] = (((oword).u64[1] \ | 452 | (oword).u64[1] = (((oword).u64[1] \ |
437 | & ~EFX_INPLACE_MASK64(64, 127, field)) \ | 453 | & ~EFX_INPLACE_MASK64(64, 127, low, high)) \ |
438 | | EFX_INSERT_FIELD64(64, 127, field, value)); \ | 454 | | EFX_INSERT64(64, 127, low, high, value)); \ |
439 | } while (0) | 455 | } while (0) |
440 | 456 | ||
441 | #define EFX_SET_QWORD_FIELD64(qword, field, value) do { \ | 457 | #define EFX_SET_QWORD64(qword, low, high, value) do { \ |
442 | (qword).u64[0] = (((qword).u64[0] \ | 458 | (qword).u64[0] = (((qword).u64[0] \ |
443 | & ~EFX_INPLACE_MASK64(0, 63, field)) \ | 459 | & ~EFX_INPLACE_MASK64(0, 63, low, high)) \ |
444 | | EFX_INSERT_FIELD64(0, 63, field, value)); \ | 460 | | EFX_INSERT64(0, 63, low, high, value)); \ |
445 | } while (0) | 461 | } while (0) |
446 | 462 | ||
447 | #define EFX_SET_OWORD_FIELD32(oword, field, value) do { \ | 463 | #define EFX_SET_OWORD32(oword, low, high, value) do { \ |
448 | (oword).u32[0] = (((oword).u32[0] \ | 464 | (oword).u32[0] = (((oword).u32[0] \ |
449 | & ~EFX_INPLACE_MASK32(0, 31, field)) \ | 465 | & ~EFX_INPLACE_MASK32(0, 31, low, high)) \ |
450 | | EFX_INSERT_FIELD32(0, 31, field, value)); \ | 466 | | EFX_INSERT32(0, 31, low, high, value)); \ |
451 | (oword).u32[1] = (((oword).u32[1] \ | 467 | (oword).u32[1] = (((oword).u32[1] \ |
452 | & ~EFX_INPLACE_MASK32(32, 63, field)) \ | 468 | & ~EFX_INPLACE_MASK32(32, 63, low, high)) \ |
453 | | EFX_INSERT_FIELD32(32, 63, field, value)); \ | 469 | | EFX_INSERT32(32, 63, low, high, value)); \ |
454 | (oword).u32[2] = (((oword).u32[2] \ | 470 | (oword).u32[2] = (((oword).u32[2] \ |
455 | & ~EFX_INPLACE_MASK32(64, 95, field)) \ | 471 | & ~EFX_INPLACE_MASK32(64, 95, low, high)) \ |
456 | | EFX_INSERT_FIELD32(64, 95, field, value)); \ | 472 | | EFX_INSERT32(64, 95, low, high, value)); \ |
457 | (oword).u32[3] = (((oword).u32[3] \ | 473 | (oword).u32[3] = (((oword).u32[3] \ |
458 | & ~EFX_INPLACE_MASK32(96, 127, field)) \ | 474 | & ~EFX_INPLACE_MASK32(96, 127, low, high)) \ |
459 | | EFX_INSERT_FIELD32(96, 127, field, value)); \ | 475 | | EFX_INSERT32(96, 127, low, high, value)); \ |
460 | } while (0) | 476 | } while (0) |
461 | 477 | ||
462 | #define EFX_SET_QWORD_FIELD32(qword, field, value) do { \ | 478 | #define EFX_SET_QWORD32(qword, low, high, value) do { \ |
463 | (qword).u32[0] = (((qword).u32[0] \ | 479 | (qword).u32[0] = (((qword).u32[0] \ |
464 | & ~EFX_INPLACE_MASK32(0, 31, field)) \ | 480 | & ~EFX_INPLACE_MASK32(0, 31, low, high)) \ |
465 | | EFX_INSERT_FIELD32(0, 31, field, value)); \ | 481 | | EFX_INSERT32(0, 31, low, high, value)); \ |
466 | (qword).u32[1] = (((qword).u32[1] \ | 482 | (qword).u32[1] = (((qword).u32[1] \ |
467 | & ~EFX_INPLACE_MASK32(32, 63, field)) \ | 483 | & ~EFX_INPLACE_MASK32(32, 63, low, high)) \ |
468 | | EFX_INSERT_FIELD32(32, 63, field, value)); \ | 484 | | EFX_INSERT32(32, 63, low, high, value)); \ |
469 | } while (0) | 485 | } while (0) |
470 | 486 | ||
471 | #define EFX_SET_DWORD_FIELD(dword, field, value) do { \ | 487 | #define EFX_SET_DWORD32(dword, low, high, value) do { \ |
472 | (dword).u32[0] = (((dword).u32[0] \ | 488 | (dword).u32[0] = (((dword).u32[0] \ |
473 | & ~EFX_INPLACE_MASK32(0, 31, field)) \ | 489 | & ~EFX_INPLACE_MASK32(0, 31, low, high)) \ |
474 | | EFX_INSERT_FIELD32(0, 31, field, value)); \ | 490 | | EFX_INSERT32(0, 31, low, high, value)); \ |
475 | } while (0) | 491 | } while (0) |
476 | 492 | ||
493 | #define EFX_SET_OWORD_FIELD64(oword, field, value) \ | ||
494 | EFX_SET_OWORD64(oword, EFX_LOW_BIT(field), \ | ||
495 | EFX_HIGH_BIT(field), value) | ||
496 | |||
497 | #define EFX_SET_QWORD_FIELD64(qword, field, value) \ | ||
498 | EFX_SET_QWORD64(qword, EFX_LOW_BIT(field), \ | ||
499 | EFX_HIGH_BIT(field), value) | ||
500 | |||
501 | #define EFX_SET_OWORD_FIELD32(oword, field, value) \ | ||
502 | EFX_SET_OWORD32(oword, EFX_LOW_BIT(field), \ | ||
503 | EFX_HIGH_BIT(field), value) | ||
504 | |||
505 | #define EFX_SET_QWORD_FIELD32(qword, field, value) \ | ||
506 | EFX_SET_QWORD32(qword, EFX_LOW_BIT(field), \ | ||
507 | EFX_HIGH_BIT(field), value) | ||
508 | |||
509 | #define EFX_SET_DWORD_FIELD(dword, field, value) \ | ||
510 | EFX_SET_DWORD32(dword, EFX_LOW_BIT(field), \ | ||
511 | EFX_HIGH_BIT(field), value) | ||
512 | |||
513 | |||
514 | |||
477 | #if BITS_PER_LONG == 64 | 515 | #if BITS_PER_LONG == 64 |
478 | #define EFX_SET_OWORD_FIELD EFX_SET_OWORD_FIELD64 | 516 | #define EFX_SET_OWORD_FIELD EFX_SET_OWORD_FIELD64 |
479 | #define EFX_SET_QWORD_FIELD EFX_SET_QWORD_FIELD64 | 517 | #define EFX_SET_QWORD_FIELD EFX_SET_QWORD_FIELD64 |
@@ -502,4 +540,10 @@ typedef union efx_oword { | |||
502 | #define EFX_DMA_TYPE_WIDTH(width) \ | 540 | #define EFX_DMA_TYPE_WIDTH(width) \ |
503 | (((width) < DMA_ADDR_T_WIDTH) ? (width) : DMA_ADDR_T_WIDTH) | 541 | (((width) < DMA_ADDR_T_WIDTH) ? (width) : DMA_ADDR_T_WIDTH) |
504 | 542 | ||
543 | |||
544 | /* Static initialiser */ | ||
545 | #define EFX_OWORD32(a, b, c, d) \ | ||
546 | { .u32 = { __constant_cpu_to_le32(a), __constant_cpu_to_le32(b), \ | ||
547 | __constant_cpu_to_le32(c), __constant_cpu_to_le32(d) } } | ||
548 | |||
505 | #endif /* EFX_BITFIELD_H */ | 549 | #endif /* EFX_BITFIELD_H */ |