Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88e829ae authored by Vadim Solomin's avatar Vadim Solomin Committed by Jinesh K. Jayakumar
Browse files

atlantic-forwarding driver v1.0.15



Signed-off-by: default avatarVadim Solomin <vadim.solomin@aquantia.com>
Signed-off-by: default avatarDmitry Bogdanov <dmitry.bogdanov@aquantia.com>
Signed-off-by: default avatarIgor Russkikh <igor.russkikh@aquantia.com>

commit 867cda83973229f68560723c9972905c589856c4
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Tue Dec 4 01:57:51 2018 +0300

    Version 1.0.15

commit 52c23fa41ef5f8f5667b454e8361a55322e3108a
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Tue Dec 4 00:38:45 2018 +0300

    Implement ethtool control for stripping Rx ethernet frame's padding

    Padding stripping only supported for frame formats with explicit
    length field

commit 6154d236021bfbe14e9c129456e5d5e585a2ba0b
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Tue Dec 4 01:48:47 2018 +0300

    Report ring's and buffer's physical addresses on ring request

commit 03002d61a96b2640684cfacefedc10e2d80afccd
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Fri Nov 23 02:56:02 2018 +0300

    Implement PHY temperature sensor

commit 02ed2019bebdf5d0347185d5022022c44c11dec8
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Fri Nov 23 01:42:47 2018 +0300

    Introduce a FW mutex, handle link interrupts in a workqueue

commit e8552ade0ab5d58cbc6c503fda92e3ed499b5615
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Mon Dec 3 23:39:42 2018 +0300

    Implement interrupt moderation for offload engine's rings

commit 49e7698a420eb3aa32e9aa3a15879f07e6cf71cf
Author: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
Date:   Mon Sep 10 16:28:24 2018 +0300

    Reset statistics via private flag

    HW counters are reported as a diff from the value at the last reset.

commit 7f4f3461aa71fbe79455f2727274320ac5aa46c3
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Fri Nov 16 22:51:41 2018 +0300

    Version 1.0.14

commit 67002520027178ef697b0ae322fc2b502d9cdd38
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Tue Nov 13 22:48:08 2018 +0300

    Implement WoL support

commit f67632663eeae770f7205ec1377f6b2010479b5c
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Fri Nov 16 22:18:46 2018 +0300

    Implement Linux PM support

commit de8bd72e1d32818286d9915c4f4d0a67af6545d6
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Wed Nov 7 21:46:45 2018 +0300

    Change the driver name to reflect the new module name

commit f4c8a7f4bbffa19abbec706b9d0beb6450a87816
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Wed Nov 7 21:36:46 2018 +0300

    Fix forwarding engine interface

    * Zero-init struct atl_nic on alloc (shouldn't be necessary)
    * Fix event index initialization in atl_fwd_request_event()

commit 8ee73a3cd4fa0d0a8384561dbf941fab074bf08a
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Mon Oct 29 14:40:54 2018 +0300

    Version 1.0.13

commit 1d5da44aa59bc94073e5ad8a33738953eb98ac6a
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Mon Oct 29 13:33:39 2018 +0300

    Integrate Linux VLAN filter hw acceleration with ethtool filters

commit dd353ed40f38958de96f0b9f8c2b95dbcc4a8b0e
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Thu Oct 18 21:21:07 2018 +0300

    Version 1.0.12

commit 7155f12f35cfb5fea62ce08c851a8a20a141f75d
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Thu Oct 18 20:02:50 2018 +0300

    Expose PHY LPI state via ethtool private flags

commit feacf926415da1af62265c8cf33afe1aae48c931
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Fri Oct 12 23:57:04 2018 +0300

    Version 1.0.11

commit 64c211cc173e23609f55f210d1220b20bd2c6e57
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Thu Oct 11 00:34:18 2018 +0300

    Add ethtool private flags tracking LPI state

commit 8e914fc4e863af0b22623be1e7efe86fe3d91927
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Tue Oct 9 00:24:07 2018 +0300

    Move HW init to PCI probe time

commit b7d1836255a54834bd700a04c9b11989b75fd760
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Mon Oct 8 19:51:50 2018 +0300

    Add more Felicity PCI IDsc

    Fixes ATLDRV-531

commit 67e24851c128c9867a9cbe1c18d0535e5311212c
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Wed Oct 3 23:13:05 2018 +0300

    Fix build errors

    * Misc build errors
    * Drop compat stub for eth_platform_get_mac_address() as apparently it
      had been cherry-picked into Ubuntu's 4.4 kernel

commit b355acb274010606e01714d0b12d15ea89650f2f
Author: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
Date:   Tue Sep 18 17:08:29 2018 +0300

    Add Host and Lost counters to statistics

    Add Host Packet Counter and Lost Packet Counter from RX Filter block to
    the statistics in 'ethtool -S'

commit 6ae04f2d2bd3ceb8f29af550b6c03dd34019198c
Author: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
Date:   Tue Sep 18 12:47:05 2018 +0300

    Add some HW counters from RMON MIB

    Add the following counters from RMON MIB: etherStatsDropEvents, etherStatsPkts,
    etherStatsOctets,etherStatsBroadcastPkts, etherStatsMulticastPkts,
    etherStatsCRCAlignErrors

commit 04ed8bcc26ec2762231c2c564109b5493771bd29
Author: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
Date:   Fri Sep 14 12:46:38 2018 +0300

    Fix advertizing EEE linkk modes and show LPI timer (AQ016)

    Advertize all supported EEE link modes if none is requested upon turning EEE on.
    Show Tx LPI Timer in ethtool output.

commit 1b0ade8a1d53aeaabc1395e403a1370afbc6066a
Author: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
Date:   Wed Sep 19 15:27:14 2018 +0300

    Turn on/off Rx XOFF flow control when needed (AQ021)

    Firmware does not set rx0_xoff_en (0x5714.1F register) and RPB continues
    sending Pause frames even when flow control is turned off.
    This fix turns on/off Rx XOFF flow control according to negotiated flow
    control settings.

commit 6d51e89a7e2c980c76da4b1f38e5a6a97550fa30
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Wed Sep 26 23:41:41 2018 +0300

    Minor IPA interface fixes

    * Remove a check obsoleted by folding the buffer page array into
      struct atl_fwd_bufs.

    * Move atl_msix_bar() from atl_compat.c to atl_fwd.c

commit 788f4f99fc390e6abbc6c7161bf4ba70ed86ec61
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Wed Sep 26 00:42:07 2018 +0300

    Version 1.0.10

commit ac838ac2b776e8a2a9eb4b15100f3674dc5a0e2c
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Wed Sep 26 00:39:51 2018 +0300

    Initial offload engine iface implementation.

commit 0f1295e2f9c8d42913a6274473ef06181bd0b9d4
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Tue Sep 11 21:59:56 2018 +0300

    Initial offload engine iface API

commit bb8e9568c67f90e3d758b98ffdd613a50582c9c1
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Tue Sep 11 22:04:21 2018 +0300

    Fix tx-lpi handling in ethtool --set-eee

    Makes tx-lpi enable follow the eee enable setting.

commit 0f72ac36bfe8441f052ced4a345648e3d0477f63
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Fri Sep 7 19:21:40 2018 +0300

    Make atl_module_init() / _exit() available for future use

commit 0c64854442d0684901df2a818d2e1e1a019c0024
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Thu Sep 6 23:27:45 2018 +0300

    Version 1.0.9

commit 1772f185d796510a97d976d8e1d5286eae1ac503
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Thu Sep 6 23:24:21 2018 +0300

    Add AQC100 / -111 / -112 IDs

commit a2fa151fbc795e3f008c3cd6fb3a0d8038b05b4e
Author: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
Date:   Wed Sep 5 19:44:27 2018 +0300

    Fix adding vlan with vlan id > 64 (AQ013)

    Wrong length (in longs instead of in bits) of the vlan bit array is
    used for looking the set bit there.

commit ebd6a3f876e7de40962c53dbccd2d644dd2dbcf8
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Thu Sep 6 20:17:32 2018 +0300

    Fix ethtool IPv4 filter reporting (AQ022)

commit 3f6d20b3dd662d094dcd8e780fc73b670a09691a
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Thu Aug 30 20:05:46 2018 +0300

    Implement ethtool interface for ethertype filters.

commit 469740b8cb8a2531385b4f96be86880a3d610e6d
Author: Vadim Solomin <vadim.solomin@aquantia.com>
Date:   Thu Sep 6 21:43:57 2018 +0300

    Restore backward compat for Linux 4.4

commit dd0ef0a364d3522f7b18de98aedee77058fe36f2
Author: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
Date:   Mon Aug 13 17:59:40 2018 +0300

    net: aquantia: atlantic-forwarding driver for Qualcomm

    Signed-off-by: default avatarDmitry Bogdanov <dmitry.bogdanov@aquantia.com>
    Signed-off-by: default avatarIgor Russkikh <igor.russkikh@aquantia.com>
    Co-authored-by: default avatarVadim Solomin <vadim.solomin@aquantia.com>

CRs-Fixed: 2309519
Change-Id: I1b302f54c00e9b3bf936eddec5e816d93cfe9772
Git-commit: abd3119fadbecba1de363c75aaaf958ec99dd2b9
Git-repo: https://github.com/aquantia/linux-4.14-atlantic-forwarding


Signed-off-by: default avatarJinesh K. Jayakumar <jineshk@codeaurora.org>
parent a487c3ab
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -21,4 +21,9 @@ config AQTION
	---help---
	  This enables the support for the aQuantia AQtion(tm) Ethernet card.

config AQFWD
	tristate "aQuantia Forwarding driver"
	depends on PCI && (X86_64 || ARM64)
	---help---
	  This enables the support for forwarding driver for the aQuantia AQtion(tm) Ethernet card.
endif # NET_VENDOR_AQUANTIA
+1 −0
Original line number Diff line number Diff line
@@ -3,3 +3,4 @@
#

obj-$(CONFIG_AQTION) += atlantic/
obj-$(CONFIG_AQFWD)  += atlantic-fwd/
+42 −0
Original line number Diff line number Diff line
################################################################################
#
# aQuantia Ethernet Controller AQtion Linux Driver
# Copyright(c) 2014-2017 aQuantia Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# The full GNU General Public License is included in this distribution in
# the file called "COPYING".
#
# Contact Information: <rdc-drv@aquantia.com>
# aQuantia Corporation, 105 E. Tasman Dr. San Jose, CA 95134, USA
#
################################################################################

#
# Makefile for the AQtion(tm) Ethernet driver
#

obj-$(CONFIG_AQFWD) += atlantic-fwd.o

atlantic-fwd-objs := atl_fw.o \
		     atl_hw.o \
		     atl_main.o \
		     atl_ring.o \
		     atl_ethtool.o \
		     atl_trace.o \
		     atl_fwd.o \
		     atl_compat.o \
		     atl_hwmon.o

CFLAGS_atl_trace.o := -I$(src)
+371 −0
Original line number Diff line number Diff line
/*
 * aQuantia Corporation Network Driver
 * Copyright (C) 2017 aQuantia Corporation. All rights reserved
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 */

#ifndef _ATL_COMMON_H_
#define _ATL_COMMON_H_

#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/list.h>
#include <linux/dma-mapping.h>
#include <linux/netdevice.h>
#include <linux/moduleparam.h>

#define ATL_VERSION "1.0.15"

struct atl_nic;

#include "atl_compat.h"
#include "atl_hw.h"

#define ATL_MAX_QUEUES 8

#include "atl_fwd.h"

struct atl_rx_ring_stats {
	uint64_t packets;
	uint64_t bytes;
	uint64_t linear_dropped;
	uint64_t alloc_skb_failed;
	uint64_t reused_head_page;
	uint64_t reused_data_page;
	uint64_t alloc_head_page;
	uint64_t alloc_data_page;
	uint64_t alloc_head_page_failed;
	uint64_t alloc_data_page_failed;
	uint64_t non_eop_descs;
	uint64_t mac_err;
	uint64_t csum_err;
	uint64_t multicast;
};

struct atl_tx_ring_stats {
	uint64_t packets;
	uint64_t bytes;
	uint64_t tx_busy;
	uint64_t tx_restart;
	uint64_t dma_map_failed;
};

struct atl_ring_stats {
	union {
		struct atl_rx_ring_stats rx;
		struct atl_tx_ring_stats tx;
	};
};

struct atl_ether_stats {
	uint64_t rx_pause;
	uint64_t tx_pause;
	uint64_t rx_ether_drops;
	uint64_t rx_ether_octets;
	uint64_t rx_ether_pkts;
	uint64_t rx_ether_broacasts;
	uint64_t rx_ether_multicasts;
	uint64_t rx_ether_crc_align_errs;
	uint64_t rx_filter_host;
	uint64_t rx_filter_lost;
};

struct atl_global_stats {
	struct atl_rx_ring_stats rx;
	struct atl_tx_ring_stats tx;

	/* MSM counters can't be reset without full HW reset, so
	 * store them in relative form:
	 * eth[i] == HW_counter - eth_base[i] */
	struct atl_ether_stats eth;
	struct atl_ether_stats eth_base;
};

enum {
	ATL_RXF_VLAN_BASE = 0,
	ATL_RXF_VLAN_MAX = ATL_VLAN_FLT_NUM,
	ATL_RXF_ETYPE_BASE = ATL_RXF_VLAN_BASE + ATL_RXF_VLAN_MAX,
	ATL_RXF_ETYPE_MAX = ATL_ETYPE_FLT_NUM,
	ATL_RXF_NTUPLE_BASE = ATL_RXF_ETYPE_BASE + ATL_RXF_ETYPE_MAX,
	ATL_RXF_NTUPLE_MAX = ATL_NTUPLE_FLT_NUM,
};

enum atl_rxf_common_cmd {
	ATL_RXF_EN = BIT(31),
	ATL_RXF_RXQ_MSK = BIT(5) - 1,
	ATL_RXF_ACT_SHIFT = 16,
	ATL_RXF_ACT_MASK = BIT(3) - 1,
	ATL_RXF_ACT_TOHOST = BIT(0) << ATL_RXF_ACT_SHIFT,
};

enum atl_ntuple_cmd {
	ATL_NTC_EN = ATL_RXF_EN, /* Filter enabled */
	ATL_NTC_V6 = BIT(30),	/* IPv6 mode -- only valid in filters
				 * 0 and 4 */
	ATL_NTC_SA = BIT(29),	/* Match source address */
	ATL_NTC_DA = BIT(28),	/* Match destination address */
	ATL_NTC_SP = BIT(27),	/* Match source port */
	ATL_NTC_DP = BIT(26),	/* Match destination port */
	ATL_NTC_PROTO = BIT(25), /* Match L4 proto */
	ATL_NTC_ARP = BIT(24),
	ATL_NTC_RXQ = BIT(23),	/* Assign Rx queue */
	ATL_NTC_ACT_SHIFT = ATL_RXF_ACT_SHIFT,
	ATL_NTC_RXQ_SHIFT = 8,
	ATL_NTC_RXQ_MASK = ATL_RXF_RXQ_MSK << ATL_NTC_RXQ_SHIFT,
	ATL_NTC_L4_MASK = BIT(3) - 1,
	ATL_NTC_L4_TCP = 0,
	ATL_NTC_L4_UDP = 1,
	ATL_NTC_L4_SCTP = 2,
	ATL_NTC_L4_ICMP = 3,
};

struct atl_rxf_ntuple {
	union {
		struct {
			__be32 dst_ip4[ATL_RXF_NTUPLE_MAX];
			__be32 src_ip4[ATL_RXF_NTUPLE_MAX];
		};
		struct {
			__be32 dst_ip6[ATL_RXF_NTUPLE_MAX / 4][4];
			__be32 src_ip6[ATL_RXF_NTUPLE_MAX / 4][4];
		};
	};
	__be16 dst_port[ATL_RXF_NTUPLE_MAX];
	__be16 src_port[ATL_RXF_NTUPLE_MAX];
	uint32_t cmd[ATL_RXF_NTUPLE_MAX];
	int count;
};

enum atl_vlan_cmd {
	ATL_VLAN_EN = ATL_RXF_EN,
	ATL_VLAN_RXQ = BIT(28),
	ATL_VLAN_RXQ_SHIFT = 20,
	ATL_VLAN_RXQ_MASK = ATL_RXF_RXQ_MSK << ATL_VLAN_RXQ_SHIFT,
	ATL_VLAN_ACT_SHIFT = ATL_RXF_ACT_SHIFT,
	ATL_VLAN_VID_MASK = BIT(12) - 1,
};

#define ATL_VID_MAP_LEN BITS_TO_LONGS(BIT(12))

struct atl_rxf_vlan {
	uint32_t cmd[ATL_RXF_VLAN_MAX];
	int count;
	unsigned long map[ATL_VID_MAP_LEN];
	int vlans_active;
	int promisc_count;
};

enum atl_etype_cmd {
	ATL_ETYPE_EN = ATL_RXF_EN,
	ATL_ETYPE_RXQ = BIT(29),
	ATL_ETYPE_RXQ_SHIFT = 20,
	ATL_ETYPE_RXQ_MASK = ATL_RXF_RXQ_MSK << ATL_ETYPE_RXQ_SHIFT,
	ATL_ETYPE_ACT_SHIFT = ATL_RXF_ACT_SHIFT,
	ATL_ETYPE_VAL_MASK = BIT(16) - 1,
};

struct atl_rxf_etype {
	uint32_t cmd[ATL_RXF_ETYPE_MAX];
	int count;
};

struct atl_queue_vec;

#define ATL_NUM_FWD_RINGS ATL_MAX_QUEUES
#define ATL_FWD_RING_BASE ATL_MAX_QUEUES /* Use TC 1 for offload
					  * engine rings */
#define ATL_NUM_MSI_VECS 32
#define ATL_NUM_NON_RING_IRQS 1

#define ATL_RXF_RING_ANY 32

#define ATL_FWD_MSI_BASE (ATL_MAX_QUEUES + ATL_NUM_NON_RING_IRQS)

enum atl_fwd_dir {
	ATL_FWDIR_RX = 0,
	ATL_FWDIR_TX = 1,
	ATL_FWDIR_NUM,
};

struct atl_fwd {
	unsigned long ring_map[ATL_FWDIR_NUM];
	struct atl_fwd_ring *rings[ATL_FWDIR_NUM][ATL_NUM_FWD_RINGS];
	unsigned long msi_map;
};

struct atl_nic {
	struct net_device *ndev;

	struct atl_queue_vec *qvecs;
	int nvecs;
	struct atl_hw hw;
	unsigned flags;
	unsigned long state;
	uint32_t priv_flags;
	struct timer_list link_timer;
	int max_mtu;
	int requested_nvecs;
	int requested_rx_size;
	int requested_tx_size;
	int rx_intr_delay;
	int tx_intr_delay;
	struct atl_global_stats stats;
	spinlock_t stats_lock;
	struct work_struct work;

	struct atl_fwd fwd;

	struct atl_rxf_ntuple rxf_ntuple;
	struct atl_rxf_vlan rxf_vlan;
	struct atl_rxf_etype rxf_etype;
};

/* Flags only modified with RTNL lock held */
enum atl_nic_flags {
	ATL_FL_MULTIPLE_VECTORS = BIT(0),
	ATL_FL_WOL = BIT(1),
};

enum atl_nic_state {
	ATL_ST_UP,
	ATL_ST_CONFIGURED,
	ATL_ST_ENABLED,
	ATL_ST_WORK_SCHED,
};

#define ATL_PF(_name) ATL_PF_ ## _name
#define ATL_PF_BIT(_name) ATL_PF_ ## _name ## _BIT
#define ATL_DEF_PF_BIT(_name) ATL_PF_BIT(_name) = BIT(ATL_PF(_name))

enum atl_priv_flags {
	ATL_PF_LPB_SYS_PB,
	ATL_PF_LPB_SYS_DMA,
	/* ATL_PF_LPB_NET_DMA, */
	ATL_PF_LPI_RX_MAC,
	ATL_PF_LPI_TX_MAC,
	ATL_PF_LPI_RX_PHY,
	ATL_PF_LPI_TX_PHY,
	ATL_PF_STATS_RESET,
	ATL_PF_STRIP_PAD,
};

enum atl_priv_flag_bits {
	ATL_DEF_PF_BIT(LPB_SYS_PB),
	ATL_DEF_PF_BIT(LPB_SYS_DMA),
	/* ATL_DEF_PF_BIT(LPB_NET_DMA), */

	ATL_PF_LPB_MASK = ATL_PF_BIT(LPB_SYS_DMA) | ATL_PF_BIT(LPB_SYS_PB)
		/* | ATL_PF_BIT(LPB_NET_DMA) */,

	ATL_DEF_PF_BIT(LPI_RX_MAC),
	ATL_DEF_PF_BIT(LPI_TX_MAC),
	ATL_DEF_PF_BIT(LPI_RX_PHY),
	ATL_DEF_PF_BIT(LPI_TX_PHY),
	ATL_PF_LPI_MASK = ATL_PF_BIT(LPI_RX_MAC) | ATL_PF_BIT(LPI_TX_MAC) |
		ATL_PF_BIT(LPI_RX_PHY) | ATL_PF_BIT(LPI_TX_PHY),

	ATL_DEF_PF_BIT(STATS_RESET),

	ATL_DEF_PF_BIT(STRIP_PAD),

	ATL_PF_RW_MASK = ATL_PF_LPB_MASK | ATL_PF_BIT(STATS_RESET) |
		ATL_PF_BIT(STRIP_PAD),
	ATL_PF_RO_MASK = ATL_PF_LPI_MASK,
};

#define ATL_MAX_MTU (16352 - ETH_FCS_LEN - ETH_HLEN)

#define ATL_MAX_RING_SIZE (8192 - 8)
#define ATL_RING_SIZE 4096

extern const char atl_driver_name[];

extern const struct ethtool_ops atl_ethtool_ops;

extern int atl_max_queues;
extern unsigned atl_rx_linear;
extern unsigned atl_min_intr_delay;

/* Logging conviniency macros.
 *
 * atl_dev_xxx are for low-level contexts and implicitly reference
 * struct atl_hw *hw;
 *
 * atl_nic_xxx are for high-level contexts and implicitly reference
 * struct atl_nic *nic; */
#define atl_dev_dbg(fmt, args...)			\
	dev_dbg(&hw->pdev->dev, fmt, ## args)
#define atl_dev_info(fmt, args...)			\
	dev_info(&hw->pdev->dev, fmt, ## args)
#define atl_dev_warn(fmt, args...)			\
	dev_warn(&hw->pdev->dev, fmt, ## args)
#define atl_dev_err(fmt, args...)			\
	dev_err(&hw->pdev->dev, fmt, ## args)

#define atl_nic_dbg(fmt, args...)		\
	dev_dbg(&nic->hw.pdev->dev, fmt, ## args)
#define atl_nic_info(fmt, args...)		\
	dev_info(&nic->hw.pdev->dev, fmt, ## args)
#define atl_nic_warn(fmt, args...)		\
	dev_warn(&nic->hw.pdev->dev, fmt, ## args)
#define atl_nic_err(fmt, args...)		\
	dev_err(&nic->hw.pdev->dev, fmt, ## args)

#define atl_module_param(_name, _type, _mode)			\
	module_param_named(_name, atl_ ## _name, _type, _mode)

netdev_tx_t atl_start_xmit(struct sk_buff *skb, struct net_device *ndev);
int atl_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid);
int atl_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vid);
void atl_set_rx_mode(struct net_device *ndev);
int atl_set_features(struct net_device *ndev, netdev_features_t features);
void atl_get_stats64(struct net_device *ndev,
	struct rtnl_link_stats64 *stats);
int atl_setup_datapath(struct atl_nic *nic);
void atl_clear_datapath(struct atl_nic *nic);
int atl_start_rings(struct atl_nic *nic);
void atl_stop_rings(struct atl_nic *nic);
int atl_alloc_rings(struct atl_nic *nic);
void atl_free_rings(struct atl_nic *nic);
irqreturn_t atl_ring_irq(int irq, void *priv);
void atl_start_hw_global(struct atl_nic *nic);
int atl_intr_init(struct atl_nic *nic);
void atl_intr_release(struct atl_nic *nic);
int atl_hw_reset(struct atl_hw *hw);
int atl_fw_init(struct atl_hw *hw);
int atl_reconfigure(struct atl_nic *nic);
void atl_reset_stats(struct atl_nic *nic);
void atl_update_global_stats(struct atl_nic *nic);
void atl_set_loopback(struct atl_nic *nic, int idx, bool on);
void atl_set_intr_mod(struct atl_nic *nic);
void atl_update_ntuple_flt(struct atl_nic *nic, int idx);
int atl_hwsem_get(struct atl_hw *hw, int idx);
void atl_hwsem_put(struct atl_hw *hw, int idx);
int __atl_msm_read(struct atl_hw *hw, uint32_t addr, uint32_t *val);
int atl_msm_read(struct atl_hw *hw, uint32_t addr, uint32_t *val);
int __atl_msm_write(struct atl_hw *hw, uint32_t addr, uint32_t val);
int atl_msm_write(struct atl_hw *hw, uint32_t addr, uint32_t val);
int atl_update_eth_stats(struct atl_nic *nic);
void atl_adjust_eth_stats(struct atl_ether_stats *stats,
	struct atl_ether_stats *base, bool add);
void atl_fwd_release_rings(struct atl_nic *nic);
int atl_get_lpi_timer(struct atl_nic *nic, uint32_t *lpi_delay);
int atl_mdio_hwsem_get(struct atl_hw *hw);
void atl_mdio_hwsem_put(struct atl_hw *hw);
int __atl_mdio_read(struct atl_hw *hw, uint8_t prtad, uint8_t mmd,
	uint16_t addr, uint16_t *val);
int atl_mdio_read(struct atl_hw *hw, uint8_t prtad, uint8_t mmd,
	uint16_t addr, uint16_t *val);
int __atl_mdio_write(struct atl_hw *hw, uint8_t prtad, uint8_t mmd,
	uint16_t addr, uint16_t val);
int atl_mdio_write(struct atl_hw *hw, uint8_t prtad, uint8_t mmd,
	uint16_t addr, uint16_t val);
void atl_refresh_rxfs(struct atl_nic *nic);
void atl_schedule_work(struct atl_nic *nic);
int atl_hwmon_init(struct atl_nic *nic);

#endif
+157 −0
Original line number Diff line number Diff line
/*
 * aQuantia Corporation Network Driver
 * Copyright (C) 2017 aQuantia Corporation. All rights reserved
 *
 * Portions Copyright (C) various contributors (see specific commit references)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 */

#include "atl_common.h"
#include "atl_ring.h"
#include <linux/msi.h>
#include <linux/cpu.h>
#include <linux/interrupt.h>

#ifdef ATL_COMPAT_PCI_IRQ_VECTOR
/* From commit aff171641d181ea573380efc3f559c9de4741fc5 */
int atl_compat_pci_irq_vector(struct pci_dev *dev, unsigned int nr)
{
	if (dev->msix_enabled) {
		struct msi_desc *entry;
		int i = 0;

		for_each_pci_msi_entry(entry, dev) {
			if (i == nr)
				return entry->irq;
			i++;
		}
		WARN_ON_ONCE(1);
		return -EINVAL;
	}

	if (dev->msi_enabled) {
		struct msi_desc *entry = first_pci_msi_entry(dev);

		if (WARN_ON_ONCE(nr >= entry->nvec_used))
			return -EINVAL;
	} else {
		if (WARN_ON_ONCE(nr > 0))
			return -EINVAL;
	}

	return dev->irq + nr;
}

#endif

#ifdef ATL_COMPAT_PCI_ALLOC_IRQ_VECTORS_AFFINITY

void atl_compat_set_affinity(int vector, struct atl_queue_vec *qvec)
{
	cpumask_t *cpumask = qvec ? &qvec->affinity_hint : NULL;

	irq_set_affinity_hint(vector, cpumask);
}

void atl_compat_calc_affinities(struct atl_nic *nic)
{
	struct pci_dev *pdev = nic->hw.pdev;
	int i;
	unsigned int cpu;

	get_online_cpus();
	cpu = cpumask_first(cpu_online_mask);

	for (i = 0; i < nic->nvecs; i++) {
		cpumask_t *cpumask = &nic->qvecs[i].affinity_hint;
		int vector;

		/* If some cpus went offline since allocating
		 * vectors, leave the remaining vectors' affininty
		 * unset.
		 */
		if (cpu >= nr_cpumask_bits)
			break;

		cpumask_clear(cpumask);
		cpumask_set_cpu(cpu, cpumask);
		cpu = cpumask_next(cpu, cpu_online_mask);
		vector = pci_irq_vector(pdev, i + ATL_NUM_NON_RING_IRQS);
	}
	put_online_cpus();
}

/* from commit 6f9a22bc5775d231ab8fbe2c2f3c88e45e3e7c28 */
static int irq_calc_affinity_vectors(int minvec, int maxvec,
	const struct irq_affinity *affd)
{
	int resv = affd->pre_vectors + affd->post_vectors;
	int vecs = maxvec - resv;
	int cpus;

	if (resv > minvec)
		return 0;

	/* Stabilize the cpumasks */
	get_online_cpus();
	cpus = cpumask_weight(cpu_online_mask);
	put_online_cpus();

	return min(cpus, vecs) + resv;
}

/* based on commit 402723ad5c625ee052432698ae5e56b02d38d4ec */
int atl_compat_pci_alloc_irq_vectors_affinity(struct pci_dev *dev,
	unsigned int min_vecs, unsigned int max_vecs, unsigned int flags,
	const struct irq_affinity *affd)
{
	static const struct irq_affinity msi_default_affd;
	int vecs = -ENOSPC;

	if (flags & PCI_IRQ_AFFINITY) {
		if (!affd)
			affd = &msi_default_affd;
	} else {
		if (WARN_ON(affd))
			affd = NULL;
	}

	if (affd)
		max_vecs = irq_calc_affinity_vectors(min_vecs, max_vecs, affd);

	if (flags & PCI_IRQ_MSIX) {
		struct msix_entry *entries;
		int i;

		entries = kcalloc(max_vecs, sizeof(*entries), GFP_KERNEL);
		if (!entries)
			return -ENOMEM;

		for (i = 0; i < max_vecs; i++)
			entries[i].entry = i;

		vecs = pci_enable_msix_range(dev, entries, min_vecs, max_vecs);
		kfree(entries);
		if (vecs > 0)
			return vecs;
	}

	if (flags & PCI_IRQ_MSI) {
		vecs = pci_enable_msi_range(dev, min_vecs, max_vecs);
		if (vecs > 0)
			return vecs;
	}

	/* use legacy irq if allowed */
	if ((flags & PCI_IRQ_LEGACY) && min_vecs == 1) {
		pci_intx(dev, 1);
		return 1;
	}

	return vecs;
}

#endif
Loading