Skip to content

Commit 13b5b7f

Browse files
aneftinJeff Kirsher
authored andcommitted
igc: Add support for Tx/Rx rings
This change adds the defines and structures necessary to support both Tx and Rx descriptor rings. Signed-off-by: Sasha Neftin <[email protected]> Tested-by: Aaron Brown <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent 3df25e4 commit 13b5b7f

File tree

8 files changed

+1172
-1
lines changed

8 files changed

+1172
-1
lines changed

drivers/net/ethernet/intel/igc/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77

88
obj-$(CONFIG_IGC) += igc.o
99

10-
igc-objs := igc_main.o igc_mac.o
10+
igc-objs := igc_main.o igc_mac.o igc_base.o

drivers/net/ethernet/intel/igc/igc.h

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,79 @@ extern char igc_driver_version[];
4646
#define MAX_Q_VECTORS 8
4747
#define MAX_STD_JUMBO_FRAME_SIZE 9216
4848

49+
/* Supported Rx Buffer Sizes */
50+
#define IGC_RXBUFFER_256 256
51+
#define IGC_RXBUFFER_2048 2048
52+
#define IGC_RXBUFFER_3072 3072
53+
54+
#define IGC_RX_HDR_LEN IGC_RXBUFFER_256
55+
56+
/* RX and TX descriptor control thresholds.
57+
* PTHRESH - MAC will consider prefetch if it has fewer than this number of
58+
* descriptors available in its onboard memory.
59+
* Setting this to 0 disables RX descriptor prefetch.
60+
* HTHRESH - MAC will only prefetch if there are at least this many descriptors
61+
* available in host memory.
62+
* If PTHRESH is 0, this should also be 0.
63+
* WTHRESH - RX descriptor writeback threshold - MAC will delay writing back
64+
* descriptors until either it has this many to write back, or the
65+
* ITR timer expires.
66+
*/
67+
#define IGC_RX_PTHRESH 8
68+
#define IGC_RX_HTHRESH 8
69+
#define IGC_TX_PTHRESH 8
70+
#define IGC_TX_HTHRESH 1
71+
#define IGC_RX_WTHRESH 4
72+
#define IGC_TX_WTHRESH 16
73+
74+
#define IGC_RX_DMA_ATTR \
75+
(DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)
76+
77+
#define IGC_TS_HDR_LEN 16
78+
79+
#define IGC_SKB_PAD (NET_SKB_PAD + NET_IP_ALIGN)
80+
81+
#if (PAGE_SIZE < 8192)
82+
#define IGC_MAX_FRAME_BUILD_SKB \
83+
(SKB_WITH_OVERHEAD(IGC_RXBUFFER_2048) - IGC_SKB_PAD - IGC_TS_HDR_LEN)
84+
#else
85+
#define IGC_MAX_FRAME_BUILD_SKB (IGC_RXBUFFER_2048 - IGC_TS_HDR_LEN)
86+
#endif
87+
4988
enum igc_state_t {
5089
__IGC_TESTING,
5190
__IGC_RESETTING,
5291
__IGC_DOWN,
5392
__IGC_PTP_TX_IN_PROGRESS,
5493
};
5594

95+
/* wrapper around a pointer to a socket buffer,
96+
* so a DMA handle can be stored along with the buffer
97+
*/
98+
struct igc_tx_buffer {
99+
union igc_adv_tx_desc *next_to_watch;
100+
unsigned long time_stamp;
101+
struct sk_buff *skb;
102+
unsigned int bytecount;
103+
u16 gso_segs;
104+
__be16 protocol;
105+
106+
DEFINE_DMA_UNMAP_ADDR(dma);
107+
DEFINE_DMA_UNMAP_LEN(len);
108+
u32 tx_flags;
109+
};
110+
111+
struct igc_rx_buffer {
112+
dma_addr_t dma;
113+
struct page *page;
114+
#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
115+
__u32 page_offset;
116+
#else
117+
__u16 page_offset;
118+
#endif
119+
__u16 pagecnt_bias;
120+
};
121+
56122
struct igc_tx_queue_stats {
57123
u64 packets;
58124
u64 bytes;
@@ -214,4 +280,63 @@ struct igc_adapter {
214280
struct igc_mac_addr *mac_table;
215281
};
216282

283+
/* igc_desc_unused - calculate if we have unused descriptors */
284+
static inline u16 igc_desc_unused(const struct igc_ring *ring)
285+
{
286+
u16 ntc = ring->next_to_clean;
287+
u16 ntu = ring->next_to_use;
288+
289+
return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;
290+
}
291+
292+
static inline struct netdev_queue *txring_txq(const struct igc_ring *tx_ring)
293+
{
294+
return netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index);
295+
}
296+
297+
enum igc_ring_flags_t {
298+
IGC_RING_FLAG_RX_3K_BUFFER,
299+
IGC_RING_FLAG_RX_BUILD_SKB_ENABLED,
300+
IGC_RING_FLAG_RX_SCTP_CSUM,
301+
IGC_RING_FLAG_RX_LB_VLAN_BSWAP,
302+
IGC_RING_FLAG_TX_CTX_IDX,
303+
IGC_RING_FLAG_TX_DETECT_HANG
304+
};
305+
306+
#define ring_uses_large_buffer(ring) \
307+
test_bit(IGC_RING_FLAG_RX_3K_BUFFER, &(ring)->flags)
308+
309+
#define ring_uses_build_skb(ring) \
310+
test_bit(IGC_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)
311+
312+
static inline unsigned int igc_rx_bufsz(struct igc_ring *ring)
313+
{
314+
#if (PAGE_SIZE < 8192)
315+
if (ring_uses_large_buffer(ring))
316+
return IGC_RXBUFFER_3072;
317+
318+
if (ring_uses_build_skb(ring))
319+
return IGC_MAX_FRAME_BUILD_SKB + IGC_TS_HDR_LEN;
320+
#endif
321+
return IGC_RXBUFFER_2048;
322+
}
323+
324+
static inline unsigned int igc_rx_pg_order(struct igc_ring *ring)
325+
{
326+
#if (PAGE_SIZE < 8192)
327+
if (ring_uses_large_buffer(ring))
328+
return 1;
329+
#endif
330+
return 0;
331+
}
332+
333+
#define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring))
334+
335+
#define IGC_RX_DESC(R, i) \
336+
(&(((union igc_adv_rx_desc *)((R)->desc))[i]))
337+
#define IGC_TX_DESC(R, i) \
338+
(&(((union igc_adv_tx_desc *)((R)->desc))[i]))
339+
#define IGC_TX_CTXTDESC(R, i) \
340+
(&(((struct igc_adv_tx_context_desc *)((R)->desc))[i]))
341+
217342
#endif /* _IGC_H_ */
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2018 Intel Corporation */
3+
4+
#include <linux/delay.h>
5+
6+
#include "igc_hw.h"
7+
#include "igc_i225.h"
8+
9+
/**
10+
* igc_rx_fifo_flush_base - Clean rx fifo after Rx enable
11+
* @hw: pointer to the HW structure
12+
*
13+
* After Rx enable, if manageability is enabled then there is likely some
14+
* bad data at the start of the fifo and possibly in the DMA fifo. This
15+
* function clears the fifos and flushes any packets that came in as rx was
16+
* being enabled.
17+
*/
18+
void igc_rx_fifo_flush_base(struct igc_hw *hw)
19+
{
20+
u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
21+
int i, ms_wait;
22+
23+
/* disable IPv6 options as per hardware errata */
24+
rfctl = rd32(IGC_RFCTL);
25+
rfctl |= IGC_RFCTL_IPV6_EX_DIS;
26+
wr32(IGC_RFCTL, rfctl);
27+
28+
if (!(rd32(IGC_MANC) & IGC_MANC_RCV_TCO_EN))
29+
return;
30+
31+
/* Disable all Rx queues */
32+
for (i = 0; i < 4; i++) {
33+
rxdctl[i] = rd32(IGC_RXDCTL(i));
34+
wr32(IGC_RXDCTL(i),
35+
rxdctl[i] & ~IGC_RXDCTL_QUEUE_ENABLE);
36+
}
37+
/* Poll all queues to verify they have shut down */
38+
for (ms_wait = 0; ms_wait < 10; ms_wait++) {
39+
usleep_range(1000, 2000);
40+
rx_enabled = 0;
41+
for (i = 0; i < 4; i++)
42+
rx_enabled |= rd32(IGC_RXDCTL(i));
43+
if (!(rx_enabled & IGC_RXDCTL_QUEUE_ENABLE))
44+
break;
45+
}
46+
47+
if (ms_wait == 10)
48+
pr_debug("Queue disable timed out after 10ms\n");
49+
50+
/* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
51+
* incoming packets are rejected. Set enable and wait 2ms so that
52+
* any packet that was coming in as RCTL.EN was set is flushed
53+
*/
54+
wr32(IGC_RFCTL, rfctl & ~IGC_RFCTL_LEF);
55+
56+
rlpml = rd32(IGC_RLPML);
57+
wr32(IGC_RLPML, 0);
58+
59+
rctl = rd32(IGC_RCTL);
60+
temp_rctl = rctl & ~(IGC_RCTL_EN | IGC_RCTL_SBP);
61+
temp_rctl |= IGC_RCTL_LPE;
62+
63+
wr32(IGC_RCTL, temp_rctl);
64+
wr32(IGC_RCTL, temp_rctl | IGC_RCTL_EN);
65+
wrfl();
66+
usleep_range(2000, 3000);
67+
68+
/* Enable Rx queues that were previously enabled and restore our
69+
* previous state
70+
*/
71+
for (i = 0; i < 4; i++)
72+
wr32(IGC_RXDCTL(i), rxdctl[i]);
73+
wr32(IGC_RCTL, rctl);
74+
wrfl();
75+
76+
wr32(IGC_RLPML, rlpml);
77+
wr32(IGC_RFCTL, rfctl);
78+
79+
/* Flush receive errors generated by workaround */
80+
rd32(IGC_ROC);
81+
rd32(IGC_RNBC);
82+
rd32(IGC_MPC);
83+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/* Copyright (c) 2018 Intel Corporation */
3+
4+
#ifndef _IGC_BASE_H
5+
#define _IGC_BASE_H
6+
7+
/* forward declaration */
8+
void igc_rx_fifo_flush_base(struct igc_hw *hw);
9+
10+
/* Transmit Descriptor - Advanced */
11+
union igc_adv_tx_desc {
12+
struct {
13+
__le64 buffer_addr; /* Address of descriptor's data buf */
14+
__le32 cmd_type_len;
15+
__le32 olinfo_status;
16+
} read;
17+
struct {
18+
__le64 rsvd; /* Reserved */
19+
__le32 nxtseq_seed;
20+
__le32 status;
21+
} wb;
22+
};
23+
24+
struct igc_adv_data_desc {
25+
__le64 buffer_addr; /* Address of the descriptor's data buffer */
26+
union {
27+
u32 data;
28+
struct {
29+
u32 datalen:16; /* Data buffer length */
30+
u32 rsvd:4;
31+
u32 dtyp:4; /* Descriptor type */
32+
u32 dcmd:8; /* Descriptor command */
33+
} config;
34+
} lower;
35+
union {
36+
u32 data;
37+
struct {
38+
u32 status:4; /* Descriptor status */
39+
u32 idx:4;
40+
u32 popts:6; /* Packet Options */
41+
u32 paylen:18; /* Payload length */
42+
} options;
43+
} upper;
44+
};
45+
46+
/* Receive Descriptor - Advanced */
47+
union igc_adv_rx_desc {
48+
struct {
49+
__le64 pkt_addr; /* Packet buffer address */
50+
__le64 hdr_addr; /* Header buffer address */
51+
} read;
52+
struct {
53+
struct {
54+
union {
55+
__le32 data;
56+
struct {
57+
__le16 pkt_info; /*RSS type, Pkt type*/
58+
/* Split Header, header buffer len */
59+
__le16 hdr_info;
60+
} hs_rss;
61+
} lo_dword;
62+
union {
63+
__le32 rss; /* RSS Hash */
64+
struct {
65+
__le16 ip_id; /* IP id */
66+
__le16 csum; /* Packet Checksum */
67+
} csum_ip;
68+
} hi_dword;
69+
} lower;
70+
struct {
71+
__le32 status_error; /* ext status/error */
72+
__le16 length; /* Packet length */
73+
__le16 vlan; /* VLAN tag */
74+
} upper;
75+
} wb; /* writeback */
76+
};
77+
78+
/* Additional Transmit Descriptor Control definitions */
79+
#define IGC_TXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Tx Queue */
80+
81+
/* Additional Receive Descriptor Control definitions */
82+
#define IGC_RXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Rx Queue */
83+
84+
/* SRRCTL bit definitions */
85+
#define IGC_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
86+
#define IGC_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
87+
#define IGC_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
88+
89+
#endif /* _IGC_BASE_H */

drivers/net/ethernet/intel/igc/igc_defines.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@
5151
#define IGC_ICR_RXO BIT(6) /* Rx overrun */
5252
#define IGC_ICR_RXT0 BIT(7) /* Rx timer intr (ring 0) */
5353
#define IGC_ICR_DRSTA BIT(30) /* Device Reset Asserted */
54+
55+
/* If this bit asserted, the driver should claim the interrupt */
56+
#define IGC_ICR_INT_ASSERTED BIT(31)
57+
5458
#define IGC_ICS_RXT0 IGC_ICR_RXT0 /* Rx timer intr */
5559

5660
#define IMS_ENABLE_MASK ( \
@@ -80,6 +84,45 @@
8084
#define IGC_GPIE_EIAME 0x40000000
8185
#define IGC_GPIE_PBA 0x80000000
8286

87+
/* Transmit Control */
88+
#define IGC_TCTL_EN 0x00000002 /* enable Tx */
89+
#define IGC_TCTL_PSP 0x00000008 /* pad short packets */
90+
#define IGC_TCTL_CT 0x00000ff0 /* collision threshold */
91+
#define IGC_TCTL_COLD 0x003ff000 /* collision distance */
92+
#define IGC_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
93+
#define IGC_TCTL_MULR 0x10000000 /* Multiple request support */
94+
95+
#define IGC_CT_SHIFT 4
96+
#define IGC_COLLISION_THRESHOLD 15
97+
98+
/* Management Control */
99+
#define IGC_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
100+
101+
/* Receive Control */
102+
#define IGC_RCTL_RST 0x00000001 /* Software reset */
103+
#define IGC_RCTL_EN 0x00000002 /* enable */
104+
#define IGC_RCTL_SBP 0x00000004 /* store bad packet */
105+
#define IGC_RCTL_UPE 0x00000008 /* unicast promisc enable */
106+
#define IGC_RCTL_MPE 0x00000010 /* multicast promisc enable */
107+
#define IGC_RCTL_LPE 0x00000020 /* long packet enable */
108+
#define IGC_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
109+
#define IGC_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
110+
111+
#define IGC_RCTL_RDMTS_HALF 0x00000000 /* Rx desc min thresh size */
112+
#define IGC_RCTL_BAM 0x00008000 /* broadcast enable */
113+
114+
/* Header split receive */
115+
#define IGC_RFCTL_IPV6_EX_DIS 0x00010000
116+
#define IGC_RFCTL_LEF 0x00040000
117+
118+
#define IGC_RCTL_SZ_256 0x00030000 /* Rx buffer size 256 */
119+
120+
#define IGC_RCTL_MO_SHIFT 12 /* multicast offset shift */
121+
#define IGC_RCTL_CFIEN 0x00080000 /* canonical form enable */
122+
#define IGC_RCTL_DPF 0x00400000 /* discard pause frames */
123+
#define IGC_RCTL_PMCF 0x00800000 /* pass MAC control frames */
124+
#define IGC_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
125+
83126
#define IGC_N0_QUEUE -1
84127

85128
#endif /* _IGC_DEFINES_H_ */

drivers/net/ethernet/intel/igc/igc_hw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "igc_defines.h"
1111
#include "igc_mac.h"
1212
#include "igc_i225.h"
13+
#include "igc_base.h"
1314

1415
#define IGC_DEV_ID_I225_LM 0x15F2
1516
#define IGC_DEV_ID_I225_V 0x15F3

0 commit comments

Comments
 (0)