powerpc/perf/hv-24x7: Move cpumask file to top folder of hv-24x7 driver
[linux-2.6-microblaze.git] / drivers / net / ethernet / sfc / ef100_rx.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /****************************************************************************
3  * Driver for Solarflare network controllers and boards
4  * Copyright 2005-2019 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  */
10
11 #include "net_driver.h"
12 #include "ef100_rx.h"
13 #include "rx_common.h"
14 #include "efx.h"
15 #include "nic_common.h"
16 #include "mcdi_functions.h"
17 #include "ef100_regs.h"
18 #include "ef100_nic.h"
19 #include "io.h"
20
21 /* Get the value of a field in the RX prefix */
22 #define PREFIX_OFFSET_W(_f)     (ESF_GZ_RX_PREFIX_ ## _f ## _LBN / 32)
23 #define PREFIX_OFFSET_B(_f)     (ESF_GZ_RX_PREFIX_ ## _f ## _LBN % 32)
24 #define PREFIX_WIDTH_MASK(_f)   ((1UL << ESF_GZ_RX_PREFIX_ ## _f ## _WIDTH) - 1)
25 #define PREFIX_WORD(_p, _f)     le32_to_cpu((__force __le32)(_p)[PREFIX_OFFSET_W(_f)])
26 #define PREFIX_FIELD(_p, _f)    ((PREFIX_WORD(_p, _f) >> PREFIX_OFFSET_B(_f)) & \
27                                  PREFIX_WIDTH_MASK(_f))
28
29 #define ESF_GZ_RX_PREFIX_NT_OR_INNER_L3_CLASS_LBN       \
30                 (ESF_GZ_RX_PREFIX_CLASS_LBN + ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L3_CLASS_LBN)
31 #define ESF_GZ_RX_PREFIX_NT_OR_INNER_L3_CLASS_WIDTH     \
32                 ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L3_CLASS_WIDTH
33
34 static bool check_fcs(struct efx_channel *channel, u32 *prefix)
35 {
36         u16 rxclass;
37         u8 l2status;
38
39         rxclass = le16_to_cpu((__force __le16)PREFIX_FIELD(prefix, CLASS));
40         l2status = PREFIX_FIELD(&rxclass, HCLASS_L2_STATUS);
41
42         if (likely(l2status == ESE_GZ_RH_HCLASS_L2_STATUS_OK))
43                 /* Everything is ok */
44                 return 0;
45
46         if (l2status == ESE_GZ_RH_HCLASS_L2_STATUS_FCS_ERR)
47                 channel->n_rx_eth_crc_err++;
48         return 1;
49 }
50
51 void __ef100_rx_packet(struct efx_channel *channel)
52 {
53         struct efx_rx_buffer *rx_buf = efx_rx_buffer(&channel->rx_queue, channel->rx_pkt_index);
54         struct efx_nic *efx = channel->efx;
55         u8 *eh = efx_rx_buf_va(rx_buf);
56         __wsum csum = 0;
57         u32 *prefix;
58
59         prefix = (u32 *)(eh - ESE_GZ_RX_PKT_PREFIX_LEN);
60
61         if (check_fcs(channel, prefix) &&
62             unlikely(!(efx->net_dev->features & NETIF_F_RXALL)))
63                 goto out;
64
65         rx_buf->len = le16_to_cpu((__force __le16)PREFIX_FIELD(prefix, LENGTH));
66         if (rx_buf->len <= sizeof(struct ethhdr)) {
67                 if (net_ratelimit())
68                         netif_err(channel->efx, rx_err, channel->efx->net_dev,
69                                   "RX packet too small (%d)\n", rx_buf->len);
70                 ++channel->n_rx_frm_trunc;
71                 goto out;
72         }
73
74         if (likely(efx->net_dev->features & NETIF_F_RXCSUM)) {
75                 if (PREFIX_FIELD(prefix, NT_OR_INNER_L3_CLASS) == 1) {
76                         ++channel->n_rx_ip_hdr_chksum_err;
77                 } else {
78                         u16 sum = be16_to_cpu((__force __be16)PREFIX_FIELD(prefix, CSUM_FRAME));
79
80                         csum = (__force __wsum) sum;
81                 }
82         }
83
84         if (channel->type->receive_skb) {
85                 struct efx_rx_queue *rx_queue =
86                         efx_channel_get_rx_queue(channel);
87
88                 /* no support for special channels yet, so just discard */
89                 WARN_ON_ONCE(1);
90                 efx_free_rx_buffers(rx_queue, rx_buf, 1);
91                 goto out;
92         }
93
94         efx_rx_packet_gro(channel, rx_buf, channel->rx_pkt_n_frags, eh, csum);
95
96 out:
97         channel->rx_pkt_n_frags = 0;
98 }
99
100 static void ef100_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index)
101 {
102         struct efx_rx_buffer *rx_buf = efx_rx_buffer(rx_queue, index);
103         struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
104         struct efx_nic *efx = rx_queue->efx;
105
106         ++rx_queue->rx_packets;
107
108         netif_vdbg(efx, rx_status, efx->net_dev,
109                    "RX queue %d received id %x\n",
110                    efx_rx_queue_index(rx_queue), index);
111
112         efx_sync_rx_buffer(efx, rx_buf, efx->rx_dma_len);
113
114         prefetch(efx_rx_buf_va(rx_buf));
115
116         rx_buf->page_offset += efx->rx_prefix_size;
117
118         efx_recycle_rx_pages(channel, rx_buf, 1);
119
120         efx_rx_flush_packet(channel);
121         channel->rx_pkt_n_frags = 1;
122         channel->rx_pkt_index = index;
123 }
124
125 void efx_ef100_ev_rx(struct efx_channel *channel, const efx_qword_t *p_event)
126 {
127         struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel);
128         unsigned int n_packets =
129                 EFX_QWORD_FIELD(*p_event, ESF_GZ_EV_RXPKTS_NUM_PKT);
130         int i;
131
132         WARN_ON_ONCE(!n_packets);
133         if (n_packets > 1)
134                 ++channel->n_rx_merge_events;
135
136         channel->irq_mod_score += 2 * n_packets;
137
138         for (i = 0; i < n_packets; ++i) {
139                 ef100_rx_packet(rx_queue,
140                                 rx_queue->removed_count & rx_queue->ptr_mask);
141                 ++rx_queue->removed_count;
142         }
143 }
144
145 void ef100_rx_write(struct efx_rx_queue *rx_queue)
146 {
147         struct efx_rx_buffer *rx_buf;
148         unsigned int idx;
149         efx_qword_t *rxd;
150         efx_dword_t rxdb;
151
152         while (rx_queue->notified_count != rx_queue->added_count) {
153                 idx = rx_queue->notified_count & rx_queue->ptr_mask;
154                 rx_buf = efx_rx_buffer(rx_queue, idx);
155                 rxd = efx_rx_desc(rx_queue, idx);
156
157                 EFX_POPULATE_QWORD_1(*rxd, ESF_GZ_RX_BUF_ADDR, rx_buf->dma_addr);
158
159                 ++rx_queue->notified_count;
160         }
161
162         wmb();
163         EFX_POPULATE_DWORD_1(rxdb, ERF_GZ_RX_RING_PIDX,
164                              rx_queue->added_count & rx_queue->ptr_mask);
165         efx_writed_page(rx_queue->efx, &rxdb,
166                         ER_GZ_RX_RING_DOORBELL, efx_rx_queue_index(rx_queue));
167 }