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

Commit 8a84e01e authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull networking fixes from David Miller:

 1) Fix BUG when decrypting empty packets in mac80211, from Ronald Wahl.

 2) nf_nat_range is not fully initialized and this is copied back to
    userspace, from Daniel Borkmann.

 3) Fix read past end of b uffer in netfilter ipset, also from Dan
    Carpenter.

 4) Signed integer overflow in ipv4 address mask creation helper
    inet_make_mask(), from Vincent BENAYOUN.

 5) VXLAN, be2net, mlx4_en, and qlcnic need ->ndo_gso_check() methods to
    properly describe the device's capabilities, from Joe Stringer.

 6) Fix memory leaks and checksum miscalculations in openvswitch, from
    Pravin B SHelar and Jesse Gross.

 7) FIB rules passes back ambiguous error code for unreachable routes,
    making behavior confusing for userspace.  Fix from Panu Matilainen.

 8) ieee802154fake_probe() doesn't release resources properly on error,
    from Alexey Khoroshilov.

 9) Fix skb_over_panic in add_grhead(), from Daniel Borkmann.

10) Fix access of stale slave pointers in bonding code, from Nikolay
    Aleksandrov.

11) Fix stack info leak in PPP pptp code, from Mathias Krause.

12) Cure locking bug in IPX stack, from Jiri Bohac.

13) Revert SKB fclone memory freeing optimization that is racey and can
    allow accesses to freed up memory, from Eric Dumazet.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (71 commits)
  tcp: Restore RFC5961-compliant behavior for SYN packets
  net: Revert "net: avoid one atomic operation in skb_clone()"
  virtio-net: validate features during probe
  cxgb4 : Fix DCB priority groups being returned in wrong order
  ipx: fix locking regression in ipx_sendmsg and ipx_recvmsg
  openvswitch: Don't validate IPv6 label masks.
  pptp: fix stack info leak in pptp_getname()
  brcmfmac: don't include linux/unaligned/access_ok.h
  cxgb4i : Don't block unload/cxgb4 unload when remote closes TCP connection
  ipv6: delete protocol and unregister rtnetlink when cleanup
  net/mlx4_en: Add VXLAN ndo calls to the PF net device ops too
  bonding: fix curr_active_slave/carrier with loadbalance arp monitoring
  mac80211: minstrel_ht: fix a crash in rate sorting
  vxlan: Inline vxlan_gso_check().
  can: m_can: update to support CAN FD features
  can: m_can: fix incorrect error messages
  can: m_can: add missing delay after setting CCCR_INIT bit
  can: m_can: fix not set can_dlc for remote frame
  can: m_can: fix possible sleep in napi poll
  can: m_can: add missing message RAM initialization
  ...
parents 928352e9 0c228e83
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -2471,7 +2471,8 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
			bond_slave_state_change(bond);
			if (BOND_MODE(bond) == BOND_MODE_XOR)
				bond_update_slave_arr(bond, NULL);
		} else if (do_failover) {
		}
		if (do_failover) {
			block_netpoll_tx();
			bond_select_active_slave(bond);
			unblock_netpoll_tx();
+2 −2
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
	long rate;
	u64 v64;

	/* Use CIA recommended sample points */
	/* Use CiA recommended sample points */
	if (bt->sample_point) {
		sampl_pt = bt->sample_point;
	} else {
@@ -382,7 +382,7 @@ void can_free_echo_skb(struct net_device *dev, unsigned int idx)
	BUG_ON(idx >= priv->echo_skb_max);

	if (priv->echo_skb[idx]) {
		kfree_skb(priv->echo_skb[idx]);
		dev_kfree_skb_any(priv->echo_skb[idx]);
		priv->echo_skb[idx] = NULL;
	}
}
+1 −0
Original line number Diff line number Diff line
config CAN_M_CAN
	depends on HAS_IOMEM
	tristate "Bosch M_CAN devices"
	---help---
	  Say Y here if you want to support for Bosch M_CAN controller.
+166 −53
Original line number Diff line number Diff line
@@ -105,14 +105,36 @@ enum m_can_mram_cfg {
	MRAM_CFG_NUM,
};

/* Fast Bit Timing & Prescaler Register (FBTP) */
#define FBTR_FBRP_MASK		0x1f
#define FBTR_FBRP_SHIFT		16
#define FBTR_FTSEG1_SHIFT	8
#define FBTR_FTSEG1_MASK	(0xf << FBTR_FTSEG1_SHIFT)
#define FBTR_FTSEG2_SHIFT	4
#define FBTR_FTSEG2_MASK	(0x7 << FBTR_FTSEG2_SHIFT)
#define FBTR_FSJW_SHIFT		0
#define FBTR_FSJW_MASK		0x3

/* Test Register (TEST) */
#define TEST_LBCK	BIT(4)

/* CC Control Register(CCCR) */
#define CCCR_TEST		BIT(7)
#define CCCR_CMR_MASK		0x3
#define CCCR_CMR_SHIFT		10
#define CCCR_CMR_CANFD		0x1
#define CCCR_CMR_CANFD_BRS	0x2
#define CCCR_CMR_CAN		0x3
#define CCCR_CME_MASK		0x3
#define CCCR_CME_SHIFT		8
#define CCCR_CME_CAN		0
#define CCCR_CME_CANFD		0x1
#define CCCR_CME_CANFD_BRS	0x2
#define CCCR_TEST		BIT(7)
#define CCCR_MON		BIT(5)
#define CCCR_CCE		BIT(1)
#define CCCR_INIT		BIT(0)
#define CCCR_CANFD		0x10

/* Bit Timing & Prescaler Register (BTP) */
#define BTR_BRP_MASK		0x3ff
@@ -204,6 +226,7 @@ enum m_can_mram_cfg {

/* Rx Buffer / FIFO Element Size Configuration (RXESC) */
#define M_CAN_RXESC_8BYTES	0x0
#define M_CAN_RXESC_64BYTES	0x777

/* Tx Buffer Configuration(TXBC) */
#define TXBC_NDTB_OFF		16
@@ -211,6 +234,7 @@ enum m_can_mram_cfg {

/* Tx Buffer Element Size Configuration(TXESC) */
#define TXESC_TBDS_8BYTES	0x0
#define TXESC_TBDS_64BYTES	0x7

/* Tx Event FIFO Con.guration (TXEFC) */
#define TXEFC_EFS_OFF		16
@@ -219,11 +243,11 @@ enum m_can_mram_cfg {
/* Message RAM Configuration (in bytes) */
#define SIDF_ELEMENT_SIZE	4
#define XIDF_ELEMENT_SIZE	8
#define RXF0_ELEMENT_SIZE	16
#define RXF1_ELEMENT_SIZE	16
#define RXF0_ELEMENT_SIZE	72
#define RXF1_ELEMENT_SIZE	72
#define RXB_ELEMENT_SIZE	16
#define TXE_ELEMENT_SIZE	8
#define TXB_ELEMENT_SIZE	16
#define TXB_ELEMENT_SIZE	72

/* Message RAM Elements */
#define M_CAN_FIFO_ID		0x0
@@ -231,11 +255,17 @@ enum m_can_mram_cfg {
#define M_CAN_FIFO_DATA(n)	(0x8 + ((n) << 2))

/* Rx Buffer Element */
/* R0 */
#define RX_BUF_ESI		BIT(31)
#define RX_BUF_XTD		BIT(30)
#define RX_BUF_RTR		BIT(29)
/* R1 */
#define RX_BUF_ANMF		BIT(31)
#define RX_BUF_EDL		BIT(21)
#define RX_BUF_BRS		BIT(20)

/* Tx Buffer Element */
/* R0 */
#define TX_BUF_XTD		BIT(30)
#define TX_BUF_RTR		BIT(29)

@@ -296,6 +326,7 @@ static inline void m_can_config_endisable(const struct m_can_priv *priv,
	if (enable) {
		/* enable m_can configuration */
		m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT);
		udelay(5);
		/* CCCR.CCE can only be set/reset while CCCR.INIT = '1' */
		m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT | CCCR_CCE);
	} else {
@@ -326,41 +357,67 @@ static inline void m_can_disable_all_interrupts(const struct m_can_priv *priv)
	m_can_write(priv, M_CAN_ILE, 0x0);
}

static void m_can_read_fifo(const struct net_device *dev, struct can_frame *cf,
			    u32 rxfs)
static void m_can_read_fifo(struct net_device *dev, u32 rxfs)
{
	struct net_device_stats *stats = &dev->stats;
	struct m_can_priv *priv = netdev_priv(dev);
	u32 id, fgi;
	struct canfd_frame *cf;
	struct sk_buff *skb;
	u32 id, fgi, dlc;
	int i;

	/* calculate the fifo get index for where to read data */
	fgi = (rxfs & RXFS_FGI_MASK) >> RXFS_FGI_OFF;
	dlc = m_can_fifo_read(priv, fgi, M_CAN_FIFO_DLC);
	if (dlc & RX_BUF_EDL)
		skb = alloc_canfd_skb(dev, &cf);
	else
		skb = alloc_can_skb(dev, (struct can_frame **)&cf);
	if (!skb) {
		stats->rx_dropped++;
		return;
	}

	if (dlc & RX_BUF_EDL)
		cf->len = can_dlc2len((dlc >> 16) & 0x0F);
	else
		cf->len = get_can_dlc((dlc >> 16) & 0x0F);

	id = m_can_fifo_read(priv, fgi, M_CAN_FIFO_ID);
	if (id & RX_BUF_XTD)
		cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG;
	else
		cf->can_id = (id >> 18) & CAN_SFF_MASK;

	if (id & RX_BUF_RTR) {
	if (id & RX_BUF_ESI) {
		cf->flags |= CANFD_ESI;
		netdev_dbg(dev, "ESI Error\n");
	}

	if (!(dlc & RX_BUF_EDL) && (id & RX_BUF_RTR)) {
		cf->can_id |= CAN_RTR_FLAG;
	} else {
		id = m_can_fifo_read(priv, fgi, M_CAN_FIFO_DLC);
		cf->can_dlc = get_can_dlc((id >> 16) & 0x0F);
		*(u32 *)(cf->data + 0) = m_can_fifo_read(priv, fgi,
							 M_CAN_FIFO_DATA(0));
		*(u32 *)(cf->data + 4) = m_can_fifo_read(priv, fgi,
							 M_CAN_FIFO_DATA(1));
		if (dlc & RX_BUF_BRS)
			cf->flags |= CANFD_BRS;

		for (i = 0; i < cf->len; i += 4)
			*(u32 *)(cf->data + i) =
				m_can_fifo_read(priv, fgi,
						M_CAN_FIFO_DATA(i / 4));
	}

	/* acknowledge rx fifo 0 */
	m_can_write(priv, M_CAN_RXF0A, fgi);

	stats->rx_packets++;
	stats->rx_bytes += cf->len;

	netif_receive_skb(skb);
}

static int m_can_do_rx_poll(struct net_device *dev, int quota)
{
	struct m_can_priv *priv = netdev_priv(dev);
	struct net_device_stats *stats = &dev->stats;
	struct sk_buff *skb;
	struct can_frame *frame;
	u32 pkts = 0;
	u32 rxfs;

@@ -374,18 +431,7 @@ static int m_can_do_rx_poll(struct net_device *dev, int quota)
		if (rxfs & RXFS_RFL)
			netdev_warn(dev, "Rx FIFO 0 Message Lost\n");

		skb = alloc_can_skb(dev, &frame);
		if (!skb) {
			stats->rx_dropped++;
			return pkts;
		}

		m_can_read_fifo(dev, frame, rxfs);

		stats->rx_packets++;
		stats->rx_bytes += frame->can_dlc;

		netif_receive_skb(skb);
		m_can_read_fifo(dev, rxfs);

		quota--;
		pkts++;
@@ -481,11 +527,23 @@ static int m_can_handle_lec_err(struct net_device *dev,
	return 1;
}

static int m_can_get_berr_counter(const struct net_device *dev,
static int __m_can_get_berr_counter(const struct net_device *dev,
				    struct can_berr_counter *bec)
{
	struct m_can_priv *priv = netdev_priv(dev);
	unsigned int ecr;

	ecr = m_can_read(priv, M_CAN_ECR);
	bec->rxerr = (ecr & ECR_REC_MASK) >> ECR_REC_SHIFT;
	bec->txerr = ecr & ECR_TEC_MASK;

	return 0;
}

static int m_can_get_berr_counter(const struct net_device *dev,
				  struct can_berr_counter *bec)
{
	struct m_can_priv *priv = netdev_priv(dev);
	int err;

	err = clk_prepare_enable(priv->hclk);
@@ -498,9 +556,7 @@ static int m_can_get_berr_counter(const struct net_device *dev,
		return err;
	}

	ecr = m_can_read(priv, M_CAN_ECR);
	bec->rxerr = (ecr & ECR_REC_MASK) >> ECR_REC_SHIFT;
	bec->txerr = ecr & ECR_TEC_MASK;
	__m_can_get_berr_counter(dev, bec);

	clk_disable_unprepare(priv->cclk);
	clk_disable_unprepare(priv->hclk);
@@ -544,7 +600,7 @@ static int m_can_handle_state_change(struct net_device *dev,
	if (unlikely(!skb))
		return 0;

	m_can_get_berr_counter(dev, &bec);
	__m_can_get_berr_counter(dev, &bec);

	switch (new_state) {
	case CAN_STATE_ERROR_ACTIVE:
@@ -596,14 +652,14 @@ static int m_can_handle_state_errors(struct net_device *dev, u32 psr)

	if ((psr & PSR_EP) &&
	    (priv->can.state != CAN_STATE_ERROR_PASSIVE)) {
		netdev_dbg(dev, "entered error warning state\n");
		netdev_dbg(dev, "entered error passive state\n");
		work_done += m_can_handle_state_change(dev,
						       CAN_STATE_ERROR_PASSIVE);
	}

	if ((psr & PSR_BO) &&
	    (priv->can.state != CAN_STATE_BUS_OFF)) {
		netdev_dbg(dev, "entered error warning state\n");
		netdev_dbg(dev, "entered error bus off state\n");
		work_done += m_can_handle_state_change(dev,
						       CAN_STATE_BUS_OFF);
	}
@@ -615,7 +671,7 @@ static void m_can_handle_other_err(struct net_device *dev, u32 irqstatus)
{
	if (irqstatus & IR_WDI)
		netdev_err(dev, "Message RAM Watchdog event due to missing READY\n");
	if (irqstatus & IR_BEU)
	if (irqstatus & IR_ELO)
		netdev_err(dev, "Error Logging Overflow\n");
	if (irqstatus & IR_BEU)
		netdev_err(dev, "Bit Error Uncorrected\n");
@@ -733,10 +789,23 @@ static const struct can_bittiming_const m_can_bittiming_const = {
	.brp_inc = 1,
};

static const struct can_bittiming_const m_can_data_bittiming_const = {
	.name = KBUILD_MODNAME,
	.tseg1_min = 2,		/* Time segment 1 = prop_seg + phase_seg1 */
	.tseg1_max = 16,
	.tseg2_min = 1,		/* Time segment 2 = phase_seg2 */
	.tseg2_max = 8,
	.sjw_max = 4,
	.brp_min = 1,
	.brp_max = 32,
	.brp_inc = 1,
};

static int m_can_set_bittiming(struct net_device *dev)
{
	struct m_can_priv *priv = netdev_priv(dev);
	const struct can_bittiming *bt = &priv->can.bittiming;
	const struct can_bittiming *dbt = &priv->can.data_bittiming;
	u16 brp, sjw, tseg1, tseg2;
	u32 reg_btp;

@@ -747,7 +816,17 @@ static int m_can_set_bittiming(struct net_device *dev)
	reg_btp = (brp << BTR_BRP_SHIFT) | (sjw << BTR_SJW_SHIFT) |
			(tseg1 << BTR_TSEG1_SHIFT) | (tseg2 << BTR_TSEG2_SHIFT);
	m_can_write(priv, M_CAN_BTP, reg_btp);
	netdev_dbg(dev, "setting BTP 0x%x\n", reg_btp);

	if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
		brp = dbt->brp - 1;
		sjw = dbt->sjw - 1;
		tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1;
		tseg2 = dbt->phase_seg2 - 1;
		reg_btp = (brp << FBTR_FBRP_SHIFT) | (sjw << FBTR_FSJW_SHIFT) |
				(tseg1 << FBTR_FTSEG1_SHIFT) |
				(tseg2 << FBTR_FTSEG2_SHIFT);
		m_can_write(priv, M_CAN_FBTP, reg_btp);
	}

	return 0;
}
@@ -767,8 +846,8 @@ static void m_can_chip_config(struct net_device *dev)

	m_can_config_endisable(priv, true);

	/* RX Buffer/FIFO Element Size 8 bytes data field */
	m_can_write(priv, M_CAN_RXESC, M_CAN_RXESC_8BYTES);
	/* RX Buffer/FIFO Element Size 64 bytes data field */
	m_can_write(priv, M_CAN_RXESC, M_CAN_RXESC_64BYTES);

	/* Accept Non-matching Frames Into FIFO 0 */
	m_can_write(priv, M_CAN_GFC, 0x0);
@@ -777,8 +856,8 @@ static void m_can_chip_config(struct net_device *dev)
	m_can_write(priv, M_CAN_TXBC, (1 << TXBC_NDTB_OFF) |
		    priv->mcfg[MRAM_TXB].off);

	/* only support 8 bytes firstly */
	m_can_write(priv, M_CAN_TXESC, TXESC_TBDS_8BYTES);
	/* support 64 bytes payload */
	m_can_write(priv, M_CAN_TXESC, TXESC_TBDS_64BYTES);

	m_can_write(priv, M_CAN_TXEFC, (1 << TXEFC_EFS_OFF) |
		    priv->mcfg[MRAM_TXE].off);
@@ -793,7 +872,8 @@ static void m_can_chip_config(struct net_device *dev)
		    RXFC_FWM_1 | priv->mcfg[MRAM_RXF1].off);

	cccr = m_can_read(priv, M_CAN_CCCR);
	cccr &= ~(CCCR_TEST | CCCR_MON);
	cccr &= ~(CCCR_TEST | CCCR_MON | (CCCR_CMR_MASK << CCCR_CMR_SHIFT) |
		(CCCR_CME_MASK << CCCR_CME_SHIFT));
	test = m_can_read(priv, M_CAN_TEST);
	test &= ~TEST_LBCK;

@@ -805,6 +885,9 @@ static void m_can_chip_config(struct net_device *dev)
		test |= TEST_LBCK;
	}

	if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
		cccr |= CCCR_CME_CANFD_BRS << CCCR_CME_SHIFT;

	m_can_write(priv, M_CAN_CCCR, cccr);
	m_can_write(priv, M_CAN_TEST, test);

@@ -869,11 +952,13 @@ static struct net_device *alloc_m_can_dev(void)

	priv->dev = dev;
	priv->can.bittiming_const = &m_can_bittiming_const;
	priv->can.data_bittiming_const = &m_can_data_bittiming_const;
	priv->can.do_set_mode = m_can_set_mode;
	priv->can.do_get_berr_counter = m_can_get_berr_counter;
	priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
					CAN_CTRLMODE_LISTENONLY |
					CAN_CTRLMODE_BERR_REPORTING;
					CAN_CTRLMODE_BERR_REPORTING |
					CAN_CTRLMODE_FD;

	return dev;
}
@@ -956,8 +1041,9 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
				    struct net_device *dev)
{
	struct m_can_priv *priv = netdev_priv(dev);
	struct can_frame *cf = (struct can_frame *)skb->data;
	u32 id;
	struct canfd_frame *cf = (struct canfd_frame *)skb->data;
	u32 id, cccr;
	int i;

	if (can_dropped_invalid_skb(dev, skb))
		return NETDEV_TX_OK;
@@ -976,11 +1062,28 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,

	/* message ram configuration */
	m_can_fifo_write(priv, 0, M_CAN_FIFO_ID, id);
	m_can_fifo_write(priv, 0, M_CAN_FIFO_DLC, cf->can_dlc << 16);
	m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0), *(u32 *)(cf->data + 0));
	m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1), *(u32 *)(cf->data + 4));
	m_can_fifo_write(priv, 0, M_CAN_FIFO_DLC, can_len2dlc(cf->len) << 16);

	for (i = 0; i < cf->len; i += 4)
		m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(i / 4),
				 *(u32 *)(cf->data + i));

	can_put_echo_skb(skb, dev, 0);

	if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
		cccr = m_can_read(priv, M_CAN_CCCR);
		cccr &= ~(CCCR_CMR_MASK << CCCR_CMR_SHIFT);
		if (can_is_canfd_skb(skb)) {
			if (cf->flags & CANFD_BRS)
				cccr |= CCCR_CMR_CANFD_BRS << CCCR_CMR_SHIFT;
			else
				cccr |= CCCR_CMR_CANFD << CCCR_CMR_SHIFT;
		} else {
			cccr |= CCCR_CMR_CAN << CCCR_CMR_SHIFT;
		}
		m_can_write(priv, M_CAN_CCCR, cccr);
	}

	/* enable first TX buffer to start transfer  */
	m_can_write(priv, M_CAN_TXBTIE, 0x1);
	m_can_write(priv, M_CAN_TXBAR, 0x1);
@@ -992,6 +1095,7 @@ static const struct net_device_ops m_can_netdev_ops = {
	.ndo_open = m_can_open,
	.ndo_stop = m_can_close,
	.ndo_start_xmit = m_can_start_xmit,
	.ndo_change_mtu = can_change_mtu,
};

static int register_m_can_dev(struct net_device *dev)
@@ -1009,7 +1113,7 @@ static int m_can_of_parse_mram(struct platform_device *pdev,
	struct resource *res;
	void __iomem *addr;
	u32 out_val[MRAM_CFG_LEN];
	int ret;
	int i, start, end, ret;

	/* message ram could be shared */
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "message_ram");
@@ -1060,6 +1164,15 @@ static int m_can_of_parse_mram(struct platform_device *pdev,
		priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num,
		priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num);

	/* initialize the entire Message RAM in use to avoid possible
	 * ECC/parity checksum errors when reading an uninitialized buffer
	 */
	start = priv->mcfg[MRAM_SIDF].off;
	end = priv->mcfg[MRAM_TXB].off +
		priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE;
	for (i = start; i < end; i += 4)
		writel(0x0, priv->mram_base + i);

	return 0;
}

+1 −0
Original line number Diff line number Diff line
@@ -628,6 +628,7 @@ static const struct net_device_ops rcar_can_netdev_ops = {
	.ndo_open = rcar_can_open,
	.ndo_stop = rcar_can_close,
	.ndo_start_xmit = rcar_can_start_xmit,
	.ndo_change_mtu = can_change_mtu,
};

static void rcar_can_rx_pkt(struct rcar_can_priv *priv)
Loading