From patchwork Mon Nov 12 15:46:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Russkikh X-Patchwork-Id: 996514 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=aquantia.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=AQUANTIA1COM.onmicrosoft.com header.i=@AQUANTIA1COM.onmicrosoft.com header.b="sE0Pnold"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42tw8n6vYjz9s3C for ; Tue, 13 Nov 2018 02:46:17 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729924AbeKMBkD (ORCPT ); Mon, 12 Nov 2018 20:40:03 -0500 Received: from mail-eopbgr740079.outbound.protection.outlook.com ([40.107.74.79]:36962 "EHLO NAM01-BN3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728103AbeKMBkD (ORCPT ); Mon, 12 Nov 2018 20:40:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=AQUANTIA1COM.onmicrosoft.com; s=selector1-aquantia-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=9PQ8GRlGvZT4rMR11rbFbYn+Uw0NzA8z01JVvnOpaqs=; b=sE0PnoldTw7Y3A10iOIaTf7Qwo7BhT3obs/SjUdwgUU2i3GZMMJYdMTLaN1nAUkH5yct0TcNyhd1n+cq9o62xToDKLMSaqVJUrmbOG9khSjLKijxsvRa4h+gr9Hc5UW5fN54G94fzUnckk1yvjuX26MNhVqhHn8HAvM86I10aI0= Received: from BY1PR0701MB1660.namprd07.prod.outlook.com (10.162.110.22) by BY2SPR8PMB287.namprd07.prod.outlook.com (10.163.192.13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1294.31; Mon, 12 Nov 2018 15:46:09 +0000 Received: from BY1PR0701MB1660.namprd07.prod.outlook.com ([fe80::c031:16d9:9580:3d11]) by BY1PR0701MB1660.namprd07.prod.outlook.com ([fe80::c031:16d9:9580:3d11%6]) with mapi id 15.20.1294.045; Mon, 12 Nov 2018 15:46:09 +0000 From: Igor Russkikh To: "David S . Miller" CC: "netdev@vger.kernel.org" , Igor Russkikh , Dmitry Bogdanov Subject: [PATCH net-next v2 6/6] net: aquantia: add support of rx-vlan-filter offload Thread-Topic: [PATCH net-next v2 6/6] net: aquantia: add support of rx-vlan-filter offload Thread-Index: AQHUep7U60BF/H/PF0iwymPBc/FRTQ== Date: Mon, 12 Nov 2018 15:46:09 +0000 Message-ID: <6a59c5e65894f4a36472c2576ef7a7326aab2940.1542037157.git.igor.russkikh@aquantia.com> References: In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: AM6PR02CA0015.eurprd02.prod.outlook.com (2603:10a6:20b:6e::28) To BY1PR0701MB1660.namprd07.prod.outlook.com (2a01:111:e400:522a::22) authentication-results: spf=none (sender IP is ) smtp.mailfrom=Igor.Russkikh@aquantia.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [95.79.108.179] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; BY2SPR8PMB287; 6:p39+HZyuvev8irJql+m+Q9wJ97k5V0xSIxHguPUJpvyLIjbnTxysgYcES36U3NkRzkuYGh5JhXZHJCJlTEMwYc2hRAY9Ayjq1ekGxo+UOgQ4F5hWaJMsQX0vJJ3CWlz1i19pZMq5ABCvYPwSLaM4Cc8ggIp1roIKbmvcxaTJmuv2XDZM8HJ7Afwzvn63YwYJx35Dy2c1bM5f6icpFgXrnV9vU3WlyGoASE5UdkXVmz4mHnP6Rqrh3wH0vgBBSXjsVSKtu9alE7HgK9ZpIvuPZhiM3M7ZaLUWwjzRFDQ4lPszT5BhhmmLoGPa9+M9neS1FFrzK4DwIkz2SbCTKnOWlV6q6avJa8N9S362uWR2ZEl26O59+Pgf/LF4UT8d3kze/24W8k+09pyGIkc0oAdvtKU1Zy+uEll4eE4EdHygS5AR8bs7x19BQXzWF5xV9x+ea616GEvy7z7MCpOrfzy0dg==; 5:BGruBTqxX58n550dGs0Qm/bhzDNDGup/TCzSQsKJwCwi8+yftgrgqPNmN/LNXJjj3zxPbOcbZZ1pZRQLHAc9119+4kbZ5WV81b2UEkZg9LKNpdw4l1P6dT1FHBP7Xj+RexcCZkHvbk7pSoINVs7VKA484ZBcxiNRVO8lpn+F8/I=; 7:tbjkAMrCODeqhmUPGnN6e7JmvxGZU2icGpuI0QcWv/+ZCiMBBumieiM4j8SWj05ZF/hpusiOb1ojr1aquQZJEpHB4NvkP5wKpFwe12qju5DO8+kw06KirOVLu+HWc7D50Kzhy/R5lJZr4r1gq0H+lw== x-ms-office365-filtering-correlation-id: 0b235b5d-fd26-4a53-7785-08d648b5f715 x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390040)(7020095)(4652040)(8989299)(5600074)(711020)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060)(7193020); SRVR:BY2SPR8PMB287; x-ms-traffictypediagnostic: BY2SPR8PMB287: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:; x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(6040522)(2401047)(8121501046)(5005006)(3002001)(3231382)(944501410)(52105112)(93006095)(93001095)(10201501046)(148016)(149066)(150057)(6041310)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123564045)(20161123562045)(201708071742011)(7699051)(76991095); SRVR:BY2SPR8PMB287; BCL:0; PCL:0; RULEID:; SRVR:BY2SPR8PMB287; x-forefront-prvs: 0854128AF0 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(376002)(396003)(346002)(136003)(366004)(39840400004)(199004)(189003)(476003)(305945005)(26005)(8676002)(7736002)(66066001)(2616005)(81156014)(256004)(14444005)(54906003)(53936002)(6506007)(186003)(102836004)(6116002)(3846002)(386003)(71200400001)(71190400001)(316002)(81166006)(8936002)(44832011)(4744004)(72206003)(11346002)(486006)(97736004)(478600001)(446003)(36756003)(118296001)(2906002)(105586002)(4326008)(14454004)(86362001)(575784001)(6916009)(99286004)(68736007)(6486002)(2900100001)(52116002)(25786009)(6436002)(76176011)(5660300001)(107886003)(106356001)(6512007); DIR:OUT; SFP:1101; SCL:1; SRVR:BY2SPR8PMB287; H:BY1PR0701MB1660.namprd07.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: aquantia.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: qQGOuT2vkCUaklFRvuYL1kALrYGdMOp/JK0HMNJnYRreyVhL6ddbGW1Ti7hxJTtOreoltisnvBgyo1FhwHPx1yqllbQRPOTwUYKqqJ7w8alE1aP55V3bEhGY8LmXyNeNlQZj56qesB+rfranu9GtO3d2T7U0oyJcB7kGmovTgKjkyJmh3yT+dQGQ/M6hi6kCfHxtJ3ILuZYJHVO7EIPmHnzVAqChdacillPijewIoP3cPNuMiv28KSvhXGTTq3k+ozNV+TDpN/UiR7Ic9Lg1zeabP9m87T/x/QxBFJ8JwrpXINt3aa1RZBuuoewPCuqShIIkgWRYf9S1YW14acevlP9B6LK9sgvwiWnxt/m+l0s= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: aquantia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0b235b5d-fd26-4a53-7785-08d648b5f715 X-MS-Exchange-CrossTenant-originalarrivaltime: 12 Nov 2018 15:46:09.6237 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 83e2e134-991c-4ede-8ced-34d47e38e6b1 X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2SPR8PMB287 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Dmitry Bogdanov Since it uses the same NIC table as rx flow vlan filter therefore rx-flow vlan filter accepts only vlans that present on the interface in case of rx-vlan-filter is on. Signed-off-by: Dmitry Bogdanov Signed-off-by: Igor Russkikh --- .../net/ethernet/aquantia/atlantic/aq_filters.c | 138 +++++++++++++++++++++ .../net/ethernet/aquantia/atlantic/aq_filters.h | 2 + drivers/net/ethernet/aquantia/atlantic/aq_hw.h | 1 + drivers/net/ethernet/aquantia/atlantic/aq_main.c | 40 +++++- drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 2 - drivers/net/ethernet/aquantia/atlantic/aq_nic.h | 3 +- .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 29 ++--- 7 files changed, 197 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c index b987c6717af6..f6145e7473b1 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c @@ -157,6 +157,14 @@ aq_check_approve_fvlan(struct aq_nic_s *aq_nic, return -EINVAL; } + if ((aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) && + (!test_bit(be16_to_cpu(fsp->h_ext.vlan_tci), + aq_nic->active_vlans))) { + netdev_err(aq_nic->ndev, + "ethtool: unknown vlan-id specified"); + return -EINVAL; + } + if (fsp->ring_cookie > aq_nic->aq_nic_cfg.num_rss_queues) { netdev_err(aq_nic->ndev, "ethtool: queue number must be in range [0, %d]", @@ -331,26 +339,108 @@ static int aq_add_del_fether(struct aq_nic_s *aq_nic, return aq_hw_ops->hw_filter_l2_clear(aq_hw, &data); } +static bool aq_fvlan_is_busy(struct aq_rx_filter_vlan *aq_vlans, int vlan) +{ + int i; + + for (i = 0; i < AQ_VLAN_MAX_FILTERS; ++i) { + if (aq_vlans[i].enable && + aq_vlans[i].queue != AQ_RX_QUEUE_NOT_ASSIGNED && + aq_vlans[i].vlan_id == vlan) { + return true; + } + } + + return false; +} + +/* Function rebuilds array of vlan filters so that filters with assigned + * queue have a precedence over just vlans on the interface. + */ +static void aq_fvlan_rebuild(struct aq_nic_s *aq_nic, + unsigned long *active_vlans, + struct aq_rx_filter_vlan *aq_vlans) +{ + bool vlan_busy = false; + int vlan = -1; + int i; + + for (i = 0; i < AQ_VLAN_MAX_FILTERS; ++i) { + if (aq_vlans[i].enable && + aq_vlans[i].queue != AQ_RX_QUEUE_NOT_ASSIGNED) + continue; + do { + vlan = find_next_bit(active_vlans, + VLAN_N_VID, + vlan + 1); + if (vlan == VLAN_N_VID) { + aq_vlans[i].enable = 0U; + aq_vlans[i].queue = AQ_RX_QUEUE_NOT_ASSIGNED; + aq_vlans[i].vlan_id = 0; + continue; + } + + vlan_busy = aq_fvlan_is_busy(aq_vlans, vlan); + if (!vlan_busy) { + aq_vlans[i].enable = 1U; + aq_vlans[i].queue = AQ_RX_QUEUE_NOT_ASSIGNED; + aq_vlans[i].vlan_id = vlan; + } + } while (vlan_busy && vlan != VLAN_N_VID); + } +} + static int aq_set_data_fvlan(struct aq_nic_s *aq_nic, struct aq_rx_filter *aq_rx_fltr, struct aq_rx_filter_vlan *aq_vlans, bool add) { const struct ethtool_rx_flow_spec *fsp = &aq_rx_fltr->aq_fsp; int location = fsp->location - AQ_RX_FIRST_LOC_FVLANID; + int i; memset(&aq_vlans[location], 0, sizeof(aq_vlans[location])); if (!add) return 0; + /* remove vlan if it was in table without queue assignment */ + for (i = 0; i < AQ_VLAN_MAX_FILTERS; ++i) { + if (aq_vlans[i].vlan_id == + (be16_to_cpu(fsp->h_ext.vlan_tci) & VLAN_VID_MASK)) { + aq_vlans[i].enable = false; + } + } + aq_vlans[location].location = location; aq_vlans[location].vlan_id = be16_to_cpu(fsp->h_ext.vlan_tci) & VLAN_VID_MASK; aq_vlans[location].queue = fsp->ring_cookie & 0x1FU; aq_vlans[location].enable = 1U; + return 0; } +int aq_del_fvlan_by_vlan(struct aq_nic_s *aq_nic, u16 vlan_id) +{ + struct aq_hw_rx_fltrs_s *rx_fltrs = aq_get_hw_rx_fltrs(aq_nic); + struct aq_rx_filter *rule = NULL; + struct hlist_node *aq_node2; + + hlist_for_each_entry_safe(rule, aq_node2, + &rx_fltrs->filter_list, aq_node) { + if (be16_to_cpu(rule->aq_fsp.h_ext.vlan_tci) == vlan_id) + break; + } + if (rule && be16_to_cpu(rule->aq_fsp.h_ext.vlan_tci) == vlan_id) { + struct ethtool_rxnfc cmd; + + cmd.fs.location = rule->aq_fsp.location; + return aq_del_rxnfc_rule(aq_nic, &cmd); + } + + return -ENOENT; +} + static int aq_add_del_fvlan(struct aq_nic_s *aq_nic, struct aq_rx_filter *aq_rx_fltr, bool add) { @@ -725,14 +815,62 @@ int aq_filters_vlans_update(struct aq_nic_s *aq_nic) { const struct aq_hw_ops *aq_hw_ops = aq_nic->aq_hw_ops; struct aq_hw_s *aq_hw = aq_nic->aq_hw; + int hweight = 0; int err = 0; + int i; if (unlikely(!aq_hw_ops->hw_filter_vlan_set)) return -EOPNOTSUPP; + if (unlikely(!aq_hw_ops->hw_filter_vlan_ctrl)) + return -EOPNOTSUPP; + + aq_fvlan_rebuild(aq_nic, aq_nic->active_vlans, + aq_nic->aq_hw_rx_fltrs.fl2.aq_vlans); + + if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) { + for (i = 0; i < BITS_TO_LONGS(VLAN_N_VID); i++) + hweight += hweight_long(aq_nic->active_vlans[i]); + + err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw, false); + if (err) + return err; + } err = aq_hw_ops->hw_filter_vlan_set(aq_hw, aq_nic->aq_hw_rx_fltrs.fl2.aq_vlans ); + if (err) + return err; + + if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) { + if (hweight < AQ_VLAN_MAX_FILTERS) + err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw, true); + /* otherwise left in promiscue mode */ + } + + return err; +} +int aq_filters_vlan_offload_off(struct aq_nic_s *aq_nic) +{ + const struct aq_hw_ops *aq_hw_ops = aq_nic->aq_hw_ops; + struct aq_hw_s *aq_hw = aq_nic->aq_hw; + int err = 0; + + memset(aq_nic->active_vlans, 0, sizeof(aq_nic->active_vlans)); + aq_fvlan_rebuild(aq_nic, aq_nic->active_vlans, + aq_nic->aq_hw_rx_fltrs.fl2.aq_vlans); + + if (unlikely(!aq_hw_ops->hw_filter_vlan_set)) + return -EOPNOTSUPP; + if (unlikely(!aq_hw_ops->hw_filter_vlan_ctrl)) + return -EOPNOTSUPP; + + err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw, false); + if (err) + return err; + err = aq_hw_ops->hw_filter_vlan_set(aq_hw, + aq_nic->aq_hw_rx_fltrs.fl2.aq_vlans + ); return err; } diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_filters.h b/drivers/net/ethernet/aquantia/atlantic/aq_filters.h index 4c57c26fd3f0..c6a08c6585d5 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_filters.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_filters.h @@ -27,8 +27,10 @@ int aq_del_rxnfc_rule(struct aq_nic_s *aq_nic, const struct ethtool_rxnfc *cmd); int aq_get_rxnfc_rule(struct aq_nic_s *aq_nic, struct ethtool_rxnfc *cmd); int aq_get_rxnfc_all_rules(struct aq_nic_s *aq_nic, struct ethtool_rxnfc *cmd, u32 *rule_locs); +int aq_del_fvlan_by_vlan(struct aq_nic_s *aq_nic, u16 vlan_id); int aq_clear_rxnfc_all_rules(struct aq_nic_s *aq_nic); int aq_reapply_rxnfc_all_rules(struct aq_nic_s *aq_nic); int aq_filters_vlans_update(struct aq_nic_s *aq_nic); +int aq_filters_vlan_offload_off(struct aq_nic_s *aq_nic); #endif /* AQ_FILTERS_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h index b0a48956e22f..81aab73dc22f 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h @@ -27,6 +27,7 @@ #define AQ_RX_MAX_RXNFC_LOC AQ_RX_LAST_LOC_FL3L4 #define AQ_VLAN_MAX_FILTERS \ (AQ_RX_LAST_LOC_FVLANID - AQ_RX_FIRST_LOC_FVLANID + 1U) +#define AQ_RX_QUEUE_NOT_ASSIGNED 0xFFU /* NIC H/W capabilities */ struct aq_hw_caps_s { diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c index ff15d3388add..2a11c1eefd8f 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c @@ -114,6 +114,13 @@ static int aq_ndev_set_features(struct net_device *ndev, goto err_exit; } } + if (!(features & NETIF_F_HW_VLAN_CTAG_FILTER)) { + if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) { + err = aq_filters_vlan_offload_off(aq_nic); + if (unlikely(err)) + goto err_exit; + } + } aq_cfg->features = features; @@ -162,6 +169,35 @@ static void aq_ndev_set_multicast_settings(struct net_device *ndev) aq_nic_set_multicast_list(aq_nic, ndev); } +static int aq_ndo_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, + u16 vid) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + + if (!aq_nic->aq_hw_ops->hw_filter_vlan_set) + return -EOPNOTSUPP; + + set_bit(vid, aq_nic->active_vlans); + + return aq_filters_vlans_update(aq_nic); +} + +static int aq_ndo_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, + u16 vid) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + + if (!aq_nic->aq_hw_ops->hw_filter_vlan_set) + return -EOPNOTSUPP; + + clear_bit(vid, aq_nic->active_vlans); + + if (-ENOENT == aq_del_fvlan_by_vlan(aq_nic, vid)) + return aq_filters_vlans_update(aq_nic); + + return 0; +} + static const struct net_device_ops aq_ndev_ops = { .ndo_open = aq_ndev_open, .ndo_stop = aq_ndev_close, @@ -169,5 +205,7 @@ static const struct net_device_ops aq_ndev_ops = { .ndo_set_rx_mode = aq_ndev_set_multicast_settings, .ndo_change_mtu = aq_ndev_change_mtu, .ndo_set_mac_address = aq_ndev_set_mac_address, - .ndo_set_features = aq_ndev_set_features + .ndo_set_features = aq_ndev_set_features, + .ndo_vlan_rx_add_vid = aq_ndo_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = aq_ndo_vlan_rx_kill_vid, }; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index 7abdc0952425..279ea58f4a9e 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -84,8 +84,6 @@ void aq_nic_cfg_start(struct aq_nic_s *self) cfg->is_lro = AQ_CFG_IS_LRO_DEF; - cfg->vlan_id = 0U; - aq_nic_rss_init(self, cfg->num_rss_queues); /*descriptors */ diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h index 6e971bd7f7b9..8e34c1e49bf2 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h @@ -35,7 +35,6 @@ struct aq_nic_cfg_s { u32 mtu; u32 flow_control; u32 link_speed_msk; - u32 vlan_id; u32 wol; u16 is_mc_list_enabled; u16 mc_list_count; @@ -98,6 +97,8 @@ struct aq_nic_s { u32 count; u8 ar[AQ_HW_MULTICAST_ADDRESS_MAX][ETH_ALEN]; } mc_list; + /* Bitmask of currently assigned vlans from linux */ + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; struct pci_dev *pdev; unsigned int msix_entry_mask; diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c index a8777751d09b..6af7d7f0cdca 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c @@ -42,7 +42,8 @@ NETIF_F_SG | \ NETIF_F_TSO | \ NETIF_F_LRO | \ - NETIF_F_NTUPLE, \ + NETIF_F_NTUPLE | \ + NETIF_F_HW_VLAN_CTAG_FILTER, \ .hw_priv_flags = IFF_UNICAST_FLT, \ .flow_control = true, \ .mtu = HW_ATL_B0_MTU_JUMBO, \ @@ -320,20 +321,11 @@ static int hw_atl_b0_hw_init_rx_path(struct aq_hw_s *self) hw_atl_rpf_vlan_outer_etht_set(self, 0x88A8U); hw_atl_rpf_vlan_inner_etht_set(self, 0x8100U); - if (cfg->vlan_id) { - hw_atl_rpf_vlan_flr_act_set(self, 1U, 0U); - hw_atl_rpf_vlan_id_flr_set(self, 0U, 0U); - hw_atl_rpf_vlan_flr_en_set(self, 0U, 0U); + hw_atl_rpf_vlan_prom_mode_en_set(self, 1); - hw_atl_rpf_vlan_accept_untagged_packets_set(self, 1U); - hw_atl_rpf_vlan_untagged_act_set(self, 1U); - - hw_atl_rpf_vlan_flr_act_set(self, 1U, 1U); - hw_atl_rpf_vlan_id_flr_set(self, cfg->vlan_id, 0U); - hw_atl_rpf_vlan_flr_en_set(self, 1U, 1U); - } else { - hw_atl_rpf_vlan_prom_mode_en_set(self, 1); - } + // Always accept untagged packets + hw_atl_rpf_vlan_accept_untagged_packets_set(self, 1U); + hw_atl_rpf_vlan_untagged_act_set(self, 1U); /* Rx Interrupts */ hw_atl_rdm_rx_desc_wr_wb_irq_en_set(self, 1U); @@ -1074,6 +1066,14 @@ static int hw_atl_b0_hw_vlan_set(struct aq_hw_s *self, return aq_hw_err_from_flags(self); } +static int hw_atl_b0_hw_vlan_ctrl(struct aq_hw_s *self, bool enable) +{ + /* set promisc in case of disabing the vland filter */ + hw_atl_rpf_vlan_prom_mode_en_set(self, !!!enable); + + return aq_hw_err_from_flags(self); +} + const struct aq_hw_ops hw_atl_ops_b0 = { .hw_set_mac_address = hw_atl_b0_hw_mac_addr_set, .hw_init = hw_atl_b0_hw_init, @@ -1102,6 +1102,7 @@ const struct aq_hw_ops hw_atl_ops_b0 = { .hw_filter_l2_clear = hw_atl_b0_hw_fl2_clear, .hw_filter_l3l4_set = hw_atl_b0_hw_fl3l4_set, .hw_filter_vlan_set = hw_atl_b0_hw_vlan_set, + .hw_filter_vlan_ctrl = hw_atl_b0_hw_vlan_ctrl, .hw_multicast_list_set = hw_atl_b0_hw_multicast_list_set, .hw_interrupt_moderation_set = hw_atl_b0_hw_interrupt_moderation_set, .hw_rss_set = hw_atl_b0_hw_rss_set,