* [Intel-wired-lan] [PATCH v3 05/11] igc: Add support for Tx/Rx rings
@ 2018-06-24 8:45 Sasha Neftin
2018-06-24 14:11 ` [Intel-wired-lan] [RFC PATCH] igc: igc_free_tx_resources() can be static kbuild test robot
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Sasha Neftin @ 2018-06-24 8:45 UTC (permalink / raw)
To: intel-wired-lan
This change adds the defines and structures necessary to support both Tx
and Rx descriptor rings.
Sasha Neftin (v2):
fixed code indentation
Sasha Nedftin (v3):
minor code fixes
Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
---
drivers/net/ethernet/intel/igc/Makefile | 3 +-
drivers/net/ethernet/intel/igc/e1000_base.c | 83 +++
drivers/net/ethernet/intel/igc/e1000_base.h | 89 +++
drivers/net/ethernet/intel/igc/e1000_defines.h | 53 ++
drivers/net/ethernet/intel/igc/e1000_hw.h | 1 +
drivers/net/ethernet/intel/igc/e1000_regs.h | 3 +
drivers/net/ethernet/intel/igc/igc.h | 127 ++++
drivers/net/ethernet/intel/igc/igc_main.c | 839 ++++++++++++++++++++++++-
8 files changed, 1193 insertions(+), 5 deletions(-)
create mode 100644 drivers/net/ethernet/intel/igc/e1000_base.c
create mode 100644 drivers/net/ethernet/intel/igc/e1000_base.h
diff --git a/drivers/net/ethernet/intel/igc/Makefile b/drivers/net/ethernet/intel/igc/Makefile
index 4563b83cd4e0..6a757ac8492d 100644
--- a/drivers/net/ethernet/intel/igc/Makefile
+++ b/drivers/net/ethernet/intel/igc/Makefile
@@ -7,4 +7,5 @@
obj-$(CONFIG_IGC) += igc.o
-igc-objs := igc_main.o e1000_mac.o
+igc-objs := igc_main.o e1000_mac.o \
+e1000_base.o
diff --git a/drivers/net/ethernet/intel/igc/e1000_base.c b/drivers/net/ethernet/intel/igc/e1000_base.c
new file mode 100644
index 000000000000..265ec98000e7
--- /dev/null
+++ b/drivers/net/ethernet/intel/igc/e1000_base.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018 Intel Corporation */
+
+#include <linux/delay.h>
+
+#include "e1000_hw.h"
+#include "e1000_i225.h"
+
+/**
+ * igc_rx_fifo_flush_base - Clean rx fifo after Rx enable
+ * @hw: pointer to the HW structure
+ *
+ * After Rx enable, if manageability is enabled then there is likely some
+ * bad data at the start of the fifo and possibly in the DMA fifo. This
+ * function clears the fifos and flushes any packets that came in as rx was
+ * being enabled.
+ **/
+void igc_rx_fifo_flush_base(struct e1000_hw *hw)
+{
+ u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
+ int i, ms_wait;
+
+ /* disable IPv6 options as per hardware errata */
+ rfctl = rd32(E1000_RFCTL);
+ rfctl |= E1000_RFCTL_IPV6_EX_DIS;
+ wr32(E1000_RFCTL, rfctl);
+
+ if (!(rd32(E1000_MANC) & E1000_MANC_RCV_TCO_EN))
+ return;
+
+ /* Disable all Rx queues */
+ for (i = 0; i < 4; i++) {
+ rxdctl[i] = rd32(E1000_RXDCTL(i));
+ wr32(E1000_RXDCTL(i),
+ rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
+ }
+ /* Poll all queues to verify they have shut down */
+ for (ms_wait = 0; ms_wait < 10; ms_wait++) {
+ usleep_range(1000, 2000);
+ rx_enabled = 0;
+ for (i = 0; i < 4; i++)
+ rx_enabled |= rd32(E1000_RXDCTL(i));
+ if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
+ break;
+ }
+
+ if (ms_wait == 10)
+ pr_debug("Queue disable timed out after 10ms\n");
+
+ /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
+ * incoming packets are rejected. Set enable and wait 2ms so that
+ * any packet that was coming in as RCTL.EN was set is flushed
+ */
+ wr32(E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
+
+ rlpml = rd32(E1000_RLPML);
+ wr32(E1000_RLPML, 0);
+
+ rctl = rd32(E1000_RCTL);
+ temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
+ temp_rctl |= E1000_RCTL_LPE;
+
+ wr32(E1000_RCTL, temp_rctl);
+ wr32(E1000_RCTL, temp_rctl | E1000_RCTL_EN);
+ wrfl();
+ usleep_range(2000, 3000);
+
+ /* Enable Rx queues that were previously enabled and restore our
+ * previous state
+ */
+ for (i = 0; i < 4; i++)
+ wr32(E1000_RXDCTL(i), rxdctl[i]);
+ wr32(E1000_RCTL, rctl);
+ wrfl();
+
+ wr32(E1000_RLPML, rlpml);
+ wr32(E1000_RFCTL, rfctl);
+
+ /* Flush receive errors generated by workaround */
+ rd32(E1000_ROC);
+ rd32(E1000_RNBC);
+ rd32(E1000_MPC);
+}
diff --git a/drivers/net/ethernet/intel/igc/e1000_base.h b/drivers/net/ethernet/intel/igc/e1000_base.h
new file mode 100644
index 000000000000..9acc41d73f4f
--- /dev/null
+++ b/drivers/net/ethernet/intel/igc/e1000_base.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2018 Intel Corporation */
+
+#ifndef _E1000_BASE_H
+#define _E1000_BASE_H
+
+/* forward declaration */
+void igc_rx_fifo_flush_base(struct e1000_hw *hw);
+
+/* Transmit Descriptor - Advanced */
+union e1000_adv_tx_desc {
+ struct {
+ __le64 buffer_addr; /* Address of descriptor's data buf */
+ __le32 cmd_type_len;
+ __le32 olinfo_status;
+ } read;
+ struct {
+ __le64 rsvd; /* Reserved */
+ __le32 nxtseq_seed;
+ __le32 status;
+ } wb;
+};
+
+struct e1000_adv_data_desc {
+ __le64 buffer_addr; /* Address of the descriptor's data buffer */
+ union {
+ u32 data;
+ struct {
+ u32 datalen:16; /* Data buffer length */
+ u32 rsvd:4;
+ u32 dtyp:4; /* Descriptor type */
+ u32 dcmd:8; /* Descriptor command */
+ } config;
+ } lower;
+ union {
+ u32 data;
+ struct {
+ u32 status:4; /* Descriptor status */
+ u32 idx:4;
+ u32 popts:6; /* Packet Options */
+ u32 paylen:18; /* Payload length */
+ } options;
+ } upper;
+};
+
+/* Receive Descriptor - Advanced */
+union e1000_adv_rx_desc {
+ struct {
+ __le64 pkt_addr; /* Packet buffer address */
+ __le64 hdr_addr; /* Header buffer address */
+ } read;
+ struct {
+ struct {
+ union {
+ __le32 data;
+ struct {
+ __le16 pkt_info; /*RSS type, Pkt type*/
+ /* Split Header, header buffer len */
+ __le16 hdr_info;
+ } hs_rss;
+ } lo_dword;
+ union {
+ __le32 rss; /* RSS Hash */
+ struct {
+ __le16 ip_id; /* IP id */
+ __le16 csum; /* Packet Checksum */
+ } csum_ip;
+ } hi_dword;
+ } lower;
+ struct {
+ __le32 status_error; /* ext status/error */
+ __le16 length; /* Packet length */
+ __le16 vlan; /* VLAN tag */
+ } upper;
+ } wb; /* writeback */
+};
+
+/* Additional Transmit Descriptor Control definitions */
+#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Tx Queue */
+
+/* Additional Receive Descriptor Control definitions */
+#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Rx Queue */
+
+/* SRRCTL bit definitions */
+#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
+#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
+#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
+
+#endif /* _E1000_BASE_H */
diff --git a/drivers/net/ethernet/intel/igc/e1000_defines.h b/drivers/net/ethernet/intel/igc/e1000_defines.h
index 1f8bc16c7029..66f8fc96dfb8 100644
--- a/drivers/net/ethernet/intel/igc/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igc/e1000_defines.h
@@ -71,6 +71,10 @@
#define E1000_ICR_RXO 0x00000040 /* Rx overrun */
#define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */
#define E1000_ICR_DRSTA 0x40000000 /* Device Reset Asserted */
+
+/* If this bit asserted, the driver should claim the interrupt */
+#define E1000_ICR_INT_ASSERTED 0x80000000
+
#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */
#define IMS_ENABLE_MASK ( \
@@ -97,4 +101,53 @@
#define E1000_GPIE_EIAME 0x40000000
#define E1000_GPIE_PBA 0x80000000
+/* Transmit Control */
+#define E1000_TCTL_EN 0x00000002 /* enable Tx */
+#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
+#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
+#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
+#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
+#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */
+
+#define E1000_CT_SHIFT 4
+#define E1000_COLLISION_THRESHOLD 15
+
+/* Management Control */
+#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
+
+/* Receive Control */
+#define E1000_RCTL_RST 0x00000001 /* Software reset */
+#define E1000_RCTL_EN 0x00000002 /* enable */
+#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
+#define E1000_RCTL_UPE 0x00000008 /* unicast promisc enable */
+#define E1000_RCTL_MPE 0x00000010 /* multicast promisc enable */
+#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
+#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
+#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
+#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
+#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
+
+#define E1000_RCTL_RDMTS_HALF 0x00000000 /* Rx desc min thresh size */
+#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
+
+/* Header split receive */
+#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
+#define E1000_RFCTL_LEF 0x00040000
+
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
+#define E1000_RCTL_SZ_2048 0x00000000 /* Rx buffer size 2048 */
+#define E1000_RCTL_SZ_1024 0x00010000 /* Rx buffer size 1024 */
+#define E1000_RCTL_SZ_512 0x00020000 /* Rx buffer size 512 */
+#define E1000_RCTL_SZ_256 0x00030000 /* Rx buffer size 256 */
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
+#define E1000_RCTL_SZ_16384 0x00010000 /* Rx buffer size 16384 */
+#define E1000_RCTL_SZ_8192 0x00020000 /* Rx buffer size 8192 */
+#define E1000_RCTL_SZ_4096 0x00030000 /* Rx buffer size 4096 */
+
+#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
+#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
+#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */
+#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
+#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
+
#endif /* _E1000_DEFINES_H_ */
diff --git a/drivers/net/ethernet/intel/igc/e1000_hw.h b/drivers/net/ethernet/intel/igc/e1000_hw.h
index 650c4ac981d9..67fa4f696b98 100644
--- a/drivers/net/ethernet/intel/igc/e1000_hw.h
+++ b/drivers/net/ethernet/intel/igc/e1000_hw.h
@@ -10,6 +10,7 @@
#include "e1000_defines.h"
#include "e1000_mac.h"
#include "e1000_i225.h"
+#include "e1000_base.h"
#define E1000_DEV_ID_I225_LM 0x15F2
#define E1000_DEV_ID_I225_V 0x15F3
diff --git a/drivers/net/ethernet/intel/igc/e1000_regs.h b/drivers/net/ethernet/intel/igc/e1000_regs.h
index 5634a01afff3..dcc4d89c9933 100644
--- a/drivers/net/ethernet/intel/igc/e1000_regs.h
+++ b/drivers/net/ethernet/intel/igc/e1000_regs.h
@@ -229,6 +229,9 @@
#define E1000_TLPIC 0x4148 /* EEE Tx LPI Count - TLPIC */
#define E1000_RLPIC 0x414C /* EEE Rx LPI Count - RLPIC */
+/* Management registers */
+#define E1000_MANC 0x05820 /* Management Control - RW */
+
/* forward declaration */
struct e1000_hw;
u32 igc_rd32(struct e1000_hw *hw, u32 reg);
diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index 7cab3e9c8e91..abf2e302c417 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -46,6 +46,47 @@ extern char igc_driver_version[];
#define MAX_Q_VECTORS 10
#define MAX_STD_JUMBO_FRAME_SIZE 9216
+#define IGC_TX_PTHRESH 8
+#define IGC_TX_HTHRESH 1
+
+/* Supported Rx Buffer Sizes */
+#define IGC_RXBUFFER_256 256
+#define IGC_RXBUFFER_2048 2048
+#define IGC_RXBUFFER_3072 3072
+
+#define IGC_RX_HDR_LEN IGC_RXBUFFER_256
+
+/* RX and TX descriptor control thresholds.
+ * PTHRESH - MAC will consider prefetch if it has fewer than this number of
+ * descriptors available in its onboard memory.
+ * Setting this to 0 disables RX descriptor prefetch.
+ * HTHRESH - MAC will only prefetch if there are@least this many descriptors
+ * available in host memory.
+ * If PTHRESH is 0, this should also be 0.
+ * WTHRESH - RX descriptor writeback threshold - MAC will delay writing back
+ * descriptors until either it has this many to write back, or the
+ * ITR timer expires.
+ */
+#define IGC_RX_PTHRESH 8
+#define IGC_RX_HTHRESH 8
+#define IGC_TX_PTHRESH 8
+#define IGC_TX_HTHRESH 1
+#define IGC_RX_WTHRESH 4
+
+#define IGC_RX_DMA_ATTR \
+ (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)
+
+#define IGC_TS_HDR_LEN 16
+
+#define IGC_SKB_PAD (NET_SKB_PAD + NET_IP_ALIGN)
+
+#if (PAGE_SIZE < 8192)
+#define IGC_MAX_FRAME_BUILD_SKB \
+ (SKB_WITH_OVERHEAD(IGC_RXBUFFER_2048) - IGC_SKB_PAD - IGC_TS_HDR_LEN)
+#else
+#define IGC_MAX_FRAME_BUILD_SKB (IGC_RXBUFFER_2048 - IGC_TS_HDR_LEN)
+#endif
+
enum e1000_state_t {
__IGC_TESTING,
__IGC_RESETTING,
@@ -53,6 +94,33 @@ enum e1000_state_t {
__IGC_PTP_TX_IN_PROGRESS,
};
+/** wrapper around a pointer to a socket buffer,
+ * so a DMA handle can be stored along with the buffer
+ **/
+struct igc_tx_buffer {
+ union e1000_adv_tx_desc *next_to_watch;
+ unsigned long time_stamp;
+ struct sk_buff *skb;
+ unsigned int bytecount;
+ u16 gso_segs;
+ __be16 protocol;
+
+ DEFINE_DMA_UNMAP_ADDR(dma);
+ DEFINE_DMA_UNMAP_LEN(len);
+ u32 tx_flags;
+};
+
+struct igc_rx_buffer {
+ dma_addr_t dma;
+ struct page *page;
+#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
+ __u32 page_offset;
+#else
+ __u16 page_offset;
+#endif
+ __u16 pagecnt_bias;
+};
+
struct igc_tx_queue_stats {
u64 packets;
u64 bytes;
@@ -218,4 +286,63 @@ struct igc_adapter {
struct igc_mac_addr *mac_table;
};
+/* igc_desc_unused - calculate if we have unused descriptors */
+static inline u16 igc_desc_unused(const struct igc_ring *ring)
+{
+ u16 ntc = ring->next_to_clean;
+ u16 ntu = ring->next_to_use;
+
+ return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;
+}
+
+static inline struct netdev_queue *txring_txq(const struct igc_ring *tx_ring)
+{
+ return netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index);
+}
+
+enum e1000_ring_flags_t {
+ IGC_RING_FLAG_RX_3K_BUFFER,
+ IGC_RING_FLAG_RX_BUILD_SKB_ENABLED,
+ IGC_RING_FLAG_RX_SCTP_CSUM,
+ IGC_RING_FLAG_RX_LB_VLAN_BSWAP,
+ IGC_RING_FLAG_TX_CTX_IDX,
+ IGC_RING_FLAG_TX_DETECT_HANG
+};
+
+#define ring_uses_large_buffer(ring) \
+ test_bit(IGC_RING_FLAG_RX_3K_BUFFER, &(ring)->flags)
+
+#define ring_uses_build_skb(ring) \
+ test_bit(IGC_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)
+
+static inline unsigned int igc_rx_bufsz(struct igc_ring *ring)
+{
+#if (PAGE_SIZE < 8192)
+ if (ring_uses_large_buffer(ring))
+ return IGC_RXBUFFER_3072;
+
+ if (ring_uses_build_skb(ring))
+ return IGC_MAX_FRAME_BUILD_SKB + IGC_TS_HDR_LEN;
+#endif
+ return IGC_RXBUFFER_2048;
+}
+
+static inline unsigned int igc_rx_pg_order(struct igc_ring *ring)
+{
+#if (PAGE_SIZE < 8192)
+ if (ring_uses_large_buffer(ring))
+ return 1;
+#endif
+ return 0;
+}
+
+#define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring))
+
+#define IGC_RX_DESC(R, i) \
+ (&(((union e1000_adv_rx_desc *)((R)->desc))[i]))
+#define IGC_TX_DESC(R, i) \
+ (&(((union e1000_adv_tx_desc *)((R)->desc))[i]))
+#define IGC_TX_CTXTDESC(R, i) \
+ (&(((struct e1000_adv_tx_context_desc *)((R)->desc))[i]))
+
#endif /* _IGC_H_ */
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 30b778c9b94b..a147a1b7585e 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -29,11 +29,21 @@ static const struct pci_device_id igc_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, igc_pci_tbl);
/* forward declaration */
+static int igc_setup_all_tx_resources(struct igc_adapter *adapter);
+static void igc_clean_tx_ring(struct igc_ring *tx_ring);
+static void igc_free_all_tx_resources(struct igc_adapter *adapter);
+static int igc_setup_all_rx_resources(struct igc_adapter *adapter);
static int igc_sw_init(struct igc_adapter *);
static void igc_configure(struct igc_adapter *adapter);
+static void igc_configure_tx(struct igc_adapter *);
+static void igc_configure_rx(struct igc_adapter *adapter);
static void igc_power_down_link(struct igc_adapter *adapter);
static void igc_set_default_mac_filter(struct igc_adapter *adapter);
+static void igc_set_rx_mode(struct net_device *netdev);
+static void igc_setup_mrqc(struct igc_adapter *adapter);
static irqreturn_t igc_msix_ring(int irq, void *data);
+static irqreturn_t igc_intr_msi(int irq, void *data);
+static irqreturn_t igc_intr(int irq, void *data);
static void igc_write_itr(struct igc_q_vector *q_vector);
static int igc_request_msix(struct igc_adapter *adapter);
static void igc_assign_vector(struct igc_q_vector *q_vector, int msix_vector);
@@ -125,6 +135,526 @@ static void igc_get_hw_control(struct igc_adapter *adapter)
}
/**
+ * igc_free_tx_resources - Free Tx Resources per Queue
+ * @tx_ring: Tx descriptor ring for a specific queue
+ *
+ * Free all transmit software resources
+ **/
+void igc_free_tx_resources(struct igc_ring *tx_ring)
+{
+ igc_clean_tx_ring(tx_ring);
+
+ vfree(tx_ring->tx_buffer_info);
+ tx_ring->tx_buffer_info = NULL;
+
+ /* if not set, then don't free */
+ if (!tx_ring->desc)
+ return;
+
+ dma_free_coherent(tx_ring->dev, tx_ring->size,
+ tx_ring->desc, tx_ring->dma);
+
+ tx_ring->desc = NULL;
+}
+
+/**
+ * igc_free_all_tx_resources - Free Tx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ **/
+static void igc_free_all_tx_resources(struct igc_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ igc_free_tx_resources(adapter->tx_ring[i]);
+}
+
+void igc_unmap_and_free_tx_resource(struct igc_ring *ring,
+ struct igc_tx_buffer *tx_buffer)
+{
+ if (tx_buffer->skb) {
+ dev_kfree_skb_any(tx_buffer->skb);
+ if (dma_unmap_len(tx_buffer, len))
+ dma_unmap_single(ring->dev,
+ dma_unmap_addr(tx_buffer, dma),
+ dma_unmap_len(tx_buffer, len),
+ DMA_TO_DEVICE);
+ } else if (dma_unmap_len(tx_buffer, len)) {
+ dma_unmap_page(ring->dev,
+ dma_unmap_addr(tx_buffer, dma),
+ dma_unmap_len(tx_buffer, len),
+ DMA_TO_DEVICE);
+ }
+ tx_buffer->next_to_watch = NULL;
+ tx_buffer->skb = NULL;
+ dma_unmap_len_set(tx_buffer, len, 0);
+ /* buffer_info must be completely set up in the transmit path */
+}
+
+/**
+ * igc_clean_tx_ring - Free Tx Buffers
+ * @tx_ring: ring to be cleaned
+ **/
+static void igc_clean_tx_ring(struct igc_ring *tx_ring)
+{
+ struct igc_tx_buffer *buffer_info;
+ unsigned long size;
+ u16 i;
+
+ if (!tx_ring->tx_buffer_info)
+ return;
+
+ /* Free all the Tx ring sk_buffs */
+ for (i = 0; i < tx_ring->count; i++) {
+ buffer_info = &tx_ring->tx_buffer_info[i];
+ igc_unmap_and_free_tx_resource(tx_ring, buffer_info);
+ }
+
+ netdev_tx_reset_queue(txring_txq(tx_ring));
+
+ size = sizeof(struct igc_tx_buffer) * tx_ring->count;
+ memset(tx_ring->tx_buffer_info, 0, size);
+
+ /* Zero out the descriptor ring */
+ memset(tx_ring->desc, 0, tx_ring->size);
+
+ tx_ring->next_to_use = 0;
+ tx_ring->next_to_clean = 0;
+}
+
+/**
+ * igc_setup_tx_resources - allocate Tx resources (Descriptors)
+ * @tx_ring: tx descriptor ring (for a specific queue) to setup
+ *
+ * Return 0 on success, negative on failure
+ **/
+int igc_setup_tx_resources(struct igc_ring *tx_ring)
+{
+ struct device *dev = tx_ring->dev;
+ int size = 0;
+
+ size = sizeof(struct igc_tx_buffer) * tx_ring->count;
+ tx_ring->tx_buffer_info = vzalloc(size);
+ if (!tx_ring->tx_buffer_info)
+ goto err;
+
+ /* round up to nearest 4K */
+ tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
+ tx_ring->size = ALIGN(tx_ring->size, 4096);
+
+ tx_ring->desc = dma_alloc_coherent(dev, tx_ring->size,
+ &tx_ring->dma, GFP_KERNEL);
+
+ if (!tx_ring->desc)
+ goto err;
+
+ tx_ring->next_to_use = 0;
+ tx_ring->next_to_clean = 0;
+
+ return 0;
+
+err:
+ vfree(tx_ring->tx_buffer_info);
+ dev_err(dev,
+ "Unable to allocate memory for the transmit descriptor ring\n");
+ return -ENOMEM;
+}
+
+/**
+ * igc_setup_all_tx_resources - wrapper to allocate Tx resources
+ * (Descriptors) for all queues
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ **/
+static int igc_setup_all_tx_resources(struct igc_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ int i, err = 0;
+
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ err = igc_setup_tx_resources(adapter->tx_ring[i]);
+ if (err) {
+ dev_err(&pdev->dev,
+ "Allocation for Tx Queue %u failed\n", i);
+ for (i--; i >= 0; i--)
+ igc_free_tx_resources(adapter->tx_ring[i]);
+ break;
+ }
+ }
+
+ return err;
+}
+
+/**
+ * igc_clean_rx_ring - Free Rx Buffers per Queue
+ * @rx_ring: ring to free buffers from
+ **/
+void igc_clean_rx_ring(struct igc_ring *rx_ring)
+{
+ u16 i = rx_ring->next_to_clean;
+
+ if (rx_ring->skb)
+ dev_kfree_skb(rx_ring->skb);
+ rx_ring->skb = NULL;
+
+ /* Free all the Rx ring sk_buffs */
+ while (i != rx_ring->next_to_alloc) {
+ struct igc_rx_buffer *buffer_info = &rx_ring->rx_buffer_info[i];
+
+ /* Invalidate cache lines that may have been written to by
+ * device so that we avoid corrupting memory.
+ */
+ dma_sync_single_range_for_cpu(rx_ring->dev,
+ buffer_info->dma,
+ buffer_info->page_offset,
+ igc_rx_bufsz(rx_ring),
+ DMA_FROM_DEVICE);
+
+ /* free resources associated with mapping */
+ dma_unmap_page_attrs(rx_ring->dev,
+ buffer_info->dma,
+ igc_rx_pg_size(rx_ring),
+ DMA_FROM_DEVICE,
+ IGC_RX_DMA_ATTR);
+ __page_frag_cache_drain(buffer_info->page,
+ buffer_info->pagecnt_bias);
+
+ i++;
+ if (i == rx_ring->count)
+ i = 0;
+ }
+
+ rx_ring->next_to_alloc = 0;
+ rx_ring->next_to_clean = 0;
+ rx_ring->next_to_use = 0;
+}
+
+/**
+ * igc_free_rx_resources - Free Rx Resources
+ * @rx_ring: ring to clean the resources from
+ *
+ * Free all receive software resources
+ **/
+void igc_free_rx_resources(struct igc_ring *rx_ring)
+{
+ igc_clean_rx_ring(rx_ring);
+
+ vfree(rx_ring->rx_buffer_info);
+ rx_ring->rx_buffer_info = NULL;
+
+ /* if not set, then don't free */
+ if (!rx_ring->desc)
+ return;
+
+ dma_free_coherent(rx_ring->dev, rx_ring->size,
+ rx_ring->desc, rx_ring->dma);
+
+ rx_ring->desc = NULL;
+}
+
+/**
+ * igc_free_all_rx_resources - Free Rx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all receive software resources
+ **/
+static void igc_free_all_rx_resources(struct igc_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ igc_free_rx_resources(adapter->rx_ring[i]);
+}
+
+/**
+ * igc_setup_rx_resources - allocate Rx resources (Descriptors)
+ * @rx_ring: rx descriptor ring (for a specific queue) to setup
+ *
+ * Returns 0 on success, negative on failure
+ **/
+int igc_setup_rx_resources(struct igc_ring *rx_ring)
+{
+ struct device *dev = rx_ring->dev;
+ int size, desc_len;
+
+ size = sizeof(struct igc_rx_buffer) * rx_ring->count;
+ rx_ring->rx_buffer_info = vzalloc(size);
+ if (!rx_ring->rx_buffer_info)
+ goto err;
+
+ desc_len = sizeof(union e1000_adv_rx_desc);
+
+ /* Round up to nearest 4K */
+ rx_ring->size = rx_ring->count * desc_len;
+ rx_ring->size = ALIGN(rx_ring->size, 4096);
+
+ rx_ring->desc = dma_alloc_coherent(dev, rx_ring->size,
+ &rx_ring->dma, GFP_KERNEL);
+
+ if (!rx_ring->desc)
+ goto err;
+
+ rx_ring->next_to_alloc = 0;
+ rx_ring->next_to_clean = 0;
+ rx_ring->next_to_use = 0;
+
+ return 0;
+
+err:
+ vfree(rx_ring->rx_buffer_info);
+ rx_ring->rx_buffer_info = NULL;
+ dev_err(dev,
+ "Unable to allocate memory for the receive descriptor ring\n");
+ return -ENOMEM;
+}
+
+/**
+ * igc_setup_all_rx_resources - wrapper to allocate Rx resources
+ * (Descriptors) for all queues
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ **/
+static int igc_setup_all_rx_resources(struct igc_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ int i, err = 0;
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ err = igc_setup_rx_resources(adapter->rx_ring[i]);
+ if (err) {
+ dev_err(&pdev->dev,
+ "Allocation for Rx Queue %u failed\n", i);
+ for (i--; i >= 0; i--)
+ igc_free_rx_resources(adapter->rx_ring[i]);
+ break;
+ }
+ }
+
+ return err;
+}
+
+static u32 igc_tx_wthresh(struct igc_adapter *adapter)
+{
+ return 16;
+}
+
+/**
+ * igc_configure_rx_ring - Configure a receive ring after Reset
+ * @adapter: board private structure
+ * @ring: receive ring to be configured
+ *
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+void igc_configure_rx_ring(struct igc_adapter *adapter,
+ struct igc_ring *ring)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ union e1000_adv_rx_desc *rx_desc;
+ u64 rdba = ring->dma;
+ int reg_idx = ring->reg_idx;
+ u32 srrctl = 0, rxdctl = 0;
+
+ /* disable the queue */
+ wr32(E1000_RXDCTL(reg_idx), 0);
+
+ /* Set DMA base address registers */
+ wr32(E1000_RDBAL(reg_idx),
+ rdba & 0x00000000ffffffffULL);
+ wr32(E1000_RDBAH(reg_idx), rdba >> 32);
+ wr32(E1000_RDLEN(reg_idx),
+ ring->count * sizeof(union e1000_adv_rx_desc));
+
+ /* initialize head and tail */
+ ring->tail = adapter->io_addr + E1000_RDT(reg_idx);
+ wr32(E1000_RDH(reg_idx), 0);
+ writel(0, ring->tail);
+
+ /* reset next-to- use/clean to place SW in sync with hardwdare */
+ ring->next_to_clean = 0;
+ ring->next_to_use = 0;
+
+ /* set descriptor configuration */
+ srrctl = IGC_RX_HDR_LEN << E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
+ if (ring_uses_large_buffer(ring))
+ srrctl |= IGC_RXBUFFER_3072 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
+ else
+ srrctl |= IGC_RXBUFFER_2048 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
+ srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
+
+ wr32(E1000_SRRCTL(reg_idx), srrctl);
+
+ rxdctl |= IGC_RX_PTHRESH;
+ rxdctl |= IGC_RX_HTHRESH << 8;
+ rxdctl |= IGC_RX_WTHRESH << 16;
+
+ /* initialize rx_buffer_info */
+ memset(ring->rx_buffer_info, 0,
+ sizeof(struct igc_rx_buffer) * ring->count);
+
+ /* initialize Rx descriptor 0 */
+ rx_desc = IGC_RX_DESC(ring, 0);
+ rx_desc->wb.upper.length = 0;
+
+ /* enable receive descriptor fetching */
+ rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
+
+ wr32(E1000_RXDCTL(reg_idx), rxdctl);
+}
+
+/**
+ * igc_configure_rx - Configure receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+static void igc_configure_rx(struct igc_adapter *adapter)
+{
+ int i;
+
+ /* Setup the HW Rx Head and Tail Descriptor Pointers and
+ * the Base and Length of the Rx Descriptor Ring
+ */
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ igc_configure_rx_ring(adapter, adapter->rx_ring[i]);
+}
+
+/**
+ * igc_configure_tx_ring - Configure transmit ring after Reset
+ * @adapter: board private structure
+ * @ring: tx ring to configure
+ *
+ * Configure a transmit ring after a reset.
+ **/
+void igc_configure_tx_ring(struct igc_adapter *adapter,
+ struct igc_ring *ring)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 txdctl = 0;
+ u64 tdba = ring->dma;
+ int reg_idx = ring->reg_idx;
+
+ /* disable the queue */
+ wr32(E1000_TXDCTL(reg_idx), 0);
+ wrfl();
+ mdelay(10);
+
+ wr32(E1000_TDLEN(reg_idx),
+ ring->count * sizeof(union e1000_adv_tx_desc));
+ wr32(E1000_TDBAL(reg_idx),
+ tdba & 0x00000000ffffffffULL);
+ wr32(E1000_TDBAH(reg_idx), tdba >> 32);
+
+ ring->tail = adapter->io_addr + E1000_TDT(reg_idx);
+ wr32(E1000_TDH(reg_idx), 0);
+ writel(0, ring->tail);
+
+ txdctl |= IGC_TX_PTHRESH;
+ txdctl |= IGC_TX_HTHRESH << 8;
+ txdctl |= igc_tx_wthresh(adapter) << 16;
+
+ txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
+ wr32(E1000_TXDCTL(reg_idx), txdctl);
+}
+
+/**
+ * igc_configure_tx - Configure transmit Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx unit of the MAC after a reset.
+ **/
+static void igc_configure_tx(struct igc_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ igc_configure_tx_ring(adapter, adapter->tx_ring[i]);
+}
+
+/**
+ * igc_setup_mrqc - configure the multiple receive queue control registers
+ * @adapter: Board private structure
+ **/
+static void igc_setup_mrqc(struct igc_adapter *adapter)
+{
+}
+
+/**
+ * igc_setup_rctl - configure the receive control registers
+ * @adapter: Board private structure
+ **/
+void igc_setup_rctl(struct igc_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 rctl;
+
+ rctl = rd32(E1000_RCTL);
+
+ rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
+ rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
+
+ rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_RDMTS_HALF |
+ (hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
+
+ /* enable stripping of CRC. It's unlikely this will break BMC
+ * redirection as it did with e1000. Newer features require
+ * that the HW strips the CRC.
+ */
+ rctl |= E1000_RCTL_SECRC;
+
+ /* disable store bad packets and clear size bits. */
+ rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_SZ_256);
+
+ /* enable LPE to allow for reception of jumbo frames */
+ rctl |= E1000_RCTL_LPE;
+
+ /* disable queue 0 to prevent tail write w/o re-config */
+ wr32(E1000_RXDCTL(0), 0);
+
+ /* This is useful for sniffing bad packets. */
+ if (adapter->netdev->features & NETIF_F_RXALL) {
+ /* UPE and MPE will be handled by normal PROMISC logic
+ * in e1000e_set_rx_mode
+ */
+ rctl |= (E1000_RCTL_SBP | /* Receive bad packets */
+ E1000_RCTL_BAM | /* RX All Bcast Pkts */
+ E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
+
+ rctl &= ~(E1000_RCTL_DPF | /* Allow filtered pause */
+ E1000_RCTL_CFIEN); /* Disable VLAN CFIEN Filter */
+ }
+
+ wr32(E1000_RCTL, rctl);
+}
+
+/**
+ * igc_setup_tctl - configure the transmit control registers
+ * @adapter: Board private structure
+ **/
+void igc_setup_tctl(struct igc_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 tctl;
+
+ /* disable queue 0 which icould be enabled by default */
+ wr32(E1000_TXDCTL(0), 0);
+
+ /* Program the Transmit Control Register */
+ tctl = rd32(E1000_TCTL);
+ tctl &= ~E1000_TCTL_CT;
+ tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
+ (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
+
+ /* Enable transmits */
+ tctl |= E1000_TCTL_EN;
+
+ wr32(E1000_TCTL, tctl);
+}
+
+/**
* igc_set_mac - Change the Ethernet Address of the NIC
* @netdev: network interface device structure
* @p: pointer to an address structure
@@ -156,6 +686,121 @@ static netdev_tx_t igc_xmit_frame(struct sk_buff *skb,
return NETDEV_TX_OK;
}
+static inline unsigned int igc_rx_offset(struct igc_ring *rx_ring)
+{
+ return ring_uses_build_skb(rx_ring) ? IGC_SKB_PAD : 0;
+}
+
+static bool igc_alloc_mapped_page(struct igc_ring *rx_ring,
+ struct igc_rx_buffer *bi)
+{
+ struct page *page = bi->page;
+ dma_addr_t dma;
+
+ /* since we are recycling buffers we should seldom need to alloc */
+ if (likely(page))
+ return true;
+
+ /* alloc new page for storage */
+ page = dev_alloc_pages(igc_rx_pg_order(rx_ring));
+ if (unlikely(!page)) {
+ rx_ring->rx_stats.alloc_failed++;
+ return false;
+ }
+
+ /* map page for use */
+ dma = dma_map_page_attrs(rx_ring->dev, page, 0,
+ igc_rx_pg_size(rx_ring),
+ DMA_FROM_DEVICE,
+ IGC_RX_DMA_ATTR);
+
+ /* if mapping failed free memory back to system since
+ * there isn't much point in holding memory we can't use
+ */
+ if (dma_mapping_error(rx_ring->dev, dma)) {
+ __free_page(page);
+
+ rx_ring->rx_stats.alloc_failed++;
+ return false;
+ }
+
+ bi->dma = dma;
+ bi->page = page;
+ bi->page_offset = igc_rx_offset(rx_ring);
+ bi->pagecnt_bias = 1;
+
+ return true;
+}
+
+/**
+ * igc_alloc_rx_buffers - Replace used receive buffers; packet split
+ * @adapter: address of board private structure
+ **/
+void igc_alloc_rx_buffers(struct igc_ring *rx_ring, u16 cleaned_count)
+{
+ union e1000_adv_rx_desc *rx_desc;
+ struct igc_rx_buffer *bi;
+ u16 i = rx_ring->next_to_use;
+ u16 bufsz;
+
+ /* nothing to do */
+ if (!cleaned_count)
+ return;
+
+ rx_desc = IGC_RX_DESC(rx_ring, i);
+ bi = &rx_ring->rx_buffer_info[i];
+ i -= rx_ring->count;
+
+ bufsz = igc_rx_bufsz(rx_ring);
+
+ do {
+ if (!igc_alloc_mapped_page(rx_ring, bi))
+ break;
+
+ /* sync the buffer for use by the device */
+ dma_sync_single_range_for_device(rx_ring->dev, bi->dma,
+ bi->page_offset, bufsz,
+ DMA_FROM_DEVICE);
+
+ /* Refresh the desc even if buffer_addrs didn't change
+ * because each write-back erases this info.
+ */
+ rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset);
+
+ rx_desc++;
+ bi++;
+ i++;
+ if (unlikely(!i)) {
+ rx_desc = IGC_RX_DESC(rx_ring, 0);
+ bi = rx_ring->rx_buffer_info;
+ i -= rx_ring->count;
+ }
+
+ /* clear the length for the next_to_use descriptor */
+ rx_desc->wb.upper.length = 0;
+
+ cleaned_count--;
+ } while (cleaned_count);
+
+ i += rx_ring->count;
+
+ if (rx_ring->next_to_use != i) {
+ /* record the next descriptor to use */
+ rx_ring->next_to_use = i;
+
+ /* update next to alloc since we have filled the ring */
+ rx_ring->next_to_alloc = i;
+
+ /* Force memory writes to complete before letting h/w
+ * know there are new descriptors to fetch. (Only
+ * applicable for weak-ordered memory model archs,
+ * such as IA-64).
+ */
+ wmb();
+ writel(i, rx_ring->tail);
+ }
+}
+
/**
* igc_ioctl - I/O control method
* @netdev: network interface device structure
@@ -196,6 +841,12 @@ int igc_up(struct igc_adapter *adapter)
rd32(E1000_ICR);
igc_irq_enable(adapter);
+ netif_tx_start_all_queues(adapter->netdev);
+
+ /* start the watchdog. */
+ hw->mac.get_link_status = 1;
+ schedule_work(&adapter->watchdog_task);
+
return 0;
}
@@ -295,7 +946,30 @@ static struct net_device_stats *igc_get_stats(struct net_device *netdev)
**/
static void igc_configure(struct igc_adapter *adapter)
{
+ struct net_device *netdev = adapter->netdev;
+ int i = 0;
+
igc_get_hw_control(adapter);
+ igc_set_rx_mode(netdev);
+
+ igc_setup_tctl(adapter);
+ igc_setup_mrqc(adapter);
+ igc_setup_rctl(adapter);
+
+ igc_configure_tx(adapter);
+ igc_configure_rx(adapter);
+
+ igc_rx_fifo_flush_base(&adapter->hw);
+
+ /* call igc_desc_unused which always leaves
+ * at least 1 descriptor unused to make sure
+ * next_to_use != next_to_clean
+ */
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ struct igc_ring *ring = adapter->rx_ring[i];
+
+ igc_alloc_rx_buffers(ring, igc_desc_unused(ring));
+ }
}
/**
@@ -343,6 +1017,19 @@ static void igc_set_default_mac_filter(struct igc_adapter *adapter)
igc_rar_set_index(adapter, 0);
}
+/**
+ * igc_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_rx_mode entry point is called whenever the unicast or multicast
+ * address lists or the network interface flags are updated. This routine is
+ * responsible for configuring the hardware for proper unicast, multicast,
+ * promiscuous mode, and all-multi behavior.
+ **/
+static void igc_set_rx_mode(struct net_device *netdev)
+{
+}
+
static irqreturn_t igc_msix_other(int irq, void *data)
{
struct igc_adapter *adapter = data;
@@ -781,6 +1468,83 @@ static void igc_update_itr(struct igc_q_vector *q_vector,
ring_container->itr = itrval;
}
+/**
+ * igc_intr_msi - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ **/
+static irqreturn_t igc_intr_msi(int irq, void *data)
+{
+ struct igc_adapter *adapter = data;
+ struct igc_q_vector *q_vector = adapter->q_vector[0];
+ struct e1000_hw *hw = &adapter->hw;
+ /* read ICR disables interrupts using IAM */
+ u32 icr = rd32(E1000_ICR);
+
+ igc_write_itr(q_vector);
+
+ if (icr & E1000_ICR_DRSTA)
+ schedule_work(&adapter->reset_task);
+
+ if (icr & E1000_ICR_DOUTSYNC) {
+ /* HW is reporting DMA is out of sync */
+ adapter->stats.doosync++;
+ }
+
+ if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+ hw->mac.get_link_status = 1;
+ if (!test_bit(__IGC_DOWN, &adapter->state))
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
+ }
+
+ napi_schedule(&q_vector->napi);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * igc_intr - Legacy Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ **/
+static irqreturn_t igc_intr(int irq, void *data)
+{
+ struct igc_adapter *adapter = data;
+ struct igc_q_vector *q_vector = adapter->q_vector[0];
+ struct e1000_hw *hw = &adapter->hw;
+ /* Interrupt Auto-Mask...upon reading ICR, interrupts are masked. No
+ * need for the IMC write
+ */
+ u32 icr = rd32(E1000_ICR);
+
+ /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
+ * not set, then the adapter didn't send an interrupt
+ */
+ if (!(icr & E1000_ICR_INT_ASSERTED))
+ return IRQ_NONE;
+
+ igc_write_itr(q_vector);
+
+ if (icr & E1000_ICR_DRSTA)
+ schedule_work(&adapter->reset_task);
+
+ if (icr & E1000_ICR_DOUTSYNC) {
+ /* HW is reporting DMA is out of sync */
+ adapter->stats.doosync++;
+ }
+
+ if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+ hw->mac.get_link_status = 1;
+ /* guard against interrupt when we're going down */
+ if (!test_bit(__IGC_DOWN, &adapter->state))
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
+ }
+
+ napi_schedule(&q_vector->napi);
+
+ return IRQ_HANDLED;
+}
+
static void igc_ring_irq_enable(struct igc_q_vector *q_vector)
{
struct igc_adapter *adapter = q_vector->adapter;
@@ -1148,6 +1912,29 @@ static int igc_alloc_q_vectors(struct igc_adapter *adapter)
}
/**
+ * igc_cache_ring_register - Descriptor ring to register mapping
+ * @adapter: board private structure to initialize
+ *
+ * Once we know the feature-set enabled for the device, we'll cache
+ * the register offset the descriptor ring is assigned to.
+ **/
+static void igc_cache_ring_register(struct igc_adapter *adapter)
+{
+ int i = 0, j = 0;
+
+ switch (adapter->hw.mac.type) {
+ case e1000_i225:
+ /* Fall through */
+ default:
+ for (; i < adapter->num_rx_queues; i++)
+ adapter->rx_ring[i]->reg_idx = i;
+ for (; j < adapter->num_tx_queues; j++)
+ adapter->tx_ring[j]->reg_idx = j;
+ break;
+ }
+}
+
+/**
* igc_init_interrupt_scheme - initialize interrupts, allocate queues/vectors
* @adapter: Pointer to adapter structure
*
@@ -1166,7 +1953,7 @@ static int igc_init_interrupt_scheme(struct igc_adapter *adapter, bool msix)
goto err_alloc_q_vectors;
}
- /* TODO complete igc_cache_ring_register */
+ igc_cache_ring_register(adapter);
return 0;
@@ -1255,6 +2042,8 @@ static void igc_irq_enable(struct igc_adapter *adapter)
**/
static int igc_request_irq(struct igc_adapter *adapter)
{
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
int err = 0;
if (adapter->flags & IGC_FLAG_HAS_MSIX) {
@@ -1262,16 +2051,38 @@ static int igc_request_irq(struct igc_adapter *adapter)
if (!err)
goto request_done;
/* fall back to MSI */
- /* TODO complete free tx/rx resources */
+ igc_free_all_tx_resources(adapter);
+ igc_free_all_rx_resources(adapter);
igc_clear_interrupt_scheme(adapter);
err = igc_init_interrupt_scheme(adapter, false);
if (err)
goto request_done;
- /* TODO complete setup tx/rx resources */
+ igc_setup_all_tx_resources(adapter);
+ igc_setup_all_rx_resources(adapter);
igc_configure(adapter);
}
+ igc_assign_vector(adapter->q_vector[0], 0);
+
+ if (adapter->flags & IGC_FLAG_HAS_MSI) {
+ err = request_irq(pdev->irq, &igc_intr_msi, 0,
+ netdev->name, adapter);
+ if (!err)
+ goto request_done;
+
+ /* fall back to legacy interrupts */
+ igc_reset_interrupt_capability(adapter);
+ adapter->flags &= ~IGC_FLAG_HAS_MSI;
+ }
+
+ err = request_irq(pdev->irq, &igc_intr, IRQF_SHARED,
+ netdev->name, adapter);
+
+ if (err)
+ dev_err(&pdev->dev, "Error %d getting interrupt\n",
+ err);
+
request_done:
return err;
}
@@ -1332,6 +2143,16 @@ static int __igc_open(struct net_device *netdev, bool resuming)
netif_carrier_off(netdev);
+ /* allocate transmit descriptors */
+ err = igc_setup_all_tx_resources(adapter);
+ if (err)
+ goto err_setup_tx;
+
+ /* allocate receive descriptors */
+ err = igc_setup_all_rx_resources(adapter);
+ if (err)
+ goto err_setup_rx;
+
igc_power_up_link(adapter);
igc_configure(adapter);
@@ -1357,6 +2178,8 @@ static int __igc_open(struct net_device *netdev, bool resuming)
rd32(E1000_ICR);
igc_irq_enable(adapter);
+ netif_tx_start_all_queues(netdev);
+
/* start the watchdog. */
hw->mac.get_link_status = 1;
schedule_work(&adapter->watchdog_task);
@@ -1368,7 +2191,11 @@ static int __igc_open(struct net_device *netdev, bool resuming)
err_req_irq:
igc_release_hw_control(adapter);
igc_power_down_link(adapter);
- /* TODO complete free_all_rx_resources */
+ igc_free_all_rx_resources(adapter);
+err_setup_rx:
+ igc_free_all_tx_resources(adapter);
+err_setup_tx:
+ igc_reset(adapter);
return err;
}
@@ -1401,6 +2228,9 @@ static int __igc_close(struct net_device *netdev, bool suspending)
igc_free_irq(adapter);
+ igc_free_all_tx_resources(adapter);
+ igc_free_all_rx_resources(adapter);
+
return 0;
}
@@ -1415,6 +2245,7 @@ static const struct net_device_ops igc_netdev_ops = {
.ndo_open = igc_open,
.ndo_stop = igc_close,
.ndo_start_xmit = igc_xmit_frame,
+ .ndo_set_rx_mode = igc_set_rx_mode,
.ndo_set_mac_address = igc_set_mac,
.ndo_change_mtu = igc_change_mtu,
.ndo_get_stats = igc_get_stats,
--
2.11.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Intel-wired-lan] [PATCH v3 05/11] igc: Add support for Tx/Rx rings
2018-06-24 8:45 [Intel-wired-lan] [PATCH v3 05/11] igc: Add support for Tx/Rx rings Sasha Neftin
2018-06-24 14:11 ` [Intel-wired-lan] [RFC PATCH] igc: igc_free_tx_resources() can be static kbuild test robot
@ 2018-06-24 14:11 ` kbuild test robot
2018-06-28 0:42 ` Shannon Nelson
2 siblings, 0 replies; 8+ messages in thread
From: kbuild test robot @ 2018-06-24 14:11 UTC (permalink / raw)
To: intel-wired-lan
Hi Sasha,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on jkirsher-next-queue/dev-queue]
[also build test WARNING on v4.18-rc2 next-20180622]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Sasha-Neftin/igc-Add-skeletal-frame-for-Intel-R-2-5G-Ethernet-Controller-support/20180624-164739
base: https://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue.git dev-queue
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__
sparse warnings: (new ones prefixed by >>)
include/linux/slab.h:631:13: sparse: undefined identifier '__builtin_mul_overflow'
drivers/net/ethernet/intel/igc/igc_main.c:1991:17: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:1991:17: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:1991:17: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:1992:17: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:1992:17: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:1992:17: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:1994:17: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:1994:17: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:1994:17: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:1997:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:1997:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:1997:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:1998:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:1998:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:1998:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:2025:17: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:2025:17: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:2025:17: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:2027:17: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:2027:17: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:2027:17: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:2028:17: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:2028:17: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:2028:17: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:2029:17: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:2029:17: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:2029:17: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:2031:17: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:2031:17: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:2031:17: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:2032:17: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:2032:17: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:2032:17: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:1144:17: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:1144:17: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:1144:17: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:1152:17: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:1152:17: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:1152:17: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:1563:25: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:1563:25: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:1563:25: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:1589:23: sparse: expression using sizeof(void)
drivers/net/ethernet/intel/igc/igc_main.c:1589:23: sparse: expression using sizeof(void)
drivers/net/ethernet/intel/igc/igc_main.c:1619:27: sparse: expression using sizeof(void)
drivers/net/ethernet/intel/igc/igc_main.c:1619:27: sparse: expression using sizeof(void)
drivers/net/ethernet/intel/igc/igc_main.c:1365:33: sparse: expression using sizeof(void)
drivers/net/ethernet/intel/igc/igc_main.c:1365:33: sparse: expression using sizeof(void)
drivers/net/ethernet/intel/igc/igc_main.c:1376:25: sparse: expression using sizeof(void)
drivers/net/ethernet/intel/igc/igc_main.c:77:6: sparse: symbol 'igc_reset' was not declared. Should it be static?
drivers/net/ethernet/intel/igc/igc_main.c:87:6: sparse: symbol 'igc_power_up_link' was not declared. Should it be static?
drivers/net/ethernet/intel/igc/igc_main.c:114:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:114:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:114:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:133:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:133:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:133:9: got unsigned char [usertype] *__val
>> drivers/net/ethernet/intel/igc/igc_main.c:143:6: sparse: symbol 'igc_free_tx_resources' was not declared. Should it be static?
>> drivers/net/ethernet/intel/igc/igc_main.c:174:6: sparse: symbol 'igc_unmap_and_free_tx_resource' was not declared. Should it be static?
>> drivers/net/ethernet/intel/igc/igc_main.c:233:5: sparse: symbol 'igc_setup_tx_resources' was not declared. Should it be static?
>> drivers/net/ethernet/intel/igc/igc_main.c:295:6: sparse: symbol 'igc_clean_rx_ring' was not declared. Should it be static?
>> drivers/net/ethernet/intel/igc/igc_main.c:341:6: sparse: symbol 'igc_free_rx_resources' was not declared. Should it be static?
>> drivers/net/ethernet/intel/igc/igc_main.c:378:5: sparse: symbol 'igc_setup_rx_resources' was not declared. Should it be static?
drivers/net/ethernet/intel/igc/igc_main.c:462:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:462:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:462:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:465:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:465:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:465:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:467:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:467:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:467:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:468:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:468:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:468:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:473:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:473:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:473:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:488:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:488:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:488:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:505:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:505:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:505:9: got unsigned char [usertype] *__val
>> drivers/net/ethernet/intel/igc/igc_main.c:452:6: sparse: symbol 'igc_configure_rx_ring' was not declared. Should it be static?
drivers/net/ethernet/intel/igc/igc_main.c:541:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:541:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:541:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:545:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:545:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:545:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:547:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:547:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:547:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:549:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:549:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:549:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:552:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:552:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:552:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:560:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:560:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:560:9: got unsigned char [usertype] *__val
>> drivers/net/ethernet/intel/igc/igc_main.c:532:6: sparse: symbol 'igc_configure_tx_ring' was not declared. Should it be static?
drivers/net/ethernet/intel/igc/igc_main.c:615:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:615:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:615:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:630:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:630:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:630:9: got unsigned char [usertype] *__val
>> drivers/net/ethernet/intel/igc/igc_main.c:589:6: sparse: symbol 'igc_setup_rctl' was not declared. Should it be static?
drivers/net/ethernet/intel/igc/igc_main.c:643:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:643:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:643:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:654:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:654:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:654:9: got unsigned char [usertype] *__val
>> drivers/net/ethernet/intel/igc/igc_main.c:637:6: sparse: symbol 'igc_setup_tctl' was not declared. Should it be static?
>> drivers/net/ethernet/intel/igc/igc_main.c:739:6: sparse: symbol 'igc_alloc_rx_buffers' was not declared. Should it be static?
drivers/net/ethernet/intel/igc/igc_main.c:822:5: sparse: symbol 'igc_up' was not declared. Should it be static?
drivers/net/ethernet/intel/igc/igc_main.c:857:6: sparse: symbol 'igc_down' was not declared. Should it be static?
drivers/net/ethernet/intel/igc/igc_main.c:921:6: sparse: symbol 'igc_update_stats' was not declared. Should it be static?
drivers/net/ethernet/intel/igc/igc_main.c:1003:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:1003:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:1003:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:1005:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:1005:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:1005:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:1055:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:1055:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:1055:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:1083:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:1083:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:1083:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:2203:5: sparse: symbol 'igc_open' was not declared. Should it be static?
drivers/net/ethernet/intel/igc/igc_main.c:2237:5: sparse: symbol 'igc_close' was not declared. Should it be static?
drivers/net/ethernet/intel/igc/igc_main.c:2302:31: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:2302:31: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:2302:31: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/igc_main.c:2404:21: sparse: incorrect type in assignment (different address spaces) @@ expected unsigned char [usertype] *hw_addr @@ got unsigned char [nounsigned char [usertype] *hw_addr @@
drivers/net/ethernet/intel/igc/igc_main.c:2404:21: expected unsigned char [usertype] *hw_addr
drivers/net/ethernet/intel/igc/igc_main.c:2404:21: got unsigned char [noderef] [usertype] <asn:2>*io_addr
include/linux/slab.h:631:13: sparse: call with no type!
--
>> drivers/net/ethernet/intel/igc/e1000_base.c:26:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/e1000_base.c:26:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/e1000_base.c:26:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/e1000_base.c:34:17: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/e1000_base.c:34:17: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/e1000_base.c:34:17: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/e1000_base.c:54:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/e1000_base.c:54:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/e1000_base.c:54:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/e1000_base.c:57:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/e1000_base.c:57:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/e1000_base.c:57:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/e1000_base.c:63:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/e1000_base.c:63:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/e1000_base.c:63:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/e1000_base.c:64:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/e1000_base.c:64:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/e1000_base.c:64:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/e1000_base.c:72:17: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/e1000_base.c:72:17: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/e1000_base.c:72:17: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/e1000_base.c:73:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/e1000_base.c:73:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/e1000_base.c:73:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/e1000_base.c:76:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/e1000_base.c:76:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/e1000_base.c:76:9: got unsigned char [usertype] *__val
drivers/net/ethernet/intel/igc/e1000_base.c:77:9: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned char [noderef] [usertype] <asn:2>*hw_addr @@ got deref] [usertype] <asn:2>*hw_addr @@
drivers/net/ethernet/intel/igc/e1000_base.c:77:9: expected unsigned char [noderef] [usertype] <asn:2>*hw_addr
drivers/net/ethernet/intel/igc/e1000_base.c:77:9: got unsigned char [usertype] *__val
Please review and possibly fold the followup patch.
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Intel-wired-lan] [RFC PATCH] igc: igc_free_tx_resources() can be static
2018-06-24 8:45 [Intel-wired-lan] [PATCH v3 05/11] igc: Add support for Tx/Rx rings Sasha Neftin
@ 2018-06-24 14:11 ` kbuild test robot
2018-06-28 8:15 ` Neftin, Sasha
2018-06-24 14:11 ` [Intel-wired-lan] [PATCH v3 05/11] igc: Add support for Tx/Rx rings kbuild test robot
2018-06-28 0:42 ` Shannon Nelson
2 siblings, 1 reply; 8+ messages in thread
From: kbuild test robot @ 2018-06-24 14:11 UTC (permalink / raw)
To: intel-wired-lan
Fixes: 6ae8ddd68f6a ("igc: Add support for Tx/Rx rings")
Signed-off-by: kbuild test robot <fengguang.wu@intel.com>
---
igc_main.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index a147a1b..78370abc 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -140,7 +140,7 @@ static void igc_get_hw_control(struct igc_adapter *adapter)
*
* Free all transmit software resources
**/
-void igc_free_tx_resources(struct igc_ring *tx_ring)
+static void igc_free_tx_resources(struct igc_ring *tx_ring)
{
igc_clean_tx_ring(tx_ring);
@@ -171,8 +171,8 @@ static void igc_free_all_tx_resources(struct igc_adapter *adapter)
igc_free_tx_resources(adapter->tx_ring[i]);
}
-void igc_unmap_and_free_tx_resource(struct igc_ring *ring,
- struct igc_tx_buffer *tx_buffer)
+static void igc_unmap_and_free_tx_resource(struct igc_ring *ring,
+ struct igc_tx_buffer *tx_buffer)
{
if (tx_buffer->skb) {
dev_kfree_skb_any(tx_buffer->skb);
@@ -230,7 +230,7 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring)
*
* Return 0 on success, negative on failure
**/
-int igc_setup_tx_resources(struct igc_ring *tx_ring)
+static int igc_setup_tx_resources(struct igc_ring *tx_ring)
{
struct device *dev = tx_ring->dev;
int size = 0;
@@ -292,7 +292,7 @@ static int igc_setup_all_tx_resources(struct igc_adapter *adapter)
* igc_clean_rx_ring - Free Rx Buffers per Queue
* @rx_ring: ring to free buffers from
**/
-void igc_clean_rx_ring(struct igc_ring *rx_ring)
+static void igc_clean_rx_ring(struct igc_ring *rx_ring)
{
u16 i = rx_ring->next_to_clean;
@@ -338,7 +338,7 @@ void igc_clean_rx_ring(struct igc_ring *rx_ring)
*
* Free all receive software resources
**/
-void igc_free_rx_resources(struct igc_ring *rx_ring)
+static void igc_free_rx_resources(struct igc_ring *rx_ring)
{
igc_clean_rx_ring(rx_ring);
@@ -375,7 +375,7 @@ static void igc_free_all_rx_resources(struct igc_adapter *adapter)
*
* Returns 0 on success, negative on failure
**/
-int igc_setup_rx_resources(struct igc_ring *rx_ring)
+static int igc_setup_rx_resources(struct igc_ring *rx_ring)
{
struct device *dev = rx_ring->dev;
int size, desc_len;
@@ -449,8 +449,8 @@ static u32 igc_tx_wthresh(struct igc_adapter *adapter)
*
* Configure the Rx unit of the MAC after a reset.
**/
-void igc_configure_rx_ring(struct igc_adapter *adapter,
- struct igc_ring *ring)
+static void igc_configure_rx_ring(struct igc_adapter *adapter,
+ struct igc_ring *ring)
{
struct e1000_hw *hw = &adapter->hw;
union e1000_adv_rx_desc *rx_desc;
@@ -529,8 +529,8 @@ static void igc_configure_rx(struct igc_adapter *adapter)
*
* Configure a transmit ring after a reset.
**/
-void igc_configure_tx_ring(struct igc_adapter *adapter,
- struct igc_ring *ring)
+static void igc_configure_tx_ring(struct igc_adapter *adapter,
+ struct igc_ring *ring)
{
struct e1000_hw *hw = &adapter->hw;
u32 txdctl = 0;
@@ -586,7 +586,7 @@ static void igc_setup_mrqc(struct igc_adapter *adapter)
* igc_setup_rctl - configure the receive control registers
* @adapter: Board private structure
**/
-void igc_setup_rctl(struct igc_adapter *adapter)
+static void igc_setup_rctl(struct igc_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
u32 rctl;
@@ -634,7 +634,7 @@ void igc_setup_rctl(struct igc_adapter *adapter)
* igc_setup_tctl - configure the transmit control registers
* @adapter: Board private structure
**/
-void igc_setup_tctl(struct igc_adapter *adapter)
+static void igc_setup_tctl(struct igc_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
u32 tctl;
@@ -736,7 +736,7 @@ static bool igc_alloc_mapped_page(struct igc_ring *rx_ring,
* igc_alloc_rx_buffers - Replace used receive buffers; packet split
* @adapter: address of board private structure
**/
-void igc_alloc_rx_buffers(struct igc_ring *rx_ring, u16 cleaned_count)
+static void igc_alloc_rx_buffers(struct igc_ring *rx_ring, u16 cleaned_count)
{
union e1000_adv_rx_desc *rx_desc;
struct igc_rx_buffer *bi;
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Intel-wired-lan] [PATCH v3 05/11] igc: Add support for Tx/Rx rings
2018-06-24 8:45 [Intel-wired-lan] [PATCH v3 05/11] igc: Add support for Tx/Rx rings Sasha Neftin
2018-06-24 14:11 ` [Intel-wired-lan] [RFC PATCH] igc: igc_free_tx_resources() can be static kbuild test robot
2018-06-24 14:11 ` [Intel-wired-lan] [PATCH v3 05/11] igc: Add support for Tx/Rx rings kbuild test robot
@ 2018-06-28 0:42 ` Shannon Nelson
2018-07-03 13:17 ` Neftin, Sasha
2 siblings, 1 reply; 8+ messages in thread
From: Shannon Nelson @ 2018-06-28 0:42 UTC (permalink / raw)
To: intel-wired-lan
On 6/24/2018 1:45 AM, Sasha Neftin wrote:
> This change adds the defines and structures necessary to support both Tx
> and Rx descriptor rings.
>
> Sasha Neftin (v2):
> fixed code indentation
>
> Sasha Nedftin (v3):
> minor code fixes
>
> Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
> ---
> drivers/net/ethernet/intel/igc/Makefile | 3 +-
> drivers/net/ethernet/intel/igc/e1000_base.c | 83 +++
> drivers/net/ethernet/intel/igc/e1000_base.h | 89 +++
> drivers/net/ethernet/intel/igc/e1000_defines.h | 53 ++
> drivers/net/ethernet/intel/igc/e1000_hw.h | 1 +
> drivers/net/ethernet/intel/igc/e1000_regs.h | 3 +
> drivers/net/ethernet/intel/igc/igc.h | 127 ++++
> drivers/net/ethernet/intel/igc/igc_main.c | 839 ++++++++++++++++++++++++-
> 8 files changed, 1193 insertions(+), 5 deletions(-)
> create mode 100644 drivers/net/ethernet/intel/igc/e1000_base.c
> create mode 100644 drivers/net/ethernet/intel/igc/e1000_base.h
>
> diff --git a/drivers/net/ethernet/intel/igc/Makefile b/drivers/net/ethernet/intel/igc/Makefile
> index 4563b83cd4e0..6a757ac8492d 100644
> --- a/drivers/net/ethernet/intel/igc/Makefile
> +++ b/drivers/net/ethernet/intel/igc/Makefile
> @@ -7,4 +7,5 @@
>
> obj-$(CONFIG_IGC) += igc.o
>
> -igc-objs := igc_main.o e1000_mac.o
> +igc-objs := igc_main.o e1000_mac.o \
> +e1000_base.o
> diff --git a/drivers/net/ethernet/intel/igc/e1000_base.c b/drivers/net/ethernet/intel/igc/e1000_base.c
> new file mode 100644
> index 000000000000..265ec98000e7
> --- /dev/null
> +++ b/drivers/net/ethernet/intel/igc/e1000_base.c
> @@ -0,0 +1,83 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (c) 2018 Intel Corporation */
> +
> +#include <linux/delay.h>
> +
> +#include "e1000_hw.h"
> +#include "e1000_i225.h"
> +
> +/**
> + * igc_rx_fifo_flush_base - Clean rx fifo after Rx enable
> + * @hw: pointer to the HW structure
> + *
> + * After Rx enable, if manageability is enabled then there is likely some
> + * bad data at the start of the fifo and possibly in the DMA fifo. This
> + * function clears the fifos and flushes any packets that came in as rx was
> + * being enabled.
> + **/
> +void igc_rx_fifo_flush_base(struct e1000_hw *hw)
> +{
> + u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
> + int i, ms_wait;
> +
> + /* disable IPv6 options as per hardware errata */
> + rfctl = rd32(E1000_RFCTL);
> + rfctl |= E1000_RFCTL_IPV6_EX_DIS;
> + wr32(E1000_RFCTL, rfctl);
Interesting... does this new hardware really have the same errata as the
82575?
> +
> + if (!(rd32(E1000_MANC) & E1000_MANC_RCV_TCO_EN))
> + return;
> +
> + /* Disable all Rx queues */
> + for (i = 0; i < 4; i++) {
> + rxdctl[i] = rd32(E1000_RXDCTL(i));
> + wr32(E1000_RXDCTL(i),
> + rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
> + }
> + /* Poll all queues to verify they have shut down */
> + for (ms_wait = 0; ms_wait < 10; ms_wait++) {
> + usleep_range(1000, 2000);
> + rx_enabled = 0;
> + for (i = 0; i < 4; i++)
> + rx_enabled |= rd32(E1000_RXDCTL(i));
> + if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
> + break;
> + }
> +
> + if (ms_wait == 10)
> + pr_debug("Queue disable timed out after 10ms\n");
> +
> + /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
> + * incoming packets are rejected. Set enable and wait 2ms so that
> + * any packet that was coming in as RCTL.EN was set is flushed
> + */
> + wr32(E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
> +
> + rlpml = rd32(E1000_RLPML);
> + wr32(E1000_RLPML, 0);
> +
> + rctl = rd32(E1000_RCTL);
> + temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
> + temp_rctl |= E1000_RCTL_LPE;
> +
> + wr32(E1000_RCTL, temp_rctl);
> + wr32(E1000_RCTL, temp_rctl | E1000_RCTL_EN);
> + wrfl();
> + usleep_range(2000, 3000);
> +
> + /* Enable Rx queues that were previously enabled and restore our
> + * previous state
> + */
> + for (i = 0; i < 4; i++)
> + wr32(E1000_RXDCTL(i), rxdctl[i]);
> + wr32(E1000_RCTL, rctl);
> + wrfl();
> +
> + wr32(E1000_RLPML, rlpml);
> + wr32(E1000_RFCTL, rfctl);
> +
> + /* Flush receive errors generated by workaround */
> + rd32(E1000_ROC);
> + rd32(E1000_RNBC);
> + rd32(E1000_MPC);
> +}
> diff --git a/drivers/net/ethernet/intel/igc/e1000_base.h b/drivers/net/ethernet/intel/igc/e1000_base.h
> new file mode 100644
> index 000000000000..9acc41d73f4f
> --- /dev/null
> +++ b/drivers/net/ethernet/intel/igc/e1000_base.h
> @@ -0,0 +1,89 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright (c) 2018 Intel Corporation */
> +
> +#ifndef _E1000_BASE_H
> +#define _E1000_BASE_H
> +
> +/* forward declaration */
> +void igc_rx_fifo_flush_base(struct e1000_hw *hw);
> +
> +/* Transmit Descriptor - Advanced */
> +union e1000_adv_tx_desc {
> + struct {
> + __le64 buffer_addr; /* Address of descriptor's data buf */
> + __le32 cmd_type_len;
> + __le32 olinfo_status;
Intent problem?
> + } read;
> + struct {
> + __le64 rsvd; /* Reserved */
> + __le32 nxtseq_seed;
> + __le32 status;
> + } wb;
> +};
> +
> +struct e1000_adv_data_desc {
> + __le64 buffer_addr; /* Address of the descriptor's data buffer */
> + union {
> + u32 data;
> + struct {
> + u32 datalen:16; /* Data buffer length */
> + u32 rsvd:4;
> + u32 dtyp:4; /* Descriptor type */
> + u32 dcmd:8; /* Descriptor command */
> + } config;
Will this bit layout work correctly on big-endian CPU?
> + } lower;
> + union {
> + u32 data;
> + struct {
> + u32 status:4; /* Descriptor status */
> + u32 idx:4;
> + u32 popts:6; /* Packet Options */
> + u32 paylen:18; /* Payload length */
Will this bit layout work correctly on big-endian CPU?
> + } options;
> + } upper;
> +};
> +
> +/* Receive Descriptor - Advanced */
> +union e1000_adv_rx_desc {
> + struct {
> + __le64 pkt_addr; /* Packet buffer address */
> + __le64 hdr_addr; /* Header buffer address */
> + } read;
> + struct {
> + struct {
> + union {
> + __le32 data;
> + struct {
> + __le16 pkt_info; /*RSS type, Pkt type*/
> + /* Split Header, header buffer len */
> + __le16 hdr_info;
> + } hs_rss;
> + } lo_dword;
> + union {
> + __le32 rss; /* RSS Hash */
> + struct {
> + __le16 ip_id; /* IP id */
> + __le16 csum; /* Packet Checksum */
> + } csum_ip;
> + } hi_dword;
> + } lower;
> + struct {
> + __le32 status_error; /* ext status/error */
> + __le16 length; /* Packet length */
> + __le16 vlan; /* VLAN tag */
> + } upper;
> + } wb; /* writeback */
> +};
> +
> +/* Additional Transmit Descriptor Control definitions */
> +#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Tx Queue */
> +
> +/* Additional Receive Descriptor Control definitions */
> +#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Rx Queue */
> +
> +/* SRRCTL bit definitions */
> +#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
> +#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
> +#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
> +
> +#endif /* _E1000_BASE_H */
> diff --git a/drivers/net/ethernet/intel/igc/e1000_defines.h b/drivers/net/ethernet/intel/igc/e1000_defines.h
> index 1f8bc16c7029..66f8fc96dfb8 100644
> --- a/drivers/net/ethernet/intel/igc/e1000_defines.h
> +++ b/drivers/net/ethernet/intel/igc/e1000_defines.h
> @@ -71,6 +71,10 @@
> #define E1000_ICR_RXO 0x00000040 /* Rx overrun */
> #define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */
> #define E1000_ICR_DRSTA 0x40000000 /* Device Reset Asserted */
> +
> +/* If this bit asserted, the driver should claim the interrupt */
> +#define E1000_ICR_INT_ASSERTED 0x80000000
> +
> #define E1000_ICS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */
>
> #define IMS_ENABLE_MASK ( \
> @@ -97,4 +101,53 @@
> #define E1000_GPIE_EIAME 0x40000000
> #define E1000_GPIE_PBA 0x80000000
>
> +/* Transmit Control */
> +#define E1000_TCTL_EN 0x00000002 /* enable Tx */
> +#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
> +#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
> +#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
> +#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
> +#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */
> +
> +#define E1000_CT_SHIFT 4
> +#define E1000_COLLISION_THRESHOLD 15
> +
> +/* Management Control */
> +#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
> +
> +/* Receive Control */
> +#define E1000_RCTL_RST 0x00000001 /* Software reset */
> +#define E1000_RCTL_EN 0x00000002 /* enable */
> +#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
> +#define E1000_RCTL_UPE 0x00000008 /* unicast promisc enable */
> +#define E1000_RCTL_MPE 0x00000010 /* multicast promisc enable */
> +#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
> +#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
> +#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
> +#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
> +#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
> +
> +#define E1000_RCTL_RDMTS_HALF 0x00000000 /* Rx desc min thresh size */
> +#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
> +
> +/* Header split receive */
> +#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
> +#define E1000_RFCTL_LEF 0x00040000
> +
> +/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
> +#define E1000_RCTL_SZ_2048 0x00000000 /* Rx buffer size 2048 */
> +#define E1000_RCTL_SZ_1024 0x00010000 /* Rx buffer size 1024 */
> +#define E1000_RCTL_SZ_512 0x00020000 /* Rx buffer size 512 */
> +#define E1000_RCTL_SZ_256 0x00030000 /* Rx buffer size 256 */
> +/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
> +#define E1000_RCTL_SZ_16384 0x00010000 /* Rx buffer size 16384 */
> +#define E1000_RCTL_SZ_8192 0x00020000 /* Rx buffer size 8192 */
> +#define E1000_RCTL_SZ_4096 0x00030000 /* Rx buffer size 4096 */
> +
> +#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
> +#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
> +#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */
> +#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
> +#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
> +
> #endif /* _E1000_DEFINES_H_ */
> diff --git a/drivers/net/ethernet/intel/igc/e1000_hw.h b/drivers/net/ethernet/intel/igc/e1000_hw.h
> index 650c4ac981d9..67fa4f696b98 100644
> --- a/drivers/net/ethernet/intel/igc/e1000_hw.h
> +++ b/drivers/net/ethernet/intel/igc/e1000_hw.h
> @@ -10,6 +10,7 @@
> #include "e1000_defines.h"
> #include "e1000_mac.h"
> #include "e1000_i225.h"
> +#include "e1000_base.h"
>
> #define E1000_DEV_ID_I225_LM 0x15F2
> #define E1000_DEV_ID_I225_V 0x15F3
> diff --git a/drivers/net/ethernet/intel/igc/e1000_regs.h b/drivers/net/ethernet/intel/igc/e1000_regs.h
> index 5634a01afff3..dcc4d89c9933 100644
> --- a/drivers/net/ethernet/intel/igc/e1000_regs.h
> +++ b/drivers/net/ethernet/intel/igc/e1000_regs.h
> @@ -229,6 +229,9 @@
> #define E1000_TLPIC 0x4148 /* EEE Tx LPI Count - TLPIC */
> #define E1000_RLPIC 0x414C /* EEE Rx LPI Count - RLPIC */
>
> +/* Management registers */
> +#define E1000_MANC 0x05820 /* Management Control - RW */
> +
> /* forward declaration */
> struct e1000_hw;
> u32 igc_rd32(struct e1000_hw *hw, u32 reg);
> diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
> index 7cab3e9c8e91..abf2e302c417 100644
> --- a/drivers/net/ethernet/intel/igc/igc.h
> +++ b/drivers/net/ethernet/intel/igc/igc.h
> @@ -46,6 +46,47 @@ extern char igc_driver_version[];
> #define MAX_Q_VECTORS 10
> #define MAX_STD_JUMBO_FRAME_SIZE 9216
>
> +#define IGC_TX_PTHRESH 8
> +#define IGC_TX_HTHRESH 1
> +
> +/* Supported Rx Buffer Sizes */
> +#define IGC_RXBUFFER_256 256
> +#define IGC_RXBUFFER_2048 2048
> +#define IGC_RXBUFFER_3072 3072
> +
> +#define IGC_RX_HDR_LEN IGC_RXBUFFER_256
> +
> +/* RX and TX descriptor control thresholds.
> + * PTHRESH - MAC will consider prefetch if it has fewer than this number of
> + * descriptors available in its onboard memory.
> + * Setting this to 0 disables RX descriptor prefetch.
> + * HTHRESH - MAC will only prefetch if there are at least this many descriptors
> + * available in host memory.
> + * If PTHRESH is 0, this should also be 0.
> + * WTHRESH - RX descriptor writeback threshold - MAC will delay writing back
> + * descriptors until either it has this many to write back, or the
> + * ITR timer expires.
> + */
> +#define IGC_RX_PTHRESH 8
> +#define IGC_RX_HTHRESH 8
> +#define IGC_TX_PTHRESH 8
> +#define IGC_TX_HTHRESH 1
> +#define IGC_RX_WTHRESH 4
> +
> +#define IGC_RX_DMA_ATTR \
> + (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)
> +
> +#define IGC_TS_HDR_LEN 16
> +
> +#define IGC_SKB_PAD (NET_SKB_PAD + NET_IP_ALIGN)
> +
> +#if (PAGE_SIZE < 8192)
> +#define IGC_MAX_FRAME_BUILD_SKB \
> + (SKB_WITH_OVERHEAD(IGC_RXBUFFER_2048) - IGC_SKB_PAD - IGC_TS_HDR_LEN)
> +#else
> +#define IGC_MAX_FRAME_BUILD_SKB (IGC_RXBUFFER_2048 - IGC_TS_HDR_LEN)
> +#endif
> +
> enum e1000_state_t {
> __IGC_TESTING,
> __IGC_RESETTING,
> @@ -53,6 +94,33 @@ enum e1000_state_t {
> __IGC_PTP_TX_IN_PROGRESS,
> };
>
> +/** wrapper around a pointer to a socket buffer,
> + * so a DMA handle can be stored along with the buffer
> + **/
This comment shouldn't have /** or **/, just /* and */
> +struct igc_tx_buffer {
> + union e1000_adv_tx_desc *next_to_watch;
> + unsigned long time_stamp;
> + struct sk_buff *skb;
> + unsigned int bytecount;
> + u16 gso_segs;
> + __be16 protocol;
> +
> + DEFINE_DMA_UNMAP_ADDR(dma);
> + DEFINE_DMA_UNMAP_LEN(len);
> + u32 tx_flags;
> +};
> +
> +struct igc_rx_buffer {
> + dma_addr_t dma;
> + struct page *page;
> +#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
> + __u32 page_offset;
> +#else
> + __u16 page_offset;
> +#endif
> + __u16 pagecnt_bias;
> +};
> +
> struct igc_tx_queue_stats {
> u64 packets;
> u64 bytes;
> @@ -218,4 +286,63 @@ struct igc_adapter {
> struct igc_mac_addr *mac_table;
> };
>
> +/* igc_desc_unused - calculate if we have unused descriptors */
> +static inline u16 igc_desc_unused(const struct igc_ring *ring)
> +{
> + u16 ntc = ring->next_to_clean;
> + u16 ntu = ring->next_to_use;
> +
> + return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;
> +}
> +
> +static inline struct netdev_queue *txring_txq(const struct igc_ring *tx_ring)
> +{
> + return netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index);
> +}
> +
> +enum e1000_ring_flags_t {
> + IGC_RING_FLAG_RX_3K_BUFFER,
> + IGC_RING_FLAG_RX_BUILD_SKB_ENABLED,
> + IGC_RING_FLAG_RX_SCTP_CSUM,
> + IGC_RING_FLAG_RX_LB_VLAN_BSWAP,
> + IGC_RING_FLAG_TX_CTX_IDX,
> + IGC_RING_FLAG_TX_DETECT_HANG
> +};
> +
> +#define ring_uses_large_buffer(ring) \
> + test_bit(IGC_RING_FLAG_RX_3K_BUFFER, &(ring)->flags)
> +
> +#define ring_uses_build_skb(ring) \
> + test_bit(IGC_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)
> +
> +static inline unsigned int igc_rx_bufsz(struct igc_ring *ring)
> +{
> +#if (PAGE_SIZE < 8192)
> + if (ring_uses_large_buffer(ring))
> + return IGC_RXBUFFER_3072;
> +
> + if (ring_uses_build_skb(ring))
> + return IGC_MAX_FRAME_BUILD_SKB + IGC_TS_HDR_LEN;
> +#endif
> + return IGC_RXBUFFER_2048;
> +}
> +
> +static inline unsigned int igc_rx_pg_order(struct igc_ring *ring)
> +{
> +#if (PAGE_SIZE < 8192)
> + if (ring_uses_large_buffer(ring))
> + return 1;
> +#endif
> + return 0;
> +}
> +
> +#define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring))
> +
> +#define IGC_RX_DESC(R, i) \
> + (&(((union e1000_adv_rx_desc *)((R)->desc))[i]))
> +#define IGC_TX_DESC(R, i) \
> + (&(((union e1000_adv_tx_desc *)((R)->desc))[i]))
> +#define IGC_TX_CTXTDESC(R, i) \
> + (&(((struct e1000_adv_tx_context_desc *)((R)->desc))[i]))
> +
> #endif /* _IGC_H_ */
> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
> index 30b778c9b94b..a147a1b7585e 100644
> --- a/drivers/net/ethernet/intel/igc/igc_main.c
> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> @@ -29,11 +29,21 @@ static const struct pci_device_id igc_pci_tbl[] = {
> MODULE_DEVICE_TABLE(pci, igc_pci_tbl);
>
> /* forward declaration */
> +static int igc_setup_all_tx_resources(struct igc_adapter *adapter);
> +static void igc_clean_tx_ring(struct igc_ring *tx_ring);
> +static void igc_free_all_tx_resources(struct igc_adapter *adapter);
> +static int igc_setup_all_rx_resources(struct igc_adapter *adapter);
> static int igc_sw_init(struct igc_adapter *);
> static void igc_configure(struct igc_adapter *adapter);
> +static void igc_configure_tx(struct igc_adapter *);
> +static void igc_configure_rx(struct igc_adapter *adapter);
> static void igc_power_down_link(struct igc_adapter *adapter);
> static void igc_set_default_mac_filter(struct igc_adapter *adapter);
> +static void igc_set_rx_mode(struct net_device *netdev);
> +static void igc_setup_mrqc(struct igc_adapter *adapter);
> static irqreturn_t igc_msix_ring(int irq, void *data);
> +static irqreturn_t igc_intr_msi(int irq, void *data);
> +static irqreturn_t igc_intr(int irq, void *data);
> static void igc_write_itr(struct igc_q_vector *q_vector);
> static int igc_request_msix(struct igc_adapter *adapter);
> static void igc_assign_vector(struct igc_q_vector *q_vector, int msix_vector);
> @@ -125,6 +135,526 @@ static void igc_get_hw_control(struct igc_adapter *adapter)
> }
>
> /**
> + * igc_free_tx_resources - Free Tx Resources per Queue
> + * @tx_ring: Tx descriptor ring for a specific queue
> + *
> + * Free all transmit software resources
> + **/
> +void igc_free_tx_resources(struct igc_ring *tx_ring)
> +{
> + igc_clean_tx_ring(tx_ring);
> +
> + vfree(tx_ring->tx_buffer_info);
> + tx_ring->tx_buffer_info = NULL;
> +
> + /* if not set, then don't free */
> + if (!tx_ring->desc)
> + return;
> +
> + dma_free_coherent(tx_ring->dev, tx_ring->size,
> + tx_ring->desc, tx_ring->dma);
> +
> + tx_ring->desc = NULL;
> +}
> +
> +/**
> + * igc_free_all_tx_resources - Free Tx Resources for All Queues
> + * @adapter: board private structure
> + *
> + * Free all transmit software resources
> + **/
> +static void igc_free_all_tx_resources(struct igc_adapter *adapter)
> +{
> + int i;
> +
> + for (i = 0; i < adapter->num_tx_queues; i++)
> + igc_free_tx_resources(adapter->tx_ring[i]);
> +}
> +
> +void igc_unmap_and_free_tx_resource(struct igc_ring *ring,
> + struct igc_tx_buffer *tx_buffer)
> +{
> + if (tx_buffer->skb) {
> + dev_kfree_skb_any(tx_buffer->skb);
> + if (dma_unmap_len(tx_buffer, len))
> + dma_unmap_single(ring->dev,
> + dma_unmap_addr(tx_buffer, dma),
> + dma_unmap_len(tx_buffer, len),
> + DMA_TO_DEVICE);
> + } else if (dma_unmap_len(tx_buffer, len)) {
> + dma_unmap_page(ring->dev,
> + dma_unmap_addr(tx_buffer, dma),
> + dma_unmap_len(tx_buffer, len),
> + DMA_TO_DEVICE);
> + }
> + tx_buffer->next_to_watch = NULL;
> + tx_buffer->skb = NULL;
> + dma_unmap_len_set(tx_buffer, len, 0);
> + /* buffer_info must be completely set up in the transmit path */
> +}
> +
> +/**
> + * igc_clean_tx_ring - Free Tx Buffers
> + * @tx_ring: ring to be cleaned
> + **/
> +static void igc_clean_tx_ring(struct igc_ring *tx_ring)
> +{
> + struct igc_tx_buffer *buffer_info;
> + unsigned long size;
> + u16 i;
> +
> + if (!tx_ring->tx_buffer_info)
> + return;
> +
> + /* Free all the Tx ring sk_buffs */
> + for (i = 0; i < tx_ring->count; i++) {
> + buffer_info = &tx_ring->tx_buffer_info[i];
> + igc_unmap_and_free_tx_resource(tx_ring, buffer_info);
> + }
> +
> + netdev_tx_reset_queue(txring_txq(tx_ring));
> +
> + size = sizeof(struct igc_tx_buffer) * tx_ring->count;
> + memset(tx_ring->tx_buffer_info, 0, size);
> +
> + /* Zero out the descriptor ring */
> + memset(tx_ring->desc, 0, tx_ring->size);
> +
> + tx_ring->next_to_use = 0;
> + tx_ring->next_to_clean = 0;
> +}
> +
> +/**
> + * igc_setup_tx_resources - allocate Tx resources (Descriptors)
> + * @tx_ring: tx descriptor ring (for a specific queue) to setup
> + *
> + * Return 0 on success, negative on failure
> + **/
> +int igc_setup_tx_resources(struct igc_ring *tx_ring)
> +{
> + struct device *dev = tx_ring->dev;
> + int size = 0;
> +
> + size = sizeof(struct igc_tx_buffer) * tx_ring->count;
> + tx_ring->tx_buffer_info = vzalloc(size);
> + if (!tx_ring->tx_buffer_info)
> + goto err;
> +
> + /* round up to nearest 4K */
> + tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
> + tx_ring->size = ALIGN(tx_ring->size, 4096);
> +
> + tx_ring->desc = dma_alloc_coherent(dev, tx_ring->size,
> + &tx_ring->dma, GFP_KERNEL);
> +
> + if (!tx_ring->desc)
> + goto err;
> +
> + tx_ring->next_to_use = 0;
> + tx_ring->next_to_clean = 0;
> +
> + return 0;
> +
> +err:
> + vfree(tx_ring->tx_buffer_info);
> + dev_err(dev,
> + "Unable to allocate memory for the transmit descriptor ring\n");
> + return -ENOMEM;
> +}
> +
> +/**
> + * igc_setup_all_tx_resources - wrapper to allocate Tx resources
> + * (Descriptors) for all queues
This should be a single line
> + * @adapter: board private structure
> + *
> + * Return 0 on success, negative on failure
> + **/
> +static int igc_setup_all_tx_resources(struct igc_adapter *adapter)
> +{
> + struct pci_dev *pdev = adapter->pdev;
> + int i, err = 0;
> +
> + for (i = 0; i < adapter->num_tx_queues; i++) {
> + err = igc_setup_tx_resources(adapter->tx_ring[i]);
> + if (err) {
> + dev_err(&pdev->dev,
> + "Allocation for Tx Queue %u failed\n", i);
> + for (i--; i >= 0; i--)
> + igc_free_tx_resources(adapter->tx_ring[i]);
> + break;
> + }
> + }
> +
> + return err;
> +}
> +
> +/**
> + * igc_clean_rx_ring - Free Rx Buffers per Queue
> + * @rx_ring: ring to free buffers from
> + **/
> +void igc_clean_rx_ring(struct igc_ring *rx_ring)
> +{
> + u16 i = rx_ring->next_to_clean;
> +
> + if (rx_ring->skb)
> + dev_kfree_skb(rx_ring->skb);
> + rx_ring->skb = NULL;
> +
> + /* Free all the Rx ring sk_buffs */
> + while (i != rx_ring->next_to_alloc) {
> + struct igc_rx_buffer *buffer_info = &rx_ring->rx_buffer_info[i];
> +
> + /* Invalidate cache lines that may have been written to by
> + * device so that we avoid corrupting memory.
> + */
> + dma_sync_single_range_for_cpu(rx_ring->dev,
> + buffer_info->dma,
> + buffer_info->page_offset,
> + igc_rx_bufsz(rx_ring),
> + DMA_FROM_DEVICE);
> +
> + /* free resources associated with mapping */
> + dma_unmap_page_attrs(rx_ring->dev,
> + buffer_info->dma,
> + igc_rx_pg_size(rx_ring),
> + DMA_FROM_DEVICE,
> + IGC_RX_DMA_ATTR);
> + __page_frag_cache_drain(buffer_info->page,
> + buffer_info->pagecnt_bias);
> +
> + i++;
> + if (i == rx_ring->count)
> + i = 0;
> + }
> +
> + rx_ring->next_to_alloc = 0;
> + rx_ring->next_to_clean = 0;
> + rx_ring->next_to_use = 0;
> +}
> +
> +/**
> + * igc_free_rx_resources - Free Rx Resources
> + * @rx_ring: ring to clean the resources from
> + *
> + * Free all receive software resources
> + **/
> +void igc_free_rx_resources(struct igc_ring *rx_ring)
> +{
> + igc_clean_rx_ring(rx_ring);
> +
> + vfree(rx_ring->rx_buffer_info);
> + rx_ring->rx_buffer_info = NULL;
> +
> + /* if not set, then don't free */
> + if (!rx_ring->desc)
> + return;
> +
> + dma_free_coherent(rx_ring->dev, rx_ring->size,
> + rx_ring->desc, rx_ring->dma);
> +
> + rx_ring->desc = NULL;
> +}
> +
> +/**
> + * igc_free_all_rx_resources - Free Rx Resources for All Queues
> + * @adapter: board private structure
> + *
> + * Free all receive software resources
> + **/
> +static void igc_free_all_rx_resources(struct igc_adapter *adapter)
> +{
> + int i;
> +
> + for (i = 0; i < adapter->num_rx_queues; i++)
> + igc_free_rx_resources(adapter->rx_ring[i]);
> +}
> +
> +/**
> + * igc_setup_rx_resources - allocate Rx resources (Descriptors)
> + * @rx_ring: rx descriptor ring (for a specific queue) to setup
> + *
> + * Returns 0 on success, negative on failure
> + **/
> +int igc_setup_rx_resources(struct igc_ring *rx_ring)
> +{
> + struct device *dev = rx_ring->dev;
> + int size, desc_len;
> +
> + size = sizeof(struct igc_rx_buffer) * rx_ring->count;
> + rx_ring->rx_buffer_info = vzalloc(size);
> + if (!rx_ring->rx_buffer_info)
> + goto err;
> +
> + desc_len = sizeof(union e1000_adv_rx_desc);
> +
> + /* Round up to nearest 4K */
> + rx_ring->size = rx_ring->count * desc_len;
> + rx_ring->size = ALIGN(rx_ring->size, 4096);
> +
> + rx_ring->desc = dma_alloc_coherent(dev, rx_ring->size,
> + &rx_ring->dma, GFP_KERNEL);
> +
> + if (!rx_ring->desc)
> + goto err;
> +
> + rx_ring->next_to_alloc = 0;
> + rx_ring->next_to_clean = 0;
> + rx_ring->next_to_use = 0;
> +
> + return 0;
> +
> +err:
> + vfree(rx_ring->rx_buffer_info);
> + rx_ring->rx_buffer_info = NULL;
> + dev_err(dev,
> + "Unable to allocate memory for the receive descriptor ring\n");
> + return -ENOMEM;
> +}
> +
> +/**
> + * igc_setup_all_rx_resources - wrapper to allocate Rx resources
> + * (Descriptors) for all queues
> + * @adapter: board private structure
> + *
> + * Return 0 on success, negative on failure
> + **/
> +static int igc_setup_all_rx_resources(struct igc_adapter *adapter)
> +{
> + struct pci_dev *pdev = adapter->pdev;
> + int i, err = 0;
> +
> + for (i = 0; i < adapter->num_rx_queues; i++) {
> + err = igc_setup_rx_resources(adapter->rx_ring[i]);
> + if (err) {
> + dev_err(&pdev->dev,
> + "Allocation for Rx Queue %u failed\n", i);
> + for (i--; i >= 0; i--)
> + igc_free_rx_resources(adapter->rx_ring[i]);
> + break;
> + }
> + }
> +
> + return err;
> +}
> +
> +static u32 igc_tx_wthresh(struct igc_adapter *adapter)
> +{
> + return 16;
Is there a #define for this? Why is this a function?
> +}
> +
> +/**
> + * igc_configure_rx_ring - Configure a receive ring after Reset
> + * @adapter: board private structure
> + * @ring: receive ring to be configured
> + *
> + * Configure the Rx unit of the MAC after a reset.
> + **/
> +void igc_configure_rx_ring(struct igc_adapter *adapter,
> + struct igc_ring *ring)
> +{
> + struct e1000_hw *hw = &adapter->hw;
> + union e1000_adv_rx_desc *rx_desc;
> + u64 rdba = ring->dma;
> + int reg_idx = ring->reg_idx;
> + u32 srrctl = 0, rxdctl = 0;
reverse xmas tree
> +
> + /* disable the queue */
> + wr32(E1000_RXDCTL(reg_idx), 0);
> +
> + /* Set DMA base address registers */
> + wr32(E1000_RDBAL(reg_idx),
> + rdba & 0x00000000ffffffffULL);
> + wr32(E1000_RDBAH(reg_idx), rdba >> 32);
> + wr32(E1000_RDLEN(reg_idx),
> + ring->count * sizeof(union e1000_adv_rx_desc));
> +
> + /* initialize head and tail */
> + ring->tail = adapter->io_addr + E1000_RDT(reg_idx);
> + wr32(E1000_RDH(reg_idx), 0);
> + writel(0, ring->tail);
> +
> + /* reset next-to- use/clean to place SW in sync with hardwdare */
s/hardwdare/hardware/
> + ring->next_to_clean = 0;
> + ring->next_to_use = 0;
> +
> + /* set descriptor configuration */
> + srrctl = IGC_RX_HDR_LEN << E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
> + if (ring_uses_large_buffer(ring))
> + srrctl |= IGC_RXBUFFER_3072 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
> + else
> + srrctl |= IGC_RXBUFFER_2048 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
> + srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
> +
> + wr32(E1000_SRRCTL(reg_idx), srrctl);
> +
> + rxdctl |= IGC_RX_PTHRESH;
> + rxdctl |= IGC_RX_HTHRESH << 8;
> + rxdctl |= IGC_RX_WTHRESH << 16;
> +
> + /* initialize rx_buffer_info */
> + memset(ring->rx_buffer_info, 0,
> + sizeof(struct igc_rx_buffer) * ring->count);
> +
> + /* initialize Rx descriptor 0 */
> + rx_desc = IGC_RX_DESC(ring, 0);
> + rx_desc->wb.upper.length = 0;
> +
> + /* enable receive descriptor fetching */
> + rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
> +
> + wr32(E1000_RXDCTL(reg_idx), rxdctl);
> +}
> +
> +/**
> + * igc_configure_rx - Configure receive Unit after Reset
> + * @adapter: board private structure
> + *
> + * Configure the Rx unit of the MAC after a reset.
> + **/
> +static void igc_configure_rx(struct igc_adapter *adapter)
> +{
> + int i;
> +
> + /* Setup the HW Rx Head and Tail Descriptor Pointers and
> + * the Base and Length of the Rx Descriptor Ring
> + */
> + for (i = 0; i < adapter->num_rx_queues; i++)
> + igc_configure_rx_ring(adapter, adapter->rx_ring[i]);
> +}
> +
> +/**
> + * igc_configure_tx_ring - Configure transmit ring after Reset
> + * @adapter: board private structure
> + * @ring: tx ring to configure
> + *
> + * Configure a transmit ring after a reset.
> + **/
> +void igc_configure_tx_ring(struct igc_adapter *adapter,
> + struct igc_ring *ring)
> +{
> + struct e1000_hw *hw = &adapter->hw;
> + u32 txdctl = 0;
> + u64 tdba = ring->dma;
> + int reg_idx = ring->reg_idx;
reverse xmas tree
> +
> + /* disable the queue */
> + wr32(E1000_TXDCTL(reg_idx), 0);
> + wrfl();
> + mdelay(10);
> +
> + wr32(E1000_TDLEN(reg_idx),
> + ring->count * sizeof(union e1000_adv_tx_desc));
> + wr32(E1000_TDBAL(reg_idx),
> + tdba & 0x00000000ffffffffULL);
> + wr32(E1000_TDBAH(reg_idx), tdba >> 32);
> +
> + ring->tail = adapter->io_addr + E1000_TDT(reg_idx);
> + wr32(E1000_TDH(reg_idx), 0);
> + writel(0, ring->tail);
> +
> + txdctl |= IGC_TX_PTHRESH;
> + txdctl |= IGC_TX_HTHRESH << 8;
> + txdctl |= igc_tx_wthresh(adapter) << 16;
> +
> + txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
> + wr32(E1000_TXDCTL(reg_idx), txdctl);
> +}
> +
> +/**
> + * igc_configure_tx - Configure transmit Unit after Reset
> + * @adapter: board private structure
> + *
> + * Configure the Tx unit of the MAC after a reset.
> + **/
> +static void igc_configure_tx(struct igc_adapter *adapter)
> +{
> + int i;
> +
> + for (i = 0; i < adapter->num_tx_queues; i++)
> + igc_configure_tx_ring(adapter, adapter->tx_ring[i]);
> +}
> +
> +/**
> + * igc_setup_mrqc - configure the multiple receive queue control registers
> + * @adapter: Board private structure
> + **/
> +static void igc_setup_mrqc(struct igc_adapter *adapter)
> +{
> +}
> +
> +/**
> + * igc_setup_rctl - configure the receive control registers
> + * @adapter: Board private structure
> + **/
> +void igc_setup_rctl(struct igc_adapter *adapter)
> +{
> + struct e1000_hw *hw = &adapter->hw;
> + u32 rctl;
> +
> + rctl = rd32(E1000_RCTL);
> +
> + rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
> + rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
> +
> + rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_RDMTS_HALF |
> + (hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
> +
> + /* enable stripping of CRC. It's unlikely this will break BMC
> + * redirection as it did with e1000. Newer features require
> + * that the HW strips the CRC.
> + */
> + rctl |= E1000_RCTL_SECRC;
> +
> + /* disable store bad packets and clear size bits. */
> + rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_SZ_256);
> +
> + /* enable LPE to allow for reception of jumbo frames */
> + rctl |= E1000_RCTL_LPE;
> +
> + /* disable queue 0 to prevent tail write w/o re-config */
> + wr32(E1000_RXDCTL(0), 0);
> +
> + /* This is useful for sniffing bad packets. */
> + if (adapter->netdev->features & NETIF_F_RXALL) {
> + /* UPE and MPE will be handled by normal PROMISC logic
> + * in e1000e_set_rx_mode
> + */
> + rctl |= (E1000_RCTL_SBP | /* Receive bad packets */
> + E1000_RCTL_BAM | /* RX All Bcast Pkts */
> + E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
> +
> + rctl &= ~(E1000_RCTL_DPF | /* Allow filtered pause */
> + E1000_RCTL_CFIEN); /* Disable VLAN CFIEN Filter */
> + }
> +
> + wr32(E1000_RCTL, rctl);
> +}
> +
> +/**
> + * igc_setup_tctl - configure the transmit control registers
> + * @adapter: Board private structure
> + **/
> +void igc_setup_tctl(struct igc_adapter *adapter)
> +{
> + struct e1000_hw *hw = &adapter->hw;
> + u32 tctl;
> +
> + /* disable queue 0 which icould be enabled by default */
> + wr32(E1000_TXDCTL(0), 0);
> +
> + /* Program the Transmit Control Register */
> + tctl = rd32(E1000_TCTL);
> + tctl &= ~E1000_TCTL_CT;
> + tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
> + (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
> +
> + /* Enable transmits */
> + tctl |= E1000_TCTL_EN;
> +
> + wr32(E1000_TCTL, tctl);
> +}
> +
> +/**
> * igc_set_mac - Change the Ethernet Address of the NIC
> * @netdev: network interface device structure
> * @p: pointer to an address structure
> @@ -156,6 +686,121 @@ static netdev_tx_t igc_xmit_frame(struct sk_buff *skb,
> return NETDEV_TX_OK;
> }
>
> +static inline unsigned int igc_rx_offset(struct igc_ring *rx_ring)
> +{
> + return ring_uses_build_skb(rx_ring) ? IGC_SKB_PAD : 0;
> +}
> +
> +static bool igc_alloc_mapped_page(struct igc_ring *rx_ring,
> + struct igc_rx_buffer *bi)
> +{
> + struct page *page = bi->page;
> + dma_addr_t dma;
> +
> + /* since we are recycling buffers we should seldom need to alloc */
> + if (likely(page))
> + return true;
> +
> + /* alloc new page for storage */
> + page = dev_alloc_pages(igc_rx_pg_order(rx_ring));
> + if (unlikely(!page)) {
> + rx_ring->rx_stats.alloc_failed++;
> + return false;
> + }
> +
> + /* map page for use */
> + dma = dma_map_page_attrs(rx_ring->dev, page, 0,
> + igc_rx_pg_size(rx_ring),
> + DMA_FROM_DEVICE,
> + IGC_RX_DMA_ATTR);
> +
> + /* if mapping failed free memory back to system since
> + * there isn't much point in holding memory we can't use
> + */
> + if (dma_mapping_error(rx_ring->dev, dma)) {
> + __free_page(page);
> +
> + rx_ring->rx_stats.alloc_failed++;
> + return false;
> + }
> +
> + bi->dma = dma;
> + bi->page = page;
> + bi->page_offset = igc_rx_offset(rx_ring);
> + bi->pagecnt_bias = 1;
> +
> + return true;
> +}
> +
> +/**
> + * igc_alloc_rx_buffers - Replace used receive buffers; packet split
> + * @adapter: address of board private structure
> + **/
> +void igc_alloc_rx_buffers(struct igc_ring *rx_ring, u16 cleaned_count)
> +{
> + union e1000_adv_rx_desc *rx_desc;
> + struct igc_rx_buffer *bi;
> + u16 i = rx_ring->next_to_use;
> + u16 bufsz;
reverse xmas tree
> +
> + /* nothing to do */
> + if (!cleaned_count)
> + return;
> +
> + rx_desc = IGC_RX_DESC(rx_ring, i);
> + bi = &rx_ring->rx_buffer_info[i];
> + i -= rx_ring->count;
> +
> + bufsz = igc_rx_bufsz(rx_ring);
> +
> + do {
> + if (!igc_alloc_mapped_page(rx_ring, bi))
> + break;
> +
> + /* sync the buffer for use by the device */
> + dma_sync_single_range_for_device(rx_ring->dev, bi->dma,
> + bi->page_offset, bufsz,
> + DMA_FROM_DEVICE);
> +
> + /* Refresh the desc even if buffer_addrs didn't change
> + * because each write-back erases this info.
> + */
> + rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset);
> +
> + rx_desc++;
> + bi++;
> + i++;
> + if (unlikely(!i)) {
> + rx_desc = IGC_RX_DESC(rx_ring, 0);
> + bi = rx_ring->rx_buffer_info;
> + i -= rx_ring->count;
> + }
> +
> + /* clear the length for the next_to_use descriptor */
> + rx_desc->wb.upper.length = 0;
> +
> + cleaned_count--;
> + } while (cleaned_count);
> +
> + i += rx_ring->count;
> +
> + if (rx_ring->next_to_use != i) {
> + /* record the next descriptor to use */
> + rx_ring->next_to_use = i;
> +
> + /* update next to alloc since we have filled the ring */
> + rx_ring->next_to_alloc = i;
> +
> + /* Force memory writes to complete before letting h/w
> + * know there are new descriptors to fetch. (Only
> + * applicable for weak-ordered memory model archs,
> + * such as IA-64).
> + */
> + wmb();
> + writel(i, rx_ring->tail);
> + }
> +}
> +
> /**
> * igc_ioctl - I/O control method
> * @netdev: network interface device structure
> @@ -196,6 +841,12 @@ int igc_up(struct igc_adapter *adapter)
> rd32(E1000_ICR);
> igc_irq_enable(adapter);
>
> + netif_tx_start_all_queues(adapter->netdev);
> +
> + /* start the watchdog. */
> + hw->mac.get_link_status = 1;
> + schedule_work(&adapter->watchdog_task);
But you don't actually add the watchdog setup until patch 11?
> +
> return 0;
> }
>
> @@ -295,7 +946,30 @@ static struct net_device_stats *igc_get_stats(struct net_device *netdev)
> **/
> static void igc_configure(struct igc_adapter *adapter)
> {
> + struct net_device *netdev = adapter->netdev;
> + int i = 0;
> +
> igc_get_hw_control(adapter);
> + igc_set_rx_mode(netdev);
> +
> + igc_setup_tctl(adapter);
> + igc_setup_mrqc(adapter);
> + igc_setup_rctl(adapter);
> +
> + igc_configure_tx(adapter);
> + igc_configure_rx(adapter);
> +
> + igc_rx_fifo_flush_base(&adapter->hw);
> +
> + /* call igc_desc_unused which always leaves
> + * at least 1 descriptor unused to make sure
> + * next_to_use != next_to_clean
> + */
> + for (i = 0; i < adapter->num_rx_queues; i++) {
> + struct igc_ring *ring = adapter->rx_ring[i];
> +
> + igc_alloc_rx_buffers(ring, igc_desc_unused(ring));
> + }
> }
>
> /**
> @@ -343,6 +1017,19 @@ static void igc_set_default_mac_filter(struct igc_adapter *adapter)
> igc_rar_set_index(adapter, 0);
> }
>
> +/**
> + * igc_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
> + * @netdev: network interface device structure
> + *
> + * The set_rx_mode entry point is called whenever the unicast or multicast
> + * address lists or the network interface flags are updated. This routine is
> + * responsible for configuring the hardware for proper unicast, multicast,
> + * promiscuous mode, and all-multi behavior.
> + **/
> +static void igc_set_rx_mode(struct net_device *netdev)
> +{
> +}
> +
> static irqreturn_t igc_msix_other(int irq, void *data)
> {
> struct igc_adapter *adapter = data;
> @@ -781,6 +1468,83 @@ static void igc_update_itr(struct igc_q_vector *q_vector,
> ring_container->itr = itrval;
> }
>
> +/**
> + * igc_intr_msi - Interrupt Handler
> + * @irq: interrupt number
> + * @data: pointer to a network interface device structure
> + **/
> +static irqreturn_t igc_intr_msi(int irq, void *data)
> +{
> + struct igc_adapter *adapter = data;
> + struct igc_q_vector *q_vector = adapter->q_vector[0];
> + struct e1000_hw *hw = &adapter->hw;
> + /* read ICR disables interrupts using IAM */
> + u32 icr = rd32(E1000_ICR);
> +
> + igc_write_itr(q_vector);
> +
> + if (icr & E1000_ICR_DRSTA)
> + schedule_work(&adapter->reset_task);
This task probably should have been set up in a previous patch, too.
> +
> + if (icr & E1000_ICR_DOUTSYNC) {
> + /* HW is reporting DMA is out of sync */
> + adapter->stats.doosync++;
> + }
> +
> + if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
> + hw->mac.get_link_status = 1;
> + if (!test_bit(__IGC_DOWN, &adapter->state))
> + mod_timer(&adapter->watchdog_timer, jiffies + 1);
And this too.
> + }
> +
> + napi_schedule(&q_vector->napi);
Extra space indented?
> +
> + return IRQ_HANDLED;
> +}
> +
> +/**
> + * igc_intr - Legacy Interrupt Handler
> + * @irq: interrupt number
> + * @data: pointer to a network interface device structure
> + **/
> +static irqreturn_t igc_intr(int irq, void *data)
> +{
> + struct igc_adapter *adapter = data;
> + struct igc_q_vector *q_vector = adapter->q_vector[0];
> + struct e1000_hw *hw = &adapter->hw;
> + /* Interrupt Auto-Mask...upon reading ICR, interrupts are masked. No
> + * need for the IMC write
> + */
> + u32 icr = rd32(E1000_ICR);
> +
> + /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
> + * not set, then the adapter didn't send an interrupt
> + */
> + if (!(icr & E1000_ICR_INT_ASSERTED))
> + return IRQ_NONE;
> +
> + igc_write_itr(q_vector);
> +
> + if (icr & E1000_ICR_DRSTA)
> + schedule_work(&adapter->reset_task);
> +
> + if (icr & E1000_ICR_DOUTSYNC) {
> + /* HW is reporting DMA is out of sync */
> + adapter->stats.doosync++;
> + }
> +
> + if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
> + hw->mac.get_link_status = 1;
> + /* guard against interrupt when we're going down */
> + if (!test_bit(__IGC_DOWN, &adapter->state))
> + mod_timer(&adapter->watchdog_timer, jiffies + 1);
> + }
> +
> + napi_schedule(&q_vector->napi);
> +
> + return IRQ_HANDLED;
> +}
> +
> static void igc_ring_irq_enable(struct igc_q_vector *q_vector)
> {
> struct igc_adapter *adapter = q_vector->adapter;
> @@ -1148,6 +1912,29 @@ static int igc_alloc_q_vectors(struct igc_adapter *adapter)
> }
>
> /**
> + * igc_cache_ring_register - Descriptor ring to register mapping
> + * @adapter: board private structure to initialize
> + *
> + * Once we know the feature-set enabled for the device, we'll cache
> + * the register offset the descriptor ring is assigned to.
> + **/
> +static void igc_cache_ring_register(struct igc_adapter *adapter)
> +{
> + int i = 0, j = 0;
> +
> + switch (adapter->hw.mac.type) {
> + case e1000_i225:
> + /* Fall through */
> + default:
> + for (; i < adapter->num_rx_queues; i++)
> + adapter->rx_ring[i]->reg_idx = i;
> + for (; j < adapter->num_tx_queues; j++)
> + adapter->tx_ring[j]->reg_idx = j;
> + break;
> + }
> +}
> +
> +/**
> * igc_init_interrupt_scheme - initialize interrupts, allocate queues/vectors
> * @adapter: Pointer to adapter structure
> *
> @@ -1166,7 +1953,7 @@ static int igc_init_interrupt_scheme(struct igc_adapter *adapter, bool msix)
> goto err_alloc_q_vectors;
> }
>
> - /* TODO complete igc_cache_ring_register */
> + igc_cache_ring_register(adapter);
>
> return 0;
>
> @@ -1255,6 +2042,8 @@ static void igc_irq_enable(struct igc_adapter *adapter)
> **/
> static int igc_request_irq(struct igc_adapter *adapter)
> {
> + struct net_device *netdev = adapter->netdev;
> + struct pci_dev *pdev = adapter->pdev;
> int err = 0;
>
> if (adapter->flags & IGC_FLAG_HAS_MSIX) {
> @@ -1262,16 +2051,38 @@ static int igc_request_irq(struct igc_adapter *adapter)
> if (!err)
> goto request_done;
> /* fall back to MSI */
> - /* TODO complete free tx/rx resources */
> + igc_free_all_tx_resources(adapter);
> + igc_free_all_rx_resources(adapter);
>
> igc_clear_interrupt_scheme(adapter);
> err = igc_init_interrupt_scheme(adapter, false);
> if (err)
> goto request_done;
> - /* TODO complete setup tx/rx resources */
> + igc_setup_all_tx_resources(adapter);
> + igc_setup_all_rx_resources(adapter);
> igc_configure(adapter);
> }
>
> + igc_assign_vector(adapter->q_vector[0], 0);
> +
> + if (adapter->flags & IGC_FLAG_HAS_MSI) {
> + err = request_irq(pdev->irq, &igc_intr_msi, 0,
> + netdev->name, adapter);
> + if (!err)
> + goto request_done;
> +
> + /* fall back to legacy interrupts */
> + igc_reset_interrupt_capability(adapter);
> + adapter->flags &= ~IGC_FLAG_HAS_MSI;
> + }
> +
> + err = request_irq(pdev->irq, &igc_intr, IRQF_SHARED,
> + netdev->name, adapter);
> +
> + if (err)
> + dev_err(&pdev->dev, "Error %d getting interrupt\n",
> + err);
> +
> request_done:
> return err;
> }
> @@ -1332,6 +2143,16 @@ static int __igc_open(struct net_device *netdev, bool resuming)
>
> netif_carrier_off(netdev);
>
> + /* allocate transmit descriptors */
> + err = igc_setup_all_tx_resources(adapter);
> + if (err)
> + goto err_setup_tx;
> +
> + /* allocate receive descriptors */
> + err = igc_setup_all_rx_resources(adapter);
> + if (err)
> + goto err_setup_rx;
> +
> igc_power_up_link(adapter);
>
> igc_configure(adapter);
> @@ -1357,6 +2178,8 @@ static int __igc_open(struct net_device *netdev, bool resuming)
> rd32(E1000_ICR);
> igc_irq_enable(adapter);
>
> + netif_tx_start_all_queues(netdev);
> +
> /* start the watchdog. */
> hw->mac.get_link_status = 1;
> schedule_work(&adapter->watchdog_task);
> @@ -1368,7 +2191,11 @@ static int __igc_open(struct net_device *netdev, bool resuming)
> err_req_irq:
> igc_release_hw_control(adapter);
> igc_power_down_link(adapter);
> - /* TODO complete free_all_rx_resources */
> + igc_free_all_rx_resources(adapter);
> +err_setup_rx:
> + igc_free_all_tx_resources(adapter);
> +err_setup_tx:
> + igc_reset(adapter);
>
> return err;
> }
> @@ -1401,6 +2228,9 @@ static int __igc_close(struct net_device *netdev, bool suspending)
>
> igc_free_irq(adapter);
>
> + igc_free_all_tx_resources(adapter);
> + igc_free_all_rx_resources(adapter);
> +
> return 0;
> }
>
> @@ -1415,6 +2245,7 @@ static const struct net_device_ops igc_netdev_ops = {
> .ndo_open = igc_open,
> .ndo_stop = igc_close,
> .ndo_start_xmit = igc_xmit_frame,
> + .ndo_set_rx_mode = igc_set_rx_mode,
> .ndo_set_mac_address = igc_set_mac,
> .ndo_change_mtu = igc_change_mtu,
> .ndo_get_stats = igc_get_stats,
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Intel-wired-lan] [RFC PATCH] igc: igc_free_tx_resources() can be static
2018-06-24 14:11 ` [Intel-wired-lan] [RFC PATCH] igc: igc_free_tx_resources() can be static kbuild test robot
@ 2018-06-28 8:15 ` Neftin, Sasha
2018-06-28 21:21 ` Shannon Nelson
0 siblings, 1 reply; 8+ messages in thread
From: Neftin, Sasha @ 2018-06-28 8:15 UTC (permalink / raw)
To: intel-wired-lan
On 6/24/2018 17:11, kbuild test robot wrote:
>
> Fixes: 6ae8ddd68f6a ("igc: Add support for Tx/Rx rings")
> Signed-off-by: kbuild test robot <fengguang.wu@intel.com>
> ---
> igc_main.c | 28 ++++++++++++++--------------
> 1 file changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
> index a147a1b..78370abc 100644
> --- a/drivers/net/ethernet/intel/igc/igc_main.c
> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> @@ -140,7 +140,7 @@ static void igc_get_hw_control(struct igc_adapter *adapter)
> *
> * Free all transmit software resources
> **/
> -void igc_free_tx_resources(struct igc_ring *tx_ring)
> +static void igc_free_tx_resources(struct igc_ring *tx_ring)
> {
> igc_clean_tx_ring(tx_ring);
>
> @@ -171,8 +171,8 @@ static void igc_free_all_tx_resources(struct igc_adapter *adapter)
> igc_free_tx_resources(adapter->tx_ring[i]);
> }
>
> -void igc_unmap_and_free_tx_resource(struct igc_ring *ring,
> - struct igc_tx_buffer *tx_buffer)
> +static void igc_unmap_and_free_tx_resource(struct igc_ring *ring,
> + struct igc_tx_buffer *tx_buffer)
> {
> if (tx_buffer->skb) {
> dev_kfree_skb_any(tx_buffer->skb);
> @@ -230,7 +230,7 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring)
> *
> * Return 0 on success, negative on failure
> **/
> -int igc_setup_tx_resources(struct igc_ring *tx_ring)
> +static int igc_setup_tx_resources(struct igc_ring *tx_ring)
> {
> struct device *dev = tx_ring->dev;
> int size = 0;
> @@ -292,7 +292,7 @@ static int igc_setup_all_tx_resources(struct igc_adapter *adapter)
> * igc_clean_rx_ring - Free Rx Buffers per Queue
> * @rx_ring: ring to free buffers from
> **/
> -void igc_clean_rx_ring(struct igc_ring *rx_ring)
> +static void igc_clean_rx_ring(struct igc_ring *rx_ring)
> {
> u16 i = rx_ring->next_to_clean;
>
> @@ -338,7 +338,7 @@ void igc_clean_rx_ring(struct igc_ring *rx_ring)
> *
> * Free all receive software resources
> **/
> -void igc_free_rx_resources(struct igc_ring *rx_ring)
> +static void igc_free_rx_resources(struct igc_ring *rx_ring)
> {
> igc_clean_rx_ring(rx_ring);
>
> @@ -375,7 +375,7 @@ static void igc_free_all_rx_resources(struct igc_adapter *adapter)
> *
> * Returns 0 on success, negative on failure
> **/
> -int igc_setup_rx_resources(struct igc_ring *rx_ring)
> +static int igc_setup_rx_resources(struct igc_ring *rx_ring)
> {
> struct device *dev = rx_ring->dev;
> int size, desc_len;
> @@ -449,8 +449,8 @@ static u32 igc_tx_wthresh(struct igc_adapter *adapter)
> *
> * Configure the Rx unit of the MAC after a reset.
> **/
> -void igc_configure_rx_ring(struct igc_adapter *adapter,
> - struct igc_ring *ring)
> +static void igc_configure_rx_ring(struct igc_adapter *adapter,
> + struct igc_ring *ring)
> {
> struct e1000_hw *hw = &adapter->hw;
> union e1000_adv_rx_desc *rx_desc;
> @@ -529,8 +529,8 @@ static void igc_configure_rx(struct igc_adapter *adapter)
> *
> * Configure a transmit ring after a reset.
> **/
> -void igc_configure_tx_ring(struct igc_adapter *adapter,
> - struct igc_ring *ring)
> +static void igc_configure_tx_ring(struct igc_adapter *adapter,
> + struct igc_ring *ring)
> {
> struct e1000_hw *hw = &adapter->hw;
> u32 txdctl = 0;
> @@ -586,7 +586,7 @@ static void igc_setup_mrqc(struct igc_adapter *adapter)
> * igc_setup_rctl - configure the receive control registers
> * @adapter: Board private structure
> **/
> -void igc_setup_rctl(struct igc_adapter *adapter)
> +static void igc_setup_rctl(struct igc_adapter *adapter)
> {
> struct e1000_hw *hw = &adapter->hw;
> u32 rctl;
> @@ -634,7 +634,7 @@ void igc_setup_rctl(struct igc_adapter *adapter)
> * igc_setup_tctl - configure the transmit control registers
> * @adapter: Board private structure
> **/
> -void igc_setup_tctl(struct igc_adapter *adapter)
> +static void igc_setup_tctl(struct igc_adapter *adapter)
> {
> struct e1000_hw *hw = &adapter->hw;
> u32 tctl;
> @@ -736,7 +736,7 @@ static bool igc_alloc_mapped_page(struct igc_ring *rx_ring,
> * igc_alloc_rx_buffers - Replace used receive buffers; packet split
> * @adapter: address of board private structure
> **/
> -void igc_alloc_rx_buffers(struct igc_ring *rx_ring, u16 cleaned_count)
> +static void igc_alloc_rx_buffers(struct igc_ring *rx_ring, u16 cleaned_count)
> {
> union e1000_adv_rx_desc *rx_desc;
> struct igc_rx_buffer *bi;
>
good. will be applied to v4.
Thanks,
Sasha
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Intel-wired-lan] [RFC PATCH] igc: igc_free_tx_resources() can be static
2018-06-28 8:15 ` Neftin, Sasha
@ 2018-06-28 21:21 ` Shannon Nelson
2018-06-29 8:32 ` Neftin, Sasha
0 siblings, 1 reply; 8+ messages in thread
From: Shannon Nelson @ 2018-06-28 21:21 UTC (permalink / raw)
To: intel-wired-lan
On 6/28/2018 1:15 AM, Neftin, Sasha wrote:
> On 6/24/2018 17:11, kbuild test robot wrote:
>>
>> Fixes: 6ae8ddd68f6a ("igc: Add support for Tx/Rx rings")
>> Signed-off-by: kbuild test robot <fengguang.wu@intel.com>
>> ---
>> ? igc_main.c |?? 28 ++++++++++++++--------------
>> ? 1 file changed, 14 insertions(+), 14 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c
>> b/drivers/net/ethernet/intel/igc/igc_main.c
>> index a147a1b..78370abc 100644
>> --- a/drivers/net/ethernet/intel/igc/igc_main.c
>> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
>> @@ -140,7 +140,7 @@ static void igc_get_hw_control(struct igc_adapter
>> *adapter)
>> ?? *
>> ?? *? Free all transmit software resources
>> ?? **/
>> -void igc_free_tx_resources(struct igc_ring *tx_ring)
>> +static void igc_free_tx_resources(struct igc_ring *tx_ring)
>> ? {
>> ????? igc_clean_tx_ring(tx_ring);
>> @@ -171,8 +171,8 @@ static void igc_free_all_tx_resources(struct
>> igc_adapter *adapter)
>> ????????? igc_free_tx_resources(adapter->tx_ring[i]);
>> ? }
>> -void igc_unmap_and_free_tx_resource(struct igc_ring *ring,
>> -??????????????????? struct igc_tx_buffer *tx_buffer)
>> +static void igc_unmap_and_free_tx_resource(struct igc_ring *ring,
>> +?????????????????????? struct igc_tx_buffer *tx_buffer)
Check the indent here and on the other similar function headers
>> ? {
>> ????? if (tx_buffer->skb) {
>> ????????? dev_kfree_skb_any(tx_buffer->skb);
>> @@ -230,7 +230,7 @@ static void igc_clean_tx_ring(struct igc_ring
>> *tx_ring)
>> ?? *
>> ?? *? Return 0 on success, negative on failure
>> ?? **/
>> -int igc_setup_tx_resources(struct igc_ring *tx_ring)
>> +static int igc_setup_tx_resources(struct igc_ring *tx_ring)
>> ? {
>> ????? struct device *dev = tx_ring->dev;
>> ????? int size = 0;
>> @@ -292,7 +292,7 @@ static int igc_setup_all_tx_resources(struct
>> igc_adapter *adapter)
>> ?? *? igc_clean_rx_ring - Free Rx Buffers per Queue
>> ?? *? @rx_ring: ring to free buffers from
>> ?? **/
>> -void igc_clean_rx_ring(struct igc_ring *rx_ring)
>> +static void igc_clean_rx_ring(struct igc_ring *rx_ring)
>> ? {
>> ????? u16 i = rx_ring->next_to_clean;
>> @@ -338,7 +338,7 @@ void igc_clean_rx_ring(struct igc_ring *rx_ring)
>> ?? *
>> ?? *? Free all receive software resources
>> ?? **/
>> -void igc_free_rx_resources(struct igc_ring *rx_ring)
>> +static void igc_free_rx_resources(struct igc_ring *rx_ring)
>> ? {
>> ????? igc_clean_rx_ring(rx_ring);
>> @@ -375,7 +375,7 @@ static void igc_free_all_rx_resources(struct
>> igc_adapter *adapter)
>> ?? *
>> ?? *? Returns 0 on success, negative on failure
>> ?? **/
>> -int igc_setup_rx_resources(struct igc_ring *rx_ring)
>> +static int igc_setup_rx_resources(struct igc_ring *rx_ring)
>> ? {
>> ????? struct device *dev = rx_ring->dev;
>> ????? int size, desc_len;
>> @@ -449,8 +449,8 @@ static u32 igc_tx_wthresh(struct igc_adapter
>> *adapter)
>> ?? *
>> ?? *? Configure the Rx unit of the MAC after a reset.
>> ?? **/
>> -void igc_configure_rx_ring(struct igc_adapter *adapter,
>> -?????????????? struct igc_ring *ring)
>> +static void igc_configure_rx_ring(struct igc_adapter *adapter,
>> +????????????????? struct igc_ring *ring)
>> ? {
>> ????? struct e1000_hw *hw = &adapter->hw;
>> ????? union e1000_adv_rx_desc *rx_desc;
>> @@ -529,8 +529,8 @@ static void igc_configure_rx(struct igc_adapter
>> *adapter)
>> ?? *
>> ?? *? Configure a transmit ring after a reset.
>> ?? **/
>> -void igc_configure_tx_ring(struct igc_adapter *adapter,
>> -?????????????? struct igc_ring *ring)
>> +static void igc_configure_tx_ring(struct igc_adapter *adapter,
>> +????????????????? struct igc_ring *ring)
>> ? {
>> ????? struct e1000_hw *hw = &adapter->hw;
>> ????? u32 txdctl = 0;
>> @@ -586,7 +586,7 @@ static void igc_setup_mrqc(struct igc_adapter
>> *adapter)
>> ?? *? igc_setup_rctl - configure the receive control registers
>> ?? *? @adapter: Board private structure
>> ?? **/
>> -void igc_setup_rctl(struct igc_adapter *adapter)
>> +static void igc_setup_rctl(struct igc_adapter *adapter)
>> ? {
>> ????? struct e1000_hw *hw = &adapter->hw;
>> ????? u32 rctl;
>> @@ -634,7 +634,7 @@ void igc_setup_rctl(struct igc_adapter *adapter)
>> ?? *? igc_setup_tctl - configure the transmit control registers
>> ?? *? @adapter: Board private structure
>> ?? **/
>> -void igc_setup_tctl(struct igc_adapter *adapter)
>> +static void igc_setup_tctl(struct igc_adapter *adapter)
>> ? {
>> ????? struct e1000_hw *hw = &adapter->hw;
>> ????? u32 tctl;
>> @@ -736,7 +736,7 @@ static bool igc_alloc_mapped_page(struct igc_ring
>> *rx_ring,
>> ?? *? igc_alloc_rx_buffers - Replace used receive buffers; packet split
>> ?? *? @adapter: address of board private structure
>> ?? **/
>> -void igc_alloc_rx_buffers(struct igc_ring *rx_ring, u16 cleaned_count)
>> +static void igc_alloc_rx_buffers(struct igc_ring *rx_ring, u16
>> cleaned_count)
>> ? {
>> ????? union e1000_adv_rx_desc *rx_desc;
>> ????? struct igc_rx_buffer *bi;
>>
> good. will be applied to v4.
> Thanks,
> Sasha
> _______________________________________________
> Intel-wired-lan mailing list
> Intel-wired-lan at osuosl.org
> https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Intel-wired-lan] [RFC PATCH] igc: igc_free_tx_resources() can be static
2018-06-28 21:21 ` Shannon Nelson
@ 2018-06-29 8:32 ` Neftin, Sasha
0 siblings, 0 replies; 8+ messages in thread
From: Neftin, Sasha @ 2018-06-29 8:32 UTC (permalink / raw)
To: intel-wired-lan
On 29/06/2018 0:21, Shannon Nelson wrote:
> On 6/28/2018 1:15 AM, Neftin, Sasha wrote:
>> On 6/24/2018 17:11, kbuild test robot wrote:
>>>
>>> Fixes: 6ae8ddd68f6a ("igc: Add support for Tx/Rx rings")
>>> Signed-off-by: kbuild test robot <fengguang.wu@intel.com>
>>> ---
>>> ? igc_main.c |?? 28 ++++++++++++++--------------
>>> ? 1 file changed, 14 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c
>>> b/drivers/net/ethernet/intel/igc/igc_main.c
>>> index a147a1b..78370abc 100644
>>> --- a/drivers/net/ethernet/intel/igc/igc_main.c
>>> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
>>> @@ -140,7 +140,7 @@ static void igc_get_hw_control(struct igc_adapter
>>> *adapter)
>>> ?? *
>>> ?? *? Free all transmit software resources
>>> ?? **/
>>> -void igc_free_tx_resources(struct igc_ring *tx_ring)
>>> +static void igc_free_tx_resources(struct igc_ring *tx_ring)
>>> ? {
>>> ????? igc_clean_tx_ring(tx_ring);
>>> @@ -171,8 +171,8 @@ static void igc_free_all_tx_resources(struct
>>> igc_adapter *adapter)
>>> ????????? igc_free_tx_resources(adapter->tx_ring[i]);
>>> ? }
>>> -void igc_unmap_and_free_tx_resource(struct igc_ring *ring,
>>> -??????????????????? struct igc_tx_buffer *tx_buffer)
>>> +static void igc_unmap_and_free_tx_resource(struct igc_ring *ring,
>>> +?????????????????????? struct igc_tx_buffer *tx_buffer)
>
> Check the indent here and on the other similar function headers
>
>
Good point, already did it and processed by checkpatch.
>>> ? {
>>> ????? if (tx_buffer->skb) {
>>> ????????? dev_kfree_skb_any(tx_buffer->skb);
>>> @@ -230,7 +230,7 @@ static void igc_clean_tx_ring(struct igc_ring
>>> *tx_ring)
>>> ?? *
>>> ?? *? Return 0 on success, negative on failure
>>> ?? **/
>>> -int igc_setup_tx_resources(struct igc_ring *tx_ring)
>>> +static int igc_setup_tx_resources(struct igc_ring *tx_ring)
>>> ? {
>>> ????? struct device *dev = tx_ring->dev;
>>> ????? int size = 0;
>>> @@ -292,7 +292,7 @@ static int igc_setup_all_tx_resources(struct
>>> igc_adapter *adapter)
>>> ?? *? igc_clean_rx_ring - Free Rx Buffers per Queue
>>> ?? *? @rx_ring: ring to free buffers from
>>> ?? **/
>>> -void igc_clean_rx_ring(struct igc_ring *rx_ring)
>>> +static void igc_clean_rx_ring(struct igc_ring *rx_ring)
>>> ? {
>>> ????? u16 i = rx_ring->next_to_clean;
>>> @@ -338,7 +338,7 @@ void igc_clean_rx_ring(struct igc_ring *rx_ring)
>>> ?? *
>>> ?? *? Free all receive software resources
>>> ?? **/
>>> -void igc_free_rx_resources(struct igc_ring *rx_ring)
>>> +static void igc_free_rx_resources(struct igc_ring *rx_ring)
>>> ? {
>>> ????? igc_clean_rx_ring(rx_ring);
>>> @@ -375,7 +375,7 @@ static void igc_free_all_rx_resources(struct
>>> igc_adapter *adapter)
>>> ?? *
>>> ?? *? Returns 0 on success, negative on failure
>>> ?? **/
>>> -int igc_setup_rx_resources(struct igc_ring *rx_ring)
>>> +static int igc_setup_rx_resources(struct igc_ring *rx_ring)
>>> ? {
>>> ????? struct device *dev = rx_ring->dev;
>>> ????? int size, desc_len;
>>> @@ -449,8 +449,8 @@ static u32 igc_tx_wthresh(struct igc_adapter
>>> *adapter)
>>> ?? *
>>> ?? *? Configure the Rx unit of the MAC after a reset.
>>> ?? **/
>>> -void igc_configure_rx_ring(struct igc_adapter *adapter,
>>> -?????????????? struct igc_ring *ring)
>>> +static void igc_configure_rx_ring(struct igc_adapter *adapter,
>>> +????????????????? struct igc_ring *ring)
>>> ? {
>>> ????? struct e1000_hw *hw = &adapter->hw;
>>> ????? union e1000_adv_rx_desc *rx_desc;
>>> @@ -529,8 +529,8 @@ static void igc_configure_rx(struct igc_adapter
>>> *adapter)
>>> ?? *
>>> ?? *? Configure a transmit ring after a reset.
>>> ?? **/
>>> -void igc_configure_tx_ring(struct igc_adapter *adapter,
>>> -?????????????? struct igc_ring *ring)
>>> +static void igc_configure_tx_ring(struct igc_adapter *adapter,
>>> +????????????????? struct igc_ring *ring)
>>> ? {
>>> ????? struct e1000_hw *hw = &adapter->hw;
>>> ????? u32 txdctl = 0;
>>> @@ -586,7 +586,7 @@ static void igc_setup_mrqc(struct igc_adapter
>>> *adapter)
>>> ?? *? igc_setup_rctl - configure the receive control registers
>>> ?? *? @adapter: Board private structure
>>> ?? **/
>>> -void igc_setup_rctl(struct igc_adapter *adapter)
>>> +static void igc_setup_rctl(struct igc_adapter *adapter)
>>> ? {
>>> ????? struct e1000_hw *hw = &adapter->hw;
>>> ????? u32 rctl;
>>> @@ -634,7 +634,7 @@ void igc_setup_rctl(struct igc_adapter *adapter)
>>> ?? *? igc_setup_tctl - configure the transmit control registers
>>> ?? *? @adapter: Board private structure
>>> ?? **/
>>> -void igc_setup_tctl(struct igc_adapter *adapter)
>>> +static void igc_setup_tctl(struct igc_adapter *adapter)
>>> ? {
>>> ????? struct e1000_hw *hw = &adapter->hw;
>>> ????? u32 tctl;
>>> @@ -736,7 +736,7 @@ static bool igc_alloc_mapped_page(struct igc_ring
>>> *rx_ring,
>>> ?? *? igc_alloc_rx_buffers - Replace used receive buffers; packet split
>>> ?? *? @adapter: address of board private structure
>>> ?? **/
>>> -void igc_alloc_rx_buffers(struct igc_ring *rx_ring, u16 cleaned_count)
>>> +static void igc_alloc_rx_buffers(struct igc_ring *rx_ring, u16
>>> cleaned_count)
>>> ? {
>>> ????? union e1000_adv_rx_desc *rx_desc;
>>> ????? struct igc_rx_buffer *bi;
>>>
>> good. will be applied to v4.
>> Thanks,
>> Sasha
>> _______________________________________________
>> Intel-wired-lan mailing list
>> Intel-wired-lan at osuosl.org
>> https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Intel-wired-lan] [PATCH v3 05/11] igc: Add support for Tx/Rx rings
2018-06-28 0:42 ` Shannon Nelson
@ 2018-07-03 13:17 ` Neftin, Sasha
0 siblings, 0 replies; 8+ messages in thread
From: Neftin, Sasha @ 2018-07-03 13:17 UTC (permalink / raw)
To: intel-wired-lan
On 6/28/2018 03:42, Shannon Nelson wrote:
> On 6/24/2018 1:45 AM, Sasha Neftin wrote:
>> This change adds the defines and structures necessary to support both Tx
>> and Rx descriptor rings.
>>
>> Sasha Neftin (v2):
>> fixed code indentation
>>
>> Sasha Nedftin (v3):
>> minor code fixes
>>
>> Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
>> ---
>> ? drivers/net/ethernet/intel/igc/Makefile??????? |?? 3 +-
>> ? drivers/net/ethernet/intel/igc/e1000_base.c??? |? 83 +++
>> ? drivers/net/ethernet/intel/igc/e1000_base.h??? |? 89 +++
>> ? drivers/net/ethernet/intel/igc/e1000_defines.h |? 53 ++
>> ? drivers/net/ethernet/intel/igc/e1000_hw.h????? |?? 1 +
>> ? drivers/net/ethernet/intel/igc/e1000_regs.h??? |?? 3 +
>> ? drivers/net/ethernet/intel/igc/igc.h?????????? | 127 ++++
>> ? drivers/net/ethernet/intel/igc/igc_main.c????? | 839
>> ++++++++++++++++++++++++-
>> ? 8 files changed, 1193 insertions(+), 5 deletions(-)
>> ? create mode 100644 drivers/net/ethernet/intel/igc/e1000_base.c
>> ? create mode 100644 drivers/net/ethernet/intel/igc/e1000_base.h
>>
>> diff --git a/drivers/net/ethernet/intel/igc/Makefile
>> b/drivers/net/ethernet/intel/igc/Makefile
>> index 4563b83cd4e0..6a757ac8492d 100644
>> --- a/drivers/net/ethernet/intel/igc/Makefile
>> +++ b/drivers/net/ethernet/intel/igc/Makefile
>> @@ -7,4 +7,5 @@
>> ? obj-$(CONFIG_IGC) += igc.o
>> -igc-objs := igc_main.o e1000_mac.o
>> +igc-objs := igc_main.o e1000_mac.o \
>> +e1000_base.o
>> diff --git a/drivers/net/ethernet/intel/igc/e1000_base.c
>> b/drivers/net/ethernet/intel/igc/e1000_base.c
>> new file mode 100644
>> index 000000000000..265ec98000e7
>> --- /dev/null
>> +++ b/drivers/net/ethernet/intel/igc/e1000_base.c
>> @@ -0,0 +1,83 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/* Copyright (c)? 2018 Intel Corporation */
>> +
>> +#include <linux/delay.h>
>> +
>> +#include "e1000_hw.h"
>> +#include "e1000_i225.h"
>> +
>> +/**
>> + *? igc_rx_fifo_flush_base - Clean rx fifo after Rx enable
>> + *? @hw: pointer to the HW structure
>> + *
>> + *? After Rx enable, if manageability is enabled then there is likely
>> some
>> + *? bad data at the start of the fifo and possibly in the DMA fifo.
>> This
>> + *? function clears the fifos and flushes any packets that came in as
>> rx was
>> + *? being enabled.
>> + **/
>> +void igc_rx_fifo_flush_base(struct e1000_hw *hw)
>> +{
>> +??? u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
>> +??? int i, ms_wait;
>> +
>> +??? /* disable IPv6 options as per hardware errata */
>> +??? rfctl = rd32(E1000_RFCTL);
>> +??? rfctl |= E1000_RFCTL_IPV6_EX_DIS;
>> +??? wr32(E1000_RFCTL, rfctl);
>
> Interesting... does this new hardware really have the same errata as the
> 82575?
>
I do not know. Probably yes, because design of MAC based on same code. I
need to check it. Anyway, this will required validation cycle.
>> +
>> +??? if (!(rd32(E1000_MANC) & E1000_MANC_RCV_TCO_EN))
>> +??????? return;
>> +
>> +??? /* Disable all Rx queues */
>> +??? for (i = 0; i < 4; i++) {
>> +??????? rxdctl[i] = rd32(E1000_RXDCTL(i));
>> +??????? wr32(E1000_RXDCTL(i),
>> +???????????? rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
>> +??? }
>> +??? /* Poll all queues to verify they have shut down */
>> +??? for (ms_wait = 0; ms_wait < 10; ms_wait++) {
>> +??????? usleep_range(1000, 2000);
>> +??????? rx_enabled = 0;
>> +??????? for (i = 0; i < 4; i++)
>> +??????????? rx_enabled |= rd32(E1000_RXDCTL(i));
>> +??????? if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
>> +??????????? break;
>> +??? }
>> +
>> +??? if (ms_wait == 10)
>> +??????? pr_debug("Queue disable timed out after 10ms\n");
>> +
>> +??? /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
>> +???? * incoming packets are rejected.? Set enable and wait 2ms so that
>> +???? * any packet that was coming in as RCTL.EN was set is flushed
>> +???? */
>> +??? wr32(E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
>> +
>> +??? rlpml = rd32(E1000_RLPML);
>> +??? wr32(E1000_RLPML, 0);
>> +
>> +??? rctl = rd32(E1000_RCTL);
>> +??? temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
>> +??? temp_rctl |= E1000_RCTL_LPE;
>> +
>> +??? wr32(E1000_RCTL, temp_rctl);
>> +??? wr32(E1000_RCTL, temp_rctl | E1000_RCTL_EN);
>> +??? wrfl();
>> +??? usleep_range(2000, 3000);
>> +
>> +??? /* Enable Rx queues that were previously enabled and restore our
>> +???? * previous state
>> +???? */
>> +??? for (i = 0; i < 4; i++)
>> +??????? wr32(E1000_RXDCTL(i), rxdctl[i]);
>> +??? wr32(E1000_RCTL, rctl);
>> +??? wrfl();
>> +
>> +??? wr32(E1000_RLPML, rlpml);
>> +??? wr32(E1000_RFCTL, rfctl);
>> +
>> +??? /* Flush receive errors generated by workaround */
>> +??? rd32(E1000_ROC);
>> +??? rd32(E1000_RNBC);
>> +??? rd32(E1000_MPC);
>> +}
>> diff --git a/drivers/net/ethernet/intel/igc/e1000_base.h
>> b/drivers/net/ethernet/intel/igc/e1000_base.h
>> new file mode 100644
>> index 000000000000..9acc41d73f4f
>> --- /dev/null
>> +++ b/drivers/net/ethernet/intel/igc/e1000_base.h
>> @@ -0,0 +1,89 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright (c)? 2018 Intel Corporation */
>> +
>> +#ifndef _E1000_BASE_H
>> +#define _E1000_BASE_H
>> +
>> +/* forward declaration */
>> +void igc_rx_fifo_flush_base(struct e1000_hw *hw);
>> +
>> +/* Transmit Descriptor - Advanced */
>> +union e1000_adv_tx_desc {
>> +??? struct {
>> +??????? __le64 buffer_addr;??? /* Address of descriptor's data buf */
>> +??????? __le32 cmd_type_len;
>> +??? __le32 olinfo_status;
>
> Intent problem?
>
Right. fix will be applied in v4.
>> +??? } read;
>> +??? struct {
>> +??????? __le64 rsvd;?????? /* Reserved */
>> +??????? __le32 nxtseq_seed;
>> +??????? __le32 status;
>> +??? } wb;
>> +};
>> +
>> +struct e1000_adv_data_desc {
>> +??? __le64 buffer_addr;??? /* Address of the descriptor's data buffer */
>> +??? union {
>> +??????? u32 data;
>> +??????? struct {
>> +??????????? u32 datalen:16; /* Data buffer length */
>> +??????????? u32 rsvd:4;
>> +??????????? u32 dtyp:4;? /* Descriptor type */
>> +??????????? u32 dcmd:8;? /* Descriptor command */
>> +??????? } config;
>
> Will this bit layout work correctly on big-endian CPU?
>
>> +??? } lower;
>> +??? union {
>> +??????? u32 data;
>> +??????? struct {
>> +??????????? u32 status:4;? /* Descriptor status */
>> +??????????? u32 idx:4;
>> +??????????? u32 popts:6;? /* Packet Options */
>> +??????????? u32 paylen:18; /* Payload length */
>
> Will this bit layout work correctly on big-endian CPU?
>
>> +??????? } options;
>> +??? } upper;
>> +};
>> +
>> +/* Receive Descriptor - Advanced */
>> +union e1000_adv_rx_desc {
>> +??? struct {
>> +??????? __le64 pkt_addr; /* Packet buffer address */
>> +??????? __le64 hdr_addr; /* Header buffer address */
>> +??? } read;
>> +??? struct {
>> +??????? struct {
>> +??????????? union {
>> +??????????????? __le32 data;
>> +??????????????? struct {
>> +??????????????????? __le16 pkt_info; /*RSS type, Pkt type*/
>> +??????????????????? /* Split Header, header buffer len */
>> +??????????????????? __le16 hdr_info;
>> +??????????????? } hs_rss;
>> +??????????? } lo_dword;
>> +??????????? union {
>> +??????????????? __le32 rss; /* RSS Hash */
>> +??????????????? struct {
>> +??????????????????? __le16 ip_id; /* IP id */
>> +??????????????????? __le16 csum; /* Packet Checksum */
>> +??????????????? } csum_ip;
>> +??????????? } hi_dword;
>> +??????? } lower;
>> +??????? struct {
>> +??????????? __le32 status_error; /* ext status/error */
>> +??????????? __le16 length; /* Packet length */
>> +??????????? __le16 vlan; /* VLAN tag */
>> +??????? } upper;
>> +??? } wb;? /* writeback */
>> +};
>> +
>> +/* Additional Transmit Descriptor Control definitions */
>> +#define E1000_TXDCTL_QUEUE_ENABLE??? 0x02000000 /* Ena specific Tx
>> Queue */
>> +
>> +/* Additional Receive Descriptor Control definitions */
>> +#define E1000_RXDCTL_QUEUE_ENABLE??? 0x02000000 /* Ena specific Rx
>> Queue */
>> +
>> +/* SRRCTL bit definitions */
>> +#define E1000_SRRCTL_BSIZEPKT_SHIFT??????? 10 /* Shift _right_ */
>> +#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT??????? 2? /* Shift _left_ */
>> +#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF??? 0x02000000
>> +
>> +#endif /* _E1000_BASE_H */
>> diff --git a/drivers/net/ethernet/intel/igc/e1000_defines.h
>> b/drivers/net/ethernet/intel/igc/e1000_defines.h
>> index 1f8bc16c7029..66f8fc96dfb8 100644
>> --- a/drivers/net/ethernet/intel/igc/e1000_defines.h
>> +++ b/drivers/net/ethernet/intel/igc/e1000_defines.h
>> @@ -71,6 +71,10 @@
>> ? #define E1000_ICR_RXO??????? 0x00000040 /* Rx overrun */
>> ? #define E1000_ICR_RXT0??????? 0x00000080 /* Rx timer intr (ring 0) */
>> ? #define E1000_ICR_DRSTA??????? 0x40000000 /* Device Reset Asserted */
>> +
>> +/* If this bit asserted, the driver should claim the interrupt */
>> +#define E1000_ICR_INT_ASSERTED??? 0x80000000
>> +
>> ? #define E1000_ICS_RXT0??????? E1000_ICR_RXT0????? /* Rx timer intr */
>> ? #define IMS_ENABLE_MASK ( \
>> @@ -97,4 +101,53 @@
>> ? #define E1000_GPIE_EIAME??? 0x40000000
>> ? #define E1000_GPIE_PBA??????? 0x80000000
>> +/* Transmit Control */
>> +#define E1000_TCTL_EN??????? 0x00000002 /* enable Tx */
>> +#define E1000_TCTL_PSP??????? 0x00000008 /* pad short packets */
>> +#define E1000_TCTL_CT??????? 0x00000ff0 /* collision threshold */
>> +#define E1000_TCTL_COLD??????? 0x003ff000 /* collision distance */
>> +#define E1000_TCTL_RTLC??????? 0x01000000 /* Re-transmit on late
>> collision */
>> +#define E1000_TCTL_MULR??????? 0x10000000 /* Multiple request support */
>> +
>> +#define E1000_CT_SHIFT??????????? 4
>> +#define E1000_COLLISION_THRESHOLD??? 15
>> +
>> +/* Management Control */
>> +#define E1000_MANC_RCV_TCO_EN??? 0x00020000 /* Receive TCO Packets
>> Enabled */
>> +
>> +/* Receive Control */
>> +#define E1000_RCTL_RST??????? 0x00000001 /* Software reset */
>> +#define E1000_RCTL_EN??????? 0x00000002 /* enable */
>> +#define E1000_RCTL_SBP??????? 0x00000004 /* store bad packet */
>> +#define E1000_RCTL_UPE??????? 0x00000008 /* unicast promisc enable */
>> +#define E1000_RCTL_MPE??????? 0x00000010 /* multicast promisc enable */
>> +#define E1000_RCTL_LPE??????? 0x00000020 /* long packet enable */
>> +#define E1000_RCTL_LBM_NO??? 0x00000000 /* no loopback mode */
>> +#define E1000_RCTL_LBM_MAC??? 0x00000040 /* MAC loopback mode */
>> +#define E1000_RCTL_LBM_TCVR??? 0x000000C0 /* tcvr loopback mode */
>> +#define E1000_RCTL_DTYP_PS??? 0x00000400 /* Packet Split descriptor */
>> +
>> +#define E1000_RCTL_RDMTS_HALF??? 0x00000000 /* Rx desc min thresh
>> size */
>> +#define E1000_RCTL_BAM??????? 0x00008000 /* broadcast enable */
>> +
>> +/* Header split receive */
>> +#define E1000_RFCTL_IPV6_EX_DIS??? 0x00010000
>> +#define E1000_RFCTL_LEF??????? 0x00040000
>> +
>> +/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
>> +#define E1000_RCTL_SZ_2048??? 0x00000000 /* Rx buffer size 2048 */
>> +#define E1000_RCTL_SZ_1024??? 0x00010000 /* Rx buffer size 1024 */
>> +#define E1000_RCTL_SZ_512??? 0x00020000 /* Rx buffer size 512 */
>> +#define E1000_RCTL_SZ_256??? 0x00030000 /* Rx buffer size 256 */
>> +/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
>> +#define E1000_RCTL_SZ_16384??? 0x00010000 /* Rx buffer size 16384 */
>> +#define E1000_RCTL_SZ_8192??? 0x00020000 /* Rx buffer size 8192 */
>> +#define E1000_RCTL_SZ_4096??? 0x00030000 /* Rx buffer size 4096 */
>> +
>> +#define E1000_RCTL_MO_SHIFT??? 12 /* multicast offset shift */
>> +#define E1000_RCTL_CFIEN??? 0x00080000 /* canonical form enable */
>> +#define E1000_RCTL_DPF??????? 0x00400000 /* discard pause frames */
>> +#define E1000_RCTL_PMCF??????? 0x00800000 /* pass MAC control frames */
>> +#define E1000_RCTL_SECRC??? 0x04000000 /* Strip Ethernet CRC */
>> +
>> ? #endif /* _E1000_DEFINES_H_ */
>> diff --git a/drivers/net/ethernet/intel/igc/e1000_hw.h
>> b/drivers/net/ethernet/intel/igc/e1000_hw.h
>> index 650c4ac981d9..67fa4f696b98 100644
>> --- a/drivers/net/ethernet/intel/igc/e1000_hw.h
>> +++ b/drivers/net/ethernet/intel/igc/e1000_hw.h
>> @@ -10,6 +10,7 @@
>> ? #include "e1000_defines.h"
>> ? #include "e1000_mac.h"
>> ? #include "e1000_i225.h"
>> +#include "e1000_base.h"
>> ? #define E1000_DEV_ID_I225_LM??????????? 0x15F2
>> ? #define E1000_DEV_ID_I225_V??????????? 0x15F3
>> diff --git a/drivers/net/ethernet/intel/igc/e1000_regs.h
>> b/drivers/net/ethernet/intel/igc/e1000_regs.h
>> index 5634a01afff3..dcc4d89c9933 100644
>> --- a/drivers/net/ethernet/intel/igc/e1000_regs.h
>> +++ b/drivers/net/ethernet/intel/igc/e1000_regs.h
>> @@ -229,6 +229,9 @@
>> ? #define E1000_TLPIC??? 0x4148 /* EEE Tx LPI Count - TLPIC */
>> ? #define E1000_RLPIC??? 0x414C /* EEE Rx LPI Count - RLPIC */
>> +/* Management registers */
>> +#define E1000_MANC??? 0x05820? /* Management Control - RW */
>> +
>> ? /* forward declaration */
>> ? struct e1000_hw;
>> ? u32 igc_rd32(struct e1000_hw *hw, u32 reg);
>> diff --git a/drivers/net/ethernet/intel/igc/igc.h
>> b/drivers/net/ethernet/intel/igc/igc.h
>> index 7cab3e9c8e91..abf2e302c417 100644
>> --- a/drivers/net/ethernet/intel/igc/igc.h
>> +++ b/drivers/net/ethernet/intel/igc/igc.h
>> @@ -46,6 +46,47 @@ extern char igc_driver_version[];
>> ? #define MAX_Q_VECTORS???????????????????? 10
>> ? #define MAX_STD_JUMBO_FRAME_SIZE??????? 9216
>> +#define IGC_TX_PTHRESH??????????? 8
>> +#define IGC_TX_HTHRESH??????????? 1
>> +
my apologies. this define duplicated. fix will be applied in v4.
>> +/* Supported Rx Buffer Sizes */
>> +#define IGC_RXBUFFER_256??????? 256
>> +#define IGC_RXBUFFER_2048??????? 2048
>> +#define IGC_RXBUFFER_3072??????? 3072
>> +
>> +#define IGC_RX_HDR_LEN??????????? IGC_RXBUFFER_256
>> +
>> +/* RX and TX descriptor control thresholds.
>> + * PTHRESH - MAC will consider prefetch if it has fewer than this
>> number of
>> + *?????????? descriptors available in its onboard memory.
>> + *?????????? Setting this to 0 disables RX descriptor prefetch.
>> + * HTHRESH - MAC will only prefetch if there are at least this many
>> descriptors
>> + *?????????? available in host memory.
>> + *?????????? If PTHRESH is 0, this should also be 0.
>> + * WTHRESH - RX descriptor writeback threshold - MAC will delay
>> writing back
>> + *?????????? descriptors until either it has this many to write back,
>> or the
>> + *?????????? ITR timer expires.
>> + */
>> +#define IGC_RX_PTHRESH??????????? 8
>> +#define IGC_RX_HTHRESH??????????? 8
>> +#define IGC_TX_PTHRESH??????????? 8
>> +#define IGC_TX_HTHRESH??????????? 1
>> +#define IGC_RX_WTHRESH??????????? 4
>> +
>> +#define IGC_RX_DMA_ATTR \
>> +??? (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)
>> +
>> +#define IGC_TS_HDR_LEN??????????? 16
>> +
>> +#define IGC_SKB_PAD??????????? (NET_SKB_PAD + NET_IP_ALIGN)
>> +
>> +#if (PAGE_SIZE < 8192)
>> +#define IGC_MAX_FRAME_BUILD_SKB \
>> +??? (SKB_WITH_OVERHEAD(IGC_RXBUFFER_2048) - IGC_SKB_PAD -
>> IGC_TS_HDR_LEN)
>> +#else
>> +#define IGC_MAX_FRAME_BUILD_SKB (IGC_RXBUFFER_2048 - IGC_TS_HDR_LEN)
>> +#endif
>> +
>> ? enum e1000_state_t {
>> ?????? __IGC_TESTING,
>> ????? __IGC_RESETTING,
>> @@ -53,6 +94,33 @@ enum e1000_state_t {
>> ?????? __IGC_PTP_TX_IN_PROGRESS,
>> ? };
>> +/** wrapper around a pointer to a socket buffer,
>> + *? so a DMA handle can be stored along with the buffer
>> + **/
>
> This comment shouldn't have /** or **/, just /* and */
>
fix will be applied in v4.
>> +struct igc_tx_buffer {
>> +??? union e1000_adv_tx_desc *next_to_watch;
>> +??? unsigned long time_stamp;
>> +??? struct sk_buff *skb;
>> +??? unsigned int bytecount;
>> +??? u16 gso_segs;
>> +??? __be16 protocol;
>> +
>> +??? DEFINE_DMA_UNMAP_ADDR(dma);
>> +??? DEFINE_DMA_UNMAP_LEN(len);
>> +??? u32 tx_flags;
>> +};
>> +
>> +struct igc_rx_buffer {
>> +??? dma_addr_t dma;
>> +??? struct page *page;
>> +#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
>> +??? __u32 page_offset;
>> +#else
>> +??? __u16 page_offset;
>> +#endif
>> +??? __u16 pagecnt_bias;
>> +};
>> +
>> ? struct igc_tx_queue_stats {
>> ????? u64 packets;
>> ????? u64 bytes;
>> @@ -218,4 +286,63 @@ struct igc_adapter {
>> ????? struct igc_mac_addr *mac_table;
>> ? };
>> +/* igc_desc_unused - calculate if we have unused descriptors */
>> +static inline u16 igc_desc_unused(const struct igc_ring *ring)
>> +{
>> +??? u16 ntc = ring->next_to_clean;
>> +??? u16 ntu = ring->next_to_use;
>> +
>> +??? return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;
>> +}
>> +
>> +static inline struct netdev_queue *txring_txq(const struct igc_ring
>> *tx_ring)
>> +{
>> +??? return netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index);
>> +}
>> +
>> +enum e1000_ring_flags_t {
>> +??? IGC_RING_FLAG_RX_3K_BUFFER,
>> +??? IGC_RING_FLAG_RX_BUILD_SKB_ENABLED,
>> +??? IGC_RING_FLAG_RX_SCTP_CSUM,
>> +??? IGC_RING_FLAG_RX_LB_VLAN_BSWAP,
>> +??? IGC_RING_FLAG_TX_CTX_IDX,
>> +??? IGC_RING_FLAG_TX_DETECT_HANG
>> +};
>> +
>> +#define ring_uses_large_buffer(ring) \
>> +??? test_bit(IGC_RING_FLAG_RX_3K_BUFFER, &(ring)->flags)
>> +
>> +#define ring_uses_build_skb(ring) \
>> +??? test_bit(IGC_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)
>> +
>> +static inline unsigned int igc_rx_bufsz(struct igc_ring *ring)
>> +{
>> +#if (PAGE_SIZE < 8192)
>> +??? if (ring_uses_large_buffer(ring))
>> +??????? return IGC_RXBUFFER_3072;
>> +
>> +??? if (ring_uses_build_skb(ring))
>> +??????? return IGC_MAX_FRAME_BUILD_SKB + IGC_TS_HDR_LEN;
>> +#endif
>> +??? return IGC_RXBUFFER_2048;
>> +}
>> +
>> +static inline unsigned int igc_rx_pg_order(struct igc_ring *ring)
>> +{
>> +#if (PAGE_SIZE < 8192)
>> +??? if (ring_uses_large_buffer(ring))
>> +??????? return 1;
>> +#endif
>> +??? return 0;
>> +}
>> +
>> +#define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring))
>> +
>> +#define IGC_RX_DESC(R, i)?????? \
>> +??? (&(((union e1000_adv_rx_desc *)((R)->desc))[i]))
>> +#define IGC_TX_DESC(R, i)?????? \
>> +??? (&(((union e1000_adv_tx_desc *)((R)->desc))[i]))
>> +#define IGC_TX_CTXTDESC(R, i)?? \
>> +??? (&(((struct e1000_adv_tx_context_desc *)((R)->desc))[i]))
>> +
>> ? #endif /* _IGC_H_ */
>> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c
>> b/drivers/net/ethernet/intel/igc/igc_main.c
>> index 30b778c9b94b..a147a1b7585e 100644
>> --- a/drivers/net/ethernet/intel/igc/igc_main.c
>> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
>> @@ -29,11 +29,21 @@ static const struct pci_device_id igc_pci_tbl[] = {
>> ? MODULE_DEVICE_TABLE(pci, igc_pci_tbl);
>> ? /* forward declaration */
>> +static int igc_setup_all_tx_resources(struct igc_adapter *adapter);
>> +static void igc_clean_tx_ring(struct igc_ring *tx_ring);
>> +static void igc_free_all_tx_resources(struct igc_adapter *adapter);
>> +static int igc_setup_all_rx_resources(struct igc_adapter *adapter);
>> ? static int igc_sw_init(struct igc_adapter *);
>> ? static void igc_configure(struct igc_adapter *adapter);
>> +static void igc_configure_tx(struct igc_adapter *);
>> +static void igc_configure_rx(struct igc_adapter *adapter);
>> ? static void igc_power_down_link(struct igc_adapter *adapter);
>> ? static void igc_set_default_mac_filter(struct igc_adapter *adapter);
>> +static void igc_set_rx_mode(struct net_device *netdev);
>> +static void igc_setup_mrqc(struct igc_adapter *adapter);
>> ? static irqreturn_t igc_msix_ring(int irq, void *data);
>> +static irqreturn_t igc_intr_msi(int irq, void *data);
>> +static irqreturn_t igc_intr(int irq, void *data);
>> ? static void igc_write_itr(struct igc_q_vector *q_vector);
>> ? static int igc_request_msix(struct igc_adapter *adapter);
>> ? static void igc_assign_vector(struct igc_q_vector *q_vector, int
>> msix_vector);
>> @@ -125,6 +135,526 @@ static void igc_get_hw_control(struct
>> igc_adapter *adapter)
>> ? }
>> ? /**
>> + *? igc_free_tx_resources - Free Tx Resources per Queue
>> + *? @tx_ring: Tx descriptor ring for a specific queue
>> + *
>> + *? Free all transmit software resources
>> + **/
>> +void igc_free_tx_resources(struct igc_ring *tx_ring)
>> +{
>> +??? igc_clean_tx_ring(tx_ring);
>> +
>> +??? vfree(tx_ring->tx_buffer_info);
>> +??? tx_ring->tx_buffer_info = NULL;
>> +
>> +??? /* if not set, then don't free */
>> +??? if (!tx_ring->desc)
>> +??????? return;
>> +
>> +??? dma_free_coherent(tx_ring->dev, tx_ring->size,
>> +????????????? tx_ring->desc, tx_ring->dma);
>> +
>> +??? tx_ring->desc = NULL;
>> +}
>> +
>> +/**
>> + *? igc_free_all_tx_resources - Free Tx Resources for All Queues
>> + *? @adapter: board private structure
>> + *
>> + *? Free all transmit software resources
>> + **/
>> +static void igc_free_all_tx_resources(struct igc_adapter *adapter)
>> +{
>> +??? int i;
>> +
>> +??? for (i = 0; i < adapter->num_tx_queues; i++)
>> +??????? igc_free_tx_resources(adapter->tx_ring[i]);
>> +}
>> +
>> +void igc_unmap_and_free_tx_resource(struct igc_ring *ring,
>> +??????????????????? struct igc_tx_buffer *tx_buffer)
>> +{
>> +??? if (tx_buffer->skb) {
>> +??????? dev_kfree_skb_any(tx_buffer->skb);
>> +??????? if (dma_unmap_len(tx_buffer, len))
>> +??????????? dma_unmap_single(ring->dev,
>> +???????????????????? dma_unmap_addr(tx_buffer, dma),
>> +???????????????????? dma_unmap_len(tx_buffer, len),
>> +???????????????????? DMA_TO_DEVICE);
>> +??? } else if (dma_unmap_len(tx_buffer, len)) {
>> +??????? dma_unmap_page(ring->dev,
>> +?????????????????? dma_unmap_addr(tx_buffer, dma),
>> +?????????????????? dma_unmap_len(tx_buffer, len),
>> +?????????????????? DMA_TO_DEVICE);
>> +??? }
>> +??? tx_buffer->next_to_watch = NULL;
>> +??? tx_buffer->skb = NULL;
>> +??? dma_unmap_len_set(tx_buffer, len, 0);
>> +??? /* buffer_info must be completely set up in the transmit path */
>> +}
>> +
>> +/**
>> + *? igc_clean_tx_ring - Free Tx Buffers
>> + *? @tx_ring: ring to be cleaned
>> + **/
>> +static void igc_clean_tx_ring(struct igc_ring *tx_ring)
>> +{
>> +??? struct igc_tx_buffer *buffer_info;
>> +??? unsigned long size;
>> +??? u16 i;
>> +
>> +??? if (!tx_ring->tx_buffer_info)
>> +??????? return;
>> +
>> +??? /* Free all the Tx ring sk_buffs */
>> +??? for (i = 0; i < tx_ring->count; i++) {
>> +??????? buffer_info = &tx_ring->tx_buffer_info[i];
>> +??????? igc_unmap_and_free_tx_resource(tx_ring, buffer_info);
>> +??? }
>> +
>> +??? netdev_tx_reset_queue(txring_txq(tx_ring));
>> +
>> +??? size = sizeof(struct igc_tx_buffer) * tx_ring->count;
>> +??? memset(tx_ring->tx_buffer_info, 0, size);
>> +
>> +??? /* Zero out the descriptor ring */
>> +??? memset(tx_ring->desc, 0, tx_ring->size);
>> +
>> +??? tx_ring->next_to_use = 0;
>> +??? tx_ring->next_to_clean = 0;
>> +}
>> +
>> +/**
>> + *? igc_setup_tx_resources - allocate Tx resources (Descriptors)
>> + *? @tx_ring: tx descriptor ring (for a specific queue) to setup
>> + *
>> + *? Return 0 on success, negative on failure
>> + **/
>> +int igc_setup_tx_resources(struct igc_ring *tx_ring)
>> +{
>> +??? struct device *dev = tx_ring->dev;
>> +??? int size = 0;
>> +
>> +??? size = sizeof(struct igc_tx_buffer) * tx_ring->count;
>> +??? tx_ring->tx_buffer_info = vzalloc(size);
>> +??? if (!tx_ring->tx_buffer_info)
>> +??????? goto err;
>> +
>> +??? /* round up to nearest 4K */
>> +??? tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
>> +??? tx_ring->size = ALIGN(tx_ring->size, 4096);
>> +
>> +??? tx_ring->desc = dma_alloc_coherent(dev, tx_ring->size,
>> +?????????????????????? &tx_ring->dma, GFP_KERNEL);
>> +
>> +??? if (!tx_ring->desc)
>> +??????? goto err;
>> +
>> +??? tx_ring->next_to_use = 0;
>> +??? tx_ring->next_to_clean = 0;
>> +
>> +??? return 0;
>> +
>> +err:
>> +??? vfree(tx_ring->tx_buffer_info);
>> +??? dev_err(dev,
>> +??????? "Unable to allocate memory for the transmit descriptor ring\n");
>> +??? return -ENOMEM;
>> +}
>> +
>> +/**
>> + *? igc_setup_all_tx_resources - wrapper to allocate Tx resources
>> + *??????????????????????????????? (Descriptors) for all queues
>
> This should be a single line
>
fix will be applied in v4.
>> + *? @adapter: board private structure
>> + *
>> + *? Return 0 on success, negative on failure
>> + **/
>> +static int igc_setup_all_tx_resources(struct igc_adapter *adapter)
>> +{
>> +??? struct pci_dev *pdev = adapter->pdev;
>> +??? int i, err = 0;
>> +
>> +??? for (i = 0; i < adapter->num_tx_queues; i++) {
>> +??????? err = igc_setup_tx_resources(adapter->tx_ring[i]);
>> +??????? if (err) {
>> +??????????? dev_err(&pdev->dev,
>> +??????????????? "Allocation for Tx Queue %u failed\n", i);
>> +??????????? for (i--; i >= 0; i--)
>> +??????????????? igc_free_tx_resources(adapter->tx_ring[i]);
>> +??????????? break;
>> +??????? }
>> +??? }
>> +
>> +??? return err;
>> +}
>> +
>> +/**
>> + *? igc_clean_rx_ring - Free Rx Buffers per Queue
>> + *? @rx_ring: ring to free buffers from
>> + **/
>> +void igc_clean_rx_ring(struct igc_ring *rx_ring)
>> +{
>> +??? u16 i = rx_ring->next_to_clean;
>> +
>> +??? if (rx_ring->skb)
>> +??????? dev_kfree_skb(rx_ring->skb);
>> +??? rx_ring->skb = NULL;
>> +
>> +??? /* Free all the Rx ring sk_buffs */
>> +??? while (i != rx_ring->next_to_alloc) {
>> +??????? struct igc_rx_buffer *buffer_info = &rx_ring->rx_buffer_info[i];
>> +
>> +??????? /* Invalidate cache lines that may have been written to by
>> +???????? * device so that we avoid corrupting memory.
>> +???????? */
>> +??????? dma_sync_single_range_for_cpu(rx_ring->dev,
>> +????????????????????????? buffer_info->dma,
>> +????????????????????????? buffer_info->page_offset,
>> +????????????????????????? igc_rx_bufsz(rx_ring),
>> +????????????????????????? DMA_FROM_DEVICE);
>> +
>> +??????? /* free resources associated with mapping */
>> +??????? dma_unmap_page_attrs(rx_ring->dev,
>> +???????????????????? buffer_info->dma,
>> +???????????????????? igc_rx_pg_size(rx_ring),
>> +???????????????????? DMA_FROM_DEVICE,
>> +???????????????????? IGC_RX_DMA_ATTR);
>> +??????? __page_frag_cache_drain(buffer_info->page,
>> +??????????????????? buffer_info->pagecnt_bias);
>> +
>> +??????? i++;
>> +??????? if (i == rx_ring->count)
>> +??????????? i = 0;
>> +??? }
>> +
>> +??? rx_ring->next_to_alloc = 0;
>> +??? rx_ring->next_to_clean = 0;
>> +??? rx_ring->next_to_use = 0;
>> +}
>> +
>> +/**
>> + *? igc_free_rx_resources - Free Rx Resources
>> + *? @rx_ring: ring to clean the resources from
>> + *
>> + *? Free all receive software resources
>> + **/
>> +void igc_free_rx_resources(struct igc_ring *rx_ring)
>> +{
>> +??? igc_clean_rx_ring(rx_ring);
>> +
>> +??? vfree(rx_ring->rx_buffer_info);
>> +??? rx_ring->rx_buffer_info = NULL;
>> +
>> +??? /* if not set, then don't free */
>> +??? if (!rx_ring->desc)
>> +??????? return;
>> +
>> +??? dma_free_coherent(rx_ring->dev, rx_ring->size,
>> +????????????? rx_ring->desc, rx_ring->dma);
>> +
>> +??? rx_ring->desc = NULL;
>> +}
>> +
>> +/**
>> + *? igc_free_all_rx_resources - Free Rx Resources for All Queues
>> + *? @adapter: board private structure
>> + *
>> + *? Free all receive software resources
>> + **/
>> +static void igc_free_all_rx_resources(struct igc_adapter *adapter)
>> +{
>> +??? int i;
>> +
>> +??? for (i = 0; i < adapter->num_rx_queues; i++)
>> +??????? igc_free_rx_resources(adapter->rx_ring[i]);
>> +}
>> +
>> +/**
>> + *? igc_setup_rx_resources - allocate Rx resources (Descriptors)
>> + *? @rx_ring:??? rx descriptor ring (for a specific queue) to setup
>> + *
>> + *? Returns 0 on success, negative on failure
>> + **/
>> +int igc_setup_rx_resources(struct igc_ring *rx_ring)
>> +{
>> +??? struct device *dev = rx_ring->dev;
>> +??? int size, desc_len;
>> +
>> +??? size = sizeof(struct igc_rx_buffer) * rx_ring->count;
>> +??? rx_ring->rx_buffer_info = vzalloc(size);
>> +??? if (!rx_ring->rx_buffer_info)
>> +??????? goto err;
>> +
>> +??? desc_len = sizeof(union e1000_adv_rx_desc);
>> +
>> +??? /* Round up to nearest 4K */
>> +??? rx_ring->size = rx_ring->count * desc_len;
>> +??? rx_ring->size = ALIGN(rx_ring->size, 4096);
>> +
>> +??? rx_ring->desc = dma_alloc_coherent(dev, rx_ring->size,
>> +?????????????????????? &rx_ring->dma, GFP_KERNEL);
>> +
>> +??? if (!rx_ring->desc)
>> +??????? goto err;
>> +
>> +??? rx_ring->next_to_alloc = 0;
>> +??? rx_ring->next_to_clean = 0;
>> +??? rx_ring->next_to_use = 0;
>> +
>> +??? return 0;
>> +
>> +err:
>> +??? vfree(rx_ring->rx_buffer_info);
>> +??? rx_ring->rx_buffer_info = NULL;
>> +??? dev_err(dev,
>> +??????? "Unable to allocate memory for the receive descriptor ring\n");
>> +??? return -ENOMEM;
>> +}
>> +
>> +/**
>> + *? igc_setup_all_rx_resources - wrapper to allocate Rx resources
>> + *??????????????????????????????? (Descriptors) for all queues
>> + *? @adapter: board private structure
>> + *
>> + *? Return 0 on success, negative on failure
>> + **/
>> +static int igc_setup_all_rx_resources(struct igc_adapter *adapter)
>> +{
>> +??? struct pci_dev *pdev = adapter->pdev;
>> +??? int i, err = 0;
>> +
>> +??? for (i = 0; i < adapter->num_rx_queues; i++) {
>> +??????? err = igc_setup_rx_resources(adapter->rx_ring[i]);
>> +??????? if (err) {
>> +??????????? dev_err(&pdev->dev,
>> +??????????????? "Allocation for Rx Queue %u failed\n", i);
>> +??????????? for (i--; i >= 0; i--)
>> +??????????????? igc_free_rx_resources(adapter->rx_ring[i]);
>> +??????????? break;
>> +??????? }
>> +??? }
>> +
>> +??? return err;
>> +}
>> +
>> +static u32 igc_tx_wthresh(struct igc_adapter *adapter)
>> +{
>> +??? return 16;
>
> Is there a #define for this?? Why is this a function?
>
Good catch. Thanks. This function should be gone. I will rework and use
define for IGC_TX_WTHRESH. Fix will be applied in v4.
>> +}
>> +
>> +/**
>> + *? igc_configure_rx_ring - Configure a receive ring after Reset
>> + *? @adapter: board private structure
>> + *? @ring: receive ring to be configured
>> + *
>> + *? Configure the Rx unit of the MAC after a reset.
>> + **/
>> +void igc_configure_rx_ring(struct igc_adapter *adapter,
>> +?????????????? struct igc_ring *ring)
>> +{
>> +??? struct e1000_hw *hw = &adapter->hw;
>> +??? union e1000_adv_rx_desc *rx_desc;
>> +??? u64 rdba = ring->dma;
>> +??? int reg_idx = ring->reg_idx;
>> +??? u32 srrctl = 0, rxdctl = 0;
>
> reverse xmas tree
>
fix will be applied in v4.
>> +
>> +??? /* disable the queue */
>> +??? wr32(E1000_RXDCTL(reg_idx), 0);
>> +
>> +??? /* Set DMA base address registers */
>> +??? wr32(E1000_RDBAL(reg_idx),
>> +???????? rdba & 0x00000000ffffffffULL);
>> +??? wr32(E1000_RDBAH(reg_idx), rdba >> 32);
>> +??? wr32(E1000_RDLEN(reg_idx),
>> +???????? ring->count * sizeof(union e1000_adv_rx_desc));
>> +
>> +??? /* initialize head and tail */
>> +??? ring->tail = adapter->io_addr + E1000_RDT(reg_idx);
>> +??? wr32(E1000_RDH(reg_idx), 0);
>> +??? writel(0, ring->tail);
>> +
>> +??? /* reset next-to- use/clean to place SW in sync with hardwdare */
>
> s/hardwdare/hardware/
>
fix will be applied in v4.
>> +??? ring->next_to_clean = 0;
>> +??? ring->next_to_use = 0;
>> +
>> +??? /* set descriptor configuration */
>> +??? srrctl = IGC_RX_HDR_LEN << E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
>> +??? if (ring_uses_large_buffer(ring))
>> +??????? srrctl |= IGC_RXBUFFER_3072 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
>> +??? else
>> +??????? srrctl |= IGC_RXBUFFER_2048 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
>> +??? srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
>> +
>> +??? wr32(E1000_SRRCTL(reg_idx), srrctl);
>> +
>> +??? rxdctl |= IGC_RX_PTHRESH;
>> +??? rxdctl |= IGC_RX_HTHRESH << 8;
>> +??? rxdctl |= IGC_RX_WTHRESH << 16;
>> +
>> +??? /* initialize rx_buffer_info */
>> +??? memset(ring->rx_buffer_info, 0,
>> +?????????? sizeof(struct igc_rx_buffer) * ring->count);
>> +
>> +??? /* initialize Rx descriptor 0 */
>> +??? rx_desc = IGC_RX_DESC(ring, 0);
>> +??? rx_desc->wb.upper.length = 0;
>> +
>> +??? /* enable receive descriptor fetching */
>> +??? rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
>> +
>> +??? wr32(E1000_RXDCTL(reg_idx), rxdctl);
>> +}
>> +
>> +/**
>> + *? igc_configure_rx - Configure receive Unit after Reset
>> + *? @adapter: board private structure
>> + *
>> + *? Configure the Rx unit of the MAC after a reset.
>> + **/
>> +static void igc_configure_rx(struct igc_adapter *adapter)
>> +{
>> +??? int i;
>> +
>> +??? /* Setup the HW Rx Head and Tail Descriptor Pointers and
>> +???? * the Base and Length of the Rx Descriptor Ring
>> +???? */
>> +??? for (i = 0; i < adapter->num_rx_queues; i++)
>> +??????? igc_configure_rx_ring(adapter, adapter->rx_ring[i]);
>> +}
>> +
>> +/**
>> + *? igc_configure_tx_ring - Configure transmit ring after Reset
>> + *? @adapter: board private structure
>> + *? @ring: tx ring to configure
>> + *
>> + *? Configure a transmit ring after a reset.
>> + **/
>> +void igc_configure_tx_ring(struct igc_adapter *adapter,
>> +?????????????? struct igc_ring *ring)
>> +{
>> +??? struct e1000_hw *hw = &adapter->hw;
>> +??? u32 txdctl = 0;
>> +??? u64 tdba = ring->dma;
>> +??? int reg_idx = ring->reg_idx;
>
> reverse xmas tree
>
fix will be applied in v4.
>> +
>> +??? /* disable the queue */
>> +??? wr32(E1000_TXDCTL(reg_idx), 0);
>> +??? wrfl();
>> +??? mdelay(10);
>> +
>> +??? wr32(E1000_TDLEN(reg_idx),
>> +???????? ring->count * sizeof(union e1000_adv_tx_desc));
>> +??? wr32(E1000_TDBAL(reg_idx),
>> +???????? tdba & 0x00000000ffffffffULL);
>> +??? wr32(E1000_TDBAH(reg_idx), tdba >> 32);
>> +
>> +??? ring->tail = adapter->io_addr + E1000_TDT(reg_idx);
>> +??? wr32(E1000_TDH(reg_idx), 0);
>> +??? writel(0, ring->tail);
>> +
>> +??? txdctl |= IGC_TX_PTHRESH;
>> +??? txdctl |= IGC_TX_HTHRESH << 8;
>> +??? txdctl |= igc_tx_wthresh(adapter) << 16;
>> +
>> +??? txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
>> +??? wr32(E1000_TXDCTL(reg_idx), txdctl);
>> +}
>> +
>> +/**
>> + *? igc_configure_tx - Configure transmit Unit after Reset
>> + *? @adapter: board private structure
>> + *
>> + *? Configure the Tx unit of the MAC after a reset.
>> + **/
>> +static void igc_configure_tx(struct igc_adapter *adapter)
>> +{
>> +??? int i;
>> +
>> +??? for (i = 0; i < adapter->num_tx_queues; i++)
>> +??????? igc_configure_tx_ring(adapter, adapter->tx_ring[i]);
>> +}
>> +
>> +/**
>> + *? igc_setup_mrqc - configure the multiple receive queue control
>> registers
>> + *? @adapter: Board private structure
>> + **/
>> +static void igc_setup_mrqc(struct igc_adapter *adapter)
>> +{
>> +}
>> +
>> +/**
>> + *? igc_setup_rctl - configure the receive control registers
>> + *? @adapter: Board private structure
>> + **/
>> +void igc_setup_rctl(struct igc_adapter *adapter)
>> +{
>> +??? struct e1000_hw *hw = &adapter->hw;
>> +??? u32 rctl;
>> +
>> +??? rctl = rd32(E1000_RCTL);
>> +
>> +??? rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
>> +??? rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
>> +
>> +??? rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_RDMTS_HALF |
>> +??????? (hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
>> +
>> +??? /* enable stripping of CRC. It's unlikely this will break BMC
>> +???? * redirection as it did with e1000. Newer features require
>> +???? * that the HW strips the CRC.
>> +???? */
>> +??? rctl |= E1000_RCTL_SECRC;
>> +
>> +??? /* disable store bad packets and clear size bits. */
>> +??? rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_SZ_256);
>> +
>> +??? /* enable LPE to allow for reception of jumbo frames */
>> +??? rctl |= E1000_RCTL_LPE;
>> +
>> +??? /* disable queue 0 to prevent tail write w/o re-config */
>> +??? wr32(E1000_RXDCTL(0), 0);
>> +
>> +??? /* This is useful for sniffing bad packets. */
>> +??? if (adapter->netdev->features & NETIF_F_RXALL) {
>> +??????? /* UPE and MPE will be handled by normal PROMISC logic
>> +???????? * in e1000e_set_rx_mode
>> +???????? */
>> +??????? rctl |= (E1000_RCTL_SBP | /* Receive bad packets */
>> +???????????? E1000_RCTL_BAM | /* RX All Bcast Pkts */
>> +???????????? E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
>> +
>> +??????? rctl &= ~(E1000_RCTL_DPF | /* Allow filtered pause */
>> +????????????? E1000_RCTL_CFIEN); /* Disable VLAN CFIEN Filter */
>> +??? }
>> +
>> +??? wr32(E1000_RCTL, rctl);
>> +}
>> +
>> +/**
>> + *? igc_setup_tctl - configure the transmit control registers
>> + *? @adapter: Board private structure
>> + **/
>> +void igc_setup_tctl(struct igc_adapter *adapter)
>> +{
>> +??? struct e1000_hw *hw = &adapter->hw;
>> +??? u32 tctl;
>> +
>> +??? /* disable queue 0 which icould be enabled by default */
>> +??? wr32(E1000_TXDCTL(0), 0);
>> +
>> +??? /* Program the Transmit Control Register */
>> +??? tctl = rd32(E1000_TCTL);
>> +??? tctl &= ~E1000_TCTL_CT;
>> +??? tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
>> +??????? (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
>> +
>> +??? /* Enable transmits */
>> +??? tctl |= E1000_TCTL_EN;
>> +
>> +??? wr32(E1000_TCTL, tctl);
>> +}
>> +
>> +/**
>> ?? *? igc_set_mac - Change the Ethernet Address of the NIC
>> ?? *? @netdev: network interface device structure
>> ?? *? @p: pointer to an address structure
>> @@ -156,6 +686,121 @@ static netdev_tx_t igc_xmit_frame(struct sk_buff
>> *skb,
>> ????? return NETDEV_TX_OK;
>> ? }
>> +static inline unsigned int igc_rx_offset(struct igc_ring *rx_ring)
>> +{
>> +??? return ring_uses_build_skb(rx_ring) ? IGC_SKB_PAD : 0;
>> +}
>> +
>> +static bool igc_alloc_mapped_page(struct igc_ring *rx_ring,
>> +????????????????? struct igc_rx_buffer *bi)
>> +{
>> +??? struct page *page = bi->page;
>> +??? dma_addr_t dma;
>> +
>> +??? /* since we are recycling buffers we should seldom need to alloc */
>> +??? if (likely(page))
>> +??????? return true;
>> +
>> +??? /* alloc new page for storage */
>> +??? page = dev_alloc_pages(igc_rx_pg_order(rx_ring));
>> +??? if (unlikely(!page)) {
>> +??????? rx_ring->rx_stats.alloc_failed++;
>> +??????? return false;
>> +??? }
>> +
>> +??? /* map page for use */
>> +??? dma = dma_map_page_attrs(rx_ring->dev, page, 0,
>> +???????????????? igc_rx_pg_size(rx_ring),
>> +???????????????? DMA_FROM_DEVICE,
>> +???????????????? IGC_RX_DMA_ATTR);
>> +
>> +??? /* if mapping failed free memory back to system since
>> +???? * there isn't much point in holding memory we can't use
>> +???? */
>> +??? if (dma_mapping_error(rx_ring->dev, dma)) {
>> +??????? __free_page(page);
>> +
>> +??????? rx_ring->rx_stats.alloc_failed++;
>> +??????? return false;
>> +??? }
>> +
>> +??? bi->dma = dma;
>> +??? bi->page = page;
>> +??? bi->page_offset = igc_rx_offset(rx_ring);
>> +??? bi->pagecnt_bias = 1;
>> +
>> +??? return true;
>> +}
>> +
>> +/**
>> + *? igc_alloc_rx_buffers - Replace used receive buffers; packet split
>> + *? @adapter: address of board private structure
>> + **/
>> +void igc_alloc_rx_buffers(struct igc_ring *rx_ring, u16 cleaned_count)
>> +{
>> +??? union e1000_adv_rx_desc *rx_desc;
>> +??? struct igc_rx_buffer *bi;
>> +??? u16 i = rx_ring->next_to_use;
>> +??? u16 bufsz;
>
> reverse xmas tree
>
fix will be applied in v4.
>> +
>> +??? /* nothing to do */
>> +??? if (!cleaned_count)
>> +??????? return;
>> +
>> +??? rx_desc = IGC_RX_DESC(rx_ring, i);
>> +??? bi = &rx_ring->rx_buffer_info[i];
>> +??? i -= rx_ring->count;
>> +
>> +??? bufsz = igc_rx_bufsz(rx_ring);
>> +
>> +??? do {
>> +??????? if (!igc_alloc_mapped_page(rx_ring, bi))
>> +??????????? break;
>> +
>> +??????? /* sync the buffer for use by the device */
>> +??????? dma_sync_single_range_for_device(rx_ring->dev, bi->dma,
>> +???????????????????????? bi->page_offset, bufsz,
>> +???????????????????????? DMA_FROM_DEVICE);
>> +
>> +??????? /* Refresh the desc even if buffer_addrs didn't change
>> +???????? * because each write-back erases this info.
>> +???????? */
>> +??????? rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset);
>> +
>> +??????? rx_desc++;
>> +??????? bi++;
>> +??????? i++;
>> +??????? if (unlikely(!i)) {
>> +??????????? rx_desc = IGC_RX_DESC(rx_ring, 0);
>> +??????????? bi = rx_ring->rx_buffer_info;
>> +??????????? i -= rx_ring->count;
>> +??????? }
>> +
>> +??????? /* clear the length for the next_to_use descriptor */
>> +??????? rx_desc->wb.upper.length = 0;
>> +
>> +??????? cleaned_count--;
>> +??? } while (cleaned_count);
>> +
>> +??? i += rx_ring->count;
>> +
>> +??? if (rx_ring->next_to_use != i) {
>> +??????? /* record the next descriptor to use */
>> +??????? rx_ring->next_to_use = i;
>> +
>> +??????? /* update next to alloc since we have filled the ring */
>> +??????? rx_ring->next_to_alloc = i;
>> +
>> +??????? /* Force memory writes to complete before letting h/w
>> +???????? * know there are new descriptors to fetch.? (Only
>> +???????? * applicable for weak-ordered memory model archs,
>> +???????? * such as IA-64).
>> +???????? */
>> +??????? wmb();
>> +??????? writel(i, rx_ring->tail);
>> +??? }
>> +}
>> +
>> ? /**
>> ?? *? igc_ioctl - I/O control method
>> ?? *? @netdev: network interface device structure
>> @@ -196,6 +841,12 @@ int igc_up(struct igc_adapter *adapter)
>> ????? rd32(E1000_ICR);
>> ????? igc_irq_enable(adapter);
>> +??? netif_tx_start_all_queues(adapter->netdev);
>> +
>> +??? /* start the watchdog. */
>> +??? hw->mac.get_link_status = 1;
>> +??? schedule_work(&adapter->watchdog_task);
>
> But you don't actually add the watchdog setup until patch 11?
>
>> +
>> ????? return 0;
>> ? }
>> @@ -295,7 +946,30 @@ static struct net_device_stats
>> *igc_get_stats(struct net_device *netdev)
>> ?? **/
>> ? static void igc_configure(struct igc_adapter *adapter)
>> ? {
>> +??? struct net_device *netdev = adapter->netdev;
>> +??? int i = 0;
>> +
>> ????? igc_get_hw_control(adapter);
>> +??? igc_set_rx_mode(netdev);
>> +
>> +??? igc_setup_tctl(adapter);
>> +??? igc_setup_mrqc(adapter);
>> +??? igc_setup_rctl(adapter);
>> +
>> +??? igc_configure_tx(adapter);
>> +??? igc_configure_rx(adapter);
>> +
>> +??? igc_rx_fifo_flush_base(&adapter->hw);
>> +
>> +??? /* call igc_desc_unused which always leaves
>> +???? * at least 1 descriptor unused to make sure
>> +???? * next_to_use != next_to_clean
>> +???? */
>> +??? for (i = 0; i < adapter->num_rx_queues; i++) {
>> +??????? struct igc_ring *ring = adapter->rx_ring[i];
>> +
>> +??????? igc_alloc_rx_buffers(ring, igc_desc_unused(ring));
>> +??? }
>> ? }
>> ? /**
>> @@ -343,6 +1017,19 @@ static void igc_set_default_mac_filter(struct
>> igc_adapter *adapter)
>> ????? igc_rar_set_index(adapter, 0);
>> ? }
>> +/**
>> + *? igc_set_rx_mode - Secondary Unicast, Multicast and Promiscuous
>> mode set
>> + *? @netdev: network interface device structure
>> + *
>> + *? The set_rx_mode entry point is called whenever the unicast or
>> multicast
>> + *? address lists or the network interface flags are updated.? This
>> routine is
>> + *? responsible for configuring the hardware for proper unicast,
>> multicast,
>> + *? promiscuous mode, and all-multi behavior.
>> + **/
>> +static void igc_set_rx_mode(struct net_device *netdev)
>> +{
>> +}
>> +
>> ? static irqreturn_t igc_msix_other(int irq, void *data)
>> ? {
>> ????? struct igc_adapter *adapter = data;
>> @@ -781,6 +1468,83 @@ static void igc_update_itr(struct igc_q_vector
>> *q_vector,
>> ????? ring_container->itr = itrval;
>> ? }
>> +/**
>> + *? igc_intr_msi - Interrupt Handler
>> + *? @irq: interrupt number
>> + *? @data: pointer to a network interface device structure
>> + **/
>> +static irqreturn_t igc_intr_msi(int irq, void *data)
>> +{
>> +??? struct igc_adapter *adapter = data;
>> +??? struct igc_q_vector *q_vector = adapter->q_vector[0];
>> +??? struct e1000_hw *hw = &adapter->hw;
>> +??? /* read ICR disables interrupts using IAM */
>> +??? u32 icr = rd32(E1000_ICR);
>> +
>> +??? igc_write_itr(q_vector);
>> +
>> +??? if (icr & E1000_ICR_DRSTA)
>> +??????? schedule_work(&adapter->reset_task);
>
> This task probably should have been set up in a previous patch, too.
>
>> +
>> +??? if (icr & E1000_ICR_DOUTSYNC) {
>> +??????? /* HW is reporting DMA is out of sync */
>> +??????? adapter->stats.doosync++;
>> +??? }
>> +
>> +??? if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
>> +??????? hw->mac.get_link_status = 1;
>> +??????? if (!test_bit(__IGC_DOWN, &adapter->state))
>> +??????????? mod_timer(&adapter->watchdog_timer, jiffies + 1);
>
> And this too.
>
>> +??? }
>> +
>> +???? napi_schedule(&q_vector->napi);
>
> Extra space indented?
>
fix will be applied in v4.
>> +
>> +??? return IRQ_HANDLED;
>> +}
>> +
>> +/**
>> + *? igc_intr - Legacy Interrupt Handler
>> + *? @irq: interrupt number
>> + *? @data: pointer to a network interface device structure
>> + **/
>> +static irqreturn_t igc_intr(int irq, void *data)
>> +{
>> +??? struct igc_adapter *adapter = data;
>> +??? struct igc_q_vector *q_vector = adapter->q_vector[0];
>> +??? struct e1000_hw *hw = &adapter->hw;
>> +??? /* Interrupt Auto-Mask...upon reading ICR, interrupts are
>> masked.? No
>> +???? * need for the IMC write
>> +???? */
>> +??? u32 icr = rd32(E1000_ICR);
>> +
>> +??? /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
>> +???? * not set, then the adapter didn't send an interrupt
>> +???? */
>> +??? if (!(icr & E1000_ICR_INT_ASSERTED))
>> +??????? return IRQ_NONE;
>> +
>> +??? igc_write_itr(q_vector);
>> +
>> +??? if (icr & E1000_ICR_DRSTA)
>> +??????? schedule_work(&adapter->reset_task);
>> +
>> +??? if (icr & E1000_ICR_DOUTSYNC) {
>> +??????? /* HW is reporting DMA is out of sync */
>> +??????? adapter->stats.doosync++;
>> +??? }
>> +
>> +??? if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
>> +??????? hw->mac.get_link_status = 1;
>> +??????? /* guard against interrupt when we're going down */
>> +??????? if (!test_bit(__IGC_DOWN, &adapter->state))
>> +??????????? mod_timer(&adapter->watchdog_timer, jiffies + 1);
>> +??? }
>> +
>> +??? napi_schedule(&q_vector->napi);
>> +
>> +??? return IRQ_HANDLED;
>> +}
>> +
>> ? static void igc_ring_irq_enable(struct igc_q_vector *q_vector)
>> ? {
>> ????? struct igc_adapter *adapter = q_vector->adapter;
>> @@ -1148,6 +1912,29 @@ static int igc_alloc_q_vectors(struct
>> igc_adapter *adapter)
>> ? }
>> ? /**
>> + *? igc_cache_ring_register - Descriptor ring to register mapping
>> + *? @adapter: board private structure to initialize
>> + *
>> + *? Once we know the feature-set enabled for the device, we'll cache
>> + *? the register offset the descriptor ring is assigned to.
>> + **/
>> +static void igc_cache_ring_register(struct igc_adapter *adapter)
>> +{
>> +??? int i = 0, j = 0;
>> +
>> +??? switch (adapter->hw.mac.type) {
>> +??? case e1000_i225:
>> +??? /* Fall through */
>> +??? default:
>> +??????? for (; i < adapter->num_rx_queues; i++)
>> +??????????? adapter->rx_ring[i]->reg_idx = i;
>> +??????? for (; j < adapter->num_tx_queues; j++)
>> +??????????? adapter->tx_ring[j]->reg_idx = j;
>> +??????? break;
>> +??? }
>> +}
>> +
>> +/**
>> ?? *? igc_init_interrupt_scheme - initialize interrupts, allocate
>> queues/vectors
>> ?? *? @adapter: Pointer to adapter structure
>> ?? *
>> @@ -1166,7 +1953,7 @@ static int igc_init_interrupt_scheme(struct
>> igc_adapter *adapter, bool msix)
>> ????????? goto err_alloc_q_vectors;
>> ????? }
>> -??? /* TODO complete igc_cache_ring_register */
>> +??? igc_cache_ring_register(adapter);
>> ????? return 0;
>> @@ -1255,6 +2042,8 @@ static void igc_irq_enable(struct igc_adapter
>> *adapter)
>> ?? **/
>> ? static int igc_request_irq(struct igc_adapter *adapter)
>> ? {
>> +??? struct net_device *netdev = adapter->netdev;
>> +??? struct pci_dev *pdev = adapter->pdev;
>> ????? int err = 0;
>> ????? if (adapter->flags & IGC_FLAG_HAS_MSIX) {
>> @@ -1262,16 +2051,38 @@ static int igc_request_irq(struct igc_adapter
>> *adapter)
>> ????????? if (!err)
>> ????????????? goto request_done;
>> ????????? /* fall back to MSI */
>> -??????? /* TODO complete free tx/rx resources */
>> +??????? igc_free_all_tx_resources(adapter);
>> +??????? igc_free_all_rx_resources(adapter);
>> ????????? igc_clear_interrupt_scheme(adapter);
>> ????????? err = igc_init_interrupt_scheme(adapter, false);
>> ????????? if (err)
>> ????????????? goto request_done;
>> -??????? /* TODO complete setup tx/rx resources */
>> +??????? igc_setup_all_tx_resources(adapter);
>> +??????? igc_setup_all_rx_resources(adapter);
>> ????????? igc_configure(adapter);
>> ????? }
>> +??? igc_assign_vector(adapter->q_vector[0], 0);
>> +
>> +??? if (adapter->flags & IGC_FLAG_HAS_MSI) {
>> +??????? err = request_irq(pdev->irq, &igc_intr_msi, 0,
>> +????????????????? netdev->name, adapter);
>> +??????? if (!err)
>> +??????????? goto request_done;
>> +
>> +??????? /* fall back to legacy interrupts */
>> +??????? igc_reset_interrupt_capability(adapter);
>> +??????? adapter->flags &= ~IGC_FLAG_HAS_MSI;
>> +??? }
>> +
>> +??? err = request_irq(pdev->irq, &igc_intr, IRQF_SHARED,
>> +????????????? netdev->name, adapter);
>> +
>> +??? if (err)
>> +??????? dev_err(&pdev->dev, "Error %d getting interrupt\n",
>> +??????????? err);
>> +
>> ? request_done:
>> ????? return err;
>> ? }
>> @@ -1332,6 +2143,16 @@ static int __igc_open(struct net_device
>> *netdev, bool resuming)
>> ????? netif_carrier_off(netdev);
>> +??? /* allocate transmit descriptors */
>> +??? err = igc_setup_all_tx_resources(adapter);
>> +??? if (err)
>> +??????? goto err_setup_tx;
>> +
>> +??? /* allocate receive descriptors */
>> +??? err = igc_setup_all_rx_resources(adapter);
>> +??? if (err)
>> +??????? goto err_setup_rx;
>> +
>> ????? igc_power_up_link(adapter);
>> ????? igc_configure(adapter);
>> @@ -1357,6 +2178,8 @@ static int __igc_open(struct net_device *netdev,
>> bool resuming)
>> ????? rd32(E1000_ICR);
>> ????? igc_irq_enable(adapter);
>> +??? netif_tx_start_all_queues(netdev);
>> +
>> ????? /* start the watchdog. */
>> ????? hw->mac.get_link_status = 1;
>> ????? schedule_work(&adapter->watchdog_task);
>> @@ -1368,7 +2191,11 @@ static int __igc_open(struct net_device
>> *netdev, bool resuming)
>> ? err_req_irq:
>> ????? igc_release_hw_control(adapter);
>> ????? igc_power_down_link(adapter);
>> -??? /* TODO complete free_all_rx_resources */
>> +??? igc_free_all_rx_resources(adapter);
>> +err_setup_rx:
>> +??? igc_free_all_tx_resources(adapter);
>> +err_setup_tx:
>> +??? igc_reset(adapter);
>> ????? return err;
>> ? }
>> @@ -1401,6 +2228,9 @@ static int __igc_close(struct net_device
>> *netdev, bool suspending)
>> ????? igc_free_irq(adapter);
>> +??? igc_free_all_tx_resources(adapter);
>> +??? igc_free_all_rx_resources(adapter);
>> +
>> ????? return 0;
>> ? }
>> @@ -1415,6 +2245,7 @@ static const struct net_device_ops
>> igc_netdev_ops = {
>> ????? .ndo_open?????????????? = igc_open,
>> ????? .ndo_stop?????????????? = igc_close,
>> ????? .ndo_start_xmit???????? = igc_xmit_frame,
>> +??? .ndo_set_rx_mode??????? = igc_set_rx_mode,
>> ????? .ndo_set_mac_address??? = igc_set_mac,
>> ????? .ndo_change_mtu???????? = igc_change_mtu,
>> ????? .ndo_get_stats????????? = igc_get_stats,
>>
>
> _______________________________________________
> Intel-wired-lan mailing list
> Intel-wired-lan at osuosl.org
> https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
Thanks for your comments. I address part (10, ten) of them
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-07-03 13:17 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-24 8:45 [Intel-wired-lan] [PATCH v3 05/11] igc: Add support for Tx/Rx rings Sasha Neftin
2018-06-24 14:11 ` [Intel-wired-lan] [RFC PATCH] igc: igc_free_tx_resources() can be static kbuild test robot
2018-06-28 8:15 ` Neftin, Sasha
2018-06-28 21:21 ` Shannon Nelson
2018-06-29 8:32 ` Neftin, Sasha
2018-06-24 14:11 ` [Intel-wired-lan] [PATCH v3 05/11] igc: Add support for Tx/Rx rings kbuild test robot
2018-06-28 0:42 ` Shannon Nelson
2018-07-03 13:17 ` Neftin, Sasha
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.