Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

Conflicts:

	net/mac80211/tx.c
This commit is contained in:
David S. Miller 2008-06-19 16:00:04 -07:00
commit 0344f1c66b
20 changed files with 311 additions and 276 deletions

View File

@ -471,7 +471,6 @@ static int atl1_get_permanent_address(struct atl1_hw *hw)
memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN); memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
return 0; return 0;
} }
return 1;
} }
/* see if SPI FLAGS exist ? */ /* see if SPI FLAGS exist ? */

View File

@ -400,26 +400,31 @@ enc28j60_packet_write(struct enc28j60_net *priv, int len, const u8 *data)
mutex_unlock(&priv->lock); mutex_unlock(&priv->lock);
} }
static unsigned long msec20_to_jiffies;
static int poll_ready(struct enc28j60_net *priv, u8 reg, u8 mask, u8 val)
{
unsigned long timeout = jiffies + msec20_to_jiffies;
/* 20 msec timeout read */
while ((nolock_regb_read(priv, reg) & mask) != val) {
if (time_after(jiffies, timeout)) {
if (netif_msg_drv(priv))
dev_dbg(&priv->spi->dev,
"reg %02x ready timeout!\n", reg);
return -ETIMEDOUT;
}
cpu_relax();
}
return 0;
}
/* /*
* Wait until the PHY operation is complete. * Wait until the PHY operation is complete.
*/ */
static int wait_phy_ready(struct enc28j60_net *priv) static int wait_phy_ready(struct enc28j60_net *priv)
{ {
unsigned long timeout = jiffies + 20 * HZ / 1000; return poll_ready(priv, MISTAT, MISTAT_BUSY, 0) ? 0 : 1;
int ret = 1;
/* 20 msec timeout read */
while (nolock_regb_read(priv, MISTAT) & MISTAT_BUSY) {
if (time_after(jiffies, timeout)) {
if (netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME
": PHY ready timeout!\n");
ret = 0;
break;
}
cpu_relax();
}
return ret;
} }
/* /*
@ -594,6 +599,32 @@ static void nolock_txfifo_init(struct enc28j60_net *priv, u16 start, u16 end)
nolock_regw_write(priv, ETXNDL, end); nolock_regw_write(priv, ETXNDL, end);
} }
/*
* Low power mode shrinks power consumption about 100x, so we'd like
* the chip to be in that mode whenever it's inactive. (However, we
* can't stay in lowpower mode during suspend with WOL active.)
*/
static void enc28j60_lowpower(struct enc28j60_net *priv, bool is_low)
{
if (netif_msg_drv(priv))
dev_dbg(&priv->spi->dev, "%s power...\n",
is_low ? "low" : "high");
mutex_lock(&priv->lock);
if (is_low) {
nolock_reg_bfclr(priv, ECON1, ECON1_RXEN);
poll_ready(priv, ESTAT, ESTAT_RXBUSY, 0);
poll_ready(priv, ECON1, ECON1_TXRTS, 0);
/* ECON2_VRPS was set during initialization */
nolock_reg_bfset(priv, ECON2, ECON2_PWRSV);
} else {
nolock_reg_bfclr(priv, ECON2, ECON2_PWRSV);
poll_ready(priv, ESTAT, ESTAT_CLKRDY, ESTAT_CLKRDY);
/* caller sets ECON1_RXEN */
}
mutex_unlock(&priv->lock);
}
static int enc28j60_hw_init(struct enc28j60_net *priv) static int enc28j60_hw_init(struct enc28j60_net *priv)
{ {
u8 reg; u8 reg;
@ -612,8 +643,8 @@ static int enc28j60_hw_init(struct enc28j60_net *priv)
priv->tx_retry_count = 0; priv->tx_retry_count = 0;
priv->max_pk_counter = 0; priv->max_pk_counter = 0;
priv->rxfilter = RXFILTER_NORMAL; priv->rxfilter = RXFILTER_NORMAL;
/* enable address auto increment */ /* enable address auto increment and voltage regulator powersave */
nolock_regb_write(priv, ECON2, ECON2_AUTOINC); nolock_regb_write(priv, ECON2, ECON2_AUTOINC | ECON2_VRPS);
nolock_rxfifo_init(priv, RXSTART_INIT, RXEND_INIT); nolock_rxfifo_init(priv, RXSTART_INIT, RXEND_INIT);
nolock_txfifo_init(priv, TXSTART_INIT, TXEND_INIT); nolock_txfifo_init(priv, TXSTART_INIT, TXEND_INIT);
@ -690,7 +721,7 @@ static int enc28j60_hw_init(struct enc28j60_net *priv)
static void enc28j60_hw_enable(struct enc28j60_net *priv) static void enc28j60_hw_enable(struct enc28j60_net *priv)
{ {
/* enable interrutps */ /* enable interrupts */
if (netif_msg_hw(priv)) if (netif_msg_hw(priv))
printk(KERN_DEBUG DRV_NAME ": %s() enabling interrupts.\n", printk(KERN_DEBUG DRV_NAME ": %s() enabling interrupts.\n",
__FUNCTION__); __FUNCTION__);
@ -726,15 +757,12 @@ enc28j60_setlink(struct net_device *ndev, u8 autoneg, u16 speed, u8 duplex)
int ret = 0; int ret = 0;
if (!priv->hw_enable) { if (!priv->hw_enable) {
if (autoneg == AUTONEG_DISABLE && speed == SPEED_10) { /* link is in low power mode now; duplex setting
* will take effect on next enc28j60_hw_init().
*/
if (autoneg == AUTONEG_DISABLE && speed == SPEED_10)
priv->full_duplex = (duplex == DUPLEX_FULL); priv->full_duplex = (duplex == DUPLEX_FULL);
if (!enc28j60_hw_init(priv)) { else {
if (netif_msg_drv(priv))
dev_err(&ndev->dev,
"hw_reset() failed\n");
ret = -EINVAL;
}
} else {
if (netif_msg_link(priv)) if (netif_msg_link(priv))
dev_warn(&ndev->dev, dev_warn(&ndev->dev,
"unsupported link setting\n"); "unsupported link setting\n");
@ -1307,7 +1335,8 @@ static int enc28j60_net_open(struct net_device *dev)
} }
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
} }
/* Reset the hardware here */ /* Reset the hardware here (and take it out of low power mode) */
enc28j60_lowpower(priv, false);
enc28j60_hw_disable(priv); enc28j60_hw_disable(priv);
if (!enc28j60_hw_init(priv)) { if (!enc28j60_hw_init(priv)) {
if (netif_msg_ifup(priv)) if (netif_msg_ifup(priv))
@ -1337,6 +1366,7 @@ static int enc28j60_net_close(struct net_device *dev)
printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__); printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
enc28j60_hw_disable(priv); enc28j60_hw_disable(priv);
enc28j60_lowpower(priv, true);
netif_stop_queue(dev); netif_stop_queue(dev);
return 0; return 0;
@ -1537,6 +1567,8 @@ static int __devinit enc28j60_probe(struct spi_device *spi)
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
SET_ETHTOOL_OPS(dev, &enc28j60_ethtool_ops); SET_ETHTOOL_OPS(dev, &enc28j60_ethtool_ops);
enc28j60_lowpower(priv, true);
ret = register_netdev(dev); ret = register_netdev(dev);
if (ret) { if (ret) {
if (netif_msg_probe(priv)) if (netif_msg_probe(priv))
@ -1556,7 +1588,7 @@ static int __devinit enc28j60_probe(struct spi_device *spi)
return ret; return ret;
} }
static int enc28j60_remove(struct spi_device *spi) static int __devexit enc28j60_remove(struct spi_device *spi)
{ {
struct enc28j60_net *priv = dev_get_drvdata(&spi->dev); struct enc28j60_net *priv = dev_get_drvdata(&spi->dev);
@ -1573,15 +1605,16 @@ static int enc28j60_remove(struct spi_device *spi)
static struct spi_driver enc28j60_driver = { static struct spi_driver enc28j60_driver = {
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.bus = &spi_bus_type,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = enc28j60_probe, .probe = enc28j60_probe,
.remove = __devexit_p(enc28j60_remove), .remove = __devexit_p(enc28j60_remove),
}; };
static int __init enc28j60_init(void) static int __init enc28j60_init(void)
{ {
msec20_to_jiffies = msecs_to_jiffies(20);
return spi_register_driver(&enc28j60_driver); return spi_register_driver(&enc28j60_driver);
} }

View File

@ -1,6 +1,7 @@
config IBM_NEW_EMAC config IBM_NEW_EMAC
tristate "IBM EMAC Ethernet support" tristate "IBM EMAC Ethernet support"
depends on PPC_DCR && PPC_MERGE depends on PPC_DCR && PPC_MERGE
select CRC32
help help
This driver supports the IBM EMAC family of Ethernet controllers This driver supports the IBM EMAC family of Ethernet controllers
typically found on 4xx embedded PowerPC chips, but also on the typically found on 4xx embedded PowerPC chips, but also on the

View File

@ -776,7 +776,6 @@ struct netxen_hardware_context {
u8 revision_id; u8 revision_id;
u16 board_type; u16 board_type;
u16 max_ports;
struct netxen_board_info boardcfg; struct netxen_board_info boardcfg;
u32 xg_linkup; u32 xg_linkup;
u32 qg_linksup; u32 qg_linksup;
@ -863,6 +862,7 @@ struct netxen_adapter {
unsigned char mac_addr[ETH_ALEN]; unsigned char mac_addr[ETH_ALEN];
int mtu; int mtu;
int portnum; int portnum;
u8 physical_port;
struct work_struct watchdog_task; struct work_struct watchdog_task;
struct timer_list watchdog_timer; struct timer_list watchdog_timer;
@ -1034,7 +1034,6 @@ int netxen_rom_se(struct netxen_adapter *adapter, int addr);
/* Functions from netxen_nic_isr.c */ /* Functions from netxen_nic_isr.c */
void netxen_initialize_adapter_sw(struct netxen_adapter *adapter); void netxen_initialize_adapter_sw(struct netxen_adapter *adapter);
void netxen_initialize_adapter_hw(struct netxen_adapter *adapter);
void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr, void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr,
struct pci_dev **used_dev); struct pci_dev **used_dev);
void netxen_initialize_adapter_ops(struct netxen_adapter *adapter); void netxen_initialize_adapter_ops(struct netxen_adapter *adapter);
@ -1077,20 +1076,6 @@ static const struct netxen_brdinfo netxen_boards[] = {
#define NUM_SUPPORTED_BOARDS ARRAY_SIZE(netxen_boards) #define NUM_SUPPORTED_BOARDS ARRAY_SIZE(netxen_boards)
static inline void get_brd_port_by_type(u32 type, int *ports)
{
int i, found = 0;
for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) {
if (netxen_boards[i].brdtype == type) {
*ports = netxen_boards[i].ports;
found = 1;
break;
}
}
if (!found)
*ports = 0;
}
static inline void get_brd_name_by_type(u32 type, char *name) static inline void get_brd_name_by_type(u32 type, char *name)
{ {
int i, found = 0; int i, found = 0;
@ -1169,5 +1154,4 @@ extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
extern struct ethtool_ops netxen_nic_ethtool_ops; extern struct ethtool_ops netxen_nic_ethtool_ops;
extern int physical_port[]; /* physical port # from virtual port.*/
#endif /* __NETXEN_NIC_H_ */ #endif /* __NETXEN_NIC_H_ */

View File

@ -369,7 +369,7 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) { for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) {
/* GB: port specific registers */ /* GB: port specific registers */
if (mode == 0 && i >= 19) if (mode == 0 && i >= 19)
window = physical_port[adapter->portnum] * window = adapter->physical_port *
NETXEN_NIC_PORT_WINDOW; NETXEN_NIC_PORT_WINDOW;
NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode]. NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode].
@ -527,7 +527,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,
{ {
struct netxen_adapter *adapter = netdev_priv(dev); struct netxen_adapter *adapter = netdev_priv(dev);
__u32 val; __u32 val;
int port = physical_port[adapter->portnum]; int port = adapter->physical_port;
if (adapter->ahw.board_type == NETXEN_NIC_GBE) { if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
@ -573,7 +573,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,
{ {
struct netxen_adapter *adapter = netdev_priv(dev); struct netxen_adapter *adapter = netdev_priv(dev);
__u32 val; __u32 val;
int port = physical_port[adapter->portnum]; int port = adapter->physical_port;
/* read mode */ /* read mode */
if (adapter->ahw.board_type == NETXEN_NIC_GBE) { if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))

View File

@ -396,11 +396,8 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
} }
adapter->intr_scheme = readl( adapter->intr_scheme = readl(
NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW));
printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name,
adapter->intr_scheme);
adapter->msi_mode = readl( adapter->msi_mode = readl(
NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_FW)); NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_FW));
DPRINTK(INFO, "Receive Peg ready too. starting stuff\n");
addr = netxen_alloc(adapter->ahw.pdev, addr = netxen_alloc(adapter->ahw.pdev,
sizeof(struct netxen_ring_ctx) + sizeof(struct netxen_ring_ctx) +
@ -408,8 +405,6 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
(dma_addr_t *) & adapter->ctx_desc_phys_addr, (dma_addr_t *) & adapter->ctx_desc_phys_addr,
&adapter->ctx_desc_pdev); &adapter->ctx_desc_pdev);
printk(KERN_INFO "ctx_desc_phys_addr: 0x%llx\n",
(unsigned long long) adapter->ctx_desc_phys_addr);
if (addr == NULL) { if (addr == NULL) {
DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
err = -ENOMEM; err = -ENOMEM;
@ -429,8 +424,6 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
adapter->max_tx_desc_count, adapter->max_tx_desc_count,
(dma_addr_t *) & hw->cmd_desc_phys_addr, (dma_addr_t *) & hw->cmd_desc_phys_addr,
&adapter->ahw.cmd_desc_pdev); &adapter->ahw.cmd_desc_pdev);
printk(KERN_INFO "cmd_desc_phys_addr: 0x%llx\n",
(unsigned long long) hw->cmd_desc_phys_addr);
if (addr == NULL) { if (addr == NULL) {
DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
@ -1032,15 +1025,15 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu) int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
{ {
netxen_nic_write_w0(adapter, netxen_nic_write_w0(adapter,
NETXEN_NIU_GB_MAX_FRAME_SIZE( NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
physical_port[adapter->portnum]), new_mtu); new_mtu);
return 0; return 0;
} }
int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
{ {
new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE; new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE;
if (physical_port[adapter->portnum] == 0) if (adapter->physical_port == 0)
netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE,
new_mtu); new_mtu);
else else
@ -1051,7 +1044,7 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
void netxen_nic_init_niu_gb(struct netxen_adapter *adapter) void netxen_nic_init_niu_gb(struct netxen_adapter *adapter)
{ {
netxen_niu_gbe_init_port(adapter, physical_port[adapter->portnum]); netxen_niu_gbe_init_port(adapter, adapter->physical_port);
} }
void void
@ -1127,7 +1120,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
void netxen_nic_flash_print(struct netxen_adapter *adapter) void netxen_nic_flash_print(struct netxen_adapter *adapter)
{ {
int valid = 1;
u32 fw_major = 0; u32 fw_major = 0;
u32 fw_minor = 0; u32 fw_minor = 0;
u32 fw_build = 0; u32 fw_build = 0;
@ -1137,70 +1129,62 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
__le32 *ptr32; __le32 *ptr32;
struct netxen_board_info *board_info = &(adapter->ahw.boardcfg); struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
if (board_info->magic != NETXEN_BDINFO_MAGIC) {
printk
("NetXen Unknown board config, Read 0x%x expected as 0x%x\n",
board_info->magic, NETXEN_BDINFO_MAGIC);
valid = 0;
}
if (board_info->header_version != NETXEN_BDINFO_VERSION) {
printk("NetXen Unknown board config version."
" Read %x, expected %x\n",
board_info->header_version, NETXEN_BDINFO_VERSION);
valid = 0;
}
if (valid) {
ptr32 = (u32 *)&serial_num;
addr = NETXEN_USER_START +
offsetof(struct netxen_new_user_info, serial_num);
for (i = 0; i < 8; i++) {
if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
printk("%s: ERROR reading %s board userarea.\n",
netxen_nic_driver_name,
netxen_nic_driver_name);
return;
}
ptr32++;
addr += sizeof(u32);
}
adapter->driver_mismatch = 0;
ptr32 = (u32 *)&serial_num;
addr = NETXEN_USER_START +
offsetof(struct netxen_new_user_info, serial_num);
for (i = 0; i < 8; i++) {
if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
printk("%s: ERROR reading %s board userarea.\n",
netxen_nic_driver_name,
netxen_nic_driver_name);
adapter->driver_mismatch = 1;
return;
}
ptr32++;
addr += sizeof(u32);
}
fw_major = readl(NETXEN_CRB_NORMALIZE(adapter,
NETXEN_FW_VERSION_MAJOR));
fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter,
NETXEN_FW_VERSION_MINOR));
fw_build =
readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB));
if (adapter->portnum == 0) {
get_brd_name_by_type(board_info->board_type, brd_name); get_brd_name_by_type(board_info->board_type, brd_name);
printk("NetXen %s Board S/N %s Chip id 0x%x\n", printk("NetXen %s Board S/N %s Chip id 0x%x\n",
brd_name, serial_num, board_info->chip_id); brd_name, serial_num, board_info->chip_id);
printk("NetXen Firmware version %d.%d.%d\n", fw_major,
printk("NetXen %s Board #%d, Chip id 0x%x\n", fw_minor, fw_build);
board_info->board_type == 0x0b ? "XGB" : "GBE",
board_info->board_num, board_info->chip_id);
fw_major = readl(NETXEN_CRB_NORMALIZE(adapter,
NETXEN_FW_VERSION_MAJOR));
fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter,
NETXEN_FW_VERSION_MINOR));
fw_build =
readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB));
printk("NetXen Firmware version %d.%d.%d\n", fw_major, fw_minor,
fw_build);
} }
if (fw_major != _NETXEN_NIC_LINUX_MAJOR) { if (fw_major != _NETXEN_NIC_LINUX_MAJOR) {
printk(KERN_ERR "The mismatch in driver version and firmware "
"version major number\n"
"Driver version major number = %d \t"
"Firmware version major number = %d \n",
_NETXEN_NIC_LINUX_MAJOR, fw_major);
adapter->driver_mismatch = 1; adapter->driver_mismatch = 1;
} }
if (fw_minor != _NETXEN_NIC_LINUX_MINOR && if (fw_minor != _NETXEN_NIC_LINUX_MINOR &&
fw_minor != (_NETXEN_NIC_LINUX_MINOR + 1)) { fw_minor != (_NETXEN_NIC_LINUX_MINOR + 1)) {
printk(KERN_ERR "The mismatch in driver version and firmware "
"version minor number\n"
"Driver version minor number = %d \t"
"Firmware version minor number = %d \n",
_NETXEN_NIC_LINUX_MINOR, fw_minor);
adapter->driver_mismatch = 1; adapter->driver_mismatch = 1;
} }
if (adapter->driver_mismatch) if (adapter->driver_mismatch) {
printk(KERN_INFO "Use the driver with version no %d.%d.xxx\n", printk(KERN_ERR "%s: driver and firmware version mismatch\n",
fw_major, fw_minor); adapter->netdev->name);
return;
}
switch (adapter->ahw.board_type) {
case NETXEN_NIC_GBE:
dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
adapter->netdev->name);
break;
case NETXEN_NIC_XGBE:
dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n",
adapter->netdev->name);
break;
}
} }

View File

@ -203,21 +203,6 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter)
} }
} }
void netxen_initialize_adapter_hw(struct netxen_adapter *adapter)
{
int ports = 0;
struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
if (netxen_nic_get_board_info(adapter) != 0)
printk("%s: Error getting board config info.\n",
netxen_nic_driver_name);
get_brd_port_by_type(board_info->board_type, &ports);
if (ports == 0)
printk(KERN_ERR "%s: Unknown board type\n",
netxen_nic_driver_name);
adapter->ahw.max_ports = ports;
}
void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
{ {
switch (adapter->ahw.board_type) { switch (adapter->ahw.board_type) {
@ -765,18 +750,13 @@ int netxen_flash_unlock(struct netxen_adapter *adapter)
int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
{ {
int addr, val, status; int addr, val;
int n, i; int n, i;
int init_delay = 0; int init_delay = 0;
struct crb_addr_pair *buf; struct crb_addr_pair *buf;
u32 off; u32 off;
/* resetall */ /* resetall */
status = netxen_nic_get_board_info(adapter);
if (status)
printk("%s: netxen_pinit_from_rom: Error getting board info\n",
netxen_nic_driver_name);
netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
NETXEN_ROMBUS_RESET); NETXEN_ROMBUS_RESET);
@ -860,10 +840,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
netxen_nic_pci_change_crbwindow(adapter, 1); netxen_nic_pci_change_crbwindow(adapter, 1);
} }
if (init_delay == 1) { if (init_delay == 1) {
msleep(2000); msleep(1000);
init_delay = 0; init_delay = 0;
} }
msleep(20); msleep(1);
} }
kfree(buf); kfree(buf);
@ -938,12 +918,28 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
void netxen_free_adapter_offload(struct netxen_adapter *adapter) void netxen_free_adapter_offload(struct netxen_adapter *adapter)
{ {
int i;
if (adapter->dummy_dma.addr) { if (adapter->dummy_dma.addr) {
pci_free_consistent(adapter->ahw.pdev, i = 100;
do {
if (dma_watchdog_shutdown_request(adapter) == 1)
break;
msleep(50);
if (dma_watchdog_shutdown_poll_result(adapter) == 1)
break;
} while (--i);
if (i) {
pci_free_consistent(adapter->ahw.pdev,
NETXEN_HOST_DUMMY_DMA_SIZE, NETXEN_HOST_DUMMY_DMA_SIZE,
adapter->dummy_dma.addr, adapter->dummy_dma.addr,
adapter->dummy_dma.phys_addr); adapter->dummy_dma.phys_addr);
adapter->dummy_dma.addr = NULL; adapter->dummy_dma.addr = NULL;
} else {
printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
adapter->netdev->name);
}
} }
} }

View File

@ -145,7 +145,7 @@ static void netxen_nic_isr_other(struct netxen_adapter *adapter)
/* verify the offset */ /* verify the offset */
val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
val = val >> physical_port[adapter->portnum]; val = val >> adapter->physical_port;
if (val == adapter->ahw.qg_linksup) if (val == adapter->ahw.qg_linksup)
return; return;
@ -199,7 +199,7 @@ void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter)
/* WINDOW = 1 */ /* WINDOW = 1 */
val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
val >>= (physical_port[adapter->portnum] * 8); val >>= (adapter->physical_port * 8);
val &= 0xff; val &= 0xff;
if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) { if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) {

View File

@ -70,17 +70,15 @@ static void netxen_nic_poll_controller(struct net_device *netdev);
static irqreturn_t netxen_intr(int irq, void *data); static irqreturn_t netxen_intr(int irq, void *data);
static irqreturn_t netxen_msi_intr(int irq, void *data); static irqreturn_t netxen_msi_intr(int irq, void *data);
int physical_port[] = {0, 1, 2, 3};
/* PCI Device ID Table */ /* PCI Device ID Table */
static struct pci_device_id netxen_pci_tbl[] __devinitdata = { static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
{PCI_DEVICE(0x4040, 0x0001)}, {PCI_DEVICE(0x4040, 0x0001), PCI_DEVICE_CLASS(0x020000, ~0)},
{PCI_DEVICE(0x4040, 0x0002)}, {PCI_DEVICE(0x4040, 0x0002), PCI_DEVICE_CLASS(0x020000, ~0)},
{PCI_DEVICE(0x4040, 0x0003)}, {PCI_DEVICE(0x4040, 0x0003), PCI_DEVICE_CLASS(0x020000, ~0)},
{PCI_DEVICE(0x4040, 0x0004)}, {PCI_DEVICE(0x4040, 0x0004), PCI_DEVICE_CLASS(0x020000, ~0)},
{PCI_DEVICE(0x4040, 0x0005)}, {PCI_DEVICE(0x4040, 0x0005), PCI_DEVICE_CLASS(0x020000, ~0)},
{PCI_DEVICE(0x4040, 0x0024)}, {PCI_DEVICE(0x4040, 0x0024), PCI_DEVICE_CLASS(0x020000, ~0)},
{PCI_DEVICE(0x4040, 0x0025)}, {PCI_DEVICE(0x4040, 0x0025), PCI_DEVICE_CLASS(0x020000, ~0)},
{0,} {0,}
}; };
@ -288,10 +286,11 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int pci_func_id = PCI_FUNC(pdev->devfn); int pci_func_id = PCI_FUNC(pdev->devfn);
DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac);
printk(KERN_INFO "%s \n", netxen_nic_driver_string); if (pci_func_id == 0)
printk(KERN_INFO "%s \n", netxen_nic_driver_string);
if (pdev->class != 0x020000) { if (pdev->class != 0x020000) {
printk(KERN_ERR"NetXen function %d, class %x will not " printk(KERN_DEBUG "NetXen function %d, class %x will not "
"be enabled.\n",pci_func_id, pdev->class); "be enabled.\n",pci_func_id, pdev->class);
return -ENODEV; return -ENODEV;
} }
@ -450,8 +449,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
*/ */
adapter->curr_window = 255; adapter->curr_window = 255;
/* initialize the adapter */ if (netxen_nic_get_board_info(adapter) != 0) {
netxen_initialize_adapter_hw(adapter); printk("%s: Error getting board config info.\n",
netxen_nic_driver_name);
err = -EIO;
goto err_out_iounmap;
}
/* /*
* Adapter in our case is quad port so initialize it before * Adapter in our case is quad port so initialize it before
@ -530,17 +533,15 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */
/* Mezz cards have PCI function 0,2,3 enabled */ /* Mezz cards have PCI function 0,2,3 enabled */
if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) switch (adapter->ahw.boardcfg.board_type) {
&& (pci_func_id >= 2)) case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
if (pci_func_id >= 2)
adapter->portnum = pci_func_id - 2; adapter->portnum = pci_func_id - 2;
break;
#ifdef CONFIG_IA64 default:
if(adapter->portnum == 0) { break;
netxen_pinit_from_rom(adapter, 0);
udelay(500);
netxen_load_firmware(adapter);
} }
#endif
init_timer(&adapter->watchdog_timer); init_timer(&adapter->watchdog_timer);
adapter->ahw.xg_linkup = 0; adapter->ahw.xg_linkup = 0;
@ -613,11 +614,18 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err = -ENODEV; err = -ENODEV;
goto err_out_free_dev; goto err_out_free_dev;
} }
} else {
writel(0, NETXEN_CRB_NORMALIZE(adapter,
CRB_CMDPEG_STATE));
netxen_pinit_from_rom(adapter, 0);
msleep(1);
netxen_load_firmware(adapter);
netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
} }
/* clear the register for future unloads/loads */ /* clear the register for future unloads/loads */
writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc)));
printk(KERN_INFO "State: 0x%0x\n", dev_info(&pdev->dev, "cmdpeg state: 0x%0x\n",
readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));
/* /*
@ -639,9 +647,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* /*
* See if the firmware gave us a virtual-physical port mapping. * See if the firmware gave us a virtual-physical port mapping.
*/ */
adapter->physical_port = adapter->portnum;
i = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_V2P(adapter->portnum))); i = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_V2P(adapter->portnum)));
if (i != 0x55555555) if (i != 0x55555555)
physical_port[adapter->portnum] = i; adapter->physical_port = i;
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_stop_queue(netdev); netif_stop_queue(netdev);
@ -654,22 +663,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_free_dev; goto err_out_free_dev;
} }
netxen_nic_flash_print(adapter);
pci_set_drvdata(pdev, adapter); pci_set_drvdata(pdev, adapter);
switch (adapter->ahw.board_type) {
case NETXEN_NIC_GBE:
printk(KERN_INFO "%s: QUAD GbE board initialized\n",
netxen_nic_driver_name);
break;
case NETXEN_NIC_XGBE:
printk(KERN_INFO "%s: XGbE board initialized\n",
netxen_nic_driver_name);
break;
}
adapter->driver_mismatch = 0;
return 0; return 0;
err_out_free_dev: err_out_free_dev:
@ -760,55 +756,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
vfree(adapter->cmd_buf_arr); vfree(adapter->cmd_buf_arr);
if (adapter->portnum == 0) { if (adapter->portnum == 0)
if (init_firmware_done) { netxen_free_adapter_offload(adapter);
i = 100;
do {
if (dma_watchdog_shutdown_request(adapter) == 1)
break;
msleep(100);
if (dma_watchdog_shutdown_poll_result(adapter) == 1)
break;
} while (--i);
if (i == 0)
printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
netdev->name);
/* clear the register for future unloads/loads */
writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc)));
printk(KERN_INFO "State: 0x%0x\n",
readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));
/* leave the hw in the same state as reboot */
writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
netxen_pinit_from_rom(adapter, 0);
msleep(1);
netxen_load_firmware(adapter);
netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
}
/* clear the register for future unloads/loads */
writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc)));
printk(KERN_INFO "State: 0x%0x\n",
readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));
i = 100;
do {
if (dma_watchdog_shutdown_request(adapter) == 1)
break;
msleep(100);
if (dma_watchdog_shutdown_poll_result(adapter) == 1)
break;
} while (--i);
if (i) {
netxen_free_adapter_offload(adapter);
} else {
printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
netdev->name);
}
}
if (adapter->irq) if (adapter->irq)
free_irq(adapter->irq, adapter); free_irq(adapter->irq, adapter);
@ -840,13 +789,15 @@ static int netxen_nic_open(struct net_device *netdev)
irq_handler_t handler; irq_handler_t handler;
unsigned long flags = IRQF_SAMPLE_RANDOM; unsigned long flags = IRQF_SAMPLE_RANDOM;
if (adapter->driver_mismatch)
return -EIO;
if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) { if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) {
err = netxen_init_firmware(adapter); err = netxen_init_firmware(adapter);
if (err != 0) { if (err != 0) {
printk(KERN_ERR "Failed to init firmware\n"); printk(KERN_ERR "Failed to init firmware\n");
return -EIO; return -EIO;
} }
netxen_nic_flash_print(adapter);
/* setup all the resources for the Phantom... */ /* setup all the resources for the Phantom... */
/* this include the descriptors for rcv, tx, and status */ /* this include the descriptors for rcv, tx, and status */
@ -895,14 +846,12 @@ static int netxen_nic_open(struct net_device *netdev)
if (adapter->set_mtu) if (adapter->set_mtu)
adapter->set_mtu(adapter, netdev->mtu); adapter->set_mtu(adapter, netdev->mtu);
if (!adapter->driver_mismatch) mod_timer(&adapter->watchdog_timer, jiffies);
mod_timer(&adapter->watchdog_timer, jiffies);
napi_enable(&adapter->napi); napi_enable(&adapter->napi);
netxen_nic_enable_int(adapter); netxen_nic_enable_int(adapter);
if (!adapter->driver_mismatch) netif_start_queue(netdev);
netif_start_queue(netdev);
return 0; return 0;
} }

View File

@ -94,7 +94,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
long timeout = 0; long timeout = 0;
long result = 0; long result = 0;
long restore = 0; long restore = 0;
long phy = physical_port[adapter->portnum]; long phy = adapter->physical_port;
__u32 address; __u32 address;
__u32 command; __u32 command;
__u32 status; __u32 status;
@ -190,7 +190,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
long timeout = 0; long timeout = 0;
long result = 0; long result = 0;
long restore = 0; long restore = 0;
long phy = physical_port[adapter->portnum]; long phy = adapter->physical_port;
__u32 address; __u32 address;
__u32 command; __u32 command;
__u32 status; __u32 status;
@ -456,7 +456,7 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
{ {
u32 portnum = physical_port[adapter->portnum]; u32 portnum = adapter->physical_port;
netxen_crb_writelit_adapter(adapter, netxen_crb_writelit_adapter(adapter,
NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), 0x1447); NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), 0x1447);
@ -573,7 +573,7 @@ static int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
{ {
u32 stationhigh; u32 stationhigh;
u32 stationlow; u32 stationlow;
int phy = physical_port[adapter->portnum]; int phy = adapter->physical_port;
u8 val[8]; u8 val[8];
if (addr == NULL) if (addr == NULL)
@ -604,7 +604,7 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
{ {
u8 temp[4]; u8 temp[4];
u32 val; u32 val;
int phy = physical_port[adapter->portnum]; int phy = adapter->physical_port;
unsigned char mac_addr[6]; unsigned char mac_addr[6];
int i; int i;
DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac);
@ -724,7 +724,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
{ {
__u32 mac_cfg0; __u32 mac_cfg0;
u32 port = physical_port[adapter->portnum]; u32 port = adapter->physical_port;
if (port > NETXEN_NIU_MAX_GBE_PORTS) if (port > NETXEN_NIU_MAX_GBE_PORTS)
return -EINVAL; return -EINVAL;
@ -740,7 +740,7 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
{ {
__u32 mac_cfg; __u32 mac_cfg;
u32 port = physical_port[adapter->portnum]; u32 port = adapter->physical_port;
if (port > NETXEN_NIU_MAX_XG_PORTS) if (port > NETXEN_NIU_MAX_XG_PORTS)
return -EINVAL; return -EINVAL;
@ -757,7 +757,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
netxen_niu_prom_mode_t mode) netxen_niu_prom_mode_t mode)
{ {
__u32 reg; __u32 reg;
u32 port = physical_port[adapter->portnum]; u32 port = adapter->physical_port;
if (port > NETXEN_NIU_MAX_GBE_PORTS) if (port > NETXEN_NIU_MAX_GBE_PORTS)
return -EINVAL; return -EINVAL;
@ -814,7 +814,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
netxen_ethernet_macaddr_t addr) netxen_ethernet_macaddr_t addr)
{ {
int phy = physical_port[adapter->portnum]; int phy = adapter->physical_port;
u8 temp[4]; u8 temp[4];
u32 val; u32 val;
@ -867,7 +867,7 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter,
netxen_ethernet_macaddr_t * addr) netxen_ethernet_macaddr_t * addr)
{ {
int phy = physical_port[adapter->portnum]; int phy = adapter->physical_port;
u32 stationhigh; u32 stationhigh;
u32 stationlow; u32 stationlow;
u8 val[8]; u8 val[8];
@ -896,7 +896,7 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
netxen_niu_prom_mode_t mode) netxen_niu_prom_mode_t mode)
{ {
__u32 reg; __u32 reg;
u32 port = physical_port[adapter->portnum]; u32 port = adapter->physical_port;
if (port > NETXEN_NIU_MAX_XG_PORTS) if (port > NETXEN_NIU_MAX_XG_PORTS)
return -EINVAL; return -EINVAL;

View File

@ -118,6 +118,7 @@ static DEFINE_PCI_DEVICE_TABLE(sky2_id_table) = {
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4355) }, /* 88E8040T */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4357) }, /* 88E8042 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4357) }, /* 88E8042 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */

View File

@ -313,6 +313,21 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
switch (tun->flags & TUN_TYPE_MASK) { switch (tun->flags & TUN_TYPE_MASK) {
case TUN_TUN_DEV: case TUN_TUN_DEV:
if (tun->flags & TUN_NO_PI) {
switch (skb->data[0] & 0xf0) {
case 0x40:
pi.proto = htons(ETH_P_IP);
break;
case 0x60:
pi.proto = htons(ETH_P_IPV6);
break;
default:
tun->dev->stats.rx_dropped++;
kfree_skb(skb);
return -EINVAL;
}
}
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
skb->protocol = pi.proto; skb->protocol = pi.proto;
skb->dev = tun->dev; skb->dev = tun->dev;

View File

@ -15,6 +15,7 @@ enum nf_ct_ext_id
/* Extensions: optional stuff which isn't permanently in struct. */ /* Extensions: optional stuff which isn't permanently in struct. */
struct nf_ct_ext { struct nf_ct_ext {
struct rcu_head rcu;
u8 offset[NF_CT_EXT_NUM]; u8 offset[NF_CT_EXT_NUM];
u8 len; u8 len;
char data[0]; char data[0];

View File

@ -556,7 +556,6 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
spin_lock_bh(&nf_nat_lock); spin_lock_bh(&nf_nat_lock);
hlist_del_rcu(&nat->bysource); hlist_del_rcu(&nat->bysource);
nat->ct = NULL;
spin_unlock_bh(&nf_nat_lock); spin_unlock_bh(&nf_nat_lock);
} }
@ -570,8 +569,8 @@ static void nf_nat_move_storage(void *new, void *old)
return; return;
spin_lock_bh(&nf_nat_lock); spin_lock_bh(&nf_nat_lock);
hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource);
new_nat->ct = ct; new_nat->ct = ct;
hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource);
spin_unlock_bh(&nf_nat_lock); spin_unlock_bh(&nf_nat_lock);
} }

View File

@ -52,7 +52,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
IP_ECN_clear(top_iph); IP_ECN_clear(top_iph);
top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
0 : XFRM_MODE_SKB_CB(skb)->frag_off; 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF));
ip_select_ident(top_iph, dst->child, NULL); ip_select_ident(top_iph, dst->child, NULL);
top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT); top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT);

View File

@ -1567,7 +1567,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
* make it big enough for everything we may ever need. * make it big enough for everything we may ever need.
*/ */
if (head_need > 0 || skb_header_cloned(skb)) { if (head_need > 0 || skb_cloned(skb)) {
head_need += IEEE80211_ENCRYPT_HEADROOM; head_need += IEEE80211_ENCRYPT_HEADROOM;
head_need += local->tx_headroom; head_need += local->tx_headroom;
head_need = max_t(int, 0, head_need); head_need = max_t(int, 0, head_need);

View File

@ -59,12 +59,19 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp)
if (!*ext) if (!*ext)
return NULL; return NULL;
INIT_RCU_HEAD(&(*ext)->rcu);
(*ext)->offset[id] = off; (*ext)->offset[id] = off;
(*ext)->len = len; (*ext)->len = len;
return (void *)(*ext) + off; return (void *)(*ext) + off;
} }
static void __nf_ct_ext_free_rcu(struct rcu_head *head)
{
struct nf_ct_ext *ext = container_of(head, struct nf_ct_ext, rcu);
kfree(ext);
}
void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
{ {
struct nf_ct_ext *new; struct nf_ct_ext *new;
@ -104,7 +111,7 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
(void *)ct->ext + ct->ext->offset[i]); (void *)ct->ext + ct->ext->offset[i]);
rcu_read_unlock(); rcu_read_unlock();
} }
kfree(ct->ext); call_rcu(&ct->ext->rcu, __nf_ct_ext_free_rcu);
ct->ext = new; ct->ext = new;
} }

View File

@ -619,6 +619,7 @@ static const struct nf_conntrack_expect_policy h245_exp_policy = {
static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = { static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = {
.name = "H.245", .name = "H.245",
.me = THIS_MODULE, .me = THIS_MODULE,
.tuple.src.l3num = AF_UNSPEC,
.tuple.dst.protonum = IPPROTO_UDP, .tuple.dst.protonum = IPPROTO_UDP,
.help = h245_help, .help = h245_help,
.expect_policy = &h245_exp_policy, .expect_policy = &h245_exp_policy,
@ -1765,6 +1766,7 @@ static void __exit nf_conntrack_h323_fini(void)
nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]); nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]);
nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]); nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]);
nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]); nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]);
nf_conntrack_helper_unregister(&nf_conntrack_helper_h245);
kfree(h323_buffer); kfree(h323_buffer);
pr_debug("nf_ct_h323: fini\n"); pr_debug("nf_ct_h323: fini\n");
} }
@ -1777,28 +1779,34 @@ static int __init nf_conntrack_h323_init(void)
h323_buffer = kmalloc(65536, GFP_KERNEL); h323_buffer = kmalloc(65536, GFP_KERNEL);
if (!h323_buffer) if (!h323_buffer)
return -ENOMEM; return -ENOMEM;
ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[0]); ret = nf_conntrack_helper_register(&nf_conntrack_helper_h245);
if (ret < 0) if (ret < 0)
goto err1; goto err1;
ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[1]); ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[0]);
if (ret < 0) if (ret < 0)
goto err2; goto err2;
ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[0]); ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[1]);
if (ret < 0) if (ret < 0)
goto err3; goto err3;
ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[1]); ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[0]);
if (ret < 0) if (ret < 0)
goto err4; goto err4;
ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[1]);
if (ret < 0)
goto err5;
pr_debug("nf_ct_h323: init success\n"); pr_debug("nf_ct_h323: init success\n");
return 0; return 0;
err4: err5:
nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]); nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]);
err3: err4:
nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]); nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]);
err2: err3:
nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]); nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]);
err2:
nf_conntrack_helper_unregister(&nf_conntrack_helper_h245);
err1: err1:
kfree(h323_buffer);
return ret; return ret;
} }

View File

@ -444,8 +444,11 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (ops->dumpit == NULL) if (ops->dumpit == NULL)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return netlink_dump_start(genl_sock, skb, nlh, genl_unlock();
ops->dumpit, ops->done); err = netlink_dump_start(genl_sock, skb, nlh,
ops->dumpit, ops->done);
genl_lock();
return err;
} }
if (ops->doit == NULL) if (ops->doit == NULL)
@ -603,9 +606,6 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
int chains_to_skip = cb->args[0]; int chains_to_skip = cb->args[0];
int fams_to_skip = cb->args[1]; int fams_to_skip = cb->args[1];
if (chains_to_skip != 0)
genl_lock();
for (i = 0; i < GENL_FAM_TAB_SIZE; i++) { for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
if (i < chains_to_skip) if (i < chains_to_skip)
continue; continue;
@ -623,9 +623,6 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
} }
errout: errout:
if (chains_to_skip != 0)
genl_unlock();
cb->args[0] = i; cb->args[0] = i;
cb->args[1] = n; cb->args[1] = n;
@ -770,7 +767,7 @@ static int __init genl_init(void)
/* we'll bump the group number right afterwards */ /* we'll bump the group number right afterwards */
genl_sock = netlink_kernel_create(&init_net, NETLINK_GENERIC, 0, genl_sock = netlink_kernel_create(&init_net, NETLINK_GENERIC, 0,
genl_rcv, NULL, THIS_MODULE); genl_rcv, &genl_mutex, THIS_MODULE);
if (genl_sock == NULL) if (genl_sock == NULL)
panic("GENL: Cannot initialize generic netlink\n"); panic("GENL: Cannot initialize generic netlink\n");

View File

@ -167,6 +167,11 @@ static inline int unix_may_send(struct sock *sk, struct sock *osk)
return (unix_peer(osk) == NULL || unix_our_peer(sk, osk)); return (unix_peer(osk) == NULL || unix_our_peer(sk, osk));
} }
static inline int unix_recvq_full(struct sock const *sk)
{
return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
}
static struct sock *unix_peer_get(struct sock *s) static struct sock *unix_peer_get(struct sock *s)
{ {
struct sock *peer; struct sock *peer;
@ -480,6 +485,8 @@ static int unix_socketpair(struct socket *, struct socket *);
static int unix_accept(struct socket *, struct socket *, int); static int unix_accept(struct socket *, struct socket *, int);
static int unix_getname(struct socket *, struct sockaddr *, int *, int); static int unix_getname(struct socket *, struct sockaddr *, int *, int);
static unsigned int unix_poll(struct file *, struct socket *, poll_table *); static unsigned int unix_poll(struct file *, struct socket *, poll_table *);
static unsigned int unix_datagram_poll(struct file *, struct socket *,
poll_table *);
static int unix_ioctl(struct socket *, unsigned int, unsigned long); static int unix_ioctl(struct socket *, unsigned int, unsigned long);
static int unix_shutdown(struct socket *, int); static int unix_shutdown(struct socket *, int);
static int unix_stream_sendmsg(struct kiocb *, struct socket *, static int unix_stream_sendmsg(struct kiocb *, struct socket *,
@ -525,7 +532,7 @@ static const struct proto_ops unix_dgram_ops = {
.socketpair = unix_socketpair, .socketpair = unix_socketpair,
.accept = sock_no_accept, .accept = sock_no_accept,
.getname = unix_getname, .getname = unix_getname,
.poll = datagram_poll, .poll = unix_datagram_poll,
.ioctl = unix_ioctl, .ioctl = unix_ioctl,
.listen = sock_no_listen, .listen = sock_no_listen,
.shutdown = unix_shutdown, .shutdown = unix_shutdown,
@ -546,7 +553,7 @@ static const struct proto_ops unix_seqpacket_ops = {
.socketpair = unix_socketpair, .socketpair = unix_socketpair,
.accept = unix_accept, .accept = unix_accept,
.getname = unix_getname, .getname = unix_getname,
.poll = datagram_poll, .poll = unix_datagram_poll,
.ioctl = unix_ioctl, .ioctl = unix_ioctl,
.listen = unix_listen, .listen = unix_listen,
.shutdown = unix_shutdown, .shutdown = unix_shutdown,
@ -981,8 +988,7 @@ static long unix_wait_for_peer(struct sock *other, long timeo)
sched = !sock_flag(other, SOCK_DEAD) && sched = !sock_flag(other, SOCK_DEAD) &&
!(other->sk_shutdown & RCV_SHUTDOWN) && !(other->sk_shutdown & RCV_SHUTDOWN) &&
(skb_queue_len(&other->sk_receive_queue) > unix_recvq_full(other);
other->sk_max_ack_backlog);
unix_state_unlock(other); unix_state_unlock(other);
@ -1056,8 +1062,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
if (other->sk_state != TCP_LISTEN) if (other->sk_state != TCP_LISTEN)
goto out_unlock; goto out_unlock;
if (skb_queue_len(&other->sk_receive_queue) > if (unix_recvq_full(other)) {
other->sk_max_ack_backlog) {
err = -EAGAIN; err = -EAGAIN;
if (!timeo) if (!timeo)
goto out_unlock; goto out_unlock;
@ -1426,9 +1431,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
goto out_unlock; goto out_unlock;
} }
if (unix_peer(other) != sk && if (unix_peer(other) != sk && unix_recvq_full(other)) {
(skb_queue_len(&other->sk_receive_queue) >
other->sk_max_ack_backlog)) {
if (!timeo) { if (!timeo) {
err = -EAGAIN; err = -EAGAIN;
goto out_unlock; goto out_unlock;
@ -1989,6 +1992,64 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl
return mask; return mask;
} }
static unsigned int unix_datagram_poll(struct file *file, struct socket *sock,
poll_table *wait)
{
struct sock *sk = sock->sk, *peer;
unsigned int mask;
poll_wait(file, sk->sk_sleep, wait);
peer = unix_peer_get(sk);
if (peer) {
if (peer != sk) {
/*
* Writability of a connected socket additionally
* depends on the state of the receive queue of the
* peer.
*/
poll_wait(file, &unix_sk(peer)->peer_wait, wait);
} else {
sock_put(peer);
peer = NULL;
}
}
mask = 0;
/* exceptional events? */
if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
mask |= POLLERR;
if (sk->sk_shutdown & RCV_SHUTDOWN)
mask |= POLLRDHUP;
if (sk->sk_shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
/* readable? */
if (!skb_queue_empty(&sk->sk_receive_queue) ||
(sk->sk_shutdown & RCV_SHUTDOWN))
mask |= POLLIN | POLLRDNORM;
/* Connection-based need to check for termination and startup */
if (sk->sk_type == SOCK_SEQPACKET) {
if (sk->sk_state == TCP_CLOSE)
mask |= POLLHUP;
/* connection hasn't started yet? */
if (sk->sk_state == TCP_SYN_SENT)
return mask;
}
/* writable? */
if (unix_writable(sk) && !(peer && unix_recvq_full(peer)))
mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
else
set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
if (peer)
sock_put(peer);
return mask;
}
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
static struct sock *first_unix_socket(int *i) static struct sock *first_unix_socket(int *i)