* Re: [PATCH] inet: don't use sk_v6_rcv_saddr directly
From: David Miller @ 2017-01-20 19:36 UTC (permalink / raw)
To: jbacik; +Cc: tom, netdev, kafai
In-Reply-To: <1484866066-25407-1-git-send-email-jbacik@fb.com>
From: Josef Bacik <jbacik@fb.com>
Date: Thu, 19 Jan 2017 17:47:46 -0500
> When comparing two sockets we need to use inet6_rcv_saddr so we get a NULL
> sk_v6_rcv_saddr if the socket isn't AF_INET6, otherwise our comparison function
> can be wrong.
>
> Fixes: 637bc8b ("inet: reset tb->fastreuseport when adding a reuseport sk")
> Signed-off-by: Josef Bacik <jbacik@fb.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next v2 0/2] net: ipv6: Improve user experience with multipath routes
From: David Ahern @ 2017-01-20 19:31 UTC (permalink / raw)
To: netdev
In-Reply-To: <1484892626-14257-1-git-send-email-dsa@cumulusnetworks.com>
On 1/19/17 11:10 PM, David Ahern wrote:
> This series closes a couple of gaps between IPv4 and IPv6 with respect
> to multipath routes:
...
> In both cases, the new behavior requires users to opt in by setting a new
> flag, RTM_F_ALL_NEXTHOPS, in the rtm_flags of struct rtmsg which is
> expected to be the ancillary header in the netlink request received from
> the user. A program must opt in to the new behavior so as to not break
> any existing applications.
>
> The opt-in behavior works for both route deletes and dumps (the two
> differences noted above), but not for notifications as notifications
> do not take user input to specify flags. The only way to have
> notifications generate RTA_MULTIPATH encodings is to have a gobal
> flag -- e.g., sysctl. I'd prefer not to add a sysctl knob for this
> backwards compatibility.
BTW, I am in favor of not requiring a user API for this but just doing it. I can't imagine anyone working with multipath routes not wanting the efficiency of the RTA_MULTIPATH attribute. These patches require an API only because of the rule not to break userspace. If we conclude to just do it without an API, the multipath_add and multipath_del need to be modified to only send a notification once at the end of the actions.
^ permalink raw reply
* Re: [Xen-devel] xennet_start_xmit assumptions
From: David Miller @ 2017-01-20 19:30 UTC (permalink / raw)
To: sowmini.varadhan; +Cc: Paul.Durrant, konrad.wilk, wei.liu2, netdev, xen-devel
In-Reply-To: <20170119224123.GB19618@oracle.com>
From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Date: Thu, 19 Jan 2017 17:41:23 -0500
> On (01/19/17 13:47), Sowmini Varadhan wrote:
>> > Specifically I'm talking about the dev_validate_header() check.
>> > That is supposed to protect us from these kinds of situations.
>>
>> ah, but I run my pf_packet application as root, so I have
>> capable(CAP_SYS_RAWIO), so I slip through the dev_validate_header()
>> check.
>
> and in that light, should dev_validate_header()
> always return false if len == 0?
>
> that will take care of all the send paths in af_packet.c
> but it impacts all drivers as well (even though it is the
> logically correct thing to do..)
I think dev_validate_header() almost does the correct thing in
the SYS_RAWIO case.
It clears out the not-provided hard header bytes, but it doesn't
adjust the skb->len. I think that is a real requirement in this
situation.
CAP_SYS_RAWIO or not, the contract we have with the device is that
there will be at least enough bytes to cover a link layer header.
This probably requires a little bit of an adjustment to the calling
convention. Perhaps:
int dev_validate_header(const struct net_device *dev,
char *ll_header, int len);
So then you can go:
new_len = dev_validate_header(dev, skb->data, len);
if (new_len < 0)
goto out_cleanup_err;
if (new_len > len)
__skb_put(skb, new_len - len);
Or something like that.
^ permalink raw reply
* Re: [pull request][net-next 00/15] Mellanox mlx5 updates 2017-01-19
From: David Miller @ 2017-01-20 19:23 UTC (permalink / raw)
To: saeedm; +Cc: netdev
In-Reply-To: <20170119223908.15924-1-saeedm@mellanox.com>
From: Saeed Mahameed <saeedm@mellanox.com>
Date: Fri, 20 Jan 2017 00:38:53 +0200
> This pull request includes some small mlx5 updates and two new features,
> The 1st exposes new HW counters to "ethtool -S" and the other introduces
> mlx5 ptp 1pps support. Details are down bleow.
>
> Please pull and let me know if there's any problem.
Pulled, thank you.
^ permalink raw reply
* Re: [PATCH v5 0/2] Add support for the ethernet switch on the ESPRESSObin
From: David Miller @ 2017-01-20 19:17 UTC (permalink / raw)
To: gregory.clement
Cc: thomas.petazzoni, andrew, f.fainelli, jason, shjzhou,
vivien.didelot, netdev, linux-kernel, jpannell, nadavh, kostap,
dingwei, linux-arm-kernel, sebastian.hesselbarth
In-Reply-To: <20170119214934.27442-1-gregory.clement@free-electrons.com>
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
Date: Thu, 19 Jan 2017 22:49:32 +0100
> I created a new family for this switch and filled the ops structure
> by selecting which seems the more appropriate functions. I rebased
> the series on net-next/master which allowed me to benefit to the
> eeprom functions introduced for the 6390.
It looks like there will be at least one more respin of this series,
specifically to remove the new family as Vivien seems to object to
this.
^ permalink raw reply
* Re: [PATCHv4 net-next 3/5] sctp: implement sender-side procedures for SSN/TSN Reset Request Parameter
From: David Miller @ 2017-01-20 19:00 UTC (permalink / raw)
To: marcelo.leitner; +Cc: lucien.xin, netdev, linux-sctp, nhorman, vyasevich
In-Reply-To: <20170120182521.GV3781@localhost.localdomain>
From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Date: Fri, 20 Jan 2017 16:25:22 -0200
> I talked offline with Xin about this and we cannot do it this way.
> Unfortunatelly we will have to take the long road here, because then
> we may send data while sending the request, as the streams are not
> closed yet. We really need to close team, send the request, and
> re-open if the send fails.
I am expecting another spin of this series, correct?
^ permalink raw reply
* Re: [PATCH v2] xen-netfront: Fix Rx stall during network stress and OOM
From: David Miller @ 2017-01-20 19:09 UTC (permalink / raw)
To: vineethp; +Cc: netdev, linux-kernel
In-Reply-To: <66b10c64-936a-8001-6855-2ff1ed626642@amazon.com>
From: Vineeth Remanan Pillai <vineethp@amazon.com>
Date: Thu, 19 Jan 2017 08:35:39 -0800
> From: Vineeth Remanan Pillai <vineethp@amazon.com>
>
> During an OOM scenario, request slots could not be created as skb
> allocation fails. So the netback cannot pass in packets and netfront
> wrongly assumes that there is no more work to be done and it disables
> polling. This causes Rx to stall.
>
> The issue is with the retry logic which schedules the timer if the
> created slots are less than NET_RX_SLOTS_MIN. The count of new request
> slots to be pushed are calculated as a difference between new req_prod
> and rsp_cons which could be more than the actual slots, if there are
> unconsumed responses.
>
> The fix is to calculate the count of newly created slots as the
> difference between new req_prod and old req_prod.
>
> Signed-off-by: Vineeth Remanan Pillai <vineethp@amazon.com>
> Reviewed-by: Juergen Gross <jgross@suse.com>
> ---
> Changes in v2:
> - Removed the old implementation of enabling polling on
> skb allocation error.
> - Corrected the refill timer logic to schedule when newly
> created slots since last push is less than NET_RX_SLOTS_MIN.
Applied.
^ permalink raw reply
* [PATCH net-next 2/2] net: systemport: Add support for SYSTEMPORT Lite
From: Florian Fainelli @ 2017-01-20 19:08 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
In-Reply-To: <20170120190827.26444-1-f.fainelli@gmail.com>
Add supporf for the SYSTEMPORT Lite Ethernet controller, this piece of hardware
is largely based on the full-blown SYSTEMPORT and differs in the following:
- no full-blown UniMAC, instead we have the MagicPacket matching from UniMAC at
same offset, and a GMII Interface Block (GIB) for the MAC-level stuff, since
we are always interfaced to an Ethernet switch which is fully Ethernet compliant
shortcuts could be made
- 16 transmit queues, whose interrupts are moved into the first Level-2 interrupt
controller bank
- slight TDMA offset change (a register was inserted after TDMA_STATUS, *sigh*)
- 256 RX descriptors (512 words) and 256 TX descriptors (not visible)
As a consequence of these two things, update the code paths accordingly to
differentiate the full-blown from the light version.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
.../devicetree/bindings/net/brcm,systemport.txt | 5 +-
drivers/net/ethernet/broadcom/bcmsysport.c | 323 +++++++++++++++++----
drivers/net/ethernet/broadcom/bcmsysport.h | 78 ++++-
3 files changed, 327 insertions(+), 79 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/brcm,systemport.txt b/Documentation/devicetree/bindings/net/brcm,systemport.txt
index 877da34145b0..83f29e0e11ba 100644
--- a/Documentation/devicetree/bindings/net/brcm,systemport.txt
+++ b/Documentation/devicetree/bindings/net/brcm,systemport.txt
@@ -1,7 +1,10 @@
* Broadcom BCM7xxx Ethernet Systemport Controller (SYSTEMPORT)
Required properties:
-- compatible: should be one of "brcm,systemport-v1.00" or "brcm,systemport"
+- compatible: should be one of:
+ "brcm,systemport-v1.00"
+ "brcm,systemportlite-v1.00" or
+ "brcm,systemport"
- reg: address and length of the register set for the device.
- interrupts: interrupts for the device, first cell must be for the rx
interrupts, and the second cell should be for the transmit queues. An
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index 31bb2c3696ec..a68d4889f5db 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -43,14 +43,43 @@ static inline void name##_writel(struct bcm_sysport_priv *priv, \
BCM_SYSPORT_IO_MACRO(intrl2_0, SYS_PORT_INTRL2_0_OFFSET);
BCM_SYSPORT_IO_MACRO(intrl2_1, SYS_PORT_INTRL2_1_OFFSET);
BCM_SYSPORT_IO_MACRO(umac, SYS_PORT_UMAC_OFFSET);
+BCM_SYSPORT_IO_MACRO(gib, SYS_PORT_GIB_OFFSET);
BCM_SYSPORT_IO_MACRO(tdma, SYS_PORT_TDMA_OFFSET);
-BCM_SYSPORT_IO_MACRO(rdma, SYS_PORT_RDMA_OFFSET);
BCM_SYSPORT_IO_MACRO(rxchk, SYS_PORT_RXCHK_OFFSET);
BCM_SYSPORT_IO_MACRO(txchk, SYS_PORT_TXCHK_OFFSET);
BCM_SYSPORT_IO_MACRO(rbuf, SYS_PORT_RBUF_OFFSET);
BCM_SYSPORT_IO_MACRO(tbuf, SYS_PORT_TBUF_OFFSET);
BCM_SYSPORT_IO_MACRO(topctrl, SYS_PORT_TOPCTRL_OFFSET);
+/* On SYSTEMPORT Lite, any register after RDMA_STATUS has the exact
+ * same layout, except it has been moved by 4 bytes up, *sigh*
+ */
+static inline u32 rdma_readl(struct bcm_sysport_priv *priv, u32 off)
+{
+ if (priv->is_lite && off >= RDMA_STATUS)
+ off += 4;
+ return __raw_readl(priv->base + SYS_PORT_RDMA_OFFSET + off);
+}
+
+static inline void rdma_writel(struct bcm_sysport_priv *priv, u32 val, u32 off)
+{
+ if (priv->is_lite && off >= RDMA_STATUS)
+ off += 4;
+ __raw_writel(val, priv->base + SYS_PORT_RDMA_OFFSET + off);
+}
+
+static inline u32 tdma_control_bit(struct bcm_sysport_priv *priv, u32 bit)
+{
+ if (!priv->is_lite) {
+ return BIT(bit);
+ } else {
+ if (bit >= ACB_ALGO)
+ return BIT(bit + 1);
+ else
+ return BIT(bit);
+ }
+}
+
/* L2-interrupt masking/unmasking helpers, does automatic saving of the applied
* mask in a software copy to avoid CPU_MASK_STATUS reads in hot-paths.
*/
@@ -143,9 +172,9 @@ static int bcm_sysport_set_tx_csum(struct net_device *dev,
priv->tsb_en = !!(wanted & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM));
reg = tdma_readl(priv, TDMA_CONTROL);
if (priv->tsb_en)
- reg |= TSB_EN;
+ reg |= tdma_control_bit(priv, TSB_EN);
else
- reg &= ~TSB_EN;
+ reg &= ~tdma_control_bit(priv, TSB_EN);
tdma_writel(priv, reg, TDMA_CONTROL);
return 0;
@@ -281,11 +310,35 @@ static void bcm_sysport_set_msglvl(struct net_device *dev, u32 enable)
priv->msg_enable = enable;
}
+static inline bool bcm_sysport_lite_stat_valid(enum bcm_sysport_stat_type type)
+{
+ switch (type) {
+ case BCM_SYSPORT_STAT_NETDEV:
+ case BCM_SYSPORT_STAT_RXCHK:
+ case BCM_SYSPORT_STAT_RBUF:
+ case BCM_SYSPORT_STAT_SOFT:
+ return true;
+ default:
+ return false;
+ }
+}
+
static int bcm_sysport_get_sset_count(struct net_device *dev, int string_set)
{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ const struct bcm_sysport_stats *s;
+ unsigned int i, j;
+
switch (string_set) {
case ETH_SS_STATS:
- return BCM_SYSPORT_STATS_LEN;
+ for (i = 0, j = 0; i < BCM_SYSPORT_STATS_LEN; i++) {
+ s = &bcm_sysport_gstrings_stats[i];
+ if (priv->is_lite &&
+ !bcm_sysport_lite_stat_valid(s->type))
+ continue;
+ j++;
+ }
+ return j;
default:
return -EOPNOTSUPP;
}
@@ -294,14 +347,21 @@ static int bcm_sysport_get_sset_count(struct net_device *dev, int string_set)
static void bcm_sysport_get_strings(struct net_device *dev,
u32 stringset, u8 *data)
{
- int i;
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ const struct bcm_sysport_stats *s;
+ int i, j;
switch (stringset) {
case ETH_SS_STATS:
- for (i = 0; i < BCM_SYSPORT_STATS_LEN; i++) {
- memcpy(data + i * ETH_GSTRING_LEN,
- bcm_sysport_gstrings_stats[i].stat_string,
+ for (i = 0, j = 0; i < BCM_SYSPORT_STATS_LEN; i++) {
+ s = &bcm_sysport_gstrings_stats[i];
+ if (priv->is_lite &&
+ !bcm_sysport_lite_stat_valid(s->type))
+ continue;
+
+ memcpy(data + j * ETH_GSTRING_LEN, s->stat_string,
ETH_GSTRING_LEN);
+ j++;
}
break;
default:
@@ -327,6 +387,9 @@ static void bcm_sysport_update_mib_counters(struct bcm_sysport_priv *priv)
case BCM_SYSPORT_STAT_MIB_RX:
case BCM_SYSPORT_STAT_MIB_TX:
case BCM_SYSPORT_STAT_RUNT:
+ if (priv->is_lite)
+ continue;
+
if (s->type != BCM_SYSPORT_STAT_MIB_RX)
offset = UMAC_MIB_STAT_OFFSET;
val = umac_readl(priv, UMAC_MIB_START + j + offset);
@@ -355,12 +418,12 @@ static void bcm_sysport_get_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{
struct bcm_sysport_priv *priv = netdev_priv(dev);
- int i;
+ int i, j;
if (netif_running(dev))
bcm_sysport_update_mib_counters(priv);
- for (i = 0; i < BCM_SYSPORT_STATS_LEN; i++) {
+ for (i = 0, j = 0; i < BCM_SYSPORT_STATS_LEN; i++) {
const struct bcm_sysport_stats *s;
char *p;
@@ -370,7 +433,8 @@ static void bcm_sysport_get_stats(struct net_device *dev,
else
p = (char *)priv;
p += s->stat_offset;
- data[i] = *(unsigned long *)p;
+ data[j] = *(unsigned long *)p;
+ j++;
}
}
@@ -573,8 +637,14 @@ static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv,
u16 len, status;
struct bcm_rsb *rsb;
- /* Determine how much we should process since last call */
- p_index = rdma_readl(priv, RDMA_PROD_INDEX);
+ /* Determine how much we should process since last call, SYSTEMPORT Lite
+ * groups the producer and consumer indexes into the same 32-bit
+ * which we access using RDMA_CONS_INDEX
+ */
+ if (!priv->is_lite)
+ p_index = rdma_readl(priv, RDMA_PROD_INDEX);
+ else
+ p_index = rdma_readl(priv, RDMA_CONS_INDEX);
p_index &= RDMA_PROD_INDEX_MASK;
if (p_index < priv->rx_c_index)
@@ -791,7 +861,11 @@ static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget)
if (work_done == 0) {
napi_complete(napi);
/* re-enable TX interrupt */
- intrl2_1_mask_clear(ring->priv, BIT(ring->index));
+ if (!ring->priv->is_lite)
+ intrl2_1_mask_clear(ring->priv, BIT(ring->index));
+ else
+ intrl2_0_mask_clear(ring->priv, BIT(ring->index +
+ INTRL2_0_TDMA_MBDONE_SHIFT));
return 0;
}
@@ -817,7 +891,15 @@ static int bcm_sysport_poll(struct napi_struct *napi, int budget)
priv->rx_c_index += work_done;
priv->rx_c_index &= RDMA_CONS_INDEX_MASK;
- rdma_writel(priv, priv->rx_c_index, RDMA_CONS_INDEX);
+
+ /* SYSTEMPORT Lite groups the producer/consumer index, producer is
+ * maintained by HW, but writes to it will be ignore while RDMA
+ * is active
+ */
+ if (!priv->is_lite)
+ rdma_writel(priv, priv->rx_c_index, RDMA_CONS_INDEX);
+ else
+ rdma_writel(priv, priv->rx_c_index << 16, RDMA_CONS_INDEX);
if (work_done < budget) {
napi_complete_done(napi, work_done);
@@ -848,6 +930,8 @@ static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct bcm_sysport_priv *priv = netdev_priv(dev);
+ struct bcm_sysport_tx_ring *txr;
+ unsigned int ring, ring_bit;
priv->irq0_stat = intrl2_0_readl(priv, INTRL2_CPU_STATUS) &
~intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS);
@@ -877,6 +961,22 @@ static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id)
bcm_sysport_resume_from_wol(priv);
}
+ if (!priv->is_lite)
+ goto out;
+
+ for (ring = 0; ring < dev->num_tx_queues; ring++) {
+ ring_bit = BIT(ring + INTRL2_0_TDMA_MBDONE_SHIFT);
+ if (!(priv->irq0_stat & ring_bit))
+ continue;
+
+ txr = &priv->tx_rings[ring];
+
+ if (likely(napi_schedule_prep(&txr->napi))) {
+ intrl2_0_mask_set(priv, ring_bit);
+ __napi_schedule(&txr->napi);
+ }
+ }
+out:
return IRQ_HANDLED;
}
@@ -930,9 +1030,11 @@ static void bcm_sysport_poll_controller(struct net_device *dev)
bcm_sysport_rx_isr(priv->irq0, priv);
enable_irq(priv->irq0);
- disable_irq(priv->irq1);
- bcm_sysport_tx_isr(priv->irq1, priv);
- enable_irq(priv->irq1);
+ if (!priv->is_lite) {
+ disable_irq(priv->irq1);
+ bcm_sysport_tx_isr(priv->irq1, priv);
+ enable_irq(priv->irq1);
+ }
}
#endif
@@ -1129,6 +1231,9 @@ static void bcm_sysport_adj_link(struct net_device *dev)
priv->old_duplex = phydev->duplex;
}
+ if (priv->is_lite)
+ goto out;
+
switch (phydev->speed) {
case SPEED_2500:
cmd_bits = CMD_SPEED_2500;
@@ -1169,8 +1274,9 @@ static void bcm_sysport_adj_link(struct net_device *dev)
reg |= cmd_bits;
umac_writel(priv, reg, UMAC_CMD);
}
-
- phy_print_status(phydev);
+out:
+ if (changed)
+ phy_print_status(phydev);
}
static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
@@ -1315,9 +1421,9 @@ static inline int tdma_enable_set(struct bcm_sysport_priv *priv,
reg = tdma_readl(priv, TDMA_CONTROL);
if (enable)
- reg |= TDMA_EN;
+ reg |= tdma_control_bit(priv, TDMA_EN);
else
- reg &= ~TDMA_EN;
+ reg &= ~tdma_control_bit(priv, TDMA_EN);
tdma_writel(priv, reg, TDMA_CONTROL);
/* Poll for TMDA disabling completion */
@@ -1342,7 +1448,7 @@ static int bcm_sysport_init_rx_ring(struct bcm_sysport_priv *priv)
int i;
/* Initialize SW view of the RX ring */
- priv->num_rx_bds = NUM_RX_DESC;
+ priv->num_rx_bds = priv->num_rx_desc_words / WORDS_PER_DESC;
priv->rx_bds = priv->base + SYS_PORT_RDMA_OFFSET;
priv->rx_c_index = 0;
priv->rx_read_ptr = 0;
@@ -1379,7 +1485,7 @@ static int bcm_sysport_init_rx_ring(struct bcm_sysport_priv *priv)
rdma_writel(priv, 0, RDMA_START_ADDR_HI);
rdma_writel(priv, 0, RDMA_START_ADDR_LO);
rdma_writel(priv, 0, RDMA_END_ADDR_HI);
- rdma_writel(priv, NUM_HW_RX_DESC_WORDS - 1, RDMA_END_ADDR_LO);
+ rdma_writel(priv, priv->num_rx_desc_words - 1, RDMA_END_ADDR_LO);
rdma_writel(priv, 1, RDMA_MBDONE_INTR);
@@ -1421,6 +1527,9 @@ static void bcm_sysport_set_rx_mode(struct net_device *dev)
struct bcm_sysport_priv *priv = netdev_priv(dev);
u32 reg;
+ if (priv->is_lite)
+ return;
+
reg = umac_readl(priv, UMAC_CMD);
if (dev->flags & IFF_PROMISC)
reg |= CMD_PROMISC;
@@ -1438,12 +1547,21 @@ static inline void umac_enable_set(struct bcm_sysport_priv *priv,
{
u32 reg;
- reg = umac_readl(priv, UMAC_CMD);
- if (enable)
- reg |= mask;
- else
- reg &= ~mask;
- umac_writel(priv, reg, UMAC_CMD);
+ if (!priv->is_lite) {
+ reg = umac_readl(priv, UMAC_CMD);
+ if (enable)
+ reg |= mask;
+ else
+ reg &= ~mask;
+ umac_writel(priv, reg, UMAC_CMD);
+ } else {
+ reg = gib_readl(priv, GIB_CONTROL);
+ if (enable)
+ reg |= mask;
+ else
+ reg &= ~mask;
+ gib_writel(priv, reg, GIB_CONTROL);
+ }
/* UniMAC stops on a packet boundary, wait for a full-sized packet
* to be processed (1 msec).
@@ -1456,6 +1574,9 @@ static inline void umac_reset(struct bcm_sysport_priv *priv)
{
u32 reg;
+ if (priv->is_lite)
+ return;
+
reg = umac_readl(priv, UMAC_CMD);
reg |= CMD_SW_RESET;
umac_writel(priv, reg, UMAC_CMD);
@@ -1468,9 +1589,17 @@ static inline void umac_reset(struct bcm_sysport_priv *priv)
static void umac_set_hw_addr(struct bcm_sysport_priv *priv,
unsigned char *addr)
{
- umac_writel(priv, (addr[0] << 24) | (addr[1] << 16) |
- (addr[2] << 8) | addr[3], UMAC_MAC0);
- umac_writel(priv, (addr[4] << 8) | addr[5], UMAC_MAC1);
+ u32 mac0 = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) |
+ addr[3];
+ u32 mac1 = (addr[4] << 8) | addr[5];
+
+ if (!priv->is_lite) {
+ umac_writel(priv, mac0, UMAC_MAC0);
+ umac_writel(priv, mac1, UMAC_MAC1);
+ } else {
+ gib_writel(priv, mac0, GIB_MAC0);
+ gib_writel(priv, mac1, GIB_MAC1);
+ }
}
static void topctrl_flush(struct bcm_sysport_priv *priv)
@@ -1515,8 +1644,11 @@ static void bcm_sysport_netif_start(struct net_device *dev)
phy_start(dev->phydev);
- /* Enable TX interrupts for the 32 TXQs */
- intrl2_1_mask_clear(priv, 0xffffffff);
+ /* Enable TX interrupts for the TXQs */
+ if (!priv->is_lite)
+ intrl2_1_mask_clear(priv, 0xffffffff);
+ else
+ intrl2_0_mask_clear(priv, INTRL2_0_TDMA_MBDONE_MASK);
/* Last call before we start the real business */
netif_tx_start_all_queues(dev);
@@ -1528,9 +1660,37 @@ static void rbuf_init(struct bcm_sysport_priv *priv)
reg = rbuf_readl(priv, RBUF_CONTROL);
reg |= RBUF_4B_ALGN | RBUF_RSB_EN;
+ /* Set a correct RSB format on SYSTEMPORT Lite */
+ if (priv->is_lite) {
+ reg &= ~RBUF_RSB_SWAP1;
+ reg |= RBUF_RSB_SWAP0;
+ }
rbuf_writel(priv, reg, RBUF_CONTROL);
}
+static inline void bcm_sysport_mask_all_intrs(struct bcm_sysport_priv *priv)
+{
+ intrl2_0_mask_set(priv, 0xffffffff);
+ intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+ if (!priv->is_lite) {
+ intrl2_1_mask_set(priv, 0xffffffff);
+ intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+ }
+}
+
+static inline void gib_set_pad_extension(struct bcm_sysport_priv *priv)
+{
+ u32 __maybe_unused reg;
+
+ /* Include Broadcom tag in pad extension */
+ if (netdev_uses_dsa(priv->netdev)) {
+ reg = gib_readl(priv, GIB_CONTROL);
+ reg &= ~(GIB_PAD_EXTENSION_MASK << GIB_PAD_EXTENSION_SHIFT);
+ reg |= ENET_BRCM_TAG_LEN << GIB_PAD_EXTENSION_SHIFT;
+ gib_writel(priv, reg, GIB_CONTROL);
+ }
+}
+
static int bcm_sysport_open(struct net_device *dev)
{
struct bcm_sysport_priv *priv = netdev_priv(dev);
@@ -1551,13 +1711,20 @@ static int bcm_sysport_open(struct net_device *dev)
rbuf_init(priv);
/* Set maximum frame length */
- umac_writel(priv, UMAC_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN);
+ if (!priv->is_lite)
+ umac_writel(priv, UMAC_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN);
+ else
+ gib_set_pad_extension(priv);
/* Set MAC address */
umac_set_hw_addr(priv, dev->dev_addr);
/* Read CRC forward */
- priv->crc_fwd = !!(umac_readl(priv, UMAC_CMD) & CMD_CRC_FWD);
+ if (!priv->is_lite)
+ priv->crc_fwd = !!(umac_readl(priv, UMAC_CMD) & CMD_CRC_FWD);
+ else
+ priv->crc_fwd = !!(gib_readl(priv, GIB_CONTROL) &
+ GIB_FCS_STRIP);
phydev = of_phy_connect(dev, priv->phy_dn, bcm_sysport_adj_link,
0, priv->phy_interface);
@@ -1572,12 +1739,7 @@ static int bcm_sysport_open(struct net_device *dev)
priv->old_pause = -1;
/* mask all interrupts and request them */
- intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET);
- intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
- intrl2_0_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
- intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET);
- intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
- intrl2_1_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
+ bcm_sysport_mask_all_intrs(priv);
ret = request_irq(priv->irq0, bcm_sysport_rx_isr, 0, dev->name, dev);
if (ret) {
@@ -1585,10 +1747,13 @@ static int bcm_sysport_open(struct net_device *dev)
goto out_phy_disconnect;
}
- ret = request_irq(priv->irq1, bcm_sysport_tx_isr, 0, dev->name, dev);
- if (ret) {
- netdev_err(dev, "failed to request TX interrupt\n");
- goto out_free_irq0;
+ if (!priv->is_lite) {
+ ret = request_irq(priv->irq1, bcm_sysport_tx_isr, 0,
+ dev->name, dev);
+ if (ret) {
+ netdev_err(dev, "failed to request TX interrupt\n");
+ goto out_free_irq0;
+ }
}
/* Initialize both hardware and software ring */
@@ -1635,7 +1800,8 @@ static int bcm_sysport_open(struct net_device *dev)
out_free_tx_ring:
for (i = 0; i < dev->num_tx_queues; i++)
bcm_sysport_fini_tx_ring(priv, i);
- free_irq(priv->irq1, dev);
+ if (!priv->is_lite)
+ free_irq(priv->irq1, dev);
out_free_irq0:
free_irq(priv->irq0, dev);
out_phy_disconnect:
@@ -1653,10 +1819,7 @@ static void bcm_sysport_netif_stop(struct net_device *dev)
phy_stop(dev->phydev);
/* mask all interrupts */
- intrl2_0_mask_set(priv, 0xffffffff);
- intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
- intrl2_1_mask_set(priv, 0xffffffff);
- intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+ bcm_sysport_mask_all_intrs(priv);
}
static int bcm_sysport_stop(struct net_device *dev)
@@ -1694,7 +1857,8 @@ static int bcm_sysport_stop(struct net_device *dev)
bcm_sysport_fini_rx_ring(priv);
free_irq(priv->irq0, dev);
- free_irq(priv->irq1, dev);
+ if (!priv->is_lite)
+ free_irq(priv->irq1, dev);
/* Disconnect from PHY */
phy_disconnect(dev->phydev);
@@ -1733,8 +1897,32 @@ static const struct net_device_ops bcm_sysport_netdev_ops = {
#define REV_FMT "v%2x.%02x"
+static const struct bcm_sysport_hw_params bcm_sysport_params[] = {
+ [SYSTEMPORT] = {
+ .is_lite = false,
+ .num_rx_desc_words = SP_NUM_HW_RX_DESC_WORDS,
+ },
+ [SYSTEMPORT_LITE] = {
+ .is_lite = true,
+ .num_rx_desc_words = SP_LT_NUM_HW_RX_DESC_WORDS,
+ },
+};
+
+static const struct of_device_id bcm_sysport_of_match[] = {
+ { .compatible = "brcm,systemportlite-v1.00",
+ .data = &bcm_sysport_params[SYSTEMPORT_LITE] },
+ { .compatible = "brcm,systemport-v1.00",
+ .data = &bcm_sysport_params[SYSTEMPORT] },
+ { .compatible = "brcm,systemport",
+ .data = &bcm_sysport_params[SYSTEMPORT] },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, bcm_sysport_of_match);
+
static int bcm_sysport_probe(struct platform_device *pdev)
{
+ const struct bcm_sysport_hw_params *params;
+ const struct of_device_id *of_id = NULL;
struct bcm_sysport_priv *priv;
struct device_node *dn;
struct net_device *dev;
@@ -1745,6 +1933,12 @@ static int bcm_sysport_probe(struct platform_device *pdev)
dn = pdev->dev.of_node;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ of_id = of_match_node(bcm_sysport_of_match, dn);
+ if (!of_id || !of_id->data)
+ return -EINVAL;
+
+ /* Fairly quickly we need to know the type of adapter we have */
+ params = of_id->data;
/* Read the Transmit/Receive Queue properties */
if (of_property_read_u32(dn, "systemport,num-txq", &txq))
@@ -1770,10 +1964,14 @@ static int bcm_sysport_probe(struct platform_device *pdev)
if (!priv->tx_rings)
return -ENOMEM;
+ priv->is_lite = params->is_lite;
+ priv->num_rx_desc_words = params->num_rx_desc_words;
+
priv->irq0 = platform_get_irq(pdev, 0);
- priv->irq1 = platform_get_irq(pdev, 1);
+ if (!priv->is_lite)
+ priv->irq1 = platform_get_irq(pdev, 1);
priv->wol_irq = platform_get_irq(pdev, 2);
- if (priv->irq0 <= 0 || priv->irq1 <= 0) {
+ if (priv->irq0 <= 0 || (priv->irq1 <= 0 && !priv->is_lite)) {
dev_err(&pdev->dev, "invalid interrupts\n");
ret = -EINVAL;
goto err_free_netdev;
@@ -1847,8 +2045,9 @@ static int bcm_sysport_probe(struct platform_device *pdev)
priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK;
dev_info(&pdev->dev,
- "Broadcom SYSTEMPORT" REV_FMT
+ "Broadcom SYSTEMPORT%s" REV_FMT
" at 0x%p (irqs: %d, %d, TXQs: %d, RXQs: %d)\n",
+ priv->is_lite ? " Lite" : "",
(priv->rev >> 8) & 0xff, priv->rev & 0xff,
priv->base, priv->irq0, priv->irq1, txq, rxq);
@@ -2044,7 +2243,10 @@ static int bcm_sysport_resume(struct device *d)
rbuf_init(priv);
/* Set maximum frame length */
- umac_writel(priv, UMAC_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN);
+ if (!priv->is_lite)
+ umac_writel(priv, UMAC_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN);
+ else
+ gib_set_pad_extension(priv);
/* Set MAC address */
umac_set_hw_addr(priv, dev->dev_addr);
@@ -2080,13 +2282,6 @@ static int bcm_sysport_resume(struct device *d)
static SIMPLE_DEV_PM_OPS(bcm_sysport_pm_ops,
bcm_sysport_suspend, bcm_sysport_resume);
-static const struct of_device_id bcm_sysport_of_match[] = {
- { .compatible = "brcm,systemport-v1.00" },
- { .compatible = "brcm,systemport" },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, bcm_sysport_of_match);
-
static struct platform_driver bcm_sysport_driver = {
.probe = bcm_sysport_probe,
.remove = bcm_sysport_remove,
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h
index f051356b0274..863ddd7870b7 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.h
+++ b/drivers/net/ethernet/broadcom/bcmsysport.h
@@ -127,6 +127,10 @@ struct bcm_rsb {
#define INTRL2_0_DESC_ALLOC_ERR (1 << 10)
#define INTRL2_0_UNEXP_PKTSIZE_ACK (1 << 11)
+/* SYSTEMPORT Lite groups the TX queues interrupts on instance 0 */
+#define INTRL2_0_TDMA_MBDONE_SHIFT 12
+#define INTRL2_0_TDMA_MBDONE_MASK (0xffff << INTRL2_0_TDMA_MBDONE_SHIFT)
+
/* RXCHK offset and defines */
#define SYS_PORT_RXCHK_OFFSET 0x300
@@ -176,7 +180,9 @@ struct bcm_rsb {
#define RBUF_OK_TO_SEND_MASK 0xff
#define RBUF_CRC_REPLACE (1 << 20)
#define RBUF_OK_TO_SEND_MODE (1 << 21)
-#define RBUF_RSB_SWAP (1 << 22)
+/* SYSTEMPORT Lite uses two bits here */
+#define RBUF_RSB_SWAP0 (1 << 22)
+#define RBUF_RSB_SWAP1 (1 << 23)
#define RBUF_ACPI_EN (1 << 23)
#define RBUF_PKT_RDY_THRESH 0x04
@@ -247,6 +253,7 @@ struct bcm_rsb {
#define MIB_RUNT_CNT_RST (1 << 1)
#define MIB_TX_CNT_RST (1 << 2)
+/* These offsets are valid for SYSTEMPORT and SYSTEMPORT Lite */
#define UMAC_MPD_CTRL 0x620
#define MPD_EN (1 << 0)
#define MSEQ_LEN_SHIFT 16
@@ -258,6 +265,34 @@ struct bcm_rsb {
#define UMAC_MDF_CTRL 0x650
#define UMAC_MDF_ADDR 0x654
+/* Only valid on SYSTEMPORT Lite */
+#define SYS_PORT_GIB_OFFSET 0x1000
+
+#define GIB_CONTROL 0x00
+#define GIB_TX_EN (1 << 0)
+#define GIB_RX_EN (1 << 1)
+#define GIB_TX_FLUSH (1 << 2)
+#define GIB_RX_FLUSH (1 << 3)
+#define GIB_GTX_CLK_SEL_SHIFT 4
+#define GIB_GTX_CLK_EXT_CLK (0 << GIB_GTX_CLK_SEL_SHIFT)
+#define GIB_GTX_CLK_125MHZ (1 << GIB_GTX_CLK_SEL_SHIFT)
+#define GIB_GTX_CLK_250MHZ (2 << GIB_GTX_CLK_SEL_SHIFT)
+#define GIB_FCS_STRIP (1 << 6)
+#define GIB_LCL_LOOP_EN (1 << 7)
+#define GIB_LCL_LOOP_TXEN (1 << 8)
+#define GIB_RMT_LOOP_EN (1 << 9)
+#define GIB_RMT_LOOP_RXEN (1 << 10)
+#define GIB_RX_PAUSE_EN (1 << 11)
+#define GIB_PREAMBLE_LEN_SHIFT 12
+#define GIB_PREAMBLE_LEN_MASK 0xf
+#define GIB_IPG_LEN_SHIFT 16
+#define GIB_IPG_LEN_MASK 0x3f
+#define GIB_PAD_EXTENSION_SHIFT 22
+#define GIB_PAD_EXTENSION_MASK 0x3f
+
+#define GIB_MAC1 0x08
+#define GIB_MAC0 0x0c
+
/* Receive DMA offset and defines */
#define SYS_PORT_RDMA_OFFSET 0x2000
@@ -409,16 +444,19 @@ struct bcm_rsb {
RING_PCP_DEI_VID)
#define TDMA_CONTROL 0x600
-#define TDMA_EN (1 << 0)
-#define TSB_EN (1 << 1)
-#define TSB_SWAP (1 << 2)
-#define ACB_ALGO (1 << 3)
+#define TDMA_EN 0
+#define TSB_EN 1
+/* Uses 2 bits on SYSTEMPORT Lite and shifts everything by 1 bit, we
+ * keep the SYSTEMPORT layout here and adjust with tdma_control_bit()
+ */
+#define TSB_SWAP 2
+#define ACB_ALGO 3
#define BUF_DATA_OFFSET_SHIFT 4
#define BUF_DATA_OFFSET_MASK 0x3ff
-#define VLAN_EN (1 << 14)
-#define SW_BRCM_TAG (1 << 15)
-#define WNC_KPT_SIZE_UPDATE (1 << 16)
-#define SYNC_PKT_SIZE (1 << 17)
+#define VLAN_EN 14
+#define SW_BRCM_TAG 15
+#define WNC_KPT_SIZE_UPDATE 16
+#define SYNC_PKT_SIZE 17
#define ACH_TXDONE_DELAY_SHIFT 18
#define ACH_TXDONE_DELAY_MASK 0xff
@@ -475,12 +513,12 @@ struct dma_desc {
};
/* Number of Receive hardware descriptor words */
-#define NUM_HW_RX_DESC_WORDS 1024
-/* Real number of usable descriptors */
-#define NUM_RX_DESC (NUM_HW_RX_DESC_WORDS / WORDS_PER_DESC)
+#define SP_NUM_HW_RX_DESC_WORDS 1024
+#define SP_LT_NUM_HW_RX_DESC_WORDS 256
-/* Internal linked-list RAM has up to 1536 entries */
-#define NUM_TX_DESC 1536
+/* Internal linked-list RAM size */
+#define SP_NUM_TX_DESC 1536
+#define SP_LT_NUM_TX_DESC 256
#define WORDS_PER_DESC (sizeof(struct dma_desc) / sizeof(u32))
@@ -627,6 +665,16 @@ struct bcm_sysport_cb {
DEFINE_DMA_UNMAP_LEN(dma_len);
};
+enum bcm_sysport_type {
+ SYSTEMPORT = 0,
+ SYSTEMPORT_LITE,
+};
+
+struct bcm_sysport_hw_params {
+ bool is_lite;
+ unsigned int num_rx_desc_words;
+};
+
/* Software view of the TX ring */
struct bcm_sysport_tx_ring {
spinlock_t lock; /* Ring lock for tx reclaim/xmit */
@@ -651,6 +699,8 @@ struct bcm_sysport_priv {
u32 irq0_mask;
u32 irq1_stat;
u32 irq1_mask;
+ bool is_lite;
+ unsigned int num_rx_desc_words;
struct napi_struct napi ____cacheline_aligned;
struct net_device *netdev;
struct platform_device *pdev;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 1/2] net: systemport: Dynamically allocate number of TX rings
From: Florian Fainelli @ 2017-01-20 19:08 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
In-Reply-To: <20170120190827.26444-1-f.fainelli@gmail.com>
In preparation for adding SYSTEMPORT Lite, which has twice as less transmit
queues than SYSTEMPORT make sure we do allocate TX rings based on the
systemport,txq property to get an appropriate memory footprint.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/broadcom/bcmsysport.c | 11 +++++++++++
drivers/net/ethernet/broadcom/bcmsysport.h | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index 744ed6ddaf37..31bb2c3696ec 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -1752,6 +1752,10 @@ static int bcm_sysport_probe(struct platform_device *pdev)
if (of_property_read_u32(dn, "systemport,num-rxq", &rxq))
rxq = 1;
+ /* Sanity check the number of transmit queues */
+ if (!txq || txq > TDMA_NUM_RINGS)
+ return -EINVAL;
+
dev = alloc_etherdev_mqs(sizeof(*priv), txq, rxq);
if (!dev)
return -ENOMEM;
@@ -1759,6 +1763,13 @@ static int bcm_sysport_probe(struct platform_device *pdev)
/* Initialize private members */
priv = netdev_priv(dev);
+ /* Allocate number of TX rings */
+ priv->tx_rings = devm_kcalloc(&pdev->dev, txq,
+ sizeof(struct bcm_sysport_tx_ring),
+ GFP_KERNEL);
+ if (!priv->tx_rings)
+ return -ENOMEM;
+
priv->irq0 = platform_get_irq(pdev, 0);
priv->irq1 = platform_get_irq(pdev, 1);
priv->wol_irq = platform_get_irq(pdev, 2);
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h
index 1c82e3da69a7..f051356b0274 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.h
+++ b/drivers/net/ethernet/broadcom/bcmsysport.h
@@ -659,7 +659,7 @@ struct bcm_sysport_priv {
int wol_irq;
/* Transmit rings */
- struct bcm_sysport_tx_ring tx_rings[TDMA_NUM_RINGS];
+ struct bcm_sysport_tx_ring *tx_rings;
/* Receive queue */
void __iomem *rx_bds;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 0/2] net: systemport: Add support for SYSTEMPORT lite
From: Florian Fainelli @ 2017-01-20 19:08 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
Hi David,
This patch series adds support for SYSTEMPORT Lite which is an evolution
of the existing SYSTEMPORT adapter.
The two generations are largely identical as far as the transmit/receive
path are concerned, and there were just a few control path changes here
and there.
Thanks!
Florian Fainelli (2):
net: systemport: Dynamically allocate number of TX rings
net: systemport: Add support for SYSTEMPORT Lite
.../devicetree/bindings/net/brcm,systemport.txt | 5 +-
drivers/net/ethernet/broadcom/bcmsysport.c | 334 +++++++++++++++++----
drivers/net/ethernet/broadcom/bcmsysport.h | 80 ++++-
3 files changed, 339 insertions(+), 80 deletions(-)
--
2.11.0
^ permalink raw reply
* [PATCH v2 iproute2] f_flower: don't set TCA_FLOWER_KEY_ETH_TYPE for "protocol all"
From: Benjamin LaHaise @ 2017-01-20 19:07 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Jamal Hadi Salim, netdev, bcrl
v2 - update to address changes in 00697ca19ae3e1118f2af82c3b41ac4335fe918b.
When using the tc flower filter, rules marked with "protocol all" do not
actually match all packets. This is due to a bug in f_flower.c that passes
in ETH_P_ALL in the TCA_FLOWER_KEY_ETH_TYPE attribute when adding a rule.
Fix this by omitting TCA_FLOWER_KEY_ETH_TYPE if the protocol is set to
ETH_P_ALL.
Fixes: 488b41d020fb ("tc: flower no need to specify the ethertype")
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Benjamin LaHaise <benjamin.lahaise@netronome.com>
Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 314c2dd..145a856 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -529,9 +529,11 @@ parse_done:
if (ret)
return ret;
- ret = addattr16(n, MAX_MSG, TCA_FLOWER_KEY_ETH_TYPE, eth_type);
- if (ret)
- return ret;
+ if (eth_type != htons(ETH_P_ALL)) {
+ ret = addattr16(n, MAX_MSG, TCA_FLOWER_KEY_ETH_TYPE, eth_type);
+ if (ret)
+ return ret;
+ }
tail->rta_len = (((void *)n)+n->nlmsg_len) - (void *)tail;
^ permalink raw reply related
* Re: [PATCH iproute2 net-next V5] tc: flower: Refactor matching flags to be more user friendly
From: Stephen Hemminger @ 2017-01-20 18:38 UTC (permalink / raw)
To: Paul Blakey
Cc: netdev, Jiri Pirko, Or Gerlitz, Roi Dayan, Jiri Benc,
Simon Horman
In-Reply-To: <1484836073-47019-1-git-send-email-paulb@mellanox.com>
On Thu, 19 Jan 2017 16:27:53 +0200
Paul Blakey <paulb@mellanox.com> wrote:
> Instead of "magic numbers" we can now specify each flag
> by name. Prefix of "no" (e.g nofrag) unsets the flag,
> otherwise it wil be set.
>
> Example:
> # add a flower filter that will drop fragmented packets
> tc filter add dev ens4f0 protocol ip parent ffff: \
> flower \
> src_mac e4:1d:2d:fd:8b:01 \
> dst_mac e4:1d:2d:fd:8b:02 \
> indev ens4f0 \
> ip_flags frag \
> action drop
>
> # add a flower filter that will drop non-fragmented packets
> tc filter add dev ens4f0 protocol ip parent ffff: \
> flower \
> src_mac e4:1d:2d:fd:8b:01 \
> dst_mac e4:1d:2d:fd:8b:02 \
> indev ens4f0 \
> ip_flags nofrag \
> action drop
>
> Fixes: 22a8f019891c ('tc: flower: support matching flags')
> Signed-off-by: Paul Blakey <paulb@mellanox.com>
> Reviewed-by: Roi Dayan <roid@mellanox.com>
> ---
>
> Hi,
> Added a framework to add new flags more easily, such
> as the upcoming tcp_flags (see kernel cls_flower), and other ip_flags.
>
> Thanks,
> Paul.
>
>
> Changelog:
>
> v5:
> Fixed wrong use of strtok to skip old prefix.
>
> v4:
> Changed prefix in manpage as well.
>
> v3:
> Changed prefix to "no" instead of "no_".
>
> v2:
> Changed delimiter to "/" to avoid shell pipe errors.
>
>
> man/man8/tc-flower.8 | 12 +++++-
> tc/f_flower.c | 117 ++++++++++++++++++++++++++++++++++++++++-----------
> 2 files changed, 102 insertions(+), 27 deletions(-)
>
Applied to net-next (defuzzed)
^ permalink raw reply
* Re: [PATCH v3 2/3] NFC: trf7970a: Add device tree option of 1.8 Volt IO voltage
From: Mark Greer @ 2017-01-20 18:37 UTC (permalink / raw)
To: Geoff Lansberry
Cc: linux-wireless, lauro.venancio, aloisio.almeida, sameo, robh+dt,
mark.rutland, netdev, devicetree, linux-kernel, justin
In-Reply-To: <1482380314-16440-2-git-send-email-geoff@kuvee.com>
On Wed, Dec 21, 2016 at 11:18:33PM -0500, Geoff Lansberry wrote:
> The TRF7970A has configuration options for supporting hardware designs
> with 1.8 Volt or 3.3 Volt IO. This commit adds a device tree option,
> using a fixed regulator binding, for setting the io voltage to match
> the hardware configuration. If no option is supplied it defaults to
> 3.3 volt configuration.
>
> Signed-off-by: Geoff Lansberry <geoff@kuvee.com>
> ---
> .../devicetree/bindings/net/nfc/trf7970a.txt | 2 ++
> drivers/nfc/trf7970a.c | 26 +++++++++++++++++++++-
Acked-by: Mark Greer <mgreer@animalcreek.com>
^ permalink raw reply
* Re: [PATCHv2 iproute2 net-next 1/5] iplink: bridge: add support for IFLA_BR_FDB_FLUSH
From: Stephen Hemminger @ 2017-01-20 18:34 UTC (permalink / raw)
To: Hangbin Liu; +Cc: netdev, Nikolay Aleksandrov
In-Reply-To: <1484719971-21693-2-git-send-email-liuhangbin@gmail.com>
On Wed, 18 Jan 2017 14:12:47 +0800
Hangbin Liu <liuhangbin@gmail.com> wrote:
> This patch implements support for the IFLA_BR_FDB_FLUSH attribute
> in iproute2 so it can flush bridge fdb dynamic entries.
>
> Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> ---
> ip/iplink_bridge.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
Applied all of these to net-next, please update man pages.
^ permalink raw reply
* Re: [PATCHv4 net-next 3/5] sctp: implement sender-side procedures for SSN/TSN Reset Request Parameter
From: Marcelo Ricardo Leitner @ 2017-01-20 18:25 UTC (permalink / raw)
To: Xin Long; +Cc: network dev, linux-sctp, Neil Horman, Vlad Yasevich, davem
In-Reply-To: <ae54d06e442d8fba6a5983fb81fb4c8ae4bee3ef.1484934853.git.lucien.xin@gmail.com>
On Sat, Jan 21, 2017 at 02:00:37AM +0800, Xin Long wrote:
> This patch is to implement Sender-Side Procedures for the SSN/TSN
> Reset Request Parameter descibed in rfc6525 section 5.1.4.
>
> It is also to add sockopt SCTP_RESET_ASSOC in rfc6525 section 6.3.3
> for users.
>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
> include/net/sctp/sctp.h | 1 +
> include/uapi/linux/sctp.h | 1 +
> net/sctp/socket.c | 29 +++++++++++++++++++++++++++++
> net/sctp/stream.c | 37 +++++++++++++++++++++++++++++++++++++
> 4 files changed, 68 insertions(+)
>
> diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
> index 3cfd365b..b93820f 100644
> --- a/include/net/sctp/sctp.h
> +++ b/include/net/sctp/sctp.h
> @@ -198,6 +198,7 @@ int sctp_offload_init(void);
> */
> int sctp_send_reset_streams(struct sctp_association *asoc,
> struct sctp_reset_streams *params);
> +int sctp_send_reset_assoc(struct sctp_association *asoc);
>
> /*
> * Module global variables
> diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
> index 03c27ce..c0bd8c3 100644
> --- a/include/uapi/linux/sctp.h
> +++ b/include/uapi/linux/sctp.h
> @@ -117,6 +117,7 @@ typedef __s32 sctp_assoc_t;
> #define SCTP_PR_ASSOC_STATUS 115
> #define SCTP_ENABLE_STREAM_RESET 118
> #define SCTP_RESET_STREAMS 119
> +#define SCTP_RESET_ASSOC 120
>
> /* PR-SCTP policies */
> #define SCTP_PR_SCTP_NONE 0x0000
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index bee4dd3..2c5c9ca 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -3812,6 +3812,32 @@ static int sctp_setsockopt_reset_streams(struct sock *sk,
> return retval;
> }
>
> +static int sctp_setsockopt_reset_assoc(struct sock *sk,
> + char __user *optval,
> + unsigned int optlen)
> +{
> + struct sctp_association *asoc;
> + sctp_assoc_t associd;
> + int retval = -EINVAL;
> +
> + if (optlen != sizeof(associd))
> + goto out;
> +
> + if (copy_from_user(&associd, optval, optlen)) {
> + retval = -EFAULT;
> + goto out;
> + }
> +
> + asoc = sctp_id2assoc(sk, associd);
> + if (!asoc)
> + goto out;
> +
> + retval = sctp_send_reset_assoc(asoc);
> +
> +out:
> + return retval;
> +}
> +
> /* API 6.2 setsockopt(), getsockopt()
> *
> * Applications use setsockopt() and getsockopt() to set or retrieve
> @@ -3984,6 +4010,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
> case SCTP_RESET_STREAMS:
> retval = sctp_setsockopt_reset_streams(sk, optval, optlen);
> break;
> + case SCTP_RESET_ASSOC:
> + retval = sctp_setsockopt_reset_assoc(sk, optval, optlen);
> + break;
> default:
> retval = -ENOPROTOOPT;
> break;
> diff --git a/net/sctp/stream.c b/net/sctp/stream.c
> index 53c67d6..3b872a8 100644
> --- a/net/sctp/stream.c
> +++ b/net/sctp/stream.c
> @@ -166,3 +166,40 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
> out:
> return retval;
> }
> +
> +int sctp_send_reset_assoc(struct sctp_association *asoc)
> +{
> + struct sctp_chunk *chunk = NULL;
> + int retval;
> + __u16 i;
> +
> + if (!asoc->peer.reconf_capable ||
> + !(asoc->strreset_enable & SCTP_ENABLE_RESET_ASSOC_REQ))
> + return -ENOPROTOOPT;
> +
> + if (asoc->strreset_outstanding)
> + return -EINPROGRESS;
> +
> + chunk = sctp_make_strreset_tsnreq(asoc);
> + if (!chunk)
> + return -ENOMEM;
> +
> + asoc->strreset_chunk = chunk;
> + sctp_chunk_hold(asoc->strreset_chunk);
> +
> + retval = sctp_send_reconf(asoc, chunk);
> + if (retval) {
> + sctp_chunk_put(asoc->strreset_chunk);
> + asoc->strreset_chunk = NULL;
> +
> + return retval;
> + }
> +
> + /* Block further xmit of data until this request is completed */
> + for (i = 0; i < asoc->stream->outcnt; i++)
> + asoc->stream->out[i].state = SCTP_STREAM_CLOSED;
I talked offline with Xin about this and we cannot do it this way.
Unfortunatelly we will have to take the long road here, because then we
may send data while sending the request, as the streams are not closed
yet.
We really need to close team, send the request, and re-open if the send
fails.
Marcelo
> +
> + asoc->strreset_outstanding = 1;
> +
> + return 0;
> +}
> --
> 2.1.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [PATCH net v1 2/2] amd-xgbe: Check xgbe_init() return code
From: Tom Lendacky @ 2017-01-20 18:14 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <20170120181352.2321.63733.stgit@tlendack-t1.amdoffice.net>
The xgbe_init() routine returns a return code indicating success or
failure, but the return code is not checked. Add code to xgbe_init()
to issue a message when failures are seen and add code to check the
xgbe_init() return code.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 4 +++-
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index c8e8a4a..a7d16db 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -3407,8 +3407,10 @@ static int xgbe_init(struct xgbe_prv_data *pdata)
/* Flush Tx queues */
ret = xgbe_flush_tx_queues(pdata);
- if (ret)
+ if (ret) {
+ netdev_err(pdata->netdev, "error flushing TX queues\n");
return ret;
+ }
/*
* Initialize DMA related features
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 9943629..1c87cc2 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -1070,7 +1070,9 @@ static int xgbe_start(struct xgbe_prv_data *pdata)
DBGPR("-->xgbe_start\n");
- hw_if->init(pdata);
+ ret = hw_if->init(pdata);
+ if (ret)
+ return ret;
xgbe_napi_enable(pdata, 1);
^ permalink raw reply related
* [PATCH net v1 1/2] amd-xgbe: Add a hardware quirk for register definitions
From: Tom Lendacky @ 2017-01-20 18:14 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <20170120181352.2321.63733.stgit@tlendack-t1.amdoffice.net>
A newer version of the hardware is using the same PCI ids for the network
device but has altered register definitions for determining the window
settings for the indirect PCS access. Add support to check for this
hardware and if found use the new register values.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-common.h | 2 ++
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 4 ++--
drivers/net/ethernet/amd/xgbe/xgbe-pci.c | 15 ++++++++++++++-
drivers/net/ethernet/amd/xgbe/xgbe.h | 2 ++
4 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
index 5b7ba25..8a280e7 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
@@ -891,6 +891,8 @@
#define PCS_V1_WINDOW_SELECT 0x03fc
#define PCS_V2_WINDOW_DEF 0x9060
#define PCS_V2_WINDOW_SELECT 0x9064
+#define PCS_V2_RV_WINDOW_DEF 0x1060
+#define PCS_V2_RV_WINDOW_SELECT 0x1064
/* PCS register entry bit positions and sizes */
#define PCS_V2_WINDOW_DEF_OFFSET_INDEX 6
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index aaf0350..c8e8a4a 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1151,7 +1151,7 @@ static int xgbe_read_mmd_regs_v2(struct xgbe_prv_data *pdata, int prtad,
offset = pdata->xpcs_window + (mmd_address & pdata->xpcs_window_mask);
spin_lock_irqsave(&pdata->xpcs_lock, flags);
- XPCS32_IOWRITE(pdata, PCS_V2_WINDOW_SELECT, index);
+ XPCS32_IOWRITE(pdata, pdata->xpcs_window_sel_reg, index);
mmd_data = XPCS16_IOREAD(pdata, offset);
spin_unlock_irqrestore(&pdata->xpcs_lock, flags);
@@ -1183,7 +1183,7 @@ static void xgbe_write_mmd_regs_v2(struct xgbe_prv_data *pdata, int prtad,
offset = pdata->xpcs_window + (mmd_address & pdata->xpcs_window_mask);
spin_lock_irqsave(&pdata->xpcs_lock, flags);
- XPCS32_IOWRITE(pdata, PCS_V2_WINDOW_SELECT, index);
+ XPCS32_IOWRITE(pdata, pdata->xpcs_window_sel_reg, index);
XPCS16_IOWRITE(pdata, offset, mmd_data);
spin_unlock_irqrestore(&pdata->xpcs_lock, flags);
}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
index e76b7f6..c2730f1 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
@@ -265,6 +265,7 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct xgbe_prv_data *pdata;
struct device *dev = &pdev->dev;
void __iomem * const *iomap_table;
+ struct pci_dev *rdev;
unsigned int ma_lo, ma_hi;
unsigned int reg;
int bar_mask;
@@ -326,8 +327,20 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (netif_msg_probe(pdata))
dev_dbg(dev, "xpcs_regs = %p\n", pdata->xpcs_regs);
+ /* Set the PCS indirect addressing definition registers */
+ rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
+ if (rdev &&
+ (rdev->vendor == PCI_VENDOR_ID_AMD) && (rdev->device == 0x15d0)) {
+ pdata->xpcs_window_def_reg = PCS_V2_RV_WINDOW_DEF;
+ pdata->xpcs_window_sel_reg = PCS_V2_RV_WINDOW_SELECT;
+ } else {
+ pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
+ pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
+ }
+ pci_dev_put(rdev);
+
/* Configure the PCS indirect addressing support */
- reg = XPCS32_IOREAD(pdata, PCS_V2_WINDOW_DEF);
+ reg = XPCS32_IOREAD(pdata, pdata->xpcs_window_def_reg);
pdata->xpcs_window = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, OFFSET);
pdata->xpcs_window <<= 6;
pdata->xpcs_window_size = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, SIZE);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index f52a9bd..0010881 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -955,6 +955,8 @@ struct xgbe_prv_data {
/* XPCS indirect addressing lock */
spinlock_t xpcs_lock;
+ unsigned int xpcs_window_def_reg;
+ unsigned int xpcs_window_sel_reg;
unsigned int xpcs_window;
unsigned int xpcs_window_size;
unsigned int xpcs_window_mask;
^ permalink raw reply related
* [PATCH net v1 0/2] amd-xgbe: AMD XGBE driver fixes 2017-01-20
From: Tom Lendacky @ 2017-01-20 18:13 UTC (permalink / raw)
To: netdev; +Cc: David Miller
This patch series addresses some issues in the AMD XGBE driver.
The following fixes are included in this driver update series:
- Add a fix for a version of the hardware that uses different register
offset values for a device with the same PCI device ID
- Add support to check the return code from the xgbe_init() function
This patch series is based on net.
---
Tom Lendacky (2):
amd-xgbe: Add a hardware quirk for register definitions
amd-xgbe: Check xgbe_init() return code
drivers/net/ethernet/amd/xgbe/xgbe-common.h | 2 ++
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 8 +++++---
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 4 +++-
drivers/net/ethernet/amd/xgbe/xgbe-pci.c | 15 ++++++++++++++-
drivers/net/ethernet/amd/xgbe/xgbe.h | 2 ++
5 files changed, 26 insertions(+), 5 deletions(-)
--
Tom Lendacky
^ permalink raw reply
* Re: [PATCH net v3] bridge: netlink: call br_changelink() during br_dev_newlink()
From: Jiri Pirko @ 2017-01-20 18:10 UTC (permalink / raw)
To: Ivan Vecera; +Cc: netdev, stephen, davem, bridge, jiri
In-Reply-To: <20170120171217.20617-1-cera@cera.cz>
Fri, Jan 20, 2017 at 06:12:17PM CET, cera@cera.cz wrote:
>Any bridge options specified during link creation (e.g. ip link add)
>are ignored as br_dev_newlink() does not process them.
>Use br_changelink() to do it.
>
>Fixes: 1332351 ("bridge: implement rtnl_link_ops->changelink")
Should have 12 chars. Other than that,
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
^ permalink raw reply
* [PATCHv4 net-next 5/5] sctp: implement sender-side procedures for Add Incoming/Outgoing Streams Request Parameter
From: Xin Long @ 2017-01-20 18:00 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
In-Reply-To: <cover.1484934853.git.lucien.xin@gmail.com>
This patch is to implement Sender-Side Procedures for the Add
Outgoing and Incoming Streams Request Parameter described in
rfc6525 section 5.1.5-5.1.6.
It is also to add sockopt SCTP_ADD_STREAMS in rfc6525 section
6.3.4 for users.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/sctp.h | 2 ++
include/uapi/linux/sctp.h | 7 ++++
net/sctp/socket.c | 29 +++++++++++++++++
net/sctp/stream.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 119 insertions(+)
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index b93820f..68ee1a6 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -199,6 +199,8 @@ int sctp_offload_init(void);
int sctp_send_reset_streams(struct sctp_association *asoc,
struct sctp_reset_streams *params);
int sctp_send_reset_assoc(struct sctp_association *asoc);
+int sctp_send_add_streams(struct sctp_association *asoc,
+ struct sctp_add_streams *params);
/*
* Module global variables
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index c0bd8c3..a91a9cc 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -118,6 +118,7 @@ typedef __s32 sctp_assoc_t;
#define SCTP_ENABLE_STREAM_RESET 118
#define SCTP_RESET_STREAMS 119
#define SCTP_RESET_ASSOC 120
+#define SCTP_ADD_STREAMS 121
/* PR-SCTP policies */
#define SCTP_PR_SCTP_NONE 0x0000
@@ -1027,4 +1028,10 @@ struct sctp_reset_streams {
uint16_t srs_stream_list[]; /* list if srs_num_streams is not 0 */
};
+struct sctp_add_streams {
+ sctp_assoc_t sas_assoc_id;
+ uint16_t sas_instrms;
+ uint16_t sas_outstrms;
+};
+
#endif /* _UAPI_SCTP_H */
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 2c5c9ca..ae0a99e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3838,6 +3838,32 @@ static int sctp_setsockopt_reset_assoc(struct sock *sk,
return retval;
}
+static int sctp_setsockopt_add_streams(struct sock *sk,
+ char __user *optval,
+ unsigned int optlen)
+{
+ struct sctp_association *asoc;
+ struct sctp_add_streams params;
+ int retval = -EINVAL;
+
+ if (optlen != sizeof(params))
+ goto out;
+
+ if (copy_from_user(¶ms, optval, optlen)) {
+ retval = -EFAULT;
+ goto out;
+ }
+
+ asoc = sctp_id2assoc(sk, params.sas_assoc_id);
+ if (!asoc)
+ goto out;
+
+ retval = sctp_send_add_streams(asoc, ¶ms);
+
+out:
+ return retval;
+}
+
/* API 6.2 setsockopt(), getsockopt()
*
* Applications use setsockopt() and getsockopt() to set or retrieve
@@ -4013,6 +4039,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
case SCTP_RESET_ASSOC:
retval = sctp_setsockopt_reset_assoc(sk, optval, optlen);
break;
+ case SCTP_ADD_STREAMS:
+ retval = sctp_setsockopt_add_streams(sk, optval, optlen);
+ break;
default:
retval = -ENOPROTOOPT;
break;
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index 3b872a8..cb255e6 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -203,3 +203,84 @@ int sctp_send_reset_assoc(struct sctp_association *asoc)
return 0;
}
+
+int sctp_send_add_streams(struct sctp_association *asoc,
+ struct sctp_add_streams *params)
+{
+ struct sctp_stream *stream = asoc->stream;
+ struct sctp_chunk *chunk = NULL;
+ int retval = -ENOMEM;
+ __u16 out, in, nums;
+
+ if (!asoc->peer.reconf_capable ||
+ !(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
+ retval = -ENOPROTOOPT;
+ goto out;
+ }
+
+ if (asoc->strreset_outstanding) {
+ retval = -EINPROGRESS;
+ goto out;
+ }
+
+ out = params->sas_outstrms;
+ in = params->sas_instrms;
+ if (stream->outcnt + out > SCTP_MAX_STREAM ||
+ stream->incnt + in > SCTP_MAX_STREAM || (!out && !in)) {
+ retval = -EINVAL;
+ goto out;
+ }
+
+ nums = stream->outcnt + out;
+ /* Use ksize to check if stream array really needs to realloc */
+ if (out && ksize(stream->out) < nums * sizeof(*stream->out)) {
+ struct sctp_stream_out *streamout;
+
+ streamout = kcalloc(nums, sizeof(*streamout), GFP_KERNEL);
+ if (!streamout)
+ goto out;
+
+ memcpy(streamout, stream->out,
+ sizeof(*streamout) * stream->outcnt);
+
+ kfree(stream->out);
+ stream->out = streamout;
+ }
+
+ nums = stream->incnt + in;
+ if (in && ksize(stream->in) < nums * sizeof(*stream->in)) {
+ struct sctp_stream_in *streamin;
+
+ streamin = kcalloc(nums, sizeof(*streamin), GFP_KERNEL);
+ if (!streamin)
+ goto out;
+
+ memcpy(streamin, stream->in,
+ sizeof(*streamin) * stream->incnt);
+
+ kfree(stream->in);
+ stream->in = streamin;
+ }
+
+ chunk = sctp_make_strreset_addstrm(asoc, out, in);
+ if (!chunk)
+ goto out;
+
+ asoc->strreset_chunk = chunk;
+ sctp_chunk_hold(asoc->strreset_chunk);
+
+ retval = sctp_send_reconf(asoc, chunk);
+ if (retval) {
+ sctp_chunk_put(asoc->strreset_chunk);
+ asoc->strreset_chunk = NULL;
+ goto out;
+ }
+
+ stream->incnt += in;
+ stream->outcnt += out;
+
+ asoc->strreset_outstanding = !!out + !!in;
+
+out:
+ return retval;
+}
--
2.1.0
^ permalink raw reply related
* [PATCHv4 net-next 4/5] sctp: add support for generating stream reconf add incoming/outgoing streams request chunk
From: Xin Long @ 2017-01-20 18:00 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
In-Reply-To: <cover.1484934853.git.lucien.xin@gmail.com>
This patch is to define Add Incoming/Outgoing Streams Request
Parameter described in rfc6525 section 4.5 and 4.6. They can
be in one same chunk trunk as rfc6525 section 3.1-7 describes,
so make them in one function.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/linux/sctp.h | 7 +++++++
include/net/sctp/sm.h | 3 +++
net/sctp/sm_make_chunk.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 56 insertions(+)
diff --git a/include/linux/sctp.h b/include/linux/sctp.h
index 95b8ed3..f1f494f 100644
--- a/include/linux/sctp.h
+++ b/include/linux/sctp.h
@@ -742,4 +742,11 @@ struct sctp_strreset_tsnreq {
__u32 request_seq;
} __packed;
+struct sctp_strreset_addstrm {
+ sctp_paramhdr_t param_hdr;
+ __u32 request_seq;
+ __u16 number_of_streams;
+ __u16 reserved;
+} __packed;
+
#endif /* __LINUX_SCTP_H__ */
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index ac37c17..3675fde 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -267,6 +267,9 @@ struct sctp_chunk *sctp_make_strreset_req(
bool out, bool in);
struct sctp_chunk *sctp_make_strreset_tsnreq(
const struct sctp_association *asoc);
+struct sctp_chunk *sctp_make_strreset_addstrm(
+ const struct sctp_association *asoc,
+ __u16 out, __u16 in);
void sctp_chunk_assign_tsn(struct sctp_chunk *);
void sctp_chunk_assign_ssn(struct sctp_chunk *);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 801450c..a44546d 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3689,3 +3689,49 @@ struct sctp_chunk *sctp_make_strreset_tsnreq(
return retval;
}
+
+/* RE-CONFIG 4.5/4.6 (ADD STREAM)
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Parameter Type = 17 | Parameter Length = 12 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Re-configuration Request Sequence Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Number of new streams | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct sctp_chunk *sctp_make_strreset_addstrm(
+ const struct sctp_association *asoc,
+ __u16 out, __u16 in)
+{
+ struct sctp_strreset_addstrm addstrm;
+ __u16 size = sizeof(addstrm);
+ struct sctp_chunk *retval;
+
+ retval = sctp_make_reconf(asoc, (!!out + !!in) * size);
+ if (!retval)
+ return NULL;
+
+ if (out) {
+ addstrm.param_hdr.type = SCTP_PARAM_RESET_ADD_OUT_STREAMS;
+ addstrm.param_hdr.length = htons(size);
+ addstrm.number_of_streams = htons(out);
+ addstrm.request_seq = htonl(asoc->strreset_outseq);
+ addstrm.reserved = 0;
+
+ sctp_addto_chunk(retval, size, &addstrm);
+ }
+
+ if (in) {
+ addstrm.param_hdr.type = SCTP_PARAM_RESET_ADD_IN_STREAMS;
+ addstrm.param_hdr.length = htons(size);
+ addstrm.number_of_streams = htons(in);
+ addstrm.request_seq = htonl(asoc->strreset_outseq + !!out);
+ addstrm.reserved = 0;
+
+ sctp_addto_chunk(retval, size, &addstrm);
+ }
+
+ return retval;
+}
--
2.1.0
^ permalink raw reply related
* [PATCHv4 net-next 3/5] sctp: implement sender-side procedures for SSN/TSN Reset Request Parameter
From: Xin Long @ 2017-01-20 18:00 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
In-Reply-To: <cover.1484934853.git.lucien.xin@gmail.com>
This patch is to implement Sender-Side Procedures for the SSN/TSN
Reset Request Parameter descibed in rfc6525 section 5.1.4.
It is also to add sockopt SCTP_RESET_ASSOC in rfc6525 section 6.3.3
for users.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/sctp.h | 1 +
include/uapi/linux/sctp.h | 1 +
net/sctp/socket.c | 29 +++++++++++++++++++++++++++++
net/sctp/stream.c | 37 +++++++++++++++++++++++++++++++++++++
4 files changed, 68 insertions(+)
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 3cfd365b..b93820f 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -198,6 +198,7 @@ int sctp_offload_init(void);
*/
int sctp_send_reset_streams(struct sctp_association *asoc,
struct sctp_reset_streams *params);
+int sctp_send_reset_assoc(struct sctp_association *asoc);
/*
* Module global variables
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index 03c27ce..c0bd8c3 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -117,6 +117,7 @@ typedef __s32 sctp_assoc_t;
#define SCTP_PR_ASSOC_STATUS 115
#define SCTP_ENABLE_STREAM_RESET 118
#define SCTP_RESET_STREAMS 119
+#define SCTP_RESET_ASSOC 120
/* PR-SCTP policies */
#define SCTP_PR_SCTP_NONE 0x0000
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index bee4dd3..2c5c9ca 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3812,6 +3812,32 @@ static int sctp_setsockopt_reset_streams(struct sock *sk,
return retval;
}
+static int sctp_setsockopt_reset_assoc(struct sock *sk,
+ char __user *optval,
+ unsigned int optlen)
+{
+ struct sctp_association *asoc;
+ sctp_assoc_t associd;
+ int retval = -EINVAL;
+
+ if (optlen != sizeof(associd))
+ goto out;
+
+ if (copy_from_user(&associd, optval, optlen)) {
+ retval = -EFAULT;
+ goto out;
+ }
+
+ asoc = sctp_id2assoc(sk, associd);
+ if (!asoc)
+ goto out;
+
+ retval = sctp_send_reset_assoc(asoc);
+
+out:
+ return retval;
+}
+
/* API 6.2 setsockopt(), getsockopt()
*
* Applications use setsockopt() and getsockopt() to set or retrieve
@@ -3984,6 +4010,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
case SCTP_RESET_STREAMS:
retval = sctp_setsockopt_reset_streams(sk, optval, optlen);
break;
+ case SCTP_RESET_ASSOC:
+ retval = sctp_setsockopt_reset_assoc(sk, optval, optlen);
+ break;
default:
retval = -ENOPROTOOPT;
break;
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index 53c67d6..3b872a8 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -166,3 +166,40 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
out:
return retval;
}
+
+int sctp_send_reset_assoc(struct sctp_association *asoc)
+{
+ struct sctp_chunk *chunk = NULL;
+ int retval;
+ __u16 i;
+
+ if (!asoc->peer.reconf_capable ||
+ !(asoc->strreset_enable & SCTP_ENABLE_RESET_ASSOC_REQ))
+ return -ENOPROTOOPT;
+
+ if (asoc->strreset_outstanding)
+ return -EINPROGRESS;
+
+ chunk = sctp_make_strreset_tsnreq(asoc);
+ if (!chunk)
+ return -ENOMEM;
+
+ asoc->strreset_chunk = chunk;
+ sctp_chunk_hold(asoc->strreset_chunk);
+
+ retval = sctp_send_reconf(asoc, chunk);
+ if (retval) {
+ sctp_chunk_put(asoc->strreset_chunk);
+ asoc->strreset_chunk = NULL;
+
+ return retval;
+ }
+
+ /* Block further xmit of data until this request is completed */
+ for (i = 0; i < asoc->stream->outcnt; i++)
+ asoc->stream->out[i].state = SCTP_STREAM_CLOSED;
+
+ asoc->strreset_outstanding = 1;
+
+ return 0;
+}
--
2.1.0
^ permalink raw reply related
* [PATCHv4 net-next 2/5] sctp: add support for generating stream reconf ssn/tsn reset request chunk
From: Xin Long @ 2017-01-20 18:00 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
In-Reply-To: <cover.1484934853.git.lucien.xin@gmail.com>
This patch is to define SSN/TSN Reset Request Parameter described
in rfc6525 section 4.3.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/linux/sctp.h | 5 +++++
include/net/sctp/sm.h | 2 ++
net/sctp/sm_make_chunk.c | 29 +++++++++++++++++++++++++++++
3 files changed, 36 insertions(+)
diff --git a/include/linux/sctp.h b/include/linux/sctp.h
index a9e7906..95b8ed3 100644
--- a/include/linux/sctp.h
+++ b/include/linux/sctp.h
@@ -737,4 +737,9 @@ struct sctp_strreset_inreq {
__u16 list_of_streams[0];
} __packed;
+struct sctp_strreset_tsnreq {
+ sctp_paramhdr_t param_hdr;
+ __u32 request_seq;
+} __packed;
+
#endif /* __LINUX_SCTP_H__ */
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 430ed13..ac37c17 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -265,6 +265,8 @@ struct sctp_chunk *sctp_make_strreset_req(
const struct sctp_association *asoc,
__u16 stream_num, __u16 *stream_list,
bool out, bool in);
+struct sctp_chunk *sctp_make_strreset_tsnreq(
+ const struct sctp_association *asoc);
void sctp_chunk_assign_tsn(struct sctp_chunk *);
void sctp_chunk_assign_ssn(struct sctp_chunk *);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index ad3445b..801450c 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3660,3 +3660,32 @@ struct sctp_chunk *sctp_make_strreset_req(
return retval;
}
+
+/* RE-CONFIG 4.3 (SSN/TSN RESET ALL)
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Parameter Type = 15 | Parameter Length = 8 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Re-configuration Request Sequence Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct sctp_chunk *sctp_make_strreset_tsnreq(
+ const struct sctp_association *asoc)
+{
+ struct sctp_strreset_tsnreq tsnreq;
+ __u16 length = sizeof(tsnreq);
+ struct sctp_chunk *retval;
+
+ retval = sctp_make_reconf(asoc, length);
+ if (!retval)
+ return NULL;
+
+ tsnreq.param_hdr.type = SCTP_PARAM_RESET_TSN_REQUEST;
+ tsnreq.param_hdr.length = htons(length);
+ tsnreq.request_seq = htonl(asoc->strreset_outseq);
+
+ sctp_addto_chunk(retval, sizeof(tsnreq), &tsnreq);
+
+ return retval;
+}
--
2.1.0
^ permalink raw reply related
* [PATCHv4 net-next 1/5] sctp: streams should be closed when stream reset request is sent successfully.
From: Xin Long @ 2017-01-20 18:00 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
In-Reply-To: <cover.1484934853.git.lucien.xin@gmail.com>
Now when sending stream reset request, it closes the streams to
block further xmit of data until this request is completed, then
calls sctp_send_reconf to send the chunk.
But if sctp_send_reconf returns err, which means the request chunk
would not be queued and sent, so the asoc will get stuck, streams
are closed and no packet was even queued.
This patch is to fix it by closing streams only when request is sent
successfully, it is also to fix a return value.
Fixes: 7f9d68ac944e ("sctp: implement sender-side procedures for SSN Reset Request Parameter")
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/sctp/stream.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index 13d5e07..53c67d6 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -136,8 +136,20 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
goto out;
chunk = sctp_make_strreset_req(asoc, str_nums, str_list, out, in);
- if (!chunk)
+ if (!chunk) {
+ retval = -ENOMEM;
goto out;
+ }
+
+ asoc->strreset_chunk = chunk;
+ sctp_chunk_hold(asoc->strreset_chunk);
+
+ retval = sctp_send_reconf(asoc, chunk);
+ if (retval) {
+ sctp_chunk_put(asoc->strreset_chunk);
+ asoc->strreset_chunk = NULL;
+ goto out;
+ }
if (out) {
if (str_nums)
@@ -150,14 +162,6 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
}
asoc->strreset_outstanding = out + in;
- asoc->strreset_chunk = chunk;
- sctp_chunk_hold(asoc->strreset_chunk);
-
- retval = sctp_send_reconf(asoc, chunk);
- if (retval) {
- sctp_chunk_put(asoc->strreset_chunk);
- asoc->strreset_chunk = NULL;
- }
out:
return retval;
--
2.1.0
^ permalink raw reply related
* [PATCHv4 net-next 0/5] sctp: add sender-side procedures for stream reconf asoc reset and add streams
From: Xin Long @ 2017-01-20 18:00 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
Patch 3/5 is to implement sender-side procedures for the SSN/TSN Reset
Request Parameter described in rfc6525 section 5.1.4, patch 2/5 is
ahead of it to define a function to make the request chunk for it.
Patch 5/5 is to implement sender-side procedures for the Add Incoming
and Outgoing Streams Request Parameter Request Parameter described in
rfc6525 section 5.1.5 and 5.1.6, patch 4/5 is ahead of it to define a
function to make the request chunk for it.
Patch 1/5 is a fix to make streams be closed only when request is sent
successfully.
v1->v2:
- put these into a smaller group.
- rename some temporary variables in the codes.
- rename the titles of the commits and improve some changelogs.
v2->v3:
- re-split the patchset and make sure it has no dead codes for review.
- move some codes into stream.c from socket.c.
v3->v4:
- add one more patch to fix a send reset stream request issue.
- doing actual work only when request is sent successfully.
- reduce some indents in sctp_send_add_streams.
Xin Long (5):
sctp: streams should be closed when stream reset request is sent
successfully.
sctp: add support for generating stream reconf ssn/tsn reset request
chunk
sctp: implement sender-side procedures for SSN/TSN Reset Request
Parameter
sctp: add support for generating stream reconf add incoming/outgoing
streams request chunk
sctp: implement sender-side procedures for Add Incoming/Outgoing
Streams Request Parameter
include/linux/sctp.h | 12 +++++
include/net/sctp/sctp.h | 3 ++
include/net/sctp/sm.h | 5 ++
include/uapi/linux/sctp.h | 8 +++
net/sctp/sm_make_chunk.c | 75 ++++++++++++++++++++++++++++
net/sctp/socket.c | 58 ++++++++++++++++++++++
net/sctp/stream.c | 124 +++++++++++++++++++++++++++++++++++++++++++++-
7 files changed, 284 insertions(+), 1 deletion(-)
--
2.1.0
^ permalink raw reply
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