Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Linus Torvalds committed Jan 15, 2008
2 parents f885b51 + 1b310fc commit 612166c
Show file tree
Hide file tree
Showing 14 changed files with 325 additions and 78 deletions.
23 changes: 14 additions & 9 deletions drivers/bluetooth/hci_ll.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,23 +204,28 @@ 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) {
BT_ERR("cannot acknowledge device wake up");
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;
}
Expand Down
7 changes: 7 additions & 0 deletions drivers/net/macvlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
218 changes: 198 additions & 20 deletions drivers/net/niu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
int err;

err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
MRVL88X2011_LED_8_TO_11_CTL);
if (err < 0)
return err;

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;
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);

err = bcm8704_reset(np);
if (err)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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)
Expand Down
33 changes: 33 additions & 0 deletions drivers/net/niu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion net/802/tr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 6 additions & 1 deletion net/8021q/vlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ static const struct header_ops vlan_header_ops = {
static int vlan_dev_init(struct net_device *dev)
{
struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
int subclass = 0;

/* IFF_BROADCAST|IFF_MULTICAST; ??? */
dev->flags = real_dev->flags & ~IFF_UP;
Expand All @@ -349,7 +350,11 @@ static int vlan_dev_init(struct net_device *dev)
dev->hard_start_xmit = vlan_dev_hard_start_xmit;
}

lockdep_set_class(&dev->_xmit_lock, &vlan_netdev_xmit_lock_key);
if (real_dev->priv_flags & IFF_802_1Q_VLAN)
subclass = 1;

lockdep_set_class_and_subclass(&dev->_xmit_lock,
&vlan_netdev_xmit_lock_key, subclass);
return 0;
}

Expand Down
Loading

0 comments on commit 612166c

Please sign in to comment.