diff options
231 files changed, 5744 insertions, 3956 deletions
diff --git a/Documentation/filesystems/nilfs2.txt b/Documentation/filesystems/nilfs2.txt index d5c0cef38a71..873a2ab2e9f8 100644 --- a/Documentation/filesystems/nilfs2.txt +++ b/Documentation/filesystems/nilfs2.txt @@ -40,7 +40,6 @@ Features which NILFS2 does not support yet: - POSIX ACLs - quotas - fsck - - resize - defragmentation Mount options diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt index 80a7a3454902..57a24108b845 100644 --- a/Documentation/networking/stmmac.txt +++ b/Documentation/networking/stmmac.txt @@ -7,7 +7,7 @@ This is the driver for the MAC 10/100/1000 on-chip Ethernet controllers (Synopsys IP blocks); it has been fully tested on STLinux platforms. Currently this network device driver is for all STM embedded MAC/GMAC -(7xxx SoCs). Other platforms start using it i.e. ARM SPEAr. +(i.e. 7xxx/5xxx SoCs) and it's known working on other platforms i.e. ARM SPEAr. DWC Ether MAC 10/100/1000 Universal version 3.41a and DWC Ether MAC 10/100 Universal version 4.0 have been used for developing the first code @@ -71,7 +71,7 @@ Several performance tests on STM platforms showed this optimisation allows to sp the CPU while having the maximum throughput. 4.4) WOL -Wake up on Lan feature through Magic Frame is only supported for the GMAC +Wake up on Lan feature through Magic and Unicast frames are supported for the GMAC core. 4.5) DMA descriptors @@ -91,11 +91,15 @@ LRO is not supported. The driver is compatible with PAL to work with PHY and GPHY devices. 4.9) Platform information -Several information came from the platform; please refer to the -driver's Header file in include/linux directory. +Several driver's information can be passed through the platform +These are included in the include/linux/stmmac.h header file +and detailed below as well: -struct plat_stmmacenet_data { + struct plat_stmmacenet_data { int bus_id; + int phy_addr; + int interface; + struct stmmac_mdio_bus_data *mdio_bus_data; int pbl; int clk_csr; int has_gmac; @@ -103,67 +107,135 @@ struct plat_stmmacenet_data { int tx_coe; int bugged_jumbo; int pmt; - void (*fix_mac_speed)(void *priv, unsigned int speed); - void (*bus_setup)(unsigned long ioaddr); -#ifdef CONFIG_STM_DRIVERS - struct stm_pad_config *pad_config; -#endif - void *bsp_priv; -}; + int force_sf_dma_mode; + void (*fix_mac_speed)(void *priv, unsigned int speed); + void (*bus_setup)(void __iomem *ioaddr); + int (*init)(struct platform_device *pdev); + void (*exit)(struct platform_device *pdev); + void *bsp_priv; + }; Where: -- pbl (Programmable Burst Length) is maximum number of - beats to be transferred in one DMA transaction. - GMAC also enables the 4xPBL by default. -- fix_mac_speed and bus_setup are used to configure internal target - registers (on STM platforms); -- has_gmac: GMAC core is on board (get it at run-time in the next step); -- bus_id: bus identifier. -- tx_coe: core is able to perform the tx csum in HW. -- enh_desc: if sets the MAC will use the enhanced descriptor structure. -- clk_csr: CSR Clock range selection. -- bugged_jumbo: some HWs are not able to perform the csum in HW for - over-sized frames due to limited buffer sizes. Setting this - flag the csum will be done in SW on JUMBO frames. - -struct plat_stmmacphy_data { - int bus_id; - int phy_addr; - unsigned int phy_mask; - int interface; - int (*phy_reset)(void *priv); - void *priv; -}; + o bus_id: bus identifier. + o phy_addr: the physical address can be passed from the platform. + If it is set to -1 the driver will automatically + detect it at run-time by probing all the 32 addresses. + o interface: PHY device's interface. + o mdio_bus_data: specific platform fields for the MDIO bus. + o pbl: the Programmable Burst Length is maximum number of beats to + be transferred in one DMA transaction. + GMAC also enables the 4xPBL by default. + o clk_csr: CSR Clock range selection. + o has_gmac: uses the GMAC core. + o enh_desc: if sets the MAC will use the enhanced descriptor structure. + o tx_coe: core is able to perform the tx csum in HW. + o bugged_jumbo: some HWs are not able to perform the csum in HW for + over-sized frames due to limited buffer sizes. + Setting this flag the csum will be done in SW on + JUMBO frames. + o pmt: core has the embedded power module (optional). + o force_sf_dma_mode: force DMA to use the Store and Forward mode + instead of the Threshold. + o fix_mac_speed: this callback is used for modifying some syscfg registers + (on ST SoCs) according to the link speed negotiated by the + physical layer . + o bus_setup: perform HW setup of the bus. For example, on some ST platforms + this field is used to configure the AMBA bridge to generate more + efficient STBus traffic. + o init/exit: callbacks used for calling a custom initialisation; + this is sometime necessary on some platforms (e.g. ST boxes) + where the HW needs to have set some PIO lines or system cfg + registers. + o custom_cfg: this is a custom configuration that can be passed while + initialising the resources. + +The we have: + + struct stmmac_mdio_bus_data { + int bus_id; + int (*phy_reset)(void *priv); + unsigned int phy_mask; + int *irqs; + int probed_phy_irq; + }; Where: -- bus_id: bus identifier; -- phy_addr: physical address used for the attached phy device; - set it to -1 to get it at run-time; -- interface: physical MII interface mode; -- phy_reset: hook to reset HW function. - -SOURCES: -- Kconfig -- Makefile -- stmmac_main.c: main network device driver; -- stmmac_mdio.c: mdio functions; -- stmmac_ethtool.c: ethtool support; -- stmmac_timer.[ch]: timer code used for mitigating the driver dma interrupts - Only tested on ST40 platforms based. -- stmmac.h: private driver structure; -- common.h: common definitions and VFTs; -- descs.h: descriptor structure definitions; -- dwmac1000_core.c: GMAC core functions; -- dwmac1000_dma.c: dma functions for the GMAC chip; -- dwmac1000.h: specific header file for the GMAC; -- dwmac100_core: MAC 100 core and dma code; -- dwmac100_dma.c: dma funtions for the MAC chip; -- dwmac1000.h: specific header file for the MAC; -- dwmac_lib.c: generic DMA functions shared among chips -- enh_desc.c: functions for handling enhanced descriptors -- norm_desc.c: functions for handling normal descriptors - -TODO: -- XGMAC controller is not supported. -- Review the timer optimisation code to use an embedded device that seems to be + o bus_id: bus identifier; + o phy_reset: hook to reset the phy device attached to the bus. + o phy_mask: phy mask passed when register the MDIO bus within the driver. + o irqs: list of IRQs, one per PHY. + o probed_phy_irq: if irqs is NULL, use this for probed PHY. + +Below an example how the structures above are using on ST platforms. + + static struct plat_stmmacenet_data stxYYY_ethernet_platform_data = { + .pbl = 32, + .has_gmac = 0, + .enh_desc = 0, + .fix_mac_speed = stxYYY_ethernet_fix_mac_speed, + | + |-> to write an internal syscfg + | on this platform when the + | link speed changes from 10 to + | 100 and viceversa + .init = &stmmac_claim_resource, + | + |-> On ST SoC this calls own "PAD" + | manager framework to claim + | all the resources necessary + | (GPIO ...). The .custom_cfg field + | is used to pass a custom config. +}; + +Below the usage of the stmmac_mdio_bus_data: on this SoC, in fact, +there are two MAC cores: one MAC is for MDIO Bus/PHY emulation +with fixed_link support. + +static struct stmmac_mdio_bus_data stmmac1_mdio_bus = { + .bus_id = 1, + | + |-> phy device on the bus_id 1 + .phy_reset = phy_reset; + | + |-> function to provide the phy_reset on this board + .phy_mask = 0, +}; + +static struct fixed_phy_status stmmac0_fixed_phy_status = { + .link = 1, + .speed = 100, + .duplex = 1, +}; + +During the board's device_init we can configure the first +MAC for fixed_link by calling: + fixed_phy_add(PHY_POLL, 1, &stmmac0_fixed_phy_status));) +and the second one, with a real PHY device attached to the bus, +by using the stmmac_mdio_bus_data structure (to provide the id, the +reset procedure etc). + +4.10) List of source files: + o Kconfig + o Makefile + o stmmac_main.c: main network device driver; + o stmmac_mdio.c: mdio functions; + o stmmac_ethtool.c: ethtool support; + o stmmac_timer.[ch]: timer code used for mitigating the driver dma interrupts + Only tested on ST40 platforms based. + o stmmac.h: private driver structure; + o common.h: common definitions and VFTs; + o descs.h: descriptor structure definitions; + o dwmac1000_core.c: GMAC core functions; + o dwmac1000_dma.c: dma functions for the GMAC chip; + o dwmac1000.h: specific header file for the GMAC; + o dwmac100_core: MAC 100 core and dma code; + o dwmac100_dma.c: dma funtions for the MAC chip; + o dwmac1000.h: specific header file for the MAC; + o dwmac_lib.c: generic DMA functions shared among chips + o enh_desc.c: functions for handling enhanced descriptors + o norm_desc.c: functions for handling normal descriptors + +5) TODO: + o XGMAC is not supported. + o Review the timer optimisation code to use an embedded device that will be available in new chip generations. diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index c67f684ee3e5..09a87e61ffcf 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -520,7 +520,7 @@ fail: */ if (have_imager()) { label = "HD imager"; - mux |= 1; + mux |= 2; /* externally mux MMC1/ENET/AIC33 to imager */ mux |= BIT(6) | BIT(5) | BIT(3); @@ -540,7 +540,7 @@ fail: resets &= ~BIT(1); if (have_tvp7002()) { - mux |= 2; + mux |= 1; resets &= ~BIT(2); label = "tvp7002 HD"; } else { diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index e7221398e5af..cafbe13a82a5 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c @@ -254,8 +254,10 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) { struct davinci_gpio_regs __iomem *g; u32 mask = 0xffff; + struct davinci_gpio_controller *d; - g = (__force struct davinci_gpio_regs __iomem *) irq_desc_get_handler_data(desc); + d = (struct davinci_gpio_controller *)irq_desc_get_handler_data(desc); + g = (struct davinci_gpio_regs __iomem *)d->regs; /* we only care about one bank */ if (irq & 1) @@ -274,11 +276,14 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) if (!status) break; __raw_writel(status, &g->intstat); - if (irq & 1) - status >>= 16; /* now demux them to the right lowlevel handler */ - n = (int)irq_get_handler_data(irq); + n = d->irq_base; + if (irq & 1) { + n += 16; + status >>= 16; + } + while (status) { res = ffs(status); n += res; @@ -424,7 +429,13 @@ static int __init davinci_gpio_irq_setup(void) /* set up all irqs in this bank */ irq_set_chained_handler(bank_irq, gpio_irq_handler); - irq_set_handler_data(bank_irq, (__force void *)g); + + /* + * Each chip handles 32 gpios, and each irq bank consists of 16 + * gpio irqs. Pass the irq bank's corresponding controller to + * the chained irq handler. + */ + irq_set_handler_data(bank_irq, &chips[gpio / 32]); for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) { irq_set_chip(irq, &gpio_irqchip); diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c index d8c1af025931..952dc126c390 100644 --- a/arch/arm/mach-davinci/irq.c +++ b/arch/arm/mach-davinci/irq.c @@ -52,6 +52,12 @@ davinci_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) struct irq_chip_type *ct; gc = irq_alloc_generic_chip("AINTC", 1, irq_start, base, handle_edge_irq); + if (!gc) { + pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n", + __func__, irq_start); + return; + } + ct = gc->chip_types; ct->chip.irq_ack = irq_gc_ack_set_bit; ct->chip.irq_mask = irq_gc_mask_clr_bit; diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 74ed81a3cb1a..07772575d7ab 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -419,14 +419,20 @@ static void notrace ixp4xx_update_sched_clock(void) /* * clocksource */ + +static cycle_t ixp4xx_clocksource_read(struct clocksource *c) +{ + return *IXP4XX_OSTS; +} + unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ; EXPORT_SYMBOL(ixp4xx_timer_freq); static void __init ixp4xx_clocksource_init(void) { init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq); - clocksource_mmio_init(&IXP4XX_OSTS, "OSTS", ixp4xx_timer_freq, 200, 32, - clocksource_mmio_readl_up); + clocksource_mmio_init(NULL, "OSTS", ixp4xx_timer_freq, 200, 32, + ixp4xx_clocksource_read); } /* diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index b197171e7d03..204bfafe4bfc 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -113,7 +113,7 @@ found: return chan; } -int s3c2410_dma_config(unsigned int channel, int xferunit) +int s3c2410_dma_config(enum dma_ch channel, int xferunit) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); @@ -297,7 +297,7 @@ static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan) return 0; } -int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op) +int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); @@ -331,7 +331,7 @@ EXPORT_SYMBOL(s3c2410_dma_ctrl); * */ -int s3c2410_dma_enqueue(unsigned int channel, void *id, +int s3c2410_dma_enqueue(enum dma_ch channel, void *id, dma_addr_t data, int size) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); @@ -415,7 +415,7 @@ err_buff: EXPORT_SYMBOL(s3c2410_dma_enqueue); -int s3c2410_dma_devconfig(unsigned int channel, +int s3c2410_dma_devconfig(enum dma_ch channel, enum s3c2410_dmasrc source, unsigned long devaddr) { @@ -463,7 +463,7 @@ int s3c2410_dma_devconfig(unsigned int channel, EXPORT_SYMBOL(s3c2410_dma_devconfig); -int s3c2410_dma_getposition(unsigned int channel, +int s3c2410_dma_getposition(enum dma_ch channel, dma_addr_t *src, dma_addr_t *dst) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); @@ -487,7 +487,7 @@ EXPORT_SYMBOL(s3c2410_dma_getposition); * get control of an dma channel */ -int s3c2410_dma_request(unsigned int channel, +int s3c2410_dma_request(enum dma_ch channel, struct s3c2410_dma_client *client, void *dev) { @@ -533,7 +533,7 @@ EXPORT_SYMBOL(s3c2410_dma_request); * allowed to go through. */ -int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) +int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *client) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); unsigned long flags; diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index a79a8ccd25f6..539bd0e3defd 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -712,7 +712,7 @@ static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel); * get control of an dma channel */ -int s3c2410_dma_request(unsigned int channel, +int s3c2410_dma_request(enum dma_ch channel, struct s3c2410_dma_client *client, void *dev) { @@ -783,7 +783,7 @@ EXPORT_SYMBOL(s3c2410_dma_request); * allowed to go through. */ -int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) +int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *client) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); unsigned long flags; @@ -974,7 +974,7 @@ static int s3c2410_dma_started(struct s3c2410_dma_chan *chan) } int -s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op) +s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); @@ -1021,7 +1021,7 @@ EXPORT_SYMBOL(s3c2410_dma_ctrl); * xfersize: size of unit in bytes (1,2,4) */ -int s3c2410_dma_config(unsigned int channel, +int s3c2410_dma_config(enum dma_ch channel, int xferunit) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); @@ -1100,7 +1100,7 @@ EXPORT_SYMBOL(s3c2410_dma_config); * devaddr: physical address of the source */ -int s3c2410_dma_devconfig(unsigned int channel, +int s3c2410_dma_devconfig(enum dma_ch channel, enum s3c2410_dmasrc source, unsigned long devaddr) { @@ -1173,7 +1173,7 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig); * returns the current transfer points for the dma source and destination */ -int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *dst) +int s3c2410_dma_getposition(enum dma_ch channel, dma_addr_t *src, dma_addr_t *dst) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); diff --git a/arch/arm/plat-samsung/dma.c b/arch/arm/plat-samsung/dma.c index cb459dd95459..6143aa147688 100644 --- a/arch/arm/plat-samsung/dma.c +++ b/arch/arm/plat-samsung/dma.c @@ -41,7 +41,7 @@ struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel) * irq? */ -int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn) +int s3c2410_dma_set_opfn(enum dma_ch channel, s3c2410_dma_opfn_t rtn) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); @@ -56,7 +56,7 @@ int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn) } EXPORT_SYMBOL(s3c2410_dma_set_opfn); -int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn) +int s3c2410_dma_set_buffdone_fn(enum dma_ch channel, s3c2410_dma_cbfn_t rtn) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); @@ -71,7 +71,7 @@ int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn) } EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn); -int s3c2410_dma_setflags(unsigned int channel, unsigned int flags) +int s3c2410_dma_setflags(enum dma_ch channel, unsigned int flags) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h index 2e8f8c6560d7..8c273b7a6f56 100644 --- a/arch/arm/plat-samsung/include/plat/dma.h +++ b/arch/arm/plat-samsung/include/plat/dma.h @@ -42,6 +42,7 @@ struct s3c2410_dma_client { }; struct s3c2410_dma_chan; +enum dma_ch; /* s3c2410_dma_cbfn_t * @@ -62,7 +63,7 @@ typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *, * request a dma channel exclusivley */ -extern int s3c2410_dma_request(unsigned int channel, +extern int s3c2410_dma_request(enum dma_ch channel, struct s3c2410_dma_client *, void *dev); @@ -71,14 +72,14 @@ extern int s3c2410_dma_request(unsigned int channel, * change the state of the dma channel */ -extern int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op); +extern int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op); /* s3c2410_dma_setflags * * set the channel's flags to a given state */ -extern int s3c2410_dma_setflags(unsigned int channel, +extern int s3c2410_dma_setflags(enum dma_ch channel, unsigned int flags); /* s3c2410_dma_free @@ -86,7 +87,7 @@ extern int s3c2410_dma_setflags(unsigned int channel, * free the dma channel (will also abort any outstanding operations) */ -extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *); +extern int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *); /* s3c2410_dma_enqueue * @@ -95,7 +96,7 @@ extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *); * drained before the buffer is given to the DMA system. */ -extern int s3c2410_dma_enqueue(unsigned int channel, void *id, +extern int s3c2410_dma_enqueue(enum dma_ch channel, void *id, dma_addr_t data, int size); /* s3c2410_dma_config @@ -103,14 +104,14 @@ extern int s3c2410_dma_enqueue(unsigned int channel, void *id, * configure the dma channel */ -extern int s3c2410_dma_config(unsigned int channel, int xferunit); +extern int s3c2410_dma_config(enum dma_ch channel, int xferunit); /* s3c2410_dma_devconfig * * configure the device we're talking to */ -extern int s3c2410_dma_devconfig(unsigned int channel, +extern int s3c2410_dma_devconfig(enum dma_ch channel, enum s3c2410_dmasrc source, unsigned long devaddr); /* s3c2410_dma_getposition @@ -118,10 +119,10 @@ extern int s3c2410_dma_devconfig(unsigned int channel, * get the position that the dma transfer is currently at */ -extern int s3c2410_dma_getposition(unsigned int channel, +extern int s3c2410_dma_getposition(enum dma_ch channel, dma_addr_t *src, dma_addr_t *dest); -extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn); -extern int s3c2410_dma_set_buffdone_fn(unsigned int, s3c2410_dma_cbfn_t rtn); +extern int s3c2410_dma_set_opfn(enum dma_ch, s3c2410_dma_opfn_t rtn); +extern int s3c2410_dma_set_buffdone_fn(enum dma_ch, s3c2410_dma_cbfn_t rtn); diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c index 0e46588d847b..657405c481d0 100644 --- a/arch/arm/plat-samsung/irq-uart.c +++ b/arch/arm/plat-samsung/irq-uart.c @@ -54,6 +54,13 @@ static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) gc = irq_alloc_generic_chip("s3c-uart", 1, uirq->base_irq, reg_base, handle_level_irq); + + if (!gc) { + pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n", + __func__, uirq->base_irq); + return; + } + ct = gc->chip_types; ct->chip.irq_ack = irq_gc_ack_set_bit; ct->chip.irq_mask = irq_gc_mask_set_bit; diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c index a607546ddbd0..f714d060370d 100644 --- a/arch/arm/plat-samsung/irq-vic-timer.c +++ b/arch/arm/plat-samsung/irq-vic-timer.c @@ -54,6 +54,13 @@ void __init s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq) s3c_tgc = irq_alloc_generic_chip("s3c-timer", 1, timer_irq, S3C64XX_TINT_CSTAT, handle_level_irq); + + if (!s3c_tgc) { + pr_err("%s: irq_alloc_generic_chip for IRQ %d failed\n", + __func__, timer_irq); + return; + } + ct = s3c_tgc->chip_types; ct->chip.irq_mask = irq_gc_mask_clr_bit; ct->chip.irq_unmask = irq_gc_mask_set_bit; diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index c018696765d4..5c74eb797f08 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -14,7 +14,7 @@ #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/spinlock.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/irq.h> #include <asm/i8259.h> @@ -215,14 +215,13 @@ spurious_8259A_irq: } } -static int i8259A_resume(struct sys_device *dev) +static void i8259A_resume(void) { if (i8259A_auto_eoi >= 0) init_8259A(i8259A_auto_eoi); - return 0; } -static int i8259A_shutdown(struct sys_device *dev) +static void i8259A_shutdown(void) { /* Put the i8259A into a quiescent state that * the kernel initialization code can get it @@ -232,26 +231,17 @@ static int i8259A_shutdown(struct sys_device *dev) outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ } - return 0; } -static struct sysdev_class i8259_sysdev_class = { - .name = "i8259", +static struct syscore_ops i8259_syscore_ops = { .resume = i8259A_resume, .shutdown = i8259A_shutdown, }; -static struct sys_device device_i8259A = { - .id = 0, - .cls = &i8259_sysdev_class, -}; - static int __init i8259A_init_sysfs(void) { - int error = sysdev_class_register(&i8259_sysdev_class); - if (!error) - error = sysdev_register(&device_i8259A); - return error; + register_syscore_ops(&i8259_syscore_ops); + return 0; } device_initcall(i8259A_init_sysfs); diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2729c6663d8a..cdf7a0a64406 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -134,6 +134,7 @@ config PPC select GENERIC_IRQ_SHOW_LEVEL select HAVE_RCU_TABLE_FREE if SMP select HAVE_SYSCALL_TRACEPOINTS + select HAVE_BPF_JIT if (PPC64 && NET) config EARLY_PRINTK bool diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index b7212b619c52..b94740f36b1a 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -154,7 +154,8 @@ core-y += arch/powerpc/kernel/ \ arch/powerpc/lib/ \ arch/powerpc/sysdev/ \ arch/powerpc/platforms/ \ - arch/powerpc/math-emu/ + arch/powerpc/math-emu/ \ + arch/powerpc/net/ core-$(CONFIG_XMON) += arch/powerpc/xmon/ core-$(CONFIG_KVM) += arch/powerpc/kvm/ diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index e472659d906c..e980faae4225 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -71,6 +71,42 @@ #define PPC_INST_ERATSX 0x7c000126 #define PPC_INST_ERATSX_DOT 0x7c000127 +/* Misc instructions for BPF compiler */ +#define PPC_INST_LD 0xe8000000 +#define PPC_INST_LHZ 0xa0000000 +#define PPC_INST_LWZ 0x80000000 +#define PPC_INST_STD 0xf8000000 +#define PPC_INST_STDU 0xf8000001 +#define PPC_INST_MFLR 0x7c0802a6 +#define PPC_INST_MTLR 0x7c0803a6 +#define PPC_INST_CMPWI 0x2c000000 +#define PPC_INST_CMPDI 0x2c200000 +#define PPC_INST_CMPLW 0x7c000040 +#define PPC_INST_CMPLWI 0x28000000 +#define PPC_INST_ADDI 0x38000000 +#define PPC_INST_ADDIS 0x3c000000 +#define PPC_INST_ADD 0x7c000214 +#define PPC_INST_SUB 0x7c000050 +#define PPC_INST_BLR 0x4e800020 +#define PPC_INST_BLRL 0x4e800021 +#define PPC_INST_MULLW 0x7c0001d6 +#define PPC_INST_MULHWU 0x7c000016 +#define PPC_INST_MULLI 0x1c000000 +#define PPC_INST_DIVWU 0x7c0003d6 +#define PPC_INST_RLWINM 0x54000000 +#define PPC_INST_RLDICR 0x78000004 +#define PPC_INST_SLW 0x7c000030 +#define PPC_INST_SRW 0x7c000430 +#define PPC_INST_AND 0x7c000038 +#define PPC_INST_ANDDOT 0x7c000039 +#define PPC_INST_OR 0x7c000378 +#define PPC_INST_ANDI 0x70000000 +#define PPC_INST_ORI 0x60000000 +#define PPC_INST_ORIS 0x64000000 +#define PPC_INST_NEG 0x7c0000d0 +#define PPC_INST_BRANCH 0x48000000 +#define PPC_INST_BRANCH_COND 0x40800000 + /* macros to insert fields into opcodes */ #define __PPC_RA(a) (((a) & 0x1f) << 16) #define __PPC_RB(b) (((b) & 0x1f) << 11) @@ -83,6 +119,10 @@ #define __PPC_T_TLB(t) (((t) & 0x3) << 21) #define __PPC_WC(w) (((w) & 0x3) << 21) #define __PPC_WS(w) (((w) & 0x1f) << 11) +#define __PPC_SH(s) __PPC_WS(s) +#define __PPC_MB(s) (((s) & 0x1f) << 6) +#define __PPC_ME(s) (((s) & 0x1f) << 1) +#define __PPC_BI(s) (((s) & 0x1f) << 16) /* * Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a diff --git a/arch/powerpc/net/Makefile b/arch/powerpc/net/Makefile new file mode 100644 index 000000000000..266b3950c3ac --- /dev/null +++ b/arch/powerpc/net/Makefile @@ -0,0 +1,4 @@ +# +# Arch-specific network modules +# +obj-$(CONFIG_BPF_JIT) += bpf_jit_64.o bpf_jit_comp.o diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h new file mode 100644 index 000000000000..af1ab5e9a691 --- /dev/null +++ b/arch/powerpc/net/bpf_jit.h @@ -0,0 +1,227 @@ +/* bpf_jit.h: BPF JIT compiler for PPC64 + * + * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ +#ifndef _BPF_JIT_H +#define _BPF_JIT_H + +#define BPF_PPC_STACK_LOCALS 32 +#define BPF_PPC_STACK_BASIC (48+64) +#define BPF_PPC_STACK_SAVE (18*8) +#define BPF_PPC_STACKFRAME (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \ + BPF_PPC_STACK_SAVE) +#define BPF_PPC_SLOWPATH_FRAME (48+64) + +/* + * Generated code register usage: + * + * As normal PPC C ABI (e.g. r1=sp, r2=TOC), with: + * + * skb r3 (Entry parameter) + * A register r4 + * X register r5 + * addr param r6 + * r7-r10 scratch + * skb->data r14 + * skb headlen r15 (skb->len - skb->data_len) + * m[0] r16 + * m[...] ... + * m[15] r31 + */ +#define r_skb 3 +#define r_ret 3 +#define r_A 4 +#define r_X 5 +#define r_addr 6 +#define r_scratch1 7 +#define r_D 14 +#define r_HL 15 +#define r_M 16 + +#ifndef __ASSEMBLY__ + +/* + * Assembly helpers from arch/powerpc/net/bpf_jit.S: + */ +extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[]; + +#define FUNCTION_DESCR_SIZE 24 + +/* + * 16-bit immediate helper macros: HA() is for use with sign-extending instrs + * (e.g. LD, ADDI). If the bottom 16 bits is "-ve", add another bit into the + * top half to negate the effect (i.e. 0xffff + 1 = 0x(1)0000). + */ +#define IMM_H(i) ((uintptr_t)(i)>>16) +#define IMM_HA(i) (((uintptr_t)(i)>>16) + \ + (((uintptr_t)(i) & 0x8000) >> 15)) +#define IMM_L(i) ((uintptr_t)(i) & 0xffff) + +#define PLANT_INSTR(d, idx, instr) \ + do { if (d) { (d)[idx] = instr; } idx++; } while (0) +#define EMIT(instr) PLANT_INSTR(image, ctx->idx, instr) + +#define PPC_NOP() EMIT(PPC_INST_NOP) +#define PPC_BLR() EMIT(PPC_INST_BLR) +#define PPC_BLRL() EMIT(PPC_INST_BLRL) +#define PPC_MTLR(r) EMIT(PPC_INST_MTLR | __PPC_RT(r)) +#define PPC_ADDI(d, a, i) EMIT(PPC_INST_ADDI | __PPC_RT(d) | \ + __PPC_RA(a) | IMM_L(i)) +#define PPC_MR(d, a) PPC_OR(d, a, a) +#define PPC_LI(r, i) PPC_ADDI(r, 0, i) +#define PPC_ADDIS(d, a, i) EMIT(PPC_INST_ADDIS | \ + __PPC_RS(d) | __PPC_RA(a) | IMM_L(i)) +#define PPC_LIS(r, i) PPC_ADDIS(r, 0, i) +#define PPC_STD(r, base, i) EMIT(PPC_INST_STD | __PPC_RS(r) | \ + __PPC_RA(base) | ((i) & 0xfffc)) + +#define PPC_LD(r, base, i) EMIT(PPC_INST_LD | __PPC_RT(r) | \ + __PPC_RA(base) | IMM_L(i)) +#define PPC_LWZ(r, base, i) EMIT(PPC_INST_LWZ | __PPC_RT(r) | \ + __PPC_RA(base) | IMM_L(i)) +#define PPC_LHZ(r, base, i) EMIT(PPC_INST_LHZ | __PPC_RT(r) | \ + __PPC_RA(base) | IMM_L(i)) +/* Convenience helpers for the above with 'far' offsets: */ +#define PPC_LD_OFFS(r, base, i) do { if ((i) < 32768) PPC_LD(r, base, i); \ + else { PPC_ADDIS(r, base, IMM_HA(i)); \ + PPC_LD(r, r, IMM_L(i)); } } while(0) + +#define PPC_LWZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LWZ(r, base, i); \ + else { PPC_ADDIS(r, base, IMM_HA(i)); \ + PPC_LWZ(r, r, IMM_L(i)); } } while(0) + +#define PPC_LHZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LHZ(r, base, i); \ + else { PPC_ADDIS(r, base, IMM_HA(i)); \ + PPC_LHZ(r, r, IMM_L(i)); } } while(0) + +#define PPC_CMPWI(a, i) EMIT(PPC_INST_CMPWI | __PPC_RA(a) | IMM_L(i)) +#define PPC_CMPDI(a, i) EMIT(PPC_INST_CMPDI | __PPC_RA(a) | IMM_L(i)) +#define PPC_CMPLWI(a, i) EMIT(PPC_INST_CMPLWI | __PPC_RA(a) | IMM_L(i)) +#define PPC_CMPLW(a, b) EMIT(PPC_INST_CMPLW | __PPC_RA(a) | __PPC_RB(b)) + +#define PPC_SUB(d, a, b) EMIT(PPC_INST_SUB | __PPC_RT(d) | \ + __PPC_RB(a) | __PPC_RA(b)) +#define PPC_ADD(d, a, b) EMIT(PPC_INST_ADD | __PPC_RT(d) | \ + __PPC_RA(a) | __PPC_RB(b)) +#define PPC_MUL(d, a, b) EMIT(PPC_INST_MULLW | __PPC_RT(d) | \ + __PPC_RA(a) | __PPC_RB(b)) +#define PPC_MULHWU(d, a, b) EMIT(PPC_INST_MULHWU | __PPC_RT(d) | \ + __PPC_RA(a) | __PPC_RB(b)) +#define PPC_MULI(d, a, i) EMIT(PPC_INST_MULLI | __PPC_RT(d) | \ + __PPC_RA(a) | IMM_L(i)) +#define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | __PPC_RT(d) | \ + __PPC_RA(a) | __PPC_RB(b)) +#define PPC_AND(d, a, b) EMIT(PPC_INST_AND | __PPC_RA(d) | \ + __PPC_RS(a) | __PPC_RB(b)) +#define PPC_ANDI(d, a, i) EMIT(PPC_INST_ANDI | __PPC_RA(d) | \ + __PPC_RS(a) | IMM_L(i)) +#define PPC_AND_DOT(d, a, b) EMIT(PPC_INST_ANDDOT | __PPC_RA(d) | \ + __PPC_RS(a) | __PPC_RB(b)) +#define PPC_OR(d, a, b) EMIT(PPC_INST_OR | __PPC_RA(d) | \ + __PPC_RS(a) | __PPC_RB(b)) +#define PPC_ORI(d, a, i) EMIT(PPC_INST_ORI | __PPC_RA(d) | \ + __PPC_RS(a) | IMM_L(i)) +#define PPC_ORIS(d, a, i) EMIT(PPC_INST_ORIS | __PPC_RA(d) | \ + __PPC_RS(a) | IMM_L(i)) +#define PPC_SLW(d, a, s) EMIT(PPC_INST_SLW | __PPC_RA(d) | \ + __PPC_RS(a) | __PPC_RB(s)) +#define PPC_SRW(d, a, s) EMIT(PPC_INST_SRW | __PPC_RA(d) | \ + __PPC_RS(a) | __PPC_RB(s)) +/* slwi = rlwinm Rx, Ry, n, 0, 31-n */ +#define PPC_SLWI(d, a, i) EMIT(PPC_INST_RLWINM | __PPC_RA(d) | \ + __PPC_RS(a) | __PPC_SH(i) | \ + __PPC_MB(0) | __PPC_ME(31-(i))) +/* srwi = rlwinm Rx, Ry, 32-n, n, 31 */ +#define PPC_SRWI(d, a, i) EMIT(PPC_INST_RLWINM | __PPC_RA(d) | \ + __PPC_RS(a) | __PPC_SH(32-(i)) | \ + __PPC_MB(i) | __PPC_ME(31)) +/* sldi = rldicr Rx, Ry, n, 63-n */ +#define PPC_SLDI(d, a, i) EMIT(PPC_INST_RLDICR | __PPC_RA(d) | \ + __PPC_RS(a) | __PPC_SH(i) | \ + __PPC_MB(63-(i)) | (((i) & 0x20) >> 4)) +#define PPC_NEG(d, a) EMIT(PPC_INST_NEG | __PPC_RT(d) | __PPC_RA(a)) + +/* Long jump; (unconditional 'branch') */ +#define PPC_JMP(dest) EMIT(PPC_INST_BRANCH | \ + (((dest) - (ctx->idx * 4)) & 0x03fffffc)) +/* "cond" here covers BO:BI fields. */ +#define PPC_BCC_SHORT(cond, dest) EMIT(PPC_INST_BRANCH_COND | \ + (((cond) & 0x3ff) << 16) | \ + (((dest) - (ctx->idx * 4)) & \ + 0xfffc)) +#define PPC_LI32(d, i) do { PPC_LI(d, IMM_L(i)); \ + if ((u32)(uintptr_t)(i) >= 32768) { \ + PPC_ADDIS(d, d, IMM_HA(i)); \ + } } while(0) +#define PPC_LI64(d, i) do { \ + if (!((uintptr_t)(i) & 0xffffffff00000000ULL)) \ + PPC_LI32(d, i); \ + else { \ + PPC_LIS(d, ((uintptr_t)(i) >> 48)); \ + if ((uintptr_t)(i) & 0x0000ffff00000000ULL) \ + PPC_ORI(d, d, \ + ((uintptr_t)(i) >> 32) & 0xffff); \ + PPC_SLDI(d, d, 32); \ + if ((uintptr_t)(i) & 0x00000000ffff0000ULL) \ + PPC_ORIS(d, d, \ + ((uintptr_t)(i) >> 16) & 0xffff); \ + if ((uintptr_t)(i) & 0x000000000000ffffULL) \ + PPC_ORI(d, d, (uintptr_t)(i) & 0xffff); \ + } } while (0); + +static inline bool is_nearbranch(int offset) +{ + return (offset < 32768) && (offset >= -32768); +} + +/* + * The fly in the ointment of code size changing from pass to pass is + * avoided by padding the short branch case with a NOP. If code size differs + * with different branch reaches we will have the issue of code moving from + * one pass to the next and will need a few passes to converge on a stable + * state. + */ +#define PPC_BCC(cond, dest) do { \ + if (is_nearbranch((dest) - (ctx->idx * 4))) { \ + PPC_BCC_SHORT(cond, dest); \ + PPC_NOP(); \ + } else { \ + /* Flip the 'T or F' bit to invert comparison */ \ + PPC_BCC_SHORT(cond ^ COND_CMP_TRUE, (ctx->idx+2)*4); \ + PPC_JMP(dest); \ + } } while(0) + +/* To create a branch condition, select a bit of cr0... */ +#define CR0_LT 0 +#define CR0_GT 1 +#define CR0_EQ 2 +/* ...and modify BO[3] */ +#define COND_CMP_TRUE 0x100 +#define COND_CMP_FALSE 0x000 +/* Together, they make all required comparisons: */ +#define COND_GT (CR0_GT | COND_CMP_TRUE) +#define COND_GE (CR0_LT | COND_CMP_FALSE) +#define COND_EQ (CR0_EQ | COND_CMP_TRUE) +#define COND_NE (CR0_EQ | COND_CMP_FALSE) +#define COND_LT (CR0_LT | COND_CMP_TRUE) + +#define SEEN_DATAREF 0x10000 /* might call external helpers */ +#define SEEN_XREG 0x20000 /* X reg is used */ +#define SEEN_MEM 0x40000 /* SEEN_MEM+(1<<n) = use mem[n] for temporary + * storage */ +#define SEEN_MEM_MSK 0x0ffff + +struct codegen_context { + unsigned int seen; + unsigned int idx; + int pc_ret0; /* bpf index of first RET #0 instruction (if any) */ +}; + +#endif + +#endif diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_64.S new file mode 100644 index 000000000000..ff4506e85cce --- /dev/null +++ b/arch/powerpc/net/bpf_jit_64.S @@ -0,0 +1,138 @@ +/* bpf_jit.S: Packet/header access helper functions + * for PPC64 BPF compiler. + * + * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <asm/ppc_asm.h> +#include "bpf_jit.h" + +/* + * All of these routines are called directly from generated code, + * whose register usage is: + * + * r3 skb + * r4,r5 A,X + * r6 *** address parameter to helper *** + * r7-r10 scratch + * r14 skb->data + * r15 skb headlen + * r16-31 M[] + */ + +/* + * To consider: These helpers are so small it could be better to just + * generate them inline. Inline code can do the simple headlen check + * then branch directly to slow_path_XXX if required. (In fact, could + * load a spare GPR with the address of slow_path_generic and pass size + * as an argument, making the call site a mtlr, li and bllr.) + * + * Technically, the "is addr < 0" check is unnecessary & slowing down + * the ABS path, as it's statically checked on generation. + */ + .globl sk_load_word +sk_load_word: + cmpdi r_addr, 0 + blt bpf_error + /* Are we accessing past headlen? */ + subi r_scratch1, r_HL, 4 + cmpd r_scratch1, r_addr + blt bpf_slow_path_word + /* Nope, just hitting the header. cr0 here is eq or gt! */ + lwzx r_A, r_D, r_addr + /* When big endian we don't need to byteswap. */ + blr /* Return success, cr0 != LT */ + + .globl sk_load_half +sk_load_half: + cmpdi r_addr, 0 + blt bpf_error + subi r_scratch1, r_HL, 2 + cmpd r_scratch1, r_addr + blt bpf_slow_path_half + lhzx r_A, r_D, r_addr + blr + + .globl sk_load_byte +sk_load_byte: + cmpdi r_addr, 0 + blt bpf_error + cmpd r_HL, r_addr + ble bpf_slow_path_byte + lbzx r_A, r_D, r_addr + blr + +/* + * BPF_S_LDX_B_MSH: ldxb 4*([offset]&0xf) + * r_addr is the offset value, already known positive + */ + .globl sk_load_byte_msh +sk_load_byte_msh: + cmpd r_HL, r_addr + ble bpf_slow_path_byte_msh + lbzx r_X, r_D, r_addr + rlwinm r_X, r_X, 2, 32-4-2, 31-2 + blr + +bpf_error: + /* Entered with cr0 = lt */ + li r3, 0 + /* Generated code will 'blt epilogue', returning 0. */ + blr + +/* Call out to skb_copy_bits: + * We'll need to back up our volatile regs first; we have + * local variable space at r1+(BPF_PPC_STACK_BASIC). + * Allocate a new stack frame here to remain ABI-compliant in + * stashing LR. + */ +#define bpf_slow_path_common(SIZE) \ + mflr r0; \ + std r0, 16(r1); \ + /* R3 goes in parameter space of caller's frame */ \ + std r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ + std r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ + std r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ + addi r5, r1, BPF_PPC_STACK_BASIC+(2*8); \ + stdu r1, -BPF_PPC_SLOWPATH_FRAME(r1); \ + /* R3 = r_skb, as passed */ \ + mr r4, r_addr; \ + li r6, SIZE; \ + bl skb_copy_bits; \ + /* R3 = 0 on success */ \ + addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ + ld r0, 16(r1); \ + ld r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ + ld r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ + mtlr r0; \ + cmpdi r3, 0; \ + blt bpf_error; /* cr0 = LT */ \ + ld r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ + /* Great success! */ + +bpf_slow_path_word: + bpf_slow_path_common(4) + /* Data value is on stack, and cr0 != LT */ + lwz r_A, BPF_PPC_STACK_BASIC+(2*8)(r1) + blr + +bpf_slow_path_half: + bpf_slow_path_common(2) + lhz r_A, BPF_PPC_STACK_BASIC+(2*8)(r1) + blr + +bpf_slow_path_byte: + bpf_slow_path_common(1) + lbz r_A, BPF_PPC_STACK_BASIC+(2*8)(r1) + blr + +bpf_slow_path_byte_msh: + bpf_slow_path_common(1) + lbz r_X, BPF_PPC_STACK_BASIC+(2*8)(r1) + rlwinm r_X, r_X, 2, 32-4-2, 31-2 + blr diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c new file mode 100644 index 000000000000..73619d3aeb6c --- /dev/null +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -0,0 +1,694 @@ +/* bpf_jit_comp.c: BPF JIT compiler for PPC64 + * + * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation + * + * Based on the x86 BPF compiler, by Eric Dumazet (eric.dumazet@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ +#include <linux/moduleloader.h> +#include <asm/cacheflush.h> +#include <linux/netdevice.h> +#include <linux/filter.h> +#include "bpf_jit.h" + +#ifndef __BIG_ENDIAN +/* There are endianness assumptions herein. */ +#error "Little-endian PPC not supported in BPF compiler" +#endif + +int bpf_jit_enable __read_mostly; + + +static inline void bpf_flush_icache(void *start, void *end) +{ + smp_wmb(); + flush_icache_range((unsigned long)start, (unsigned long)end); +} + +static void bpf_jit_build_prologue(struct sk_filter *fp, u32 *image, + struct codegen_context *ctx) +{ + int i; + const struct sock_filter *filter = fp->insns; + + if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) { + /* Make stackframe */ + if (ctx->seen & SEEN_DATAREF) { + /* If we call any helpers (for loads), save LR */ + EMIT(PPC_INST_MFLR | __PPC_RT(0)); + PPC_STD(0, 1, 16); + + /* Back up non-volatile regs. */ + PPC_STD(r_D, 1, -(8*(32-r_D))); + PPC_STD(r_HL, 1, -(8*(32-r_HL))); + } + if (ctx->seen & SEEN_MEM) { + /* + * Conditionally save regs r15-r31 as some will be used + * for M[] data. + */ + for (i = r_M; i < (r_M+16); i++) { + if (ctx->seen & (1 << (i-r_M))) + PPC_STD(i, 1, -(8*(32-i))); + } + } + EMIT(PPC_INST_STDU | __PPC_RS(1) | __PPC_RA(1) | + (-BPF_PPC_STACKFRAME & 0xfffc)); + } + + if (ctx->seen & SEEN_DATAREF) { + /* + * If this filter needs to access skb data, + * prepare r_D and r_HL: + * r_HL = skb->len - skb->data_len + * r_D = skb->data + */ + PPC_LWZ_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, + data_len)); + PPC_LWZ_OFFS(r_HL, r_skb, offsetof(struct sk_buff, len)); + PPC_SUB(r_HL, r_HL, r_scratch1); + PPC_LD_OFFS(r_D, r_skb, offsetof(struct sk_buff, data)); + } + + if (ctx->seen & SEEN_XREG) { + /* + * TODO: Could also detect whether first instr. sets X and + * avoid this (as below, with A). + */ + PPC_LI(r_X, 0); + } + + switch (filter[0].code) { + case BPF_S_RET_K: + case BPF_S_LD_W_LEN: + case BPF_S_ANC_PROTOCOL: + case BPF_S_ANC_IFINDEX: + case BPF_S_ANC_MARK: + case BPF_S_ANC_RXHASH: + case BPF_S_ANC_CPU: + case BPF_S_ANC_QUEUE: + case BPF_S_LD_W_ABS: + case BPF_S_LD_H_ABS: + case BPF_S_LD_B_ABS: + /* first instruction sets A register (or is RET 'constant') */ + break; + default: + /* make sure we dont leak kernel information to user */ + PPC_LI(r_A, 0); + } +} + +static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) +{ + int i; + + if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) { + PPC_ADDI(1, 1, BPF_PPC_STACKFRAME); + if (ctx->seen & SEEN_DATAREF) { + PPC_LD(0, 1, 16); + PPC_MTLR(0); + PPC_LD(r_D, 1, -(8*(32-r_D))); + PPC_LD(r_HL, 1, -(8*(32-r_HL))); + } + if (ctx->seen & SEEN_MEM) { + /* Restore any saved non-vol registers */ + for (i = r_M; i < (r_M+16); i++) { + if (ctx->seen & (1 << (i-r_M))) + PPC_LD(i, 1, -(8*(32-i))); + } + } + } + /* The RETs have left a return value in R3. */ + + PPC_BLR(); +} + +/* Assemble the body code between the prologue & epilogue. */ +static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, + struct codegen_context *ctx, + unsigned int *addrs) +{ + const struct sock_filter *filter = fp->insns; + int flen = fp->len; + u8 *func; + unsigned int true_cond; + int i; + + /* Start of epilogue code */ + unsigned int exit_addr = addrs[flen]; + + for (i = 0; i < flen; i++) { + unsigned int K = filter[i].k; + + /* + * addrs[] maps a BPF bytecode address into a real offset from + * the start of the body code. + */ + addrs[i] = ctx->idx * 4; + + switch (filter[i].code) { + /*** ALU ops ***/ + case BPF_S_ALU_ADD_X: /* A += X; */ + ctx->seen |= SEEN_XREG; + PPC_ADD(r_A, r_A, r_X); + break; + case BPF_S_ALU_ADD_K: /* A += K; */ + if (!K) + break; + PPC_ADDI(r_A, r_A, IMM_L(K)); + if (K >= 32768) + PPC_ADDIS(r_A, r_A, IMM_HA(K)); + break; + case BPF_S_ALU_SUB_X: /* A -= X; */ + ctx->seen |= SEEN_XREG; + PPC_SUB(r_A, r_A, r_X); + break; + case BPF_S_ALU_SUB_K: /* A -= K */ + if (!K) + break; + PPC_ADDI(r_A, r_A, IMM_L(-K)); + if (K >= 32768) + PPC_ADDIS(r_A, r_A, IMM_HA(-K)); + break; + case BPF_S_ALU_MUL_X: /* A *= X; */ + ctx->seen |= SEEN_XREG; + PPC_MUL(r_A, r_A, r_X); + break; + case BPF_S_ALU_MUL_K: /* A *= K */ + if (K < 32768) + PPC_MULI(r_A, r_A, K); + else { + PPC_LI32(r_scratch1, K); + PPC_MUL(r_A, r_A, r_scratch1); + } + break; + case BPF_S_ALU_DIV_X: /* A /= X; */ + ctx->seen |= SEEN_XREG; + PPC_CMPWI(r_X, 0); + if (ctx->pc_ret0 != -1) { + PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]); + } else { + /* + * Exit, returning 0; first pass hits here + * (longer worst-case code size). + */ + PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12); + PPC_LI(r_ret, 0); + PPC_JMP(exit_addr); + } + PPC_DIVWU(r_A, r_A, r_X); + break; + case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */ + PPC_LI32(r_scratch1, K); + /* Top 32 bits of 64bit result -> A */ + PPC_MULHWU(r_A, r_A, r_scratch1); + break; + case BPF_S_ALU_AND_X: + ctx->seen |= SEEN_XREG; + PPC_AND(r_A, r_A, r_X); + break; + case BPF_S_ALU_AND_K: + if (!IMM_H(K)) + PPC_ANDI(r_A, r_A, K); + else { + PPC_LI32(r_scratch1, K); + PPC_AND(r_A, r_A, r_scratch1); + } + break; + case BPF_S_ALU_OR_X: + ctx->seen |= SEEN_XREG; + PPC_OR(r_A, r_A, r_X); + break; + case BPF_S_ALU_OR_K: + if (IMM_L(K)) + PPC_ORI(r_A, r_A, IMM_L(K)); + if (K >= 65536) + PPC_ORIS(r_A, r_A, IMM_H(K)); + break; + case BPF_S_ALU_LSH_X: /* A <<= X; */ + ctx->seen |= SEEN_XREG; + PPC_SLW(r_A, r_A, r_X); + break; + case BPF_S_ALU_LSH_K: + if (K == 0) + break; + else + PPC_SLWI(r_A, r_A, K); + break; + case BPF_S_ALU_RSH_X: /* A >>= X; */ + ctx->seen |= SEEN_XREG; + PPC_SRW(r_A, r_A, r_X); + break; + case BPF_S_ALU_RSH_K: /* A >>= K; */ + if (K == 0) + break; + else + PPC_SRWI(r_A, r_A, K); + break; + case BPF_S_ALU_NEG: + PPC_NEG(r_A, r_A); + break; + case BPF_S_RET_K: + PPC_LI32(r_ret, K); + if (!K) { + if (ctx->pc_ret0 == -1) + ctx->pc_ret0 = i; + } + /* + * If this isn't the very last instruction, branch to + * the epilogue if we've stuff to clean up. Otherwise, + * if there's nothing to tidy, just return. If we /are/ + * the last instruction, we're about to fall through to + * the epilogue to return. + */ + if (i != flen - 1) { + /* + * Note: 'seen' is properly valid only on pass + * #2. Both parts of this conditional are the + * same instruction size though, meaning the + * first pass will still correctly determine the + * code size/addresses. + */ + if (ctx->seen) + PPC_JMP(exit_addr); + else + PPC_BLR(); + } + break; + case BPF_S_RET_A: + PPC_MR(r_ret, r_A); + if (i != flen - 1) { + if (ctx->seen) + PPC_JMP(exit_addr); + else + PPC_BLR(); + } + break; + case BPF_S_MISC_TAX: /* X = A */ + PPC_MR(r_X, r_A); + break; + case BPF_S_MISC_TXA: /* A = X */ + ctx->seen |= SEEN_XREG; + PPC_MR(r_A, r_X); + break; + + /*** Constant loads/M[] access ***/ + case BPF_S_LD_IMM: /* A = K */ + PPC_LI32(r_A, K); + break; + case BPF_S_LDX_IMM: /* X = K */ + PPC_LI32(r_X, K); + break; + case BPF_S_LD_MEM: /* A = mem[K] */ + PPC_MR(r_A, r_M + (K & 0xf)); + ctx->seen |= SEEN_MEM | (1<<(K & 0xf)); + break; + case BPF_S_LDX_MEM: /* X = mem[K] */ + PPC_MR(r_X, r_M + (K & 0xf)); + ctx->seen |= SEEN_MEM | (1<<(K & 0xf)); + break; + case BPF_S_ST: /* mem[K] = A */ + PPC_MR(r_M + (K & 0xf), r_A); + ctx->seen |= SEEN_MEM | (1<<(K & 0xf)); + break; + case BPF_S_STX: /* mem[K] = X */ + PPC_MR(r_M + (K & 0xf), r_X); + ctx->seen |= SEEN_XREG | SEEN_MEM | (1<<(K & 0xf)); + break; + case BPF_S_LD_W_LEN: /* A = skb->len; */ + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); + PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, len)); + break; + case BPF_S_LDX_W_LEN: /* X = skb->len; */ + PPC_LWZ_OFFS(r_X, r_skb, offsetof(struct sk_buff, len)); + break; + + /*** Ancillary info loads ***/ + + /* None of the BPF_S_ANC* codes appear to be passed by + * sk_chk_filter(). The interpreter and the x86 BPF + * compiler implement them so we do too -- they may be + * planted in future. + */ + case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */ + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, + protocol) != 2); + PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, + protocol)); + /* ntohs is a NOP with BE loads. */ + break; + case BPF_S_ANC_IFINDEX: + PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, + dev)); + PPC_CMPDI(r_scratch1, 0); + if (ctx->pc_ret0 != -1) { + PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]); + } else { + /* Exit, returning 0; first pass hits here. */ + PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12); + PPC_LI(r_ret, 0); + PPC_JMP(exit_addr); + } + BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, + ifindex) != 4); + PPC_LWZ_OFFS(r_A, r_scratch1, + offsetof(struct net_device, ifindex)); + break; + case BPF_S_ANC_MARK: + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); + PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, + mark)); + break; + case BPF_S_ANC_RXHASH: + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4); + PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, + rxhash)); + break; + case BPF_S_ANC_QUEUE: + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, + queue_mapping) != 2); + PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, + queue_mapping)); + break; + case BPF_S_ANC_CPU: +#ifdef CONFIG_SMP + /* + * PACA ptr is r13: + * raw_smp_processor_id() = local_paca->paca_index + */ + BUILD_BUG_ON(FIELD_SIZEOF(struct paca_struct, + paca_index) != 2); + PPC_LHZ_OFFS(r_A, 13, + offsetof(struct paca_struct, paca_index)); +#else + PPC_LI(r_A, 0); +#endif + break; + + /*** Absolute loads from packet header/data ***/ + case BPF_S_LD_W_ABS: + func = sk_load_word; + goto common_load; + case BPF_S_LD_H_ABS: + func = sk_load_half; + goto common_load; + case BPF_S_LD_B_ABS: + func = sk_load_byte; + common_load: + /* + * Load from [K]. Reference with the (negative) + * SKF_NET_OFF/SKF_LL_OFF offsets is unsupported. + */ + ctx->seen |= SEEN_DATAREF; + if ((int)K < 0) + return -ENOTSUPP; + PPC_LI64(r_scratch1, func); + PPC_MTLR(r_scratch1); + PPC_LI32(r_addr, K); + PPC_BLRL(); + /* + * Helper returns 'lt' condition on error, and an + * appropriate return value in r3 + */ + PPC_BCC(COND_LT, exit_addr); + break; + + /*** Indirect loads from packet header/data ***/ + case BPF_S_LD_W_IND: + func = sk_load_word; + goto common_load_ind; + case BPF_S_LD_H_IND: + func = sk_load_half; + goto common_load_ind; + case BPF_S_LD_B_IND: + func = sk_load_byte; + common_load_ind: + /* + * Load from [X + K]. Negative offsets are tested for + * in the helper functions, and result in a 'ret 0'. + */ + ctx->seen |= SEEN_DATAREF | SEEN_XREG; + PPC_LI64(r_scratch1, func); + PPC_MTLR(r_scratch1); + PPC_ADDI(r_addr, r_X, IMM_L(K)); + if (K >= 32768) + PPC_ADDIS(r_addr, r_addr, IMM_HA(K)); + PPC_BLRL(); + /* If error, cr0.LT set */ + PPC_BCC(COND_LT, exit_addr); + break; + + case BPF_S_LDX_B_MSH: + /* + * x86 version drops packet (RET 0) when K<0, whereas + * interpreter does allow K<0 (__load_pointer, special + * ancillary data). common_load returns ENOTSUPP if K<0, + * so we fall back to interpreter & filter works. + */ + func = sk_load_byte_msh; + goto common_load; + break; + + /*** Jump and branches ***/ + case BPF_S_JMP_JA: + if (K != 0) + PPC_JMP(addrs[i + 1 + K]); + break; + + case BPF_S_JMP_JGT_K: + case BPF_S_JMP_JGT_X: + true_cond = COND_GT; + goto cond_branch; + case BPF_S_JMP_JGE_K: + case BPF_S_JMP_JGE_X: + true_cond = COND_GE; + goto cond_branch; + case BPF_S_JMP_JEQ_K: + case BPF_S_JMP_JEQ_X: + true_cond = COND_EQ; + goto cond_branch; + case BPF_S_JMP_JSET_K: + case BPF_S_JMP_JSET_X: + true_cond = COND_NE; + /* Fall through */ + cond_branch: + /* same targets, can avoid doing the test :) */ + if (filter[i].jt == filter[i].jf) { + if (filter[i].jt > 0) + PPC_JMP(addrs[i + 1 + filter[i].jt]); + break; + } + + switch (filter[i].code) { + case BPF_S_JMP_JGT_X: + case BPF_S_JMP_JGE_X: + case BPF_S_JMP_JEQ_X: + ctx->seen |= SEEN_XREG; + PPC_CMPLW(r_A, r_X); + break; + case BPF_S_JMP_JSET_X: + ctx->seen |= SEEN_XREG; + PPC_AND_DOT(r_scratch1, r_A, r_X); + break; + case BPF_S_JMP_JEQ_K: + case BPF_S_JMP_JGT_K: + case BPF_S_JMP_JGE_K: + if (K < 32768) + PPC_CMPLWI(r_A, K); + else { + PPC_LI32(r_scratch1, K); + PPC_CMPLW(r_A, r_scratch1); + } + break; + case BPF_S_JMP_JSET_K: + if (K < 32768) + /* PPC_ANDI is /only/ dot-form */ + PPC_ANDI(r_scratch1, r_A, K); + else { + PPC_LI32(r_scratch1, K); + PPC_AND_DOT(r_scratch1, r_A, + r_scratch1); + } + break; + } + /* Sometimes branches are constructed "backward", with + * the false path being the branch and true path being + * a fallthrough to the next instruction. + */ + if (filter[i].jt == 0) + /* Swap the sense of the branch */ + PPC_BCC(true_cond ^ COND_CMP_TRUE, + addrs[i + 1 + filter[i].jf]); + else { + PPC_BCC(true_cond, addrs[i + 1 + filter[i].jt]); + if (filter[i].jf != 0) + PPC_JMP(addrs[i + 1 + filter[i].jf]); + } + break; + default: + /* The filter contains something cruel & unusual. + * We don't handle it, but also there shouldn't be + * anything missing from our list. + */ + if (printk_ratelimit()) + pr_err("BPF filter opcode %04x (@%d) unsupported\n", + filter[i].code, i); + return -ENOTSUPP; + } + + } + /* Set end-of-body-code address for exit. */ + addrs[i] = ctx->idx * 4; + + return 0; +} + +void bpf_jit_compile(struct sk_filter *fp) +{ + unsigned int proglen; + unsigned int alloclen; + u32 *image = NULL; + u32 *code_base; + unsigned int *addrs; + struct codegen_context cgctx; + int pass; + int flen = fp->len; + + if (!bpf_jit_enable) + return; + + addrs = kzalloc((flen+1) * sizeof(*addrs), GFP_KERNEL); + if (addrs == NULL) + return; + + /* + * There are multiple assembly passes as the generated code will change + * size as it settles down, figuring out the max branch offsets/exit + * paths required. + * + * The range of standard conditional branches is +/- 32Kbytes. Since + * BPF_MAXINSNS = 4096, we can only jump from (worst case) start to + * finish with 8 bytes/instruction. Not feasible, so long jumps are + * used, distinct from short branches. + * + * Current: + * + * For now, both branch types assemble to 2 words (short branches padded + * with a NOP); this is less efficient, but assembly will always complete + * after exactly 3 passes: + * + * First pass: No code buffer; Program is "faux-generated" -- no code + * emitted but maximum size of output determined (and addrs[] filled + * in). Also, we note whether we use M[], whether we use skb data, etc. + * All generation choices assumed to be 'worst-case', e.g. branches all + * far (2 instructions), return path code reduction not available, etc. + * + * Second pass: Code buffer allocated with size determined previously. + * Prologue generated to support features we have seen used. Exit paths + * determined and addrs[] is filled in again, as code may be slightly + * smaller as a result. + * + * Third pass: Code generated 'for real', and branch destinations + * determined from now-accurate addrs[] map. + * + * Ideal: + * + * If we optimise this, near branches will be shorter. On the + * first assembly pass, we should err on the side of caution and + * generate the biggest code. On subsequent passes, branches will be + * generated short or long and code size will reduce. With smaller + * code, more branches may fall into the short category, and code will + * reduce more. + * + * Finally, if we see one pass generate code the same size as the + * previous pass we have converged and should now generate code for + * real. Allocating at the end will also save the memory that would + * otherwise be wasted by the (small) current code shrinkage. + * Preferably, we should do a small number of passes (e.g. 5) and if we + * haven't converged by then, get impatient and force code to generate + * as-is, even if the odd branch would be left long. The chances of a + * long jump are tiny with all but the most enormous of BPF filter + * inputs, so we should usually converge on the third pass. + */ + + cgctx.idx = 0; + cgctx.seen = 0; + cgctx.pc_ret0 = -1; + /* Scouting faux-generate pass 0 */ + if (bpf_jit_build_body(fp, 0, &cgctx, addrs)) + /* We hit something illegal or unsupported. */ + goto out; + + /* + * Pretend to build prologue, given the features we've seen. This will + * update ctgtx.idx as it pretends to output instructions, then we can + * calculate total size from idx. + */ + bpf_jit_build_prologue(fp, 0, &cgctx); + bpf_jit_build_epilogue(0, &cgctx); + + proglen = cgctx.idx * 4; + alloclen = proglen + FUNCTION_DESCR_SIZE; + image = module_alloc(max_t(unsigned int, alloclen, + sizeof(struct work_struct))); + if (!image) + goto out; + + code_base = image + (FUNCTION_DESCR_SIZE/4); + + /* Code generation passes 1-2 */ + for (pass = 1; pass < 3; pass++) { + /* Now build the prologue, body code & epilogue for real. */ + cgctx.idx = 0; + bpf_jit_build_prologue(fp, code_base, &cgctx); + bpf_jit_build_body(fp, code_base, &cgctx, addrs); + bpf_jit_build_epilogue(code_base, &cgctx); + + if (bpf_jit_enable > 1) + pr_info("Pass %d: shrink = %d, seen = 0x%x\n", pass, + proglen - (cgctx.idx * 4), cgctx.seen); + } + + if (bpf_jit_enable > 1) + pr_info("flen=%d proglen=%u pass=%d image=%p\n", + flen, proglen, pass, image); + + if (image) { + if (bpf_jit_enable > 1) + print_hex_dump(KERN_ERR, "JIT code: ", + DUMP_PREFIX_ADDRESS, + 16, 1, code_base, + proglen, false); + + bpf_flush_icache(code_base, code_base + (proglen/4)); + /* Function descriptor nastiness: Address + TOC */ + ((u64 *)image)[0] = (u64)code_base; + ((u64 *)image)[1] = local_paca->kernel_toc; + fp->bpf_func = (void *)image; + } +out: + kfree(addrs); + return; +} + +static void jit_free_defer(struct work_struct *arg) +{ + module_free(NULL, arg); +} + +/* run from softirq, we must use a work_struct to call + * module_free() from process context + */ +void bpf_jit_free(struct sk_filter *fp) +{ + if (fp->bpf_func != sk_run_filter) { + struct work_struct *work = (struct work_struct *)fp->bpf_func; + + INIT_WORK(work, jit_free_defer); + schedule_work(work); + } +} diff --git a/arch/sparc/include/asm/irqflags_32.h b/arch/sparc/include/asm/irqflags_32.h index d4d0711de0f9..14848909e0de 100644 --- a/arch/sparc/include/asm/irqflags_32.h +++ b/arch/sparc/include/asm/irqflags_32.h @@ -18,7 +18,7 @@ extern void arch_local_irq_restore(unsigned long); extern unsigned long arch_local_irq_save(void); extern void arch_local_irq_enable(void); -static inline unsigned long arch_local_save_flags(void) +static inline notrace unsigned long arch_local_save_flags(void) { unsigned long flags; @@ -26,17 +26,17 @@ static inline unsigned long arch_local_save_flags(void) return flags; } -static inline void arch_local_irq_disable(void) +static inline notrace void arch_local_irq_disable(void) { arch_local_irq_save(); } -static inline bool arch_irqs_disabled_flags(unsigned long flags) +static inline notrace bool arch_irqs_disabled_flags(unsigned long flags) { return (flags & PSR_PIL) != 0; } -static inline bool arch_irqs_disabled(void) +static inline notrace bool arch_irqs_disabled(void) { return arch_irqs_disabled_flags(arch_local_save_flags()); } diff --git a/arch/sparc/include/asm/irqflags_64.h b/arch/sparc/include/asm/irqflags_64.h index aab969c82c2b..23cd27f6beb4 100644 --- a/arch/sparc/include/asm/irqflags_64.h +++ b/arch/sparc/include/asm/irqflags_64.h @@ -14,7 +14,7 @@ #ifndef __ASSEMBLY__ -static inline unsigned long arch_local_save_flags(void) +static inline notrace unsigned long arch_local_save_flags(void) { unsigned long flags; @@ -26,7 +26,7 @@ static inline unsigned long arch_local_save_flags(void) return flags; } -static inline void arch_local_irq_restore(unsigned long flags) +static inline notrace void arch_local_irq_restore(unsigned long flags) { __asm__ __volatile__( "wrpr %0, %%pil" @@ -36,7 +36,7 @@ static inline void arch_local_irq_restore(unsigned long flags) ); } -static inline void arch_local_irq_disable(void) +static inline notrace void arch_local_irq_disable(void) { __asm__ __volatile__( "wrpr %0, %%pil" @@ -46,7 +46,7 @@ static inline void arch_local_irq_disable(void) ); } -static inline void arch_local_irq_enable(void) +static inline notrace void arch_local_irq_enable(void) { __asm__ __volatile__( "wrpr 0, %%pil" @@ -56,17 +56,17 @@ static inline void arch_local_irq_enable(void) ); } -static inline int arch_irqs_disabled_flags(unsigned long flags) +static inline notrace int arch_irqs_disabled_flags(unsigned long flags) { return (flags > 0); } -static inline int arch_irqs_disabled(void) +static inline notrace int arch_irqs_disabled(void) { return arch_irqs_disabled_flags(arch_local_save_flags()); } -static inline unsigned long arch_local_irq_save(void) +static inline notrace unsigned long arch_local_irq_save(void) { unsigned long flags, tmp; diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 9fe08a1ea6c6..f445e98463e6 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -293,7 +293,7 @@ maybe_smp4m_msg: WRITE_PAUSE wr %l4, PSR_ET, %psr WRITE_PAUSE - sll %o3, 28, %o2 ! shift for simpler checks below + srl %o3, 28, %o2 ! shift for simpler checks below maybe_smp4m_msg_check_single: andcc %o2, 0x1, %g0 beq,a maybe_smp4m_msg_check_mask diff --git a/arch/sparc/mm/leon_mm.c b/arch/sparc/mm/leon_mm.c index c0e01297e64e..e485a6804998 100644 --- a/arch/sparc/mm/leon_mm.c +++ b/arch/sparc/mm/leon_mm.c @@ -226,7 +226,7 @@ void leon3_getCacheRegs(struct leon3_cacheregs *regs) * Leon2 and Leon3 differ in their way of telling cache information * */ -int leon_flush_needed(void) +int __init leon_flush_needed(void) { int flush_needed = -1; unsigned int ssize, sets; diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index abda3786a5d7..181bc2f7bb74 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c @@ -139,13 +139,23 @@ static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) { struct platform_device *ghes_dev; struct ghes_arr *ghes_arr = data; - int rc; + int rc, i; if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) return 0; if (!((struct acpi_hest_generic *)hest_hdr)->enabled) return 0; + for (i = 0; i < ghes_arr->count; i++) { + struct acpi_hest_header *hdr; + ghes_dev = ghes_arr->ghes_devs[i]; + hdr = *(struct acpi_hest_header **)ghes_dev->dev.platform_data; + if (hdr->source_id == hest_hdr->source_id) { + pr_warning(FW_WARN HEST_PFX "Duplicated hardware error source ID: %d.\n", + hdr->source_id); + return -EIO; + } + } ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); if (!ghes_dev) return -ENOMEM; diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 52ca9649d769..372f9b70f7f4 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1333,23 +1333,6 @@ int acpi_resources_are_enforced(void) EXPORT_SYMBOL(acpi_resources_are_enforced); /* - * Create and initialize a spinlock. - */ -acpi_status -acpi_os_create_lock(acpi_spinlock *out_handle) -{ - spinlock_t *lock; - - lock = ACPI_ALLOCATE(sizeof(spinlock_t)); - if (!lock) - return AE_NO_MEMORY; - spin_lock_init(lock); - *out_handle = lock; - - return AE_OK; -} - -/* * Deallocate the memory for a spinlock. */ void acpi_os_delete_lock(acpi_spinlock handle) diff --git a/drivers/char/random.c b/drivers/char/random.c index d4ddeba56682..729281961f22 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1523,6 +1523,21 @@ __u32 secure_ip_id(__be32 daddr) return half_md4_transform(hash, keyptr->secret); } +__u32 secure_ipv6_id(const __be32 daddr[4]) +{ + const struct keydata *keyptr; + __u32 hash[4]; + + keyptr = get_keyptr(); + + hash[0] = (__force __u32)daddr[0]; + hash[1] = (__force __u32)daddr[1]; + hash[2] = (__force __u32)daddr[2]; + hash[3] = (__force __u32)daddr[3]; + + return half_md4_transform(hash, keyptr->secret); +} + #ifdef CONFIG_INET __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/wm831x-gpio.c index 309644cf4d9b..2bcfb0be09ff 100644 --- a/drivers/gpio/wm831x-gpio.c +++ b/drivers/gpio/wm831x-gpio.c @@ -180,6 +180,7 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) break; case WM831X_GPIO_PULL_UP: pull = "pullup"; + break; default: pull = "INVALID PULL"; break; diff --git a/drivers/hwmon/adm1275.c b/drivers/hwmon/adm1275.c index b9b7caf4a1d2..8bc1bd663721 100644 --- a/drivers/hwmon/adm1275.c +++ b/drivers/hwmon/adm1275.c @@ -53,23 +53,23 @@ static int adm1275_probe(struct i2c_client *client, info->direct[PSC_VOLTAGE_IN] = true; info->direct[PSC_VOLTAGE_OUT] = true; info->direct[PSC_CURRENT_OUT] = true; - info->m[PSC_CURRENT_OUT] = 800; + info->m[PSC_CURRENT_OUT] = 807; info->b[PSC_CURRENT_OUT] = 20475; info->R[PSC_CURRENT_OUT] = -1; info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; if (config & ADM1275_VRANGE) { - info->m[PSC_VOLTAGE_IN] = 19045; + info->m[PSC_VOLTAGE_IN] = 19199; info->b[PSC_VOLTAGE_IN] = 0; info->R[PSC_VOLTAGE_IN] = -2; - info->m[PSC_VOLTAGE_OUT] = 19045; + info->m[PSC_VOLTAGE_OUT] = 19199; info->b[PSC_VOLTAGE_OUT] = 0; info->R[PSC_VOLTAGE_OUT] = -2; } else { - info->m[PSC_VOLTAGE_IN] = 6666; + info->m[PSC_VOLTAGE_IN] = 6720; info->b[PSC_VOLTAGE_IN] = 0; info->R[PSC_VOLTAGE_IN] = -1; - info->m[PSC_VOLTAGE_OUT] = 6666; + info->m[PSC_VOLTAGE_OUT] = 6720; info->b[PSC_VOLTAGE_OUT] = 0; info->R[PSC_VOLTAGE_OUT] = -1; } diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index dcb78a7a8047..00e98517f94c 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -674,6 +674,7 @@ static int atk_debugfs_gitm_get(void *p, u64 *val) else err = -EIO; + ACPI_FREE(ret); return err; } diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index bb6405b92007..5f5247750430 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -1538,7 +1538,7 @@ static struct attribute *it87_attributes_label[] = { }; static const struct attribute_group it87_group_label = { - .attrs = it87_attributes_vid, + .attrs = it87_attributes_label, }; /* SuperIO detection - will change isa_address if a chip is found */ diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c index 12a54aa29776..14335bbc9bdc 100644 --- a/drivers/hwmon/max1111.c +++ b/drivers/hwmon/max1111.c @@ -40,6 +40,8 @@ struct max1111_data { struct spi_transfer xfer[2]; uint8_t *tx_buf; uint8_t *rx_buf; + struct mutex drvdata_lock; + /* protect msg, xfer and buffers from multiple access */ }; static int max1111_read(struct device *dev, int channel) @@ -48,6 +50,9 @@ static int max1111_read(struct device *dev, int channel) uint8_t v1, v2; int err; + /* writing to drvdata struct is not thread safe, wait on mutex */ + mutex_lock(&data->drvdata_lock); + data->tx_buf[0] = (channel << MAX1111_CTRL_SEL_SH) | MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 | MAX1111_CTRL_SGL | MAX1111_CTRL_UNI | MAX1111_CTRL_STR; @@ -55,12 +60,15 @@ static int max1111_read(struct device *dev, int channel) err = spi_sync(data->spi, &data->msg); if (err < 0) { dev_err(dev, "spi_sync failed with %d\n", err); + mutex_unlock(&data->drvdata_lock); return err; } v1 = data->rx_buf[0]; v2 = data->rx_buf[1]; + mutex_unlock(&data->drvdata_lock); + if ((v1 & 0xc0) || (v2 & 0x3f)) return -EINVAL; @@ -176,6 +184,8 @@ static int __devinit max1111_probe(struct spi_device *spi) if (err) goto err_free_data; + mutex_init(&data->drvdata_lock); + data->spi = spi; spi_set_drvdata(spi, data); @@ -213,6 +223,7 @@ static int __devexit max1111_remove(struct spi_device *spi) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); + mutex_destroy(&data->drvdata_lock); kfree(data->rx_buf); kfree(data->tx_buf); kfree(data); diff --git a/drivers/hwmon/pmbus_core.c b/drivers/hwmon/pmbus_core.c index 744672c1f26d..8e31a8e2c746 100644 --- a/drivers/hwmon/pmbus_core.c +++ b/drivers/hwmon/pmbus_core.c @@ -362,8 +362,8 @@ static struct pmbus_data *pmbus_update_device(struct device *dev) * Convert linear sensor values to milli- or micro-units * depending on sensor type. */ -static int pmbus_reg2data_linear(struct pmbus_data *data, - struct pmbus_sensor *sensor) +static long pmbus_reg2data_linear(struct pmbus_data *data, + struct pmbus_sensor *sensor) { s16 exponent; s32 mantissa; @@ -397,15 +397,15 @@ static int pmbus_reg2data_linear(struct pmbus_data *data, else val >>= -exponent; - return (int)val; + return val; } /* * Convert direct sensor values to milli- or micro-units * depending on sensor type. */ -static int pmbus_reg2data_direct(struct pmbus_data *data, - struct pmbus_sensor *sensor) +static long pmbus_reg2data_direct(struct pmbus_data *data, + struct pmbus_sensor *sensor) { long val = (s16) sensor->data; long m, b, R; @@ -440,12 +440,12 @@ static int pmbus_reg2data_direct(struct pmbus_data *data, R++; } - return (int)((val - b) / m); + return (val - b) / m; } -static int pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) +static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) { - int val; + long val; if (data->info->direct[sensor->class]) val = pmbus_reg2data_direct(data, sensor); @@ -619,7 +619,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) if (!s1 && !s2) *val = !!regval; else { - int v1, v2; + long v1, v2; struct pmbus_sensor *sensor1, *sensor2; sensor1 = &data->sensors[s1]; @@ -661,7 +661,7 @@ static ssize_t pmbus_show_sensor(struct device *dev, if (sensor->data < 0) return sensor->data; - return snprintf(buf, PAGE_SIZE, "%d\n", pmbus_reg2data(data, sensor)); + return snprintf(buf, PAGE_SIZE, "%ld\n", pmbus_reg2data(data, sensor)); } static ssize_t pmbus_set_sensor(struct device *dev, diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 96fa9a4cafdf..be36cbeae630 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -2917,24 +2917,19 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) goto skip_rx_indicate0; - if ((cqe_misc & NES_NIC_CQE_TAG_VALID) && - (nesvnic->vlan_grp != NULL)) { + if (cqe_misc & NES_NIC_CQE_TAG_VALID) { vlan_tag = (u16)(le32_to_cpu( cq->cq_vbase[head].cqe_words[NES_NIC_CQE_TAG_PKT_TYPE_IDX]) >> 16); nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n", nesvnic->netdev->name, vlan_tag); - if (nes_use_lro) - lro_vlan_hwaccel_receive_skb(&nesvnic->lro_mgr, rx_skb, - nesvnic->vlan_grp, vlan_tag, NULL); - else - nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag); - } else { - if (nes_use_lro) - lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL); - else - nes_netif_rx(rx_skb); + + __vlan_hwaccel_put_tag(rx_skb, vlan_tag); } + if (nes_use_lro) + lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL); + else + netif_receive_skb(rx_skb); skip_rx_indicate0: ; diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 91594116f947..c3241479ec0e 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h @@ -1211,7 +1211,6 @@ struct nes_vnic { /* void *mem; */ struct nes_device *nesdev; struct net_device *netdev; - struct vlan_group *vlan_grp; atomic_t rx_skbs_needed; atomic_t rx_skb_timer_running; int budget; @@ -1357,7 +1356,4 @@ struct nes_terminate_hdr { #define NES_LINK_RECHECK_DELAY msecs_to_jiffies(50) #define NES_LINK_RECHECK_MAX 60 -#define nes_vlan_rx vlan_hwaccel_receive_skb -#define nes_netif_rx netif_receive_skb - #endif /* __NES_HW_H */ diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index d3a1c41cfd27..9d7ffebff213 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -1584,23 +1584,19 @@ static const struct ethtool_ops nes_ethtool_ops = { .set_pauseparam = nes_netdev_set_pauseparam, }; - -static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) +static void nes_vlan_mode(struct net_device *netdev, struct nes_device *nesdev, u32 features) { - struct nes_vnic *nesvnic = netdev_priv(netdev); - struct nes_device *nesdev = nesvnic->nesdev; struct nes_adapter *nesadapter = nesdev->nesadapter; u32 u32temp; unsigned long flags; spin_lock_irqsave(&nesadapter->phy_lock, flags); - nesvnic->vlan_grp = grp; nes_debug(NES_DBG_NETDEV, "%s: %s\n", __func__, netdev->name); /* Enable/Disable VLAN Stripping */ u32temp = nes_read_indexed(nesdev, NES_IDX_PCIX_DIAG); - if (grp) + if (features & NETIF_F_HW_VLAN_RX) u32temp &= 0xfdffffff; else u32temp |= 0x02000000; @@ -1609,17 +1605,44 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g spin_unlock_irqrestore(&nesadapter->phy_lock, flags); } +static u32 nes_fix_features(struct net_device *netdev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int nes_set_features(struct net_device *netdev, u32 features) +{ + struct nes_vnic *nesvnic = netdev_priv(netdev); + struct nes_device *nesdev = nesvnic->nesdev; + u32 changed = netdev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + nes_vlan_mode(netdev, nesdev, features); + + return 0; +} + static const struct net_device_ops nes_netdev_ops = { - .ndo_open = nes_netdev_open, + .ndo_open = nes_netdev_open, .ndo_stop = nes_netdev_stop, - .ndo_start_xmit = nes_netdev_start_xmit, + .ndo_start_xmit = nes_netdev_start_xmit, .ndo_get_stats = nes_netdev_get_stats, - .ndo_tx_timeout = nes_netdev_tx_timeout, + .ndo_tx_timeout = nes_netdev_tx_timeout, .ndo_set_mac_address = nes_netdev_set_mac_address, .ndo_set_multicast_list = nes_netdev_set_multicast_list, .ndo_change_mtu = nes_netdev_change_mtu, .ndo_validate_addr = eth_validate_addr, - .ndo_vlan_rx_register = nes_netdev_vlan_rx_register, + .ndo_fix_features = nes_fix_features, + .ndo_set_features = nes_set_features, }; /** @@ -1656,7 +1679,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, netdev->ethtool_ops = &nes_ethtool_ops; netif_napi_add(netdev, &nesvnic->napi, nes_netdev_poll, 128); nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n"); - netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + netdev->features |= NETIF_F_HW_VLAN_TX; /* Fill in the port structure */ nesvnic->netdev = netdev; @@ -1683,7 +1706,8 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, netdev->dev_addr[5] = (u8)u64temp; memcpy(netdev->perm_addr, netdev->dev_addr, 6); - netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_IP_CSUM; + netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_HW_VLAN_RX; if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV)) netdev->hw_features |= NETIF_F_TSO; netdev->features |= netdev->hw_features; @@ -1815,6 +1839,8 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, nes_init_phy(nesdev); } + nes_vlan_mode(netdev, nesdev, netdev->features); + return netdev; } diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 98278041d75f..5b6b451d4694 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1988,6 +1988,14 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) { if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0) goto err0; + + /* If we took control of the bus, we need to force + reinitialization. This is because many ts_bus_ctrl() + functions strobe the RESET pin on the demod, and if the + frontend thread already exists then the dvb_init() routine + won't get called (which is what usually does initial + register configuration). */ + fepriv->reinitialise = 1; } if ((ret = dvb_generic_open (inode, file)) < 0) diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index e4c97fd6f05a..52798a111e16 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -168,7 +168,7 @@ config RADIO_MAXIRADIO config RADIO_MIROPCM20 tristate "miroSOUND PCM20 radio" - depends on ISA && VIDEO_V4L2 && SND + depends on ISA && ISA_DMA_API && VIDEO_V4L2 && SND select SND_ISA select SND_MIRO ---help--- @@ -201,7 +201,7 @@ config RADIO_SF16FMI config RADIO_SF16FMR2 tristate "SF16FMR2 Radio" - depends on ISA && VIDEO_V4L2 + depends on ISA && VIDEO_V4L2 && SND ---help--- Choose Y here if you have one of these FM radio cards. diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c index deca2e06ff22..c9f4a8e65dc4 100644 --- a/drivers/media/radio/si4713-i2c.c +++ b/drivers/media/radio/si4713-i2c.c @@ -1033,7 +1033,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev, char ps_name[MAX_RDS_PS_NAME + 1]; len = control->size - 1; - if (len > MAX_RDS_PS_NAME) { + if (len < 0 || len > MAX_RDS_PS_NAME) { rval = -ERANGE; goto exit; } @@ -1057,7 +1057,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev, char radio_text[MAX_RDS_RADIO_TEXT + 1]; len = control->size - 1; - if (len > MAX_RDS_RADIO_TEXT) { + if (len < 0 || len > MAX_RDS_RADIO_TEXT) { rval = -ERANGE; goto exit; } diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 06dfe0957b5e..ec972dc25790 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -558,9 +558,10 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, inout, data1); break; case MCE_CMD_S_TIMEOUT: - /* value is in units of 50us, so x*50/100 or x/2 ms */ + /* value is in units of 50us, so x*50/1000 ms */ dev_info(dev, "%s receive timeout of %d ms\n", - inout, ((data1 << 8) | data2) / 2); + inout, + ((data1 << 8) | data2) * MCE_TIME_UNIT / 1000); break; case MCE_CMD_G_TIMEOUT: dev_info(dev, "Get receive timeout\n"); @@ -847,7 +848,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index) switch (ir->buf_in[index]) { /* 2-byte return value commands */ case MCE_CMD_S_TIMEOUT: - ir->rc->timeout = US_TO_NS((hi << 8 | lo) / 2); + ir->rc->timeout = US_TO_NS((hi << 8 | lo) * MCE_TIME_UNIT); break; /* 1-byte return value commands */ @@ -1078,7 +1079,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) rc->priv = ir; rc->driver_type = RC_DRIVER_IR_RAW; rc->allowed_protos = RC_TYPE_ALL; - rc->timeout = US_TO_NS(1000); + rc->timeout = MS_TO_NS(100); if (!ir->flags.no_tx) { rc->s_tx_mask = mceusb_set_tx_mask; rc->s_tx_carrier = mceusb_set_tx_carrier; diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 565f24c20d77..ce595f9ab4c7 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -1110,7 +1110,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) rdev->dev.parent = &pdev->dev; rdev->driver_name = NVT_DRIVER_NAME; rdev->map_name = RC_MAP_RC6_MCE; - rdev->timeout = US_TO_NS(1000); + rdev->timeout = MS_TO_NS(100); /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD); #if 0 diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index 64d9b2136ff6..419777a832ee 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -2060,12 +2060,8 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev, goto fail_irq; } - if (!pci_enable_msi(pci_dev)) - err = request_irq(pci_dev->irq, cx23885_irq, - IRQF_DISABLED, dev->name, dev); - else - err = request_irq(pci_dev->irq, cx23885_irq, - IRQF_SHARED | IRQF_DISABLED, dev->name, dev); + err = request_irq(pci_dev->irq, cx23885_irq, + IRQF_SHARED | IRQF_DISABLED, dev->name, dev); if (err < 0) { printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name, pci_dev->irq); @@ -2114,7 +2110,6 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev) /* unregister stuff */ free_irq(pci_dev->irq, dev); - pci_disable_msi(pci_dev); cx23885_dev_unregister(dev); v4l2_device_unregister(v4l2_dev); diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index cfa9f7efe93d..a03945ab9f08 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -714,10 +714,19 @@ static int tuner_remove(struct i2c_client *client) * returns 0. * This function is needed for boards that have a separate tuner for * radio (like devices with tea5767). + * NOTE: mt20xx uses V4L2_TUNER_DIGITAL_TV and calls set_tv_freq to + * select a TV frequency. So, t_mode = T_ANALOG_TV could actually + * be used to represent a Digital TV too. */ static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode) { - if ((1 << mode & t->mode_mask) == 0) + int t_mode; + if (mode == V4L2_TUNER_RADIO) + t_mode = T_RADIO; + else + t_mode = T_ANALOG_TV; + + if ((t_mode & t->mode_mask) == 0) return -EINVAL; return 0; @@ -984,7 +993,7 @@ static void tuner_status(struct dvb_frontend *fe) case V4L2_TUNER_RADIO: p = "radio"; break; - case V4L2_TUNER_DIGITAL_TV: + case V4L2_TUNER_DIGITAL_TV: /* Used by mt20xx */ p = "digital TV"; break; case V4L2_TUNER_ANALOG_TV: @@ -1135,9 +1144,8 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) return 0; if (vt->type == t->mode && analog_ops->get_afc) vt->afc = analog_ops->get_afc(&t->fe); - if (vt->type == V4L2_TUNER_ANALOG_TV) + if (t->mode != V4L2_TUNER_RADIO) { vt->capability |= V4L2_TUNER_CAP_NORM; - if (vt->type != V4L2_TUNER_RADIO) { vt->rangelow = tv_range[0] * 16; vt->rangehigh = tv_range[1] * 16; return 0; diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index d7c1bfe4b6ec..536038b22710 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -69,10 +69,7 @@ #include <linux/firmware.h> #include <linux/slab.h> #include <linux/prefetch.h> - -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #include <linux/if_vlan.h> -#endif #ifdef SIOCETHTOOL #include <linux/ethtool.h> @@ -171,15 +168,6 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl); #define BOARD_IDX_STATIC 0 #define BOARD_IDX_OVERFLOW -1 -#if (defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)) && \ - defined(NETIF_F_HW_VLAN_RX) -#define ACENIC_DO_VLAN 1 -#define ACE_RCB_VLAN_FLAG RCB_FLG_VLAN_ASSIST -#else -#define ACENIC_DO_VLAN 0 -#define ACE_RCB_VLAN_FLAG 0 -#endif - #include "acenic.h" /* @@ -465,9 +453,6 @@ static const struct net_device_ops ace_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = ace_set_mac_addr, .ndo_change_mtu = ace_change_mtu, -#if ACENIC_DO_VLAN - .ndo_vlan_rx_register = ace_vlan_rx_register, -#endif }; static int __devinit acenic_probe_one(struct pci_dev *pdev, @@ -491,9 +476,7 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev, ap->name = pci_name(pdev); dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; -#if ACENIC_DO_VLAN dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; -#endif dev->watchdog_timeo = 5*HZ; @@ -1248,7 +1231,7 @@ static int __devinit ace_init(struct net_device *dev) set_aceaddr(&info->rx_std_ctrl.rngptr, ap->rx_ring_base_dma); info->rx_std_ctrl.max_len = ACE_STD_BUFSIZE; info->rx_std_ctrl.flags = - RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG; + RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | RCB_FLG_VLAN_ASSIST; memset(ap->rx_std_ring, 0, RX_STD_RING_ENTRIES * sizeof(struct rx_desc)); @@ -1264,7 +1247,7 @@ static int __devinit ace_init(struct net_device *dev) (sizeof(struct rx_desc) * RX_STD_RING_ENTRIES))); info->rx_jumbo_ctrl.max_len = 0; info->rx_jumbo_ctrl.flags = - RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG; + RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | RCB_FLG_VLAN_ASSIST; memset(ap->rx_jumbo_ring, 0, RX_JUMBO_RING_ENTRIES * sizeof(struct rx_desc)); @@ -1286,7 +1269,7 @@ static int __devinit ace_init(struct net_device *dev) RX_JUMBO_RING_ENTRIES)))); info->rx_mini_ctrl.max_len = ACE_MINI_SIZE; info->rx_mini_ctrl.flags = - RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR|ACE_RCB_VLAN_FLAG; + RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR|RCB_FLG_VLAN_ASSIST; for (i = 0; i < RX_MINI_RING_ENTRIES; i++) ap->rx_mini_ring[i].flags = @@ -1332,7 +1315,7 @@ static int __devinit ace_init(struct net_device *dev) } info->tx_ctrl.max_len = ACE_TX_RING_ENTRIES(ap); - tmp = RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG; + tmp = RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | RCB_FLG_VLAN_ASSIST; /* * The Tigon I does not like having the TX ring in host memory ;-( @@ -1674,7 +1657,7 @@ static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs) struct rx_desc *rd; dma_addr_t mapping; - skb = alloc_skb(ACE_STD_BUFSIZE + NET_IP_ALIGN, GFP_ATOMIC); + skb = dev_alloc_skb(ACE_STD_BUFSIZE + NET_IP_ALIGN); if (!skb) break; @@ -1735,7 +1718,7 @@ static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs) struct rx_desc *rd; dma_addr_t mapping; - skb = alloc_skb(ACE_MINI_BUFSIZE + NET_IP_ALIGN, GFP_ATOMIC); + skb = dev_alloc_skb(ACE_MINI_BUFSIZE + NET_IP_ALIGN); if (!skb) break; @@ -1791,7 +1774,7 @@ static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs) struct rx_desc *rd; dma_addr_t mapping; - skb = alloc_skb(ACE_JUMBO_BUFSIZE + NET_IP_ALIGN, GFP_ATOMIC); + skb = dev_alloc_skb(ACE_JUMBO_BUFSIZE + NET_IP_ALIGN); if (!skb) break; @@ -2038,12 +2021,9 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm) } /* send it up */ -#if ACENIC_DO_VLAN - if (ap->vlgrp && (bd_flags & BD_FLG_VLAN_TAG)) { - vlan_hwaccel_rx(skb, ap->vlgrp, retdesc->vlan); - } else -#endif - netif_rx(skb); + if ((bd_flags & BD_FLG_VLAN_TAG)) + __vlan_hwaccel_put_tag(skb, retdesc->vlan); + netif_rx(skb); dev->stats.rx_packets++; dev->stats.rx_bytes += retdesc->size; @@ -2262,24 +2242,6 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } - -#if ACENIC_DO_VLAN -static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct ace_private *ap = netdev_priv(dev); - unsigned long flags; - - local_irq_save(flags); - ace_mask_irq(dev); - - ap->vlgrp = grp; - - ace_unmask_irq(dev); - local_irq_restore(flags); -} -#endif /* ACENIC_DO_VLAN */ - - static int ace_open(struct net_device *dev) { struct ace_private *ap = netdev_priv(dev); @@ -2449,16 +2411,12 @@ ace_load_tx_bd(struct ace_private *ap, struct tx_desc *desc, u64 addr, writel(addr >> 32, &io->addr.addrhi); writel(addr & 0xffffffff, &io->addr.addrlo); writel(flagsize, &io->flagsize); -#if ACENIC_DO_VLAN writel(vlan_tag, &io->vlanres); -#endif } else { desc->addr.addrhi = addr >> 32; desc->addr.addrlo = addr; desc->flagsize = flagsize; -#if ACENIC_DO_VLAN desc->vlanres = vlan_tag; -#endif } } @@ -2486,12 +2444,10 @@ restart: flagsize = (skb->len << 16) | (BD_FLG_END); if (skb->ip_summed == CHECKSUM_PARTIAL) flagsize |= BD_FLG_TCP_UDP_SUM; -#if ACENIC_DO_VLAN if (vlan_tx_tag_present(skb)) { flagsize |= BD_FLG_VLAN_TAG; vlan_tag = vlan_tx_tag_get(skb); } -#endif desc = ap->tx_ring + idx; idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap); @@ -2509,12 +2465,10 @@ restart: flagsize = (skb_headlen(skb) << 16); if (skb->ip_summed == CHECKSUM_PARTIAL) flagsize |= BD_FLG_TCP_UDP_SUM; -#if ACENIC_DO_VLAN if (vlan_tx_tag_present(skb)) { flagsize |= BD_FLG_VLAN_TAG; vlan_tag = vlan_tx_tag_get(skb); } -#endif ace_load_tx_bd(ap, ap->tx_ring + idx, mapping, flagsize, vlan_tag); diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h index fd25a3b47fef..f67dc9b0eb80 100644 --- a/drivers/net/acenic.h +++ b/drivers/net/acenic.h @@ -665,10 +665,6 @@ struct ace_private struct rx_desc *rx_mini_ring; struct rx_desc *rx_return_ring; -#if ACENIC_DO_VLAN - struct vlan_group *vlgrp; -#endif - int tasklet_pending, jumbo; struct tasklet_struct ace_tasklet; @@ -790,8 +786,5 @@ static void ace_free_descriptors(struct net_device *dev); static void ace_init_cleanup(struct net_device *dev); static struct net_device_stats *ace_get_stats(struct net_device *dev); static int read_eeprom_byte(struct net_device *dev, unsigned long offset); -#if ACENIC_DO_VLAN -static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp); -#endif #endif /* _ACENIC_H_ */ diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index db6d2da5a8f3..78002ef9c0e5 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -661,15 +661,6 @@ static void amd8111e_free_ring(struct amd8111e_priv* lp) } } -#if AMD8111E_VLAN_TAG_USED -/* -This is the receive indication function for packets with vlan tag. -*/ -static int amd8111e_vlan_rx(struct amd8111e_priv *lp, struct sk_buff *skb, u16 vlan_tag) -{ - return vlan_hwaccel_receive_skb(skb, lp->vlgrp,vlan_tag); -} -#endif /* This function will free all the transmit skbs that are actually transmitted by the device. It will check the ownership of the skb before freeing the skb. @@ -764,7 +755,7 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget) #if AMD8111E_VLAN_TAG_USED vtag = status & TT_MASK; /*MAC will strip vlan tag*/ - if(lp->vlgrp != NULL && vtag !=0) + if (vtag != 0) min_pkt_len =MIN_PKT_LEN - 4; else #endif @@ -799,12 +790,12 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget) skb->protocol = eth_type_trans(skb, dev); #if AMD8111E_VLAN_TAG_USED - if(lp->vlgrp != NULL && (vtag == TT_VLAN_TAGGED)){ - amd8111e_vlan_rx(lp, skb, - le16_to_cpu(lp->rx_ring[rx_index].tag_ctrl_info)); - } else + if (vtag == TT_VLAN_TAGGED){ + u16 vlan_tag = le16_to_cpu(lp->rx_ring[rx_index].tag_ctrl_info); + __vlan_hwaccel_put_tag(skb, vlan_tag); + } #endif - netif_receive_skb(skb); + netif_receive_skb(skb); /*COAL update rx coalescing parameters*/ lp->coal_conf.rx_packets++; lp->coal_conf.rx_bytes += pkt_len; @@ -1598,16 +1589,6 @@ static int amd8111e_change_mtu(struct net_device *dev, int new_mtu) return err; } -#if AMD8111E_VLAN_TAG_USED -static void amd8111e_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct amd8111e_priv *lp = netdev_priv(dev); - spin_lock_irq(&lp->lock); - lp->vlgrp = grp; - spin_unlock_irq(&lp->lock); -} -#endif - static int amd8111e_enable_magicpkt(struct amd8111e_priv* lp) { writel( VAL1|MPPLBA, lp->mmio + CMD3); @@ -1822,9 +1803,6 @@ static const struct net_device_ops amd8111e_netdev_ops = { .ndo_set_mac_address = amd8111e_set_mac_address, .ndo_do_ioctl = amd8111e_ioctl, .ndo_change_mtu = amd8111e_change_mtu, -#if AMD8111E_VLAN_TAG_USED - .ndo_vlan_rx_register = amd8111e_vlan_rx_register, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = amd8111e_poll, #endif diff --git a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h index b5926af03a7e..2ff2e7a12dd0 100644 --- a/drivers/net/amd8111e.h +++ b/drivers/net/amd8111e.h @@ -783,9 +783,6 @@ struct amd8111e_priv{ struct net_device *next; int mii; struct mii_if_info mii_if; -#if AMD8111E_VLAN_TAG_USED - struct vlan_group *vlgrp; -#endif char opened; unsigned int drv_rx_errors; struct amd8111e_coalesce_conf coal_conf; diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h index 0f481b983bcf..ca70e16b6e2c 100644 --- a/drivers/net/atl1c/atl1c.h +++ b/drivers/net/atl1c/atl1c.h @@ -555,7 +555,6 @@ struct atl1c_smb { struct atl1c_adapter { struct net_device *netdev; struct pci_dev *pdev; - struct vlan_group *vlgrp; struct napi_struct napi; struct atl1c_hw hw; struct atl1c_hw_stats hw_stats; diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 1269ba5d6e56..972244218408 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -411,29 +411,29 @@ static void atl1c_set_multi(struct net_device *netdev) } } -static void atl1c_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) +static void __atl1c_vlan_mode(u32 features, u32 *mac_ctrl_data) +{ + if (features & NETIF_F_HW_VLAN_RX) { + /* enable VLAN tag insert/strip */ + *mac_ctrl_data |= MAC_CTRL_RMV_VLAN; + } else { + /* disable VLAN tag insert/strip */ + *mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN; + } +} + +static void atl1c_vlan_mode(struct net_device *netdev, u32 features) { struct atl1c_adapter *adapter = netdev_priv(netdev); struct pci_dev *pdev = adapter->pdev; u32 mac_ctrl_data = 0; if (netif_msg_pktdata(adapter)) - dev_dbg(&pdev->dev, "atl1c_vlan_rx_register\n"); + dev_dbg(&pdev->dev, "atl1c_vlan_mode\n"); atl1c_irq_disable(adapter); - - adapter->vlgrp = grp; AT_READ_REG(&adapter->hw, REG_MAC_CTRL, &mac_ctrl_data); - - if (grp) { - /* enable VLAN tag insert/strip */ - mac_ctrl_data |= MAC_CTRL_RMV_VLAN; - } else { - /* disable VLAN tag insert/strip */ - mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN; - } - + __atl1c_vlan_mode(features, &mac_ctrl_data); AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data); atl1c_irq_enable(adapter); } @@ -443,9 +443,10 @@ static void atl1c_restore_vlan(struct atl1c_adapter *adapter) struct pci_dev *pdev = adapter->pdev; if (netif_msg_pktdata(adapter)) - dev_dbg(&pdev->dev, "atl1c_restore_vlan !"); - atl1c_vlan_rx_register(adapter->netdev, adapter->vlgrp); + dev_dbg(&pdev->dev, "atl1c_restore_vlan\n"); + atl1c_vlan_mode(adapter->netdev, adapter->netdev->features); } + /* * atl1c_set_mac - Change the Ethernet Address of the NIC * @netdev: network interface device structure @@ -483,12 +484,31 @@ static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter, static u32 atl1c_fix_features(struct net_device *netdev, u32 features) { + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + if (netdev->mtu > MAX_TSO_FRAME_SIZE) features &= ~(NETIF_F_TSO | NETIF_F_TSO6); return features; } +static int atl1c_set_features(struct net_device *netdev, u32 features) +{ + u32 changed = netdev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + atl1c_vlan_mode(netdev, features); + + return 0; +} + /* * atl1c_change_mtu - Change the Maximum Transfer Unit * @netdev: network interface device structure @@ -1433,8 +1453,7 @@ static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter) mac_ctrl_data |= ((hw->preamble_len & MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); - if (adapter->vlgrp) - mac_ctrl_data |= MAC_CTRL_RMV_VLAN; + __atl1c_vlan_mode(netdev->features, &mac_ctrl_data); mac_ctrl_data |= MAC_CTRL_BC_EN; if (netdev->flags & IFF_PROMISC) @@ -1878,14 +1897,14 @@ rrs_checked: skb_put(skb, length - ETH_FCS_LEN); skb->protocol = eth_type_trans(skb, netdev); atl1c_rx_checksum(adapter, skb, rrs); - if (unlikely(adapter->vlgrp) && rrs->word3 & RRS_VLAN_INS) { + if (rrs->word3 & RRS_VLAN_INS) { u16 vlan; AT_TAG_TO_VLAN(rrs->vlan_tag, vlan); vlan = le16_to_cpu(vlan); - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vlan); - } else - netif_receive_skb(skb); + __vlan_hwaccel_put_tag(skb, vlan); + } + netif_receive_skb(skb); (*work_done)++; count++; @@ -2507,8 +2526,7 @@ static int atl1c_suspend(struct device *dev) /* clear phy interrupt */ atl1c_read_phy_reg(hw, MII_ISR, &mii_intr_status_data); /* Config MAC Ctrl register */ - if (adapter->vlgrp) - mac_ctrl_data |= MAC_CTRL_RMV_VLAN; + __atl1c_vlan_mode(netdev->features, &mac_ctrl_data); /* magic packet maybe Broadcast&multicast&Unicast frame */ if (wufc & AT_WUFC_MAG) @@ -2581,14 +2599,14 @@ static const struct net_device_ops atl1c_netdev_ops = { .ndo_stop = atl1c_close, .ndo_validate_addr = eth_validate_addr, .ndo_start_xmit = atl1c_xmit_frame, - .ndo_set_mac_address = atl1c_set_mac_addr, + .ndo_set_mac_address = atl1c_set_mac_addr, .ndo_set_multicast_list = atl1c_set_multi, .ndo_change_mtu = atl1c_change_mtu, .ndo_fix_features = atl1c_fix_features, + .ndo_set_features = atl1c_set_features, .ndo_do_ioctl = atl1c_ioctl, .ndo_tx_timeout = atl1c_tx_timeout, .ndo_get_stats = atl1c_get_stats, - .ndo_vlan_rx_register = atl1c_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = atl1c_netpoll, #endif @@ -2607,11 +2625,11 @@ static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev) /* TODO: add when ready */ netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | - NETIF_F_HW_VLAN_TX | + NETIF_F_HW_VLAN_RX | NETIF_F_TSO | NETIF_F_TSO6; netdev->features = netdev->hw_features | - NETIF_F_HW_VLAN_RX; + NETIF_F_HW_VLAN_TX; return 0; } diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h index 8c8181b53286..829b5ad71d0d 100644 --- a/drivers/net/atl1e/atl1e.h +++ b/drivers/net/atl1e/atl1e.h @@ -433,7 +433,6 @@ struct atl1e_rx_ring { struct atl1e_adapter { struct net_device *netdev; struct pci_dev *pdev; - struct vlan_group *vlgrp; struct napi_struct napi; struct mii_if_info mii; /* MII interface info */ struct atl1e_hw hw; diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index c3c5db13cf22..d8d411998fa3 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -313,8 +313,18 @@ static void atl1e_set_multi(struct net_device *netdev) } } -static void atl1e_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) +static void __atl1e_vlan_mode(u32 features, u32 *mac_ctrl_data) +{ + if (features & NETIF_F_HW_VLAN_RX) { + /* enable VLAN tag insert/strip */ + *mac_ctrl_data |= MAC_CTRL_RMV_VLAN; + } else { + /* disable VLAN tag insert/strip */ + *mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN; + } +} + +static void atl1e_vlan_mode(struct net_device *netdev, u32 features) { struct atl1e_adapter *adapter = netdev_priv(netdev); u32 mac_ctrl_data = 0; @@ -322,18 +332,8 @@ static void atl1e_vlan_rx_register(struct net_device *netdev, netdev_dbg(adapter->netdev, "%s\n", __func__); atl1e_irq_disable(adapter); - - adapter->vlgrp = grp; mac_ctrl_data = AT_READ_REG(&adapter->hw, REG_MAC_CTRL); - - if (grp) { - /* enable VLAN tag insert/strip */ - mac_ctrl_data |= MAC_CTRL_RMV_VLAN; - } else { - /* disable VLAN tag insert/strip */ - mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN; - } - + __atl1e_vlan_mode(features, &mac_ctrl_data); AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data); atl1e_irq_enable(adapter); } @@ -341,8 +341,9 @@ static void atl1e_vlan_rx_register(struct net_device *netdev, static void atl1e_restore_vlan(struct atl1e_adapter *adapter) { netdev_dbg(adapter->netdev, "%s\n", __func__); - atl1e_vlan_rx_register(adapter->netdev, adapter->vlgrp); + atl1e_vlan_mode(adapter->netdev, adapter->netdev->features); } + /* * atl1e_set_mac - Change the Ethernet Address of the NIC * @netdev: network interface device structure @@ -369,6 +370,30 @@ static int atl1e_set_mac_addr(struct net_device *netdev, void *p) return 0; } +static u32 atl1e_fix_features(struct net_device *netdev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int atl1e_set_features(struct net_device *netdev, u32 features) +{ + u32 changed = netdev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + atl1e_vlan_mode(netdev, features); + + return 0; +} + /* * atl1e_change_mtu - Change the Maximum Transfer Unit * @netdev: network interface device structure @@ -1039,8 +1064,7 @@ static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter) value |= (((u32)adapter->hw.preamble_len & MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); - if (adapter->vlgrp) - value |= MAC_CTRL_RMV_VLAN; + __atl1e_vlan_mode(netdev->features, &value); value |= MAC_CTRL_BC_EN; if (netdev->flags & IFF_PROMISC) @@ -1423,19 +1447,16 @@ static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que, skb->protocol = eth_type_trans(skb, netdev); atl1e_rx_checksum(adapter, skb, prrs); - if (unlikely(adapter->vlgrp && - (prrs->pkt_flag & RRS_IS_VLAN_TAG))) { + if (prrs->pkt_flag & RRS_IS_VLAN_TAG) { u16 vlan_tag = (prrs->vtag >> 4) | ((prrs->vtag & 7) << 13) | ((prrs->vtag & 8) << 9); netdev_dbg(netdev, "RXD VLAN TAG<RRD>=0x%04x\n", prrs->vtag); - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, - vlan_tag); - } else { - netif_receive_skb(skb); + __vlan_hwaccel_put_tag(skb, vlan_tag); } + netif_receive_skb(skb); skip_pkt: /* skip current packet whether it's ok or not. */ @@ -1811,7 +1832,7 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb, tpd = atl1e_get_tpd(adapter); - if (unlikely(vlan_tx_tag_present(skb))) { + if (vlan_tx_tag_present(skb)) { u16 vlan_tag = vlan_tx_tag_get(skb); u16 atl1e_vlan_tag; @@ -2093,8 +2114,7 @@ static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state) MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); - if (adapter->vlgrp) - mac_ctrl_data |= MAC_CTRL_RMV_VLAN; + __atl1e_vlan_mode(netdev->features, &mac_ctrl_data); /* magic packet maybe Broadcast&multicast&Unicast frame */ if (wufc & AT_WUFC_MAG) @@ -2195,10 +2215,11 @@ static const struct net_device_ops atl1e_netdev_ops = { .ndo_set_multicast_list = atl1e_set_multi, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = atl1e_set_mac_addr, + .ndo_fix_features = atl1e_fix_features, + .ndo_set_features = atl1e_set_features, .ndo_change_mtu = atl1e_change_mtu, .ndo_do_ioctl = atl1e_ioctl, .ndo_tx_timeout = atl1e_tx_timeout, - .ndo_vlan_rx_register = atl1e_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = atl1e_netpoll, #endif @@ -2217,9 +2238,9 @@ static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev) atl1e_set_ethtool_ops(netdev); netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO | - NETIF_F_HW_VLAN_TX; - netdev->features = netdev->hw_features | - NETIF_F_HW_VLAN_RX | NETIF_F_LLTX; + NETIF_F_HW_VLAN_RX; + netdev->features = netdev->hw_features | NETIF_F_LLTX | + NETIF_F_HW_VLAN_TX; return 0; } diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index cd5789ff3726..6f0e9403004b 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -1285,8 +1285,7 @@ static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter) value |= (((u32) adapter->hw.preamble_len & MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); /* vlan */ - if (adapter->vlgrp) - value |= MAC_CTRL_RMV_VLAN; + __atlx_vlan_mode(netdev->features, &value); /* rx checksum if (adapter->rx_csum) value |= MAC_CTRL_RX_CHKSUM_EN; @@ -2023,13 +2022,14 @@ rrd_ok: atl1_rx_checksum(adapter, rrd, skb); skb->protocol = eth_type_trans(skb, adapter->netdev); - if (adapter->vlgrp && (rrd->pkt_flg & PACKET_FLAG_VLAN_INS)) { + if (rrd->pkt_flg & PACKET_FLAG_VLAN_INS) { u16 vlan_tag = (rrd->vlan_tag >> 4) | ((rrd->vlan_tag & 7) << 13) | ((rrd->vlan_tag & 8) << 9); - vlan_hwaccel_rx(skb, adapter->vlgrp, vlan_tag); - } else - netif_rx(skb); + + __vlan_hwaccel_put_tag(skb, vlan_tag); + } + netif_rx(skb); /* let protocol layer free skb */ buffer_info->skb = NULL; @@ -2783,8 +2783,7 @@ static int atl1_suspend(struct device *dev) ctrl |= MAC_CTRL_DUPLX; ctrl |= (((u32)adapter->hw.preamble_len & MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); - if (adapter->vlgrp) - ctrl |= MAC_CTRL_RMV_VLAN; + __atlx_vlan_mode(netdev->features, &ctrl); if (wufc & ATLX_WUFC_MAG) ctrl |= MAC_CTRL_BC_EN; iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL); @@ -2874,9 +2873,10 @@ static const struct net_device_ops atl1_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = atl1_set_mac, .ndo_change_mtu = atl1_change_mtu, + .ndo_fix_features = atlx_fix_features, + .ndo_set_features = atlx_set_features, .ndo_do_ioctl = atlx_ioctl, .ndo_tx_timeout = atlx_tx_timeout, - .ndo_vlan_rx_register = atlx_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = atl1_poll_controller, #endif @@ -2984,7 +2984,8 @@ static int __devinit atl1_probe(struct pci_dev *pdev, netdev->features |= NETIF_F_SG; netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); - netdev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_TSO; + netdev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_TSO | + NETIF_F_HW_VLAN_RX; /* is this valid? see atl1_setup_mac_ctrl() */ netdev->features |= NETIF_F_RXCSUM; diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h index 68de8cbfb3ec..109d6da8be97 100644 --- a/drivers/net/atlx/atl1.h +++ b/drivers/net/atlx/atl1.h @@ -753,7 +753,6 @@ struct atl1_adapter { struct pci_dev *pdev; struct atl1_sft_stats soft_stats; - struct vlan_group *vlgrp; u32 rx_buffer_len; u32 wol; u16 link_speed; diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index 24e15926ceea..e0f87cf1e2ba 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -361,36 +361,59 @@ static inline void atl2_irq_disable(struct atl2_adapter *adapter) synchronize_irq(adapter->pdev->irq); } -#ifdef NETIF_F_HW_VLAN_TX -static void atl2_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) +static void __atl2_vlan_mode(u32 features, u32 *ctrl) +{ + if (features & NETIF_F_HW_VLAN_RX) { + /* enable VLAN tag insert/strip */ + *ctrl |= MAC_CTRL_RMV_VLAN; + } else { + /* disable VLAN tag insert/strip */ + *ctrl &= ~MAC_CTRL_RMV_VLAN; + } +} + +static void atl2_vlan_mode(struct net_device *netdev, u32 features) { struct atl2_adapter *adapter = netdev_priv(netdev); u32 ctrl; atl2_irq_disable(adapter); - adapter->vlgrp = grp; - if (grp) { - /* enable VLAN tag insert/strip */ - ctrl = ATL2_READ_REG(&adapter->hw, REG_MAC_CTRL); - ctrl |= MAC_CTRL_RMV_VLAN; - ATL2_WRITE_REG(&adapter->hw, REG_MAC_CTRL, ctrl); - } else { - /* disable VLAN tag insert/strip */ - ctrl = ATL2_READ_REG(&adapter->hw, REG_MAC_CTRL); - ctrl &= ~MAC_CTRL_RMV_VLAN; - ATL2_WRITE_REG(&adapter->hw, REG_MAC_CTRL, ctrl); - } + ctrl = ATL2_READ_REG(&adapter->hw, REG_MAC_CTRL); + __atl2_vlan_mode(features, &ctrl); + ATL2_WRITE_REG(&adapter->hw, REG_MAC_CTRL, ctrl); atl2_irq_enable(adapter); } static void atl2_restore_vlan(struct atl2_adapter *adapter) { - atl2_vlan_rx_register(adapter->netdev, adapter->vlgrp); + atl2_vlan_mode(adapter->netdev, adapter->netdev->features); +} + +static u32 atl2_fix_features(struct net_device *netdev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int atl2_set_features(struct net_device *netdev, u32 features) +{ + u32 changed = netdev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + atl2_vlan_mode(netdev, features); + + return 0; } -#endif static void atl2_intr_rx(struct atl2_adapter *adapter) { @@ -424,14 +447,13 @@ static void atl2_intr_rx(struct atl2_adapter *adapter) memcpy(skb->data, rxd->packet, rx_size); skb_put(skb, rx_size); skb->protocol = eth_type_trans(skb, netdev); -#ifdef NETIF_F_HW_VLAN_TX - if (adapter->vlgrp && (rxd->status.vlan)) { + if (rxd->status.vlan) { u16 vlan_tag = (rxd->status.vtag>>4) | ((rxd->status.vtag&7) << 13) | ((rxd->status.vtag&8) << 9); - vlan_hwaccel_rx(skb, adapter->vlgrp, vlan_tag); - } else -#endif + + __vlan_hwaccel_put_tag(skb, vlan_tag); + } netif_rx(skb); netdev->stats.rx_bytes += rx_size; netdev->stats.rx_packets++; @@ -704,9 +726,7 @@ static int atl2_open(struct net_device *netdev) atl2_set_multi(netdev); init_ring_ptrs(adapter); -#ifdef NETIF_F_HW_VLAN_TX atl2_restore_vlan(adapter); -#endif if (atl2_configure(adapter)) { err = -EIO; @@ -1082,9 +1102,7 @@ static int atl2_up(struct atl2_adapter *adapter) atl2_set_multi(netdev); init_ring_ptrs(adapter); -#ifdef NETIF_F_HW_VLAN_TX atl2_restore_vlan(adapter); -#endif if (atl2_configure(adapter)) { err = -EIO; @@ -1145,8 +1163,7 @@ static void atl2_setup_mac_ctrl(struct atl2_adapter *adapter) MAC_CTRL_PRMLEN_SHIFT); /* vlan */ - if (adapter->vlgrp) - value |= MAC_CTRL_RMV_VLAN; + __atl2_vlan_mode(netdev->features, &value); /* filter mode */ value |= MAC_CTRL_BC_EN; @@ -1312,9 +1329,10 @@ static const struct net_device_ops atl2_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = atl2_set_mac, .ndo_change_mtu = atl2_change_mtu, + .ndo_fix_features = atl2_fix_features, + .ndo_set_features = atl2_set_features, .ndo_do_ioctl = atl2_ioctl, .ndo_tx_timeout = atl2_tx_timeout, - .ndo_vlan_rx_register = atl2_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = atl2_poll_controller, #endif @@ -1410,7 +1428,7 @@ static int __devinit atl2_probe(struct pci_dev *pdev, err = -EIO; - netdev->hw_features = NETIF_F_SG; + netdev->hw_features = NETIF_F_SG | NETIF_F_HW_VLAN_RX; netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); /* Init PHY as early as possible due to power saving issue */ diff --git a/drivers/net/atlx/atl2.h b/drivers/net/atlx/atl2.h index 927e4de6474d..78344ddf4bf0 100644 --- a/drivers/net/atlx/atl2.h +++ b/drivers/net/atlx/atl2.h @@ -453,9 +453,6 @@ struct atl2_adapter { /* OS defined structs */ struct net_device *netdev; struct pci_dev *pdev; -#ifdef NETIF_F_HW_VLAN_TX - struct vlan_group *vlgrp; -#endif u32 wol; u16 link_speed; u16 link_duplex; diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c index afb7f7dd1bb1..aabcf4b5745a 100644 --- a/drivers/net/atlx/atlx.c +++ b/drivers/net/atlx/atlx.c @@ -211,8 +211,18 @@ static void atlx_link_chg_task(struct work_struct *work) spin_unlock_irqrestore(&adapter->lock, flags); } -static void atlx_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) +static void __atlx_vlan_mode(u32 features, u32 *ctrl) +{ + if (features & NETIF_F_HW_VLAN_RX) { + /* enable VLAN tag insert/strip */ + *ctrl |= MAC_CTRL_RMV_VLAN; + } else { + /* disable VLAN tag insert/strip */ + *ctrl &= ~MAC_CTRL_RMV_VLAN; + } +} + +static void atlx_vlan_mode(struct net_device *netdev, u32 features) { struct atlx_adapter *adapter = netdev_priv(netdev); unsigned long flags; @@ -220,27 +230,40 @@ static void atlx_vlan_rx_register(struct net_device *netdev, spin_lock_irqsave(&adapter->lock, flags); /* atlx_irq_disable(adapter); FIXME: confirm/remove */ - adapter->vlgrp = grp; - - if (grp) { - /* enable VLAN tag insert/strip */ - ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL); - ctrl |= MAC_CTRL_RMV_VLAN; - iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL); - } else { - /* disable VLAN tag insert/strip */ - ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL); - ctrl &= ~MAC_CTRL_RMV_VLAN; - iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL); - } - + ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL); + __atlx_vlan_mode(features, &ctrl); + iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL); /* atlx_irq_enable(adapter); FIXME */ spin_unlock_irqrestore(&adapter->lock, flags); } static void atlx_restore_vlan(struct atlx_adapter *adapter) { - atlx_vlan_rx_register(adapter->netdev, adapter->vlgrp); + atlx_vlan_mode(adapter->netdev, adapter->netdev->features); +} + +static u32 atlx_fix_features(struct net_device *netdev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int atlx_set_features(struct net_device *netdev, u32 features) +{ + u32 changed = netdev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + atlx_vlan_mode(netdev, features); + + return 0; } #endif /* ATLX_C */ diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index f520a5c75032..054fa67bc4e3 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -2390,7 +2390,7 @@ err: } /* Uses mbox */ -int be_cmd_check_native_mode(struct be_adapter *adapter) +int be_cmd_req_native_mode(struct be_adapter *adapter) { struct be_mcc_wrb *wrb; struct be_cmd_req_set_func_cap *req; diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 1151df6b0020..8e4d48824fe9 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -1545,7 +1545,7 @@ extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); extern void be_detect_dump_ue(struct be_adapter *adapter); extern int be_cmd_get_die_temperature(struct be_adapter *adapter); extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); -extern int be_cmd_check_native_mode(struct be_adapter *adapter); +extern int be_cmd_req_native_mode(struct be_adapter *adapter); extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size); extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf); diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index ae2d2622a18e..c411bb1845fd 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2511,6 +2511,8 @@ static int be_setup(struct be_adapter *adapter) int status; u8 mac[ETH_ALEN]; + be_cmd_req_native_mode(adapter); + cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_MULTICAST; @@ -2618,6 +2620,8 @@ static int be_clear(struct be_adapter *adapter) be_cmd_if_destroy(adapter, adapter->if_handle, 0); + adapter->be3_native = 0; + /* tell fw we're done with firing cmds */ be_cmd_fw_clean(adapter); return 0; @@ -3215,8 +3219,6 @@ static int be_get_config(struct be_adapter *adapter) if (status) return status; - be_cmd_check_native_mode(adapter); - if ((num_vfs && adapter->sriov_enabled) || (adapter->function_mode & 0x400) || lancer_chip(adapter) || !be_physfn(adapter)) { diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index fa997bfc2e53..c89c9b28cb7d 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -15,6 +15,7 @@ * All rights reserved * www.brocade.com */ +#include <linux/bitops.h> #include <linux/netdevice.h> #include <linux/skbuff.h> #include <linux/etherdevice.h> @@ -24,6 +25,7 @@ #include <linux/if_ether.h> #include <linux/ip.h> #include <linux/prefetch.h> +#include <linux/if_vlan.h> #include "bnad.h" #include "bna.h" @@ -514,24 +516,16 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget) rcb->rxq->rx_bytes += skb->len; skb->protocol = eth_type_trans(skb, bnad->netdev); - if (bnad->vlan_grp && (flags & BNA_CQ_EF_VLAN)) { - struct bnad_rx_ctrl *rx_ctrl = - (struct bnad_rx_ctrl *)ccb->ctrl; - if (skb->ip_summed == CHECKSUM_UNNECESSARY) - vlan_gro_receive(&rx_ctrl->napi, bnad->vlan_grp, - ntohs(cmpl->vlan_tag), skb); - else - vlan_hwaccel_receive_skb(skb, - bnad->vlan_grp, - ntohs(cmpl->vlan_tag)); - - } else { /* Not VLAN tagged/stripped */ - struct bnad_rx_ctrl *rx_ctrl = - (struct bnad_rx_ctrl *)ccb->ctrl; - if (skb->ip_summed == CHECKSUM_UNNECESSARY) - napi_gro_receive(&rx_ctrl->napi, skb); - else - netif_receive_skb(skb); + if (flags & BNA_CQ_EF_VLAN) + __vlan_hwaccel_put_tag(skb, ntohs(cmpl->vlan_tag)); + + if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + struct bnad_rx_ctrl *rx_ctrl; + + rx_ctrl = (struct bnad_rx_ctrl *) ccb->ctrl; + napi_gro_receive(&rx_ctrl->napi, skb); + } else { + netif_receive_skb(skb); } next: @@ -1981,19 +1975,14 @@ bnad_enable_default_bcast(struct bnad *bnad) static void bnad_restore_vlans(struct bnad *bnad, u32 rx_id) { - u16 vlan_id; + u16 vid; unsigned long flags; - if (!bnad->vlan_grp) - return; - BUG_ON(!(VLAN_N_VID == (BFI_MAX_VLAN + 1))); - for (vlan_id = 0; vlan_id < VLAN_N_VID; vlan_id++) { - if (!vlan_group_get_device(bnad->vlan_grp, vlan_id)) - continue; + for_each_set_bit(vid, bnad->active_vlans, VLAN_N_VID) { spin_lock_irqsave(&bnad->bna_lock, flags); - bna_rx_vlan_add(bnad->rx_info[rx_id].rx, vlan_id); + bna_rx_vlan_add(bnad->rx_info[rx_id].rx, vid); spin_unlock_irqrestore(&bnad->bna_lock, flags); } } @@ -2796,17 +2785,6 @@ bnad_change_mtu(struct net_device *netdev, int new_mtu) } static void -bnad_vlan_rx_register(struct net_device *netdev, - struct vlan_group *vlan_grp) -{ - struct bnad *bnad = netdev_priv(netdev); - - mutex_lock(&bnad->conf_mutex); - bnad->vlan_grp = vlan_grp; - mutex_unlock(&bnad->conf_mutex); -} - -static void bnad_vlan_rx_add_vid(struct net_device *netdev, unsigned short vid) { @@ -2820,6 +2798,7 @@ bnad_vlan_rx_add_vid(struct net_device *netdev, spin_lock_irqsave(&bnad->bna_lock, flags); bna_rx_vlan_add(bnad->rx_info[0].rx, vid); + set_bit(vid, bnad->active_vlans); spin_unlock_irqrestore(&bnad->bna_lock, flags); mutex_unlock(&bnad->conf_mutex); @@ -2838,6 +2817,7 @@ bnad_vlan_rx_kill_vid(struct net_device *netdev, mutex_lock(&bnad->conf_mutex); spin_lock_irqsave(&bnad->bna_lock, flags); + clear_bit(vid, bnad->active_vlans); bna_rx_vlan_del(bnad->rx_info[0].rx, vid); spin_unlock_irqrestore(&bnad->bna_lock, flags); @@ -2887,7 +2867,6 @@ static const struct net_device_ops bnad_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = bnad_set_mac_address, .ndo_change_mtu = bnad_change_mtu, - .ndo_vlan_rx_register = bnad_vlan_rx_register, .ndo_vlan_rx_add_vid = bnad_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = bnad_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h index ccdabad0a40c..7aa550b6182d 100644 --- a/drivers/net/bna/bnad.h +++ b/drivers/net/bna/bnad.h @@ -24,6 +24,7 @@ #include <linux/etherdevice.h> #include <linux/mutex.h> #include <linux/firmware.h> +#include <linux/if_vlan.h> /* Fix for IA64 */ #include <asm/checksum.h> @@ -216,7 +217,7 @@ struct bnad { struct bnad_tx_info tx_info[BNAD_MAX_TXS]; struct bnad_rx_info rx_info[BNAD_MAX_RXS]; - struct vlan_group *vlan_grp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; /* * These q numbers are global only because * they are used to calculate MSIx vectors. diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 3ad9b70ef1b2..4b2b57018a02 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -56,8 +56,8 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.1.10" -#define DRV_MODULE_RELDATE "July 12, 2011" +#define DRV_MODULE_VERSION "2.1.11" +#define DRV_MODULE_RELDATE "July 20, 2011" #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.1.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1a.fw" @@ -8097,7 +8097,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->fw_version[j++] = ' '; for (i = 0; i < 3 && j < 28; i++) { reg = bnx2_reg_rd_ind(bp, addr + i * 4); - reg = swab32(reg); + reg = be32_to_cpu(reg); memcpy(&bp->fw_version[j], ®, 4); j += 4; } diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 53fa8ea983e9..c423504a755f 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -966,6 +966,8 @@ struct bnx2x_slowpath { union { struct function_start_data func_start; + /* pfc configuration for DCBX ramrod */ + struct flow_control_configuration pfc_config; } func_rdata; /* used by dmae command executer */ @@ -980,8 +982,6 @@ struct bnx2x_slowpath { u32 wb_comp; u32 wb_data[4]; - /* pfc configuration for DCBX ramrod */ - struct flow_control_configuration pfc_config; }; #define bnx2x_sp(bp, var) (&bp->slowpath->var) @@ -1104,7 +1104,7 @@ struct bnx2x { #define BP_VN(bp) (BP_E1HVN(bp)) /*remove when approved*/ #define BP_L_ID(bp) (BP_E1HVN(bp) << 2) #define BP_FW_MB_IDX(bp) (BP_PORT(bp) +\ - BP_VN(bp) * (CHIP_IS_E1x(bp) ? 2 : 1)) + BP_VN(bp) * ((CHIP_IS_E1x(bp) || (CHIP_MODE_IS_4_PORT(bp))) ? 2 : 1)) struct net_device *dev; struct pci_dev *pdev; @@ -1417,9 +1417,6 @@ struct bnx2x { char fw_ver[32]; const struct firmware *firmware; - /* LLDP params */ - struct bnx2x_config_lldp_params lldp_config_params; - /* DCB support on/off */ u16 dcb_state; #define BNX2X_DCB_STATE_OFF 0 @@ -1923,6 +1920,9 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY | \ AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY) +#define HW_PRTY_ASSERT_SET_4 (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR) + #define RSS_FLAGS(bp) \ (TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY | \ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY | \ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index b05ce9306dea..5b0dba6d4efa 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -676,7 +676,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) /* non TPA */ len = le16_to_cpu(cqe_fp->pkt_len); pad = cqe_fp->placement_offset; - dma_sync_single_for_device(&bp->pdev->dev, + dma_sync_single_for_cpu(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), pad + RX_COPY_THRESH, DMA_FROM_DEVICE); @@ -1828,6 +1828,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) rc = bnx2x_func_start(bp); if (rc) { BNX2X_ERR("Function start failed!\n"); + bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); LOAD_ERROR_EXIT(bp, load_error3); } @@ -1988,6 +1989,9 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) return -EINVAL; } + /* Stop Tx */ + bnx2x_tx_disable(bp); + #ifdef BCM_CNIC bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD); #endif @@ -1996,9 +2000,6 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bp->rx_mode = BNX2X_RX_MODE_NONE; - /* Stop Tx */ - bnx2x_tx_disable(bp); - del_timer_sync(&bp->timer); /* Set ALWAYS_ALIVE bit in shmem */ @@ -2041,6 +2042,9 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) */ bnx2x_squeeze_objects(bp); + /* There should be no more pending SP commands at this stage */ + bp->sp_state = 0; + bp->port.pmf = 0; /* Free SKBs, SGEs, TPA pool and driver internals */ @@ -3326,6 +3330,29 @@ int bnx2x_get_link_cfg_idx(struct bnx2x *bp) return LINK_CONFIG_IDX(sel_phy_idx); } +#if defined(NETDEV_FCOE_WWNN) && defined(BCM_CNIC) +int bnx2x_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type) +{ + struct bnx2x *bp = netdev_priv(dev); + struct cnic_eth_dev *cp = &bp->cnic_eth_dev; + + switch (type) { + case NETDEV_FCOE_WWNN: + *wwn = HILO_U64(cp->fcoe_wwn_node_name_hi, + cp->fcoe_wwn_node_name_lo); + break; + case NETDEV_FCOE_WWPN: + *wwn = HILO_U64(cp->fcoe_wwn_port_name_hi, + cp->fcoe_wwn_port_name_lo); + break; + default: + return -EINVAL; + } + + return 0; +} +#endif + /* called with rtnl_lock */ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) { diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 595d4cdada3e..223bfeebc597 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -522,6 +522,17 @@ void bnx2x_free_mem_bp(struct bnx2x *bp); */ int bnx2x_change_mtu(struct net_device *dev, int new_mtu); +#if defined(BCM_CNIC) && (defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)) +/** + * bnx2x_fcoe_get_wwn - return the requested WWN value for this port + * + * @dev: net_device + * @wwn: output buffer + * @type: WWN type: NETDEV_FCOE_WWNN (node) or NETDEV_FCOE_WWPN (port) + * + */ +int bnx2x_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type); +#endif u32 bnx2x_fix_features(struct net_device *dev, u32 features); int bnx2x_set_features(struct net_device *dev, u32 features); @@ -936,16 +947,11 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, u16 cons, u16 prod) { - struct bnx2x *bp = fp->bp; struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod]; struct eth_rx_bd *cons_bd = &fp->rx_desc_ring[cons]; struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod]; - dma_sync_single_for_device(&bp->pdev->dev, - dma_unmap_addr(cons_rx_buf, mapping), - RX_COPY_THRESH, DMA_FROM_DEVICE); - dma_unmap_addr_set(prod_rx_buf, mapping, dma_unmap_addr(cons_rx_buf, mapping)); prod_rx_buf->skb = cons_rx_buf->skb; diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c index 3bfba44961d3..d028794a2298 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.c +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -29,10 +29,10 @@ #endif /* forward declarations of dcbx related functions */ -static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp); +static int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp); static void bnx2x_pfc_set_pfc(struct bnx2x *bp); static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp); -static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp); +static int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp); static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp, u32 *set_configuration_ets_pg, u32 *pri_pg_tbl); @@ -47,8 +47,25 @@ static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp, struct cos_help_data *cos_data, u32 *pg_pri_orginal_spread, struct dcbx_ets_feature *ets); -static void bnx2x_dcbx_fw_struct(struct bnx2x *bp); +static void bnx2x_dcbx_fw_struct(struct bnx2x *bp, + struct bnx2x_func_tx_start_params*); +/* helpers: read/write len bytes from addr into buff by REG_RD/REG_WR */ +static void bnx2x_read_data(struct bnx2x *bp, u32 *buff, + u32 addr, u32 len) +{ + int i; + for (i = 0; i < len; i += 4, buff++) + *buff = REG_RD(bp, addr + i); +} + +static void bnx2x_write_data(struct bnx2x *bp, u32 *buff, + u32 addr, u32 len) +{ + int i; + for (i = 0; i < len; i += 4, buff++) + REG_WR(bp, addr + i, *buff); +} static void bnx2x_pfc_set(struct bnx2x *bp) { @@ -205,7 +222,11 @@ static void bnx2x_dcbx_get_ap_feature(struct bnx2x *bp, if (GET_FLAGS(error, DCBX_LOCAL_APP_ERROR)) DP(NETIF_MSG_LINK, "DCBX_LOCAL_APP_ERROR\n"); - if (app->enabled && !GET_FLAGS(error, DCBX_LOCAL_APP_ERROR)) { + if (GET_FLAGS(error, DCBX_LOCAL_APP_MISMATCH)) + DP(NETIF_MSG_LINK, "DCBX_LOCAL_APP_MISMATCH\n"); + + if (app->enabled && + !GET_FLAGS(error, DCBX_LOCAL_APP_ERROR | DCBX_LOCAL_APP_MISMATCH)) { bp->dcbx_port_params.app.enabled = true; @@ -300,7 +321,7 @@ static void bnx2x_dcbx_get_pfc_feature(struct bnx2x *bp, DP(NETIF_MSG_LINK, "DCBX_LOCAL_PFC_ERROR\n"); if (bp->dcbx_port_params.app.enabled && - !GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR) && + !GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR | DCBX_LOCAL_PFC_MISMATCH) && pfc->enabled) { bp->dcbx_port_params.pfc.enabled = true; bp->dcbx_port_params.pfc.priority_non_pauseable_mask = @@ -329,8 +350,8 @@ static int bnx2x_dcbx_read_mib(struct bnx2x *bp, u32 offset, int read_mib_type) { - int max_try_read = 0, i; - u32 *buff, mib_size, prefix_seq_num, suffix_seq_num; + int max_try_read = 0; + u32 mib_size, prefix_seq_num, suffix_seq_num; struct lldp_remote_mib *remote_mib ; struct lldp_local_mib *local_mib; @@ -349,9 +370,7 @@ static int bnx2x_dcbx_read_mib(struct bnx2x *bp, offset += BP_PORT(bp) * mib_size; do { - buff = base_mib_addr; - for (i = 0; i < mib_size; i += 4, buff++) - *buff = REG_RD(bp, offset + i); + bnx2x_read_data(bp, base_mib_addr, offset, mib_size); max_try_read++; @@ -382,12 +401,8 @@ static int bnx2x_dcbx_read_mib(struct bnx2x *bp, static void bnx2x_pfc_set_pfc(struct bnx2x *bp) { - if (BP_PORT(bp)) { - BNX2X_ERR("4 port mode is not supported"); - return; - } - - if (bp->dcbx_port_params.pfc.enabled) + if (bp->dcbx_port_params.pfc.enabled && + !(bp->dcbx_error & DCBX_REMOTE_MIB_ERROR)) /* * 1. Fills up common PFC structures if required * 2. Configure NIG, MAC and BRB via the elink @@ -397,25 +412,30 @@ static void bnx2x_pfc_set_pfc(struct bnx2x *bp) bnx2x_pfc_clear(bp); } -static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp) +static int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp) { - DP(NETIF_MSG_LINK, "sending STOP TRAFFIC\n"); - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, - 0 /* connectionless */, - 0 /* dataHi is zero */, - 0 /* dataLo is zero */, - NONE_CONNECTION_TYPE); + struct bnx2x_func_state_params func_params = {0}; + + func_params.f_obj = &bp->func_obj; + func_params.cmd = BNX2X_F_CMD_TX_STOP; + + DP(NETIF_MSG_LINK, "STOP TRAFFIC\n"); + return bnx2x_func_state_change(bp, &func_params); } -static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp) +static int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp) { - bnx2x_dcbx_fw_struct(bp); - DP(NETIF_MSG_LINK, "sending START TRAFFIC\n"); - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC, - 0, /* connectionless */ - U64_HI(bnx2x_sp_mapping(bp, pfc_config)), - U64_LO(bnx2x_sp_mapping(bp, pfc_config)), - NONE_CONNECTION_TYPE); + struct bnx2x_func_state_params func_params = {0}; + struct bnx2x_func_tx_start_params *tx_params = + &func_params.params.tx_start; + + func_params.f_obj = &bp->func_obj; + func_params.cmd = BNX2X_F_CMD_TX_START; + + bnx2x_dcbx_fw_struct(bp, tx_params); + + DP(NETIF_MSG_LINK, "START TRAFFIC\n"); + return bnx2x_func_state_change(bp, &func_params); } static void bnx2x_dcbx_2cos_limit_update_ets_config(struct bnx2x *bp) @@ -522,7 +542,8 @@ static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp) { bnx2x_ets_disabled(&bp->link_params, &bp->link_vars); - if (!bp->dcbx_port_params.ets.enabled) + if (!bp->dcbx_port_params.ets.enabled || + (bp->dcbx_error & DCBX_REMOTE_MIB_ERROR)) return; if (CHIP_IS_E3B0(bp)) @@ -739,61 +760,14 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) } } - -#define LLDP_STATS_OFFSET(bp) (BP_PORT(bp)*\ - sizeof(struct lldp_dcbx_stat)) - -/* calculate struct offset in array according to chip information */ -#define LLDP_PARAMS_OFFSET(bp) (BP_PORT(bp)*sizeof(struct lldp_params)) - #define LLDP_ADMIN_MIB_OFFSET(bp) (PORT_MAX*sizeof(struct lldp_params) + \ BP_PORT(bp)*sizeof(struct lldp_admin_mib)) -static void bnx2x_dcbx_lldp_updated_params(struct bnx2x *bp, - u32 dcbx_lldp_params_offset) -{ - struct lldp_params lldp_params = {0}; - u32 i = 0, *buff = NULL; - u32 offset = dcbx_lldp_params_offset + LLDP_PARAMS_OFFSET(bp); - - DP(NETIF_MSG_LINK, "lldp_offset 0x%x\n", offset); - - if ((bp->lldp_config_params.overwrite_settings == - BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE)) { - /* Read the data first */ - buff = (u32 *)&lldp_params; - for (i = 0; i < sizeof(struct lldp_params); i += 4, buff++) - *buff = REG_RD(bp, (offset + i)); - - lldp_params.msg_tx_hold = - (u8)bp->lldp_config_params.msg_tx_hold; - lldp_params.msg_fast_tx_interval = - (u8)bp->lldp_config_params.msg_fast_tx; - lldp_params.tx_crd_max = - (u8)bp->lldp_config_params.tx_credit_max; - lldp_params.msg_tx_interval = - (u8)bp->lldp_config_params.msg_tx_interval; - lldp_params.tx_fast = - (u8)bp->lldp_config_params.tx_fast; - - /* Write the data.*/ - buff = (u32 *)&lldp_params; - for (i = 0; i < sizeof(struct lldp_params); i += 4, buff++) - REG_WR(bp, (offset + i) , *buff); - - - } else if (BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == - bp->lldp_config_params.overwrite_settings) - bp->lldp_config_params.overwrite_settings = - BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID; -} - static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, u32 dcbx_lldp_params_offset) { struct lldp_admin_mib admin_mib; u32 i, other_traf_type = PREDEFINED_APP_IDX_MAX, traf_type = 0; - u32 *buff; u32 offset = dcbx_lldp_params_offset + LLDP_ADMIN_MIB_OFFSET(bp); /*shortcuts*/ @@ -801,18 +775,18 @@ static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, struct bnx2x_config_dcbx_params *dp = &bp->dcbx_config_params; memset(&admin_mib, 0, sizeof(struct lldp_admin_mib)); - buff = (u32 *)&admin_mib; + /* Read the data first */ - for (i = 0; i < sizeof(struct lldp_admin_mib); i += 4, buff++) - *buff = REG_RD(bp, (offset + i)); + bnx2x_read_data(bp, (u32 *)&admin_mib, offset, + sizeof(struct lldp_admin_mib)); if (bp->dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_ON) SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); else RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); - if ((BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == - dp->overwrite_settings)) { + if (dp->overwrite_settings == BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE) { + RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_CEE_VERSION_MASK); admin_mib.ver_cfg_flags |= (dp->admin_dcbx_version << DCBX_CEE_VERSION_SHIFT) & @@ -908,19 +882,17 @@ static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, af->app.default_pri = (u8)dp->admin_default_priority; - } else if (BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == - dp->overwrite_settings) - dp->overwrite_settings = BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID; + } /* Write the data. */ - buff = (u32 *)&admin_mib; - for (i = 0; i < sizeof(struct lldp_admin_mib); i += 4, buff++) - REG_WR(bp, (offset + i), *buff); + bnx2x_write_data(bp, (u32 *)&admin_mib, offset, + sizeof(struct lldp_admin_mib)); + } void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled) { - if (!CHIP_IS_E1x(bp) && !CHIP_MODE_IS_4_PORT(bp)) { + if (!CHIP_IS_E1x(bp)) { bp->dcb_state = dcb_on; bp->dcbx_enabled = dcbx_enabled; } else { @@ -1029,9 +1001,6 @@ void bnx2x_dcbx_init(struct bnx2x *bp) bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0); if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) { - bnx2x_dcbx_lldp_updated_params(bp, - dcbx_lldp_params_offset); - bnx2x_dcbx_admin_mib_updated_params(bp, dcbx_lldp_params_offset); @@ -1043,7 +1012,7 @@ void bnx2x_dcbx_init(struct bnx2x *bp) } static void bnx2x_dcbx_print_cos_params(struct bnx2x *bp, - struct flow_control_configuration *pfc_fw_cfg) + struct bnx2x_func_tx_start_params *pfc_fw_cfg) { u8 pri = 0; u8 cos = 0; @@ -1821,17 +1790,19 @@ static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp, } } -static void bnx2x_dcbx_fw_struct(struct bnx2x *bp) +static void bnx2x_dcbx_fw_struct(struct bnx2x *bp, + struct bnx2x_func_tx_start_params *pfc_fw_cfg) { - struct flow_control_configuration *pfc_fw_cfg = NULL; u16 pri_bit = 0; u8 cos = 0, pri = 0; struct priority_cos *tt2cos; u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; - pfc_fw_cfg = (struct flow_control_configuration *) - bnx2x_sp(bp, pfc_config); - memset(pfc_fw_cfg, 0, sizeof(struct flow_control_configuration)); + memset(pfc_fw_cfg, 0, sizeof(*pfc_fw_cfg)); + + /* to disable DCB - the structure must be zeroed */ + if (bp->dcbx_error & DCBX_REMOTE_MIB_ERROR) + return; /*shortcut*/ tt2cos = pfc_fw_cfg->traffic_type_to_priority_cos; diff --git a/drivers/net/bnx2x/bnx2x_dump.h b/drivers/net/bnx2x/bnx2x_dump.h index 407531a9ab13..b983825d0ee9 100644 --- a/drivers/net/bnx2x/bnx2x_dump.h +++ b/drivers/net/bnx2x/bnx2x_dump.h @@ -37,39 +37,78 @@ #define RI_E1H 0x2 #define RI_E2 0x4 #define RI_E3 0x8 +#define RI_E3B0 0x10 #define RI_ONLINE 0x100 +#define RI_OFFLINE 0x0 #define RI_PATH0_DUMP 0x200 #define RI_PATH1_DUMP 0x400 -#define RI_E1_OFFLINE (RI_E1) -#define RI_E1_ONLINE (RI_E1 | RI_ONLINE) -#define RI_E1H_OFFLINE (RI_E1H) -#define RI_E1H_ONLINE (RI_E1H | RI_ONLINE) -#define RI_E2_OFFLINE (RI_E2) -#define RI_E2_ONLINE (RI_E2 | RI_ONLINE) -#define RI_E3_OFFLINE (RI_E3) -#define RI_E3_ONLINE (RI_E3 | RI_ONLINE) -#define RI_E1E1H_OFFLINE (RI_E1 | RI_E1H) -#define RI_E1E1H_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) -#define RI_E1E1HE2_OFFLINE (RI_E1 | RI_E1H | RI_E2) -#define RI_E1E1HE2_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_ONLINE) -#define RI_E1HE2_OFFLINE (RI_E2 | RI_E1H) -#define RI_E1HE2_ONLINE (RI_E2 | RI_E1H | RI_ONLINE) -#define RI_E1E2_OFFLINE (RI_E2 | RI_E1) -#define RI_E1E2_ONLINE (RI_E2 | RI_E1 | RI_ONLINE) -#define RI_E1E3_OFFLINE (RI_E1 | RI_E3) -#define RI_E1E3_ONLINE (RI_E1 | RI_E3 | RI_ONLINE) -#define RI_E1HE3_OFFLINE (RI_E1H | RI_E3) -#define RI_E1HE3_ONLINE (RI_E1H | RI_E3 | RI_ONLINE) -#define RI_E2E3_OFFLINE (RI_E2 | RI_E3) -#define RI_E2E3_ONLINE (RI_E2 | RI_E3 | RI_ONLINE) -#define RI_E1E1HE3_OFFLINE (RI_E1 | RI_E1H | RI_E3) -#define RI_E1E1HE3_ONLINE (RI_E1 | RI_E1H | RI_E3 | RI_ONLINE) -#define RI_E1HE2E3_OFFLINE (RI_E2 | RI_E1H | RI_E3) -#define RI_E1HE2E3_ONLINE (RI_E2 | RI_E1H | RI_E3 | RI_ONLINE) -#define RI_E1E2E3_OFFLINE (RI_E2 | RI_E1 | RI_E3) -#define RI_E1E2E3_ONLINE (RI_E2 | RI_E1 | RI_E3 | RI_ONLINE) -#define RI_ALL_OFFLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3) -#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3 | RI_ONLINE) + +#define RI_E1_ONLINE (RI_E1 | RI_ONLINE) +#define RI_E1H_ONLINE (RI_E1H | RI_ONLINE) +#define RI_E1E1H_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) +#define RI_E2_ONLINE (RI_E2 | RI_ONLINE) +#define RI_E1E2_ONLINE (RI_E1 | RI_E2 | RI_ONLINE) +#define RI_E1HE2_ONLINE (RI_E1H | RI_E2 | RI_ONLINE) +#define RI_E1E1HE2_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_ONLINE) +#define RI_E3_ONLINE (RI_E3 | RI_ONLINE) +#define RI_E1E3_ONLINE (RI_E1 | RI_E3 | RI_ONLINE) +#define RI_E1HE3_ONLINE (RI_E1H | RI_E3 | RI_ONLINE) +#define RI_E1E1HE3_ONLINE (RI_E1 | RI_E1H | RI_E3 | RI_ONLINE) +#define RI_E2E3_ONLINE (RI_E2 | RI_E3 | RI_ONLINE) +#define RI_E1E2E3_ONLINE (RI_E1 | RI_E2 | RI_E3 | RI_ONLINE) +#define RI_E1HE2E3_ONLINE (RI_E1H | RI_E2 | RI_E3 | RI_ONLINE) +#define RI_E1E1HE2E3_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3 | RI_ONLINE) +#define RI_E3B0_ONLINE (RI_E3B0 | RI_ONLINE) +#define RI_E1E3B0_ONLINE (RI_E1 | RI_E3B0 | RI_ONLINE) +#define RI_E1HE3B0_ONLINE (RI_E1H | RI_E3B0 | RI_ONLINE) +#define RI_E1E1HE3B0_ONLINE (RI_E1 | RI_E1H | RI_E3B0 | RI_ONLINE) +#define RI_E2E3B0_ONLINE (RI_E2 | RI_E3B0 | RI_ONLINE) +#define RI_E1E2E3B0_ONLINE (RI_E1 | RI_E2 | RI_E3B0 | RI_ONLINE) +#define RI_E1HE2E3B0_ONLINE (RI_E1H | RI_E2 | RI_E3B0 | RI_ONLINE) +#define RI_E1E1HE2E3B0_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3B0 | RI_ONLINE) +#define RI_E3E3B0_ONLINE (RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1E3E3B0_ONLINE (RI_E1 | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1HE3E3B0_ONLINE (RI_E1H | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1E1HE3E3B0_ONLINE (RI_E1 | RI_E1H | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E2E3E3B0_ONLINE (RI_E2 | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1E2E3E3B0_ONLINE (RI_E1 | RI_E2 | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1HE2E3E3B0_ONLINE (RI_E1H | RI_E2 | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1E1HE2E3E3B0_ONLINE \ + (RI_E1 | RI_E1H | RI_E2 | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1_OFFLINE (RI_E1 | RI_OFFLINE) +#define RI_E1H_OFFLINE (RI_E1H | RI_OFFLINE) +#define RI_E1E1H_OFFLINE (RI_E1 | RI_E1H | RI_OFFLINE) +#define RI_E2_OFFLINE (RI_E2 | RI_OFFLINE) +#define RI_E1E2_OFFLINE (RI_E1 | RI_E2 | RI_OFFLINE) +#define RI_E1HE2_OFFLINE (RI_E1H | RI_E2 | RI_OFFLINE) +#define RI_E1E1HE2_OFFLINE (RI_E1 | RI_E1H | RI_E2 | RI_OFFLINE) +#define RI_E3_OFFLINE (RI_E3 | RI_OFFLINE) +#define RI_E1E3_OFFLINE (RI_E1 | RI_E3 | RI_OFFLINE) +#define RI_E1HE3_OFFLINE (RI_E1H | RI_E3 | RI_OFFLINE) +#define RI_E1E1HE3_OFFLINE (RI_E1 | RI_E1H | RI_E3 | RI_OFFLINE) +#define RI_E2E3_OFFLINE (RI_E2 | RI_E3 | RI_OFFLINE) +#define RI_E1E2E3_OFFLINE (RI_E1 | RI_E2 | RI_E3 | RI_OFFLINE) +#define RI_E1HE2E3_OFFLINE (RI_E1H | RI_E2 | RI_E3 | RI_OFFLINE) +#define RI_E1E1HE2E3_OFFLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3 | RI_OFFLINE) +#define RI_E3B0_OFFLINE (RI_E3B0 | RI_OFFLINE) +#define RI_E1E3B0_OFFLINE (RI_E1 | RI_E3B0 | RI_OFFLINE) +#define RI_E1HE3B0_OFFLINE (RI_E1H | RI_E3B0 | RI_OFFLINE) +#define RI_E1E1HE3B0_OFFLINE (RI_E1 | RI_E1H | RI_E3B0 | RI_OFFLINE) +#define RI_E2E3B0_OFFLINE (RI_E2 | RI_E3B0 | RI_OFFLINE) +#define RI_E1E2E3B0_OFFLINE (RI_E1 | RI_E2 | RI_E3B0 | RI_OFFLINE) +#define RI_E1HE2E3B0_OFFLINE (RI_E1H | RI_E2 | RI_E3B0 | RI_OFFLINE) +#define RI_E1E1HE2E3B0_OFFLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3B0 | RI_OFFLINE) +#define RI_E3E3B0_OFFLINE (RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E1E3E3B0_OFFLINE (RI_E1 | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E1HE3E3B0_OFFLINE (RI_E1H | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E1E1HE3E3B0_OFFLINE (RI_E1 | RI_E1H | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E2E3E3B0_OFFLINE (RI_E2 | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E1E2E3E3B0_OFFLINE (RI_E1 | RI_E2 | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E1HE2E3E3B0_OFFLINE (RI_E1H | RI_E2 | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E1E1HE2E3E3B0_OFFLINE \ + (RI_E1 | RI_E1H | RI_E2 | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_ALL_ONLINE RI_E1E1HE2E3E3B0_ONLINE +#define RI_ALL_OFFLINE RI_E1E1HE2E3E3B0_OFFLINE #define DBG_DMP_TRACE_BUFFER_SIZE 0x800 #define DBG_DMP_TRACE_BUFFER_OFFSET(shmem0_offset) \ @@ -108,716 +147,991 @@ struct wreg_addr { }; static const struct reg_addr reg_addrs[] = { - { 0x2000, 341, RI_ALL_ONLINE }, { 0x2800, 103, RI_ALL_ONLINE }, - { 0x3000, 287, RI_ALL_ONLINE }, { 0x3800, 331, RI_ALL_ONLINE }, - { 0x8800, 6, RI_ALL_ONLINE }, { 0x8818, 1, RI_E1HE2E3_ONLINE }, - { 0x9000, 147, RI_E2E3_ONLINE }, { 0x924c, 1, RI_E2_ONLINE }, - { 0x9250, 16, RI_E2E3_ONLINE }, { 0x9400, 33, RI_E2E3_ONLINE }, - { 0x9484, 5, RI_E3_ONLINE }, { 0xa000, 27, RI_ALL_ONLINE }, - { 0xa06c, 1, RI_E1E1H_ONLINE }, { 0xa070, 71, RI_ALL_ONLINE }, - { 0xa18c, 4, RI_E1E1H_ONLINE }, { 0xa19c, 62, RI_ALL_ONLINE }, - { 0xa294, 2, RI_E1E1H_ONLINE }, { 0xa29c, 2, RI_ALL_ONLINE }, - { 0xa2a4, 2, RI_E1E1HE2_ONLINE }, { 0xa2ac, 52, RI_ALL_ONLINE }, - { 0xa39c, 7, RI_E1HE2E3_ONLINE }, { 0xa3b8, 2, RI_E3_ONLINE }, - { 0xa3c0, 3, RI_E1HE2E3_ONLINE }, { 0xa3d0, 1, RI_E1HE2E3_ONLINE }, - { 0xa3d8, 1, RI_E1HE2E3_ONLINE }, { 0xa3e0, 1, RI_E1HE2E3_ONLINE }, - { 0xa3e8, 1, RI_E1HE2E3_ONLINE }, { 0xa3f0, 1, RI_E1HE2E3_ONLINE }, - { 0xa3f8, 1, RI_E1HE2E3_ONLINE }, { 0xa400, 40, RI_ALL_ONLINE }, - { 0xa4a0, 1, RI_E1E1HE2_ONLINE }, { 0xa4a4, 2, RI_ALL_ONLINE }, - { 0xa4ac, 2, RI_E1E1H_ONLINE }, { 0xa4b4, 1, RI_E1E1HE2_ONLINE }, - { 0xa4b8, 2, RI_E1E1H_ONLINE }, { 0xa4c0, 3, RI_ALL_ONLINE }, - { 0xa4cc, 5, RI_E1E1H_ONLINE }, { 0xa4e0, 3, RI_ALL_ONLINE }, - { 0xa4fc, 2, RI_ALL_ONLINE }, { 0xa504, 1, RI_E1E1H_ONLINE }, - { 0xa508, 3, RI_ALL_ONLINE }, { 0xa518, 1, RI_ALL_ONLINE }, - { 0xa520, 1, RI_ALL_ONLINE }, { 0xa528, 1, RI_ALL_ONLINE }, - { 0xa530, 1, RI_ALL_ONLINE }, { 0xa538, 1, RI_ALL_ONLINE }, - { 0xa540, 1, RI_ALL_ONLINE }, { 0xa548, 1, RI_E1E1H_ONLINE }, - { 0xa550, 1, RI_E1E1H_ONLINE }, { 0xa558, 1, RI_E1E1H_ONLINE }, - { 0xa560, 1, RI_E1E1H_ONLINE }, { 0xa568, 1, RI_E1E1H_ONLINE }, - { 0xa570, 1, RI_ALL_ONLINE }, { 0xa580, 1, RI_ALL_ONLINE }, - { 0xa590, 1, RI_ALL_ONLINE }, { 0xa5a0, 1, RI_E1E1HE2_ONLINE }, - { 0xa5c0, 1, RI_ALL_ONLINE }, { 0xa5e0, 1, RI_E1HE2E3_ONLINE }, - { 0xa5e8, 1, RI_E1HE2E3_ONLINE }, { 0xa5f0, 1, RI_E1HE2E3_ONLINE }, - { 0xa5f8, 1, RI_E1HE2_ONLINE }, { 0xa5fc, 9, RI_E1HE2E3_ONLINE }, - { 0xa620, 6, RI_E2E3_ONLINE }, { 0xa638, 20, RI_E2_ONLINE }, - { 0xa688, 42, RI_E2E3_ONLINE }, { 0xa730, 1, RI_E2_ONLINE }, - { 0xa734, 2, RI_E2E3_ONLINE }, { 0xa73c, 4, RI_E2_ONLINE }, - { 0xa74c, 5, RI_E2E3_ONLINE }, { 0xa760, 5, RI_E2_ONLINE }, - { 0xa774, 7, RI_E2E3_ONLINE }, { 0xa790, 15, RI_E2_ONLINE }, - { 0xa7cc, 4, RI_E2E3_ONLINE }, { 0xa7e0, 6, RI_E3_ONLINE }, - { 0xa800, 18, RI_E2_ONLINE }, { 0xa848, 33, RI_E2E3_ONLINE }, - { 0xa8cc, 2, RI_E3_ONLINE }, { 0xa8d4, 4, RI_E2E3_ONLINE }, - { 0xa8e4, 1, RI_E3_ONLINE }, { 0xa8e8, 1, RI_E2E3_ONLINE }, - { 0xa8f0, 1, RI_E2E3_ONLINE }, { 0xa8f8, 30, RI_E3_ONLINE }, - { 0xa974, 73, RI_E3_ONLINE }, { 0xac30, 1, RI_E3_ONLINE }, - { 0xac40, 1, RI_E3_ONLINE }, { 0xac50, 1, RI_E3_ONLINE }, - { 0x10000, 9, RI_ALL_ONLINE }, { 0x10024, 1, RI_E1E1HE2_ONLINE }, - { 0x10028, 5, RI_ALL_ONLINE }, { 0x1003c, 6, RI_E1E1HE2_ONLINE }, - { 0x10054, 20, RI_ALL_ONLINE }, { 0x100a4, 4, RI_E1E1HE2_ONLINE }, - { 0x100b4, 11, RI_ALL_ONLINE }, { 0x100e0, 4, RI_E1E1HE2_ONLINE }, - { 0x100f0, 8, RI_ALL_ONLINE }, { 0x10110, 6, RI_E1E1HE2_ONLINE }, - { 0x10128, 110, RI_ALL_ONLINE }, { 0x102e0, 4, RI_E1E1HE2_ONLINE }, - { 0x102f0, 18, RI_ALL_ONLINE }, { 0x10338, 20, RI_E1E1HE2_ONLINE }, - { 0x10388, 10, RI_ALL_ONLINE }, { 0x10400, 6, RI_E1E1HE2_ONLINE }, - { 0x10418, 6, RI_ALL_ONLINE }, { 0x10430, 10, RI_E1E1HE2_ONLINE }, - { 0x10458, 22, RI_ALL_ONLINE }, { 0x104b0, 12, RI_E1E1HE2_ONLINE }, - { 0x104e0, 1, RI_ALL_ONLINE }, { 0x104e8, 2, RI_ALL_ONLINE }, - { 0x104f4, 2, RI_ALL_ONLINE }, { 0x10500, 146, RI_ALL_ONLINE }, - { 0x10750, 2, RI_E1E1HE2_ONLINE }, { 0x10760, 2, RI_E1E1HE2_ONLINE }, - { 0x10770, 2, RI_E1E1HE2_ONLINE }, { 0x10780, 2, RI_E1E1HE2_ONLINE }, - { 0x10790, 2, RI_ALL_ONLINE }, { 0x107a0, 2, RI_E1E1HE2_ONLINE }, - { 0x107b0, 2, RI_E1E1HE2_ONLINE }, { 0x107c0, 2, RI_E1E1HE2_ONLINE }, - { 0x107d0, 2, RI_E1E1HE2_ONLINE }, { 0x107e0, 2, RI_ALL_ONLINE }, - { 0x10880, 2, RI_ALL_ONLINE }, { 0x10900, 2, RI_ALL_ONLINE }, - { 0x16000, 1, RI_E1HE2_ONLINE }, { 0x16004, 25, RI_E1HE2E3_ONLINE }, - { 0x16070, 18, RI_E1HE2E3_ONLINE }, { 0x160c0, 7, RI_E1HE2E3_ONLINE }, - { 0x160dc, 2, RI_E1HE2_ONLINE }, { 0x160e4, 10, RI_E1HE2E3_ONLINE }, - { 0x1610c, 2, RI_E1HE2_ONLINE }, { 0x16114, 6, RI_E1HE2E3_ONLINE }, - { 0x16140, 48, RI_E1HE2E3_ONLINE }, { 0x16204, 5, RI_E1HE2E3_ONLINE }, - { 0x18000, 1, RI_E1HE2E3_ONLINE }, { 0x18008, 1, RI_E1HE2E3_ONLINE }, - { 0x18010, 35, RI_E2E3_ONLINE }, { 0x180a4, 2, RI_E2E3_ONLINE }, - { 0x180c0, 109, RI_E2E3_ONLINE }, { 0x18274, 1, RI_E2_ONLINE }, - { 0x18278, 81, RI_E2E3_ONLINE }, { 0x18440, 63, RI_E2E3_ONLINE }, - { 0x18570, 42, RI_E3_ONLINE }, { 0x20000, 24, RI_ALL_ONLINE }, - { 0x20060, 8, RI_ALL_ONLINE }, { 0x20080, 94, RI_ALL_ONLINE }, - { 0x201f8, 1, RI_E1E1H_ONLINE }, { 0x201fc, 1, RI_ALL_ONLINE }, - { 0x20200, 1, RI_E1E1H_ONLINE }, { 0x20204, 1, RI_ALL_ONLINE }, - { 0x20208, 1, RI_E1E1H_ONLINE }, { 0x2020c, 39, RI_ALL_ONLINE }, - { 0x202c8, 1, RI_E2E3_ONLINE }, { 0x202d8, 4, RI_E2E3_ONLINE }, - { 0x20400, 2, RI_ALL_ONLINE }, { 0x2040c, 8, RI_ALL_ONLINE }, - { 0x2042c, 18, RI_E1HE2E3_ONLINE }, { 0x20480, 1, RI_ALL_ONLINE }, - { 0x20500, 1, RI_ALL_ONLINE }, { 0x20600, 1, RI_ALL_ONLINE }, - { 0x28000, 1, RI_ALL_ONLINE }, { 0x28004, 8191, RI_ALL_OFFLINE }, - { 0x30000, 1, RI_ALL_ONLINE }, { 0x30004, 16383, RI_ALL_OFFLINE }, - { 0x40000, 98, RI_ALL_ONLINE }, { 0x401a8, 8, RI_E1HE2E3_ONLINE }, - { 0x401c8, 1, RI_E1H_ONLINE }, { 0x401cc, 2, RI_E1HE2E3_ONLINE }, - { 0x401d4, 2, RI_E2E3_ONLINE }, { 0x40200, 4, RI_ALL_ONLINE }, - { 0x40220, 18, RI_E2E3_ONLINE }, { 0x40268, 2, RI_E3_ONLINE }, - { 0x40400, 43, RI_ALL_ONLINE }, { 0x404cc, 3, RI_E1HE2E3_ONLINE }, - { 0x404e0, 1, RI_E2E3_ONLINE }, { 0x40500, 2, RI_ALL_ONLINE }, - { 0x40510, 2, RI_ALL_ONLINE }, { 0x40520, 2, RI_ALL_ONLINE }, - { 0x40530, 2, RI_ALL_ONLINE }, { 0x40540, 2, RI_ALL_ONLINE }, - { 0x40550, 10, RI_E2E3_ONLINE }, { 0x40610, 2, RI_E2E3_ONLINE }, - { 0x42000, 164, RI_ALL_ONLINE }, { 0x422c0, 4, RI_E2E3_ONLINE }, - { 0x422d4, 5, RI_E1HE2E3_ONLINE }, { 0x422e8, 1, RI_E2E3_ONLINE }, - { 0x42400, 49, RI_ALL_ONLINE }, { 0x424c8, 38, RI_ALL_ONLINE }, - { 0x42568, 2, RI_ALL_ONLINE }, { 0x42640, 5, RI_E2E3_ONLINE }, - { 0x42800, 1, RI_ALL_ONLINE }, { 0x50000, 1, RI_ALL_ONLINE }, - { 0x50004, 19, RI_ALL_ONLINE }, { 0x50050, 8, RI_ALL_ONLINE }, - { 0x50070, 88, RI_ALL_ONLINE }, { 0x501f0, 4, RI_E1HE2E3_ONLINE }, - { 0x50200, 2, RI_ALL_ONLINE }, { 0x5020c, 7, RI_ALL_ONLINE }, - { 0x50228, 6, RI_E1HE2E3_ONLINE }, { 0x50240, 1, RI_ALL_ONLINE }, - { 0x50280, 1, RI_ALL_ONLINE }, { 0x50300, 1, RI_E2E3_ONLINE }, - { 0x5030c, 1, RI_E2E3_ONLINE }, { 0x50318, 1, RI_E2E3_ONLINE }, - { 0x5031c, 1, RI_E2E3_ONLINE }, { 0x50320, 2, RI_E2E3_ONLINE }, - { 0x52000, 1, RI_ALL_ONLINE }, { 0x54000, 1, RI_ALL_ONLINE }, - { 0x54004, 3327, RI_ALL_OFFLINE }, { 0x58000, 1, RI_ALL_ONLINE }, - { 0x58004, 8191, RI_E1E1H_OFFLINE }, { 0x60000, 26, RI_ALL_ONLINE }, - { 0x60068, 8, RI_E1E1H_ONLINE }, { 0x60088, 12, RI_ALL_ONLINE }, - { 0x600b8, 9, RI_E1E1H_ONLINE }, { 0x600dc, 1, RI_ALL_ONLINE }, - { 0x600e0, 5, RI_E1E1H_ONLINE }, { 0x600f4, 1, RI_E1E1HE2_ONLINE }, - { 0x600f8, 1, RI_E1E1H_ONLINE }, { 0x600fc, 8, RI_ALL_ONLINE }, - { 0x6013c, 24, RI_E1H_ONLINE }, { 0x6019c, 2, RI_E2E3_ONLINE }, - { 0x601ac, 18, RI_E2E3_ONLINE }, { 0x60200, 1, RI_ALL_ONLINE }, - { 0x60204, 2, RI_ALL_OFFLINE }, { 0x60210, 13, RI_E2E3_ONLINE }, - { 0x61000, 1, RI_ALL_ONLINE }, { 0x61004, 511, RI_ALL_OFFLINE }, - { 0x61800, 512, RI_E3_OFFLINE }, { 0x70000, 8, RI_ALL_ONLINE }, - { 0x70020, 8184, RI_ALL_OFFLINE }, { 0x78000, 8192, RI_E3_OFFLINE }, - { 0x85000, 3, RI_ALL_ONLINE }, { 0x8501c, 7, RI_ALL_ONLINE }, - { 0x85048, 1, RI_ALL_ONLINE }, { 0x85200, 32, RI_ALL_ONLINE }, + { 0x2000, 341, RI_ALL_ONLINE }, + { 0x2800, 103, RI_ALL_ONLINE }, + { 0x3000, 287, RI_ALL_ONLINE }, + { 0x3800, 331, RI_ALL_ONLINE }, + { 0x8800, 6, RI_ALL_ONLINE }, + { 0x8818, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x9000, 147, RI_E2E3E3B0_ONLINE }, + { 0x924c, 1, RI_E2_ONLINE }, + { 0x9250, 16, RI_E2E3E3B0_ONLINE }, + { 0x9400, 33, RI_E2E3E3B0_ONLINE }, + { 0x9484, 5, RI_E3E3B0_ONLINE }, + { 0xa000, 27, RI_ALL_ONLINE }, + { 0xa06c, 1, RI_E1E1H_ONLINE }, + { 0xa070, 71, RI_ALL_ONLINE }, + { 0xa18c, 4, RI_E1E1H_ONLINE }, + { 0xa19c, 62, RI_ALL_ONLINE }, + { 0xa294, 2, RI_E1E1H_ONLINE }, + { 0xa29c, 2, RI_ALL_ONLINE }, + { 0xa2a4, 2, RI_E1E1HE2_ONLINE }, + { 0xa2ac, 52, RI_ALL_ONLINE }, + { 0xa39c, 7, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3b8, 2, RI_E3E3B0_ONLINE }, + { 0xa3c0, 3, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3d0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3d8, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3e0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3e8, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3f0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3f8, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa400, 40, RI_ALL_ONLINE }, + { 0xa4a0, 1, RI_E1E1HE2_ONLINE }, + { 0xa4a4, 2, RI_ALL_ONLINE }, + { 0xa4ac, 2, RI_E1E1H_ONLINE }, + { 0xa4b4, 1, RI_E1E1HE2_ONLINE }, + { 0xa4b8, 2, RI_E1E1H_ONLINE }, + { 0xa4c0, 3, RI_ALL_ONLINE }, + { 0xa4cc, 5, RI_E1E1H_ONLINE }, + { 0xa4e0, 3, RI_ALL_ONLINE }, + { 0xa4fc, 2, RI_ALL_ONLINE }, + { 0xa504, 1, RI_E1E1H_ONLINE }, + { 0xa508, 3, RI_ALL_ONLINE }, + { 0xa518, 1, RI_ALL_ONLINE }, + { 0xa520, 1, RI_ALL_ONLINE }, + { 0xa528, 1, RI_ALL_ONLINE }, + { 0xa530, 1, RI_ALL_ONLINE }, + { 0xa538, 1, RI_ALL_ONLINE }, + { 0xa540, 1, RI_ALL_ONLINE }, + { 0xa548, 1, RI_E1E1H_ONLINE }, + { 0xa550, 1, RI_E1E1H_ONLINE }, + { 0xa558, 1, RI_E1E1H_ONLINE }, + { 0xa560, 1, RI_E1E1H_ONLINE }, + { 0xa568, 1, RI_E1E1H_ONLINE }, + { 0xa570, 1, RI_ALL_ONLINE }, + { 0xa580, 1, RI_ALL_ONLINE }, + { 0xa590, 1, RI_ALL_ONLINE }, + { 0xa5a0, 1, RI_E1E1HE2_ONLINE }, + { 0xa5c0, 1, RI_ALL_ONLINE }, + { 0xa5e0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa5e8, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa5f0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa5f8, 1, RI_E1HE2_ONLINE }, + { 0xa5fc, 9, RI_E1HE2E3E3B0_ONLINE }, + { 0xa620, 6, RI_E2E3E3B0_ONLINE }, + { 0xa638, 20, RI_E2_ONLINE }, + { 0xa688, 42, RI_E2E3E3B0_ONLINE }, + { 0xa730, 1, RI_E2_ONLINE }, + { 0xa734, 2, RI_E2E3E3B0_ONLINE }, + { 0xa73c, 4, RI_E2_ONLINE }, + { 0xa74c, 5, RI_E2E3E3B0_ONLINE }, + { 0xa760, 5, RI_E2_ONLINE }, + { 0xa774, 7, RI_E2E3E3B0_ONLINE }, + { 0xa790, 15, RI_E2_ONLINE }, + { 0xa7cc, 4, RI_E2E3E3B0_ONLINE }, + { 0xa7e0, 6, RI_E3E3B0_ONLINE }, + { 0xa800, 18, RI_E2_ONLINE }, + { 0xa848, 33, RI_E2E3E3B0_ONLINE }, + { 0xa8cc, 2, RI_E3E3B0_ONLINE }, + { 0xa8d4, 4, RI_E2E3E3B0_ONLINE }, + { 0xa8e4, 1, RI_E3E3B0_ONLINE }, + { 0xa8e8, 1, RI_E2E3E3B0_ONLINE }, + { 0xa8f0, 1, RI_E2E3E3B0_ONLINE }, + { 0xa8f8, 30, RI_E3E3B0_ONLINE }, + { 0xa974, 73, RI_E3E3B0_ONLINE }, + { 0xac30, 1, RI_E3E3B0_ONLINE }, + { 0xac40, 1, RI_E3E3B0_ONLINE }, + { 0xac50, 1, RI_E3E3B0_ONLINE }, + { 0xac60, 1, RI_E3B0_ONLINE }, + { 0x10000, 9, RI_ALL_ONLINE }, + { 0x10024, 1, RI_E1E1HE2_ONLINE }, + { 0x10028, 5, RI_ALL_ONLINE }, + { 0x1003c, 6, RI_E1E1HE2_ONLINE }, + { 0x10054, 20, RI_ALL_ONLINE }, + { 0x100a4, 4, RI_E1E1HE2_ONLINE }, + { 0x100b4, 11, RI_ALL_ONLINE }, + { 0x100e0, 4, RI_E1E1HE2_ONLINE }, + { 0x100f0, 8, RI_ALL_ONLINE }, + { 0x10110, 6, RI_E1E1HE2_ONLINE }, + { 0x10128, 110, RI_ALL_ONLINE }, + { 0x102e0, 4, RI_E1E1HE2_ONLINE }, + { 0x102f0, 18, RI_ALL_ONLINE }, + { 0x10338, 20, RI_E1E1HE2_ONLINE }, + { 0x10388, 10, RI_ALL_ONLINE }, + { 0x10400, 6, RI_E1E1HE2_ONLINE }, + { 0x10418, 6, RI_ALL_ONLINE }, + { 0x10430, 10, RI_E1E1HE2_ONLINE }, + { 0x10458, 22, RI_ALL_ONLINE }, + { 0x104b0, 12, RI_E1E1HE2_ONLINE }, + { 0x104e0, 1, RI_ALL_ONLINE }, + { 0x104e8, 2, RI_ALL_ONLINE }, + { 0x104f4, 2, RI_ALL_ONLINE }, + { 0x10500, 146, RI_ALL_ONLINE }, + { 0x10750, 2, RI_E1E1HE2_ONLINE }, + { 0x10760, 2, RI_E1E1HE2_ONLINE }, + { 0x10770, 2, RI_E1E1HE2_ONLINE }, + { 0x10780, 2, RI_E1E1HE2_ONLINE }, + { 0x10790, 2, RI_ALL_ONLINE }, + { 0x107a0, 2, RI_E1E1HE2_ONLINE }, + { 0x107b0, 2, RI_E1E1HE2_ONLINE }, + { 0x107c0, 2, RI_E1E1HE2_ONLINE }, + { 0x107d0, 2, RI_E1E1HE2_ONLINE }, + { 0x107e0, 2, RI_ALL_ONLINE }, + { 0x10880, 2, RI_ALL_ONLINE }, + { 0x10900, 2, RI_ALL_ONLINE }, + { 0x16000, 1, RI_E1HE2_ONLINE }, + { 0x16004, 25, RI_E1HE2E3E3B0_ONLINE }, + { 0x16070, 8, RI_E1HE2E3E3B0_ONLINE }, + { 0x16090, 4, RI_E1HE2E3_ONLINE }, + { 0x160a0, 6, RI_E1HE2E3E3B0_ONLINE }, + { 0x160c0, 7, RI_E1HE2E3E3B0_ONLINE }, + { 0x160dc, 2, RI_E1HE2_ONLINE }, + { 0x160e4, 10, RI_E1HE2E3E3B0_ONLINE }, + { 0x1610c, 2, RI_E1HE2_ONLINE }, + { 0x16114, 6, RI_E1HE2E3E3B0_ONLINE }, + { 0x16140, 48, RI_E1HE2E3E3B0_ONLINE }, + { 0x16204, 5, RI_E1HE2E3E3B0_ONLINE }, + { 0x18000, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x18008, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x18010, 35, RI_E2E3E3B0_ONLINE }, + { 0x180a4, 2, RI_E2E3E3B0_ONLINE }, + { 0x180c0, 9, RI_E2E3E3B0_ONLINE }, + { 0x180e4, 1, RI_E2E3_ONLINE }, + { 0x180e8, 2, RI_E2E3E3B0_ONLINE }, + { 0x180f0, 1, RI_E2E3_ONLINE }, + { 0x180f4, 79, RI_E2E3E3B0_ONLINE }, + { 0x18230, 1, RI_E2E3_ONLINE }, + { 0x18234, 2, RI_E2E3E3B0_ONLINE }, + { 0x1823c, 1, RI_E2E3_ONLINE }, + { 0x18240, 13, RI_E2E3E3B0_ONLINE }, + { 0x18274, 1, RI_E2_ONLINE }, + { 0x18278, 81, RI_E2E3E3B0_ONLINE }, + { 0x18440, 63, RI_E2E3E3B0_ONLINE }, + { 0x18570, 42, RI_E3E3B0_ONLINE }, + { 0x18618, 25, RI_E3B0_ONLINE }, + { 0x18680, 44, RI_E3B0_ONLINE }, + { 0x18748, 12, RI_E3B0_ONLINE }, + { 0x18788, 1, RI_E3B0_ONLINE }, + { 0x1879c, 6, RI_E3B0_ONLINE }, + { 0x187c4, 51, RI_E3B0_ONLINE }, + { 0x18a00, 48, RI_E3B0_ONLINE }, + { 0x20000, 24, RI_ALL_ONLINE }, + { 0x20060, 8, RI_ALL_ONLINE }, + { 0x20080, 94, RI_ALL_ONLINE }, + { 0x201f8, 1, RI_E1E1H_ONLINE }, + { 0x201fc, 1, RI_ALL_ONLINE }, + { 0x20200, 1, RI_E1E1H_ONLINE }, + { 0x20204, 1, RI_ALL_ONLINE }, + { 0x20208, 1, RI_E1E1H_ONLINE }, + { 0x2020c, 39, RI_ALL_ONLINE }, + { 0x202c8, 1, RI_E2E3E3B0_ONLINE }, + { 0x202d8, 4, RI_E2E3E3B0_ONLINE }, + { 0x202f0, 1, RI_E3B0_ONLINE }, + { 0x20400, 2, RI_ALL_ONLINE }, + { 0x2040c, 8, RI_ALL_ONLINE }, + { 0x2042c, 18, RI_E1HE2E3E3B0_ONLINE }, + { 0x20480, 1, RI_ALL_ONLINE }, + { 0x20500, 1, RI_ALL_ONLINE }, + { 0x20600, 1, RI_ALL_ONLINE }, + { 0x28000, 1, RI_ALL_ONLINE }, + { 0x28004, 8191, RI_ALL_OFFLINE }, + { 0x30000, 1, RI_ALL_ONLINE }, + { 0x30004, 16383, RI_ALL_OFFLINE }, + { 0x40000, 98, RI_ALL_ONLINE }, + { 0x401a8, 8, RI_E1HE2E3E3B0_ONLINE }, + { 0x401c8, 1, RI_E1H_ONLINE }, + { 0x401cc, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x401d4, 2, RI_E2E3E3B0_ONLINE }, + { 0x40200, 4, RI_ALL_ONLINE }, + { 0x40220, 6, RI_E2E3E3B0_ONLINE }, + { 0x40238, 8, RI_E2E3_ONLINE }, + { 0x40258, 4, RI_E2E3E3B0_ONLINE }, + { 0x40268, 2, RI_E3E3B0_ONLINE }, + { 0x40270, 17, RI_E3B0_ONLINE }, + { 0x40400, 43, RI_ALL_ONLINE }, + { 0x404cc, 3, RI_E1HE2E3E3B0_ONLINE }, + { 0x404e0, 1, RI_E2E3E3B0_ONLINE }, + { 0x40500, 2, RI_ALL_ONLINE }, + { 0x40510, 2, RI_ALL_ONLINE }, + { 0x40520, 2, RI_ALL_ONLINE }, + { 0x40530, 2, RI_ALL_ONLINE }, + { 0x40540, 2, RI_ALL_ONLINE }, + { 0x40550, 10, RI_E2E3E3B0_ONLINE }, + { 0x40610, 2, RI_E2E3E3B0_ONLINE }, + { 0x42000, 164, RI_ALL_ONLINE }, + { 0x422c0, 4, RI_E2E3E3B0_ONLINE }, + { 0x422d4, 5, RI_E1HE2E3E3B0_ONLINE }, + { 0x422e8, 1, RI_E2E3E3B0_ONLINE }, + { 0x42400, 49, RI_ALL_ONLINE }, + { 0x424c8, 38, RI_ALL_ONLINE }, + { 0x42568, 2, RI_ALL_ONLINE }, + { 0x42640, 5, RI_E2E3E3B0_ONLINE }, + { 0x42800, 1, RI_ALL_ONLINE }, + { 0x50000, 1, RI_ALL_ONLINE }, + { 0x50004, 19, RI_ALL_ONLINE }, + { 0x50050, 8, RI_ALL_ONLINE }, + { 0x50070, 88, RI_ALL_ONLINE }, + { 0x501f0, 4, RI_E1HE2E3E3B0_ONLINE }, + { 0x50200, 2, RI_ALL_ONLINE }, + { 0x5020c, 7, RI_ALL_ONLINE }, + { 0x50228, 6, RI_E1HE2E3E3B0_ONLINE }, + { 0x50240, 1, RI_ALL_ONLINE }, + { 0x50280, 1, RI_ALL_ONLINE }, + { 0x50300, 1, RI_E2E3E3B0_ONLINE }, + { 0x5030c, 1, RI_E2E3E3B0_ONLINE }, + { 0x50318, 1, RI_E2E3E3B0_ONLINE }, + { 0x5031c, 1, RI_E2E3E3B0_ONLINE }, + { 0x50320, 2, RI_E2E3E3B0_ONLINE }, + { 0x50330, 1, RI_E3B0_ONLINE }, + { 0x52000, 1, RI_ALL_ONLINE }, + { 0x54000, 1, RI_ALL_ONLINE }, + { 0x54004, 3327, RI_ALL_OFFLINE }, + { 0x58000, 1, RI_ALL_ONLINE }, + { 0x58004, 8191, RI_E1E1H_OFFLINE }, + { 0x60000, 26, RI_ALL_ONLINE }, + { 0x60068, 8, RI_E1E1H_ONLINE }, + { 0x60088, 12, RI_ALL_ONLINE }, + { 0x600b8, 9, RI_E1E1H_ONLINE }, + { 0x600dc, 1, RI_ALL_ONLINE }, + { 0x600e0, 5, RI_E1E1H_ONLINE }, + { 0x600f4, 1, RI_E1E1HE2_ONLINE }, + { 0x600f8, 1, RI_E1E1H_ONLINE }, + { 0x600fc, 8, RI_ALL_ONLINE }, + { 0x6013c, 24, RI_E1H_ONLINE }, + { 0x6019c, 2, RI_E2E3E3B0_ONLINE }, + { 0x601ac, 18, RI_E2E3E3B0_ONLINE }, + { 0x60200, 1, RI_ALL_ONLINE }, + { 0x60204, 2, RI_ALL_OFFLINE }, + { 0x60210, 13, RI_E2E3E3B0_ONLINE }, + { 0x60244, 16, RI_E3B0_ONLINE }, + { 0x61000, 1, RI_ALL_ONLINE }, + { 0x61004, 511, RI_ALL_OFFLINE }, + { 0x61800, 512, RI_E3E3B0_OFFLINE }, + { 0x70000, 8, RI_ALL_ONLINE }, + { 0x70020, 8184, RI_ALL_OFFLINE }, + { 0x78000, 8192, RI_E3E3B0_OFFLINE }, + { 0x85000, 3, RI_ALL_ONLINE }, + { 0x8501c, 7, RI_ALL_ONLINE }, + { 0x85048, 1, RI_ALL_ONLINE }, + { 0x85200, 32, RI_ALL_ONLINE }, { 0xb0000, 16384, RI_E1H_ONLINE }, - { 0xc1000, 7, RI_ALL_ONLINE }, { 0xc103c, 2, RI_E2E3_ONLINE }, - { 0xc1800, 2, RI_ALL_ONLINE }, { 0xc2000, 164, RI_ALL_ONLINE }, - { 0xc22c0, 5, RI_E2E3_ONLINE }, { 0xc22d8, 4, RI_E2E3_ONLINE }, - { 0xc2400, 49, RI_ALL_ONLINE }, { 0xc24c8, 38, RI_ALL_ONLINE }, - { 0xc2568, 2, RI_ALL_ONLINE }, { 0xc2600, 1, RI_ALL_ONLINE }, - { 0xc4000, 165, RI_ALL_ONLINE }, { 0xc42d8, 2, RI_E2E3_ONLINE }, - { 0xc42e0, 7, RI_E1HE2E3_ONLINE }, { 0xc42fc, 1, RI_E2E3_ONLINE }, - { 0xc4400, 51, RI_ALL_ONLINE }, { 0xc44d0, 38, RI_ALL_ONLINE }, - { 0xc4570, 2, RI_ALL_ONLINE }, { 0xc4578, 5, RI_E2E3_ONLINE }, - { 0xc4600, 1, RI_ALL_ONLINE }, { 0xd0000, 19, RI_ALL_ONLINE }, - { 0xd004c, 8, RI_ALL_ONLINE }, { 0xd006c, 91, RI_ALL_ONLINE }, - { 0xd01fc, 1, RI_E2E3_ONLINE }, { 0xd0200, 2, RI_ALL_ONLINE }, - { 0xd020c, 7, RI_ALL_ONLINE }, { 0xd0228, 18, RI_E1HE2E3_ONLINE }, - { 0xd0280, 1, RI_ALL_ONLINE }, { 0xd0300, 1, RI_ALL_ONLINE }, - { 0xd0400, 1, RI_ALL_ONLINE }, { 0xd4000, 1, RI_ALL_ONLINE }, - { 0xd4004, 2559, RI_ALL_OFFLINE }, { 0xd8000, 1, RI_ALL_ONLINE }, - { 0xd8004, 8191, RI_ALL_OFFLINE }, { 0xe0000, 21, RI_ALL_ONLINE }, - { 0xe0054, 8, RI_ALL_ONLINE }, { 0xe0074, 49, RI_ALL_ONLINE }, - { 0xe0138, 1, RI_E1E1H_ONLINE }, { 0xe013c, 35, RI_ALL_ONLINE }, - { 0xe01f4, 1, RI_E2_ONLINE }, { 0xe01f8, 1, RI_E2E3_ONLINE }, - { 0xe0200, 2, RI_ALL_ONLINE }, { 0xe020c, 8, RI_ALL_ONLINE }, - { 0xe022c, 18, RI_E1HE2E3_ONLINE }, { 0xe0280, 1, RI_ALL_ONLINE }, - { 0xe0300, 1, RI_ALL_ONLINE }, { 0xe1000, 1, RI_ALL_ONLINE }, - { 0xe2000, 1, RI_ALL_ONLINE }, { 0xe2004, 2047, RI_ALL_OFFLINE }, - { 0xf0000, 1, RI_ALL_ONLINE }, { 0xf0004, 16383, RI_ALL_OFFLINE }, - { 0x101000, 12, RI_ALL_ONLINE }, { 0x101050, 1, RI_E1HE2E3_ONLINE }, - { 0x101054, 3, RI_E2E3_ONLINE }, { 0x101100, 1, RI_ALL_ONLINE }, - { 0x101800, 8, RI_ALL_ONLINE }, { 0x102000, 18, RI_ALL_ONLINE }, - { 0x102068, 6, RI_E2E3_ONLINE }, { 0x102080, 17, RI_ALL_ONLINE }, - { 0x1020c8, 8, RI_E1H_ONLINE }, { 0x1020e8, 9, RI_E2E3_ONLINE }, - { 0x102400, 1, RI_ALL_ONLINE }, { 0x103000, 26, RI_ALL_ONLINE }, - { 0x103098, 5, RI_E1HE2E3_ONLINE }, { 0x1030ac, 2, RI_E2E3_ONLINE }, - { 0x1030b4, 1, RI_E2_ONLINE }, { 0x1030b8, 7, RI_E2E3_ONLINE }, - { 0x1030d8, 8, RI_E2E3_ONLINE }, { 0x103400, 1, RI_E2E3_ONLINE }, - { 0x103404, 135, RI_E2E3_OFFLINE }, { 0x103800, 8, RI_ALL_ONLINE }, - { 0x104000, 63, RI_ALL_ONLINE }, { 0x10411c, 16, RI_E2E3_ONLINE }, - { 0x104200, 17, RI_ALL_ONLINE }, { 0x104400, 64, RI_ALL_ONLINE }, - { 0x104500, 192, RI_ALL_OFFLINE }, { 0x104800, 64, RI_ALL_ONLINE }, - { 0x104900, 192, RI_ALL_OFFLINE }, { 0x105000, 256, RI_ALL_ONLINE }, - { 0x105400, 768, RI_ALL_OFFLINE }, { 0x107000, 7, RI_E2E3_ONLINE }, - { 0x10701c, 1, RI_E3_ONLINE }, { 0x108000, 33, RI_E1E1H_ONLINE }, - { 0x1080ac, 5, RI_E1H_ONLINE }, { 0x108100, 5, RI_E1E1H_ONLINE }, - { 0x108120, 5, RI_E1E1H_ONLINE }, { 0x108200, 74, RI_E1E1H_ONLINE }, - { 0x108400, 74, RI_E1E1H_ONLINE }, { 0x108800, 152, RI_E1E1H_ONLINE }, - { 0x110000, 111, RI_E2E3_ONLINE }, { 0x1101dc, 1, RI_E3_ONLINE }, - { 0x110200, 4, RI_E2E3_ONLINE }, { 0x120000, 2, RI_ALL_ONLINE }, - { 0x120008, 4, RI_ALL_ONLINE }, { 0x120018, 3, RI_ALL_ONLINE }, - { 0x120024, 4, RI_ALL_ONLINE }, { 0x120034, 3, RI_ALL_ONLINE }, - { 0x120040, 4, RI_ALL_ONLINE }, { 0x120050, 3, RI_ALL_ONLINE }, - { 0x12005c, 4, RI_ALL_ONLINE }, { 0x12006c, 3, RI_ALL_ONLINE }, - { 0x120078, 4, RI_ALL_ONLINE }, { 0x120088, 3, RI_ALL_ONLINE }, - { 0x120094, 4, RI_ALL_ONLINE }, { 0x1200a4, 3, RI_ALL_ONLINE }, - { 0x1200b0, 4, RI_ALL_ONLINE }, { 0x1200c0, 3, RI_ALL_ONLINE }, - { 0x1200cc, 4, RI_ALL_ONLINE }, { 0x1200dc, 3, RI_ALL_ONLINE }, - { 0x1200e8, 4, RI_ALL_ONLINE }, { 0x1200f8, 3, RI_ALL_ONLINE }, - { 0x120104, 4, RI_ALL_ONLINE }, { 0x120114, 1, RI_ALL_ONLINE }, - { 0x120118, 22, RI_ALL_ONLINE }, { 0x120170, 2, RI_E1E1H_ONLINE }, - { 0x120178, 243, RI_ALL_ONLINE }, { 0x120544, 4, RI_E1E1H_ONLINE }, - { 0x120554, 6, RI_ALL_ONLINE }, { 0x12059c, 6, RI_E1HE2E3_ONLINE }, - { 0x1205b4, 1, RI_E1HE2E3_ONLINE }, { 0x1205b8, 15, RI_E1HE2E3_ONLINE }, - { 0x1205f4, 1, RI_E1HE2_ONLINE }, { 0x1205f8, 4, RI_E2E3_ONLINE }, - { 0x120618, 1, RI_E2E3_ONLINE }, { 0x12061c, 20, RI_E1HE2E3_ONLINE }, - { 0x12066c, 11, RI_E1HE2E3_ONLINE }, { 0x120698, 3, RI_E2E3_ONLINE }, - { 0x1206a4, 1, RI_E2_ONLINE }, { 0x1206a8, 1, RI_E2E3_ONLINE }, - { 0x1206b0, 75, RI_E2E3_ONLINE }, { 0x1207dc, 1, RI_E2_ONLINE }, - { 0x1207fc, 1, RI_E2E3_ONLINE }, { 0x12080c, 65, RI_ALL_ONLINE }, - { 0x120910, 7, RI_E2E3_ONLINE }, { 0x120930, 9, RI_E2E3_ONLINE }, - { 0x12095c, 37, RI_E3_ONLINE }, { 0x120a00, 2, RI_E1E1HE2_ONLINE }, - { 0x120b00, 1, RI_E3_ONLINE }, { 0x122000, 2, RI_ALL_ONLINE }, - { 0x122008, 2046, RI_E1_OFFLINE }, { 0x128000, 2, RI_E1HE2E3_ONLINE }, - { 0x128008, 6142, RI_E1HE2E3_OFFLINE }, - { 0x130000, 35, RI_E2E3_ONLINE }, - { 0x130100, 29, RI_E2E3_ONLINE }, { 0x130180, 1, RI_E2E3_ONLINE }, - { 0x130200, 1, RI_E2E3_ONLINE }, { 0x130280, 1, RI_E2E3_ONLINE }, - { 0x130300, 5, RI_E2E3_ONLINE }, { 0x130380, 1, RI_E2E3_ONLINE }, - { 0x130400, 1, RI_E2E3_ONLINE }, { 0x130480, 5, RI_E2E3_ONLINE }, - { 0x130800, 72, RI_E2E3_ONLINE }, { 0x131000, 136, RI_E2E3_ONLINE }, - { 0x132000, 148, RI_E2E3_ONLINE }, { 0x134000, 544, RI_E2E3_ONLINE }, - { 0x140000, 64, RI_ALL_ONLINE }, { 0x140100, 5, RI_E1E1H_ONLINE }, - { 0x140114, 45, RI_ALL_ONLINE }, { 0x140200, 6, RI_ALL_ONLINE }, - { 0x140220, 4, RI_E2E3_ONLINE }, { 0x140240, 4, RI_E2E3_ONLINE }, - { 0x140260, 4, RI_E2E3_ONLINE }, { 0x140280, 4, RI_E2E3_ONLINE }, - { 0x1402a0, 4, RI_E2E3_ONLINE }, { 0x1402c0, 4, RI_E2E3_ONLINE }, - { 0x1402e0, 13, RI_E2E3_ONLINE }, { 0x144000, 4, RI_E1E1H_ONLINE }, - { 0x148000, 4, RI_E1E1H_ONLINE }, { 0x14c000, 4, RI_E1E1H_ONLINE }, - { 0x150000, 4, RI_E1E1H_ONLINE }, { 0x154000, 4, RI_E1E1H_ONLINE }, - { 0x158000, 4, RI_E1E1H_ONLINE }, { 0x15c000, 2, RI_E1HE2E3_ONLINE }, - { 0x15c008, 5, RI_E1H_ONLINE }, { 0x15c020, 27, RI_E2E3_ONLINE }, - { 0x15c090, 13, RI_E2E3_ONLINE }, { 0x15c0c8, 34, RI_E2E3_ONLINE }, - { 0x15c150, 4, RI_E3_ONLINE }, { 0x160004, 6, RI_E3_ONLINE }, - { 0x160040, 6, RI_E3_ONLINE }, { 0x16005c, 6, RI_E3_ONLINE }, - { 0x160078, 2, RI_E3_ONLINE }, { 0x160300, 8, RI_E3_ONLINE }, - { 0x160330, 6, RI_E3_ONLINE }, { 0x160404, 6, RI_E3_ONLINE }, - { 0x160440, 6, RI_E3_ONLINE }, { 0x16045c, 6, RI_E3_ONLINE }, - { 0x160478, 2, RI_E3_ONLINE }, { 0x160700, 8, RI_E3_ONLINE }, - { 0x160730, 6, RI_E3_ONLINE }, { 0x161000, 7, RI_ALL_ONLINE }, - { 0x16103c, 2, RI_E2E3_ONLINE }, { 0x161800, 2, RI_ALL_ONLINE }, - { 0x162000, 54, RI_E3_ONLINE }, { 0x162200, 60, RI_E3_ONLINE }, - { 0x162400, 54, RI_E3_ONLINE }, { 0x162600, 60, RI_E3_ONLINE }, - { 0x162800, 54, RI_E3_ONLINE }, { 0x162a00, 60, RI_E3_ONLINE }, - { 0x162c00, 54, RI_E3_ONLINE }, { 0x162e00, 60, RI_E3_ONLINE }, - { 0x163000, 1, RI_E3_ONLINE }, { 0x163008, 1, RI_E3_ONLINE }, - { 0x163010, 1, RI_E3_ONLINE }, { 0x163018, 1, RI_E3_ONLINE }, - { 0x163020, 5, RI_E3_ONLINE }, { 0x163038, 3, RI_E3_ONLINE }, - { 0x163048, 3, RI_E3_ONLINE }, { 0x163058, 1, RI_E3_ONLINE }, - { 0x163060, 1, RI_E3_ONLINE }, { 0x163068, 1, RI_E3_ONLINE }, - { 0x163070, 3, RI_E3_ONLINE }, { 0x163080, 1, RI_E3_ONLINE }, - { 0x163088, 3, RI_E3_ONLINE }, { 0x163098, 1, RI_E3_ONLINE }, - { 0x1630a0, 1, RI_E3_ONLINE }, { 0x1630a8, 1, RI_E3_ONLINE }, - { 0x1630c0, 1, RI_E3_ONLINE }, { 0x1630c8, 1, RI_E3_ONLINE }, - { 0x1630d0, 1, RI_E3_ONLINE }, { 0x1630d8, 1, RI_E3_ONLINE }, - { 0x1630e0, 2, RI_E3_ONLINE }, { 0x163110, 1, RI_E3_ONLINE }, - { 0x163120, 2, RI_E3_ONLINE }, { 0x163420, 4, RI_E3_ONLINE }, - { 0x163438, 2, RI_E3_ONLINE }, { 0x163488, 2, RI_E3_ONLINE }, - { 0x163520, 2, RI_E3_ONLINE }, { 0x163800, 1, RI_E3_ONLINE }, - { 0x163808, 1, RI_E3_ONLINE }, { 0x163810, 1, RI_E3_ONLINE }, - { 0x163818, 1, RI_E3_ONLINE }, { 0x163820, 5, RI_E3_ONLINE }, - { 0x163838, 3, RI_E3_ONLINE }, { 0x163848, 3, RI_E3_ONLINE }, - { 0x163858, 1, RI_E3_ONLINE }, { 0x163860, 1, RI_E3_ONLINE }, - { 0x163868, 1, RI_E3_ONLINE }, { 0x163870, 3, RI_E3_ONLINE }, - { 0x163880, 1, RI_E3_ONLINE }, { 0x163888, 3, RI_E3_ONLINE }, - { 0x163898, 1, RI_E3_ONLINE }, { 0x1638a0, 1, RI_E3_ONLINE }, - { 0x1638a8, 1, RI_E3_ONLINE }, { 0x1638c0, 1, RI_E3_ONLINE }, - { 0x1638c8, 1, RI_E3_ONLINE }, { 0x1638d0, 1, RI_E3_ONLINE }, - { 0x1638d8, 1, RI_E3_ONLINE }, { 0x1638e0, 2, RI_E3_ONLINE }, - { 0x163910, 1, RI_E3_ONLINE }, { 0x163920, 2, RI_E3_ONLINE }, - { 0x163c20, 4, RI_E3_ONLINE }, { 0x163c38, 2, RI_E3_ONLINE }, - { 0x163c88, 2, RI_E3_ONLINE }, { 0x163d20, 2, RI_E3_ONLINE }, - { 0x164000, 60, RI_ALL_ONLINE }, { 0x164110, 2, RI_E1HE2E3_ONLINE }, - { 0x164118, 15, RI_E2E3_ONLINE }, { 0x164200, 1, RI_ALL_ONLINE }, - { 0x164208, 1, RI_ALL_ONLINE }, { 0x164210, 1, RI_ALL_ONLINE }, - { 0x164218, 1, RI_ALL_ONLINE }, { 0x164220, 1, RI_ALL_ONLINE }, - { 0x164228, 1, RI_ALL_ONLINE }, { 0x164230, 1, RI_ALL_ONLINE }, - { 0x164238, 1, RI_ALL_ONLINE }, { 0x164240, 1, RI_ALL_ONLINE }, - { 0x164248, 1, RI_ALL_ONLINE }, { 0x164250, 1, RI_ALL_ONLINE }, - { 0x164258, 1, RI_ALL_ONLINE }, { 0x164260, 1, RI_ALL_ONLINE }, - { 0x164270, 2, RI_ALL_ONLINE }, { 0x164280, 2, RI_ALL_ONLINE }, - { 0x164800, 2, RI_ALL_ONLINE }, { 0x165000, 2, RI_ALL_ONLINE }, - { 0x166000, 164, RI_ALL_ONLINE }, { 0x1662cc, 7, RI_E2E3_ONLINE }, - { 0x166400, 49, RI_ALL_ONLINE }, { 0x1664c8, 38, RI_ALL_ONLINE }, - { 0x166568, 2, RI_ALL_ONLINE }, { 0x166570, 5, RI_E2E3_ONLINE }, - { 0x166800, 1, RI_ALL_ONLINE }, { 0x168000, 137, RI_ALL_ONLINE }, - { 0x168224, 2, RI_E1E1H_ONLINE }, { 0x16822c, 29, RI_ALL_ONLINE }, - { 0x1682a0, 12, RI_E1E1H_ONLINE }, { 0x1682d0, 12, RI_ALL_ONLINE }, - { 0x168300, 2, RI_E1E1H_ONLINE }, { 0x168308, 68, RI_ALL_ONLINE }, - { 0x168418, 2, RI_E1E1H_ONLINE }, { 0x168420, 6, RI_ALL_ONLINE }, - { 0x168800, 19, RI_ALL_ONLINE }, { 0x168900, 1, RI_ALL_ONLINE }, - { 0x168a00, 128, RI_ALL_ONLINE }, { 0x16a000, 1, RI_ALL_ONLINE }, - { 0x16a004, 1535, RI_ALL_OFFLINE }, { 0x16c000, 1, RI_ALL_ONLINE }, - { 0x16c004, 1535, RI_ALL_OFFLINE }, { 0x16e000, 16, RI_E1H_ONLINE }, - { 0x16e040, 8, RI_E2E3_ONLINE }, { 0x16e100, 1, RI_E1H_ONLINE }, - { 0x16e200, 2, RI_E1H_ONLINE }, { 0x16e400, 161, RI_E1H_ONLINE }, - { 0x16e684, 2, RI_E1HE2E3_ONLINE }, { 0x16e68c, 12, RI_E1H_ONLINE }, - { 0x16e6bc, 4, RI_E1HE2E3_ONLINE }, { 0x16e6cc, 4, RI_E1H_ONLINE }, - { 0x16e6e0, 12, RI_E2E3_ONLINE }, { 0x16e768, 17, RI_E2E3_ONLINE }, - { 0x170000, 24, RI_ALL_ONLINE }, { 0x170060, 4, RI_E1E1H_ONLINE }, - { 0x170070, 65, RI_ALL_ONLINE }, { 0x170194, 11, RI_E2E3_ONLINE }, - { 0x1701c4, 1, RI_E2E3_ONLINE }, { 0x1701cc, 7, RI_E2E3_ONLINE }, - { 0x1701e8, 1, RI_E3_ONLINE }, { 0x1701ec, 1, RI_E2E3_ONLINE }, - { 0x1701f4, 1, RI_E2E3_ONLINE }, { 0x170200, 4, RI_ALL_ONLINE }, - { 0x170214, 1, RI_ALL_ONLINE }, { 0x170218, 77, RI_E2E3_ONLINE }, - { 0x170400, 64, RI_E2E3_ONLINE }, { 0x178000, 1, RI_ALL_ONLINE }, - { 0x180000, 61, RI_ALL_ONLINE }, { 0x18013c, 2, RI_E1HE2E3_ONLINE }, - { 0x180200, 58, RI_ALL_ONLINE }, { 0x180340, 4, RI_ALL_ONLINE }, - { 0x180380, 1, RI_E2E3_ONLINE }, { 0x180388, 1, RI_E2E3_ONLINE }, - { 0x180390, 1, RI_E2E3_ONLINE }, { 0x180398, 1, RI_E2E3_ONLINE }, - { 0x1803a0, 5, RI_E2E3_ONLINE }, { 0x1803b4, 2, RI_E3_ONLINE }, - { 0x180400, 1, RI_ALL_ONLINE }, { 0x180404, 255, RI_E1E1H_OFFLINE }, - { 0x181000, 4, RI_ALL_ONLINE }, { 0x181010, 1020, RI_ALL_OFFLINE }, - { 0x182000, 4, RI_E3_ONLINE }, { 0x1a0000, 1, RI_ALL_ONLINE }, + { 0xc1000, 7, RI_ALL_ONLINE }, + { 0xc103c, 2, RI_E2E3E3B0_ONLINE }, + { 0xc1800, 2, RI_ALL_ONLINE }, + { 0xc2000, 164, RI_ALL_ONLINE }, + { 0xc22c0, 5, RI_E2E3E3B0_ONLINE }, + { 0xc22d8, 4, RI_E2E3E3B0_ONLINE }, + { 0xc2400, 49, RI_ALL_ONLINE }, + { 0xc24c8, 38, RI_ALL_ONLINE }, + { 0xc2568, 2, RI_ALL_ONLINE }, + { 0xc2600, 1, RI_ALL_ONLINE }, + { 0xc4000, 165, RI_ALL_ONLINE }, + { 0xc42d8, 2, RI_E2E3E3B0_ONLINE }, + { 0xc42e0, 7, RI_E1HE2E3E3B0_ONLINE }, + { 0xc42fc, 1, RI_E2E3E3B0_ONLINE }, + { 0xc4400, 51, RI_ALL_ONLINE }, + { 0xc44d0, 38, RI_ALL_ONLINE }, + { 0xc4570, 2, RI_ALL_ONLINE }, + { 0xc4578, 5, RI_E2E3E3B0_ONLINE }, + { 0xc4600, 1, RI_ALL_ONLINE }, + { 0xd0000, 19, RI_ALL_ONLINE }, + { 0xd004c, 8, RI_ALL_ONLINE }, + { 0xd006c, 91, RI_ALL_ONLINE }, + { 0xd01fc, 1, RI_E2E3E3B0_ONLINE }, + { 0xd0200, 2, RI_ALL_ONLINE }, + { 0xd020c, 7, RI_ALL_ONLINE }, + { 0xd0228, 18, RI_E1HE2E3E3B0_ONLINE }, + { 0xd0280, 1, RI_ALL_ONLINE }, + { 0xd0300, 1, RI_ALL_ONLINE }, + { 0xd0400, 1, RI_ALL_ONLINE }, + { 0xd0818, 1, RI_E3B0_ONLINE }, + { 0xd4000, 1, RI_ALL_ONLINE }, + { 0xd4004, 2559, RI_ALL_OFFLINE }, + { 0xd8000, 1, RI_ALL_ONLINE }, + { 0xd8004, 8191, RI_ALL_OFFLINE }, + { 0xe0000, 21, RI_ALL_ONLINE }, + { 0xe0054, 8, RI_ALL_ONLINE }, + { 0xe0074, 49, RI_ALL_ONLINE }, + { 0xe0138, 1, RI_E1E1H_ONLINE }, + { 0xe013c, 35, RI_ALL_ONLINE }, + { 0xe01f4, 1, RI_E2_ONLINE }, + { 0xe01f8, 1, RI_E2E3E3B0_ONLINE }, + { 0xe0200, 2, RI_ALL_ONLINE }, + { 0xe020c, 8, RI_ALL_ONLINE }, + { 0xe022c, 18, RI_E1HE2E3E3B0_ONLINE }, + { 0xe0280, 1, RI_ALL_ONLINE }, + { 0xe0300, 1, RI_ALL_ONLINE }, + { 0xe0400, 1, RI_E3B0_ONLINE }, + { 0xe1000, 1, RI_ALL_ONLINE }, + { 0xe2000, 1, RI_ALL_ONLINE }, + { 0xe2004, 2047, RI_ALL_OFFLINE }, + { 0xf0000, 1, RI_ALL_ONLINE }, + { 0xf0004, 16383, RI_ALL_OFFLINE }, + { 0x101000, 12, RI_ALL_ONLINE }, + { 0x101050, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x101054, 3, RI_E2E3E3B0_ONLINE }, + { 0x101100, 1, RI_ALL_ONLINE }, + { 0x101800, 8, RI_ALL_ONLINE }, + { 0x102000, 18, RI_ALL_ONLINE }, + { 0x102068, 6, RI_E2E3E3B0_ONLINE }, + { 0x102080, 17, RI_ALL_ONLINE }, + { 0x1020c8, 8, RI_E1H_ONLINE }, + { 0x1020e8, 9, RI_E2E3E3B0_ONLINE }, + { 0x102400, 1, RI_ALL_ONLINE }, + { 0x103000, 26, RI_ALL_ONLINE }, + { 0x103098, 5, RI_E1HE2E3E3B0_ONLINE }, + { 0x1030ac, 2, RI_E2E3E3B0_ONLINE }, + { 0x1030b4, 1, RI_E2_ONLINE }, + { 0x1030b8, 7, RI_E2E3E3B0_ONLINE }, + { 0x1030d8, 8, RI_E2E3E3B0_ONLINE }, + { 0x103400, 1, RI_E2E3E3B0_ONLINE }, + { 0x103404, 135, RI_E2E3E3B0_OFFLINE }, + { 0x103800, 8, RI_ALL_ONLINE }, + { 0x104000, 63, RI_ALL_ONLINE }, + { 0x10411c, 16, RI_E2E3E3B0_ONLINE }, + { 0x104200, 17, RI_ALL_ONLINE }, + { 0x104400, 64, RI_ALL_ONLINE }, + { 0x104500, 192, RI_ALL_OFFLINE }, + { 0x104800, 64, RI_ALL_ONLINE }, + { 0x104900, 192, RI_ALL_OFFLINE }, + { 0x105000, 256, RI_ALL_ONLINE }, + { 0x105400, 768, RI_ALL_OFFLINE }, + { 0x107000, 7, RI_E2E3E3B0_ONLINE }, + { 0x10701c, 1, RI_E3E3B0_ONLINE }, + { 0x108000, 33, RI_E1E1H_ONLINE }, + { 0x1080ac, 5, RI_E1H_ONLINE }, + { 0x108100, 5, RI_E1E1H_ONLINE }, + { 0x108120, 5, RI_E1E1H_ONLINE }, + { 0x108200, 74, RI_E1E1H_ONLINE }, + { 0x108400, 74, RI_E1E1H_ONLINE }, + { 0x108800, 152, RI_E1E1H_ONLINE }, + { 0x110000, 111, RI_E2E3E3B0_ONLINE }, + { 0x1101dc, 1, RI_E3E3B0_ONLINE }, + { 0x110200, 4, RI_E2E3E3B0_ONLINE }, + { 0x120000, 2, RI_ALL_ONLINE }, + { 0x120008, 4, RI_ALL_ONLINE }, + { 0x120018, 3, RI_ALL_ONLINE }, + { 0x120024, 4, RI_ALL_ONLINE }, + { 0x120034, 3, RI_ALL_ONLINE }, + { 0x120040, 4, RI_ALL_ONLINE }, + { 0x120050, 3, RI_ALL_ONLINE }, + { 0x12005c, 4, RI_ALL_ONLINE }, + { 0x12006c, 3, RI_ALL_ONLINE }, + { 0x120078, 4, RI_ALL_ONLINE }, + { 0x120088, 3, RI_ALL_ONLINE }, + { 0x120094, 4, RI_ALL_ONLINE }, + { 0x1200a4, 3, RI_ALL_ONLINE }, + { 0x1200b0, 4, RI_ALL_ONLINE }, + { 0x1200c0, 3, RI_ALL_ONLINE }, + { 0x1200cc, 4, RI_ALL_ONLINE }, + { 0x1200dc, 3, RI_ALL_ONLINE }, + { 0x1200e8, 4, RI_ALL_ONLINE }, + { 0x1200f8, 3, RI_ALL_ONLINE }, + { 0x120104, 4, RI_ALL_ONLINE }, + { 0x120114, 1, RI_ALL_ONLINE }, + { 0x120118, 22, RI_ALL_ONLINE }, + { 0x120170, 2, RI_E1E1H_ONLINE }, + { 0x120178, 243, RI_ALL_ONLINE }, + { 0x120544, 4, RI_E1E1H_ONLINE }, + { 0x120554, 6, RI_ALL_ONLINE }, + { 0x12059c, 6, RI_E1HE2E3E3B0_ONLINE }, + { 0x1205b4, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1205b8, 15, RI_E1HE2E3E3B0_ONLINE }, + { 0x1205f4, 1, RI_E1HE2_ONLINE }, + { 0x1205f8, 4, RI_E2E3E3B0_ONLINE }, + { 0x120618, 1, RI_E2E3E3B0_ONLINE }, + { 0x12061c, 20, RI_E1HE2E3E3B0_ONLINE }, + { 0x12066c, 11, RI_E1HE2E3E3B0_ONLINE }, + { 0x120698, 3, RI_E2E3E3B0_ONLINE }, + { 0x1206a4, 1, RI_E2_ONLINE }, + { 0x1206a8, 1, RI_E2E3E3B0_ONLINE }, + { 0x1206b0, 75, RI_E2E3E3B0_ONLINE }, + { 0x1207dc, 1, RI_E2_ONLINE }, + { 0x1207fc, 1, RI_E2E3E3B0_ONLINE }, + { 0x12080c, 65, RI_ALL_ONLINE }, + { 0x120910, 7, RI_E2E3E3B0_ONLINE }, + { 0x120930, 9, RI_E2E3E3B0_ONLINE }, + { 0x12095c, 37, RI_E3E3B0_ONLINE }, + { 0x120a00, 2, RI_E1E1HE2_ONLINE }, + { 0x120b00, 1, RI_E3E3B0_ONLINE }, + { 0x122000, 2, RI_ALL_ONLINE }, + { 0x122008, 2046, RI_E1_OFFLINE }, + { 0x128000, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x128008, 6142, RI_E1HE2E3E3B0_OFFLINE }, + { 0x130000, 35, RI_E2E3E3B0_ONLINE }, + { 0x130100, 29, RI_E2E3E3B0_ONLINE }, + { 0x130180, 1, RI_E2E3E3B0_ONLINE }, + { 0x130200, 1, RI_E2E3E3B0_ONLINE }, + { 0x130280, 1, RI_E2E3E3B0_ONLINE }, + { 0x130300, 5, RI_E2E3E3B0_ONLINE }, + { 0x130380, 1, RI_E2E3E3B0_ONLINE }, + { 0x130400, 1, RI_E2E3E3B0_ONLINE }, + { 0x130480, 5, RI_E2E3E3B0_ONLINE }, + { 0x130800, 72, RI_E2E3E3B0_ONLINE }, + { 0x131000, 136, RI_E2E3E3B0_ONLINE }, + { 0x132000, 148, RI_E2E3E3B0_ONLINE }, + { 0x134000, 544, RI_E2E3E3B0_ONLINE }, + { 0x140000, 1, RI_ALL_ONLINE }, + { 0x140004, 9, RI_E1E1HE2E3_ONLINE }, + { 0x140028, 8, RI_ALL_ONLINE }, + { 0x140048, 10, RI_E1E1HE2E3_ONLINE }, + { 0x140070, 1, RI_ALL_ONLINE }, + { 0x140074, 10, RI_E1E1HE2E3_ONLINE }, + { 0x14009c, 1, RI_ALL_ONLINE }, + { 0x1400a0, 5, RI_E1E1HE2E3_ONLINE }, + { 0x1400b4, 7, RI_ALL_ONLINE }, + { 0x1400d0, 10, RI_E1E1HE2E3_ONLINE }, + { 0x1400f8, 2, RI_ALL_ONLINE }, + { 0x140100, 5, RI_E1E1H_ONLINE }, + { 0x140114, 5, RI_E1E1HE2E3_ONLINE }, + { 0x140128, 7, RI_ALL_ONLINE }, + { 0x140144, 9, RI_E1E1HE2E3_ONLINE }, + { 0x140168, 8, RI_ALL_ONLINE }, + { 0x140188, 3, RI_E1E1HE2E3_ONLINE }, + { 0x140194, 13, RI_ALL_ONLINE }, + { 0x140200, 6, RI_E1E1HE2E3_ONLINE }, + { 0x140220, 4, RI_E2E3_ONLINE }, + { 0x140240, 4, RI_E2E3_ONLINE }, + { 0x140260, 4, RI_E2E3_ONLINE }, + { 0x140280, 4, RI_E2E3_ONLINE }, + { 0x1402a0, 4, RI_E2E3_ONLINE }, + { 0x1402c0, 4, RI_E2E3_ONLINE }, + { 0x1402e0, 2, RI_E2E3_ONLINE }, + { 0x1402e8, 2, RI_E2E3E3B0_ONLINE }, + { 0x1402f0, 9, RI_E2E3_ONLINE }, + { 0x140314, 44, RI_E3B0_ONLINE }, + { 0x1403d0, 70, RI_E3B0_ONLINE }, + { 0x144000, 4, RI_E1E1H_ONLINE }, + { 0x148000, 4, RI_E1E1H_ONLINE }, + { 0x14c000, 4, RI_E1E1H_ONLINE }, + { 0x150000, 4, RI_E1E1H_ONLINE }, + { 0x154000, 4, RI_E1E1H_ONLINE }, + { 0x158000, 4, RI_E1E1H_ONLINE }, + { 0x15c000, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x15c008, 5, RI_E1H_ONLINE }, + { 0x15c020, 8, RI_E2E3E3B0_ONLINE }, + { 0x15c040, 1, RI_E2E3_ONLINE }, + { 0x15c044, 2, RI_E2E3E3B0_ONLINE }, + { 0x15c04c, 8, RI_E2E3_ONLINE }, + { 0x15c06c, 8, RI_E2E3E3B0_ONLINE }, + { 0x15c090, 13, RI_E2E3E3B0_ONLINE }, + { 0x15c0c8, 24, RI_E2E3E3B0_ONLINE }, + { 0x15c128, 2, RI_E2E3_ONLINE }, + { 0x15c130, 8, RI_E2E3E3B0_ONLINE }, + { 0x15c150, 2, RI_E3E3B0_ONLINE }, + { 0x15c158, 2, RI_E3_ONLINE }, + { 0x15c160, 149, RI_E3B0_ONLINE }, + { 0x161000, 7, RI_ALL_ONLINE }, + { 0x16103c, 2, RI_E2E3E3B0_ONLINE }, + { 0x161800, 2, RI_ALL_ONLINE }, + { 0x162000, 54, RI_E3E3B0_ONLINE }, + { 0x162200, 60, RI_E3E3B0_ONLINE }, + { 0x162400, 54, RI_E3E3B0_ONLINE }, + { 0x162600, 60, RI_E3E3B0_ONLINE }, + { 0x162800, 54, RI_E3E3B0_ONLINE }, + { 0x162a00, 60, RI_E3E3B0_ONLINE }, + { 0x162c00, 54, RI_E3E3B0_ONLINE }, + { 0x162e00, 60, RI_E3E3B0_ONLINE }, + { 0x164000, 60, RI_ALL_ONLINE }, + { 0x164110, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x164118, 15, RI_E2E3E3B0_ONLINE }, + { 0x164200, 1, RI_ALL_ONLINE }, + { 0x164208, 1, RI_ALL_ONLINE }, + { 0x164210, 1, RI_ALL_ONLINE }, + { 0x164218, 1, RI_ALL_ONLINE }, + { 0x164220, 1, RI_ALL_ONLINE }, + { 0x164228, 1, RI_ALL_ONLINE }, + { 0x164230, 1, RI_ALL_ONLINE }, + { 0x164238, 1, RI_ALL_ONLINE }, + { 0x164240, 1, RI_ALL_ONLINE }, + { 0x164248, 1, RI_ALL_ONLINE }, + { 0x164250, 1, RI_ALL_ONLINE }, + { 0x164258, 1, RI_ALL_ONLINE }, + { 0x164260, 1, RI_ALL_ONLINE }, + { 0x164270, 2, RI_ALL_ONLINE }, + { 0x164280, 2, RI_ALL_ONLINE }, + { 0x164800, 2, RI_ALL_ONLINE }, + { 0x165000, 2, RI_ALL_ONLINE }, + { 0x166000, 164, RI_ALL_ONLINE }, + { 0x1662cc, 7, RI_E2E3E3B0_ONLINE }, + { 0x166400, 49, RI_ALL_ONLINE }, + { 0x1664c8, 38, RI_ALL_ONLINE }, + { 0x166568, 2, RI_ALL_ONLINE }, + { 0x166570, 5, RI_E2E3E3B0_ONLINE }, + { 0x166800, 1, RI_ALL_ONLINE }, + { 0x168000, 137, RI_ALL_ONLINE }, + { 0x168224, 2, RI_E1E1H_ONLINE }, + { 0x16822c, 29, RI_ALL_ONLINE }, + { 0x1682a0, 12, RI_E1E1H_ONLINE }, + { 0x1682d0, 12, RI_ALL_ONLINE }, + { 0x168300, 2, RI_E1E1H_ONLINE }, + { 0x168308, 68, RI_ALL_ONLINE }, + { 0x168418, 2, RI_E1E1H_ONLINE }, + { 0x168420, 6, RI_ALL_ONLINE }, + { 0x168800, 19, RI_ALL_ONLINE }, + { 0x168900, 1, RI_ALL_ONLINE }, + { 0x168a00, 128, RI_ALL_ONLINE }, + { 0x16a000, 1, RI_ALL_ONLINE }, + { 0x16a004, 1535, RI_ALL_OFFLINE }, + { 0x16c000, 1, RI_ALL_ONLINE }, + { 0x16c004, 1535, RI_ALL_OFFLINE }, + { 0x16e000, 16, RI_E1H_ONLINE }, + { 0x16e040, 8, RI_E2E3E3B0_ONLINE }, + { 0x16e100, 1, RI_E1H_ONLINE }, + { 0x16e200, 2, RI_E1H_ONLINE }, + { 0x16e400, 161, RI_E1H_ONLINE }, + { 0x16e684, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x16e68c, 12, RI_E1H_ONLINE }, + { 0x16e6bc, 4, RI_E1HE2E3E3B0_ONLINE }, + { 0x16e6cc, 4, RI_E1H_ONLINE }, + { 0x16e6e0, 2, RI_E2E3E3B0_ONLINE }, + { 0x16e6e8, 5, RI_E2E3_ONLINE }, + { 0x16e6fc, 5, RI_E2E3E3B0_ONLINE }, + { 0x16e768, 17, RI_E2E3E3B0_ONLINE }, + { 0x16e7ac, 12, RI_E3B0_ONLINE }, + { 0x170000, 24, RI_ALL_ONLINE }, + { 0x170060, 4, RI_E1E1H_ONLINE }, + { 0x170070, 65, RI_ALL_ONLINE }, + { 0x170194, 11, RI_E2E3E3B0_ONLINE }, + { 0x1701c4, 1, RI_E2E3E3B0_ONLINE }, + { 0x1701cc, 7, RI_E2E3E3B0_ONLINE }, + { 0x1701e8, 1, RI_E3E3B0_ONLINE }, + { 0x1701ec, 1, RI_E2E3E3B0_ONLINE }, + { 0x1701f4, 1, RI_E2E3E3B0_ONLINE }, + { 0x170200, 4, RI_ALL_ONLINE }, + { 0x170214, 1, RI_ALL_ONLINE }, + { 0x170218, 77, RI_E2E3E3B0_ONLINE }, + { 0x170400, 64, RI_E2E3E3B0_ONLINE }, + { 0x178000, 1, RI_ALL_ONLINE }, + { 0x180000, 61, RI_ALL_ONLINE }, + { 0x18013c, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x180200, 58, RI_ALL_ONLINE }, + { 0x180340, 4, RI_ALL_ONLINE }, + { 0x180380, 1, RI_E2E3E3B0_ONLINE }, + { 0x180388, 1, RI_E2E3E3B0_ONLINE }, + { 0x180390, 1, RI_E2E3E3B0_ONLINE }, + { 0x180398, 1, RI_E2E3E3B0_ONLINE }, + { 0x1803a0, 5, RI_E2E3E3B0_ONLINE }, + { 0x1803b4, 2, RI_E3E3B0_ONLINE }, + { 0x180400, 1, RI_ALL_ONLINE }, + { 0x180404, 255, RI_E1E1H_OFFLINE }, + { 0x181000, 4, RI_ALL_ONLINE }, + { 0x181010, 1020, RI_ALL_OFFLINE }, + { 0x182000, 4, RI_E3E3B0_ONLINE }, + { 0x1a0000, 1, RI_ALL_ONLINE }, { 0x1a0004, 5631, RI_ALL_OFFLINE }, - { 0x1a5800, 2560, RI_E1HE2E3_OFFLINE }, - { 0x1a8000, 1, RI_ALL_ONLINE }, { 0x1a8004, 8191, RI_E1HE2E3_OFFLINE }, - { 0x1b0000, 1, RI_ALL_ONLINE }, { 0x1b0004, 15, RI_E1H_OFFLINE }, - { 0x1b0040, 1, RI_E1HE2E3_ONLINE }, { 0x1b0044, 239, RI_E1H_OFFLINE }, - { 0x1b0400, 1, RI_ALL_ONLINE }, { 0x1b0404, 255, RI_E1H_OFFLINE }, - { 0x1b0800, 1, RI_ALL_ONLINE }, { 0x1b0840, 1, RI_E1HE2E3_ONLINE }, - { 0x1b0c00, 1, RI_ALL_ONLINE }, { 0x1b1000, 1, RI_ALL_ONLINE }, - { 0x1b1040, 1, RI_E1HE2E3_ONLINE }, { 0x1b1400, 1, RI_ALL_ONLINE }, - { 0x1b1440, 1, RI_E1HE2E3_ONLINE }, { 0x1b1480, 1, RI_E1HE2E3_ONLINE }, - { 0x1b14c0, 1, RI_E1HE2E3_ONLINE }, { 0x1b1800, 128, RI_ALL_OFFLINE }, - { 0x1b1c00, 128, RI_ALL_OFFLINE }, { 0x1b2000, 1, RI_ALL_ONLINE }, - { 0x1b2400, 1, RI_E1HE2E3_ONLINE }, { 0x1b2404, 5631, RI_E2E3_OFFLINE }, - { 0x1b8000, 1, RI_ALL_ONLINE }, { 0x1b8040, 1, RI_ALL_ONLINE }, - { 0x1b8080, 1, RI_ALL_ONLINE }, { 0x1b80c0, 1, RI_ALL_ONLINE }, - { 0x1b8100, 1, RI_ALL_ONLINE }, { 0x1b8140, 1, RI_ALL_ONLINE }, - { 0x1b8180, 1, RI_ALL_ONLINE }, { 0x1b81c0, 1, RI_ALL_ONLINE }, - { 0x1b8200, 1, RI_ALL_ONLINE }, { 0x1b8240, 1, RI_ALL_ONLINE }, - { 0x1b8280, 1, RI_ALL_ONLINE }, { 0x1b82c0, 1, RI_ALL_ONLINE }, - { 0x1b8300, 1, RI_ALL_ONLINE }, { 0x1b8340, 1, RI_ALL_ONLINE }, - { 0x1b8380, 1, RI_ALL_ONLINE }, { 0x1b83c0, 1, RI_ALL_ONLINE }, - { 0x1b8400, 1, RI_ALL_ONLINE }, { 0x1b8440, 1, RI_ALL_ONLINE }, - { 0x1b8480, 1, RI_ALL_ONLINE }, { 0x1b84c0, 1, RI_ALL_ONLINE }, - { 0x1b8500, 1, RI_ALL_ONLINE }, { 0x1b8540, 1, RI_ALL_ONLINE }, - { 0x1b8580, 1, RI_ALL_ONLINE }, { 0x1b85c0, 19, RI_E2E3_ONLINE }, - { 0x1b8800, 1, RI_ALL_ONLINE }, { 0x1b8840, 1, RI_ALL_ONLINE }, - { 0x1b8880, 1, RI_ALL_ONLINE }, { 0x1b88c0, 1, RI_ALL_ONLINE }, - { 0x1b8900, 1, RI_ALL_ONLINE }, { 0x1b8940, 1, RI_ALL_ONLINE }, - { 0x1b8980, 1, RI_ALL_ONLINE }, { 0x1b89c0, 1, RI_ALL_ONLINE }, - { 0x1b8a00, 1, RI_ALL_ONLINE }, { 0x1b8a40, 1, RI_ALL_ONLINE }, - { 0x1b8a80, 1, RI_ALL_ONLINE }, { 0x1b8ac0, 1, RI_ALL_ONLINE }, - { 0x1b8b00, 1, RI_ALL_ONLINE }, { 0x1b8b40, 1, RI_ALL_ONLINE }, - { 0x1b8b80, 1, RI_ALL_ONLINE }, { 0x1b8bc0, 1, RI_ALL_ONLINE }, - { 0x1b8c00, 1, RI_ALL_ONLINE }, { 0x1b8c40, 1, RI_ALL_ONLINE }, - { 0x1b8c80, 1, RI_ALL_ONLINE }, { 0x1b8cc0, 1, RI_ALL_ONLINE }, - { 0x1b8cc4, 1, RI_E2E3_ONLINE }, { 0x1b8d00, 1, RI_ALL_ONLINE }, - { 0x1b8d40, 1, RI_ALL_ONLINE }, { 0x1b8d80, 1, RI_ALL_ONLINE }, - { 0x1b8dc0, 1, RI_ALL_ONLINE }, { 0x1b8e00, 1, RI_ALL_ONLINE }, - { 0x1b8e40, 1, RI_ALL_ONLINE }, { 0x1b8e80, 1, RI_ALL_ONLINE }, - { 0x1b8e84, 1, RI_E2E3_ONLINE }, { 0x1b8ec0, 1, RI_E1HE2E3_ONLINE }, - { 0x1b8f00, 1, RI_E1HE2E3_ONLINE }, { 0x1b8f40, 1, RI_E1HE2E3_ONLINE }, - { 0x1b8f80, 1, RI_E1HE2E3_ONLINE }, { 0x1b8fc0, 1, RI_E1HE2E3_ONLINE }, - { 0x1b8fc4, 2, RI_E2E3_ONLINE }, { 0x1b8fd0, 6, RI_E2E3_ONLINE }, - { 0x1b8fe8, 2, RI_E3_ONLINE }, { 0x1b9000, 1, RI_E2E3_ONLINE }, - { 0x1b9040, 3, RI_E2E3_ONLINE }, { 0x1b905c, 1, RI_E3_ONLINE }, - { 0x1b9400, 14, RI_E2E3_ONLINE }, { 0x1b943c, 19, RI_E2E3_ONLINE }, - { 0x1b9490, 10, RI_E2E3_ONLINE }, { 0x1c0000, 2, RI_ALL_ONLINE }, - { 0x200000, 65, RI_ALL_ONLINE }, { 0x20014c, 2, RI_E1HE2E3_ONLINE }, - { 0x200200, 58, RI_ALL_ONLINE }, { 0x200340, 4, RI_ALL_ONLINE }, - { 0x200380, 1, RI_E2E3_ONLINE }, { 0x200388, 1, RI_E2E3_ONLINE }, - { 0x200390, 1, RI_E2E3_ONLINE }, { 0x200398, 1, RI_E2E3_ONLINE }, - { 0x2003a0, 1, RI_E2E3_ONLINE }, { 0x2003a8, 2, RI_E2E3_ONLINE }, - { 0x200400, 1, RI_ALL_ONLINE }, { 0x200404, 255, RI_E1E1H_OFFLINE }, - { 0x202000, 4, RI_ALL_ONLINE }, { 0x202010, 2044, RI_ALL_OFFLINE }, - { 0x204000, 4, RI_E3_ONLINE }, { 0x220000, 1, RI_ALL_ONLINE }, + { 0x1a5800, 2560, RI_E1HE2E3E3B0_OFFLINE }, + { 0x1a8000, 1, RI_ALL_ONLINE }, + { 0x1a8004, 8191, RI_E1HE2E3E3B0_OFFLINE }, + { 0x1b0000, 1, RI_ALL_ONLINE }, + { 0x1b0004, 15, RI_E1H_OFFLINE }, + { 0x1b0040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b0044, 239, RI_E1H_OFFLINE }, + { 0x1b0400, 1, RI_ALL_ONLINE }, + { 0x1b0404, 255, RI_E1H_OFFLINE }, + { 0x1b0800, 1, RI_ALL_ONLINE }, + { 0x1b0840, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b0c00, 1, RI_ALL_ONLINE }, + { 0x1b1000, 1, RI_ALL_ONLINE }, + { 0x1b1040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b1400, 1, RI_ALL_ONLINE }, + { 0x1b1440, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b1480, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b14c0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b1800, 128, RI_ALL_OFFLINE }, + { 0x1b1c00, 128, RI_ALL_OFFLINE }, + { 0x1b2000, 1, RI_ALL_ONLINE }, + { 0x1b2400, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b2404, 5631, RI_E2E3E3B0_OFFLINE }, + { 0x1b8000, 1, RI_ALL_ONLINE }, + { 0x1b8040, 1, RI_ALL_ONLINE }, + { 0x1b8080, 1, RI_ALL_ONLINE }, + { 0x1b80c0, 1, RI_ALL_ONLINE }, + { 0x1b8100, 1, RI_ALL_ONLINE }, + { 0x1b8140, 1, RI_ALL_ONLINE }, + { 0x1b8180, 1, RI_ALL_ONLINE }, + { 0x1b81c0, 1, RI_ALL_ONLINE }, + { 0x1b8200, 1, RI_ALL_ONLINE }, + { 0x1b8240, 1, RI_ALL_ONLINE }, + { 0x1b8280, 1, RI_ALL_ONLINE }, + { 0x1b82c0, 1, RI_ALL_ONLINE }, + { 0x1b8300, 1, RI_ALL_ONLINE }, + { 0x1b8340, 1, RI_ALL_ONLINE }, + { 0x1b8380, 1, RI_ALL_ONLINE }, + { 0x1b83c0, 1, RI_ALL_ONLINE }, + { 0x1b8400, 1, RI_ALL_ONLINE }, + { 0x1b8440, 1, RI_ALL_ONLINE }, + { 0x1b8480, 1, RI_ALL_ONLINE }, + { 0x1b84c0, 1, RI_ALL_ONLINE }, + { 0x1b8500, 1, RI_ALL_ONLINE }, + { 0x1b8540, 1, RI_ALL_ONLINE }, + { 0x1b8580, 1, RI_ALL_ONLINE }, + { 0x1b85c0, 19, RI_E2E3E3B0_ONLINE }, + { 0x1b8800, 1, RI_ALL_ONLINE }, + { 0x1b8840, 1, RI_ALL_ONLINE }, + { 0x1b8880, 1, RI_ALL_ONLINE }, + { 0x1b88c0, 1, RI_ALL_ONLINE }, + { 0x1b8900, 1, RI_ALL_ONLINE }, + { 0x1b8940, 1, RI_ALL_ONLINE }, + { 0x1b8980, 1, RI_ALL_ONLINE }, + { 0x1b89c0, 1, RI_ALL_ONLINE }, + { 0x1b8a00, 1, RI_ALL_ONLINE }, + { 0x1b8a40, 1, RI_ALL_ONLINE }, + { 0x1b8a80, 1, RI_ALL_ONLINE }, + { 0x1b8ac0, 1, RI_ALL_ONLINE }, + { 0x1b8b00, 1, RI_ALL_ONLINE }, + { 0x1b8b40, 1, RI_ALL_ONLINE }, + { 0x1b8b80, 1, RI_ALL_ONLINE }, + { 0x1b8bc0, 1, RI_ALL_ONLINE }, + { 0x1b8c00, 1, RI_ALL_ONLINE }, + { 0x1b8c40, 1, RI_ALL_ONLINE }, + { 0x1b8c80, 1, RI_ALL_ONLINE }, + { 0x1b8cc0, 1, RI_ALL_ONLINE }, + { 0x1b8cc4, 1, RI_E2E3E3B0_ONLINE }, + { 0x1b8d00, 1, RI_ALL_ONLINE }, + { 0x1b8d40, 1, RI_ALL_ONLINE }, + { 0x1b8d80, 1, RI_ALL_ONLINE }, + { 0x1b8dc0, 1, RI_ALL_ONLINE }, + { 0x1b8e00, 1, RI_ALL_ONLINE }, + { 0x1b8e40, 1, RI_ALL_ONLINE }, + { 0x1b8e80, 1, RI_ALL_ONLINE }, + { 0x1b8e84, 1, RI_E2E3E3B0_ONLINE }, + { 0x1b8ec0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b8f00, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b8f40, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b8f80, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b8fc0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b8fc4, 2, RI_E2E3E3B0_ONLINE }, + { 0x1b8fd0, 6, RI_E2E3E3B0_ONLINE }, + { 0x1b8fe8, 2, RI_E3E3B0_ONLINE }, + { 0x1b9000, 1, RI_E2E3E3B0_ONLINE }, + { 0x1b9040, 3, RI_E2E3E3B0_ONLINE }, + { 0x1b905c, 1, RI_E3E3B0_ONLINE }, + { 0x1b9064, 1, RI_E3B0_ONLINE }, + { 0x1b9080, 10, RI_E3B0_ONLINE }, + { 0x1b9400, 14, RI_E2E3E3B0_ONLINE }, + { 0x1b943c, 19, RI_E2E3E3B0_ONLINE }, + { 0x1b9490, 10, RI_E2E3E3B0_ONLINE }, + { 0x1c0000, 2, RI_ALL_ONLINE }, + { 0x200000, 65, RI_ALL_ONLINE }, + { 0x20014c, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x200200, 58, RI_ALL_ONLINE }, + { 0x200340, 4, RI_ALL_ONLINE }, + { 0x200380, 1, RI_E2E3E3B0_ONLINE }, + { 0x200388, 1, RI_E2E3E3B0_ONLINE }, + { 0x200390, 1, RI_E2E3E3B0_ONLINE }, + { 0x200398, 1, RI_E2E3E3B0_ONLINE }, + { 0x2003a0, 1, RI_E2E3E3B0_ONLINE }, + { 0x2003a8, 2, RI_E2E3E3B0_ONLINE }, + { 0x200400, 1, RI_ALL_ONLINE }, + { 0x200404, 255, RI_E1E1H_OFFLINE }, + { 0x202000, 4, RI_ALL_ONLINE }, + { 0x202010, 2044, RI_ALL_OFFLINE }, + { 0x204000, 4, RI_E3E3B0_ONLINE }, + { 0x220000, 1, RI_ALL_ONLINE }, { 0x220004, 5631, RI_ALL_OFFLINE }, - { 0x225800, 2560, RI_E1HE2E3_OFFLINE }, - { 0x228000, 1, RI_ALL_ONLINE }, { 0x228004, 8191, RI_E1HE2E3_OFFLINE }, - { 0x230000, 1, RI_ALL_ONLINE }, { 0x230004, 15, RI_E1H_OFFLINE }, - { 0x230040, 1, RI_E1HE2E3_ONLINE }, { 0x230044, 239, RI_E1H_OFFLINE }, - { 0x230400, 1, RI_ALL_ONLINE }, { 0x230404, 255, RI_E1H_OFFLINE }, - { 0x230800, 1, RI_ALL_ONLINE }, { 0x230840, 1, RI_E1HE2E3_ONLINE }, - { 0x230c00, 1, RI_ALL_ONLINE }, { 0x231000, 1, RI_ALL_ONLINE }, - { 0x231040, 1, RI_E1HE2E3_ONLINE }, { 0x231400, 1, RI_ALL_ONLINE }, - { 0x231440, 1, RI_E1HE2E3_ONLINE }, { 0x231480, 1, RI_E1HE2E3_ONLINE }, - { 0x2314c0, 1, RI_E1HE2E3_ONLINE }, { 0x231800, 128, RI_ALL_OFFLINE }, - { 0x231c00, 128, RI_ALL_OFFLINE }, { 0x232000, 1, RI_ALL_ONLINE }, - { 0x232400, 1, RI_E1HE2E3_ONLINE }, { 0x232404, 5631, RI_E2E3_OFFLINE }, - { 0x238000, 1, RI_ALL_ONLINE }, { 0x238040, 1, RI_ALL_ONLINE }, - { 0x238080, 1, RI_ALL_ONLINE }, { 0x2380c0, 1, RI_ALL_ONLINE }, - { 0x238100, 1, RI_ALL_ONLINE }, { 0x238140, 1, RI_ALL_ONLINE }, - { 0x238180, 1, RI_ALL_ONLINE }, { 0x2381c0, 1, RI_ALL_ONLINE }, - { 0x238200, 1, RI_ALL_ONLINE }, { 0x238240, 1, RI_ALL_ONLINE }, - { 0x238280, 1, RI_ALL_ONLINE }, { 0x2382c0, 1, RI_ALL_ONLINE }, - { 0x238300, 1, RI_ALL_ONLINE }, { 0x238340, 1, RI_ALL_ONLINE }, - { 0x238380, 1, RI_ALL_ONLINE }, { 0x2383c0, 1, RI_ALL_ONLINE }, - { 0x238400, 1, RI_ALL_ONLINE }, { 0x238440, 1, RI_ALL_ONLINE }, - { 0x238480, 1, RI_ALL_ONLINE }, { 0x2384c0, 1, RI_ALL_ONLINE }, - { 0x238500, 1, RI_ALL_ONLINE }, { 0x238540, 1, RI_ALL_ONLINE }, - { 0x238580, 1, RI_ALL_ONLINE }, { 0x2385c0, 19, RI_E2E3_ONLINE }, - { 0x238800, 1, RI_ALL_ONLINE }, { 0x238840, 1, RI_ALL_ONLINE }, - { 0x238880, 1, RI_ALL_ONLINE }, { 0x2388c0, 1, RI_ALL_ONLINE }, - { 0x238900, 1, RI_ALL_ONLINE }, { 0x238940, 1, RI_ALL_ONLINE }, - { 0x238980, 1, RI_ALL_ONLINE }, { 0x2389c0, 1, RI_ALL_ONLINE }, - { 0x238a00, 1, RI_ALL_ONLINE }, { 0x238a40, 1, RI_ALL_ONLINE }, - { 0x238a80, 1, RI_ALL_ONLINE }, { 0x238ac0, 1, RI_ALL_ONLINE }, - { 0x238b00, 1, RI_ALL_ONLINE }, { 0x238b40, 1, RI_ALL_ONLINE }, - { 0x238b80, 1, RI_ALL_ONLINE }, { 0x238bc0, 1, RI_ALL_ONLINE }, - { 0x238c00, 1, RI_ALL_ONLINE }, { 0x238c40, 1, RI_ALL_ONLINE }, - { 0x238c80, 1, RI_ALL_ONLINE }, { 0x238cc0, 1, RI_ALL_ONLINE }, - { 0x238cc4, 1, RI_E2E3_ONLINE }, { 0x238d00, 1, RI_ALL_ONLINE }, - { 0x238d40, 1, RI_ALL_ONLINE }, { 0x238d80, 1, RI_ALL_ONLINE }, - { 0x238dc0, 1, RI_ALL_ONLINE }, { 0x238e00, 1, RI_ALL_ONLINE }, - { 0x238e40, 1, RI_ALL_ONLINE }, { 0x238e80, 1, RI_ALL_ONLINE }, - { 0x238e84, 1, RI_E2E3_ONLINE }, { 0x238ec0, 1, RI_E1HE2E3_ONLINE }, - { 0x238f00, 1, RI_E1HE2E3_ONLINE }, { 0x238f40, 1, RI_E1HE2E3_ONLINE }, - { 0x238f80, 1, RI_E1HE2E3_ONLINE }, { 0x238fc0, 1, RI_E1HE2E3_ONLINE }, - { 0x238fc4, 2, RI_E2E3_ONLINE }, { 0x238fd0, 6, RI_E2E3_ONLINE }, - { 0x238fe8, 2, RI_E3_ONLINE }, { 0x239000, 1, RI_E2E3_ONLINE }, - { 0x239040, 3, RI_E2E3_ONLINE }, { 0x23905c, 1, RI_E3_ONLINE }, - { 0x240000, 2, RI_ALL_ONLINE }, { 0x280000, 65, RI_ALL_ONLINE }, - { 0x28014c, 2, RI_E1HE2E3_ONLINE }, { 0x280200, 58, RI_ALL_ONLINE }, - { 0x280340, 4, RI_ALL_ONLINE }, { 0x280380, 1, RI_E2E3_ONLINE }, - { 0x280388, 1, RI_E2E3_ONLINE }, { 0x280390, 1, RI_E2E3_ONLINE }, - { 0x280398, 1, RI_E2E3_ONLINE }, { 0x2803a0, 1, RI_E2E3_ONLINE }, - { 0x2803a8, 2, RI_E2E3_ONLINE }, { 0x280400, 1, RI_ALL_ONLINE }, - { 0x280404, 255, RI_E1E1H_OFFLINE }, { 0x282000, 4, RI_ALL_ONLINE }, - { 0x282010, 2044, RI_ALL_OFFLINE }, { 0x284000, 4, RI_E3_ONLINE }, - { 0x2a0000, 1, RI_ALL_ONLINE }, { 0x2a0004, 5631, RI_ALL_OFFLINE }, - { 0x2a5800, 2560, RI_E1HE2E3_OFFLINE }, { 0x2a8000, 1, RI_ALL_ONLINE }, - { 0x2a8004, 8191, RI_E1HE2E3_OFFLINE }, { 0x2b0000, 1, RI_ALL_ONLINE }, - { 0x2b0004, 15, RI_E1H_OFFLINE }, { 0x2b0040, 1, RI_E1HE2E3_ONLINE }, - { 0x2b0044, 239, RI_E1H_OFFLINE }, { 0x2b0400, 1, RI_ALL_ONLINE }, - { 0x2b0404, 255, RI_E1H_OFFLINE }, { 0x2b0800, 1, RI_ALL_ONLINE }, - { 0x2b0840, 1, RI_E1HE2E3_ONLINE }, { 0x2b0c00, 1, RI_ALL_ONLINE }, - { 0x2b1000, 1, RI_ALL_ONLINE }, { 0x2b1040, 1, RI_E1HE2E3_ONLINE }, - { 0x2b1400, 1, RI_ALL_ONLINE }, { 0x2b1440, 1, RI_E1HE2E3_ONLINE }, - { 0x2b1480, 1, RI_E1HE2E3_ONLINE }, { 0x2b14c0, 1, RI_E1HE2E3_ONLINE }, - { 0x2b1800, 128, RI_ALL_OFFLINE }, { 0x2b1c00, 128, RI_ALL_OFFLINE }, - { 0x2b2000, 1, RI_ALL_ONLINE }, { 0x2b2400, 1, RI_E1HE2E3_ONLINE }, - { 0x2b2404, 5631, RI_E2E3_OFFLINE }, { 0x2b8000, 1, RI_ALL_ONLINE }, - { 0x2b8040, 1, RI_ALL_ONLINE }, { 0x2b8080, 1, RI_ALL_ONLINE }, - { 0x2b80c0, 1, RI_ALL_ONLINE }, { 0x2b8100, 1, RI_ALL_ONLINE }, - { 0x2b8140, 1, RI_ALL_ONLINE }, { 0x2b8180, 1, RI_ALL_ONLINE }, - { 0x2b81c0, 1, RI_ALL_ONLINE }, { 0x2b8200, 1, RI_ALL_ONLINE }, - { 0x2b8240, 1, RI_ALL_ONLINE }, { 0x2b8280, 1, RI_ALL_ONLINE }, - { 0x2b82c0, 1, RI_ALL_ONLINE }, { 0x2b8300, 1, RI_ALL_ONLINE }, - { 0x2b8340, 1, RI_ALL_ONLINE }, { 0x2b8380, 1, RI_ALL_ONLINE }, - { 0x2b83c0, 1, RI_ALL_ONLINE }, { 0x2b8400, 1, RI_ALL_ONLINE }, - { 0x2b8440, 1, RI_ALL_ONLINE }, { 0x2b8480, 1, RI_ALL_ONLINE }, - { 0x2b84c0, 1, RI_ALL_ONLINE }, { 0x2b8500, 1, RI_ALL_ONLINE }, - { 0x2b8540, 1, RI_ALL_ONLINE }, { 0x2b8580, 1, RI_ALL_ONLINE }, - { 0x2b85c0, 19, RI_E2E3_ONLINE }, { 0x2b8800, 1, RI_ALL_ONLINE }, - { 0x2b8840, 1, RI_ALL_ONLINE }, { 0x2b8880, 1, RI_ALL_ONLINE }, - { 0x2b88c0, 1, RI_ALL_ONLINE }, { 0x2b8900, 1, RI_ALL_ONLINE }, - { 0x2b8940, 1, RI_ALL_ONLINE }, { 0x2b8980, 1, RI_ALL_ONLINE }, - { 0x2b89c0, 1, RI_ALL_ONLINE }, { 0x2b8a00, 1, RI_ALL_ONLINE }, - { 0x2b8a40, 1, RI_ALL_ONLINE }, { 0x2b8a80, 1, RI_ALL_ONLINE }, - { 0x2b8ac0, 1, RI_ALL_ONLINE }, { 0x2b8b00, 1, RI_ALL_ONLINE }, - { 0x2b8b40, 1, RI_ALL_ONLINE }, { 0x2b8b80, 1, RI_ALL_ONLINE }, - { 0x2b8bc0, 1, RI_ALL_ONLINE }, { 0x2b8c00, 1, RI_ALL_ONLINE }, - { 0x2b8c40, 1, RI_ALL_ONLINE }, { 0x2b8c80, 1, RI_ALL_ONLINE }, - { 0x2b8cc0, 1, RI_ALL_ONLINE }, { 0x2b8cc4, 1, RI_E2E3_ONLINE }, - { 0x2b8d00, 1, RI_ALL_ONLINE }, { 0x2b8d40, 1, RI_ALL_ONLINE }, - { 0x2b8d80, 1, RI_ALL_ONLINE }, { 0x2b8dc0, 1, RI_ALL_ONLINE }, - { 0x2b8e00, 1, RI_ALL_ONLINE }, { 0x2b8e40, 1, RI_ALL_ONLINE }, - { 0x2b8e80, 1, RI_ALL_ONLINE }, { 0x2b8e84, 1, RI_E2E3_ONLINE }, - { 0x2b8ec0, 1, RI_E1HE2E3_ONLINE }, { 0x2b8f00, 1, RI_E1HE2E3_ONLINE }, - { 0x2b8f40, 1, RI_E1HE2E3_ONLINE }, { 0x2b8f80, 1, RI_E1HE2E3_ONLINE }, - { 0x2b8fc0, 1, RI_E1HE2E3_ONLINE }, { 0x2b8fc4, 2, RI_E2E3_ONLINE }, - { 0x2b8fd0, 6, RI_E2E3_ONLINE }, { 0x2b8fe8, 2, RI_E3_ONLINE }, - { 0x2b9000, 1, RI_E2E3_ONLINE }, { 0x2b9040, 3, RI_E2E3_ONLINE }, - { 0x2b905c, 1, RI_E3_ONLINE }, { 0x2b9400, 14, RI_E2E3_ONLINE }, - { 0x2b943c, 19, RI_E2E3_ONLINE }, { 0x2b9490, 10, RI_E2E3_ONLINE }, - { 0x2c0000, 2, RI_ALL_ONLINE }, { 0x300000, 65, RI_ALL_ONLINE }, - { 0x30014c, 2, RI_E1HE2E3_ONLINE }, { 0x300200, 58, RI_ALL_ONLINE }, - { 0x300340, 4, RI_ALL_ONLINE }, { 0x300380, 1, RI_E2E3_ONLINE }, - { 0x300388, 1, RI_E2E3_ONLINE }, { 0x300390, 1, RI_E2E3_ONLINE }, - { 0x300398, 1, RI_E2E3_ONLINE }, { 0x3003a0, 1, RI_E2E3_ONLINE }, - { 0x3003a8, 2, RI_E2E3_ONLINE }, { 0x300400, 1, RI_ALL_ONLINE }, - { 0x300404, 255, RI_E1E1H_OFFLINE }, { 0x302000, 4, RI_ALL_ONLINE }, - { 0x302010, 2044, RI_ALL_OFFLINE }, { 0x304000, 4, RI_E3_ONLINE }, - { 0x320000, 1, RI_ALL_ONLINE }, { 0x320004, 5631, RI_ALL_OFFLINE }, - { 0x325800, 2560, RI_E1HE2E3_OFFLINE }, { 0x328000, 1, RI_ALL_ONLINE }, - { 0x328004, 8191, RI_E1HE2E3_OFFLINE }, { 0x330000, 1, RI_ALL_ONLINE }, - { 0x330004, 15, RI_E1H_OFFLINE }, { 0x330040, 1, RI_E1HE2E3_ONLINE }, - { 0x330044, 239, RI_E1H_OFFLINE }, { 0x330400, 1, RI_ALL_ONLINE }, - { 0x330404, 255, RI_E1H_OFFLINE }, { 0x330800, 1, RI_ALL_ONLINE }, - { 0x330840, 1, RI_E1HE2E3_ONLINE }, { 0x330c00, 1, RI_ALL_ONLINE }, - { 0x331000, 1, RI_ALL_ONLINE }, { 0x331040, 1, RI_E1HE2E3_ONLINE }, - { 0x331400, 1, RI_ALL_ONLINE }, { 0x331440, 1, RI_E1HE2E3_ONLINE }, - { 0x331480, 1, RI_E1HE2E3_ONLINE }, { 0x3314c0, 1, RI_E1HE2E3_ONLINE }, - { 0x331800, 128, RI_ALL_OFFLINE }, { 0x331c00, 128, RI_ALL_OFFLINE }, - { 0x332000, 1, RI_ALL_ONLINE }, { 0x332400, 1, RI_E1HE2E3_ONLINE }, - { 0x332404, 5631, RI_E2E3_OFFLINE }, { 0x338000, 1, RI_ALL_ONLINE }, - { 0x338040, 1, RI_ALL_ONLINE }, { 0x338080, 1, RI_ALL_ONLINE }, - { 0x3380c0, 1, RI_ALL_ONLINE }, { 0x338100, 1, RI_ALL_ONLINE }, - { 0x338140, 1, RI_ALL_ONLINE }, { 0x338180, 1, RI_ALL_ONLINE }, - { 0x3381c0, 1, RI_ALL_ONLINE }, { 0x338200, 1, RI_ALL_ONLINE }, - { 0x338240, 1, RI_ALL_ONLINE }, { 0x338280, 1, RI_ALL_ONLINE }, - { 0x3382c0, 1, RI_ALL_ONLINE }, { 0x338300, 1, RI_ALL_ONLINE }, - { 0x338340, 1, RI_ALL_ONLINE }, { 0x338380, 1, RI_ALL_ONLINE }, - { 0x3383c0, 1, RI_ALL_ONLINE }, { 0x338400, 1, RI_ALL_ONLINE }, - { 0x338440, 1, RI_ALL_ONLINE }, { 0x338480, 1, RI_ALL_ONLINE }, - { 0x3384c0, 1, RI_ALL_ONLINE }, { 0x338500, 1, RI_ALL_ONLINE }, - { 0x338540, 1, RI_ALL_ONLINE }, { 0x338580, 1, RI_ALL_ONLINE }, - { 0x3385c0, 19, RI_E2E3_ONLINE }, { 0x338800, 1, RI_ALL_ONLINE }, - { 0x338840, 1, RI_ALL_ONLINE }, { 0x338880, 1, RI_ALL_ONLINE }, - { 0x3388c0, 1, RI_ALL_ONLINE }, { 0x338900, 1, RI_ALL_ONLINE }, - { 0x338940, 1, RI_ALL_ONLINE }, { 0x338980, 1, RI_ALL_ONLINE }, - { 0x3389c0, 1, RI_ALL_ONLINE }, { 0x338a00, 1, RI_ALL_ONLINE }, - { 0x338a40, 1, RI_ALL_ONLINE }, { 0x338a80, 1, RI_ALL_ONLINE }, - { 0x338ac0, 1, RI_ALL_ONLINE }, { 0x338b00, 1, RI_ALL_ONLINE }, - { 0x338b40, 1, RI_ALL_ONLINE }, { 0x338b80, 1, RI_ALL_ONLINE }, - { 0x338bc0, 1, RI_ALL_ONLINE }, { 0x338c00, 1, RI_ALL_ONLINE }, - { 0x338c40, 1, RI_ALL_ONLINE }, { 0x338c80, 1, RI_ALL_ONLINE }, - { 0x338cc0, 1, RI_ALL_ONLINE }, { 0x338cc4, 1, RI_E2E3_ONLINE }, - { 0x338d00, 1, RI_ALL_ONLINE }, { 0x338d40, 1, RI_ALL_ONLINE }, - { 0x338d80, 1, RI_ALL_ONLINE }, { 0x338dc0, 1, RI_ALL_ONLINE }, - { 0x338e00, 1, RI_ALL_ONLINE }, { 0x338e40, 1, RI_ALL_ONLINE }, - { 0x338e80, 1, RI_ALL_ONLINE }, { 0x338e84, 1, RI_E2E3_ONLINE }, - { 0x338ec0, 1, RI_E1HE2E3_ONLINE }, { 0x338f00, 1, RI_E1HE2E3_ONLINE }, - { 0x338f40, 1, RI_E1HE2E3_ONLINE }, { 0x338f80, 1, RI_E1HE2E3_ONLINE }, - { 0x338fc0, 1, RI_E1HE2E3_ONLINE }, { 0x338fc4, 2, RI_E2E3_ONLINE }, - { 0x338fd0, 6, RI_E2E3_ONLINE }, { 0x338fe8, 2, RI_E3_ONLINE }, - { 0x339000, 1, RI_E2E3_ONLINE }, { 0x339040, 3, RI_E2E3_ONLINE }, - { 0x33905c, 1, RI_E3_ONLINE }, { 0x340000, 2, RI_ALL_ONLINE }, + { 0x225800, 2560, RI_E1HE2E3E3B0_OFFLINE }, + { 0x228000, 1, RI_ALL_ONLINE }, + { 0x228004, 8191, RI_E1HE2E3E3B0_OFFLINE }, + { 0x230000, 1, RI_ALL_ONLINE }, + { 0x230004, 15, RI_E1H_OFFLINE }, + { 0x230040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x230044, 239, RI_E1H_OFFLINE }, + { 0x230400, 1, RI_ALL_ONLINE }, + { 0x230404, 255, RI_E1H_OFFLINE }, + { 0x230800, 1, RI_ALL_ONLINE }, + { 0x230840, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x230c00, 1, RI_ALL_ONLINE }, + { 0x231000, 1, RI_ALL_ONLINE }, + { 0x231040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x231400, 1, RI_ALL_ONLINE }, + { 0x231440, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x231480, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2314c0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x231800, 128, RI_ALL_OFFLINE }, + { 0x231c00, 128, RI_ALL_OFFLINE }, + { 0x232000, 1, RI_ALL_ONLINE }, + { 0x232400, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x232404, 5631, RI_E2E3E3B0_OFFLINE }, + { 0x238000, 1, RI_ALL_ONLINE }, + { 0x238040, 1, RI_ALL_ONLINE }, + { 0x238080, 1, RI_ALL_ONLINE }, + { 0x2380c0, 1, RI_ALL_ONLINE }, + { 0x238100, 1, RI_ALL_ONLINE }, + { 0x238140, 1, RI_ALL_ONLINE }, + { 0x238180, 1, RI_ALL_ONLINE }, + { 0x2381c0, 1, RI_ALL_ONLINE }, + { 0x238200, 1, RI_ALL_ONLINE }, + { 0x238240, 1, RI_ALL_ONLINE }, + { 0x238280, 1, RI_ALL_ONLINE }, + { 0x2382c0, 1, RI_ALL_ONLINE }, + { 0x238300, 1, RI_ALL_ONLINE }, + { 0x238340, 1, RI_ALL_ONLINE }, + { 0x238380, 1, RI_ALL_ONLINE }, + { 0x2383c0, 1, RI_ALL_ONLINE }, + { 0x238400, 1, RI_ALL_ONLINE }, + { 0x238440, 1, RI_ALL_ONLINE }, + { 0x238480, 1, RI_ALL_ONLINE }, + { 0x2384c0, 1, RI_ALL_ONLINE }, + { 0x238500, 1, RI_ALL_ONLINE }, + { 0x238540, 1, RI_ALL_ONLINE }, + { 0x238580, 1, RI_ALL_ONLINE }, + { 0x2385c0, 19, RI_E2E3E3B0_ONLINE }, + { 0x238800, 1, RI_ALL_ONLINE }, + { 0x238840, 1, RI_ALL_ONLINE }, + { 0x238880, 1, RI_ALL_ONLINE }, + { 0x2388c0, 1, RI_ALL_ONLINE }, + { 0x238900, 1, RI_ALL_ONLINE }, + { 0x238940, 1, RI_ALL_ONLINE }, + { 0x238980, 1, RI_ALL_ONLINE }, + { 0x2389c0, 1, RI_ALL_ONLINE }, + { 0x238a00, 1, RI_ALL_ONLINE }, + { 0x238a40, 1, RI_ALL_ONLINE }, + { 0x238a80, 1, RI_ALL_ONLINE }, + { 0x238ac0, 1, RI_ALL_ONLINE }, + { 0x238b00, 1, RI_ALL_ONLINE }, + { 0x238b40, 1, RI_ALL_ONLINE }, + { 0x238b80, 1, RI_ALL_ONLINE }, + { 0x238bc0, 1, RI_ALL_ONLINE }, + { 0x238c00, 1, RI_ALL_ONLINE }, + { 0x238c40, 1, RI_ALL_ONLINE }, + { 0x238c80, 1, RI_ALL_ONLINE }, + { 0x238cc0, 1, RI_ALL_ONLINE }, + { 0x238cc4, 1, RI_E2E3E3B0_ONLINE }, + { 0x238d00, 1, RI_ALL_ONLINE }, + { 0x238d40, 1, RI_ALL_ONLINE }, + { 0x238d80, 1, RI_ALL_ONLINE }, + { 0x238dc0, 1, RI_ALL_ONLINE }, + { 0x238e00, 1, RI_ALL_ONLINE }, + { 0x238e40, 1, RI_ALL_ONLINE }, + { 0x238e80, 1, RI_ALL_ONLINE }, + { 0x238e84, 1, RI_E2E3E3B0_ONLINE }, + { 0x238ec0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x238f00, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x238f40, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x238f80, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x238fc0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x238fc4, 2, RI_E2E3E3B0_ONLINE }, + { 0x238fd0, 6, RI_E2E3E3B0_ONLINE }, + { 0x238fe8, 2, RI_E3E3B0_ONLINE }, + { 0x239000, 1, RI_E2E3E3B0_ONLINE }, + { 0x239040, 3, RI_E2E3E3B0_ONLINE }, + { 0x23905c, 1, RI_E3E3B0_ONLINE }, + { 0x239064, 1, RI_E3B0_ONLINE }, + { 0x239080, 10, RI_E3B0_ONLINE }, + { 0x240000, 2, RI_ALL_ONLINE }, + { 0x280000, 65, RI_ALL_ONLINE }, + { 0x28014c, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x280200, 58, RI_ALL_ONLINE }, + { 0x280340, 4, RI_ALL_ONLINE }, + { 0x280380, 1, RI_E2E3E3B0_ONLINE }, + { 0x280388, 1, RI_E2E3E3B0_ONLINE }, + { 0x280390, 1, RI_E2E3E3B0_ONLINE }, + { 0x280398, 1, RI_E2E3E3B0_ONLINE }, + { 0x2803a0, 1, RI_E2E3E3B0_ONLINE }, + { 0x2803a8, 2, RI_E2E3E3B0_ONLINE }, + { 0x280400, 1, RI_ALL_ONLINE }, + { 0x280404, 255, RI_E1E1H_OFFLINE }, + { 0x282000, 4, RI_ALL_ONLINE }, + { 0x282010, 2044, RI_ALL_OFFLINE }, + { 0x284000, 4, RI_E3E3B0_ONLINE }, + { 0x2a0000, 1, RI_ALL_ONLINE }, + { 0x2a0004, 5631, RI_ALL_OFFLINE }, + { 0x2a5800, 2560, RI_E1HE2E3E3B0_OFFLINE }, + { 0x2a8000, 1, RI_ALL_ONLINE }, + { 0x2a8004, 8191, RI_E1HE2E3E3B0_OFFLINE }, + { 0x2b0000, 1, RI_ALL_ONLINE }, + { 0x2b0004, 15, RI_E1H_OFFLINE }, + { 0x2b0040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b0044, 239, RI_E1H_OFFLINE }, + { 0x2b0400, 1, RI_ALL_ONLINE }, + { 0x2b0404, 255, RI_E1H_OFFLINE }, + { 0x2b0800, 1, RI_ALL_ONLINE }, + { 0x2b0840, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b0c00, 1, RI_ALL_ONLINE }, + { 0x2b1000, 1, RI_ALL_ONLINE }, + { 0x2b1040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b1400, 1, RI_ALL_ONLINE }, + { 0x2b1440, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b1480, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b14c0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b1800, 128, RI_ALL_OFFLINE }, + { 0x2b1c00, 128, RI_ALL_OFFLINE }, + { 0x2b2000, 1, RI_ALL_ONLINE }, + { 0x2b2400, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b2404, 5631, RI_E2E3E3B0_OFFLINE }, + { 0x2b8000, 1, RI_ALL_ONLINE }, + { 0x2b8040, 1, RI_ALL_ONLINE }, + { 0x2b8080, 1, RI_ALL_ONLINE }, + { 0x2b80c0, 1, RI_ALL_ONLINE }, + { 0x2b8100, 1, RI_ALL_ONLINE }, + { 0x2b8140, 1, RI_ALL_ONLINE }, + { 0x2b8180, 1, RI_ALL_ONLINE }, + { 0x2b81c0, 1, RI_ALL_ONLINE }, + { 0x2b8200, 1, RI_ALL_ONLINE }, + { 0x2b8240, 1, RI_ALL_ONLINE }, + { 0x2b8280, 1, RI_ALL_ONLINE }, + { 0x2b82c0, 1, RI_ALL_ONLINE }, + { 0x2b8300, 1, RI_ALL_ONLINE }, + { 0x2b8340, 1, RI_ALL_ONLINE }, + { 0x2b8380, 1, RI_ALL_ONLINE }, + { 0x2b83c0, 1, RI_ALL_ONLINE }, + { 0x2b8400, 1, RI_ALL_ONLINE }, + { 0x2b8440, 1, RI_ALL_ONLINE }, + { 0x2b8480, 1, RI_ALL_ONLINE }, + { 0x2b84c0, 1, RI_ALL_ONLINE }, + { 0x2b8500, 1, RI_ALL_ONLINE }, + { 0x2b8540, 1, RI_ALL_ONLINE }, + { 0x2b8580, 1, RI_ALL_ONLINE }, + { 0x2b85c0, 19, RI_E2E3E3B0_ONLINE }, + { 0x2b8800, 1, RI_ALL_ONLINE }, + { 0x2b8840, 1, RI_ALL_ONLINE }, + { 0x2b8880, 1, RI_ALL_ONLINE }, + { 0x2b88c0, 1, RI_ALL_ONLINE }, + { 0x2b8900, 1, RI_ALL_ONLINE }, + { 0x2b8940, 1, RI_ALL_ONLINE }, + { 0x2b8980, 1, RI_ALL_ONLINE }, + { 0x2b89c0, 1, RI_ALL_ONLINE }, + { 0x2b8a00, 1, RI_ALL_ONLINE }, + { 0x2b8a40, 1, RI_ALL_ONLINE }, + { 0x2b8a80, 1, RI_ALL_ONLINE }, + { 0x2b8ac0, 1, RI_ALL_ONLINE }, + { 0x2b8b00, 1, RI_ALL_ONLINE }, + { 0x2b8b40, 1, RI_ALL_ONLINE }, + { 0x2b8b80, 1, RI_ALL_ONLINE }, + { 0x2b8bc0, 1, RI_ALL_ONLINE }, + { 0x2b8c00, 1, RI_ALL_ONLINE }, + { 0x2b8c40, 1, RI_ALL_ONLINE }, + { 0x2b8c80, 1, RI_ALL_ONLINE }, + { 0x2b8cc0, 1, RI_ALL_ONLINE }, + { 0x2b8cc4, 1, RI_E2E3E3B0_ONLINE }, + { 0x2b8d00, 1, RI_ALL_ONLINE }, + { 0x2b8d40, 1, RI_ALL_ONLINE }, + { 0x2b8d80, 1, RI_ALL_ONLINE }, + { 0x2b8dc0, 1, RI_ALL_ONLINE }, + { 0x2b8e00, 1, RI_ALL_ONLINE }, + { 0x2b8e40, 1, RI_ALL_ONLINE }, + { 0x2b8e80, 1, RI_ALL_ONLINE }, + { 0x2b8e84, 1, RI_E2E3E3B0_ONLINE }, + { 0x2b8ec0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b8f00, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b8f40, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b8f80, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b8fc0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b8fc4, 2, RI_E2E3E3B0_ONLINE }, + { 0x2b8fd0, 6, RI_E2E3E3B0_ONLINE }, + { 0x2b8fe8, 2, RI_E3E3B0_ONLINE }, + { 0x2b9000, 1, RI_E2E3E3B0_ONLINE }, + { 0x2b9040, 3, RI_E2E3E3B0_ONLINE }, + { 0x2b905c, 1, RI_E3E3B0_ONLINE }, + { 0x2b9064, 1, RI_E3B0_ONLINE }, + { 0x2b9080, 10, RI_E3B0_ONLINE }, + { 0x2b9400, 14, RI_E2E3E3B0_ONLINE }, + { 0x2b943c, 19, RI_E2E3E3B0_ONLINE }, + { 0x2b9490, 10, RI_E2E3E3B0_ONLINE }, + { 0x2c0000, 2, RI_ALL_ONLINE }, + { 0x300000, 65, RI_ALL_ONLINE }, + { 0x30014c, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x300200, 58, RI_ALL_ONLINE }, + { 0x300340, 4, RI_ALL_ONLINE }, + { 0x300380, 1, RI_E2E3E3B0_ONLINE }, + { 0x300388, 1, RI_E2E3E3B0_ONLINE }, + { 0x300390, 1, RI_E2E3E3B0_ONLINE }, + { 0x300398, 1, RI_E2E3E3B0_ONLINE }, + { 0x3003a0, 1, RI_E2E3E3B0_ONLINE }, + { 0x3003a8, 2, RI_E2E3E3B0_ONLINE }, + { 0x300400, 1, RI_ALL_ONLINE }, + { 0x300404, 255, RI_E1E1H_OFFLINE }, + { 0x302000, 4, RI_ALL_ONLINE }, + { 0x302010, 2044, RI_ALL_OFFLINE }, + { 0x304000, 4, RI_E3E3B0_ONLINE }, + { 0x320000, 1, RI_ALL_ONLINE }, + { 0x320004, 5631, RI_ALL_OFFLINE }, + { 0x325800, 2560, RI_E1HE2E3E3B0_OFFLINE }, + { 0x328000, 1, RI_ALL_ONLINE }, + { 0x328004, 8191, RI_E1HE2E3E3B0_OFFLINE }, + { 0x330000, 1, RI_ALL_ONLINE }, + { 0x330004, 15, RI_E1H_OFFLINE }, + { 0x330040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x330044, 239, RI_E1H_OFFLINE }, + { 0x330400, 1, RI_ALL_ONLINE }, + { 0x330404, 255, RI_E1H_OFFLINE }, + { 0x330800, 1, RI_ALL_ONLINE }, + { 0x330840, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x330c00, 1, RI_ALL_ONLINE }, + { 0x331000, 1, RI_ALL_ONLINE }, + { 0x331040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x331400, 1, RI_ALL_ONLINE }, + { 0x331440, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x331480, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x3314c0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x331800, 128, RI_ALL_OFFLINE }, + { 0x331c00, 128, RI_ALL_OFFLINE }, + { 0x332000, 1, RI_ALL_ONLINE }, + { 0x332400, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x332404, 5631, RI_E2E3E3B0_OFFLINE }, + { 0x338000, 1, RI_ALL_ONLINE }, + { 0x338040, 1, RI_ALL_ONLINE }, + { 0x338080, 1, RI_ALL_ONLINE }, + { 0x3380c0, 1, RI_ALL_ONLINE }, + { 0x338100, 1, RI_ALL_ONLINE }, + { 0x338140, 1, RI_ALL_ONLINE }, + { 0x338180, 1, RI_ALL_ONLINE }, + { 0x3381c0, 1, RI_ALL_ONLINE }, + { 0x338200, 1, RI_ALL_ONLINE }, + { 0x338240, 1, RI_ALL_ONLINE }, + { 0x338280, 1, RI_ALL_ONLINE }, + { 0x3382c0, 1, RI_ALL_ONLINE }, + { 0x338300, 1, RI_ALL_ONLINE }, + { 0x338340, 1, RI_ALL_ONLINE }, + { 0x338380, 1, RI_ALL_ONLINE }, + { 0x3383c0, 1, RI_ALL_ONLINE }, + { 0x338400, 1, RI_ALL_ONLINE }, + { 0x338440, 1, RI_ALL_ONLINE }, + { 0x338480, 1, RI_ALL_ONLINE }, + { 0x3384c0, 1, RI_ALL_ONLINE }, + { 0x338500, 1, RI_ALL_ONLINE }, + { 0x338540, 1, RI_ALL_ONLINE }, + { 0x338580, 1, RI_ALL_ONLINE }, + { 0x3385c0, 19, RI_E2E3E3B0_ONLINE }, + { 0x338800, 1, RI_ALL_ONLINE }, + { 0x338840, 1, RI_ALL_ONLINE }, + { 0x338880, 1, RI_ALL_ONLINE }, + { 0x3388c0, 1, RI_ALL_ONLINE }, + { 0x338900, 1, RI_ALL_ONLINE }, + { 0x338940, 1, RI_ALL_ONLINE }, + { 0x338980, 1, RI_ALL_ONLINE }, + { 0x3389c0, 1, RI_ALL_ONLINE }, + { 0x338a00, 1, RI_ALL_ONLINE }, + { 0x338a40, 1, RI_ALL_ONLINE }, + { 0x338a80, 1, RI_ALL_ONLINE }, + { 0x338ac0, 1, RI_ALL_ONLINE }, + { 0x338b00, 1, RI_ALL_ONLINE }, + { 0x338b40, 1, RI_ALL_ONLINE }, + { 0x338b80, 1, RI_ALL_ONLINE }, + { 0x338bc0, 1, RI_ALL_ONLINE }, + { 0x338c00, 1, RI_ALL_ONLINE }, + { 0x338c40, 1, RI_ALL_ONLINE }, + { 0x338c80, 1, RI_ALL_ONLINE }, + { 0x338cc0, 1, RI_ALL_ONLINE }, + { 0x338cc4, 1, RI_E2E3E3B0_ONLINE }, + { 0x338d00, 1, RI_ALL_ONLINE }, + { 0x338d40, 1, RI_ALL_ONLINE }, + { 0x338d80, 1, RI_ALL_ONLINE }, + { 0x338dc0, 1, RI_ALL_ONLINE }, + { 0x338e00, 1, RI_ALL_ONLINE }, + { 0x338e40, 1, RI_ALL_ONLINE }, + { 0x338e80, 1, RI_ALL_ONLINE }, + { 0x338e84, 1, RI_E2E3E3B0_ONLINE }, + { 0x338ec0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x338f00, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x338f40, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x338f80, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x338fc0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x338fc4, 2, RI_E2E3E3B0_ONLINE }, + { 0x338fd0, 6, RI_E2E3E3B0_ONLINE }, + { 0x338fe8, 2, RI_E3E3B0_ONLINE }, + { 0x339000, 1, RI_E2E3E3B0_ONLINE }, + { 0x339040, 3, RI_E2E3E3B0_ONLINE }, + { 0x33905c, 1, RI_E3E3B0_ONLINE }, + { 0x339064, 1, RI_E3B0_ONLINE }, + { 0x339080, 10, RI_E3B0_ONLINE }, + { 0x340000, 2, RI_ALL_ONLINE }, }; #define REGS_COUNT ARRAY_SIZE(reg_addrs) -static const struct reg_addr idle_addrs[] = { - { 0x2104, 1, RI_ALL_ONLINE }, { 0x2110, 2, RI_ALL_ONLINE }, - { 0x211c, 8, RI_ALL_ONLINE }, { 0x2814, 1, RI_ALL_ONLINE }, - { 0x281c, 2, RI_ALL_ONLINE }, { 0x2854, 1, RI_ALL_ONLINE }, - { 0x285c, 1, RI_ALL_ONLINE }, { 0x3040, 1, RI_ALL_ONLINE }, - { 0x9010, 7, RI_E2E3_ONLINE }, { 0x9030, 1, RI_E2E3_ONLINE }, - { 0x9068, 16, RI_E2E3_ONLINE }, { 0x9230, 2, RI_E2E3_ONLINE }, - { 0x9244, 1, RI_E2E3_ONLINE }, { 0x9298, 1, RI_E2E3_ONLINE }, - { 0x92a8, 1, RI_E2E3_ONLINE }, { 0xa38c, 1, RI_ALL_ONLINE }, - { 0xa3c4, 1, RI_E1HE2E3_ONLINE }, { 0xa404, 3, RI_ALL_ONLINE }, - { 0xa42c, 12, RI_ALL_ONLINE }, { 0xa600, 5, RI_E1HE2E3_ONLINE }, - { 0xa618, 1, RI_E1HE2E3_ONLINE }, { 0xa714, 1, RI_E2E3_ONLINE }, - { 0xa720, 1, RI_E2E3_ONLINE }, { 0xa750, 1, RI_E2E3_ONLINE }, - { 0xc09c, 1, RI_E1E1H_ONLINE }, { 0x103b0, 1, RI_ALL_ONLINE }, - { 0x103c0, 1, RI_ALL_ONLINE }, { 0x103d0, 1, RI_E1H_ONLINE }, - { 0x10418, 1, RI_ALL_ONLINE }, { 0x10420, 1, RI_ALL_ONLINE }, - { 0x10428, 1, RI_ALL_ONLINE }, { 0x10460, 1, RI_ALL_ONLINE }, - { 0x10474, 1, RI_ALL_ONLINE }, { 0x104e0, 1, RI_ALL_ONLINE }, - { 0x104ec, 1, RI_ALL_ONLINE }, { 0x104f8, 1, RI_ALL_ONLINE }, - { 0x10508, 1, RI_ALL_ONLINE }, { 0x10530, 1, RI_ALL_ONLINE }, - { 0x10538, 1, RI_ALL_ONLINE }, { 0x10548, 1, RI_ALL_ONLINE }, - { 0x10558, 1, RI_ALL_ONLINE }, { 0x182a8, 1, RI_E2E3_ONLINE }, - { 0x182b8, 1, RI_E2E3_ONLINE }, { 0x18308, 1, RI_E2E3_ONLINE }, - { 0x18318, 1, RI_E2E3_ONLINE }, { 0x18338, 1, RI_E2E3_ONLINE }, - { 0x18348, 1, RI_E2E3_ONLINE }, { 0x183bc, 1, RI_E2E3_ONLINE }, - { 0x183cc, 1, RI_E2E3_ONLINE }, { 0x18570, 1, RI_E3_ONLINE }, - { 0x18578, 1, RI_E3_ONLINE }, { 0x1858c, 1, RI_E3_ONLINE }, - { 0x18594, 1, RI_E3_ONLINE }, { 0x2021c, 11, RI_ALL_ONLINE }, - { 0x202a8, 1, RI_ALL_ONLINE }, { 0x202b8, 1, RI_ALL_ONLINE }, - { 0x20404, 1, RI_ALL_ONLINE }, { 0x2040c, 2, RI_ALL_ONLINE }, - { 0x2041c, 2, RI_ALL_ONLINE }, { 0x40154, 14, RI_ALL_ONLINE }, - { 0x40198, 1, RI_ALL_ONLINE }, { 0x404ac, 1, RI_ALL_ONLINE }, - { 0x404bc, 1, RI_ALL_ONLINE }, { 0x42290, 1, RI_ALL_ONLINE }, - { 0x422a0, 1, RI_ALL_ONLINE }, { 0x422b0, 1, RI_ALL_ONLINE }, - { 0x42548, 1, RI_ALL_ONLINE }, { 0x42550, 1, RI_ALL_ONLINE }, - { 0x42558, 1, RI_ALL_ONLINE }, { 0x50160, 8, RI_ALL_ONLINE }, - { 0x501d0, 1, RI_ALL_ONLINE }, { 0x501e0, 1, RI_ALL_ONLINE }, - { 0x50204, 1, RI_ALL_ONLINE }, { 0x5020c, 2, RI_ALL_ONLINE }, - { 0x5021c, 1, RI_ALL_ONLINE }, { 0x60090, 1, RI_ALL_ONLINE }, - { 0x6011c, 1, RI_ALL_ONLINE }, { 0x6012c, 1, RI_ALL_ONLINE }, - { 0xc101c, 1, RI_ALL_ONLINE }, { 0xc102c, 1, RI_ALL_ONLINE }, - { 0xc2290, 1, RI_ALL_ONLINE }, { 0xc22a0, 1, RI_ALL_ONLINE }, - { 0xc22b0, 1, RI_ALL_ONLINE }, { 0xc2548, 1, RI_ALL_ONLINE }, - { 0xc2550, 1, RI_ALL_ONLINE }, { 0xc2558, 1, RI_ALL_ONLINE }, - { 0xc4294, 1, RI_ALL_ONLINE }, { 0xc42a4, 1, RI_ALL_ONLINE }, - { 0xc42b4, 1, RI_ALL_ONLINE }, { 0xc4550, 1, RI_ALL_ONLINE }, - { 0xc4558, 1, RI_ALL_ONLINE }, { 0xc4560, 1, RI_ALL_ONLINE }, - { 0xd016c, 8, RI_ALL_ONLINE }, { 0xd01d8, 1, RI_ALL_ONLINE }, - { 0xd01e8, 1, RI_ALL_ONLINE }, { 0xd0204, 1, RI_ALL_ONLINE }, - { 0xd020c, 3, RI_ALL_ONLINE }, { 0xe0154, 8, RI_ALL_ONLINE }, - { 0xe01c8, 1, RI_ALL_ONLINE }, { 0xe01d8, 1, RI_ALL_ONLINE }, - { 0xe0204, 1, RI_ALL_ONLINE }, { 0xe020c, 2, RI_ALL_ONLINE }, - { 0xe021c, 2, RI_ALL_ONLINE }, { 0x101014, 1, RI_ALL_ONLINE }, - { 0x101030, 1, RI_ALL_ONLINE }, { 0x101040, 1, RI_ALL_ONLINE }, - { 0x102058, 1, RI_ALL_ONLINE }, { 0x102080, 16, RI_ALL_ONLINE }, - { 0x103004, 2, RI_ALL_ONLINE }, { 0x103068, 1, RI_ALL_ONLINE }, - { 0x103078, 1, RI_ALL_ONLINE }, { 0x103088, 1, RI_ALL_ONLINE }, - { 0x10309c, 2, RI_E1HE2E3_ONLINE }, { 0x1030b8, 2, RI_E2E3_ONLINE }, - { 0x1030cc, 1, RI_E2E3_ONLINE }, { 0x1030e0, 1, RI_E2E3_ONLINE }, - { 0x104004, 1, RI_ALL_ONLINE }, { 0x104018, 1, RI_ALL_ONLINE }, - { 0x104020, 1, RI_ALL_ONLINE }, { 0x10403c, 1, RI_ALL_ONLINE }, - { 0x1040fc, 1, RI_ALL_ONLINE }, { 0x10410c, 1, RI_ALL_ONLINE }, - { 0x104400, 64, RI_ALL_ONLINE }, { 0x104800, 64, RI_ALL_ONLINE }, - { 0x105000, 256, RI_ALL_ONLINE }, { 0x108094, 1, RI_E1E1H_ONLINE }, - { 0x1201b0, 2, RI_ALL_ONLINE }, { 0x12032c, 1, RI_ALL_ONLINE }, - { 0x12036c, 3, RI_ALL_ONLINE }, { 0x120408, 2, RI_ALL_ONLINE }, - { 0x120414, 15, RI_ALL_ONLINE }, { 0x120478, 2, RI_ALL_ONLINE }, - { 0x12052c, 1, RI_ALL_ONLINE }, { 0x120564, 3, RI_ALL_ONLINE }, - { 0x12057c, 1, RI_ALL_ONLINE }, { 0x12058c, 1, RI_ALL_ONLINE }, - { 0x120608, 1, RI_E1HE2E3_ONLINE }, { 0x120778, 2, RI_E2E3_ONLINE }, - { 0x120808, 3, RI_ALL_ONLINE }, { 0x120818, 1, RI_ALL_ONLINE }, - { 0x120820, 1, RI_ALL_ONLINE }, { 0x120828, 1, RI_ALL_ONLINE }, - { 0x120830, 1, RI_ALL_ONLINE }, { 0x120838, 1, RI_ALL_ONLINE }, - { 0x120840, 1, RI_ALL_ONLINE }, { 0x120848, 1, RI_ALL_ONLINE }, - { 0x120850, 1, RI_ALL_ONLINE }, { 0x120858, 1, RI_ALL_ONLINE }, - { 0x120860, 1, RI_ALL_ONLINE }, { 0x120868, 1, RI_ALL_ONLINE }, - { 0x120870, 1, RI_ALL_ONLINE }, { 0x120878, 1, RI_ALL_ONLINE }, - { 0x120880, 1, RI_ALL_ONLINE }, { 0x120888, 1, RI_ALL_ONLINE }, - { 0x120890, 1, RI_ALL_ONLINE }, { 0x120898, 1, RI_ALL_ONLINE }, - { 0x1208a0, 1, RI_ALL_ONLINE }, { 0x1208a8, 1, RI_ALL_ONLINE }, - { 0x1208b0, 1, RI_ALL_ONLINE }, { 0x1208b8, 1, RI_ALL_ONLINE }, - { 0x1208c0, 1, RI_ALL_ONLINE }, { 0x1208c8, 1, RI_ALL_ONLINE }, - { 0x1208d0, 1, RI_ALL_ONLINE }, { 0x1208d8, 1, RI_ALL_ONLINE }, - { 0x1208e0, 1, RI_ALL_ONLINE }, { 0x1208e8, 1, RI_ALL_ONLINE }, - { 0x1208f0, 1, RI_ALL_ONLINE }, { 0x1208f8, 1, RI_ALL_ONLINE }, - { 0x120900, 1, RI_ALL_ONLINE }, { 0x120908, 1, RI_ALL_ONLINE }, - { 0x130030, 1, RI_E2E3_ONLINE }, { 0x13004c, 3, RI_E2E3_ONLINE }, - { 0x130064, 2, RI_E2E3_ONLINE }, { 0x13009c, 1, RI_E2E3_ONLINE }, - { 0x130130, 1, RI_E2E3_ONLINE }, { 0x13016c, 1, RI_E2E3_ONLINE }, - { 0x130300, 1, RI_E2E3_ONLINE }, { 0x130480, 1, RI_E2E3_ONLINE }, - { 0x14005c, 2, RI_ALL_ONLINE }, { 0x1400d0, 2, RI_ALL_ONLINE }, - { 0x1400e0, 1, RI_ALL_ONLINE }, { 0x1401c8, 1, RI_ALL_ONLINE }, - { 0x140200, 6, RI_ALL_ONLINE }, { 0x16101c, 1, RI_ALL_ONLINE }, - { 0x16102c, 1, RI_ALL_ONLINE }, { 0x164014, 2, RI_ALL_ONLINE }, - { 0x1640f0, 1, RI_ALL_ONLINE }, { 0x166290, 1, RI_ALL_ONLINE }, - { 0x1662a0, 1, RI_ALL_ONLINE }, { 0x1662b0, 1, RI_ALL_ONLINE }, - { 0x166548, 1, RI_ALL_ONLINE }, { 0x166550, 1, RI_ALL_ONLINE }, - { 0x166558, 1, RI_ALL_ONLINE }, { 0x168000, 1, RI_ALL_ONLINE }, - { 0x168008, 1, RI_ALL_ONLINE }, { 0x168010, 1, RI_ALL_ONLINE }, - { 0x168018, 1, RI_ALL_ONLINE }, { 0x168028, 2, RI_ALL_ONLINE }, - { 0x168058, 4, RI_ALL_ONLINE }, { 0x168070, 1, RI_ALL_ONLINE }, - { 0x168238, 1, RI_ALL_ONLINE }, { 0x1682d0, 2, RI_ALL_ONLINE }, - { 0x1682e0, 1, RI_ALL_ONLINE }, { 0x168300, 2, RI_E1E1H_ONLINE }, - { 0x168308, 65, RI_ALL_ONLINE }, { 0x168410, 2, RI_ALL_ONLINE }, - { 0x168438, 1, RI_ALL_ONLINE }, { 0x168448, 1, RI_ALL_ONLINE }, - { 0x168a00, 128, RI_ALL_ONLINE }, { 0x16e200, 128, RI_E1H_ONLINE }, - { 0x16e404, 2, RI_E1H_ONLINE }, { 0x16e584, 64, RI_E1H_ONLINE }, - { 0x16e684, 2, RI_E1HE2E3_ONLINE }, { 0x16e68c, 4, RI_E1H_ONLINE }, - { 0x16e6fc, 4, RI_E2E3_ONLINE }, { 0x1700a4, 1, RI_ALL_ONLINE }, - { 0x1700ac, 2, RI_ALL_ONLINE }, { 0x1700c0, 1, RI_ALL_ONLINE }, - { 0x170174, 1, RI_ALL_ONLINE }, { 0x170184, 1, RI_ALL_ONLINE }, - { 0x1800f4, 1, RI_ALL_ONLINE }, { 0x180104, 1, RI_ALL_ONLINE }, - { 0x180114, 1, RI_ALL_ONLINE }, { 0x180124, 1, RI_ALL_ONLINE }, - { 0x18026c, 1, RI_ALL_ONLINE }, { 0x1802a0, 1, RI_ALL_ONLINE }, - { 0x1b8000, 1, RI_ALL_ONLINE }, { 0x1b8040, 1, RI_ALL_ONLINE }, - { 0x1b8080, 1, RI_ALL_ONLINE }, { 0x1b80c0, 1, RI_ALL_ONLINE }, - { 0x200104, 1, RI_ALL_ONLINE }, { 0x200114, 1, RI_ALL_ONLINE }, - { 0x200124, 1, RI_ALL_ONLINE }, { 0x200134, 1, RI_ALL_ONLINE }, - { 0x20026c, 1, RI_ALL_ONLINE }, { 0x2002a0, 1, RI_ALL_ONLINE }, - { 0x238000, 1, RI_ALL_ONLINE }, { 0x238040, 1, RI_ALL_ONLINE }, - { 0x238080, 1, RI_ALL_ONLINE }, { 0x2380c0, 1, RI_ALL_ONLINE }, - { 0x280104, 1, RI_ALL_ONLINE }, { 0x280114, 1, RI_ALL_ONLINE }, - { 0x280124, 1, RI_ALL_ONLINE }, { 0x280134, 1, RI_ALL_ONLINE }, - { 0x28026c, 1, RI_ALL_ONLINE }, { 0x2802a0, 1, RI_ALL_ONLINE }, - { 0x2b8000, 1, RI_ALL_ONLINE }, { 0x2b8040, 1, RI_ALL_ONLINE }, - { 0x2b8080, 1, RI_ALL_ONLINE }, { 0x300104, 1, RI_ALL_ONLINE }, - { 0x300114, 1, RI_ALL_ONLINE }, { 0x300124, 1, RI_ALL_ONLINE }, - { 0x300134, 1, RI_ALL_ONLINE }, { 0x30026c, 1, RI_ALL_ONLINE }, - { 0x3002a0, 1, RI_ALL_ONLINE }, { 0x338000, 1, RI_ALL_ONLINE }, - { 0x338040, 1, RI_ALL_ONLINE }, { 0x338080, 1, RI_ALL_ONLINE }, - { 0x3380c0, 1, RI_ALL_ONLINE } -}; -#define IDLE_REGS_COUNT ARRAY_SIZE(idle_addrs) - -static const u32 read_reg_e1_0[] = { 0x1b1000 }; -#define WREGS_COUNT_E1 ARRAY_SIZE(read_reg_e1_0) - -static const struct wreg_addr wreg_addrs_e1[WREGS_COUNT_E1] = { - { 0x1b0c00, 192, 1, read_reg_e1_0, RI_E1_OFFLINE } -}; - -static const u32 read_reg_e1h_0[] = { 0x1b1040, 0x1b1000 }; -#define WREGS_COUNT_E1H ARRAY_SIZE(read_reg_e1h_0) - -static const struct wreg_addr wreg_addrs_e1h[WREGS_COUNT_E1H] = { - { 0x1b0c00, 256, 2, read_reg_e1h_0, RI_E1H_OFFLINE } -}; - -static const u32 read_reg_e2_0[] = { 0x1b1040, 0x1b1000 }; -#define WREGS_COUNT_E2 ARRAY_SIZE(read_reg_e2_0) - -static const struct wreg_addr wreg_addrs_e2[WREGS_COUNT_E2] = { - { 0x1b0c00, 128, 2, read_reg_e2_0, RI_E2_OFFLINE } -}; - -static const u32 read_reg_e3_0[] = { 0x1b1040, 0x1b1000 }; -#define WREGS_COUNT_E3 ARRAY_SIZE(read_reg_e3_0) - -static const struct wreg_addr wreg_addrs_e3[WREGS_COUNT_E3] = { - { 0x1b0c00, 128, 2, read_reg_e3_0, RI_E3_OFFLINE } }; - -static const struct dump_sign dump_sign_all = { 0x4dbe9fca, 0x60011, 0x3a }; - -static const u32 timer_status_regs_e1[] = { 0x164014, 0x164018 }; -#define TIMER_REGS_COUNT_E1 ARRAY_SIZE(timer_status_regs_e1) - -static const u32 timer_scan_regs_e1[TIMER_REGS_COUNT_E1] = { - 0x1640d0, 0x1640d4 }; - -static const u32 timer_status_regs_e1h[] = { 0x164014, 0x164018 }; -#define TIMER_REGS_COUNT_E1H ARRAY_SIZE(timer_status_regs_e1h) - -static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] = { - 0x1640d0, 0x1640d4 }; - -static const u32 timer_status_regs_e2[] = { 0x164014, 0x164018 }; -#define TIMER_REGS_COUNT_E2 ARRAY_SIZE(timer_status_regs_e2) - -static const u32 timer_scan_regs_e2[TIMER_REGS_COUNT_E2] = { - 0x1640d0, 0x1640d4 }; - -static const u32 timer_status_regs_e3[] = { 0x164014, 0x164018 }; -#define TIMER_REGS_COUNT_E3 ARRAY_SIZE(timer_status_regs_e3) - -static const u32 timer_scan_regs_e3[TIMER_REGS_COUNT_E3] = { - 0x1640d0, 0x1640d4 }; - -#define PAGE_MODE_VALUES_E1 0 - -#define PAGE_READ_REGS_E1 0 - -#define PAGE_WRITE_REGS_E1 0 - -static const u32 page_vals_e1[] = { 0 }; - -static const u32 page_write_regs_e1[] = { 0 }; - -static const struct reg_addr page_read_regs_e1[] = { - { 0x0, 0, RI_E1_ONLINE } }; - -#define PAGE_MODE_VALUES_E1H 0 - -#define PAGE_READ_REGS_E1H 0 - -#define PAGE_WRITE_REGS_E1H 0 - -static const u32 page_vals_e1h[] = { 0 }; - -static const u32 page_write_regs_e1h[] = { 0 }; - -static const struct reg_addr page_read_regs_e1h[] = { - { 0x0, 0, RI_E1H_ONLINE } }; +static const struct dump_sign dump_sign_all = { 0x4e23fde1, 0x70017, 0x3a }; static const u32 page_vals_e2[] = { 0, 128 }; #define PAGE_MODE_VALUES_E2 ARRAY_SIZE(page_vals_e2) @@ -836,7 +1150,7 @@ static const u32 page_write_regs_e3[] = { 328476 }; #define PAGE_WRITE_REGS_E3 ARRAY_SIZE(page_write_regs_e3) static const struct reg_addr page_read_regs_e3[] = { - { 0x58000, 4608, RI_E3_ONLINE } }; + { 0x58000, 4608, RI_E3E3B0_ONLINE } }; #define PAGE_READ_REGS_E3 ARRAY_SIZE(page_read_regs_e3) #endif /* BNX2X_DUMP_H */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index ac0223135b7c..221863059dae 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -500,78 +500,179 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) #define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE) #define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE) #define IS_E2_ONLINE(info) (((info) & RI_E2_ONLINE) == RI_E2_ONLINE) +#define IS_E3_ONLINE(info) (((info) & RI_E3_ONLINE) == RI_E3_ONLINE) +#define IS_E3B0_ONLINE(info) (((info) & RI_E3B0_ONLINE) == RI_E3B0_ONLINE) + +static inline bool bnx2x_is_reg_online(struct bnx2x *bp, + const struct reg_addr *reg_info) +{ + if (CHIP_IS_E1(bp)) + return IS_E1_ONLINE(reg_info->info); + else if (CHIP_IS_E1H(bp)) + return IS_E1H_ONLINE(reg_info->info); + else if (CHIP_IS_E2(bp)) + return IS_E2_ONLINE(reg_info->info); + else if (CHIP_IS_E3A0(bp)) + return IS_E3_ONLINE(reg_info->info); + else if (CHIP_IS_E3B0(bp)) + return IS_E3B0_ONLINE(reg_info->info); + else + return false; +} + +/******* Paged registers info selectors ********/ +static inline const u32 *__bnx2x_get_page_addr_ar(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) + return page_vals_e2; + else if (CHIP_IS_E3(bp)) + return page_vals_e3; + else + return NULL; +} + +static inline u32 __bnx2x_get_page_reg_num(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) + return PAGE_MODE_VALUES_E2; + else if (CHIP_IS_E3(bp)) + return PAGE_MODE_VALUES_E3; + else + return 0; +} + +static inline const u32 *__bnx2x_get_page_write_ar(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) + return page_write_regs_e2; + else if (CHIP_IS_E3(bp)) + return page_write_regs_e3; + else + return NULL; +} + +static inline u32 __bnx2x_get_page_write_num(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) + return PAGE_WRITE_REGS_E2; + else if (CHIP_IS_E3(bp)) + return PAGE_WRITE_REGS_E3; + else + return 0; +} + +static inline const struct reg_addr *__bnx2x_get_page_read_ar(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) + return page_read_regs_e2; + else if (CHIP_IS_E3(bp)) + return page_read_regs_e3; + else + return NULL; +} + +static inline u32 __bnx2x_get_page_read_num(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) + return PAGE_READ_REGS_E2; + else if (CHIP_IS_E3(bp)) + return PAGE_READ_REGS_E3; + else + return 0; +} + +static inline int __bnx2x_get_regs_len(struct bnx2x *bp) +{ + int num_pages = __bnx2x_get_page_reg_num(bp); + int page_write_num = __bnx2x_get_page_write_num(bp); + const struct reg_addr *page_read_addr = __bnx2x_get_page_read_ar(bp); + int page_read_num = __bnx2x_get_page_read_num(bp); + int regdump_len = 0; + int i, j, k; + + for (i = 0; i < REGS_COUNT; i++) + if (bnx2x_is_reg_online(bp, ®_addrs[i])) + regdump_len += reg_addrs[i].size; + + for (i = 0; i < num_pages; i++) + for (j = 0; j < page_write_num; j++) + for (k = 0; k < page_read_num; k++) + if (bnx2x_is_reg_online(bp, &page_read_addr[k])) + regdump_len += page_read_addr[k].size; + + return regdump_len; +} static int bnx2x_get_regs_len(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); int regdump_len = 0; - int i, j, k; - if (CHIP_IS_E1(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E1_ONLINE(reg_addrs[i].info)) - regdump_len += reg_addrs[i].size; - - for (i = 0; i < WREGS_COUNT_E1; i++) - if (IS_E1_ONLINE(wreg_addrs_e1[i].info)) - regdump_len += wreg_addrs_e1[i].size * - (1 + wreg_addrs_e1[i].read_regs_count); - - } else if (CHIP_IS_E1H(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E1H_ONLINE(reg_addrs[i].info)) - regdump_len += reg_addrs[i].size; - - for (i = 0; i < WREGS_COUNT_E1H; i++) - if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info)) - regdump_len += wreg_addrs_e1h[i].size * - (1 + wreg_addrs_e1h[i].read_regs_count); - } else if (!CHIP_IS_E1x(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E2_ONLINE(reg_addrs[i].info)) - regdump_len += reg_addrs[i].size; - - for (i = 0; i < WREGS_COUNT_E2; i++) - if (IS_E2_ONLINE(wreg_addrs_e2[i].info)) - regdump_len += wreg_addrs_e2[i].size * - (1 + wreg_addrs_e2[i].read_regs_count); - - for (i = 0; i < PAGE_MODE_VALUES_E2; i++) - for (j = 0; j < PAGE_WRITE_REGS_E2; j++) { - for (k = 0; k < PAGE_READ_REGS_E2; k++) - if (IS_E2_ONLINE(page_read_regs_e2[k]. - info)) - regdump_len += - page_read_regs_e2[k].size; - } - } + regdump_len = __bnx2x_get_regs_len(bp); regdump_len *= 4; regdump_len += sizeof(struct dump_hdr); return regdump_len; } -static inline void bnx2x_read_pages_regs_e2(struct bnx2x *bp, u32 *p) +/** + * bnx2x_read_pages_regs - read "paged" registers + * + * @bp device handle + * @p output buffer + * + * Reads "paged" memories: memories that may only be read by first writing to a + * specific address ("write address") and then reading from a specific address + * ("read address"). There may be more than one write address per "page" and + * more than one read address per write address. + */ +static inline void bnx2x_read_pages_regs(struct bnx2x *bp, u32 *p) { u32 i, j, k, n; - - for (i = 0; i < PAGE_MODE_VALUES_E2; i++) { - for (j = 0; j < PAGE_WRITE_REGS_E2; j++) { - REG_WR(bp, page_write_regs_e2[j], page_vals_e2[i]); - for (k = 0; k < PAGE_READ_REGS_E2; k++) - if (IS_E2_ONLINE(page_read_regs_e2[k].info)) + /* addresses of the paged registers */ + const u32 *page_addr = __bnx2x_get_page_addr_ar(bp); + /* number of paged registers */ + int num_pages = __bnx2x_get_page_reg_num(bp); + /* write addresses */ + const u32 *write_addr = __bnx2x_get_page_write_ar(bp); + /* number of write addresses */ + int write_num = __bnx2x_get_page_write_num(bp); + /* read addresses info */ + const struct reg_addr *read_addr = __bnx2x_get_page_read_ar(bp); + /* number of read addresses */ + int read_num = __bnx2x_get_page_read_num(bp); + + for (i = 0; i < num_pages; i++) { + for (j = 0; j < write_num; j++) { + REG_WR(bp, write_addr[j], page_addr[i]); + for (k = 0; k < read_num; k++) + if (bnx2x_is_reg_online(bp, &read_addr[k])) for (n = 0; n < - page_read_regs_e2[k].size; n++) + read_addr[k].size; n++) *p++ = REG_RD(bp, - page_read_regs_e2[k].addr + n*4); + read_addr[k].addr + n*4); } } } +static inline void __bnx2x_get_regs(struct bnx2x *bp, u32 *p) +{ + u32 i, j; + + /* Read the regular registers */ + for (i = 0; i < REGS_COUNT; i++) + if (bnx2x_is_reg_online(bp, ®_addrs[i])) + for (j = 0; j < reg_addrs[i].size; j++) + *p++ = REG_RD(bp, reg_addrs[i].addr + j*4); + + /* Read "paged" registes */ + bnx2x_read_pages_regs(bp, p); +} + static void bnx2x_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p) { - u32 *p = _p, i, j; + u32 *p = _p; struct bnx2x *bp = netdev_priv(dev); struct dump_hdr dump_hdr = {0}; @@ -605,33 +706,9 @@ static void bnx2x_get_regs(struct net_device *dev, memcpy(p, &dump_hdr, sizeof(struct dump_hdr)); p += dump_hdr.hdr_size + 1; - if (CHIP_IS_E1(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E1_ONLINE(reg_addrs[i].info)) - for (j = 0; j < reg_addrs[i].size; j++) - *p++ = REG_RD(bp, - reg_addrs[i].addr + j*4); - - } else if (CHIP_IS_E1H(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E1H_ONLINE(reg_addrs[i].info)) - for (j = 0; j < reg_addrs[i].size; j++) - *p++ = REG_RD(bp, - reg_addrs[i].addr + j*4); - - } else if (!CHIP_IS_E1x(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E2_ONLINE(reg_addrs[i].info)) - for (j = 0; j < reg_addrs[i].size; j++) - *p++ = REG_RD(bp, - reg_addrs[i].addr + j*4); - - if (CHIP_IS_E2(bp)) - bnx2x_read_pages_regs_e2(bp, p); - else - /* E3 paged registers read is unimplemented yet */ - WARN_ON(1); - } + /* Actually read the registers */ + __bnx2x_get_regs(bp, p); + /* Re-enable parity attentions */ bnx2x_clear_blocks_parity(bp); bnx2x_enable_blocks_parity(bp); @@ -1752,7 +1829,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) goto test_loopback_rx_exit; rx_buf = &fp_rx->rx_buf_ring[RX_BD(fp_rx->rx_bd_cons)]; - dma_sync_single_for_device(&bp->pdev->dev, + dma_sync_single_for_cpu(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), fp_rx->rx_buf_size, DMA_FROM_DEVICE); skb = rx_buf->skb; diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index ce3b5662ca5a..06727f32e505 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -1834,6 +1834,7 @@ struct lldp_local_mib { #define DCBX_LOCAL_APP_ERROR 0x00000004 #define DCBX_LOCAL_PFC_MISMATCH 0x00000010 #define DCBX_LOCAL_APP_MISMATCH 0x00000020 + #define DCBX_REMOTE_MIB_ERROR 0x00000040 struct dcbx_features features; u32 suffix_seq_num; }; diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index 82795a8349f6..4d748e77d1ac 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -326,25 +326,25 @@ struct src_ent { /**************************************************************************** * Parity configuration ****************************************************************************/ -#define BLOCK_PRTY_INFO(block, en_mask, m1, m1h, m2) \ +#define BLOCK_PRTY_INFO(block, en_mask, m1, m1h, m2, m3) \ { \ block##_REG_##block##_PRTY_MASK, \ block##_REG_##block##_PRTY_STS_CLR, \ - en_mask, {m1, m1h, m2}, #block \ + en_mask, {m1, m1h, m2, m3}, #block \ } -#define BLOCK_PRTY_INFO_0(block, en_mask, m1, m1h, m2) \ +#define BLOCK_PRTY_INFO_0(block, en_mask, m1, m1h, m2, m3) \ { \ block##_REG_##block##_PRTY_MASK_0, \ block##_REG_##block##_PRTY_STS_CLR_0, \ - en_mask, {m1, m1h, m2}, #block"_0" \ + en_mask, {m1, m1h, m2, m3}, #block"_0" \ } -#define BLOCK_PRTY_INFO_1(block, en_mask, m1, m1h, m2) \ +#define BLOCK_PRTY_INFO_1(block, en_mask, m1, m1h, m2, m3) \ { \ block##_REG_##block##_PRTY_MASK_1, \ block##_REG_##block##_PRTY_STS_CLR_1, \ - en_mask, {m1, m1h, m2}, #block"_1" \ + en_mask, {m1, m1h, m2, m3}, #block"_1" \ } static const struct { @@ -355,6 +355,7 @@ static const struct { u32 e1; /* 57710 */ u32 e1h; /* 57711 */ u32 e2; /* 57712 */ + u32 e3; /* 578xx */ } reg_mask; /* Register mask (all valid bits) */ char name[7]; /* Block's longest name is 6 characters long * (name + suffix) @@ -372,48 +373,56 @@ static const struct { /* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't * want to handle "system kill" flow at the moment. */ - BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff), - BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), - BLOCK_PRTY_INFO_1(PXP2, 0x7ff, 0x7f, 0x7f, 0x7ff), - BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0), - BLOCK_PRTY_INFO(NIG, 0xffffffff, 0x3fffffff, 0xffffffff, 0), - BLOCK_PRTY_INFO_0(NIG, 0xffffffff, 0, 0, 0xffffffff), - BLOCK_PRTY_INFO_1(NIG, 0xffff, 0, 0, 0xffff), - BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff), - BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1), - BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff), - BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3), + BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff, + 0x7ffffff), + BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff), + BLOCK_PRTY_INFO_1(PXP2, 0x1ffffff, 0x7f, 0x7f, 0x7ff, 0x1ffffff), + BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0, 0), + BLOCK_PRTY_INFO(NIG, 0xffffffff, 0x3fffffff, 0xffffffff, 0, 0), + BLOCK_PRTY_INFO_0(NIG, 0xffffffff, 0, 0, 0xffffffff, 0xffffffff), + BLOCK_PRTY_INFO_1(NIG, 0xffff, 0, 0, 0xff, 0xffff), + BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff, 0x7ff), + BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1, 0x1), + BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff, 0xfff), + BLOCK_PRTY_INFO(ATC, 0x1f, 0, 0, 0x1f, 0x1f), + BLOCK_PRTY_INFO(PGLUE_B, 0x3, 0, 0, 0x3, 0x3), + BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3, 0x3), {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0xf, - {0xf, 0xf, 0xf}, "UPB"}, + {0xf, 0xf, 0xf, 0xf}, "UPB"}, {GRCBASE_XPB + PB_REG_PB_PRTY_MASK, GRCBASE_XPB + PB_REG_PB_PRTY_STS_CLR, 0, - {0xf, 0xf, 0xf}, "XPB"}, - BLOCK_PRTY_INFO(SRC, 0x4, 0x7, 0x7, 0x7), - BLOCK_PRTY_INFO(CDU, 0, 0x1f, 0x1f, 0x1f), - BLOCK_PRTY_INFO(CFC, 0, 0xf, 0xf, 0xf), - BLOCK_PRTY_INFO(DBG, 0, 0x1, 0x1, 0x1), - BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf), - BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf), - BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff), - BLOCK_PRTY_INFO(PBF, 0, 0, 0x3ffff, 0xfffffff), - BLOCK_PRTY_INFO(TM, 0, 0, 0x7f, 0x7f), - BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff), - BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff), - BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff), - BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff), - BLOCK_PRTY_INFO(TCM, 0, 0, 0x7ffffff, 0x7ffffff), - BLOCK_PRTY_INFO(CCM, 0, 0, 0x7ffffff, 0x7ffffff), - BLOCK_PRTY_INFO(UCM, 0, 0, 0x7ffffff, 0x7ffffff), - BLOCK_PRTY_INFO(XCM, 0, 0, 0x3fffffff, 0x3fffffff), - BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), - BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f), - BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), - BLOCK_PRTY_INFO_1(USEM, 0, 0x3, 0x1f, 0x1f), - BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), - BLOCK_PRTY_INFO_1(CSEM, 0, 0x3, 0x1f, 0x1f), - BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), - BLOCK_PRTY_INFO_1(XSEM, 0, 0x3, 0x1f, 0x3f), + {0xf, 0xf, 0xf, 0xf}, "XPB"}, + BLOCK_PRTY_INFO(SRC, 0x4, 0x7, 0x7, 0x7, 0x7), + BLOCK_PRTY_INFO(CDU, 0, 0x1f, 0x1f, 0x1f, 0x1f), + BLOCK_PRTY_INFO(CFC, 0, 0xf, 0xf, 0xf, 0x3f), + BLOCK_PRTY_INFO(DBG, 0, 0x1, 0x1, 0x1, 0x1), + BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf, 0xf), + BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf, 0xf), + BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff, 0xff), + BLOCK_PRTY_INFO(PBF, 0, 0, 0x3ffff, 0xfffff, 0xfffffff), + BLOCK_PRTY_INFO(TM, 0, 0, 0x7f, 0x7f, 0x7f), + BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff, 0x7ff), + BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff), + BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff, 0x7ff), + BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff), + BLOCK_PRTY_INFO(TCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff), + BLOCK_PRTY_INFO(CCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff), + BLOCK_PRTY_INFO(UCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff), + BLOCK_PRTY_INFO(XCM, 0, 0, 0x3fffffff, 0x3fffffff, 0x3fffffff), + BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff), + BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f, 0x3f), + BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff), + BLOCK_PRTY_INFO_1(USEM, 0, 0x3, 0x1f, 0x1f, 0x1f), + BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff), + BLOCK_PRTY_INFO_1(CSEM, 0, 0x3, 0x1f, 0x1f, 0x1f), + BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff), + BLOCK_PRTY_INFO_1(XSEM, 0, 0x3, 0x1f, 0x3f, 0x3f), }; @@ -464,8 +473,10 @@ static inline u32 bnx2x_parity_reg_mask(struct bnx2x *bp, int idx) return bnx2x_blocks_parity_data[idx].reg_mask.e1; else if (CHIP_IS_E1H(bp)) return bnx2x_blocks_parity_data[idx].reg_mask.e1h; - else + else if (CHIP_IS_E2(bp)) return bnx2x_blocks_parity_data[idx].reg_mask.e2; + else /* CHIP_IS_E3 */ + return bnx2x_blocks_parity_data[idx].reg_mask.e3; } static inline void bnx2x_disable_blocks_parity(struct bnx2x *bp) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 8a374a77cdc9..e1ec1a302474 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2699,8 +2699,10 @@ static inline unsigned long bnx2x_get_q_flags(struct bnx2x *bp, if (IS_FCOE_FP(fp)) __set_bit(BNX2X_Q_FLG_FCOE, &flags); - if (!fp->disable_tpa) + if (!fp->disable_tpa) { __set_bit(BNX2X_Q_FLG_TPA, &flags); + __set_bit(BNX2X_Q_FLG_TPA_IPV6, &flags); + } if (leading) { __set_bit(BNX2X_Q_FLG_LEADING_RSS, &flags); @@ -2982,8 +2984,12 @@ static inline void bnx2x_sp_prod_update(struct bnx2x *bp) { int func = BP_FUNC(bp); - /* Make sure that BD data is updated before writing the producer */ - wmb(); + /* + * Make sure that BD data is updated before writing the producer: + * BD data is written to the memory, the producer is read from the + * memory, thus we need a full memory barrier to ensure the ordering. + */ + mb(); REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func), bp->spq_prod_idx); @@ -3811,6 +3817,10 @@ static inline int bnx2x_check_blocks_with_parity1(u32 sig, int par_num, if (print) _print_next_block(par_num++, "USDM"); break; + case AEU_INPUTS_ATTN_BITS_UCM_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "UCM"); + break; case AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR: if (print) _print_next_block(par_num++, "USEMI"); @@ -3823,6 +3833,10 @@ static inline int bnx2x_check_blocks_with_parity1(u32 sig, int par_num, if (print) _print_next_block(par_num++, "CSDM"); break; + case AEU_INPUTS_ATTN_BITS_CCM_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "CCM"); + break; } /* Clear the bit */ @@ -3927,32 +3941,67 @@ static inline int bnx2x_check_blocks_with_parity3(u32 sig, int par_num, return par_num; } +static inline int bnx2x_check_blocks_with_parity4(u32 sig, int par_num, + bool print) +{ + int i = 0; + u32 cur_bit = 0; + for (i = 0; sig; i++) { + cur_bit = ((u32)0x1 << i); + if (sig & cur_bit) { + switch (cur_bit) { + case AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "PGLUE_B"); + break; + case AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "ATC"); + break; + } + + /* Clear the bit */ + sig &= ~cur_bit; + } + } + + return par_num; +} + static inline bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print, - u32 sig0, u32 sig1, u32 sig2, u32 sig3) + u32 *sig) { - if ((sig0 & HW_PRTY_ASSERT_SET_0) || (sig1 & HW_PRTY_ASSERT_SET_1) || - (sig2 & HW_PRTY_ASSERT_SET_2) || (sig3 & HW_PRTY_ASSERT_SET_3)) { + if ((sig[0] & HW_PRTY_ASSERT_SET_0) || + (sig[1] & HW_PRTY_ASSERT_SET_1) || + (sig[2] & HW_PRTY_ASSERT_SET_2) || + (sig[3] & HW_PRTY_ASSERT_SET_3) || + (sig[4] & HW_PRTY_ASSERT_SET_4)) { int par_num = 0; DP(NETIF_MSG_HW, "Was parity error: HW block parity attention: " - "[0]:0x%08x [1]:0x%08x " - "[2]:0x%08x [3]:0x%08x\n", - sig0 & HW_PRTY_ASSERT_SET_0, - sig1 & HW_PRTY_ASSERT_SET_1, - sig2 & HW_PRTY_ASSERT_SET_2, - sig3 & HW_PRTY_ASSERT_SET_3); + "[0]:0x%08x [1]:0x%08x [2]:0x%08x [3]:0x%08x " + "[4]:0x%08x\n", + sig[0] & HW_PRTY_ASSERT_SET_0, + sig[1] & HW_PRTY_ASSERT_SET_1, + sig[2] & HW_PRTY_ASSERT_SET_2, + sig[3] & HW_PRTY_ASSERT_SET_3, + sig[4] & HW_PRTY_ASSERT_SET_4); if (print) netdev_err(bp->dev, "Parity errors detected in blocks: "); par_num = bnx2x_check_blocks_with_parity0( - sig0 & HW_PRTY_ASSERT_SET_0, par_num, print); + sig[0] & HW_PRTY_ASSERT_SET_0, par_num, print); par_num = bnx2x_check_blocks_with_parity1( - sig1 & HW_PRTY_ASSERT_SET_1, par_num, global, print); + sig[1] & HW_PRTY_ASSERT_SET_1, par_num, global, print); par_num = bnx2x_check_blocks_with_parity2( - sig2 & HW_PRTY_ASSERT_SET_2, par_num, print); + sig[2] & HW_PRTY_ASSERT_SET_2, par_num, print); par_num = bnx2x_check_blocks_with_parity3( - sig3 & HW_PRTY_ASSERT_SET_3, par_num, global, print); + sig[3] & HW_PRTY_ASSERT_SET_3, par_num, global, print); + par_num = bnx2x_check_blocks_with_parity4( + sig[4] & HW_PRTY_ASSERT_SET_4, par_num, print); + if (print) pr_cont("\n"); + return true; } else return false; @@ -3967,7 +4016,7 @@ static inline bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print, */ bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print) { - struct attn_route attn; + struct attn_route attn = { {0} }; int port = BP_PORT(bp); attn.sig[0] = REG_RD(bp, @@ -3983,8 +4032,12 @@ bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print) MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4); - return bnx2x_parity_attn(bp, global, print, attn.sig[0], attn.sig[1], - attn.sig[2], attn.sig[3]); + if (!CHIP_IS_E1x(bp)) + attn.sig[4] = REG_RD(bp, + MISC_REG_AEU_AFTER_INVERT_5_FUNC_0 + + port*4); + + return bnx2x_parity_attn(bp, global, print, attn.sig); } @@ -4403,11 +4456,17 @@ static void bnx2x_eq_int(struct bnx2x *bp) case EVENT_RING_OPCODE_STOP_TRAFFIC: DP(NETIF_MSG_IFUP, "got STOP TRAFFIC\n"); + if (f_obj->complete_cmd(bp, f_obj, + BNX2X_F_CMD_TX_STOP)) + break; bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_PAUSED); goto next_spqe; case EVENT_RING_OPCODE_START_TRAFFIC: DP(NETIF_MSG_IFUP, "got START TRAFFIC\n"); + if (f_obj->complete_cmd(bp, f_obj, + BNX2X_F_CMD_TX_START)) + break; bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED); goto next_spqe; case EVENT_RING_OPCODE_FUNCTION_START: @@ -4514,8 +4573,15 @@ static void bnx2x_sp_task(struct work_struct *work) struct bnx2x_fastpath *fp = bnx2x_fcoe_fp(bp); if ((!NO_FCOE(bp)) && - (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) + (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { + /* + * Prevent local bottom-halves from running as + * we are going to change the local NAPI list. + */ + local_bh_disable(); napi_schedule(&bnx2x_fcoe(bp, napi)); + local_bh_enable(); + } #endif /* Handle EQ completions */ bnx2x_eq_int(bp); @@ -7536,6 +7602,71 @@ void bnx2x_send_unload_done(struct bnx2x *bp) bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); } +static inline int bnx2x_func_wait_started(struct bnx2x *bp) +{ + int tout = 50; + int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; + + if (!bp->port.pmf) + return 0; + + /* + * (assumption: No Attention from MCP at this stage) + * PMF probably in the middle of TXdisable/enable transaction + * 1. Sync IRS for default SB + * 2. Sync SP queue - this guarantes us that attention handling started + * 3. Wait, that TXdisable/enable transaction completes + * + * 1+2 guranty that if DCBx attention was scheduled it already changed + * pending bit of transaction from STARTED-->TX_STOPPED, if we alredy + * received complettion for the transaction the state is TX_STOPPED. + * State will return to STARTED after completion of TX_STOPPED-->STARTED + * transaction. + */ + + /* make sure default SB ISR is done */ + if (msix) + synchronize_irq(bp->msix_table[0].vector); + else + synchronize_irq(bp->pdev->irq); + + flush_workqueue(bnx2x_wq); + + while (bnx2x_func_get_state(bp, &bp->func_obj) != + BNX2X_F_STATE_STARTED && tout--) + msleep(20); + + if (bnx2x_func_get_state(bp, &bp->func_obj) != + BNX2X_F_STATE_STARTED) { +#ifdef BNX2X_STOP_ON_ERROR + return -EBUSY; +#else + /* + * Failed to complete the transaction in a "good way" + * Force both transactions with CLR bit + */ + struct bnx2x_func_state_params func_params = {0}; + + DP(BNX2X_MSG_SP, "Hmmm... unexpected function state! " + "Forcing STARTED-->TX_ST0PPED-->STARTED\n"); + + func_params.f_obj = &bp->func_obj; + __set_bit(RAMROD_DRV_CLR_ONLY, + &func_params.ramrod_flags); + + /* STARTED-->TX_ST0PPED */ + func_params.cmd = BNX2X_F_CMD_TX_STOP; + bnx2x_func_state_change(bp, &func_params); + + /* TX_ST0PPED-->STARTED */ + func_params.cmd = BNX2X_F_CMD_TX_START; + return bnx2x_func_state_change(bp, &func_params); +#endif + } + + return 0; +} + void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) { int port = BP_PORT(bp); @@ -7595,6 +7726,26 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) netif_addr_unlock_bh(bp->dev); + + /* + * Send the UNLOAD_REQUEST to the MCP. This will return if + * this function should perform FUNC, PORT or COMMON HW + * reset. + */ + reset_code = bnx2x_send_unload_req(bp, unload_mode); + + /* + * (assumption: No Attention from MCP at this stage) + * PMF probably in the middle of TXdisable/enable transaction + */ + rc = bnx2x_func_wait_started(bp); + if (rc) { + BNX2X_ERR("bnx2x_func_wait_started failed\n"); +#ifdef BNX2X_STOP_ON_ERROR + return; +#endif + } + /* Close multi and leading connections * Completions for ramrods are collected in a synchronous way */ @@ -7622,13 +7773,6 @@ unload_error: #endif } - /* - * Send the UNLOAD_REQUEST to the MCP. This will return if - * this function should perform FUNC, PORT or COMMON HW - * reset. - */ - reset_code = bnx2x_send_unload_req(bp, unload_mode); - /* Disable HW interrupts, NAPI */ bnx2x_netif_stop(bp, 1); @@ -7835,7 +7979,7 @@ static void bnx2x_pxp_prep(struct bnx2x *bp) static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global) { u32 not_reset_mask1, reset_mask1, not_reset_mask2, reset_mask2; - u32 global_bits2; + u32 global_bits2, stay_reset2; /* * Bits that have to be set in reset_mask2 if we want to reset 'global' @@ -7845,6 +7989,7 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global) MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CPU | MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CORE; + /* Don't reset the following blocks */ not_reset_mask1 = MISC_REGISTERS_RESET_REG_1_RST_HC | MISC_REGISTERS_RESET_REG_1_RST_PXPV | @@ -7858,19 +8003,35 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global) MISC_REGISTERS_RESET_REG_2_RST_RBCN | MISC_REGISTERS_RESET_REG_2_RST_GRC | MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_REG_HARD_CORE | - MISC_REGISTERS_RESET_REG_2_RST_MCP_N_HARD_CORE_RST_B; + MISC_REGISTERS_RESET_REG_2_RST_MCP_N_HARD_CORE_RST_B | + MISC_REGISTERS_RESET_REG_2_RST_ATC | + MISC_REGISTERS_RESET_REG_2_PGLC; + /* + * Keep the following blocks in reset: + * - all xxMACs are handled by the bnx2x_link code. + */ + stay_reset2 = + MISC_REGISTERS_RESET_REG_2_RST_BMAC0 | + MISC_REGISTERS_RESET_REG_2_RST_BMAC1 | + MISC_REGISTERS_RESET_REG_2_RST_EMAC0 | + MISC_REGISTERS_RESET_REG_2_RST_EMAC1 | + MISC_REGISTERS_RESET_REG_2_UMAC0 | + MISC_REGISTERS_RESET_REG_2_UMAC1 | + MISC_REGISTERS_RESET_REG_2_XMAC | + MISC_REGISTERS_RESET_REG_2_XMAC_SOFT; + + /* Full reset masks according to the chip */ reset_mask1 = 0xffffffff; if (CHIP_IS_E1(bp)) reset_mask2 = 0xffff; - else + else if (CHIP_IS_E1H(bp)) reset_mask2 = 0x1ffff; - - if (CHIP_IS_E3(bp)) { - reset_mask2 |= MISC_REGISTERS_RESET_REG_2_MSTAT0; - reset_mask2 |= MISC_REGISTERS_RESET_REG_2_MSTAT1; - } + else if (CHIP_IS_E2(bp)) + reset_mask2 = 0xfffff; + else /* CHIP_IS_E3 */ + reset_mask2 = 0x3ffffff; /* Don't reset global blocks unless we need to */ if (!global) @@ -7899,7 +8060,12 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global) barrier(); mmiowb(); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, reset_mask2); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, + reset_mask2 & (~stay_reset2)); + + barrier(); + mmiowb(); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, reset_mask1); mmiowb(); } @@ -9007,10 +9173,13 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) #ifdef BCM_CNIC static void __devinit bnx2x_get_cnic_info(struct bnx2x *bp) { + int port = BP_PORT(bp); + int func = BP_ABS_FUNC(bp); + u32 max_iscsi_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, - drv_lic_key[BP_PORT(bp)].max_iscsi_conn); + drv_lic_key[port].max_iscsi_conn); u32 max_fcoe_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, - drv_lic_key[BP_PORT(bp)].max_fcoe_conn); + drv_lic_key[port].max_fcoe_conn); /* Get the number of maximum allowed iSCSI and FCoE connections */ bp->cnic_eth_dev.max_iscsi_conn = @@ -9021,11 +9190,59 @@ static void __devinit bnx2x_get_cnic_info(struct bnx2x *bp) (max_fcoe_conn & BNX2X_MAX_FCOE_INIT_CONN_MASK) >> BNX2X_MAX_FCOE_INIT_CONN_SHIFT; + /* Read the WWN: */ + if (!IS_MF(bp)) { + /* Port info */ + bp->cnic_eth_dev.fcoe_wwn_port_name_hi = + SHMEM_RD(bp, + dev_info.port_hw_config[port]. + fcoe_wwn_port_name_upper); + bp->cnic_eth_dev.fcoe_wwn_port_name_lo = + SHMEM_RD(bp, + dev_info.port_hw_config[port]. + fcoe_wwn_port_name_lower); + + /* Node info */ + bp->cnic_eth_dev.fcoe_wwn_node_name_hi = + SHMEM_RD(bp, + dev_info.port_hw_config[port]. + fcoe_wwn_node_name_upper); + bp->cnic_eth_dev.fcoe_wwn_node_name_lo = + SHMEM_RD(bp, + dev_info.port_hw_config[port]. + fcoe_wwn_node_name_lower); + } else if (!IS_MF_SD(bp)) { + u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); + + /* + * Read the WWN info only if the FCoE feature is enabled for + * this function. + */ + if (cfg & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD) { + /* Port info */ + bp->cnic_eth_dev.fcoe_wwn_port_name_hi = + MF_CFG_RD(bp, func_ext_config[func]. + fcoe_wwn_port_name_upper); + bp->cnic_eth_dev.fcoe_wwn_port_name_lo = + MF_CFG_RD(bp, func_ext_config[func]. + fcoe_wwn_port_name_lower); + + /* Node info */ + bp->cnic_eth_dev.fcoe_wwn_node_name_hi = + MF_CFG_RD(bp, func_ext_config[func]. + fcoe_wwn_node_name_upper); + bp->cnic_eth_dev.fcoe_wwn_node_name_lo = + MF_CFG_RD(bp, func_ext_config[func]. + fcoe_wwn_node_name_lower); + } + } + BNX2X_DEV_INFO("max_iscsi_conn 0x%x max_fcoe_conn 0x%x\n", bp->cnic_eth_dev.max_iscsi_conn, bp->cnic_eth_dev.max_fcoe_conn); - /* If mamimum allowed number of connections is zero - + /* + * If maximum allowed number of connections is zero - * disable the feature. */ if (!bp->cnic_eth_dev.max_iscsi_conn) @@ -9103,6 +9320,12 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) val = SHMEM_RD(bp, dev_info.port_hw_config[port]. iscsi_mac_lower); bnx2x_set_mac_buf(iscsi_mac, val, val2); + + val2 = SHMEM_RD(bp, dev_info.port_hw_config[port]. + fcoe_fip_mac_upper); + val = SHMEM_RD(bp, dev_info.port_hw_config[port]. + fcoe_fip_mac_lower); + bnx2x_set_mac_buf(fip_mac, val, val2); #endif } @@ -9110,13 +9333,9 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); #ifdef BCM_CNIC - /* Set the FCoE MAC in modes other then MF_SI */ - if (!CHIP_IS_E1x(bp)) { - if (IS_MF_SD(bp)) - memcpy(fip_mac, bp->dev->dev_addr, ETH_ALEN); - else if (!IS_MF(bp)) - memcpy(fip_mac, iscsi_mac, ETH_ALEN); - } + /* Set the FCoE MAC in MF_SD mode */ + if (!CHIP_IS_E1x(bp) && IS_MF_SD(bp)) + memcpy(fip_mac, bp->dev->dev_addr, ETH_ALEN); /* Disable iSCSI if MAC configuration is * invalid. @@ -9896,6 +10115,9 @@ static const struct net_device_ops bnx2x_netdev_ops = { #endif .ndo_setup_tc = bnx2x_setup_tc, +#if defined(NETDEV_FCOE_WWNN) && defined(BCM_CNIC) + .ndo_fcoe_get_wwn = bnx2x_fcoe_get_wwn, +#endif }; static inline int bnx2x_set_coherency_mask(struct bnx2x *bp) @@ -10478,8 +10700,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, bp->qm_cid_count = bnx2x_set_qm_cid_count(bp); #ifdef BCM_CNIC - /* disable FCOE L2 queue for E1x*/ - if (CHIP_IS_E1x(bp)) + /* disable FCOE L2 queue for E1x and E3*/ + if (CHIP_IS_E1x(bp) || CHIP_IS_E3(bp)) bp->flags |= NO_FCOE_FLAG; #endif diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 005c05af0905..02461fef8751 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -32,7 +32,11 @@ /* [R 1] ATC initalization done */ #define ATC_REG_ATC_INIT_DONE 0x1100bc /* [RC 6] Interrupt register #0 read clear */ -#define ATC_REG_ATC_INT_STS_CLR 0x1101c0 +#define ATC_REG_ATC_INT_STS_CLR 0x1101c0 +/* [RW 5] Parity mask register #0 read/write */ +#define ATC_REG_ATC_PRTY_MASK 0x1101d8 +/* [RC 5] Parity register #0 read clear */ +#define ATC_REG_ATC_PRTY_STS_CLR 0x1101d0 /* [RW 19] Interrupt mask register #0 read/write */ #define BRB1_REG_BRB1_INT_MASK 0x60128 /* [R 19] Interrupt register #0 read */ @@ -367,7 +371,7 @@ mechanism. The fields are: [5:0] - message length; [12:6] - message pointer; 18:13] - next pointer. */ #define CCM_REG_XX_DESCR_TABLE 0xd0300 -#define CCM_REG_XX_DESCR_TABLE_SIZE 36 +#define CCM_REG_XX_DESCR_TABLE_SIZE 24 /* [R 7] Used to read the value of XX protection Free counter. */ #define CCM_REG_XX_FREE 0xd0184 /* [RW 6] Initial value for the credit counter; responsible for fulfilling @@ -2676,8 +2680,12 @@ #define PGLUE_B_REG_PGLUE_B_INT_STS 0x9298 /* [RC 9] Interrupt register #0 read clear */ #define PGLUE_B_REG_PGLUE_B_INT_STS_CLR 0x929c +/* [RW 2] Parity mask register #0 read/write */ +#define PGLUE_B_REG_PGLUE_B_PRTY_MASK 0x92b4 /* [R 2] Parity register #0 read */ #define PGLUE_B_REG_PGLUE_B_PRTY_STS 0x92a8 +/* [RC 2] Parity register #0 read clear */ +#define PGLUE_B_REG_PGLUE_B_PRTY_STS_CLR 0x92ac /* [R 13] Details of first request received with error. [2:0] - PFID. [3] - * VF_VALID. [9:4] - VFID. [11:10] - Error Code - 0 - Indicates Completion * Timeout of a User Tx non-posted request. 1 - unsupported request. 2 - @@ -4218,7 +4226,7 @@ mechanism. The fields are: [5:0] - length of the message; 15:6] - message pointer; 20:16] - next pointer. */ #define TCM_REG_XX_DESCR_TABLE 0x50280 -#define TCM_REG_XX_DESCR_TABLE_SIZE 32 +#define TCM_REG_XX_DESCR_TABLE_SIZE 29 /* [R 6] Use to read the value of XX protection Free counter. */ #define TCM_REG_XX_FREE 0x50178 /* [RW 6] Initial value for the credit counter; responsible for fulfilling @@ -4746,7 +4754,7 @@ mechanism. The fields are:[5:0] - message length; 14:6] - message pointer; 19:15] - next pointer. */ #define UCM_REG_XX_DESCR_TABLE 0xe0280 -#define UCM_REG_XX_DESCR_TABLE_SIZE 32 +#define UCM_REG_XX_DESCR_TABLE_SIZE 27 /* [R 6] Use to read the XX protection Free counter. */ #define UCM_REG_XX_FREE 0xe016c /* [RW 6] Initial value for the credit counter; responsible for fulfilling @@ -5686,8 +5694,13 @@ #define MISC_REGISTERS_RESET_REG_2_CLEAR 0x598 #define MISC_REGISTERS_RESET_REG_2_MSTAT0 (0x1<<24) #define MISC_REGISTERS_RESET_REG_2_MSTAT1 (0x1<<25) +#define MISC_REGISTERS_RESET_REG_2_PGLC (0x1<<19) +#define MISC_REGISTERS_RESET_REG_2_RST_ATC (0x1<<17) #define MISC_REGISTERS_RESET_REG_2_RST_BMAC0 (0x1<<0) +#define MISC_REGISTERS_RESET_REG_2_RST_BMAC1 (0x1<<1) +#define MISC_REGISTERS_RESET_REG_2_RST_EMAC0 (0x1<<2) #define MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE (0x1<<14) +#define MISC_REGISTERS_RESET_REG_2_RST_EMAC1 (0x1<<3) #define MISC_REGISTERS_RESET_REG_2_RST_EMAC1_HARD_CORE (0x1<<15) #define MISC_REGISTERS_RESET_REG_2_RST_GRC (0x1<<4) #define MISC_REGISTERS_RESET_REG_2_RST_MCP_N_HARD_CORE_RST_B (0x1<<6) @@ -5700,6 +5713,7 @@ #define MISC_REGISTERS_RESET_REG_2_RST_RBCN (0x1<<9) #define MISC_REGISTERS_RESET_REG_2_SET 0x594 #define MISC_REGISTERS_RESET_REG_2_UMAC0 (0x1<<20) +#define MISC_REGISTERS_RESET_REG_2_UMAC1 (0x1<<21) #define MISC_REGISTERS_RESET_REG_2_XMAC (0x1<<22) #define MISC_REGISTERS_RESET_REG_2_XMAC_SOFT (0x1<<23) #define MISC_REGISTERS_RESET_REG_3_CLEAR 0x5a8 diff --git a/drivers/net/bnx2x/bnx2x_sp.c b/drivers/net/bnx2x/bnx2x_sp.c index 358c33997536..df52f110c6c5 100644 --- a/drivers/net/bnx2x/bnx2x_sp.c +++ b/drivers/net/bnx2x/bnx2x_sp.c @@ -1563,8 +1563,13 @@ static int bnx2x_execute_vlan_mac(struct bnx2x *bp, idx++; } - /* Commit the data writes towards the memory */ - mb(); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ rc = bnx2x_sp_post(bp, o->ramrod_cmd, r->cid, U64_HI(r->rdata_mapping), @@ -1684,6 +1689,12 @@ int bnx2x_config_vlan_mac( if (!bnx2x_exe_queue_empty(&o->exe_queue)) rc = 1; + if (test_bit(RAMROD_DRV_CLR_ONLY, ramrod_flags)) { + DP(BNX2X_MSG_SP, "RAMROD_DRV_CLR_ONLY requested: " + "clearing a pending bit.\n"); + raw->clear_pending(raw); + } + /* Execute commands if required */ if (cont || test_bit(RAMROD_EXEC, ramrod_flags) || test_bit(RAMROD_COMP_WAIT, ramrod_flags)) { @@ -2224,8 +2235,13 @@ static int bnx2x_set_rx_mode_e2(struct bnx2x *bp, data->header.rule_cnt, p->rx_accept_flags, p->tx_accept_flags); - /* Commit writes towards the memory before sending a ramrod */ - mb(); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ /* Send a ramrod */ rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_FILTER_RULES, p->cid, @@ -2918,16 +2934,22 @@ static int bnx2x_mcast_setup_e2(struct bnx2x *bp, if (!o->total_pending_num) bnx2x_mcast_refresh_registry_e2(bp, o); - /* Commit writes towards the memory before sending a ramrod */ - mb(); - - /* If CLEAR_ONLY was requested - don't send a ramrod and clear + /* + * If CLEAR_ONLY was requested - don't send a ramrod and clear * RAMROD_PENDING status immediately. */ if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) { raw->clear_pending(raw); return 0; } else { + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ + /* Send a ramrod */ rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_MULTICAST_RULES, raw->cid, U64_HI(raw->rdata_mapping), @@ -3404,16 +3426,22 @@ static int bnx2x_mcast_setup_e1(struct bnx2x *bp, if (rc) return rc; - /* Commit writes towards the memory before sending a ramrod */ - mb(); - - /* If CLEAR_ONLY was requested - don't send a ramrod and clear + /* + * If CLEAR_ONLY was requested - don't send a ramrod and clear * RAMROD_PENDING status immediately. */ if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) { raw->clear_pending(raw); return 0; } else { + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ + /* Send a ramrod */ rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, raw->cid, U64_HI(raw->rdata_mapping), @@ -4038,8 +4066,13 @@ static int bnx2x_setup_rss(struct bnx2x *bp, data->capabilities |= ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY; } - /* Commit writes towards the memory before sending a ramrod */ - mb(); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ /* Send a ramrod */ rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_RSS_UPDATE, r->cid, @@ -4240,7 +4273,7 @@ static void bnx2x_q_fill_setup_data_e2(struct bnx2x *bp, /* Rx data */ /* IPv6 TPA supported for E2 and above only */ - data->rx.tpa_en |= test_bit(BNX2X_Q_FLG_TPA, ¶ms->flags) * + data->rx.tpa_en |= test_bit(BNX2X_Q_FLG_TPA_IPV6, ¶ms->flags) * CLIENT_INIT_RX_DATA_TPA_EN_IPV6; } @@ -4505,7 +4538,13 @@ static inline int bnx2x_q_send_setup_e1x(struct bnx2x *bp, /* Fill the ramrod data */ bnx2x_q_fill_setup_data_cmn(bp, params, rdata); - mb(); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX], U64_HI(data_mapping), @@ -4528,6 +4567,13 @@ static inline int bnx2x_q_send_setup_e2(struct bnx2x *bp, bnx2x_q_fill_setup_data_cmn(bp, params, rdata); bnx2x_q_fill_setup_data_e2(bp, params, rdata); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX], U64_HI(data_mapping), @@ -4665,7 +4711,13 @@ static inline int bnx2x_q_send_update(struct bnx2x *bp, /* Fill the ramrod data */ bnx2x_q_fill_update_data(bp, o, update_params, rdata); - mb(); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_UPDATE, o->cids[cid_index], U64_HI(data_mapping), @@ -4874,6 +4926,22 @@ static int bnx2x_queue_chk_transition(struct bnx2x *bp, ¶ms->params.update; u8 next_tx_only = o->num_tx_only; + /* + * Forget all pending for completion commands if a driver only state + * transition has been requested. + */ + if (test_bit(RAMROD_DRV_CLR_ONLY, ¶ms->ramrod_flags)) { + o->pending = 0; + o->next_state = BNX2X_Q_STATE_MAX; + } + + /* + * Don't allow a next state transition if we are in the middle of + * the previous one. + */ + if (o->pending) + return -EBUSY; + switch (state) { case BNX2X_Q_STATE_RESET: if (cmd == BNX2X_Q_CMD_INIT) @@ -5053,6 +5121,21 @@ void bnx2x_queue_set_cos_cid(struct bnx2x *bp, } /********************** Function state object *********************************/ +enum bnx2x_func_state bnx2x_func_get_state(struct bnx2x *bp, + struct bnx2x_func_sp_obj *o) +{ + /* in the middle of transaction - return INVALID state */ + if (o->pending) + return BNX2X_F_STATE_MAX; + + /* + * unsure the order of reading of o->pending and o->state + * o->pending should be read first + */ + rmb(); + + return o->state; +} static int bnx2x_func_wait_comp(struct bnx2x *bp, struct bnx2x_func_sp_obj *o, @@ -5143,6 +5226,22 @@ static int bnx2x_func_chk_transition(struct bnx2x *bp, enum bnx2x_func_state state = o->state, next_state = BNX2X_F_STATE_MAX; enum bnx2x_func_cmd cmd = params->cmd; + /* + * Forget all pending for completion commands if a driver only state + * transition has been requested. + */ + if (test_bit(RAMROD_DRV_CLR_ONLY, ¶ms->ramrod_flags)) { + o->pending = 0; + o->next_state = BNX2X_F_STATE_MAX; + } + + /* + * Don't allow a next state transition if we are in the middle of + * the previous one. + */ + if (o->pending) + return -EBUSY; + switch (state) { case BNX2X_F_STATE_RESET: if (cmd == BNX2X_F_CMD_HW_INIT) @@ -5160,6 +5259,13 @@ static int bnx2x_func_chk_transition(struct bnx2x *bp, case BNX2X_F_STATE_STARTED: if (cmd == BNX2X_F_CMD_STOP) next_state = BNX2X_F_STATE_INITIALIZED; + else if (cmd == BNX2X_F_CMD_TX_STOP) + next_state = BNX2X_F_STATE_TX_STOPPED; + + break; + case BNX2X_F_STATE_TX_STOPPED: + if (cmd == BNX2X_F_CMD_TX_START) + next_state = BNX2X_F_STATE_STARTED; break; default: @@ -5430,7 +5536,13 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp, rdata->path_id = BP_PATH(bp); rdata->network_cos_mode = start_params->network_cos_mode; - mb(); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_START, 0, U64_HI(data_mapping), @@ -5444,6 +5556,38 @@ static inline int bnx2x_func_send_stop(struct bnx2x *bp, NONE_CONNECTION_TYPE); } +static inline int bnx2x_func_send_tx_stop(struct bnx2x *bp, + struct bnx2x_func_state_params *params) +{ + return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, 0, 0, 0, + NONE_CONNECTION_TYPE); +} +static inline int bnx2x_func_send_tx_start(struct bnx2x *bp, + struct bnx2x_func_state_params *params) +{ + struct bnx2x_func_sp_obj *o = params->f_obj; + struct flow_control_configuration *rdata = + (struct flow_control_configuration *)o->rdata; + dma_addr_t data_mapping = o->rdata_mapping; + struct bnx2x_func_tx_start_params *tx_start_params = + ¶ms->params.tx_start; + int i; + + memset(rdata, 0, sizeof(*rdata)); + + rdata->dcb_enabled = tx_start_params->dcb_enabled; + rdata->dcb_version = tx_start_params->dcb_version; + rdata->dont_add_pri_0_en = tx_start_params->dont_add_pri_0_en; + + for (i = 0; i < ARRAY_SIZE(rdata->traffic_type_to_priority_cos); i++) + rdata->traffic_type_to_priority_cos[i] = + tx_start_params->traffic_type_to_priority_cos[i]; + + return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC, 0, + U64_HI(data_mapping), + U64_LO(data_mapping), NONE_CONNECTION_TYPE); +} + static int bnx2x_func_send_cmd(struct bnx2x *bp, struct bnx2x_func_state_params *params) { @@ -5456,6 +5600,10 @@ static int bnx2x_func_send_cmd(struct bnx2x *bp, return bnx2x_func_send_stop(bp, params); case BNX2X_F_CMD_HW_RESET: return bnx2x_func_hw_reset(bp, params); + case BNX2X_F_CMD_TX_STOP: + return bnx2x_func_send_tx_stop(bp, params); + case BNX2X_F_CMD_TX_START: + return bnx2x_func_send_tx_start(bp, params); default: BNX2X_ERR("Unknown command: %d\n", params->cmd); return -EINVAL; diff --git a/drivers/net/bnx2x/bnx2x_sp.h b/drivers/net/bnx2x/bnx2x_sp.h index 83f3b0b44211..9a517c2e9f1b 100644 --- a/drivers/net/bnx2x/bnx2x_sp.h +++ b/drivers/net/bnx2x/bnx2x_sp.h @@ -749,6 +749,7 @@ enum bnx2x_queue_cmd { /* queue SETUP + INIT flags */ enum { BNX2X_Q_FLG_TPA, + BNX2X_Q_FLG_TPA_IPV6, BNX2X_Q_FLG_STATS, BNX2X_Q_FLG_ZERO_STATS, BNX2X_Q_FLG_ACTIVE, @@ -996,6 +997,7 @@ enum bnx2x_func_state { BNX2X_F_STATE_RESET, BNX2X_F_STATE_INITIALIZED, BNX2X_F_STATE_STARTED, + BNX2X_F_STATE_TX_STOPPED, BNX2X_F_STATE_MAX, }; @@ -1005,6 +1007,8 @@ enum bnx2x_func_cmd { BNX2X_F_CMD_START, BNX2X_F_CMD_STOP, BNX2X_F_CMD_HW_RESET, + BNX2X_F_CMD_TX_STOP, + BNX2X_F_CMD_TX_START, BNX2X_F_CMD_MAX, }; @@ -1047,6 +1051,13 @@ struct bnx2x_func_start_params { u8 network_cos_mode; }; +struct bnx2x_func_tx_start_params { + struct priority_cos traffic_type_to_priority_cos[MAX_TRAFFIC_TYPES]; + u8 dcb_enabled; + u8 dcb_version; + u8 dont_add_pri_0_en; +}; + struct bnx2x_func_state_params { struct bnx2x_func_sp_obj *f_obj; @@ -1061,6 +1072,7 @@ struct bnx2x_func_state_params { struct bnx2x_func_hw_init_params hw_init; struct bnx2x_func_hw_reset_params hw_reset; struct bnx2x_func_start_params start; + struct bnx2x_func_tx_start_params tx_start; } params; }; @@ -1152,6 +1164,8 @@ void bnx2x_init_func_obj(struct bnx2x *bp, int bnx2x_func_state_change(struct bnx2x *bp, struct bnx2x_func_state_params *params); +enum bnx2x_func_state bnx2x_func_get_state(struct bnx2x *bp, + struct bnx2x_func_sp_obj *o); /******************* Queue State **************/ void bnx2x_init_queue_obj(struct bnx2x *bp, struct bnx2x_queue_sp_obj *obj, u8 cl_id, u32 *cids, diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 2df9276720a0..7f8b20a34ee3 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -635,7 +635,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon client_info->ntt = 0; } - if (bond->vlgrp) { + if (bond_vlan_used(bond)) { if (!vlan_get_tag(skb, &client_info->vlan_id)) client_info->tag = 1; } @@ -847,7 +847,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]) skb->priority = TC_PRIO_CONTROL; skb->dev = slave->dev; - if (bond->vlgrp) { + if (bond_vlan_used(bond)) { struct vlan_entry *vlan; vlan = bond_next_vlan(bond, diff --git a/drivers/net/bonding/bond_ipv6.c b/drivers/net/bonding/bond_ipv6.c index 84fbd4ebd778..027a0ee7d85b 100644 --- a/drivers/net/bonding/bond_ipv6.c +++ b/drivers/net/bonding/bond_ipv6.c @@ -183,10 +183,10 @@ static int bond_inet6addr_event(struct notifier_block *this, } list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { - if (!bond->vlgrp) - continue; - vlan_dev = vlan_group_get_device(bond->vlgrp, - vlan->vlan_id); + rcu_read_lock(); + vlan_dev = __vlan_find_dev_deep(bond->dev, + vlan->vlan_id); + rcu_read_unlock(); if (vlan_dev == event_dev) { switch (event) { case NETDEV_UP: diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 61265f74ed3d..02842d05c11f 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -408,9 +408,8 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, } /* - * In the following 3 functions, bond_vlan_rx_register(), bond_vlan_rx_add_vid - * and bond_vlan_rx_kill_vid, We don't protect the slave list iteration with a - * lock because: + * In the following 2 functions, bond_vlan_rx_add_vid and bond_vlan_rx_kill_vid, + * We don't protect the slave list iteration with a lock because: * a. This operation is performed in IOCTL context, * b. The operation is protected by the RTNL semaphore in the 8021q code, * c. Holding a lock with BH disabled while directly calling a base driver @@ -426,33 +425,6 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, */ /** - * bond_vlan_rx_register - Propagates registration to slaves - * @bond_dev: bonding net device that got called - * @grp: vlan group being registered - */ -static void bond_vlan_rx_register(struct net_device *bond_dev, - struct vlan_group *grp) -{ - struct bonding *bond = netdev_priv(bond_dev); - struct slave *slave; - int i; - - write_lock_bh(&bond->lock); - bond->vlgrp = grp; - write_unlock_bh(&bond->lock); - - bond_for_each_slave(bond, slave, i) { - struct net_device *slave_dev = slave->dev; - const struct net_device_ops *slave_ops = slave_dev->netdev_ops; - - if ((slave_dev->features & NETIF_F_HW_VLAN_RX) && - slave_ops->ndo_vlan_rx_register) { - slave_ops->ndo_vlan_rx_register(slave_dev, grp); - } - } -} - -/** * bond_vlan_rx_add_vid - Propagates adding an id to slaves * @bond_dev: bonding net device that got called * @vid: vlan id being added @@ -489,7 +461,6 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid) { struct bonding *bond = netdev_priv(bond_dev); struct slave *slave; - struct net_device *vlan_dev; int i, res; bond_for_each_slave(bond, slave, i) { @@ -498,12 +469,7 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid) if ((slave_dev->features & NETIF_F_HW_VLAN_FILTER) && slave_ops->ndo_vlan_rx_kill_vid) { - /* Save and then restore vlan_dev in the grp array, - * since the slave's driver might clear it. - */ - vlan_dev = vlan_group_get_device(bond->vlgrp, vid); slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vid); - vlan_group_set_device(bond->vlgrp, vid, vlan_dev); } } @@ -519,13 +485,6 @@ static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *sla struct vlan_entry *vlan; const struct net_device_ops *slave_ops = slave_dev->netdev_ops; - if (!bond->vlgrp) - return; - - if ((slave_dev->features & NETIF_F_HW_VLAN_RX) && - slave_ops->ndo_vlan_rx_register) - slave_ops->ndo_vlan_rx_register(slave_dev, bond->vlgrp); - if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) || !(slave_ops->ndo_vlan_rx_add_vid)) return; @@ -539,30 +498,16 @@ static void bond_del_vlans_from_slave(struct bonding *bond, { const struct net_device_ops *slave_ops = slave_dev->netdev_ops; struct vlan_entry *vlan; - struct net_device *vlan_dev; - - if (!bond->vlgrp) - return; if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) || !(slave_ops->ndo_vlan_rx_kill_vid)) - goto unreg; + return; list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { if (!vlan->vlan_id) continue; - /* Save and then restore vlan_dev in the grp array, - * since the slave's driver might clear it. - */ - vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vlan->vlan_id); - vlan_group_set_device(bond->vlgrp, vlan->vlan_id, vlan_dev); } - -unreg: - if ((slave_dev->features & NETIF_F_HW_VLAN_RX) && - slave_ops->ndo_vlan_rx_register) - slave_ops->ndo_vlan_rx_register(slave_dev, NULL); } /*------------------------------- Link status -------------------------------*/ @@ -836,13 +781,13 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) __bond_resend_igmp_join_requests(bond->dev); /* rejoin all groups on vlan devices */ - if (bond->vlgrp) { - list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { - vlan_dev = vlan_group_get_device(bond->vlgrp, - vlan->vlan_id); - if (vlan_dev) - __bond_resend_igmp_join_requests(vlan_dev); - } + list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { + rcu_read_lock(); + vlan_dev = __vlan_find_dev_deep(bond->dev, + vlan->vlan_id); + rcu_read_unlock(); + if (vlan_dev) + __bond_resend_igmp_join_requests(vlan_dev); } if (--bond->igmp_retrans > 0) @@ -1415,9 +1360,9 @@ out: return features; } -#define BOND_VLAN_FEATURES (NETIF_F_ALL_TX_OFFLOADS | \ - NETIF_F_SOFT_FEATURES | \ - NETIF_F_LRO) +#define BOND_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \ + NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \ + NETIF_F_HIGHDMA | NETIF_F_LRO) static void bond_compute_features(struct bonding *bond) { @@ -1557,7 +1502,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) /* no need to lock since we're protected by rtnl_lock */ if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) { pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name); - if (bond->vlgrp) { + if (bond_vlan_used(bond)) { pr_err("%s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n", bond_dev->name, slave_dev->name, bond_dev->name); return -EPERM; @@ -2065,7 +2010,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) */ memset(bond_dev->dev_addr, 0, bond_dev->addr_len); - if (bond->vlgrp) { + if (bond_vlan_used(bond)) { pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", bond_dev->name, bond_dev->name); pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n", @@ -2247,7 +2192,7 @@ static int bond_release_all(struct net_device *bond_dev) */ memset(bond_dev->dev_addr, 0, bond_dev->addr_len); - if (bond->vlgrp) { + if (bond_vlan_used(bond)) { pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", bond_dev->name, bond_dev->name); pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n", @@ -2685,7 +2630,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) if (!targets[i]) break; pr_debug("basa: target %x\n", targets[i]); - if (!bond->vlgrp) { + if (!bond_vlan_used(bond)) { pr_debug("basa: empty vlan: arp_send\n"); bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], bond->master_ip, 0); @@ -2720,7 +2665,10 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) vlan_id = 0; list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { - vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); + rcu_read_lock(); + vlan_dev = __vlan_find_dev_deep(bond->dev, + vlan->vlan_id); + rcu_read_unlock(); if (vlan_dev == rt->dst.dev) { vlan_id = vlan->vlan_id; pr_debug("basa: vlan match on %s %d\n", @@ -3381,9 +3329,8 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, } list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { - if (!bond->vlgrp) - continue; - vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); + vlan_dev = __vlan_find_dev_deep(bond->dev, + vlan->vlan_id); if (vlan_dev == event_dev) { switch (event) { case NETDEV_UP: @@ -4335,10 +4282,9 @@ static const struct net_device_ops bond_netdev_ops = { .ndo_do_ioctl = bond_do_ioctl, .ndo_set_multicast_list = bond_set_multicast_list, .ndo_change_mtu = bond_change_mtu, - .ndo_set_mac_address = bond_set_mac_address, + .ndo_set_mac_address = bond_set_mac_address, .ndo_neigh_setup = bond_neigh_setup, - .ndo_vlan_rx_register = bond_vlan_rx_register, - .ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid, + .ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_netpoll_setup = bond_netpoll_setup, diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 2936171f5332..43526a2d275c 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -240,7 +240,6 @@ struct bonding { struct alb_bond_info alb_info; struct bond_params params; struct list_head vlan_list; - struct vlan_group *vlgrp; struct workqueue_struct *wq; struct delayed_work mii_work; struct delayed_work arp_work; @@ -253,6 +252,11 @@ struct bonding { #endif /* CONFIG_DEBUG_FS */ }; +static inline bool bond_vlan_used(struct bonding *bond) +{ + return !list_empty(&bond->vlan_list); +} + #define bond_slave_get_rcu(dev) \ ((struct slave *) rcu_dereference(dev->rx_handler_data)) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index d0f8c7e67e7d..9bf1116e5b5e 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -208,7 +208,7 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt) return 0; } -int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt) +static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt) { struct can_priv *priv = netdev_priv(dev); int err; diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 65e54fd0a8d7..f523f1cc5142 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -96,10 +96,6 @@ struct slcan { unsigned long flags; /* Flag values/ mode etc */ #define SLF_INUSE 0 /* Channel in use */ #define SLF_ERROR 1 /* Parity, etc. error */ - - unsigned char leased; - dev_t line; - pid_t pid; }; static struct net_device **slcan_devs; @@ -446,7 +442,7 @@ static void slc_sync(void) break; sl = netdev_priv(dev); - if (sl->tty || sl->leased) + if (sl->tty) continue; if (dev->flags & IFF_UP) dev_close(dev); @@ -534,8 +530,6 @@ static int slcan_open(struct tty_struct *tty) sl->tty = tty; tty->disc_data = sl; - sl->line = tty_devnum(tty); - sl->pid = current->pid; if (!test_bit(SLF_INUSE, &sl->flags)) { /* Perform the low-level SLCAN initialization. */ @@ -586,8 +580,6 @@ static void slcan_close(struct tty_struct *tty) tty->disc_data = NULL; sl->tty = NULL; - if (!sl->leased) - sl->line = 0; /* Flush network side */ unregister_netdev(sl->dev); diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h index c26d863e1697..5ccbed1784d2 100644 --- a/drivers/net/chelsio/common.h +++ b/drivers/net/chelsio/common.h @@ -240,8 +240,6 @@ struct adapter { struct work_struct ext_intr_handler_task; struct adapter_params params; - struct vlan_group *vlan_grp; - /* Terminator modules. */ struct sge *sge; struct peespi *espi; diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index b422d83f5343..3edbbc4c5112 100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c @@ -263,6 +263,8 @@ static int cxgb_open(struct net_device *dev) if (!other_ports && adapter->params.stats_update_period) schedule_mac_stats_update(adapter, adapter->params.stats_update_period); + + t1_vlan_mode(adapter, dev->features); return 0; } @@ -849,19 +851,30 @@ static int t1_set_mac_addr(struct net_device *dev, void *p) return 0; } -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -static void t1_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) +static u32 t1_fix_features(struct net_device *dev, u32 features) { - struct adapter *adapter = dev->ml_priv; + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; - spin_lock_irq(&adapter->async_lock); - adapter->vlan_grp = grp; - t1_set_vlan_accel(adapter, grp != NULL); - spin_unlock_irq(&adapter->async_lock); + return features; } -#endif +static int t1_set_features(struct net_device *dev, u32 features) +{ + u32 changed = dev->features ^ features; + struct adapter *adapter = dev->ml_priv; + + if (changed & NETIF_F_HW_VLAN_RX) + t1_vlan_mode(adapter, features); + + return 0; +} #ifdef CONFIG_NET_POLL_CONTROLLER static void t1_netpoll(struct net_device *dev) { @@ -955,9 +968,8 @@ static const struct net_device_ops cxgb_netdev_ops = { .ndo_do_ioctl = t1_ioctl, .ndo_change_mtu = t1_change_mtu, .ndo_set_mac_address = t1_set_mac_addr, -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) - .ndo_vlan_rx_register = t1_vlan_rx_register, -#endif + .ndo_fix_features = t1_fix_features, + .ndo_set_features = t1_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = t1_netpoll, #endif @@ -1080,10 +1092,9 @@ static int __devinit init_one(struct pci_dev *pdev, if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; if (vlan_tso_capable(adapter)) { -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; -#endif + netdev->hw_features |= NETIF_F_HW_VLAN_RX; /* T204: disable TSO */ if (!(is_T2(adapter)) || bi->port_number != 4) { diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 58380d240619..e9a03fffef15 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -742,13 +742,14 @@ static inline void setup_ring_params(struct adapter *adapter, u64 addr, /* * Enable/disable VLAN acceleration. */ -void t1_set_vlan_accel(struct adapter *adapter, int on_off) +void t1_vlan_mode(struct adapter *adapter, u32 features) { struct sge *sge = adapter->sge; - sge->sge_control &= ~F_VLAN_XTRACT; - if (on_off) + if (features & NETIF_F_HW_VLAN_RX) sge->sge_control |= F_VLAN_XTRACT; + else + sge->sge_control &= ~F_VLAN_XTRACT; if (adapter->open_device_map) { writel(sge->sge_control, adapter->regs + A_SG_CONTROL); readl(adapter->regs + A_SG_CONTROL); /* flush */ @@ -1397,12 +1398,11 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) } else skb_checksum_none_assert(skb); - if (unlikely(adapter->vlan_grp && p->vlan_valid)) { + if (p->vlan_valid) { st->vlan_xtract++; - vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, - ntohs(p->vlan)); - } else - netif_receive_skb(skb); + __vlan_hwaccel_put_tag(skb, ntohs(p->vlan)); + } + netif_receive_skb(skb); } /* @@ -1875,13 +1875,11 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev) } cpl->iff = dev->if_port; -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) if (vlan_tx_tag_present(skb)) { cpl->vlan_valid = 1; cpl->vlan = htons(vlan_tx_tag_get(skb)); st->vlan_insert++; } else -#endif cpl->vlan_valid = 0; send: diff --git a/drivers/net/chelsio/sge.h b/drivers/net/chelsio/sge.h index 00cc37fc1f6f..e03980bcdd65 100644 --- a/drivers/net/chelsio/sge.h +++ b/drivers/net/chelsio/sge.h @@ -79,7 +79,7 @@ irqreturn_t t1_interrupt(int irq, void *cookie); int t1_poll(struct napi_struct *, int); netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev); -void t1_set_vlan_accel(struct adapter *adapter, int on_off); +void t1_vlan_mode(struct adapter *adapter, u32 features); void t1_sge_start(struct sge *); void t1_sge_stop(struct sge *); int t1_sge_intr_error_handler(struct sge *); diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index ea75f65a179c..94a2e541006d 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -1172,7 +1172,7 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->iro_arr = ethdev->iro_arr; - cp->max_cid_space = MAX_ISCSI_TBL_SZ + BNX2X_FCOE_NUM_CONNECTIONS; + cp->max_cid_space = MAX_ISCSI_TBL_SZ; cp->iscsi_start_cid = start_cid; cp->fcoe_start_cid = start_cid + MAX_ISCSI_TBL_SZ; @@ -1183,14 +1183,6 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->fcoe_init_cid = 0x10; } - if (start_cid < BNX2X_ISCSI_START_CID) { - u32 delta = BNX2X_ISCSI_START_CID - start_cid; - - cp->iscsi_start_cid = BNX2X_ISCSI_START_CID; - cp->fcoe_start_cid += delta; - cp->max_cid_space += delta; - } - cp->iscsi_tbl = kzalloc(sizeof(struct cnic_iscsi) * MAX_ISCSI_TBL_SZ, GFP_KERNEL); if (!cp->iscsi_tbl) @@ -2456,6 +2448,30 @@ static int cnic_bnx2x_fcoe_destroy(struct cnic_dev *dev, struct kwqe *kwqe) return ret; } +static void cnic_bnx2x_delete_wait(struct cnic_dev *dev, u32 start_cid) +{ + struct cnic_local *cp = dev->cnic_priv; + u32 i; + + for (i = start_cid; i < cp->max_cid_space; i++) { + struct cnic_context *ctx = &cp->ctx_tbl[i]; + int j; + + while (test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags)) + msleep(10); + + for (j = 0; j < 5; j++) { + if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) + break; + msleep(20); + } + + if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) + netdev_warn(dev->netdev, "CID %x not deleted\n", + ctx->cid); + } +} + static int cnic_bnx2x_fcoe_fw_destroy(struct cnic_dev *dev, struct kwqe *kwqe) { struct fcoe_kwqe_destroy *req; @@ -2464,6 +2480,8 @@ static int cnic_bnx2x_fcoe_fw_destroy(struct cnic_dev *dev, struct kwqe *kwqe) int ret; u32 cid; + cnic_bnx2x_delete_wait(dev, MAX_ISCSI_TBL_SZ); + req = (struct fcoe_kwqe_destroy *) kwqe; cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid); @@ -3938,7 +3956,6 @@ static void cnic_close_bnx2x_conn(struct cnic_sock *csk, u32 opcode) static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - int i; if (!cp->ctx_tbl) return; @@ -3946,23 +3963,7 @@ static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev) if (!netif_running(dev->netdev)) return; - for (i = 0; i < cp->max_cid_space; i++) { - struct cnic_context *ctx = &cp->ctx_tbl[i]; - int j; - - while (test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags)) - msleep(10); - - for (j = 0; j < 5; j++) { - if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) - break; - msleep(20); - } - - if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) - netdev_warn(dev->netdev, "CID %x not deleted\n", - ctx->cid); - } + cnic_bnx2x_delete_wait(dev, 0); cancel_delayed_work(&cp->delete_task); flush_workqueue(cnic_wq); @@ -5333,6 +5334,27 @@ static struct cnic_dev *is_cnic_dev(struct net_device *dev) return cdev; } +static void cnic_rcv_netevent(struct cnic_local *cp, unsigned long event, + u16 vlan_id) +{ + int if_type; + + rcu_read_lock(); + for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { + struct cnic_ulp_ops *ulp_ops; + void *ctx; + + ulp_ops = rcu_dereference(cp->ulp_ops[if_type]); + if (!ulp_ops || !ulp_ops->indicate_netevent) + continue; + + ctx = cp->ulp_handle[if_type]; + + ulp_ops->indicate_netevent(ctx, event, vlan_id); + } + rcu_read_unlock(); +} + /** * netdev event handler */ @@ -5341,7 +5363,6 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event, { struct net_device *netdev = ptr; struct cnic_dev *dev; - int if_type; int new_dev = 0; dev = cnic_from_netdev(netdev); @@ -5371,20 +5392,7 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event, cnic_ulp_start(dev); } - rcu_read_lock(); - for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { - struct cnic_ulp_ops *ulp_ops; - void *ctx; - - ulp_ops = rcu_dereference(cp->ulp_ops[if_type]); - if (!ulp_ops || !ulp_ops->indicate_netevent) - continue; - - ctx = cp->ulp_handle[if_type]; - - ulp_ops->indicate_netevent(ctx, event); - } - rcu_read_unlock(); + cnic_rcv_netevent(cp, event, 0); if (event == NETDEV_GOING_DOWN) { cnic_ulp_stop(dev); @@ -5400,6 +5408,19 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event, goto done; } cnic_put(dev); + } else { + struct net_device *realdev; + u16 vid; + + vid = cnic_get_vlan(netdev, &realdev); + if (realdev) { + dev = cnic_from_netdev(realdev); + if (dev) { + vid |= VLAN_TAG_PRESENT; + cnic_rcv_netevent(dev->cnic_priv, event, vid); + cnic_put(dev); + } + } } done: return NOTIFY_DONE; diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 642b9d56a1c6..79443e0dbf96 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.5.6" -#define CNIC_MODULE_RELDATE "July 12, 2011" +#define CNIC_MODULE_VERSION "2.5.7" +#define CNIC_MODULE_RELDATE "July 20, 2011" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 @@ -181,6 +181,11 @@ struct cnic_eth_dev { u32 max_fcoe_conn; u32 max_rdma_conn; u32 fcoe_init_cid; + u32 fcoe_wwn_port_name_hi; + u32 fcoe_wwn_port_name_lo; + u32 fcoe_wwn_node_name_hi; + u32 fcoe_wwn_node_name_lo; + u16 iscsi_l2_client_id; u16 iscsi_l2_cid; u8 iscsi_mac[ETH_ALEN]; @@ -313,7 +318,7 @@ struct cnic_ulp_ops { void (*cnic_stop)(void *ulp_ctx); void (*indicate_kcqes)(void *ulp_ctx, struct kcqe *cqes[], u32 num_cqes); - void (*indicate_netevent)(void *ulp_ctx, unsigned long event); + void (*indicate_netevent)(void *ulp_ctx, unsigned long event, u16 vid); void (*cm_connect_complete)(struct cnic_sock *); void (*cm_close_complete)(struct cnic_sock *); void (*cm_abort_complete)(struct cnic_sock *); diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 7300de5a1426..8b395b537330 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h @@ -45,7 +45,6 @@ #include "t3cdev.h" #include <asm/io.h> -struct vlan_group; struct adapter; struct sge_qset; struct port_info; @@ -66,7 +65,6 @@ struct iscsi_config { struct port_info { struct adapter *adapter; - struct vlan_group *vlan_grp; struct sge_qset *qs; u8 port_id; u8 nqsets; diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 9081ce037149..93b41a7ac175 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -2532,25 +2532,51 @@ static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) } } -static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp) +static void cxgb_vlan_mode(struct net_device *dev, u32 features) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; - pi->vlan_grp = grp; - if (adapter->params.rev > 0) - t3_set_vlan_accel(adapter, 1 << pi->port_id, grp != NULL); - else { + if (adapter->params.rev > 0) { + t3_set_vlan_accel(adapter, 1 << pi->port_id, + features & NETIF_F_HW_VLAN_RX); + } else { /* single control for all ports */ - unsigned int i, have_vlans = 0; + unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; + for_each_port(adapter, i) - have_vlans |= adap2pinfo(adapter, i)->vlan_grp != NULL; + have_vlans |= + adapter->port[i]->features & NETIF_F_HW_VLAN_RX; t3_set_vlan_accel(adapter, 1, have_vlans); } t3_synchronize_rx(adapter, pi); } +static u32 cxgb_fix_features(struct net_device *dev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int cxgb_set_features(struct net_device *dev, u32 features) +{ + u32 changed = dev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + cxgb_vlan_mode(dev, features); + + return 0; +} + #ifdef CONFIG_NET_POLL_CONTROLLER static void cxgb_netpoll(struct net_device *dev) { @@ -3131,7 +3157,8 @@ static const struct net_device_ops cxgb_netdev_ops = { .ndo_do_ioctl = cxgb_ioctl, .ndo_change_mtu = cxgb_change_mtu, .ndo_set_mac_address = cxgb_set_mac_addr, - .ndo_vlan_rx_register = vlan_rx_register, + .ndo_fix_features = cxgb_fix_features, + .ndo_set_features = cxgb_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = cxgb_netpoll, #endif @@ -3263,9 +3290,8 @@ static int __devinit init_one(struct pci_dev *pdev, netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len - 1; netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_TSO | NETIF_F_RXCSUM; - netdev->features |= netdev->hw_features | - NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_RX; + netdev->features |= netdev->hw_features | NETIF_F_HW_VLAN_TX; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; @@ -3329,6 +3355,9 @@ static int __devinit init_one(struct pci_dev *pdev, err = sysfs_create_group(&adapter->port[0]->dev.kobj, &cxgb3_attr_group); + for_each_port(adapter, i) + cxgb_vlan_mode(adapter->port[i], adapter->port[i]->features); + print_port_info(adapter, ai); return 0; diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index fa1b450af825..32636a1d62a5 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -176,16 +176,13 @@ static struct net_device *get_iff_from_mac(struct adapter *adapter, int i; for_each_port(adapter, i) { - struct vlan_group *grp; struct net_device *dev = adapter->port[i]; - const struct port_info *p = netdev_priv(dev); if (!memcmp(dev->dev_addr, mac, ETH_ALEN)) { if (vlan && vlan != VLAN_VID_MASK) { - grp = p->vlan_grp; - dev = NULL; - if (grp) - dev = vlan_group_get_device(grp, vlan); + rcu_read_lock(); + dev = __vlan_find_dev_deep(dev, vlan); + rcu_read_unlock(); } else if (netif_is_bond_slave(dev)) { while (dev->master) dev = dev->master; diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 76bf5892b962..d6fa1777a343 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -2028,28 +2028,11 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq, skb_checksum_none_assert(skb); skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]); - if (unlikely(p->vlan_valid)) { - struct vlan_group *grp = pi->vlan_grp; - + if (p->vlan_valid) { qs->port_stats[SGE_PSTAT_VLANEX]++; - if (likely(grp)) - if (lro) - vlan_gro_receive(&qs->napi, grp, - ntohs(p->vlan), skb); - else { - if (unlikely(pi->iscsic.flags)) { - unsigned short vtag = ntohs(p->vlan) & - VLAN_VID_MASK; - skb->dev = vlan_group_get_device(grp, - vtag); - cxgb3_process_iscsi_prov_pack(pi, skb); - } - __vlan_hwaccel_rx(skb, grp, ntohs(p->vlan), - rq->polling); - } - else - dev_kfree_skb_any(skb); - } else if (rq->polling) { + __vlan_hwaccel_put_tag(skb, ntohs(p->vlan)); + } + if (rq->polling) { if (lro) napi_gro_receive(&qs->napi, skb); else { @@ -2147,14 +2130,8 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]); - if (unlikely(cpl->vlan_valid)) { - struct vlan_group *grp = pi->vlan_grp; - - if (likely(grp != NULL)) { - vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan)); - return; - } - } + if (cpl->vlan_valid) + __vlan_hwaccel_put_tag(skb, ntohs(cpl->vlan)); napi_gro_frags(&qs->napi); } diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index bc9982a4c1f4..223a7f72343b 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -276,7 +276,6 @@ enum { }; struct adapter; -struct vlan_group; struct sge_rspq; struct port_info { diff --git a/drivers/net/cxgb4vf/adapter.h b/drivers/net/cxgb4vf/adapter.h index 6e9a8d9ef592..594334d5c711 100644 --- a/drivers/net/cxgb4vf/adapter.h +++ b/drivers/net/cxgb4vf/adapter.h @@ -92,7 +92,6 @@ struct sge_rspq; */ struct port_info { struct adapter *adapter; /* our adapter */ - struct vlan_group *vlan_grp; /* out VLAN group */ u16 viid; /* virtual interface ID */ s16 xact_addr_filt; /* index of our MAC address filter */ u16 rss_size; /* size of VI's RSS table slice */ diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 3942a825b3dd..ec799139dfe2 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -209,18 +209,8 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok) * ====================== */ -/* - * Record our new VLAN Group and enable/disable hardware VLAN Tag extraction - * based on whether the specified VLAN Group pointer is NULL or not. - */ -static void cxgb4vf_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) -{ - struct port_info *pi = netdev_priv(dev); - pi->vlan_grp = grp; - t4vf_set_rxmode(pi->adapter, pi->viid, -1, -1, -1, -1, grp != NULL, 0); -} + /* * Perform the MAC and PHY actions needed to enable a "port" (Virtual @@ -233,9 +223,9 @@ static int link_start(struct net_device *dev) /* * We do not set address filters and promiscuity here, the stack does - * that step explicitly. + * that step explicitly. Enable vlan accel. */ - ret = t4vf_set_rxmode(pi->adapter, pi->viid, dev->mtu, -1, -1, -1, -1, + ret = t4vf_set_rxmode(pi->adapter, pi->viid, dev->mtu, -1, -1, -1, 1, true); if (ret == 0) { ret = t4vf_change_mac(pi->adapter, pi->viid, @@ -1102,6 +1092,32 @@ static int cxgb4vf_change_mtu(struct net_device *dev, int new_mtu) return ret; } +static u32 cxgb4vf_fix_features(struct net_device *dev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int cxgb4vf_set_features(struct net_device *dev, u32 features) +{ + struct port_info *pi = netdev_priv(dev); + u32 changed = dev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + t4vf_set_rxmode(pi->adapter, pi->viid, -1, -1, -1, -1, + features & NETIF_F_HW_VLAN_TX, 0); + + return 0; +} + /* * Change the devices MAC address. */ @@ -2431,7 +2447,8 @@ static const struct net_device_ops cxgb4vf_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = cxgb4vf_do_ioctl, .ndo_change_mtu = cxgb4vf_change_mtu, - .ndo_vlan_rx_register = cxgb4vf_vlan_rx_register, + .ndo_fix_features = cxgb4vf_fix_features, + .ndo_set_features = cxgb4vf_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = cxgb4vf_poll_controller, #endif @@ -2600,12 +2617,11 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, netdev->hw_features = NETIF_F_SG | TSO_FLAGS | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM; + NETIF_F_HW_VLAN_RX | NETIF_F_RXCSUM; netdev->vlan_features = NETIF_F_SG | TSO_FLAGS | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA; - netdev->features = netdev->hw_features | - NETIF_F_HW_VLAN_RX; + netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_TX; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c index 5fd75fdaa631..cffb328c46c3 100644 --- a/drivers/net/cxgb4vf/sge.c +++ b/drivers/net/cxgb4vf/sge.c @@ -1491,20 +1491,10 @@ static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl, skb->ip_summed = CHECKSUM_UNNECESSARY; skb_record_rx_queue(skb, rxq->rspq.idx); - if (unlikely(pkt->vlan_ex)) { - struct port_info *pi = netdev_priv(rxq->rspq.netdev); - struct vlan_group *grp = pi->vlan_grp; - - rxq->stats.vlan_ex++; - if (likely(grp)) { - ret = vlan_gro_frags(&rxq->rspq.napi, grp, - be16_to_cpu(pkt->vlan)); - goto stats; - } - } + if (pkt->vlan_ex) + __vlan_hwaccel_put_tag(skb, be16_to_cpu(pkt->vlan)); ret = napi_gro_frags(&rxq->rspq.napi); -stats: if (ret == GRO_HELD) rxq->stats.lro_pkts++; else if (ret == GRO_MERGED || ret == GRO_MERGED_FREE) @@ -1525,7 +1515,6 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, const struct pkt_gl *gl) { struct sk_buff *skb; - struct port_info *pi; const struct cpl_rx_pkt *pkt = (void *)&rsp[1]; bool csum_ok = pkt->csum_calc && !pkt->err_vec; struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq); @@ -1553,7 +1542,6 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, __skb_pull(skb, PKTSHIFT); skb->protocol = eth_type_trans(skb, rspq->netdev); skb_record_rx_queue(skb, rspq->idx); - pi = netdev_priv(skb->dev); rxq->stats.pkts++; if (csum_ok && (rspq->netdev->features & NETIF_F_RXCSUM) && @@ -1569,20 +1557,12 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, } else skb_checksum_none_assert(skb); - /* - * Deliver the packet to the stack. - */ - if (unlikely(pkt->vlan_ex)) { - struct vlan_group *grp = pi->vlan_grp; - + if (pkt->vlan_ex) { rxq->stats.vlan_ex++; - if (likely(grp)) - vlan_hwaccel_receive_skb(skb, grp, - be16_to_cpu(pkt->vlan)); - else - dev_kfree_skb_any(skb); - } else - netif_receive_skb(skb); + __vlan_hwaccel_put_tag(skb, be16_to_cpu(pkt->vlan)); + } + + netif_receive_skb(skb); return 0; } diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 8676899120c3..24f41da8c4be 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -215,7 +215,7 @@ struct e1000_adapter { struct timer_list tx_fifo_stall_timer; struct timer_list watchdog_timer; struct timer_list phy_info_timer; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u16 mng_vlan_id; u32 bd_number; u32 rx_buffer_len; diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 188d99ae9084..f97afda941d7 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -30,6 +30,8 @@ #include <net/ip6_checksum.h> #include <linux/io.h> #include <linux/prefetch.h> +#include <linux/bitops.h> +#include <linux/if_vlan.h> /* Intel Media SOC GbE MDIO physical base address */ static unsigned long ce4100_gbe_mdio_base_phy; @@ -166,7 +168,8 @@ static void e1000_smartspeed(struct e1000_adapter *adapter); static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb); -static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); +static bool e1000_vlan_used(struct e1000_adapter *adapter); +static void e1000_vlan_mode(struct net_device *netdev, u32 features); static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid); static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); static void e1000_restore_vlan(struct e1000_adapter *adapter); @@ -330,21 +333,24 @@ static void e1000_update_mng_vlan(struct e1000_adapter *adapter) struct net_device *netdev = adapter->netdev; u16 vid = hw->mng_cookie.vlan_id; u16 old_vid = adapter->mng_vlan_id; - if (adapter->vlgrp) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) { - if (hw->mng_cookie.status & - E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) { - e1000_vlan_rx_add_vid(netdev, vid); - adapter->mng_vlan_id = vid; - } else - adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; - if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && - (vid != old_vid) && - !vlan_group_get_device(adapter->vlgrp, old_vid)) - e1000_vlan_rx_kill_vid(netdev, old_vid); - } else + if (!e1000_vlan_used(adapter)) + return; + + if (!test_bit(vid, adapter->active_vlans)) { + if (hw->mng_cookie.status & + E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) { + e1000_vlan_rx_add_vid(netdev, vid); adapter->mng_vlan_id = vid; + } else { + adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; + } + if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && + (vid != old_vid) && + !test_bit(old_vid, adapter->active_vlans)) + e1000_vlan_rx_kill_vid(netdev, old_vid); + } else { + adapter->mng_vlan_id = vid; } } @@ -797,11 +803,28 @@ static int e1000_is_need_ioport(struct pci_dev *pdev) } } +static u32 e1000_fix_features(struct net_device *netdev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + static int e1000_set_features(struct net_device *netdev, u32 features) { struct e1000_adapter *adapter = netdev_priv(netdev); u32 changed = features ^ netdev->features; + if (changed & NETIF_F_HW_VLAN_RX) + e1000_vlan_mode(netdev, features); + if (!(changed & NETIF_F_RXCSUM)) return 0; @@ -822,18 +845,17 @@ static const struct net_device_ops e1000_netdev_ops = { .ndo_get_stats = e1000_get_stats, .ndo_set_rx_mode = e1000_set_rx_mode, .ndo_set_mac_address = e1000_set_mac, - .ndo_tx_timeout = e1000_tx_timeout, + .ndo_tx_timeout = e1000_tx_timeout, .ndo_change_mtu = e1000_change_mtu, .ndo_do_ioctl = e1000_ioctl, .ndo_validate_addr = eth_validate_addr, - - .ndo_vlan_rx_register = e1000_vlan_rx_register, .ndo_vlan_rx_add_vid = e1000_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = e1000_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = e1000_netpoll, #endif - .ndo_set_features = e1000_set_features, + .ndo_fix_features = e1000_fix_features, + .ndo_set_features = e1000_set_features, }; /** @@ -1036,9 +1058,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (hw->mac_type >= e1000_82543) { netdev->hw_features = NETIF_F_SG | - NETIF_F_HW_CSUM; + NETIF_F_HW_CSUM | + NETIF_F_HW_VLAN_RX; netdev->features = NETIF_F_HW_VLAN_TX | - NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; } @@ -1197,6 +1219,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (err) goto err_register; + e1000_vlan_mode(netdev, netdev->features); + /* print bus type/speed/width info */ e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n", ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""), @@ -1441,8 +1465,7 @@ static int e1000_close(struct net_device *netdev) * the same ID is registered on the host OS (let 8021q kill it) */ if ((hw->mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) && - !(adapter->vlgrp && - vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) { + !test_bit(adapter->mng_vlan_id, adapter->active_vlans)) { e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); } @@ -2233,7 +2256,7 @@ static void e1000_set_rx_mode(struct net_device *netdev) else rctl &= ~E1000_RCTL_MPE; /* Enable VLAN filter if there is a VLAN */ - if (adapter->vlgrp) + if (e1000_vlan_used(adapter)) rctl |= E1000_RCTL_VFE; } @@ -2379,13 +2402,16 @@ bool e1000_has_link(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; bool link_active = false; - /* get_link_status is set on LSC (link status) interrupt or - * rx sequence error interrupt. get_link_status will stay - * false until the e1000_check_for_link establishes link - * for copper adapters ONLY + /* get_link_status is set on LSC (link status) interrupt or rx + * sequence error interrupt (except on intel ce4100). + * get_link_status will stay false until the + * e1000_check_for_link establishes link for copper adapters + * ONLY */ switch (hw->media_type) { case e1000_media_type_copper: + if (hw->mac_type == e1000_ce4100) + hw->get_link_status = 1; if (hw->get_link_status) { e1000_check_for_link(hw); link_active = !hw->get_link_status; @@ -3180,7 +3206,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, } } - if (unlikely(vlan_tx_tag_present(skb))) { + if (vlan_tx_tag_present(skb)) { tx_flags |= E1000_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT); } @@ -3735,12 +3761,12 @@ static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status, { skb->protocol = eth_type_trans(skb, adapter->netdev); - if ((unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP)))) - vlan_gro_receive(&adapter->napi, adapter->vlgrp, - le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK, - skb); - else - napi_gro_receive(&adapter->napi, skb); + if (status & E1000_RXD_STAT_VP) { + u16 vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK; + + __vlan_hwaccel_put_tag(skb, vid); + } + napi_gro_receive(&adapter->napi, skb); } /** @@ -4523,46 +4549,61 @@ void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value) outl(value, port); } -static void e1000_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) +static bool e1000_vlan_used(struct e1000_adapter *adapter) +{ + u16 vid; + + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) + return true; + return false; +} + +static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, + bool filter_on) { - struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - u32 ctrl, rctl; + u32 rctl; if (!test_bit(__E1000_DOWN, &adapter->flags)) e1000_irq_disable(adapter); - adapter->vlgrp = grp; - - if (grp) { - /* enable VLAN tag insert/strip */ - ctrl = er32(CTRL); - ctrl |= E1000_CTRL_VME; - ew32(CTRL, ctrl); + if (filter_on) { /* enable VLAN receive filtering */ rctl = er32(RCTL); rctl &= ~E1000_RCTL_CFIEN; - if (!(netdev->flags & IFF_PROMISC)) + if (!(adapter->netdev->flags & IFF_PROMISC)) rctl |= E1000_RCTL_VFE; ew32(RCTL, rctl); e1000_update_mng_vlan(adapter); } else { - /* disable VLAN tag insert/strip */ - ctrl = er32(CTRL); - ctrl &= ~E1000_CTRL_VME; - ew32(CTRL, ctrl); - /* disable VLAN receive filtering */ rctl = er32(RCTL); rctl &= ~E1000_RCTL_VFE; ew32(RCTL, rctl); + } - if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) { - e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); - adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; - } + if (!test_bit(__E1000_DOWN, &adapter->flags)) + e1000_irq_enable(adapter); +} + +static void e1000_vlan_mode(struct net_device *netdev, u32 features) +{ + struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; + u32 ctrl; + + if (!test_bit(__E1000_DOWN, &adapter->flags)) + e1000_irq_disable(adapter); + + ctrl = er32(CTRL); + if (features & NETIF_F_HW_VLAN_RX) { + /* enable VLAN tag insert/strip */ + ctrl |= E1000_CTRL_VME; + } else { + /* disable VLAN tag insert/strip */ + ctrl &= ~E1000_CTRL_VME; } + ew32(CTRL, ctrl); if (!test_bit(__E1000_DOWN, &adapter->flags)) e1000_irq_enable(adapter); @@ -4578,11 +4619,17 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid) E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) && (vid == adapter->mng_vlan_id)) return; + + if (!e1000_vlan_used(adapter)) + e1000_vlan_filter_on_off(adapter, true); + /* add VID to filter table */ index = (vid >> 5) & 0x7F; vfta = E1000_READ_REG_ARRAY(hw, VFTA, index); vfta |= (1 << (vid & 0x1F)); e1000_write_vfta(hw, index, vfta); + + set_bit(vid, adapter->active_vlans); } static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) @@ -4593,7 +4640,6 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) if (!test_bit(__E1000_DOWN, &adapter->flags)) e1000_irq_disable(adapter); - vlan_group_set_device(adapter->vlgrp, vid, NULL); if (!test_bit(__E1000_DOWN, &adapter->flags)) e1000_irq_enable(adapter); @@ -4602,20 +4648,23 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) vfta = E1000_READ_REG_ARRAY(hw, VFTA, index); vfta &= ~(1 << (vid & 0x1F)); e1000_write_vfta(hw, index, vfta); + + clear_bit(vid, adapter->active_vlans); + + if (!e1000_vlan_used(adapter)) + e1000_vlan_filter_on_off(adapter, false); } static void e1000_restore_vlan(struct e1000_adapter *adapter) { - e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp); + u16 vid; - if (adapter->vlgrp) { - u16 vid; - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) - continue; - e1000_vlan_rx_add_vid(adapter->netdev, vid); - } - } + if (!e1000_vlan_used(adapter)) + return; + + e1000_vlan_filter_on_off(adapter, true); + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) + e1000_vlan_rx_add_vid(adapter->netdev, vid); } int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx) diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 6c7257bd73fc..7dd5e6a0d998 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -457,7 +457,6 @@ struct ehea_port { struct ehea_port_res port_res[EHEA_MAX_PORT_RES]; struct platform_device ofdev; /* Open Firmware Device */ struct ehea_mc_list *mc_list; /* Multicast MAC addresses */ - struct vlan_group *vgrp; struct ehea_eq *qp_eq; struct work_struct reset_task; struct mutex port_lock; diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 3fd5a2400348..be2cb4ab8b4f 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -683,24 +683,13 @@ static int get_skb_hdr(struct sk_buff *skb, void **iphdr, static void ehea_proc_skb(struct ehea_port_res *pr, struct ehea_cqe *cqe, struct sk_buff *skb) { - int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) && - pr->port->vgrp); - - if (skb->dev->features & NETIF_F_LRO) { - if (vlan_extracted) - lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb, - pr->port->vgrp, - cqe->vlan_tag, - cqe); - else - lro_receive_skb(&pr->lro_mgr, skb, cqe); - } else { - if (vlan_extracted) - vlan_hwaccel_receive_skb(skb, pr->port->vgrp, - cqe->vlan_tag); - else - netif_receive_skb(skb); - } + if (cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) + __vlan_hwaccel_put_tag(skb, cqe->vlan_tag); + + if (skb->dev->features & NETIF_F_LRO) + lro_receive_skb(&pr->lro_mgr, skb, cqe); + else + netif_receive_skb(skb); } static int ehea_proc_rwqes(struct net_device *dev, @@ -2339,32 +2328,6 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } -static void ehea_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) -{ - struct ehea_port *port = netdev_priv(dev); - struct ehea_adapter *adapter = port->adapter; - struct hcp_ehea_port_cb1 *cb1; - u64 hret; - - port->vgrp = grp; - - cb1 = (void *)get_zeroed_page(GFP_KERNEL); - if (!cb1) { - pr_err("no mem for cb1\n"); - goto out; - } - - hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, - H_PORT_CB1, H_PORT_CB1_ALL, cb1); - if (hret != H_SUCCESS) - pr_err("modify_ehea_port failed\n"); - - free_page((unsigned long)cb1); -out: - return; -} - static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { struct ehea_port *port = netdev_priv(dev); @@ -2406,8 +2369,6 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) int index; u64 hret; - vlan_group_set_device(port->vgrp, vid, NULL); - cb1 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb1) { pr_err("no mem for cb1\n"); @@ -3202,7 +3163,6 @@ static const struct net_device_ops ehea_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = ehea_set_multicast_list, .ndo_change_mtu = ehea_change_mtu, - .ndo_vlan_rx_register = ehea_vlan_rx_register, .ndo_vlan_rx_add_vid = ehea_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = ehea_vlan_rx_kill_vid, .ndo_tx_timeout = ehea_tx_watchdog, diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index f0b062b4a223..ce76d9a8ca6e 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -94,7 +94,6 @@ struct enic { ____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX]; spinlock_t wq_lock[ENIC_WQ_MAX]; unsigned int wq_count; - struct vlan_group *vlan_group; u16 loop_enable; u16 loop_tag; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index e25800fa96ca..67a27cd304dd 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1029,14 +1029,6 @@ static void enic_set_rx_mode(struct net_device *netdev) } } -/* rtnl lock is held */ -static void enic_vlan_rx_register(struct net_device *netdev, - struct vlan_group *vlan_group) -{ - struct enic *enic = netdev_priv(netdev); - enic->vlan_group = vlan_group; -} - /* netif_tx_lock held, BHs disabled */ static void enic_tx_timeout(struct net_device *netdev) { @@ -1264,23 +1256,13 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, skb->dev = netdev; - if (vlan_stripped) { - - if (netdev->features & NETIF_F_GRO) - vlan_gro_receive(&enic->napi[q_number], - enic->vlan_group, vlan_tci, skb); - else - vlan_hwaccel_receive_skb(skb, - enic->vlan_group, vlan_tci); + if (vlan_stripped) + __vlan_hwaccel_put_tag(skb, vlan_tci); - } else { - - if (netdev->features & NETIF_F_GRO) - napi_gro_receive(&enic->napi[q_number], skb); - else - netif_receive_skb(skb); - - } + if (netdev->features & NETIF_F_GRO) + napi_gro_receive(&enic->napi[q_number], skb); + else + netif_receive_skb(skb); } else { /* Buffer overflow @@ -2124,7 +2106,6 @@ static const struct net_device_ops enic_netdev_dynamic_ops = { .ndo_set_multicast_list = enic_set_rx_mode, .ndo_set_mac_address = enic_set_mac_address_dynamic, .ndo_change_mtu = enic_change_mtu, - .ndo_vlan_rx_register = enic_vlan_rx_register, .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid, .ndo_tx_timeout = enic_tx_timeout, @@ -2146,7 +2127,6 @@ static const struct net_device_ops enic_netdev_ops = { .ndo_set_rx_mode = enic_set_rx_mode, .ndo_set_multicast_list = enic_set_rx_mode, .ndo_change_mtu = enic_change_mtu, - .ndo_vlan_rx_register = enic_vlan_rx_register, .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid, .ndo_tx_timeout = enic_tx_timeout, diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 537b6957bb79..e64cd9ceac3f 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -820,9 +820,6 @@ struct fe_priv { struct nv_skb_map *tx_end_flip; int tx_stop; - /* vlan fields */ - struct vlan_group *vlangrp; - /* msi/msi-x fields */ u32 msi_flags; struct msix_entry msi_x_entry[NV_MSI_X_MAX_VECTORS]; @@ -2766,17 +2763,13 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) skb->protocol = eth_type_trans(skb, dev); prefetch(skb->data); - if (likely(!np->vlangrp)) { - napi_gro_receive(&np->napi, skb); - } else { - vlanflags = le32_to_cpu(np->get_rx.ex->buflow); - if (vlanflags & NV_RX3_VLAN_TAG_PRESENT) { - vlan_gro_receive(&np->napi, np->vlangrp, - vlanflags & NV_RX3_VLAN_TAG_MASK, skb); - } else { - napi_gro_receive(&np->napi, skb); - } + vlanflags = le32_to_cpu(np->get_rx.ex->buflow); + if (vlanflags & NV_RX3_VLAN_TAG_PRESENT) { + u16 vid = vlanflags & NV_RX3_VLAN_TAG_MASK; + + __vlan_hwaccel_put_tag(skb, vid); } + napi_gro_receive(&np->napi, skb); dev->stats.rx_packets++; dev->stats.rx_bytes += len; @@ -4484,6 +4477,27 @@ static u32 nv_fix_features(struct net_device *dev, u32 features) return features; } +static void nv_vlan_mode(struct net_device *dev, u32 features) +{ + struct fe_priv *np = get_nvpriv(dev); + + spin_lock_irq(&np->lock); + + if (features & NETIF_F_HW_VLAN_RX) + np->txrxctl_bits |= NVREG_TXRXCTL_VLANSTRIP; + else + np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANSTRIP; + + if (features & NETIF_F_HW_VLAN_TX) + np->txrxctl_bits |= NVREG_TXRXCTL_VLANINS; + else + np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANINS; + + writel(np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); + + spin_unlock_irq(&np->lock); +} + static int nv_set_features(struct net_device *dev, u32 features) { struct fe_priv *np = netdev_priv(dev); @@ -4504,6 +4518,9 @@ static int nv_set_features(struct net_device *dev, u32 features) spin_unlock_irq(&np->lock); } + if (changed & (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX)) + nv_vlan_mode(dev, features); + return 0; } @@ -4879,29 +4896,6 @@ static const struct ethtool_ops ops = { .self_test = nv_self_test, }; -static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct fe_priv *np = get_nvpriv(dev); - - spin_lock_irq(&np->lock); - - /* save vlan group */ - np->vlangrp = grp; - - if (grp) { - /* enable vlan on MAC */ - np->txrxctl_bits |= NVREG_TXRXCTL_VLANSTRIP | NVREG_TXRXCTL_VLANINS; - } else { - /* disable vlan on MAC */ - np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANSTRIP; - np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANINS; - } - - writel(np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); - - spin_unlock_irq(&np->lock); -} - /* The mgmt unit and driver use a semaphore to access the phy during init */ static int nv_mgmt_acquire_sema(struct net_device *dev) { @@ -5208,7 +5202,6 @@ static const struct net_device_ops nv_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = nv_set_mac_address, .ndo_set_multicast_list = nv_set_multicast, - .ndo_vlan_rx_register = nv_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = nv_poll_controller, #endif @@ -5226,7 +5219,6 @@ static const struct net_device_ops nv_netdev_ops_optimized = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = nv_set_mac_address, .ndo_set_multicast_list = nv_set_multicast, - .ndo_vlan_rx_register = nv_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = nv_poll_controller, #endif diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 3321d714ca22..835cd2588148 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -140,8 +140,6 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit); static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue); static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int amount_pull); -static void gfar_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp); void gfar_halt(struct net_device *dev); static void gfar_halt_nodisable(struct net_device *dev); void gfar_start(struct net_device *dev); @@ -391,10 +389,11 @@ static void gfar_init_mac(struct net_device *ndev) rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE; /* keep vlan related bits if it's enabled */ - if (priv->vlgrp) { + if (ndev->features & NETIF_F_HW_VLAN_TX) rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT; + + if (ndev->features & NETIF_F_HW_VLAN_RX) tctrl |= TCTRL_VLINS; - } /* Init rctrl based on our settings */ gfar_write(®s->rctrl, rctrl); @@ -467,7 +466,6 @@ static const struct net_device_ops gfar_netdev_ops = { .ndo_tx_timeout = gfar_timeout, .ndo_do_ioctl = gfar_ioctl, .ndo_get_stats = gfar_get_stats, - .ndo_vlan_rx_register = gfar_vlan_rx_register, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -507,10 +505,17 @@ void unlock_tx_qs(struct gfar_private *priv) spin_unlock(&priv->tx_queue[i]->txlock); } +static bool gfar_is_vlan_on(struct gfar_private *priv) +{ + return (priv->ndev->features & NETIF_F_HW_VLAN_RX) || + (priv->ndev->features & NETIF_F_HW_VLAN_TX); +} + /* Returns 1 if incoming frames use an FCB */ static inline int gfar_uses_fcb(struct gfar_private *priv) { - return priv->vlgrp || (priv->ndev->features & NETIF_F_RXCSUM) || + return gfar_is_vlan_on(priv) || + (priv->ndev->features & NETIF_F_RXCSUM) || (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER); } @@ -1038,10 +1043,10 @@ static int gfar_probe(struct platform_device *ofdev) NETIF_F_RXCSUM | NETIF_F_HIGHDMA; } - priv->vlgrp = NULL; - - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) { + dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + } if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { priv->extended_hash = 1; @@ -2287,10 +2292,25 @@ static int gfar_set_mac_address(struct net_device *dev) return 0; } +/* Check if rx parser should be activated */ +void gfar_check_rx_parser_mode(struct gfar_private *priv) +{ + struct gfar __iomem *regs; + u32 tempval; + + regs = priv->gfargrp[0].regs; + + tempval = gfar_read(®s->rctrl); + /* If parse is no longer required, then disable parser */ + if (tempval & RCTRL_REQ_PARSER) + tempval |= RCTRL_PRSDEP_INIT; + else + tempval &= ~RCTRL_PRSDEP_INIT; + gfar_write(®s->rctrl, tempval); +} /* Enables and disables VLAN insertion/extraction */ -static void gfar_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) +void gfar_vlan_mode(struct net_device *dev, u32 features) { struct gfar_private *priv = netdev_priv(dev); struct gfar __iomem *regs = NULL; @@ -2301,34 +2321,30 @@ static void gfar_vlan_rx_register(struct net_device *dev, local_irq_save(flags); lock_rx_qs(priv); - priv->vlgrp = grp; - - if (grp) { + if (features & NETIF_F_HW_VLAN_TX) { /* Enable VLAN tag insertion */ tempval = gfar_read(®s->tctrl); tempval |= TCTRL_VLINS; - gfar_write(®s->tctrl, tempval); - - /* Enable VLAN tag extraction */ - tempval = gfar_read(®s->rctrl); - tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT); - gfar_write(®s->rctrl, tempval); } else { /* Disable VLAN tag insertion */ tempval = gfar_read(®s->tctrl); tempval &= ~TCTRL_VLINS; gfar_write(®s->tctrl, tempval); + } + if (features & NETIF_F_HW_VLAN_RX) { + /* Enable VLAN tag extraction */ + tempval = gfar_read(®s->rctrl); + tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT); + gfar_write(®s->rctrl, tempval); + } else { /* Disable VLAN tag extraction */ tempval = gfar_read(®s->rctrl); tempval &= ~RCTRL_VLEX; - /* If parse is no longer required, then disable parser */ - if (tempval & RCTRL_REQ_PARSER) - tempval |= RCTRL_PRSDEP_INIT; - else - tempval &= ~RCTRL_PRSDEP_INIT; gfar_write(®s->rctrl, tempval); + + gfar_check_rx_parser_mode(priv); } gfar_change_mtu(dev, dev->mtu); @@ -2345,7 +2361,7 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) int oldsize = priv->rx_buffer_size; int frame_size = new_mtu + ETH_HLEN; - if (priv->vlgrp) + if (gfar_is_vlan_on(priv)) frame_size += VLAN_HLEN; if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) { @@ -2698,11 +2714,12 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, /* Tell the skb what kind of packet this is */ skb->protocol = eth_type_trans(skb, dev); + /* Set vlan tag */ + if (fcb->flags & RXFCB_VLN) + __vlan_hwaccel_put_tag(skb, fcb->vlctl); + /* Send the packet up the stack */ - if (unlikely(priv->vlgrp && (fcb->flags & RXFCB_VLN))) - ret = vlan_hwaccel_receive_skb(skb, priv->vlgrp, fcb->vlctl); - else - ret = netif_receive_skb(skb); + ret = netif_receive_skb(skb); if (NET_RX_DROP == ret) priv->extra_stats.kernel_dropped++; diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 27499c606a4a..9aa43773e8e3 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -286,7 +286,7 @@ extern const char gfar_driver_version[]; #define RCTRL_PROM 0x00000008 #define RCTRL_EMEN 0x00000002 #define RCTRL_REQ_PARSER (RCTRL_VLEX | RCTRL_IPCSEN | \ - RCTRL_TUCSEN) + RCTRL_TUCSEN | RCTRL_FILREN) #define RCTRL_CHECKSUMMING (RCTRL_IPCSEN | RCTRL_TUCSEN | \ RCTRL_PRSDEP_INIT) #define RCTRL_EXTHASH (RCTRL_GHTX) @@ -1077,8 +1077,6 @@ struct gfar_private { struct sk_buff_head rx_recycle; - struct vlan_group *vlgrp; - /* RX queue filer rule set*/ struct ethtool_rx_list rx_list; struct mutex rx_queue_access; @@ -1182,6 +1180,8 @@ extern void gfar_configure_coalescing(struct gfar_private *priv, unsigned long tx_mask, unsigned long rx_mask); void gfar_init_sysfs(struct net_device *dev); int gfar_set_features(struct net_device *dev, u32 features); +extern void gfar_check_rx_parser_mode(struct gfar_private *priv); +extern void gfar_vlan_mode(struct net_device *dev, u32 features); extern const struct ethtool_ops gfar_ethtool_ops; diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 203369cc1272..6e350692d118 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -526,6 +526,9 @@ int gfar_set_features(struct net_device *dev, u32 features) int err = 0, i = 0; u32 changed = dev->features ^ features; + if (changed & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)) + gfar_vlan_mode(dev, features); + if (!(changed & NETIF_F_RXCSUM)) return 0; diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 2cd4082c86ca..7b8ddd830f19 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -512,6 +512,16 @@ #define E1000_GCR_CMPL_TMOUT_RESEND 0x00010000 #define E1000_GCR_CAP_VER2 0x00040000 +/* mPHY Address Control and Data Registers */ +#define E1000_MPHY_ADDR_CTL 0x0024 /* mPHY Address Control Register */ +#define E1000_MPHY_ADDR_CTL_OFFSET_MASK 0xFFFF0000 +#define E1000_MPHY_DATA 0x0E10 /* mPHY Data Register */ + +/* mPHY PCS CLK Register */ +#define E1000_MPHY_PCS_CLK_REG_OFFSET 0x0004 /* mPHY PCS CLK AFE CSR Offset */ +/* mPHY Near End Digital Loopback Override Bit */ +#define E1000_MPHY_PCS_CLK_REG_DIGINELBEN 0x10 + /* PHY Control Register */ #define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ #define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index 0389ff6ea696..265e151b66c4 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h @@ -37,6 +37,8 @@ #include <linux/clocksource.h> #include <linux/timecompare.h> #include <linux/net_tstamp.h> +#include <linux/bitops.h> +#include <linux/if_vlan.h> struct igb_adapter; @@ -252,7 +254,7 @@ static inline int igb_desc_unused(struct igb_ring *ring) struct igb_adapter { struct timer_list watchdog_timer; struct timer_list phy_info_timer; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u16 mng_vlan_id; u32 bd_number; u32 wol; diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index ed63ff4cf6d6..ff244ce803ce 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -1461,6 +1461,22 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter) /* use CTRL_EXT to identify link type as SGMII can appear as copper */ if (reg & E1000_CTRL_EXT_LINK_MODE_MASK) { + if ((hw->device_id == E1000_DEV_ID_DH89XXCC_SGMII) || + (hw->device_id == E1000_DEV_ID_DH89XXCC_SERDES) || + (hw->device_id == E1000_DEV_ID_DH89XXCC_BACKPLANE) || + (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP)) { + + /* Enable DH89xxCC MPHY for near end loopback */ + reg = rd32(E1000_MPHY_ADDR_CTL); + reg = (reg & E1000_MPHY_ADDR_CTL_OFFSET_MASK) | + E1000_MPHY_PCS_CLK_REG_OFFSET; + wr32(E1000_MPHY_ADDR_CTL, reg); + + reg = rd32(E1000_MPHY_DATA); + reg |= E1000_MPHY_PCS_CLK_REG_DIGINELBEN; + wr32(E1000_MPHY_DATA, reg); + } + reg = rd32(E1000_RCTL); reg |= E1000_RCTL_LBM_TCVR; wr32(E1000_RCTL, reg); @@ -1502,6 +1518,23 @@ static void igb_loopback_cleanup(struct igb_adapter *adapter) u32 rctl; u16 phy_reg; + if ((hw->device_id == E1000_DEV_ID_DH89XXCC_SGMII) || + (hw->device_id == E1000_DEV_ID_DH89XXCC_SERDES) || + (hw->device_id == E1000_DEV_ID_DH89XXCC_BACKPLANE) || + (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP)) { + u32 reg; + + /* Disable near end loopback on DH89xxCC */ + reg = rd32(E1000_MPHY_ADDR_CTL); + reg = (reg & E1000_MPHY_ADDR_CTL_OFFSET_MASK) | + E1000_MPHY_PCS_CLK_REG_OFFSET; + wr32(E1000_MPHY_ADDR_CTL, reg); + + reg = rd32(E1000_MPHY_DATA); + reg &= ~E1000_MPHY_PCS_CLK_REG_DIGINELBEN; + wr32(E1000_MPHY_DATA, reg); + } + rctl = rd32(E1000_RCTL); rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); wr32(E1000_RCTL, rctl); diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index f4d82b2859da..cb8c6bbbf0d2 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -28,6 +28,7 @@ #include <linux/module.h> #include <linux/types.h> #include <linux/init.h> +#include <linux/bitops.h> #include <linux/vmalloc.h> #include <linux/pagemap.h> #include <linux/netdevice.h> @@ -46,6 +47,7 @@ #include <linux/if_ether.h> #include <linux/aer.h> #include <linux/prefetch.h> +#include <linux/if_vlan.h> #ifdef CONFIG_IGB_DCA #include <linux/dca.h> #endif @@ -140,7 +142,7 @@ static bool igb_clean_rx_irq_adv(struct igb_q_vector *, int *, int); static int igb_ioctl(struct net_device *, struct ifreq *, int cmd); static void igb_tx_timeout(struct net_device *); static void igb_reset_task(struct work_struct *); -static void igb_vlan_rx_register(struct net_device *, struct vlan_group *); +static void igb_vlan_mode(struct net_device *netdev, u32 features); static void igb_vlan_rx_add_vid(struct net_device *, u16); static void igb_vlan_rx_kill_vid(struct net_device *, u16); static void igb_restore_vlan(struct igb_adapter *); @@ -1362,7 +1364,7 @@ static void igb_update_mng_vlan(struct igb_adapter *adapter) if ((old_vid != (u16)IGB_MNG_VLAN_NONE) && (vid != old_vid) && - !vlan_group_get_device(adapter->vlgrp, old_vid)) { + !test_bit(old_vid, adapter->active_vlans)) { /* remove VID from filter table */ igb_vfta_set(hw, old_vid, false); } @@ -1748,10 +1750,25 @@ void igb_reset(struct igb_adapter *adapter) igb_get_phy_info(hw); } +static u32 igb_fix_features(struct net_device *netdev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + static int igb_set_features(struct net_device *netdev, u32 features) { struct igb_adapter *adapter = netdev_priv(netdev); int i; + u32 changed = netdev->features ^ features; for (i = 0; i < adapter->num_rx_queues; i++) { if (features & NETIF_F_RXCSUM) @@ -1760,6 +1777,9 @@ static int igb_set_features(struct net_device *netdev, u32 features) adapter->rx_ring[i]->flags &= ~IGB_RING_FLAG_RX_CSUM; } + if (changed & NETIF_F_HW_VLAN_RX) + igb_vlan_mode(netdev, features); + return 0; } @@ -1775,7 +1795,6 @@ static const struct net_device_ops igb_netdev_ops = { .ndo_do_ioctl = igb_ioctl, .ndo_tx_timeout = igb_tx_timeout, .ndo_validate_addr = eth_validate_addr, - .ndo_vlan_rx_register = igb_vlan_rx_register, .ndo_vlan_rx_add_vid = igb_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = igb_vlan_rx_kill_vid, .ndo_set_vf_mac = igb_ndo_set_vf_mac, @@ -1785,7 +1804,8 @@ static const struct net_device_ops igb_netdev_ops = { #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = igb_netpoll, #endif - .ndo_set_features = igb_set_features, + .ndo_fix_features = igb_fix_features, + .ndo_set_features = igb_set_features, }; /** @@ -1930,11 +1950,11 @@ static int __devinit igb_probe(struct pci_dev *pdev, NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_RXCSUM; + NETIF_F_RXCSUM | + NETIF_F_HW_VLAN_RX; netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_TX | - NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; netdev->vlan_features |= NETIF_F_TSO; @@ -2057,6 +2077,8 @@ static int __devinit igb_probe(struct pci_dev *pdev, if (err) goto err_register; + igb_vlan_mode(netdev, netdev->features); + /* carrier off reporting is important to ethtool even BEFORE open */ netif_carrier_off(netdev); @@ -2939,12 +2961,11 @@ static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size, **/ static void igb_rlpml_set(struct igb_adapter *adapter) { - u32 max_frame_size = adapter->max_frame_size; + u32 max_frame_size; struct e1000_hw *hw = &adapter->hw; u16 pf_id = adapter->vfs_allocated_count; - if (adapter->vlgrp) - max_frame_size += VLAN_TAG_SIZE; + max_frame_size = adapter->max_frame_size + VLAN_TAG_SIZE; /* if vfs are enabled we set RLPML to the largest possible request * size and set the VMOLR RLPML to the size we need */ @@ -5693,25 +5714,6 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) return count < tx_ring->count; } -/** - * igb_receive_skb - helper function to handle rx indications - * @q_vector: structure containing interrupt and ring information - * @skb: packet to send up - * @vlan_tag: vlan tag for packet - **/ -static void igb_receive_skb(struct igb_q_vector *q_vector, - struct sk_buff *skb, - u16 vlan_tag) -{ - struct igb_adapter *adapter = q_vector->adapter; - - if (vlan_tag && adapter->vlgrp) - vlan_gro_receive(&q_vector->napi, adapter->vlgrp, - vlan_tag, skb); - else - napi_gro_receive(&q_vector->napi, skb); -} - static inline void igb_rx_checksum_adv(struct igb_ring *ring, u32 status_err, struct sk_buff *skb) { @@ -5809,7 +5811,6 @@ static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector, unsigned int i; u32 staterr; u16 length; - u16 vlan_tag; i = rx_ring->next_to_clean; buffer_info = &rx_ring->buffer_info[i]; @@ -5894,10 +5895,12 @@ send_up: skb->protocol = eth_type_trans(skb, netdev); skb_record_rx_queue(skb, rx_ring->queue_index); - vlan_tag = ((staterr & E1000_RXD_STAT_VP) ? - le16_to_cpu(rx_desc->wb.upper.vlan) : 0); + if (staterr & E1000_RXD_STAT_VP) { + u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan); - igb_receive_skb(q_vector, skb, vlan_tag); + __vlan_hwaccel_put_tag(skb, vid); + } + napi_gro_receive(&q_vector->napi, skb); next_desc: rx_desc->wb.upper.status_error = 0; @@ -6290,17 +6293,15 @@ s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value) return 0; } -static void igb_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) +static void igb_vlan_mode(struct net_device *netdev, u32 features) { struct igb_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; u32 ctrl, rctl; igb_irq_disable(adapter); - adapter->vlgrp = grp; - if (grp) { + if (features & NETIF_F_HW_VLAN_RX) { /* enable VLAN tag insert/strip */ ctrl = rd32(E1000_CTRL); ctrl |= E1000_CTRL_VME; @@ -6334,6 +6335,8 @@ static void igb_vlan_rx_add_vid(struct net_device *netdev, u16 vid) /* add the filter since PF can receive vlans w/o entry in vlvf */ igb_vfta_set(hw, vid, true); + + set_bit(vid, adapter->active_vlans); } static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) @@ -6344,7 +6347,6 @@ static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) s32 err; igb_irq_disable(adapter); - vlan_group_set_device(adapter->vlgrp, vid, NULL); if (!test_bit(__IGB_DOWN, &adapter->state)) igb_irq_enable(adapter); @@ -6355,20 +6357,16 @@ static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) /* if vid was not present in VLVF just remove it from table */ if (err) igb_vfta_set(hw, vid, false); + + clear_bit(vid, adapter->active_vlans); } static void igb_restore_vlan(struct igb_adapter *adapter) { - igb_vlan_rx_register(adapter->netdev, adapter->vlgrp); + u16 vid; - if (adapter->vlgrp) { - u16 vid; - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) - continue; - igb_vlan_rx_add_vid(adapter->netdev, vid); - } - } + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) + igb_vlan_rx_add_vid(adapter->netdev, vid); } int igb_set_spd_dplx(struct igb_adapter *adapter, u32 spd, u8 dplx) diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h index d5dad5d607d6..fd4a7b780fdd 100644 --- a/drivers/net/igbvf/igbvf.h +++ b/drivers/net/igbvf/igbvf.h @@ -34,7 +34,7 @@ #include <linux/timer.h> #include <linux/io.h> #include <linux/netdevice.h> - +#include <linux/if_vlan.h> #include "vf.h" @@ -173,7 +173,7 @@ struct igbvf_adapter { const struct igbvf_info *ei; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u32 bd_number; u32 rx_buffer_len; u32 polling_interval; diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 64b47bf01e17..1330c8e932da 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -100,12 +100,12 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter, struct sk_buff *skb, u32 status, u16 vlan) { - if (adapter->vlgrp && (status & E1000_RXD_STAT_VP)) - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, - le16_to_cpu(vlan) & - E1000_RXD_SPC_VLAN_MASK); - else - netif_receive_skb(skb); + if (status & E1000_RXD_STAT_VP) { + u16 vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK; + + __vlan_hwaccel_put_tag(skb, vid); + } + netif_receive_skb(skb); } static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter, @@ -1167,12 +1167,10 @@ static int igbvf_poll(struct napi_struct *napi, int budget) */ static void igbvf_set_rlpml(struct igbvf_adapter *adapter) { - int max_frame_size = adapter->max_frame_size; + int max_frame_size; struct e1000_hw *hw = &adapter->hw; - if (adapter->vlgrp) - max_frame_size += VLAN_TAG_SIZE; - + max_frame_size = adapter->max_frame_size + VLAN_TAG_SIZE; e1000_rlpml_set_vf(hw, max_frame_size); } @@ -1183,6 +1181,8 @@ static void igbvf_vlan_rx_add_vid(struct net_device *netdev, u16 vid) if (hw->mac.ops.set_vfta(hw, vid, true)) dev_err(&adapter->pdev->dev, "Failed to add vlan id %d\n", vid); + else + set_bit(vid, adapter->active_vlans); } static void igbvf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) @@ -1191,7 +1191,6 @@ static void igbvf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) struct e1000_hw *hw = &adapter->hw; igbvf_irq_disable(adapter); - vlan_group_set_device(adapter->vlgrp, vid, NULL); if (!test_bit(__IGBVF_DOWN, &adapter->state)) igbvf_irq_enable(adapter); @@ -1199,30 +1198,16 @@ static void igbvf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) if (hw->mac.ops.set_vfta(hw, vid, false)) dev_err(&adapter->pdev->dev, "Failed to remove vlan id %d\n", vid); -} - -static void igbvf_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) -{ - struct igbvf_adapter *adapter = netdev_priv(netdev); - - adapter->vlgrp = grp; + else + clear_bit(vid, adapter->active_vlans); } static void igbvf_restore_vlan(struct igbvf_adapter *adapter) { u16 vid; - if (!adapter->vlgrp) - return; - - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) - continue; + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) igbvf_vlan_rx_add_vid(adapter->netdev, vid); - } - - igbvf_set_rlpml(adapter); } /** @@ -2203,7 +2188,7 @@ static netdev_tx_t igbvf_xmit_frame_ring_adv(struct sk_buff *skb, return NETDEV_TX_BUSY; } - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { tx_flags |= IGBVF_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << IGBVF_TX_FLAGS_VLAN_SHIFT); } @@ -2556,7 +2541,6 @@ static const struct net_device_ops igbvf_netdev_ops = { .ndo_change_mtu = igbvf_change_mtu, .ndo_do_ioctl = igbvf_ioctl, .ndo_tx_timeout = igbvf_tx_timeout, - .ndo_vlan_rx_register = igbvf_vlan_rx_register, .ndo_vlan_rx_add_vid = igbvf_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = igbvf_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 744b64108130..e04a8e49e6dc 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -214,12 +214,10 @@ struct ixgbe_ring { struct ixgbe_rx_buffer *rx_buffer_info; }; unsigned long state; - u8 atr_sample_rate; - u8 atr_count; + u8 __iomem *tail; + u16 count; /* amount of descriptors */ u16 rx_buf_len; - u16 next_to_use; - u16 next_to_clean; u8 queue_index; /* needed for multiqueue queue management */ u8 reg_idx; /* holds the special value that gets @@ -227,15 +225,13 @@ struct ixgbe_ring { * associated with this ring, which is * different for DCB and RSS modes */ - u8 dcb_tc; - - u16 work_limit; /* max work per interrupt */ - - u8 __iomem *tail; + u8 atr_sample_rate; + u8 atr_count; - unsigned int total_bytes; - unsigned int total_packets; + u16 next_to_use; + u16 next_to_clean; + u8 dcb_tc; struct ixgbe_queue_stats stats; struct u64_stats_sync syncp; union { @@ -277,6 +273,18 @@ struct ixgbe_ring_feature { int mask; } ____cacheline_internodealigned_in_smp; +struct ixgbe_ring_container { +#if MAX_RX_QUEUES > MAX_TX_QUEUES + DECLARE_BITMAP(idx, MAX_RX_QUEUES); +#else + DECLARE_BITMAP(idx, MAX_TX_QUEUES); +#endif + unsigned int total_bytes; /* total bytes processed this int */ + unsigned int total_packets; /* total packets processed this int */ + u16 work_limit; /* total work allowed per interrupt */ + u8 count; /* total number of rings in vector */ + u8 itr; /* current ITR setting for ring */ +}; #define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \ ? 8 : 1) @@ -294,12 +302,7 @@ struct ixgbe_q_vector { int cpu; /* CPU for DCA */ #endif struct napi_struct napi; - DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */ - DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */ - u8 rxr_count; /* Rx ring count assigned to this vector */ - u8 txr_count; /* Tx ring count assigned to this vector */ - u8 tx_itr; - u8 rx_itr; + struct ixgbe_ring_container rx, tx; u32 eitr; cpumask_var_t affinity_mask; char name[IFNAMSIZ + 9]; @@ -413,6 +416,9 @@ struct ixgbe_adapter { u16 eitr_low; u16 eitr_high; + /* Work limits */ + u16 tx_work_limit; + /* TX */ struct ixgbe_ring *tx_ring[MAX_TX_QUEUES] ____cacheline_aligned_in_smp; int num_tx_queues; @@ -581,21 +587,19 @@ extern s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw, u16 soft_id); extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, union ixgbe_atr_input *mask); -extern void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, - struct ixgbe_ring *ring); -extern void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter, - struct ixgbe_ring *ring); extern void ixgbe_set_rx_mode(struct net_device *netdev); extern int ixgbe_setup_tc(struct net_device *dev, u8 tc); extern void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32); +extern void ixgbe_do_reset(struct net_device *netdev); #ifdef IXGBE_FCOE extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); extern int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, u32 tx_flags, u8 *hdr_len); extern void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter); extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, - union ixgbe_adv_rx_desc *rx_desc, - struct sk_buff *skb); + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb, + u32 staterr); extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, struct scatterlist *sgl, unsigned int sgc); extern int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 074e9baf069a..dc649553a0a6 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -442,109 +442,6 @@ static int ixgbe_set_pauseparam(struct net_device *netdev, return 0; } -static void ixgbe_do_reset(struct net_device *netdev) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - - if (netif_running(netdev)) - ixgbe_reinit_locked(adapter); - else - ixgbe_reset(adapter); -} - -static u32 ixgbe_get_rx_csum(struct net_device *netdev) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - return adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED; -} - -static void ixgbe_set_rsc(struct ixgbe_adapter *adapter) -{ - int i; - - for (i = 0; i < adapter->num_rx_queues; i++) { - struct ixgbe_ring *ring = adapter->rx_ring[i]; - if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { - set_ring_rsc_enabled(ring); - ixgbe_configure_rscctl(adapter, ring); - } else { - ixgbe_clear_rscctl(adapter, ring); - } - } -} - -static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - bool need_reset = false; - - if (data) { - adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED; - } else { - adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED; - - if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) { - adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; - netdev->features &= ~NETIF_F_LRO; - } - - switch (adapter->hw.mac.type) { - case ixgbe_mac_X540: - ixgbe_set_rsc(adapter); - break; - case ixgbe_mac_82599EB: - need_reset = true; - break; - default: - break; - } - } - - if (need_reset) - ixgbe_do_reset(netdev); - - return 0; -} - -static u32 ixgbe_get_tx_csum(struct net_device *netdev) -{ - return (netdev->features & NETIF_F_IP_CSUM) != 0; -} - -static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - u32 feature_list; - - feature_list = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); - switch (adapter->hw.mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - feature_list |= NETIF_F_SCTP_CSUM; - break; - default: - break; - } - if (data) - netdev->features |= feature_list; - else - netdev->features &= ~feature_list; - - return 0; -} - -static int ixgbe_set_tso(struct net_device *netdev, u32 data) -{ - if (data) { - netdev->features |= NETIF_F_TSO; - netdev->features |= NETIF_F_TSO6; - } else { - netdev->features &= ~NETIF_F_TSO; - netdev->features &= ~NETIF_F_TSO6; - } - return 0; -} - static u32 ixgbe_get_msglevel(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); @@ -2103,7 +2000,7 @@ static int ixgbe_get_coalesce(struct net_device *netdev, { struct ixgbe_adapter *adapter = netdev_priv(netdev); - ec->tx_max_coalesced_frames_irq = adapter->tx_ring[0]->work_limit; + ec->tx_max_coalesced_frames_irq = adapter->tx_work_limit; /* only valid if in constant ITR mode */ switch (adapter->rx_itr_setting) { @@ -2122,7 +2019,7 @@ static int ixgbe_get_coalesce(struct net_device *netdev, } /* if in mixed tx/rx queues per vector mode, report only rx settings */ - if (adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count) + if (adapter->q_vector[0]->tx.count && adapter->q_vector[0]->rx.count) return 0; /* only valid if in constant ITR mode */ @@ -2187,12 +2084,12 @@ static int ixgbe_set_coalesce(struct net_device *netdev, bool need_reset = false; /* don't accept tx specific changes if we've got mixed RxTx vectors */ - if (adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count + if (adapter->q_vector[0]->tx.count && adapter->q_vector[0]->rx.count && ec->tx_coalesce_usecs) return -EINVAL; if (ec->tx_max_coalesced_frames_irq) - adapter->tx_ring[0]->work_limit = ec->tx_max_coalesced_frames_irq; + adapter->tx_work_limit = ec->tx_max_coalesced_frames_irq; if (ec->rx_coalesce_usecs > 1) { /* check the limits */ @@ -2261,18 +2158,20 @@ static int ixgbe_set_coalesce(struct net_device *netdev, int num_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; for (i = 0; i < num_vectors; i++) { q_vector = adapter->q_vector[i]; - if (q_vector->txr_count && !q_vector->rxr_count) + if (q_vector->tx.count && !q_vector->rx.count) /* tx only */ q_vector->eitr = adapter->tx_eitr_param; else /* rx only or mixed */ q_vector->eitr = adapter->rx_eitr_param; + q_vector->tx.work_limit = adapter->tx_work_limit; ixgbe_write_eitr(q_vector); } /* Legacy Interrupt Mode */ } else { q_vector = adapter->q_vector[0]; q_vector->eitr = adapter->rx_eitr_param; + q_vector->tx.work_limit = adapter->tx_work_limit; ixgbe_write_eitr(q_vector); } @@ -2287,81 +2186,6 @@ static int ixgbe_set_coalesce(struct net_device *netdev, return 0; } -static int ixgbe_set_flags(struct net_device *netdev, u32 data) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - bool need_reset = false; - int rc; - -#ifdef CONFIG_IXGBE_DCB - if ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && - !(data & ETH_FLAG_RXVLAN)) - return -EINVAL; -#endif - - need_reset = (data & ETH_FLAG_RXVLAN) != - (netdev->features & NETIF_F_HW_VLAN_RX); - - if ((data & ETH_FLAG_RXHASH) && - !(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) - return -EOPNOTSUPP; - - rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE | - ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | - ETH_FLAG_RXHASH); - if (rc) - return rc; - - /* if state changes we need to update adapter->flags and reset */ - if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) && - (!!(data & ETH_FLAG_LRO) != - !!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) { - if ((data & ETH_FLAG_LRO) && - (!adapter->rx_itr_setting || - (adapter->rx_itr_setting > IXGBE_MAX_RSC_INT_RATE))) { - e_info(probe, "rx-usecs set too low, " - "not enabling RSC.\n"); - } else { - adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED; - switch (adapter->hw.mac.type) { - case ixgbe_mac_X540: - ixgbe_set_rsc(adapter); - break; - case ixgbe_mac_82599EB: - need_reset = true; - break; - default: - break; - } - } - } - - /* - * Check if Flow Director n-tuple support was enabled or disabled. If - * the state changed, we need to reset. - */ - if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) { - /* turn off ATR, enable perfect filters and reset */ - if (data & ETH_FLAG_NTUPLE) { - adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; - adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE; - need_reset = true; - } - } else if (!(data & ETH_FLAG_NTUPLE)) { - /* turn off Flow Director, set ATR and reset */ - adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; - if ((adapter->flags & IXGBE_FLAG_RSS_ENABLED) && - !(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) - adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; - need_reset = true; - } - - if (need_reset) - ixgbe_do_reset(netdev); - - return 0; -} - static int ixgbe_get_ethtool_fdir_entry(struct ixgbe_adapter *adapter, struct ethtool_rxnfc *cmd) { @@ -2744,16 +2568,8 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { .set_ringparam = ixgbe_set_ringparam, .get_pauseparam = ixgbe_get_pauseparam, .set_pauseparam = ixgbe_set_pauseparam, - .get_rx_csum = ixgbe_get_rx_csum, - .set_rx_csum = ixgbe_set_rx_csum, - .get_tx_csum = ixgbe_get_tx_csum, - .set_tx_csum = ixgbe_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, .get_msglevel = ixgbe_get_msglevel, .set_msglevel = ixgbe_set_msglevel, - .get_tso = ethtool_op_get_tso, - .set_tso = ixgbe_set_tso, .self_test = ixgbe_diag_test, .get_strings = ixgbe_get_strings, .set_phys_id = ixgbe_set_phys_id, @@ -2761,8 +2577,6 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { .get_ethtool_stats = ixgbe_get_ethtool_stats, .get_coalesce = ixgbe_get_coalesce, .set_coalesce = ixgbe_set_coalesce, - .get_flags = ethtool_op_get_flags, - .set_flags = ixgbe_set_flags, .get_rxnfc = ixgbe_get_rxnfc, .set_rxnfc = ixgbe_set_rxnfc, }; diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index f0c1018bbf31..824edae77865 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -37,25 +37,6 @@ #include <scsi/libfcoe.h> /** - * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type - * @rx_desc: advanced rx descriptor - * - * Returns : true if it is FCoE pkt - */ -static inline bool ixgbe_rx_is_fcoe(union ixgbe_adv_rx_desc *rx_desc) -{ - u16 p; - - p = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.pkt_info); - if (p & IXGBE_RXDADV_PKTTYPE_ETQF) { - p &= IXGBE_RXDADV_PKTTYPE_ETQF_MASK; - p >>= IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT; - return p == IXGBE_ETQF_FILTER_FCOE; - } - return false; -} - -/** * ixgbe_fcoe_clear_ddp - clear the given ddp context * @ddp - ptr to the ixgbe_fcoe_ddp * @@ -136,7 +117,6 @@ out_ddp_put: return len; } - /** * ixgbe_fcoe_ddp_setup - called to set up ddp context * @netdev: the corresponding net_device @@ -380,23 +360,20 @@ int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, */ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc, - struct sk_buff *skb) + struct sk_buff *skb, + u32 staterr) { u16 xid; u32 fctl; - u32 sterr, fceofe, fcerr, fcstat; + u32 fceofe, fcerr, fcstat; int rc = -EINVAL; struct ixgbe_fcoe *fcoe; struct ixgbe_fcoe_ddp *ddp; struct fc_frame_header *fh; struct fcoe_crc_eof *crc; - if (!ixgbe_rx_is_fcoe(rx_desc)) - goto ddp_out; - - sterr = le32_to_cpu(rx_desc->wb.upper.status_error); - fcerr = (sterr & IXGBE_RXDADV_ERR_FCERR); - fceofe = (sterr & IXGBE_RXDADV_ERR_FCEOFE); + fcerr = (staterr & IXGBE_RXDADV_ERR_FCERR); + fceofe = (staterr & IXGBE_RXDADV_ERR_FCEOFE); if (fcerr == IXGBE_FCERR_BADCRC) skb_checksum_none_assert(skb); else @@ -425,7 +402,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, if (fcerr | fceofe) goto ddp_out; - fcstat = (sterr & IXGBE_RXDADV_STAT_FCSTAT); + fcstat = (staterr & IXGBE_RXDADV_STAT_FCSTAT); if (fcstat) { /* update length of DDPed data */ ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index de307965dfee..1be617545dc9 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -805,7 +805,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) && - (count < tx_ring->work_limit)) { + (count < q_vector->tx.work_limit)) { bool cleaned = false; rmb(); /* read buffer_info after eop_desc */ for ( ; !cleaned; count++) { @@ -834,11 +834,11 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, } tx_ring->next_to_clean = i; - tx_ring->total_bytes += total_bytes; - tx_ring->total_packets += total_packets; - u64_stats_update_begin(&tx_ring->syncp); - tx_ring->stats.packets += total_packets; tx_ring->stats.bytes += total_bytes; + tx_ring->stats.packets += total_packets; + u64_stats_update_begin(&tx_ring->syncp); + q_vector->tx.total_bytes += total_bytes; + q_vector->tx.total_packets += total_packets; u64_stats_update_end(&tx_ring->syncp); if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) { @@ -886,7 +886,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, } } - return count < tx_ring->work_limit; + return count < q_vector->tx.work_limit; } #ifdef CONFIG_IXGBE_DCA @@ -959,17 +959,17 @@ static void ixgbe_update_dca(struct ixgbe_q_vector *q_vector) if (q_vector->cpu == cpu) goto out_no_update; - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { + r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); + for (i = 0; i < q_vector->tx.count; i++) { ixgbe_update_tx_dca(adapter, adapter->tx_ring[r_idx], cpu); - r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, + r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, r_idx + 1); } - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rx.count; i++) { ixgbe_update_rx_dca(adapter, adapter->rx_ring[r_idx], cpu); - r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, r_idx + 1); } @@ -1039,6 +1039,24 @@ static inline void ixgbe_rx_hash(union ixgbe_adv_rx_desc *rx_desc, } /** + * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type + * @adapter: address of board private structure + * @rx_desc: advanced rx descriptor + * + * Returns : true if it is FCoE pkt + */ +static inline bool ixgbe_rx_is_fcoe(struct ixgbe_adapter *adapter, + union ixgbe_adv_rx_desc *rx_desc) +{ + __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; + + return (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && + ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_ETQF_MASK)) == + (cpu_to_le16(IXGBE_ETQF_FILTER_FCOE << + IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT))); +} + +/** * ixgbe_receive_skb - Send a completed packet up the stack * @adapter: board private structure * @skb: packet to send up @@ -1070,14 +1088,14 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, * @adapter: address of board private structure * @status_err: hardware indication of status of receive * @skb: skb currently being received and modified + * @status_err: status error value of last descriptor in packet **/ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc, - struct sk_buff *skb) + struct sk_buff *skb, + u32 status_err) { - u32 status_err = le32_to_cpu(rx_desc->wb.upper.status_error); - - skb_checksum_none_assert(skb); + skb->ip_summed = CHECKSUM_NONE; /* Rx csum disabled */ if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED)) @@ -1421,14 +1439,12 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, } /* ERR_MASK will only have valid bits if EOP set */ - if (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) { - /* trim packet back to size 0 and recycle it */ - __pskb_trim(skb, 0); - rx_buffer_info->skb = skb; + if (unlikely(staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK)) { + dev_kfree_skb_any(skb); goto next_desc; } - ixgbe_rx_checksum(adapter, rx_desc, skb); + ixgbe_rx_checksum(adapter, rx_desc, skb, staterr); if (adapter->netdev->features & NETIF_F_RXHASH) ixgbe_rx_hash(rx_desc, skb); @@ -1439,8 +1455,9 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, skb->protocol = eth_type_trans(skb, rx_ring->netdev); #ifdef IXGBE_FCOE /* if ddp, not passing to ULD unless for FCP_RSP or error */ - if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { - ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb); + if (ixgbe_rx_is_fcoe(adapter, rx_desc)) { + ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb, + staterr); if (!ddp_bytes) goto next_desc; } @@ -1486,12 +1503,12 @@ next_desc: } #endif /* IXGBE_FCOE */ - rx_ring->total_packets += total_rx_packets; - rx_ring->total_bytes += total_rx_bytes; u64_stats_update_begin(&rx_ring->syncp); rx_ring->stats.packets += total_rx_packets; rx_ring->stats.bytes += total_rx_bytes; u64_stats_update_end(&rx_ring->syncp); + q_vector->rx.total_packets += total_rx_packets; + q_vector->rx.total_bytes += total_rx_bytes; } static int ixgbe_clean_rxonly(struct napi_struct *, int); @@ -1517,31 +1534,31 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) for (v_idx = 0; v_idx < q_vectors; v_idx++) { q_vector = adapter->q_vector[v_idx]; /* XXX for_each_set_bit(...) */ - r_idx = find_first_bit(q_vector->rxr_idx, + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { + for (i = 0; i < q_vector->rx.count; i++) { u8 reg_idx = adapter->rx_ring[r_idx]->reg_idx; ixgbe_set_ivar(adapter, 0, reg_idx, v_idx); - r_idx = find_next_bit(q_vector->rxr_idx, + r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, r_idx + 1); } - r_idx = find_first_bit(q_vector->txr_idx, + r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { + for (i = 0; i < q_vector->tx.count; i++) { u8 reg_idx = adapter->tx_ring[r_idx]->reg_idx; ixgbe_set_ivar(adapter, 1, reg_idx, v_idx); - r_idx = find_next_bit(q_vector->txr_idx, + r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, r_idx + 1); } - if (q_vector->txr_count && !q_vector->rxr_count) + if (q_vector->tx.count && !q_vector->rx.count) /* tx only */ q_vector->eitr = adapter->tx_eitr_param; - else if (q_vector->rxr_count) + else if (q_vector->rx.count) /* rx or mixed */ q_vector->eitr = adapter->rx_eitr_param; @@ -1597,11 +1614,8 @@ enum latency_range { /** * ixgbe_update_itr - update the dynamic ITR value based on statistics - * @adapter: pointer to adapter - * @eitr: eitr setting (ints per sec) to give last timeslice - * @itr_setting: current throttle rate in ints/second - * @packets: the number of packets during this measurement interval - * @bytes: the number of bytes during this measurement interval + * @q_vector: structure containing interrupt and ring information + * @ring_container: structure containing ring performance data * * Stores a new ITR value based on packets and byte * counts during the last interrupt. The advantage of per interrupt @@ -1613,17 +1627,18 @@ enum latency_range { * this functionality is controlled by the InterruptThrottleRate module * parameter (see ixgbe_param.c) **/ -static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter, - u32 eitr, u8 itr_setting, - int packets, int bytes) +static void ixgbe_update_itr(struct ixgbe_q_vector *q_vector, + struct ixgbe_ring_container *ring_container) { - unsigned int retval = itr_setting; - u32 timepassed_us; u64 bytes_perint; + struct ixgbe_adapter *adapter = q_vector->adapter; + int bytes = ring_container->total_bytes; + int packets = ring_container->total_packets; + u32 timepassed_us; + u8 itr_setting = ring_container->itr; if (packets == 0) - goto update_itr_done; - + return; /* simple throttlerate management * 0-20MB/s lowest (100000 ints/s) @@ -1631,28 +1646,32 @@ static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter, * 100-1249MB/s bulk (8000 ints/s) */ /* what was last interrupt timeslice? */ - timepassed_us = 1000000/eitr; + timepassed_us = 1000000/q_vector->eitr; bytes_perint = bytes / timepassed_us; /* bytes/usec */ switch (itr_setting) { case lowest_latency: if (bytes_perint > adapter->eitr_low) - retval = low_latency; + itr_setting = low_latency; break; case low_latency: if (bytes_perint > adapter->eitr_high) - retval = bulk_latency; + itr_setting = bulk_latency; else if (bytes_perint <= adapter->eitr_low) - retval = lowest_latency; + itr_setting = lowest_latency; break; case bulk_latency: if (bytes_perint <= adapter->eitr_high) - retval = low_latency; + itr_setting = low_latency; break; } -update_itr_done: - return retval; + /* clear work counters since we have the values we need */ + ring_container->total_bytes = 0; + ring_container->total_packets = 0; + + /* write updated itr to ring container */ + ring_container->itr = itr_setting; } /** @@ -1698,44 +1717,15 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector) IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg); } -static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) +static void ixgbe_set_itr(struct ixgbe_q_vector *q_vector) { - struct ixgbe_adapter *adapter = q_vector->adapter; - int i, r_idx; - u32 new_itr; - u8 current_itr, ret_itr; - - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { - struct ixgbe_ring *tx_ring = adapter->tx_ring[r_idx]; - ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, - q_vector->tx_itr, - tx_ring->total_packets, - tx_ring->total_bytes); - /* if the result for this queue would decrease interrupt - * rate for this vector then use that result */ - q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ? - q_vector->tx_itr - 1 : ret_itr); - r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); - } + u32 new_itr = q_vector->eitr; + u8 current_itr; - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { - struct ixgbe_ring *rx_ring = adapter->rx_ring[r_idx]; - ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, - q_vector->rx_itr, - rx_ring->total_packets, - rx_ring->total_bytes); - /* if the result for this queue would decrease interrupt - * rate for this vector then use that result */ - q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ? - q_vector->rx_itr - 1 : ret_itr); - r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, - r_idx + 1); - } + ixgbe_update_itr(q_vector, &q_vector->tx); + ixgbe_update_itr(q_vector, &q_vector->rx); - current_itr = max(q_vector->rx_itr, q_vector->tx_itr); + current_itr = max(q_vector->rx.itr, q_vector->tx.itr); switch (current_itr) { /* counts and packets in update_itr are dependent on these numbers */ @@ -1746,16 +1736,17 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) new_itr = 20000; /* aka hwitr = ~200 */ break; case bulk_latency: - default: new_itr = 8000; break; + default: + break; } if (new_itr != q_vector->eitr) { /* do an exponential smoothing */ new_itr = ((q_vector->eitr * 9) + new_itr)/10; - /* save the algorithm value here, not the smoothed one */ + /* save the algorithm value here */ q_vector->eitr = new_itr; ixgbe_write_eitr(q_vector); @@ -1995,15 +1986,13 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data) struct ixgbe_ring *tx_ring; int i, r_idx; - if (!q_vector->txr_count) + if (!q_vector->tx.count) return IRQ_HANDLED; - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { + r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); + for (i = 0; i < q_vector->tx.count; i++) { tx_ring = adapter->tx_ring[r_idx]; - tx_ring->total_bytes = 0; - tx_ring->total_packets = 0; - r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, + r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, r_idx + 1); } @@ -2031,16 +2020,14 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) ixgbe_update_dca(q_vector); #endif - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rx.count; i++) { rx_ring = adapter->rx_ring[r_idx]; - rx_ring->total_bytes = 0; - rx_ring->total_packets = 0; - r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, r_idx + 1); } - if (!q_vector->rxr_count) + if (!q_vector->rx.count) return IRQ_HANDLED; /* EIAM disabled interrupts (on this vector) for us */ @@ -2057,24 +2044,20 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data) int r_idx; int i; - if (!q_vector->txr_count && !q_vector->rxr_count) + if (!q_vector->tx.count && !q_vector->rx.count) return IRQ_HANDLED; - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { + r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); + for (i = 0; i < q_vector->tx.count; i++) { ring = adapter->tx_ring[r_idx]; - ring->total_bytes = 0; - ring->total_packets = 0; - r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, + r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, r_idx + 1); } - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rx.count; i++) { ring = adapter->rx_ring[r_idx]; - ring->total_bytes = 0; - ring->total_packets = 0; - r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, r_idx + 1); } @@ -2106,7 +2089,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) ixgbe_update_dca(q_vector); #endif - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); rx_ring = adapter->rx_ring[r_idx]; ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget); @@ -2115,7 +2098,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) if (work_done < budget) { napi_complete(napi); if (adapter->rx_itr_setting & 1) - ixgbe_set_itr_msix(q_vector); + ixgbe_set_itr(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx)); @@ -2147,33 +2130,33 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) ixgbe_update_dca(q_vector); #endif - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { + r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); + for (i = 0; i < q_vector->tx.count; i++) { ring = adapter->tx_ring[r_idx]; tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring); - r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, + r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, r_idx + 1); } /* attempt to distribute budget to each queue fairly, but don't allow * the budget to go below 1 because we'll exit polling */ - budget /= (q_vector->rxr_count ?: 1); + budget /= (q_vector->rx.count ?: 1); budget = max(budget, 1); - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rx.count; i++) { ring = adapter->rx_ring[r_idx]; ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget); - r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, r_idx + 1); } - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); ring = adapter->rx_ring[r_idx]; /* If all Rx work done, exit the polling mode */ if (work_done < budget) { napi_complete(napi); if (adapter->rx_itr_setting & 1) - ixgbe_set_itr_msix(q_vector); + ixgbe_set_itr(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx)); @@ -2205,7 +2188,7 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget) ixgbe_update_dca(q_vector); #endif - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); + r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); tx_ring = adapter->tx_ring[r_idx]; if (!ixgbe_clean_tx_irq(q_vector, tx_ring)) @@ -2215,7 +2198,7 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget) if (work_done < budget) { napi_complete(napi); if (adapter->tx_itr_setting & 1) - ixgbe_set_itr_msix(q_vector); + ixgbe_set_itr(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx)); @@ -2230,8 +2213,8 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, struct ixgbe_q_vector *q_vector = a->q_vector[v_idx]; struct ixgbe_ring *rx_ring = a->rx_ring[r_idx]; - set_bit(r_idx, q_vector->rxr_idx); - q_vector->rxr_count++; + set_bit(r_idx, q_vector->rx.idx); + q_vector->rx.count++; rx_ring->q_vector = q_vector; } @@ -2241,9 +2224,10 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, struct ixgbe_q_vector *q_vector = a->q_vector[v_idx]; struct ixgbe_ring *tx_ring = a->tx_ring[t_idx]; - set_bit(t_idx, q_vector->txr_idx); - q_vector->txr_count++; + set_bit(t_idx, q_vector->tx.idx); + q_vector->tx.count++; tx_ring->q_vector = q_vector; + q_vector->tx.work_limit = a->tx_work_limit; } /** @@ -2332,10 +2316,10 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) if (err) return err; -#define SET_HANDLER(_v) (((_v)->rxr_count && (_v)->txr_count) \ +#define SET_HANDLER(_v) (((_v)->rx.count && (_v)->tx.count) \ ? &ixgbe_msix_clean_many : \ - (_v)->rxr_count ? &ixgbe_msix_clean_rx : \ - (_v)->txr_count ? &ixgbe_msix_clean_tx : \ + (_v)->rx.count ? &ixgbe_msix_clean_rx : \ + (_v)->tx.count ? &ixgbe_msix_clean_tx : \ NULL) for (vector = 0; vector < q_vectors; vector++) { struct ixgbe_q_vector *q_vector = adapter->q_vector[vector]; @@ -2386,51 +2370,6 @@ free_queue_irqs: return err; } -static void ixgbe_set_itr(struct ixgbe_adapter *adapter) -{ - struct ixgbe_q_vector *q_vector = adapter->q_vector[0]; - struct ixgbe_ring *rx_ring = adapter->rx_ring[0]; - struct ixgbe_ring *tx_ring = adapter->tx_ring[0]; - u32 new_itr = q_vector->eitr; - u8 current_itr; - - q_vector->tx_itr = ixgbe_update_itr(adapter, new_itr, - q_vector->tx_itr, - tx_ring->total_packets, - tx_ring->total_bytes); - q_vector->rx_itr = ixgbe_update_itr(adapter, new_itr, - q_vector->rx_itr, - rx_ring->total_packets, - rx_ring->total_bytes); - - current_itr = max(q_vector->rx_itr, q_vector->tx_itr); - - switch (current_itr) { - /* counts and packets in update_itr are dependent on these numbers */ - case lowest_latency: - new_itr = 100000; - break; - case low_latency: - new_itr = 20000; /* aka hwitr = ~200 */ - break; - case bulk_latency: - new_itr = 8000; - break; - default: - break; - } - - if (new_itr != q_vector->eitr) { - /* do an exponential smoothing */ - new_itr = ((q_vector->eitr * 9) + new_itr)/10; - - /* save the algorithm value here */ - q_vector->eitr = new_itr; - - ixgbe_write_eitr(q_vector); - } -} - /** * ixgbe_irq_enable - Enable default interrupt generation settings * @adapter: board private structure @@ -2528,10 +2467,6 @@ static irqreturn_t ixgbe_intr(int irq, void *data) ixgbe_check_fan_failure(adapter, eicr); if (napi_schedule_prep(&(q_vector->napi))) { - adapter->tx_ring[0]->total_packets = 0; - adapter->tx_ring[0]->total_bytes = 0; - adapter->rx_ring[0]->total_packets = 0; - adapter->rx_ring[0]->total_bytes = 0; /* would disable interrupts here but EIAM disabled it */ __napi_schedule(&(q_vector->napi)); } @@ -2553,10 +2488,10 @@ static inline void ixgbe_reset_q_vectors(struct ixgbe_adapter *adapter) for (i = 0; i < q_vectors; i++) { struct ixgbe_q_vector *q_vector = adapter->q_vector[i]; - bitmap_zero(q_vector->rxr_idx, MAX_RX_QUEUES); - bitmap_zero(q_vector->txr_idx, MAX_TX_QUEUES); - q_vector->rxr_count = 0; - q_vector->txr_count = 0; + bitmap_zero(q_vector->rx.idx, MAX_RX_QUEUES); + bitmap_zero(q_vector->tx.idx, MAX_TX_QUEUES); + q_vector->rx.count = 0; + q_vector->tx.count = 0; } } @@ -2601,8 +2536,8 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter) i--; for (; i >= 0; i--) { /* free only the irqs that were actually requested */ - if (!adapter->q_vector[i]->rxr_count && - !adapter->q_vector[i]->txr_count) + if (!adapter->q_vector[i]->rx.count && + !adapter->q_vector[i]->tx.count) continue; free_irq(adapter->msix_entries[i].vector, @@ -2927,28 +2862,11 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) } /** - * ixgbe_clear_rscctl - disable RSC for the indicated ring - * @adapter: address of board private structure - * @ring: structure containing ring specific data - **/ -void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter, - struct ixgbe_ring *ring) -{ - struct ixgbe_hw *hw = &adapter->hw; - u32 rscctrl; - u8 reg_idx = ring->reg_idx; - - rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(reg_idx)); - rscctrl &= ~IXGBE_RSCCTL_RSCEN; - IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl); -} - -/** * ixgbe_configure_rscctl - enable RSC for the indicated ring * @adapter: address of board private structure * @index: index of ring to set **/ -void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, +static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, struct ixgbe_ring *ring) { struct ixgbe_hw *hw = &adapter->hw; @@ -3616,10 +3534,10 @@ static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) q_vector = adapter->q_vector[q_idx]; napi = &q_vector->napi; if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { - if (!q_vector->rxr_count || !q_vector->txr_count) { - if (q_vector->txr_count == 1) + if (!q_vector->rx.count || !q_vector->tx.count) { + if (q_vector->tx.count == 1) napi->poll = &ixgbe_clean_txonly; - else if (q_vector->rxr_count == 1) + else if (q_vector->rx.count == 1) napi->poll = &ixgbe_clean_rxonly; } } @@ -4299,7 +4217,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget) if (work_done < budget) { napi_complete(napi); if (adapter->rx_itr_setting & 1) - ixgbe_set_itr(adapter); + ixgbe_set_itr(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_enable_queues(adapter, IXGBE_EIMS_RTX_QUEUE); } @@ -4965,7 +4883,7 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter) if (!q_vector) goto err_out; q_vector->adapter = adapter; - if (q_vector->txr_count && !q_vector->rxr_count) + if (q_vector->tx.count && !q_vector->rx.count) q_vector->eitr = adapter->tx_eitr_param; else q_vector->eitr = adapter->rx_eitr_param; @@ -5224,6 +5142,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->tx_ring_count = IXGBE_DEFAULT_TXD; adapter->rx_ring_count = IXGBE_DEFAULT_RXD; + /* set default work limits */ + adapter->tx_work_limit = adapter->tx_ring_count; + /* initialize eeprom parameters */ if (ixgbe_init_eeprom_params_generic(hw)) { e_dev_err("EEPROM initialization failed\n"); @@ -5270,7 +5191,6 @@ int ixgbe_setup_tx_resources(struct ixgbe_ring *tx_ring) tx_ring->next_to_use = 0; tx_ring->next_to_clean = 0; - tx_ring->work_limit = tx_ring->count; return 0; err: @@ -5979,7 +5899,7 @@ static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter) /* get one bit for every active tx/rx interrupt vector */ for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) { struct ixgbe_q_vector *qv = adapter->q_vector[i]; - if (qv->rxr_count || qv->txr_count) + if (qv->rx.count || qv->tx.count) eics |= ((u64)1 << i); } } @@ -6084,9 +6004,7 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter) (flow_tx ? "TX" : "None")))); netif_carrier_on(netdev); -#ifdef HAVE_IPLINK_VF_CONFIG ixgbe_check_vf_rate_limit(adapter); -#endif /* HAVE_IPLINK_VF_CONFIG */ } /** @@ -6785,7 +6703,7 @@ static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) return 0; } -static int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) +static inline int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) { if (likely(ixgbe_desc_unused(tx_ring) >= size)) return 0; @@ -6795,11 +6713,10 @@ static int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) { struct ixgbe_adapter *adapter = netdev_priv(dev); - int txq = smp_processor_id(); + int txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : + smp_processor_id(); #ifdef IXGBE_FCOE - __be16 protocol; - - protocol = vlan_get_protocol(skb); + __be16 protocol = vlan_get_protocol(skb); if (((protocol == htons(ETH_P_FCOE)) || (protocol == htons(ETH_P_FIP))) && @@ -7188,6 +7105,98 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) return 0; } +void ixgbe_do_reset(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + else + ixgbe_reset(adapter); +} + +static u32 ixgbe_fix_features(struct net_device *netdev, u32 data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + +#ifdef CONFIG_DCB + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) + data &= ~NETIF_F_HW_VLAN_RX; +#endif + + /* return error if RXHASH is being enabled when RSS is not supported */ + if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) + data &= ~NETIF_F_RXHASH; + + /* If Rx checksum is disabled, then RSC/LRO should also be disabled */ + if (!(data & NETIF_F_RXCSUM)) + data &= ~NETIF_F_LRO; + + /* Turn off LRO if not RSC capable or invalid ITR settings */ + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) { + data &= ~NETIF_F_LRO; + } else if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) && + (adapter->rx_itr_setting != 1 && + adapter->rx_itr_setting > IXGBE_MAX_RSC_INT_RATE)) { + data &= ~NETIF_F_LRO; + e_info(probe, "rx-usecs set too low, not enabling RSC\n"); + } + + return data; +} + +static int ixgbe_set_features(struct net_device *netdev, u32 data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + bool need_reset = false; + + /* If Rx checksum is disabled, then RSC/LRO should also be disabled */ + if (!(data & NETIF_F_RXCSUM)) + adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED; + else + adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED; + + /* Make sure RSC matches LRO, reset if change */ + if (!!(data & NETIF_F_LRO) != + !!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) { + adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED; + switch (adapter->hw.mac.type) { + case ixgbe_mac_X540: + case ixgbe_mac_82599EB: + need_reset = true; + break; + default: + break; + } + } + + /* + * Check if Flow Director n-tuple support was enabled or disabled. If + * the state changed, we need to reset. + */ + if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) { + /* turn off ATR, enable perfect filters and reset */ + if (data & NETIF_F_NTUPLE) { + adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; + adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE; + need_reset = true; + } + } else if (!(data & NETIF_F_NTUPLE)) { + /* turn off Flow Director, set ATR and reset */ + adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; + if ((adapter->flags & IXGBE_FLAG_RSS_ENABLED) && + !(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; + need_reset = true; + } + + if (need_reset) + ixgbe_do_reset(netdev); + + return 0; + +} + static const struct net_device_ops ixgbe_netdev_ops = { .ndo_open = ixgbe_open, .ndo_stop = ixgbe_close, @@ -7219,6 +7228,8 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_fcoe_disable = ixgbe_fcoe_disable, .ndo_fcoe_get_wwn = ixgbe_fcoe_get_wwn, #endif /* IXGBE_FCOE */ + .ndo_set_features = ixgbe_set_features, + .ndo_fix_features = ixgbe_fix_features, }; static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter, @@ -7486,20 +7497,24 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->features = NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | - NETIF_F_HW_VLAN_FILTER; + NETIF_F_HW_VLAN_FILTER | + NETIF_F_TSO | + NETIF_F_TSO6 | + NETIF_F_GRO | + NETIF_F_RXHASH | + NETIF_F_RXCSUM; - netdev->features |= NETIF_F_IPV6_CSUM; - netdev->features |= NETIF_F_TSO; - netdev->features |= NETIF_F_TSO6; - netdev->features |= NETIF_F_GRO; - netdev->features |= NETIF_F_RXHASH; + netdev->hw_features = netdev->features; switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: netdev->features |= NETIF_F_SCTP_CSUM; + netdev->hw_features |= NETIF_F_SCTP_CSUM | + NETIF_F_NTUPLE; break; default: break; @@ -7538,6 +7553,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->vlan_features |= NETIF_F_HIGHDMA; } + if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) + netdev->hw_features |= NETIF_F_LRO; if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) netdev->features |= NETIF_F_LRO; @@ -7574,25 +7591,24 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, if (err) goto err_sw_init; - if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) + if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) { + netdev->hw_features &= ~NETIF_F_RXHASH; netdev->features &= ~NETIF_F_RXHASH; + } switch (pdev->device) { case IXGBE_DEV_ID_82599_SFP: /* Only this subdevice supports WOL */ if (pdev->subsystem_device == IXGBE_SUBDEV_ID_82599_SFP) - adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | - IXGBE_WUFC_MC | IXGBE_WUFC_BC); + adapter->wol = IXGBE_WUFC_MAG; break; case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: /* All except this subdevice support WOL */ if (pdev->subsystem_device != IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) - adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | - IXGBE_WUFC_MC | IXGBE_WUFC_BC); + adapter->wol = IXGBE_WUFC_MAG; break; case IXGBE_DEV_ID_82599_KX4: - adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | - IXGBE_WUFC_MC | IXGBE_WUFC_BC); + adapter->wol = IXGBE_WUFC_MAG; break; default: adapter->wol = 0; diff --git a/drivers/net/ixgbevf/ixgbevf.h b/drivers/net/ixgbevf/ixgbevf.h index a2bbbb358161..8857df4dd3b9 100644 --- a/drivers/net/ixgbevf/ixgbevf.h +++ b/drivers/net/ixgbevf/ixgbevf.h @@ -29,9 +29,11 @@ #define _IXGBEVF_H_ #include <linux/types.h> +#include <linux/bitops.h> #include <linux/timer.h> #include <linux/io.h> #include <linux/netdevice.h> +#include <linux/if_vlan.h> #include "vf.h" @@ -185,9 +187,7 @@ struct ixgbevf_q_vector { /* board specific private data structure */ struct ixgbevf_adapter { struct timer_list watchdog_timer; -#ifdef NETIF_F_HW_VLAN_TX - struct vlan_group *vlgrp; -#endif + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u16 bd_number; struct work_struct reset_task; struct ixgbevf_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index fec36bde1994..3b880a27f8d1 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -30,6 +30,7 @@ Copyright (c)2006 - 2007 Myricom, Inc. for some LRO specific code ******************************************************************************/ #include <linux/types.h> +#include <linux/bitops.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> @@ -288,21 +289,17 @@ static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector, { struct ixgbevf_adapter *adapter = q_vector->adapter; bool is_vlan = (status & IXGBE_RXD_STAT_VP); - u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); - if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) { - if (adapter->vlgrp && is_vlan) - vlan_gro_receive(&q_vector->napi, - adapter->vlgrp, - tag, skb); - else + if (is_vlan) { + u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); + + __vlan_hwaccel_put_tag(skb, tag); + } + + if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) napi_gro_receive(&q_vector->napi, skb); - } else { - if (adapter->vlgrp && is_vlan) - vlan_hwaccel_rx(skb, adapter->vlgrp, tag); - else + else netif_rx(skb); - } } /** @@ -1401,24 +1398,6 @@ static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter) } } -static void ixgbevf_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) -{ - struct ixgbevf_adapter *adapter = netdev_priv(netdev); - struct ixgbe_hw *hw = &adapter->hw; - int i, j; - u32 ctrl; - - adapter->vlgrp = grp; - - for (i = 0; i < adapter->num_rx_queues; i++) { - j = adapter->rx_ring[i].reg_idx; - ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j)); - ctrl |= IXGBE_RXDCTL_VME; - IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(j), ctrl); - } -} - static void ixgbevf_vlan_rx_add_vid(struct net_device *netdev, u16 vid) { struct ixgbevf_adapter *adapter = netdev_priv(netdev); @@ -1427,6 +1406,7 @@ static void ixgbevf_vlan_rx_add_vid(struct net_device *netdev, u16 vid) /* add VID to filter table */ if (hw->mac.ops.set_vfta) hw->mac.ops.set_vfta(hw, vid, 0, true); + set_bit(vid, adapter->active_vlans); } static void ixgbevf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) @@ -1434,31 +1414,18 @@ static void ixgbevf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) struct ixgbevf_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; - if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) - ixgbevf_irq_disable(adapter); - - vlan_group_set_device(adapter->vlgrp, vid, NULL); - - if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) - ixgbevf_irq_enable(adapter, true, true); - /* remove VID from filter table */ if (hw->mac.ops.set_vfta) hw->mac.ops.set_vfta(hw, vid, 0, false); + clear_bit(vid, adapter->active_vlans); } static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter) { - ixgbevf_vlan_rx_register(adapter->netdev, adapter->vlgrp); + u16 vid; - if (adapter->vlgrp) { - u16 vid; - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) - continue; - ixgbevf_vlan_rx_add_vid(adapter->netdev, vid); - } - } + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) + ixgbevf_vlan_rx_add_vid(adapter->netdev, vid); } static int ixgbevf_write_uc_addr_list(struct net_device *netdev) @@ -1648,7 +1615,7 @@ static int ixgbevf_up_complete(struct ixgbevf_adapter *adapter) for (i = 0; i < num_rx_rings; i++) { j = adapter->rx_ring[i].reg_idx; rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j)); - rxdctl |= IXGBE_RXDCTL_ENABLE; + rxdctl |= IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME; if (hw->mac.type == ixgbe_mac_X540_vf) { rxdctl &= ~IXGBE_RXDCTL_RLPMLMASK; rxdctl |= ((netdev->mtu + ETH_HLEN + ETH_FCS_LEN) | @@ -3258,7 +3225,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_set_mac_address = ixgbevf_set_mac, .ndo_change_mtu = ixgbevf_change_mtu, .ndo_tx_timeout = ixgbevf_tx_timeout, - .ndo_vlan_rx_register = ixgbevf_vlan_rx_register, .ndo_vlan_rx_add_vid = ixgbevf_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = ixgbevf_vlan_rx_kill_vid, }; diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 6b2a5e744255..3ac262f55633 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -751,20 +751,28 @@ jme_make_new_rx_buf(struct jme_adapter *jme, int i) struct jme_ring *rxring = &(jme->rxring[0]); struct jme_buffer_info *rxbi = rxring->bufinf + i; struct sk_buff *skb; + dma_addr_t mapping; skb = netdev_alloc_skb(jme->dev, jme->dev->mtu + RX_EXTRA_LEN); if (unlikely(!skb)) return -ENOMEM; + mapping = pci_map_page(jme->pdev, virt_to_page(skb->data), + offset_in_page(skb->data), skb_tailroom(skb), + PCI_DMA_FROMDEVICE); + if (unlikely(pci_dma_mapping_error(jme->pdev, mapping))) { + dev_kfree_skb(skb); + return -ENOMEM; + } + + if (likely(rxbi->mapping)) + pci_unmap_page(jme->pdev, rxbi->mapping, + rxbi->len, PCI_DMA_FROMDEVICE); + rxbi->skb = skb; rxbi->len = skb_tailroom(skb); - rxbi->mapping = pci_map_page(jme->pdev, - virt_to_page(skb->data), - offset_in_page(skb->data), - rxbi->len, - PCI_DMA_FROMDEVICE); - + rxbi->mapping = mapping; return 0; } @@ -1048,16 +1056,12 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx) skb_checksum_none_assert(skb); if (rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_TAGON)) { - if (jme->vlgrp) { - jme->jme_vlan_rx(skb, jme->vlgrp, - le16_to_cpu(rxdesc->descwb.vlan)); - NET_STAT(jme).rx_bytes += 4; - } else { - dev_kfree_skb(skb); - } - } else { - jme->jme_rx(skb); + u16 vid = le16_to_cpu(rxdesc->descwb.vlan); + + __vlan_hwaccel_put_tag(skb, vid); + NET_STAT(jme).rx_bytes += 4; } + jme->jme_rx(skb); if ((rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_DEST)) == cpu_to_le16(RXWBFLAG_DEST_MUL)) @@ -2282,16 +2286,6 @@ static inline void jme_resume_rx(struct jme_adapter *jme) } static void -jme_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) -{ - struct jme_adapter *jme = netdev_priv(netdev); - - jme_pause_rx(jme); - jme->vlgrp = grp; - jme_resume_rx(jme); -} - -static void jme_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info) { @@ -2401,7 +2395,6 @@ jme_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ecmd) test_bit(JME_FLAG_POLL, &jme->flags)) { clear_bit(JME_FLAG_POLL, &jme->flags); jme->jme_rx = netif_rx; - jme->jme_vlan_rx = vlan_hwaccel_rx; dpi->cur = PCC_P1; dpi->attempt = PCC_P1; dpi->cnt = 0; @@ -2411,7 +2404,6 @@ jme_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ecmd) !(test_bit(JME_FLAG_POLL, &jme->flags))) { set_bit(JME_FLAG_POLL, &jme->flags); jme->jme_rx = netif_receive_skb; - jme->jme_vlan_rx = vlan_hwaccel_receive_skb; jme_interrupt_mode(jme); } @@ -2850,7 +2842,6 @@ static const struct net_device_ops jme_netdev_ops = { .ndo_set_multicast_list = jme_set_multi, .ndo_change_mtu = jme_change_mtu, .ndo_tx_timeout = jme_tx_timeout, - .ndo_vlan_rx_register = jme_vlan_rx_register, .ndo_fix_features = jme_fix_features, .ndo_set_features = jme_set_features, }; @@ -2933,7 +2924,6 @@ jme_init_one(struct pci_dev *pdev, jme->pdev = pdev; jme->dev = netdev; jme->jme_rx = netif_rx; - jme->jme_vlan_rx = vlan_hwaccel_rx; jme->old_mtu = netdev->mtu = 1500; jme->phylink = 0; jme->tx_ring_size = 1 << 10; diff --git a/drivers/net/jme.h b/drivers/net/jme.h index 1481a62a1f36..c1f8b893e2ea 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -451,7 +451,6 @@ struct jme_adapter { u32 msg_enable; struct ethtool_cmd old_ecmd; unsigned int old_mtu; - struct vlan_group *vlgrp; struct dynpcc_info dpi; atomic_t intr_sem; atomic_t link_changing; @@ -459,9 +458,6 @@ struct jme_adapter { atomic_t rx_cleaning; atomic_t rx_empty; int (*jme_rx)(struct sk_buff *skb); - int (*jme_vlan_rx)(struct sk_buff *skb, - struct vlan_group *grp, - unsigned short vlan_tag); DECLARE_NAPI_STRUCT DECLARE_NET_DEVICE_STATS }; diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index cc67cbe670cb..ba631fcece34 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -510,17 +510,6 @@ static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, return stats; } -static void macvlan_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) -{ - struct macvlan_dev *vlan = netdev_priv(dev); - struct net_device *lowerdev = vlan->lowerdev; - const struct net_device_ops *ops = lowerdev->netdev_ops; - - if (ops->ndo_vlan_rx_register) - ops->ndo_vlan_rx_register(lowerdev, grp); -} - static void macvlan_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { @@ -575,7 +564,6 @@ static const struct net_device_ops macvlan_netdev_ops = { .ndo_set_multicast_list = macvlan_set_multicast_list, .ndo_get_stats64 = macvlan_dev_get_stats64, .ndo_validate_addr = eth_validate_addr, - .ndo_vlan_rx_register = macvlan_vlan_rx_register, .ndo_vlan_rx_add_vid = macvlan_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = macvlan_vlan_rx_kill_vid, }; diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 61850adae6f7..9d3f57e76f2f 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -45,25 +45,6 @@ #include "mlx4_en.h" #include "en_port.h" - -static void mlx4_en_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_en_dev *mdev = priv->mdev; - int err; - - en_dbg(HW, priv, "Registering VLAN group:%p\n", grp); - priv->vlgrp = grp; - - mutex_lock(&mdev->state_lock); - if (mdev->device_up && priv->port_up) { - err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, grp); - if (err) - en_err(priv, "Failed configuring VLAN filter\n"); - } - mutex_unlock(&mdev->state_lock); -} - static void mlx4_en_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { struct mlx4_en_priv *priv = netdev_priv(dev); @@ -71,16 +52,14 @@ static void mlx4_en_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) int err; int idx; - if (!priv->vlgrp) - return; + en_dbg(HW, priv, "adding VLAN:%d\n", vid); - en_dbg(HW, priv, "adding VLAN:%d (vlgrp entry:%p)\n", - vid, vlan_group_get_device(priv->vlgrp, vid)); + set_bit(vid, priv->active_vlans); /* Add VID to port VLAN filter */ mutex_lock(&mdev->state_lock); if (mdev->device_up && priv->port_up) { - err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp); + err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); if (err) en_err(priv, "Failed configuring VLAN filter\n"); } @@ -97,12 +76,9 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) int err; int idx; - if (!priv->vlgrp) - return; + en_dbg(HW, priv, "Killing VID:%d\n", vid); - en_dbg(HW, priv, "Killing VID:%d (vlgrp:%p vlgrp entry:%p)\n", - vid, priv->vlgrp, vlan_group_get_device(priv->vlgrp, vid)); - vlan_group_set_device(priv->vlgrp, vid, NULL); + clear_bit(vid, priv->active_vlans); /* Remove VID from port VLAN filter */ mutex_lock(&mdev->state_lock); @@ -112,7 +88,7 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) en_err(priv, "could not find vid %d in cache\n", vid); if (mdev->device_up && priv->port_up) { - err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp); + err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); if (err) en_err(priv, "Failed configuring VLAN filter\n"); } @@ -265,12 +241,10 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) priv->flags |= MLX4_EN_FLAG_MC_PROMISC; } - if (priv->vlgrp) { - /* Disable port VLAN filter */ - err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, NULL); - if (err) - en_err(priv, "Failed disabling VLAN filter\n"); - } + /* Disable port VLAN filter */ + err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); + if (err) + en_err(priv, "Failed disabling VLAN filter\n"); } goto out; } @@ -304,7 +278,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) } /* Enable port VLAN filter */ - err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp); + err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); if (err) en_err(priv, "Failed enabling VLAN filter\n"); } @@ -1046,7 +1020,6 @@ static const struct net_device_ops mlx4_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = mlx4_en_change_mtu, .ndo_tx_timeout = mlx4_en_tx_timeout, - .ndo_vlan_rx_register = mlx4_en_vlan_rx_register, .ndo_vlan_rx_add_vid = mlx4_en_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = mlx4_en_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c index f2a4f5dd313d..2a74bc81b9f7 100644 --- a/drivers/net/mlx4/en_port.c +++ b/drivers/net/mlx4/en_port.c @@ -48,7 +48,7 @@ int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port, MLX4_CMD_SET_MCAST_FLTR, MLX4_CMD_TIME_CLASS_B); } -int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, u8 port, struct vlan_group *grp) +int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, struct mlx4_en_priv *priv) { struct mlx4_cmd_mailbox *mailbox; struct mlx4_set_vlan_fltr_mbox *filter; @@ -63,20 +63,15 @@ int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, u8 port, struct vlan_group *grp) return PTR_ERR(mailbox); filter = mailbox->buf; - if (grp) { - memset(filter, 0, sizeof *filter); - for (i = VLAN_FLTR_SIZE - 1; i >= 0; i--) { - entry = 0; - for (j = 0; j < 32; j++) - if (vlan_group_get_device(grp, index++)) - entry |= 1 << j; - filter->entry[i] = cpu_to_be32(entry); - } - } else { - /* When no vlans are configured we block all vlans */ - memset(filter, 0, sizeof(*filter)); + memset(filter, 0, sizeof(*filter)); + for (i = VLAN_FLTR_SIZE - 1; i >= 0; i--) { + entry = 0; + for (j = 0; j < 32; j++) + if (test_bit(index++, priv->active_vlans)) + entry |= 1 << j; + filter->entry[i] = cpu_to_be32(entry); } - err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_VLAN_FLTR, + err = mlx4_cmd(dev, mailbox->dma, priv->port, 0, MLX4_CMD_SET_VLAN_FLTR, MLX4_CMD_TIME_CLASS_B); mlx4_free_cmd_mailbox(dev, mailbox); return err; diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 5197b50b2d81..37cc9e5c56be 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -611,11 +611,14 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud gro_skb->truesize += length; gro_skb->ip_summed = CHECKSUM_UNNECESSARY; - if (priv->vlgrp && (cqe->vlan_my_qpn & - cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK))) - vlan_gro_frags(&cq->napi, priv->vlgrp, be16_to_cpu(cqe->sl_vid)); - else - napi_gro_frags(&cq->napi); + if (cqe->vlan_my_qpn & + cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK)) { + u16 vid = be16_to_cpu(cqe->sl_vid); + + __vlan_hwaccel_put_tag(gro_skb, vid); + } + + napi_gro_frags(&cq->napi); goto next; } @@ -647,13 +650,12 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud skb->protocol = eth_type_trans(skb, dev); skb_record_rx_queue(skb, cq->ring); + if (be32_to_cpu(cqe->vlan_my_qpn) & + MLX4_CQE_VLAN_PRESENT_MASK) + __vlan_hwaccel_put_tag(skb, be16_to_cpu(cqe->sl_vid)); + /* Push it up the stack */ - if (priv->vlgrp && (be32_to_cpu(cqe->vlan_my_qpn) & - MLX4_CQE_VLAN_PRESENT_MASK)) { - vlan_hwaccel_receive_skb(skb, priv->vlgrp, - be16_to_cpu(cqe->sl_vid)); - } else - netif_receive_skb(skb); + netif_receive_skb(skb); next: ++cq->mcq.cons_index; diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 0b5150df0585..ed84811766e6 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -34,10 +34,12 @@ #ifndef _MLX4_EN_H_ #define _MLX4_EN_H_ +#include <linux/bitops.h> #include <linux/compiler.h> #include <linux/list.h> #include <linux/mutex.h> #include <linux/netdevice.h> +#include <linux/if_vlan.h> #include <linux/mlx4/device.h> #include <linux/mlx4/qp.h> @@ -418,7 +420,7 @@ struct mlx4_en_priv { struct mlx4_en_dev *mdev; struct mlx4_en_port_profile *prof; struct net_device *dev; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; struct net_device_stats stats; struct net_device_stats ret_stats; struct mlx4_en_port_state port_state; @@ -553,7 +555,7 @@ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring); void mlx4_en_rx_irq(struct mlx4_cq *mcq); int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port, u64 mac, u64 clear, u8 mode); -int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, u8 port, struct vlan_group *grp); +int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, struct mlx4_en_priv *priv); int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu, u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx); int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 77220687b92a..f744d291218a 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -53,8 +53,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 75 -#define NETXEN_NIC_LINUX_VERSIONID "4.0.75" +#define _NETXEN_NIC_LINUX_SUBVERSION 76 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.76" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) @@ -1302,6 +1302,7 @@ int netxen_nic_wol_supported(struct netxen_adapter *adapter); int netxen_init_dummy_dma(struct netxen_adapter *adapter); void netxen_free_dummy_dma(struct netxen_adapter *adapter); +int netxen_check_flash_fw_compatibility(struct netxen_adapter *adapter); int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); int netxen_load_firmware(struct netxen_adapter *adapter); int netxen_need_fw_reset(struct netxen_adapter *adapter); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index ca59b4f026f0..e8993a76a080 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -964,6 +964,35 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) return 0; } +#define NETXEN_MIN_P3_FW_SUPP NETXEN_VERSION_CODE(4, 0, 505) + +int +netxen_check_flash_fw_compatibility(struct netxen_adapter *adapter) +{ + u32 flash_fw_ver, min_fw_ver; + + if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) + return 0; + + if (netxen_rom_fast_read(adapter, + NX_FW_VERSION_OFFSET, (int *)&flash_fw_ver)) { + dev_err(&adapter->pdev->dev, "Unable to read flash fw" + "version\n"); + return -EIO; + } + + flash_fw_ver = NETXEN_DECODE_VERSION(flash_fw_ver); + min_fw_ver = NETXEN_MIN_P3_FW_SUPP; + if (flash_fw_ver >= min_fw_ver) + return 0; + + dev_info(&adapter->pdev->dev, "Flash fw[%d.%d.%d] is < min fw supported" + "[4.0.505]. Please update firmware on flash\n", + _major(flash_fw_ver), _minor(flash_fw_ver), + _build(flash_fw_ver)); + return -EINVAL; +} + static char *fw_name[] = { NX_P2_MN_ROMIMAGE_NAME, NX_P3_CT_ROMIMAGE_NAME, @@ -1071,10 +1100,12 @@ static int netxen_validate_firmware(struct netxen_adapter *adapter) { __le32 val; - u32 ver, min_ver, bios; + __le32 flash_fw_ver; + u32 file_fw_ver, min_ver, bios; struct pci_dev *pdev = adapter->pdev; const struct firmware *fw = adapter->fw; u8 fw_type = adapter->fw_type; + u32 crbinit_fix_fw; if (fw_type == NX_UNIFIED_ROMIMAGE) { if (netxen_nic_validate_unified_romimage(adapter)) @@ -1091,16 +1122,18 @@ netxen_validate_firmware(struct netxen_adapter *adapter) val = nx_get_fw_version(adapter); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) - min_ver = NETXEN_VERSION_CODE(4, 0, 216); + min_ver = NETXEN_MIN_P3_FW_SUPP; else min_ver = NETXEN_VERSION_CODE(3, 4, 216); - ver = NETXEN_DECODE_VERSION(val); + file_fw_ver = NETXEN_DECODE_VERSION(val); - if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { + if ((_major(file_fw_ver) > _NETXEN_NIC_LINUX_MAJOR) || + (file_fw_ver < min_ver)) { dev_err(&pdev->dev, "%s: firmware version %d.%d.%d unsupported\n", - fw_name[fw_type], _major(ver), _minor(ver), _build(ver)); + fw_name[fw_type], _major(file_fw_ver), _minor(file_fw_ver), + _build(file_fw_ver)); return -EINVAL; } @@ -1112,17 +1145,34 @@ netxen_validate_firmware(struct netxen_adapter *adapter) return -EINVAL; } - /* check if flashed firmware is newer */ if (netxen_rom_fast_read(adapter, - NX_FW_VERSION_OFFSET, (int *)&val)) + NX_FW_VERSION_OFFSET, (int *)&flash_fw_ver)) { + dev_err(&pdev->dev, "Unable to read flash fw version\n"); return -EIO; - val = NETXEN_DECODE_VERSION(val); - if (val > ver) { - dev_info(&pdev->dev, "%s: firmware is older than flash\n", - fw_name[fw_type]); + } + flash_fw_ver = NETXEN_DECODE_VERSION(flash_fw_ver); + + /* New fw from file is not allowed, if fw on flash is < 4.0.554 */ + crbinit_fix_fw = NETXEN_VERSION_CODE(4, 0, 554); + if (file_fw_ver >= crbinit_fix_fw && flash_fw_ver < crbinit_fix_fw && + NX_IS_REVISION_P3(adapter->ahw.revision_id)) { + dev_err(&pdev->dev, "Incompatibility detected between driver " + "and firmware version on flash. This configuration " + "is not recommended. Please update the firmware on " + "flash immediately\n"); return -EINVAL; } + /* check if flashed firmware is newer only for no-mn and P2 case*/ + if (!netxen_p3_has_mn(adapter) || + NX_IS_REVISION_P2(adapter->ahw.revision_id)) { + if (flash_fw_ver > file_fw_ver) { + dev_info(&pdev->dev, "%s: firmware is older than flash\n", + fw_name[fw_type]); + return -EINVAL; + } + } + NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); return 0; } diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 30f41e62049a..f574edff7fcb 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1388,6 +1388,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } + err = netxen_check_flash_fw_compatibility(adapter); + if (err) + goto err_out_iounmap; + if (adapter->portnum == 0) { val = NXRD32(adapter, NX_CRB_DEV_REF_COUNT); if (val != 0xffffffff && val != 0) { diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index d3afb458987e..e736aec588fc 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -430,10 +430,6 @@ struct ns83820 { struct pci_dev *pci_dev; struct net_device *ndev; -#ifdef NS83820_VLAN_ACCEL_SUPPORT - struct vlan_group *vlgrp; -#endif - struct rx_info rx_info; struct tasklet_struct rx_tasklet; @@ -494,22 +490,6 @@ static inline void kick_rx(struct net_device *ndev) #define start_tx_okay(dev) \ (((NR_TX_DESC-2 + dev->tx_done_idx - dev->tx_free_idx) % NR_TX_DESC) > MIN_TX_DESC_FREE) - -#ifdef NS83820_VLAN_ACCEL_SUPPORT -static void ns83820_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp) -{ - struct ns83820 *dev = PRIV(ndev); - - spin_lock_irq(&dev->misc_lock); - spin_lock(&dev->tx_lock); - - dev->vlgrp = grp; - - spin_unlock(&dev->tx_lock); - spin_unlock_irq(&dev->misc_lock); -} -#endif - /* Packet Receiver * * The hardware supports linked lists of receive descriptors for @@ -930,14 +910,12 @@ static void rx_irq(struct net_device *ndev) #ifdef NS83820_VLAN_ACCEL_SUPPORT if(extsts & EXTSTS_VPKT) { unsigned short tag; + tag = ntohs(extsts & EXTSTS_VTG_MASK); - rx_rc = vlan_hwaccel_rx(skb,dev->vlgrp,tag); - } else { - rx_rc = netif_rx(skb); + __vlan_hwaccel_put_tag(skb, tag); } -#else - rx_rc = netif_rx(skb); #endif + rx_rc = netif_rx(skb); if (NET_RX_DROP == rx_rc) { netdev_mangle_me_harder_failed: ndev->stats.rx_dropped++; @@ -1961,11 +1939,8 @@ static const struct net_device_ops netdev_ops = { .ndo_change_mtu = ns83820_change_mtu, .ndo_set_multicast_list = ns83820_set_multicast, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_tx_timeout = ns83820_tx_timeout, -#ifdef NS83820_VLAN_ACCEL_SUPPORT - .ndo_vlan_rx_register = ns83820_vlan_rx_register, -#endif }; static int __devinit ns83820_init_one(struct pci_dev *pci_dev, diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 718879b35b7d..bc9a4bb31980 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -348,8 +348,9 @@ static int pppoe_device_event(struct notifier_block *this, /* Only look at sockets that are using this specific device. */ switch (event) { + case NETDEV_CHANGEADDR: case NETDEV_CHANGEMTU: - /* A change in mtu is a bad thing, requiring + /* A change in mtu or address is a bad thing, requiring * LCP re-negotiation. */ diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 3579229db4a9..5ca1b562443c 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -4198,18 +4198,13 @@ static void qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) { struct qlcnic_adapter *adapter = netdev_priv(netdev); - struct vlan_group *grp; struct net_device *dev; u16 vid; qlcnic_config_indev_addr(adapter, netdev, event); - grp = rcu_dereference_rtnl(netdev->vlgrp); - if (!grp) - return; - for_each_set_bit(vid, adapter->vlans, VLAN_N_VID) { - dev = vlan_group_get_device(grp, vid); + dev = __vlan_find_dev_deep(netdev, vid); if (!dev) continue; qlcnic_config_indev_addr(adapter, dev, event); diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 794252c0aedd..8731f79c9efc 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -11,6 +11,7 @@ #include <linux/pci.h> #include <linux/netdevice.h> #include <linux/rtnetlink.h> +#include <linux/if_vlan.h> /* * General definitions... @@ -2052,7 +2053,7 @@ struct ql_adapter { struct nic_stats nic_stats; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; /* PCI Configuration information for this device */ struct pci_dev *pdev; diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 68fbfac7a3bf..743e3ec729c2 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -7,6 +7,7 @@ */ #include <linux/kernel.h> #include <linux/init.h> +#include <linux/bitops.h> #include <linux/types.h> #include <linux/module.h> #include <linux/list.h> @@ -33,6 +34,7 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> +#include <linux/if_vlan.h> #include <linux/skbuff.h> #include <linux/if_vlan.h> #include <linux/delay.h> @@ -415,7 +417,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type, (qdev-> func << CAM_OUT_FUNC_SHIFT) | (0 << CAM_OUT_CQ_ID_SHIFT)); - if (qdev->vlgrp) + if (qdev->ndev->features & NETIF_F_HW_VLAN_RX) cam_output |= CAM_OUT_RV; /* route to NIC core */ ql_write32(qdev, MAC_ADDR_DATA, cam_output); @@ -1507,10 +1509,9 @@ static void ql_process_mac_rx_gro_page(struct ql_adapter *qdev, rx_ring->rx_bytes += length; skb->ip_summed = CHECKSUM_UNNECESSARY; skb_record_rx_queue(skb, rx_ring->cq_id); - if (qdev->vlgrp && (vlan_id != 0xffff)) - vlan_gro_frags(&rx_ring->napi, qdev->vlgrp, vlan_id); - else - napi_gro_frags(napi); + if (vlan_id != 0xffff) + __vlan_hwaccel_put_tag(skb, vlan_id); + napi_gro_frags(napi); } /* Process an inbound completion from an rx ring. */ @@ -1594,17 +1595,12 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, } skb_record_rx_queue(skb, rx_ring->cq_id); - if (skb->ip_summed == CHECKSUM_UNNECESSARY) { - if (qdev->vlgrp && (vlan_id != 0xffff)) - vlan_gro_receive(napi, qdev->vlgrp, vlan_id, skb); - else - napi_gro_receive(napi, skb); - } else { - if (qdev->vlgrp && (vlan_id != 0xffff)) - vlan_hwaccel_receive_skb(skb, qdev->vlgrp, vlan_id); - else - netif_receive_skb(skb); - } + if (vlan_id != 0xffff) + __vlan_hwaccel_put_tag(skb, vlan_id); + if (skb->ip_summed == CHECKSUM_UNNECESSARY) + napi_gro_receive(napi, skb); + else + netif_receive_skb(skb); return; err_out: dev_kfree_skb_any(skb); @@ -1707,18 +1703,12 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev, } skb_record_rx_queue(skb, rx_ring->cq_id); - if (skb->ip_summed == CHECKSUM_UNNECESSARY) { - if (qdev->vlgrp && (vlan_id != 0xffff)) - vlan_gro_receive(&rx_ring->napi, qdev->vlgrp, - vlan_id, skb); - else - napi_gro_receive(&rx_ring->napi, skb); - } else { - if (qdev->vlgrp && (vlan_id != 0xffff)) - vlan_hwaccel_receive_skb(skb, qdev->vlgrp, vlan_id); - else - netif_receive_skb(skb); - } + if (vlan_id != 0xffff) + __vlan_hwaccel_put_tag(skb, vlan_id); + if (skb->ip_summed == CHECKSUM_UNNECESSARY) + napi_gro_receive(&rx_ring->napi, skb); + else + netif_receive_skb(skb); } static void ql_realign_skb(struct sk_buff *skb, int len) @@ -2028,22 +2018,12 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev, rx_ring->rx_packets++; rx_ring->rx_bytes += skb->len; skb_record_rx_queue(skb, rx_ring->cq_id); - if (skb->ip_summed == CHECKSUM_UNNECESSARY) { - if (qdev->vlgrp && - (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) && - (vlan_id != 0)) - vlan_gro_receive(&rx_ring->napi, qdev->vlgrp, - vlan_id, skb); - else - napi_gro_receive(&rx_ring->napi, skb); - } else { - if (qdev->vlgrp && - (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) && - (vlan_id != 0)) - vlan_hwaccel_receive_skb(skb, qdev->vlgrp, vlan_id); - else - netif_receive_skb(skb); - } + if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) && (vlan_id != 0)) + __vlan_hwaccel_put_tag(skb, vlan_id); + if (skb->ip_summed == CHECKSUM_UNNECESSARY) + napi_gro_receive(&rx_ring->napi, skb); + else + netif_receive_skb(skb); } /* Process an inbound completion from an rx ring. */ @@ -2334,71 +2314,111 @@ static int ql_napi_poll_msix(struct napi_struct *napi, int budget) return work_done; } -static void qlge_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp) +static void qlge_vlan_mode(struct net_device *ndev, u32 features) { struct ql_adapter *qdev = netdev_priv(ndev); - qdev->vlgrp = grp; - if (grp) { - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, + if (features & NETIF_F_HW_VLAN_RX) { + netif_printk(qdev, ifup, KERN_DEBUG, ndev, "Turning on VLAN in NIC_RCV_CFG.\n"); ql_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK | - NIC_RCV_CFG_VLAN_MATCH_AND_NON); + NIC_RCV_CFG_VLAN_MATCH_AND_NON); } else { - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, + netif_printk(qdev, ifup, KERN_DEBUG, ndev, "Turning off VLAN in NIC_RCV_CFG.\n"); ql_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK); } } -static void qlge_vlan_rx_add_vid(struct net_device *ndev, u16 vid) +static u32 qlge_fix_features(struct net_device *ndev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int qlge_set_features(struct net_device *ndev, u32 features) +{ + u32 changed = ndev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + qlge_vlan_mode(ndev, features); + + return 0; +} + +static void __qlge_vlan_rx_add_vid(struct ql_adapter *qdev, u16 vid) { - struct ql_adapter *qdev = netdev_priv(ndev); u32 enable_bit = MAC_ADDR_E; - int status; - status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); - if (status) - return; if (ql_set_mac_addr_reg (qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) { netif_err(qdev, ifup, qdev->ndev, "Failed to init vlan address.\n"); } - ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); } -static void qlge_vlan_rx_kill_vid(struct net_device *ndev, u16 vid) +static void qlge_vlan_rx_add_vid(struct net_device *ndev, u16 vid) { struct ql_adapter *qdev = netdev_priv(ndev); - u32 enable_bit = 0; int status; status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); if (status) return; + __qlge_vlan_rx_add_vid(qdev, vid); + set_bit(vid, qdev->active_vlans); + + ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); +} + +static void __qlge_vlan_rx_kill_vid(struct ql_adapter *qdev, u16 vid) +{ + u32 enable_bit = 0; + if (ql_set_mac_addr_reg (qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) { netif_err(qdev, ifup, qdev->ndev, "Failed to clear vlan address.\n"); } - ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); +} + +static void qlge_vlan_rx_kill_vid(struct net_device *ndev, u16 vid) +{ + struct ql_adapter *qdev = netdev_priv(ndev); + int status; + + status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); + if (status) + return; + + __qlge_vlan_rx_kill_vid(qdev, vid); + clear_bit(vid, qdev->active_vlans); + ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); } static void qlge_restore_vlan(struct ql_adapter *qdev) { - qlge_vlan_rx_register(qdev->ndev, qdev->vlgrp); + int status; + u16 vid; - if (qdev->vlgrp) { - u16 vid; - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(qdev->vlgrp, vid)) - continue; - qlge_vlan_rx_add_vid(qdev->ndev, vid); - } - } + status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); + if (status) + return; + + for_each_set_bit(vid, qdev->active_vlans, VLAN_N_VID) + __qlge_vlan_rx_add_vid(qdev, vid); + + ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); } /* MSI-X Multiple Vector Interrupt Handler for inbound completions. */ @@ -4661,7 +4681,8 @@ static const struct net_device_ops qlge_netdev_ops = { .ndo_set_mac_address = qlge_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_tx_timeout = qlge_tx_timeout, - .ndo_vlan_rx_register = qlge_vlan_rx_register, + .ndo_fix_features = qlge_fix_features, + .ndo_set_features = qlge_set_features, .ndo_vlan_rx_add_vid = qlge_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = qlge_vlan_rx_kill_vid, }; diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 00f06e9a7796..b64fcee483aa 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -677,9 +677,11 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id) if (status & RX_FIFO_FULL) dev->stats.rx_fifo_errors++; - /* Mask off RX interrupt */ - misr &= ~RX_INTS; - napi_schedule(&lp->napi); + if (likely(napi_schedule_prep(&lp->napi))) { + /* Mask off RX interrupt */ + misr &= ~RX_INTS; + __napi_schedule(&lp->napi); + } } /* TX interrupt request */ diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 3ddd33936aa7..40bcb82d9116 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -435,6 +435,7 @@ enum rtl_register_content { AcceptMulticast = 0x04, AcceptMyPhys = 0x02, AcceptAllPhys = 0x01, +#define RX_CONFIG_ACCEPT_MASK 0x3f /* TxConfigBits */ TxInterFrameGapShift = 24, @@ -3943,11 +3944,8 @@ err_pm_runtime_put: static void rtl_rx_close(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - u32 rxcfg = RTL_R32(RxConfig); - rxcfg &= ~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast | - AcceptMyPhys | AcceptAllPhys); - RTL_W32(RxConfig, rxcfg); + RTL_W32(RxConfig, RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK); } static void rtl8169_hw_reset(struct rtl8169_private *tp) @@ -5586,7 +5584,7 @@ static void rtl_set_rx_mode(struct net_device *dev) spin_lock_irqsave(&tp->lock, flags); - tmp = RTL_R32(RxConfig) | rx_mode; + tmp = (RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode; if (tp->mac_version > RTL_GIGA_MAC_VER_06) { u32 data = mc_filter[0]; diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 043850b8c304..277d48b0800a 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -356,56 +356,6 @@ static void do_s2io_copy_mac_addr(struct s2io_nic *sp, int offset, u64 mac_addr) sp->def_mac_addr[offset].mac_addr[0] = (u8) (mac_addr >> 40); } -/* Add the vlan */ -static void s2io_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) -{ - int i; - struct s2io_nic *nic = netdev_priv(dev); - unsigned long flags[MAX_TX_FIFOS]; - struct config_param *config = &nic->config; - struct mac_info *mac_control = &nic->mac_control; - - for (i = 0; i < config->tx_fifo_num; i++) { - struct fifo_info *fifo = &mac_control->fifos[i]; - - spin_lock_irqsave(&fifo->tx_lock, flags[i]); - } - - nic->vlgrp = grp; - - for (i = config->tx_fifo_num - 1; i >= 0; i--) { - struct fifo_info *fifo = &mac_control->fifos[i]; - - spin_unlock_irqrestore(&fifo->tx_lock, flags[i]); - } -} - -/* Unregister the vlan */ -static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) -{ - int i; - struct s2io_nic *nic = netdev_priv(dev); - unsigned long flags[MAX_TX_FIFOS]; - struct config_param *config = &nic->config; - struct mac_info *mac_control = &nic->mac_control; - - for (i = 0; i < config->tx_fifo_num; i++) { - struct fifo_info *fifo = &mac_control->fifos[i]; - - spin_lock_irqsave(&fifo->tx_lock, flags[i]); - } - - if (nic->vlgrp) - vlan_group_set_device(nic->vlgrp, vid, NULL); - - for (i = config->tx_fifo_num - 1; i >= 0; i--) { - struct fifo_info *fifo = &mac_control->fifos[i]; - - spin_unlock_irqrestore(&fifo->tx_lock, flags[i]); - } -} - /* * Constants to be programmed into the Xena's registers, to configure * the XAUI. @@ -7737,8 +7687,6 @@ static const struct net_device_ops s2io_netdev_ops = { .ndo_set_mac_address = s2io_set_mac_addr, .ndo_change_mtu = s2io_change_mtu, .ndo_set_features = s2io_set_features, - .ndo_vlan_rx_register = s2io_vlan_rx_register, - .ndo_vlan_rx_kill_vid = s2io_vlan_rx_kill_vid, .ndo_tx_timeout = s2io_tx_watchdog, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = s2io_netpoll, @@ -8617,18 +8565,12 @@ static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag) struct s2io_nic *sp = netdev_priv(dev); skb->protocol = eth_type_trans(skb, dev); - if (sp->vlgrp && vlan_tag && (sp->vlan_strip_flag)) { - /* Queueing the vlan frame to the upper layer */ - if (sp->config.napi) - vlan_hwaccel_receive_skb(skb, sp->vlgrp, vlan_tag); - else - vlan_hwaccel_rx(skb, sp->vlgrp, vlan_tag); - } else { - if (sp->config.napi) - netif_receive_skb(skb); - else - netif_rx(skb); - } + if (vlan_tag && sp->vlan_strip_flag) + __vlan_hwaccel_put_tag(skb, vlan_tag); + if (sp->config.napi) + netif_receive_skb(skb); + else + netif_rx(skb); } static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 800b3a44e653..ae3c8e79b32f 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -939,7 +939,6 @@ struct s2io_nic { int task_flag; unsigned long long start_time; - struct vlan_group *vlgrp; int vlan_strip_flag; #define MSIX_FLG 0xA5 int num_entries; diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 8befe697bd76..f11b3f3df24f 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -807,7 +807,6 @@ static int slip_open(struct tty_struct *tty) sl->tty = tty; tty->disc_data = sl; - sl->line = tty_devnum(tty); sl->pid = current->pid; if (!test_bit(SLF_INUSE, &sl->flags)) { @@ -874,8 +873,6 @@ static void slip_close(struct tty_struct *tty) tty->disc_data = NULL; sl->tty = NULL; - if (!sl->leased) - sl->line = 0; /* VSV = very important to remove timers */ #ifdef CONFIG_SLIP_SMART diff --git a/drivers/net/slip.h b/drivers/net/slip.h index 914e958abbfc..aa0764ce2342 100644 --- a/drivers/net/slip.h +++ b/drivers/net/slip.h @@ -90,7 +90,6 @@ struct slip { unsigned char mode; /* SLIP mode */ unsigned char leased; - dev_t line; pid_t pid; #define SL_MODE_SLIP 0 #define SL_MODE_CSLIP 1 diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 9bc6c20e8b97..1ff3491c8240 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1004,9 +1004,7 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, } if (data_status & SPIDER_NET_VLAN_PACKET) { - /* further enhancements: HW-accel VLAN - * vlan_hwaccel_receive_skb - */ + /* further enhancements: HW-accel VLAN */ } /* update netdevice statistics */ diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 860a50815f84..7ae1f990a98e 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -561,7 +561,7 @@ struct netdev_private { struct net_device *dev; struct pci_dev *pci_dev; #ifdef VLAN_SUPPORT - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; #endif void *queue_mem; dma_addr_t queue_mem_dma; @@ -607,18 +607,6 @@ static const struct ethtool_ops ethtool_ops; #ifdef VLAN_SUPPORT -static void netdev_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct netdev_private *np = netdev_priv(dev); - - spin_lock(&np->lock); - if (debug > 2) - printk("%s: Setting vlgrp to %p\n", dev->name, grp); - np->vlgrp = grp; - set_rx_mode(dev); - spin_unlock(&np->lock); -} - static void netdev_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { struct netdev_private *np = netdev_priv(dev); @@ -626,6 +614,7 @@ static void netdev_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) spin_lock(&np->lock); if (debug > 1) printk("%s: Adding vlanid %d to vlan filter\n", dev->name, vid); + set_bit(vid, np->active_vlans); set_rx_mode(dev); spin_unlock(&np->lock); } @@ -637,7 +626,7 @@ static void netdev_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) spin_lock(&np->lock); if (debug > 1) printk("%s: removing vlanid %d from vlan filter\n", dev->name, vid); - vlan_group_set_device(np->vlgrp, vid, NULL); + clear_bit(vid, np->active_vlans); set_rx_mode(dev); spin_unlock(&np->lock); } @@ -648,15 +637,14 @@ static const struct net_device_ops netdev_ops = { .ndo_open = netdev_open, .ndo_stop = netdev_close, .ndo_start_xmit = start_tx, - .ndo_tx_timeout = tx_timeout, - .ndo_get_stats = get_stats, + .ndo_tx_timeout = tx_timeout, + .ndo_get_stats = get_stats, .ndo_set_multicast_list = &set_rx_mode, - .ndo_do_ioctl = netdev_ioctl, + .ndo_do_ioctl = netdev_ioctl, .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, #ifdef VLAN_SUPPORT - .ndo_vlan_rx_register = netdev_vlan_rx_register, .ndo_vlan_rx_add_vid = netdev_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = netdev_vlan_rx_kill_vid, #endif @@ -1528,21 +1516,17 @@ static int __netdev_rx(struct net_device *dev, int *quota) printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2)); } #ifdef VLAN_SUPPORT - if (np->vlgrp && le16_to_cpu(desc->status2) & 0x0200) { + if (le16_to_cpu(desc->status2) & 0x0200) { u16 vlid = le16_to_cpu(desc->vlanid); if (debug > 4) { printk(KERN_DEBUG " netdev_rx() vlanid = %d\n", vlid); } - /* - * vlan_hwaccel_rx expects a packet with the VLAN tag - * stripped out. - */ - vlan_hwaccel_rx(skb, np->vlgrp, vlid); - } else + __vlan_hwaccel_put_tag(skb, vlid); + } #endif /* VLAN_SUPPORT */ - netif_receive_skb(skb); + netif_receive_skb(skb); dev->stats.rx_packets++; next_rx: @@ -1752,6 +1736,32 @@ static struct net_device_stats *get_stats(struct net_device *dev) return &dev->stats; } +#ifdef VLAN_SUPPORT +static u32 set_vlan_mode(struct netdev_private *np) +{ + u32 ret = VlanMode; + u16 vid; + void __iomem *filter_addr = np->base + HashTable + 8; + int vlan_count = 0; + + for_each_set_bit(vid, np->active_vlans, VLAN_N_VID) { + if (vlan_count == 32) + break; + writew(vid, filter_addr); + filter_addr += 16; + vlan_count++; + } + if (vlan_count == 32) { + ret |= PerfectFilterVlan; + while (vlan_count < 32) { + writew(0, filter_addr); + filter_addr += 16; + vlan_count++; + } + } + return ret; +} +#endif /* VLAN_SUPPORT */ static void set_rx_mode(struct net_device *dev) { @@ -1760,30 +1770,9 @@ static void set_rx_mode(struct net_device *dev) u32 rx_mode = MinVLANPrio; struct netdev_hw_addr *ha; int i; -#ifdef VLAN_SUPPORT - rx_mode |= VlanMode; - if (np->vlgrp) { - int vlan_count = 0; - void __iomem *filter_addr = ioaddr + HashTable + 8; - for (i = 0; i < VLAN_VID_MASK; i++) { - if (vlan_group_get_device(np->vlgrp, i)) { - if (vlan_count >= 32) - break; - writew(i, filter_addr); - filter_addr += 16; - vlan_count++; - } - } - if (i == VLAN_VID_MASK) { - rx_mode |= PerfectFilterVlan; - while (vlan_count < 32) { - writew(0, filter_addr); - filter_addr += 16; - vlan_count++; - } - } - } +#ifdef VLAN_SUPPORT + rx_mode |= set_vlan_mode(np); #endif /* VLAN_SUPPORT */ if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index 2b076b313622..de1929b2641b 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -20,7 +20,7 @@ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> *******************************************************************************/ -#define DRV_MODULE_VERSION "Nov_2010" +#define DRV_MODULE_VERSION "July_2011" #include <linux/stmmac.h> #include "common.h" @@ -56,14 +56,9 @@ struct stmmac_priv { struct stmmac_extra_stats xstats; struct napi_struct napi; - phy_interface_t phy_interface; - int phy_addr; - int phy_mask; - int (*phy_reset) (void *priv); int rx_coe; int no_csum_insertion; - int phy_irq; struct phy_device *phydev; int oldlink; int speed; @@ -71,6 +66,7 @@ struct stmmac_priv { unsigned int flow_ctrl; unsigned int pause; struct mii_bus *mii; + int mii_irq[PHY_MAX_ADDR]; u32 msg_enable; spinlock_t lock; @@ -79,9 +75,6 @@ struct stmmac_priv { #ifdef CONFIG_STMMAC_TIMER struct stmmac_timer *tm; #endif -#ifdef STMMAC_VLAN_TAG_USED - struct vlan_group *vlgrp; -#endif struct plat_stmmacenet_data *plat; }; diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index d37ebc80623a..c6e567e04eff 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -49,7 +49,6 @@ #include "stmmac.h" #define STMMAC_RESOURCE_NAME "stmmaceth" -#define PHY_RESOURCE_NAME "stmmacphy" #undef STMMAC_DEBUG /*#define STMMAC_DEBUG*/ @@ -305,18 +304,13 @@ static int stmmac_init_phy(struct net_device *dev) priv->speed = 0; priv->oldduplex = -1; - if (priv->phy_addr == -1) { - /* We don't have a PHY, so do nothing */ - return 0; - } - snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id); snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, - priv->phy_addr); + priv->plat->phy_addr); pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id); phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0, - priv->phy_interface); + priv->plat->interface); if (IS_ERR(phydev)) { pr_err("%s: Could not attach to PHY\n", dev->name); @@ -335,7 +329,7 @@ static int stmmac_init_phy(struct net_device *dev) return -ENODEV; } pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" - " Link = %d\n", dev->name, phydev->phy_id, phydev->link); + " Link = %d\n", dev->name, phydev->phy_id, phydev->link); priv->phydev = phydev; @@ -1421,20 +1415,6 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return ret; } -#ifdef STMMAC_VLAN_TAG_USED -static void stmmac_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) -{ - struct stmmac_priv *priv = netdev_priv(dev); - - DBG(probe, INFO, "%s: Setting vlgrp to %p\n", dev->name, grp); - - spin_lock(&priv->lock); - priv->vlgrp = grp; - spin_unlock(&priv->lock); -} -#endif - static const struct net_device_ops stmmac_netdev_ops = { .ndo_open = stmmac_open, .ndo_start_xmit = stmmac_xmit, @@ -1445,9 +1425,6 @@ static const struct net_device_ops stmmac_netdev_ops = { .ndo_tx_timeout = stmmac_tx_timeout, .ndo_do_ioctl = stmmac_ioctl, .ndo_set_config = stmmac_config, -#ifdef STMMAC_VLAN_TAG_USED - .ndo_vlan_rx_register = stmmac_vlan_rx_register, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = stmmac_poll_controller, #endif @@ -1545,71 +1522,6 @@ static int stmmac_mac_device_setup(struct net_device *dev) return 0; } -static int stmmacphy_dvr_probe(struct platform_device *pdev) -{ - struct plat_stmmacphy_data *plat_dat = pdev->dev.platform_data; - - pr_debug("stmmacphy_dvr_probe: added phy for bus %d\n", - plat_dat->bus_id); - - return 0; -} - -static int stmmacphy_dvr_remove(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver stmmacphy_driver = { - .driver = { - .name = PHY_RESOURCE_NAME, - }, - .probe = stmmacphy_dvr_probe, - .remove = stmmacphy_dvr_remove, -}; - -/** - * stmmac_associate_phy - * @dev: pointer to device structure - * @data: points to the private structure. - * Description: Scans through all the PHYs we have registered and checks if - * any are associated with our MAC. If so, then just fill in - * the blanks in our local context structure - */ -static int stmmac_associate_phy(struct device *dev, void *data) -{ - struct stmmac_priv *priv = (struct stmmac_priv *)data; - struct plat_stmmacphy_data *plat_dat = dev->platform_data; - - DBG(probe, DEBUG, "%s: checking phy for bus %d\n", __func__, - plat_dat->bus_id); - - /* Check that this phy is for the MAC being initialised */ - if (priv->plat->bus_id != plat_dat->bus_id) - return 0; - - /* OK, this PHY is connected to the MAC. - Go ahead and get the parameters */ - DBG(probe, DEBUG, "%s: OK. Found PHY config\n", __func__); - priv->phy_irq = - platform_get_irq_byname(to_platform_device(dev), "phyirq"); - DBG(probe, DEBUG, "%s: PHY irq on bus %d is %d\n", __func__, - plat_dat->bus_id, priv->phy_irq); - - /* Override with kernel parameters if supplied XXX CRS XXX - * this needs to have multiple instances */ - if ((phyaddr >= 0) && (phyaddr <= 31)) - plat_dat->phy_addr = phyaddr; - - priv->phy_addr = plat_dat->phy_addr; - priv->phy_mask = plat_dat->phy_mask; - priv->phy_interface = plat_dat->interface; - priv->phy_reset = plat_dat->phy_reset; - - DBG(probe, DEBUG, "%s: exiting\n", __func__); - return 1; /* forces exit of driver_for_each_device() */ -} - /** * stmmac_dvr_probe * @pdev: platform device pointer @@ -1700,14 +1612,10 @@ static int stmmac_dvr_probe(struct platform_device *pdev) if (ret < 0) goto out_plat_exit; - /* associate a PHY - it is provided by another platform bus */ - if (!driver_for_each_device - (&(stmmacphy_driver.driver), NULL, (void *)priv, - stmmac_associate_phy)) { - pr_err("No PHY device is associated with this MAC!\n"); - ret = -ENODEV; - goto out_unregister; - } + /* Override with kernel parameters if supplied XXX CRS XXX + * this needs to have multiple instances */ + if ((phyaddr >= 0) && (phyaddr <= 31)) + priv->plat->phy_addr = phyaddr; pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n" "\tIO base addr: 0x%p)\n", ndev->name, pdev->name, @@ -1907,11 +1815,6 @@ static int __init stmmac_init_module(void) { int ret; - if (platform_driver_register(&stmmacphy_driver)) { - pr_err("No PHY devices registered!\n"); - return -ENODEV; - } - ret = platform_driver_register(&stmmac_driver); return ret; } @@ -1922,7 +1825,6 @@ static int __init stmmac_init_module(void) */ static void __exit stmmac_cleanup_module(void) { - platform_driver_unregister(&stmmacphy_driver); platform_driver_unregister(&stmmac_driver); } @@ -1934,33 +1836,52 @@ static int __init stmmac_cmdline_opt(char *str) if (!str || !*str) return -EINVAL; while ((opt = strsep(&str, ",")) != NULL) { - if (!strncmp(opt, "debug:", 6)) - strict_strtoul(opt + 6, 0, (unsigned long *)&debug); - else if (!strncmp(opt, "phyaddr:", 8)) - strict_strtoul(opt + 8, 0, (unsigned long *)&phyaddr); - else if (!strncmp(opt, "dma_txsize:", 11)) - strict_strtoul(opt + 11, 0, - (unsigned long *)&dma_txsize); - else if (!strncmp(opt, "dma_rxsize:", 11)) - strict_strtoul(opt + 11, 0, - (unsigned long *)&dma_rxsize); - else if (!strncmp(opt, "buf_sz:", 7)) - strict_strtoul(opt + 7, 0, (unsigned long *)&buf_sz); - else if (!strncmp(opt, "tc:", 3)) - strict_strtoul(opt + 3, 0, (unsigned long *)&tc); - else if (!strncmp(opt, "watchdog:", 9)) - strict_strtoul(opt + 9, 0, (unsigned long *)&watchdog); - else if (!strncmp(opt, "flow_ctrl:", 10)) - strict_strtoul(opt + 10, 0, - (unsigned long *)&flow_ctrl); - else if (!strncmp(opt, "pause:", 6)) - strict_strtoul(opt + 6, 0, (unsigned long *)&pause); + if (!strncmp(opt, "debug:", 6)) { + if (strict_strtoul(opt + 6, 0, (unsigned long *)&debug)) + goto err; + } else if (!strncmp(opt, "phyaddr:", 8)) { + if (strict_strtoul(opt + 8, 0, + (unsigned long *)&phyaddr)) + goto err; + } else if (!strncmp(opt, "dma_txsize:", 11)) { + if (strict_strtoul(opt + 11, 0, + (unsigned long *)&dma_txsize)) + goto err; + } else if (!strncmp(opt, "dma_rxsize:", 11)) { + if (strict_strtoul(opt + 11, 0, + (unsigned long *)&dma_rxsize)) + goto err; + } else if (!strncmp(opt, "buf_sz:", 7)) { + if (strict_strtoul(opt + 7, 0, + (unsigned long *)&buf_sz)) + goto err; + } else if (!strncmp(opt, "tc:", 3)) { + if (strict_strtoul(opt + 3, 0, (unsigned long *)&tc)) + goto err; + } else if (!strncmp(opt, "watchdog:", 9)) { + if (strict_strtoul(opt + 9, 0, + (unsigned long *)&watchdog)) + goto err; + } else if (!strncmp(opt, "flow_ctrl:", 10)) { + if (strict_strtoul(opt + 10, 0, + (unsigned long *)&flow_ctrl)) + goto err; + } else if (!strncmp(opt, "pause:", 6)) { + if (strict_strtoul(opt + 6, 0, (unsigned long *)&pause)) + goto err; #ifdef CONFIG_STMMAC_TIMER - else if (!strncmp(opt, "tmrate:", 7)) - strict_strtoul(opt + 7, 0, (unsigned long *)&tmrate); + } else if (!strncmp(opt, "tmrate:", 7)) { + if (strict_strtoul(opt + 7, 0, + (unsigned long *)&tmrate)) + goto err; #endif + } } return 0; + +err: + pr_err("%s: ERROR broken module parameter conversion", __func__); + return -EINVAL; } __setup("stmmaceth=", stmmac_cmdline_opt); diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c index 29a6bb6b8058..9c3b9d5c3411 100644 --- a/drivers/net/stmmac/stmmac_mdio.c +++ b/drivers/net/stmmac/stmmac_mdio.c @@ -113,9 +113,9 @@ static int stmmac_mdio_reset(struct mii_bus *bus) struct stmmac_priv *priv = netdev_priv(ndev); unsigned int mii_address = priv->hw->mii.addr; - if (priv->phy_reset) { + if (priv->plat->mdio_bus_data->phy_reset) { pr_debug("stmmac_mdio_reset: calling phy_reset\n"); - priv->phy_reset(priv->plat->bsp_priv); + priv->plat->mdio_bus_data->phy_reset(priv->plat->bsp_priv); } /* This is a workaround for problems with the STE101P PHY. @@ -138,30 +138,29 @@ int stmmac_mdio_register(struct net_device *ndev) struct mii_bus *new_bus; int *irqlist; struct stmmac_priv *priv = netdev_priv(ndev); + struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data; int addr, found; + if (!mdio_bus_data) + return 0; + new_bus = mdiobus_alloc(); if (new_bus == NULL) return -ENOMEM; - irqlist = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); - if (irqlist == NULL) { - err = -ENOMEM; - goto irqlist_alloc_fail; - } - - /* Assign IRQ to phy at address phy_addr */ - if (priv->phy_addr != -1) - irqlist[priv->phy_addr] = priv->phy_irq; + if (mdio_bus_data->irqs) + irqlist = mdio_bus_data->irqs; + else + irqlist = priv->mii_irq; new_bus->name = "STMMAC MII Bus"; new_bus->read = &stmmac_mdio_read; new_bus->write = &stmmac_mdio_write; new_bus->reset = &stmmac_mdio_reset; - snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id); + snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", mdio_bus_data->bus_id); new_bus->priv = ndev; new_bus->irq = irqlist; - new_bus->phy_mask = priv->phy_mask; + new_bus->phy_mask = mdio_bus_data->phy_mask; new_bus->parent = priv->device; err = mdiobus_register(new_bus); if (err != 0) { @@ -172,18 +171,50 @@ int stmmac_mdio_register(struct net_device *ndev) priv->mii = new_bus; found = 0; - for (addr = 0; addr < 32; addr++) { + for (addr = 0; addr < PHY_MAX_ADDR; addr++) { struct phy_device *phydev = new_bus->phy_map[addr]; if (phydev) { - if (priv->phy_addr == -1) { - priv->phy_addr = addr; - phydev->irq = priv->phy_irq; - irqlist[addr] = priv->phy_irq; + int act = 0; + char irq_num[4]; + char *irq_str; + + /* + * If an IRQ was provided to be assigned after + * the bus probe, do it here. + */ + if ((mdio_bus_data->irqs == NULL) && + (mdio_bus_data->probed_phy_irq > 0)) { + irqlist[addr] = mdio_bus_data->probed_phy_irq; + phydev->irq = mdio_bus_data->probed_phy_irq; } - pr_info("%s: PHY ID %08x at %d IRQ %d (%s)%s\n", - ndev->name, phydev->phy_id, addr, - phydev->irq, dev_name(&phydev->dev), - (addr == priv->phy_addr) ? " active" : ""); + + /* + * If we're going to bind the MAC to this PHY bus, + * and no PHY number was provided to the MAC, + * use the one probed here. + */ + if ((priv->plat->bus_id == mdio_bus_data->bus_id) && + (priv->plat->phy_addr == -1)) + priv->plat->phy_addr = addr; + + act = (priv->plat->bus_id == mdio_bus_data->bus_id) && + (priv->plat->phy_addr == addr); + switch (phydev->irq) { + case PHY_POLL: + irq_str = "POLL"; + break; + case PHY_IGNORE_INTERRUPT: + irq_str = "IGNORE"; + break; + default: + sprintf(irq_num, "%d", phydev->irq); + irq_str = irq_num; + break; + } + pr_info("%s: PHY ID %08x at %d IRQ %s (%s)%s\n", + ndev->name, phydev->phy_id, addr, + irq_str, dev_name(&phydev->dev), + act ? " active" : ""); found = 1; } } @@ -192,10 +223,9 @@ int stmmac_mdio_register(struct net_device *ndev) pr_warning("%s: No PHY found\n", ndev->name); return 0; + bus_register_fail: - kfree(irqlist); -irqlist_alloc_fail: - kfree(new_bus); + mdiobus_free(new_bus); return err; } @@ -210,7 +240,8 @@ int stmmac_mdio_unregister(struct net_device *ndev) mdiobus_unregister(priv->mii); priv->mii->priv = NULL; - kfree(priv->mii); + mdiobus_free(priv->mii); + priv->mii = NULL; return 0; } diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 80fbee0d40af..749bbf18dc6a 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -742,22 +742,6 @@ static void bdx_vlan_rx_kill_vid(struct net_device *ndev, unsigned short vid) __bdx_vlan_rx_vid(ndev, vid, 0); } -/* - * bdx_vlan_rx_register - kernel hook for adding VLAN group - * @ndev network device - * @grp VLAN group - */ -static void -bdx_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp) -{ - struct bdx_priv *priv = netdev_priv(ndev); - - ENTER; - DBG("device='%s', group='%p'\n", ndev->name, grp); - priv->vlgrp = grp; - RET(); -} - /** * bdx_change_mtu - Change the Maximum Transfer Unit * @netdev: network interface device structure @@ -1146,21 +1130,15 @@ NETIF_RX_MUX(struct bdx_priv *priv, u32 rxd_val1, u16 rxd_vlan, struct sk_buff *skb) { ENTER; - DBG("rxdd->flags.bits.vtag=%d vlgrp=%p\n", GET_RXD_VTAG(rxd_val1), - priv->vlgrp); - if (priv->vlgrp && GET_RXD_VTAG(rxd_val1)) { - DBG("%s: vlan rcv vlan '%x' vtag '%x', device name '%s'\n", + DBG("rxdd->flags.bits.vtag=%d\n", GET_RXD_VTAG(rxd_val1)); + if (GET_RXD_VTAG(rxd_val1)) { + DBG("%s: vlan rcv vlan '%x' vtag '%x'\n", priv->ndev->name, GET_RXD_VLAN_ID(rxd_vlan), - GET_RXD_VTAG(rxd_val1), - vlan_group_get_device(priv->vlgrp, - GET_RXD_VLAN_ID(rxd_vlan))->name); - /* NAPI variant of receive functions */ - vlan_hwaccel_receive_skb(skb, priv->vlgrp, - GET_RXD_VLAN_TCI(rxd_vlan)); - } else { - netif_receive_skb(skb); + GET_RXD_VTAG(rxd_val1)); + __vlan_hwaccel_put_tag(skb, GET_RXD_VLAN_TCI(rxd_vlan)); } + netif_receive_skb(skb); } static void bdx_recycle_skb(struct bdx_priv *priv, struct rxd_desc *rxdd) @@ -1877,7 +1855,7 @@ static void bdx_tx_push_desc_safe(struct bdx_priv *priv, void *data, int size) } static const struct net_device_ops bdx_netdev_ops = { - .ndo_open = bdx_open, + .ndo_open = bdx_open, .ndo_stop = bdx_close, .ndo_start_xmit = bdx_tx_transmit, .ndo_validate_addr = eth_validate_addr, @@ -1885,7 +1863,6 @@ static const struct net_device_ops bdx_netdev_ops = { .ndo_set_multicast_list = bdx_setmulti, .ndo_change_mtu = bdx_change_mtu, .ndo_set_mac_address = bdx_set_mac, - .ndo_vlan_rx_register = bdx_vlan_rx_register, .ndo_vlan_rx_add_vid = bdx_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = bdx_vlan_rx_kill_vid, }; diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h index c5642fefc9e7..709ebd6e28b4 100644 --- a/drivers/net/tehuti.h +++ b/drivers/net/tehuti.h @@ -250,7 +250,6 @@ struct bdx_priv { struct rxf_fifo rxf_fifo0; struct rxdb *rxdb; /* rx dbs to store skb pointers */ int napi_stop; - struct vlan_group *vlgrp; /* Tx FIFOs: 1 for data desc, 1 for empty (acks) desc */ struct txd_fifo txd_fifo0; diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a5ff82d3b750..803576568154 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1858,6 +1858,12 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) } if (!tp->setlpicnt) { + if (current_link_up == 1 && + !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { + tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000); + TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); + } + val = tr32(TG3_CPMU_EEE_MODE); tw32(TG3_CPMU_EEE_MODE, val & ~TG3_CPMU_EEEMD_LPI_ENABLE); } @@ -1872,7 +1878,9 @@ static void tg3_phy_eee_enable(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) && !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { - tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0003); + val = MII_TG3_DSP_TAP26_ALNOKO | + MII_TG3_DSP_TAP26_RMRXSTO; + tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); } @@ -3128,20 +3136,6 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) if (!err) { u32 err2; - switch (GET_ASIC_REV(tp->pci_chip_rev_id)) { - case ASIC_REV_5717: - case ASIC_REV_57765: - if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val)) - tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val | - MII_TG3_DSP_CH34TP2_HIBW01); - /* Fall through */ - case ASIC_REV_5719: - val = MII_TG3_DSP_TAP26_ALNOKO | - MII_TG3_DSP_TAP26_RMRXSTO | - MII_TG3_DSP_TAP26_OPCSINPT; - tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); - } - val = 0; /* Advertise 100-BaseTX EEE ability */ if (advertise & ADVERTISED_100baseT_Full) @@ -3150,6 +3144,25 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) if (advertise & ADVERTISED_1000baseT_Full) val |= MDIO_AN_EEE_ADV_1000T; err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); + if (err) + val = 0; + + switch (GET_ASIC_REV(tp->pci_chip_rev_id)) { + case ASIC_REV_5717: + case ASIC_REV_57765: + case ASIC_REV_5719: + /* If we advertised any eee advertisements above... */ + if (val) + val = MII_TG3_DSP_TAP26_ALNOKO | + MII_TG3_DSP_TAP26_RMRXSTO | + MII_TG3_DSP_TAP26_OPCSINPT; + tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); + /* Fall through */ + case ASIC_REV_5720: + if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val)) + tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val | + MII_TG3_DSP_CH34TP2_HIBW01); + } err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); if (!err) @@ -7412,16 +7425,11 @@ static int tg3_chip_reset(struct tg3 *tp) tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); } - if (tg3_flag(tp, ENABLE_APE)) - tp->mac_mode = MAC_MODE_APE_TX_EN | - MAC_MODE_APE_RX_EN | - MAC_MODE_TDE_ENABLE; - if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { - tp->mac_mode |= MAC_MODE_PORT_MODE_TBI; + tp->mac_mode = MAC_MODE_PORT_MODE_TBI; val = tp->mac_mode; } else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) { - tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; + tp->mac_mode = MAC_MODE_PORT_MODE_GMII; val = tp->mac_mode; } else val = 0; @@ -8559,12 +8567,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) udelay(10); } - if (tg3_flag(tp, ENABLE_APE)) - tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; - else - tp->mac_mode = 0; tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | - MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE; + MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | + MAC_MODE_FHDE_ENABLE; + if (tg3_flag(tp, ENABLE_APE)) + tp->mac_mode |= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; if (!tg3_flag(tp, 5705_PLUS) && !(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) @@ -8716,15 +8723,24 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) udelay(100); if (tg3_flag(tp, ENABLE_RSS)) { + int i = 0; u32 reg = MAC_RSS_INDIR_TBL_0; - u8 *ent = (u8 *)&val; - /* Setup the indirection table */ - for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) { - int idx = i % sizeof(val); + if (tp->irq_cnt == 2) { + for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i += 8) { + tw32(reg, 0x0); + reg += 4; + } + } else { + u32 val; - ent[idx] = i % (tp->irq_cnt - 1); - if (idx == sizeof(val) - 1) { + while (i < TG3_RSS_INDIR_TBL_SIZE) { + val = i % (tp->irq_cnt - 1); + i++; + for (; i % 8; i++) { + val <<= 4; + val |= (i % (tp->irq_cnt - 1)); + } tw32(reg, val); reg += 4; } @@ -9167,7 +9183,7 @@ static int tg3_test_interrupt(struct tg3 *tp) * Turn off MSI one shot mode. Otherwise this test has no * observable way to know whether the interrupt was delivered. */ - if (tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) { + if (tg3_flag(tp, 57765_PLUS)) { val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE; tw32(MSGINT_MODE, val); } @@ -9195,6 +9211,10 @@ static int tg3_test_interrupt(struct tg3 *tp) break; } + if (tg3_flag(tp, 57765_PLUS) && + tnapi->hw_status->status_tag != tnapi->last_tag) + tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24); + msleep(10); } @@ -9209,7 +9229,7 @@ static int tg3_test_interrupt(struct tg3 *tp) if (intr_ok) { /* Reenable MSI one shot mode. */ - if (tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) { + if (tg3_flag(tp, 57765_PLUS)) { val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE; tw32(MSGINT_MODE, val); } @@ -10553,7 +10573,7 @@ static void tg3_get_ethtool_stats(struct net_device *dev, memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); } -static __be32 * tg3_vpd_readblock(struct tg3 *tp) +static __be32 *tg3_vpd_readblock(struct tg3 *tp, u32 *vpdlen) { int i; __be32 *buf; @@ -10620,6 +10640,8 @@ static __be32 * tg3_vpd_readblock(struct tg3 *tp) goto error; } + *vpdlen = len; + return buf; error: @@ -10633,13 +10655,13 @@ error: #define NVRAM_SELFBOOT_FORMAT1_3_SIZE 0x1c #define NVRAM_SELFBOOT_FORMAT1_4_SIZE 0x20 #define NVRAM_SELFBOOT_FORMAT1_5_SIZE 0x24 -#define NVRAM_SELFBOOT_FORMAT1_6_SIZE 0x4c +#define NVRAM_SELFBOOT_FORMAT1_6_SIZE 0x50 #define NVRAM_SELFBOOT_HW_SIZE 0x20 #define NVRAM_SELFBOOT_DATA_SIZE 0x1c static int tg3_test_nvram(struct tg3 *tp) { - u32 csum, magic; + u32 csum, magic, len; __be32 *buf; int i, j, k, err = 0, size; @@ -10780,18 +10802,17 @@ static int tg3_test_nvram(struct tg3 *tp) kfree(buf); - buf = tg3_vpd_readblock(tp); + buf = tg3_vpd_readblock(tp, &len); if (!buf) return -ENOMEM; - i = pci_vpd_find_tag((u8 *)buf, 0, TG3_NVM_VPD_LEN, - PCI_VPD_LRDT_RO_DATA); + i = pci_vpd_find_tag((u8 *)buf, 0, len, PCI_VPD_LRDT_RO_DATA); if (i > 0) { j = pci_vpd_lrdt_size(&((u8 *)buf)[i]); if (j < 0) goto out; - if (i + PCI_VPD_LRDT_TAG_SIZE + j > TG3_NVM_VPD_LEN) + if (i + PCI_VPD_LRDT_TAG_SIZE + j > len) goto out; i += PCI_VPD_LRDT_TAG_SIZE; @@ -13135,7 +13156,9 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) } if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && - ((tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 && + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 || + (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 && tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) || (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && tp->pci_chip_rev_id != CHIPREV_ID_57765_A0))) @@ -13187,14 +13210,14 @@ static void __devinit tg3_read_vpd(struct tg3 *tp) { u8 *vpd_data; unsigned int block_end, rosize, len; + u32 vpdlen; int j, i = 0; - vpd_data = (u8 *)tg3_vpd_readblock(tp); + vpd_data = (u8 *)tg3_vpd_readblock(tp, &vpdlen); if (!vpd_data) goto out_no_vpd; - i = pci_vpd_find_tag(vpd_data, 0, TG3_NVM_VPD_LEN, - PCI_VPD_LRDT_RO_DATA); + i = pci_vpd_find_tag(vpd_data, 0, vpdlen, PCI_VPD_LRDT_RO_DATA); if (i < 0) goto out_not_found; @@ -13202,7 +13225,7 @@ static void __devinit tg3_read_vpd(struct tg3 *tp) block_end = i + PCI_VPD_LRDT_TAG_SIZE + rosize; i += PCI_VPD_LRDT_TAG_SIZE; - if (block_end > TG3_NVM_VPD_LEN) + if (block_end > vpdlen) goto out_not_found; j = pci_vpd_find_info_keyword(vpd_data, i, rosize, @@ -13227,7 +13250,7 @@ static void __devinit tg3_read_vpd(struct tg3 *tp) goto partno; memcpy(tp->fw_ver, &vpd_data[j], len); - strncat(tp->fw_ver, " bc ", TG3_NVM_VPD_LEN - len - 1); + strncat(tp->fw_ver, " bc ", vpdlen - len - 1); } partno: @@ -13240,7 +13263,7 @@ partno: i += PCI_VPD_INFO_FLD_HDR_SIZE; if (len > TG3_BPN_SIZE || - (len + i) > TG3_NVM_VPD_LEN) + (len + i) > vpdlen) goto out_not_found; memcpy(tp->board_part_number, &vpd_data[i], len); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 6a43fc51d870..691539ba17b3 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2180,7 +2180,7 @@ #define MII_TG3_DSP_TAP26_OPCSINPT 0x0004 #define MII_TG3_DSP_AADJ1CH0 0x001f #define MII_TG3_DSP_CH34TP2 0x4022 -#define MII_TG3_DSP_CH34TP2_HIBW01 0x017b +#define MII_TG3_DSP_CH34TP2_HIBW01 0x01ff #define MII_TG3_DSP_AADJ1CH3 0x601f #define MII_TG3_DSP_AADJ1CH3_ADCCKADJ 0x0002 #define MII_TG3_DSP_EXP1_INT_STAT 0x0f01 diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 468512731966..9a21ca3873fc 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -879,7 +879,6 @@ static void dmfe_free_tx_pkt(struct DEVICE *dev, struct dmfe_board_info * db) txptr = db->tx_remove_ptr; while(db->tx_packet_cnt) { tdes0 = le32_to_cpu(txptr->tdes0); - pr_debug("tdes0=%x\n", tdes0); if (tdes0 & 0x80000000) break; @@ -889,7 +888,6 @@ static void dmfe_free_tx_pkt(struct DEVICE *dev, struct dmfe_board_info * db) /* Transmit statistic counter */ if ( tdes0 != 0x7fffffff ) { - pr_debug("tdes0=%x\n", tdes0); dev->stats.collisions += (tdes0 >> 3) & 0xf; dev->stats.tx_bytes += le32_to_cpu(txptr->tdes1) & 0x7ff; if (tdes0 & TDES0_ERR_MASK) { @@ -986,7 +984,6 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) /* error summary bit check */ if (rdes0 & 0x8000) { /* This is a error packet */ - pr_debug("rdes0: %x\n", rdes0); dev->stats.rx_errors++; if (rdes0 & 1) dev->stats.rx_fifo_errors++; @@ -1638,7 +1635,6 @@ static u8 dmfe_sense_speed(struct dmfe_board_info * db) else /* DM9102/DM9102A */ phy_mode = phy_read(db->ioaddr, db->phy_addr, 17, db->chip_id) & 0xf000; - pr_debug("Phy_mode %x\n", phy_mode); switch (phy_mode) { case 0x1000: db->op_mode = DMFE_10MHF; break; case 0x2000: db->op_mode = DMFE_10MFD; break; diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 6998aa6b7bb7..52502883523e 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -1502,6 +1502,10 @@ static const struct usb_device_id products [] = { USB_DEVICE (0x04f1, 0x3008), .driver_info = (unsigned long) &ax8817x_info, }, { + // ASIX AX88772B 10/100 + USB_DEVICE (0x0b95, 0x772b), + .driver_info = (unsigned long) &ax88772_info, +}, { // ASIX AX88772 10/100 USB_DEVICE (0x0b95, 0x7720), .driver_info = (unsigned long) &ax88772_info, diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index f92924283d3b..a9aa4a3fbfbe 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -45,6 +45,7 @@ #include <linux/module.h> #include <linux/types.h> +#include <linux/bitops.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/errno.h> @@ -76,6 +77,7 @@ #include <linux/udp.h> #include <linux/crc-ccitt.h> #include <linux/crc32.h> +#include <linux/if_vlan.h> #include "via-velocity.h" @@ -501,6 +503,7 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index, static void velocity_init_cam_filter(struct velocity_info *vptr) { struct mac_regs __iomem *regs = vptr->mac_regs; + unsigned int vid, i = 0; /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */ WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, ®s->MCFG); @@ -513,30 +516,17 @@ static void velocity_init_cam_filter(struct velocity_info *vptr) mac_set_cam_mask(regs, vptr->mCAMmask); /* Enable VCAMs */ - if (vptr->vlgrp) { - unsigned int vid, i = 0; - - if (!vlan_group_get_device(vptr->vlgrp, 0)) - WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); - - for (vid = 1; (vid < VLAN_VID_MASK); vid++) { - if (vlan_group_get_device(vptr->vlgrp, vid)) { - mac_set_vlan_cam(regs, i, (u8 *) &vid); - vptr->vCAMmask[i / 8] |= 0x1 << (i % 8); - if (++i >= VCAM_SIZE) - break; - } - } - mac_set_vlan_cam_mask(regs, vptr->vCAMmask); - } -} -static void velocity_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) -{ - struct velocity_info *vptr = netdev_priv(dev); + if (test_bit(0, vptr->active_vlans)) + WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); - vptr->vlgrp = grp; + for_each_set_bit(vid, vptr->active_vlans, VLAN_N_VID) { + mac_set_vlan_cam(regs, i, (u8 *) &vid); + vptr->vCAMmask[i / 8] |= 0x1 << (i % 8); + if (++i >= VCAM_SIZE) + break; + } + mac_set_vlan_cam_mask(regs, vptr->vCAMmask); } static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) @@ -544,6 +534,7 @@ static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) struct velocity_info *vptr = netdev_priv(dev); spin_lock_irq(&vptr->lock); + set_bit(vid, vptr->active_vlans); velocity_init_cam_filter(vptr); spin_unlock_irq(&vptr->lock); } @@ -553,7 +544,7 @@ static void velocity_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid struct velocity_info *vptr = netdev_priv(dev); spin_lock_irq(&vptr->lock); - vlan_group_set_device(vptr->vlgrp, vid, NULL); + clear_bit(vid, vptr->active_vlans); velocity_init_cam_filter(vptr); spin_unlock_irq(&vptr->lock); } @@ -2094,11 +2085,12 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx) skb_put(skb, pkt_len - 4); skb->protocol = eth_type_trans(skb, vptr->dev); - if (vptr->vlgrp && (rd->rdesc0.RSR & RSR_DETAG)) { - vlan_hwaccel_rx(skb, vptr->vlgrp, - swab16(le16_to_cpu(rd->rdesc1.PQTAG))); - } else - netif_rx(skb); + if (rd->rdesc0.RSR & RSR_DETAG) { + u16 vid = swab16(le16_to_cpu(rd->rdesc1.PQTAG)); + + __vlan_hwaccel_put_tag(skb, vid); + } + netif_rx(skb); stats->rx_bytes += pkt_len; @@ -2641,7 +2633,6 @@ static const struct net_device_ops velocity_netdev_ops = { .ndo_do_ioctl = velocity_ioctl, .ndo_vlan_rx_add_vid = velocity_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = velocity_vlan_rx_kill_vid, - .ndo_vlan_rx_register = velocity_vlan_rx_register, }; /** diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h index 0f1f05f6c4f8..4cb9f13485e9 100644 --- a/drivers/net/via-velocity.h +++ b/drivers/net/via-velocity.h @@ -1437,7 +1437,7 @@ struct velocity_info { struct pci_dev *pdev; struct net_device *dev; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u8 ip_addr[4]; enum chip_type chip_id; diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index fbea637eb742..0c7321c35ad4 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -705,14 +705,6 @@ static void virtnet_netpoll(struct net_device *dev) } #endif -static void virtnet_free(struct net_device *dev) -{ - struct virtnet_info *vi = netdev_priv(dev); - - free_percpu(vi->stats); - free_netdev(dev); -} - static int virtnet_open(struct net_device *dev) { struct virtnet_info *vi = netdev_priv(dev); @@ -959,7 +951,6 @@ static int virtnet_probe(struct virtio_device *vdev) /* Set up network device as normal. */ dev->netdev_ops = &virtnet_netdev; dev->features = NETIF_F_HIGHDMA; - dev->destructor = virtnet_free; SET_ETHTOOL_OPS(dev, &virtnet_ethtool_ops); SET_NETDEV_DEV(dev, &vdev->dev); @@ -1122,6 +1113,7 @@ static void __devexit virtnet_remove(struct virtio_device *vdev) while (vi->pages) __free_pages(get_a_page(vi, GFP_KERNEL), 0); + free_percpu(vi->stats); free_netdev(vi->dev); } diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 009277e1084f..1cbacb389652 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2647,7 +2647,7 @@ vmxnet3_declare_features(struct vmxnet3_adapter *adapter, bool dma64) NETIF_F_HW_VLAN_RX | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_LRO; if (dma64) - netdev->features |= NETIF_F_HIGHDMA; + netdev->hw_features |= NETIF_F_HIGHDMA; netdev->vlan_features = netdev->hw_features & ~(NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_FILTER; @@ -2993,6 +2993,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, goto err_ver; } + SET_NETDEV_DEV(netdev, &pdev->dev); vmxnet3_declare_features(adapter, dma64); adapter->dev_number = atomic_read(&devices_found); @@ -3038,7 +3039,6 @@ vmxnet3_probe_device(struct pci_dev *pdev, netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); netif_set_real_num_rx_queues(adapter->netdev, adapter->num_rx_queues); - SET_NETDEV_DEV(netdev, &pdev->dev); err = register_netdev(netdev); if (err) { diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 15d878b4547c..178348a258d2 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -43,6 +43,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/bitops.h> #include <linux/if_vlan.h> #include <linux/interrupt.h> #include <linux/pci.h> @@ -308,13 +309,10 @@ vxge_rx_complete(struct vxge_ring *ring, struct sk_buff *skb, u16 vlan, "%s: %s:%d skb protocol = %d", ring->ndev->name, __func__, __LINE__, skb->protocol); - if (ring->vlgrp && ext_info->vlan && - (ring->vlan_tag_strip == - VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE)) - vlan_gro_receive(ring->napi_p, ring->vlgrp, - ext_info->vlan, skb); - else - napi_gro_receive(ring->napi_p, skb); + if (ext_info->vlan && + ring->vlan_tag_strip == VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE) + __vlan_hwaccel_put_tag(skb, ext_info->vlan); + napi_gro_receive(ring->napi_p, skb); vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__); @@ -1489,15 +1487,11 @@ vxge_restore_vpath_vid_table(struct vxge_vpath *vpath) struct vxgedev *vdev = vpath->vdev; u16 vid; - if (vdev->vlgrp && vpath->is_open) { + if (!vpath->is_open) + return status; - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(vdev->vlgrp, vid)) - continue; - /* Add these vlan to the vid table */ - status = vxge_hw_vpath_vid_add(vpath->handle, vid); - } - } + for_each_set_bit(vid, vdev->active_vlans, VLAN_N_VID) + status = vxge_hw_vpath_vid_add(vpath->handle, vid); return status; } @@ -3303,60 +3297,6 @@ static void vxge_tx_watchdog(struct net_device *dev) } /** - * vxge_vlan_rx_register - * @dev: net device pointer. - * @grp: vlan group - * - * Vlan group registration - */ -static void -vxge_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct vxgedev *vdev; - struct vxge_vpath *vpath; - int vp; - u64 vid; - enum vxge_hw_status status; - int i; - - vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - - vdev = netdev_priv(dev); - - vpath = &vdev->vpaths[0]; - if ((NULL == grp) && (vpath->is_open)) { - /* Get the first vlan */ - status = vxge_hw_vpath_vid_get(vpath->handle, &vid); - - while (status == VXGE_HW_OK) { - - /* Delete this vlan from the vid table */ - for (vp = 0; vp < vdev->no_of_vpath; vp++) { - vpath = &vdev->vpaths[vp]; - if (!vpath->is_open) - continue; - - vxge_hw_vpath_vid_delete(vpath->handle, vid); - } - - /* Get the next vlan to be deleted */ - vpath = &vdev->vpaths[0]; - status = vxge_hw_vpath_vid_get(vpath->handle, &vid); - } - } - - vdev->vlgrp = grp; - - for (i = 0; i < vdev->no_of_vpath; i++) { - if (vdev->vpaths[i].is_configured) - vdev->vpaths[i].ring.vlgrp = grp; - } - - vxge_debug_entryexit(VXGE_TRACE, - "%s:%d Exiting...", __func__, __LINE__); -} - -/** * vxge_vlan_rx_add_vid * @dev: net device pointer. * @vid: vid @@ -3366,12 +3306,10 @@ vxge_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) static void vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { - struct vxgedev *vdev; + struct vxgedev *vdev = netdev_priv(dev); struct vxge_vpath *vpath; int vp_id; - vdev = netdev_priv(dev); - /* Add these vlan to the vid table */ for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) { vpath = &vdev->vpaths[vp_id]; @@ -3379,6 +3317,7 @@ vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) continue; vxge_hw_vpath_vid_add(vpath->handle, vid); } + set_bit(vid, vdev->active_vlans); } /** @@ -3391,16 +3330,12 @@ vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) static void vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) { - struct vxgedev *vdev; + struct vxgedev *vdev = netdev_priv(dev); struct vxge_vpath *vpath; int vp_id; vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - vdev = netdev_priv(dev); - - vlan_group_set_device(vdev->vlgrp, vid, NULL); - /* Delete this vlan from the vid table */ for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) { vpath = &vdev->vpaths[vp_id]; @@ -3410,6 +3345,7 @@ vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) } vxge_debug_entryexit(VXGE_TRACE, "%s:%d Exiting...", __func__, __LINE__); + clear_bit(vid, vdev->active_vlans); } static const struct net_device_ops vxge_netdev_ops = { @@ -3424,7 +3360,6 @@ static const struct net_device_ops vxge_netdev_ops = { .ndo_change_mtu = vxge_change_mtu, .ndo_fix_features = vxge_fix_features, .ndo_set_features = vxge_set_features, - .ndo_vlan_rx_register = vxge_vlan_rx_register, .ndo_vlan_rx_kill_vid = vxge_vlan_rx_kill_vid, .ndo_vlan_rx_add_vid = vxge_vlan_rx_add_vid, .ndo_tx_timeout = vxge_tx_watchdog, diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index 66e6de86ff0c..f52a42d1dbb7 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -18,6 +18,8 @@ #include "vxge-config.h" #include "vxge-version.h" #include <linux/list.h> +#include <linux/bitops.h> +#include <linux/if_vlan.h> #define VXGE_DRIVER_NAME "vxge" #define VXGE_DRIVER_VENDOR "Neterion, Inc" @@ -287,7 +289,6 @@ struct vxge_ring { #define VXGE_MAX_MAC_ADDR_COUNT 30 int vlan_tag_strip; - struct vlan_group *vlgrp; u32 rx_vector_no; enum vxge_hw_status last_status; @@ -332,7 +333,7 @@ struct vxgedev { struct net_device *ndev; struct pci_dev *pdev; struct __vxge_hw_device *devh; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; int vlan_tag_strip; struct vxge_config config; unsigned long state; diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index d3cee33e554c..26a4110eeb2d 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -720,7 +720,7 @@ struct qeth_card { wait_queue_head_t wait_q; spinlock_t vlanlock; spinlock_t mclock; - struct vlan_group *vlangrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; struct list_head vid_list; struct list_head mc_list; struct work_struct kernel_thread_starter; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index dd08f7b42fb8..4550573c25e5 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1097,7 +1097,6 @@ static int qeth_setup_card(struct qeth_card *card) card->dev = NULL; spin_lock_init(&card->vlanlock); spin_lock_init(&card->mclock); - card->vlangrp = NULL; spin_lock_init(&card->lock); spin_lock_init(&card->ip_lock); spin_lock_init(&card->thread_mask_lock); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index e2c9ac5fcb36..fafb8c299540 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -13,6 +13,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/bitops.h> #include <linux/string.h> #include <linux/errno.h> #include <linux/kernel.h> @@ -23,6 +24,7 @@ #include <linux/inetdevice.h> #include <linux/igmp.h> #include <linux/slab.h> +#include <linux/if_vlan.h> #include <net/ip.h> #include <net/arp.h> @@ -1696,16 +1698,18 @@ static void qeth_l3_add_mc(struct qeth_card *card, struct in_device *in4_dev) static void qeth_l3_add_vlan_mc(struct qeth_card *card) { struct in_device *in_dev; - struct vlan_group *vg; - int i; + u16 vid; QETH_CARD_TEXT(card, 4, "addmcvl"); - if (!qeth_is_supported(card, IPA_FULL_VLAN) || (card->vlangrp == NULL)) + if (!qeth_is_supported(card, IPA_FULL_VLAN)) return; - vg = card->vlangrp; - for (i = 0; i < VLAN_N_VID; i++) { - struct net_device *netdev = vlan_group_get_device(vg, i); + for_each_set_bit(vid, card->active_vlans, VLAN_N_VID) { + struct net_device *netdev; + + rcu_read_lock(); + netdev = __vlan_find_dev_deep(card->dev, vid); + rcu_read_unlock(); if (netdev == NULL || !(netdev->flags & IFF_UP)) continue; @@ -1759,16 +1763,16 @@ static void qeth_l3_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev) static void qeth_l3_add_vlan_mc6(struct qeth_card *card) { struct inet6_dev *in_dev; - struct vlan_group *vg; - int i; + u16 vid; QETH_CARD_TEXT(card, 4, "admc6vl"); - if (!qeth_is_supported(card, IPA_FULL_VLAN) || (card->vlangrp == NULL)) + if (!qeth_is_supported(card, IPA_FULL_VLAN)) return; - vg = card->vlangrp; - for (i = 0; i < VLAN_N_VID; i++) { - struct net_device *netdev = vlan_group_get_device(vg, i); + for_each_set_bit(vid, card->active_vlans, VLAN_N_VID) { + struct net_device *netdev; + + netdev = __vlan_find_dev_deep(card->dev, vid); if (netdev == NULL || !(netdev->flags & IFF_UP)) continue; @@ -1806,10 +1810,12 @@ static void qeth_l3_free_vlan_addresses4(struct qeth_card *card, struct in_device *in_dev; struct in_ifaddr *ifa; struct qeth_ipaddr *addr; + struct net_device *netdev; QETH_CARD_TEXT(card, 4, "frvaddr4"); - in_dev = in_dev_get(vlan_group_get_device(card->vlangrp, vid)); + netdev = __vlan_find_dev_deep(card->dev, vid); + in_dev = in_dev_get(netdev); if (!in_dev) return; for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { @@ -1832,10 +1838,12 @@ static void qeth_l3_free_vlan_addresses6(struct qeth_card *card, struct inet6_dev *in6_dev; struct inet6_ifaddr *ifa; struct qeth_ipaddr *addr; + struct net_device *netdev; QETH_CARD_TEXT(card, 4, "frvaddr6"); - in6_dev = in6_dev_get(vlan_group_get_device(card->vlangrp, vid)); + netdev = __vlan_find_dev_deep(card->dev, vid); + in6_dev = in6_dev_get(netdev); if (!in6_dev) return; list_for_each_entry(ifa, &in6_dev->addr_list, if_list) { @@ -1856,26 +1864,15 @@ static void qeth_l3_free_vlan_addresses6(struct qeth_card *card, static void qeth_l3_free_vlan_addresses(struct qeth_card *card, unsigned short vid) { - if (!card->vlangrp) - return; qeth_l3_free_vlan_addresses4(card, vid); qeth_l3_free_vlan_addresses6(card, vid); } -static void qeth_l3_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) +static void qeth_l3_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { struct qeth_card *card = dev->ml_priv; - unsigned long flags; - - QETH_CARD_TEXT(card, 4, "vlanreg"); - spin_lock_irqsave(&card->vlanlock, flags); - card->vlangrp = grp; - spin_unlock_irqrestore(&card->vlanlock, flags); -} -static void qeth_l3_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) -{ + set_bit(vid, card->active_vlans); return; } @@ -1892,7 +1889,7 @@ static void qeth_l3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) spin_lock_irqsave(&card->vlanlock, flags); /* unregister IP addresses of vlan device */ qeth_l3_free_vlan_addresses(card, vid); - vlan_group_set_device(card->vlangrp, vid, NULL); + clear_bit(vid, card->active_vlans); spin_unlock_irqrestore(&card->vlanlock, flags); qeth_l3_set_multicast_list(card->dev); } @@ -2014,10 +2011,8 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card, &vlan_tag); len = skb->len; if (is_vlan && !card->options.sniffer) - vlan_gro_receive(&card->napi, card->vlangrp, - vlan_tag, skb); - else - napi_gro_receive(&card->napi, skb); + __vlan_hwaccel_put_tag(skb, vlan_tag); + napi_gro_receive(&card->napi, skb); break; case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */ skb->pkt_type = PACKET_HOST; @@ -2118,15 +2113,15 @@ static int qeth_l3_verify_vlan_dev(struct net_device *dev, struct qeth_card *card) { int rc = 0; - struct vlan_group *vg; - int i; + u16 vid; - vg = card->vlangrp; - if (!vg) - return rc; + for_each_set_bit(vid, card->active_vlans, VLAN_N_VID) { + struct net_device *netdev; - for (i = 0; i < VLAN_N_VID; i++) { - if (vlan_group_get_device(vg, i) == dev) { + rcu_read_lock(); + netdev = __vlan_find_dev_deep(dev, vid); + rcu_read_unlock(); + if (netdev == dev) { rc = QETH_VLAN_CARD; break; } @@ -2803,7 +2798,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, * before we're going to overwrite this location with next hop ip. * v6 uses passthrough, v4 sets the tag in the QDIO header. */ - if (card->vlangrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { if ((ipv == 4) || (card->info.type == QETH_CARD_TYPE_IQD)) hdr->hdr.l3.ext_flags = QETH_HDR_EXT_VLAN_FRAME; else @@ -2988,8 +2983,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) skb_pull(new_skb, ETH_HLEN); } - if (ipv != 4 && card->vlangrp && - vlan_tx_tag_present(new_skb)) { + if (ipv != 4 && vlan_tx_tag_present(new_skb)) { skb_push(new_skb, VLAN_HLEN); skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4); skb_copy_to_linear_data_offset(new_skb, 4, @@ -3233,14 +3227,13 @@ static const struct net_device_ops qeth_l3_netdev_ops = { .ndo_start_xmit = qeth_l3_hard_start_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = qeth_l3_set_multicast_list, - .ndo_do_ioctl = qeth_l3_do_ioctl, - .ndo_change_mtu = qeth_change_mtu, - .ndo_fix_features = qeth_l3_fix_features, - .ndo_set_features = qeth_l3_set_features, - .ndo_vlan_rx_register = qeth_l3_vlan_rx_register, + .ndo_do_ioctl = qeth_l3_do_ioctl, + .ndo_change_mtu = qeth_change_mtu, + .ndo_fix_features = qeth_l3_fix_features, + .ndo_set_features = qeth_l3_set_features, .ndo_vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid, - .ndo_tx_timeout = qeth_tx_timeout, + .ndo_tx_timeout = qeth_tx_timeout, }; static const struct net_device_ops qeth_l3_osa_netdev_ops = { @@ -3250,14 +3243,13 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = { .ndo_start_xmit = qeth_l3_hard_start_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = qeth_l3_set_multicast_list, - .ndo_do_ioctl = qeth_l3_do_ioctl, - .ndo_change_mtu = qeth_change_mtu, - .ndo_fix_features = qeth_l3_fix_features, - .ndo_set_features = qeth_l3_set_features, - .ndo_vlan_rx_register = qeth_l3_vlan_rx_register, + .ndo_do_ioctl = qeth_l3_do_ioctl, + .ndo_change_mtu = qeth_change_mtu, + .ndo_fix_features = qeth_l3_fix_features, + .ndo_set_features = qeth_l3_set_features, .ndo_vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid, - .ndo_tx_timeout = qeth_tx_timeout, + .ndo_tx_timeout = qeth_tx_timeout, .ndo_neigh_setup = qeth_l3_neigh_setup, }; diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 7a16ca1c3ecf..9eebaebdaa78 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -767,17 +767,23 @@ static void bnx2fc_destroy_timer(unsigned long data) * * @context: adapter structure pointer * @event: event type + * @vlan_id: vlan id - associated vlan id with this event * * Handles NETDEV_UP, NETDEV_DOWN, NETDEV_GOING_DOWN,NETDEV_CHANGE and * NETDEV_CHANGE_MTU events */ -static void bnx2fc_indicate_netevent(void *context, unsigned long event) +static void bnx2fc_indicate_netevent(void *context, unsigned long event, + u16 vlan_id) { struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context; struct fc_lport *lport = hba->ctlr.lp; struct fc_lport *vport; u32 link_possible = 1; + /* Ignore vlans for now */ + if (vlan_id != 0) + return; + if (!test_bit(BNX2FC_CREATE_DONE, &hba->init_done)) { BNX2FC_MISC_DBG("driver not ready. event=%s %ld\n", hba->netdev->name, event); diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index 5c54a2d9b834..372d30c099cc 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -2386,14 +2386,20 @@ static void bnx2i_indicate_kcqe(void *context, struct kcqe *kcqe[], * bnx2i_indicate_netevent - Generic netdev event handler * @context: adapter structure pointer * @event: event type + * @vlan_id: vlans id - associated vlan id with this event * * Handles four netdev events, NETDEV_UP, NETDEV_DOWN, * NETDEV_GOING_DOWN and NETDEV_CHANGE */ -static void bnx2i_indicate_netevent(void *context, unsigned long event) +static void bnx2i_indicate_netevent(void *context, unsigned long event, + u16 vlan_id) { struct bnx2i_hba *hba = context; + /* Ignore all netevent coming from vlans */ + if (vlan_id != 0) + return; + switch (event) { case NETDEV_UP: if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state)) diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c index b25bae29042e..95555d25fcb3 100644 --- a/drivers/staging/et131x/et131x_netdev.c +++ b/drivers/staging/et131x/et131x_netdev.c @@ -97,7 +97,6 @@ int et131x_tx(struct sk_buff *skb, struct net_device *netdev); void et131x_tx_timeout(struct net_device *netdev); int et131x_change_mtu(struct net_device *netdev, int new_mtu); int et131x_set_mac_addr(struct net_device *netdev, void *new_mac); -void et131x_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); void et131x_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); void et131x_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 9536d386bb38..21d816e9dfa5 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -599,8 +599,7 @@ config IT87_WDT config HP_WATCHDOG tristate "HP ProLiant iLO2+ Hardware Watchdog Timer" - depends on X86 - default m + depends on X86 && PCI help A software monitoring watchdog and NMI sourcing driver. This driver will detect lockups and provide a stack trace. This is a driver that diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 79743d146be6..0c1d91756528 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1438,12 +1438,15 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, struct dentry *temp; char *path; int len, pos; + unsigned seq; if (dentry == NULL) return ERR_PTR(-EINVAL); retry: len = 0; + seq = read_seqbegin(&rename_lock); + rcu_read_lock(); for (temp = dentry; !IS_ROOT(temp);) { struct inode *inode = temp->d_inode; if (inode && ceph_snap(inode) == CEPH_SNAPDIR) @@ -1455,10 +1458,12 @@ retry: len += 1 + temp->d_name.len; temp = temp->d_parent; if (temp == NULL) { + rcu_read_unlock(); pr_err("build_path corrupt dentry %p\n", dentry); return ERR_PTR(-EINVAL); } } + rcu_read_unlock(); if (len) len--; /* no leading '/' */ @@ -1467,9 +1472,12 @@ retry: return ERR_PTR(-ENOMEM); pos = len; path[pos] = 0; /* trailing null */ + rcu_read_lock(); for (temp = dentry; !IS_ROOT(temp) && pos != 0; ) { - struct inode *inode = temp->d_inode; + struct inode *inode; + spin_lock(&temp->d_lock); + inode = temp->d_inode; if (inode && ceph_snap(inode) == CEPH_SNAPDIR) { dout("build_path path+%d: %p SNAPDIR\n", pos, temp); @@ -1478,21 +1486,26 @@ retry: break; } else { pos -= temp->d_name.len; - if (pos < 0) + if (pos < 0) { + spin_unlock(&temp->d_lock); break; + } strncpy(path + pos, temp->d_name.name, temp->d_name.len); } + spin_unlock(&temp->d_lock); if (pos) path[--pos] = '/'; temp = temp->d_parent; if (temp == NULL) { + rcu_read_unlock(); pr_err("build_path corrupt dentry\n"); kfree(path); return ERR_PTR(-EINVAL); } } - if (pos != 0) { + rcu_read_unlock(); + if (pos != 0 || read_seqretry(&rename_lock, seq)) { pr_err("build_path did not end path lookup where " "expected, namelen is %d, pos is %d\n", len, pos); /* presumably this is only possible if racing with a diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 3e2989976297..bc4b12ca537b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -35,6 +35,7 @@ #include <linux/delay.h> #include <linux/kthread.h> #include <linux/freezer.h> +#include <linux/namei.h> #include <net/ipv6.h> #include "cifsfs.h" #include "cifspdu.h" @@ -542,14 +543,12 @@ static const struct super_operations cifs_super_ops = { static struct dentry * cifs_get_root(struct smb_vol *vol, struct super_block *sb) { - int xid, rc; - struct inode *inode; - struct qstr name; - struct dentry *dparent = NULL, *dchild = NULL, *alias; + struct dentry *dentry; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - unsigned int i, full_len, len; - char *full_path = NULL, *pstart; + char *full_path = NULL; + char *s, *p; char sep; + int xid; full_path = cifs_build_path_to_root(vol, cifs_sb, cifs_sb_master_tcon(cifs_sb)); @@ -560,73 +559,32 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) xid = GetXid(); sep = CIFS_DIR_SEP(cifs_sb); - dparent = dget(sb->s_root); - full_len = strlen(full_path); - full_path[full_len] = sep; - pstart = full_path + 1; - - for (i = 1, len = 0; i <= full_len; i++) { - if (full_path[i] != sep || !len) { - len++; - continue; - } - - full_path[i] = 0; - cFYI(1, "get dentry for %s", pstart); - - name.name = pstart; - name.len = len; - name.hash = full_name_hash(pstart, len); - dchild = d_lookup(dparent, &name); - if (dchild == NULL) { - cFYI(1, "not exists"); - dchild = d_alloc(dparent, &name); - if (dchild == NULL) { - dput(dparent); - dparent = ERR_PTR(-ENOMEM); - goto out; - } - } - - cFYI(1, "get inode"); - if (dchild->d_inode == NULL) { - cFYI(1, "not exists"); - inode = NULL; - if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) - rc = cifs_get_inode_info_unix(&inode, full_path, - sb, xid); - else - rc = cifs_get_inode_info(&inode, full_path, - NULL, sb, xid, NULL); - if (rc) { - dput(dchild); - dput(dparent); - dparent = ERR_PTR(rc); - goto out; - } - alias = d_materialise_unique(dchild, inode); - if (alias != NULL) { - dput(dchild); - if (IS_ERR(alias)) { - dput(dparent); - dparent = ERR_PTR(-EINVAL); /* XXX */ - goto out; - } - dchild = alias; - } - } - cFYI(1, "parent %p, child %p", dparent, dchild); - - dput(dparent); - dparent = dchild; - len = 0; - pstart = full_path + i + 1; - full_path[i] = sep; - } -out: + dentry = dget(sb->s_root); + p = s = full_path; + + do { + struct inode *dir = dentry->d_inode; + struct dentry *child; + + /* skip separators */ + while (*s == sep) + s++; + if (!*s) + break; + p = s++; + /* next separator */ + while (*s && *s != sep) + s++; + + mutex_lock(&dir->i_mutex); + child = lookup_one_len(p, dentry, s - p); + mutex_unlock(&dir->i_mutex); + dput(dentry); + dentry = child; + } while (!IS_ERR(dentry)); _FreeXid(xid); kfree(full_path); - return dparent; + return dentry; } static int cifs_set_super(struct super_block *sb, void *data) diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 0900e1658c96..036ca83e5f46 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -129,5 +129,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); extern const struct export_operations cifs_export_ops; #endif /* CIFS_NFSD_EXPORT */ -#define CIFS_VERSION "1.73" +#define CIFS_VERSION "1.74" #endif /* _CIFSFS_H */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index dbd669cc5bc7..ccc1afa0bf3b 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3485,7 +3485,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid) goto out; } - snprintf(username, MAX_USERNAME_SIZE, "krb50x%x", fsuid); + snprintf(username, sizeof(username), "krb50x%x", fsuid); vol_info->username = username; vol_info->local_nls = cifs_sb->local_nls; vol_info->linux_uid = fsuid; diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 81914df47ef1..fa8c21d913bc 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -55,6 +55,7 @@ build_path_from_dentry(struct dentry *direntry) char dirsep; struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); + unsigned seq; if (direntry == NULL) return NULL; /* not much we can do if dentry is freed and @@ -68,22 +69,29 @@ build_path_from_dentry(struct dentry *direntry) dfsplen = 0; cifs_bp_rename_retry: namelen = dfsplen; + seq = read_seqbegin(&rename_lock); + rcu_read_lock(); for (temp = direntry; !IS_ROOT(temp);) { namelen += (1 + temp->d_name.len); temp = temp->d_parent; if (temp == NULL) { cERROR(1, "corrupt dentry"); + rcu_read_unlock(); return NULL; } } + rcu_read_unlock(); full_path = kmalloc(namelen+1, GFP_KERNEL); if (full_path == NULL) return full_path; full_path[namelen] = 0; /* trailing null */ + rcu_read_lock(); for (temp = direntry; !IS_ROOT(temp);) { + spin_lock(&temp->d_lock); namelen -= 1 + temp->d_name.len; if (namelen < 0) { + spin_unlock(&temp->d_lock); break; } else { full_path[namelen] = dirsep; @@ -91,14 +99,17 @@ cifs_bp_rename_retry: temp->d_name.len); cFYI(0, "name: %s", full_path + namelen); } + spin_unlock(&temp->d_lock); temp = temp->d_parent; if (temp == NULL) { cERROR(1, "corrupt dentry"); + rcu_read_unlock(); kfree(full_path); return NULL; } } - if (namelen != dfsplen) { + rcu_read_unlock(); + if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) { cERROR(1, "did not end path lookup where expected namelen is %d", namelen); /* presumably this is only possible if racing with a rename diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 3892ab817a36..d3e619692ee0 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -428,8 +428,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { flags |= NTLMSSP_NEGOTIATE_SIGN; if (!ses->server->session_estab) - flags |= NTLMSSP_NEGOTIATE_KEY_XCH | - NTLMSSP_NEGOTIATE_EXTENDED_SEC; + flags |= NTLMSSP_NEGOTIATE_KEY_XCH; } sec_blob->NegotiateFlags = cpu_to_le32(flags); @@ -465,10 +464,11 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; if (ses->server->sec_mode & - (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) + (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { flags |= NTLMSSP_NEGOTIATE_SIGN; - if (ses->server->sec_mode & SECMODE_SIGN_REQUIRED) - flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + if (!ses->server->session_estab) + flags |= NTLMSSP_NEGOTIATE_KEY_XCH; + } tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE); sec_blob->NegotiateFlags = cpu_to_le32(flags); diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index e141939080f0..739fb59bcdc2 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -37,7 +37,7 @@ static DEFINE_MUTEX(read_mutex); /* These macros may change in future, to provide better st_ino semantics. */ #define OFFSET(x) ((x)->i_ino) -static unsigned long cramino(struct cramfs_inode *cino, unsigned int offset) +static unsigned long cramino(const struct cramfs_inode *cino, unsigned int offset) { if (!cino->offset) return offset + 1; @@ -61,7 +61,7 @@ static unsigned long cramino(struct cramfs_inode *cino, unsigned int offset) } static struct inode *get_cramfs_inode(struct super_block *sb, - struct cramfs_inode *cramfs_inode, unsigned int offset) + const struct cramfs_inode *cramfs_inode, unsigned int offset) { struct inode *inode; static struct timespec zerotime; @@ -317,7 +317,7 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent) /* Set it all up.. */ sb->s_op = &cramfs_ops; root = get_cramfs_inode(sb, &super.root, 0); - if (!root) + if (IS_ERR(root)) goto out; sb->s_root = d_alloc_root(root); if (!sb->s_root) { @@ -423,6 +423,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { unsigned int offset = 0; + struct inode *inode = NULL; int sorted; mutex_lock(&read_mutex); @@ -449,8 +450,8 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s for (;;) { if (!namelen) { - mutex_unlock(&read_mutex); - return ERR_PTR(-EIO); + inode = ERR_PTR(-EIO); + goto out; } if (name[namelen-1]) break; @@ -462,17 +463,18 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s if (retval > 0) continue; if (!retval) { - struct cramfs_inode entry = *de; - mutex_unlock(&read_mutex); - d_add(dentry, get_cramfs_inode(dir->i_sb, &entry, dir_off)); - return NULL; + inode = get_cramfs_inode(dir->i_sb, de, dir_off); + break; } /* else (retval < 0) */ if (sorted) break; } +out: mutex_unlock(&read_mutex); - d_add(dentry, NULL); + if (IS_ERR(inode)) + return ERR_CAST(inode); + d_add(dentry, inode); return NULL; } diff --git a/fs/dcache.c b/fs/dcache.c index 37f72ee5bf7c..6e4ea6d87774 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2213,14 +2213,15 @@ static void dentry_unlock_parents_for_move(struct dentry *dentry, * The hash value has to match the hash queue that the dentry is on.. */ /* - * d_move - move a dentry + * __d_move - move a dentry * @dentry: entry to move * @target: new dentry * * Update the dcache to reflect the move of a file name. Negative - * dcache entries should not be moved in this way. + * dcache entries should not be moved in this way. Caller hold + * rename_lock. */ -void d_move(struct dentry * dentry, struct dentry * target) +static void __d_move(struct dentry * dentry, struct dentry * target) { if (!dentry->d_inode) printk(KERN_WARNING "VFS: moving negative dcache entry\n"); @@ -2228,8 +2229,6 @@ void d_move(struct dentry * dentry, struct dentry * target) BUG_ON(d_ancestor(dentry, target)); BUG_ON(d_ancestor(target, dentry)); - write_seqlock(&rename_lock); - dentry_lock_for_move(dentry, target); write_seqcount_begin(&dentry->d_seq); @@ -2275,6 +2274,20 @@ void d_move(struct dentry * dentry, struct dentry * target) spin_unlock(&target->d_lock); fsnotify_d_move(dentry); spin_unlock(&dentry->d_lock); +} + +/* + * d_move - move a dentry + * @dentry: entry to move + * @target: new dentry + * + * Update the dcache to reflect the move of a file name. Negative + * dcache entries should not be moved in this way. + */ +void d_move(struct dentry *dentry, struct dentry *target) +{ + write_seqlock(&rename_lock); + __d_move(dentry, target); write_sequnlock(&rename_lock); } EXPORT_SYMBOL(d_move); @@ -2302,7 +2315,7 @@ struct dentry *d_ancestor(struct dentry *p1, struct dentry *p2) * This helper attempts to cope with remotely renamed directories * * It assumes that the caller is already holding - * dentry->d_parent->d_inode->i_mutex and the inode->i_lock + * dentry->d_parent->d_inode->i_mutex, inode->i_lock and rename_lock * * Note: If ever the locking in lock_rename() changes, then please * remember to update this too... @@ -2317,11 +2330,6 @@ static struct dentry *__d_unalias(struct inode *inode, if (alias->d_parent == dentry->d_parent) goto out_unalias; - /* Check for loops */ - ret = ERR_PTR(-ELOOP); - if (d_ancestor(alias, dentry)) - goto out_err; - /* See lock_rename() */ ret = ERR_PTR(-EBUSY); if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex)) @@ -2331,7 +2339,7 @@ static struct dentry *__d_unalias(struct inode *inode, goto out_err; m2 = &alias->d_parent->d_inode->i_mutex; out_unalias: - d_move(alias, dentry); + __d_move(alias, dentry); ret = alias; out_err: spin_unlock(&inode->i_lock); @@ -2416,15 +2424,24 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) alias = __d_find_alias(inode, 0); if (alias) { actual = alias; - /* Is this an anonymous mountpoint that we could splice - * into our tree? */ - if (IS_ROOT(alias)) { + write_seqlock(&rename_lock); + + if (d_ancestor(alias, dentry)) { + /* Check for loops */ + actual = ERR_PTR(-ELOOP); + } else if (IS_ROOT(alias)) { + /* Is this an anonymous mountpoint that we + * could splice into our tree? */ __d_materialise_dentry(dentry, alias); + write_sequnlock(&rename_lock); __d_drop(alias); goto found; + } else { + /* Nope, but we must(!) avoid directory + * aliasing */ + actual = __d_unalias(inode, dentry, alias); } - /* Nope, but we must(!) avoid directory aliasing */ - actual = __d_unalias(inode, dentry, alias); + write_sequnlock(&rename_lock); if (IS_ERR(actual)) dput(alias); goto out_nolock; diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 06065bd37fc3..c57beddcc217 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c @@ -913,7 +913,7 @@ struct dentry *exofs_get_parent(struct dentry *child) unsigned long ino = exofs_parent_ino(child); if (!ino) - return NULL; + return ERR_PTR(-ESTALE); return d_obtain_alias(exofs_iget(child->d_inode->i_sb, ino)); } diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 802ac5eeba28..f9fbbe96c222 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -1069,6 +1069,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) return 0; gfs2_log_lock(sdp); + spin_lock(&sdp->sd_ail_lock); head = bh = page_buffers(page); do { if (atomic_read(&bh->b_count)) @@ -1080,6 +1081,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) goto not_possible; bh = bh->b_this_page; } while(bh != head); + spin_unlock(&sdp->sd_ail_lock); gfs2_log_unlock(sdp); head = bh = page_buffers(page); @@ -1112,6 +1114,7 @@ not_possible: /* Should never happen */ WARN_ON(buffer_dirty(bh)); WARN_ON(buffer_pinned(bh)); cannot_release: + spin_unlock(&sdp->sd_ail_lock); gfs2_log_unlock(sdp); return 0; } diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 8ef70f464731..2cca29316bd6 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -47,10 +47,10 @@ static void __gfs2_ail_flush(struct gfs2_glock *gl) bd_ail_gl_list); bh = bd->bd_bh; gfs2_remove_from_ail(bd); - spin_unlock(&sdp->sd_ail_lock); - bd->bd_bh = NULL; bh->b_private = NULL; + spin_unlock(&sdp->sd_ail_lock); + bd->bd_blkno = bh->b_blocknr; gfs2_log_lock(sdp); gfs2_assert_withdraw(sdp, !buffer_busy(bh)); @@ -221,8 +221,10 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags) } } - if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) + if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) { + gfs2_log_flush(gl->gl_sbd, NULL); gl->gl_sbd->sd_rindex_uptodate = 0; + } if (ip && S_ISREG(ip->i_inode.i_mode)) truncate_inode_pages(ip->i_inode.i_mapping, 0); } diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 0a064e91ac70..81206e70cbf6 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -17,6 +17,7 @@ #include <linux/buffer_head.h> #include <linux/rcupdate.h> #include <linux/rculist_bl.h> +#include <linux/completion.h> #define DIO_WAIT 0x00000010 #define DIO_METADATA 0x00000020 @@ -546,6 +547,7 @@ struct gfs2_sbd { struct gfs2_glock *sd_trans_gl; wait_queue_head_t sd_glock_wait; atomic_t sd_glock_disposal; + struct completion sd_locking_init; /* Inode Stuff */ diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 903115f2bb34..85c62923ee29 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -903,6 +903,7 @@ void gfs2_meta_syncfs(struct gfs2_sbd *sdp) if (gfs2_ail1_empty(sdp)) break; } + gfs2_log_flush(sdp, NULL); } static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 8ac9ae189b53..2a77071fb7b6 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -72,6 +72,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) init_waitqueue_head(&sdp->sd_glock_wait); atomic_set(&sdp->sd_glock_disposal, 0); + init_completion(&sdp->sd_locking_init); spin_lock_init(&sdp->sd_statfs_spin); spin_lock_init(&sdp->sd_rindex_spin); @@ -1017,11 +1018,13 @@ hostdata_error: fsname++; if (lm->lm_mount == NULL) { fs_info(sdp, "Now mounting FS...\n"); + complete(&sdp->sd_locking_init); return 0; } ret = lm->lm_mount(sdp, fsname); if (ret == 0) fs_info(sdp, "Joined cluster. Now mounting FS...\n"); + complete(&sdp->sd_locking_init); return ret; } diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index ed540e7018be..fb0edf735483 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -757,13 +757,17 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc) struct timespec atime; struct gfs2_dinode *di; int ret = -EAGAIN; + int unlock_required = 0; /* Skip timestamp update, if this is from a memalloc */ if (current->flags & PF_MEMALLOC) goto do_flush; - ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); - if (ret) - goto do_flush; + if (!gfs2_glock_is_locked_by_me(ip->i_gl)) { + ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); + if (ret) + goto do_flush; + unlock_required = 1; + } ret = gfs2_trans_begin(sdp, RES_DINODE, 0); if (ret) goto do_unlock; @@ -780,7 +784,8 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc) } gfs2_trans_end(sdp); do_unlock: - gfs2_glock_dq_uninit(&gh); + if (unlock_required) + gfs2_glock_dq_uninit(&gh); do_flush: if (wbc->sync_mode == WB_SYNC_ALL) gfs2_log_flush(GFS2_SB(inode), ip->i_gl); @@ -1427,7 +1432,20 @@ out: return error; } -/* +/** + * gfs2_evict_inode - Remove an inode from cache + * @inode: The inode to evict + * + * There are three cases to consider: + * 1. i_nlink == 0, we are final opener (and must deallocate) + * 2. i_nlink == 0, we are not the final opener (and cannot deallocate) + * 3. i_nlink > 0 + * + * If the fs is read only, then we have to treat all cases as per #3 + * since we are unable to do any deallocation. The inode will be + * deallocated by the next read/write node to attempt an allocation + * in the same resource group + * * We have to (at the moment) hold the inodes main lock to cover * the gap between unlocking the shared lock on the iopen lock and * taking the exclusive lock. I'd rather do a shared -> exclusive @@ -1470,6 +1488,8 @@ static void gfs2_evict_inode(struct inode *inode) if (error) goto out_truncate; + /* Case 1 starts here */ + if (S_ISDIR(inode->i_mode) && (ip->i_diskflags & GFS2_DIF_EXHASH)) { error = gfs2_dir_exhash_dealloc(ip); @@ -1493,13 +1513,16 @@ static void gfs2_evict_inode(struct inode *inode) goto out_unlock; out_truncate: + /* Case 2 starts here */ error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); if (error) goto out_unlock; - gfs2_final_release_pages(ip); + /* Needs to be done before glock release & also in a transaction */ + truncate_inode_pages(&inode->i_data, 0); gfs2_trans_end(sdp); out_unlock: + /* Error path for case 1 */ if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) gfs2_glock_dq(&ip->i_iopen_gh); gfs2_holder_uninit(&ip->i_iopen_gh); @@ -1507,6 +1530,7 @@ out_unlock: if (error && error != GLR_TRYFAILED && error != -EROFS) fs_warn(sdp, "gfs2_evict_inode: %d\n", error); out: + /* Case 3 starts here */ truncate_inode_pages(&inode->i_data, 0); end_writeback(inode); diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index e20eab37bc80..443cabcfcd23 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -338,6 +338,9 @@ static ssize_t lkfirst_store(struct gfs2_sbd *sdp, const char *buf, size_t len) rv = sscanf(buf, "%u", &first); if (rv != 1 || first > 1) return -EINVAL; + rv = wait_for_completion_killable(&sdp->sd_locking_init); + if (rv) + return rv; spin_lock(&sdp->sd_jindex_spin); rv = -EBUSY; if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0) @@ -414,7 +417,9 @@ static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len) rv = sscanf(buf, "%d", &jid); if (rv != 1) return -EINVAL; - + rv = wait_for_completion_killable(&sdp->sd_locking_init); + if (rv) + return rv; spin_lock(&sdp->sd_jindex_spin); rv = -EINVAL; if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c index 87ed48e0343d..85c098a499f3 100644 --- a/fs/hppfs/hppfs.c +++ b/fs/hppfs/hppfs.c @@ -139,7 +139,8 @@ static int file_removed(struct dentry *dentry, const char *file) static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, struct nameidata *nd) { - struct dentry *proc_dentry, *new, *parent; + struct dentry *proc_dentry, *parent; + struct qstr *name = &dentry->d_name; struct inode *inode; int err, deleted; @@ -149,23 +150,9 @@ static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, else if (deleted) return ERR_PTR(-ENOENT); - err = -ENOMEM; parent = HPPFS_I(ino)->proc_dentry; mutex_lock(&parent->d_inode->i_mutex); - proc_dentry = d_lookup(parent, &dentry->d_name); - if (proc_dentry == NULL) { - proc_dentry = d_alloc(parent, &dentry->d_name); - if (proc_dentry == NULL) { - mutex_unlock(&parent->d_inode->i_mutex); - goto out; - } - new = (*parent->d_inode->i_op->lookup)(parent->d_inode, - proc_dentry, NULL); - if (new) { - dput(proc_dentry); - proc_dentry = new; - } - } + proc_dentry = lookup_one_len(name->name, parent, name->len); mutex_unlock(&parent->d_inode->i_mutex); if (IS_ERR(proc_dentry)) @@ -174,13 +161,11 @@ static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, err = -ENOMEM; inode = get_inode(ino->i_sb, proc_dentry); if (!inode) - goto out_dput; + goto out; d_add(dentry, inode); return NULL; - out_dput: - dput(proc_dentry); out: return ERR_PTR(err); } @@ -690,8 +675,10 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) struct inode *proc_ino = dentry->d_inode; struct inode *inode = new_inode(sb); - if (!inode) + if (!inode) { + dput(dentry); return ERR_PTR(-ENOMEM); + } if (S_ISDIR(dentry->d_inode->i_mode)) { inode->i_op = &hppfs_dir_iops; @@ -704,7 +691,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) inode->i_fop = &hppfs_file_fops; } - HPPFS_I(inode)->proc_dentry = dget(dentry); + HPPFS_I(inode)->proc_dentry = dentry; inode->i_uid = proc_ino->i_uid; inode->i_gid = proc_ino->i_gid; @@ -737,7 +724,7 @@ static int hppfs_fill_super(struct super_block *sb, void *d, int silent) sb->s_fs_info = proc_mnt; err = -ENOMEM; - root_inode = get_inode(sb, proc_mnt->mnt_sb->s_root); + root_inode = get_inode(sb, dget(proc_mnt->mnt_sb->s_root)); if (!root_inode) goto out_mntput; diff --git a/fs/libfs.c b/fs/libfs.c index c88eab55aec9..275ca4749a2e 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -822,7 +822,7 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf, goto out; attr->set_buf[size] = '\0'; - val = simple_strtol(attr->set_buf, NULL, 0); + val = simple_strtoll(attr->set_buf, NULL, 0); ret = attr->set(attr->data, val); if (ret == 0) ret = len; /* on success, claim we got the whole input */ diff --git a/fs/namei.c b/fs/namei.c index 0223c41fb114..14ab8d3f2f0c 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -433,6 +433,8 @@ static int unlazy_walk(struct nameidata *nd, struct dentry *dentry) goto err_parent; BUG_ON(nd->inode != parent->d_inode); } else { + if (dentry->d_parent != parent) + goto err_parent; spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); if (!__d_rcu_to_refcount(dentry, nd->seq)) goto err_child; @@ -940,7 +942,6 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, * Don't forget we might have a non-mountpoint managed dentry * that wants to block transit. */ - *inode = path->dentry->d_inode; if (unlikely(managed_dentry_might_block(path->dentry))) return false; @@ -953,6 +954,12 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, path->mnt = mounted; path->dentry = mounted->mnt_root; nd->seq = read_seqcount_begin(&path->dentry->d_seq); + /* + * Update the inode too. We don't need to re-check the + * dentry sequence number here after this d_inode read, + * because a mount-point is always pinned. + */ + *inode = path->dentry->d_inode; } return true; } diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 29309e25417f..b57aab9a1184 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -56,16 +56,12 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, stru lock_ufs(dir->i_sb); ino = ufs_inode_by_name(dir, &dentry->d_name); - if (ino) { + if (ino) inode = ufs_iget(dir->i_sb, ino); - if (IS_ERR(inode)) { - unlock_ufs(dir->i_sb); - return ERR_CAST(inode); - } - } unlock_ufs(dir->i_sb); - d_add(dentry, inode); - return NULL; + if (IS_ERR(inode)) + return ERR_CAST(inode); + return d_splice_alias(inode, dentry); } /* diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 3a10ef5914eb..6cd5b6403a7b 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -210,7 +210,7 @@ struct acpi_device_power_state { struct acpi_device_power { int state; /* Current state */ struct acpi_device_power_flags flags; - struct acpi_device_power_state states[4]; /* Power states (D0-D3) */ + struct acpi_device_power_state states[ACPI_D_STATE_COUNT]; /* Power states (D0-D3Cold) */ }; /* Performance Management */ diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index a756bc8d866d..4543b6f75867 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -98,8 +98,11 @@ acpi_os_table_override(struct acpi_table_header *existing_table, /* * Spinlock primitives */ + +#ifndef acpi_os_create_lock acpi_status acpi_os_create_lock(acpi_spinlock *out_handle); +#endif void acpi_os_delete_lock(acpi_spinlock handle); diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 5d2a5e9544d9..2ce1be9f6291 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h @@ -159,6 +159,24 @@ static inline void *acpi_os_acquire_object(acpi_cache_t * cache) } while (0) #endif +/* + * When lockdep is enabled, the spin_lock_init() macro stringifies it's + * argument and uses that as a name for the lock in debugging. + * By executing spin_lock_init() in a macro the key changes from "lock" for + * all locks to the name of the argument of acpi_os_create_lock(), which + * prevents lockdep from reporting false positives for ACPICA locks. + */ +#define acpi_os_create_lock(__handle) \ +({ \ + spinlock_t *lock = ACPI_ALLOCATE(sizeof(*lock)); \ + \ + if (lock) { \ + *(__handle) = lock; \ + spin_lock_init(*(__handle)); \ + } \ + lock ? AE_OK : AE_NO_MEMORY; \ +}) + #endif /* __KERNEL__ */ #endif /* __ACLINUX_H__ */ diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index e08f344c6cff..3d53efd25ab9 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -182,6 +182,7 @@ {0x1002, 0x6750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6758, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6759, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x675F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6761, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6762, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ @@ -192,6 +193,7 @@ {0x1002, 0x6767, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6768, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6770, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6778, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6779, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ diff --git a/include/linux/audit.h b/include/linux/audit.h index 9d339eb27881..0c8006129fb2 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -613,6 +613,12 @@ extern void audit_log_d_path(struct audit_buffer *ab, extern void audit_log_key(struct audit_buffer *ab, char *key); extern void audit_log_lost(const char *message); +#ifdef CONFIG_SECURITY +extern void audit_log_secctx(struct audit_buffer *ab, u32 secid); +#else +#define audit_log_secctx(b,s) do { ; } while (0) +#endif + extern int audit_update_lsm_rules(void); /* Private API (for audit.c only) */ @@ -635,6 +641,7 @@ extern int audit_enabled; #define audit_log_untrustedstring(a,s) do { ; } while (0) #define audit_log_d_path(b, p, d) do { ; } while (0) #define audit_log_key(b, k) do { ; } while (0) +#define audit_log_secctx(b,s) do { ; } while (0) #define audit_enabled 0 #endif #endif diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index bc03e40fd7fd..44da4822bcab 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -91,25 +91,6 @@ struct vlan_group { struct rcu_head rcu; }; -static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, - u16 vlan_id) -{ - struct net_device **array; - array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; - return array ? array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] : NULL; -} - -static inline void vlan_group_set_device(struct vlan_group *vg, - u16 vlan_id, - struct net_device *dev) -{ - struct net_device **array; - if (!vg) - return; - array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; - array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev; -} - static inline int is_vlan_dev(struct net_device *dev) { return dev->priv_flags & IFF_802_1Q_VLAN; @@ -120,23 +101,17 @@ static inline int is_vlan_dev(struct net_device *dev) #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +extern struct net_device *__vlan_find_dev_deep(struct net_device *real_dev, + u16 vlan_id); extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); extern u16 vlan_dev_vlan_id(const struct net_device *dev); -extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, - u16 vlan_tci, int polling); extern bool vlan_do_receive(struct sk_buff **skb); extern struct sk_buff *vlan_untag(struct sk_buff *skb); -extern gro_result_t -vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, - unsigned int vlan_tci, struct sk_buff *skb); -extern gro_result_t -vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, - unsigned int vlan_tci); #else -static inline struct net_device *vlan_find_dev(struct net_device *real_dev, - u16 vlan_id) +static inline struct net_device * +__vlan_find_dev_deep(struct net_device *real_dev, u16 vlan_id) { return NULL; } @@ -153,13 +128,6 @@ static inline u16 vlan_dev_vlan_id(const struct net_device *dev) return 0; } -static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, - u16 vlan_tci, int polling) -{ - BUG(); - return NET_XMIT_SUCCESS; -} - static inline bool vlan_do_receive(struct sk_buff **skb) { if ((*skb)->vlan_tci & VLAN_VID_MASK) @@ -171,49 +139,9 @@ static inline struct sk_buff *vlan_untag(struct sk_buff *skb) { return skb; } - -static inline gro_result_t -vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, - unsigned int vlan_tci, struct sk_buff *skb) -{ - return GRO_DROP; -} - -static inline gro_result_t -vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, - unsigned int vlan_tci) -{ - return GRO_DROP; -} #endif /** - * vlan_hwaccel_rx - netif_rx wrapper for VLAN RX acceleration - * @skb: buffer - * @grp: vlan group - * @vlan_tci: VLAN TCI as received from the card - */ -static inline int vlan_hwaccel_rx(struct sk_buff *skb, - struct vlan_group *grp, - u16 vlan_tci) -{ - return __vlan_hwaccel_rx(skb, grp, vlan_tci, 0); -} - -/** - * vlan_hwaccel_receive_skb - netif_receive_skb wrapper for VLAN RX acceleration - * @skb: buffer - * @grp: vlan group - * @vlan_tci: VLAN TCI as received from the card - */ -static inline int vlan_hwaccel_receive_skb(struct sk_buff *skb, - struct vlan_group *grp, - u16 vlan_tci) -{ - return __vlan_hwaccel_rx(skb, grp, vlan_tci, 1); -} - -/** * vlan_insert_tag - regular VLAN tag inserting * @skb: skbuff to tag * @vlan_tci: VLAN TCI to insert diff --git a/include/linux/inet_lro.h b/include/linux/inet_lro.h index c4335faebb63..2cf55afbcd4e 100644 --- a/include/linux/inet_lro.h +++ b/include/linux/inet_lro.h @@ -50,7 +50,6 @@ struct net_lro_desc { struct skb_frag_struct *next_frag; struct iphdr *iph; struct tcphdr *tcph; - struct vlan_group *vgrp; __wsum data_csum; __be32 tcp_rcv_tsecr; __be32 tcp_rcv_tsval; @@ -60,7 +59,6 @@ struct net_lro_desc { u16 ip_tot_len; u16 tcp_saw_tstamp; /* timestamps enabled */ __be16 tcp_window; - u16 vlan_tag; int pkt_aggr_cnt; /* counts aggregated packets */ int vlan_packet; int mss; @@ -137,16 +135,6 @@ void lro_receive_skb(struct net_lro_mgr *lro_mgr, void *priv); /* - * Processes a SKB with VLAN HW acceleration support - */ - -void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr, - struct sk_buff *skb, - struct vlan_group *vgrp, - u16 vlan_tag, - void *priv); - -/* * Processes a fragment list * * This functions aggregate fragments and generate SKBs do pass @@ -165,13 +153,6 @@ void lro_receive_frags(struct net_lro_mgr *lro_mgr, struct skb_frag_struct *frags, int len, int true_size, void *priv, __wsum sum); -void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr, - struct skb_frag_struct *frags, - int len, int true_size, - struct vlan_group *vgrp, - u16 vlan_tag, - void *priv, __wsum sum); - /* * Forward all aggregated SKBs held by lro_mgr to network stack */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 52c4e3835aa6..34f3abc6457a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -530,7 +530,7 @@ struct netdev_queue { struct Qdisc *qdisc; unsigned long state; struct Qdisc *qdisc_sleeping; -#ifdef CONFIG_RPS +#if defined(CONFIG_RPS) || defined(CONFIG_XPS) struct kobject kobj; #endif #if defined(CONFIG_XPS) && defined(CONFIG_NUMA) @@ -768,12 +768,6 @@ struct netdev_tc_txq { * 3. Update dev->stats asynchronously and atomically, and define * neither operation. * - * void (*ndo_vlan_rx_register)(struct net_device *dev, struct vlan_group *grp); - * If device support VLAN receive acceleration - * (ie. dev->features & NETIF_F_HW_VLAN_RX), then this function is called - * when vlan groups for the device changes. Note: grp is NULL - * if no vlan's groups are being used. - * * void (*ndo_vlan_rx_add_vid)(struct net_device *dev, unsigned short vid); * If device support VLAN filtering (dev->features & NETIF_F_HW_VLAN_FILTER) * this function is called when a VLAN id is registered. @@ -892,8 +886,6 @@ struct net_device_ops { struct rtnl_link_stats64 *storage); struct net_device_stats* (*ndo_get_stats)(struct net_device *dev); - void (*ndo_vlan_rx_register)(struct net_device *dev, - struct vlan_group *grp); void (*ndo_vlan_rx_add_vid)(struct net_device *dev, unsigned short vid); void (*ndo_vlan_rx_kill_vid)(struct net_device *dev, @@ -1070,12 +1062,6 @@ struct net_device { #define NETIF_F_ALL_FCOE (NETIF_F_FCOE_CRC | NETIF_F_FCOE_MTU | \ NETIF_F_FSO) -#define NETIF_F_ALL_TX_OFFLOADS (NETIF_F_ALL_CSUM | NETIF_F_SG | \ - NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \ - NETIF_F_HIGHDMA | \ - NETIF_F_SCTP_CSUM | \ - NETIF_F_ALL_FCOE) - /* * If one device supports one of these features, then enable them * for all in netdev_increment_features. @@ -1193,7 +1179,7 @@ struct net_device { unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ -#ifdef CONFIG_RPS +#if defined(CONFIG_RPS) || defined(CONFIG_XPS) struct kset *queues_kset; struct netdev_rx_queue *_rx; diff --git a/include/linux/netfilter/ipset/ip_set_ahash.h b/include/linux/netfilter/ipset/ip_set_ahash.h index c5b06aaa205c..b89fb79cb44f 100644 --- a/include/linux/netfilter/ipset/ip_set_ahash.h +++ b/include/linux/netfilter/ipset/ip_set_ahash.h @@ -28,7 +28,32 @@ /* Number of elements to store in an initial array block */ #define AHASH_INIT_SIZE 4 /* Max number of elements to store in an array block */ -#define AHASH_MAX_SIZE (3*4) +#define AHASH_MAX_SIZE (3*AHASH_INIT_SIZE) + +/* Max number of elements can be tuned */ +#ifdef IP_SET_HASH_WITH_MULTI +#define AHASH_MAX(h) ((h)->ahash_max) + +static inline u8 +tune_ahash_max(u8 curr, u32 multi) +{ + u32 n; + + if (multi < curr) + return curr; + + n = curr + AHASH_INIT_SIZE; + /* Currently, at listing one hash bucket must fit into a message. + * Therefore we have a hard limit here. + */ + return n > curr && n <= 64 ? n : curr; +} +#define TUNE_AHASH_MAX(h, multi) \ + ((h)->ahash_max = tune_ahash_max((h)->ahash_max, multi)) +#else +#define AHASH_MAX(h) AHASH_MAX_SIZE +#define TUNE_AHASH_MAX(h, multi) +#endif /* A hash bucket */ struct hbucket { @@ -60,6 +85,9 @@ struct ip_set_hash { u32 timeout; /* timeout value, if enabled */ struct timer_list gc; /* garbage collection when timeout enabled */ struct type_pf_next next; /* temporary storage for uadd */ +#ifdef IP_SET_HASH_WITH_MULTI + u8 ahash_max; /* max elements in an array block */ +#endif #ifdef IP_SET_HASH_WITH_NETMASK u8 netmask; /* netmask value for subnets to store */ #endif @@ -211,12 +239,16 @@ ip_set_hash_destroy(struct ip_set *set) set->data = NULL; } -#define HKEY(data, initval, htable_bits) \ -(jhash2((u32 *)(data), sizeof(struct type_pf_elem)/sizeof(u32), initval) \ - & jhash_mask(htable_bits)) - #endif /* _IP_SET_AHASH_H */ +#ifndef HKEY_DATALEN +#define HKEY_DATALEN sizeof(struct type_pf_elem) +#endif + +#define HKEY(data, initval, htable_bits) \ +(jhash2((u32 *)(data), HKEY_DATALEN/sizeof(u32), initval) \ + & jhash_mask(htable_bits)) + #define CONCAT(a, b, c) a##b##c #define TOKEN(a, b, c) CONCAT(a, b, c) @@ -275,12 +307,13 @@ ip_set_hash_destroy(struct ip_set *set) /* Add an element to the hash table when resizing the set: * we spare the maintenance of the internal counters. */ static int -type_pf_elem_add(struct hbucket *n, const struct type_pf_elem *value) +type_pf_elem_add(struct hbucket *n, const struct type_pf_elem *value, + u8 ahash_max) { if (n->pos >= n->size) { void *tmp; - if (n->size >= AHASH_MAX_SIZE) + if (n->size >= ahash_max) /* Trigger rehashing */ return -EAGAIN; @@ -335,7 +368,7 @@ retry: for (j = 0; j < n->pos; j++) { data = ahash_data(n, j); m = hbucket(t, HKEY(data, h->initval, htable_bits)); - ret = type_pf_elem_add(m, data); + ret = type_pf_elem_add(m, data, AHASH_MAX(h)); if (ret < 0) { read_unlock_bh(&set->lock); ahash_destroy(t); @@ -359,7 +392,7 @@ retry: return 0; } -static void +static inline void type_pf_data_next(struct ip_set_hash *h, const struct type_pf_elem *d); /* Add an element to a hash and update the internal counters when succeeded, @@ -372,7 +405,7 @@ type_pf_add(struct ip_set *set, void *value, u32 timeout, u32 flags) const struct type_pf_elem *d = value; struct hbucket *n; int i, ret = 0; - u32 key; + u32 key, multi = 0; if (h->elements >= h->maxelem) return -IPSET_ERR_HASH_FULL; @@ -382,12 +415,12 @@ type_pf_add(struct ip_set *set, void *value, u32 timeout, u32 flags) key = HKEY(value, h->initval, t->htable_bits); n = hbucket(t, key); for (i = 0; i < n->pos; i++) - if (type_pf_data_equal(ahash_data(n, i), d)) { + if (type_pf_data_equal(ahash_data(n, i), d, &multi)) { ret = -IPSET_ERR_EXIST; goto out; } - - ret = type_pf_elem_add(n, value); + TUNE_AHASH_MAX(h, multi); + ret = type_pf_elem_add(n, value, AHASH_MAX(h)); if (ret != 0) { if (ret == -EAGAIN) type_pf_data_next(h, d); @@ -415,13 +448,13 @@ type_pf_del(struct ip_set *set, void *value, u32 timeout, u32 flags) struct hbucket *n; int i; struct type_pf_elem *data; - u32 key; + u32 key, multi = 0; key = HKEY(value, h->initval, t->htable_bits); n = hbucket(t, key); for (i = 0; i < n->pos; i++) { data = ahash_data(n, i); - if (!type_pf_data_equal(data, d)) + if (!type_pf_data_equal(data, d, &multi)) continue; if (i != n->pos - 1) /* Not last one */ @@ -462,17 +495,17 @@ type_pf_test_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout) struct hbucket *n; const struct type_pf_elem *data; int i, j = 0; - u32 key; + u32 key, multi = 0; u8 host_mask = SET_HOST_MASK(set->family); pr_debug("test by nets\n"); - for (; j < host_mask && h->nets[j].cidr; j++) { + for (; j < host_mask && h->nets[j].cidr && !multi; j++) { type_pf_data_netmask(d, h->nets[j].cidr); key = HKEY(d, h->initval, t->htable_bits); n = hbucket(t, key); for (i = 0; i < n->pos; i++) { data = ahash_data(n, i); - if (type_pf_data_equal(data, d)) + if (type_pf_data_equal(data, d, &multi)) return 1; } } @@ -490,7 +523,7 @@ type_pf_test(struct ip_set *set, void *value, u32 timeout, u32 flags) struct hbucket *n; const struct type_pf_elem *data; int i; - u32 key; + u32 key, multi = 0; #ifdef IP_SET_HASH_WITH_NETS /* If we test an IP address and not a network address, @@ -503,7 +536,7 @@ type_pf_test(struct ip_set *set, void *value, u32 timeout, u32 flags) n = hbucket(t, key); for (i = 0; i < n->pos; i++) { data = ahash_data(n, i); - if (type_pf_data_equal(data, d)) + if (type_pf_data_equal(data, d, &multi)) return 1; } return 0; @@ -660,14 +693,14 @@ type_pf_data_timeout_set(struct type_pf_elem *data, u32 timeout) static int type_pf_elem_tadd(struct hbucket *n, const struct type_pf_elem *value, - u32 timeout) + u8 ahash_max, u32 timeout) { struct type_pf_elem *data; if (n->pos >= n->size) { void *tmp; - if (n->size >= AHASH_MAX_SIZE) + if (n->size >= ahash_max) /* Trigger rehashing */ return -EAGAIN; @@ -772,7 +805,7 @@ retry: for (j = 0; j < n->pos; j++) { data = ahash_tdata(n, j); m = hbucket(t, HKEY(data, h->initval, htable_bits)); - ret = type_pf_elem_tadd(m, data, + ret = type_pf_elem_tadd(m, data, AHASH_MAX(h), type_pf_data_timeout(data)); if (ret < 0) { read_unlock_bh(&set->lock); @@ -803,9 +836,9 @@ type_pf_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags) const struct type_pf_elem *d = value; struct hbucket *n; struct type_pf_elem *data; - int ret = 0, i, j = AHASH_MAX_SIZE + 1; + int ret = 0, i, j = AHASH_MAX(h) + 1; bool flag_exist = flags & IPSET_FLAG_EXIST; - u32 key; + u32 key, multi = 0; if (h->elements >= h->maxelem) /* FIXME: when set is full, we slow down here */ @@ -819,18 +852,18 @@ type_pf_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags) n = hbucket(t, key); for (i = 0; i < n->pos; i++) { data = ahash_tdata(n, i); - if (type_pf_data_equal(data, d)) { + if (type_pf_data_equal(data, d, &multi)) { if (type_pf_data_expired(data) || flag_exist) j = i; else { ret = -IPSET_ERR_EXIST; goto out; } - } else if (j == AHASH_MAX_SIZE + 1 && + } else if (j == AHASH_MAX(h) + 1 && type_pf_data_expired(data)) j = i; } - if (j != AHASH_MAX_SIZE + 1) { + if (j != AHASH_MAX(h) + 1) { data = ahash_tdata(n, j); #ifdef IP_SET_HASH_WITH_NETS del_cidr(h, data->cidr, HOST_MASK); @@ -840,7 +873,8 @@ type_pf_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags) type_pf_data_timeout_set(data, timeout); goto out; } - ret = type_pf_elem_tadd(n, d, timeout); + TUNE_AHASH_MAX(h, multi); + ret = type_pf_elem_tadd(n, d, AHASH_MAX(h), timeout); if (ret != 0) { if (ret == -EAGAIN) type_pf_data_next(h, d); @@ -865,13 +899,13 @@ type_pf_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags) struct hbucket *n; int i; struct type_pf_elem *data; - u32 key; + u32 key, multi = 0; key = HKEY(value, h->initval, t->htable_bits); n = hbucket(t, key); for (i = 0; i < n->pos; i++) { data = ahash_tdata(n, i); - if (!type_pf_data_equal(data, d)) + if (!type_pf_data_equal(data, d, &multi)) continue; if (type_pf_data_expired(data)) return -IPSET_ERR_EXIST; @@ -911,16 +945,16 @@ type_pf_ttest_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout) struct type_pf_elem *data; struct hbucket *n; int i, j = 0; - u32 key; + u32 key, multi = 0; u8 host_mask = SET_HOST_MASK(set->family); - for (; j < host_mask && h->nets[j].cidr; j++) { + for (; j < host_mask && h->nets[j].cidr && !multi; j++) { type_pf_data_netmask(d, h->nets[j].cidr); key = HKEY(d, h->initval, t->htable_bits); n = hbucket(t, key); for (i = 0; i < n->pos; i++) { data = ahash_tdata(n, i); - if (type_pf_data_equal(data, d)) + if (type_pf_data_equal(data, d, &multi)) return !type_pf_data_expired(data); } } @@ -936,7 +970,7 @@ type_pf_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags) struct type_pf_elem *data, *d = value; struct hbucket *n; int i; - u32 key; + u32 key, multi = 0; #ifdef IP_SET_HASH_WITH_NETS if (d->cidr == SET_HOST_MASK(set->family)) @@ -946,7 +980,7 @@ type_pf_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags) n = hbucket(t, key); for (i = 0; i < n->pos; i++) { data = ahash_tdata(n, i); - if (type_pf_data_equal(data, d)) + if (type_pf_data_equal(data, d, &multi)) return !type_pf_data_expired(data); } return 0; @@ -1054,6 +1088,8 @@ type_pf_gc_init(struct ip_set *set) IPSET_GC_PERIOD(h->timeout)); } +#undef HKEY_DATALEN +#undef HKEY #undef type_pf_data_equal #undef type_pf_data_isnull #undef type_pf_data_copy diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index 2b11fc1a86be..74d33861473c 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -60,6 +60,9 @@ struct nfnl_callback { int (*call)(struct sock *nl, struct sk_buff *skb, const struct nlmsghdr *nlh, const struct nlattr * const cda[]); + int (*call_rcu)(struct sock *nl, struct sk_buff *skb, + const struct nlmsghdr *nlh, + const struct nlattr * const cda[]); const struct nla_policy *policy; /* netlink attribute policy */ const u_int16_t attr_count; /* number of nlattr's */ }; diff --git a/include/linux/netfilter/nfnetlink_queue.h b/include/linux/netfilter/nfnetlink_queue.h index af94e0014ebd..24b32e6c009e 100644 --- a/include/linux/netfilter/nfnetlink_queue.h +++ b/include/linux/netfilter/nfnetlink_queue.h @@ -8,6 +8,7 @@ enum nfqnl_msg_types { NFQNL_MSG_PACKET, /* packet from kernel to userspace */ NFQNL_MSG_VERDICT, /* verdict from userspace to kernel */ NFQNL_MSG_CONFIG, /* connect to a particular queue */ + NFQNL_MSG_VERDICT_BATCH, /* batchv from userspace to kernel */ NFQNL_MSG_MAX }; diff --git a/include/linux/random.h b/include/linux/random.h index fb7ab9de5f36..ce29a040c8dc 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -58,6 +58,7 @@ extern void get_random_bytes(void *buf, int nbytes); void generate_random_uuid(unsigned char uuid_out[16]); extern __u32 secure_ip_id(__be32 daddr); +extern __u32 secure_ipv6_id(const __be32 daddr[4]); extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); extern u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, __be16 dport); diff --git a/include/linux/sdla.h b/include/linux/sdla.h index 564acd3a71c1..9995c7fc3f60 100644 --- a/include/linux/sdla.h +++ b/include/linux/sdla.h @@ -112,11 +112,7 @@ struct sdla_dlci_conf { short Tb_max; }; -#ifndef __KERNEL__ - -void sdla(void *cfg_info, char *dev, struct frad_conf *conf, int quiet); - -#else +#ifdef __KERNEL__ /* important Z80 window addresses */ #define SDLA_CONTROL_WND 0xE000 diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 05d775690b72..0dddc9e42b6b 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -28,11 +28,21 @@ #include <linux/platform_device.h> -/* platform data for platform device structure's platform_data field */ +/* Platfrom data for platform device structure's platform_data field */ + +struct stmmac_mdio_bus_data { + int bus_id; + int (*phy_reset)(void *priv); + unsigned int phy_mask; + int *irqs; + int probed_phy_irq; +}; -/* Private data for the STM on-board ethernet driver */ struct plat_stmmacenet_data { int bus_id; + int phy_addr; + int interface; + struct stmmac_mdio_bus_data *mdio_bus_data; int pbl; int clk_csr; int has_gmac; @@ -48,14 +58,4 @@ struct plat_stmmacenet_data { void *custom_cfg; void *bsp_priv; }; - -struct plat_stmmacphy_data { - int bus_id; - int phy_addr; - unsigned int phy_mask; - int interface; - int (*phy_reset)(void *priv); - void *priv; -}; #endif - diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 39d123081e7e..4233e6f9841d 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -71,7 +71,7 @@ static inline bool inet_metrics_new(const struct inet_peer *p) } /* can be called with or without local BH being disabled */ -struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create); +struct inet_peer *inet_getpeer(const struct inetpeer_addr *daddr, int create); static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create) { @@ -106,11 +106,18 @@ static inline void inet_peer_refcheck(const struct inet_peer *p) /* can be called with or without local BH being disabled */ -static inline __u16 inet_getid(struct inet_peer *p, int more) +static inline int inet_getid(struct inet_peer *p, int more) { + int old, new; more++; inet_peer_refcheck(p); - return atomic_add_return(more, &p->ip_id_count) - more; + do { + old = atomic_read(&p->ip_id_count); + new = old + more; + if (!new) + new = 1; + } while (atomic_cmpxchg(&p->ip_id_count, old, new) != old); + return new; } #endif /* _NET_INETPEER_H */ diff --git a/include/net/ipv6.h b/include/net/ipv6.h index c033ed00df7d..3b5ac1fbff39 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -463,17 +463,7 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); } -static __inline__ void ipv6_select_ident(struct frag_hdr *fhdr) -{ - static u32 ipv6_fragmentation_id = 1; - static DEFINE_SPINLOCK(ip6_id_lock); - - spin_lock_bh(&ip6_id_lock); - fhdr->identification = htonl(ipv6_fragmentation_id); - if (++ipv6_fragmentation_id == 0) - ipv6_fragmentation_id = 1; - spin_unlock_bh(&ip6_id_lock); -} +extern void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt); /* * Prototypes exported by ipv6 diff --git a/kernel/audit.c b/kernel/audit.c index 939500317066..52501b5d4902 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -55,6 +55,9 @@ #include <net/sock.h> #include <net/netlink.h> #include <linux/skbuff.h> +#ifdef CONFIG_SECURITY +#include <linux/security.h> +#endif #include <linux/netlink.h> #include <linux/freezer.h> #include <linux/tty.h> @@ -1502,6 +1505,32 @@ void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, } } +#ifdef CONFIG_SECURITY +/** + * audit_log_secctx - Converts and logs SELinux context + * @ab: audit_buffer + * @secid: security number + * + * This is a helper function that calls security_secid_to_secctx to convert + * secid to secctx and then adds the (converted) SELinux context to the audit + * log by calling audit_log_format, thus also preventing leak of internal secid + * to userspace. If secid cannot be converted audit_panic is called. + */ +void audit_log_secctx(struct audit_buffer *ab, u32 secid) +{ + u32 len; + char *secctx; + + if (security_secid_to_secctx(secid, &secctx, &len)) { + audit_panic("Cannot convert secid to context"); + } else { + audit_log_format(ab, " obj=%s", secctx); + security_release_secctx(secctx, len); + } +} +EXPORT_SYMBOL(audit_log_secctx); +#endif + EXPORT_SYMBOL(audit_log_start); EXPORT_SYMBOL(audit_log_end); EXPORT_SYMBOL(audit_log_format); diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 7e59ffb3d0ba..ba06207b1dd3 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -84,9 +84,32 @@ DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); static struct rcu_state *rcu_state; +/* + * The rcu_scheduler_active variable transitions from zero to one just + * before the first task is spawned. So when this variable is zero, RCU + * can assume that there is but one task, allowing RCU to (for example) + * optimized synchronize_sched() to a simple barrier(). When this variable + * is one, RCU must actually do all the hard work required to detect real + * grace periods. This variable is also used to suppress boot-time false + * positives from lockdep-RCU error checking. + */ int rcu_scheduler_active __read_mostly; EXPORT_SYMBOL_GPL(rcu_scheduler_active); +/* + * The rcu_scheduler_fully_active variable transitions from zero to one + * during the early_initcall() processing, which is after the scheduler + * is capable of creating new tasks. So RCU processing (for example, + * creating tasks for RCU priority boosting) must be delayed until after + * rcu_scheduler_fully_active transitions from zero to one. We also + * currently delay invocation of any RCU callbacks until after this point. + * + * It might later prove better for people registering RCU callbacks during + * early boot to take responsibility for these callbacks, but one step at + * a time. + */ +static int rcu_scheduler_fully_active __read_mostly; + #ifdef CONFIG_RCU_BOOST /* @@ -98,7 +121,6 @@ DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status); DEFINE_PER_CPU(int, rcu_cpu_kthread_cpu); DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); DEFINE_PER_CPU(char, rcu_cpu_has_work); -static char rcu_kthreads_spawnable; #endif /* #ifdef CONFIG_RCU_BOOST */ @@ -1467,6 +1489,8 @@ static void rcu_process_callbacks(struct softirq_action *unused) */ static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) { + if (unlikely(!ACCESS_ONCE(rcu_scheduler_fully_active))) + return; if (likely(!rsp->boost)) { rcu_do_batch(rsp, rdp); return; diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 14dc7dd00902..75113cb7c4fb 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h @@ -1532,7 +1532,7 @@ static int __cpuinit rcu_spawn_one_cpu_kthread(int cpu) struct sched_param sp; struct task_struct *t; - if (!rcu_kthreads_spawnable || + if (!rcu_scheduler_fully_active || per_cpu(rcu_cpu_kthread_task, cpu) != NULL) return 0; t = kthread_create(rcu_cpu_kthread, (void *)(long)cpu, "rcuc%d", cpu); @@ -1639,7 +1639,7 @@ static int __cpuinit rcu_spawn_one_node_kthread(struct rcu_state *rsp, struct sched_param sp; struct task_struct *t; - if (!rcu_kthreads_spawnable || + if (!rcu_scheduler_fully_active || rnp->qsmaskinit == 0) return 0; if (rnp->node_kthread_task == NULL) { @@ -1665,7 +1665,7 @@ static int __init rcu_spawn_kthreads(void) int cpu; struct rcu_node *rnp; - rcu_kthreads_spawnable = 1; + rcu_scheduler_fully_active = 1; for_each_possible_cpu(cpu) { per_cpu(rcu_cpu_has_work, cpu) = 0; if (cpu_online(cpu)) @@ -1687,7 +1687,7 @@ static void __cpuinit rcu_prepare_kthreads(int cpu) struct rcu_node *rnp = rdp->mynode; /* Fire up the incoming CPU's kthread and leaf rcu_node kthread. */ - if (rcu_kthreads_spawnable) { + if (rcu_scheduler_fully_active) { (void)rcu_spawn_one_cpu_kthread(cpu); if (rnp->node_kthread_task == NULL) (void)rcu_spawn_one_node_kthread(rcu_state, rnp); @@ -1726,6 +1726,13 @@ static void rcu_cpu_kthread_setrt(int cpu, int to_rt) { } +static int __init rcu_scheduler_really_started(void) +{ + rcu_scheduler_fully_active = 1; + return 0; +} +early_initcall(rcu_scheduler_really_started); + static void __cpuinit rcu_prepare_kthreads(int cpu) { } diff --git a/kernel/sched.c b/kernel/sched.c index 9769c756ad66..3dc716f6d8ad 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -7757,6 +7757,9 @@ static void init_cfs_rq(struct cfs_rq *cfs_rq, struct rq *rq) #endif #endif cfs_rq->min_vruntime = (u64)(-(1LL << 20)); +#ifndef CONFIG_64BIT + cfs_rq->min_vruntime_copy = cfs_rq->min_vruntime; +#endif } static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq) diff --git a/mm/vmscan.c b/mm/vmscan.c index 5ed24b94c5e6..d036e59d302b 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2310,7 +2310,8 @@ static bool pgdat_balanced(pg_data_t *pgdat, unsigned long balanced_pages, for (i = 0; i <= classzone_idx; i++) present_pages += pgdat->node_zones[i].present_pages; - return balanced_pages > (present_pages >> 2); + /* A special case here: if zone has no page, we think it's balanced */ + return balanced_pages >= (present_pages >> 2); } /* is kswapd sleeping prematurely? */ diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index d24c4644b930..8970ba139d73 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -134,8 +134,6 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) vlan_gvrp_uninit_applicant(real_dev); rcu_assign_pointer(real_dev->vlgrp, NULL); - if (ops->ndo_vlan_rx_register) - ops->ndo_vlan_rx_register(real_dev, NULL); /* Free the group, after all cpu's are done. */ call_rcu(&grp->rcu, vlan_rcu_free); @@ -207,8 +205,6 @@ int register_vlan_dev(struct net_device *dev) grp->nr_vlans++; if (ngrp) { - if (ops->ndo_vlan_rx_register && (real_dev->features & NETIF_F_HW_VLAN_RX)) - ops->ndo_vlan_rx_register(real_dev, ngrp); rcu_assign_pointer(real_dev->vlgrp, ngrp); } if (real_dev->features & NETIF_F_HW_VLAN_FILTER) diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index b132f542b44b..9fd45f3571f9 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -74,6 +74,25 @@ static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev) return netdev_priv(dev); } +static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, + u16 vlan_id) +{ + struct net_device **array; + array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; + return array ? array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] : NULL; +} + +static inline void vlan_group_set_device(struct vlan_group *vg, + u16 vlan_id, + struct net_device *dev) +{ + struct net_device **array; + if (!vg) + return; + array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; + array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev; +} + /* Must be invoked with rcu_read_lock or with RTNL. */ static inline struct net_device *vlan_find_dev(struct net_device *real_dev, u16 vlan_id) diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index fcc684678af6..5f27f8e30254 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -63,6 +63,27 @@ bool vlan_do_receive(struct sk_buff **skbp) return true; } +/* Must be invoked with rcu_read_lock or with RTNL. */ +struct net_device *__vlan_find_dev_deep(struct net_device *real_dev, + u16 vlan_id) +{ + struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp); + + if (grp) { + return vlan_group_get_device(grp, vlan_id); + } else { + /* + * Bonding slaves do not have grp assigned to themselves. + * Grp is assigned to bonding master instead. + */ + if (netif_is_bond_slave(real_dev)) + return __vlan_find_dev_deep(real_dev->master, vlan_id); + } + + return NULL; +} +EXPORT_SYMBOL(__vlan_find_dev_deep); + struct net_device *vlan_dev_real_dev(const struct net_device *dev) { return vlan_dev_info(dev)->real_dev; @@ -75,31 +96,6 @@ u16 vlan_dev_vlan_id(const struct net_device *dev) } EXPORT_SYMBOL(vlan_dev_vlan_id); -/* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */ -int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, - u16 vlan_tci, int polling) -{ - __vlan_hwaccel_put_tag(skb, vlan_tci); - return polling ? netif_receive_skb(skb) : netif_rx(skb); -} -EXPORT_SYMBOL(__vlan_hwaccel_rx); - -gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, - unsigned int vlan_tci, struct sk_buff *skb) -{ - __vlan_hwaccel_put_tag(skb, vlan_tci); - return napi_gro_receive(napi, skb); -} -EXPORT_SYMBOL(vlan_gro_receive); - -gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, - unsigned int vlan_tci) -{ - __vlan_hwaccel_put_tag(napi->skb, vlan_tci); - return napi_gro_frags(napi); -} -EXPORT_SYMBOL(vlan_gro_frags); - static struct sk_buff *vlan_reorder_header(struct sk_buff *skb) { if (skb_cow(skb, skb_headroom(skb)) < 0) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 49bb75294b7d..934e221c1d07 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -530,7 +530,11 @@ static int vlan_dev_init(struct net_device *dev) (1<<__LINK_STATE_DORMANT))) | (1<<__LINK_STATE_PRESENT); - dev->hw_features = NETIF_F_ALL_TX_OFFLOADS; + dev->hw_features = NETIF_F_ALL_CSUM | NETIF_F_SG | + NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | + NETIF_F_HIGHDMA | NETIF_F_SCTP_CSUM | + NETIF_F_ALL_FCOE; + dev->features |= real_dev->vlan_features | NETIF_F_LLTX; dev->gso_max_size = real_dev->gso_max_size; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index f7f8e2cd3f70..3204ba8a701c 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -763,7 +763,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn) struct sock *parent = bt_sk(sk)->parent; rsp.result = cpu_to_le16(L2CAP_CR_PEND); rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND); - parent->sk_data_ready(parent, 0); + if (parent) + parent->sk_data_ready(parent, 0); } else { l2cap_state_change(chan, BT_CONFIG); @@ -2523,8 +2524,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr sk = chan->sk; - if ((bt_sk(sk)->defer_setup && chan->state != BT_CONNECT2) || - (!bt_sk(sk)->defer_setup && chan->state != BT_CONFIG)) { + if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) { struct l2cap_cmd_rej_cid rej; rej.reason = cpu_to_le16(L2CAP_REJ_INVALID_CID); @@ -4150,7 +4150,8 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) struct sock *parent = bt_sk(sk)->parent; res = L2CAP_CR_PEND; stat = L2CAP_CS_AUTHOR_PEND; - parent->sk_data_ready(parent, 0); + if (parent) + parent->sk_data_ready(parent, 0); } else { l2cap_state_change(chan, BT_CONFIG); res = L2CAP_CR_SUCCESS; diff --git a/net/ceph/ceph_fs.c b/net/ceph/ceph_fs.c index a3a3a31d3c37..41466ccb972a 100644 --- a/net/ceph/ceph_fs.c +++ b/net/ceph/ceph_fs.c @@ -36,16 +36,19 @@ int ceph_flags_to_mode(int flags) if ((flags & O_DIRECTORY) == O_DIRECTORY) return CEPH_FILE_MODE_PIN; #endif - if ((flags & O_APPEND) == O_APPEND) - flags |= O_WRONLY; - if ((flags & O_ACCMODE) == O_RDWR) - mode = CEPH_FILE_MODE_RDWR; - else if ((flags & O_ACCMODE) == O_WRONLY) + switch (flags & O_ACCMODE) { + case O_WRONLY: mode = CEPH_FILE_MODE_WR; - else + break; + case O_RDONLY: mode = CEPH_FILE_MODE_RD; - + break; + case O_RDWR: + case O_ACCMODE: /* this is what the VFS does */ + mode = CEPH_FILE_MODE_RDWR; + break; + } #ifdef O_LAZY if (flags & O_LAZY) mode |= CEPH_FILE_MODE_LAZY; diff --git a/net/core/ethtool.c b/net/core/ethtool.c index b7c12a63d0ce..6cdba5fc2bed 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -923,7 +923,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) regs.len = reglen; regbuf = vzalloc(reglen); - if (!regbuf) + if (reglen && !regbuf) return -ENOMEM; ops->get_regs(dev, ®s, regbuf); @@ -932,7 +932,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) if (copy_to_user(useraddr, ®s, sizeof(regs))) goto out; useraddr += offsetof(struct ethtool_regs, data); - if (copy_to_user(useraddr, regbuf, regs.len)) + if (regbuf && copy_to_user(useraddr, regbuf, regs.len)) goto out; ret = 0; diff --git a/net/core/skbuff.c b/net/core/skbuff.c index d220119f13ab..2beda824636e 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -799,7 +799,8 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { if (skb_copy_ubufs(skb, gfp_mask)) { - kfree(n); + kfree_skb(n); + n = NULL; goto out; } skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY; diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c index 85a0f75dae64..ef7ae6049a51 100644 --- a/net/ipv4/inet_lro.c +++ b/net/ipv4/inet_lro.c @@ -146,8 +146,7 @@ static __wsum lro_tcp_data_csum(struct iphdr *iph, struct tcphdr *tcph, int len) } static void lro_init_desc(struct net_lro_desc *lro_desc, struct sk_buff *skb, - struct iphdr *iph, struct tcphdr *tcph, - u16 vlan_tag, struct vlan_group *vgrp) + struct iphdr *iph, struct tcphdr *tcph) { int nr_frags; __be32 *ptr; @@ -173,8 +172,6 @@ static void lro_init_desc(struct net_lro_desc *lro_desc, struct sk_buff *skb, } lro_desc->mss = tcp_data_len; - lro_desc->vgrp = vgrp; - lro_desc->vlan_tag = vlan_tag; lro_desc->active = 1; lro_desc->data_csum = lro_tcp_data_csum(iph, tcph, @@ -309,29 +306,17 @@ static void lro_flush(struct net_lro_mgr *lro_mgr, skb_shinfo(lro_desc->parent)->gso_size = lro_desc->mss; - if (lro_desc->vgrp) { - if (lro_mgr->features & LRO_F_NAPI) - vlan_hwaccel_receive_skb(lro_desc->parent, - lro_desc->vgrp, - lro_desc->vlan_tag); - else - vlan_hwaccel_rx(lro_desc->parent, - lro_desc->vgrp, - lro_desc->vlan_tag); - - } else { - if (lro_mgr->features & LRO_F_NAPI) - netif_receive_skb(lro_desc->parent); - else - netif_rx(lro_desc->parent); - } + if (lro_mgr->features & LRO_F_NAPI) + netif_receive_skb(lro_desc->parent); + else + netif_rx(lro_desc->parent); LRO_INC_STATS(lro_mgr, flushed); lro_clear_desc(lro_desc); } static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb, - struct vlan_group *vgrp, u16 vlan_tag, void *priv) + void *priv) { struct net_lro_desc *lro_desc; struct iphdr *iph; @@ -360,7 +345,7 @@ static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb, goto out; skb->ip_summed = lro_mgr->ip_summed_aggr; - lro_init_desc(lro_desc, skb, iph, tcph, vlan_tag, vgrp); + lro_init_desc(lro_desc, skb, iph, tcph); LRO_INC_STATS(lro_mgr, aggregated); return 0; } @@ -433,8 +418,7 @@ static struct sk_buff *lro_gen_skb(struct net_lro_mgr *lro_mgr, static struct sk_buff *__lro_proc_segment(struct net_lro_mgr *lro_mgr, struct skb_frag_struct *frags, int len, int true_size, - struct vlan_group *vgrp, - u16 vlan_tag, void *priv, __wsum sum) + void *priv, __wsum sum) { struct net_lro_desc *lro_desc; struct iphdr *iph; @@ -480,7 +464,7 @@ static struct sk_buff *__lro_proc_segment(struct net_lro_mgr *lro_mgr, tcph = (void *)((u8 *)skb->data + vlan_hdr_len + IP_HDR_LEN(iph)); - lro_init_desc(lro_desc, skb, iph, tcph, 0, NULL); + lro_init_desc(lro_desc, skb, iph, tcph); LRO_INC_STATS(lro_mgr, aggregated); return NULL; } @@ -514,7 +498,7 @@ void lro_receive_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb, void *priv) { - if (__lro_proc_skb(lro_mgr, skb, NULL, 0, priv)) { + if (__lro_proc_skb(lro_mgr, skb, priv)) { if (lro_mgr->features & LRO_F_NAPI) netif_receive_skb(skb); else @@ -523,29 +507,13 @@ void lro_receive_skb(struct net_lro_mgr *lro_mgr, } EXPORT_SYMBOL(lro_receive_skb); -void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr, - struct sk_buff *skb, - struct vlan_group *vgrp, - u16 vlan_tag, - void *priv) -{ - if (__lro_proc_skb(lro_mgr, skb, vgrp, vlan_tag, priv)) { - if (lro_mgr->features & LRO_F_NAPI) - vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag); - else - vlan_hwaccel_rx(skb, vgrp, vlan_tag); - } -} -EXPORT_SYMBOL(lro_vlan_hwaccel_receive_skb); - void lro_receive_frags(struct net_lro_mgr *lro_mgr, struct skb_frag_struct *frags, int len, int true_size, void *priv, __wsum sum) { struct sk_buff *skb; - skb = __lro_proc_segment(lro_mgr, frags, len, true_size, NULL, 0, - priv, sum); + skb = __lro_proc_segment(lro_mgr, frags, len, true_size, priv, sum); if (!skb) return; @@ -556,26 +524,6 @@ void lro_receive_frags(struct net_lro_mgr *lro_mgr, } EXPORT_SYMBOL(lro_receive_frags); -void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr, - struct skb_frag_struct *frags, - int len, int true_size, - struct vlan_group *vgrp, - u16 vlan_tag, void *priv, __wsum sum) -{ - struct sk_buff *skb; - - skb = __lro_proc_segment(lro_mgr, frags, len, true_size, vgrp, - vlan_tag, priv, sum); - if (!skb) - return; - - if (lro_mgr->features & LRO_F_NAPI) - vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag); - else - vlan_hwaccel_rx(skb, vgrp, vlan_tag); -} -EXPORT_SYMBOL(lro_vlan_hwaccel_receive_frags); - void lro_flush_all(struct net_lro_mgr *lro_mgr) { int i; diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 90c5f0d1bcf3..e38213817d0a 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -391,7 +391,7 @@ static int inet_peer_gc(struct inet_peer_base *base, return cnt; } -struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create) +struct inet_peer *inet_getpeer(const struct inetpeer_addr *daddr, int create) { struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; struct inet_peer_base *base = family_to_base(daddr->family); @@ -436,7 +436,10 @@ relookup: p->daddr = *daddr; atomic_set(&p->refcnt, 1); atomic_set(&p->rid, 0); - atomic_set(&p->ip_id_count, secure_ip_id(daddr->addr.a4)); + atomic_set(&p->ip_id_count, + (daddr->family == AF_INET) ? + secure_ip_id(daddr->addr.a4) : + secure_ipv6_id(daddr->addr.a6)); p->tcp_ts_stamp = 0; p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; p->rate_tokens = 0; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index be27e609a98b..ccaaa851ab42 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -734,7 +734,7 @@ static inline int ip_ufo_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), void *from, int length, int hh_len, int fragheaderlen, - int transhdrlen, int mtu, unsigned int flags) + int transhdrlen, int maxfraglen, unsigned int flags) { struct sk_buff *skb; int err; @@ -767,7 +767,7 @@ static inline int ip_ufo_append_data(struct sock *sk, skb->csum = 0; /* specify the length of each IP datagram fragment */ - skb_shinfo(skb)->gso_size = mtu - fragheaderlen; + skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen; skb_shinfo(skb)->gso_type = SKB_GSO_UDP; __skb_queue_tail(queue, skb); } @@ -831,7 +831,7 @@ static int __ip_append_data(struct sock *sk, (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) { err = ip_ufo_append_data(sk, queue, getfrag, from, length, hh_len, fragheaderlen, transhdrlen, - mtu, flags); + maxfraglen, flags); if (err) goto error; return 0; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 8db0e4875ad8..32e5339db0c8 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -596,6 +596,31 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) return offset; } +void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) +{ + static atomic_t ipv6_fragmentation_id; + int old, new; + + if (rt) { + struct inet_peer *peer; + + if (!rt->rt6i_peer) + rt6_bind_peer(rt, 1); + peer = rt->rt6i_peer; + if (peer) { + fhdr->identification = htonl(inet_getid(peer, 0)); + return; + } + } + do { + old = atomic_read(&ipv6_fragmentation_id); + new = old + 1; + if (!new) + new = 1; + } while (atomic_cmpxchg(&ipv6_fragmentation_id, old, new) != old); + fhdr->identification = htonl(new); +} + int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) { struct sk_buff *frag; @@ -680,7 +705,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) skb_reset_network_header(skb); memcpy(skb_network_header(skb), tmp_hdr, hlen); - ipv6_select_ident(fh); + ipv6_select_ident(fh, rt); fh->nexthdr = nexthdr; fh->reserved = 0; fh->frag_off = htons(IP6_MF); @@ -826,7 +851,7 @@ slow_path: fh->nexthdr = nexthdr; fh->reserved = 0; if (!frag_id) { - ipv6_select_ident(fh); + ipv6_select_ident(fh, rt); frag_id = fh->identification; } else fh->identification = frag_id; @@ -1076,7 +1101,8 @@ static inline int ip6_ufo_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), void *from, int length, int hh_len, int fragheaderlen, - int transhdrlen, int mtu,unsigned int flags) + int transhdrlen, int mtu,unsigned int flags, + struct rt6_info *rt) { struct sk_buff *skb; @@ -1120,7 +1146,7 @@ static inline int ip6_ufo_append_data(struct sock *sk, skb_shinfo(skb)->gso_size = (mtu - fragheaderlen - sizeof(struct frag_hdr)) & ~7; skb_shinfo(skb)->gso_type = SKB_GSO_UDP; - ipv6_select_ident(&fhdr); + ipv6_select_ident(&fhdr, rt); skb_shinfo(skb)->ip6_frag_id = fhdr.identification; __skb_queue_tail(&sk->sk_write_queue, skb); @@ -1286,7 +1312,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, err = ip6_ufo_append_data(sk, getfrag, from, length, hh_len, fragheaderlen, - transhdrlen, mtu, flags); + transhdrlen, mtu, flags, rt); if (err) goto error; return 0; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index ddef80f568b0..e8987da06667 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -72,7 +72,8 @@ #define RT6_TRACE(x...) do { ; } while (0) #endif -static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); +static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, + const struct in6_addr *dest); static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); static unsigned int ip6_default_advmss(const struct dst_entry *dst); static unsigned int ip6_default_mtu(const struct dst_entry *dst); @@ -690,7 +691,8 @@ int ip6_ins_rt(struct rt6_info *rt) return __ip6_ins_rt(rt, &info); } -static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_addr *daddr, +static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort, + const struct in6_addr *daddr, const struct in6_addr *saddr) { struct rt6_info *rt; @@ -699,7 +701,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add * Clone the route. */ - rt = ip6_rt_copy(ort); + rt = ip6_rt_copy(ort, daddr); if (rt) { struct neighbour *neigh; @@ -707,12 +709,11 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add if (!(rt->rt6i_flags&RTF_GATEWAY)) { if (rt->rt6i_dst.plen != 128 && - ipv6_addr_equal(&rt->rt6i_dst.addr, daddr)) + ipv6_addr_equal(&ort->rt6i_dst.addr, daddr)) rt->rt6i_flags |= RTF_ANYCAST; ipv6_addr_copy(&rt->rt6i_gateway, daddr); } - ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); rt->rt6i_dst.plen = 128; rt->rt6i_flags |= RTF_CACHE; rt->dst.flags |= DST_HOST; @@ -759,11 +760,12 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add return rt; } -static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, const struct in6_addr *daddr) +static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, + const struct in6_addr *daddr) { - struct rt6_info *rt = ip6_rt_copy(ort); + struct rt6_info *rt = ip6_rt_copy(ort, daddr); + if (rt) { - ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); rt->rt6i_dst.plen = 128; rt->rt6i_flags |= RTF_CACHE; rt->dst.flags |= DST_HOST; @@ -907,7 +909,10 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori new->input = dst_discard; new->output = dst_discard; - dst_copy_metrics(new, &ort->dst); + if (dst_metrics_read_only(&ort->dst)) + new->_metrics = ort->dst._metrics; + else + dst_copy_metrics(new, &ort->dst); rt->rt6i_idev = ort->rt6i_idev; if (rt->rt6i_idev) in6_dev_hold(rt->rt6i_idev); @@ -1067,6 +1072,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, rt->rt6i_idev = idev; dst_set_neighbour(&rt->dst, neigh); atomic_set(&rt->dst.__refcnt, 1); + ipv6_addr_copy(&rt->rt6i_dst.addr, addr); dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); rt->dst.output = ip6_output; @@ -1584,7 +1590,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, if (neigh == dst_get_neighbour(&rt->dst)) goto out; - nrt = ip6_rt_copy(rt); + nrt = ip6_rt_copy(rt, dest); if (nrt == NULL) goto out; @@ -1592,7 +1598,6 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, if (on_link) nrt->rt6i_flags &= ~RTF_GATEWAY; - ipv6_addr_copy(&nrt->rt6i_dst.addr, dest); nrt->rt6i_dst.plen = 128; nrt->dst.flags |= DST_HOST; @@ -1730,7 +1735,8 @@ void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *sad * Misc support functions */ -static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) +static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, + const struct in6_addr *dest) { struct net *net = dev_net(ort->rt6i_dev); struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, @@ -1740,6 +1746,8 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) rt->dst.input = ort->dst.input; rt->dst.output = ort->dst.output; + ipv6_addr_copy(&rt->rt6i_dst.addr, dest); + rt->rt6i_dst.plen = ort->rt6i_dst.plen; dst_copy_metrics(&rt->dst, &ort->dst); rt->dst.error = ort->dst.error; rt->rt6i_idev = ort->rt6i_idev; @@ -1752,7 +1760,6 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; rt->rt6i_metric = 0; - memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key)); #ifdef CONFIG_IPV6_SUBTREES memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key)); #endif diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 328985c40883..29213b51c499 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1359,7 +1359,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, u32 features) fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen); fptr->nexthdr = nexthdr; fptr->reserved = 0; - ipv6_select_ident(fptr); + ipv6_select_ident(fptr, (struct rt6_info *)skb_dst(skb)); /* Fragment the skb. ipv6 header and the remaining fields of the * fragment header are updated in ipv6_gso_segment() diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c index fa80bb9b9c81..f2d576e6b769 100644 --- a/net/netfilter/ipset/ip_set_hash_ip.c +++ b/net/netfilter/ipset/ip_set_hash_ip.c @@ -53,7 +53,8 @@ struct hash_ip4_telem { static inline bool hash_ip4_data_equal(const struct hash_ip4_elem *ip1, - const struct hash_ip4_elem *ip2) + const struct hash_ip4_elem *ip2, + u32 *multi) { return ip1->ip == ip2->ip; } @@ -225,7 +226,8 @@ struct hash_ip6_telem { static inline bool hash_ip6_data_equal(const struct hash_ip6_elem *ip1, - const struct hash_ip6_elem *ip2) + const struct hash_ip6_elem *ip2, + u32 *multi) { return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0; } diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c index bbf51b67b170..6ee10f5d59bd 100644 --- a/net/netfilter/ipset/ip_set_hash_ipport.c +++ b/net/netfilter/ipset/ip_set_hash_ipport.c @@ -60,7 +60,8 @@ struct hash_ipport4_telem { static inline bool hash_ipport4_data_equal(const struct hash_ipport4_elem *ip1, - const struct hash_ipport4_elem *ip2) + const struct hash_ipport4_elem *ip2, + u32 *multi) { return ip1->ip == ip2->ip && ip1->port == ip2->port && @@ -276,7 +277,8 @@ struct hash_ipport6_telem { static inline bool hash_ipport6_data_equal(const struct hash_ipport6_elem *ip1, - const struct hash_ipport6_elem *ip2) + const struct hash_ipport6_elem *ip2, + u32 *multi) { return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 && ip1->port == ip2->port && diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c index 96525f529a54..fb90e344e907 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportip.c +++ b/net/netfilter/ipset/ip_set_hash_ipportip.c @@ -62,7 +62,8 @@ struct hash_ipportip4_telem { static inline bool hash_ipportip4_data_equal(const struct hash_ipportip4_elem *ip1, - const struct hash_ipportip4_elem *ip2) + const struct hash_ipportip4_elem *ip2, + u32 *multi) { return ip1->ip == ip2->ip && ip1->ip2 == ip2->ip2 && @@ -286,7 +287,8 @@ struct hash_ipportip6_telem { static inline bool hash_ipportip6_data_equal(const struct hash_ipportip6_elem *ip1, - const struct hash_ipportip6_elem *ip2) + const struct hash_ipportip6_elem *ip2, + u32 *multi) { return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 && ipv6_addr_cmp(&ip1->ip2.in6, &ip2->ip2.in6) == 0 && diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index d2d6ab89f087..deb3e3dfa5fc 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c @@ -62,7 +62,8 @@ struct hash_ipportnet4_telem { static inline bool hash_ipportnet4_data_equal(const struct hash_ipportnet4_elem *ip1, - const struct hash_ipportnet4_elem *ip2) + const struct hash_ipportnet4_elem *ip2, + u32 *multi) { return ip1->ip == ip2->ip && ip1->ip2 == ip2->ip2 && @@ -335,7 +336,8 @@ struct hash_ipportnet6_telem { static inline bool hash_ipportnet6_data_equal(const struct hash_ipportnet6_elem *ip1, - const struct hash_ipportnet6_elem *ip2) + const struct hash_ipportnet6_elem *ip2, + u32 *multi) { return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 && ipv6_addr_cmp(&ip1->ip2.in6, &ip2->ip2.in6) == 0 && diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c index 2d4b1f48e8c9..60d016541c58 100644 --- a/net/netfilter/ipset/ip_set_hash_net.c +++ b/net/netfilter/ipset/ip_set_hash_net.c @@ -58,7 +58,8 @@ struct hash_net4_telem { static inline bool hash_net4_data_equal(const struct hash_net4_elem *ip1, - const struct hash_net4_elem *ip2) + const struct hash_net4_elem *ip2, + u32 *multi) { return ip1->ip == ip2->ip && ip1->cidr == ip2->cidr; } @@ -249,7 +250,8 @@ struct hash_net6_telem { static inline bool hash_net6_data_equal(const struct hash_net6_elem *ip1, - const struct hash_net6_elem *ip2) + const struct hash_net6_elem *ip2, + u32 *multi) { return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 && ip1->cidr == ip2->cidr; diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c index 3d6c53b6211a..e13095deb50d 100644 --- a/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/net/netfilter/ipset/ip_set_hash_netiface.c @@ -99,7 +99,7 @@ iface_test(struct rb_root *root, const char **iface) while (n) { const char *d = iface_data(n); - int res = ifname_compare(*iface, d); + long res = ifname_compare(*iface, d); if (res < 0) n = n->rb_left; @@ -121,7 +121,7 @@ iface_add(struct rb_root *root, const char **iface) while (*n) { char *ifname = iface_data(*n); - int res = ifname_compare(*iface, ifname); + long res = ifname_compare(*iface, ifname); p = *n; if (res < 0) @@ -159,31 +159,42 @@ hash_netiface_same_set(const struct ip_set *a, const struct ip_set *b); /* The type variant functions: IPv4 */ +struct hash_netiface4_elem_hashed { + __be32 ip; + u8 physdev; + u8 cidr; + u16 padding; +}; + +#define HKEY_DATALEN sizeof(struct hash_netiface4_elem_hashed) + /* Member elements without timeout */ struct hash_netiface4_elem { __be32 ip; - const char *iface; u8 physdev; u8 cidr; u16 padding; + const char *iface; }; /* Member elements with timeout support */ struct hash_netiface4_telem { __be32 ip; - const char *iface; u8 physdev; u8 cidr; u16 padding; + const char *iface; unsigned long timeout; }; static inline bool hash_netiface4_data_equal(const struct hash_netiface4_elem *ip1, - const struct hash_netiface4_elem *ip2) + const struct hash_netiface4_elem *ip2, + u32 *multi) { return ip1->ip == ip2->ip && ip1->cidr == ip2->cidr && + (++*multi) && ip1->physdev == ip2->physdev && ip1->iface == ip2->iface; } @@ -257,6 +268,7 @@ nla_put_failure: #define IP_SET_HASH_WITH_NETS #define IP_SET_HASH_WITH_RBTREE +#define IP_SET_HASH_WITH_MULTI #define PF 4 #define HOST_MASK 32 @@ -424,29 +436,40 @@ hash_netiface_same_set(const struct ip_set *a, const struct ip_set *b) /* The type variant functions: IPv6 */ +struct hash_netiface6_elem_hashed { + union nf_inet_addr ip; + u8 physdev; + u8 cidr; + u16 padding; +}; + +#define HKEY_DATALEN sizeof(struct hash_netiface6_elem_hashed) + struct hash_netiface6_elem { union nf_inet_addr ip; - const char *iface; u8 physdev; u8 cidr; u16 padding; + const char *iface; }; struct hash_netiface6_telem { union nf_inet_addr ip; - const char *iface; u8 physdev; u8 cidr; u16 padding; + const char *iface; unsigned long timeout; }; static inline bool hash_netiface6_data_equal(const struct hash_netiface6_elem *ip1, - const struct hash_netiface6_elem *ip2) + const struct hash_netiface6_elem *ip2, + u32 *multi) { return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 && ip1->cidr == ip2->cidr && + (++*multi) && ip1->physdev == ip2->physdev && ip1->iface == ip2->iface; } @@ -681,6 +704,7 @@ hash_netiface_create(struct ip_set *set, struct nlattr *tb[], u32 flags) h->maxelem = maxelem; get_random_bytes(&h->initval, sizeof(h->initval)); h->timeout = IPSET_NO_TIMEOUT; + h->ahash_max = AHASH_MAX_SIZE; hbits = htable_bits(hashsize); h->table = ip_set_alloc( diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c index fe203d12f56b..8f9de7207ec9 100644 --- a/net/netfilter/ipset/ip_set_hash_netport.c +++ b/net/netfilter/ipset/ip_set_hash_netport.c @@ -59,7 +59,8 @@ struct hash_netport4_telem { static inline bool hash_netport4_data_equal(const struct hash_netport4_elem *ip1, - const struct hash_netport4_elem *ip2) + const struct hash_netport4_elem *ip2, + u32 *multi) { return ip1->ip == ip2->ip && ip1->port == ip2->port && @@ -300,7 +301,8 @@ struct hash_netport6_telem { static inline bool hash_netport6_data_equal(const struct hash_netport6_elem *ip1, - const struct hash_netport6_elem *ip2) + const struct hash_netport6_elem *ip2, + u32 *multi) { return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 && ip1->port == ip2->port && diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index b4a4532823e8..1905976b5135 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -37,7 +37,7 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NETFILTER); static char __initdata nfversion[] = "0.30"; -static const struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT]; +static const struct nfnetlink_subsystem __rcu *subsys_table[NFNL_SUBSYS_COUNT]; static DEFINE_MUTEX(nfnl_mutex); void nfnl_lock(void) @@ -59,7 +59,7 @@ int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n) nfnl_unlock(); return -EBUSY; } - subsys_table[n->subsys_id] = n; + rcu_assign_pointer(subsys_table[n->subsys_id], n); nfnl_unlock(); return 0; @@ -71,7 +71,7 @@ int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n) nfnl_lock(); subsys_table[n->subsys_id] = NULL; nfnl_unlock(); - + synchronize_rcu(); return 0; } EXPORT_SYMBOL_GPL(nfnetlink_subsys_unregister); @@ -83,7 +83,7 @@ static inline const struct nfnetlink_subsystem *nfnetlink_get_subsys(u_int16_t t if (subsys_id >= NFNL_SUBSYS_COUNT) return NULL; - return subsys_table[subsys_id]; + return rcu_dereference(subsys_table[subsys_id]); } static inline const struct nfnl_callback * @@ -139,21 +139,27 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) type = nlh->nlmsg_type; replay: + rcu_read_lock(); ss = nfnetlink_get_subsys(type); if (!ss) { #ifdef CONFIG_MODULES - nfnl_unlock(); + rcu_read_unlock(); request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type)); - nfnl_lock(); + rcu_read_lock(); ss = nfnetlink_get_subsys(type); if (!ss) #endif + { + rcu_read_unlock(); return -EINVAL; + } } nc = nfnetlink_find_client(type, ss); - if (!nc) + if (!nc) { + rcu_read_unlock(); return -EINVAL; + } { int min_len = NLMSG_SPACE(sizeof(struct nfgenmsg)); @@ -167,7 +173,23 @@ replay: if (err < 0) return err; - err = nc->call(net->nfnl, skb, nlh, (const struct nlattr **)cda); + if (nc->call_rcu) { + err = nc->call_rcu(net->nfnl, skb, nlh, + (const struct nlattr **)cda); + rcu_read_unlock(); + } else { + rcu_read_unlock(); + nfnl_lock(); + if (rcu_dereference_protected( + subsys_table[NFNL_SUBSYS_ID(type)], + lockdep_is_held(&nfnl_mutex)) != ss || + nfnetlink_find_client(type, ss) != nc) + err = -EAGAIN; + else + err = nc->call(net->nfnl, skb, nlh, + (const struct nlattr **)cda); + nfnl_unlock(); + } if (err == -EAGAIN) goto replay; return err; @@ -176,9 +198,7 @@ replay: static void nfnetlink_rcv(struct sk_buff *skb) { - nfnl_lock(); netlink_rcv_skb(skb, &nfnetlink_rcv_msg); - nfnl_unlock(); } static int __net_init nfnetlink_net_init(struct net *net) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index fdd2fafe0a14..49132bddd73e 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -58,7 +58,7 @@ struct nfqnl_instance { */ spinlock_t lock; unsigned int queue_total; - atomic_t id_sequence; /* 'sequence' of pkt ids */ + unsigned int id_sequence; /* 'sequence' of pkt ids */ struct list_head queue_list; /* packets in queue */ }; @@ -171,6 +171,13 @@ __enqueue_entry(struct nfqnl_instance *queue, struct nf_queue_entry *entry) queue->queue_total++; } +static void +__dequeue_entry(struct nfqnl_instance *queue, struct nf_queue_entry *entry) +{ + list_del(&entry->list); + queue->queue_total--; +} + static struct nf_queue_entry * find_dequeue_entry(struct nfqnl_instance *queue, unsigned int id) { @@ -185,10 +192,8 @@ find_dequeue_entry(struct nfqnl_instance *queue, unsigned int id) } } - if (entry) { - list_del(&entry->list); - queue->queue_total--; - } + if (entry) + __dequeue_entry(queue, entry); spin_unlock_bh(&queue->lock); @@ -213,13 +218,15 @@ nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn, unsigned long data) static struct sk_buff * nfqnl_build_packet_message(struct nfqnl_instance *queue, - struct nf_queue_entry *entry) + struct nf_queue_entry *entry, + __be32 **packet_id_ptr) { sk_buff_data_t old_tail; size_t size; size_t data_len = 0; struct sk_buff *skb; - struct nfqnl_msg_packet_hdr pmsg; + struct nlattr *nla; + struct nfqnl_msg_packet_hdr *pmsg; struct nlmsghdr *nlh; struct nfgenmsg *nfmsg; struct sk_buff *entskb = entry->skb; @@ -272,12 +279,11 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, nfmsg->version = NFNETLINK_V0; nfmsg->res_id = htons(queue->queue_num); - entry->id = atomic_inc_return(&queue->id_sequence); - pmsg.packet_id = htonl(entry->id); - pmsg.hw_protocol = entskb->protocol; - pmsg.hook = entry->hook; - - NLA_PUT(skb, NFQA_PACKET_HDR, sizeof(pmsg), &pmsg); + nla = __nla_reserve(skb, NFQA_PACKET_HDR, sizeof(*pmsg)); + pmsg = nla_data(nla); + pmsg->hw_protocol = entskb->protocol; + pmsg->hook = entry->hook; + *packet_id_ptr = &pmsg->packet_id; indev = entry->indev; if (indev) { @@ -389,6 +395,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) struct sk_buff *nskb; struct nfqnl_instance *queue; int err = -ENOBUFS; + __be32 *packet_id_ptr; /* rcu_read_lock()ed by nf_hook_slow() */ queue = instance_lookup(queuenum); @@ -402,7 +409,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) goto err_out; } - nskb = nfqnl_build_packet_message(queue, entry); + nskb = nfqnl_build_packet_message(queue, entry, &packet_id_ptr); if (nskb == NULL) { err = -ENOMEM; goto err_out; @@ -421,6 +428,8 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) queue->queue_total); goto err_out_free_nskb; } + entry->id = ++queue->id_sequence; + *packet_id_ptr = htonl(entry->id); /* nfnetlink_unicast will either free the nskb or add it to a socket */ err = nfnetlink_unicast(nskb, &init_net, queue->peer_pid, MSG_DONTWAIT); @@ -608,6 +617,92 @@ static const struct nla_policy nfqa_verdict_policy[NFQA_MAX+1] = { [NFQA_PAYLOAD] = { .type = NLA_UNSPEC }, }; +static const struct nla_policy nfqa_verdict_batch_policy[NFQA_MAX+1] = { + [NFQA_VERDICT_HDR] = { .len = sizeof(struct nfqnl_msg_verdict_hdr) }, + [NFQA_MARK] = { .type = NLA_U32 }, +}; + +static struct nfqnl_instance *verdict_instance_lookup(u16 queue_num, int nlpid) +{ + struct nfqnl_instance *queue; + + queue = instance_lookup(queue_num); + if (!queue) + return ERR_PTR(-ENODEV); + + if (queue->peer_pid != nlpid) + return ERR_PTR(-EPERM); + + return queue; +} + +static struct nfqnl_msg_verdict_hdr* +verdicthdr_get(const struct nlattr * const nfqa[]) +{ + struct nfqnl_msg_verdict_hdr *vhdr; + unsigned int verdict; + + if (!nfqa[NFQA_VERDICT_HDR]) + return NULL; + + vhdr = nla_data(nfqa[NFQA_VERDICT_HDR]); + verdict = ntohl(vhdr->verdict); + if ((verdict & NF_VERDICT_MASK) > NF_MAX_VERDICT) + return NULL; + return vhdr; +} + +static int nfq_id_after(unsigned int id, unsigned int max) +{ + return (int)(id - max) > 0; +} + +static int +nfqnl_recv_verdict_batch(struct sock *ctnl, struct sk_buff *skb, + const struct nlmsghdr *nlh, + const struct nlattr * const nfqa[]) +{ + struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); + struct nf_queue_entry *entry, *tmp; + unsigned int verdict, maxid; + struct nfqnl_msg_verdict_hdr *vhdr; + struct nfqnl_instance *queue; + LIST_HEAD(batch_list); + u16 queue_num = ntohs(nfmsg->res_id); + + queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).pid); + if (IS_ERR(queue)) + return PTR_ERR(queue); + + vhdr = verdicthdr_get(nfqa); + if (!vhdr) + return -EINVAL; + + verdict = ntohl(vhdr->verdict); + maxid = ntohl(vhdr->id); + + spin_lock_bh(&queue->lock); + + list_for_each_entry_safe(entry, tmp, &queue->queue_list, list) { + if (nfq_id_after(entry->id, maxid)) + break; + __dequeue_entry(queue, entry); + list_add_tail(&entry->list, &batch_list); + } + + spin_unlock_bh(&queue->lock); + + if (list_empty(&batch_list)) + return -ENOENT; + + list_for_each_entry_safe(entry, tmp, &batch_list, list) { + if (nfqa[NFQA_MARK]) + entry->skb->mark = ntohl(nla_get_be32(nfqa[NFQA_MARK])); + nf_reinject(entry, verdict); + } + return 0; +} + static int nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, const struct nlmsghdr *nlh, @@ -620,39 +715,23 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, struct nfqnl_instance *queue; unsigned int verdict; struct nf_queue_entry *entry; - int err; - rcu_read_lock(); queue = instance_lookup(queue_num); - if (!queue) { - err = -ENODEV; - goto err_out_unlock; - } + if (!queue) - if (queue->peer_pid != NETLINK_CB(skb).pid) { - err = -EPERM; - goto err_out_unlock; - } + queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).pid); + if (IS_ERR(queue)) + return PTR_ERR(queue); - if (!nfqa[NFQA_VERDICT_HDR]) { - err = -EINVAL; - goto err_out_unlock; - } + vhdr = verdicthdr_get(nfqa); + if (!vhdr) + return -EINVAL; - vhdr = nla_data(nfqa[NFQA_VERDICT_HDR]); verdict = ntohl(vhdr->verdict); - if ((verdict & NF_VERDICT_MASK) > NF_MAX_VERDICT) { - err = -EINVAL; - goto err_out_unlock; - } - entry = find_dequeue_entry(queue, ntohl(vhdr->id)); - if (entry == NULL) { - err = -ENOENT; - goto err_out_unlock; - } - rcu_read_unlock(); + if (entry == NULL) + return -ENOENT; if (nfqa[NFQA_PAYLOAD]) { if (nfqnl_mangle(nla_data(nfqa[NFQA_PAYLOAD]), @@ -665,10 +744,6 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, nf_reinject(entry, verdict); return 0; - -err_out_unlock: - rcu_read_unlock(); - return err; } static int @@ -781,14 +856,17 @@ err_out_unlock: } static const struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = { - [NFQNL_MSG_PACKET] = { .call = nfqnl_recv_unsupp, + [NFQNL_MSG_PACKET] = { .call_rcu = nfqnl_recv_unsupp, .attr_count = NFQA_MAX, }, - [NFQNL_MSG_VERDICT] = { .call = nfqnl_recv_verdict, + [NFQNL_MSG_VERDICT] = { .call_rcu = nfqnl_recv_verdict, .attr_count = NFQA_MAX, .policy = nfqa_verdict_policy }, [NFQNL_MSG_CONFIG] = { .call = nfqnl_recv_config, .attr_count = NFQA_CFG_MAX, .policy = nfqa_cfg_policy }, + [NFQNL_MSG_VERDICT_BATCH]={ .call_rcu = nfqnl_recv_verdict_batch, + .attr_count = NFQA_MAX, + .policy = nfqa_verdict_batch_policy }, }; static const struct nfnetlink_subsystem nfqnl_subsys = { @@ -870,7 +948,7 @@ static int seq_show(struct seq_file *s, void *v) inst->peer_pid, inst->queue_total, inst->copy_mode, inst->copy_range, inst->queue_dropped, inst->queue_user_dropped, - atomic_read(&inst->id_sequence), 1); + inst->id_sequence, 1); } static const struct seq_operations nfqnl_seq_ops = { diff --git a/net/netfilter/xt_AUDIT.c b/net/netfilter/xt_AUDIT.c index 363a99ec0637..4bca15a0c385 100644 --- a/net/netfilter/xt_AUDIT.c +++ b/net/netfilter/xt_AUDIT.c @@ -163,6 +163,11 @@ audit_tg(struct sk_buff *skb, const struct xt_action_param *par) break; } +#ifdef CONFIG_NETWORK_SECMARK + if (skb->secmark) + audit_log_secctx(ab, skb->secmark); +#endif + audit_log_end(ab); errout: diff --git a/net/sctp/output.c b/net/sctp/output.c index b4f3cf06d8da..08b3cead6503 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -500,23 +500,20 @@ int sctp_packet_transmit(struct sctp_packet *packet) * Note: Adler-32 is no longer applicable, as has been replaced * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. */ - if (!sctp_checksum_disable && - !(dst->dev->features & (NETIF_F_NO_CSUM | NETIF_F_SCTP_CSUM))) { - __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); + if (!sctp_checksum_disable) { + if (!(dst->dev->features & NETIF_F_SCTP_CSUM)) { + __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); - /* 3) Put the resultant value into the checksum field in the - * common header, and leave the rest of the bits unchanged. - */ - sh->checksum = sctp_end_cksum(crc32); - } else { - if (dst->dev->features & NETIF_F_SCTP_CSUM) { + /* 3) Put the resultant value into the checksum field in the + * common header, and leave the rest of the bits unchanged. + */ + sh->checksum = sctp_end_cksum(crc32); + } else { /* no need to seed pseudo checksum for SCTP */ nskb->ip_summed = CHECKSUM_PARTIAL; nskb->csum_start = (skb_transport_header(nskb) - nskb->head); nskb->csum_offset = offsetof(struct sctphdr, checksum); - } else { - nskb->ip_summed = CHECKSUM_UNNECESSARY; } } diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index c2fc0356c2a4..83014a7c2e14 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1190,7 +1190,6 @@ SND_SOC_DAPM_INPUT("DMIC1DAT"), SND_SOC_DAPM_INPUT("DMIC2DAT"), SND_SOC_DAPM_INPUT("Clock"), -SND_SOC_DAPM_MICBIAS("MICBIAS", WM8994_MICBIAS, 2, 0), SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev, SND_SOC_DAPM_PRE_PMU), @@ -1509,8 +1508,10 @@ static const struct snd_soc_dapm_route wm8994_revd_intercon[] = { { "AIF2DACDAT", NULL, "AIF1DACDAT" }, { "AIF1ADCDAT", NULL, "AIF2ADCDAT" }, { "AIF2ADCDAT", NULL, "AIF1ADCDAT" }, - { "MICBIAS", NULL, "CLK_SYS" }, - { "MICBIAS", NULL, "MICBIAS Supply" }, + { "MICBIAS1", NULL, "CLK_SYS" }, + { "MICBIAS1", NULL, "MICBIAS Supply" }, + { "MICBIAS2", NULL, "CLK_SYS" }, + { "MICBIAS2", NULL, "MICBIAS Supply" }, }; static const struct snd_soc_dapm_route wm8994_intercon[] = { @@ -2763,7 +2764,7 @@ static void wm8958_default_micdet(u16 status, void *data) report = SND_JACK_MICROPHONE; /* Everything else is buttons; just assign slots */ - if (status & 0x1c0) + if (status & 0x1c) report |= SND_JACK_BTN_0; done: diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c index d6f4703b3c07..770a71a15366 100644 --- a/sound/soc/sh/fsi-ak4642.c +++ b/sound/soc/sh/fsi-ak4642.c @@ -97,7 +97,7 @@ static int fsi_ak4642_remove(struct platform_device *pdev) static struct fsi_ak4642_data fsi_a_ak4642 = { .name = "AK4642", - .card = "FSIA (AK4642)", + .card = "FSIA-AK4642", .cpu_dai = "fsia-dai", .codec = "ak4642-codec.0-0012", .platform = "sh_fsi.0", @@ -106,7 +106,7 @@ static struct fsi_ak4642_data fsi_a_ak4642 = { static struct fsi_ak4642_data fsi_b_ak4642 = { .name = "AK4642", - .card = "FSIB (AK4642)", + .card = "FSIB-AK4642", .cpu_dai = "fsib-dai", .codec = "ak4642-codec.0-0012", .platform = "sh_fsi.0", @@ -115,7 +115,7 @@ static struct fsi_ak4642_data fsi_b_ak4642 = { static struct fsi_ak4642_data fsi_a_ak4643 = { .name = "AK4643", - .card = "FSIA (AK4643)", + .card = "FSIA-AK4643", .cpu_dai = "fsia-dai", .codec = "ak4642-codec.0-0013", .platform = "sh_fsi.0", @@ -124,7 +124,7 @@ static struct fsi_ak4642_data fsi_a_ak4643 = { static struct fsi_ak4642_data fsi_b_ak4643 = { .name = "AK4643", - .card = "FSIB (AK4643)", + .card = "FSIB-AK4643", .cpu_dai = "fsib-dai", .codec = "ak4642-codec.0-0013", .platform = "sh_fsi.0", @@ -133,7 +133,7 @@ static struct fsi_ak4642_data fsi_b_ak4643 = { static struct fsi_ak4642_data fsi2_a_ak4642 = { .name = "AK4642", - .card = "FSI2A (AK4642)", + .card = "FSI2A-AK4642", .cpu_dai = "fsia-dai", .codec = "ak4642-codec.0-0012", .platform = "sh_fsi2", @@ -142,7 +142,7 @@ static struct fsi_ak4642_data fsi2_a_ak4642 = { static struct fsi_ak4642_data fsi2_b_ak4642 = { .name = "AK4642", - .card = "FSI2B (AK4642)", + .card = "FSI2B-AK4642", .cpu_dai = "fsib-dai", .codec = "ak4642-codec.0-0012", .platform = "sh_fsi2", @@ -151,7 +151,7 @@ static struct fsi_ak4642_data fsi2_b_ak4642 = { static struct fsi_ak4642_data fsi2_a_ak4643 = { .name = "AK4643", - .card = "FSI2A (AK4643)", + .card = "FSI2A-AK4643", .cpu_dai = "fsia-dai", .codec = "ak4642-codec.0-0013", .platform = "sh_fsi2", @@ -160,7 +160,7 @@ static struct fsi_ak4642_data fsi2_a_ak4643 = { static struct fsi_ak4642_data fsi2_b_ak4643 = { .name = "AK4643", - .card = "FSI2B (AK4643)", + .card = "FSI2B-AK4643", .cpu_dai = "fsib-dai", .codec = "ak4642-codec.0-0013", .platform = "sh_fsi2", diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c index dbafd7ac5590..59553fd8c2fb 100644 --- a/sound/soc/sh/fsi-da7210.c +++ b/sound/soc/sh/fsi-da7210.c @@ -42,7 +42,7 @@ static struct snd_soc_dai_link fsi_da7210_dai = { }; static struct snd_soc_card fsi_soc_card = { - .name = "FSI (DA7210)", + .name = "FSI-DA7210", .dai_link = &fsi_da7210_dai, .num_links = 1, }; diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c index 9719985eb82d..d3d9fd880680 100644 --- a/sound/soc/sh/fsi-hdmi.c +++ b/sound/soc/sh/fsi-hdmi.c @@ -83,13 +83,13 @@ static int fsi_hdmi_remove(struct platform_device *pdev) static struct fsi_hdmi_data fsi2_a_hdmi = { .cpu_dai = "fsia-dai", - .card = "FSI2A (SH MOBILE HDMI)", + .card = "FSI2A-HDMI", .id = FSI_PORT_A, }; static struct fsi_hdmi_data fsi2_b_hdmi = { .cpu_dai = "fsib-dai", - .card = "FSI2B (SH MOBILE HDMI)", + .card = "FSI2B-HDMI", .id = FSI_PORT_B, }; |