Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next

Ben Hutchings says:

====================
Some bug fixes that should go into 3.7:

1. Fix oops when removing device with SR-IOV enabled. (This regression
was introduced by the last set of changes, so the fix does not need to
be applied to any earlier kernel versions.)
2. Fix firmware structure field lookup bug that resulted in missing
sensor information.
3. Fix bug that makes self-test do very little in some configurations.
4. Fix the numbering of ethtool RX flow steering filters to reflect the
real hardware priorities.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+76 -82
+11 -11
drivers/net/ethernet/sfc/bitfield.h
··· 120 120 * [0,high-low), with garbage in bits [high-low+1,...). 121 121 */ 122 122 #define EFX_EXTRACT_NATIVE(native_element, min, max, low, high) \ 123 - (((low > max) || (high < min)) ? 0 : \ 124 - ((low > min) ? \ 125 - ((native_element) >> (low - min)) : \ 126 - ((native_element) << (min - low)))) 123 + ((low) > (max) || (high) < (min) ? 0 : \ 124 + (low) > (min) ? \ 125 + (native_element) >> ((low) - (min)) : \ 126 + (native_element) << ((min) - (low))) 127 127 128 128 /* 129 129 * Extract bit field portion [low,high) from the 64-bit little-endian ··· 142 142 #define EFX_EXTRACT_OWORD64(oword, low, high) \ 143 143 ((EFX_EXTRACT64((oword).u64[0], 0, 63, low, high) | \ 144 144 EFX_EXTRACT64((oword).u64[1], 64, 127, low, high)) & \ 145 - EFX_MASK64(high + 1 - low)) 145 + EFX_MASK64((high) + 1 - (low))) 146 146 147 147 #define EFX_EXTRACT_QWORD64(qword, low, high) \ 148 148 (EFX_EXTRACT64((qword).u64[0], 0, 63, low, high) & \ 149 - EFX_MASK64(high + 1 - low)) 149 + EFX_MASK64((high) + 1 - (low))) 150 150 151 151 #define EFX_EXTRACT_OWORD32(oword, low, high) \ 152 152 ((EFX_EXTRACT32((oword).u32[0], 0, 31, low, high) | \ 153 153 EFX_EXTRACT32((oword).u32[1], 32, 63, low, high) | \ 154 154 EFX_EXTRACT32((oword).u32[2], 64, 95, low, high) | \ 155 155 EFX_EXTRACT32((oword).u32[3], 96, 127, low, high)) & \ 156 - EFX_MASK32(high + 1 - low)) 156 + EFX_MASK32((high) + 1 - (low))) 157 157 158 158 #define EFX_EXTRACT_QWORD32(qword, low, high) \ 159 159 ((EFX_EXTRACT32((qword).u32[0], 0, 31, low, high) | \ 160 160 EFX_EXTRACT32((qword).u32[1], 32, 63, low, high)) & \ 161 - EFX_MASK32(high + 1 - low)) 161 + EFX_MASK32((high) + 1 - (low))) 162 162 163 163 #define EFX_EXTRACT_DWORD(dword, low, high) \ 164 164 (EFX_EXTRACT32((dword).u32[0], 0, 31, low, high) & \ 165 - EFX_MASK32(high + 1 - low)) 165 + EFX_MASK32((high) + 1 - (low))) 166 166 167 167 #define EFX_OWORD_FIELD64(oword, field) \ 168 168 EFX_EXTRACT_OWORD64(oword, EFX_LOW_BIT(field), \ ··· 442 442 cpu_to_le32(EFX_INSERT_NATIVE(min, max, low, high, value)) 443 443 444 444 #define EFX_INPLACE_MASK64(min, max, low, high) \ 445 - EFX_INSERT64(min, max, low, high, EFX_MASK64(high + 1 - low)) 445 + EFX_INSERT64(min, max, low, high, EFX_MASK64((high) + 1 - (low))) 446 446 447 447 #define EFX_INPLACE_MASK32(min, max, low, high) \ 448 - EFX_INSERT32(min, max, low, high, EFX_MASK32(high + 1 - low)) 448 + EFX_INSERT32(min, max, low, high, EFX_MASK32((high) + 1 - (low))) 449 449 450 450 #define EFX_SET_OWORD64(oword, low, high, value) do { \ 451 451 (oword).u64[0] = (((oword).u64[0] \
+4 -7
drivers/net/ethernet/sfc/ethtool.c
··· 337 337 unsigned int test_index, 338 338 struct ethtool_string *strings, u64 *data) 339 339 { 340 - struct efx_channel *channel = efx_get_channel(efx, 0); 340 + struct efx_channel *channel = 341 + efx_get_channel(efx, efx->tx_channel_offset); 341 342 struct efx_tx_queue *tx_queue; 342 343 343 344 efx_for_each_channel_tx_queue(tx_queue, channel) { ··· 961 960 int rc; 962 961 963 962 /* Check that user wants us to choose the location */ 964 - if (rule->location != RX_CLS_LOC_ANY && 965 - rule->location != RX_CLS_LOC_FIRST && 966 - rule->location != RX_CLS_LOC_LAST) 963 + if (rule->location != RX_CLS_LOC_ANY) 967 964 return -EINVAL; 968 965 969 966 /* Range-check ring_cookie */ ··· 975 976 rule->m_ext.data[1])) 976 977 return -EINVAL; 977 978 978 - efx_filter_init_rx(&spec, EFX_FILTER_PRI_MANUAL, 979 - (rule->location == RX_CLS_LOC_FIRST) ? 980 - EFX_FILTER_FLAG_RX_OVERRIDE_IP : 0, 979 + efx_filter_init_rx(&spec, EFX_FILTER_PRI_MANUAL, 0, 981 980 (rule->ring_cookie == RX_CLS_FLOW_DISC) ? 982 981 0xfff : rule->ring_cookie); 983 982
+53 -55
drivers/net/ethernet/sfc/filter.c
··· 162 162 !!(table->spec[EFX_FILTER_INDEX_UC_DEF].flags & 163 163 EFX_FILTER_FLAG_RX_RSS)); 164 164 EFX_SET_OWORD_FIELD( 165 - filter_ctl, FRF_CZ_UNICAST_NOMATCH_IP_OVERRIDE, 166 - !!(table->spec[EFX_FILTER_INDEX_UC_DEF].flags & 167 - EFX_FILTER_FLAG_RX_OVERRIDE_IP)); 168 - EFX_SET_OWORD_FIELD( 169 165 filter_ctl, FRF_CZ_MULTICAST_NOMATCH_Q_ID, 170 166 table->spec[EFX_FILTER_INDEX_MC_DEF].dmaq_id); 171 167 EFX_SET_OWORD_FIELD( 172 168 filter_ctl, FRF_CZ_MULTICAST_NOMATCH_RSS_ENABLED, 173 169 !!(table->spec[EFX_FILTER_INDEX_MC_DEF].flags & 174 170 EFX_FILTER_FLAG_RX_RSS)); 175 - EFX_SET_OWORD_FIELD( 176 - filter_ctl, FRF_CZ_MULTICAST_NOMATCH_IP_OVERRIDE, 177 - !!(table->spec[EFX_FILTER_INDEX_MC_DEF].flags & 178 - EFX_FILTER_FLAG_RX_OVERRIDE_IP)); 179 171 } 180 172 181 173 efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL); ··· 472 480 473 481 case EFX_FILTER_TABLE_RX_MAC: { 474 482 bool is_wild = spec->type == EFX_FILTER_MAC_WILD; 475 - EFX_POPULATE_OWORD_8( 483 + EFX_POPULATE_OWORD_7( 476 484 *filter, 477 485 FRF_CZ_RMFT_RSS_EN, 478 486 !!(spec->flags & EFX_FILTER_FLAG_RX_RSS), 479 487 FRF_CZ_RMFT_SCATTER_EN, 480 488 !!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER), 481 - FRF_CZ_RMFT_IP_OVERRIDE, 482 - !!(spec->flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP), 483 489 FRF_CZ_RMFT_RXQ_ID, spec->dmaq_id, 484 490 FRF_CZ_RMFT_WILDCARD_MATCH, is_wild, 485 491 FRF_CZ_RMFT_DEST_MAC_HI, spec->data[2], ··· 557 567 } 558 568 559 569 /* 560 - * Construct/deconstruct external filter IDs. These must be ordered 561 - * by matching priority, for RX NFC semantics. 570 + * Construct/deconstruct external filter IDs. At least the RX filter 571 + * IDs must be ordered by matching priority, for RX NFC semantics. 562 572 * 563 - * Each RX MAC filter entry has a flag for whether it can override an 564 - * RX IP filter that also matches. So we assign locations for MAC 565 - * filters with overriding behaviour, then for IP filters, then for 566 - * MAC filters without overriding behaviour. 573 + * Deconstruction needs to be robust against invalid IDs so that 574 + * efx_filter_remove_id_safe() and efx_filter_get_filter_safe() can 575 + * accept user-provided IDs. 567 576 */ 568 577 569 - #define EFX_FILTER_MATCH_PRI_RX_MAC_OVERRIDE_IP 0 570 - #define EFX_FILTER_MATCH_PRI_RX_DEF_OVERRIDE_IP 1 571 - #define EFX_FILTER_MATCH_PRI_NORMAL_BASE 2 578 + #define EFX_FILTER_MATCH_PRI_COUNT 5 579 + 580 + static const u8 efx_filter_type_match_pri[EFX_FILTER_TYPE_COUNT] = { 581 + [EFX_FILTER_TCP_FULL] = 0, 582 + [EFX_FILTER_UDP_FULL] = 0, 583 + [EFX_FILTER_TCP_WILD] = 1, 584 + [EFX_FILTER_UDP_WILD] = 1, 585 + [EFX_FILTER_MAC_FULL] = 2, 586 + [EFX_FILTER_MAC_WILD] = 3, 587 + [EFX_FILTER_UC_DEF] = 4, 588 + [EFX_FILTER_MC_DEF] = 4, 589 + }; 590 + 591 + static const enum efx_filter_table_id efx_filter_range_table[] = { 592 + EFX_FILTER_TABLE_RX_IP, /* RX match pri 0 */ 593 + EFX_FILTER_TABLE_RX_IP, 594 + EFX_FILTER_TABLE_RX_MAC, 595 + EFX_FILTER_TABLE_RX_MAC, 596 + EFX_FILTER_TABLE_RX_DEF, /* RX match pri 4 */ 597 + EFX_FILTER_TABLE_COUNT, /* TX match pri 0; invalid */ 598 + EFX_FILTER_TABLE_COUNT, /* invalid */ 599 + EFX_FILTER_TABLE_TX_MAC, 600 + EFX_FILTER_TABLE_TX_MAC, /* TX match pri 3 */ 601 + }; 572 602 573 603 #define EFX_FILTER_INDEX_WIDTH 13 574 604 #define EFX_FILTER_INDEX_MASK ((1 << EFX_FILTER_INDEX_WIDTH) - 1) 575 605 576 - static inline u32 efx_filter_make_id(enum efx_filter_table_id table_id, 577 - unsigned int index, u8 flags) 606 + static inline u32 607 + efx_filter_make_id(const struct efx_filter_spec *spec, unsigned int index) 578 608 { 579 - unsigned int match_pri = EFX_FILTER_MATCH_PRI_NORMAL_BASE + table_id; 609 + unsigned int range; 580 610 581 - if (flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP) { 582 - if (table_id == EFX_FILTER_TABLE_RX_MAC) 583 - match_pri = EFX_FILTER_MATCH_PRI_RX_MAC_OVERRIDE_IP; 584 - else if (table_id == EFX_FILTER_TABLE_RX_DEF) 585 - match_pri = EFX_FILTER_MATCH_PRI_RX_DEF_OVERRIDE_IP; 586 - } 611 + range = efx_filter_type_match_pri[spec->type]; 612 + if (!(spec->flags & EFX_FILTER_FLAG_RX)) 613 + range += EFX_FILTER_MATCH_PRI_COUNT; 587 614 588 - return match_pri << EFX_FILTER_INDEX_WIDTH | index; 615 + return range << EFX_FILTER_INDEX_WIDTH | index; 589 616 } 590 617 591 618 static inline enum efx_filter_table_id efx_filter_id_table_id(u32 id) 592 619 { 593 - unsigned int match_pri = id >> EFX_FILTER_INDEX_WIDTH; 620 + unsigned int range = id >> EFX_FILTER_INDEX_WIDTH; 594 621 595 - switch (match_pri) { 596 - case EFX_FILTER_MATCH_PRI_RX_MAC_OVERRIDE_IP: 597 - return EFX_FILTER_TABLE_RX_MAC; 598 - case EFX_FILTER_MATCH_PRI_RX_DEF_OVERRIDE_IP: 599 - return EFX_FILTER_TABLE_RX_DEF; 600 - default: 601 - return match_pri - EFX_FILTER_MATCH_PRI_NORMAL_BASE; 602 - } 622 + if (range < ARRAY_SIZE(efx_filter_range_table)) 623 + return efx_filter_range_table[range]; 624 + else 625 + return EFX_FILTER_TABLE_COUNT; /* invalid */ 603 626 } 604 627 605 628 static inline unsigned int efx_filter_id_index(u32 id) ··· 622 619 623 620 static inline u8 efx_filter_id_flags(u32 id) 624 621 { 625 - unsigned int match_pri = id >> EFX_FILTER_INDEX_WIDTH; 622 + unsigned int range = id >> EFX_FILTER_INDEX_WIDTH; 626 623 627 - if (match_pri < EFX_FILTER_MATCH_PRI_NORMAL_BASE) 628 - return EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_RX_OVERRIDE_IP; 629 - else if (match_pri <= 630 - EFX_FILTER_MATCH_PRI_NORMAL_BASE + EFX_FILTER_TABLE_RX_DEF) 624 + if (range < EFX_FILTER_MATCH_PRI_COUNT) 631 625 return EFX_FILTER_FLAG_RX; 632 626 else 633 627 return EFX_FILTER_FLAG_TX; ··· 633 633 u32 efx_filter_get_rx_id_limit(struct efx_nic *efx) 634 634 { 635 635 struct efx_filter_state *state = efx->filter_state; 636 - unsigned int table_id = EFX_FILTER_TABLE_RX_DEF; 636 + unsigned int range = EFX_FILTER_MATCH_PRI_COUNT - 1; 637 + enum efx_filter_table_id table_id; 637 638 638 639 do { 640 + table_id = efx_filter_range_table[range]; 639 641 if (state->table[table_id].size != 0) 640 - return ((EFX_FILTER_MATCH_PRI_NORMAL_BASE + table_id) 641 - << EFX_FILTER_INDEX_WIDTH) + 642 + return range << EFX_FILTER_INDEX_WIDTH | 642 643 state->table[table_id].size; 643 - } while (table_id--); 644 + } while (range--); 644 645 645 646 return 0; 646 647 } ··· 719 718 netif_vdbg(efx, hw, efx->net_dev, 720 719 "%s: filter type %d index %d rxq %u set", 721 720 __func__, spec->type, filter_idx, spec->dmaq_id); 722 - rc = efx_filter_make_id(table->id, filter_idx, spec->flags); 721 + rc = efx_filter_make_id(spec, filter_idx); 723 722 724 723 out: 725 724 spin_unlock_bh(&state->lock); ··· 782 781 spin_lock_bh(&state->lock); 783 782 784 783 if (test_bit(filter_idx, table->used_bitmap) && 785 - spec->priority == priority && 786 - !((spec->flags ^ filter_flags) & EFX_FILTER_FLAG_RX_OVERRIDE_IP)) { 784 + spec->priority == priority) { 787 785 efx_filter_table_clear_entry(efx, table, filter_idx); 788 786 if (table->used == 0) 789 787 efx_filter_table_reset_search_depth(table); ··· 833 833 spin_lock_bh(&state->lock); 834 834 835 835 if (test_bit(filter_idx, table->used_bitmap) && 836 - spec->priority == priority && 837 - !((spec->flags ^ filter_flags) & EFX_FILTER_FLAG_RX_OVERRIDE_IP)) { 836 + spec->priority == priority) { 838 837 *spec_buf = *spec; 839 838 rc = 0; 840 839 } else { ··· 926 927 goto out; 927 928 } 928 929 buf[count++] = efx_filter_make_id( 929 - table_id, filter_idx, 930 - table->spec[filter_idx].flags); 930 + &table->spec[filter_idx], filter_idx); 931 931 } 932 932 } 933 933 }
+1 -6
drivers/net/ethernet/sfc/filter.h
··· 61 61 * according to the indirection table. 62 62 * @EFX_FILTER_FLAG_RX_SCATTER: Enable DMA scatter on the receiving 63 63 * queue. 64 - * @EFX_FILTER_FLAG_RX_OVERRIDE_IP: Enables a MAC filter to override 65 - * any IP filter that matches the same packet. By default, IP 66 - * filters take precedence. 67 64 * @EFX_FILTER_FLAG_RX: Filter is for RX 68 65 * @EFX_FILTER_FLAG_TX: Filter is for TX 69 66 */ 70 67 enum efx_filter_flags { 71 68 EFX_FILTER_FLAG_RX_RSS = 0x01, 72 69 EFX_FILTER_FLAG_RX_SCATTER = 0x02, 73 - EFX_FILTER_FLAG_RX_OVERRIDE_IP = 0x04, 74 70 EFX_FILTER_FLAG_RX = 0x08, 75 71 EFX_FILTER_FLAG_TX = 0x10, 76 72 }; ··· 84 88 * 85 89 * The @priority field is used by software to determine whether a new 86 90 * filter may replace an old one. The hardware priority of a filter 87 - * depends on the filter type and %EFX_FILTER_FLAG_RX_OVERRIDE_IP 88 - * flag. 91 + * depends on the filter type. 89 92 */ 90 93 struct efx_filter_spec { 91 94 u8 type:4;
+4 -2
drivers/net/ethernet/sfc/mcdi.h
··· 113 113 #define MCDI_EVENT_FIELD(_ev, _field) \ 114 114 EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field) 115 115 #define MCDI_ARRAY_FIELD(_buf, _field1, _type, _index, _field2) \ 116 - EFX_DWORD_FIELD( \ 116 + EFX_EXTRACT_DWORD( \ 117 117 *((efx_dword_t *) \ 118 118 (MCDI_ARRAY_PTR(_buf, _field1, _type, _index) + \ 119 119 (MC_CMD_ ## _type ## _TYPEDEF_ ## _field2 ## _OFST & ~3))), \ 120 - MC_CMD_ ## _type ## _TYPEDEF_ ## _field2) 120 + MC_CMD_ ## _type ## _TYPEDEF_ ## _field2 ## _LBN & 0x1f, \ 121 + (MC_CMD_ ## _type ## _TYPEDEF_ ## _field2 ## _LBN & 0x1f) + \ 122 + MC_CMD_ ## _type ## _TYPEDEF_ ## _field2 ## _WIDTH - 1) 121 123 122 124 extern void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len); 123 125 extern int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
+2 -1
drivers/net/ethernet/sfc/selftest.c
··· 614 614 { 615 615 enum efx_loopback_mode mode; 616 616 struct efx_loopback_state *state; 617 - struct efx_channel *channel = efx_get_channel(efx, 0); 617 + struct efx_channel *channel = 618 + efx_get_channel(efx, efx->tx_channel_offset); 618 619 struct efx_tx_queue *tx_queue; 619 620 int rc = 0; 620 621
+1
drivers/net/ethernet/sfc/siena_sriov.c
··· 1035 1035 static const struct efx_channel_type efx_sriov_channel_type = { 1036 1036 .handle_no_channel = efx_sriov_handle_no_channel, 1037 1037 .pre_probe = efx_sriov_probe_channel, 1038 + .post_remove = efx_channel_dummy_op_void, 1038 1039 .get_name = efx_sriov_get_channel_name, 1039 1040 /* no copy operation; channel must not be reallocated */ 1040 1041 .keep_eventq = true,