.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /**************************************************************************** |
---|
2 | 3 | * Driver for Solarflare network controllers and boards |
---|
3 | 4 | * Copyright 2005-2006 Fen Systems Ltd. |
---|
4 | 5 | * Copyright 2006-2013 Solarflare Communications Inc. |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify it |
---|
7 | | - * under the terms of the GNU General Public License version 2 as published |
---|
8 | | - * by the Free Software Foundation, incorporated herein by reference. |
---|
9 | 6 | */ |
---|
10 | 7 | |
---|
11 | 8 | #include <linux/bitops.h> |
---|
.. | .. |
---|
18 | 15 | #include "net_driver.h" |
---|
19 | 16 | #include "bitfield.h" |
---|
20 | 17 | #include "efx.h" |
---|
| 18 | +#include "rx_common.h" |
---|
21 | 19 | #include "nic.h" |
---|
22 | 20 | #include "farch_regs.h" |
---|
23 | 21 | #include "sriov.h" |
---|
.. | .. |
---|
322 | 320 | unsigned write_ptr; |
---|
323 | 321 | unsigned old_write_count = tx_queue->write_count; |
---|
324 | 322 | |
---|
325 | | - tx_queue->xmit_more_available = false; |
---|
| 323 | + tx_queue->xmit_pending = false; |
---|
326 | 324 | if (unlikely(tx_queue->write_count == tx_queue->insert_count)) |
---|
327 | 325 | return; |
---|
328 | 326 | |
---|
.. | .. |
---|
374 | 372 | struct efx_nic *efx = tx_queue->efx; |
---|
375 | 373 | unsigned entries; |
---|
376 | 374 | |
---|
| 375 | + tx_queue->type = ((tx_queue->label & 1) ? EFX_TXQ_TYPE_OUTER_CSUM : 0) | |
---|
| 376 | + ((tx_queue->label & 2) ? EFX_TXQ_TYPE_HIGHPRI : 0); |
---|
377 | 377 | entries = tx_queue->ptr_mask + 1; |
---|
378 | 378 | return efx_alloc_special_buffer(efx, &tx_queue->txd, |
---|
379 | 379 | entries * sizeof(efx_qword_t)); |
---|
.. | .. |
---|
381 | 381 | |
---|
382 | 382 | void efx_farch_tx_init(struct efx_tx_queue *tx_queue) |
---|
383 | 383 | { |
---|
384 | | - int csum = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD; |
---|
| 384 | + int csum = tx_queue->type & EFX_TXQ_TYPE_OUTER_CSUM; |
---|
385 | 385 | struct efx_nic *efx = tx_queue->efx; |
---|
386 | 386 | efx_oword_t reg; |
---|
387 | 387 | |
---|
.. | .. |
---|
397 | 397 | FRF_AZ_TX_DESCQ_EVQ_ID, |
---|
398 | 398 | tx_queue->channel->channel, |
---|
399 | 399 | FRF_AZ_TX_DESCQ_OWNER_ID, 0, |
---|
400 | | - FRF_AZ_TX_DESCQ_LABEL, tx_queue->queue, |
---|
| 400 | + FRF_AZ_TX_DESCQ_LABEL, tx_queue->label, |
---|
401 | 401 | FRF_AZ_TX_DESCQ_SIZE, |
---|
402 | 402 | __ffs(tx_queue->txd.entries), |
---|
403 | 403 | FRF_AZ_TX_DESCQ_TYPE, 0, |
---|
.. | .. |
---|
411 | 411 | |
---|
412 | 412 | EFX_POPULATE_OWORD_1(reg, |
---|
413 | 413 | FRF_BZ_TX_PACE, |
---|
414 | | - (tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI) ? |
---|
| 414 | + (tx_queue->type & EFX_TXQ_TYPE_HIGHPRI) ? |
---|
415 | 415 | FFE_BZ_TX_PACE_OFF : |
---|
416 | 416 | FFE_BZ_TX_PACE_RESERVED); |
---|
417 | 417 | efx_writeo_table(efx, ®, FR_BZ_TX_PACE_TBL, tx_queue->queue); |
---|
| 418 | + |
---|
| 419 | + tx_queue->tso_version = 1; |
---|
418 | 420 | } |
---|
419 | 421 | |
---|
420 | 422 | static void efx_farch_flush_tx_queue(struct efx_tx_queue *tx_queue) |
---|
.. | .. |
---|
833 | 835 | /* Transmit completion */ |
---|
834 | 836 | tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR); |
---|
835 | 837 | tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL); |
---|
836 | | - tx_queue = efx_channel_get_tx_queue( |
---|
837 | | - channel, tx_ev_q_label % EFX_TXQ_TYPES); |
---|
| 838 | + tx_queue = channel->tx_queue + |
---|
| 839 | + (tx_ev_q_label % EFX_MAX_TXQ_PER_CHANNEL); |
---|
838 | 840 | efx_xmit_done(tx_queue, tx_ev_desc_ptr); |
---|
839 | 841 | } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) { |
---|
840 | 842 | /* Rewrite the FIFO write pointer */ |
---|
841 | 843 | tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL); |
---|
842 | | - tx_queue = efx_channel_get_tx_queue( |
---|
843 | | - channel, tx_ev_q_label % EFX_TXQ_TYPES); |
---|
| 844 | + tx_queue = channel->tx_queue + |
---|
| 845 | + (tx_ev_q_label % EFX_MAX_TXQ_PER_CHANNEL); |
---|
844 | 846 | |
---|
845 | 847 | netif_tx_lock(efx->net_dev); |
---|
846 | 848 | efx_farch_notify_tx_desc(tx_queue); |
---|
.. | .. |
---|
865 | 867 | bool rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err; |
---|
866 | 868 | bool rx_ev_frm_trunc, rx_ev_tobe_disc; |
---|
867 | 869 | bool rx_ev_other_err, rx_ev_pause_frm; |
---|
868 | | - bool rx_ev_hdr_type, rx_ev_mcast_pkt; |
---|
869 | | - unsigned rx_ev_pkt_type; |
---|
870 | 870 | |
---|
871 | | - rx_ev_hdr_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_HDR_TYPE); |
---|
872 | | - rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_MCAST_PKT); |
---|
873 | 871 | rx_ev_tobe_disc = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_TOBE_DISC); |
---|
874 | | - rx_ev_pkt_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PKT_TYPE); |
---|
875 | 872 | rx_ev_buf_owner_id_err = EFX_QWORD_FIELD(*event, |
---|
876 | 873 | FSF_AZ_RX_EV_BUF_OWNER_ID_ERR); |
---|
877 | 874 | rx_ev_ip_hdr_chksum_err = EFX_QWORD_FIELD(*event, |
---|
.. | .. |
---|
920 | 917 | rx_ev_tobe_disc ? " [TOBE_DISC]" : "", |
---|
921 | 918 | rx_ev_pause_frm ? " [PAUSE]" : ""); |
---|
922 | 919 | } |
---|
| 920 | +#else |
---|
| 921 | + (void) rx_ev_other_err; |
---|
923 | 922 | #endif |
---|
924 | 923 | |
---|
925 | 924 | if (efx->net_dev->features & NETIF_F_RXALL) |
---|
.. | .. |
---|
1040 | 1039 | switch (rx_ev_hdr_type) { |
---|
1041 | 1040 | case FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP: |
---|
1042 | 1041 | flags |= EFX_RX_PKT_TCP; |
---|
1043 | | - /* fall through */ |
---|
| 1042 | + fallthrough; |
---|
1044 | 1043 | case FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP: |
---|
1045 | 1044 | flags |= EFX_RX_PKT_CSUMMED; |
---|
1046 | | - /* fall through */ |
---|
| 1045 | + fallthrough; |
---|
1047 | 1046 | case FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_OTHER: |
---|
1048 | 1047 | case FSE_AZ_RX_EV_HDR_TYPE_OTHER: |
---|
1049 | 1048 | break; |
---|
.. | .. |
---|
1082 | 1081 | efx_farch_handle_tx_flush_done(struct efx_nic *efx, efx_qword_t *event) |
---|
1083 | 1082 | { |
---|
1084 | 1083 | struct efx_tx_queue *tx_queue; |
---|
| 1084 | + struct efx_channel *channel; |
---|
1085 | 1085 | int qid; |
---|
1086 | 1086 | |
---|
1087 | 1087 | qid = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_SUBDATA); |
---|
1088 | | - if (qid < EFX_TXQ_TYPES * (efx->n_tx_channels + efx->n_extra_tx_channels)) { |
---|
1089 | | - tx_queue = efx_get_tx_queue(efx, qid / EFX_TXQ_TYPES, |
---|
1090 | | - qid % EFX_TXQ_TYPES); |
---|
1091 | | - if (atomic_cmpxchg(&tx_queue->flush_outstanding, 1, 0)) { |
---|
| 1088 | + if (qid < EFX_MAX_TXQ_PER_CHANNEL * (efx->n_tx_channels + efx->n_extra_tx_channels)) { |
---|
| 1089 | + channel = efx_get_tx_channel(efx, qid / EFX_MAX_TXQ_PER_CHANNEL); |
---|
| 1090 | + tx_queue = channel->tx_queue + (qid % EFX_MAX_TXQ_PER_CHANNEL); |
---|
| 1091 | + if (atomic_cmpxchg(&tx_queue->flush_outstanding, 1, 0)) |
---|
1092 | 1092 | efx_farch_magic_event(tx_queue->channel, |
---|
1093 | 1093 | EFX_CHANNEL_MAGIC_TX_DRAIN(tx_queue)); |
---|
1094 | | - } |
---|
1095 | 1094 | } |
---|
1096 | 1095 | } |
---|
1097 | 1096 | |
---|
.. | .. |
---|
1318 | 1317 | if (efx->type->handle_global_event && |
---|
1319 | 1318 | efx->type->handle_global_event(channel, &event)) |
---|
1320 | 1319 | break; |
---|
1321 | | - /* else fall through */ |
---|
| 1320 | + fallthrough; |
---|
1322 | 1321 | default: |
---|
1323 | 1322 | netif_err(channel->efx, hw, channel->efx->net_dev, |
---|
1324 | 1323 | "channel %d unknown event type %d (data " |
---|
.. | .. |
---|
1680 | 1679 | * and the descriptor caches for those channels. |
---|
1681 | 1680 | */ |
---|
1682 | 1681 | buftbl_min = ((efx->n_rx_channels * EFX_MAX_DMAQ_SIZE + |
---|
1683 | | - total_tx_channels * EFX_TXQ_TYPES * EFX_MAX_DMAQ_SIZE + |
---|
| 1682 | + total_tx_channels * EFX_MAX_TXQ_PER_CHANNEL * EFX_MAX_DMAQ_SIZE + |
---|
1684 | 1683 | efx->n_channels * EFX_MAX_EVQ_SIZE) |
---|
1685 | 1684 | * sizeof(efx_qword_t) / EFX_BUF_SIZE); |
---|
1686 | | - vi_count = max(efx->n_channels, total_tx_channels * EFX_TXQ_TYPES); |
---|
| 1685 | + vi_count = max(efx->n_channels, total_tx_channels * EFX_MAX_TXQ_PER_CHANNEL); |
---|
1687 | 1686 | |
---|
1688 | 1687 | #ifdef CONFIG_SFC_SRIOV |
---|
1689 | 1688 | if (efx->type->sriov_wanted) { |
---|
.. | .. |
---|
2045 | 2044 | EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT | |
---|
2046 | 2045 | EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT): |
---|
2047 | 2046 | is_full = true; |
---|
2048 | | - /* fall through */ |
---|
| 2047 | + fallthrough; |
---|
2049 | 2048 | case (EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO | |
---|
2050 | 2049 | EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT): { |
---|
2051 | 2050 | __be32 rhost, host1, host2; |
---|
.. | .. |
---|
2096 | 2095 | |
---|
2097 | 2096 | case EFX_FILTER_MATCH_LOC_MAC | EFX_FILTER_MATCH_OUTER_VID: |
---|
2098 | 2097 | is_full = true; |
---|
2099 | | - /* fall through */ |
---|
| 2098 | + fallthrough; |
---|
2100 | 2099 | case EFX_FILTER_MATCH_LOC_MAC: |
---|
2101 | 2100 | spec->type = (is_full ? EFX_FARCH_FILTER_MAC_FULL : |
---|
2102 | 2101 | EFX_FARCH_FILTER_MAC_WILD); |
---|
.. | .. |
---|
2143 | 2142 | case EFX_FARCH_FILTER_TCP_FULL: |
---|
2144 | 2143 | case EFX_FARCH_FILTER_UDP_FULL: |
---|
2145 | 2144 | is_full = true; |
---|
2146 | | - /* fall through */ |
---|
| 2145 | + fallthrough; |
---|
2147 | 2146 | case EFX_FARCH_FILTER_TCP_WILD: |
---|
2148 | 2147 | case EFX_FARCH_FILTER_UDP_WILD: { |
---|
2149 | 2148 | __be32 host1, host2; |
---|
.. | .. |
---|
2187 | 2186 | |
---|
2188 | 2187 | case EFX_FARCH_FILTER_MAC_FULL: |
---|
2189 | 2188 | is_full = true; |
---|
2190 | | - /* fall through */ |
---|
| 2189 | + fallthrough; |
---|
2191 | 2190 | case EFX_FARCH_FILTER_MAC_WILD: |
---|
2192 | 2191 | gen_spec->match_flags = EFX_FILTER_MATCH_LOC_MAC; |
---|
2193 | 2192 | if (is_full) |
---|
.. | .. |
---|
2594 | 2593 | enum efx_farch_filter_table_id table_id; |
---|
2595 | 2594 | struct efx_farch_filter_table *table; |
---|
2596 | 2595 | unsigned int filter_idx; |
---|
2597 | | - struct efx_farch_filter_spec *spec; |
---|
2598 | 2596 | int rc; |
---|
2599 | 2597 | |
---|
2600 | 2598 | table_id = efx_farch_filter_id_table_id(filter_id); |
---|
.. | .. |
---|
2606 | 2604 | if (filter_idx >= table->size) |
---|
2607 | 2605 | return -ENOENT; |
---|
2608 | 2606 | down_write(&state->lock); |
---|
2609 | | - spec = &table->spec[filter_idx]; |
---|
2610 | 2607 | |
---|
2611 | 2608 | rc = efx_farch_filter_remove(efx, table, filter_idx, priority); |
---|
2612 | 2609 | up_write(&state->lock); |
---|