* Re: [PATCH wpan 2/2] net: mac802154: tx: expand tailroom if necessary
From: Stefan Schmidt @ 2018-08-06 9:26 UTC (permalink / raw)
To: Alexander Aring, stefan; +Cc: linux-wpan, netdev, kernel
In-Reply-To: <20180702203203.21316-2-aring@mojatatu.com>
Hello.
On 07/02/2018 10:32 PM, Alexander Aring wrote:
> This patch is necessary if case of AF_PACKET or other socket interface
> which I am aware of it and didn't allocated the necessary room.
>
> Reported-by: David Palma <david.palma@ntnu.no>
> Reported-by: Rabi Narayan Sahoo <rabinarayans0828@gmail.com>
> Signed-off-by: Alexander Aring <aring@mojatatu.com>
> ---
> net/mac802154/tx.c | 15 ++++++++++++++-
> 1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
> index 7e253455f9dd..bcd1a5e6ebf4 100644
> --- a/net/mac802154/tx.c
> +++ b/net/mac802154/tx.c
> @@ -63,8 +63,21 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
> int ret;
>
> if (!(local->hw.flags & IEEE802154_HW_TX_OMIT_CKSUM)) {
> - u16 crc = crc_ccitt(0, skb->data, skb->len);
> + struct sk_buff *nskb;
> + u16 crc;
> +
> + if (unlikely(skb_tailroom(skb) < IEEE802154_FCS_LEN)) {
> + nskb = skb_copy_expand(skb, 0, IEEE802154_FCS_LEN,
> + GFP_ATOMIC);
> + if (likely(nskb)) {
> + consume_skb(skb);
> + skb = nskb;
> + } else {
> + goto err_tx;
> + }
> + }
>
> + crc = crc_ccitt(0, skb->data, skb->len);
> put_unaligned_le16(crc, skb_put(skb, 2));
> }
>
>
This patch has been applied to the wpan-next tree and will be
part of the next pull request to net-next. Thanks!
I know you submitted this for wpan instead of wpan-next, but with rc8
being out I will not submit another pull request for 4.18. Instead I
added cc stable to the patch to make sure it gets picked into the stable
tree once 4.18 is out.
regards
Stefan Schmidt
^ permalink raw reply
* RE: [PATCH v2 0/2] net/sctp: Avoid allocating high order memory with kmalloc()
From: David Laight @ 2018-08-06 9:34 UTC (permalink / raw)
To: 'Michael Tuexen', Marcelo Ricardo Leitner
Cc: Konstantin Khorenko, oleg.babin@gmail.com, netdev@vger.kernel.org,
linux-sctp@vger.kernel.org, David S . Miller, Vlad Yasevich,
Neil Horman, Xin Long, Andrey Ryabinin
In-Reply-To: <2D7531CF-9E0A-4B33-83E5-724B7C88F363@lurchi.franken.de>
From: Michael Tuexen
> Sent: 03 August 2018 21:57
...
> >> Given how useless SCTP streams are, does anything actually use
> >> more than about 4?
> >
> > Maybe Michael can help us with that. I'm also curious now.
> In the context of SIGTRAN I have seen 17 streams...
Ok, I've seen 17 there as well, 5 is probably more common.
> In the context of WebRTC I have seen more streams. In general,
> the streams concept seems to be useful. QUIC has lots of streams.
>
> So I'm wondering why they are considered useless.
> David, can you elaborate on this?
I don't think a lot of people know what they actually are.
Streams just allow some receive data to forwarded to applications when receive
message(s) on stream(s) are lost and have to be retransmitted.
I suspect some people think that the separate streams have separate flow control,
not just separate data sequences.
M2PA separates control message (stream 0) from user data (stream 1).
I think the spec even suggests this is so control messages get through when
user data is flow controlled off - not true (it would be true for ISO
transport's 'expedited data).
M3UA will use 16 streams (one for each (ITU) SLS), but uses stream 0 for control.
If a data message is lost then data for the other sls can be passed to the
userpart/mtp3 - this might save bursty processing when the SACK-requested
retransmission arrives. But I doubt you'd want to run M3UA on anything lossy
enough for more than 4 data streams to make sense.
Even M3UA separating control onto stream 0 data onto 1-n doesn't seem useful to me.
If QUIC is using 'lots of streams' is it just using the stream-id as a qualifier
for the data? Rather than requiring the 'not head of line blocking' feature
of sctp streams?
Thought....
Could we let the application set large stream-ids, but actually mask them
down to (say) 32 for the protocol code?
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
^ permalink raw reply
* [PATCH net-next] tcp: fix the calculation of sysctl_max_tw_buckets in tcp_sk_init()
From: Yafang Shao @ 2018-08-06 11:47 UTC (permalink / raw)
To: edumazet, davem, yanhaishuang; +Cc: netdev, linux-kernel, Yafang Shao
tcp_hashinfo.ehash_mask is always an odd number, which is set in function
alloc_large_system_hash(). See bellow,
if (_hash_mask)
*_hash_mask = (1 << log2qty) - 1; <<< always odd number
Hence the local variable 'cnt' is a even number, as a result of that it is
no difference to do the incrementation here.
Maybe the compiler could also optimize it, but this code is a little ugly.
Fix: fee83d09 ("ipv4: Namespaceify tcp_max_syn_backlog knob")
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
net/ipv4/tcp_ipv4.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 9e041fa..a9b7c4b 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2543,7 +2543,7 @@ static int __net_init tcp_sk_init(struct net *net)
net->ipv4.sysctl_tcp_tw_reuse = 2;
cnt = tcp_hashinfo.ehash_mask + 1;
- net->ipv4.tcp_death_row.sysctl_max_tw_buckets = (cnt + 1) / 2;
+ net->ipv4.tcp_death_row.sysctl_max_tw_buckets = cnt / 2;
net->ipv4.tcp_death_row.hashinfo = &tcp_hashinfo;
net->ipv4.sysctl_max_syn_backlog = max(128, cnt / 256);
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH] can: sja1000: plx_pci: add support for ASEM CAN raw device
From: Marc Kleine-Budde @ 2018-08-06 12:05 UTC (permalink / raw)
To: Flavio Suligoi, Wolfgang Grandegger
Cc: David S . Miller, linux-can, netdev, linux-kernel
In-Reply-To: <1533556850-4297-1-git-send-email-f.suligoi@asem.it>
[-- Attachment #1.1: Type: text/plain, Size: 6061 bytes --]
On 08/06/2018 02:00 PM, Flavio Suligoi wrote:
> This patch adds support for ASEM opto-isolated dual channels
> CAN raw device (http://www.asem.it)
>
> Signed-off-by: Flavio Suligoi <f.suligoi@asem.it>
> ---
> drivers/net/can/sja1000/Kconfig | 1 +
> drivers/net/can/sja1000/plx_pci.c | 68 ++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 68 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig
> index 1e65cb6..f6dc899 100644
> --- a/drivers/net/can/sja1000/Kconfig
> +++ b/drivers/net/can/sja1000/Kconfig
> @@ -88,6 +88,7 @@ config CAN_PLX_PCI
> - TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/)
> - IXXAT Automation PC-I 04/PCI card (http://www.ixxat.com/)
> - Connect Tech Inc. CANpro/104-Plus Opto (CRG001) card (http://www.connecttech.com)
> + - ASEM CAN raw - 2 isolated CAN channels (www.asem.it)
>
> config CAN_TSCAN1
> tristate "TS-CAN1 PC104 boards"
> diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c
> index f8ff25c..864fe8d 100644
> --- a/drivers/net/can/sja1000/plx_pci.c
> +++ b/drivers/net/can/sja1000/plx_pci.c
> @@ -46,7 +46,8 @@ MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, "
> "esd CAN-PCIe/2000, "
> "Connect Tech Inc. CANpro/104-Plus Opto (CRG001), "
> "IXXAT PC-I 04/PCI, "
> - "ELCUS CAN-200-PCI")
> + "ELCUS CAN-200-PCI, "
> + "ASEM DUAL CAN-RAW")
> MODULE_LICENSE("GPL v2");
>
> #define PLX_PCI_MAX_CHAN 2
> @@ -70,7 +71,9 @@ struct plx_pci_card {
> */
>
> #define PLX_LINT1_EN 0x1 /* Local interrupt 1 enable */
> +#define PLX_LINT1_POL (1 << 1) /* Local interrupt 1 polarity */
> #define PLX_LINT2_EN (1 << 3) /* Local interrupt 2 enable */
> +#define PLX_LINT2_POL (1 << 4) /* Local interrupt 1 polarity */
^^^ 2?
> #define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */
> #define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */
>
> @@ -92,6 +95,9 @@ struct plx_pci_card {
> */
> #define PLX_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
>
> +/* OCR setting for ASEM Dual CAN raw */
> +#define ASEM_PCI_OCR 0xfe
> +
> /*
> * In the CDR register, you should set CBP to 1.
> * You will probably also want to set the clock divider value to 7
> @@ -145,10 +151,20 @@ struct plx_pci_card {
> #define MOXA_PCI_VENDOR_ID 0x1393
> #define MOXA_PCI_DEVICE_ID 0x0100
>
> +#define ASEM_DUAL_CAN_VENDOR_ID 0x10b5
> +#define ASEM_DUAL_CAN_DEVICE_ID 0x9030
> +#define ASEM_DUAL_CAN_SUB_VENDOR_ID 0x3000
> +#define ASEM_DUAL_CAN_SUB_DEVICE_ID 0x1001
> +#define ASEM_DUAL_CAN_SUB_DEVICE_ID_BIS 0x1002
> +#define ASEM_DUAL_CAN_RESET_REGISTER 0x54
> +#define ASEM_DUAL_CAN_RESET_MASK_CAN1 0x20
> +#define ASEM_DUAL_CAN_RESET_MASK_CAN2 0x04
> +
> static void plx_pci_reset_common(struct pci_dev *pdev);
> static void plx9056_pci_reset_common(struct pci_dev *pdev);
> static void plx_pci_reset_marathon_pci(struct pci_dev *pdev);
> static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev);
> +static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev);
>
> struct plx_pci_channel_map {
> u32 bar;
> @@ -269,6 +285,14 @@ static struct plx_pci_card_info plx_pci_card_info_moxa = {
> /* based on PLX9052 */
> };
>
> +static struct plx_pci_card_info plx_pci_card_info_asem_dual_can = {
> + "ASEM Dual CAN raw PCI", 2,
> + PLX_PCI_CAN_CLOCK, ASEM_PCI_OCR, PLX_PCI_CDR,
> + {0, 0x00, 0x00}, { {2, 0x00, 0x00}, {4, 0x00, 0x00} },
> + &plx_pci_reset_asem_dual_can_raw
> + /* based on PLX9030 */
> +};
> +
> static const struct pci_device_id plx_pci_tbl[] = {
> {
> /* Adlink PCI-7841/cPCI-7841 */
> @@ -375,6 +399,20 @@ static const struct pci_device_id plx_pci_tbl[] = {
> 0, 0,
> (kernel_ulong_t)&plx_pci_card_info_moxa
> },
> + {
> + /* ASEM Dual CAN raw */
> + ASEM_DUAL_CAN_VENDOR_ID, ASEM_DUAL_CAN_DEVICE_ID,
> + ASEM_DUAL_CAN_SUB_VENDOR_ID, ASEM_DUAL_CAN_SUB_DEVICE_ID,
> + 0, 0,
> + (kernel_ulong_t)&plx_pci_card_info_asem_dual_can
> + },
> + {
> + /* ASEM Dual CAN raw -new model */
> + ASEM_DUAL_CAN_VENDOR_ID, ASEM_DUAL_CAN_DEVICE_ID,
> + ASEM_DUAL_CAN_SUB_VENDOR_ID, ASEM_DUAL_CAN_SUB_DEVICE_ID_BIS,
> + 0, 0,
> + (kernel_ulong_t)&plx_pci_card_info_asem_dual_can
> + },
> { 0,}
> };
> MODULE_DEVICE_TABLE(pci, plx_pci_tbl);
> @@ -524,6 +562,34 @@ static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev)
> }
> }
>
> +/* Special reset function for ASEM Dual CAN raw card */
> +static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev)
> +{
> + void __iomem *bar0_addr;
> + static const int reset_bar;
> + u8 tmpval;
> +
> + plx_pci_reset_common(pdev);
> +
> + bar0_addr = pci_iomap(pdev, reset_bar, 0);
> + if (!bar0_addr) {
> + dev_err(&pdev->dev, "Failed to remap reset "
> + "space %d (BAR%d)\n", 0, reset_bar);
please don't break strings
just return here, so you can remove the indention for the else...
> + } else {
> + /* reset the two SJA1000 chips */
> + tmpval = ioread8(bar0_addr + ASEM_DUAL_CAN_RESET_REGISTER);
> + tmpval &= ~(ASEM_DUAL_CAN_RESET_MASK_CAN1 |
> + ASEM_DUAL_CAN_RESET_MASK_CAN2);
> + iowrite8(tmpval, bar0_addr + ASEM_DUAL_CAN_RESET_REGISTER);
> + usleep_range(300, 400);
> + tmpval |= ASEM_DUAL_CAN_RESET_MASK_CAN1 |
> + ASEM_DUAL_CAN_RESET_MASK_CAN2;
> + iowrite8(tmpval, bar0_addr + ASEM_DUAL_CAN_RESET_REGISTER);
> + usleep_range(300, 400);
> + pci_iounmap(pdev, bar0_addr);
> + }
> +}
> +
> static void plx_pci_del_card(struct pci_dev *pdev)
> {
> struct plx_pci_card *card = pci_get_drvdata(pdev);
>
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* [PATCH] Use Kconfig flag to remove support of deprecated BE2/BE3 adapters
From: Petr Oros @ 2018-08-06 12:12 UTC (permalink / raw)
To: netdev
Cc: ivecera, Sathya Perla, Ajit Khaparde, Sriharsha Basavapatna,
Somnath Kotur, David S. Miller, linux-kernel
Add flags to remove support of deprecated BE2/BE3 adapters.
BE2 disable will reduce .ko size by 2kb and BE3 by 3kb.
Disable both will reduce .ko size by 9kb.
With dissabled support is also removed coresponding PCI IDs
and codepath with [BE2|BE3|BEx]_chip checks.
New help style in Kconfig
Signed-off-by: Petr Oros <poros@redhat.com>
---
drivers/net/ethernet/emulex/benet/Kconfig | 20 ++++++++++++++++++--
drivers/net/ethernet/emulex/benet/be.h | 8 ++++++++
drivers/net/ethernet/emulex/benet/be_main.c | 6 +++++-
3 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/Kconfig b/drivers/net/ethernet/emulex/benet/Kconfig
index b4853ec9de8d..68a9c40adc2a 100644
--- a/drivers/net/ethernet/emulex/benet/Kconfig
+++ b/drivers/net/ethernet/emulex/benet/Kconfig
@@ -1,7 +1,7 @@
config BE2NET
tristate "ServerEngines' 10Gbps NIC - BladeEngine"
depends on PCI
- ---help---
+ help
This driver implements the NIC functionality for ServerEngines'
10Gbps network adapter - BladeEngine.
@@ -10,6 +10,22 @@ config BE2NET_HWMON
depends on BE2NET && HWMON
depends on !(BE2NET=y && HWMON=m)
default y
- ---help---
+ help
Say Y here if you want to expose thermal sensor data on
be2net network adapter.
+
+config BE2NET_BE2
+ bool "Support for deprecated BE2 chipsets"
+ depends on BE2NET
+ default y
+ help
+ Say Y here if you want to use deprecated Emulex devices based
+ on BE2 chipsets.
+
+config BE2NET_BE3
+ bool "Support for deprecated BE3 chipsets"
+ depends on BE2NET
+ default y
+ help
+ Say Y here if you want to use deprecated Emulex devices based
+ on BE3 chipsets.
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 382891f81e09..3038578ec7a7 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -779,11 +779,19 @@ static inline u16 be_max_any_irqs(struct be_adapter *adapter)
#define skyhawk_chip(adapter) (adapter->pdev->device == OC_DEVICE_ID5 || \
adapter->pdev->device == OC_DEVICE_ID6)
+#ifdef CONFIG_BE2NET_BE3
#define BE3_chip(adapter) (adapter->pdev->device == BE_DEVICE_ID2 || \
adapter->pdev->device == OC_DEVICE_ID2)
+#else
+#define BE3_chip(adapter) (0)
+#endif /* CONFIG_BE2NET_BE3 */
+#ifdef CONFIG_BE2NET_BE2
#define BE2_chip(adapter) (adapter->pdev->device == BE_DEVICE_ID1 || \
adapter->pdev->device == OC_DEVICE_ID1)
+#else
+#define BE2_chip(adapter) (0)
+#endif /* CONFIG_BE2NET_BE2 */
#define BEx_chip(adapter) (BE3_chip(adapter) || BE2_chip(adapter))
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 8f755009ff38..d5b3f0139832 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -47,10 +47,14 @@ MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data.");
static struct workqueue_struct *be_err_recovery_workq;
static const struct pci_device_id be_dev_ids[] = {
+#ifdef CONFIG_BE2NET_BE2
{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
- { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
+#endif /* CONFIG_BE2NET_BE2 */
+#ifdef CONFIG_BE2NET_BE3
+ { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
+#endif /* CONFIG_BE2NET_BE3 */
{ PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)},
{ PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID4)},
{ PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID5)},
--
2.16.4
^ permalink raw reply related
* Re: [PATCH v6 10/18] x86/power/64: Remove VLA usage
From: Rafael J. Wysocki @ 2018-08-06 10:28 UTC (permalink / raw)
To: Kees Cook
Cc: Rafael J. Wysocki, Herbert Xu, Arnd Bergmann, Eric Biggers,
Gustavo A. R. Silva, Alasdair Kergon, Rabin Vincent, Tim Chen,
Pavel Machek, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
the arch/x86 maintainers, Philipp Reisner, Lars Ellenberg,
Jens Axboe, Giovanni Cabiddu, Mike Snitzer, Paul Mackerras,
Greg Kroah-Hartman <gregkh@
In-Reply-To: <CAGXu5j+NPCc2hq5x7JUwgKYvY6zKN28YdtHbHVapnpgC3GwCsg@mail.gmail.com>
On Wednesday, July 25, 2018 8:01:47 PM CEST Kees Cook wrote:
> On Wed, Jul 25, 2018 at 4:32 AM, Rafael J. Wysocki <rafael@kernel.org> wrote:
> > On Tue, Jul 24, 2018 at 6:49 PM, Kees Cook <keescook@chromium.org> wrote:
> >> In the quest to remove all stack VLA usage from the kernel[1], this
> >> removes the discouraged use of AHASH_REQUEST_ON_STACK by switching to
> >> shash directly and allocating the descriptor in heap memory (which should
> >> be fine: the tfm has already been allocated there too).
> >>
> >> [1] https://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com
> >>
> >> Signed-off-by: Kees Cook <keescook@chromium.org>
> >> Acked-by: Pavel Machek <pavel@ucw.cz>
> >
> > I think I can queue this up if there are no objections from others.
> >
> > Do you want me to do that?
>
> Sure thing. It looks like the other stand-alone patches like this one
> are getting taken into the non-crypto trees, so that's fine.
>
Applied now, thanks!
^ permalink raw reply
* Re: [PATCH 07/10] dt-bindings: phy: add DT binding for Microsemi Ocelot SerDes muxing
From: Quentin Schulz @ 2018-08-06 12:47 UTC (permalink / raw)
To: Andrew Lunn
Cc: alexandre.belloni, ralf, paul.burton, jhogan, robh+dt,
mark.rutland, davem, kishon, f.fainelli, linux-mips, devicetree,
linux-kernel, netdev, allan.nielsen, thomas.petazzoni
In-Reply-To: <20180801143147.GA16322@lunn.ch>
[-- Attachment #1: Type: text/plain, Size: 3468 bytes --]
Hi Andrew,
On Wed, Aug 01, 2018 at 04:31:47PM +0200, Andrew Lunn wrote:
> > > Maybe this should be serdes-mux? The SERDES itself should have some
> > > registers somewhere. If you ever decide to make use of phylink,
> > > e.g. to support SFP, you are going to need to know if the SERDES is
> > > up. So you might need to add the actual SERDES device, in addition to
> > > the mux for the SERDES.
> > >
> >
> > I'm not sure to follow.
> >
> > To be honest, I might have mislead you. The whole configuration of the
> > serdes is in the hsio register address space. For now, muxing is the
> > only reason there is a driver for the serdes but there are other things
> > that can be configured (though not used yet): de/serializer, input/output
> > buffers, PLL, ... configuration registers for the SerDes.
>
> When you are using the SERDES for networking, you need to know if the
> SERDES has achieved sync. For example, when the SERDES connects to an
> optical SFP module, the SERDES bit stream continues unmodified over
> the optical link to the SERDES in the peer. The optical module can
> tell you if it is receiving optical power, but it cannot tell you if
> the optical signal makes any sense. The SERDES however knows how to
> decode the bitstream, sync to it, etc. So you need some registers in
> the SERDES to get this status information. Typically, you can also get
> access to the SGMII/1000Base-X code word, so you can do
> auto-negotiation, or know if you need to send each bit 10 or 100 times
> in order to do 100Mbps or 10Mbps. If you are connecting to a PHY which
> can do > 1Gbps, you need to change the SERDES between SGMII,
> 1000Base-X, 2500Base-X, etc. Before you can say the link is up, you
> want the PHY to tell you it has link to its peer PHY, and you want to
> know the SERDES is ready. Typically the SERDES is last, since you
> don't know what to configure the SERDES to until the PHY is finished
> negotiating the link to its peer.
>
> If you look at any of the Marvell SERDES interfaces, found in PHYs or
> switches, there are dozens of registers for controlling the SERDES.
>
> Now, it could be we don't have a clear definition of what a SERDES
> is. The Marvell documents has a lot in its definition of SERDES, where
> as what you could be purely a 'dumb' parallel to serial convert, and
> all the rest of the logic is in the Ethernet MAC and the PCIe device?
>
> Now, back to my original point. Where are the registers for 'the rest
> of this logic'? If they are in the MAC address space, we don't have a
> problem. If they are somewhere else, maybe you will need to add
> another device. What is this device called? That is why i'm trying to
> differentiate between the 'SERDES-MUX' and the 'SERDES'.
>
If I've correctly read the datasheet of the switch, the sync status bit
is in the MAC address space. Same for 1000BASE-X/SGMII, autonegotiation.
The point I was trying to make was that this driver isn't only for
"muxing". There are also a handful of registers for
(electronically-related ?) features of SerDes (e.g. "control of phase
regulator logic", "deserializer phase control", a few
thresholds/hysteresis/frequencies, etc...
I understand that "serdes" isn't also fully matching the work done by
this driver as some features are handled within the MAC controller
address space.
Let me know if something bothers you/does not make sense,
Thanks,
Quentin
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH] Use Kconfig flag to remove support of deprecated BE2/BE3 adapters
From: Ivan Vecera @ 2018-08-06 13:03 UTC (permalink / raw)
To: Petr Oros, netdev
Cc: Sathya Perla, Ajit Khaparde, Sriharsha Basavapatna, Somnath Kotur,
David S. Miller, linux-kernel
In-Reply-To: <20180806121230.23690-1-poros@redhat.com>
On 6.8.2018 14:12, Petr Oros wrote:
> Add flags to remove support of deprecated BE2/BE3 adapters.
> BE2 disable will reduce .ko size by 2kb and BE3 by 3kb.
> Disable both will reduce .ko size by 9kb.
>
> With dissabled support is also removed coresponding PCI IDs
> and codepath with [BE2|BE3|BEx]_chip checks.
>
> New help style in Kconfig
>
> Signed-off-by: Petr Oros <poros@redhat.com>
Note that this should be placed to -next...
Reviewed-by: Ivan Vecera <ivecera@redhat.com>
> ---
> drivers/net/ethernet/emulex/benet/Kconfig | 20 ++++++++++++++++++--
> drivers/net/ethernet/emulex/benet/be.h | 8 ++++++++
> drivers/net/ethernet/emulex/benet/be_main.c | 6 +++++-
> 3 files changed, 31 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/emulex/benet/Kconfig b/drivers/net/ethernet/emulex/benet/Kconfig
> index b4853ec9de8d..68a9c40adc2a 100644
> --- a/drivers/net/ethernet/emulex/benet/Kconfig
> +++ b/drivers/net/ethernet/emulex/benet/Kconfig
> @@ -1,7 +1,7 @@
> config BE2NET
> tristate "ServerEngines' 10Gbps NIC - BladeEngine"
> depends on PCI
> - ---help---
> + help
> This driver implements the NIC functionality for ServerEngines'
> 10Gbps network adapter - BladeEngine.
>
> @@ -10,6 +10,22 @@ config BE2NET_HWMON
> depends on BE2NET && HWMON
> depends on !(BE2NET=y && HWMON=m)
> default y
> - ---help---
> + help
> Say Y here if you want to expose thermal sensor data on
> be2net network adapter.
> +
> +config BE2NET_BE2
> + bool "Support for deprecated BE2 chipsets"
> + depends on BE2NET
> + default y
> + help
> + Say Y here if you want to use deprecated Emulex devices based
> + on BE2 chipsets.
> +
> +config BE2NET_BE3
> + bool "Support for deprecated BE3 chipsets"
> + depends on BE2NET
> + default y
> + help
> + Say Y here if you want to use deprecated Emulex devices based
> + on BE3 chipsets.
> diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
> index 382891f81e09..3038578ec7a7 100644
> --- a/drivers/net/ethernet/emulex/benet/be.h
> +++ b/drivers/net/ethernet/emulex/benet/be.h
> @@ -779,11 +779,19 @@ static inline u16 be_max_any_irqs(struct be_adapter *adapter)
> #define skyhawk_chip(adapter) (adapter->pdev->device == OC_DEVICE_ID5 || \
> adapter->pdev->device == OC_DEVICE_ID6)
>
> +#ifdef CONFIG_BE2NET_BE3
> #define BE3_chip(adapter) (adapter->pdev->device == BE_DEVICE_ID2 || \
> adapter->pdev->device == OC_DEVICE_ID2)
> +#else
> +#define BE3_chip(adapter) (0)
> +#endif /* CONFIG_BE2NET_BE3 */
>
> +#ifdef CONFIG_BE2NET_BE2
> #define BE2_chip(adapter) (adapter->pdev->device == BE_DEVICE_ID1 || \
> adapter->pdev->device == OC_DEVICE_ID1)
> +#else
> +#define BE2_chip(adapter) (0)
> +#endif /* CONFIG_BE2NET_BE2 */
>
> #define BEx_chip(adapter) (BE3_chip(adapter) || BE2_chip(adapter))
>
> diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
> index 8f755009ff38..d5b3f0139832 100644
> --- a/drivers/net/ethernet/emulex/benet/be_main.c
> +++ b/drivers/net/ethernet/emulex/benet/be_main.c
> @@ -47,10 +47,14 @@ MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data.");
> static struct workqueue_struct *be_err_recovery_workq;
>
> static const struct pci_device_id be_dev_ids[] = {
> +#ifdef CONFIG_BE2NET_BE2
> { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
> - { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
> { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
> +#endif /* CONFIG_BE2NET_BE2 */
> +#ifdef CONFIG_BE2NET_BE3
> + { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
> { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
> +#endif /* CONFIG_BE2NET_BE3 */
> { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)},
> { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID4)},
> { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID5)},
>
^ permalink raw reply
* [PATCH RFC net-next 0/1] net/tls: Combined memory allocation for decryption request
From: Vakul Garg @ 2018-08-06 16:38 UTC (permalink / raw)
To: netdev; +Cc: borisp, aviadye, davejwatson, davem, Vakul Garg
This patch does a combined memory allocation from heap for scatterlists,
aead_request, aad and iv for the tls record decryption path. In present
code, aead_request is allocated from heap, scatterlists on a conditional
basis are allocated on heap or on stack. This is inefficient as it may
requires multiple kmalloc/kfree.
The initialization vector passed in cryption request is allocated on
stack. This is a problem since the stack memory is not dma-able from
crypto accelerators.
Doing one combined memory allocation for each decryption request fixes
both the above issues. It also paves a way to be able to submit multiple
async decryption requests while the previous one is pending i.e. being
processed or queued.
This patch has been built over Doron Roberts-Kedes's patch:
"net/tls: Calculate nsg for zerocopy path without skb_cow_data"
Vakul Garg (1):
net/tls: Combined memory allocation for decryption request
include/net/tls.h | 4 -
net/tls/tls_sw.c | 256 +++++++++++++++++++++++++++++++-----------------------
2 files changed, 147 insertions(+), 113 deletions(-)
--
2.13.6
^ permalink raw reply
* [PATCH RFC net-next 1/1] net/tls: Combined memory allocation for decryption request
From: Vakul Garg @ 2018-08-06 16:38 UTC (permalink / raw)
To: netdev; +Cc: borisp, aviadye, davejwatson, davem, Vakul Garg
In-Reply-To: <20180806163810.30880-1-vakul.garg@nxp.com>
For preparing decryption request, several memory chunks are required
(aead_req, sgin, sgout, iv, aad). For submitting the decrypt request to
an accelerator, it is required that the buffers which are read by the
accelerator must be dma-able and not come from stack. The buffers for
aad and iv can be separately kmalloced each, but it is inefficient.
This patch does a combined allocation for preparing decryption request
and then segments into aead_req || sgin || sgout || iv || aad.
Signed-off-by: Vakul Garg <vakul.garg@nxp.com>
---
include/net/tls.h | 4 -
net/tls/tls_sw.c | 257 +++++++++++++++++++++++++++++++-----------------------
2 files changed, 148 insertions(+), 113 deletions(-)
diff --git a/include/net/tls.h b/include/net/tls.h
index d8b3b6578c01..d5c683e8bb22 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -124,10 +124,6 @@ struct tls_sw_context_rx {
struct sk_buff *recv_pkt;
u8 control;
bool decrypted;
-
- char rx_aad_ciphertext[TLS_AAD_SPACE_SIZE];
- char rx_aad_plaintext[TLS_AAD_SPACE_SIZE];
-
};
struct tls_record_info {
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index cd5ed2d1dbe8..a478b06fc015 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -118,19 +118,13 @@ static int tls_do_decryption(struct sock *sk,
struct scatterlist *sgout,
char *iv_recv,
size_t data_len,
- struct sk_buff *skb,
- gfp_t flags)
+ struct aead_request *aead_req)
{
struct tls_context *tls_ctx = tls_get_ctx(sk);
struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
- struct aead_request *aead_req;
-
int ret;
- aead_req = aead_request_alloc(ctx->aead_recv, flags);
- if (!aead_req)
- return -ENOMEM;
-
+ aead_request_set_tfm(aead_req, ctx->aead_recv);
aead_request_set_ad(aead_req, TLS_AAD_SPACE_SIZE);
aead_request_set_crypt(aead_req, sgin, sgout,
data_len + tls_ctx->rx.tag_size,
@@ -139,8 +133,6 @@ static int tls_do_decryption(struct sock *sk,
crypto_req_done, &ctx->async_wait);
ret = crypto_wait_req(crypto_aead_decrypt(aead_req), &ctx->async_wait);
-
- aead_request_free(aead_req);
return ret;
}
@@ -727,8 +719,138 @@ static struct sk_buff *tls_wait_data(struct sock *sk, int flags,
return skb;
}
+/* This function decrypts the input skb into either out_iov or in out_sg
+ * or in skb buffers itself. The input parameter 'zc' indicates if
+ * zero-copy mode needs to be tried or not. With zero-copy mode, either
+ * out_iov or out_sg must be non-NULL. In case both out_iov and out_sg are
+ * NULL, then the decryption happens inside skb buffers itself, i.e.
+ * zero-copy gets disabled and 'zc' is updated.
+ */
+
+static int decrypt_internal(struct sock *sk, struct sk_buff *skb,
+ struct iov_iter *out_iov,
+ struct scatterlist *out_sg,
+ int *chunk, bool *zc)
+{
+ struct tls_context *tls_ctx = tls_get_ctx(sk);
+ struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
+ struct strp_msg *rxm = strp_msg(skb);
+ int n_sgin, n_sgout, nsg, mem_size, aead_size, err, pages = 0;
+ struct aead_request *aead_req;
+ struct sk_buff *unused;
+ u8 *aad, *iv, *mem = NULL;
+ struct scatterlist *sgin = NULL;
+ struct scatterlist *sgout = NULL;
+ const int data_len = rxm->full_len - tls_ctx->rx.overhead_size;
+
+ if (*zc && (out_iov || out_sg)) {
+ if (out_iov)
+ n_sgout = iov_iter_npages(out_iov, INT_MAX) + 1;
+ else if (out_sg)
+ n_sgout = sg_nents(out_sg);
+ else
+ goto no_zerocopy;
+
+ n_sgin = skb_nsg(skb, rxm->offset + tls_ctx->rx.prepend_size,
+ rxm->full_len - tls_ctx->rx.prepend_size);
+ } else {
+no_zerocopy:
+ n_sgout = 0;
+ *zc = false;
+ n_sgin = skb_cow_data(skb, 0, &unused);
+ }
+
+ if (n_sgin < 1)
+ return -EBADMSG;
+
+ /* Increment to accommodate AAD */
+ n_sgin = n_sgin + 1;
+
+ nsg = n_sgin + n_sgout;
+
+ aead_size = sizeof(*aead_req) + crypto_aead_reqsize(ctx->aead_recv);
+ mem_size = aead_size + (nsg * sizeof(struct scatterlist));
+ mem_size = mem_size + TLS_AAD_SPACE_SIZE;
+ mem_size = mem_size + crypto_aead_ivsize(ctx->aead_recv);
+
+ /* Allocate a single block of memory which contains
+ * aead_req || sgin[] || sgout[] || aad || iv.
+ * This order achieves correct alignment for aead_req, sgin, sgout.
+ */
+ mem = kmalloc(mem_size, sk->sk_allocation);
+ if (!mem)
+ return -ENOMEM;
+
+ /* Segment the allocated memory */
+ aead_req = (struct aead_request *)mem;
+ sgin = (struct scatterlist *)(mem + aead_size);
+ sgout = sgin + n_sgin;
+ aad = (u8 *)(sgout + n_sgout);
+ iv = aad + TLS_AAD_SPACE_SIZE;
+
+ /* Prepare IV */
+ err = skb_copy_bits(skb, rxm->offset + TLS_HEADER_SIZE,
+ iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
+ tls_ctx->rx.iv_size);
+ if (err < 0) {
+ kfree(mem);
+ return err;
+ }
+ memcpy(iv, tls_ctx->rx.iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
+
+ /* Prepare AAD */
+ tls_make_aad(aad, rxm->full_len - tls_ctx->rx.overhead_size,
+ tls_ctx->rx.rec_seq, tls_ctx->rx.rec_seq_size,
+ ctx->control);
+
+ /* Prepare sgin */
+ sg_init_table(sgin, n_sgin);
+ sg_set_buf(&sgin[0], aad, TLS_AAD_SPACE_SIZE);
+ err = skb_to_sgvec(skb, &sgin[1],
+ rxm->offset + tls_ctx->rx.prepend_size,
+ rxm->full_len - tls_ctx->rx.prepend_size);
+ if (err < 0) {
+ kfree(mem);
+ return err;
+ }
+
+ if (n_sgout) {
+ if (out_iov) {
+ sg_init_table(sgout, n_sgout);
+ sg_set_buf(&sgout[0], aad, TLS_AAD_SPACE_SIZE);
+
+ *chunk = 0;
+ err = zerocopy_from_iter(sk, out_iov, data_len, &pages,
+ chunk, &sgout[1],
+ (n_sgout - 1), false);
+ if (err < 0)
+ goto fallback_to_reg_recv;
+ } else if (out_sg) {
+ memcpy(sgout, out_sg, n_sgout * sizeof(*sgout));
+ } else {
+ goto fallback_to_reg_recv;
+ }
+ } else {
+fallback_to_reg_recv:
+ sgout = sgin;
+ pages = 0;
+ *chunk = 0;
+ *zc = false;
+ }
+
+ /* Prepare and submit AEAD request */
+ err = tls_do_decryption(sk, sgin, sgout, iv, data_len, aead_req);
+
+ /* Release the pages in case iov was mapped to pages */
+ for (; pages > 0; pages--)
+ put_page(sg_page(&sgout[pages]));
+
+ kfree(mem);
+ return err;
+}
+
static int decrypt_skb_update(struct sock *sk, struct sk_buff *skb,
- struct scatterlist *sgout, bool *zc)
+ struct iov_iter *dest, int *chunk, bool *zc)
{
struct tls_context *tls_ctx = tls_get_ctx(sk);
struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
@@ -741,7 +863,7 @@ static int decrypt_skb_update(struct sock *sk, struct sk_buff *skb,
return err;
#endif
if (!ctx->decrypted) {
- err = decrypt_skb(sk, skb, sgout);
+ err = decrypt_internal(sk, skb, dest, NULL, chunk, zc);
if (err < 0)
return err;
} else {
@@ -760,67 +882,10 @@ static int decrypt_skb_update(struct sock *sk, struct sk_buff *skb,
int decrypt_skb(struct sock *sk, struct sk_buff *skb,
struct scatterlist *sgout)
{
- struct tls_context *tls_ctx = tls_get_ctx(sk);
- struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
- char iv[TLS_CIPHER_AES_GCM_128_SALT_SIZE + MAX_IV_SIZE];
- struct scatterlist sgin_arr[MAX_SKB_FRAGS + 2];
- struct scatterlist *sgin = &sgin_arr[0];
- struct strp_msg *rxm = strp_msg(skb);
- int ret, nsg;
- struct sk_buff *unused;
-
- ret = skb_copy_bits(skb, rxm->offset + TLS_HEADER_SIZE,
- iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
- tls_ctx->rx.iv_size);
- if (ret < 0)
- return ret;
-
- memcpy(iv, tls_ctx->rx.iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
- if (!sgout) {
- nsg = skb_cow_data(skb, 0, &unused);
- } else {
- nsg = skb_nsg(skb,
- rxm->offset + tls_ctx->rx.prepend_size,
- rxm->full_len - tls_ctx->rx.prepend_size);
- if (nsg <= 0)
- return nsg;
- }
-
- // We need one extra for ctx->rx_aad_ciphertext
- nsg++;
-
- if (nsg > ARRAY_SIZE(sgin_arr))
- sgin = kmalloc_array(nsg, sizeof(*sgin), sk->sk_allocation);
-
- if (!sgout)
- sgout = sgin;
-
- sg_init_table(sgin, nsg);
- sg_set_buf(&sgin[0], ctx->rx_aad_ciphertext, TLS_AAD_SPACE_SIZE);
-
- nsg = skb_to_sgvec(skb, &sgin[1],
- rxm->offset + tls_ctx->rx.prepend_size,
- rxm->full_len - tls_ctx->rx.prepend_size);
- if (nsg < 0) {
- ret = nsg;
- goto out;
- }
-
- tls_make_aad(ctx->rx_aad_ciphertext,
- rxm->full_len - tls_ctx->rx.overhead_size,
- tls_ctx->rx.rec_seq,
- tls_ctx->rx.rec_seq_size,
- ctx->control);
-
- ret = tls_do_decryption(sk, sgin, sgout, iv,
- rxm->full_len - tls_ctx->rx.overhead_size,
- skb, sk->sk_allocation);
-
-out:
- if (sgin != &sgin_arr[0])
- kfree(sgin);
+ bool zc = true;
+ int chunk;
- return ret;
+ return decrypt_internal(sk, skb, NULL, sgout, &chunk, &zc);
}
static bool tls_sw_advance_skb(struct sock *sk, struct sk_buff *skb,
@@ -899,43 +964,17 @@ int tls_sw_recvmsg(struct sock *sk,
}
if (!ctx->decrypted) {
- int page_count;
- int to_copy;
-
- page_count = iov_iter_npages(&msg->msg_iter,
- MAX_SKB_FRAGS);
- to_copy = rxm->full_len - tls_ctx->rx.overhead_size;
- if (!is_kvec && to_copy <= len && page_count < MAX_SKB_FRAGS &&
- likely(!(flags & MSG_PEEK))) {
- struct scatterlist sgin[MAX_SKB_FRAGS + 1];
- int pages = 0;
+ int to_copy = rxm->full_len - tls_ctx->rx.overhead_size;
+ if (!is_kvec && to_copy <= len &&
+ likely(!(flags & MSG_PEEK)))
zc = true;
- sg_init_table(sgin, MAX_SKB_FRAGS + 1);
- sg_set_buf(&sgin[0], ctx->rx_aad_plaintext,
- TLS_AAD_SPACE_SIZE);
-
- err = zerocopy_from_iter(sk, &msg->msg_iter,
- to_copy, &pages,
- &chunk, &sgin[1],
- MAX_SKB_FRAGS, false);
- if (err < 0)
- goto fallback_to_reg_recv;
-
- err = decrypt_skb_update(sk, skb, sgin, &zc);
- for (; pages > 0; pages--)
- put_page(sg_page(&sgin[pages]));
- if (err < 0) {
- tls_err_abort(sk, EBADMSG);
- goto recv_end;
- }
- } else {
-fallback_to_reg_recv:
- err = decrypt_skb_update(sk, skb, NULL, &zc);
- if (err < 0) {
- tls_err_abort(sk, EBADMSG);
- goto recv_end;
- }
+
+ err = decrypt_skb_update(sk, skb, &msg->msg_iter,
+ &chunk, &zc);
+ if (err < 0) {
+ tls_err_abort(sk, EBADMSG);
+ goto recv_end;
}
ctx->decrypted = true;
}
@@ -986,7 +1025,7 @@ ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos,
int err = 0;
long timeo;
int chunk;
- bool zc;
+ bool zc = false;
lock_sock(sk);
@@ -1003,7 +1042,7 @@ ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos,
}
if (!ctx->decrypted) {
- err = decrypt_skb_update(sk, skb, NULL, &zc);
+ err = decrypt_skb_update(sk, skb, NULL, &chunk, &zc);
if (err < 0) {
tls_err_abort(sk, EBADMSG);
--
2.13.6
^ permalink raw reply related
* e1000e driver stuck at 10Mbps after reconnection
From: Camille Bordignon @ 2018-08-06 11:59 UTC (permalink / raw)
To: Jeff Kirsher; +Cc: David S. Miller, intel-wired-lan, netdev
Hello,
Recently we experienced some issues with intel NIC (I219-LM and I219-V).
It seems that after a wire reconnection, auto-negotation "fails" and
link speed drips to 10 Mbps.
>From kernel logs:
[17616.346150] e1000e: enp0s31f6 NIC Link is Down
[17627.003322] e1000e: enp0s31f6 NIC Link is Up 10 Mbps Full Duplex, Flow Control: None
[17627.003325] e1000e 0000:00:1f.6 enp0s31f6: 10/100 speed: disabling TSO
$ethtool enp0s31f6
Settings for enp0s31f6:
Supported ports: [ TP ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Supported pause frame use: No
Supports auto-negotiation: Yes
Supported FEC modes: Not reported
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Advertised pause frame use: No
Advertised auto-negotiation: Yes
Advertised FEC modes: Not reported
Speed: 10Mb/s
Duplex: Full
Port: Twisted Pair
PHYAD: 1
Transceiver: internal
Auto-negotiation: on
MDI-X: on (auto)
Supports Wake-on: pumbg
Wake-on: g
Current message level: 0x00000007 (7)
drv probe link
Link detected: yes
Notice that if disconnection last less than about 5 seconds,
nothing wrong happens.
And if after last failure, disconnection / connection occurs again and
last less than 5 seconds, link speed is back to 1000 Mbps.
[18075.350678] e1000e: enp0s31f6 NIC Link is Down
[18078.716245] e1000e: enp0s31f6 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None
The following patch seems to fix this issue.
However I don't clearly understand why.
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 3ba0c90e7055..763c013960f1 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -5069,7 +5069,7 @@ static bool e1000e_has_link(struct e1000_adapter *adapter)
case e1000_media_type_copper:
if (hw->mac.get_link_status) {
ret_val = hw->mac.ops.check_for_link(hw);
- link_active = !hw->mac.get_link_status;
+ link_active = false;
} else {
link_active = true;
}
Maybe this is related to watchdog task.
I've found out this fix by comparing with last commit that works fine :
commit 0b76aae741abb9d16d2c0e67f8b1e766576f897d.
However I don't know if this information is relevant.
Thank you.
Camille Bordignon
^ permalink raw reply related
* Re: [PATCH] Bluetooth: remove redundant variables 'adv_set' and 'cp'
From: Johan Hedberg @ 2018-08-06 14:09 UTC (permalink / raw)
To: YueHaibing; +Cc: marcel, linux-kernel, netdev, davem, linux-bluetooth
In-Reply-To: <20180806110851.8568-1-yuehaibing@huawei.com>
Hi YueHaibing,
On Mon, Aug 06, 2018, YueHaibing wrote:
> Variables 'adv_set' and 'cp' are being assigned but are never used hence
> they are redundant and can be removed.
>
> Cleans up clang warnings:
> net/bluetooth/hci_event.c:1135:29: warning: variable 'adv_set' set but not used [-Wunused-but-set-variable]
> net/bluetooth/mgmt.c:3359:39: warning: variable 'cp' set but not used [-Wunused-but-set-variable]
>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> ---
> net/bluetooth/hci_event.c | 3 ---
> net/bluetooth/mgmt.c | 3 ---
> 2 files changed, 6 deletions(-)
Applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* [PATCH net-next] ip6_tunnel: collect_md xmit: Use ip_tunnel_key's provided src address
From: Shmulik Ladkani @ 2018-08-06 12:00 UTC (permalink / raw)
To: David S . Miller; +Cc: Alexei Starovoitov, netdev, shmulik, Shmulik Ladkani
When using an ip6tnl device in collect_md mode, the xmit methods ignore
the ipv6.src field present in skb_tunnel_info's key, both for route
calculation purposes (flowi6 construction) and for assigning the
packet's final ipv6h->saddr.
This makes it impossible specifying a desired ipv6 local address in the
encapsulating header (for example, when using tc action tunnel_key).
This is also not aligned with behavior of ipip (ipv4) in collect_md
mode, where the key->u.ipv4.src gets used.
Fix, by assigning fl6.saddr with given key->u.ipv6.src.
In case ipv6.src is not specified, ip6_tnl_xmit uses existing saddr
selection code.
Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
Reviewed-by: Eyal Birger <eyal.birger@gmail.com>
Fixes: 8d79266bc48c ("ip6_tunnel: add collect_md mode to IPv6 tunnels")
---
net/ipv6/ip6_tunnel.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 00e138a44cbb..820cebe0c687 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1113,7 +1113,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
dst = NULL;
goto tx_err_link_failure;
}
- if (t->parms.collect_md &&
+ if (t->parms.collect_md && ipv6_addr_any(&fl6->saddr) &&
ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
&fl6->daddr, 0, &fl6->saddr))
goto tx_err_link_failure;
@@ -1255,6 +1255,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
key = &tun_info->key;
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_proto = IPPROTO_IPIP;
+ fl6.saddr = key->u.ipv6.src;
fl6.daddr = key->u.ipv6.dst;
fl6.flowlabel = key->label;
dsfield = key->tos;
@@ -1326,6 +1327,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
key = &tun_info->key;
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_proto = IPPROTO_IPV6;
+ fl6.saddr = key->u.ipv6.src;
fl6.daddr = key->u.ipv6.dst;
fl6.flowlabel = key->label;
dsfield = key->tos;
--
2.18.0
^ permalink raw reply related
* [PATCH] can: sja1000: plx_pci: add support for ASEM CAN raw device
From: Flavio Suligoi @ 2018-08-06 12:00 UTC (permalink / raw)
To: Wolfgang Grandegger, Marc Kleine-Budde
Cc: David S . Miller, linux-can, netdev, linux-kernel, Flavio Suligoi
This patch adds support for ASEM opto-isolated dual channels
CAN raw device (http://www.asem.it)
Signed-off-by: Flavio Suligoi <f.suligoi@asem.it>
---
drivers/net/can/sja1000/Kconfig | 1 +
drivers/net/can/sja1000/plx_pci.c | 68 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig
index 1e65cb6..f6dc899 100644
--- a/drivers/net/can/sja1000/Kconfig
+++ b/drivers/net/can/sja1000/Kconfig
@@ -88,6 +88,7 @@ config CAN_PLX_PCI
- TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/)
- IXXAT Automation PC-I 04/PCI card (http://www.ixxat.com/)
- Connect Tech Inc. CANpro/104-Plus Opto (CRG001) card (http://www.connecttech.com)
+ - ASEM CAN raw - 2 isolated CAN channels (www.asem.it)
config CAN_TSCAN1
tristate "TS-CAN1 PC104 boards"
diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c
index f8ff25c..864fe8d 100644
--- a/drivers/net/can/sja1000/plx_pci.c
+++ b/drivers/net/can/sja1000/plx_pci.c
@@ -46,7 +46,8 @@ MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, "
"esd CAN-PCIe/2000, "
"Connect Tech Inc. CANpro/104-Plus Opto (CRG001), "
"IXXAT PC-I 04/PCI, "
- "ELCUS CAN-200-PCI")
+ "ELCUS CAN-200-PCI, "
+ "ASEM DUAL CAN-RAW")
MODULE_LICENSE("GPL v2");
#define PLX_PCI_MAX_CHAN 2
@@ -70,7 +71,9 @@ struct plx_pci_card {
*/
#define PLX_LINT1_EN 0x1 /* Local interrupt 1 enable */
+#define PLX_LINT1_POL (1 << 1) /* Local interrupt 1 polarity */
#define PLX_LINT2_EN (1 << 3) /* Local interrupt 2 enable */
+#define PLX_LINT2_POL (1 << 4) /* Local interrupt 1 polarity */
#define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */
#define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */
@@ -92,6 +95,9 @@ struct plx_pci_card {
*/
#define PLX_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
+/* OCR setting for ASEM Dual CAN raw */
+#define ASEM_PCI_OCR 0xfe
+
/*
* In the CDR register, you should set CBP to 1.
* You will probably also want to set the clock divider value to 7
@@ -145,10 +151,20 @@ struct plx_pci_card {
#define MOXA_PCI_VENDOR_ID 0x1393
#define MOXA_PCI_DEVICE_ID 0x0100
+#define ASEM_DUAL_CAN_VENDOR_ID 0x10b5
+#define ASEM_DUAL_CAN_DEVICE_ID 0x9030
+#define ASEM_DUAL_CAN_SUB_VENDOR_ID 0x3000
+#define ASEM_DUAL_CAN_SUB_DEVICE_ID 0x1001
+#define ASEM_DUAL_CAN_SUB_DEVICE_ID_BIS 0x1002
+#define ASEM_DUAL_CAN_RESET_REGISTER 0x54
+#define ASEM_DUAL_CAN_RESET_MASK_CAN1 0x20
+#define ASEM_DUAL_CAN_RESET_MASK_CAN2 0x04
+
static void plx_pci_reset_common(struct pci_dev *pdev);
static void plx9056_pci_reset_common(struct pci_dev *pdev);
static void plx_pci_reset_marathon_pci(struct pci_dev *pdev);
static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev);
+static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev);
struct plx_pci_channel_map {
u32 bar;
@@ -269,6 +285,14 @@ static struct plx_pci_card_info plx_pci_card_info_moxa = {
/* based on PLX9052 */
};
+static struct plx_pci_card_info plx_pci_card_info_asem_dual_can = {
+ "ASEM Dual CAN raw PCI", 2,
+ PLX_PCI_CAN_CLOCK, ASEM_PCI_OCR, PLX_PCI_CDR,
+ {0, 0x00, 0x00}, { {2, 0x00, 0x00}, {4, 0x00, 0x00} },
+ &plx_pci_reset_asem_dual_can_raw
+ /* based on PLX9030 */
+};
+
static const struct pci_device_id plx_pci_tbl[] = {
{
/* Adlink PCI-7841/cPCI-7841 */
@@ -375,6 +399,20 @@ static const struct pci_device_id plx_pci_tbl[] = {
0, 0,
(kernel_ulong_t)&plx_pci_card_info_moxa
},
+ {
+ /* ASEM Dual CAN raw */
+ ASEM_DUAL_CAN_VENDOR_ID, ASEM_DUAL_CAN_DEVICE_ID,
+ ASEM_DUAL_CAN_SUB_VENDOR_ID, ASEM_DUAL_CAN_SUB_DEVICE_ID,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_asem_dual_can
+ },
+ {
+ /* ASEM Dual CAN raw -new model */
+ ASEM_DUAL_CAN_VENDOR_ID, ASEM_DUAL_CAN_DEVICE_ID,
+ ASEM_DUAL_CAN_SUB_VENDOR_ID, ASEM_DUAL_CAN_SUB_DEVICE_ID_BIS,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_asem_dual_can
+ },
{ 0,}
};
MODULE_DEVICE_TABLE(pci, plx_pci_tbl);
@@ -524,6 +562,34 @@ static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev)
}
}
+/* Special reset function for ASEM Dual CAN raw card */
+static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev)
+{
+ void __iomem *bar0_addr;
+ static const int reset_bar;
+ u8 tmpval;
+
+ plx_pci_reset_common(pdev);
+
+ bar0_addr = pci_iomap(pdev, reset_bar, 0);
+ if (!bar0_addr) {
+ dev_err(&pdev->dev, "Failed to remap reset "
+ "space %d (BAR%d)\n", 0, reset_bar);
+ } else {
+ /* reset the two SJA1000 chips */
+ tmpval = ioread8(bar0_addr + ASEM_DUAL_CAN_RESET_REGISTER);
+ tmpval &= ~(ASEM_DUAL_CAN_RESET_MASK_CAN1 |
+ ASEM_DUAL_CAN_RESET_MASK_CAN2);
+ iowrite8(tmpval, bar0_addr + ASEM_DUAL_CAN_RESET_REGISTER);
+ usleep_range(300, 400);
+ tmpval |= ASEM_DUAL_CAN_RESET_MASK_CAN1 |
+ ASEM_DUAL_CAN_RESET_MASK_CAN2;
+ iowrite8(tmpval, bar0_addr + ASEM_DUAL_CAN_RESET_REGISTER);
+ usleep_range(300, 400);
+ pci_iounmap(pdev, bar0_addr);
+ }
+}
+
static void plx_pci_del_card(struct pci_dev *pdev)
{
struct plx_pci_card *card = pci_get_drvdata(pdev);
--
2.7.4
^ permalink raw reply related
* Re: [endianness bug?] cxgb4_next_header .match_val/.match_mask should be net-endian
From: Rahul Lakkireddy @ 2018-08-06 12:12 UTC (permalink / raw)
To: Al Viro; +Cc: netdev@vger.kernel.org, ganeshgr, David S. Miller
In-Reply-To: <20180805152811.GF15082@ZenIV.linux.org.uk>
On Sunday, August 08/05/18, 2018 at 20:58:11 +0530, Al Viro wrote:
> AFAICS, cxgb4_next_header() expects to find match_val/match_mask in
> struct cxgb4_next_header stored as big-endian:
>
> /* Found a possible candidate. Find a key that
> * matches the corresponding offset, value, and
> * mask to jump to next header.
> */
> for (j = 0; j < cls->knode.sel->nkeys; j++) {
> off = cls->knode.sel->keys[j].off;
> val = cls->knode.sel->keys[j].val;
> mask = cls->knode.sel->keys[j].mask;
>
> if (next[i].match_off == off &&
> next[i].match_val == val &&
> next[i].match_mask == mask) {
> found = true;
> break;
> }
> }
>
> Here ->keys[] is struct tc_u32_key and there mask and val are definitely
> __be32. match_val and match_mask are never changed after initialization
> and they are set to:
>
> * .match_off = 8, .match_val = 0x600, .match_mask = 0xFF00
> meant to check for IPV4.Protocol == TCP, i.e. octet at offset 9 being 6
> * .match_off = 8, .match_val = 0x1100, .match_mask = 0xFF00
> meant to check for IPV4.Protocol == UDP, i.e. octet at offset 9 being 0x11
> * .match_off = 4, .match_val = 0x60000, .match_mask = 0xFF0000
> IPV6.NextHeader == TCP, i.e. octet at offset 6 being 6
> * .match_off = 4, .match_val = 0x110000, .match_mask = 0xFF0000
> IPV6.NextHeader == UDP, i.e. octet at offset 6 being 0x11
>
> On little-endian host those do yield the right values - e.g. 0x1100 is
> {0, 17, 0, 0}, etc. On big-endian, though, these will end up checking
> in IPv4 case the octet at offset 10 (i.e. upper 16 bits of checksum) and for IPv6
> - the octet at offset 5 (i.e. the lower 8 bits of payload length).
>
> Unless I'm misreading that code, it needs the following to do the right
> thing both on l-e and b-e. Comments?
>
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
> ---
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32_parse.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32_parse.h
> index a4b99edcc339..ec226b1cebf4 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32_parse.h
> +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32_parse.h
> @@ -259,11 +259,11 @@ struct cxgb4_next_header {
> */
> static const struct cxgb4_next_header cxgb4_ipv4_jumps[] = {
> { .offset = 0, .offoff = 0, .shift = 6, .mask = 0xF,
> - .match_off = 8, .match_val = 0x600, .match_mask = 0xFF00,
> - .jump = cxgb4_tcp_fields },
> + .match_off = 8, .match_val = htonl(6 << 16),
> + .match_mask = htonl(0xff<<16), .jump = cxgb4_tcp_fields },
> { .offset = 0, .offoff = 0, .shift = 6, .mask = 0xF,
> - .match_off = 8, .match_val = 0x1100, .match_mask = 0xFF00,
> - .jump = cxgb4_udp_fields },
> + .match_off = 8, .match_val = htonl(17 << 16),
> + .match_mask = htonl(0xff<<16), .jump = cxgb4_udp_fields },
> { .jump = NULL }
> };
>
> @@ -272,11 +272,11 @@ static const struct cxgb4_next_header cxgb4_ipv4_jumps[] = {
> */
> static const struct cxgb4_next_header cxgb4_ipv6_jumps[] = {
> { .offset = 0x28, .offoff = 0, .shift = 0, .mask = 0,
> - .match_off = 4, .match_val = 0x60000, .match_mask = 0xFF0000,
> - .jump = cxgb4_tcp_fields },
> + .match_off = 4, .match_val = htonl(6 << 8),
> + .match_mask = htonl(0xff << 8), .jump = cxgb4_tcp_fields },
> { .offset = 0x28, .offoff = 0, .shift = 0, .mask = 0,
> - .match_off = 4, .match_val = 0x110000, .match_mask = 0xFF0000,
> - .jump = cxgb4_udp_fields },
> + .match_off = 4, .match_val = htonl(17 << 8),
> + .match_mask = htonl(0xff << 8), .jump = cxgb4_udp_fields },
> { .jump = NULL }
> };
>
Your observation is correct. The current logic is broken for
Big-Endian. Thanks for fixing it up Al!
As you've already found in the other email thread, ->mask also
needs to be fixed. Should be ".mask = htons(0xf << 8)".
Thanks,
Rahul
^ permalink raw reply
* Re: [endianness bug] cxgb4: mk_act_open_req() buggers ->{local,peer}_ip on big-endian hosts
From: Rahul Lakkireddy @ 2018-08-06 12:15 UTC (permalink / raw)
To: Al Viro; +Cc: ganeshgr, David Miller, netdev@vger.kernel.org
In-Reply-To: <20180805172238.GH15082@ZenIV.linux.org.uk>
On Sunday, August 08/05/18, 2018 at 22:52:38 +0530, Al Viro wrote:
> Unlike fs.val.lport and fs.val.fport, cxgb4_process_flow_match()
> sets fs.val.{l,f}ip to net-endian values without conversion - they come
> straight from flow_dissector_key_ipv4_addrs ->dst and ->src resp. So
> the assignment in mk_act_open_req() ought to be a straigh copy.
>
> As far as I know, T4 PCIe cards do exist, so it's not as if that
> thing could only be found on little-endian systems...
>
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
> ---
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
> index 00fc5f1afb1d..7dddb9e748b8 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
> +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
> @@ -1038,10 +1038,8 @@ static void mk_act_open_req(struct filter_entry *f, struct sk_buff *skb,
> OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ACT_OPEN_REQ, qid_filterid));
> req->local_port = cpu_to_be16(f->fs.val.lport);
> req->peer_port = cpu_to_be16(f->fs.val.fport);
> - req->local_ip = f->fs.val.lip[0] | f->fs.val.lip[1] << 8 |
> - f->fs.val.lip[2] << 16 | f->fs.val.lip[3] << 24;
> - req->peer_ip = f->fs.val.fip[0] | f->fs.val.fip[1] << 8 |
> - f->fs.val.fip[2] << 16 | f->fs.val.fip[3] << 24;
> + memcpy(&req->local_ip, f->fs.val.lip, 4);
> + memcpy(&req->peer_ip, f->fs.val.fip, 4);
> req->opt0 = cpu_to_be64(NAGLE_V(f->fs.newvlan == VLAN_REMOVE ||
> f->fs.newvlan == VLAN_REWRITE) |
> DELACK_V(f->fs.hitcnts) |
Thanks for fix Al!
Acked-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
^ permalink raw reply
* Re: [pull request][net-next 00/10] Mellanox, mlx5 and devlink updates 2018-07-31
From: Eran Ben Elisha @ 2018-08-06 13:01 UTC (permalink / raw)
To: Jakub Kicinski
Cc: David Miller, saeedm, netdev, jiri, alexander.duyck, helgaas
In-Reply-To: <20180802155315.48aaab19@cakuba.netronome.com>
>>
>> Hi Dave,
>> I would like to re-state that this feature was not meant to be a generic
>> one. This feature was added in order to resolve a HW bug which exist in
>> a small portion of our devices.
>
> Would you mind describing the HW bug in more detail? To a outside
> reviewer it really looks like you're adding a feature. What are you
> working around? Is the lack of full AQM on the PCIe side of the chip
> considered a bug?
In multiple function environment, there is an issue with buffer
allocation per function which may lead to starvation. There is an HW WA
for mitigate this starvation by identifying this state and apply early
drop/mark.
>
>> Those params will be used only on those current HWs and won't be in
>> use for our future devices.
>
> I'm glad that is your plan today, however, customers may get used to
> the simple interface you're adding now. This means the API you are
> adding is effectively becoming an API other drivers may need to
> implement to keep compatibility with someone's proprietary
> orchestration.
This issue was refactored, thus no need to have this WA at all in future
NICs. So I don't believe we will end up in the situation you are describing.
It is less likely that other vendors will be facing the same issue and
will have to support such param. it was burn out of a bug and not as a
feature which other may follow.
>
>> During the discussions, several alternatives where offered to be used by
>> various members of the community. These alternatives includes TC and
>> enhancements to PCI configuration tools.
>>
>> Regarding the TC, from my perspective, this is not an option as:
>> 1) The HW mechanism handles multiple functions and therefore cannot be
>> configured on as a regular TC
>
> Could you elaborate? What are the multiple functions? You seem to be
> adding a knob to enable ECN marking and a knob for choosing between
> some predefined slopes.
PSB, The sloped are dynamic and enabled in a dynamic way.
Indeed, we are adding a very specific knob for very non standard
specific issue which can be used in addition to standard ECN marking.
>
> In what way would your solution not behave like a RED offload?
Existing Algo (RED, PIE, etc) are static, configurable. Our HW WA is
dynamic (dynamic slope), adjusted and auto enabled.
>
> With TC offload you'd also get a well-defined set of statistics, I
> presume right now you're planning on adding a set of ethtool -S
> counters?
>
>> 2) No PF + representors modeling can be applied here, this is a
>> MultiHost environment where one host is not aware to the other hosts,
>> and each is running on its own pci/driver. It is a device working mode
>> configuration.
>
> Yes, the multihost part makes it less pleasant. But this is a problem
> we have to tackle separately, at some point. It's not a center of
> attention here.
Agree, however the multihost part makes it non-transparent if we chose a
solution which is not based on direct vendor configuration. This will
lead to a bad user experience.
>
>> 3) The current HW W/A is very limited, maybe it has a similar algorithm
>> as WRED, but is being used for much simpler different use case (pci bus
>> congestion).
>
> No one is requesting full RED offload here.. if someone sets the
> parameters you can't support you simply won't offload them. And ignore
> the parameters which only make sense in software terms. Look at the
> docs for mlxsw:
>
> https://github.com/Mellanox/mlxsw/wiki/Queues-Management#offloading-red
>
> It says "not offloaded" in a number of places.
>
>> It cannot be compared to a standard TC capability (RED/WRED), and
>> defining it as a offload fully controlled by the user will be a big
>> misuse.
>
> It's generally preferable to implement a subset of exiting well defined
> API than create vendor knobs, hence hardly a misuse.
As written above, this is not the case here.
>
>> (for example, drop rate cannot be configured)
>
> I don't know what "configuring drop rate" means in case of RED..
>
>> regarding the PCI config tools, there was a consensus that such tool is
>> not acceptable as it is not a part of the PCI spec.
>
> As I said, this has nothing to do with PCI being the transport. The
> port you're running over could be serial, SPI or anything else. You
> have congestion on a port of a device, that's a networking problem.
>
>> Since module param/sysfs/debugfs/etc are no longer acceptable, and
>> current drivers still desired with a way to do some configurations to
>> the device/driver which cannot used standard Linux tool or by other
>> vendors, devlink params was developed (under the assumption that this
>> tool will be helpful for those needs, and those only).
>>
>> From my perspective, Devlink is the tool to configure the device for
>> handling such unexpected bugs, i.e "PCIe buffer congestion handling
>> workaround".
>
> Hm. Are you calling it a bug because you had to work around silicon
> limitation in firmware? Hm. I'm very intrigued by the framing :)
>
^ permalink raw reply
* [PATCH v2] can: sja1000: plx_pci: add support for ASEM CAN raw device
From: Flavio Suligoi @ 2018-08-06 13:17 UTC (permalink / raw)
To: Wolfgang Grandegger, Marc Kleine-Budde
Cc: David S . Miller, linux-can, netdev, linux-kernel, Flavio Suligoi
In-Reply-To: <a6b6906d-6f53-9bf2-d87e-49ae3f208f00@pengutronix.de>
This patch adds support for ASEM opto-isolated dual channels
CAN raw device (http://www.asem.it)
Signed-off-by: Flavio Suligoi <f.suligoi@asem.it>
---
v2: - renamed ASEM_... constants to reduce space size;
- remove "else" in "plx_pci_reset_asem_dual_can_raw" function to avoid
strings breaking
drivers/net/can/sja1000/Kconfig | 1 +
drivers/net/can/sja1000/plx_pci.c | 67 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig
index 1e65cb6..f6dc899 100644
--- a/drivers/net/can/sja1000/Kconfig
+++ b/drivers/net/can/sja1000/Kconfig
@@ -88,6 +88,7 @@ config CAN_PLX_PCI
- TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/)
- IXXAT Automation PC-I 04/PCI card (http://www.ixxat.com/)
- Connect Tech Inc. CANpro/104-Plus Opto (CRG001) card (http://www.connecttech.com)
+ - ASEM CAN raw - 2 isolated CAN channels (www.asem.it)
config CAN_TSCAN1
tristate "TS-CAN1 PC104 boards"
diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c
index f8ff25c..d8dfa06 100644
--- a/drivers/net/can/sja1000/plx_pci.c
+++ b/drivers/net/can/sja1000/plx_pci.c
@@ -46,7 +46,8 @@ MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, "
"esd CAN-PCIe/2000, "
"Connect Tech Inc. CANpro/104-Plus Opto (CRG001), "
"IXXAT PC-I 04/PCI, "
- "ELCUS CAN-200-PCI")
+ "ELCUS CAN-200-PCI, "
+ "ASEM DUAL CAN-RAW")
MODULE_LICENSE("GPL v2");
#define PLX_PCI_MAX_CHAN 2
@@ -70,7 +71,9 @@ struct plx_pci_card {
*/
#define PLX_LINT1_EN 0x1 /* Local interrupt 1 enable */
+#define PLX_LINT1_POL (1 << 1) /* Local interrupt 1 polarity */
#define PLX_LINT2_EN (1 << 3) /* Local interrupt 2 enable */
+#define PLX_LINT2_POL (1 << 4) /* Local interrupt 1 polarity */
#define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */
#define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */
@@ -92,6 +95,9 @@ struct plx_pci_card {
*/
#define PLX_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
+/* OCR setting for ASEM Dual CAN raw */
+#define ASEM_PCI_OCR 0xfe
+
/*
* In the CDR register, you should set CBP to 1.
* You will probably also want to set the clock divider value to 7
@@ -145,10 +151,20 @@ struct plx_pci_card {
#define MOXA_PCI_VENDOR_ID 0x1393
#define MOXA_PCI_DEVICE_ID 0x0100
+#define ASEM_RAW_CAN_VENDOR_ID 0x10b5
+#define ASEM_RAW_CAN_DEVICE_ID 0x9030
+#define ASEM_RAW_CAN_SUB_VENDOR_ID 0x3000
+#define ASEM_RAW_CAN_SUB_DEVICE_ID 0x1001
+#define ASEM_RAW_CAN_SUB_DEVICE_ID_BIS 0x1002
+#define ASEM_RAW_CAN_RST_REGISTER 0x54
+#define ASEM_RAW_CAN_RST_MASK_CAN1 0x20
+#define ASEM_RAW_CAN_RST_MASK_CAN2 0x04
+
static void plx_pci_reset_common(struct pci_dev *pdev);
static void plx9056_pci_reset_common(struct pci_dev *pdev);
static void plx_pci_reset_marathon_pci(struct pci_dev *pdev);
static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev);
+static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev);
struct plx_pci_channel_map {
u32 bar;
@@ -269,6 +285,14 @@ static struct plx_pci_card_info plx_pci_card_info_moxa = {
/* based on PLX9052 */
};
+static struct plx_pci_card_info plx_pci_card_info_asem_dual_can = {
+ "ASEM Dual CAN raw PCI", 2,
+ PLX_PCI_CAN_CLOCK, ASEM_PCI_OCR, PLX_PCI_CDR,
+ {0, 0x00, 0x00}, { {2, 0x00, 0x00}, {4, 0x00, 0x00} },
+ &plx_pci_reset_asem_dual_can_raw
+ /* based on PLX9030 */
+};
+
static const struct pci_device_id plx_pci_tbl[] = {
{
/* Adlink PCI-7841/cPCI-7841 */
@@ -375,6 +399,20 @@ static const struct pci_device_id plx_pci_tbl[] = {
0, 0,
(kernel_ulong_t)&plx_pci_card_info_moxa
},
+ {
+ /* ASEM Dual CAN raw */
+ ASEM_RAW_CAN_VENDOR_ID, ASEM_RAW_CAN_DEVICE_ID,
+ ASEM_RAW_CAN_SUB_VENDOR_ID, ASEM_RAW_CAN_SUB_DEVICE_ID,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_asem_dual_can
+ },
+ {
+ /* ASEM Dual CAN raw -new model */
+ ASEM_RAW_CAN_VENDOR_ID, ASEM_RAW_CAN_DEVICE_ID,
+ ASEM_RAW_CAN_SUB_VENDOR_ID, ASEM_RAW_CAN_SUB_DEVICE_ID_BIS,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_asem_dual_can
+ },
{ 0,}
};
MODULE_DEVICE_TABLE(pci, plx_pci_tbl);
@@ -524,6 +562,33 @@ static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev)
}
}
+/* Special reset function for ASEM Dual CAN raw card */
+static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev)
+{
+ void __iomem *bar0_addr;
+ static const int reset_bar;
+ u8 tmpval;
+
+ plx_pci_reset_common(pdev);
+
+ bar0_addr = pci_iomap(pdev, reset_bar, 0);
+ if (!bar0_addr) {
+ dev_err(&pdev->dev, "Failed to remap reset "
+ "space %d (BAR%d)\n", 0, reset_bar);
+ return;
+ }
+
+ /* reset the two SJA1000 chips */
+ tmpval = ioread8(bar0_addr + ASEM_RAW_CAN_RST_REGISTER);
+ tmpval &= ~(ASEM_RAW_CAN_RST_MASK_CAN1 | ASEM_RAW_CAN_RST_MASK_CAN2);
+ iowrite8(tmpval, bar0_addr + ASEM_RAW_CAN_RST_REGISTER);
+ usleep_range(300, 400);
+ tmpval |= ASEM_RAW_CAN_RST_MASK_CAN1 | ASEM_RAW_CAN_RST_MASK_CAN2;
+ iowrite8(tmpval, bar0_addr + ASEM_RAW_CAN_RST_REGISTER);
+ usleep_range(300, 400);
+ pci_iounmap(pdev, bar0_addr);
+}
+
static void plx_pci_del_card(struct pci_dev *pdev)
{
struct plx_pci_card *card = pci_get_drvdata(pdev);
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v2] can: sja1000: plx_pci: add support for ASEM CAN raw device
From: Marc Kleine-Budde @ 2018-08-06 13:49 UTC (permalink / raw)
To: Flavio Suligoi, Wolfgang Grandegger
Cc: David S . Miller, linux-can, netdev, linux-kernel
In-Reply-To: <1533561432-27034-1-git-send-email-f.suligoi@asem.it>
[-- Attachment #1.1: Type: text/plain, Size: 6120 bytes --]
On 08/06/2018 03:17 PM, Flavio Suligoi wrote:
> This patch adds support for ASEM opto-isolated dual channels
> CAN raw device (http://www.asem.it)
>
> Signed-off-by: Flavio Suligoi <f.suligoi@asem.it>
> ---
>
> v2: - renamed ASEM_... constants to reduce space size;
> - remove "else" in "plx_pci_reset_asem_dual_can_raw" function to avoid
> strings breaking
>
> drivers/net/can/sja1000/Kconfig | 1 +
> drivers/net/can/sja1000/plx_pci.c | 67 ++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 67 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig
> index 1e65cb6..f6dc899 100644
> --- a/drivers/net/can/sja1000/Kconfig
> +++ b/drivers/net/can/sja1000/Kconfig
> @@ -88,6 +88,7 @@ config CAN_PLX_PCI
> - TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/)
> - IXXAT Automation PC-I 04/PCI card (http://www.ixxat.com/)
> - Connect Tech Inc. CANpro/104-Plus Opto (CRG001) card (http://www.connecttech.com)
> + - ASEM CAN raw - 2 isolated CAN channels (www.asem.it)
>
> config CAN_TSCAN1
> tristate "TS-CAN1 PC104 boards"
> diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c
> index f8ff25c..d8dfa06 100644
> --- a/drivers/net/can/sja1000/plx_pci.c
> +++ b/drivers/net/can/sja1000/plx_pci.c
> @@ -46,7 +46,8 @@ MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, "
> "esd CAN-PCIe/2000, "
> "Connect Tech Inc. CANpro/104-Plus Opto (CRG001), "
> "IXXAT PC-I 04/PCI, "
> - "ELCUS CAN-200-PCI")
> + "ELCUS CAN-200-PCI, "
> + "ASEM DUAL CAN-RAW")
> MODULE_LICENSE("GPL v2");
>
> #define PLX_PCI_MAX_CHAN 2
> @@ -70,7 +71,9 @@ struct plx_pci_card {
> */
>
> #define PLX_LINT1_EN 0x1 /* Local interrupt 1 enable */
> +#define PLX_LINT1_POL (1 << 1) /* Local interrupt 1 polarity */
> #define PLX_LINT2_EN (1 << 3) /* Local interrupt 2 enable */
> +#define PLX_LINT2_POL (1 << 4) /* Local interrupt 1 polarity */
^^^
2?
> #define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */
> #define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */
>
> @@ -92,6 +95,9 @@ struct plx_pci_card {
> */
> #define PLX_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
>
> +/* OCR setting for ASEM Dual CAN raw */
> +#define ASEM_PCI_OCR 0xfe
> +
> /*
> * In the CDR register, you should set CBP to 1.
> * You will probably also want to set the clock divider value to 7
> @@ -145,10 +151,20 @@ struct plx_pci_card {
> #define MOXA_PCI_VENDOR_ID 0x1393
> #define MOXA_PCI_DEVICE_ID 0x0100
>
> +#define ASEM_RAW_CAN_VENDOR_ID 0x10b5
> +#define ASEM_RAW_CAN_DEVICE_ID 0x9030
> +#define ASEM_RAW_CAN_SUB_VENDOR_ID 0x3000
> +#define ASEM_RAW_CAN_SUB_DEVICE_ID 0x1001
> +#define ASEM_RAW_CAN_SUB_DEVICE_ID_BIS 0x1002
> +#define ASEM_RAW_CAN_RST_REGISTER 0x54
> +#define ASEM_RAW_CAN_RST_MASK_CAN1 0x20
> +#define ASEM_RAW_CAN_RST_MASK_CAN2 0x04
> +
> static void plx_pci_reset_common(struct pci_dev *pdev);
> static void plx9056_pci_reset_common(struct pci_dev *pdev);
> static void plx_pci_reset_marathon_pci(struct pci_dev *pdev);
> static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev);
> +static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev);
>
> struct plx_pci_channel_map {
> u32 bar;
> @@ -269,6 +285,14 @@ static struct plx_pci_card_info plx_pci_card_info_moxa = {
> /* based on PLX9052 */
> };
>
> +static struct plx_pci_card_info plx_pci_card_info_asem_dual_can = {
> + "ASEM Dual CAN raw PCI", 2,
> + PLX_PCI_CAN_CLOCK, ASEM_PCI_OCR, PLX_PCI_CDR,
> + {0, 0x00, 0x00}, { {2, 0x00, 0x00}, {4, 0x00, 0x00} },
> + &plx_pci_reset_asem_dual_can_raw
> + /* based on PLX9030 */
> +};
> +
> static const struct pci_device_id plx_pci_tbl[] = {
> {
> /* Adlink PCI-7841/cPCI-7841 */
> @@ -375,6 +399,20 @@ static const struct pci_device_id plx_pci_tbl[] = {
> 0, 0,
> (kernel_ulong_t)&plx_pci_card_info_moxa
> },
> + {
> + /* ASEM Dual CAN raw */
> + ASEM_RAW_CAN_VENDOR_ID, ASEM_RAW_CAN_DEVICE_ID,
> + ASEM_RAW_CAN_SUB_VENDOR_ID, ASEM_RAW_CAN_SUB_DEVICE_ID,
> + 0, 0,
> + (kernel_ulong_t)&plx_pci_card_info_asem_dual_can
> + },
> + {
> + /* ASEM Dual CAN raw -new model */
> + ASEM_RAW_CAN_VENDOR_ID, ASEM_RAW_CAN_DEVICE_ID,
> + ASEM_RAW_CAN_SUB_VENDOR_ID, ASEM_RAW_CAN_SUB_DEVICE_ID_BIS,
> + 0, 0,
> + (kernel_ulong_t)&plx_pci_card_info_asem_dual_can
> + },
> { 0,}
> };
> MODULE_DEVICE_TABLE(pci, plx_pci_tbl);
> @@ -524,6 +562,33 @@ static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev)
> }
> }
>
> +/* Special reset function for ASEM Dual CAN raw card */
> +static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev)
> +{
> + void __iomem *bar0_addr;
> + static const int reset_bar;
> + u8 tmpval;
> +
> + plx_pci_reset_common(pdev);
> +
> + bar0_addr = pci_iomap(pdev, reset_bar, 0);
> + if (!bar0_addr) {
> + dev_err(&pdev->dev, "Failed to remap reset "
> + "space %d (BAR%d)\n", 0, reset_bar);
Please put the string into just one line.
> + return;
> + }
> +
> + /* reset the two SJA1000 chips */
> + tmpval = ioread8(bar0_addr + ASEM_RAW_CAN_RST_REGISTER);
> + tmpval &= ~(ASEM_RAW_CAN_RST_MASK_CAN1 | ASEM_RAW_CAN_RST_MASK_CAN2);
> + iowrite8(tmpval, bar0_addr + ASEM_RAW_CAN_RST_REGISTER);
> + usleep_range(300, 400);
> + tmpval |= ASEM_RAW_CAN_RST_MASK_CAN1 | ASEM_RAW_CAN_RST_MASK_CAN2;
> + iowrite8(tmpval, bar0_addr + ASEM_RAW_CAN_RST_REGISTER);
> + usleep_range(300, 400);
> + pci_iounmap(pdev, bar0_addr);
> +}
> +
> static void plx_pci_del_card(struct pci_dev *pdev)
> {
> struct plx_pci_card *card = pci_get_drvdata(pdev);
>
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v3] can: sja1000: plx_pci: add support for ASEM CAN raw device
From: Marc Kleine-Budde @ 2018-08-06 16:07 UTC (permalink / raw)
To: Flavio Suligoi, Wolfgang Grandegger
Cc: David S . Miller, linux-can, netdev, linux-kernel
In-Reply-To: <1533564703-32194-1-git-send-email-f.suligoi@asem.it>
[-- Attachment #1.1: Type: text/plain, Size: 6195 bytes --]
On 08/06/2018 04:11 PM, Flavio Suligoi wrote:
> This patch adds support for ASEM opto-isolated dual channels
> CAN raw device (http://www.asem.it)
>
> Signed-off-by: Flavio Suligoi <f.suligoi@asem.it>
> ---
>
> v2: - rename ASEM_... constants to reduce space size;
> - remove "else" in "plx_pci_reset_asem_dual_can_raw" function to avoid
> strings breaking
> v3: - fix wrong comment for PLX_LINT2_POL
> - put string into just one line in "plx_pci_reset_asem_dual_can_raw"
> function
>
> drivers/net/can/sja1000/Kconfig | 1 +
> drivers/net/can/sja1000/plx_pci.c | 67 ++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 67 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig
> index 1e65cb6..f6dc899 100644
> --- a/drivers/net/can/sja1000/Kconfig
> +++ b/drivers/net/can/sja1000/Kconfig
> @@ -88,6 +88,7 @@ config CAN_PLX_PCI
> - TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/)
> - IXXAT Automation PC-I 04/PCI card (http://www.ixxat.com/)
> - Connect Tech Inc. CANpro/104-Plus Opto (CRG001) card (http://www.connecttech.com)
> + - ASEM CAN raw - 2 isolated CAN channels (www.asem.it)
>
> config CAN_TSCAN1
> tristate "TS-CAN1 PC104 boards"
> diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c
> index f8ff25c..f3915db 100644
> --- a/drivers/net/can/sja1000/plx_pci.c
> +++ b/drivers/net/can/sja1000/plx_pci.c
> @@ -46,7 +46,8 @@ MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, "
> "esd CAN-PCIe/2000, "
> "Connect Tech Inc. CANpro/104-Plus Opto (CRG001), "
> "IXXAT PC-I 04/PCI, "
> - "ELCUS CAN-200-PCI")
> + "ELCUS CAN-200-PCI, "
> + "ASEM DUAL CAN-RAW")
> MODULE_LICENSE("GPL v2");
>
> #define PLX_PCI_MAX_CHAN 2
> @@ -70,7 +71,9 @@ struct plx_pci_card {
> */
>
> #define PLX_LINT1_EN 0x1 /* Local interrupt 1 enable */
> +#define PLX_LINT1_POL (1 << 1) /* Local interrupt 1 polarity */
> #define PLX_LINT2_EN (1 << 3) /* Local interrupt 2 enable */
> +#define PLX_LINT2_POL (1 << 4) /* Local interrupt 2 polarity */
> #define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */
> #define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */
>
> @@ -92,6 +95,9 @@ struct plx_pci_card {
> */
> #define PLX_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
>
> +/* OCR setting for ASEM Dual CAN raw */
> +#define ASEM_PCI_OCR 0xfe
> +
> /*
> * In the CDR register, you should set CBP to 1.
> * You will probably also want to set the clock divider value to 7
> @@ -145,10 +151,20 @@ struct plx_pci_card {
> #define MOXA_PCI_VENDOR_ID 0x1393
> #define MOXA_PCI_DEVICE_ID 0x0100
>
> +#define ASEM_RAW_CAN_VENDOR_ID 0x10b5
> +#define ASEM_RAW_CAN_DEVICE_ID 0x9030
> +#define ASEM_RAW_CAN_SUB_VENDOR_ID 0x3000
> +#define ASEM_RAW_CAN_SUB_DEVICE_ID 0x1001
> +#define ASEM_RAW_CAN_SUB_DEVICE_ID_BIS 0x1002
> +#define ASEM_RAW_CAN_RST_REGISTER 0x54
> +#define ASEM_RAW_CAN_RST_MASK_CAN1 0x20
> +#define ASEM_RAW_CAN_RST_MASK_CAN2 0x04
> +
> static void plx_pci_reset_common(struct pci_dev *pdev);
> static void plx9056_pci_reset_common(struct pci_dev *pdev);
> static void plx_pci_reset_marathon_pci(struct pci_dev *pdev);
> static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev);
> +static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev);
>
> struct plx_pci_channel_map {
> u32 bar;
> @@ -269,6 +285,14 @@ static struct plx_pci_card_info plx_pci_card_info_moxa = {
> /* based on PLX9052 */
> };
>
> +static struct plx_pci_card_info plx_pci_card_info_asem_dual_can = {
> + "ASEM Dual CAN raw PCI", 2,
> + PLX_PCI_CAN_CLOCK, ASEM_PCI_OCR, PLX_PCI_CDR,
> + {0, 0x00, 0x00}, { {2, 0x00, 0x00}, {4, 0x00, 0x00} },
> + &plx_pci_reset_asem_dual_can_raw
> + /* based on PLX9030 */
> +};
> +
> static const struct pci_device_id plx_pci_tbl[] = {
> {
> /* Adlink PCI-7841/cPCI-7841 */
> @@ -375,6 +399,20 @@ static const struct pci_device_id plx_pci_tbl[] = {
> 0, 0,
> (kernel_ulong_t)&plx_pci_card_info_moxa
> },
> + {
> + /* ASEM Dual CAN raw */
> + ASEM_RAW_CAN_VENDOR_ID, ASEM_RAW_CAN_DEVICE_ID,
> + ASEM_RAW_CAN_SUB_VENDOR_ID, ASEM_RAW_CAN_SUB_DEVICE_ID,
> + 0, 0,
> + (kernel_ulong_t)&plx_pci_card_info_asem_dual_can
> + },
> + {
> + /* ASEM Dual CAN raw -new model */
> + ASEM_RAW_CAN_VENDOR_ID, ASEM_RAW_CAN_DEVICE_ID,
> + ASEM_RAW_CAN_SUB_VENDOR_ID, ASEM_RAW_CAN_SUB_DEVICE_ID_BIS,
> + 0, 0,
> + (kernel_ulong_t)&plx_pci_card_info_asem_dual_can
> + },
> { 0,}
> };
> MODULE_DEVICE_TABLE(pci, plx_pci_tbl);
> @@ -524,6 +562,33 @@ static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev)
> }
> }
>
> +/* Special reset function for ASEM Dual CAN raw card */
> +static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev)
> +{
> + void __iomem *bar0_addr;
> + static const int reset_bar;
> + u8 tmpval;
> +
> + plx_pci_reset_common(pdev);
> +
> + bar0_addr = pci_iomap(pdev, reset_bar, 0);
We can just use '0' instead of 'reset_bar' here, right?
Marc
> + if (!bar0_addr) {
> + dev_err(&pdev->dev, "Failed to remap reset space %d (BAR%d)\n",
> + 0, reset_bar);
> + return;
> + }
> +
> + /* reset the two SJA1000 chips */
> + tmpval = ioread8(bar0_addr + ASEM_RAW_CAN_RST_REGISTER);
> + tmpval &= ~(ASEM_RAW_CAN_RST_MASK_CAN1 | ASEM_RAW_CAN_RST_MASK_CAN2);
> + iowrite8(tmpval, bar0_addr + ASEM_RAW_CAN_RST_REGISTER);
> + usleep_range(300, 400);
> + tmpval |= ASEM_RAW_CAN_RST_MASK_CAN1 | ASEM_RAW_CAN_RST_MASK_CAN2;
> + iowrite8(tmpval, bar0_addr + ASEM_RAW_CAN_RST_REGISTER);
> + usleep_range(300, 400);
> + pci_iounmap(pdev, bar0_addr);
> +}
> +
> static void plx_pci_del_card(struct pci_dev *pdev)
> {
> struct plx_pci_card *card = pci_get_drvdata(pdev);
>
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* [PATCH v3] can: sja1000: plx_pci: add support for ASEM CAN raw device
From: Flavio Suligoi @ 2018-08-06 14:11 UTC (permalink / raw)
To: Wolfgang Grandegger, Marc Kleine-Budde
Cc: David S . Miller, linux-can, netdev, linux-kernel, Flavio Suligoi
In-Reply-To: <ac6e38c7-f794-6efd-4942-9b2a3fa7a0d0@pengutronix.de>
This patch adds support for ASEM opto-isolated dual channels
CAN raw device (http://www.asem.it)
Signed-off-by: Flavio Suligoi <f.suligoi@asem.it>
---
v2: - rename ASEM_... constants to reduce space size;
- remove "else" in "plx_pci_reset_asem_dual_can_raw" function to avoid
strings breaking
v3: - fix wrong comment for PLX_LINT2_POL
- put string into just one line in "plx_pci_reset_asem_dual_can_raw"
function
drivers/net/can/sja1000/Kconfig | 1 +
drivers/net/can/sja1000/plx_pci.c | 67 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig
index 1e65cb6..f6dc899 100644
--- a/drivers/net/can/sja1000/Kconfig
+++ b/drivers/net/can/sja1000/Kconfig
@@ -88,6 +88,7 @@ config CAN_PLX_PCI
- TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/)
- IXXAT Automation PC-I 04/PCI card (http://www.ixxat.com/)
- Connect Tech Inc. CANpro/104-Plus Opto (CRG001) card (http://www.connecttech.com)
+ - ASEM CAN raw - 2 isolated CAN channels (www.asem.it)
config CAN_TSCAN1
tristate "TS-CAN1 PC104 boards"
diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c
index f8ff25c..f3915db 100644
--- a/drivers/net/can/sja1000/plx_pci.c
+++ b/drivers/net/can/sja1000/plx_pci.c
@@ -46,7 +46,8 @@ MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, "
"esd CAN-PCIe/2000, "
"Connect Tech Inc. CANpro/104-Plus Opto (CRG001), "
"IXXAT PC-I 04/PCI, "
- "ELCUS CAN-200-PCI")
+ "ELCUS CAN-200-PCI, "
+ "ASEM DUAL CAN-RAW")
MODULE_LICENSE("GPL v2");
#define PLX_PCI_MAX_CHAN 2
@@ -70,7 +71,9 @@ struct plx_pci_card {
*/
#define PLX_LINT1_EN 0x1 /* Local interrupt 1 enable */
+#define PLX_LINT1_POL (1 << 1) /* Local interrupt 1 polarity */
#define PLX_LINT2_EN (1 << 3) /* Local interrupt 2 enable */
+#define PLX_LINT2_POL (1 << 4) /* Local interrupt 2 polarity */
#define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */
#define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */
@@ -92,6 +95,9 @@ struct plx_pci_card {
*/
#define PLX_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
+/* OCR setting for ASEM Dual CAN raw */
+#define ASEM_PCI_OCR 0xfe
+
/*
* In the CDR register, you should set CBP to 1.
* You will probably also want to set the clock divider value to 7
@@ -145,10 +151,20 @@ struct plx_pci_card {
#define MOXA_PCI_VENDOR_ID 0x1393
#define MOXA_PCI_DEVICE_ID 0x0100
+#define ASEM_RAW_CAN_VENDOR_ID 0x10b5
+#define ASEM_RAW_CAN_DEVICE_ID 0x9030
+#define ASEM_RAW_CAN_SUB_VENDOR_ID 0x3000
+#define ASEM_RAW_CAN_SUB_DEVICE_ID 0x1001
+#define ASEM_RAW_CAN_SUB_DEVICE_ID_BIS 0x1002
+#define ASEM_RAW_CAN_RST_REGISTER 0x54
+#define ASEM_RAW_CAN_RST_MASK_CAN1 0x20
+#define ASEM_RAW_CAN_RST_MASK_CAN2 0x04
+
static void plx_pci_reset_common(struct pci_dev *pdev);
static void plx9056_pci_reset_common(struct pci_dev *pdev);
static void plx_pci_reset_marathon_pci(struct pci_dev *pdev);
static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev);
+static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev);
struct plx_pci_channel_map {
u32 bar;
@@ -269,6 +285,14 @@ static struct plx_pci_card_info plx_pci_card_info_moxa = {
/* based on PLX9052 */
};
+static struct plx_pci_card_info plx_pci_card_info_asem_dual_can = {
+ "ASEM Dual CAN raw PCI", 2,
+ PLX_PCI_CAN_CLOCK, ASEM_PCI_OCR, PLX_PCI_CDR,
+ {0, 0x00, 0x00}, { {2, 0x00, 0x00}, {4, 0x00, 0x00} },
+ &plx_pci_reset_asem_dual_can_raw
+ /* based on PLX9030 */
+};
+
static const struct pci_device_id plx_pci_tbl[] = {
{
/* Adlink PCI-7841/cPCI-7841 */
@@ -375,6 +399,20 @@ static const struct pci_device_id plx_pci_tbl[] = {
0, 0,
(kernel_ulong_t)&plx_pci_card_info_moxa
},
+ {
+ /* ASEM Dual CAN raw */
+ ASEM_RAW_CAN_VENDOR_ID, ASEM_RAW_CAN_DEVICE_ID,
+ ASEM_RAW_CAN_SUB_VENDOR_ID, ASEM_RAW_CAN_SUB_DEVICE_ID,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_asem_dual_can
+ },
+ {
+ /* ASEM Dual CAN raw -new model */
+ ASEM_RAW_CAN_VENDOR_ID, ASEM_RAW_CAN_DEVICE_ID,
+ ASEM_RAW_CAN_SUB_VENDOR_ID, ASEM_RAW_CAN_SUB_DEVICE_ID_BIS,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_asem_dual_can
+ },
{ 0,}
};
MODULE_DEVICE_TABLE(pci, plx_pci_tbl);
@@ -524,6 +562,33 @@ static void plx_pci_reset_marathon_pcie(struct pci_dev *pdev)
}
}
+/* Special reset function for ASEM Dual CAN raw card */
+static void plx_pci_reset_asem_dual_can_raw(struct pci_dev *pdev)
+{
+ void __iomem *bar0_addr;
+ static const int reset_bar;
+ u8 tmpval;
+
+ plx_pci_reset_common(pdev);
+
+ bar0_addr = pci_iomap(pdev, reset_bar, 0);
+ if (!bar0_addr) {
+ dev_err(&pdev->dev, "Failed to remap reset space %d (BAR%d)\n",
+ 0, reset_bar);
+ return;
+ }
+
+ /* reset the two SJA1000 chips */
+ tmpval = ioread8(bar0_addr + ASEM_RAW_CAN_RST_REGISTER);
+ tmpval &= ~(ASEM_RAW_CAN_RST_MASK_CAN1 | ASEM_RAW_CAN_RST_MASK_CAN2);
+ iowrite8(tmpval, bar0_addr + ASEM_RAW_CAN_RST_REGISTER);
+ usleep_range(300, 400);
+ tmpval |= ASEM_RAW_CAN_RST_MASK_CAN1 | ASEM_RAW_CAN_RST_MASK_CAN2;
+ iowrite8(tmpval, bar0_addr + ASEM_RAW_CAN_RST_REGISTER);
+ usleep_range(300, 400);
+ pci_iounmap(pdev, bar0_addr);
+}
+
static void plx_pci_del_card(struct pci_dev *pdev)
{
struct plx_pci_card *card = pci_get_drvdata(pdev);
--
2.7.4
^ permalink raw reply related
* Re: [PATCH] Use Kconfig flag to remove support of deprecated BE2/BE3 adapters
From: Christoph Hellwig @ 2018-08-06 16:21 UTC (permalink / raw)
To: Petr Oros
Cc: netdev, ivecera, Sathya Perla, Ajit Khaparde,
Sriharsha Basavapatna, Somnath Kotur, David S. Miller,
linux-kernel
In-Reply-To: <20180806121230.23690-1-poros@redhat.com>
On Mon, Aug 06, 2018 at 02:12:28PM +0200, Petr Oros wrote:
> Add flags to remove support of deprecated BE2/BE3 adapters.
> BE2 disable will reduce .ko size by 2kb and BE3 by 3kb.
> Disable both will reduce .ko size by 9kb.
>
> With dissabled support is also removed coresponding PCI IDs
> and codepath with [BE2|BE3|BEx]_chip checks.
deprecated seems like a really odd world for hardware.
Are they just old? Did they never ship in large numbers?
If you just make some cards optional why not also add options
for families of newer cards for those who only have the older ones
in their systems?
^ permalink raw reply
* [PATCH bpf-next 0/3] Implement bpf map queue
From: Mauricio Vasquez B @ 2018-08-06 13:58 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann; +Cc: netdev
Bpf queue map is a new kind of map that provides a LIFO/FIFO queue
implementation.
In some applications, like a SNAT, it is necessary to keep track of
a pool of free elemenets, network ports in this case, then a queue
can be used for that purpose.
Signed-off-by: Mauricio Vasquez B <mauricio.vasquez@polito.it>
---
Mauricio Vasquez B (3):
bpf: add bpf queue map
selftests/bpf: add test cases for BPF_MAP_TYPE_QUEUE
bpf: add sample for BPF_MAP_TYPE_QUEUE
include/linux/bpf_types.h | 1
include/uapi/linux/bpf.h | 5 +
kernel/bpf/Makefile | 2
kernel/bpf/queuemap.c | 287 +++++++++++++++++++++++++++++++
kernel/bpf/syscall.c | 61 +++++--
kernel/bpf/verifier.c | 16 +-
samples/bpf/.gitignore | 1
samples/bpf/Makefile | 3
samples/bpf/test_map_in_map_user.c | 9 -
samples/bpf/test_queuemap.sh | 37 ++++
samples/bpf/test_queuemap_kern.c | 51 ++++++
samples/bpf/test_queuemap_user.c | 53 ++++++
tools/include/uapi/linux/bpf.h | 5 +
tools/testing/selftests/bpf/test_maps.c | 72 ++++++++
14 files changed, 577 insertions(+), 26 deletions(-)
create mode 100644 kernel/bpf/queuemap.c
create mode 100755 samples/bpf/test_queuemap.sh
create mode 100644 samples/bpf/test_queuemap_kern.c
create mode 100644 samples/bpf/test_queuemap_user.c
^ permalink raw reply
* [PATCH bpf-next 1/3] bpf: add bpf queue map
From: Mauricio Vasquez B @ 2018-08-06 13:58 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann; +Cc: netdev
In-Reply-To: <153356387977.6981.12236150594041620482.stgit@kernel>
Bpf queue implements a LIFO/FIFO data containers for ebpf programs.
It allows to push an element to the queue by using the update operation
and to pop an element from the queue by using the lookup operation.
A use case for this is to keep track of a pool of elements, like
network ports in a SNAT.
Signed-off-by: Mauricio Vasquez B <mauricio.vasquez@polito.it>
---
include/linux/bpf_types.h | 1
include/uapi/linux/bpf.h | 5 +
kernel/bpf/Makefile | 2
kernel/bpf/queuemap.c | 287 +++++++++++++++++++++++++++++++++++++++++++++
kernel/bpf/syscall.c | 61 +++++++---
kernel/bpf/verifier.c | 16 ++-
6 files changed, 353 insertions(+), 19 deletions(-)
create mode 100644 kernel/bpf/queuemap.c
diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
index c5700c2d5549..6c7a62f3fe43 100644
--- a/include/linux/bpf_types.h
+++ b/include/linux/bpf_types.h
@@ -58,3 +58,4 @@ BPF_MAP_TYPE(BPF_MAP_TYPE_CPUMAP, cpu_map_ops)
BPF_MAP_TYPE(BPF_MAP_TYPE_XSKMAP, xsk_map_ops)
#endif
#endif
+BPF_MAP_TYPE(BPF_MAP_TYPE_QUEUE, queue_map_ops)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 0ebaaf7f3568..2c171c40eb45 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -120,6 +120,7 @@ enum bpf_map_type {
BPF_MAP_TYPE_CPUMAP,
BPF_MAP_TYPE_XSKMAP,
BPF_MAP_TYPE_SOCKHASH,
+ BPF_MAP_TYPE_QUEUE,
};
enum bpf_prog_type {
@@ -255,6 +256,10 @@ enum bpf_attach_type {
/* Flag for stack_map, store build_id+offset instead of pointer */
#define BPF_F_STACK_BUILD_ID (1U << 5)
+/* Flags for queue_map, type of queue */
+#define BPF_F_QUEUE_FIFO (1U << 16)
+#define BPF_F_QUEUE_LIFO (2U << 16)
+
enum bpf_stack_build_id_status {
/* user space need an empty entry to identify end of a trace */
BPF_STACK_BUILD_ID_EMPTY = 0,
diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
index f27f5496d6fe..30f02ef66635 100644
--- a/kernel/bpf/Makefile
+++ b/kernel/bpf/Makefile
@@ -2,7 +2,7 @@
obj-y := core.o
obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o
-obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o
+obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o queuemap.o
obj-$(CONFIG_BPF_SYSCALL) += disasm.o
obj-$(CONFIG_BPF_SYSCALL) += btf.o
ifeq ($(CONFIG_NET),y)
diff --git a/kernel/bpf/queuemap.c b/kernel/bpf/queuemap.c
new file mode 100644
index 000000000000..ab30af43b4cc
--- /dev/null
+++ b/kernel/bpf/queuemap.c
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * queuemap.c: BPF queue map
+ *
+ * Copyright (c) 2018 Politecnico di Torino
+ */
+#include <linux/bpf.h>
+#include <linux/rculist.h>
+#include <linux/slab.h>
+#include "percpu_freelist.h"
+
+#define QUEUE_CREATE_FLAG_MASK \
+ (BPF_F_NO_PREALLOC | BPF_F_NUMA_NODE | BPF_F_RDONLY | BPF_F_WRONLY | \
+ BPF_F_QUEUE_FIFO | BPF_F_QUEUE_LIFO)
+
+enum queue_type {
+ QUEUE_FIFO = (BPF_F_QUEUE_FIFO >> 16),
+ QUEUE_LIFO = (BPF_F_QUEUE_LIFO >> 16),
+};
+
+struct bpf_queue {
+ struct bpf_map map;
+ struct list_head head;
+ struct pcpu_freelist freelist;
+ void *nodes;
+ enum queue_type type;
+ raw_spinlock_t lock;
+ atomic_t count;
+ u32 node_size;
+};
+
+struct queue_node {
+ struct pcpu_freelist_node fnode;
+ struct bpf_queue *queue;
+ struct list_head list;
+ struct rcu_head rcu;
+ char element[0] __aligned(8);
+};
+
+static bool queue_map_is_prealloc(struct bpf_queue *queue)
+{
+ return !(queue->map.map_flags & BPF_F_NO_PREALLOC);
+}
+
+/* Called from syscall */
+static int queue_map_alloc_check(union bpf_attr *attr)
+{
+ /* check sanity of attributes */
+ if (attr->max_entries == 0 || attr->key_size != 0 ||
+ attr->value_size == 0 || attr->map_flags & ~QUEUE_CREATE_FLAG_MASK)
+ return -EINVAL;
+
+ if ((attr->map_flags >> 16) != QUEUE_FIFO &&
+ (attr->map_flags >> 16) != QUEUE_LIFO) {
+ return -EINVAL;
+ }
+
+ if (attr->value_size > KMALLOC_MAX_SIZE)
+ /* if value_size is bigger, the user space won't be able to
+ * access the elements.
+ */
+ return -E2BIG;
+
+ return 0;
+}
+
+static int prealloc_init(struct bpf_queue *queue)
+{
+ u32 node_size = sizeof(struct queue_node) +
+ round_up(queue->map.value_size, 8);
+ u32 num_entries = queue->map.max_entries;
+ int err;
+
+ queue->nodes = bpf_map_area_alloc(node_size * num_entries,
+ queue->map.numa_node);
+ if (!queue->nodes)
+ return -ENOMEM;
+
+ err = pcpu_freelist_init(&queue->freelist);
+ if (err)
+ goto free_nodes;
+
+ pcpu_freelist_populate(&queue->freelist,
+ queue->nodes +
+ offsetof(struct queue_node, fnode),
+ node_size, num_entries);
+
+ return 0;
+
+free_nodes:
+ bpf_map_area_free(queue->nodes);
+ return err;
+}
+
+static void prealloc_destroy(struct bpf_queue *queue)
+{
+ bpf_map_area_free(queue->nodes);
+ pcpu_freelist_destroy(&queue->freelist);
+}
+
+static struct bpf_map *queue_map_alloc(union bpf_attr *attr)
+{
+ struct bpf_queue *queue;
+ u64 cost = sizeof(*queue);
+ int ret;
+
+ queue = kzalloc(sizeof(*queue), GFP_USER);
+ if (!queue)
+ return ERR_PTR(-ENOMEM);
+
+ bpf_map_init_from_attr(&queue->map, attr);
+
+ queue->node_size = sizeof(struct queue_node) +
+ round_up(attr->value_size, 8);
+ cost += (u64) attr->max_entries * queue->node_size;
+ if (cost >= U32_MAX - PAGE_SIZE) {
+ ret = -E2BIG;
+ goto free_queue;
+ }
+
+ queue->map.pages = round_up(cost, PAGE_SIZE) >> PAGE_SHIFT;
+
+ ret = bpf_map_precharge_memlock(queue->map.pages);
+ if (ret)
+ goto free_queue;
+
+ INIT_LIST_HEAD(&queue->head);
+
+ raw_spin_lock_init(&queue->lock);
+
+ queue->type = attr->map_flags >> 16;
+
+ if (queue_map_is_prealloc(queue))
+ ret = prealloc_init(queue);
+ if (ret)
+ goto free_queue;
+
+ return &queue->map;
+
+free_queue:
+ kfree(queue);
+ return ERR_PTR(ret);
+}
+
+/* Called when map->refcnt goes to zero, either from workqueue or from syscall */
+static void queue_map_free(struct bpf_map *map)
+{
+ struct bpf_queue *queue = container_of(map, struct bpf_queue, map);
+ struct queue_node *l;
+
+ /* at this point bpf_prog->aux->refcnt == 0 and this map->refcnt == 0,
+ * so the programs (can be more than one that used this map) were
+ * disconnected from events. Wait for outstanding critical sections in
+ * these programs to complete
+ */
+ synchronize_rcu();
+
+ /* some of queue_elem_free_rcu() callbacks for elements of this map may
+ * not have executed. Wait for them.
+ */
+ rcu_barrier();
+ if (!queue_map_is_prealloc(queue))
+ list_for_each_entry_rcu(l, &queue->head, list) {
+ list_del_rcu(&l->list);
+ kfree(l);
+ }
+ else
+ prealloc_destroy(queue);
+ kfree(queue);
+}
+
+static void queue_elem_free_rcu(struct rcu_head *head)
+{
+ struct queue_node *l = container_of(head, struct queue_node, rcu);
+ struct bpf_queue *queue = l->queue;
+
+ /* must increment bpf_prog_active to avoid kprobe+bpf triggering while
+ * we're calling kfree, otherwise deadlock is possible if kprobes
+ * are placed somewhere inside of slub
+ */
+ preempt_disable();
+ __this_cpu_inc(bpf_prog_active);
+ if (queue_map_is_prealloc(queue))
+ pcpu_freelist_push(&queue->freelist, &l->fnode);
+ else
+ kfree(l);
+ __this_cpu_dec(bpf_prog_active);
+ preempt_enable();
+}
+
+/* Called from syscall or from eBPF program */
+static void *queue_map_lookup_elem(struct bpf_map *map, void *key)
+{
+ struct bpf_queue *queue = container_of(map, struct bpf_queue, map);
+ unsigned long flags;
+ struct queue_node *node;
+
+ raw_spin_lock_irqsave(&queue->lock, flags);
+
+ node = list_first_or_null_rcu(&queue->head, struct queue_node, list);
+ if (!node) {
+ raw_spin_unlock_irqrestore(&queue->lock, flags);
+ return NULL;
+ }
+
+ if (!queue_map_is_prealloc(queue))
+ atomic_dec(&queue->count);
+
+ list_del_rcu(&node->list);
+ call_rcu(&node->rcu, queue_elem_free_rcu);
+
+ raw_spin_unlock_irqrestore(&queue->lock, flags);
+
+ return &node->element;
+}
+
+/* Called from syscall or from eBPF program */
+static int queue_map_update_elem(struct bpf_map *map, void *key, void *value,
+ u64 map_flags)
+{
+ struct bpf_queue *queue = container_of(map, struct bpf_queue, map);
+ unsigned long flags;
+ struct queue_node *new;
+
+ if (!queue_map_is_prealloc(queue)) {
+ if (atomic_inc_return(&queue->count) > queue->map.max_entries) {
+ atomic_dec(&queue->count);
+ return -E2BIG;
+ }
+
+ new = kmalloc_node(queue->node_size, GFP_ATOMIC | __GFP_NOWARN,
+ queue->map.numa_node);
+ if (!new) {
+ atomic_dec(&queue->count);
+ return -ENOMEM;
+ }
+ } else {
+ struct pcpu_freelist_node *l;
+
+ l = pcpu_freelist_pop(&queue->freelist);
+ if (!l)
+ return -E2BIG;
+ new = container_of(l, struct queue_node, fnode);
+ }
+
+ memcpy(new->element, value, queue->map.value_size);
+ new->queue = queue;
+
+ raw_spin_lock_irqsave(&queue->lock, flags);
+ switch (queue->type) {
+ case QUEUE_FIFO:
+ list_add_tail_rcu(&new->list, &queue->head);
+ break;
+
+ case QUEUE_LIFO:
+ list_add_rcu(&new->list, &queue->head);
+ break;
+ }
+
+ raw_spin_unlock_irqrestore(&queue->lock, flags);
+
+ return 0;
+}
+
+/* Called from syscall or from eBPF program */
+static int queue_map_delete_elem(struct bpf_map *map, void *key)
+{
+ return -EINVAL;
+}
+
+/* Called from syscall */
+static int queue_map_get_next_key(struct bpf_map *map, void *key,
+ void *next_key)
+{
+ return -EINVAL;
+}
+
+const struct bpf_map_ops queue_map_ops = {
+ .map_alloc_check = queue_map_alloc_check,
+ .map_alloc = queue_map_alloc,
+ .map_free = queue_map_free,
+ .map_lookup_elem = queue_map_lookup_elem,
+ .map_update_elem = queue_map_update_elem,
+ .map_delete_elem = queue_map_delete_elem,
+ .map_get_next_key = queue_map_get_next_key,
+};
+
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index a31a1ba0f8ea..7e9a11d69eef 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -622,11 +622,19 @@ static int map_lookup_elem(union bpf_attr *attr)
err = -EPERM;
goto err_put;
}
+ if (map->map_type != BPF_MAP_TYPE_QUEUE) {
+ key = memdup_user(ukey, map->key_size);
+ if (IS_ERR(key)) {
+ err = PTR_ERR(key);
+ goto err_put;
+ }
+ } else {
+ if (ukey) {
+ err = -EINVAL;
+ goto err_put;
+ }
- key = memdup_user(ukey, map->key_size);
- if (IS_ERR(key)) {
- err = PTR_ERR(key);
- goto err_put;
+ key = NULL;
}
if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
@@ -709,10 +717,19 @@ static int map_update_elem(union bpf_attr *attr)
goto err_put;
}
- key = memdup_user(ukey, map->key_size);
- if (IS_ERR(key)) {
- err = PTR_ERR(key);
- goto err_put;
+ if (map->map_type != BPF_MAP_TYPE_QUEUE) {
+ key = memdup_user(ukey, map->key_size);
+ if (IS_ERR(key)) {
+ err = PTR_ERR(key);
+ goto err_put;
+ }
+ } else {
+ if (ukey) {
+ err = -EINVAL;
+ goto err_put;
+ }
+
+ key = NULL;
}
if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
@@ -803,10 +820,19 @@ static int map_delete_elem(union bpf_attr *attr)
goto err_put;
}
- key = memdup_user(ukey, map->key_size);
- if (IS_ERR(key)) {
- err = PTR_ERR(key);
- goto err_put;
+ if (map->map_type != BPF_MAP_TYPE_QUEUE) {
+ key = memdup_user(ukey, map->key_size);
+ if (IS_ERR(key)) {
+ err = PTR_ERR(key);
+ goto err_put;
+ }
+ } else {
+ if (ukey) {
+ err = -EINVAL;
+ goto err_put;
+ }
+
+ key = NULL;
}
if (bpf_map_is_dev_bound(map)) {
@@ -855,9 +881,14 @@ static int map_get_next_key(union bpf_attr *attr)
}
if (ukey) {
- key = memdup_user(ukey, map->key_size);
- if (IS_ERR(key)) {
- err = PTR_ERR(key);
+ if (map->map_type != BPF_MAP_TYPE_QUEUE) {
+ key = memdup_user(ukey, map->key_size);
+ if (IS_ERR(key)) {
+ err = PTR_ERR(key);
+ goto err_put;
+ }
+ } else {
+ err = -EINVAL;
goto err_put;
}
} else {
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 25e47c195874..83099a9a21d9 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1976,8 +1976,12 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
return -EACCES;
}
- if (arg_type == ARG_PTR_TO_MAP_KEY ||
- arg_type == ARG_PTR_TO_MAP_VALUE) {
+ if (arg_type == ARG_PTR_TO_MAP_KEY) {
+ expected_type = PTR_TO_STACK;
+ if (!type_is_pkt_pointer(type) && type != PTR_TO_MAP_VALUE &&
+ type != expected_type && type != SCALAR_VALUE)
+ goto err_type;
+ } else if (arg_type == ARG_PTR_TO_MAP_VALUE) {
expected_type = PTR_TO_STACK;
if (!type_is_pkt_pointer(type) && type != PTR_TO_MAP_VALUE &&
type != expected_type)
@@ -2021,6 +2025,7 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
/* bpf_map_xxx(map_ptr) call: remember that map_ptr */
meta->map_ptr = reg->map_ptr;
} else if (arg_type == ARG_PTR_TO_MAP_KEY) {
+ bool zero_size_allowed = false;
/* bpf_map_xxx(..., map_ptr, ..., key) call:
* check that [key, key + map->key_size) are within
* stack limits and initialized
@@ -2034,8 +2039,13 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
verbose(env, "invalid map_ptr to access map->key\n");
return -EACCES;
}
+
+ if (meta->map_ptr->map_type == BPF_MAP_TYPE_QUEUE)
+ zero_size_allowed = true;
+
err = check_helper_mem_access(env, regno,
- meta->map_ptr->key_size, false,
+ meta->map_ptr->key_size,
+ zero_size_allowed,
NULL);
} else if (arg_type == ARG_PTR_TO_MAP_VALUE) {
/* bpf_map_xxx(..., map_ptr, ..., value) call:
^ permalink raw reply related
* [PATCH bpf-next 2/3] selftests/bpf: add test cases for BPF_MAP_TYPE_QUEUE
From: Mauricio Vasquez B @ 2018-08-06 13:58 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann; +Cc: netdev
In-Reply-To: <153356387977.6981.12236150594041620482.stgit@kernel>
Signed-off-by: Mauricio Vasquez B <mauricio.vasquez@polito.it>
---
tools/include/uapi/linux/bpf.h | 5 ++
tools/testing/selftests/bpf/test_maps.c | 72 +++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+)
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 0ebaaf7f3568..2c171c40eb45 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -120,6 +120,7 @@ enum bpf_map_type {
BPF_MAP_TYPE_CPUMAP,
BPF_MAP_TYPE_XSKMAP,
BPF_MAP_TYPE_SOCKHASH,
+ BPF_MAP_TYPE_QUEUE,
};
enum bpf_prog_type {
@@ -255,6 +256,10 @@ enum bpf_attach_type {
/* Flag for stack_map, store build_id+offset instead of pointer */
#define BPF_F_STACK_BUILD_ID (1U << 5)
+/* Flags for queue_map, type of queue */
+#define BPF_F_QUEUE_FIFO (1U << 16)
+#define BPF_F_QUEUE_LIFO (2U << 16)
+
enum bpf_stack_build_id_status {
/* user space need an empty entry to identify end of a trace */
BPF_STACK_BUILD_ID_EMPTY = 0,
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c
index 6c253343a6f9..34567b017dbb 100644
--- a/tools/testing/selftests/bpf/test_maps.c
+++ b/tools/testing/selftests/bpf/test_maps.c
@@ -457,6 +457,77 @@ static void test_devmap(int task, void *data)
close(fd);
}
+static void test_queuemap(int task, void *data)
+{
+ __u32 value;
+ int fd, i;
+
+ /* test FIFO */
+ fd = bpf_create_map(BPF_MAP_TYPE_QUEUE, 0, sizeof(value), 32,
+ BPF_F_QUEUE_FIFO);
+ if (fd < 0) {
+ printf("Failed to create queuemap '%s'!\n", strerror(errno));
+ exit(1);
+ }
+
+ /* Push 32 elements */
+ for (i = 0; i < 32; i++) {
+ value = 1000 - i * 3;
+ assert(bpf_map_update_elem(fd, NULL, &value, 0) == 0);
+ }
+
+ /* Check that element cannot be pushed due to max_entries limit */
+ value = 1000;
+ assert(bpf_map_update_elem(fd, NULL, &value, 0) == -1 &&
+ errno == E2BIG);
+
+ /* Pop all elements */
+ for (i = 0; i < 32; i++)
+ assert(bpf_map_lookup_elem(fd, NULL, &value) == 0 &&
+ value == (1000 - i * 3));
+
+ /* Check that there are not elements left */
+ assert(bpf_map_lookup_elem(fd, NULL, &value) == -1 && errno == ENOENT);
+
+ assert(bpf_map_delete_elem(fd, NULL) == -1 && errno == EINVAL);
+ assert(bpf_map_get_next_key(fd, NULL, NULL) == -1 && errno == EINVAL);
+
+ close(fd);
+
+ /* test LIFO */
+ fd = bpf_create_map(BPF_MAP_TYPE_QUEUE, 0, sizeof(value), 32,
+ BPF_F_QUEUE_LIFO);
+ if (fd < 0) {
+ printf("Failed to create queuemap '%s'!\n", strerror(errno));
+ exit(1);
+ }
+
+ /* Push 32 elements */
+ for (i = 0; i < 32; i++) {
+ value = 1000 - i * 3;
+ assert(bpf_map_update_elem(fd, NULL, &value, 0) == 0);
+ }
+
+ /* Check that element cannot be pushed due to max_entries limit */
+ value = 1000;
+ assert(bpf_map_update_elem(fd, NULL, &value, 0) == -1 &&
+ errno == E2BIG);
+
+ /* Pop all elements */
+ for (i = 31; i >= 0; i--)
+ assert(bpf_map_lookup_elem(fd, NULL, &value) == 0 &&
+ value == (1000 - i * 3));
+
+ /* Check that there are not elements left */
+ assert(bpf_map_lookup_elem(fd, NULL, &value) == -1 &&
+ errno == ENOENT);
+
+ assert(bpf_map_delete_elem(fd, NULL) == -1 && errno == EINVAL);
+ assert(bpf_map_get_next_key(fd, NULL, NULL) == -1 && errno == EINVAL);
+
+ close(fd);
+}
+
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
@@ -1162,6 +1233,7 @@ static void run_all_tests(void)
test_arraymap_percpu_many_keys();
test_devmap(0, NULL);
+ test_queuemap(0, NULL);
test_sockmap(0, NULL);
test_map_large();
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox