提交 78f9bbb5 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6:
  ariadne: remove redundant NULL check
  ip6ip6: autoload ip6 tunnel
  net: bridge builtin vs. ipv6 modular
  ipv6: Don't create clones of host routes.
  pktgen: fix errata in show results
  ipv4: Fix erroneous uses of ifa_address.
  vxge: update MAINTAINERS
  r6040: bump to version 0.27 and date 23Feb2011
  r6040: fix multicast operations
  rds: prevent BUG_ON triggering on congestion map updates
  bonding 802.3ad: Rename rx_machine_lock to state_machine_lock
  bonding 802.3ad: Fix the state machine locking v2
  drivers/net/macvtap: fix error check
  net: fix multithreaded signal handling in unix recv routines
  net: Enter net/ipv6/ even if CONFIG_IPV6=n
  net/smsc911x.c: Set the VLAN1 register to fix VLAN MTU problem
  bnx2x: fix MaxBW configuration
  bnx2x: (NPAR) prevent HW access in D3 state
  bnx2x: fix link notification
  bnx2x: fix non-pmf device load flow

Doing my first --no-ff merge here, to get the explicit merge commit.

David did a back-merge in order to get commit 8909c9ad ("net: don't
allow CAP_NET_ADMIN to load non-netdev kernel modules") so that we can
add Stephen Hemminger's fix to handle ip6 tunnels as well, which uses
the MODULE_ALIAS_NETDEV() macro created by that change.
...@@ -4292,10 +4292,7 @@ S: Maintained ...@@ -4292,10 +4292,7 @@ S: Maintained
F: net/sched/sch_netem.c F: net/sched/sch_netem.c
NETERION 10GbE DRIVERS (s2io/vxge) NETERION 10GbE DRIVERS (s2io/vxge)
M: Ramkrishna Vepa <ramkrishna.vepa@exar.com> M: Jon Mason <jdmason@kudzu.us>
M: Sivakumar Subramani <sivakumar.subramani@exar.com>
M: Sreenivasa Honnur <sreenivasa.honnur@exar.com>
M: Jon Mason <jon.mason@exar.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/Linux?Anonymous W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/Linux?Anonymous
W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/X3100Linux?Anonymous W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/X3100Linux?Anonymous
......
...@@ -425,11 +425,6 @@ static irqreturn_t ariadne_interrupt(int irq, void *data) ...@@ -425,11 +425,6 @@ static irqreturn_t ariadne_interrupt(int irq, void *data)
int csr0, boguscnt; int csr0, boguscnt;
int handled = 0; int handled = 0;
if (dev == NULL) {
printk(KERN_WARNING "ariadne_interrupt(): irq for unknown device.\n");
return IRQ_NONE;
}
lance->RAP = CSR0; /* PCnet-ISA Controller Status */ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
if (!(lance->RDP & INTR)) /* Check if any interrupt has been */ if (!(lance->RDP & INTR)) /* Check if any interrupt has been */
......
...@@ -1211,6 +1211,7 @@ struct bnx2x { ...@@ -1211,6 +1211,7 @@ struct bnx2x {
/* DCBX Negotation results */ /* DCBX Negotation results */
struct dcbx_features dcbx_local_feat; struct dcbx_features dcbx_local_feat;
u32 dcbx_error; u32 dcbx_error;
u32 pending_max;
}; };
/** /**
...@@ -1616,8 +1617,8 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, ...@@ -1616,8 +1617,8 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
/* CMNG constants, as derived from system spec calculations */ /* CMNG constants, as derived from system spec calculations */
/* default MIN rate in case VNIC min rate is configured to zero - 100Mbps */ /* default MIN rate in case VNIC min rate is configured to zero - 100Mbps */
#define DEF_MIN_RATE 100 #define DEF_MIN_RATE 100
/* resolution of the rate shaping timer - 100 usec */ /* resolution of the rate shaping timer - 400 usec */
#define RS_PERIODIC_TIMEOUT_USEC 100 #define RS_PERIODIC_TIMEOUT_USEC 400
/* number of bytes in single QM arbitration cycle - /* number of bytes in single QM arbitration cycle -
* coefficient for calculating the fairness timer */ * coefficient for calculating the fairness timer */
#define QM_ARB_BYTES 160000 #define QM_ARB_BYTES 160000
......
...@@ -996,6 +996,23 @@ void bnx2x_free_skbs(struct bnx2x *bp) ...@@ -996,6 +996,23 @@ void bnx2x_free_skbs(struct bnx2x *bp)
bnx2x_free_rx_skbs(bp); bnx2x_free_rx_skbs(bp);
} }
void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value)
{
/* load old values */
u32 mf_cfg = bp->mf_config[BP_VN(bp)];
if (value != bnx2x_extract_max_cfg(bp, mf_cfg)) {
/* leave all but MAX value */
mf_cfg &= ~FUNC_MF_CFG_MAX_BW_MASK;
/* set new MAX value */
mf_cfg |= (value << FUNC_MF_CFG_MAX_BW_SHIFT)
& FUNC_MF_CFG_MAX_BW_MASK;
bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, mf_cfg);
}
}
static void bnx2x_free_msix_irqs(struct bnx2x *bp) static void bnx2x_free_msix_irqs(struct bnx2x *bp)
{ {
int i, offset = 1; int i, offset = 1;
...@@ -1464,6 +1481,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) ...@@ -1464,6 +1481,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bnx2x_set_eth_mac(bp, 1); bnx2x_set_eth_mac(bp, 1);
if (bp->pending_max) {
bnx2x_update_max_mf_config(bp, bp->pending_max);
bp->pending_max = 0;
}
if (bp->port.pmf) if (bp->port.pmf)
bnx2x_initial_phy_init(bp, load_mode); bnx2x_initial_phy_init(bp, load_mode);
......
...@@ -341,6 +341,15 @@ void bnx2x_dcbx_init(struct bnx2x *bp); ...@@ -341,6 +341,15 @@ void bnx2x_dcbx_init(struct bnx2x *bp);
*/ */
int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state);
/**
* Updates MAX part of MF configuration in HW
* (if required)
*
* @param bp
* @param value
*/
void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value);
/* dev_close main block */ /* dev_close main block */
int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode);
......
...@@ -238,7 +238,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -238,7 +238,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
speed |= (cmd->speed_hi << 16); speed |= (cmd->speed_hi << 16);
if (IS_MF_SI(bp)) { if (IS_MF_SI(bp)) {
u32 param = 0, part; u32 part;
u32 line_speed = bp->link_vars.line_speed; u32 line_speed = bp->link_vars.line_speed;
/* use 10G if no link detected */ /* use 10G if no link detected */
...@@ -251,24 +251,22 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -251,24 +251,22 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
REQ_BC_VER_4_SET_MF_BW); REQ_BC_VER_4_SET_MF_BW);
return -EINVAL; return -EINVAL;
} }
part = (speed * 100) / line_speed; part = (speed * 100) / line_speed;
if (line_speed < speed || !part) { if (line_speed < speed || !part) {
BNX2X_DEV_INFO("Speed setting should be in a range " BNX2X_DEV_INFO("Speed setting should be in a range "
"from 1%% to 100%% " "from 1%% to 100%% "
"of actual line speed\n"); "of actual line speed\n");
return -EINVAL; return -EINVAL;
} }
/* load old values */
param = bp->mf_config[BP_VN(bp)];
/* leave only MIN value */ if (bp->state != BNX2X_STATE_OPEN)
param &= FUNC_MF_CFG_MIN_BW_MASK; /* store value for following "load" */
bp->pending_max = part;
/* set new MAX value */ else
param |= (part << FUNC_MF_CFG_MAX_BW_SHIFT) bnx2x_update_max_mf_config(bp, part);
& FUNC_MF_CFG_MAX_BW_MASK;
bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param);
return 0; return 0;
} }
......
...@@ -2092,8 +2092,9 @@ static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type) ...@@ -2092,8 +2092,9 @@ static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type)
bnx2x_calc_vn_weight_sum(bp); bnx2x_calc_vn_weight_sum(bp);
/* calculate and set min-max rate for each vn */ /* calculate and set min-max rate for each vn */
for (vn = VN_0; vn < E1HVN_MAX; vn++) if (bp->port.pmf)
bnx2x_init_vn_minmax(bp, vn); for (vn = VN_0; vn < E1HVN_MAX; vn++)
bnx2x_init_vn_minmax(bp, vn);
/* always enable rate shaping and fairness */ /* always enable rate shaping and fairness */
bp->cmng.flags.cmng_enables |= bp->cmng.flags.cmng_enables |=
...@@ -2162,13 +2163,6 @@ static void bnx2x_link_attn(struct bnx2x *bp) ...@@ -2162,13 +2163,6 @@ static void bnx2x_link_attn(struct bnx2x *bp)
bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
} }
/* indicate link status only if link status actually changed */
if (prev_link_status != bp->link_vars.link_status)
bnx2x_link_report(bp);
if (IS_MF(bp))
bnx2x_link_sync_notify(bp);
if (bp->link_vars.link_up && bp->link_vars.line_speed) { if (bp->link_vars.link_up && bp->link_vars.line_speed) {
int cmng_fns = bnx2x_get_cmng_fns_mode(bp); int cmng_fns = bnx2x_get_cmng_fns_mode(bp);
...@@ -2180,6 +2174,13 @@ static void bnx2x_link_attn(struct bnx2x *bp) ...@@ -2180,6 +2174,13 @@ static void bnx2x_link_attn(struct bnx2x *bp)
DP(NETIF_MSG_IFUP, DP(NETIF_MSG_IFUP,
"single function mode without fairness\n"); "single function mode without fairness\n");
} }
if (IS_MF(bp))
bnx2x_link_sync_notify(bp);
/* indicate link status only if link status actually changed */
if (prev_link_status != bp->link_vars.link_status)
bnx2x_link_report(bp);
} }
void bnx2x__link_status_update(struct bnx2x *bp) void bnx2x__link_status_update(struct bnx2x *bp)
......
...@@ -281,23 +281,23 @@ static inline int __check_agg_selection_timer(struct port *port) ...@@ -281,23 +281,23 @@ static inline int __check_agg_selection_timer(struct port *port)
} }
/** /**
* __get_rx_machine_lock - lock the port's RX machine * __get_state_machine_lock - lock the port's state machines
* @port: the port we're looking at * @port: the port we're looking at
* *
*/ */
static inline void __get_rx_machine_lock(struct port *port) static inline void __get_state_machine_lock(struct port *port)
{ {
spin_lock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); spin_lock_bh(&(SLAVE_AD_INFO(port->slave).state_machine_lock));
} }
/** /**
* __release_rx_machine_lock - unlock the port's RX machine * __release_state_machine_lock - unlock the port's state machines
* @port: the port we're looking at * @port: the port we're looking at
* *
*/ */
static inline void __release_rx_machine_lock(struct port *port) static inline void __release_state_machine_lock(struct port *port)
{ {
spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).state_machine_lock));
} }
/** /**
...@@ -388,14 +388,14 @@ static u8 __get_duplex(struct port *port) ...@@ -388,14 +388,14 @@ static u8 __get_duplex(struct port *port)
} }
/** /**
* __initialize_port_locks - initialize a port's RX machine spinlock * __initialize_port_locks - initialize a port's STATE machine spinlock
* @port: the port we're looking at * @port: the port we're looking at
* *
*/ */
static inline void __initialize_port_locks(struct port *port) static inline void __initialize_port_locks(struct port *port)
{ {
// make sure it isn't called twice // make sure it isn't called twice
spin_lock_init(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); spin_lock_init(&(SLAVE_AD_INFO(port->slave).state_machine_lock));
} }
//conversions //conversions
...@@ -1025,9 +1025,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) ...@@ -1025,9 +1025,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
{ {
rx_states_t last_state; rx_states_t last_state;
// Lock to prevent 2 instances of this function to run simultaneously(rx interrupt and periodic machine callback)
__get_rx_machine_lock(port);
// keep current State Machine state to compare later if it was changed // keep current State Machine state to compare later if it was changed
last_state = port->sm_rx_state; last_state = port->sm_rx_state;
...@@ -1133,7 +1130,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) ...@@ -1133,7 +1130,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
pr_err("%s: An illegal loopback occurred on adapter (%s).\n" pr_err("%s: An illegal loopback occurred on adapter (%s).\n"
"Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n",
port->slave->dev->master->name, port->slave->dev->name); port->slave->dev->master->name, port->slave->dev->name);
__release_rx_machine_lock(port);
return; return;
} }
__update_selected(lacpdu, port); __update_selected(lacpdu, port);
...@@ -1153,7 +1149,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) ...@@ -1153,7 +1149,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
break; break;
} }
} }
__release_rx_machine_lock(port);
} }
/** /**
...@@ -2155,6 +2150,12 @@ void bond_3ad_state_machine_handler(struct work_struct *work) ...@@ -2155,6 +2150,12 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
goto re_arm; goto re_arm;
} }
/* Lock around state machines to protect data accessed
* by all (e.g., port->sm_vars). ad_rx_machine may run
* concurrently due to incoming LACPDU.
*/
__get_state_machine_lock(port);
ad_rx_machine(NULL, port); ad_rx_machine(NULL, port);
ad_periodic_machine(port); ad_periodic_machine(port);
ad_port_selection_logic(port); ad_port_selection_logic(port);
...@@ -2164,6 +2165,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) ...@@ -2164,6 +2165,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
// turn off the BEGIN bit, since we already handled it // turn off the BEGIN bit, since we already handled it
if (port->sm_vars & AD_PORT_BEGIN) if (port->sm_vars & AD_PORT_BEGIN)
port->sm_vars &= ~AD_PORT_BEGIN; port->sm_vars &= ~AD_PORT_BEGIN;
__release_state_machine_lock(port);
} }
re_arm: re_arm:
...@@ -2200,7 +2203,10 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u ...@@ -2200,7 +2203,10 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
case AD_TYPE_LACPDU: case AD_TYPE_LACPDU:
pr_debug("Received LACPDU on port %d\n", pr_debug("Received LACPDU on port %d\n",
port->actor_port_number); port->actor_port_number);
/* Protect against concurrent state machines */
__get_state_machine_lock(port);
ad_rx_machine(lacpdu, port); ad_rx_machine(lacpdu, port);
__release_state_machine_lock(port);
break; break;
case AD_TYPE_MARKER: case AD_TYPE_MARKER:
......
...@@ -264,7 +264,8 @@ struct ad_bond_info { ...@@ -264,7 +264,8 @@ struct ad_bond_info {
struct ad_slave_info { struct ad_slave_info {
struct aggregator aggregator; // 802.3ad aggregator structure struct aggregator aggregator; // 802.3ad aggregator structure
struct port port; // 802.3ad port structure struct port port; // 802.3ad port structure
spinlock_t rx_machine_lock; // To avoid race condition between callback and receive interrupt spinlock_t state_machine_lock; /* mutex state machines vs.
incoming LACPDU */
u16 id; u16 id;
}; };
......
...@@ -528,8 +528,9 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, ...@@ -528,8 +528,9 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q,
vnet_hdr_len = q->vnet_hdr_sz; vnet_hdr_len = q->vnet_hdr_sz;
err = -EINVAL; err = -EINVAL;
if ((len -= vnet_hdr_len) < 0) if (len < vnet_hdr_len)
goto err; goto err;
len -= vnet_hdr_len;
err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0, err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0,
sizeof(vnet_hdr)); sizeof(vnet_hdr));
......
...@@ -49,8 +49,8 @@ ...@@ -49,8 +49,8 @@
#include <asm/processor.h> #include <asm/processor.h>
#define DRV_NAME "r6040" #define DRV_NAME "r6040"
#define DRV_VERSION "0.26" #define DRV_VERSION "0.27"
#define DRV_RELDATE "30May2010" #define DRV_RELDATE "23Feb2011"
/* PHY CHIP Address */ /* PHY CHIP Address */
#define PHY1_ADDR 1 /* For MAC1 */ #define PHY1_ADDR 1 /* For MAC1 */
...@@ -69,6 +69,8 @@ ...@@ -69,6 +69,8 @@
/* MAC registers */ /* MAC registers */
#define MCR0 0x00 /* Control register 0 */ #define MCR0 0x00 /* Control register 0 */
#define MCR0_PROMISC 0x0020 /* Promiscuous mode */
#define MCR0_HASH_EN 0x0100 /* Enable multicast hash table function */
#define MCR1 0x04 /* Control register 1 */ #define MCR1 0x04 /* Control register 1 */
#define MAC_RST 0x0001 /* Reset the MAC */ #define MAC_RST 0x0001 /* Reset the MAC */
#define MBCR 0x08 /* Bus control */ #define MBCR 0x08 /* Bus control */
...@@ -851,77 +853,92 @@ static void r6040_multicast_list(struct net_device *dev) ...@@ -851,77 +853,92 @@ static void r6040_multicast_list(struct net_device *dev)
{ {
struct r6040_private *lp = netdev_priv(dev); struct r6040_private *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base; void __iomem *ioaddr = lp->base;
u16 *adrp;
u16 reg;
unsigned long flags; unsigned long flags;
struct netdev_hw_addr *ha; struct netdev_hw_addr *ha;
int i; int i;
u16 *adrp;
u16 hash_table[4] = { 0 };
spin_lock_irqsave(&lp->lock, flags);
/* MAC Address */ /* Keep our MAC Address */
adrp = (u16 *)dev->dev_addr; adrp = (u16 *)dev->dev_addr;
iowrite16(adrp[0], ioaddr + MID_0L); iowrite16(adrp[0], ioaddr + MID_0L);
iowrite16(adrp[1], ioaddr + MID_0M); iowrite16(adrp[1], ioaddr + MID_0M);
iowrite16(adrp[2], ioaddr + MID_0H); iowrite16(adrp[2], ioaddr + MID_0H);
/* Promiscous Mode */
spin_lock_irqsave(&lp->lock, flags);
/* Clear AMCP & PROM bits */ /* Clear AMCP & PROM bits */
reg = ioread16(ioaddr) & ~0x0120; lp->mcr0 = ioread16(ioaddr + MCR0) & ~(MCR0_PROMISC | MCR0_HASH_EN);
if (dev->flags & IFF_PROMISC) {
reg |= 0x0020;
lp->mcr0 |= 0x0020;
}
/* Too many multicast addresses
* accept all traffic */
else if ((netdev_mc_count(dev) > MCAST_MAX) ||
(dev->flags & IFF_ALLMULTI))
reg |= 0x0020;
iowrite16(reg, ioaddr); /* Promiscuous mode */
spin_unlock_irqrestore(&lp->lock, flags); if (dev->flags & IFF_PROMISC)
lp->mcr0 |= MCR0_PROMISC;
/* Build the hash table */ /* Enable multicast hash table function to
if (netdev_mc_count(dev) > MCAST_MAX) { * receive all multicast packets. */
u16 hash_table[4]; else if (dev->flags & IFF_ALLMULTI) {
u32 crc; lp->mcr0 |= MCR0_HASH_EN;
for (i = 0; i < 4; i++) for (i = 0; i < MCAST_MAX ; i++) {
hash_table[i] = 0; iowrite16(0, ioaddr + MID_1L + 8 * i);
iowrite16(0, ioaddr + MID_1M + 8 * i);
iowrite16(0, ioaddr + MID_1H + 8 * i);
}
for (i = 0; i < 4; i++)
hash_table[i] = 0xffff;
}
/* Use internal multicast address registers if the number of
* multicast addresses is not greater than MCAST_MAX. */
else if (netdev_mc_count(dev) <= MCAST_MAX) {
i = 0;
netdev_for_each_mc_addr(ha, dev) { netdev_for_each_mc_addr(ha, dev) {
char *addrs = ha->addr; u16 *adrp = (u16 *) ha->addr;
iowrite16(adrp[0], ioaddr + MID_1L + 8 * i);
iowrite16(adrp[1], ioaddr + MID_1M + 8 * i);
iowrite16(adrp[2], ioaddr + MID_1H + 8 * i);
i++;
}
while (i < MCAST_MAX) {
iowrite16(0, ioaddr + MID_1L + 8 * i);
iowrite16(0, ioaddr + MID_1M + 8 * i);
iowrite16(0, ioaddr + MID_1H + 8 * i);
i++;
}
}
/* Otherwise, Enable multicast hash table function. */
else {
u32 crc;
if (!(*addrs & 1)) lp->mcr0 |= MCR0_HASH_EN;
continue;
for (i = 0; i < MCAST_MAX ; i++) {
iowrite16(0, ioaddr + MID_1L + 8 * i);
iowrite16(0, ioaddr + MID_1M + 8 * i);
iowrite16(0, ioaddr + MID_1H + 8 * i);
}
crc = ether_crc_le(6, addrs); /* Build multicast hash table */
netdev_for_each_mc_addr(ha, dev) {
u8 *addrs = ha->addr;
crc = ether_crc(ETH_ALEN, addrs);
crc >>= 26; crc >>= 26;
hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); hash_table[crc >> 4] |= 1 << (crc & 0xf);
} }
/* Fill the MAC hash tables with their values */ }
iowrite16(lp->mcr0, ioaddr + MCR0);
/* Fill the MAC hash tables with their values */
if (lp->mcr0 && MCR0_HASH_EN) {
iowrite16(hash_table[0], ioaddr + MAR0); iowrite16(hash_table[0], ioaddr + MAR0);
iowrite16(hash_table[1], ioaddr + MAR1); iowrite16(hash_table[1], ioaddr + MAR1);
iowrite16(hash_table[2], ioaddr + MAR2); iowrite16(hash_table[2], ioaddr + MAR2);
iowrite16(hash_table[3], ioaddr + MAR3); iowrite16(hash_table[3], ioaddr + MAR3);
} }
/* Multicast Address 1~4 case */
i = 0; spin_unlock_irqrestore(&lp->lock, flags);
netdev_for_each_mc_addr(ha, dev) {
if (i >= MCAST_MAX)
break;
adrp = (u16 *) ha->addr;
iowrite16(adrp[0], ioaddr + MID_1L + 8 * i);
iowrite16(adrp[1], ioaddr + MID_1M + 8 * i);
iowrite16(adrp[2], ioaddr + MID_1H + 8 * i);
i++;
}
while (i < MCAST_MAX) {
iowrite16(0xffff, ioaddr + MID_1L + 8 * i);
iowrite16(0xffff, ioaddr + MID_1M + 8 * i);
iowrite16(0xffff, ioaddr + MID_1H + 8 * i);
i++;
}
} }
static void netdev_get_drvinfo(struct net_device *dev, static void netdev_get_drvinfo(struct net_device *dev,
......
...@@ -1178,6 +1178,11 @@ static int smsc911x_open(struct net_device *dev) ...@@ -1178,6 +1178,11 @@ static int smsc911x_open(struct net_device *dev)
smsc911x_reg_write(pdata, HW_CFG, 0x00050000); smsc911x_reg_write(pdata, HW_CFG, 0x00050000);
smsc911x_reg_write(pdata, AFC_CFG, 0x006E3740); smsc911x_reg_write(pdata, AFC_CFG, 0x006E3740);
/* Increase the legal frame size of VLAN tagged frames to 1522 bytes */
spin_lock_irq(&pdata->mac_lock);
smsc911x_mac_write(pdata, VLAN1, ETH_P_8021Q);
spin_unlock_irq(&pdata->mac_lock);
/* Make sure EEPROM has finished loading before setting GPIO_CFG */ /* Make sure EEPROM has finished loading before setting GPIO_CFG */
timeout = 50; timeout = 50;
while ((smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) && while ((smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) &&
......
...@@ -19,9 +19,7 @@ obj-$(CONFIG_NETFILTER) += netfilter/ ...@@ -19,9 +19,7 @@ obj-$(CONFIG_NETFILTER) += netfilter/
obj-$(CONFIG_INET) += ipv4/ obj-$(CONFIG_INET) += ipv4/
obj-$(CONFIG_XFRM) += xfrm/ obj-$(CONFIG_XFRM) += xfrm/
obj-$(CONFIG_UNIX) += unix/ obj-$(CONFIG_UNIX) += unix/
ifneq ($(CONFIG_IPV6),) obj-$(CONFIG_NET) += ipv6/
obj-y += ipv6/
endif
obj-$(CONFIG_PACKET) += packet/ obj-$(CONFIG_PACKET) += packet/
obj-$(CONFIG_NET_KEY) += key/ obj-$(CONFIG_NET_KEY) += key/
obj-$(CONFIG_BRIDGE) += bridge/ obj-$(CONFIG_BRIDGE) += bridge/
......
...@@ -6,6 +6,7 @@ config BRIDGE ...@@ -6,6 +6,7 @@ config BRIDGE
tristate "802.1d Ethernet Bridging" tristate "802.1d Ethernet Bridging"
select LLC select LLC
select STP select STP
depends on IPV6 || IPV6=n
---help--- ---help---
If you say Y here, then your Linux box will be able to act as an If you say Y here, then your Linux box will be able to act as an
Ethernet bridge, which means that the different Ethernet segments it Ethernet bridge, which means that the different Ethernet segments it
......
...@@ -3321,7 +3321,7 @@ static void show_results(struct pktgen_dev *pkt_dev, int nr_frags) ...@@ -3321,7 +3321,7 @@ static void show_results(struct pktgen_dev *pkt_dev, int nr_frags)
pkt_dev->started_at); pkt_dev->started_at);
ktime_t idle = ns_to_ktime(pkt_dev->idle_acc); ktime_t idle = ns_to_ktime(pkt_dev->idle_acc);
p += sprintf(p, "OK: %llu(c%llu+d%llu) nsec, %llu (%dbyte,%dfrags)\n", p += sprintf(p, "OK: %llu(c%llu+d%llu) usec, %llu (%dbyte,%dfrags)\n",
(unsigned long long)ktime_to_us(elapsed), (unsigned long long)ktime_to_us(elapsed),
(unsigned long long)ktime_to_us(ktime_sub(elapsed, idle)), (unsigned long long)ktime_to_us(ktime_sub(elapsed, idle)),
(unsigned long long)ktime_to_us(idle), (unsigned long long)ktime_to_us(idle),
......
...@@ -670,7 +670,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg) ...@@ -670,7 +670,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
ifap = &ifa->ifa_next) { ifap = &ifa->ifa_next) {
if (!strcmp(ifr.ifr_name, ifa->ifa_label) && if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
sin_orig.sin_addr.s_addr == sin_orig.sin_addr.s_addr ==
ifa->ifa_address) { ifa->ifa_local) {
break; /* found */ break; /* found */
} }
} }
...@@ -1040,8 +1040,8 @@ static void inetdev_send_gratuitous_arp(struct net_device *dev, ...@@ -1040,8 +1040,8 @@ static void inetdev_send_gratuitous_arp(struct net_device *dev,
return; return;
arp_send(ARPOP_REQUEST, ETH_P_ARP, arp_send(ARPOP_REQUEST, ETH_P_ARP,
ifa->ifa_address, dev, ifa->ifa_local, dev,
ifa->ifa_address, NULL, ifa->ifa_local, NULL,
dev->dev_addr, NULL); dev->dev_addr, NULL);
} }
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
MODULE_AUTHOR("Ville Nuorvala"); MODULE_AUTHOR("Ville Nuorvala");
MODULE_DESCRIPTION("IPv6 tunneling device"); MODULE_DESCRIPTION("IPv6 tunneling device");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS_NETDEV("ip6tnl0");
#ifdef IP6_TNL_DEBUG #ifdef IP6_TNL_DEBUG
#define IP6_TNL_TRACE(x...) printk(KERN_DEBUG "%s:" x "\n", __func__) #define IP6_TNL_TRACE(x...) printk(KERN_DEBUG "%s:" x "\n", __func__)
......
...@@ -739,8 +739,10 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, ...@@ -739,8 +739,10 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src); nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src);
else else if (!(rt->dst.flags & DST_HOST))
nrt = rt6_alloc_clone(rt, &fl->fl6_dst); nrt = rt6_alloc_clone(rt, &fl->fl6_dst);
else
goto out2;
dst_release(&rt->dst); dst_release(&rt->dst);
rt = nrt ? : net->ipv6.ip6_null_entry; rt = nrt ? : net->ipv6.ip6_null_entry;
......
...@@ -551,7 +551,10 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, ...@@ -551,7 +551,10 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
if (conn->c_loopback if (conn->c_loopback
&& rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) {
rds_cong_map_updated(conn->c_fcong, ~(u64) 0); rds_cong_map_updated(conn->c_fcong, ~(u64) 0);
return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; scat = &rm->data.op_sg[sg];
ret = sizeof(struct rds_header) + RDS_CONG_MAP_BYTES;
ret = min_t(int, ret, scat->length - conn->c_xmit_data_off);
return ret;
} }
/* FIXME we may overallocate here */ /* FIXME we may overallocate here */
......
...@@ -61,10 +61,15 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm, ...@@ -61,10 +61,15 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm,
unsigned int hdr_off, unsigned int sg, unsigned int hdr_off, unsigned int sg,
unsigned int off) unsigned int off)
{ {
struct scatterlist *sgp = &rm->data.op_sg[sg];
int ret = sizeof(struct rds_header) +
be32_to_cpu(rm->m_inc.i_hdr.h_len);
/* Do not send cong updates to loopback */ /* Do not send cong updates to loopback */
if (rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { if (rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) {
rds_cong_map_updated(conn->c_fcong, ~(u64) 0); rds_cong_map_updated(conn->c_fcong, ~(u64) 0);
return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; ret = min_t(int, ret, sgp->length - conn->c_xmit_data_off);
goto out;
} }
BUG_ON(hdr_off || sg || off); BUG_ON(hdr_off || sg || off);
...@@ -80,8 +85,8 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm, ...@@ -80,8 +85,8 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm,
NULL); NULL);
rds_inc_put(&rm->m_inc); rds_inc_put(&rm->m_inc);
out:
return sizeof(struct rds_header) + be32_to_cpu(rm->m_inc.i_hdr.h_len); return ret;
} }
/* /*
......
...@@ -1724,7 +1724,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1724,7 +1724,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
msg->msg_namelen = 0; msg->msg_namelen = 0;
mutex_lock(&u->readlock); err = mutex_lock_interruptible(&u->readlock);
if (err) {
err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
goto out;
}
skb = skb_recv_datagram(sk, flags, noblock, &err); skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb) { if (!skb) {
...@@ -1864,7 +1868,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1864,7 +1868,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
memset(&tmp_scm, 0, sizeof(tmp_scm)); memset(&tmp_scm, 0, sizeof(tmp_scm));
} }
mutex_lock(&u->readlock); err = mutex_lock_interruptible(&u->readlock);
if (err) {
err = sock_intr_errno(timeo);
goto out;
}
do { do {
int chunk; int chunk;
...@@ -1895,11 +1903,12 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1895,11 +1903,12 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
timeo = unix_stream_data_wait(sk, timeo); timeo = unix_stream_data_wait(sk, timeo);
if (signal_pending(current)) { if (signal_pending(current)
|| mutex_lock_interruptible(&u->readlock)) {
err = sock_intr_errno(timeo); err = sock_intr_errno(timeo);
goto out; goto out;
} }
mutex_lock(&u->readlock);
continue; continue;
unlock: unlock:
unix_state_unlock(sk); unix_state_unlock(sk);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册