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

Commit 612166c7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6:
  [TOKENRING]: rif_timer not initialized properly
  [NETFILTER]: bridge: fix double POST_ROUTING invocation
  [NETFILTER]: xt_helper: Do not bypass RCU
  [NETFILTER]: ip6t_eui64: Fixes calculation of Universal/Local bit
  [MACVLAN]: Prevent nesting macvlan devices
  [VLAN]: nested VLAN: fix lockdep's recursive locking warning
  [DECNET] ROUTE: fix rcu_dereference() uses in /proc/net/decnet_cache
  [BLUETOOTH]: Always send explicit hci_ll wake-up acks.
  [BLUETOOTH]: rfcomm tty BUG_ON() code fix
  [AX25] af_ax25: Possible circular locking.
  [AX25]: Kill user triggable printks.
  [IPV4] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache
  [NEIGH]: Fix race between neigh_parms_release and neightbl_fill_parms
  [NIU]: Support for Marvell PHY
parents f885b519 1b310fca
Loading
Loading
Loading
Loading
+14 −9
Original line number Diff line number Diff line
@@ -204,6 +204,19 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu)
	spin_lock_irqsave(&ll->hcill_lock, flags);

	switch (ll->hcill_state) {
	case HCILL_ASLEEP_TO_AWAKE:
		/*
		 * This state means that both the host and the BRF chip
		 * have simultaneously sent a wake-up-indication packet.
		 * Traditionaly, in this case, receiving a wake-up-indication
		 * was enough and an additional wake-up-ack wasn't needed.
		 * This has changed with the BRF6350, which does require an
		 * explicit wake-up-ack. Other BRF versions, which do not
		 * require an explicit ack here, do accept it, thus it is
		 * perfectly safe to always send one.
		 */
		BT_DBG("dual wake-up-indication");
		/* deliberate fall-through - do not add break */
	case HCILL_ASLEEP:
		/* acknowledge device wake up */
		if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) {
@@ -211,16 +224,8 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu)
			goto out;
		}
		break;
	case HCILL_ASLEEP_TO_AWAKE:
		/*
		 * this state means that a wake-up-indication
		 * is already on its way to the device,
		 * and will serve as the required wake-up-ack
		 */
		BT_DBG("dual wake-up-indication");
		break;
	default:
		/* any other state are illegal */
		/* any other state is illegal */
		BT_ERR("received HCILL_WAKE_UP_IND in state %ld", ll->hcill_state);
		break;
	}
+7 −0
Original line number Diff line number Diff line
@@ -384,6 +384,13 @@ static int macvlan_newlink(struct net_device *dev,
	if (lowerdev == NULL)
		return -ENODEV;

	/* Don't allow macvlans on top of other macvlans - its not really
	 * wrong, but lockdep can't handle it and its not useful for anything
	 * you couldn't do directly on top of the real device.
	 */
	if (lowerdev->rtnl_link_ops == dev->rtnl_link_ops)
		return -ENODEV;

	if (!tb[IFLA_MTU])
		dev->mtu = lowerdev->mtu;
	else if (dev->mtu > lowerdev->mtu)
+198 −20
Original line number Diff line number Diff line
@@ -801,22 +801,90 @@ static int bcm8704_init_user_dev3(struct niu *np)
	return 0;
}

static int xcvr_init_10g(struct niu *np)
static int mrvl88x2011_act_led(struct niu *np, int val)
{
	struct niu_link_config *lp = &np->link_config;
	u16 analog_stat0, tx_alarm_status;
	int	err;
	u64 val;

	val = nr64_mac(XMAC_CONFIG);
	val &= ~XMAC_CONFIG_LED_POLARITY;
	val |= XMAC_CONFIG_FORCE_LED_ON;
	nw64_mac(XMAC_CONFIG, val);
	err  = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
		MRVL88X2011_LED_8_TO_11_CTL);
	if (err < 0)
		return err;

	/* XXX shared resource, lock parent XXX */
	val = nr64(MIF_CONFIG);
	val |= MIF_CONFIG_INDIRECT_MODE;
	nw64(MIF_CONFIG, val);
	err &= ~MRVL88X2011_LED(MRVL88X2011_LED_ACT,MRVL88X2011_LED_CTL_MASK);
	err |=  MRVL88X2011_LED(MRVL88X2011_LED_ACT,val);

	return mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
			  MRVL88X2011_LED_8_TO_11_CTL, err);
}

static int mrvl88x2011_led_blink_rate(struct niu *np, int rate)
{
	int	err;

	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
			MRVL88X2011_LED_BLINK_CTL);
	if (err >= 0) {
		err &= ~MRVL88X2011_LED_BLKRATE_MASK;
		err |= (rate << 4);

		err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
				 MRVL88X2011_LED_BLINK_CTL, err);
	}

	return err;
}

static int xcvr_init_10g_mrvl88x2011(struct niu *np)
{
	int	err;

	/* Set LED functions */
	err = mrvl88x2011_led_blink_rate(np, MRVL88X2011_LED_BLKRATE_134MS);
	if (err)
		return err;

	/* led activity */
	err = mrvl88x2011_act_led(np, MRVL88X2011_LED_CTL_OFF);
	if (err)
		return err;

	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
			MRVL88X2011_GENERAL_CTL);
	if (err < 0)
		return err;

	err |= MRVL88X2011_ENA_XFPREFCLK;

	err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
			 MRVL88X2011_GENERAL_CTL, err);
	if (err < 0)
		return err;

	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
			MRVL88X2011_PMA_PMD_CTL_1);
	if (err < 0)
		return err;

	if (np->link_config.loopback_mode == LOOPBACK_MAC)
		err |= MRVL88X2011_LOOPBACK;
	else
		err &= ~MRVL88X2011_LOOPBACK;

	err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
			 MRVL88X2011_PMA_PMD_CTL_1, err);
	if (err < 0)
		return err;

	/* Enable PMD  */
	return mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
			  MRVL88X2011_10G_PMD_TX_DIS, MRVL88X2011_ENA_PMDTX);
}

static int xcvr_init_10g_bcm8704(struct niu *np)
{
	struct niu_link_config *lp = &np->link_config;
	u16 analog_stat0, tx_alarm_status;
	int err;

	err = bcm8704_reset(np);
	if (err)
@@ -896,6 +964,38 @@ static int xcvr_init_10g(struct niu *np)
	return 0;
}

static int xcvr_init_10g(struct niu *np)
{
	int phy_id, err;
	u64 val;

	val = nr64_mac(XMAC_CONFIG);
	val &= ~XMAC_CONFIG_LED_POLARITY;
	val |= XMAC_CONFIG_FORCE_LED_ON;
	nw64_mac(XMAC_CONFIG, val);

	/* XXX shared resource, lock parent XXX */
	val = nr64(MIF_CONFIG);
	val |= MIF_CONFIG_INDIRECT_MODE;
	nw64(MIF_CONFIG, val);

	phy_id = phy_decode(np->parent->port_phy, np->port);
	phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];

	/* handle different phy types */
	switch (phy_id & NIU_PHY_ID_MASK) {
	case NIU_PHY_ID_MRVL88X2011:
		err = xcvr_init_10g_mrvl88x2011(np);
		break;

	default: /* bcom 8704 */
		err = xcvr_init_10g_bcm8704(np);
		break;
	}

	return 0;
}

static int mii_reset(struct niu *np)
{
	int limit, err;
@@ -1082,19 +1182,68 @@ static int niu_link_status_common(struct niu *np, int link_up)
	return 0;
}

static int link_status_10g(struct niu *np, int *link_up_p)
static int link_status_10g_mrvl(struct niu *np, int *link_up_p)
{
	unsigned long flags;
	int err, link_up;
	int err, link_up, pma_status, pcs_status;

	link_up = 0;

	spin_lock_irqsave(&np->lock, flags);
	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
			MRVL88X2011_10G_PMD_STATUS_2);
	if (err < 0)
		goto out;

	err = -EINVAL;
	if (np->link_config.loopback_mode != LOOPBACK_DISABLED)
	/* Check PMA/PMD Register: 1.0001.2 == 1 */
	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
			MRVL88X2011_PMA_PMD_STATUS_1);
	if (err < 0)
		goto out;

	pma_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1 : 0);

        /* Check PMC Register : 3.0001.2 == 1: read twice */
	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
			MRVL88X2011_PMA_PMD_STATUS_1);
	if (err < 0)
		goto out;

	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
			MRVL88X2011_PMA_PMD_STATUS_1);
	if (err < 0)
		goto out;

	pcs_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1 : 0);

        /* Check XGXS Register : 4.0018.[0-3,12] */
	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV4_ADDR,
			MRVL88X2011_10G_XGXS_LANE_STAT);
	if (err < 0)
		goto out;

	if (err == (PHYXS_XGXS_LANE_STAT_ALINGED | PHYXS_XGXS_LANE_STAT_LANE3 |
		    PHYXS_XGXS_LANE_STAT_LANE2 | PHYXS_XGXS_LANE_STAT_LANE1 |
		    PHYXS_XGXS_LANE_STAT_LANE0 | PHYXS_XGXS_LANE_STAT_MAGIC |
		    0x800))
		link_up = (pma_status && pcs_status) ? 1 : 0;

	np->link_config.active_speed = SPEED_10000;
	np->link_config.active_duplex = DUPLEX_FULL;
	err = 0;
out:
	mrvl88x2011_act_led(np, (link_up ?
				 MRVL88X2011_LED_CTL_PCS_ACT :
				 MRVL88X2011_LED_CTL_OFF));

	*link_up_p = link_up;
	return err;
}

static int link_status_10g_bcom(struct niu *np, int *link_up_p)
{
	int err, link_up;

	link_up = 0;

	err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR,
			BCM8704_PMD_RCV_SIGDET);
	if (err < 0)
@@ -1134,9 +1283,37 @@ static int link_status_10g(struct niu *np, int *link_up_p)
	err = 0;

out:
	*link_up_p = link_up;
	return err;
}

static int link_status_10g(struct niu *np, int *link_up_p)
{
	unsigned long flags;
	int err = -EINVAL;

	spin_lock_irqsave(&np->lock, flags);

	if (np->link_config.loopback_mode == LOOPBACK_DISABLED) {
		int phy_id;

		phy_id = phy_decode(np->parent->port_phy, np->port);
		phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];

		/* handle different phy types */
		switch (phy_id & NIU_PHY_ID_MASK) {
		case NIU_PHY_ID_MRVL88X2011:
			err = link_status_10g_mrvl(np, link_up_p);
			break;

		default: /* bcom 8704 */
			err = link_status_10g_bcom(np, link_up_p);
			break;
		}
	}

	spin_unlock_irqrestore(&np->lock, flags);

	*link_up_p = link_up;
	return err;
}

@@ -6297,7 +6474,8 @@ static int __devinit phy_record(struct niu_parent *parent,
	if (dev_id_1 < 0 || dev_id_2 < 0)
		return 0;
	if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) {
		if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704)
		if (((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) &&
		    ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011))
			return 0;
	} else {
		if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R)
+33 −0
Original line number Diff line number Diff line
@@ -2538,6 +2538,39 @@ struct fcram_hash_ipv6 {
#define NIU_PHY_ID_MASK			0xfffff0f0
#define NIU_PHY_ID_BCM8704		0x00206030
#define NIU_PHY_ID_BCM5464R		0x002060b0
#define NIU_PHY_ID_MRVL88X2011		0x01410020

/* MRVL88X2011 register addresses */
#define MRVL88X2011_USER_DEV1_ADDR	1
#define MRVL88X2011_USER_DEV2_ADDR	2
#define MRVL88X2011_USER_DEV3_ADDR	3
#define MRVL88X2011_USER_DEV4_ADDR	4
#define MRVL88X2011_PMA_PMD_CTL_1	0x0000
#define MRVL88X2011_PMA_PMD_STATUS_1	0x0001
#define MRVL88X2011_10G_PMD_STATUS_2	0x0008
#define MRVL88X2011_10G_PMD_TX_DIS	0x0009
#define MRVL88X2011_10G_XGXS_LANE_STAT	0x0018
#define MRVL88X2011_GENERAL_CTL		0x8300
#define MRVL88X2011_LED_BLINK_CTL	0x8303
#define MRVL88X2011_LED_8_TO_11_CTL	0x8306

/* MRVL88X2011 register control */
#define MRVL88X2011_ENA_XFPREFCLK	0x0001
#define MRVL88X2011_ENA_PMDTX		0x0000
#define MRVL88X2011_LOOPBACK            0x1
#define MRVL88X2011_LED_ACT		0x1
#define MRVL88X2011_LNK_STATUS_OK	0x4
#define MRVL88X2011_LED_BLKRATE_MASK	0x70
#define MRVL88X2011_LED_BLKRATE_034MS	0x0
#define MRVL88X2011_LED_BLKRATE_067MS	0x1
#define MRVL88X2011_LED_BLKRATE_134MS	0x2
#define MRVL88X2011_LED_BLKRATE_269MS	0x3
#define MRVL88X2011_LED_BLKRATE_538MS	0x4
#define MRVL88X2011_LED_CTL_OFF		0x0
#define MRVL88X2011_LED_CTL_PCS_ACT	0x5
#define MRVL88X2011_LED_CTL_MASK	0x7
#define MRVL88X2011_LED(n,v)		((v)<<((n)*4))
#define MRVL88X2011_LED_STAT(n,v)	((v)>>((n)*4))

#define BCM8704_PMA_PMD_DEV_ADDR	1
#define BCM8704_PCS_DEV_ADDR		2
+1 −1
Original line number Diff line number Diff line
@@ -642,7 +642,7 @@ struct net_device *alloc_trdev(int sizeof_priv)
static int __init rif_init(void)
{
	init_timer(&rif_timer);
	rif_timer.expires  = sysctl_tr_rif_timeout;
	rif_timer.expires  = jiffies + sysctl_tr_rif_timeout;
	rif_timer.data     = 0L;
	rif_timer.function = rif_check_expire;
	add_timer(&rif_timer);
Loading