From patchwork Mon Nov 12 15:46:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Russkikh X-Patchwork-Id: 996513 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="EILykNwE"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42tw8m6lFYz9s1x for ; Tue, 13 Nov 2018 02:46:16 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729899AbeKMBkC (ORCPT ); Mon, 12 Nov 2018 20:40:02 -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 S1729832AbeKMBkB (ORCPT ); Mon, 12 Nov 2018 20:40:01 -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=DTFGZPOaRPPWgsfiwo9eoPL7m/ujivRnU1Rf3uUpGSQ=; b=EILykNwE7ztYtdqPjNKP1Re448iHsKAp9sELJ6YRe8JsVLWj3Zlm4qIYZELNiSfhvzmxw08Z4E0HsGQrl57ZRA4D5/Hy56Jm89zsDZOQzNwZucxJklthlLTqCNQpKlY+onHFTeOfC8nFJhVATuvDZGYj6wREvMAbp1riQ1kC4Kw= 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:07 +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:07 +0000 From: Igor Russkikh To: "David S . Miller" CC: "netdev@vger.kernel.org" , Igor Russkikh , Dmitry Bogdanov Subject: [PATCH net-next v2 5/6] net: aquantia: add ethertype and PCP to rx flow filters Thread-Topic: [PATCH net-next v2 5/6] net: aquantia: add ethertype and PCP to rx flow filters Thread-Index: AQHUep7TyQ0vG9sC6E2r5XEMuRM6sA== Date: Mon, 12 Nov 2018 15:46:07 +0000 Message-ID: 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:JYinFGJROIF7/IfymTvzNqlhV7g8oWAm+V08NDzZyTW4dOM0b7lZEvzAYzz1C/D3Qe4q1gKfyJlxiMQJlpVo5uwl+ObbuTHMnK/mMVgXA3cgtJHRVB0GOragY9UdViiukpSywglaslITKAR9E7bqM2V77lXmAfbkTqccZEsBCzDUmYqi84xbT13LfBECR8esnfGES/wkl6Pyd629CEtg93aTEtjdK6NjGrOYy+eolRlkYpu8R/icF6/OPzWqBkXMn9x6g131O0mCdVkRHO2bJb29RazmcbHAnpODg7gNcPMeusjpHof+3A1Pu3CCkqD8R2bbiCw9FWK4mAVzAqUc81g/K26PTdoxHQQigNpBOQwxEmltqPfwz4/MRW5mRwDSI/tA0V9O+UM5jN1L9tKAJNqVmxIgfB94YFfyk836LtXsfNjwyfyNiOMRtU/Mkrnc8uP7hkQp5+T1fECgkc9UWw==; 5:dnfI/OTw/0r3cOVwUxwma0q8yBvI8scsgmBucb36RB4w+A6tUMUOa5Kda8ETNsM2tQnnhIq9DGnCJr9Z2cCQ813JYgvWgqtgYbc/jjvwEYuTwFZQsCCuUUaFaDYq+WMsJDB6C5ln6Ta1MH+CI9EPIvCT3BZYODxMqnM3q7BjOFA=; 7:xddFhj7GFicRv8jnrB0a+TFYM5sd/zrXAZhheuYyfeP3isRkirloS3SUKEfkaxrTB+pu2W4B+mLCBGBcpocvrv5Opu7dhKjLGTwdghk3Ld45+VOwUE0Q5eQvlAT4ec/jnXkI8rfDNOf5SbIiQRgpFg== x-ms-office365-filtering-correlation-id: 0f9e0dda-ee31-482c-1097-08d648b5f60a 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)(54906003)(53936002)(6506007)(186003)(102836004)(6116002)(3846002)(386003)(71200400001)(71190400001)(316002)(81166006)(8936002)(44832011)(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)(309714004); 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: sx7MkPsKvgrUCg4uF62c0OE/Jcxk9ewxuJAzZ+UIuSerCeQv/U13gtYMLx40fvNPSCzwqtM5qqQp56dayHph31DG0lc9yclVxdoE3t3aX3sJ4pUH4z7rZ0IM6sTxhiYGe1XgFEIhftGj9lkUYqcJ8rLZx7O4EriXZlvReBndclKDMxT3lBeflpRqSYPBHH3VAmgaL4mWQzMFgQlIn4gKV8yMovDl7P6afSjLbao/7b5LiqLGSUuf6bbCECUD80cpdYueQo4uW47sKb9js4TTw7/qQWQzTIH55N0PO+DIU3r1+8u+Y6ZHibKV+/80Rxbc4W99N5uDtPg7P3TTTFWeZPqnlr2AdQ/gahjfms4lbSs= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: aquantia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0f9e0dda-ee31-482c-1097-08d648b5f60a X-MS-Exchange-CrossTenant-originalarrivaltime: 12 Nov 2018 15:46:07.6221 (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 L2 EtherType filters allows to filter packet by EtherType field or both EtherType and User Priority (PCP) field of 802.1Q. UserPriority (vlan) parameter must be accompanied by mask 0x1FFF. That is to distinguish VLAN filter from L2 Ethertype filter with UserPriority since both User Priority and VLAN ID are passed in the same 'vlan' parameter. Example: To add a filter that directs IP4 packess of priority 3 to queue 3: ethtool -N flow-type ether proto 0x800 vlan 0x600 m 0x1FFF \ action 3 loc 16 Signed-off-by: Dmitry Bogdanov Signed-off-by: Igor Russkikh --- .../net/ethernet/aquantia/atlantic/aq_filters.c | 83 ++++++++++++++++++++-- .../net/ethernet/aquantia/atlantic/aq_filters.h | 1 + drivers/net/ethernet/aquantia/atlantic/aq_hw.h | 8 +++ .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 37 ++++++++++ .../aquantia/atlantic/hw_atl/hw_atl_utils.h | 8 +++ 5 files changed, 133 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c index c5240bc487b4..b987c6717af6 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c @@ -120,6 +120,30 @@ static int aq_check_approve_fl3l4(struct aq_nic_s *aq_nic, } static int __must_check +aq_check_approve_fl2(struct aq_nic_s *aq_nic, + struct aq_hw_rx_fltrs_s *rx_fltrs, + struct ethtool_rx_flow_spec *fsp) +{ + if (fsp->location < AQ_RX_FIRST_LOC_FETHERT || + fsp->location > AQ_RX_LAST_LOC_FETHERT) { + netdev_err(aq_nic->ndev, + "ethtool: location must be in range [%d, %d]", + AQ_RX_FIRST_LOC_FETHERT, + AQ_RX_LAST_LOC_FETHERT); + return -EINVAL; + } + + if (be16_to_cpu(fsp->m_ext.vlan_tci) == VLAN_PRIO_MASK && + fsp->m_u.ether_spec.h_proto == 0U) { + netdev_err(aq_nic->ndev, + "ethtool: proto (ether_type) parameter must be specfied"); + return -EINVAL; + } + + return 0; +} + +static int __must_check aq_check_approve_fvlan(struct aq_nic_s *aq_nic, struct aq_hw_rx_fltrs_s *rx_fltrs, struct ethtool_rx_flow_spec *fsp) @@ -152,6 +176,8 @@ aq_check_filter(struct aq_nic_s *aq_nic, if (fsp->flow_type & FLOW_EXT) { if (be16_to_cpu(fsp->m_ext.vlan_tci) == VLAN_VID_MASK) { err = aq_check_approve_fvlan(aq_nic, rx_fltrs, fsp); + } else if (be16_to_cpu(fsp->m_ext.vlan_tci) == VLAN_PRIO_MASK) { + err = aq_check_approve_fl2(aq_nic, rx_fltrs, fsp); } else { netdev_err(aq_nic->ndev, "ethtool: invalid vlan mask 0x%x specified", @@ -161,7 +187,7 @@ aq_check_filter(struct aq_nic_s *aq_nic, } else { switch (fsp->flow_type & ~FLOW_EXT) { case ETHER_FLOW: - err = -EOPNOTSUPP; + err = aq_check_approve_fl2(aq_nic, rx_fltrs, fsp); break; case TCP_V4_FLOW: case UDP_V4_FLOW: @@ -210,6 +236,10 @@ aq_rule_is_not_support(struct aq_nic_s *aq_nic, netdev_err(aq_nic->ndev, "ethtool: The specified tos tclass are not supported\n"); rule_is_not_support = true; + } else if (fsp->flow_type & FLOW_MAC_EXT) { + netdev_err(aq_nic->ndev, + "ethtool: MAC_EXT is not supported"); + rule_is_not_support = true; } return rule_is_not_support; @@ -259,6 +289,48 @@ aq_check_rule(struct aq_nic_s *aq_nic, return err; } +static void aq_set_data_fl2(struct aq_nic_s *aq_nic, + struct aq_rx_filter *aq_rx_fltr, + struct aq_rx_filter_l2 *data, bool add) +{ + const struct ethtool_rx_flow_spec *fsp = &aq_rx_fltr->aq_fsp; + + memset(data, 0, sizeof(*data)); + + data->location = fsp->location - AQ_RX_FIRST_LOC_FETHERT; + + if (fsp->ring_cookie != RX_CLS_FLOW_DISC) + data->queue = fsp->ring_cookie; + else + data->queue = -1; + + data->ethertype = be16_to_cpu(fsp->h_u.ether_spec.h_proto); + data->user_priority_en = be16_to_cpu(fsp->m_ext.vlan_tci) + == VLAN_PRIO_MASK; + data->user_priority = (be16_to_cpu(fsp->h_ext.vlan_tci) + & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; +} + +static int aq_add_del_fether(struct aq_nic_s *aq_nic, + struct aq_rx_filter *aq_rx_fltr, bool add) +{ + struct aq_rx_filter_l2 data; + struct aq_hw_s *aq_hw = aq_nic->aq_hw; + const struct aq_hw_ops *aq_hw_ops = aq_nic->aq_hw_ops; + + aq_set_data_fl2(aq_nic, aq_rx_fltr, &data, add); + + if (unlikely(!aq_hw_ops->hw_filter_l2_set)) + return -EOPNOTSUPP; + if (unlikely(!aq_hw_ops->hw_filter_l2_clear)) + return -EOPNOTSUPP; + + if (add) + return aq_hw_ops->hw_filter_l2_set(aq_hw, &data); + else + return aq_hw_ops->hw_filter_l2_clear(aq_hw, &data); +} + 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) @@ -424,13 +496,16 @@ static int aq_add_del_rule(struct aq_nic_s *aq_nic, == VLAN_VID_MASK) { aq_rx_fltr->type = aq_rx_filter_vlan; err = aq_add_del_fvlan(aq_nic, aq_rx_fltr, add); - } else { - err = -EINVAL; + } else if (be16_to_cpu(aq_rx_fltr->aq_fsp.m_ext.vlan_tci) + == VLAN_PRIO_MASK) { + aq_rx_fltr->type = aq_rx_filter_ethertype; + err = aq_add_del_fether(aq_nic, aq_rx_fltr, add); } } else { switch (aq_rx_fltr->aq_fsp.flow_type & ~FLOW_EXT) { case ETHER_FLOW: - err = -EOPNOTSUPP; + aq_rx_fltr->type = aq_rx_filter_ethertype; + err = aq_add_del_fether(aq_nic, aq_rx_fltr, add); break; case TCP_V4_FLOW: case UDP_V4_FLOW: diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_filters.h b/drivers/net/ethernet/aquantia/atlantic/aq_filters.h index bbaf331a55bb..4c57c26fd3f0 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_filters.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_filters.h @@ -9,6 +9,7 @@ #include "aq_nic.h" enum aq_rx_filter_type { + aq_rx_filter_ethertype, aq_rx_filter_vlan, aq_rx_filter_l3l4 }; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h index d31474c8a498..b0a48956e22f 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h @@ -20,6 +20,8 @@ #define AQ_RX_FIRST_LOC_FVLANID 0U #define AQ_RX_LAST_LOC_FVLANID 15U +#define AQ_RX_FIRST_LOC_FETHERT 16U +#define AQ_RX_LAST_LOC_FETHERT 31U #define AQ_RX_FIRST_LOC_FL3L4 32U #define AQ_RX_LAST_LOC_FL3L4 39U #define AQ_RX_MAX_RXNFC_LOC AQ_RX_LAST_LOC_FL3L4 @@ -198,6 +200,12 @@ struct aq_hw_ops { int (*hw_filter_l3l4_clear)(struct aq_hw_s *self, struct aq_rx_filter_l3l4 *data); + int (*hw_filter_l2_set)(struct aq_hw_s *self, + struct aq_rx_filter_l2 *data); + + int (*hw_filter_l2_clear)(struct aq_hw_s *self, + struct aq_rx_filter_l2 *data); + int (*hw_filter_vlan_set)(struct aq_hw_s *self, struct aq_rx_filter_vlan *aq_vlans); 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 4ee30fa2e36b..a8777751d09b 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 @@ -1003,6 +1003,41 @@ static int hw_atl_b0_hw_fl3l4_set(struct aq_hw_s *self, return aq_hw_err_from_flags(self); } +static int hw_atl_b0_hw_fl2_set(struct aq_hw_s *self, + struct aq_rx_filter_l2 *data) +{ + hw_atl_rpf_etht_flr_en_set(self, 1U, data->location); + hw_atl_rpf_etht_flr_set(self, data->ethertype, data->location); + hw_atl_rpf_etht_user_priority_en_set(self, + !!data->user_priority_en, + data->location); + if (data->user_priority_en) + hw_atl_rpf_etht_user_priority_set(self, + data->user_priority, + data->location); + + if (data->queue < 0) { + hw_atl_rpf_etht_flr_act_set(self, 0U, data->location); + hw_atl_rpf_etht_rx_queue_en_set(self, 0U, data->location); + } else { + hw_atl_rpf_etht_flr_act_set(self, 1U, data->location); + hw_atl_rpf_etht_rx_queue_en_set(self, 1U, data->location); + hw_atl_rpf_etht_rx_queue_set(self, data->queue, data->location); + } + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_fl2_clear(struct aq_hw_s *self, + struct aq_rx_filter_l2 *data) +{ + hw_atl_rpf_etht_flr_en_set(self, 0U, data->location); + hw_atl_rpf_etht_flr_set(self, 0U, data->location); + hw_atl_rpf_etht_user_priority_en_set(self, 0U, data->location); + + return aq_hw_err_from_flags(self); +} + /** * @brief Set VLAN filter table * @details Configure VLAN filter table to accept (and assign the queue) traffic @@ -1063,6 +1098,8 @@ const struct aq_hw_ops hw_atl_ops_b0 = { .hw_ring_rx_init = hw_atl_b0_hw_ring_rx_init, .hw_ring_tx_init = hw_atl_b0_hw_ring_tx_init, .hw_packet_filter_set = hw_atl_b0_hw_packet_filter_set, + .hw_filter_l2_set = hw_atl_b0_hw_fl2_set, + .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_multicast_list_set = hw_atl_b0_hw_multicast_list_set, diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h index 3c5b81420361..48278e333462 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h @@ -252,6 +252,14 @@ struct aq_rx_filter_vlan { u8 queue; }; +struct aq_rx_filter_l2 { + s8 queue; + u8 location; + u8 user_priority_en; + u8 user_priority; + u16 ethertype; +}; + struct aq_rx_filter_l3l4 { u32 cmd; u8 location;